Forráskód Böngészése

Module Kompatibilität hinzugefügt

Patrick Baumgartner 4 éve
szülő
commit
9c886857b4
12 módosított fájl, 748 hozzáadás és 431 törlés
  1. 12 6
      DynLoader/main.py
  2. 58 37
      DynLoader/modInfo.py
  3. 14 9
      README.md
  4. 1 1
      Stats/DeviceStats.py
  5. 299 37
      Stats/HouseStats.py
  6. 8 1
      Stats/OutdoorStats.py
  7. 2 0
      Stats/__init__.py
  8. 258 259
      Stats/main.py
  9. 12 1
      Trixy.pyproj
  10. 14 10
      VoicePlay/main.py
  11. 11 13
      main.py
  12. 59 57
      mods/README.md

+ 12 - 6
DynLoader/main.py

@@ -7,14 +7,12 @@ from DynLoader.modInfo import modInfo
 class DynLoaderMod(object):
 
 
-    instance = None
+    instance = dict()
     @staticmethod
     def getInstance():
-        if DynLoaderMod.instance==None:
-            DynLoaderMod.instance = DynLoaderMod()
         return DynLoaderMod.instance
 
-    def __init__(self,dir,method_prefix=""):
+    def __init__(self,dir:str,method_prefix:str=""):
         self._modules = []
         files = os.listdir(dir)
         self._prefix = method_prefix
@@ -23,8 +21,16 @@ class DynLoaderMod(object):
             if f!='__pycache__' and f.endswith(".py"):
                 self._modules.append({
                     "file": f,
-                    "modInfo": modInfo(dir+"/"+f)
+                    "modInfo": modInfo(dir+f, os.path.splitext(f)[0], "mods"),
+                    "path": dir+f
                 })
+            elif f!='__pycache__' and os.path.exists(dir+f+"/__init__.py"):
+                self._modules.append({
+                    "file": f+"/__init__.py",
+                    "modInfo": modInfo(dir+f+"/__init__.py", os.path.splitext(f)[0], "mods"),
+                    "path": dir+f+"/__init__.py"
+                })
+        DynLoaderMod.instance = self
         
     def __del__(self):
         #for x in range(self._modules):
@@ -37,7 +43,7 @@ class DynLoaderMod(object):
     def execute(self, method, arg1 = None, arg2 = None, arg3 = None):
         for m in self._modules:
             if m["modInfo"].Loaded:
-                m["modInfo"].Execute(method, arg1, arg2, arg3)
+                m["modInfo"].Execute(self._prefix + method, arg1, arg2, arg3)
 
 
     

+ 58 - 37
DynLoader/modInfo.py

@@ -7,12 +7,16 @@ import sys
 
 class modInfo(object):
 
-    def __init__(self, path):
+    def __init__(self, path:str,className:str, classPath:str):
+        print("Load Module: " + classPath)
         self._loaded = False
         self._size = 0
         self._path = ""
         self._mod = None
-        self.Path = path
+        self._className = className
+        self._classPath = classPath
+        #self.Path = path
+        self.__setPath(path)
 
 
     def __del__(self):
@@ -21,40 +25,47 @@ class modInfo(object):
         del self._mod
         del self._path
         del self._size
+        del self._className
+        del self._classPath
 
 
     def Unload(self):
+        #TODO realy unload the module
         if self._loaded == False:
             return
         self._loaded = False
 
 
 
-    def Execute(self, methode, arg1 = None, arg2 = None,arg3 = None):
+    def Execute(self, methode:str, arg1 = None, arg2 = None,arg3 = None):
         if self._loaded == False:
             return
-        methode = getattr(self._mod, methode)
-        if methode:
-            if arg1 == None and arg2==None and arg3 == None:
-                methode()
-            elif arg2 == None and arg3 == None:
-                methode(arg1)
-            elif arg3 == None:
-                methode(arg1, arg2)
-            else:
-                methode(arg1, arg2, arg3)
+        isActive = getattr(self._instance, "IsActive")
+        if isActive():
+            methode = getattr(self._instance, methode)
+            if methode:
+                if arg1 == None and arg2==None and arg3 == None:
+                    methode()
+                elif arg2 == None and arg3 == None:
+                    methode(arg1)
+                elif arg3 == None:
+                    methode(arg1, arg2)
+                else:
+                    methode(arg1, arg2, arg3)
 
 
 
 
-    def _loadModule(self, moduleName):
+    def _loadModule(self, moduleName:str):
         module = None
