Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tasmota mqtt switch with two state_topic (tele and stat) - wrong HASS state #18703

Closed
hhaim opened this issue Nov 25, 2018 · 20 comments
Closed

Comments

@hhaim
Copy link

hhaim commented Nov 25, 2018

I'm not sure if this is a bug or a feature and I would like to get an opinion how to solve this.

The problem:

Tasmota switch has two topics to report a state – without using both, HASS can have a the wrong state after restart or if device had a reset, for a very long time (OFF while the power is ON) only changing the state can fix this. This is a very serious issue in some cases (Boiler case)

More details:

tele/pow0/STATE = {"Time":"2018-11-24T16:59:06","Uptime":"2T22:12:00","Vcc":3.206,"POWER":"ON","Wifi":{"AP":1,"SSId":"fbi-4","RSSI":100,"APMac":"30:B5:C2:96:6D:96"}}

stat/b0/RESULT = {"POWER":"OFF"}

stat topic is sent after command while tele topic is sent periodically every x sec (e.g. 300 sec).

At first, I've used the stat topic something like this (from the tasmota wiki)

`

  • platform: mqtt
    name: "ac1"
    state_topic: "stat/s0/RESULT"
    value_template: '{{ value_json["POWER1"] }}'
    command_topic: "cmnd/s0/POWER1"
    availability_topic: "tele/s0/LWT"
    qos: 1
    payload_on: "ON"
    payload_off: "OFF"
    payload_available: "Online"
    payload_not_available: "Offline"
    retain: false
    but this does not catch thetele` state update.

HASS default Mqtt switch does not support more than one topic/template per switch.

Options to solve this:

  1. Add a private mqtt switch that support a list of [topic/template] – does not seem very complicated
  2. Adding another switch with the same name but with different topic state create a new mqtt object but it seems associated to the same GUI object and API and it get updated

somthing like this:

`

  • platform: mqtt
    name: "ac1"
    state_topic: "tele/s0/STATE"
    value_template: '{{ value_json["POWER1"] }}'
    command_topic: "cmnd/s0/POWER1"
    availability_topic: "tele/s0/LWT"
    qos: 1
    payload_on: "ON"
    payload_off: "OFF"
    payload_available: "Online"
    payload_not_available: "Offline"
    retain: false
    `
    I don't know why it works but it seems both mqtt objects update the same GUI entity (same name "ac1")

Questions:

  1. Is option Added LuciDeviceScanner to scan OpenWrt Luci-RPC enabled router's state. #2 a valid workaround? will it work on lovelace-ui?
  2. Is it better to add a new mqtt switch with more than one state_topic?
  3. add to HA startup.yaml (from tasmota wiki)

`

  • service: mqtt.publish
    data:
    topic: "cmnd/s0/power1"
    payload: ""
    `

This will force the update only at startup
The problem with this option that 'reset' of tasmota (without the reset from HASS) will keep the state wrong, so I think only option #1 or option #2 are valid
(let's say the device can change the state by itself without command and report it)

  1. Setting a mqtt retain flag is not a valid answer
@emontnemery
Copy link
Contributor

emontnemery commented Nov 25, 2018

This should be fixed in Tasmota, I opened arendst/Tasmota#4450.

@hhaim
Copy link
Author

hhaim commented Nov 25, 2018

Could you elaborate about the direction of fix? Haveing one topic from Tasmota point of view does not seems to me as the right solution (it is simple)

Looking into Tasmota reset sequence, stat topic is sent so option #3 is enough for common cases (state can change only by cmnd topic) but not robust as I would like it to be.

Moreover I would be happy to understand why option #2 solve the issue (from HASS perspective)

@emontnemery
Copy link
Contributor

emontnemery commented Nov 25, 2018

@hhaim 2) most likely hides the issue due to a (now fixed) race condition which incorrectly made MQTT devices with same name share entity id
This was fixed in #18445

The PR I opened on Tasmota sends the periodic updates as stat/s0/RESULT instead of as Tele/s0/STATUS

Let's continue the discussion in arendst/Tasmota#4450

@hhaim
Copy link
Author

hhaim commented Nov 25, 2018

