enesbcs / shellyteacher4domo

Shelly device teacher for Domoticz MQTT Autodiscovery hardware
Apache License 2.0
10 stars 4 forks source link

Not a BUG: Modify to Tastomateacher4domo #42

Open sincze opened 7 months ago

sincze commented 7 months ago

Hi.

Inspired by your work.

I don't know if you are interested in adapting this code so it can handle the new Tasmota autodiscovery as well ? Tasmota team dropped support for "Setoption19 1" a legacy homeassistant auto discovery and introduced a new version.

In theory with the correct templates it should be possible right? link: https://www.domoticz.com/forum/viewtopic.php?p=312108#p312108

Many thanks for taking it into consideration.

enesbcs commented 7 months ago

In theory it is possible, although there are a lots of sensors and mysterious RGB settings beyond the standard relays in Tasmota which i have no clue how it works. Shelly Gen1 devices has a good online documentation about MQTT commands, Shelly Gen2 has some cryptic documentation, which needs a lots of guesswork, but i do not found any good documentation about Tasmota MQTT topics and possible values... just its pure command list which is not telling any useful to this task.

But FYI:

  1. Legacy "Setoption19 1" method still can be used with Tasmota devices, (in fact i still use this at my v13 Tasmota) as it can be enabled when compiling Tasmota from source code. https://github.com/arendst/Tasmota/blob/8223777e4f4195a43787a90956f2d77527d7d3a1/tasmota/my_user_config.h#L428
#define USE_HOME_ASSISTANT                           // Enable Home Assistant Discovery Support (+12k code, +6 bytes mem)
//#define USE_TASMOTA_DISCOVERY                      // Disable Tasmota Discovery support (+2k code)
  1. In case of ESP32, the Discovery can be implemented on the device side on Tasmota Berry, as i did that on my own thermostat: https://github.com/enesbcs/tasmota-custom-scripts/blob/edae4cd58badc6aad4b86853c9e50426390b32e6/thermostat/thermostat.be#L319
enesbcs commented 7 months ago

"Tasmota docs are open source and are maintained by the community," :)

I've found this information on Tasmota github regarding TasmotaDiscovery:

Preliminary discovery message format example Topic: tasmota/discovery/49A3BC Payload:

{
  "btn":[0,0,0,0],                                  // Buttons, 0: disabled: 1: enabled
  "dn":"Living Room",                               // Device name
  "ip":"192.168.15.10",                             // IP address
  "fn":["Ceiling Lamp", "Floor Lamp"],              // List of friendly names
  "ft":"%prefix%/%topic%/",                         // Fulltopic
  "hn":"tasmota_49A3BC-0956",                       // Hostname
  "mac":"49A3BC873A78",                             // MAC address
  "md":"Sonoff Dual",                               // Module
  "ofln":"Offline",                                 // D_OFFLINE
  "onln":"Online",                                  // D_ONLINE
  "rl":[0,0,0,0,0,0,0,0],                           // Relays, 0: disabled, 1: relay, 2.. future extension (fan, shutter?)
  "so":{"13":0,"17":1,"30":0,"37":1,"68":0,"73":1}, // SetOption needed by HA to map Tasmota devices to HA entities and triggers
  "state":["OFF","ON","TOGGLE","HOLD"],             // StateText[0..3]
  "sw":"13.3.0"                                     // Tasmota SW build version
  "swc":[0,0,0,0,0,0,0,0],                          // Switches, 0: disabled: 1: enabled
  "t":"tasmota_49A3BC",                             // Topic
  "tp":["cmnd","stat","tele"],                      // [SUB_PREFIX, PUB_PREFIX, PUB_PREFIX2]
  "lt_st":0,                                        // Light subtype
  "ver":1                                           // Discovery protocol version, must be 1
}
{
"bat":0, // is the device battery driven and provide % of remainign power?
"dslp":0, // is the device deep_speep configured, will change online/offline behavior in HA. device ia expected to sleep most of the time
"if":0,
"lk":0,
"ty":0,
"sho":[], // configured shutteroptions, reverse, locked,.... works with HA
"sht":[] // configured shutters. Works with HA for shutters and blinds
"swc":[-1,-1,-1,-1,-1,-1,-1,-1], // I suppose this was sw, but why -1?
"swn":[null,null,null,null,null,null,null,null],
}