-        moduleName = moduleName.replace("/",".")
+        moduleName = self._classPath + "." + self._className
+        print("- moduleName: " + moduleName)
         try:
             del sys.modules[moduleName]
         except BaseException as err:
             pass
         try:
+            print("try to import module "+moduleName)
             module = importlib.import_module(moduleName)
         except BaseException as err:
             serr = str(err)
@@ -62,19 +73,15 @@ class modInfo(object):
         return module
 
     def _reloadModule(self, moduleName):
-        module = loadModule(moduleName)
+        module = self.loadModule(moduleName)
         moduleName = moduleName.replace("/",".")
         moduleName, modulePath = str(module).replace("' from '", "||").replace("<module '", '').replace("'>", '').split("||")
         if (modulePath.endswith(".pyc")):
             import os
             os.remove(modulePath)
-            module = loadModule(moduleName)
+            module = self.loadModule(moduleName)
         return module
 
-    def _getInstance(self, moduleName, param1, param2, param3):
-        module = reloadModule(moduleName)
-        instance = eval("module." + moduleName + "(param1, param2, param3)")
-        return instance
 
 
 
@@ -84,37 +91,51 @@ class modInfo(object):
 
     @Path.setter
     def Path(self,value):
+        self.__setPath(value)
+
+
+    @property
+    def Size(self):
+        return self._size
+
+    @property
+    def Module(self):
+        return self._mod
+
+    @property
+    def Loaded(self):
+        return self._loaded
+
+    def __setPath(self, value):
         if self._path == value: 
             return
-        print("Set Path to "+value)
 
         self.Unload()
         if value == "":
             return
         self._path = value
         if os.path.isfile(value):
+            print("- file exists")
             self._size = os.path.getsize(self._path)
+            print("- size: " + str(self._size))
             try:
                 #self._mod = __import__(self._path)
                 self._mod = self._loadModule(self._path)
-                self._loaded = True
+                print("- _loadModule("+self._path+") done")
+                self._instance = getattr(self._mod, self._className)()
+                if self._instance==None:
+                    print("- failed to create instance")
+                    self._loaded = False
+                else:
+                    print("instance created")
+                    self._loaded = True
+                print("- loaded done")
             except ImportError:
+                print("- ImportError")
                 self._mod = None
                 self._loaded = False
         else:
+            print("- Not found")
             self._mod = None
             self._loaded = False
-            self._size = 0
-
-
-    @property
-    def Size(self):
-        return self._size
-
-    @property
-    def Module(self):
-        return self._mod
-
-    @property
-    def Loaded(self):
-        return self._loaded
+            self._size = 0

+ 14 - 9
README.md

@@ -1,12 +1,17 @@
-# Trixy
+Trixy
+===================================================
 
-## Installation
+Installation
+---------------------------------------------------
 
-## Useage
+Useage
+---------------------------------------------------
 
-## Python Package Requirements
-numpy
-pydub
-librosa
-configparser
-deepspeech
+Python Package Requirements
+---------------------------------------------------
+numpy  
+pydub  
+librosa  
+configparser  
+deepspeech  
+pyyaml  

+ 1 - 1
Stats/DeviceStats.py

@@ -125,7 +125,7 @@ class DeviceStats(object):
         self.Thread_Save.start()
         if(True):
             config = configparser.ConfigParser()
-            config.read('config.ini')
+            config.read('config/stats.ini')
             if "Locked_Stats" in config:
                 if "angry" in config["Locked_Stats"]:
                     self._locked_angry = float(config["Locked_Stats"]["angry"])

+ 299 - 37
Stats/HouseStats.py

