Sonoff RF Bridge. Strategies for receiving data

@123 The more I learn the more I find I need to learn. Thanks, I will re-look at this. In the end, Strategy 2 is still awesome and I’m not planning on changing it in my system…

Hi - awesome work.

I have an issue with the second setup - Demultiplexer. I have HA .112.1 in Docker. I have SonoffTasmota 8.3.1. From 6 sensors, 1 of them does not want to change the status.
.py script:

d = { '068B23':['balcony_door','ON','true'],
      '068B29':['balcony_door','OFF','true'],
      '058703':['livingroom_window','ON','true'],
      '058709':['livingroom_window','OFF','true'],
      '025683':['kids_window','ON','true'],
      '025689':['kids_window','OFF','true'],
      '01BD09':['kitchen_window','ON','true'],
      '058709':['kitchen_window','OFF','true'],
      '001B33':['bedroom_window','ON','true'],
      '001B39':['bedroom_window','OFF','true'],
      '012073':['balcony_window','ON','true'],
      '012079':['balcony_window','OFF','true'],
      'F2A0E6':['kitchen_presence','ON','false']
    }

p = data.get('payload')

if p is not None:
  if p in d.keys():
    service_data = {'topic':'home/{}'.format(d[p][0]), 'payload':'{}'.format(d[p][1]), 'qos':0, 'retain':'{}'.format(d[p][2])}
  else:
    service_data = {'topic':'home/unknown', 'payload':'{}'.format(p), 'qos':0, 'retain':'false'}
    logger.warning('<rfbridge_demux> Received unknown RF command: {}'.format(p))
  hass.services.call('mqtt', 'publish', service_data, False)

sensors:

  - platform: mqtt
    state_topic: 'home/balcony_door'
    name: "Balcony Door"
    device_class: door

  - platform: mqtt
    state_topic: 'home/livingroom_window'
    name: "Livingroom Window"
    device_class: window

automation:

  alias: rfbridge_demultiplexer
  description: ''
  trigger:
  - platform: mqtt
    topic: tele/sonoff/RESULT
  condition: []
  action:
  - service: python_script.rfbridge_demux
    data_template:
      payload: '{{trigger.payload_json.RfReceived.Data}}'

I cannot understand where the issue might be - the Livingroom Window does not change it’s status from open to close and vice-a-versa, although Sononff Console reports the codes - On and Off:

14:05:33 MQT: tele/sonoff/RESULT = {"Time":"2020-07-03T14:05:33","RfReceived":{"Sync":12880,"Low":450,"High":1250,"Data":"058703","RfKey":"None"}}
14:05:36 MQT: tele/sonoff/RESULT = {"Time":"2020-07-03T14:05:36","RfReceived":{"Sync":12900,"Low":450,"High":1240,"Data":"058709","RfKey":"None"}}

I don’t see anything wrong with the python_script, the dictionary entries for the window’s two states, or with the binary_sensor’s configuration. It works for the other sensors just not this one window sensor.

I suggest you use an MQTT client to subscribe to home/livingroom_window then open/close the window and confirm you receive payloads ON and OFF.

@123 - I got it - it was my mistake - stupid mistake - I copy-pasted in the py code to make the entries - and duplicated one of the codes:

'058709':['livingroom_window','OFF','true'],

'058709':['kitchen_window','OFF','true'],

My mistake completly - got it working perfectly now. Sorry for the waisted time.

I think something has changed in the lastest version of home assistant. when i restart home assistant all my buttons and motion sensors are “unavailable”

Did not have this problem before 0.112

Others have reported the same issue but I have not experienced it after upgrading from 0.111 to 0.112.

I carried out experiments to detect behavioral difference between the two versions that might explain why some people are reporting binary_sensors have unavailable states on startup. I performed three experiments and none were able to detect a difference. Therefore the people who are experiencing the issue will have to determine the cause.