I think it may be converted to old style Autodiscovery and saved as retained configuration objects with some (i mean a lots of) work.

enesbcs commented 7 months ago

@sincze TasmotaDiscovery support added at testing branch. No binaries yet, can be run under python3. https://github.com/enesbcs/shellyteacher4domo/blob/testing/README.md

sincze commented 7 months ago

@sincze TasmotaDiscovery support added at testing branch. No binaries yet, can be run under python3. https://github.com/enesbcs/shellyteacher4domo/blob/testing/README.md

Followed the instructions as indicated on the Domoticz forum, probably I missed a pre-requirement step.

image
enesbcs commented 7 months ago

@sincze TasmotaDiscovery support added at testing branch. No binaries yet, can be run under python3. https://github.com/enesbcs/shellyteacher4domo/blob/testing/README.md

Followed the instructions as indicated on the Domoticz forum, probably I missed a pre-requirement step.

You have to set settings.py if you are not using the GUI to change yout mqtt broker IP and the autodiscovery topic if you are not using 'homeassistant'. (please do not use the 'tasmota' prefix for autodiscovery output, as this is the input) And of course use tasmo=True to enable new function and when something not works debug=True may also help.

sincze commented 7 months ago

It already start detecting devices when I modified the settings.ini.

image image
enesbcs commented 7 months ago

interesting, you are using Tasmota on Shelly devices?

sincze commented 7 months ago

Mmm busted. You got me.

To be honest. That's correct.

I got shelly on shelly fw Older shelly on tasmota fw And esp32 on tasmota fw.

sincze commented 7 months ago
image

Will need to do some debugging updated from 2022.2 to 2024.3 in test. Flip a switch in Domoticz and the tasmota light switches on, however Domoticz does not reflect that state with an on switch. Making it impossible to turn the light off ;-)

enesbcs commented 7 months ago

Will need to do some debugging updated from 2022.2 to 2024.3 in test. Flip a switch in Domoticz and the tasmota light switches on, however Domoticz does not reflect that state with an on switch. Making it impossible to turn the light off ;-)

I guess Tasmota reports its change in /POWER if only one relay found but reacts to /POWER1. Just guessing. Only you can see what happens in MQTT Explorer on your system.

sincze commented 7 months ago

The following happens in the Sonoff Basic Switch:

image