@@ -1,49 +1,311 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+from datetime import datetime
+from abc import ABC, abstractmethod
+
+
+class _airStats(object):
+    oxigenLevel = 0
+    nitrogenLevel = 0
+    methaneLevel = 0
+    sulfurDioxidLevel = 0
+    carbonMonoxidLevel = 0
+    carbonDioxidLevel = 0
+    particles_pm1 = 0
+    particles_pm5 = 0
+    particles_pm10 = 0
+
+    def getJSON(self):
+        return {
+            "Oxigen": self.oxigenLevel,
+            "Nitrogen": self.nitrogenLevel,
+            "Methane": self.methaneLevel,
+            "Sulfurdioxid": self.sulfurDioxidLevel,
+            "Carbonmonoxid": self.carbonMonoxidLevel,
+            "Carbondioxid": self.carbonDioxidLevel,
+            "Particles_PM1": self.particles_pm1,
+            "Particles_PM5": self.particles_pm5,
+            "Particles_PM10":self.particles_pm10
+        }
+
+class _temperatureProperty:
+    _temperature = dict()
+    __temperature_count = 0
+    __temperature_coldest = 22
+    __temperature_hottest = 22
+    __temperature_avg = 22
+
+    @property
+    def count(self) -> int:
+        return self.__temperature_count
+
+    @property
+    def coldest(self) -> float:
+        return self.__temperature_coldest
+
+    @property
+    def hottest(self) -> float:
+        return self.__temperature_hottest
+
+    @property
+    def avg(self) -> float:
+        if self.__temperature_count==0:
+            return 20.0
+        else:
+            return self.__temperature_avg
+
+    def set(self, id:str, value:float):
+        if id in self._temperature:
+            if self._temperature[id] == value:
+                # Value exists and didn't change
+                return
+        # Key doesn't exists or value has changed
+        self._temperature[id] = value
+        count = 0
+        tempMin = 99.9
+        tempMax = 0.0
+        tempTotal = 0.0
+        for k,v in self._temperature.items():
+            count+=1
+            tempTotal+=v
+            if tempMin > v:
+                tempMin = v
+            if tempMax < v:
+                tempMax = v
+        self.__temperature_count = int(count)
+        self.__temperature_coldest = float(tempMin)
+        self.__temperature_hottest = float(tempMax)
+        if count==0:
+            return 20.0
+        else:
+            self.__temperature_avg = float(tempTotal / count)
+
+    def getJSON(self):
+        return {
+            "count": self.count,
+            "avg": self.avg,
+            "coldest": self.coldest,
+            "hottest": self.hottest
+        }
+
+class _toggleProperty(ABC):
+    _objects = dict()
+    _count = 0
+    _active = 0
+    _inactive = 0
+    _time_active = datetime.now()
+    _time_inactive = datetime.now()
+    _time_all_active = datetime.now()
+    _time_all_inactive = datetime.now()
+
+    @property
+    def count(self) -> int:
+        return self._count
+
+    def set(self, id:str, state:bool):
+        if id in self._objects:
+            if self._objects[id] == state:
+                # Value exists and didn't change
+                return
+        # Key doesn't exists or value has changed
+        if self._count == self._off:
+            self._time_all_inactive = datetime.now()
+        if self._off>0:
+            self._time_inactive = datetime.now()
+        if self._count == self._open:
+            self._time_all_active = datetime.now()
+        if self._on>0:
+            self._time_active = datetime.now()
+
+        self._objects[id] = state
+        count = 0
+        countOn = 0
+        countOff = 0
+        for k,v in self._objects.items():
+            count+=1
+            if v==True:
+                countOn+=1
+            else:
+                countOff+=1
+        self._count = count
+        self._active = countOn
+        self._inactive = countOff
+
+    @abstractmethod
+    def getJSON(self):
+        pass
+
+    def _readableTime(self, time:datetime):
+        return time
+
+class _onOffProperty(_toggleProperty):
+    @property
+    def bAllOn(self) -> bool:
+        return self._count <= self._active
+
+    @property
+    def bAllOff(self) -> bool:
+        return self._count <= self._inactive
+
+    @property
+    def on(self) -> int:
+        return self._active
+
+    @property
+    def off(self) -> int:
+        return self._inactive
+
+    @property
+    def lastTimeOn(self) -> datetime:
+        if self._active>0:
+            return datetime.now()
+        else:
+            self._time_active
+
+    @property 
+    def lastTimeAllOn(self) -> datetime:
+        if self._count == self._active:
+            return datetime.now()
+        else:
+            self._time_all_active
+
+    @property 
+    def laseTimeOff(self) -> datetime:
+        if self._inactive>0:
+            return datetime.now()
+        else:
+            return self._time_inactive
+
+    @property 
+    def lastTimeAllOff(self) -> datetime:
+        if self._count == self._inactive:
+            return datetime.now()
+        else:
+            return self._time_all_inactive
+
+    def getJSON(self):
+        return {
+            "All_Off": self.bAllOn,
+            "All_On": self.bAllOff,
+            "LastTimeOpen": self._readableTime(self.lastTimeOn),
+            "LaseTimeClose": self._readableTime(self.laseTimeOff),
+            "LastTimeAllOpen": self._readableTime(self.lastTimeAllOn),
+            "LastTimeAllClosed": self._readableTime(self.lastTimeAllOff),
+            "Count": self.count,
+            "OnCount": self.on,
+            "OffCount": self.off
+        }
+
+class _openCloseProperty(_toggleProperty):
+    @property
+    def bAllOpen(self) -> bool:
+        return self._count <= self._active
+
+    @property
+    def bAllClose(self) -> bool:
+        return self._count <= self._inactive
+
+    @property
+    def open(self) -> int:
+        return self._active
+
+    @property
+    def close(self) -> int:
+        return self._inactive
+
+    @property
+    def lastTimeOpen(self) -> datetime:
+        if self._active>0:
+            return datetime.now()
+        else:
+            self._time_active
+
+    @property 
+    def lastTimeAllOpen(self) -> datetime:
+        if self._count == self._active:
+            return datetime.now()
+        else:
+            self._time_all_active
+
+    @property 
+    def laseTimeClose(self) -> datetime:
+        if self._inactive>0:
+            return datetime.now()
+        else:
+            return self._time_inactive
+
+    @property 
+    def lastTimeAllClose(self) -> datetime:
+        if self._count == self._inactive:
+            return datetime.now()
+        else:
+            return self._time_all_inactive
+
+    def getJSON(self):
+        return {
+            "All_Closed": self.bAllOpen,
+            "All_Opened": self.bAllClose,
+            "LastTimeOpen": self._readableTime(self.lastTimeOpen),
+            "LaseTimeClose": self._readableTime(self.laseTimeClose),
+            "LastTimeAllOpen": self._readableTime(self.lastTimeAllOpen),
+            "LastTimeAllClosed": self._readableTime(self.lastTimeAllClose),
+            "Count": self.count,
+            "OpenCount": self.open,
+            "CloseCount": self.close
+        }
 
 class HouseStats(object):
