include my own pythons plugin in the domoticz

Python and python framework

Moderator: leecollings

Post Reply
svd71
Posts: 16
Joined: Saturday 09 January 2021 17:58
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

include my own pythons plugin in the domoticz

Post by svd71 »

Hi all.

I have old Paspberry pi 3B with 1G on the board, Bullseye, and Domoticz Version: 2024.7.

I did installed couple of plugins: SamsungTV, Mikrotik, RPi, tasmota-auto.

But I have problem with my own plugin. I had checked all:
permissions, owner, start in console with python (run without errors).
After restart of domoticz-service does not see any information in the log about plugins-initialization process.

I have did a mistake in the plugins code and restart the service again - no error messages.

can somebody explain me what I did wrong?

BR.
User avatar
waltervl
Posts: 6676
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2025.1
Location: NL
Contact:

Re: include my own pythons plugin in the domoticz

Post by waltervl »

Did you add it as a hardware gateway?
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
User avatar
madpatrick
Posts: 758
Joined: Monday 26 December 2016 12:17
Target OS: Linux
Domoticz version: 2025.2
Location: Netherlands
Contact:

Re: include my own pythons plugin in the domoticz

Post by madpatrick »

Can you share the plugin then we can test if it works with others systems
-= HP server GEN11 =- ZwaveJS-=- Domoticz v2025.2 -=- Dashticz =-
-= Checkout https://github.com/MadPatrick for the plugins =-
svd71
Posts: 16
Joined: Saturday 09 January 2021 17:58
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: include my own pythons plugin in the domoticz

Post by svd71 »

@madpatrick : The plugin is hier in spoiler:
Spoiler: show

Code: Select all

"""
<plugin 
    key="TasmotaMQTTIntegration" 
    name="Tasmota MQTT Integration" 
    author="S.Pfaffenrot" 
    version="1.0.0" 
    externallink="https://tasmota.github.io/docs/">

    <description>
        Tasmota MQTT Integration Plugin<br/>
        This plugin listens to MQTT messages from Tasmota devices and updates corresponding Domoticz switches based on JSON in their descriptions.
    </description>

    <params>
        <param field="Address" label="MQTT Server" width="200px" required="true" default="localhost"/>
        <param field="Port" label="MQTT Port" width="40px" required="true" default="1883"/>
        <param field="Username" label="MQTT Username" width="200px" required="false"/>
        <param field="Password" label="MQTT Password" width="200px" required="false" password="true"/>
        <param field="Mode6" label="Debug" width="75px">
            <options>
                <option label="True" value="Debug"/>
                <option label="False" value="Normal" default="true" />
            </options>
        </param>
    </params>

</plugin>
"""
aaaaaaaa
errmsg = ""
try:
	import Domoticz
except Exception as e:
    errmsg += "tas:Domoticz core start error: "+str(e)
try:
	import json
except Exception as e:
    errmsg += "tas: json: "+str(e)
try:
	import paho.mqtt.client as mqtt
except Exception as e:
    errmsg += "tas: mqtt::MqttClient import error: "+str(e)


class BasePlugin:
    def __init__(self):
        self.mqttClient = None
        self.mqttConnected = False
        self.debug = False

    def onStart(self):
        if Parameters["Mode6"] == "Debug":
            self.debug = True
            Domoticz.Debugging(1)
        else:
            Domoticz.Debugging(0)

        Domoticz.Log("tas: plugin starting...")

        # Create MQTT client
        self.mqttClient = mqtt.Client()
        self.mqttClient.on_connect = self.onMQTTConnect
        self.mqttClient.on_disconnect = self.onMQTTDisconnect
        self.mqttClient.on_message = self.onMQTTMessage

        if Parameters["Username"] != "":
            self.mqttClient.username_pw_set(Parameters["Username"], Parameters["Password"])

        # Connect to MQTT
        try:
            self.mqttClient.connect(Parameters["Address"], int(Parameters["Port"]), 60)
            self.mqttClient.loop_start()
        except Exception as e:
            Domoticz.Error("tas: MQTT connection error: " + str(e))

    def onStop(self):
        Domoticz.Log("tas: Plugin stopping...")
        if self.mqttClient is not None:
            self.mqttClient.loop_stop()
            self.mqttClient.disconnect()

    def onMQTTConnect(self, client, userdata, flags, rc):
        if rc == 0:
            self.mqttConnected = True
            Domoticz.Log("tas: Connected to MQTT broker with result code " + str(rc))
            # Subscribe to relevant topics
            self.mqttClient.subscribe("tele/#")
            self.mqttClient.subscribe("stat/#")
        else:
            Domoticz.Error("tas: Failed to connect to MQTT, return code: " + str(rc))
            self.mqttConnected = False

    def onMQTTDisconnect(self, client, userdata, rc):
        self.mqttConnected = False
        Domoticz.Log("tas: Disconnected from MQTT broker with result code " + str(rc))

    def onMQTTMessage(self, client, userdata, msg):
        try:
            topic = msg.topic
            payload = msg.payload.decode("utf-8")
            if self.debug:
                Domoticz.Debug("tas: MQTT Message: Topic=" + topic + ", Payload=" + payload)

            # Parse topic to extract device topic (e.g., tasmota_94F93D)
            topic_parts = topic.split('/')
            if len(topic_parts) < 2:
                return
            device_topic = topic_parts[1]  # e.g., tasmota_94F93D

            # Parse JSON payload
            payload_json = json.loads(payload)

            # Case 1: tele/.../SENSOR = {"Time":..., "Switch3":"OFF"}
            if topic.startswith("tele/") and "SENSOR" in topic_parts:
                for key, value in payload_json.items():
                    if key.startswith("Switch") and value in ["ON", "OFF"]:
                        switch_name = key  # e.g., Switch3
                        new_state = value  # ON or OFF
                        self.updateDomoticzDevice(device_topic, switch_name, new_state)

            # Case 2: stat/.../RESULT = {"Switch3":{"Action":"TOGGLE"}}
            elif topic.startswith("stat/") and "RESULT" in topic_parts:
                for key, value in payload_json.items():
                    if key.startswith("Switch") and isinstance(value, dict) and "Action" in value and value["Action"] == "TOGGLE":
                        switch_name = key  # e.g., Switch3
                        self.toggleDomoticzDevice(device_topic, switch_name)

        except Exception as e:
            Domoticz.Error("tas: Error processing MQTT message: " + str(e))

    def updateDomoticzDevice(self, device_topic, switch_name, new_state):
        # Find Domoticz device with matching JSON in Description
        found = False
        for dev_id, device in Devices.items():
            try:
                desc_json = json.loads(device.Description)
                if isinstance(desc_json, dict) and \
                   "Topic" in desc_json and desc_json["Topic"] == f"cmnd/{device_topic}" and \
                   "Device" in desc_json and desc_json["Device"] == switch_name:
                    found = True
                    # Update status: ON -> 1 (or 100 for level), OFF -> 0
                    nvalue = 1 if new_state == "ON" else 0
                    svalue = "100" if new_state == "ON" else "0"  # For selector or dimmer, adjust if needed
                    device.Update(nValue=nvalue, sValue=svalue)
                    Domoticz.Log(f"tas: Updated device {dev_id} ({device.Name}) to {new_state}")
                    break
            except json.JSONDecodeError:
                pass  # Invalid JSON in description, skip

        if not found:
            Domoticz.Log(f"tas: No matching Domoticz device found for {device_topic}/{switch_name}")

    def toggleDomoticzDevice(self, device_topic, switch_name):
        # Find Domoticz device and toggle it
        found = False
        for dev_id, device in Devices.items():
            try:
                desc_json = json.loads(device.Description)
                if isinstance(desc_json, dict) and \
                   "Topic" in desc_json and desc_json["Topic"] == f"cmnd/{device_topic}" and \
                   "Device" in desc_json and desc_json["Device"] == switch_name:
                    found = True
                    # Toggle: if currently ON (nValue=1), set to OFF, and vice versa
                    new_nvalue = 0 if device.nValue == 1 else 1
                    new_svalue = "0" if new_nvalue == 0 else "100"
                    device.Update(nValue=new_nvalue, sValue=new_svalue)
                    new_state = "ON" if new_nvalue == 1 else "OFF"
                    Domoticz.Log(f"tas: Toggled device {dev_id} ({device.Name}) to {new_state}")
                    break
            except json.JSONDecodeError:
                pass

        if not found:
            Domoticz.Log(f"tas: No matching Domoticz device found for {device_topic}/{switch_name}")

global _plugin
_plugin = BasePlugin()

def onStart():
    global _plugin
    _plugin.onStart()

def onStop():
    global _plugin
    _plugin.onStop()

def onConnect(Connection, Status, Description):
    pass

def onMessage(Connection, Data):
    pass

def onCommand(Unit, Command, Level, Color):
    pass

def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
    pass

def onDisconnect(Connection):
    pass

def onHeartbeat():
    pass
@walterw: what is it a "hardware gateway" and how need to add to the domoticz? Send please me a link to description of process if it present.
User avatar
waltervl
Posts: 6676
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2025.1
Location: NL
Contact:

Re: include my own pythons plugin in the domoticz

Post by waltervl »

svd71 wrote: Monday 29 December 2025 12:41 @walterw: what is it a "hardware gateway" and how need to add to the domoticz? Send please me a link to description of process if it present.
That is in menu Setup-Hardware
See wiki for installing a plugin https://wiki.domoticz.com/Using_Python_ ... g_a_plugin


By the way, there is already a MQTT Tasmoticz plugin available:
viewtopic.php?t=21918
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
svd71
Posts: 16
Joined: Saturday 09 January 2021 17:58
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: include my own pythons plugin in the domoticz

Post by svd71 »

thank you very much!

I have it. But it is same question, why I did not see it in the menu "Hardware" for settings.
Attachments
image_2025-12-29_132036243.png
image_2025-12-29_132036243.png (91.26 KiB) Viewed 31 times
image_2025-12-29_131901691.png
image_2025-12-29_131901691.png (38.61 KiB) Viewed 31 times
image_2025-12-29_131834765.png
image_2025-12-29_131834765.png (11.79 KiB) Viewed 31 times
User avatar
waltervl
Posts: 6676
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2025.1
Location: NL
Contact:

Re: include my own pythons plugin in the domoticz

Post by waltervl »

You first have to add it in the form below this list: https://wiki.domoticz.com/Hardware_Setu ... re_Gateway
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
svd71
Posts: 16
Joined: Saturday 09 January 2021 17:58
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: include my own pythons plugin in the domoticz

Post by svd71 »

Thank you very much!
I had found it !!!
Attachments
image_2025-12-29_135404741.png
image_2025-12-29_135404741.png (35.11 KiB) Viewed 26 times
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest