Problem with MQTT retain?

I have a annoying problem.

I have one lamp that is controlled with a sonoff and MQTT. The lamp also have a regular wall switch before the sonoff. The sonoff is configured so that it always powers on active. This way I can turn off the lamp with automations, and for WAF it’s possible to flick the wall switch to reboot the sonoff to active mode.

Problem is that HASS turns off the sonoff after a couple off seconds if the lamp switch in HASS is inactive when I flick the wall switch. I have tried with retain set to false, but it’s the same.

My config looks like this:

  • platform: mqtt
    name: “Kjokken”
    command_topic: “cmnd/sonoff-kjokken/POWER”
    payload_on: “ON”
    payload_off: “OFF”
    qos: 1
    retain: false
    optimistic: false

Is the retain flag for MQTT switch working?

Have you cleared the broker database of the the retained status by doing something like

mosquitto_pub -t cmnd/sonoff-kjokken/POWER -r -n

If not, the last message with the retained flag set will still be in the database. If this was the off command, the broker will send this when the sonoff is powered up, which would explain the behaviour you are getting.

The sonoff itself could send a status with retain flag.

What you could do is push a ON status on start from the sonoff, so the mqtt broker and hass will be aware that the sonoff as just been turned ON.

Good idea, problem is that I run Hassio and the ResinOS have a totally different subnet. I can’t access the sonoff from inside the SSH

You can send the message from anywhere you can access your broker - a pc, laptop or mobile phone. It doesn’t have to be on the Pi.

That’s true. But it didn’t help.

I tried different configurations on the sonoff too, I’m begining to wonder if HASS ingnores the false flag for retain, it seems like retain is always on…

Do you have any ideas on how to push a status on boot? I’m using tasmota, but everything I try gets overruled by HASS

Edit: Solved. Got it working by resetting the sonoff to defaults and configuring it again. Nothing wrong with HASS

This certainly is not true. What happens you do

mosquitto_sub -t cmnd/sonoff-kjokken/POWER -v

If the message is still retained in the broker’s database, it will print out the retained value.

It was a problem with tasmota/missconfiguration of tasmota

1 Like

Hi, What was the issue on the Tasmota Configuration? I am having this same issue where if I power cycle the Sonoff switch while it was on with in a second or two it seems as though HA shuts it off.

Please share your solution for reference and for ppl that need help.

Hi guys. I kinda have the same problem. It is not a Tasmota problem since I run my own code. There is something retained by mosquitto Broker or by Home assistant… can’t see client ID and I can’t figure it out.
I’m running latest HASSIO (0.65.5) and latest mosquitto installed via ADD-ON.
The problem is that every time a client (i’m using nodered or MQTTFX) is listening to certain topics (in my case all of them - #) I see initial states fired. Even If I connect and I publish a state, this is ignored and an old state is published.
As per exemple my MQTT light should start turned off and the initial color would be white. I publish this states, but as soon as I subscribe I get “ON” and blue color.
This also happens with MQTT light effect. I used once a dummy configuraytion for test and everytime I connect I get a not (anymore) existing effect. I patched this, but since this behaviour is quite unpredictable (I don’t understand why those specific values are retained) I cannot foresee a solution.
I have the impression that the retained values are fired by home assistant, since all the tests I have made not using HA MQTT light (pure mqtt pub and subscribe with mqttfx or mqttlens) don’t have such a problem.
of course retain: false

The broker retains the last message sent with the retain flag. If you subsequently post messages without the retain flag set, this is not forgotten, and any client subscribing to that topic will receive the retained values.

If you want to remove the retained values, you can publish a message to that topic without a payload and with the retain flag set to false.

Or to override the values, you must publish the message with the retain flag set.


@gpbenton thank you!! I actually published a retained message (retain true) with no payload and it worked perfectly. thank you a lot.

1 Like

I know I am responding to an old topic but perhaps I can add to this:

I had problems too where I was unsure if I had to set powerretain 1 or 0 on the sonoff side. because when I was tinkering with the system at night the light status would get out of sync so they’d go off or on.

I came accross another topic stating that adding a check whenever your HA is restarted that it would solve all my problems:

- alias: “Power state on HA start-up”
platform: homeassistant
event: start
- service: mqtt.publish
topic: “cmnd/LampTafeltje/POWER”
payload: “”
- service: mqtt.publish
topic: “cmnd/LampTV/POWER”
payload: “”
- service: mqtt.publish
topic: “cmnd/LampBank/POWER”
payload: “”
- service: mqtt.publish
topic: “cmnd/LampArwen/POWER”
payload: “”
- service: mqtt.publish
topic: “cmnd/LampEettafel/POWER”
payload: “”

Some of my sonoff devices currently have retain 1, some have retain 0 (just checked) and it doesn’t make a damn difference. they never go out of a wack.

I was also struggling with state/retain after restarts reading this topic.
I am running all TASMOTA and to obtain status after HA/MQTT restart, created a small pyscript (=custom component) to pick up the tele commands of TASMOTA.
So after 5 minutes (default TASMOTA tele timing) all status messages are received and switches set accordingly in HA.

@linuxbak:/var/lib/docker/volumes/ha-storage/_data$ cat pyscript/
def tasmota_tele(topic=None, payload=None, payload_obj=None):"tasmota_tele: got action {topic} id {payload_obj} {type(payload_obj)}")
    if payload_obj is not None:"POWER","No Power found in json"))
        t = topic.split("/")
        tt = t[2].lower()
        if tt not in ["vera","masu1","masu2"]:
          entp =  payload_obj.get("POWER","").lower()
          if entp != "":
            ents = state.get("switch.%s"%tt)
            if entp ==  ents:
      "XX %s: %s == %s" % (tt, entp, ents) )
      "XX %s: %s <> %s" % (tt, entp, ents) )
                state.set("switch.%s"%tt, entp)

    #"No json payload")

The mqtt devices are defined as below. The name must be the same as the mqtt device name. Still checking out the patch that allows a friendly name on mqtt switches for the UI…

    ## Node Anchors

      switch: &tasmota_sw
          platform: mqtt
          qos: 1
          payload_on: "ON"
          payload_off: "OFF"
          payload_available: "Online"
          payload_not_available: "Offline"
          retain: false

  - <<: *tasmota_sw
    name: "bw201"
    state_topic: "mc35/stat/bw201/POWER"
    command_topic: "mc35/cmnd/bw201/POWER"
    availability_topic: "mc35/tele/bw201/LWT"
  - <<: *tasmota_sw
    name: "bw202"
    state_topic: "mc35/stat/bw202/POWER"
    command_topic: "mc35/cmnd/bw202/POWER"
    availability_topic: "mc35/tele/bw202/LWT"