-    temp_avg = 20.0
-    temp_coldest = 99.0
-    temp_hottest = 0.0
+    
+    def __init__(self):
+        self._movements = dict()
+        self._rooms = dict()
+        self._air = _airStats()
+        self.__lightsProp = _onOffProperty()
+        self.__switchesProp = _onOffProperty()
+        self.__windowsProp = _openCloseProperty()
+        self.__doorsProp = _openCloseProperty()
+        self.__temperature = _temperatureProperty()
 
-    bAllWindowOpen = False
-    bAllWindowClosed = False
-    bAllDoorOpen = False
-    bAllDoorClosed = False
-    bAllLightOn = False
-    bAllLightOff = False
-    bAtHome = False
-    bSleeping = False
+    @property
+    def Lights(self) -> _onOffProperty:
+        return self.__lightsProp
 
-    timeWindowWasOpen = 0
-    timeWindowWasClosed = 0
+    @property
+    def Switches(self) -> _onOffProperty:
+        return self.__switchesProp
 
-    timeDoorWasOpen = 0
-    timeDoorWasClosed = 0
+    @property
+    def Windows(self) -> _onOffProperty:
+        return self.__windowsProp
+
+    @property
+    def Doors(self) -> _onOffProperty:
+        return self.__doorsProp
+    
+    @property
+    def Temperature(self) -> _temperatureProperty:
+        return self.__temperature
+    
+    @property
+    def Air(self) -> _airStats:
+        return self._air
+    
+    #TODO Rooms
+
+    #TODO Movement Stats
 
     def getJson(self):
         return {
-            "temp": {
-                "avg": self.temp_avg,
-                "coldest": self.temp_coldest,
-                "hottest": self.temp_hottest
-            },
-            "Windows": {
-                "All_Closed": self.bAllWindowClosed,
-                "All_Opened": self.bAllWindowOpen,
-                "LastOpenTime": self.timeWindowWasOpen,
-                "LastClosedTime": self.timeWindowWasClosed
-            },
-            "Doors": {
-                "All_Closed": self.bAllDoorClosed,
-                "All_Opened": self.bAllDoorOpen,
-                "LastOpenTime": self.timeDoorWasOpen,
-                "LastClosedTime": self.timeDoorWasClosed
-            },
-            "Lights": {
-                "All_On": self.bAllLightOn,
-                "All_Off": self.bAllLightOff
+            "Temperature": self.Temperature.getJSON(),
+            "Windows": self.Windows.getJSON(),
+            "Doors": self.Doors.getJSON(),
+            "Lights": self.Lights.getJSON(),
+            "Switches": self.Lights.getJSON(),
+            "Air": self.Air.getJSON(),
+            "Rooms": {
+                # TODO
             },
-            "OwnerAtHome": self.bAtHome,
-            "OwnerSleeping": self.bSleeping
+            "Movements": {
+                # TODO
+            }
         }

+ 8 - 1
Stats/OutdoorStats.py

@@ -11,6 +11,12 @@ class OutdoorStats(object):
     Clouds = 0.0
     bRaining = False
     bSnowing = False
+    MoonPhase = {
+        "index" : 0,
+        "phase" : 0,
+        "pos" : 0,
+        "name": ""
+    }
 
     def getJson(self):
         return {
@@ -22,5 +28,6 @@ class OutdoorStats(object):
             "WindDegree": self.WindDegree,
             "Clouds": self.Clouds,
             "bRaining": self.bRaining,
-            "bSnowing": self.bSnowing
+            "bSnowing": self.bSnowing,
+            "Moon": self.MoonPhase
         }

+ 2 - 0
Stats/__init__.py

@@ -1 +1,3 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
 from Stats.main import Stats

+ 258 - 259
Stats/main.py

@@ -1,6 +1,5 @@
 #!/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
@@ -20,7 +19,7 @@ from lib.RepeatTimer import RepeatTimer
 import lib.MoonPhase as mp
 import random
 
-class Stats(object):
+class Stats:
 
     instance = None
     @staticmethod
@@ -29,18 +28,16 @@ class Stats(object):
             Stats.instance = Stats()
         return Stats.instance
 
-    deviceStats = _DeviceStats()
-    houseStats = _HouseStats()
-    micLevel = _MicLevel()
-    outdoorStats = _OutdoorStats()
-    ownerStats = _OwnerStats()
-    talkingStats = _TalkingStats()
-    adminStats = _AdminStats()
-
-    weather = OpenWeatherMap.OpenWeatherMap()
+    #deviceStats:_DeviceStats = _DeviceStats()
+    #houseStats:_HouseStats = _HouseStats()
+    #micLevel:_MicLevel = _MicLevel()
+    #outdoorStats = _OutdoorStats()
+    #ownerStats = _OwnerStats()
+    #talkingStats = _TalkingStats()
+    #adminStats = _AdminStats()
 
 
-    UPDATE_EMOTION_DELAY_MINUTE = 1.66
+    UPDATE_EMOTION_DELAY_MINUTE = 0.2
     UPDATE_HOMEMATIC_DELAY_MINUTE = 1
     UPDATE_DATETIME_DELAY_MINUTE = 10
     UPDATE_OUTDOOR_DELAY_MINUTE = 2.1
@@ -52,56 +49,30 @@ class Stats(object):
     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')
+            config.read('config/stats.ini')
         except:
             print("Failed to get Config")
             config = dict
-        if "Homematic" not in config:
-            config.add_section("Homematic")
-            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._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)
@@ -120,85 +91,112 @@ class Stats(object):
         self.Thread_Emotion.start()
 
         print("- - Init Stats done")
