MQTT sensor "blinking" when payload doesn't always contain value?

Maybe someone here has a good idea how to resolve this…

I’m using RTL2MQTT addon to pull in a bunch of Acurite sensors. This works great…but I just got a new weather station for Christmas and it sends the information over 3 messages.

Problem is when I make the MQTT sensors for the payload data, it “blinks” out because apparently unlike basic temp sensors, not all the data is in every message but they are all published to the same station/object ID.

Here’s what it sends:

{
"time" : "2021-01-29 09:26:27",
"model" : "Acurite-Atlas",
"id" : 1234,
"channel" : "C",
"sequence_num" : 0,
"battery_ok" : 1,
"message_type" : 37,
"wind_avg_mi_h" : 3.000,
"temperature_F" : 26.200,
"humidity" : 45,
"strike_count" : 0,
"strike_distance" : 31,
"exception" : 0,
"raw_msg" : "01e76581c5962d009ff5"
}

{
"time" : "2021-01-29 09:40:17",
"model" : "Acurite-Atlas",
"id" : 1234,
"channel" : "C",
"sequence_num" : 0,
"battery_ok" : 1,
"message_type" : 39,
"wind_avg_mi_h" : 5.000,
"uv" : 1,
"lux" : 15810,
"strike_count" : 0,
"strike_distance" : 31,
"exception" : 0,
"raw_msg" : "05e7e782410c2d009f6e"
}

{
"time" : "2021-01-29 09:46:07",
"model" : "Acurite-Atlas",
"id" : 1234,
"channel" : "C",
"sequence_num" : 2,
"battery_ok" : 1,
"message_type" : 38,
"wind_avg_mi_h" : 4.000,
"wind_dir_deg" : 223.000,
"rain_in" : 0.150,
"strike_count" : 0,
"strike_distance" : 31,
"exception" : 0,
"raw_msg" : "09e7668206fc0f009f88"
}

And here’s the YAML I am trying to use:

sensor:

  - platform: mqtt
    name: "Wx Station Temperature"
    unique_id: "wx_station_temperature"
    force_update: true
    state_topic: "homeassistant/sensor/rtl433/Acurite-Atlas/1234"
    # Yes, this really reports in F not C unlike other Acurite sensors
    unit_of_measurement: '°F'
    value_template: "{{ value_json.temperature_F }}"

I was hoping if it was missing the field in the value_template somehow it would just “skip” that message but apparently it doesn’t work that way. I’m not sure if there is a “neat” way to do this without a horribly convoluted “store the value somewhere else and feed it back into itself if it is missing” process of template nonsense.

EDIT: Oops, also the “sequence number” is not useful…that’s just it resends the same message 3x each to compensate for errors or something.

Will the firmware allow you to change the MQTT to ‘retain’?
If not, then you might have to make some intermediate sensors to ‘store’ the value.
The reason it blinks out is that the data is not retained on the MQTT broker, so when it goes to read the data is not actually there.

So my understanding is the messages are split due to FCC rules it can only send X long Y often on 433MHz unlicensed and they can’t fit all the data in.

The RTL2MQTT just decodes the RF transmissions and pushes them out over MQTT as-is…there’s no “retain” it just shovels data as it comes. I don’t know if there is a way to change the behavior of that or not.

Link to the addon info that publishes:

Also this is not the only thing it’s publishing…it pushes a LOT of different sensors I have so I need to make sure changes don’t break the others.

If you can’t set the MQTT to retain, you can make your own work around by creating a sensor that updates the value from your MQTT data when available and don’t change it when it is not available, so you always have a reading. A value_template in a sensor with some if statements will work; it would be easier if you added an availability_template to your MQTT sensor.

That would only happen when Home Assistant disconnects/reconnects to the MQTT Broker (i.e. whenever either Home Assistant or the MQTT Broker is restarted).


@mmiller7
The issue here is that the payload published to the topic doesn’t always include the temperature. However, the MQTT Sensor is configured to always expect a temperature within the payload.

When it doesn’t get one, the template fails to produce a value. The sensor’s graph displays an absence of a value whenever one wasn’t received.

The solution is to enhance the template so that whenever there is no reported temperature in the received payload, the template simply reports its existing value.

Try this:

sensor:
  - platform: mqtt
    name: "Wx Station Temperature"
    unique_id: "wx_station_temperature"
    force_update: true
    state_topic: "homeassistant/sensor/rtl433/Acurite-Atlas/1234"
    unit_of_measurement: '°F'
    value_template: >
      {% if value_json.temperature_F is defined %}
        {{ value_json.temperature_F }}
      {% else %}
        {{ states('sensor.wx_station_temperature') }}
      {% endif %}
4 Likes

Are there multiple temperature sensors or just one?

If you have multiple temperature sensors, whose data is published to the same topic, you will need to adopt a strategy for demultiplexing it (i.e. assigning received data to the correct MQTT Sensor).

I proposed two ways of handling the issue in this topic. It’s for a Sonoff RF Bridge but the strategies remain the same for any device that multiplexes data from several sensors into a single MQTT topic.

My other things are all on different topics, this is the first time I have encountered this issue of “same topic” so far.

Can that be done as one sensor, or will I need 2+ sensors (one to pull it out, one to copy that over if available)?

As a programmer, the one proposed solution by @123 makes sense to me but if there’s an easy “better” way that I am not aware of and scales fairly easily (eventually I want to break ALL the sensor data out the weather station sends) I am open to considering other options, whatever ends up being the least “messy”. I dislike how intermediate sensors effectively feel like “global variables” and makes a mess looking for a specific one when there are too many almost-identical ones.

Will ‘availability template’ make it hold the last when its not available and simply skip the update, or would it then blink between “unavailable” and the temperature?

@123 just accomplished what I was saying in a more elegant way. I didn’t realize you could have a sensor refer to itself; that makes it a lot easier and less messy.

My idea was for an if statement to see if the sensor was marked unavailable then don’t change the value, ‘else’ read the new MQTT data. I would go with @123 since it is nice and concise. He ‘effectively’ uses an availability_template but build into the value_template.

Now I think I may go back and redo some of my sensors.

1 Like

Ah, yes I was aware you could do that (from working around random bad values some stuff sends) but I was hoping that “does it exist” had a more elegant way…kind of like how “condition” can negate the trigger of an automation was what I hoped to find but for sensor updates.

Since the if/else returning itself sounds like the best option I’ll go with that as my solution.

Thanks everyone!