Let me provide the current debug log first: subscribed tasmota/discovery/# on_message::payload::{"ip":"10.10.40.29","dn":"lamp_slaapkamer","fn":["lamp_slaapkamer",null,null,null,null,null,null,null],"hn":"tasmota_lamp_slaapkamer","mac":"807D3A013787","md":"Neo Coolcam 16","ofln":"Offline","onln":"Online","state":["OFF","ON","TOGGLE","HOLD"],"sw":"8.5.1","t":"tasmota_lamp_slaapklamer","ft":"%prefix%/%topic%/","tp":["cmnd","stat","tele"],"rl":[1,0,0,0,0,0,0,0],"swc":[-1,-1,-1,-1,-1,-1,-1,-1],"btn":[0,0,0,0],"so":{"11":0,"13":0,"17":0,"20":0,"30":0,"68":0,"73":0,"80":0},"lk":1,"lt_st":0,"ver":1} 807D3A013787 alive on_message::payload::{"sn":{"Time":"2023-12-24T15:05:36","ENERGY":{"TotalStartTime":"2020-07-21T17:38:02","Total":72.977,"Yesterday":0.149,"Today":0.113,"Power":1,"ApparentPower":4,"ReactivePower":4,"Factor":0.30,"Voltage":238,"Current":0.018}},"ver":1} 807D3A013787 alive on_message::payload::{"ip":"10.10.40.23","dn":"lamp_badkamer","fn":["lamp_badkamer",null,null,null,null,null,null,null],"hn":"tasmota_basic_badkamer","mac":"5CCF7F984841","md":"Sonoff Basic","ofln":"Offline","onln":"Online","state":["OFF","ON","TOGGLE","HOLD"],"sw":"8.5.1","t":"tasmota_lamp_badkamer","ft":"%prefix%/%topic%/","tp":["cmnd","stat","tele"],"rl":[1,0,0,0,0,0,0,0],"swc":[-1,-1,-1,-1,-1,-1,-1,-1],"btn":[0,0,0,0],"so":{"11":0,"13":0,"17":1,"20":0,"30":0,"68":0,"73":0,"80":0},"lk":1,"lt_st":0,"ver":1} 5CCF7F984841 alive on_message::payload::{"sn":{"Time":"2023-12-08T09:51:28"},"ver":1} 5CCF7F984841 alive on_message::payload::{"ip":"10.10.40.55","dn":"Tasmota","fn":["Tasmota","",null,null,null,null,null,null],"hn":"tasmota-zigbee-bridge-1571","mac":"C82B96064623","md":"Sonoff ZigRouter","ty":0,"if":0,"ofln":"Offline","onln":"Online","state":["OFF","ON","TOGGLE","HOLD"],"sw":"13.2.0","t":"tasmota_zigbee_bridge","ft":"%prefix%/%topic%/","tp":["cmnd","stat","tele"],"rl":[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"swc":[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"swn":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"btn":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"so":{"4":0,"11":0,"13":0,"17":0,"20":0,"30":0,"68":0,"73":0,"82":0,"114":0,"117":0},"lk":0,"lt_st":0,"bat":0,"dslp":0,"sho":[],"sht":[],"ver":1}

image
sincze commented 7 months ago

I am also fiddeling with the setup mentioned here to spot the differences https://www.domoticz.com/forum/viewtopic.php?p=312108#p312108

sincze commented 7 months ago

OK to get the switch working I took the JSON from what the teacher created and modified it to the following:

shelly-pi5/switch/68C63AA84B81_RL_1/config

{
    "name": "friend-sonoff-spare",
    "stat_t": "stat/tasmota_spare-A84B81/POWER",
    "avty_t": "tele/tasmota_spare-A84B81/LWT",
    "pl_avail": "Online",
    "pl_not_avail": "Offline",
    "cmd_t": "cmnd/tasmota_spare-A84B81/POWER",
    "pl_on": "ON",
    "pl_off": "OFF",
    "val_tpl": "{{value_json.POWER}}",
    "uniq_id": "68C63AA84B81_RL_1",
    "dev": {
        "ids": [
            "68C63AA84B81"
        ]
    }
}

However the following minimum change POWER1 to POWER is also sufficient.

{
    "name": "lamp_badkamer",
    "stat_t": "stat/tasmota_lamp_badkamer/POWER",
    "cmd_t": "cmnd/tasmota_lamp_badkamer/POWER",
    "avty_t": "tele/tasmota_lamp_badkamer/LWT",
    "pl_avail": "Online",
    "pl_not_avail": "Offline",
    "pl_on": "ON",
    "pl_off": "OFF",
    "uniq_id": "5CCF7F984841_RL_1"
}

Now I am able to control ON and OFF.

IF we do not modify the script the following also fixes the issue SetOption26 1

SetOption26 Use indexes even when only one relay is present

0 = messages use POWER (default)
1 = messages use POWER1
enesbcs commented 7 months ago

Its very interesting that Tasmota does not use Power1 when only one relay present, in its default behaviour. Can be added to the script as exception.

enesbcs commented 7 months ago

OK to get the switch working I took the JSON from what the teacher created and modified it to the following:

  "stat_t": "stat/tasmota_spare-A84B81/POWER",
  "val_tpl": "{{value_json.POWER}}",

Its very interesting config object. I do not know how its possibly works, as the POWER structure is not a JSON. :D Maybe its state topic was tele_topic earlier, and val_tpl never actualized to the new struct by the Tasmota devs.

enesbcs commented 7 months ago

Power1 fix added at commit https://github.com/enesbcs/shellyteacher4domo/commit/17f0ba7beeacdb7ba6a377707aef20fda9cfc38e

sincze commented 5 months ago

Today I Build a nice sensor in Tasmota. image

The Teacher finds the device

on_message::payload::{"ip":"192.168.xxx.xxx","dn":"CV-Ruimte","fn":["Door","Relais1","Relais2","Relais3",null,null,null,null],"hn":"cv-ruimte-5830","mac":"DC4F220756C6","md":"Technische Ruimte","ty":0,"if":0,"ofln":"Offline","onln":"Online","state":["OFF","ON","TOGGLE","HOLD"],"sw":"13.4.0","t":"cv-ruimte","ft":"%prefix%/%topic%/","tp":["cmnd","stat","tele"],"rl":[1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"swc":[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"swn":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"btn":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"so":{"4":0,"11":0,"13":0,"17":0,"20":0,"30":0,"68":0,"73":0,"82":0,"114":0,"117":0},"lk":0,"lt_st":0,"bat":0,"dslp":0,"sho":[],"sht":[],"ver":1}
DC4F220756C6 alive
on_message::payload::{"sn":{"Time":"2024-03-31T08:46:17","Switch1":"ON","DS18B20-1":{"Id":"3CCCE3810022","Temperature":18.4},"DS18B20-2":{"Id":"3CF0E381CD74","Temperature":17.7},"TempUnit":"C"},"ver":1}
DC4F220756C6 alive

It generates the Temp Sensors. However the Door and Relais are Missing. Would this be a complexity issue that can be solved ?? image

enesbcs commented 5 months ago

It generates the Temp Sensors. However the Door and Relais are Missing. Would this be a complexity issue that can be solved ?

on_message::payload::{"ip":"192.168.xxx.xxx","dn":"CV-Ruimte","fn":["Door","Relais1","Relais2","Relais3",null,null,null,null],"hn":"cv-ruimte-5830","mac":"DC4F220756C6","md":"Technische Ruimte","ty":0,"if":0,"ofln":"Offline","onln":"Online","state":["OFF","ON","TOGGLE","HOLD"],"sw":"13.4.0","t":"cv-ruimte","ft":"%prefix%/%topic%/","tp":["cmnd","stat","tele"],"rl":[1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"swc":[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],"swn":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"btn":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"so":{"4":0,"11":0,"13":0,"17":0,"20":0,"30":0,"68":0,"73":0,"82":0,"114":0,"117":0},"lk":0,"lt_st":0,"bat":0,"dslp":0,"sho":[],"sht":[],"ver":1}
DC4F220756C6 alive
on_message::payload::{"sn":{"Time":"2024-03-31T08:46:17","Switch1":"ON","DS18B20-1":{"Id":"3CCCE3810022","Temperature":18.4},"DS18B20-2":{"Id":"3CF0E381CD74","Temperature":17.7},"TempUnit":"C"},"ver":1}
DC4F220756C6 alive

For some unknown reason, Tasmota devs thinks it is necessary to report config in two distinct message, one for the sensors and another one for everything else. In my current implementation i read first the "config", than wait for "sensors" structure for 5 x 0.1 seconds and if its arrived than i will send out the config payload.

I guess in case the sensors come first, than the relays will never be processed. Currently i have no idea how to solve this, as this never happened with my test Tasmota device so far.

I tried your payloads directly with the common.py in offline mode, where Tasmota_Discovery() is declared and it constructs the relay config payloads correctly.

{'topic': '%discovery_prefix%/binary_sensor/DC4F220756C6_online/config', 'payload': '{"name": "CV-Ruimte Online", "stat_t": "tele/cv-ruimte/LWT", "pl_on": "Online", "pl_off": "Offline", "uniq_id": "DC4F220756C6_online", "device": {"name": "CV-Ruimte", "identifiers": ["DC4F220756C6"], "model": "Technische Ruimte", "sw_version": "13.4.0"}}'}, 

{'topic': '%discovery_prefix%/switch/DC4F220756C6_RL_1/config', 'payload': '{"name": "Door", "stat_t": "stat/cv-ruimte/POWER1", "cmd_t": "cmnd/cv-ruimte/POWER1", "avty_t": "tele/cv-ruimte/LWT", "pl_avail": "Online", "pl_not_avail": "Offline", "pl_on": "ON", "pl_off": "OFF", "uniq_id": "DC4F220756C6_RL_1"}'}, 

{'topic': '%discovery_prefix%/switch/DC4F220756C6_RL_2/config', 'payload': '{"name": "Relais1", "stat_t": "stat/cv-ruimte/POWER2", "cmd_t": "cmnd/cv-ruimte/POWER2", "avty_t": "tele/cv-ruimte/LWT", "pl_avail": "Online", "pl_not_avail": "Offline", "pl_on": "ON", "pl_off": "OFF", "uniq_id": "DC4F220756C6_RL_2"}'}, 

{'topic': '%discovery_prefix%/switch/DC4F220756C6_RL_3/config', 'payload': '{"name": "Relais2", "stat_t": "stat/cv-ruimte/POWER3", "cmd_t": "cmnd/cv-ruimte/POWER3", "avty_t": "tele/cv-ruimte/LWT", "pl_avail": "Online", "pl_not_avail": "Offline", "pl_on": "ON", "pl_off": "OFF", "uniq_id": "DC4F220756C6_RL_3"}'}, 

{'topic': '%discovery_prefix%/switch/DC4F220756C6_RL_4/config', 'payload': '{"name": "Relais3", "stat_t": "stat/cv-ruimte/POWER4", "cmd_t": "cmnd/cv-ruimte/POWER4", "avty_t": "tele/cv-ruimte/LWT", "pl_avail": "Online", "pl_not_avail": "Offline", "pl_on": "ON", "pl_off": "OFF", "uniq_id": "DC4F220756C6_RL_4"}'}, 

{'topic': '%discovery_prefix%/sensor/DC4F220756C6-ds18b20-1/id/config', 'payload': '{"name": "CV-Ruimte DS18B20-1 Id", "stat_t": "tele/cv-ruimte/SENSOR", "value_template": "{{ value_json.DS18B20-1.Id }}", "stat_cla": "measurement", "uniq_id": "DC4F220756C6-ds18b20-1-id"}'}, 

{'topic': '%discovery_prefix%/sensor/DC4F220756C6-ds18b20-1/temperature/config', 'payload': '{"name": "CV-Ruimte DS18B20-1 Temperature", "stat_t": "tele/cv-ruimte/SENSOR", "value_template": "{{ value_json.DS18B20-1.Temperature }}", "stat_cla": "measurement", "unit_of_meas": "C", "dev_cla": "temperature", "device": {"name": "CV-Ruimte DS18B20-1", "identifiers": ["DC4F220756C6-DS18B20-1"]}, "uniq_id": "DC4F220756C6-ds18b20-1-temperature"}'}, 

{'topic': '%discovery_prefix%/sensor/DC4F220756C6-ds18b20-2/id/config', 'payload': '{"name": "CV-Ruimte DS18B20-2 Id", "stat_t": "tele/cv-ruimte/SENSOR", "value_template": "{{ value_json.DS18B20-2.Id }}", "stat_cla": "measurement", "uniq_id": "DC4F220756C6-ds18b20-2-id"}'}, 

{'topic': '%discovery_prefix%/sensor/DC4F220756C6-ds18b20-2/temperature/config', 'payload': '{"name": "CV-Ruimte DS18B20-2 Temperature", "stat_t": "tele/cv-ruimte/SENSOR", "value_template": "{{ value_json.DS18B20-2.Temperature }}", "stat_cla": "measurement", "unit_of_meas": "C", "dev_cla": "temperature", "device": {"name": "CV-Ruimte DS18B20-2", "identifiers": ["DC4F220756C6-DS18B20-2"]}, "uniq_id": "DC4F220756C6-ds18b20-2-temperature"}'}]