Example #1
0
    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.devices_manager = DevicesManager()
        self.devices_manager.set_devices(Devices)
        device_topic = Parameters["Mode1"].strip()

        if (Parameters["Mode2"] == "Dimmer"):
            self.controller = Dimmer(self.devices_manager, device_topic)
        elif (Parameters["Mode2"] == "PwmDimmer"):
            self.controller = PwmDimmer(self.devices_manager, device_topic)
        elif (Parameters["Mode2"] == "RGB"):
            self.controller = ColorDimmer(self.devices_manager, device_topic, 3)
        elif (Parameters["Mode2"] == "RGBW"):
            self.controller = ColorDimmer(self.devices_manager, device_topic, 4)
        elif (Parameters["Mode2"] == "RGBWW"):
            self.controller = ColorDimmer(self.devices_manager, device_topic, 5)

        self.controller.checkDevices()

        self.topics = list(["stat/" + device_topic + "/RESULT", "tele/" + device_topic + "/STATE"])
        
        mqtt_server_address = Parameters["Address"].strip()
        mqtt_server_port = Parameters["Port"].strip()
        mqtt_client_id = Parameters["Mode3"].strip()
        self.mqttClient = MqttClient(mqtt_server_address, mqtt_server_port, mqtt_client_id, self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, self.onMQTTSubscribed)
    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.install()
        self.base_topic = Parameters["Mode1"].strip()

        mqtt_server_address = Parameters["Address"].strip()
        mqtt_server_port = Parameters["Port"].strip()
        mqtt_client_id = Parameters["Mode3"].strip()
        self.mqttClient = MqttClient(mqtt_server_address, mqtt_server_port, mqtt_client_id, self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, self.onMQTTSubscribed)

        self.api = API(Devices, self.onApiCommand)
        self.devices_manager = DevicesManager()
        self.groups_manager = GroupsManager()
    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

        mqtt_server_address = Parameters["Address"].strip()
        mqtt_server_port = Parameters["Port"].strip()
        mqtt_client_id = Parameters["Mode3"].strip()
        self.mqttClient = MqttClient(mqtt_server_address, mqtt_server_port,
                                     mqtt_client_id, self.onMQTTConnected,
                                     self.onMQTTDisconnected,
                                     self.onMQTTPublish, self.onMQTTSubscribed)

        self.devices_manager = DevicesManager()
        self.groups_manager = GroupsManager()
    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.install()
        self.base_topic = "zigbee2mqtt"
        self.subscribed_for_devices = False

        mqtt_server_address = "127.0.0.1"
        mqtt_server_port = "1883"
        mqtt_client_id = ""
        self.mqttClient = MqttClient(mqtt_server_address, mqtt_server_port,
                                     mqtt_client_id, self.onMQTTConnected,
                                     self.onMQTTDisconnected,
                                     self.onMQTTPublish, self.onMQTTSubscribed)

        self.api = API(Devices, self.onApiCommand)
        self.devices_manager = DevicesManager()
        self.groups_manager = GroupsManager()
