__init__.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from Stats.DeviceStats import DeviceStats as _DeviceStats
  4. from Stats.HouseStats import HouseStats as _HouseStats
  5. from Stats.MicLevel import MicLevel as _MicLevel
  6. from Stats.OutdoorStats import OutdoorStats as _OutdoorStats
  7. from Stats.OwnerStats import OwnerStats as _OwnerStats
  8. from Stats.TalkingStats import TalkingStats as _TalkingStats
  9. from Stats.AdminStats import AdminStats as _AdminStats
  10. import MicCapture
  11. import OpenWeatherMap
  12. from Homematic import Homematic
  13. from threading import Timer
  14. import time
  15. import datetime
  16. import configparser
  17. from RepeatTimer import RepeatTimer
  18. import lib.MoonPhase as mp
  19. import random
  20. class Stats(object):
  21. instance = None
  22. @staticmethod
  23. def getInstance():
  24. if Stats.instance==None:
  25. Stats.instance = Stats()
  26. return Stats.instance
  27. deviceStats = _DeviceStats()
  28. houseStats = _HouseStats()
  29. micLevel = _MicLevel()
  30. outdoorStats = _OutdoorStats()
  31. ownerStats = _OwnerStats()
  32. talkingStats = _TalkingStats()
  33. adminStats = _AdminStats()
  34. weather = OpenWeatherMap.OpenWeatherMap()
  35. UPDATE_EMOTION_DELAY_MINUTE = 1.66
  36. UPDATE_HOMEMATIC_DELAY_MINUTE = 1
  37. UPDATE_DATETIME_DELAY_MINUTE = 10
  38. UPDATE_OUTDOOR_DELAY_MINUTE = 2.1
  39. UPDATE_MIC_DELAY_MINUTE = 0.5
  40. Thread_Homematic = None
  41. Thread_Emotion = None
  42. Thread_DateTime = None
  43. Thread_OutDoor = None
  44. Thread_Mic = None
  45. lastUpdate = 0.0
  46. homematic = None
  47. moonPhase = None
  48. Mic = MicCapture.MicCapture()
  49. def __init__(self):
  50. print("Init Stats")
  51. print("- Read Config")
  52. try:
  53. config = configparser.ConfigParser()
  54. config.read('config.ini')
  55. except:
  56. print("Failed to get Config")
  57. config = dict
  58. config["Homematic"] = dict
  59. config["Homematic"]["url"]=""
  60. config["Homematic"]["SwitchList"]=""
  61. config["Homematic"]["LightList"]=""
  62. config["Homematic"]["TermoList"]=""
  63. config["Homematic"]["DoorList"]=""
  64. config["Homematic"]["WindowList"]=""
  65. self.moonPhase = mp.phase(time=datetime.datetime.now())
  66. self.deviceStats.lastUpdate = time.time()
  67. print("- Init Homematic")
  68. if config["Homematic"]["url"]!="":
  69. self.homematic = Homematic(config["Homematic"]["url"], {
  70. "SwitchList":config["Homematic"]["SwitchList"],
  71. "LightList":config["Homematic"]["LightList"],
  72. "TermoList":config["Homematic"]["TermoList"],
  73. "DoorList":config["Homematic"]["DoorList"],
  74. "WindowList":config["Homematic"]["WindowList"]
  75. })
  76. if self.homematic.bConnected:
  77. print("- - Homematic conected")
  78. print("- - Update HomeMatic")
  79. self.__UpdateHomematic()
  80. print("- - Start Homematic-Timer")
  81. self.Thread_Homematic = RepeatTimer(self.UPDATE_HOMEMATIC_DELAY_MINUTE*60, self.__UpdateHomematic)
  82. self.Thread_Homematic.start()
  83. else:
  84. print("- - No homatic")
  85. print("- - HomeMatic Done")
  86. else:
  87. print("- - Homematic failed")
  88. self.__UpdateDateTime()
  89. self.Thread_DateTime = RepeatTimer(self.UPDATE_DATETIME_DELAY_MINUTE*60, self.__UpdateDateTime)
  90. self.Thread_DateTime.start()
  91. self.__UpdateOutdoor()
  92. self.Thread_OutDoor = RepeatTimer(self.UPDATE_OUTDOOR_DELAY_MINUTE*60, self.__UpdateOutdoor)
  93. self.Thread_OutDoor.start()
  94. self.Thread_Mic = RepeatTimer(self.UPDATE_MIC_DELAY_MINUTE*60, self.__UpdateMic)
  95. self.Thread_Mic.start()
  96. print("- Init Emotion")
  97. self.Thread_Emotion = RepeatTimer(self.UPDATE_EMOTION_DELAY_MINUTE*60, self.__UpdateEmotion)
  98. print("- - Start Emotion Timer")
  99. self.Thread_Emotion.start()
  100. print("- - Init Stats done")
  101. return super().__init__()
  102. def __UpdateMic(self):
  103. self.Mic.Update()
  104. self.micLevel.Volume_Min = self.Mic.LastResult["min"]
  105. self.micLevel.Volume_Max = self.Mic.LastResult["max"]
  106. self.micLevel.Volume_Avg = self.Mic.LastResult["avg"]
  107. print(self.micLevel.getJson())
  108. def __UpdateDateTime(self):
  109. self.moonPhase = mp.phase(time=datetime.datetime.now())
  110. def __UpdateOutdoor(self):
  111. self.weather.Update()
  112. self.outdoorStats.bRaining = self.weather.CurrentLocation.Rain.PerHour>0.1
  113. self.outdoorStats.bSnowing = self.weather.CurrentLocation.Rain.PerHour>0.1 and self.weather.CurrentLocation.Main.TempMax<1
  114. self.outdoorStats.bWindy = self.weather.CurrentLocation.Wind.Speed>20
  115. self.outdoorStats.Clouds = self.weather.CurrentLocation.Clouds.All
  116. self.outdoorStats.Humidity = self.weather.CurrentLocation.Main.Humidity
  117. self.outdoorStats.Pressure = self.weather.CurrentLocation.Main.Pressure
  118. self.outdoorStats.Temperature = self.weather.CurrentLocation.Main.Temperature
  119. self.outdoorStats.WindDegree = self.weather.CurrentLocation.Wind.Deg
  120. self.outdoorStats.WindSpeed = self.weather.CurrentLocation.Wind.Speed
  121. def __UpdateHomematic(self):
  122. print("Update Homematic")
  123. self.homematic.updateDevices()
  124. # Check open/closed windows
  125. self.houseStats.bAllWindowOpen = True
  126. self.houseStats.bAllWindowClosed = True
  127. for ise in self.homematic.favWindowList:
  128. if self.homematic.windowList[ise]["value"]==False:
  129. self.houseStats.bAllWindowOpen = False
  130. else:
  131. self.houseStats.bAllWindowClosed = False
  132. # Check open/closed doors
  133. self.houseStats.bAllDoorOpen = True
  134. self.houseStats.bAllDoorClosed = True
  135. for ise in self.homematic.favDoorList:
  136. if self.homematic.doorList[ise]["value"]==False:
  137. self.houseStats.bAllDoorOpen = False
  138. else:
  139. self.houseStats.bAllDoorClosed = False
  140. # Check all Lights
  141. self.houseStats.bAllLightOn = True
  142. self.houseStats.bAllLightOff = True
  143. for ise in self.homematic.favLightList:
  144. if self.homematic.lightList[ise]["value"]==False:
  145. self.houseStats.bAllLightOn = False
  146. else:
  147. self.houseStats.bAllLightOff = False
  148. # Termo
  149. temp_min=40.0
  150. temp_max=0.0
  151. temp_avg_add=0.0
  152. temp_avg_count=0
  153. for ise in self.homematic.favThermoList:
  154. if self.homematic.thermoList[ise]["value"] > temp_max:
  155. temp_max = self.homematic.thermoList[ise]["value"]
  156. if self.homematic.thermoList[ise]["value"] < temp_min:
  157. temp_min = self.homematic.thermoList[ise]["value"]
  158. temp_avg_add += self.homematic.thermoList[ise]["value"]
  159. temp_avg_count += 1
  160. self.houseStats.temp_avg = temp_avg_add / temp_avg_count
  161. self.houseStats.temp_coldest = temp_min
  162. self.houseStats.temp_hottest = temp_max
  163. def __UpdateEmotion(self):
  164. print("Update Emotion")
  165. newTime = int(time.time())
  166. updateDur = float(self.deviceStats.MAX_VALUE * ((newTime - self.deviceStats.lastUpdate) / 3600)) # Per Thausend
  167. self.deviceStats.lastUpdate = newTime
  168. #curHour = ((newTime % 86400) / 3600)
  169. curHour = datetime.datetime.now().hour
  170. moonImpact = 1.0
  171. # Define MoonPhase Impact
  172. if self.moonPhase["phase"]==4:
  173. if self.outdoorStats.Clouds>80:
  174. if curHour>23 or curHour<6:
  175. moonImpact += random.randint(0,9)/60
  176. else:
  177. moonImpact += random.randint(0,5)/80
  178. else:
  179. if curHour>23 or curHour<6:
  180. moonImpact += random.randint(0,9)/120
  181. else:
  182. moonImpact += random.randint(0,5)/180
  183. # Calculate impact for stats calculation
  184. impact = moonImpact
  185. if time.time() - self.deviceStats.lastTimeToLoud > 600:
  186. self.deviceStats.toLoud += float(updateDur / 8) * impact
  187. if time.time() - self.deviceStats.lastTimeToQuiet > 600:
  188. self.deviceStats.toQuiet += float(updateDur / 8) * impact
  189. # Home depended
  190. if self.houseStats.temp_avg > 25.0 or self.houseStats.temp_hottest > 28.0:
  191. self.deviceStats.hot += float(updateDur / 12) * impact
  192. else:
  193. self.deviceStats.hot -= float(updateDur / 38) * impact
  194. if self.houseStats.temp_avg < 17.0 or self.houseStats.temp_hottest < 15.0:
  195. self.deviceStats.freezy += float(updateDur / 12) * impact
  196. else:
  197. self.deviceStats.freezy -= float(updateDur / 38) * impact
  198. if self.deviceStats.hot <200 and self.deviceStats.freezy < 200:
  199. self.deviceStats.temperate -= float(updateDur / 12) * impact
  200. else:
  201. self.deviceStats.temperate += float(updateDur / 48) * impact
  202. self.deviceStats.toLoud -= (float)(updateDur / 48)
  203. if self.houseStats.bAtHome == True and self.houseStats.AtSleep == False:
  204. self.deviceStats.toQuiet -= (float)(updateDur / 48)
  205. # substractive
  206. self.deviceStats.angry -= (float)(updateDur / 48) * impact # 48std to 1000
  207. self.deviceStats.annoyed -= (float)(updateDur / 50)
  208. self.deviceStats.aroused -= (float)(updateDur / 72) * impact
  209. if self.houseStats.bSleeping:
  210. self.deviceStats.exhausted -= (float)(updateDur / 18)
  211. else:
  212. self.deviceStats.exhausted -= (float)(updateDur / 48)
  213. self.deviceStats.humanity -= (float)(updateDur / 48)
  214. self.deviceStats.naiv -= (float)(updateDur / 48)
  215. self.deviceStats.shy -= (float)(updateDur / 500)
  216. self.deviceStats.soziality -= (float)(updateDur / 48) * impact
  217. self.deviceStats.usefull -= (float)(updateDur / 48)
  218. # Additive
  219. self.deviceStats.bored += (float)(updateDur / 50)
  220. if self.houseStats.bSleeping:
  221. self.deviceStats.energy += (float)(updateDur / 14) * impact
  222. else:
  223. self.deviceStats.energy += (float)(updateDur / 30) * impact
  224. self.deviceStats.useless += (float)(updateDur / 168) # 168 = 1 Woche
  225. if self.deviceStats.angry>500 or self.deviceStats.annoyed>400 or self.deviceStats.depressive>300 or self.deviceStats.energy<100 or self.deviceStats.sleepy>500 or self.deviceStats.toLoud>300:
  226. self.deviceStats.exhausted += (float)(updateDur / 18)
  227. if self.deviceStats.toQuiet > 50:
  228. if self.deviceStats.toQuiet > 150:
  229. if self.deviceStats.toQuiet > 450:
  230. if self.deviceStats.toQuiet > 600:
  231. self.deviceStats.lonely+= (float)(updateDur / 5)
  232. else:
  233. self.deviceStats.lonely+=(float)(updateDur / 8)
  234. else:
  235. self.deviceStats.lonely+=(float)(updateDur / 32)
  236. else:
  237. self.deviceStats.lonely+=(float)(updateDur / 64)
  238. # Dependend
  239. if self.deviceStats.usefull > 600:
  240. self.deviceStats.happyness += (float)(updateDur / 20) * impact
  241. elif self.deviceStats.usefull > 400:
  242. self.deviceStats.happyness += (float)(updateDur / 40) * impact
  243. elif self.deviceStats.usefull > 300 and self.deviceStats.useless < 300:
  244. self.deviceStats.happyness += (float)(updateDur / 50) * impact
  245. else:
  246. self.deviceStats.happyness -= (float)(updateDur / 20)
  247. if self.deviceStats.temperate > 300:
  248. self.deviceStats.angry += (float)(updateDur / 60) * impact
  249. if self.deviceStats.freezy > 400 or self.deviceStats.hot > 400:
  250. self.deviceStats.angry += (float)(updateDur / 50) * impact
  251. if self.deviceStats.toLoud > 300 or self.deviceStats.toQuiet > 500:
  252. self.deviceStats.angry += (float)(updateDur / 30) * impact
  253. if self.houseStats.bSleeping:
  254. self.deviceStats.sleepy -= (float)(updateDur / 15) * impact
  255. else:
  256. if self.deviceStats.toQuiet > 300:
  257. self.deviceStats.sleepy += (float)(updateDur / 24);
  258. if curHour > 21 or curHour < 8:
  259. self.deviceStats.sleepy += (float)(updateDur / 48)
  260. if self.outdoorStats.bRaining == True:
  261. if self.outdoorStats.bWindy:
  262. self.deviceStats.depressive += (float)(updateDur / 10)
  263. else:
  264. self.deviceStats.depressive += (float)(updateDur / 20)
  265. elif self.deviceStats.angry > 650:
  266. self.deviceStats.depressive += (float)(updateDur / 40) * impact
  267. elif self.deviceStats.angry > 500:
  268. self.deviceStats.depressive += (float)(updateDur / 50) * impact
  269. elif self.deviceStats.angry > 300:
  270. self.deviceStats.depressive += (float)(updateDur / 90) * impact
  271. else:
  272. self.deviceStats.depressive -= (float)(updateDur / 50)
  273. self.deviceStats.excited += (float)(updateDur / 50)
  274. if self.deviceStats.depressive > 70:
  275. if self.deviceStats.angry < 100:
  276. self.deviceStats.happyness += (float)(updateDur / 120)
  277. if self.deviceStats.compfortable > 300:
  278. self.deviceStats.happyness += (float)(updateDur / 120)
  279. else:
  280. if self.deviceStats.angry < 120:
  281. self.deviceStats.happyness += (float)(updateDur / 120)
  282. if self.deviceStats.angry < 80:
  283. self.deviceStats.happyness += (float)(updateDur / 45)
  284. if self.deviceStats.compfortable > 300:
  285. self.deviceStats.happyness += (float)(updateDur / 90)
  286. if self.deviceStats.happyness > 150:
  287. self.deviceStats.funny += (float)(updateDur / 48) # Depends on happyness (>100) and other stats
  288. if self.deviceStats.happyness > 300:
  289. self.deviceStats.funny += (float)(updateDur / 48) # Depends on happyness (>100) and other stats
  290. else:
  291. self.deviceStats.funny -= (float)(updateDur / 90) # Depends on other stats
  292. if self.deviceStats.hot < 100 and self.deviceStats.freezy < 100:
  293. self.deviceStats.compfortable += (float)(updateDur / 90) # Depends on other stats
  294. if self.deviceStats.toLoud < 200 and self.deviceStats.toQuiet < 400:
  295. self.deviceStats.compfortable += (float)(updateDur / 120) # Depends on other stats
  296. if self.deviceStats.hot > 800 or self.deviceStats.freezy > 800:
  297. self.deviceStats.compfortable -= (float)(updateDur / 20) # Depends on other stats
  298. self.deviceStats.playful -= (float)(updateDur / 20) * impact # Depends on other stats
  299. self.deviceStats.energy -= (float)(updateDur / 15) * impact
  300. elif self.deviceStats.hot > 400 or self.deviceStats.freezy > 350:
  301. self.deviceStats.compfortable -= (float)(updateDur / 80) # Depends on other stats
  302. self.deviceStats.energy -= (float)(updateDur / 30)
  303. elif self.deviceStats.hot > 200 or self.deviceStats.freezy > 100:
  304. self.deviceStats.compfortable -= (float)(updateDur / 150) # Depends on other stats
  305. if self.deviceStats.toLoud > 800 or self.deviceStats.toQuiet > 800:
  306. self.deviceStats.compfortable -= (float)(updateDur / 20) # Depends on other stats
  307. self.deviceStats.angry += (float)(updateDur / 20) * impact
  308. self.deviceStats.sleepy += (float)(updateDur / 20)
  309. self.deviceStats.lonely -= (float)(updateDur / 100) * impact
  310. self.deviceStats.happyness -= (float)(updateDur / 100)
  311. self.deviceStats.bored -= (float)(updateDur / 100)
  312. self.deviceStats.annoyed += (float)(updateDur / 100)
  313. elif self.deviceStats.toLoud > 400 or self.deviceStats.toQuiet > 80:
  314. self.deviceStats.compfortable -= (float)(updateDur / 80) # Depends on other stats
  315. self.deviceStats.angry += (float)(updateDur / 80)
  316. self.deviceStats.sleepy += (float)(updateDur / 80) * impact
  317. self.deviceStats.annoyed += (float)(updateDur / 150) * impact
  318. elif self.deviceStats.toLoud > 200 or self.deviceStats.toQuiet > 100:
  319. self.deviceStats.compfortable -= (float)(updateDur / 150) # Depends on other stats
  320. self.deviceStats.sleepy += (float)(updateDur / 100)
  321. if self.deviceStats.happyness > 650 and self.deviceStats.funny > 500:
  322. self.deviceStats.playful += (float)(updateDur / 8) # Depends on naiv, funny and other stats
  323. elif self.deviceStats.happyness > 500 and self.deviceStats.funny > 500:
  324. self.deviceStats.playful += (float)(updateDur / 12) * impact # Depends on naiv, funny and other stats
  325. elif self.deviceStats.happyness > 300 and self.deviceStats.funny > 300:
  326. self.deviceStats.playful += (float)(updateDur / 18) # Depends on naiv, funny and other stats
  327. elif self.deviceStats.happyness > 150 and self.deviceStats.funny > 150:
  328. self.deviceStats.playful += (float)(updateDur / 48) # Depends on naiv, funny and other stats
  329. else:
  330. self.deviceStats.playful -= (float)(updateDur / 48) * impact # Depends on naiv, funny and other stats
  331. if self.deviceStats.angry > 800:
  332. self.deviceStats.sad += (float)(updateDur / 12)
  333. elif self.deviceStats.angry > 600:
  334. self.deviceStats.sad += (float)(updateDur / 18)
  335. elif self.deviceStats.angry > 450:
  336. self.deviceStats.sad += (float)(updateDur / 24)
  337. elif self.deviceStats.angry > 250:
  338. self.deviceStats.sad += (float)(updateDur / 30)
  339. else:
  340. self.deviceStats.sad -= (float)(updateDur / 48)
  341. self.deviceStats.Save()
  342. def getJson(self):
  343. return {
  344. "DeviceStats": self.deviceStats.getJson(),
  345. "HouseStats": self.houseStats.getJson(),
  346. "MicLevel": self.micLevel.getJson(),
  347. "OutdoorStats": self.outdoorStats.getJson(),
  348. "OwnerStats": self.ownerStats.getJson(),
  349. "TalkingStats": self.talkingStats.getJson()
  350. }
  351. def __del__(self):
  352. print("Del Stat-Classes")
  353. self.Thread_Emotion.cancel()
  354. self.Thread_Homematic.cancel()
  355. self.Thread_DateTime.cancel()
  356. self.Thread_OutDoor.cancel()
  357. self.Thread_Mic.cancel()
  358. del self.Thread_Emotion
  359. del self.Thread_Homematic
  360. del self.Thread_DateTime
  361. del self.Thread_OutDoor
  362. del self.Thread_Mic
  363. del self.deviceStats
  364. del self.HouseStats
  365. del self.MicLevel
  366. del self.OutdoorStats
  367. del self.OwnerStats
  368. del self.TalkingStats