Mqtt switch incorrect state

Hi everybody,

I have all my tasmota controlled devices set up as mqtt switches. Most of the time, most of them display the correct state (so if I had turned on my office fan, the switch would be on).

However, some other times, this does not work. A device that is currently on is displayed as off; the only way to fix this (when using the webinterface on my smartphone, for example) is to click the switch with precise timing.

Let’s say my office fan is actually on, but home-assistant displays it as off; I will have to switch it to on, but then it will change back to off after a few seconds. If I switch it on, then back off, it will stay on, but still display off. If I time it just right, I will turn the switch to on (which the device already is), wait a second or so, then turn it to off. If the timing is right, the device will turn off and the status will be correct.

This is pretty annoying and I am sure this can be fixed, so would somebody please help me do so?

This is an example switch from my configuration

- name: "Arbeitszimmer Rechner"
  command_topic: "cmnd/tasmota-1834/POWER"
  state_topic: "stat/tasmota-1834/POWER"
  icon: mdi:laptop
  <<: &meintemplate
    platform: mqtt
    qos: 2
    retain: false
    payload_on: "ON"
    payload_off: "OFF"
    state_on: "ON"
    state_off: "OFF"

The tasmota device (it is a Gosund SP1) has the following options set that might be relevant

  • teleperiod 10 (report current status each 10 seconds)
  • powerretain 1 (retain power value)
  • sensorretain 1 (device measures energy consumption; if I retain this, I will get the most recent stats right when (re)starting home-assistant instead of having to wait for them to be reported again)

I used to have retain: true set in the switch .yaml file. However, this would cause devices to keep this state, even if I didn’t want them to (for example, manually turning of a switch by hand instead of via home-assistant would result in it turning back on a few seconds later).

I considered using tele/tasmota-1834/STATE and then using the appropriate json value for this, but if I manually observe stat/tasmota-1834/POWER via command line and change the status, it will display the correct result; so home-assistant should know the current state; also, since all my tasmota devices have powerretain ON, I’d expect each device to constantly display it’s status (or rather, each switch in home-assistant being set to the correct value).

Have I made an obvious mistake in my configuration that I didn’t see? Btw., the <<: &meintemplate line is just so that I can have these very values in each following switch in that file without having to copying and pasting the same lines over and over again.

Thanks in advance for your help :slight_smile:

Are you sure that the state & command topics are correct for each device?

I’ve had a few times when I was copying/pasting things to set up a new device that I forgot to change parts of the set up to the new device and left the old device info in and I had similar results.

1 Like

You didn’t enable discovery?
Which Tasmota are you using? The standard sonoff.bin?

1 Like

Thank you both @finity @DavidFW1960

I am absolutely positive that state and command topics are correct. After all, I am able to control each device via home-assistant; only some times the states of individual items are incorrect, but once I “fix” this (right timing to set home-assistant button to actual state), they work fine again. At least the command topic has to be correct, or home-assistant should not be able to control the devices at all.

Might this be due to multiple use of the webGUI? I always have a pinned tab open with home-assistant in my browser, and on my phone the home-assistant URL is saved to the launcher as a shortcut. Unfortunately my browser (firefox for android) sometimes keeps opening new instances when I access the page via launcher instead of just focusing the window that was still open in the browser.

I purposely did not enable discovery. I used setoption19 0, which disables discovery in tasmota. While I do use home-assistant’s discovery feature (because I also use some ESPHomes and zigbee2mqtt devices - which are discovered just fine), I don’t use this for tasmota. I have found that it doesn’t work as I expected it.

For example, all my tasmota devices have names like tasmota-nnnn (those 4 n are auto-generated when flashing using the device’s mac address). Some other people would name their devices SW_light_office or something, but I have been using these devices with node-red for a few years before switching to home-assistant and this pattern was useful there. So even if I used discovery on them, I’d only have switches names tasmota-1234 instead of something I could work with. I can, of course, change this, but all devices are already set up using mqtt because when I did my inital setup, I wasn’t aware of the discovery feature and had already created multiple yaml files for the switches.

I will try and set up a new tasmota device and connect it via discovery too see whether there is a change. If so, I might change my existing tasmota devices to use the discovery feature as well. I just found it curious that they usually work just fine, but every now and then there is an exception…

There’s a great video around about retain settings… I’ll see if I can find it for you.
You are using retain: true… that is going to cause random lights turning on at some time so you want to get rid of that and remove the retained message from the broker.
Ok here’s the video

Hers’s the settings you want to execute in the console:

switchretain off
buttonretain on
buttonretain off
poweronstate 3
powerretain on
1 Like

I have seen a video by DrZZs about mqtt retain (can’t find it in my youtube history any longer for some reason), and made sure to set retain: false on all home-assistant switches. I set retain on all tasmotas to true, so that home-assistant will always still receive the correct state after a restart (because the tasmota device itself retained it’s last (=current) state).

See my edit above

Well that will have some nasty consequences! The better way is to publish a blank payload to the state topic… there are automations on Tasmota that show that.

Setting retain: true in Home Assistant will cause the switch to turn on say if the WiFi reconnects or if the broker reconnects to the switch. Retained settings should only be made on the device.

Sorry, not a native speaker. Perhaps I explained this wrong… but what you described there is exactly what I am doing. Home Assistant is set to retain: false, and tasmota devices are set to powerretain 1 (which pretty much equals retain: true).

However, sending a blank payload to the state topic is something I will look into. I remember reading something like that somewhere (tasmota wiki? I’ll check after posting this), but forgot about it until now that you’ve mentioned it. I believe it was an action performed by Home Assistant upon (re)start “requesting” each device’s status so that they would be in sync.

Oh crap! You’re right… swear I saw retain: true! But probably some other thread. You’re all good.

Here is the automation I use for the state when HA starts:

- id: '1532478833428'
  alias: Power State Tasmota on HA Start-Up
  trigger:
  - event: start
    platform: homeassistant
  action:
  - data:
      payload: ''
      topic: sonoffs/cmnd/state
    service: mqtt.publish

Sonoffs is the group topic so that will fix all switches in that group.
If you are not using discovery, the topic will be cmnd/sonoffs/state

Otherwise you have to wait for the telemetry period (default 300 seconds) for them to update but with that automation - no waiting.

Awesome, thank you! That is a much better approach.