Questions for you:

  1. Does it only affect binary_sensor or also sensor? Is any other type of entity affected?
  2. Are the affected entities configured manually, as YAML definitions, or are they configured automatically via MQTT Discovery?
  3. Do the affected devices publish their state as retained messages?

I am seeing this too and I hope this data might help in troubleshooting…

It definitely appears to be only the binary sensors.
It does not seem to be affected by the retain flag as I have discovered while investigating this that I erroneously(?) had two of my battery alert sensors set to retain: true (all the others are false).

Interestingly, I don’t think all binary sensors are affected…

For example:

  • My front door (retain: true) seems to be ok, but not the front door battery (retain: false)

  • My shower room window (retain: true) seems to be ok, but not the shower room battery (retain: true)

None of my PIRs initialise.

The only common link I can find is that those that are ‘misbehaving’ only have one possible state defined i.e. ON.


rfbridge_demux.py

      'DC970A':['front_door','ON','true'],
      'DC970E':['front_door','OFF','true'],
      'DC9706':['front_door_battery_alert','ON','false'],

      '11C60A':['shower_room_window','ON','true'],
      '11C60E':['shower_room_window','OFF','true'],
      '11C606':['shower_room_window_battery','ON','true'],

      'BC4E8A':['PIR_sitting_room','ON','false'],

binary_sensor:

  # Front Door
  - platform: mqtt
    name: "Front Door"
    state_topic: "433/front_door"
    device_class: Door

  # Front Door Battery
  - platform: mqtt
    name: "Front Door Battery Alert"
    state_topic: "433/front_door_battery_alert"
    off_delay: 1

  # Shower Room Window
  - platform: mqtt
    name: "Shower Room Window"
    state_topic: "433/shower_room_window"
    device_class: Window

  # Shower Room Window Battery
  - platform: mqtt
    name: "Shower Room Window Battery Alert"
    state_topic: "433/shower_room_window_battery_alert"
    off_delay: 1
    
  # PIR 03 - Sitting Room
  - platform: mqtt
    name: pir_sitting_room
    state_topic: 433/PIR_sitting_room
    device_class: motion
    off_delay: 1

(I’m guessing the battery sensors are unknown because they have never actually been set because the battery has never yet run down whereas the PIR is unavailable because obviously someone did once go in that room!?).

I encourage you to comment in this GitHub issue:

Based on what people are reporting here, something has definitely changed in how MQTT Binary Sensors are handled in 0.112.

If the MQTT integration is connected to the broker, and the binary_sensor’s state_topic does NOT have a retained message, the default behavior has always been to set the binary_sensor’s state to off. If people are reporting the default state is now unavailable that’s entirely new behavior.

I’ve performed a few simple tests and cannot reproduce the unavailable behavior. That doesn’t mean people who have observed it are wrong, just that I’m ill-equipped to represent this problem to the developers. That’s why I suggest that everyone who is experiencing the problem should provide details of what they have observed in the linked Issue.


NOTE

A bit of history:

Many versions ago, you didn’t need to use Strategy 1 or Strategy 2 for binary_sensors. You only needed to specify values for payload_on and payload_off.

If the received payload failed to contain either of the two values, nothing would happen. In other words, there would be no error message reporting “No matching payload”.

Then it was decided that this arrangement was too lax and if the received payload failed to match payload_on or payload_off then it should be reported in the log with “No matching payload”.

This modification caused a problem for anyone who had multiple binary_sensors subscribed to the same state_topic (as is the case when using a Sonoff RF Bridge, OpenMQTTGateway, and other devices that “multiplex” payloads in one topic). Now logs were filled with “No matching payload” messages.

Strategy 1 and Strategy 2 mitigate the situation by using a template (instead of payload_on and payload_off) to set the state. If the received payload is NOT a matching payload, it simply uses the existing state.

This has worked well for many users, predominately because it was almost impossible for the binary_sensor’s state to be unavailable. That’s because the default state of a binary_sensor has traditionally been off even if the MQTT integration wasn’t connected to the broker or, upon startup, there was no retained message available for the binary_sensor’s state.