Understood. So for the common case option #2 is not valid. Only option #1 will solve the common issue.

Regarding Tasmota, looked into the PR. Seems as good solution.
For Switch topic would be “stat/[dev]/+” while for sensor, it could still have a more granular topic like “stat/[dev]/SENSOR”

@emontnemery
Copy link
Contributor

Yes, 1) would have been a solution, but perhaps unnecessarily complex to support lists of topics.

@mkh595
Copy link

mkh595 commented Nov 28, 2018

@hhaim, @emontnemery: Send tele/STATUS as state/RESULT doesn't solve problem of update in HA or other automation software. Still have to wait up to teleperiod for update.

There are two simple options on HA side:

  • use recorder like this example and all switches and input selects restore last known state after HA restart automatically
db_url: !secret database_url
purge_interval: 1
purge_keep_days: 5

include:
  domains:
    - switch
    - input_select
  • use automation after HA restart with group topic (here sonoffxxx) and all sonoffs respond with state/RESULT and update state in HA. If you have unit with more relays, just repeate it for power2, power3, etc. This option cover also situation if sonoff change state when HA is off, e.g. during restart
- alias: HASS Startup
  trigger:
    platform: homeassistant
    event: start
  action:
    - service: mqtt.publish
      data:
        topic: "cmnd/sonoffxxx/power1"
        payload: ""

@emontnemery
Copy link
Contributor

@mkh595 You're right, an automation is required to get correct state immediately after restart of HA.

Instead of the automation you mention, use this one to get all states, not just relay state:

- alias: "Power state on HA start-up"
  trigger:
    platform: homeassistant
    event: start
  action:
    - service: mqtt.publish
      data:
        topic: "cmnd/sonoffs/state"
        payload: "" 

@hhaim
Copy link
Author

hhaim commented Nov 28, 2018

Yes, this is by the book solution, I've mention it in the question and maybe I wasn't clear enogth

"add to HA startup.yaml (from tasmota wiki)
`

service: mqtt.publish
data:
topic: "cmnd/s0/power1"
payload: ""
`"

The problem is that there are two method (two topics) to reports the state
The RESULT is published only when asked by command and STAUTS is always there, why not to use it??
I thnk that the propuse solution by @emontnemery is more robust as both STATUS and RESULTs will be processed by the MQTT HASS entity (be based from same topic using +), There won't be a need for the startup script etc and my boiler won't blow up due to state sync issue

@mkh595
Copy link

mkh595 commented Nov 28, 2018

RESULT is published only when asked by command
That's not true, result is send when relay change state automatically.

But why do you have problem with two methods? Why do you need to use both?
Switch I have defined

 state_topic: "stat/topic/POWER1"
 command_topic: "cmnd/topic/POWER1"

When sonoff is restarted, it always send stat/topic/POWER1 at start so there is no issue with sync.
If HA is restarted, it ask via cmnd/grouptopic/POWER1 for status of all relays, there is no issue with sync.
I don't need use tele/topic/STATE to periodically update status of relays. Why? This telepriod message is for sensors like temp, humi etc. which change values.

Btw. if your HA die or blow up, you will not have problem with sync and your boiler?
Don't do things more complicated.

@emontnemery
Copy link
Contributor

more robust as both STATUS and RESULTs will be processed by the MQTT HASS entity

Yes, this is exactly the point.

@mkh595 If the MQTT broker is restarted, or some MQTT message is simply lost, there is absolutely no guarantee that the states are is sync. By using tele/topic/STATE, you are guaranteed a sync within the teleperiod and whenever there is a status change.

@hhaim
Copy link
Author

hhaim commented Dec 9, 2018

(a few lines of code). It requires minimal YAML configuration (short topic only) and support both topics/LWT as defaults. It does not require the startup script configuration etc.

@garymcleanuk
Copy link

more robust as both STATUS and RESULTs will be processed by the MQTT HASS entity

Yes, this is exactly the point.

@mkh595 If the MQTT broker is restarted, or some MQTT message is simply lost, there is absolutely no guarantee that the states are is sync. By using tele/topic/STATE, you are guaranteed a sync within the teleperiod and whenever there is a status change.

I have the same issue. Restarting MQTT you can loose the state of the relay esp if someone has turned it on/off using "Sonoff Button" or a timer in Tasmota..

@hhaim
Copy link
Author

hhaim commented Dec 19, 2018

I can share my custom Tasmota switch and binary sensor if required.

@trommegutten
Copy link

If anyone are interested: I have the telemetry period set to 300 seconds (default). After a restart of HA, I don't want to wait 5 minutes before receiving Wattage update (tele/%topic%/SENSOR). I've solved this problem by forcing a restart of all my tasmota devices. Everything is then synced within 10-15 seconds.

- id: cad87c3737d34034ad94b779be64cec1
  alias: "Force sonoffs restart on HA start-up"
  initial_state: True
  trigger:
    platform: homeassistant
    event: start
  action:
    - service: mqtt.publish
      data:
        topic: "cmnd/sonoffs/restart"
        payload: "1"

My sensor configurations in HA are like this

sensor:
  - platform: mqtt
    name: "power_b1entre_shelly_185"
    state_topic: "tele/b1entre_shelly1_185/SENSOR"
    value_template: "{{value_json['ENERGY'].Power }}"
    unit_of_measurement : "W"

If anyone have a better solution please post it.

@hhaim
Copy link
Author

hhaim commented Jan 27, 2019

I've written a custom switch/sensor/binary sensor for Tasmota. It handles both messages in a clean way
There is no need to change Tasmota configuration.

see here:
mqtt_tasmota

You define it like this:

https://github.com/hhaim/hass/blob/master/configuration.yaml


switch:
  - platform: mqtt_tasmota
    name: ac1
    index: '1'
    stopic: s0

The Qos is 1 by default (hass->mqtt broker). Tasmota does not support Qos>0 (from Tasmota -> broker)

Even if there is a drop of STATUS packet , the hass will be sync in the next /tele/ mqtt packet.

@hhaim
Copy link
Author

hhaim commented Jan 27, 2019

If anyone are interested: I have the telemetry period set to 300 seconds (default). After a restart of HA, I don't want to wait 5 minutes before receiving Wattage update (tele/%topic%/SENSOR). I've solved this problem by forcing a restart of all my tasmota devices. Everything is then synced within 10-15 seconds.

- id: cad87c3737d34034ad94b779be64cec1
  alias: "Force sonoffs restart on HA start-up"
  initial_state: True
  trigger:
    platform: homeassistant
    event: start
  action:
    - service: mqtt.publish
      data:
        topic: "cmnd/sonoffs/restart"
        payload: "1"

My sensor configurations in HA are like this

sensor:
  - platform: mqtt
    name: "power_b1entre_shelly_185"
    state_topic: "tele/b1entre_shelly1_185/SENSOR"
    value_template: "{{value_json['ENERGY'].Power }}"
    unit_of_measurement : "W"

If anyone have a better solution please post it.

BTW this code is not bulletproof. Qos from Tasmota is 0. So you might not get the RESULT in some case.
Getting both tele and stat would be better.

@gufonero
Copy link

I am not very happy with the solution based on forcing telemetry updates in Tasmota devices whenever a state change happens. It seems to work, but I think it is unnatural and innecessarily pollutes the MQTT message log.

I believe the custom HA switch by @hhaim is the best way to go: it responds to all relevant standard Tasmota messages and, as a big plus, makes device configuration extremely simple and error-free.

@hhaim Thank you for sharing your Tasmota custom components (BTW, your reference to them in your message above is broken). I have been using a modified version of the switch component, which allows for POWER as equivalent of POWER1 in state messages, and also fixes a deprecated MQTT receive-message callback. It's working like a charm. I would be happy to share those changes if you would like to integrate them into your component.

@hhaim
Copy link
Author

hhaim commented Jul 25, 2019

@gufonero thanks, I am almost blown my boiler with the old method :-)
The new component works fine for 6 months now.

The new links:

  1. The wiki how to install
  2. example for how to use almost the same.
  3. The code is here

@nunojpg
Copy link

nunojpg commented Feb 1, 2020

The same behavior can also be achieved by enabling SetOption59 in every Tasmota device and using state_topic STATE.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants