main.py 19 KB

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