def onConnect(self, Connection, Status, Description): Domoticz.Debug("onConnect called") if self.isStarted and (Connection == self.httpConn): self.handleConnection()
def getOverview(self, delay=0): Domoticz.Debug("getOverview called") sendData = {'Verb': 'GET', 'URL': '/api/slides/overview' } self.slideRequest(sendData, delay)
def onDisconnect(self, Connection): Domoticz.Debug("onDisconnect called") self.myConn.Connect() self._checkMovement = 0
def CreateDomoDevice(self, Devices, DeviceID): def FreeUnit(self, Devices): FreeUnit = "" for x in range(1, 256): Domoticz.Debug("FreeUnit - is device " + str(x) + " exist ?") if x not in Devices: Domoticz.Debug("FreeUnit - device " + str(x) + " not exist") FreeUnit = x return FreeUnit if FreeUnit == "": FreeUnit = len(Devices) + 1 Domoticz.Debug("FreeUnit - Free Device Unit find : " + str(x)) return FreeUnit for Ep in self.ListOfDevices[DeviceID]['Ep']: # CLD CLD # Use 'type' at level EndPoint if existe if 'Type' in self.ListOfDevices[DeviceID]['Ep'][Ep]: if self.ListOfDevices[DeviceID]['Ep'][Ep]['Type'] != "": dType = self.ListOfDevices[DeviceID]['Ep'][Ep]['Type'] aType = str(dType) Type = aType.split("/") Domoticz.Log("CreateDomoDevice - Type via ListOfDevice: " + str(Type) + " Ep : " + str(Ep)) else: if self.ListOfDevices[DeviceID]['Type'] == {}: Type = GetType(self, DeviceID, Ep).split("/") Domoticz.Log("CreateDomoDevice - Type via GetType: " + str(Type) + " Ep : " + str(Ep)) else: Type = self.ListOfDevices[DeviceID]['Type'].split("/") Domoticz.Log("CreateDomoDevice - Type : '" + str(Type) + "'") if Type != "": if "Humi" in Type and "Temp" in Type and "Baro" in Type: t = "Temp+Hum+Baro" # Detecteur temp + Hum + Baro Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), TypeName=t, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if "Humi" in Type and "Temp" in Type: t = "Temp+Hum" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), TypeName=t, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() #For color Bulb if ("Switch" in Type) and ("LvlControl" in Type) and ("ColorControl" in Type): Type = ['ColorControl'] elif ("Switch" in Type) and ("LvlControl" in Type): Type = ['LvlControl'] for t in Type: Domoticz.Log("CreateDomoDevice - Device ID : " + str(DeviceID) + " Device EP : " + str(Ep) + " Type : " + str(t)) if t == "Temp": # Detecteur temp self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), TypeName="Temperature", Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "Humi": # Detecteur hum self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), TypeName="Humidity", Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "Baro": # Detecteur Baro self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), TypeName="Barometer", Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "Door": # capteur ouverture/fermeture xiaomi self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=73, Switchtype=2, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "Motion": # detecteur de presence self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=73, Switchtype=8, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "MSwitch": # interrupteur multi lvl 86sw2 xiaomi self.ListOfDevices[DeviceID]['Status'] = "inDB" Options = { "LevelActions": "||||", "LevelNames": "Push|1 Click|2 Click|3 Click|4 Click", "LevelOffHidden": "false", "SelectorStyle": "0", "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t } Domoticz.Device(DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=62, Switchtype=18, Options=Options).Create() if t == "DSwitch": # interrupteur double sur EP different self.ListOfDevices[DeviceID]['Status'] = "inDB" Options = { "LevelActions": "|||", "LevelNames": "Off|Left Click|Right Click|Both Click", "LevelOffHidden": "true", "SelectorStyle": "0", "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t } Domoticz.Device(DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=62, Switchtype=18, Options=Options).Create() if t == "DButton": # interrupteur double sur EP different self.ListOfDevices[DeviceID]['Status'] = "inDB" Options = { "LevelActions": "|||", "LevelNames": "Off|Left Click|Right Click|Both Click", "LevelOffHidden": "true", "SelectorStyle": "0", "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t } Domoticz.Device(DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=62, Switchtype=18, Options=Options).Create() if t == "Smoke": # detecteur de fumee self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=73, Switchtype=5, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "Lux": # Lux sensors self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=246, Subtype=1, Switchtype=0, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "Switch": # inter sans fils 1 touche 86sw1 xiaomi self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=73, Switchtype=0, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "Button": # inter sans fils 1 touche 86sw1 xiaomi self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=73, Switchtype=9, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "Aqara" or t == "XCube": # Xiaomi Magic Cube self.ListOfDevices[DeviceID]['Status'] = "inDB" Options = { "LevelActions": "|||||||||", "LevelNames": "Off|Shake|Wakeup|Drop|90°|180°|Push|Tap|Rotation", "LevelOffHidden": "true", "SelectorStyle": "0", "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t } Domoticz.Device(DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=62, Switchtype=18, Options=Options).Create() if t == "Water": # detecteur d'eau self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=73, Switchtype=0, Image=11, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "Plug": # prise pilote self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=73, Switchtype=0, Image=1, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "LvlControl" and self.ListOfDevices[DeviceID][ 'Model'] == "shutter.Profalux": # Volet Roulant / Shutter / Blinds, let's created blindspercentageinverted devic self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=73, Switchtype=16, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "LvlControl" and self.ListOfDevices[DeviceID][ 'Model'] != "shutter.Profalux": # variateur de luminosite + On/off self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=244, Subtype=73, Switchtype=7, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() if t == "ColorControl": # variateur de couleur/luminosite/on-off self.ListOfDevices[DeviceID]['Status'] = "inDB" # Type 0xF1 pTypeColorSwitch #SubType sTypeColor_RGB_W 0x01 // RGB + white, either RGB or white can be lit #SubType sTypeColor_RGB 0x02 // RGB #SubType sTypeColor_White 0x03 // Monochrome white #SubType sTypeColor_RGB_CW_WW 0x04 // RGB + cold white + warm white, either RGB or white can be lit #SubType sTypeColor_LivCol 0x05 #SubType sTypeColor_RGB_W_Z 0x06 // Like RGBW, but allows combining RGB and white #SubType sTypeColor_RGB_CW_WW_Z 0x07 // Like RGBWW, but allows combining RGB and white #SubType sTypeColor_CW_WW 0x08 // Cold white + Warm white # Switchtype 7 STYPE_Dimmer if self.ListOfDevices[DeviceID][ 'Model'] == "Ampoule.LED1624G9.Tradfri": Subtype_ = 2 elif self.ListOfDevices[DeviceID][ 'Model'] == "Ampoule.LED1545G12.Tradfri": Subtype_ = 8 else: Subtype_ = 7 Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=FreeUnit(self, Devices), Type=241, Subtype=Subtype_, Switchtype=7, Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create() #Ajout meter if t == "PowerMeter": # Power Prise Xiaomi Domoticz.Debug("Ajout Meter") self.ListOfDevices[DeviceID]['Status'] = "inDB" Domoticz.Device( DeviceID=str(DeviceID), Name=str(t) + "-" + str(DeviceID) + "-" + str(Ep), Unit=len(Devices) + 1, TypeName="Usage", Options={ "Zigate": str(self.ListOfDevices[DeviceID]), "TypeName": t }).Create()
def onMessage(self, Connection, Data): strData = Data.decode("utf-8", "ignore") Domoticz.Debug("onMessage called with Data: '" + str(strData) + "'") self.oustandingPings = 0 try: # Beacon messages to find the amplifier if (Connection.Name == "Beacon"): dictAMXB = DecodeDDDMessage(strData) if (strData.find(Parameters["Mode2"]) >= 0): self.DenonConn = None self.DenonConn = Domoticz.Connection( Name="Telnet", Transport="TCP/IP", Protocol="Line", Address=Connection.Address, Port=Parameters["Port"]) self.DenonConn.Connect() try: Domoticz.Log( dictAMXB['Make'] + ", " + dictAMXB['Model'] + " Receiver discovered successfully at address: " + Connection.Address) except KeyError: Domoticz.Log( "'Unknown' Receiver discovered successfully at address: " + Connection.Address) else: try: Domoticz.Log("Discovery message for Class: '" + dictAMXB['SDKClass'] + "', Make '" + dictAMXB['Make'] + "', Model '" + dictAMXB['Model'] + "' seen at address: " + Connection.Address) except KeyError: Domoticz.Log("Discovery message '" + str(strData) + "' seen at address: " + Connection.Address) # Otherwise handle amplifier else: strData = strData.strip() action = strData[0:2] detail = strData[2:] if (action in self.pollingDict): self.lastMessage = action if (action == "PW"): # Power Status if (detail == "STANDBY"): self.powerOn = False elif (detail == "ON"): self.powerOn = True else: Domoticz.Debug("Unknown: Action " + action + ", Detail '" + detail + "' ignored.") elif (action == "ZM"): # Main Zone on/off if (detail == "ON"): self.mainOn = True elif (detail == "OFF"): self.mainOn = False else: Domoticz.Debug("Unknown: Action " + action + ", Detail '" + detail + "' ignored.") elif (action == "SI"): # Main Zone Source Input for key, value in self.selectorMap.items(): if (detail == value): self.mainSource = key elif (action == "MV"): # Master Volume if (detail.isdigit()): if (abs(self.mainVolume1) != int(detail[0:2])): self.mainVolume1 = int(detail[0:2]) elif (detail[0:3] == "MAX"): Domoticz.Debug("Unknown: Action " + action + ", Detail '" + detail + "' ignored.") else: Domoticz.Log("Unknown: Action " + action + ", Detail '" + detail + "' ignored.") elif (action == "MU"): # Overall Mute if (detail == "ON"): self.mainVolume1 = abs(self.mainVolume1) * -1 elif (detail == "OFF"): self.mainVolume1 = abs(self.mainVolume1) else: Domoticz.Debug("Unknown: Action " + action + ", Detail '" + detail + "' ignored.") elif (action == "Z2"): # Zone 2 # Zone 2 response, make sure we have Zone 2 devices in Domoticz and they are polled if (4 not in Devices): LevelActions = '|' * Parameters["Mode4"].count('|') Domoticz.Device(Name="Zone 2", Unit=4, TypeName="Selector Switch", Switchtype=18, Image=5, Options=self.SourceOptions).Create() Domoticz.Log("Zone 2 responded, devices added.") if (5 not in Devices): Domoticz.Device(Name="Volume 2", Unit=5, Type=244, Subtype=73, Switchtype=7, Image=8).Create() if ("Z2" not in self.pollingDict): self.pollingDict = { "PW": "ZM?\r", "ZM": "SI?\r", "SI": "MV?\r", "MV": "MU?\r", "MU": "Z2?\r", "Z2": "PW?\r" } if (detail == "ON"): self.zone2On = True elif (detail == "OFF"): self.zone2On = False elif (detail == "MUON"): self.zone2Volume = abs(self.zone2Volume) * -1 elif (detail == "MUOFF"): self.zone2Volume = abs(self.zone2Volume) elif (detail.isdigit()): if (abs(self.zone2Volume) != int(detail[0:2])): self.zone2Volume = int(detail[0:2]) else: for key, value in self.selectorMap.items(): if (detail == value): self.zone2Source = key elif (action == "Z3"): # Zone 3 # Zone 3 response, make sure we have Zone 3 devices in Domoticz and they are polled if (6 not in Devices): LevelActions = '|' * Parameters["Mode4"].count('|') Domoticz.Device(Name="Zone 3", Unit=6, TypeName="Selector Switch", Switchtype=18, Image=5, Options=self.SourceOptions).Create() Domoticz.Log("Zone 3 responded, devices added.") if (7 not in Devices): Domoticz.Device(Name="Volume 3", Unit=7, Type=244, Subtype=73, Switchtype=7, Image=8).Create() if ("Z3" not in self.pollingDict): self.pollingDict = { "PW": "ZM?\r", "ZM": "SI?\r", "SI": "MV?\r", "MV": "MU?\r", "MU": "Z2?\r", "Z2": "Z3?\r", "Z3": "PW?\r" } if (detail == "ON"): self.zone3On = True elif (detail == "OFF"): self.zone3On = False elif (detail == "MUON"): self.zone3Volume = abs(self.zone3Volume) * -1 elif (detail == "MUOFF"): self.zone3Volume = abs(self.zone3Volume) elif (detail.isdigit()): if (abs(self.zone3Volume) != int(detail[0:2])): self.zone3Volume = int(detail[0:2]) else: for key, value in self.selectorMap.items(): if (detail == value): self.zone3Source = key else: if (self.ignoreMessages.find(action) < 0): Domoticz.Debug("Unknown message '" + action + "' ignored.") self.SyncDevices(0) except Exception as inst: Domoticz.Error("Exception in onMessage, called with Data: '" + str(strData) + "'") Domoticz.Error("Exception detail: '" + str(inst) + "'") raise
def onConnect(self, Connection, Status, Description): Domoticz.Debug("MIIOServer connection status is [%s] [%s]" % (Status, Description))
def onCommand(self, Unit, Command, Level, Hue): Domoticz.Debug("onCommand called for Unit " + str(Unit) + ": Command '" + str(Command) + "', Level: " + str(Level)) if self.statusUnit not in Devices: Domoticz.Error('Status device is required') return sDevice = Devices[self.statusUnit] if self.statusUnit == Unit: if 'On' == Command and self.isOFF: if self.apiRequest('start'): UpdateDevice(Unit, 1, self.states[5]) # Cleaning elif 'Off' == Command and self.isON: if sDevice.sValue == self.states[11] and self.apiRequest( 'pause'): # Stop if Spot cleaning UpdateDevice(Unit, 0, self.states[3]) # Waiting elif self.apiRequest('home'): UpdateDevice(Unit, 1, self.states[6]) # Back to home elif self.controlUnit == Unit: if Level == 10: # Clean if self.apiRequest('start') and self.isOFF: UpdateDevice(self.statusUnit, 1, self.states[5]) # Cleaning elif Level == 20: # Home if self.apiRequest('home') and sDevice.sValue in [ self.states[5], self.states[3], self.states[10] ]: # Cleaning, Waiting, Paused UpdateDevice(self.statusUnit, 1, self.states[6]) # Back to home elif Level == 30: # Spot if self.apiRequest( 'spot' ) and self.isOFF and sDevice.sValue != self.states[ 8]: # Spot cleaning will not start if Charging UpdateDevice(self.statusUnit, 1, self.states[11]) # Spot cleaning elif Level == 40: # Pause if self.apiRequest('pause') and self.isON: if sDevice.sValue == self.states[ 11]: # For Spot cleaning - Pause treats as Stop UpdateDevice(self.statusUnit, 0, self.states[3]) # Waiting else: UpdateDevice(self.statusUnit, 0, self.states[10]) # Paused elif Level == 50: # Stop if self.apiRequest( 'stop') and self.isON and sDevice.sValue not in [ self.states[11], self.states[6] ]: # Stop doesn't work for Spot cleaning, Back to home UpdateDevice(self.statusUnit, 0, self.states[3]) # Waiting elif Level == 60: # Find self.apiRequest('find') elif self.fanDimmerUnit == Unit and Parameters['Mode5'] == 'dimmer': Level = 1 if Level == 0 else 100 if Level > 100 else Level if self.apiRequest('set_fan_level', Level): UpdateDevice(self.fanDimmerUnit, 2, str(Level)) elif self.fanSelectorUnit == Unit and Parameters['Mode5'] == 'selector': num_level = {10: 38, 20: 60, 30: 77, 40: 90}.get(Level, None) if num_level and self.apiRequest('set_fan_level', num_level): UpdateDevice(self.fanSelectorUnit, 1, str(Level)) elif self.cResetControlUnit == Unit: if Level == 10: # Reset Main Brush if self.apiRequest('care_reset_main_brush'): UpdateDevice(self.cMainBrushUnit, 100, '100') elif Level == 20: # Reset Side Brush if self.apiRequest('care_reset_side_brush'): UpdateDevice(self.cSideBrushUnit, 100, '100') elif Level == 30: # Reset Filter if self.apiRequest('care_reset_filter'): UpdateDevice(self.cFilterUnit, 100, '100') elif Level == 40: # Reset Sensors if self.apiRequest('care_reset_sensor'): UpdateDevice(self.cSensorsUnit, 100, '100') self.apiRequest('consumable_status')
def onHeartbeat(self): now = datetime.now() if Devices[1].sValue == "0": # Thermostat is off if self.forced or self.heat: # thermostat setting was just changed so we kill the heating self.forced = False self.endheat = now Domoticz.Debug("Switching heat Off !") self.switchHeat(False) if self.nexttemps <= now: # call the Domoticz json API for a temperature devices update, to get the lastest temps... self.readTemps() elif Devices[1].sValue == "20": # Thermostat is in forced mode if self.forced: if self.endheat <= now: self.forced = False self.endheat = now Domoticz.Debug("Forced mode Off !") Devices[1].Update(nValue=1, sValue="10") # set thermostat to normal mode self.switchHeat(False) else: self.forced = True self.endheat = now + timedelta(minutes=self.forcedduration) Domoticz.Debug("Forced mode On !") self.switchHeat(True) if self.nexttemps <= now: # call the Domoticz json API for a temperature devices update, to get the lastest temps... self.readTemps() else: # Thermostat is in mode auto if self.forced: # thermostat setting was just changed from "forced" so we kill the forced mode self.forced = False self.endheat = now self.nextcalc = now # this will force a recalculation on next heartbeat Domoticz.Debug("Forced mode Off !") self.switchHeat(False) elif (self.endheat <= now or self.pause) and self.heat: # heat cycle is over self.endheat = now self.heat = False if self.Internals['LastPwr'] < 100: self.switchHeat(False) # if power was 100(i.e. a full cycle), then we let the next calculation (at next heartbeat) decide # to switch off in order to avoid potentially damaging quick off/on cycles to the heater(s) elif self.pause and not self.pauserequested: # we are in pause and the pause switch is now off if self.pauserequestchangedtime + timedelta(minutes=self.pauseoffdelay) <= now: Domoticz.Debug("Pause is now Off") self.pause = False elif not self.pause and self.pauserequested: # we are not in pause and the pause switch is now on if self.pauserequestchangedtime + timedelta(minutes=self.pauseondelay) <= now: Domoticz.Debug("Pause is now On") self.pause = True self.switchHeat(False) elif self.pause and self.nexttemps <= now: # added to update thermostat temp even in pause mode # call the Domoticz json API for a temperature devices update, to get the lastest temps... self.readTemps() elif (self.nextcalc <= now) and not self.pause: # we start a new calculation self.nextcalc = now + timedelta(minutes=self.calculate_period) Domoticz.Debug("Next calculation time will be : " + str(self.nextcalc)) # make current setpoint used in calculation reflect the select mode (10= normal, 20 = economy) if Devices[2].sValue == "10": self.setpoint = float(Devices[4].sValue) else: self.setpoint = float(Devices[5].sValue) # call the Domoticz json API for a temperature devices update, to get the lastest temps... if self.readTemps(): # do the thermostat work self.AutoMode() else: # make sure we switch off heating if there was an error with reading the temp self.switchHeat(False) # check if need to refresh setpoints so that they do not turn red in GUI if self.nextupdate <= now: self.nextupdate = now + timedelta(minutes=int(Settings["SensorTimeout"])) Devices[4].Update(nValue=0, sValue=Devices[4].sValue) Devices[5].Update(nValue=0, sValue=Devices[5].sValue)
def registerDevices(self): try: self.brel_devices = {} # Get the token and device list brel_api = brel(Parameters['Address'], self.u_port, self.brel_devices) self.brel_devices = brel_api.request_device_list() if 'grp-0' not in self.brel_devices['devices']: # Add group-devices to self.brel_devices self.brel_devices['devices']['grp-0'] = { 'mac': 'grp-0', 'deviceType': 'group', 'data': { 'currentPosition': 0, 'currentAngle': 0, 'RSSI': 12 } } except: Domoticz.Debug('Connection to gateway timed out') self.hasTimedOut = True return if self.hasTimedOut: return # Generate the AccessToken try: AccessToken = self.GenerateAccessToken() Domoticz.Status('AccessToken {} generated.'.format(AccessToken)) except: Domoticz.Error('AccessToken could not be generated.') self.hasTimedOut = True return if self.hasTimedOut: return unitIds = self.indexRegisteredDevices() name_number = 0 # Add unregistred brel_devices for brel_device in self.brel_devices['devices']: devID = str(brel_device) devType = str( self.brel_devices['devices'][brel_device]['deviceType']) if devType != '02000001': # Gateway if devType == 'group': name = 'Group All' report = True else: name = 'Blinds {}' report = None if devID + ":P" not in unitIds or devID + ":A" not in unitIds: if len(Devices) > 0: name_number = int(len(Devices) / 2) name_number = name_number + 1 name = name.format(name_number) if devID + ":P" not in unitIds: new_unit_id = firstFree() Domoticz.Device( Name=name, Unit=new_unit_id, Type=244, Subtype=73, Switchtype=13, DeviceID=devID + ":P", Used=1, ).Create() self.updateDevice(new_unit_id, None, Report=report) if devID + ":A" not in unitIds: new_unit_id = firstFree() Domoticz.Device( Name=name + " Tilt", Unit=new_unit_id, Type=244, Subtype=73, Switchtype=7, DeviceID=devID + ":A", Used=1, ).Create() self.updateDevice(new_unit_id, None, Report=report) self.hasTimedOut = False
def readTemps(self): # set update flag for next temp update self.nexttemps = datetime.now() + timedelta(minutes=5) # fetch all the devices from the API and scan for sensors noerror = True listintemps = [] listouttemps = [] devicesAPI = DomoticzAPI( "type=devices&filter=temp&used=true&order=Name") if devicesAPI: for device in devicesAPI[ "result"]: # parse the devices for temperature sensors idx = int(device["idx"]) if idx in self.InTempSensors: if "Temp" in device: Domoticz.Debug("device: {}-{} = {}".format( device["idx"], device["Name"], device["Temp"])) # check temp sensor is not timed out if not SensorTimedOut(device["LastUpdate"]): listintemps.append(device["Temp"]) else: Domoticz.Error( "skipping timed out temperature sensor {}". format(device["Name"])) else: Domoticz.Error( "device: {}-{} is not a Temperature sensor".format( device["idx"], device["Name"])) elif idx in self.OutTempSensors: if "Temp" in device: Domoticz.Debug("device: {}-{} = {}".format( device["idx"], device["Name"], device["Temp"])) # check temp sensor is not timed out if not SensorTimedOut(device["LastUpdate"]): listouttemps.append(device["Temp"]) else: Domoticz.Error( "skipping timed out temperature sensor {}". format(device["Name"])) else: Domoticz.Error( "device: {}-{} is not a Temperature sensor".format( device["idx"], device["Name"])) # calculate the average inside temperature nbtemps = len(listintemps) if nbtemps > 0: self.intemp = round(sum(listintemps) / nbtemps, 1) Devices[6].Update( nValue=0, sValue=str(self.intemp) ) # update the dummy device showing the current thermostat temp else: Domoticz.Error( "No Inside Temperature found... Switching Thermostat Off") Devices[1].Update(nValue=0, sValue="0") # switch off the thermostat noerror = False # calculate the average outside temperature nbtemps = len(listouttemps) if nbtemps > 0: self.outtemp = round(sum(listouttemps) / nbtemps, 1) else: Domoticz.Debug("No Outside Temperature found...") self.outtemp = None self.WriteLog("Inside Temperature = {}".format(self.intemp), "Verbose") self.WriteLog("Outside Temperature = {}".format(self.outtemp), "Verbose") return noerror
def onStart(self): # setup the appropriate logging level try: debuglevel = int(Parameters["Mode6"]) except ValueError: debuglevel = 0 self.loglevel = Parameters["Mode6"] if debuglevel != 0: self.debug = True Domoticz.Debugging(debuglevel) DumpConfigToLog() self.loglevel = "Verbose" else: self.debug = False Domoticz.Debugging(0) # create the child devices if these do not exist yet devicecreated = [] if 1 not in Devices: Options = {"LevelActions": "||", "LevelNames": "Off|Auto|Forced", "LevelOffHidden": "false", "SelectorStyle": "0"} Domoticz.Device(Name="Thermostat Control", Unit=1, TypeName="Selector Switch", Switchtype=18, Image=15, Options=Options, Used=1).Create() devicecreated.append(deviceparam(1, 0, "0")) # default is Off state if 2 not in Devices: Options = {"LevelActions": "||", "LevelNames": "Off|Normal|Economy", "LevelOffHidden": "true", "SelectorStyle": "0"} Domoticz.Device(Name="Thermostat Mode", Unit=2, TypeName="Selector Switch", Switchtype=18, Image=15, Options=Options, Used=1).Create() devicecreated.append(deviceparam(2, 0, "10")) # default is normal mode if 3 not in Devices: Domoticz.Device(Name="Thermostat Pause", Unit=3, TypeName="Switch", Image=9, Used=1).Create() devicecreated.append(deviceparam(3, 0, "")) # default is Off if 4 not in Devices: Domoticz.Device(Name="Setpoint Normal", Unit=4, Type=242, Subtype=1, Used=1).Create() devicecreated.append(deviceparam(4, 0, "20")) # default is 20 degrees if 5 not in Devices: Domoticz.Device(Name="Setpoint Economy", Unit=5, Type=242, Subtype=1, Used=1).Create() devicecreated.append(deviceparam(5 ,0, "20")) # default is 20 degrees if 6 not in Devices: Domoticz.Device(Name="Thermostat temp", Unit=6, TypeName="Temperature").Create() devicecreated.append(deviceparam(6, 0, "20")) # default is 20 degrees # if any device has been created in onStart(), now is time to update its defaults for device in devicecreated: Devices[device.unit].Update(nValue=device.nvalue, sValue=device.svalue) # build lists of sensors and switches self.InTempSensors = parseCSV(Parameters["Mode1"]) Domoticz.Debug("Inside Temperature sensors = {}".format(self.InTempSensors)) self.OutTempSensors = parseCSV(Parameters["Mode2"]) Domoticz.Debug("Outside Temperature sensors = {}".format(self.OutTempSensors)) self.Heaters = parseCSV(Parameters["Mode3"]) Domoticz.Debug("Heaters = {}".format(self.Heaters)) # splits additional parameters params = parseCSV(Parameters["Mode5"]) if len(params) == 5: self.calculate_period = CheckParam("Calculation Period", params[0], 30) if self.calculate_period < 5: Domoticz.Error("Invalid calculation period parameter. Using minimum of 5 minutes !") self.calculate_period = 5 self.minheatpower = CheckParam("Minimum Heating (%)", params[1], 0) if self.minheatpower > 100: Domoticz.Error("Invalid minimum heating parameter. Using maximum of 100% !") self.minheatpower = 100 self.pauseondelay = CheckParam("Pause On Delay", params[2], 2) self.pauseoffdelay = CheckParam("Pause Off Delay", params[3], 0) self.forcedduration = CheckParam("Forced Mode Duration", params[4], 60) if self.forcedduration < 30: Domoticz.Error("Invalid forced mode duration parameter. Using minimum of 30 minutes !") self.calculate_period = 30 else: Domoticz.Error("Error reading Mode5 parameters") # loads persistent variables from dedicated user variable # note: to reset the thermostat to default values (i.e. ignore all past learning), # just delete the relevant "<plugin name>-InternalVariables" user variable Domoticz GUI and restart plugin self.getUserVar() # if mode = off then make sure actual heating is off just in case if was manually set to on if Devices[1].sValue == "0": self.switchHeat(False)
def connectHomeConnect(self, username, password, ascope): #'Request authorization to access home appliance" and "Return device code, user code, verification uri, ..." url_authorization = BASEURL + "/security/oauth/device_authorization" scope = "IdentifyAppliance " + ascope + "-Monitor " + ascope + "-Settings" data_authorization = {"client_id": self.clientid, "scope": scope} response_authorization = requests.post(url_authorization, data_authorization, HEADER_URLENCODED) Domoticz.Debug(response_authorization.text) json_data_authorization = json.loads(response_authorization.text) response_authorization.close() device_code = "" verification_uri_complete = "" user_code = "" for key, value in json_data_authorization.items(): Domoticz.Debug(key + " --> " + str(value)) if key == "device_code": device_code = value if key == "verification_uri_complete": verification_uri_complete = value if key == "user_code": user_code = value Domoticz.Log("device_code: " + device_code) Domoticz.Log("verification_uri_complete: " + verification_uri_complete) Domoticz.Debug("user_code: " + user_code) #Enter user code, log in and authorize access authorized = False if (device_code != "") and (verification_uri_complete != "") and (user_code != ""): session = requests.Session() #log in part payload_login = { "client_id": self.clientid, "user_code": user_code, "email": username, "password": password } url_login = BASEURL + "/security/oauth/device_login" response_login = session.post(url_login, data=payload_login) Domoticz.Debug(response_login.text) sessionid = response_login.text[response_login.text. find("session_id\" value=\"") + len("session_id\" value=\""):] sessionid = sessionid[:sessionid.find("\"")] Domoticz.Log("sessionid: " + sessionid) response_login.close() #authorize part #payload_grant = {"session_id": sessionid, "client_id": self.clientid, "user_code": user_code, "email": username, "app_name": APP_NAME, "scope": scope} payload_grant = { "user_code": user_code, "session_id": sessionid, "input_aborted": "false", "app_name": APP_NAME, "accept_language": "nl", "client_id": self.clientid, "email": username, "scope": scope, "region": "EU", "environment": "PRD" } url_grant = BASEURL + "/security/oauth/device_grant" response_grant = session.post(url_grant, data=payload_grant) Domoticz.Debug("response_grant: " + response_grant.text) authorized = True response_grant.close() #Token request if authorized: Domoticz.Log("Device \"" + device_code + "\" is authorized by Home-Connect.") url_tokenrequest = BASEURL + "/security/oauth/token" payload_tokenrequest = { "grant_type": "device_code", "device_code": device_code, "client_id": self.clientid } response_tokenrequest = requests.post(url_tokenrequest, payload_tokenrequest, HEADER_URLENCODED) Domoticz.Debug("response_tokenrequest: " + response_tokenrequest.text) json_tokenrequest = json.loads(response_tokenrequest.text) response_tokenrequest.close() for key, value in json_tokenrequest.items(): Domoticz.Debug(key + " --> " + str(value)) if key == "access_token": self.access_token = value if key == "expires_in": self.token_expired = datetime.datetime.now( ) + datetime.timedelta( seconds=value) #default 86400 seconds (=24h) if key == "refresh_token": self.refresh_token = value Domoticz.Log("Device \"" + device_code + "\" has token: " + self.access_token) else: Domoticz.Error("Device \"" + device_code + "\" is not authorized by Home_Connect.") return
def setPowerState(self, devicetype, state): Domoticz.Debug("setPowerState") url_setPowerState = BASEURL + "/api/homeappliances/" + self.haId + "/settings/BSH.Common.Setting.PowerState" header = { "Content-Type": "application/vnd.bsh.sdk.v1+json", "Authorization": "Bearer " + self.access_token } data = None if state == "On": l1 = [self.DEVICE_DISHWASHER, self.DEVICE_HOOD] if devicetype in l1: data = json.dumps({ 'data': { 'key': 'BSH.Common.Setting.PowerState', 'value': 'BSH.Common.EnumType.PowerState.On', 'type': 'BSH.Common.EnumType.PowerState', 'constraints': { 'allowedvalues': [ 'BSH.Common.EnumType.Powerstate.On', 'BSH.Common.EnumType.PowerState.Off' ] } } }) elif devicetype == self.DEVICE_OVEN: data = json.dumps({ 'data': { 'key': 'BSH.Common.Setting.PowerState', 'value': 'BSH.Common.EnumType.PowerState.On', 'type': 'BSH.Common.EnumType.PowerState', 'constraints': { 'allowedvalues': [ 'BSH.Common.EnumType.Powerstate.On', 'BSH.Common.EnumType.PowerState.Standby' ] } } }) elif state == "Off": data = json.dumps({ 'data': { 'key': 'BSH.Common.Setting.PowerState', 'value': 'BSH.Common.EnumType.PowerState.Off', 'type': 'BSH.Common.EnumType.PowerState', 'constraints': { 'allowedvalues': [ 'BSH.Common.EnumType.Powerstate.On', 'BSH.Common.EnumType.PowerState.Off' ] } } }) elif state == "Standby": data = json.dumps({ 'data': { 'key': 'BSH.Common.Setting.PowerState', 'value': 'BSH.Common.EnumType.PowerState.Standby', 'type': 'BSH.Common.EnumType.PowerState', 'constraints': { 'allowedvalues': [ 'BSH.Common.EnumType.Powerstate.On', 'BSH.Common.EnumType.PowerState.Standby' ] } } }) response = requests.put(url_setPowerState, headers=header, data=data) Domoticz.Debug(str(response.status_code)) if str(response.status_code) == "204": response.close() return True response.close() return False
def onMessage(self, Connection, Data): Domoticz.Debug("onMessage called") # if started and not stopping if self.isStarted and (Connection == self.httpConn): self.handleConnection(Data)
def onMessage(self, Connection, Data): Domoticz.Debug("onMessage called: Connection=" + str(Connection) + ", Data=" + str(Data)) return
def onConnect(self, Connection, Status, Description): Domoticz.Debug("onConnect called")
def onDisconnect(self, Connection): Domoticz.Debug("onDisconnect called") return
def onCommand(self, Unit, Command, Level, Hue): Domoticz.Debug("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level)) devID = str(Devices[Unit].DeviceID).split(":")[0] devType = str(self.brel_devices['devices'][devID]['deviceType']) devCommands = {} if Command == "On" or Command == "Off": if Parameters['Mode2']: try: defaults = eval('{' + str(Parameters['Mode2']) + '}') except: defaults = {} if devID == 'grp-0': idx = 0 else: idx = Devices[Unit].ID if idx not in defaults: if -1 in defaults: idx = -1 # if len(defaults) < 1: # defaults = eval("{0:{1:{'P':15,'A':25},0:{'P':80,'A':80}},1:{1:{'P':15,'A':25},0:{'P':80,'A':80}},3:{1:{'P':15,'A':25},0:{'P':80,'A':80}}}") try: if Command == "On": # closed if Devices[Unit].DeviceID[-2:] == ':P': try: if idx in defaults: for com in defaults[idx]['c']: devCommands[com] = defaults[idx]['c'][com] else: Error except: devCommands['P'] = 100 if Devices[Unit].DeviceID[-2:] == ':A': devCommands['A'] = 80 # 90 degrees = open elif Command == "Off": # open if Devices[Unit].DeviceID[-2:] == ':P': try: if idx in defaults: for com in defaults[idx]['o']: devCommands[com] = defaults[idx]['o'][com] else: Error except: devCommands['P'] = 0 if Devices[Unit].DeviceID[-2:] == ':A': devCommands['A'] = 0 elif Command == "Set Level": Domoticz.Debug("Command Level: {}".format(Level)) newLevel = int(Level) if newLevel not in range(0, 101): newLevel = 100 if newLevel > 100 else 0 if Devices[Unit].DeviceID[-2:] == ':P': devCommands['P'] = str(newLevel) if Devices[Unit].DeviceID[-2:] == ':A': newLevel = round((180 / 100) * newLevel) devCommands['A'] = str(newLevel) if devCommands: if 'P' in devCommands: self.brel_devices['devices'][devID]['data'][ 'currentPosition'] = devCommands['P'] if 'A' in devCommands: self.brel_devices['devices'][devID]['data'][ 'currentAngle'] = devCommands['A'] if devID == 'grp-0': for brel_device in self.brel_devices['devices']: if self.brel_devices['devices'][brel_device][ 'deviceType'] != 'group' and self.brel_devices[ 'devices'][brel_device][ 'deviceType'] != '02000001': # Gateway:: if 'P' in devCommands: self.brel_devices['devices'][brel_device][ 'data']['currentPosition'] = devCommands[ 'P'] if 'A' in devCommands: self.brel_devices['devices'][brel_device][ 'data']['currentAngle'] = devCommands['A'] brel_api = brel(Parameters['Address'], self.u_port, self.brel_devices) brel_command_ack = brel_api.send_command( brel_device, devCommands) self.overrideGrpCommands = self.overrideGrpCommands + 1 for com in devCommands: self.updateDevice(int( self.DeviceIDdict[brel_device + ':' + com]), None, Report=True) else: brel_api = brel(Parameters['Address'], self.u_port, self.brel_devices) brel_command_ack = brel_api.send_command( devID, devCommands) for com in devCommands: self.updateDevice(int(self.DeviceIDdict[devID + ':' + com]), None, Report=True) Domoticz.Debug("Finnished command") except KeyError: Domoticz.Error( "OnCommand failed for device: {} with command: {} and level: {}" .format(devID, Command, Level)) except: comObj = {"Unit": Unit, "Command": Command, "Level": Level} Domoticz.Debug( "Command timed out. Pushing {} onto commandQueue".format( comObj)) self.commandQueue.append(comObj)
def onMessage(self, Connection, Data): try: self.unpacker.feed(Data) for result in self.unpacker: Domoticz.Debug("Got: %s" % result) if 'exception' in result: return if result['cmd'] == 'status': UpdateDevice( self.statusUnit, (1 if result['state_code'] in [5, 6, 11] else 0), # ON is Cleaning, Back to home, Spot cleaning self.states.get(result['state_code'], 'Undefined')) UpdateDevice(self.batteryUnit, result['battery'], str(result['battery']), result['battery'], AlwaysUpdate=(self.heartBeatCnt % 100 == 0)) if Parameters['Mode5'] == 'dimmer': UpdateDevice( self.fanDimmerUnit, 2, str(result['fan_level']) ) # nValue=2 for show percentage, instead ON/OFF state else: level = { 38: 10, 60: 20, 77: 30, 90: 40 }.get(result['fan_level'], None) if level: UpdateDevice(self.fanSelectorUnit, 1, str(level)) elif result['cmd'] == 'consumable_status': mainBrush = cPercent(result['main_brush'], 300) sideBrush = cPercent(result['side_brush'], 200) filter = cPercent(result['filter'], 150) sensors = cPercent(result['sensor'], 30) UpdateDevice(self.cMainBrushUnit, mainBrush, str(mainBrush), AlwaysUpdate=True) UpdateDevice(self.cSideBrushUnit, sideBrush, str(sideBrush), AlwaysUpdate=True) UpdateDevice(self.cFilterUnit, filter, str(filter), AlwaysUpdate=True) UpdateDevice(self.cSensorsUnit, sensors, str(sensors), AlwaysUpdate=True) except msgpack.UnpackException as e: Domoticz.Error('Unpacker exception [%s]' % str(e))
def onHeartbeat(self): self.now = datetime.now() # fool proof checking.... based on users feedback if not all(device in Devices for device in (1, 2, 3, 4, 5, 6, 7)): Domoticz.Error( "one or more devices required by the plugin is/are missing, please check domoticz device creation settings and restart !" ) return if Devices[1].sValue == "0": # Thermostat is off if self.forced or self.heat: # thermostat setting was just changed so we kill the heating self.forced = False self.endheat = self.now Domoticz.Debug("Switching heat Off !") self.switchHeat(False) elif Devices[1].sValue == "20": # Thermostat is in forced mode if self.forced: if self.endheat <= self.now: self.forced = False self.endheat = self.now Domoticz.Debug("Forced mode Off !") Devices[1].Update( nValue=1, sValue="10") # set thermostat to normal mode self.switchHeat(False) else: self.forced = True self.endheat = self.now + timedelta( minutes=self.forcedduration) Domoticz.Debug("Forced mode On !") self.switchHeat(True) else: # Thermostat is in mode auto if self.forced: # thermostat setting was just changed from "forced" so we kill the forced mode self.forced = False self.endheat = self.now self.nextcalc = self.now # this will force a recalculation on next heartbeat Domoticz.Debug("Forced mode Off !") self.switchHeat(False) elif (self.endheat <= self.now or self.pause) and self.heat: # heat cycle is over self.endheat = self.now self.heat = False if self.Internals['LastPwr'] < 100: self.switchHeat(False) # if power was 100(i.e. a full cycle), then we let the next calculation (at next heartbeat) decide # to switch off in order to avoid potentially damaging quick off/on cycles to the heater(s) elif self.pause and not self.pauserequested: # we are in pause and the pause switch is now off if self.pauserequestchangedtime + timedelta( minutes=self.pauseoffdelay) <= self.now: self.WriteLog("Pause is now Off", "Status") self.pause = False elif not self.pause and self.pauserequested: # we are not in pause and the pause switch is now on if self.pauserequestchangedtime + timedelta( minutes=self.pauseondelay) <= self.now: self.WriteLog("Pause is now On", "Status") self.pause = True self.switchHeat(False) elif (self.nextcalc <= self.now) and not self.pause: # we start a new calculation self.nextcalc = self.now + timedelta( minutes=self.calculate_period) self.WriteLog( "Next calculation time will be : " + str(self.nextcalc), "Verbose") # make current setpoint used in calculation reflect the select mode (10= normal, 20 = economy) if Devices[2].sValue == "10": self.setpoint = float(Devices[4].sValue) else: self.setpoint = float(Devices[5].sValue) # call the Domoticz json API for a temperature devices update, to get the lastest temps... if self.readTemps(): # do the thermostat work self.AutoMode() else: # make sure we switch off heating if there was an error with reading the temp self.switchHeat(False) if self.nexttemps <= self.now: # call the Domoticz json API for a temperature devices update, to get the lastest temps (and avoid the # connection time out time after 10mins that floods domoticz logs in versions of domoticz since spring 2018) self.readTemps() # check if need to refresh setpoints so that they do not turn red in GUI if self.nextupdate <= self.now: self.nextupdate = self.now + timedelta( minutes=int(Settings["SensorTimeout"])) Devices[4].Update(nValue=0, sValue=Devices[4].sValue) Devices[5].Update(nValue=0, sValue=Devices[5].sValue)
def onDisconnect(self, Connection): Domoticz.Debug("MIIOServer disconnected")
def AutoMode(self): self.WriteLog( "Temperatures: Inside = {} / Outside = {}".format( self.intemp, self.outtemp), "Verbose") if self.intemp > self.setpoint + self.deltamax: self.WriteLog("Temperature exceeds setpoint", "Verbose") overshoot = True power = 0 else: overshoot = False if self.learn: self.AutoCallib() else: self.learn = True if self.outtemp is None: power = round( (self.setpoint - self.intemp) * self.Internals["ConstC"], 1) else: power = round( (self.setpoint - self.intemp) * self.Internals["ConstC"] + (self.setpoint - self.outtemp) * self.Internals["ConstT"], 1) if power < 0: power = 0 # lower limit elif power > 100: power = 100 # upper limit # apply minimum power as required if power < self.minheatpower and (Parameters["Mode4"] == "Forced" or not overshoot): self.WriteLog( "Calculated power is {}, applying minimum power of {}".format( power, self.minheatpower), "Verbose") power = self.minheatpower Devices[7].Update(nValue=Devices[7].nValue, sValue=str(power), TimedOut=False) heatduration = round(power * self.calculate_period / 100) self.WriteLog( "Calculation: Power = {} -> heat duration = {} minutes".format( power, heatduration), "Verbose") if power <= 0: self.switchHeat(False) Domoticz.Debug("No heating requested.") else: self.endheat = self.now + timedelta(minutes=heatduration) Domoticz.Debug("End Heat time = " + str(self.endheat)) self.switchHeat(True) if self.Internals["ALStatus"] < 2: self.Internals['LastPwr'] = power self.Internals['LastInT'] = self.intemp self.Internals['LastOutT'] = self.outtemp self.Internals['LastSetPoint'] = self.setpoint self.Internals['ALStatus'] = 1 self.saveUserVar( ) # update user variables with latest learning self.lastcalc = self.now
def MajDomoDevice(self, Devices, DeviceID, Ep, clusterID, value, Color_=''): Domoticz.Debug("MajDomoDevice - Device ID : " + str(DeviceID) + " - Device EP : " + str(Ep) + " - Type : " + str(clusterID) + " - Value : " + str(value) + " - Hue : " + str(Color_)) x = 0 Type = TypeFromCluster(clusterID) Domoticz.Debug("MajDomoDevice - Type = " + str(Type)) for x in Devices: if Devices[x].DeviceID == str(DeviceID): DOptions = Devices[x].Options Dtypename = DOptions['TypeName'] DOptions['Zigate'] = str(self.ListOfDevices[DeviceID]) SignalLevel = self.ListOfDevices[DeviceID]['RSSI'] Domoticz.Debug("MajDomoDevice - Dtypename = " + str(Dtypename)) if Dtypename == "PowerMeter" and clusterID == "000c": nValue = float(value) sValue = value Domoticz.Debug("MajDomoDevice PowerMeter : " + sValue) UpdateDevice_v2(Devices, x, nValue, str(sValue), DOptions, SignalLevel) if Dtypename == "Temp+Hum+Baro": #temp+hum+Baro xiaomi Bar_forecast = '0' # Set barometer forecast to 0 (No info) if Type == "Temp": CurrentnValue = Devices[x].nValue CurrentsValue = Devices[x].sValue Domoticz.Debug("MajDomoDevice temp CurrentsValue : " + CurrentsValue) SplitData = CurrentsValue.split(";") NewSvalue = '%s;%s;%s;%s;%s' % (str(value), SplitData[1], SplitData[2], SplitData[3], Bar_forecast) Domoticz.Debug("MajDomoDevice temp NewSvalue : " + NewSvalue) UpdateDevice_v2(Devices, x, 0, str(NewSvalue), DOptions, SignalLevel) if Type == "Humi": CurrentnValue = Devices[x].nValue CurrentsValue = Devices[x].sValue Domoticz.Debug("MajDomoDevice hum CurrentsValue : " + CurrentsValue) SplitData = CurrentsValue.split(";") NewSvalue = '%s;%s;%s;%s;%s' % (SplitData[0], str(value), SplitData[2], SplitData[3], Bar_forecast) Domoticz.Debug("MajDomoDevice hum NewSvalue : " + NewSvalue) UpdateDevice_v2(Devices, x, 0, str(NewSvalue), DOptions, SignalLevel) if Type == "Baro": # barometer CurrentnValue = Devices[x].nValue CurrentsValue = Devices[x].sValue Domoticz.Debug("MajDomoDevice baro CurrentsValue : " + CurrentsValue) SplitData = CurrentsValue.split(";") valueBaro = '%s;%s;%s;%s;%s' % (SplitData[0], SplitData[1], str(value), SplitData[3], Bar_forecast) UpdateDevice_v2(Devices, x, 0, str(valueBaro), DOptions, SignalLevel) if Dtypename == "Temp+Hum": #temp+hum xiaomi if Type == "Temp": CurrentnValue = Devices[x].nValue CurrentsValue = Devices[x].sValue Domoticz.Debug("MajDomoDevice temp CurrentsValue : " + CurrentsValue) SplitData = CurrentsValue.split(";") NewSvalue = '%s;%s;%s' % (str(value), SplitData[1], SplitData[2]) Domoticz.Debug("MajDomoDevice temp NewSvalue : " + NewSvalue) UpdateDevice_v2(Devices, x, 0, str(NewSvalue), DOptions, SignalLevel) if Type == "Humi": CurrentnValue = Devices[x].nValue CurrentsValue = Devices[x].sValue Domoticz.Debug("MajDomoDevice hum CurrentsValue : " + CurrentsValue) SplitData = CurrentsValue.split(";") NewSvalue = '%s;%s;%s' % (SplitData[0], str(value), SplitData[2]) Domoticz.Debug("MajDomoDevice hum NewSvalue : " + NewSvalue) UpdateDevice_v2(Devices, x, 0, str(NewSvalue), DOptions, SignalLevel) if Type == Dtypename == "Temp": # temperature UpdateDevice_v2(Devices, x, 0, str(value), DOptions, SignalLevel) if Type == Dtypename == "Humi": # humidite UpdateDevice_v2(Devices, x, int(value), "0", DOptions, SignalLevel) if Type == Dtypename == "Baro": # barometre CurrentnValue = Devices[x].nValue CurrentsValue = Devices[x].sValue Domoticz.Debug("MajDomoDevice baro CurrentsValue : " + CurrentsValue) SplitData = CurrentsValue.split(";") valueBaro = '%s;%s' % (value, SplitData[0]) UpdateDevice_v2(Devices, x, 0, str(valueBaro), DOptions, SignalLevel) # CLD CLD if Dtypename == "Plug" and Type == "Switch": if value == "01": UpdateDevice_v2(Devices, x, 1, "On", DOptions, SignalLevel) elif value == "00": UpdateDevice_v2(Devices, x, 0, "Off", DOptions, SignalLevel) if Type == "Door" and Dtypename == "Door": # Door / Window if value == "01": state = "Open" UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) elif value == "00": state = "Closed" UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) if Type == "Switch" and Dtypename == "Door": # porte / fenetre if value == "01": state = "Open" #Correction Thiklop : value n'est pas toujours un entier. Exécution de l'updatedevice dans le test UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) elif value == "00": state = "Closed" #Correction Thiklop : idem UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) #Fin de la correction if Type == Dtypename == "Switch": # switch simple if value == "01": state = "On" elif value == "00": state = "Off" UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) if value == "01": state = "Open" elif value == "00": state = "Closed" UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) if Type == "Switch" and Dtypename == "Button": # boutton simple if value == "01": state = "On" UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) else: return if Type == "Switch" and Dtypename == "Water": # detecteur d eau if value == "01": state = "On" elif value == "00": state = "Off" UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) if Type == "Switch" and Dtypename == "Smoke": # detecteur de fume if value == "01": state = "On" elif value == "00": state = "Off" UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) if Type == "Switch" and Dtypename == "MSwitch": # multi lvl switch if value == "00": state = "00" elif value == "01": state = "10" elif value == "02": state = "20" elif value == "03": state = "30" elif value == "04": state = "40" else: state = "0" UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) if Type == "Switch" and Dtypename == "DSwitch": # double switch avec EP different ====> a voir pour passer en deux switch simple ... a corriger/modifier if Ep == "01": if value == "01" or value == "00": state = "10" data = "01" elif Ep == "02": if value == "01" or value == "00": state = "20" data = "02" elif Ep == "03": if value == "01" or value == "00": state = "30" data = "03" UpdateDevice_v2(Devices, x, int(data), str(state), DOptions, SignalLevel) if Type == "Switch" and Dtypename == "DButton": # double bouttons avec EP different ====> a voir pour passer en deux bouttons simple ... idem DSwitch ??? if Ep == "01": if value == "01" or value == "00": state = "10" data = "01" elif Ep == "02": if value == "01" or value == "00": state = "20" data = "02" elif Ep == "03": if value == "01" or value == "00": state = "30" data = "03" UpdateDevice_v2(Devices, x, int(data), str(state), DOptions, SignalLevel) if Type == "XCube" and Dtypename == "Aqara" and Ep == "02": #Magic Cube Acara Domoticz.Debug( "MajDomoDevice - XCube update device with data = " + str(value)) UpdateDevice_v2(Devices, x, int(value), str(value), DOptions, SignalLevel) if Type == "XCube" and Dtypename == "Aqara" and Ep == "03": #Magic Cube Acara Rotation Domoticz.Debug( "MajDomoDevice - XCube update device with data = " + str(value)) UpdateDevice_v2(Devices, x, int(value), str(value), DOptions, SignalLevel) if Type == Dtypename == "XCube" and Ep == "02": # cube xiaomi if value == "0000": #shake state = "10" data = "01" UpdateDevice_v2(Devices, x, int(data), str(state), DOptions, SignalLevel) elif value == "0204" or value == "0200" or value == "0203" or value == "0201" or value == "0202" or value == "0205": #tap state = "50" data = "05" UpdateDevice_v2(Devices, x, int(data), str(state), DOptions, SignalLevel) elif value == "0103" or value == "0100" or value == "0104" or value == "0101" or value == "0102" or value == "0105": #Slide state = "20" data = "02" UpdateDevice_v2(Devices, x, int(data), str(state), DOptions, SignalLevel) elif value == "0003": #Free Fall state = "70" data = "07" UpdateDevice_v2(Devices, x, int(data), str(state), DOptions, SignalLevel) elif value >= "0004" and value <= "0059": #90° state = "30" data = "03" UpdateDevice_v2(Devices, x, int(data), str(state), DOptions, SignalLevel) elif value >= "0060": #180° state = "90" data = "09" UpdateDevice_v2(Devices, x, int(data), str(state), DOptions, SignalLevel) if Type == Dtypename == "Lux": UpdateDevice_v2(Devices, x, int(value), str(value), DOptions, SignalLevel) if Type == Dtypename == "Motion": #Correction Thiklop : value pas toujours un entier : #'onMessage' failed 'ValueError':'invalid literal for int() with base 10: '00031bd000''. # UpdateDevice dans le if if value == "01": state = "On" UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) elif value == "00": state = "Off" UpdateDevice_v2(Devices, x, int(value), str(state), DOptions, SignalLevel) #Fin de correction if Type == Dtypename == "LvlControl": try: sValue = round((int(value, 16) / 255) * 100) except: Domoticz.Error("MajDomoDevice - value is not an int = " + str(value)) else: Domoticz.Debug("MajDomoDevice LvlControl - DvID : " + str(DeviceID) + " - Device EP : " + str(Ep) + " - Value : " + str(sValue) + " sValue : " + str(Devices[x].sValue)) nValue = 2 if str(nValue) != str( Devices[x].nValue) or str(sValue) != str( Devices[x].sValue): Domoticz.Debug("MajDomoDevice update DevID : " + str(DeviceID) + " from " + str(Devices[x].nValue) + " to " + str(nValue)) UpdateDevice_v2(Devices, x, str(nValue), str(sValue), DOptions, SignalLevel) if Type == Dtypename == "ColorControl": try: sValue = round((int(value, 16) / 255) * 100) except: Domoticz.Error("MajDomoDevice - value is not an int = " + str(value)) else: Domoticz.Debug("MajDomoDevice ColorControl - DvID : " + str(DeviceID) + " - Device EP : " + str(Ep) + " - Value : " + str(sValue) + " sValue : " + str(Devices[x].sValue)) nValue = 2 if str(nValue) != str(Devices[x].nValue) or str(sValue) != str( Devices[x].sValue) or str(Color_) != str( Devices[x].Color): Domoticz.Debug("MajDomoDevice update DevID : " + str(DeviceID) + " from " + str(Devices[x].nValue) + " to " + str(nValue)) UpdateDevice_v2(Devices, x, str(nValue), str(sValue), DOptions, SignalLevel, Color_)
def readTemps(self): # set update flag for next temp update self.nexttemps = self.now + timedelta(minutes=5) # fetch all the devices from the API and scan for sensors noerror = True listintemps = [] listouttemps = [] devicesAPI = DomoticzAPI( "type=devices&filter=temp&used=true&order=Name") if devicesAPI: for idx in self.InTempSensors: for device in devicesAPI[ "result"]: # parse the devices for temperature sensors if idx == int(device["idx"]): if "Temp" in device: Domoticz.Debug("device: {}-{} = {}".format( device["idx"], device["Name"], device["Temp"])) # check temp sensor is not timed out if not self.SensorTimedOut(idx, device["Name"], device["LastUpdate"]): listintemps.append(device["Temp"]) else: Domoticz.Error( "device: {}-{} is not a Temperature sensor". format(device["idx"], device["Name"])) for idx in self.OutTempSensors: for device in devicesAPI[ "result"]: # parse the devices for temperature sensors if idx == int(device["idx"]): if "Temp" in device: Domoticz.Debug("device: {}-{} = {}".format( device["idx"], device["Name"], device["Temp"])) # check temp sensor is not timed out if not self.SensorTimedOut(idx, device["Name"], device["LastUpdate"]): listouttemps.append(device["Temp"]) else: Domoticz.Error( "device: {}-{} is not a Temperature sensor". format(device["idx"], device["Name"])) # calculate the average inside temperature nbtemps = len(listintemps) if nbtemps > 0: self.intemp = round(sum(listintemps) / nbtemps, 1) # update the dummy device showing the current thermostat temp Devices[6].Update(nValue=0, sValue=str(self.intemp), TimedOut=False) if self.intemperror: # there was previously an invalid inside temperature reading... reset to normal self.intemperror = False self.WriteLog( "Inside Temperature reading is now valid again: Resuming normal operation", "Status") # we remove the timedout flag on the thermostat switch Devices[1].Update(nValue=Devices[1].nValue, sValue=Devices[1].sValue, TimedOut=False) else: # no valid inside temperature noerror = False if not self.intemperror: self.intemperror = True Domoticz.Error( "No Inside Temperature found: Switching heating Off") self.switchHeat(False) # we mark both the thermostat switch and the thermostat temp devices as timedout Devices[1].Update(nValue=Devices[1].nValue, sValue=Devices[1].sValue, TimedOut=True) Devices[6].Update(nValue=Devices[6].nValue, sValue=Devices[6].sValue, TimedOut=True) # calculate the average outside temperature nbtemps = len(listouttemps) if nbtemps > 0: self.outtemp = round(sum(listouttemps) / nbtemps, 1) else: Domoticz.Debug("No Outside Temperature found...") self.outtemp = None Domoticz.Debug("Inside Temperature = {}".format(self.intemp)) Domoticz.Debug("Outside Temperature = {}".format(self.outtemp)) return noerror
def slideStop(self, id, level): Domoticz.Debug("slideStop called") sendData = {'Verb': 'POST', 'URL': '/api/slide/{}/stop'.format(id) } self.slideRequest(sendData)
def onStop(self): Domoticz.Debug("onStop called") return
def onNotification(self, Name, Subject, Text, Status, Priority, Sound, ImageFile): Domoticz.Debug("Notification: " + Name + "," + Subject + "," + Text + "," + Status + "," + str(Priority) + "," + Sound + "," + ImageFile)
def onConnect(self, Connection, Status, Description): Domoticz.Debug("onConnect called: Connection=" + str(Connection) + ", Status=" + str(Status) + ", Description=" + str(Description)) return
def LogMessage(Message): Domoticz.Debug(Message)
def onStop(self): Domoticz.Debug("onStop called") # prevent error messages during disabling plugin self.isStarted = False