MQTT - topic - help

I have 1 topic, but with 4 different sensors.
Is there a way to create a template to get the differing data?

home/rtl_433 {"time" : "2019-02-10 13:50:09", "brand" : "OS", "model" : "PCR800", "id" : 253, "channel" : 0, "battery" : "OK", "rain_rate" : 0.010, "rain_total" : 1.272}

home/rtl_433 {"time" : "2019-02-10 13:50:22", "brand" : "OS", "model" : "WGR800", "id" : 187, "channel" : 0, "battery" : "OK", "gust" : 1.500, "average" : 1.100, "direction" : 180.000}

home/rtl_433 {"time" : "2019-02-10 13:50:56", "brand" : "OS", "model" : "THGR810", "id" : 55, "channel" : 1, "battery" : "OK", "temperature_C" : 29.100, "humidity" : 19}

home/rtl_433 {"time" : "2019-02-10 13:50:16", "model" : "Acurite tower sensor", "id" : 11794, "sensor_id" : 11794, "channel" : "A", "temperature_C" : 24.000, "humidity" : 33, "battery_low" : 0}

for example, the first entry, require ‘rain rate’

Just configure an MQTT sensor

I have this mqtt sensors for rtl_433 devices.

  - platform: mqtt
    state_topic: "home/rtl_433"
    name: "Aussen Humi Nexus"
    unit_of_measurement: "%"
    value_template: >
      {% if value_json is defined and value_json.id == 138 %}
        {{ value_json.humidity }}
      {% else %}
        {{ states('sensor.aussen_humi_nexus') }}
      {% endif %}

The template checks for the id of the sensor and if there is another id, the sensor gets his own value.

1 Like

Here are two ways to handle the messages from the single topic (home/rtl_433).

1 - Each sensor is subscribed to the same topic.
Example: Five sensors.

All five sensors are subscribed to the same topic (home/rtl_433). Each sensor examines the received message and determines if it belongs to it.

home/rtl_433 ==> Sensor1 (Is this message for me?)
home/rtl_433 ==> Sensor2 (Is this message for me?)
home/rtl_433 ==> Sensor3 (Is this message for me?)
home/rtl_433 ==> Sensor4 (Is this message for me?)
home/rtl_433 ==> Sensor5 (Is this message for me?)

2 - An automation separates the single multiplexed topic (home/rtl_433) into separate topics; it creates one topic per sensor.
Example: Five sensors.

The automation is a demultiplexer (DEMUX). Its trigger is subscribed to one topic (home/rtl_433). In its action it examines the received message, determines which one of the five sensors it belongs to, and publishes it to the sensor’s dedicated topic.

The five sensors are subscribed to their dedicated topics and only receive messages meant for them.

home/rtl_433 ==> DEMUX ----> home/sensor1
                       |
                       |---> home/sensor2
                       |
                       |---> home/sensor3
                       |
                       |---> home/sensor4
                       |
                       |---> home/sensor5

home/sensor1 ==> Sensor1
home/sensor2 ==> Sensor2
home/sensor3 ==> Sensor3
home/sensor4 ==> Sensor4
home/sensor5 ==> Sensor5

The demultiplexing function can be done with an automation or, if you are already using Node-red, with a Node-red flow.

1 Like

Great, that works - thanks VDRainer

In case anyone is interested in using the demultiplexer solution, here is the needed automation and examples of how to configure the sensors. This has been tested and proven to work using the four JSON messages shown above.

In automations.yaml:

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

Because the demultiplexer creates one topic per sensor, it simplifies the configuration of each sensor.

In sensors.yaml:

  - platform: mqtt
    name: "Sensor 1"
    state_topic: "home/sensor253"
    value_template: "{{value_json.rain_rate}}"

  - platform: mqtt
    name: "Sensor 2"
    state_topic: "home/sensor187"
    value_template: "{{value_json.gust}}"

  - platform: mqtt
    name: "Sensor 3"
    state_topic: "home/sensor55"
    value_template: "{{value_json.temperature_C}}"
    unit_of_measurement: '°C'

  - platform: mqtt
    name: "Sensor 4"
    state_topic: "home/sensor11794"
    value_template: "{{value_json.temperature_C}}"
    unit_of_measurement: '°C'

Sensors


EDIT
One advantage of the demultiplexer solution is the ability to publish retained messages (just add retain: true in the automation’s action section). Now when Home Assistant restarts and re-subscribes to each sensor topic, it receives the last published value for each sensor.

4 Likes

As an aside, might need to post under templates?
Trying to get compass direction entered from wind direction, was working, but now not!

  value_template: >
    {% if value_json is defined and value_json.id == 187 %}
      {{ value_json.direction }} 
    {% else %}       
      {{ states('sensor.wind_direction') }}
    {% endif %} 