-        return super().__init__()
+
+    @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())
+        #print(self.micLevel.getJson())
 
     def __UpdateDateTime(self):
-        self.moonPhase = mp.phase(time=datetime.datetime.now())
+        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
+        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
+        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 self._outdoorStats.MoonPhase["phase"]==4:
+            if self._outdoorStats.Clouds>80:
                 if curHour>23 or curHour<6:
                     moonImpact += random.randint(0,9)/60
                 else:
@@ -212,194 +210,195 @@ class Stats(object):
         # 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
+        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
+        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.temp_avg < 17.0 or self.houseStats.temp_hottest < 15.0:
-            self.deviceStats.freezy += float(updateDur / 12) * impact
+            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
+            self._deviceStats.freezy -= float(updateDur / 38) * impact
 
-        if self.deviceStats.hot <200 and self.deviceStats.freezy < 200:
-            self.deviceStats.temperate -= float(updateDur / 12) * 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.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)
+        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.houseStats.bSleeping:
-            self.deviceStats.exhausted -= (float)(updateDur / 18)
+        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)
+            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
+        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
+            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.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)
+        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)
+                        self._deviceStats.lonely+=(float)(updateDur / 8)
                 else:
-                    self.deviceStats.lonely+=(float)(updateDur / 32)
+                    self._deviceStats.lonely+=(float)(updateDur / 32)
             else:
