MQTT: To Retain, or Not To Retain?

Hello beautiful people!!

I think I understand what retain does, but maybe I don’t since I’ve read a lot of people “fixing” problems by turning off retain: true.

Here’s my (mis)understanding/desire:
If a sensor publishes a message and includes the retain flag (we’ll use a temperature probe for the example), any client subscribed to that topic will see that topic and ‘37’ for the temperature. If another client comes online an hour later, and no other messages have come from the probe, it subscribes and reads ‘37’.

Now if that same sensor publishes a message and does not include the retain flag, any client currently subscribed will get ‘37’ for that topic. However, any client not currently online that comes on an hour later will subscribe to that topic and get a ‘null’ until another message is sent by the sensor.

A better/more real world for me “problem” is battery level. When a device publishes it’s device level, I want that to persist across restarting HA, or if HA happens to be down, when HA comes online, I want it to “read” that battery level. Is “retain” not the solution to this issue? If I restart HA, how can I persistently have that data available?

Thanks for any thoughts/feedback/schooling!
-Chad

you could use retain, the nice thing is that if the value is the same the device just doesn’t send a new message. Part of the beauty of MQTT.

As for getting battery level, sure you could use retain or you could just request it at HA startup. There’s a trigger for that. As long as the client is available to request the data you should have no problem. You can even just request it every so often (if need be).

Anytime my HA instance starts up I just query all the local MQTT devices for their current states/values etc, because no other device really needs this data (I’m not reading from another mqtt client) so retain really isn’t necessary. It becomes necessary if you need to monitor state changes from something other than the HA dashboard, ie MQTT Dash for android. Retain is there just for new clients to get old messages without having to ask.

There’s a lot more, that I don’t know, but this should maybe answer some of your questions.

1 Like

Use retain if you need to know the state when you startup and either can’t/don’t want to persist it yourself or can’t/don’t want to read it on startup. I use Node Red and log the actions from each message. Every time I make a tiny change and re-deploy, retained messages are resent and generate a bunch of unnecessary logging messages. So I tend to avoid retain like the plague and persist in HA. However, I have some low power temperature MQTT devices that are not connected to HA. They don’t like to stay awake just so I can read state occasionally. For these I use retain.

Retain also has a nasty habit of propagating itself accidentally. If you read one message and write another, the retain flag can get propagated from the input to the output, depending on the code.

1 Like

As for getting battery level, sure you could use retain or you could just request it at HA startup. There’s a trigger for that. As long as the client is available to request the data you should have no problem. You can even just request it every so often (if need be).

This describes my issue well but how do you actually get HA to do the request on start up or periodically?

In my particular case, I’m using Sonoff temperature and humidity sensors via a Sonoff ZigBee bridge.
It can take a very long time after a reload of HA config to get the first values.

There are triggers that allow you to fire off automations at boot or restart.

- alias: name here
  trigger: 
      platform: homeassistant
      event: start
  action:
    - service: your script/scene/whatever here

HTH

you could use retain, the nice thing is that if the value is the same the device just doesn’t send a new message. Part of the beauty of MQTT.

only if someone programmed it this way
and not always it is desired i.e. if your temperature or voltage did not update on HA you might not know: sensor died due to battery or something else
no, not always desired behaviour

that’s what last will and testament is for