Mqtt.py log warning "No matching payload found for entity"

I’m using 0.90.1 and can confirm that the solution I provided above does not need a custom MQTT component. My MQTT binary_sensor is using the 0.90.1 release version of the MQTT component and, with my suggested solution, the sensors do not cause the “No matching payload …” message to appear.

BTW, if you are using OpenMQTTGateway , there’s a post within this thread, by @1technophile , explaining how to make it publish to one topic per sensor. If you make his suggested modification, there’s no need for demultiplexing.

Well, it’s one topic per value as far as I understood. I have a door sensor that sends 2 codes, and I would need a binary_sensor subscribed to these 2 topics (can this even be done?).
Anyway, the demultiplexer solution gives me more control and with less configuration in home assistant.

I may have stumbled upon your post about the automation demultiplexer while trying to figure this out and this was what inspired me to go this route.
So, for that, I want to say thanks :slight_smile:

1 Like

I also use Node-red and, when I first encountered this issue, my first thought was to create a flow to demultiplex the MQTT topic. Then I challenged myself to create an automation to do it … and it was easier than I thought. Whether Node-red or an automation, as long as it gets the job done.

Apparently that “topic per value” approach is best suitable suitable for one-code devices.
But in a case like yours there’s still hope.
For example, you can create 2 automations (each subscribe to its topic) that change state of an input_boolean, and a template sensor that reflects its state if you prefer something fancier that a toggle switch in your GUI.
I haven’t tired it yet (too many devices to convert), but it should work.

I believe there are other ways to do that, anyone?

If not upgrading that often, can still do brain surgery with a hammer and modify the binary_sensor.py directly in the site-packages folder :slight_smile: It will be overwritten each time a new HA version is installed, though.

Best way to solve this is to reverse the PR that introduced the warning in the first place.

I started from there, but read this and my next post.

Ok, I think I got it, thanks to @123 .

An MQTT binary sensor HAS to know its state, and it can be done either by providing value_template that returns ON/OFF (default payload_on/payload_off values) OR making sure payload_on and payload_off are the only values that being published to that topic.
Having only payload_on and payload_off defined and allowing something that is not matched by above mentioned payloads to be published to that topic triggers that warning.
So basically that warning means: look, your MQTT switch received a message, but couldn’t react (as there is no corresponding rule in a form of payload_xxx OR value_template ), something is wrong with your configuration.
Pretty obvious, isn’t it.

And there are at least 3 ways to get rid of that warning with binary_sensors:

  1. Provide value_template definition that returns only ON/OFF
  2. Provide payload_on and payload_off AND make sure these are the only 2 values that are allowed in that topic.
  3. Provide value_template definition that returns only payload_on or payload_off values

I’m off to fix my switches :wink:

But it’s not wrong :slight_smile: OpenMQTT binary sensors work fine while removing the four lines in the binary_sensor.py.

Anyway, I can’t test it but for binary sensors that only use one value (switches, PIR sensors) an automation that forwards each payload into its separate mqtt topic could be used and then change the binary sensor topic (for open door sensors or other devices that send two codes it needs templating).

- platform: "mqtt"
  name: "friendly_name"
  state_topic: "home/433toMQTT/code_from_device"
  payload_on: 'code_from_device'
  payload_off: 'off'
  force_update: true
  off_delay: 1


- alias: OpenMQTT forward
  initial_state: True
  trigger:
    - platform: mqtt
      topic: 'home/433toMQTT'
  action:
    - service: mqtt.publish
      data_template:
        topic: 'home/433toMQTT/{{trigger.payload}}'
        payload_template: '{{ trigger.payload}}'

yes, it’s not wrong.
I presume the author just wanted to make easier debugging situations like “Why on Earth my sensor is not working?!” as potentially that can happen.
And yes, you can get rid of these warnings just by fixing your config and not touching the HA code, result!

yes, there are many ways to skin a cat :wink:
I use input_booleans and this automation (one per device)

- alias: "[int] pir__catch_code__groung_floor__hall"
  initial_state: true
  trigger:
    platform: mqtt
    topic: !secret rf_bridge__topic
  condition:
    condition: template
    value_template: "{{ (trigger.payload_json['value'] == 13937454) and (states.input_boolean.pir_groung_floor_hall.state == 'off') }}"
  action:
  - service: input_boolean.turn_on
    data:
      entity_id: input_boolean.pir_groung_floor_hall
  - delay: !secret pir__reset_indicator_interval
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.pir_groung_floor_hall

but maybe it’s time to enable value as topic suffix and replace it with MQTT binary sensor with off_delay…

UPDATE: here is my version for PIRs - instead of input_boolean and automation I can have just

- platform: mqtt
  name: pir_1st_floor_landing
  state_topic: !secret pir_1st_floor_landing_topic
  value_template: 'ON'
  device_class: motion # this bit can be moved to customize_glob.yaml for all pir_*
  off_delay: !secret pir_off_delay

I like it!

