| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- from Stats.DeviceStats import DeviceStats as _DeviceStats
- from Stats.HouseStats import HouseStats as _HouseStats
- from Stats.MicLevel import MicLevel as _MicLevel
- from Stats.OutdoorStats import OutdoorStats as _OutdoorStats
- from Stats.OwnerStats import OwnerStats as _OwnerStats
- from Stats.TalkingStats import TalkingStats as _TalkingStats
- from Stats.AdminStats import AdminStats as _AdminStats
- import MicCapture
- import OpenWeatherMap
- #from Homematic import Homematic
- from threading import Timer
- import time
- import datetime
- import configparser
- from lib.RepeatTimer import RepeatTimer
- import lib.MoonPhase as mp
- import random
- class Stats:
- instance = None
- @staticmethod
- def getInstance():
- if Stats.instance==None:
- Stats.instance = Stats()
- return Stats.instance
- #deviceStats:_DeviceStats = _DeviceStats()
- #houseStats:_HouseStats = _HouseStats()
- #micLevel:_MicLevel = _MicLevel()
- #outdoorStats = _OutdoorStats()
- #ownerStats = _OwnerStats()
- #talkingStats = _TalkingStats()
- #adminStats = _AdminStats()
- UPDATE_EMOTION_DELAY_MINUTE = 0.2
- UPDATE_HOMEMATIC_DELAY_MINUTE = 1
- UPDATE_DATETIME_DELAY_MINUTE = 10
- UPDATE_OUTDOOR_DELAY_MINUTE = 2.1
- UPDATE_MIC_DELAY_MINUTE = 0.5
- #Thread_Homematic = None
- #Thread_Emotion = None
- #Thread_DateTime = None
- #Thread_OutDoor = None
- #Thread_Mic = None
- #lastUpdate = 0.0
- Mic = MicCapture.MicCapture()
- def __init__(self):
- print("Init Stats")
- self.lastUpdate = 0.0
- self.Thread_Homematic = None
- self.Thread_Emotion = None
- self.Thread_DateTime = None
- self.Thread_OutDoor = None
- self.Thread_Mic = None
-
- print("- Read Config")
- try:
- config = configparser.ConfigParser()
- config.read('config/stats.ini')
- except:
- print("Failed to get Config")
- config = dict
- self._weather = OpenWeatherMap.OpenWeatherMap()
- self._deviceStats:_DeviceStats = _DeviceStats()
- self._houseStats:_HouseStats = _HouseStats()
- self._micLevel:_MicLevel = _MicLevel()
- self._outdoorStats = _OutdoorStats()
- self._ownerStats = _OwnerStats()
- self._talkingStats = _TalkingStats()
- self._adminStats = _AdminStats()
- self._outdoorStats.MoonPhase = mp.phase(time=datetime.datetime.now())
- self._deviceStats.lastUpdate = time.time()
- self.__UpdateDateTime()
- self.Thread_DateTime = RepeatTimer(self.UPDATE_DATETIME_DELAY_MINUTE*60, self.__UpdateDateTime)
- self.Thread_DateTime.start()
- self.__UpdateOutdoor()
- self.Thread_OutDoor = RepeatTimer(self.UPDATE_OUTDOOR_DELAY_MINUTE*60, self.__UpdateOutdoor)
- self.Thread_OutDoor.start()
- self.Thread_Mic = RepeatTimer(self.UPDATE_MIC_DELAY_MINUTE*60, self.__UpdateMic)
- self.Thread_Mic.start()
-
- print("- Init Emotion")
- self.Thread_Emotion = RepeatTimer(self.UPDATE_EMOTION_DELAY_MINUTE*60, self.__UpdateEmotion)
- print("- - Start Emotion Timer")
- self.Thread_Emotion.start()
- print("- - Init Stats done")
- @property
- def HouseStats(self) -> _HouseStats:
- return self._houseStats
- @property
- def DeviceStats(self) -> _DeviceStats:
- return self._deviceStats
- @property
- def OutdoorStats(self) -> _OutdoorStats:
- return self._outdoorStats
- @property
- def OwnerStats(self) -> _OwnerStats:
- return self._ownerStats
- @property
- def TalkingStats(self) -> _TalkingStats:
- return self._talkingStats
- @property
- def AdminStats(self) -> _AdminStats:
- return self._adminStats
- @property
- def WeatherInfo(self) -> OpenWeatherMap.OpenWeatherMap:
- return self._weather
- def __UpdateMic(self):
- self.Mic.Update()
- self._micLevel.Volume_Min = self.Mic.LastResult["min"]
- self._micLevel.Volume_Max = self.Mic.LastResult["max"]
- self._micLevel.Volume_Avg = self.Mic.LastResult["avg"]
- #print(self._micLevel.getJson())
- def __UpdateDateTime(self):
- self._outdoorStats.MoonPhase = mp.phase(time=datetime.datetime.now())
- def __UpdateOutdoor(self):
- self._weather.Update()
- self._outdoorStats.bRaining = self._weather.CurrentLocation.Rain.PerHour>0.1
- self._outdoorStats.bSnowing = self._weather.CurrentLocation.Rain.PerHour>0.1 and self.weather.CurrentLocation.Main.TempMax<1
- self._outdoorStats.bWindy = self._weather.CurrentLocation.Wind.Speed>20
- self._outdoorStats.Clouds = self._weather.CurrentLocation.Clouds.All
- self._outdoorStats.Humidity = self._weather.CurrentLocation.Main.Humidity
- self._outdoorStats.Pressure = self._weather.CurrentLocation.Main.Pressure
- self._outdoorStats.Temperature = self._weather.CurrentLocation.Main.Temperature
- self._outdoorStats.WindDegree = self._weather.CurrentLocation.Wind.Deg
- self._outdoorStats.WindSpeed = self._weather.CurrentLocation.Wind.Speed
- #def __UpdateHomematic(self):
- # print("Update Homematic")
- # self.homematic.updateDevices()
- # # Check open/closed windows
- # self.houseStats.bAllWindowOpen = True
- # self.houseStats.bAllWindowClosed = True
- # for ise in self.homematic.favWindowList:
- # if self.homematic.windowList[ise]["value"]==False:
- # self.houseStats.bAllWindowOpen = False
- # else:
- # self.houseStats.bAllWindowClosed = False
- # # Check open/closed doors
- # self.houseStats.bAllDoorOpen = True
- # self.houseStats.bAllDoorClosed = True
- # for ise in self.homematic.favDoorList:
- # if self.homematic.doorList[ise]["value"]==False:
- # self.houseStats.bAllDoorOpen = False
- # else:
- # self.houseStats.bAllDoorClosed = False
- # # Check all Lights
- # self.houseStats.bAllLightOn = True
- # self.houseStats.bAllLightOff = True
- # for ise in self.homematic.favLightList:
- # if self.homematic.lightList[ise]["value"]==False:
- # self.houseStats.bAllLightOn = False
- # else:
- # self.houseStats.bAllLightOff = False
- # # Termo
- # temp_min=40.0
- # temp_max=0.0
- # temp_avg_add=0.0
- # temp_avg_count=0
- # for ise in self.homematic.favThermoList:
- # if self.homematic.thermoList[ise]["value"] > temp_max:
- # temp_max = self.homematic.thermoList[ise]["value"]
- # if self.homematic.thermoList[ise]["value"] < temp_min:
- # temp_min = self.homematic.thermoList[ise]["value"]
- # temp_avg_add += self.homematic.thermoList[ise]["value"]
- # temp_avg_count += 1
- # self.houseStats.temp_avg = temp_avg_add / temp_avg_count
- # self.houseStats.temp_coldest = temp_min
- # self.houseStats.temp_hottest = temp_max
- def __UpdateEmotion(self):
- print("Update Emotion")
- newTime = int(time.time())
- updateDur = float(self._deviceStats.MAX_VALUE * ((newTime - self._deviceStats.lastUpdate) / 3600)) # Per Thausend
- self._deviceStats.lastUpdate = newTime
- #curHour = ((newTime % 86400) / 3600)
- curHour = datetime.datetime.now().hour
- moonImpact = 1.0
- # Define MoonPhase Impact
- if self._outdoorStats.MoonPhase["phase"]==4:
- if self._outdoorStats.Clouds>80:
- if curHour>23 or curHour<6:
- moonImpact += random.randint(0,9)/60
- else:
- moonImpact += random.randint(0,5)/80
- else:
- if curHour>23 or curHour<6:
- moonImpact += random.randint(0,9)/120
- else:
- moonImpact += random.randint(0,5)/180
- # Calculate impact for stats calculation
- impact = moonImpact
- if time.time() - self._deviceStats.lastTimeToLoud > 600:
- self._deviceStats.toLoud += float(updateDur / 8) * impact
- if time.time() - self._deviceStats.lastTimeToQuiet > 600:
- self._deviceStats.toQuiet += float(updateDur / 8) * impact
-
- # Home depended
- if self._houseStats.Temperature.avg > 25.0 or self._houseStats.Temperature.hottest > 28.0:
- self._deviceStats.hot += float(updateDur / 12) * impact
- else:
- self._deviceStats.hot -= float(updateDur / 38) * impact
- if self._houseStats.Temperature.avg < 17.0 or self._houseStats.Temperature.coldest < 15.0:
- self._deviceStats.freezy += float(updateDur / 12) * impact
- else:
- self._deviceStats.freezy -= float(updateDur / 38) * impact
- if self._deviceStats.hot <200 and self._deviceStats.freezy < 200:
- self._deviceStats.temperate -= float(updateDur / 12) * impact
- else:
- self._deviceStats.temperate += float(updateDur / 48) * impact
- self._deviceStats.toLoud -= (float)(updateDur / 48)
- if self._ownerStats.bIsAtHome == True and self._ownerStats.bSleeping == False:
- self._deviceStats.toQuiet -= (float)(updateDur / 48)
- # substractive
- self._deviceStats.angry -= (float)(updateDur / 48) * impact # 48std to 1000
- self._deviceStats.annoyed -= (float)(updateDur / 50)
- self._deviceStats.aroused -= (float)(updateDur / 72) * impact
- if self._ownerStats.bSleeping:
- self._deviceStats.exhausted -= (float)(updateDur / 18)
- else:
- self._deviceStats.exhausted -= (float)(updateDur / 48)
- self._deviceStats.humanity -= (float)(updateDur / 48)
- self._deviceStats.naiv -= (float)(updateDur / 48)
- self._deviceStats.shy -= (float)(updateDur / 500)
- self._deviceStats.soziality -= (float)(updateDur / 48) * impact
- self._deviceStats.usefull -= (float)(updateDur / 48)
- # Additive
- self._deviceStats.bored += (float)(updateDur / 50)
- if self._ownerStats.bSleeping:
- self._deviceStats.energy += (float)(updateDur / 14) * impact
- else:
- self._deviceStats.energy += (float)(updateDur / 30) * impact
- self._deviceStats.useless += (float)(updateDur / 168) # 168 = 1 Woche
- 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:
- self._deviceStats.exhausted += (float)(updateDur / 18)
- if self._deviceStats.toQuiet > 50:
- if self._deviceStats.toQuiet > 150:
- if self._deviceStats.toQuiet > 450:
- if self._deviceStats.toQuiet > 600:
- self._deviceStats.lonely+= (float)(updateDur / 5)
- else:
- self._deviceStats.lonely+=(float)(updateDur / 8)
- else:
- self._deviceStats.lonely+=(float)(updateDur / 32)
- else:
- self._deviceStats.lonely+=(float)(updateDur / 64)
- # Dependend
- if self._deviceStats.usefull > 600:
- self._deviceStats.happyness += (float)(updateDur / 20) * impact
- elif self._deviceStats.usefull > 400:
- self._deviceStats.happyness += (float)(updateDur / 40) * impact
- elif self._deviceStats.usefull > 300 and self._deviceStats.useless < 300:
- self._deviceStats.happyness += (float)(updateDur / 50) * impact
- else:
- self._deviceStats.happyness -= (float)(updateDur / 20)
- if self._deviceStats.temperate > 300:
- self._deviceStats.angry += (float)(updateDur / 60) * impact
- if self._deviceStats.freezy > 400 or self._deviceStats.hot > 400:
- self._deviceStats.angry += (float)(updateDur / 50) * impact
- if self._deviceStats.toLoud > 300 or self._deviceStats.toQuiet > 500:
- self._deviceStats.angry += (float)(updateDur / 30) * impact
- if self._ownerStats.bSleeping:
- self._deviceStats.sleepy -= (float)(updateDur / 15) * impact
- else:
- if self._deviceStats.toQuiet > 300:
- self._deviceStats.sleepy += (float)(updateDur / 24);
- if curHour > 21 or curHour < 8:
- self._deviceStats.sleepy += (float)(updateDur / 48)
- if self._outdoorStats.bRaining == True:
- if self._outdoorStats.bWindy:
- self._deviceStats.depressive += (float)(updateDur / 10)
- else:
- self._deviceStats.depressive += (float)(updateDur / 20)
- elif self._deviceStats.angry > 650:
- self._deviceStats.depressive += (float)(updateDur / 40) * impact
- elif self._deviceStats.angry > 500:
- self._deviceStats.depressive += (float)(updateDur / 50) * impact
- elif self._deviceStats.angry > 300:
- self._deviceStats.depressive += (float)(updateDur / 90) * impact
- else:
- self._deviceStats.depressive -= (float)(updateDur / 50)
-
- self._deviceStats.excited += (float)(updateDur / 50)
- if self._deviceStats.depressive > 70:
- if self._deviceStats.angry < 100:
- self._deviceStats.happyness += (float)(updateDur / 120)
- if self._deviceStats.compfortable > 300:
- self._deviceStats.happyness += (float)(updateDur / 120)
- else:
- if self._deviceStats.angry < 120:
- self._deviceStats.happyness += (float)(updateDur / 120)
- if self._deviceStats.angry < 80:
- self._deviceStats.happyness += (float)(updateDur / 45)
- if self._deviceStats.compfortable > 300:
- self._deviceStats.happyness += (float)(updateDur / 90)
-
- if self._deviceStats.happyness > 150:
- self._deviceStats.funny += (float)(updateDur / 48) # Depends on happyness (>100) and other stats
- if self._deviceStats.happyness > 300:
- self._deviceStats.funny += (float)(updateDur / 48) # Depends on happyness (>100) and other stats
- else:
- self._deviceStats.funny -= (float)(updateDur / 90) # Depends on other stats
- if self._deviceStats.hot < 100 and self._deviceStats.freezy < 100:
- self._deviceStats.compfortable += (float)(updateDur / 90) # Depends on other stats
- if self._deviceStats.toLoud < 200 and self._deviceStats.toQuiet < 400:
- self._deviceStats.compfortable += (float)(updateDur / 120) # Depends on other stats
-
- if self._deviceStats.hot > 800 or self._deviceStats.freezy > 800:
- self._deviceStats.compfortable -= (float)(updateDur / 20) # Depends on other stats
- self._deviceStats.playful -= (float)(updateDur / 20) * impact # Depends on other stats
- self._deviceStats.energy -= (float)(updateDur / 15) * impact
- elif self._deviceStats.hot > 400 or self._deviceStats.freezy > 350:
- self._deviceStats.compfortable -= (float)(updateDur / 80) # Depends on other stats
- self._deviceStats.energy -= (float)(updateDur / 30)
- elif self._deviceStats.hot > 200 or self._deviceStats.freezy > 100:
- self._deviceStats.compfortable -= (float)(updateDur / 150) # Depends on other stats
-
- if self._deviceStats.toLoud > 800 or self._deviceStats.toQuiet > 800:
- self._deviceStats.compfortable -= (float)(updateDur / 20) # Depends on other stats
- self._deviceStats.angry += (float)(updateDur / 20) * impact
- self._deviceStats.sleepy += (float)(updateDur / 20)
- self._deviceStats.lonely -= (float)(updateDur / 100) * impact
- self._deviceStats.happyness -= (float)(updateDur / 100)
- self._deviceStats.bored -= (float)(updateDur / 100)
- self._deviceStats.annoyed += (float)(updateDur / 100)
- elif self._deviceStats.toLoud > 400 or self._deviceStats.toQuiet > 80:
- self._deviceStats.compfortable -= (float)(updateDur / 80) # Depends on other stats
- self._deviceStats.angry += (float)(updateDur / 80)
- self._deviceStats.sleepy += (float)(updateDur / 80) * impact
- self._deviceStats.annoyed += (float)(updateDur / 150) * impact
- elif self._deviceStats.toLoud > 200 or self._deviceStats.toQuiet > 100:
- self._deviceStats.compfortable -= (float)(updateDur / 150) # Depends on other stats
- self._deviceStats.sleepy += (float)(updateDur / 100)
-
- if self._deviceStats.happyness > 650 and self._deviceStats.funny > 500:
- self._deviceStats.playful += (float)(updateDur / 8) # Depends on naiv, funny and other stats
- elif self._deviceStats.happyness > 500 and self._deviceStats.funny > 500:
- self._deviceStats.playful += (float)(updateDur / 12) * impact # Depends on naiv, funny and other stats
- elif self._deviceStats.happyness > 300 and self._deviceStats.funny > 300:
- self._deviceStats.playful += (float)(updateDur / 18) # Depends on naiv, funny and other stats
- elif self._deviceStats.happyness > 150 and self._deviceStats.funny > 150:
- self._deviceStats.playful += (float)(updateDur / 48) # Depends on naiv, funny and other stats
- else:
- self._deviceStats.playful -= (float)(updateDur / 48) * impact # Depends on naiv, funny and other stats
- if self._deviceStats.angry > 800:
- self._deviceStats.sad += (float)(updateDur / 12)
- elif self._deviceStats.angry > 600:
- self._deviceStats.sad += (float)(updateDur / 18)
- elif self._deviceStats.angry > 450:
- self._deviceStats.sad += (float)(updateDur / 24)
- elif self._deviceStats.angry > 250:
- self._deviceStats.sad += (float)(updateDur / 30)
- else:
- self._deviceStats.sad -= (float)(updateDur / 48)
- self._deviceStats.Save()
-
- def getJson(self):
- return {
- "DeviceStats": self._deviceStats.getJson(),
- "HouseStats": self._houseStats.getJson(),
- "MicLevel": self._micLevel.getJson(),
- "OutdoorStats": self._outdoorStats.getJson(),
- "OwnerStats": self._ownerStats.getJson(),
- "TalkingStats": self._talkingStats.getJson()
- }
- def __del__(self):
- print("Del Stat-Classes")
- self.Thread_Emotion.cancel()
- self.Thread_Homematic.cancel()
- self.Thread_DateTime.cancel()
- self.Thread_OutDoor.cancel()
- self.Thread_Mic.cancel()
- del self.Thread_Emotion
- del self.Thread_Homematic
- del self.Thread_DateTime
- del self.Thread_OutDoor
- del self.Thread_Mic
- del self._deviceStats
- del self._HouseStats
- del self._MicLevel
- del self._OutdoorStats
- del self._OwnerStats
- del self._TalkingStats
|