trying to add this

 value_template: >-
      {%if states.sensor.wind_direction.state | float<=11 %}North
      {% elif states.sensor.wind_direction.state | float>348 %}North
      {% elif states.sensor.wind_direction.state | float<=34 | float>11 %}North North East
      {% elif states.sensor.wind_direction.state | float<=56 | float>34 %}North East
      {% elif states.sensor.wind_direction.state | float<=79 | float>56 %}East North East
      {% elif states.sensor.wind_direction.state | float<=101 | float>79 %}East
      {% elif states.sensor.wind_direction.state | float<=124 | float>101 %}East South East
      {% elif states.sensor.wind_direction.state | float<=146 | float>124 %}South East
      {% elif states.sensor.wind_direction.state | float<=169 | float>146 %}South South East
      {% elif states.sensor.wind_direction.state | float<=191 | float>169 %}South
      {% elif states.sensor.wind_direction.state | float<=214 | float>191 %}South South West
      {% elif states.sensor.wind_direction.state | float<=236 | float>214 %}South West
      {% elif states.sensor.wind_direction.state | float<=259 | float>236 %}West South West
      {% elif states.sensor.wind_direction.state | float<=281 | float>259 %}West
      {% elif states.sensor.wind_direction.state | float<=304 | float>281 %}West North West
      {% elif states.sensor.wind_direction.state | float<=326 | float>304 %}West North West
      {% elif states.sensor.wind_direction.state | float<=348 | float>326 %}North North West
      {%- endif %}

I used the Template Editor to confirm that this works:

 value_template: >-
      {% set wd = states('sensor.wind_direction') | int %}
      {% if wd <= 11 or wd > 348 %}North
      {% elif wd >11 and wd <=34 %}North North East
      {% elif wd >34 and wd <=56 %}North East
      {% elif wd >56 and wd <=79 %}East North East
      {% elif wd >79 and wd <=101 %}East
      {% elif wd >101 and wd <=124 %}East South East
      {% elif wd >124 and wd <=146 %}South East
      {% elif wd >146 and wd <=169 %}South South East
      {% elif wd >169 and wd <=191 %}South
      {% elif wd >191 and wd <=214 %}South South West
      {% elif wd >214 and wd <=236 %}South West
      {% elif wd >236 and wd <=259 %}West South West
      {% elif wd >259 and wd <=281 %}West
      {% elif wd >281 and wd <=304 %}West North West
      {% elif wd >304 and wd <=326 %}West North West
      {% elif wd >326 and wd <=348 %}North North West
      {% endif %}

Thanks 123
but how do I get the data into it in the first place?

  value_template: >-
    {% if value_json is defined and value_json.id == 187 %}
      {{ value_json.direction }} 
    {% endif %}
    {%if states.sensor.wind_direction.state | float<=11 %}North
    {% elif states.sensor.wind_direction.state | float>348 %}North
    {% elif states.sensor.wind_direction.state | float<=34 | float>11 %}North North East
.
.

doesn’t work

I misunderstood; I thought you were going to do something else. Anyway, how about this?

  value_template: >-
    {% if value_json is defined and value_json.id == 187 %}
      {% set wd = value_json.direction | int %}
      {% if wd <= 11 or wd > 348 %}North
      {% elif wd >11 and wd <=34 %}North North East
      {% elif wd >34 and wd <=56 %}North East
      {% elif wd >56 and wd <=79 %}East North East
      {% elif wd >79 and wd <=101 %}East
      {% elif wd >101 and wd <=124 %}East South East
      {% elif wd >124 and wd <=146 %}South East
      {% elif wd >146 and wd <=169 %}South South East
      {% elif wd >169 and wd <=191 %}South
      {% elif wd >191 and wd <=214 %}South South West
      {% elif wd >214 and wd <=236 %}South West
      {% elif wd >236 and wd <=259 %}West South West
      {% elif wd >259 and wd <=281 %}West
      {% elif wd >281 and wd <=304 %}West North West
      {% elif wd >304 and wd <=326 %}West North West
      {% elif wd >326 and wd <=348 %}North North West
      {% endif %}
    {% else %}       
      {{ states('sensor.wind_direction') }}
    {% endif %} 
1 Like

Thanks 123 - works great

This works fantastically.

I now am passing messages from both rtl_433 and rtlamr to mqtt. The 433 stuff is a breeze with your code to demux it. I’m stuck on the rtlamr. The json is setup differently. These messages look like:

{“Time”:“2019-06-06T22:36:26.868755773-04:00”,“Offset”:0,“Length”:0,“Type”:“SCM”,“Message”:{“ID”:48446577,“Type”:12,“TamperPhy”:0,“TamperEnc”:0,“Consumption”:614874,“ChecksumVal”:26890}}