I imagine the automation you posted was meant to represent the concept and not a working example? These lines below will produce a horrendously long MQTT topic because the typical payload is a long string in JSON format.

    - service: mqtt.publish
      data_template:
        topic: 'home/433toMQTT/{{trigger.payload}}'
        payload_template: '{{ trigger.payload}}'

Ideally, you want to demultiplex tele/rf_bridge/RESULT using each sensor’s unique identifier, or its unique payload, instead of its entire payload. I’ve already supplied links to two other relevant examples of demultiplexer automations (see above), but it’s worth repeating at least one of them.

In this post, the assumption is the RF buttons are uniquely identified by Sync.

  - alias: 'sonoff bridge demultiplexer'
    hide_entity: true
    trigger:
      platform: mqtt
      topic: tele/sonoff/RESULT
    action:
      service: mqtt.publish
      data_template:
        topic: "home/button/{{trigger.payload_json.RfReceived.Sync|string }}"
        payload: 'ON'

Binary_sensors are defined for each RF button:

  - platform: mqtt
    name: "Button 1"
    state_topic: "home/button/13550" # <--- 13550 comes from Sync
    off_delay: 1

  - platform: mqtt
    name: "Button 2"
    state_topic: "home/button/13560"
    off_delay: 1

If Sync can’t be used to uniquely identify the RF device, then the recourse is to use the device’s payload which is often represented by Data.

    action:
      service: mqtt.publish
      data_template:
        topic: "home/button/{{trigger.payload_json.RfReceived.Data|string }}"
        payload: 'ON'
  - platform: mqtt
    name: "Button 1"
    state_topic: "home/button/2B4AC"
    off_delay: 1

This works as long as the RF devices only report when they are on and not off such as certain models of motion sensor, RF button, and contact sensor (that’s the same constraint you mentioned for your automation example).

If the RF devices report both their on and off states (two payloads), yet have no unique identifier within the payload, then this simplistic demultiplexing automation is no longer useful. It will produce two topics per sensor and that’s unusable for MQTT Sensor or Binary Sensor.

For this situation, the automation’s data_template requires a more complex template that is aware of each sensor’s Data payload, representing on and off, and forwards it to the sensor’s single topic. It’s not difficult, just more work.

Nope; it is a working automation for use with OpenMQTT 433Mhz gateway (codes received from the 433Mhz devices are up to 10 char in length if not using the JSON functionality for the payload). Agree that using JSON payload in the topic is a no go.

For PIRs with only one state I use the method given by @123

Am I missing something* or is there a down side to this solution, because I can’t see one? All the other solutions seem to require more code.

*Serious question, not trying to be difficult.

None that I’m aware of.

FWIW, if there are many sensors, my preferred solution is the demultiplexer because I believe it’s more efficient. Here’s why:

  • Imagine you have ten binary_sensors and all are subscribed to one topic: tele/rf_bridge/RESULT.
  • Each time the topic has a new payload it’s evaluated ten times (once by each binary_sensor).

Using a demultiplexer:

  • Each time the topic has a new payload it’s evaluated by the automation which forwards the payload to a specific topic.
  • The binary_sensor subscribed to the topic evaluates the payload.

That’s a maximum of two evaluations for every payload as opposed to ten per payload.

So if you only have 2 or 3 devices then the demultiplexer automation and the template-based solution are equally efficient. However, when there are many devices, the demultiplexer has the advantage.

Good point. But (and I haven’t entirely thought this through…) how does this method deal with a mix of sensors some of which have two states and some only one. Specifically, what if you wish to retain the states of door/window sensors which have two states but do not want to retain states of PIR sensors which have only one?

The demultiplexer would presumably need a (possibly very) complex template to decide when to retain?

I offer you the “deluxe” solution. :slight_smile:

Let’s say we have three RF sensors:

  1. A contact sensor that reports both its on and off states (assume ‘A1A’ = ‘ON’ and ‘A2A’ = ‘OFF’).
  2. A motion sensor that reports only its on state (assume ‘B1B’ = ‘ON’).
  3. A button that only reports its on state (assume ‘C1C’ = ‘ON’).
  • Because the contact sensor reports both of its states, the demultiplexer automation can use retain: true when publishing to the contact sensor’s topic. When Home Assistant restarts, it will re-subscribe to the contact sensor topic’s and receive its current (retained) state from the broker. :+1:

  • The other two sensors (motion sensor and button) don’t report their off state. We will use the off_delay option to automatically reset them to off. However, this technique does not publish off to their respective MQTT topic (i.e. once set to on the topic will always show on). Therefore the demultiplexer automation should publish to their topics using retain: false. Otherwise, using retain: true, when you restart Home Assistant, it would erroneously set these sensors to on. :-1:

To make the automation neater, and avoid elaborate if-elif-else trees, we will use dictionaries.

This one defines which commands belongs to a sensor’s topic.

{ 'A1A':'sensor1', 'A2A':'sensor1', 'B1B':'sensor2', 'C1C':'sensor3' }

