| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- #!/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 RepeatTimer import RepeatTimer
- import lib.MoonPhase as mp
- import random
- class Stats(object):
- instance = None
- @staticmethod
- def getInstance():
- if Stats.instance==None:
- Stats.instance = Stats()
- return Stats.instance
- deviceStats = _DeviceStats()
- houseStats = _HouseStats()
- micLevel = _MicLevel()
- outdoorStats = _OutdoorStats()
- ownerStats = _OwnerStats()
- talkingStats = _TalkingStats()
- adminStats = _AdminStats()
- weather = OpenWeatherMap.OpenWeatherMap()
- UPDATE_EMOTION_DELAY_MINUTE = 1.66
- 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
- homematic = None
- moonPhase = None
- Mic = MicCapture.MicCapture()
- def __init__(self):
- print("Init Stats")
- print("- Read Config")
- try:
- config = configparser.ConfigParser()
- config.read('config.ini')
- except:
- print("Failed to get Config")
- config = dict
- config["Homematic"] = dict
- config["Homematic"]["url"]=""
- config["Homematic"]["SwitchList"]=""
- config["Homematic"]["LightList"]=""
- config["Homematic"]["TermoList"]=""
- config["Homematic"]["DoorList"]=""
- config["Homematic"]["WindowList"]=""
- self.moonPhase = mp.phase(time=datetime.datetime.now())
- self.deviceStats.lastUpdate = time.time()
- print("- Init Homematic")
- if config["Homematic"]["url"]!="":
- self.homematic = Homematic(config["Homematic"]["url"], {
- "SwitchList":config["Homematic"]["SwitchList"],
- "LightList":config["Homematic"]["LightList"],
- "TermoList":config["Homematic"]["TermoList"],
- "DoorList":config["Homematic"]["DoorList"],
- "WindowList":config["Homematic"]["WindowList"]
- })
- if self.homematic.bConnected:
- print("- - Homematic conected")
- print("- - Update HomeMatic")
- self.__UpdateHomematic()
- print("- - Start Homematic-Timer")
- self.Thread_Homematic = RepeatTimer(self.UPDATE_HOMEMATIC_DELAY_MINUTE*60, self.__UpdateHomematic)
- self.Thread_Homematic.start()
- else:
- print("- - No homatic")
- print("- - HomeMatic Done")
- else:
- print("- - Homematic failed")
- 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")
- return super().__init__()
- 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.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.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.temp_avg > 25.0 or self.houseStats.temp_hottest > 28.0:
- self.deviceStats.hot += float(updateDur / 12) * impact
- else:
- self.deviceStats.hot -= float(updateDur / 38) * impact
- if self.houseStats.temp_avg < 17.0 or self.houseStats.temp_hottest < 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.houseStats.bAtHome == True and self.houseStats.AtSleep == 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.houseStats.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.houseStats.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.houseStats.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
|