Example #5
0
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.install()
        self.base_topic = Parameters["Mode1"].strip()
        self.subscribed_for_devices = False

        mqtt_server_address = Parameters["Address"].strip()
        mqtt_server_port = Parameters["Port"].strip()
        mqtt_client_id = Parameters["Mode3"].strip()
        self.mqttClient = MqttClient(mqtt_server_address, mqtt_server_port,
                                     mqtt_client_id, self.onMQTTConnected,
                                     self.onMQTTDisconnected,
                                     self.onMQTTPublish, self.onMQTTSubscribed)

        self.api = API(Devices, self.publishToMqtt)
        self.devices_manager = DevicesManager()
        self.groups_manager = GroupsManager()

    def checkDevices(self):
        Domoticz.Debug("checkDevices called")

    def onStop(self):
        Domoticz.Debug("onStop called")
        self.uninstall()

    def onCommand(self, Unit, Command, Level, Color):
        Domoticz.Debug("onCommand: " + Command + ", level (" + str(Level) +
                       ") Color:" + Color)

        message = None
        device = Devices[
            Unit]  #Devices is Domoticz collection of devices for this hardware
        device_params = device.DeviceID.split('_')
        entity_id = device_params[0]

        if (self.devices_manager.get_device_by_id(entity_id) != None):
            message = self.devices_manager.handle_command(
                Devices, device, Command, Level, Color)
        elif (self.groups_manager.get_group_by_deviceid(device.DeviceID) !=
              None):
            message = self.groups_manager.handle_command(
                device, Command, Level, Color)
        else:
            Domoticz.Log('Can\'t process command from device "' + device.Name +
                         '"')

        if (message != None):
            self.publishToMqtt(message['topic'], message['payload'])

    def publishToMqtt(self, topic, payload):
        self.mqttClient.publish(self.base_topic + '/' + topic, payload)

    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 onDeviceModified(self, unit):
        if (unit == 255):
            self.api.handle_request(Devices[unit].sValue)
            return

    def onMessage(self, Connection, Data):
        self.mqttClient.onMessage(Connection, Data)

    def onHeartbeat(self):
        self.mqttClient.onHeartbeat()

    def onMQTTConnected(self):
        self.mqttClient.subscribe([self.base_topic + '/bridge/#'])

    def onMQTTDisconnected(self):
        self.subscribed_for_devices = False

    def onMQTTSubscribed(self):
        Domoticz.Debug("onMQTTSubscribed")

    def onMQTTPublish(self, topic, message):
        Domoticz.Debug("MQTT message: " + topic + " " + str(message))
        topic = topic.replace(self.base_topic + '/', '')

        self.api.handle_mqtt_message(topic, message)

        if (topic == 'bridge/config/permit_join'
                or topic == 'bridge/config/devices'):
            return

        if (topic == 'bridge/config'):
            permit_join = 'enabled' if message['permit_join'] else 'disabled'
            Domoticz.Debug('Zigbee2mqtt log level is ' + message['log_level'])
            Domoticz.Log('Joining new devices is ' + permit_join +
                         ' on the zigbee bridge')
            return

        if (topic == 'bridge/state'):
            Domoticz.Log('Zigbee2mqtt bridge is ' + message)

            if message == 'online':
                self.publishToMqtt('bridge/config/devices', '')
                self.publishToMqtt('bridge/config/groups', '')

            return

        if (topic == 'bridge/log'):
            if message['type'] == 'devices':
                Domoticz.Log('Received available devices list from bridge')

                self.devices_manager.clear()
                self.devices_manager.update(Devices, message['message'])

                if self.subscribed_for_devices == False:
                    self.mqttClient.subscribe([self.base_topic + '/+'])
                    self.subscribed_for_devices = True

            if message['type'] == 'groups':
                Domoticz.Log('Received groups list from bridge')
                self.groups_manager.register_groups(Devices,
                                                    message['message'])

            if message['type'] == 'device_connected' or message[
                    'type'] == 'device_removed':
                self.publishToMqtt('bridge/config/devices', '')

            if message['type'] == 'ota_update':
                Domoticz.Log(message['message'])

            return

        if (self.devices_manager.get_device_by_name(topic) != None):
            self.devices_manager.handle_mqtt_message(Devices, topic, message)
        elif (self.groups_manager.get_group_by_name(topic) != None):
            self.groups_manager.handle_mqtt_message(topic, message)

    def install(self):
        Domoticz.Log('Installing plugin custom page...')

        try:
            source_path = os.path.dirname(
                os.path.abspath(__file__)) + '/frontend'
            templates_path = os.path.abspath(source_path +
                                             '/../../../www/templates')
            dst_plugin_path = templates_path + '/zigbee2mqtt'

            Domoticz.Debug('Copying files from ' + source_path + ' to ' +
                           templates_path)

            if not (os.path.isdir(dst_plugin_path)):
                os.makedirs(dst_plugin_path)

            copy2(source_path + '/zigbee2mqtt.html', templates_path)
            copy2(source_path + '/zigbee2mqtt.js', templates_path)
            copy2(source_path + '/zigbee_devices.js', dst_plugin_path)
            copy2(source_path + '/zigbee_groups.js', dst_plugin_path)
            copy2(source_path + '/libs/leaflet.js', dst_plugin_path)
            copy2(source_path + '/libs/leaflet.css', dst_plugin_path)
            copy2(source_path + '/libs/viz.js', dst_plugin_path)
            copy2(source_path + '/libs/viz.full.render.js', dst_plugin_path)

            Domoticz.Log('Installing plugin custom page completed.')
        except Exception as e:
            Domoticz.Error('Error during installing plugin custom page')
            Domoticz.Error(repr(e))

    def uninstall(self):
        Domoticz.Log('Uninstalling plugin custom page...')

        try:
            templates_path = os.path.abspath(
                os.path.dirname(os.path.abspath(__file__)) +
                '/../../www/templates')
            dst_plugin_path = templates_path + '/zigbee2mqtt'

            Domoticz.Debug('Removing files from ' + templates_path)

            if (os.path.isdir(dst_plugin_path)):
                rmtree(dst_plugin_path)

            if os.path.exists(templates_path + "/zigbee2mqtt.html"):
                os.remove(templates_path + "/zigbee2mqtt.html")

            if os.path.exists(templates_path + "/zigbee2mqtt.js"):
                os.remove(templates_path + "/zigbee2mqtt.js")

            Domoticz.Log('Uninstalling plugin custom page completed.')
        except Exception as e:
            Domoticz.Error('Error during uninstalling plugin custom page')
            Domoticz.Error(repr(e))
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.install()
        self.base_topic = Parameters["Mode1"].strip()

        mqtt_server_address = Parameters["Address"].strip()
        mqtt_server_port = Parameters["Port"].strip()
        mqtt_client_id = Parameters["Mode3"].strip()
        self.mqttClient = MqttClient(mqtt_server_address, mqtt_server_port, mqtt_client_id, self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, self.onMQTTSubscribed)

        self.api = API(Devices, self.onApiCommand)
        self.devices_manager = DevicesManager()
        self.groups_manager = GroupsManager()

    def checkDevices(self):
        Domoticz.Debug("checkDevices called")

    def onStop(self):
        Domoticz.Debug("onStop called")
        self.uninstall()


    def onCommand(self, Unit, Command, Level, Color):
        Domoticz.Debug("onCommand: " + Command + ", level (" + str(Level) + ") Color:" + Color)

        message = None
        device = Devices[Unit] #Devices is Domoticz collection of devices for this hardware
        device_params = device.DeviceID.split('_')
        entity_id = device_params[0]

        if (self.devices_manager.get_device_by_id(entity_id) != None):
            message = self.devices_manager.handle_command(device, Command, Level, Color)
        elif(self.groups_manager.get_group_by_deviceid(device.DeviceID) != None):
            message = self.groups_manager.handle_command(device, Command, Level, Color)
        else:
            Domoticz.Log('Can\'t process command from device "' + device.Name + '"')

        if (message != None):
            self.publishToMqtt(message['topic'], message['payload'])

    def onApiCommand(self, command, data):
        if command == 'publish_mqtt':
            return self.publishToMqtt(data['topic'], data['payload'])
        elif command == 'remove_device':
            return self.devices_manager.remove(data)
        else:
            Domoticz.Error('Internal API command "' + command +'" is not supported by plugin')

    def publishToMqtt(self, topic, payload):
        self.mqttClient.publish(self.base_topic + '/' + topic, payload)

    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 onDeviceModified(self, unit):
        if (unit == 255):
            self.api.handle_request(Devices[unit].sValue)
            return

    def onMessage(self, Connection, Data):
        self.mqttClient.onMessage(Connection, Data)

    def onHeartbeat(self):
        self.mqttClient.onHeartbeat()

    def onMQTTConnected(self):
        self.mqttClient.subscribe([self.base_topic + '/#'])

    def onMQTTDisconnected(self):
        Domoticz.Debug('Disconnected from MQTT server')

    def onMQTTSubscribed(self):
        Domoticz.Debug('Subscribed to "' + self.base_topic + '/#" topic')

    def onMQTTPublish(self, topic, message):
        # Domoticz.Debug("MQTT message: " + topic + " " + str(message))
        topic = topic.replace(self.base_topic + '/', '')

        self.api.handle_mqtt_message(topic, message)

        if (topic == 'bridge/config/permit_join'):
            return

        if (topic == 'bridge/config/logging'):
            # TODO: Add log feature
            return

        if (topic == 'bridge/devices'):
            Domoticz.Log('Received available devices list from bridge')
            self.devices_manager.set_devices(message)
            return

        if (topic == 'bridge/config'):
            permit_join = 'enabled' if message['permit_join'] else 'disabled'
            Domoticz.Debug('Zigbee2mqtt log level is ' + message['log_level'])
            Domoticz.Log('Joining new devices is ' + permit_join + ' on the zigbee bridge')
            return

        if (topic == 'bridge/state'):
            Domoticz.Log('Zigbee2mqtt bridge is ' + message)

            if message == 'online':
                # self.publishToMqtt('bridge/config/devices', '')
                self.publishToMqtt('bridge/config/groups', '')

            return

        if (topic == 'bridge/log'):
            is_connected = message['type'] == 'device_connected'
            is_removed = message['type'] == 'device_removed'
            is_paired = message['type'] == 'pairing' and message['message'] == 'interview_successful'

            if message['type'] == 'groups':
                Domoticz.Log('Received groups list from bridge')
                self.groups_manager.register_groups(message['message'])

            if is_connected or is_removed or is_paired:
                self.publishToMqtt('bridge/config/devices/get', '')

            if message['type'] == 'ota_update':
                Domoticz.Log(message['message'])

            if message['type'] == 'zigbee_publish_error':
                #an error occured on publish to the zigbee network
                deviceMeta = message['meta']
                Domoticz.Error("A Zigbee publish error occured for device '" + deviceMeta['friendly_name'] + "' with error message: " + message['message'])

            return

        if (self.devices_manager.get_device_by_name(topic) != None):
            self.devices_manager.handle_mqtt_message(topic, message)
        elif (self.groups_manager.get_group_by_name(topic) != None):
            self.groups_manager.handle_mqtt_message(topic, message)

    def install(self):
        Domoticz.Log('Installing plugin custom page...')

        try:
            source_path = Parameters['HomeFolder'] + 'frontend'
            templates_path = Parameters['StartupFolder'] + 'www/templates'
            dst_plugin_path = templates_path + '/zigbee2mqtt'

            Domoticz.Debug('Copying files from ' + source_path + ' to ' + templates_path)

            if not (os.path.isdir(dst_plugin_path)):
                os.makedirs(dst_plugin_path)

            copy2(source_path + '/zigbee2mqtt.html', templates_path)
            copy2(source_path + '/zigbee2mqtt.js', templates_path)
            copy2(source_path + '/zigbee_devices.js', dst_plugin_path)
            copy2(source_path + '/zigbee_groups.js', dst_plugin_path)
            copy2(source_path + '/libs/leaflet.js', dst_plugin_path)
            copy2(source_path + '/libs/leaflet.css', dst_plugin_path)
            copy2(source_path + '/libs/viz.js', dst_plugin_path)
            copy2(source_path + '/libs/viz.full.render.js', dst_plugin_path)
            
            Domoticz.Log('Installing plugin custom page completed.')
        except Exception as e:
            Domoticz.Error('Error during installing plugin custom page')
            Domoticz.Error(repr(e))

    def uninstall(self):
        Domoticz.Log('Uninstalling plugin custom page...')

        try:
            templates_path = Parameters['StartupFolder'] + 'www/templates'
            dst_plugin_path = templates_path + '/zigbee2mqtt'

            Domoticz.Debug('Removing files from ' + templates_path)

            if (os.path.isdir(dst_plugin_path)):
                rmtree(dst_plugin_path)

            if os.path.exists(templates_path + "/zigbee2mqtt.html"):
                os.remove(templates_path + "/zigbee2mqtt.html")

            if os.path.exists(templates_path + "/zigbee2mqtt.js"):
                os.remove(templates_path + "/zigbee2mqtt.js")

            Domoticz.Log('Uninstalling plugin custom page completed.')
        except Exception as e:
            Domoticz.Error('Error during uninstalling plugin custom page')
            Domoticz.Error(repr(e))
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

        mqtt_server_address = Parameters["Address"].strip()
        mqtt_server_port = Parameters["Port"].strip()
        mqtt_client_id = Parameters["Mode3"].strip()
        self.mqttClient = MqttClient(mqtt_server_address, mqtt_server_port,
                                     mqtt_client_id, self.onMQTTConnected,
                                     self.onMQTTDisconnected,
                                     self.onMQTTPublish, self.onMQTTSubscribed)

        self.devices_manager = DevicesManager()
        self.groups_manager = GroupsManager()

    def checkDevices(self):
        Domoticz.Debug("checkDevices called")

    def onStop(self):
        Domoticz.Debug("onStop called")

    def handlePairingMode(self):
        permit_join = 'true' if self.pairing_enabled else 'false'
        self.mqttClient.publish(self.base_topic + '/bridge/config/permit_join',
                                permit_join)

    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('_')
        entity_id = device_params[0]

        if (self.devices_manager.get_device_by_id(entity_id) != None):
            message = self.devices_manager.handle_command(
                Devices, device, Command, Level, Color)
        elif (self.groups_manager.get_group_by_deviceid(device.DeviceID) !=
              None):
            message = self.groups_manager.handle_command(
                device, Command, Level, Color)
        else:
            Domoticz.Log('Can\'t process command from device "' + device.Name +
                         '"')

        if (message != None):
            self.mqttClient.publish(self.base_topic + '/' + message['topic'],
                                    message['payload'])

    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):
        self.mqttClient.onHeartbeat()

    def onMQTTConnected(self):
        self.mqttClient.subscribe([self.base_topic + '/bridge/#'])

    def onMQTTDisconnected(self):
        self.subscribed_for_devices = False

    def onMQTTSubscribed(self):
        Domoticz.Debug("onMQTTSubscribed")

    def onMQTTPublish(self, topic, message):
        Domoticz.Debug("MQTT message: " + topic + " " + str(message))

        if (topic == self.base_topic + '/bridge/config/permit_join'
                or topic == self.base_topic + '/bridge/config/devices'):
            return

        if (topic == self.base_topic + '/bridge/config'):
            permit_join = 'enabled' if message['permit_join'] else 'disabled'
            Domoticz.Debug('Zigbee2mqtt log level is ' + message['log_level'])
            Domoticz.Log('Joining new devices is ' + permit_join +
                         ' on the zigbee bridge')
            return

        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.mqttClient.publish(
                    self.base_topic + '/bridge/config/groups', '')
                self.handlePairingMode()

            return

        if (topic == self.base_topic + '/bridge/log'):
            if message['type'] == 'devices':
                Domoticz.Log('Received available devices list from bridge')

                self.devices_manager.clear()
                self.devices_manager.update(Devices, message['message'])

                if self.subscribed_for_devices == False:
                    self.mqttClient.subscribe([self.base_topic + '/+'])
                    self.subscribed_for_devices = True

            if message['type'] == 'groups':
                Domoticz.Log('Received groups list from bridge')
                self.groups_manager.register_groups(Devices,
                                                    message['message'])

            if message['type'] == 'device_connected' or message[
                    'type'] == 'device_removed':
                self.mqttClient.publish(
                    self.base_topic + '/bridge/config/devices', '')

            return

        entity_name = topic.replace(self.base_topic + "/", "")

        if (self.devices_manager.get_device_by_name(entity_name) != None):
            self.devices_manager.handle_mqtt_message(Devices, entity_name,
                                                     message)
        elif (self.groups_manager.get_group_by_name(entity_name) != None):
            self.groups_manager.handle_mqtt_message(entity_name, message)
        else:
            Domoticz.Debug('Unhandled message from zigbee2mqtt: ' + topic +
                           ' ' + str(message))
