class BasePlugin: mqttClient = None def onStart(self): self.debugging = Parameters["Mode6"] if self.debugging == "Verbose+": Domoticz.Debugging(2 + 4 + 8 + 16 + 64) if self.debugging == "Verbose": Domoticz.Debugging(2 + 4 + 8 + 16 + 64) if self.debugging == "Debug": Domoticz.Debugging(2 + 4 + 8) self.controller = EmsDevices() self.controller.checkDevices() self.topics = list([ "home/ems-esp/thermostat_data", "home/ems-esp/boiler_data", "home/ems-esp/STATE" ]) self.mqttserveraddress = Parameters["Address"].replace(" ", "") self.mqttserverport = Parameters["Port"].replace(" ", "") self.mqttClient = MqttClient(self.mqttserveraddress, self.mqttserverport, self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, self.onMQTTSubscribed) def checkDevices(self): Domoticz.Log("checkDevices called") def onStop(self): Domoticz.Log("onStop called") def onCommand(self, Unit, Command, Level, Color): Domoticz.Debug("Command: " + Command + " (" + str(Level)) self.controller.onCommand(self.mqttClient, Unit, Command, Level, Color) def onConnect(self, Connection, Status, Description): self.mqttClient.onConnect(Connection, Status, Description) def onDisconnect(self, Connection): self.mqttClient.onDisconnect(Connection) def onMessage(self, Connection, Data): self.mqttClient.onMessage(Connection, Data) def onHeartbeat(self): Domoticz.Debug("Heartbeating...") # Reconnect if connection has dropped if self.mqttClient.mqttConn is None or ( not self.mqttClient.mqttConn.Connecting() and not self.mqttClient.mqttConn.Connected() or not self.mqttClient.isConnected): Domoticz.Debug("Reconnecting") self.mqttClient.Open() else: self.mqttClient.Ping() def onMQTTConnected(self): Domoticz.Debug("onMQTTConnected") self.mqttClient.Subscribe(self.topics) def onMQTTDisconnected(self): Domoticz.Debug("onMQTTDisconnected") def onMQTTSubscribed(self): Domoticz.Debug("onMQTTSubscribed") def onMQTTPublish(self, topic, rawmessage): Domoticz.Debug("MQTT message: " + topic + " " + str(rawmessage)) message = "" try: message = json.loads(rawmessage.decode('utf8')) except ValueError: message = rawmessage.decode('utf8') if (topic in self.topics): self.controller.onMqttMessage(topic, message)
class BasePlugin: HEARTBEAT_SEC = 10 def __init__(self): self.mqttClient = None self.myroomba = None self.state = None self.batpct = None self.execute = None self.MqttUpdatereceived = False self.lastMqttUpdate = datetime.now() return def onStart(self): # Debugging On/Off self.debug = _DEBUG_ON if Parameters["Mode6"] == "Debug" else _DEBUG_OFF Domoticz.Debugging(self.debug) # Create images if necessary if _IMAGE_ROOMBA not in Images: Domoticz.Image("Roomba.zip").Create() # Create devices (USED BY DEFAULT) CreateDevicesUsed() TimeoutDevice(All=True) # Create devices (NOT USED BY DEFAULT) CreateDevicesNotUsed() # Global settings DumpConfigToLog() # Start MQTT try: self.mqttClient = MqttClient('localhost', '1883', self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, self.onMQTTSubscribed) except Exception as e: Domoticz.Error("MQTT client start error: " + str(e)) self.mqttClient = None def onStop(self): Domoticz.Debug("onStop called") def onCommand(self, Unit, Command, Level, Color): # react to commands arrived from Domoticz Domoticz.Debug("Command: " + Command + " (" + str(Level) + ") Color:" + Color) if Unit == _UNIT_RUNNING: if Command == 'On': if self.state == 'Charging': self.mqttClient.Publish(_COMMANDS, 'start') else: self.mqttClient.Publish(_COMMANDS, 'dock') else: self.mqttClient.Publish(_COMMANDS, 'stop') self.execute = _DOCK def onConnect(self, Connection, Status, Description): Domoticz.Debug("Connection: " + str(Status)) if self.mqttClient is not None: self.mqttClient.onConnect(Connection, Status, Description) def onDisconnect(self, Connection): if self.mqttClient is not None: self.mqttClient.onDisconnect(Connection) def onMessage(self, Connection, Data): if self.mqttClient is not None: self.mqttClient.onMessage(Connection, Data) def onHeartbeat(self): Domoticz.Debug("Heartbeating...") if self.mqttClient is not None: try: # Reconnect if connection has dropped if self.mqttClient.mqttConn is None or ( not self.mqttClient.mqttConn.Connecting() and not self.mqttClient.mqttConn.Connected() or not self.mqttClient.isConnected): Domoticz.Debug("Reconnecting") self.mqttClient.Open() else: self.mqttClient.Ping() # Commands to Roomba if self.execute == _DOCK: if self.state == 'Stopped': self.mqttClient.Publish(_COMMANDS, 'dock') if self.state == 'Charging': self.execute = None except Exception as e: Domoticz.Error("onHeartbeat: " + str(e)) # Update devices if self.MqttUpdatereceived: if self.state: UpdateDevice(_UNIT_STATE, 0, self.state, Images[_IMAGE_ROOMBA].ID) if self.state == 'Running': UpdateDevice(_UNIT_RUNNING, 1, 1, Images[_IMAGE_ROOMBA].ID) else: UpdateDevice(_UNIT_RUNNING, 0, 0, Images[_IMAGE_ROOMBA].ID) if self.batpct: UpdateDeviceBatSig(_UNIT_RUNNING, self.batpct) UpdateDevice(_UNIT_BAT, self.batpct, self.batpct, Images[_IMAGE_ROOMBA].ID) self.MqttUpdatereceived = False # Check if getting information from MQTT Broker if (datetime.now() - self.lastMqttUpdate).total_seconds() > int( Parameters["Mode5"]) * 60: TimeoutDevice(All=True) def onMQTTConnected(self): Domoticz.Debug("onMQTTConnected") if self.mqttClient is not None: self.mqttClient.Subscribe([_STATE, _BATPCT]) def onMQTTDisconnected(self): Domoticz.Debug("onMQTTDisconnected") def onMQTTSubscribed(self): Domoticz.Debug("onMQTTSubscribed") def onMQTTPublish(self, topic, message): # process incoming MQTT statuses message = message.decode('utf-8') Domoticz.Debug("MQTT message: " + topic + " " + message) if topic == _STATE: self.state = message self.lastMqttUpdate = datetime.now() self.MqttUpdatereceived = True if topic == _BATPCT: self.batpct = int(message) self.lastMqttUpdate = datetime.now() self.MqttUpdatereceived = True
class BasePlugin: mqttClient = None def onStart(self): self.debugging = Parameters["Mode6"] if self.debugging == "Verbose": Domoticz.Debugging(2 + 4 + 8 + 16 + 64) if self.debugging == "Debug": Domoticz.Debugging(2) Domoticz.Debug("onStart called") self.base_topic = Parameters["Mode1"].strip() self.pairing_enabled = True if Parameters["Mode2"] == 'true' else False self.subscribed_for_devices = False self.mqttserveraddress = Parameters["Address"].strip() self.mqttserverport = Parameters["Port"].strip() self.mqttClient = MqttClient(self.mqttserveraddress, self.mqttserverport, self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, self.onMQTTSubscribed) self.available_devices = DeviceStorage.getInstance() def checkDevices(self): Domoticz.Debug("checkDevices called") def onStop(self): Domoticz.Debug("onStop called") def handlePairingMode(self): if (self.pairing_enabled): self.mqttClient.Publish( self.base_topic + '/bridge/config/permit_join', 'true') Domoticz.Log("Joining new devices is enabled on the zigbee bridge") else: self.mqttClient.Publish( self.base_topic + '/bridge/config/permit_join', 'false') Domoticz.Log( "Joining new devices is disabled on the zigbee bridge") def onCommand(self, Unit, Command, Level, Color): Domoticz.Debug("onCommand: " + Command + ", level (" + str(Level) + ") Color:" + Color) device = Devices[ Unit] #Devices is Domoticz collection of devices for this hardware device_params = device.DeviceID.split('_') device_id = device_params[0] alias = device_params[1] device_data = self.available_devices.get_device_by_id(device_id) if (device_data == None): Domoticz.Log('Device ' + device.Name + ' does not have registered zigbee2mqtt device') return model = device_data['model'] if (model in adapter_by_model): adapter = adapter_by_model[model](Devices) message = adapter.handleCommand(alias, device, device_data, Command, Level, Color) if (message != None): self.mqttClient.Publish( self.base_topic + '/' + message['topic'], message['payload']) else: Domoticz.Log('Device ' + device.Name + ' does not have adapter (model: "' + model + '"') def onConnect(self, Connection, Status, Description): Domoticz.Debug("onConnect called") self.mqttClient.onConnect(Connection, Status, Description) def onDisconnect(self, Connection): self.mqttClient.onDisconnect(Connection) def onMessage(self, Connection, Data): self.mqttClient.onMessage(Connection, Data) def onHeartbeat(self): Domoticz.Debug("Heartbeating...") # Reconnect if connection has dropped if self.mqttClient.mqttConn is None or ( not self.mqttClient.mqttConn.Connecting() and not self.mqttClient.mqttConn.Connected() or not self.mqttClient.isConnected): Domoticz.Debug("Reconnecting") self.mqttClient.Open() else: self.mqttClient.Ping() def onMQTTConnected(self): self.mqttClient.Subscribe([self.base_topic + '/bridge/#']) def onMQTTDisconnected(self): Domoticz.Debug("onMQTTDisconnected") def onMQTTSubscribed(self): Domoticz.Debug("onMQTTSubscribed") def onMQTTPublish(self, topic, message): Domoticz.Debug("MQTT message: " + topic + " " + str(message)) if (topic == self.base_topic + '/bridge/state'): Domoticz.Log('Zigbee2mqtt bridge is ' + message) if message == 'online': self.mqttClient.Publish( self.base_topic + '/bridge/config/devices', '') self.handlePairingMode() return if (topic == self.base_topic + '/bridge/log'): if message['type'] == 'devices': Domoticz.Log('Received available devices list from bridge') self.available_devices.update(Devices, message['message']) if self.subscribed_for_devices == False: self.mqttClient.Subscribe([self.base_topic + '/+']) self.subscribed_for_devices = True return device_name = topic.replace(self.base_topic + "/", "") device_data = self.available_devices.get_device_by_name(device_name) if (device_data != None): model = device_data['model'] if (model in adapter_by_model): zigbee_message = ZigbeeMessage(message) adapter = adapter_by_model[model](Devices) adapter.handleMqttMessage(device_data, zigbee_message) else: Domoticz.Debug('Unsupported zigbee device type with model "' + model + '"') else: Domoticz.Debug('Unhandled message from zigbee2mqtt: ' + topic + ' ' + str(message))
class BasePlugin: mqttClient = None def onStart(self): self.debugging = Parameters["Mode6"] if self.debugging == "Verbose": Domoticz.Debugging(2 + 4 + 8 + 16 + 64) if self.debugging == "Debug": Domoticz.Debugging(2) self.base_topic = "shellies" # hardwired self.mqttserveraddress = Parameters["Address"].strip() self.mqttserverport = Parameters["Port"].strip() self.mqttClient = MqttClient(self.mqttserveraddress, self.mqttserverport, self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, self.onMQTTSubscribed) def checkDevices(self): Domoticz.Debug("checkDevices called") def onStop(self): Domoticz.Debug("onStop called") def onCommand(self, Unit, Command, Level, Color): # react to commands arrived from Domoticz Domoticz.Debug("Command: " + Command + " (" + str(Level) + ") Color:" + Color) device = Devices[Unit] device_id = device.DeviceID.split('-') relnum = -1 try: relnum = int(device_id[2].strip()) except: relnum = -1 if relnum in range( 0, 4) and len(device_id) == 3: # check if is it a normal relay mqttpath = self.base_topic + "/" + device_id[0] + "-" + device_id[ 1] + "/relay/" + device_id[2] + "/command" cmd = Command.strip().lower() Domoticz.Debug(mqttpath + " " + cmd) if cmd in ["on", "off"]: # commands are simply on or off self.mqttClient.Publish(mqttpath, cmd) if cmd == "off": device.Update( Level, Command) # force device update if it is offline # otherwise check if it is a roller shutter elif relnum in range( 0, 4) and len(device_id) == 4 and device_id[len(device_id) - 1] == "roller": cmd = Command.strip().lower() scmd = "" # Translate Domoticz command to Shelly command if cmd == "stop": scmd = "stop" elif cmd == "on": scmd = "open" elif cmd == "off": scmd = "close" if scmd != "": mqttpath = self.base_topic + "/" + device_id[ 0] + "-" + device_id[1] + "/roller/" + device_id[ 2] + "/command" self.mqttClient.Publish(mqttpath, scmd) # experimental support for v1.4 Percentage poisitioning elif relnum in range( 0, 4) and len(device_id) == 4 and device_id[len(device_id) - 1] == "pos": cmnd = str(Command).strip().lower() pos = str(Level).strip().lower() if ((cmnd == "set level") or (cmnd == "off" and pos != "50" and pos != "100")): # percentage requested mqttpath = self.base_topic + "/" + device_id[ 0] + "-" + device_id[1] + "/roller/" + device_id[ 2] + "/command/pos" Domoticz.Debug(mqttpath + " " + str(Command) + " " + str(Level)) self.mqttClient.Publish(mqttpath, pos) else: # command arrived scmd = "" # Translate Domoticz command to Shelly command if cmnd == "on": scmd = "open" elif cmnd == "off": scmd = "close" if scmd != "": mqttpath = self.base_topic + "/" + device_id[ 0] + "-" + device_id[1] + "/roller/" + device_id[ 2] + "/command" self.mqttClient.Publish(mqttpath, scmd) def onConnect(self, Connection, Status, Description): self.mqttClient.onConnect(Connection, Status, Description) def onDisconnect(self, Connection): self.mqttClient.onDisconnect(Connection) def onMessage(self, Connection, Data): self.mqttClient.onMessage(Connection, Data) def onHeartbeat(self): Domoticz.Debug("Heartbeating...") # Reconnect if connection has dropped if self.mqttClient.mqttConn is None or ( not self.mqttClient.mqttConn.Connecting() and not self.mqttClient.mqttConn.Connected() or not self.mqttClient.isConnected): Domoticz.Debug("Reconnecting") self.mqttClient.Open() else: self.mqttClient.Ping() def onMQTTConnected(self): self.mqttClient.Subscribe([self.base_topic + '/#']) def onMQTTDisconnected(self): Domoticz.Debug("onMQTTDisconnected") def onMQTTSubscribed(self): Domoticz.Debug("onMQTTSubscribed") def onMQTTPublish(self, topic, message): # process incoming MQTT statuses if "/announce" in topic: # announce did not contain any information for us return False try: topic = str(topic) message = str(message) except: Domoticz.Debug("MQTT message is not a valid string!" ) #if message is not a real string, drop it return False Domoticz.Debug("MQTT message: " + topic + " " + str(message)) mqttpath = topic.split('/') if (mqttpath[0] == self.base_topic): # RELAY type, not command->process if (len(mqttpath) > 3) and (mqttpath[2] == "relay") and ("/command" not in topic): unitname = mqttpath[1] + "-" + mqttpath[3] unitname = unitname.strip() devtype = 1 try: funcid = int(mqttpath[3].strip()) devtype = 0 except: devtype = 1 if len(mqttpath) == 5 and devtype == 0: devtype = 2 subval = "" if devtype == 1: subval = mqttpath[3].strip() elif devtype == 2: subval = mqttpath[4].strip() if subval == "power" or subval == "energy": unitname = mqttpath[1] + "-energy" iUnit = -1 for Device in Devices: try: if (Devices[Device].DeviceID.strip() == unitname): iUnit = Device break except: pass if iUnit < 0: # if device does not exists in Domoticz, than create it iUnit = 0 for x in range(1, 256): if x not in Devices: iUnit = x break if iUnit == 0: iUnit = len(Devices) + 1 if devtype == 0: Domoticz.Device(Name=unitname, Unit=iUnit, TypeName="Switch", Used=1, DeviceID=unitname).Create() else: if subval == "energy" or subval == "power": Domoticz.Device(Name=unitname, Unit=iUnit, Type=243, Subtype=29, Used=1, DeviceID=unitname).Create() if devtype == 0: scmd = str(message).strip().lower() if (str(Devices[iUnit].sValue).lower() != scmd): if (scmd == "on"): # set device status if needed Devices[iUnit].Update(1, "On") else: Devices[iUnit].Update(0, "Off") else: curval = Devices[iUnit].sValue try: prevdata = curval.split(";") except: prevdata = [] if len(prevdata) < 2: prevdata.append(0) prevdata.append(0) try: mval = float(str(message).strip()) except: mval = str(message).strip() sval = "" if subval == "power": sval = str(mval) + ";" + str(prevdata[1]) elif subval == "energy": try: mval2 = (mval / 100) # 10*Wh? except: mval2 = str(mval) sval = str(prevdata[0]) + ";" + str(mval2) Devices[iUnit].Update(0, sval) return True # ROLLER type, not command->process elif (len(mqttpath) > 3) and (mqttpath[2] == "roller") and ("/command" not in topic): if mqttpath[len(mqttpath) - 1] == "pos": unitname = mqttpath[1] + "-" + mqttpath[3] + "-pos" else: unitname = mqttpath[1] + "-" + mqttpath[3] + "-roller" unitname = unitname.strip() iUnit = -1 for Device in Devices: try: if (Devices[Device].DeviceID.strip() == unitname): iUnit = Device break except: pass if iUnit < 0: # if device does not exists in Domoticz, than create it iUnit = 0 for x in range(1, 256): if x not in Devices: iUnit = x break if iUnit == 0: iUnit = len(Devices) + 1 if "-pos" in unitname: Domoticz.Device(Name=unitname, Unit=iUnit, Type=244, Subtype=62, Switchtype=13, Used=1, DeviceID=unitname).Create( ) # create Blinds Percentage else: Domoticz.Device(Name=unitname, Unit=iUnit, Type=244, Subtype=62, Switchtype=15, Used=1, DeviceID=unitname).Create( ) # create Venetian Blinds EU type if "-pos" in unitname: try: pval = str(message).strip() nval = 0 if int(pval) > 0 and int(pval) < 100: nval = 2 if int(pval) > 99: nval = 1 Devices[iUnit].Update(nval, pval) except: Domoticz.Debug("MQTT message error " + str(topic) + ":" + str(message)) else: bcmd = str(message).strip().lower() if bcmd == "stop" and str( Devices[iUnit].sValue).lower() != "stop": Devices[iUnit].Update(17, "Stop") # stop return True elif bcmd == "open" and str( Devices[iUnit].sValue).lower() != "off": Devices[iUnit].Update(0, "Off") # open return True elif bcmd == "close" and str( Devices[iUnit].sValue).lower() != "on": Devices[iUnit].Update(1, "On") # close return True # INPUT type, not command->process elif (len(mqttpath) > 3) and (mqttpath[2] == "input") and ( mqttpath[len(mqttpath) - 1] != "command"): unitname = mqttpath[1] + "-" + mqttpath[3] + "-input" unitname = unitname.strip() iUnit = -1 for Device in Devices: try: if (Devices[Device].DeviceID.strip() == unitname): iUnit = Device break except: pass if iUnit < 0: # if device does not exists in Domoticz, than create it iUnit = 0 for x in range(1, 256): if x not in Devices: iUnit = x break if iUnit == 0: iUnit = len(Devices) + 1 Domoticz.Device(Name=unitname, Unit=iUnit, TypeName="Switch", Used=1, DeviceID=unitname).Create() if str(message).lower == "on" or str(message) == "1": scmd = "on" else: scmd = "off" if (str(Devices[iUnit].sValue).lower() != scmd): if (scmd == "on"): # set device status if needed Devices[iUnit].Update(1, "On") else: Devices[iUnit].Update(0, "Off") # SENSOR type, not command->process elif (len(mqttpath) > 3) and (mqttpath[2] == "sensor") and ( mqttpath[3] in ['temperature', 'humidity', 'battery' ]) and (("shellysense" in mqttpath[1]) or ("shellyht" in mqttpath[1])): unitname = mqttpath[1] + "-sensor" unitname = unitname.strip() iUnit = -1 for Device in Devices: try: if (Devices[Device].DeviceID.strip() == unitname): iUnit = Device break except: pass if iUnit < 0: # if device does not exists in Domoticz, than create it iUnit = 0 for x in range(1, 256): if x not in Devices: iUnit = x break if iUnit == 0: iUnit = len(Devices) + 1 Domoticz.Device( Name=unitname, Unit=iUnit, TypeName="Temp+Hum", Used=1, DeviceID=unitname).Create() # create Temp+Hum Type=82 stype = mqttpath[3].strip().lower() curval = Devices[iUnit].sValue try: mval = float(message) except: mval = str(message).strip() if stype == "battery": Devices[iUnit].Update(0, curval, BatteryLevel=int(mval)) elif stype == "temperature": try: env = curval.split(";") except: env = [0, 0] if len(env) < 3: env.append(0) env.append(0) env.append(0) sval = str(mval) + ";" + str(env[1]) + ";" + str(env[2]) Devices[iUnit].Update(0, sval) elif stype == "humidity": hstat = 0 try: env = curval.split(";") except: env = [0, 0] if len(env) < 1: env.append(0) if int(mval) >= 50 and int(mval) <= 70: hstat = 1 elif int(mval) < 40: hstat = 2 elif int(mval) > 70: hstat = 3 sval = str(env[0]) + ";" + str(mval) + ";" + str(hstat) Devices[iUnit].Update(0, sval)
class BasePlugin: mqttClient = None domoticzDevicesByName = None domoticzDevicesById = None linkedDevices = None def onStart(self): self.debugging = Parameters["Mode6"] if self.debugging == "Verbose": Domoticz.Debugging(2 + 4 + 8 + 16 + 64) if self.debugging == "Debug": Domoticz.Debugging(2) Domoticz.Debug("onStart called") self.base_topic = Parameters["Mode1"].strip() self.domoticz_port = int(Parameters["Port"].strip()) self.delete_removed_devices = Parameters["Mode5"].strip() if Parameters["Address"].find('mqtt.gbridge.io') >= 0: self.domoticz_mqtt_used = False else: self.domoticz_mqtt_used = True self.mqttClient = MqttClient(Parameters["Address"].strip().split(":")[0], Parameters["Address"].strip().split(":")[1], self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, self.onMQTTSubscribed) self.gBridgeClient = gBridgeClient(Parameters["Mode2"].strip(), Parameters["Mode3"].strip(), Parameters["Mode4"].strip()) self.domoticz_client = DomoticzClient(self.domoticz_port) self.syncDevices() Domoticz.Debug("Done") def syncDevices(self): Domoticz.Debug('Starting sync') bridge_devices = self.gBridgeClient.fetchDevicesFromBridge() domoticz_devices = self.domoticz_client.fetchDevicesFromDomoticz() self.linkedDevices = self.domoticz_client.getLinkedDevices(domoticz_devices) Domoticz.Debug('Linked devices: ' + str(self.linkedDevices)) self.domoticzDevicesByName = self.domoticz_client.getDevicesByName(domoticz_devices) self.domoticzDevicesById = {x['idx']: x for x in list(self.domoticzDevicesByName.values())} Domoticz.Debug('Domoticz devices available for gBridge: ' + str(self.domoticzDevicesByName.keys())) self.gBridgeClient.syncDevices(self.domoticzDevicesByName, bridge_devices, self.delete_removed_devices == 'True') def onStop(self): Domoticz.Debug("onStop called") def onCommand(self, Unit, Command, Level, Color): Domoticz.Debug("onCommand: " + Command + ", level (" + str(Level) + ") Color:" + Color) def onConnect(self, Connection, Status, Description): Domoticz.Debug("onConnect called") self.mqttClient.onConnect(Connection, Status, Description) def onDisconnect(self, Connection): self.mqttClient.onDisconnect(Connection) def onMessage(self, Connection, Data): Domoticz.Debug('Incoming message!' + str(Data)) self.mqttClient.onMessage(Connection, Data) def onHeartbeat(self): Domoticz.Debug("Heartbeating...") # Reconnect if connection has dropped if self.mqttClient.mqttConn is None or ( not self.mqttClient.mqttConn.Connecting() and not self.mqttClient.mqttConn.Connected() or not self.mqttClient.isConnected): Domoticz.Debug("Reconnecting") self.mqttClient.Open() else: self.mqttClient.Ping() def onMQTTConnected(self): self.mqttClient.Subscribe([self.base_topic + '/#']) if self.domoticz_mqtt_used: self.mqttClient.Subscribe(['domoticz/out']) def onMQTTDisconnected(self): Domoticz.Debug("onMQTTDisconnected") def onMQTTSubscribed(self): Domoticz.Debug("onMQTTSubscribed") def onMQTTPublish(self, topic, message): Domoticz.Debug("MQTT message: " + topic + " " + str(message)) if str(topic) == 'domoticz/out': if message.get('idx') is not None: domoticz_id = str(message['idx']) if message.get('Type') is not None and (message['Type'] == 'Scene' or message['Type'] == 'Group'): domoticz_id = 'group_' + domoticz_id else: return device = None if domoticz_id in self.domoticzDevicesById: device = self.domoticzDevicesById[domoticz_id] elif domoticz_id in self.linkedDevices and self.linkedDevices[domoticz_id] in self.domoticzDevicesById: # Get the device to which this device message is linked to, for example, device id 13 -> update device 12 device = self.domoticzDevicesById[self.linkedDevices[domoticz_id]] if device is not None: adapter = getAdapter(device) if adapter is not None: adapter.publishStateFromDomoticzTopic(self.mqttClient, device, self.base_topic, message) else: Domoticz.Error('No adapter registered to publish state for device: %s' % str(device)) else: if message == 'SYNC': self.syncDevices() elif topic.endswith('/set'): Domoticz.Debug('Published new state for device, topic: %s, state: %s' % (topic, message)) else: match = re.search(self.base_topic + '/(.*)/(.*)', topic) if match: device_id = match.group(1) # Backwards compatibility, previously the device name was used as topic name if device_id in self.domoticzDevicesByName: device = self.domoticzDevicesByName[device_id] elif device_id in self.domoticzDevicesById: device = self.domoticzDevicesById[device_id] else: Domoticz.Log('Received message for device which is not in Domoticz: %s, skipping' % device_id) return action = match.group(2) adapter = getAdapter(device) if adapter is not None: adapter.handleMqttMessage(device, str(message), action, self.domoticz_port) if not self.domoticz_mqtt_used: adapter.publishState(self.mqttClient, device, self.base_topic, message) # answer directly else: Domoticz.Error('No adapter registered for action: %s for device: %s' % (action, str(device)))