-                self.deviceStats.lonely+=(float)(updateDur / 64)
+                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
+        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)
+            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._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
+        if self._ownerStats.bSleeping:
+            self._deviceStats.sleepy -= (float)(updateDur / 15) * impact
         else:
-            if self.deviceStats.toQuiet > 300:
-                self.deviceStats.sleepy += (float)(updateDur / 24);
+            if self._deviceStats.toQuiet > 300:
+                self._deviceStats.sleepy += (float)(updateDur / 24);
             if curHour > 21 or curHour < 8:
-                self.deviceStats.sleepy += (float)(updateDur / 48)
+                self._deviceStats.sleepy += (float)(updateDur / 48)
 
-        if self.outdoorStats.bRaining == True:
-            if self.outdoorStats.bWindy:
-                self.deviceStats.depressive += (float)(updateDur / 10)
+        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
+                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.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)
+        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.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
+        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
+            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.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.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
+        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
+            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)
+        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()
+            self._deviceStats.sad -= (float)(updateDur / 48)
+        self._deviceStats.Save()
+        print(self.getJson())
         
 
     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()
+            "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):
@@ -417,9 +416,9 @@ class Stats(object):
         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
+        del self._deviceStats
+        del self._HouseStats
+        del self._MicLevel
+        del self._OutdoorStats
+        del self._OwnerStats
+        del self._TalkingStats

+ 12 - 1
Trixy.pyproj

@@ -29,6 +29,8 @@
     <Compile Include="main.py" />
     <Compile Include="MicCapture\WindowsCapture.py" />
     <Compile Include="MicCapture\__init__.py" />
+    <Compile Include="mods\BaseMod.py" />
+    <Compile Include="mods\WindowsSay\__init__.py" />
     <Compile Include="OpenWeatherMap\WeatherData.py" />
     <Compile Include="OpenWeatherMap\WeatherData_Clouds.py" />
     <Compile Include="OpenWeatherMap\WeatherData_Coords.py" />
@@ -39,7 +41,6 @@
     <Compile Include="OpenWeatherMap\WeatherData_Weather.py" />
     <Compile Include="OpenWeatherMap\WeatherData_Wind.py" />
     <Compile Include="OpenWeatherMap\__init__.py" />
-    <Compile Include="RepeatTimer.py" />
     <Compile Include="Stats\AdminStats.py" />
     <Compile Include="Stats\DeviceStats.py" />
     <Compile Include="Stats\HouseStats.py" />
@@ -56,13 +57,23 @@
   </ItemGroup>
   <ItemGroup>
     <Content Include=".gitignore" />
+    <Content Include="config\config.ini" />
+    <Content Include="config\deepspeech.ini" />
+    <Content Include="config\email.ini" />
+    <Content Include="config\mqtt.ini" />
+    <Content Include="config\pico.ini" />
+    <Content Include="config\README.md" />
+    <Content Include="config\stats.ini" />
     <Content Include="LICENSE" />