In 0.112, it’s now possible for the binary_sensor’s state to be unavailable. It’s only supposed to report that state when the MQTT integration is NOT connected to the broker. However, people are reporting it can be unavailable even when the MQTT integration is connected.

This creates a problem for the templates used in Strategy 1 and 2. Here’s the situation:

  • Restart Home Assistant.
  • MQTT integration connects to the broker.
  • Some MQTT Binary Sensors report their state is unavailable (this is new behavior in 0.112).
  • A payload is received via a shared state_topic (i.e. several binary_sensors receive the same payload).
  • If the payload is not a match, the template in Strategy 1 and 2 uses the binary_sensor’s current state.
  • However, the current state is unavailable and you can only set a binary_sensor to either ON or OFF.
  • As a result, Home Assistant reports “No matching payload”.

The correction for this is supposed to come in 0.113. If I understood it correctly, a binary_sensor’s behavior may be reverted to the way it worked many versions ago when it simply ignored a non-matching payload. If that’s true, then it implies there will no longer be a need to use either Strategy 1 or 2.

Anyway, time will tell. Until then, I suggest users affected by all of this provide assistance to the developers.

1 Like

Well, this is awkward.
I just did another restart for unrelated reasons, the second one since upgrading to 112, and all my sensors are initialised.

I wonder if it was an artefact of the database upgrade? Or simply a timing issue with connecting to the broker?

Anyway I’ll keep an eye on it…

Your background was very interesting so I don’t feel I completely wasted all your time with your typically full and informative reply.

Thanks and sorry if you do feel it was a waste of your time.

That would be unusual because it would mean it uses the database to set an entity’s state. It uses an entirely different file for restoring states but not for MQTT sensors.

I don’t feel I’ve wasted my time but I do feel I’ve spent too much time on it. I have not experienced the issue and I don’t even have a Sonoff RF Bridge, OpenMQTTGateway, or any other device that uses one state_topic to publish payloads intended for multiple entities. I have little to gain from continued involvement in this issue.

1 Like

FYI

The issue of MQTT-based entities whose states are set to unavailable at startup even with a proper connection to the broker, has been identified to be a bug in Issue 37662.

There are currently two open PR’s to correct the problem.

1 Like

I’m trying to set up Strategy 2. I followed all the steps but my binary sensors only show up as unavailable. I’m not sure how to troubleshoot this…

If you’re using version 0.112 it’s probably due to a bug in the MQTT integration. For more information, read my previous post.

Here it is my approach with the newer capabilities available on automations, since HA 0.113 and onwards:

## Demuxing alarm RF remotes
- alias: 'rfbridge_demultiplexer_alarm'
  name: 'Demux alarm RF remotes' 
  mode: queued
  max: 3
  trigger:
  - platform: mqtt
    topic: tele/RF_Bridge/RESULT
  condition:
    - condition: template
      value_template: >
        {{ not(trigger.payload_json.RfReceived.Data == none) }}     
  action:
    - choose:
      - conditions:
          - condition: template
            value_template: >
              {% set arm_codes = 'ABCDEF', 'GHIJKL', 'MNOPQ' %}
              {{ trigger.payload_json.RfReceived.Data in arm_codes }}
        sequence:
          - service: alarm_control_panel.alarm_arm_away
            entity_id: alarm_control_panel.home_alarm
      - conditions:
          - condition: template
            value_template: >
              {% set disarm_codes = '12345', '67890', 'QWERT' %}
              {{ trigger.payload_json.RfReceived.Data in disarm_codes }}
        sequence:
          - service: alarm_control_panel.alarm_disarm
            entity_id: alarm_control_panel.home_alarm
      - conditions:
          - condition: template
            value_template: >
              {% set home_arm_codes = 'ZXCVB', 'MNBVC', 'POIUY' %}
              {{ trigger.payload_json.RfReceived.Data in home_arm_codes }}
        sequence:
          - service: alarm_control_panel.alarm_arm_home
            entity_id: alarm_control_panel.home_alarm
      - conditions:
          - condition: template
            value_template: >
              {% set sos_codes = 'TGBYH', 'EDCRF', 'QAZWS' %}
              {{ trigger.payload_json.RfReceived.Data in sos_codes }}
        sequence:
          - service: persistent_notification.create
            data:
              message: 'SOS! SOS! SOS!'
      default:
#        - service: persistent_notification.create
#          data:
#            message: Some other RF code was received!

This is an example to 3 RF remotes, like the ones used on home alarms or garage doors, with multiple functions and buttons for those. Such as:

Is it? A garage door remote-control employs a rolling code to prevent replay attacks (i.e. detect the transmitted code, then send the same code later).

If your key-fob is being detected by a Sonoff RF Bridge, it doesn’t employ it and is vulnerable to a replay attack. It’s not the most secure means of activating/de-activating a security system and not “like the ones used on home alarms or garage doors”.

1 Like

I’m not in towards a discussion on what is secure or not. This is merely an arbitrary example on what is possible to achieve regarding this demux RF codes topic, using the latest evolutions on automations, since HA 0.113. An all-in-one approach, without messing around with python scripts, with no need to define any binary_sensors/entities in general, much simpler, through straight and plain yaml code.

My 2 cents.

1 Like

But you literally said it was like a garage door opener and even went as far as to include a picture of one. I’ve simply pointed out you’ve made a misleading a statement.

No need to define any binary_sensors? Well, yeah, your example doesn’t use any so there’s that. However, it does use an “entity” namely alarm_control_panel.home_alarm and I’m quite sure you had to define that.

It doesn’t scale well; with many sensors (try 20) the result is a very long chain of conditions, as opposed to a compact dictionary in a python_script. Plus to get to the 20th condition, it must evaluate the first 19 conditions whereas a key-lookup for a dictionary is fast and efficient.

If you try this technique with a binary_sensor that reports both its on and off states, you need one condition for its on state and another for off state. For ten binary_sensors, that’s twenty conditions. More conditions are needed if the binary_sensor also reports low-battery.

Handling each received code takes about 6 lines of YAML. 10 binary_sensors x 2 codes x 6 lines = 120 lines of “straight and plain”, and lengthy, YAML.

1 Like

I’m using RF door sensors, and as mentioned, with multiple states (open, closed, battery), the code to check states becomes lengthy.

The sensors I use transmit a unique ID for each, with a single character state code appended to the end of the ID string.

To overcome the need for lengthy code, my automation takes the unique ID and publishes an MQTT message to the homeassistant topic with the device ID set to the unique ID of the door sensor, as well as fields for device class, etc. If you have auto configuration set up for mqtt on homeassistant, it reads the MQTT and creates binary sensors corresponding to each door sensor.

A second automation publishes the state of the sensor to MQTT, again under the unique ID, which homeassistant uses to update the state of the corresponding binary sensor.

Both automations are triggered by homeassistant receiving data from the rfbridge result topic, and have some conditions to filter the signal for length and structure so it’s not firing all the time. I also keep the create automation disabled except when I am setting up a new sensor since it seems there is lots of RF noise that even with filters results in the creation of random devices.

I hope this is clear enough to understand - it’s been a while since I wrote the automations and I’m working from memory which is a little fuzzy. Let me know if anyone wants details.

1 Like

LOL. I have been tearing my hair out trying to figure out why half of my sensors worked, but not the other half. It was exactly this problem. I just couldn’t see it.

Thanks for a great tutorial. Works like a charm on my 5 water sensors, and 6 door sensors.

I would be interested in seeing this. My door sensors end with A for open, and E for closed, with the first five characters the ID, like yours. I have not yet figured out the battery info yet, though.