#!/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