+    <Content Include="mods\README.md" />
     <Content Include="README.md" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="lib\" />
     <Folder Include="MicCapture\" />
     <Folder Include="cache\" />
+    <Folder Include="config\" />
+    <Folder Include="mods\WindowsSay\" />
     <Folder Include="OpenWeatherMap\" />
     <Folder Include="TextConfig\" />
     <Folder Include="Stats\" />

+ 14 - 10
VoicePlay/main.py

@@ -5,6 +5,7 @@ import win32com.client
 import platform
 import wave
 import os
+from DynLoader import DynLoaderMod as dyn
 
 class Voice:
 
@@ -17,18 +18,21 @@ class Voice:
         return Voice.instance
     
     def __init__(self):
-        self.sys = platform.system()
-        if self.sys=="Windows":
-            self.speaker = win32com.client.Dispatch("SAPI.SpVoice")
-        else:
-            self.speaker = None
+        #self.sys = platform.system()
+        #if self.sys=="Windows":
+        #    self.speaker = win32com.client.Dispatch("SAPI.SpVoice")
+        #else:
+        #    self.speaker = None
+        pass
 
     def Say(self, text):
-        if self.speaker != None:
-            self.speaker.Rate = 0.0
-            self.speaker.Speak(text)
-        else:
-            self.__svox(text)
+        dyn.getInstance().execute("Say",text)
+        #if self.speaker != None:
+        #    self.speaker.Rate = 0.0
+        #    self.speaker.Speak(text)
+        #else:
+        #    self.__svox(text)
+        
 
     def __svox(self, text):
         pass

+ 11 - 13
main.py

@@ -1,22 +1,20 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
-print("Import DynLoader")
-import DynLoader as dyn
-print("Import VoicePlay")
-import VoicePlay as speach
-print("Import Stats")
-import Stats as mood
-print("Import Done")
+
+from DynLoader import DynLoaderMod as dyn
+from VoicePlay import Voice as speach
+from Stats import Stats
 
 if __name__ == "__main__":
-    print("Starte Anwendung")
+    print("Start application")
 
     print("Init Mods")
-    mod = dyn.DynLoaderMod("mods/")
+    mod = dyn("mods/", "on")
+
+    print("Init Stats")
+    stats:Stats = Stats.getInstance()
 
     print("Init Speech")
-    speach.Voice.getInstance().Say("Hallo Welt")
-    print("Hallo Welt")
-    mod.execute("PlaySound")
+    speach.getInstance().Say("Willkommen")
 
-    print(mood.Stats.getInstance().deviceStats.aroused)
+    mod.execute("PlaySound", "welcome.wav")

+ 59 - 57
mods/README.md

@@ -5,10 +5,11 @@ Mods sind allgemeine Modifikationen die bei bestimmten Events ausgelöst werden.
 Hierfür wird ein entsprechender Ordner in dem "mods/" erstellt, dass die entsprechenden Script-Dateien beinhaltet.
 
 ## Aufbau
- >  class MyMod:
- >
- >    def onBeforeText(text:str) : str
- >      return text.replace("apple","banana")
+ >  from mods import BaseMod
+ >  class MyMod(BaseMod): 
+ > 
+ >    def onBeforeText(text:str) : str 
+ >      return text.replace("apple","banana") 
 
 ## inDevice / outDevice
 inDevice ist das Gerät, auf dem der Befehl 
@@ -16,81 +17,82 @@ outDevice ist das Gerät, auf dem die entsprechende Aktion geschehen soll,
 
 ## Trigger
 ### Mod-Trigger
-> def onBeforeRegister() : bool
-> def onRegister()
-> def onBeforeUnregister() : bool
-> def onUnregister()
+> def onBeforeRegister() : bool 
+> def onRegister() 
+> def onBeforeUnregister() : bool 
+> def onUnregister() 
 
 ### Speech
-> def onBeforeText(text:str) : str
-> def onAfterText(text:str) : str
+> def onBeforeText(text:str) : str 
+> def onAfterText(text:str) : str 
 > 
-> def onSay(outDevice:str, text:str)
+> def onSay(outDevice:str, text:str) 
 
 ### Assistent
