MQTT Multiple-Sensor JSON Messages : Why falling back to zero when sending single sensor-values - Is retaining of other values possible?

In my application I send multiple sensor-values typically together in one go.
For example I send three sensors in one JSON-Message:

{"kitchen_temp":18.8,"kitchen_humd":33,"kitchen_brightness":1400} 

as a MQTT-Message to the topic ‘/kitchen/sensors’

This is all well handled after having sent the MQTT configuration messages earlier:
/kitchen/config {"name":"Temperature     (Kitchen)","unique_id":"kitchen_temp","object_id":"kitchen_temp","state_topic":"/kitchen/sensors","value_template":"{{value_json.kitchen_temp}}","device_class":"temperature","unit_of_measurement":"°C", ...,..}
/kitchen/config {"name":"Humidity        (Kitchen)","unique_id":"kitchen_humd","object_id":"kitchen_humd","state_topic":"/kitchen/sensors","value_template":"{{value_json.kitchen_humd}}","device_class":"humidity","unit_of_measurement":"%" ...,..}
/kitchen/config {"name":"Lightbrightness (Kitchen)","unique_id":"kitchen_brightness","object_id":"kitchen_brightness","state_topic":"/kitchen/sensors","value_template":"{{value_json.kitchen_brightness}}","device_class":"illuminance","unit_of_measurement":"L", ...,..}

(Some of the fields are not included here in this explanation-example to make this post more readable)

Now I want to send an alarming change in the Temperature and send an MQTT-message with only the value for Temperature.
So I send :

{"kitchen_temp":26.4} 

to the same topic ‘/kitchen/sensors’
I expected that only the value of the Temperature-sensor gets updated with the new value, which it does, but I notice also that in doing so the sensor-values of ALL OTHER values for ‘kitchen’ set to ‘0’ (zero), so only if the complete message comes which is sent at regular intervals the value of Humidity and Brightness are restored to its current value again, after sending a single sensor-value they are set to zero.

My question is how I can achieve that the other values do NOT get lost when only one sensor value is sent.
One could suggest just to send all of them again and problem solved, but in my system I have much more sensors in one area, and to use it as a trigger in an automation
since as a single value it is clear the alarm is related to the Temperature, as mentioned in this example.

I am surprised that things go to 0 since there is no value in the message with a 0 of these other sensors. They are only not there in the last message, but they are configured (!) and do have a current value.
So I would like to have a behaviour such that I can feed one or more sensor-values and with no new values that the old ones are still valid.
Is there any setting for that, or should I send all the sensor values as separate messages, giving more strain on the application.
Advice is welcome.

No there’s no setting for that. It’s really designed where one topic sets the state of one entity. I think you have a couple options:

  1. Pick a topic per sensor, don’t share
  2. Don’t just pass kitchen_temp. Also pass the current values for the other kitchen devices even though they haven’t updated. Your application will have to keep track of that.
  3. Kind of hack it with value_template. value_template is supposed to set the state from value or value_json. But nothing stops it from looking at the state of other entities, including its own state. So you could do something like this:
{{value_json.kitchen_temp | default(states('sensor.kitchen_temp') | float(0)) }}

So basically if kitchen_temp is missing it falls back on its own state.

Note that the last bit float(0) is important. Not sure if you’re aware of this yet since it seems like your stuck on a different part but MQTT entities don’t restore state. After a restart of HA or a reload of the MQTT integration all the entities will have state unknown until the next time an MQTT message comes in on the topic its watching. So if immediately after a restart you send a message like this:

{"kitchen_temp":26.4} 

The temperature and light brightness sensors are going to have a problem. A message came in that triggers them to update their state but it has no value for them and their current state is unknown (non-numeric). float(0) will cause it to default to 0 in these cases.

That may throw off your history though, not sure how long it is between updates with these devices. If that’s a problem then you’d have to use an availability_template to make sure the sensors were unavailable when the message didn’t include a state update for them and their previous state is not numeric. Or use option 1 or 2 above instead.

Woow, impressed with your knowledge and speed of answering my question.
Indeed three options. I am tempted to try Option 3. This since I like to look at the stream of MQTT Messages of my MQTT server and notice that indeed a separate single value is sent. Also I guess that is easier when defining a trigger for automation, but maybe that handles multiple values just as well. I have to study that more, since I do not understand how that works exactly using advanced templates, which are like regular expressions (I never could grasp them), so I like to keep it as simple as possible. But a one time ‘hacky’ configuration of suggested by you in Option 3 would allow me to leave the rest the same.Since I program that in, I only have to change the code for the /config a bit more. If that works, then as stated, the automation for an Alarm is easier to implement (for me at least). It also gives me a greater insight in how things work. Option 1 crossed my mind, but I like to see them coming in together (visual feedback) so that is why I embarked on Multiple Sensors in the JSON-message. Option 2 I indeed suggested, but it looses the ‘exception’ aspect of one value in visual terms.
As stated complete sets of sensors are sent at regular intervals all together. So a reboot of HA should not be a problem.
Thanks a lot Mike. It is nice to feel some support it works like Red Bulll, only less sugar. !

1 Like