What do I change (or create a second automation) to pull out the Consumption value and push that to mqtt with the ID?

Thanks.

- alias: 'rtlamr demultiplexer'
  hide_entity: true
  trigger:
    platform: mqtt
    topic: home/rtlamr
  action:
    service: mqtt.publish
    data_template:
      topic: "{{ 'home/sensor' + trigger.payload_json.message.id|string }}"
      payload: "{{trigger.payload_json.message.consumption}}"

and

- platform: mqtt
    name: "Sensor 1"
    state_topic: "home/sensor48446577"

you need to change trigger’s topic according to your situation.
and my assumption is codes of rtf_433 and rtlamr do not collide.

Looks good but fix the template in the payload: option. Your fingers were moving so fast that they overlooked to include _json in the template. :slight_smile:

      payload: "{{trigger.payload_json.message.consumption}}"
                                 ^^^^^

No luck. IDs are unique in mqtt but layout of json isn’t. All my 433mhz temp sensors show in HA fine.

HA error logged:
2019-06-07 20:46:10 ERROR (MainThread) [homeassistant.helpers.service] Error rendering data template: UndefinedError: ‘dict object’ has no attribute ‘message’

Mqtt message sent from rtlamr is below when I subscript to that topic with another tool:

{“Time”:“2019-06-07T20:28:56.553509617-04:00”,“Offset”:0,“Length”:0,“Type”:“SCM”,“Message”:{“ID”:48446577,“Type”:12,“TamperPhy”:0,“TamperEnc”:0,“Consumption”:614950,“ChecksumVal”:37409}}

Automations.yaml is

  • id: 433_demux
    alias: rtl_433 demultiplexer
    hide_entity: true
    initial_state: true
    trigger:
    platform: mqtt
    topic: Greenbrier433/projpi
    action:
    service: mqtt.publish
    data_template:
    topic: ‘{{ ‘‘home/sensor’’ + trigger.payload_json.id|string }}’
    payload: ‘{{trigger.payload}}’
  • id: rtlamr_demux
    alias: rtlamr demultiplexer
    hide_entity: true
    initial_state: true
    trigger:
    platform: mqtt
    topic: Greenbrier433/projpi
    action:
    service: mqtt.publish
    data_template:
    topic: ‘{{ ‘‘home/sensor’’ + trigger.payload_json.message.id|string }}’
    payload: ‘{{trigger.payload_json.message.consumption}}’

The JSON data uses key words containing upper and lowercase letters:

{"Time":"2019-06-07T20:28:56.553509617-04:00","Offset":0,"Length":0,"Type":"SCM","Message":{"ID":48446577,"Type":12,"TamperPhy":0,"TamperEnc":0,"Consumption":614950,"ChecksumVal":37409}}

The template has to refer to the key words precisely as they appear in the JSON data.

Modify the topic and payload templates to match the ones shown below:

- alias: 'rtlamr demultiplexer'
  hide_entity: true
  trigger:
    platform: mqtt
    topic: home/rtlamr
  action:
    service: mqtt.publish
    data_template:
      topic: "{{ 'home/sensor' + trigger.payload_json.Message.ID | string }}"
      payload: "{{trigger.payload_json.Message.Consumption}}"

I also noticed that you are have two automations, both are subscribed to the same topic Greenbrier433/projpi but the JSON payload each one receives is not in the same format? Did I understand that correctly?

If that’s the case, this is not an effective arrangement. The two automations should be subscribed to separate topics, not the same one.

Awesome. I switched the script that does the listening and put the 433 sensors and the rtlamr output in different topics.

No errors now, my 433 stuff flows into HA but my rtlamr stuff just doesn’t show up.

Interestingly, none of my working 433 or my non working rtlamr mqtt sensors show up in the entity registry. But the 433’s graph on a Lovelace card just fine, and the rtlamr sensors show up as entities on a Lovelace card just with no data.

I’ve also noticed that while both mqtt topics are json data, the 433 stuff has an automation payload of just

payload: ‘{{trigger.payload}}’

Which works fine

But the rtlamr automation has a payload of

Payload: ‘{{trigger.payload_json.Message.Consumption}}’

Should I scale the rtlamr payload back to just trigger.payload and then parse the piece I want in the sensor.yaml value template instead?

Putting the payload alone in the automation and then using the sensor to specific which piece to show worked! Not sure why the other way didn’t but thank you for all the input that got me connecting the dots!

that happens if you use data: instead of data_template: or do not enclose your template {{trigger.payload_json.Message.Consumption}} in single/double quotes, i.e no template resolution is happening, it literally uses what it gets