This one defines which commands represents ON or OFF.

{ 'A1A':'ON', 'A2A':'OFF', 'B1B':'ON', 'C1C':'ON' }

Finally, this one defines which commands are retained or not.

{ 'A1A':'true', 'A2A':'true', 'B1B':'false', 'C1C':'false' }

Putting it all together, we get this demultiplexer automation. If it receives a command that is not defined in the dictionaries, it will publish it to home/unknown (with retain: false).

- alias: 'RF_Bridge demultiplexer'
  hide_entity: true
  trigger:
    platform: mqtt
    topic: tele/RF_Bridge/RESULT
  action:
    service: mqtt.publish
    data_template:
      topic: >-
        {% set cmd = trigger.payload_json.RfReceived.Data %}
        {% set commands = { 'A1A':'sensor1', 'A2A':'sensor1', 'B1B':'sensor2', 'C1C':'sensor3' } %}
        {% set topic = commands[cmd] if cmd in commands.keys() else 'unknown' %}
        home/{{topic}}
      payload: >-
        {% set cmd = trigger.payload_json.RfReceived.Data %}
        {% set commands = { 'A1A':'ON', 'A2A':'OFF', 'B1B':'ON', 'C1C':'ON' } %}
        {% set payload = commands[cmd] if cmd in commands.keys() else cmd %}
        {{payload}}
      retain: >-
        {% set cmd = trigger.payload_json.RfReceived.Data %}
        {% set commands = { 'A1A':'true', 'A2A':'true', 'B1B':'false', 'C1C':'false' } %}
        {% set retain = commands[cmd] if cmd in commands.keys() else 'false' %}
        {{retain}}

Configuring the binary sensors becomes an easy task:

  - platform: mqtt
    name: 'Bathroom Door'
    state_topic: 'home/sensor1'
    device_class: Door

  - platform: mqtt
    name: 'Hallway Motion'
    state_topic: 'home/sensor2'
    off_delay: 5
    device_class: motion

  - platform: mqtt
    name: 'Button1'
    state_topic: 'home/sensor3'
    off_delay: 1

FWIW, I tested all of this and can confirm it works.

6 Likes

Indeed you do!

Thanks, that is not only a great solution but a bit of an education for me too. Tomorrow I was planning on embarking on some

I’ll let you know if it doesn’t :wink::grin::rofl:

EDIT: So far, so good! Thank you once again.

This seems like a very ingenious solution. Do we still need to have a sensor that represents the current RFRecieved Data from the SonoffRF unit in order for the the trigger to work?

Ie this…

- platform: mqtt
  state_topic: 'tele/RF_Bridge/RESULT'
  value_template: '{{ value_json.RfReceived.Data }}'
  name: "Sonoff RF Bridge"
  expire_after: 1

This is the demultiplexer automation’s trigger:

  trigger:
    platform: mqtt
    topic: tele/RF_Bridge/RESULT

No other sensor is needed to trigger it.

Sincere thanks for sharing this solution. Equally impressive and effective.

My working and tested solution (for alarming purposes)…

# ALARM - vklopi alarm DSC spodaj (RF ključ C)
- id: '30006'
  alias: 'ALARM - vklopi alarm DSC spodaj (RF ključ C)'
  hide_entity: true
  trigger:
    - platform: mqtt
      topic: "tele/Sonoff-RF-Bridge/RESULT"
    - platform: mqtt
      topic: "tele/Sonoff-RF-Bridge2/RESULT"
  condition:
    condition: and
    conditions:
    - condition: template
      value_template: "{{ trigger.payload_json.RfReceived.Data == '!RF-SECRET-RECEIVED-CODE-KEY-C' }}"
    - condition: state
      entity_id: alarm_control_panel.DSC5020
      state: disarmed
  action:
    service: alarm_control_panel.alarm_arm_away
    data:
      entity_id: alarm_control_panel.DSC5020
      code: !SECRET-DSC-ALARM-CODE

# ALARM - izklopi alarm DSC spodaj (RF ključ D)
- id: '30007'
  alias: 'ALARM - izklopi alarm DSC spodaj (RF ključ D)'
  hide_entity: true
  trigger:
    - platform: mqtt
      topic: "tele/Sonoff-RF-Bridge/RESULT"
    - platform: mqtt
      topic: "tele/Sonoff-RF-Bridge2/RESULT"
  condition:
    condition: or
    conditions:
    - condition: template
      value_template: "{{ trigger.payload_json.RfReceived.Data == '!RF-SECRET-RECEIVED-CODE-KEY-D' }}"
    - condition: state
      entity_id: alarm_control_panel.DSC5020
      state: armed_away
    - condition: state
      entity_id: alarm_control_panel.DSC5020
      state: armed_home
  action:
    service: alarm_control_panel.alarm_disarm
    data:
      entity_id: alarm_control_panel.DSC5020
      code: !SECRET-DSC-ALARM-CODE