Template sensor based on mqtt data?

Could someone help me figure out how to setup a sensor/automation that gets a message like below from mqtt, and then returns the temp in F (76.1 in the example)to a specific sensor based on the field channel? So for the mqtt below, I’d want a sensor that reflects the temp when channel=6 and can likely ignore the sensor ID value since that changes when I change sensor batteries but the channel number 6 won’t change.

{“time”:“2021-07-28 17:37:48”,“protocol”:113,“model”:“AmbientWeather-WH31E”,“id”:238,“channel”:6,“battery_ok”:1,“temperature_F”:76.1,“humidity”:63,“data”:“f400000000”,“mic”:“CRC”,“mod”:“FSK”,“freq1”:433.99008,“freq2”:433.83955,“rssi”:-0.117954,“snr”:8.17913,“noise”:-8.29708}

My old system using 433mhz sensors that didn’t have channel numbers was all ID based which sucked since I had to remap the sensors anytime I changed the batteries.

The template editor in Developer Tools section of the HA user interface is your friend.

Not sure if this helps or not, but try this in the template editor

{% set value_json={"time": "2021 - 07 - 28 17: 37: 48","protocol": 113,"model": "AmbientWeather - WH31E","id": 238,"channel": 6,"battery_ok": 1,"temperature_F": 76.1,"humidity": 63,"data": "f400000000","mic": "CRC","mod": "FSK","freq1": 433.99008,"freq2": 433.83955,"rssi": -0.117954,"snr": 8.17913,"noise": -8.29708} %}

{% if value_json.channel == 6 %}
  {{ value_json.temperature_F }}
{% else %}
  Ignore
{%endif %}

You can then play around the JSON payload in the first line until you get your template correct.

All you need to do is create an MQTT Sensor.

Set its value_template to extract the value of the temperature_F key from the received payload but only if the channel key’s value is 6 (otherwise make it report its current value).

sensor:
  - platform: mqtt
    name: Outdoor Temperature
    state_topic: whatever/433mhz/gadget
    unit_of_measurement: '°F'
    device_class: temperature
    value_template: "{{ value_json.temperature_F if value_json.channel == 6 else states('sensor.outdoor_temperature') }}"
1 Like

Hmm ok will give this a whirl.

I have an automation as such, since my rPi running rtl_433 just dumps a bunch of sensors all to a single topic. I tried adding the example code that’s commented out to record more steps for troubleshooting but the automation won’t start if I uncomment those lines, but the config checker didn’t return any errors.

- id: '1627508815362'
  alias: 433 TempChannel Multiplexer
 # traces:
 #  - stored_traces: 50
  description: ''
  trigger:
  - platform: mqtt
    topic: home/433
  condition: []
  action:
  - service: mqtt.publish
    data_template:
      topic: '{{ ''home/sensor'' + trigger.payload_json.channel | s$
      payload: '{{trigger.payload}}'
  mode: single


Which I’m hoping republishes the data as a unique topic per sensor(well channel).

Based on my longstanding automation that did this is below, but it created a new topic by the “Id” in the sensor which changes when you change the batteries, and not all my sensors have the channel dip switches I later discovered.


- id: 433_demux                                                     
  alias: rtl_433 demultiplexer                                      
  initial_state: true                                               
  trigger:                                                          
    platform: mqtt                                                  
    topic: home/433                                                 
  action:                                                           
    service: mqtt.publish                                           
    data_template:                                                  
      topic: '{{ ''home/sensor'' + trigger.payload_json.id | string$
      payload: '{{trigger.payload}}'  

I don’t know if you had a chance to read this but it might give you some ideas if you ever use 433MHz binary sensors (the article is applicable for any MQTT-based 433 MHz receiver, not just the Sonoff RF Bridge).

If you use this to demultiplex the topic’s payload:

- id: '1627508815362'
  alias: 433 TempChannel Multiplexer
  trigger:
  - platform: mqtt
    topic: home/433
  action:
  - service: mqtt.publish
    data:
      topic: 'home/sensor{{ trigger.payload_json.channel }}'
      payload: '{{ trigger.payload }}'
  mode: single

then you can use this for the sensor:

sensor:
  - platform: mqtt
    name: Outdoor Temperature
    state_topic: home/sensor6
    unit_of_measurement: '°F'
    device_class: temperature
    value_template: '{{ value_json.temperature_F  }}'

Okay, the automation republished this as topic home/sensor6


{"time":"2021-07-28 21:27:42","protocol":113,"model":"AmbientWeather-WH31E","id":238,"channel":6,"battery_ok":1,"temperature_F":55.58,"humidity":44,"data":"7600000000","mic":"CRC","mod":"FSK","freq1":433.9768,"freq2":433.84298,"rssi":-0.13023,"snr":13.01577,"noise":-13.146}

But my mqtt sensor isn’t showing anything.


- platform: mqtt
    name: "GarageFridge6"
    state_topic: "home/sensor6"
    device_class: temperature
    value_template: "{{ value_json.temperature_F if value_json.channel == 6 else states('sensor.GarageFridge6') }}"
# value_template: "{{value_json.temperature_F}}"
    unit_of_measurement: 'F'



If the sensor’s configuration looks exactly the way you posted it, then it has an indentation error. Compare with the example I posted above.

Also, check the appearance of the payload published to home/sensor6. Ideally, check it with an MQTT client like MQTT Explorer. Just noticed you already looked at it.

The sensor’s template can be shortened, like in the recent example I posted, because now it no longer needs to check the channel.

sensor:
  - platform: mqtt
    name: GarageFridge6
    state_topic: home/sensor6
    unit_of_measurement: '°F'
    device_class: temperature
    value_template: '{{ value_json.temperature_F  }}'

Just tested the automation and sensor examples I suggested and they appear to work as desired:

The Unit System for my Home Assistant is set to Metric so the 55.58 degrees Fahrenheit is automatically converted to 13.1 Celsius.

Aha, I had forgotten that I whitelisted sensors in the recorder setup, so it wasn’t displaying on the history graph card I use… worked like a charm now.

1 Like

Glad to hear it.

Please consider marking my post (above) with the Solution tag. It will automatically place a check-mark next to the topic’s title which signals to other users that this topic has been resolved. It will also place a link below your first post that leads to the solution post. All of this helps users find answers to similar questions.

could someone help to create a virtual sensor in HA based on MQTT data? I can`t extract the needed data for sensor :
in my MQTT broker, I receive :

ybapart_zb-broker
    LWT = Online
    SENSOR = {"ZbReceived":{"0xAFEA":{"Device":"0xAFEA","Temperature":26.63,"Humidity":51.79,"Pressure":981,"PressureScale":-1,"PressureScaledValue":9816,"SeaPressure":981,"Endpoint":1,"LinkQuality":94}}}

for sensor I need to extract: device ID (“0xAFEA”) and Temperature float data

so I try to create sensor in configuration.yaml →

"
mqtt:
 sensor:
   - name: "apart1_Temp"
     unique_id: apart1_temp
     device_class: "temperature"
     state_topic: "tele/ybapart_zb-broker/SENSOR"
     unit_of_measurement: "°C"
     value_template: "{{ value_json.ZbReceived.0xAFEA.Temperature }}"
"

but it doesn’t work

seems like something is wrong in value_templeate: or ??

Yes. For keys starting with digits you must use bracket notation:

     value_template: "{{ value_json['ZbReceived']['0xAFEA']['Temperature'] }}"

In this case, it’s translating the hex number and looking for the 45034th element; if the key starting with a digit isn’t “translatable” it just breaks:

Dot notation also can’t be used where the key is a function name on the object:

Safer to use bracket notation all the time to avoid such issues.

1 Like

great thanks
now its works