-> def onWeakWord(weakword:str)
-> def onSystemCommand(intent, slots)
-> def onCommand(intent, slots)
+> def onWeakWord(weakword:str) 
+> def onSystemCommand(intent, slots) 
+> def onCommand(intent, slots) 
 >
-> def onBeforeTimerSet(duration:int) : bool
-> def onTimerSet(duration:int)
-> def onTimer(duration)
+> def onBeforeTimerSet(duration:int) : bool 
+> def onTimerSet(duration:int) 
+> def onTimer(duration) 
 > 
-> def onBeforeJoke() : bool
-> def onJoke() : bool
-> def onSearchNextJoke(category) : bool
+> def onBeforeJoke() : bool 
+> def onJoke() : bool 
+> def onSearchNextJoke(category) : bool 
 > 
-> def onBeforeMusicPlay() : bool
-> def onMusicPlay()
-> def onBeforeMusicChanged(interpret:str, song:str) : bool
-> def onMusicChanged(interpret:str, song:str)
-> def onBeforeMusicStop() : bool
-> def onMusicStop()
-> def onSearchNextSong(category) : str
+> def onBeforeMusicPlay() : bool 
+> def onMusicPlay() 
+> def onBeforeMusicChanged(interpret:str, song:str) : bool 
+> def onMusicChanged(interpret:str, song:str) 
+> def onBeforeMusicStop() : bool 
+> def onMusicStop() 
+> def onSearchNextSong(category) : str 
 > 
-> def onBeforeNote() : bool
-> def onNote(text:str) : str
-> def onBeforeNoteSave(text:str) : bool
-> def onNoteSave(text:str)
+> def onBeforeNote() : bool 
+> def onNote(text:str) : str 
+> def onBeforeNoteSave(text:str) : bool 
+> def onNoteSave(text:str) 
 
 ### Smart Home
 > def onWindowOpened(window:str)
-> def onWindowClosed(window:str)
-> def onWindow(window:str, open:bool)
+> def onWindowClosed(window:str) 
+> def onWindow(window:str, open:bool) 
 > 
-> def onDoorOpened(door:str)
-> def onDoorClosed(door:str)
-> def onDoor(door:str, open:bool)
+> def onDoorOpened(door:str) 
+> def onDoorClosed(door:str) 
+> def onDoor(door:str, open:bool) 
 > 
-> def onSwitchOn(switch:str)
-> def onSwitchOff(switch:str)
-> def onSwitch(switch:str, on:bool)
+> def onSwitchOn(switch:str) 
+> def onSwitchOff(switch:str) 
+> def onSwitch(switch:str, on:bool) 
 > 
-> def onMovement(device:str)
+> def onMovement(device:str) 
 > 
-> def onTemperature(device:str, temperature)
+> def onTemperature(device:str, temperature) 
 
 ### SmartHome Controll
-> def onBeforeSwitchOn(switch:str) : bool
-> def onBeforeSwitchOff(switch:str) : bool
-> def onBeforeTeperature(device:str) : bool
+> def onBeforeSwitchOn(switch:str) : bool 
+> def onBeforeSwitchOff(switch:str) : bool 
+> def onBeforeTeperature(device:str) : bool 
 
 ### Outdoor Stats
-> def onMoonphase(moonphase:str)
-> def onDayChanged()
-> def onMoodChanged()
+> def onMoonphase(moonphase:str) 
+> def onDayChanged() 
+> def onMoodChanged() 
 
 ### User Stats
-> def onUserLeave()
-> def onUserArrived()
-> def onUserWeakup()
-> def onUserSleep()
+> def onUserLeave() 
+> def onUserArrived() 
+> def onUserWeakup() 
+> def onUserSleep() 
 
 ### System
-> def onReset()
-> def onRestart()
+> def onReset() 
+> def onRestart() 
+> def onConfig() 
 > def onConfigChanged(config, oldValue, newValue)
-> def onUpdate()
-> def onBeforeUpdate() : bool
-> def onSyncronice() : bool
-> def onFilesSyncroniceRequest() : list
+> def onUpdate() 
+> def onBeforeUpdate() : bool 
+> def onSyncronice() : bool 
+> def onFilesSyncroniceRequest() : list