Example #8
0
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.devices_manager = DevicesManager()
        self.devices_manager.set_devices(Devices)
        device_topic = Parameters["Mode1"].strip()

        if (Parameters["Mode2"] == "Dimmer"):
            self.controller = Dimmer(self.devices_manager, device_topic)
        elif (Parameters["Mode2"] == "PwmDimmer"):
            self.controller = PwmDimmer(self.devices_manager, device_topic)
        elif (Parameters["Mode2"] == "RGB"):
            self.controller = ColorDimmer(self.devices_manager, device_topic, 3)
        elif (Parameters["Mode2"] == "RGBW"):
            self.controller = ColorDimmer(self.devices_manager, device_topic, 4)
        elif (Parameters["Mode2"] == "RGBWW"):
            self.controller = ColorDimmer(self.devices_manager, device_topic, 5)

        self.controller.checkDevices()

        self.topics = list(["stat/" + device_topic + "/RESULT", "tele/" + device_topic + "/STATE"])
        
        mqtt_server_address = Parameters["Address"].strip()
        mqtt_server_port = Parameters["Port"].strip()
        mqtt_client_id = Parameters["Mode3"].strip()
        self.mqttClient = MqttClient(mqtt_server_address, mqtt_server_port, mqtt_client_id, 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) + ") Color:" + Color)
        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):
        self.mqttClient.onHeartbeat()

    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, message):
        Domoticz.Debug("MQTT message: " + topic + " " + str(message))

        if (topic in self.topics):
            self.controller.onMqttMessage(topic, 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.install()
        self.base_topic = Parameters["Mode1"].strip()

        mqtt_server_address = Parameters["Address"].strip()
        mqtt_server_port = Parameters["Port"].strip()
        mqtt_client_id = Parameters["Mode3"].strip()
        self.mqttClient = MqttClient(mqtt_server_address, mqtt_server_port,
                                     mqtt_client_id, self.onMQTTConnected,
                                     self.onMQTTDisconnected,
                                     self.onMQTTPublish, self.onMQTTSubscribed)

        self.api = API(self.onApiCommand)
        self.devices_manager = DevicesManager()
        self.groups_manager = GroupsManager()

    def checkDevices(self):
        domoticz.debug("checkDevices called")

    def onStop(self):
        domoticz.debug("onStop called")
        self.uninstall()

    def onCommand(self, device_id, unit, command, Level, Color):
        domoticz.debug("[Command] Device " + device_id + '(' + str(unit) +
                       '): ' + command + "(level = " + str(Level) +
                       ", color = " + Color + ')')

        message = None
        domoticz_device = domoticz.get_device(device_id, unit)
        zigbee_device_alias = configuration.get_zigbee_feature_data(
            device_id, unit)

        if zigbee_device_alias == None:
            domoticz.log('Can\'t process command from device "' +
                         domoticz_device.Name + '"')

        if self.groups_manager.get_group_by_id(
                zigbee_device_alias['zigbee']['address']) != None:
            message = self.groups_manager.handle_command(
                device_id, unit, command, Level, Color)
        else:
            message = self.devices_manager.handle_command(
                device_id, unit, command, Level, Color)

        if (message != None):
            self.publishToMqtt(message['topic'], message['payload'])

    def onApiCommand(self, command, data):
        if command == 'publish_mqtt':
            return self.publishToMqtt(data['topic'], data['payload'])
        elif command == 'remove_device':
            return self.devices_manager.remove(data)
        else:
            domoticz.error('Internal API command "' + command +
                           '" is not supported by plugin')

    def publishToMqtt(self, topic, payload):
        self.mqttClient.publish(self.base_topic + '/' + topic, payload)

    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 onDeviceModified(self, device_id, unit):
        if device_id == 'api_transport' and unit == 255:
            device = domoticz.get_device(device_id, unit)
            self.api.handle_request(device.sValue)
            return

    def onMessage(self, Connection, Data):
        self.mqttClient.onMessage(Connection, Data)

    def onHeartbeat(self):
        self.mqttClient.onHeartbeat()

    def onMQTTConnected(self):
        self.mqttClient.subscribe([self.base_topic + '/#'])

    def onMQTTDisconnected(self):
        domoticz.debug('Disconnected from MQTT server')

    def onMQTTSubscribed(self):
        domoticz.debug('Subscribed to "' + self.base_topic + '/#" topic')

    def onMQTTPublish(self, topic, message):
        # domoticz.debug("MQTT message: " + topic + " " + str(message))
        topic = topic.replace(self.base_topic + '/', '')

        self.api.handle_mqtt_message(topic, message)
        bridge.handle_mqtt_message(topic, message)

        if (topic == 'bridge/config/permit_join'):
            return

        if (topic == 'bridge/config/logging') or (topic == 'bridge/logging'):
            # TODO: Add log feature
            return

        if (topic == 'bridge/devices'):
            self.devices_manager.set_devices(message)
            return

        if (topic == 'bridge/config'):
            permit_join = 'enabled' if message['permit_join'] else 'disabled'
            domoticz.debug('Zigbee2mqtt log level is ' + message['log_level'])
            domoticz.log('Joining new devices is ' + permit_join +
                         ' on the zigbee bridge')
            return

        if (topic == 'bridge/state'):
            domoticz.log('Zigbee2mqtt bridge is ' + message)
            return

        if (topic == 'bridge/log'):
            is_connected = message['type'] == 'device_connected'
            is_removed = message['type'] == 'device_removed'
            is_paired = message['type'] == 'pairing' and message[
                'message'] == 'interview_successful'

            if message['type'] == 'groups':
                domoticz.log('Received groups list from bridge')
                self.groups_manager.register_groups(message['message'])

            if is_connected or is_removed or is_paired:
                self.publishToMqtt('bridge/config/devices/get', '')

            if message['type'] == 'ota_update':
                domoticz.log(message['message'])

            if (message['type'] == 'device_renamed'):
                domoticz.debug("Device renamed from '{0}' to '{1}'".format(
                    message['message']['from'], message['message']['to']))
                if (self.devices_manager.get_device_by_name(
                        message['message']['from']) != None):
                    domoticz.debug("attempt to rename on bridge/log")
                    toRename = self.devices_manager.get_device_by_name(
                        message['message']['from'])
                    toRename.zigbee_device['friendly_name'] = message[
                        'message']['to']
                    self.devices_manager.devices[
                        toRename.zigbee_device['ieee_address']] = toRename
                else:
                    domoticz.debug("attempt to rename failed on bridge/log")

            if message['type'] == 'zigbee_publish_error':
                #an error occured on publish to the zigbee network
                deviceMeta = message['meta']
                domoticz.error("A Zigbee publish error occured for device '" +
                               deviceMeta['friendly_name'] +
                               "' with error message: " + message['message'])

            return

        if (self.groups_manager.get_group_by_name(topic) != None):
            self.groups_manager.handle_mqtt_message(topic, message)
        elif (self.devices_manager.get_device_by_name(topic) != None):
            self.devices_manager.handle_mqtt_message(topic, message)

    def install(self):
        domoticz.log('Installing plugin custom page...')

        try:
            source_path = Parameters['HomeFolder'] + 'frontend'
            templates_path = Parameters['StartupFolder'] + 'www/templates'
            dst_plugin_path = templates_path + '/zigbee2mqtt'

            domoticz.debug('Copying files from ' + source_path + ' to ' +
                           templates_path)

            if not (os.path.isdir(dst_plugin_path)):
                os.makedirs(dst_plugin_path)

            copy2(source_path + '/zigbee2mqtt.html', templates_path)
            copy2(source_path + '/zigbee2mqtt.js', templates_path)
            copy2(source_path + '/plugin_config.js', dst_plugin_path)
            copy2(source_path + '/zigbee_devices.js', dst_plugin_path)
            copy2(source_path + '/zigbee_groups.js', dst_plugin_path)
            copy2(source_path + '/libs/leaflet.js', dst_plugin_path)
            copy2(source_path + '/libs/leaflet.css', dst_plugin_path)
            copy2(source_path + '/libs/viz.js', dst_plugin_path)
            copy2(source_path + '/libs/viz.full.render.js', dst_plugin_path)
            copy2(source_path + '/libs/ace_json_mode.js', dst_plugin_path)
            copy2(source_path + '/libs/ace_worker_json.js', dst_plugin_path)

            domoticz.log('Installing plugin custom page completed.')
        except Exception as e:
            domoticz.error('Error during installing plugin custom page')
            domoticz.error(repr(e))

    def uninstall(self):
        domoticz.log('Uninstalling plugin custom page...')

        try:
            templates_path = Parameters['StartupFolder'] + 'www/templates'
            dst_plugin_path = templates_path + '/zigbee2mqtt'

            domoticz.debug('Removing files from ' + templates_path)

            if (os.path.isdir(dst_plugin_path)):
                rmtree(dst_plugin_path)

            if os.path.exists(templates_path + "/zigbee2mqtt.html"):
                os.remove(templates_path + "/zigbee2mqtt.html")

            if os.path.exists(templates_path + "/zigbee2mqtt.js"):
                os.remove(templates_path + "/zigbee2mqtt.js")

            domoticz.log('Uninstalling plugin custom page completed.')
        except Exception as e:
            domoticz.error('Error during uninstalling plugin custom page')
            domoticz.error(repr(e))
Example #10
0
    else:
        logging.error('Unacceptable message code class:%d', code_class)


def on_error(ws, error):
    logging.error('websocket error:%s', error)


def on_close(ws):
    logging.info('### closed ###')


def on_open(ws):
    devices_proxy = DevicesProxy(devices_manager, ws)
    devices_proxy.start()


if __name__ == '__main__':
    websocket.enableTrace(True)

    devices_manager = DevicesManager(license_serial_num)

    ws = websocket.WebSocketApp(
        'ws://www.linkio.me:9999/device_monitor?Id=' + license_serial_num,
        #ws = websocket.WebSocketApp('ws://127.0.0.1:9999/device_monitor?Id=' + license_serial_num,
        on_message=on_message,
        on_error=on_error,
        on_close=on_close)
    ws.on_open = on_open
    ws.run_forever()