Like many, I have a tasmotized Sonoff RF Bridge, as well as a collection of door/window and motion sensors that beam a signal to the RF Bridge on various state changes. This signal usually consists of a unique ID and a state, run together in one string, along with some signal parameters:
rfbridge/tele/RESULT = {“Time”:“2020-08-24T22:08:05”,“RfReceived”:{“Sync”:14050,“Low”:470,“High”:1350,“Data”:“D3FD1A”,“RfKey”:“None”}}
rfbridge/tele/RESULT = {“Time”:“2020-08-24T22:08:10”,“RfReceived”:{“Sync”:14000,“Low”:470,“High”:1350,“Data”:“D3FD1E”,“RfKey”:“None”}}
Where D3FD1 is the unique ID, A means open and E means closed (6 means low battery).
As the number of sensors grows, trying to keep track of the codes using automations to set the value of binary sensors leads to a big pile of code that needs maintaining with any change. There have been a few solutions that used a python script to loop through the IDs, but it still means you need to kep the script updated.
To solve this I created a pair of automations that are triggered by the publication of data to the rfbridge/tele/RESULT topic, and then create and maintain MQTT devices in Home Assistant corresponding to each sensor.
Upon being triggered, the automations first filter the data through some conditions (since there is a surprising amount of RF garbage noise that looks like a signal but isn’t) for signal paramaters (Sync, Low and High values) as well as data structure (does it end with an E, A or 6).
One automation then takes data that manages to make it through the filters and publishes a pair of MQTT messages to the homeassistant/binary_sensor topic - one for battery OK or not, the other for open or closed. These messages include the unique ID of the sensor, the device class (door or battery), MQTT topic the device publishes on*, manufacturer (put what you want here), retain flag etc. If you have auto discover set up in HomeAssistant, it will receive the messages on the HomeAssistant topic and create a device under the unique ID of the door sensor, with a binary sensor entity each for battery and open/closed state of the sensor.
I also have an input boolean set up to control the triggering of this automation - it is set to off each time the automation runs so that you can control when it is listening for new devices. Even with the filtering I still found many new devices after a few days that were created by noise rather than new sensors. Just turn on the input boolean, trigger the sensor, and it will create a new device and then stop listening.
The second automation also publishes a pair of MQTT messages, but to the topic created in the first automation (see * above), one message each for battery and open/closed state. This updates the entities created by the first automation, relaying the state of the physical sensor through to the corresponding entity in HomeAssistant. While there is still noise received that causes nonsense MQTT messages to be generated, because they don’t correspond to anything HomeAssistant recognizes they are ignored.
While what I have posted below is targeted at door/window sensors, anything that produces a signal that an RF Bridge can receive should work, including motion sensors, moisture sensors, vibration sensors etc. You will have to edit the signal paramaters (hint: look at the console on your RF Bridge to see what it’s receiving) as well as the data bit (not everything uses the same values), but the principle remains the same.
Last note, I have the data automation set to retain= true. This means that the state of a door or window will survive a reboot, but it also means that the nonsense MQTT messages will pile up in the MQTT server. I dont know what to do about that…
Code:
- alias: door_sensor_device_config
trigger:
platform: mqtt
topic: rfbridge/tele/RESULT
condition:
condition: and
conditions:
- condition: template
value_template: '{{trigger.payload_json.RfReceived.Sync | int > 13800 }}'
- condition: state
entity_id: input_boolean.door_sensor_discovery
state: 'on'
- condition: or
conditions:
- condition: template
value_template: '{{trigger.payload_json.RfReceived.Data[-1] == "A" }}'
- condition: template
value_template: '{{trigger.payload_json.RfReceived.Data[-1] == "E" }}'
- condition: template
value_template: '{{trigger.payload_json.RfReceived.Data[-1] == "6" }}'
action:
- service: mqtt.publish
data_template:
topic: '{{ ''homeassistant/binary_sensor/batt_state'' + trigger.payload_json.RfReceived.Data[:5]
+ ''/config'' }}'
payload: "{\n \"name\": \"{{ 'Door/Window Battery ' + trigger.payload_json.RfReceived.Data[:5]}}\"\
,\n \"stat_t\": \"~BATT_STATE\",\n \"device_class\": \"battery\",\n \"\
uniq_id\": \"{{ 'Batt-' + trigger.payload_json.RfReceived.Data[:5]}}\",\n\
\ \"device\": {\n \"identifiers\": [\n \"{{trigger.payload_json.RfReceived.Data[:5]}}\"\
\n ],\n \"name\": \"{{ 'Door/Window ' + trigger.payload_json.RfReceived.Data[:5]}}\"\
,\n \"model\": \"Door/Window Sensor\"\n,\n \"manufacturer\": \"CompanyName\"\
\n },\n \"~\": \"{{ trigger.payload_json.RfReceived.Data[:5] + '/tele/'\
\ }}\"\n}"
retain: true
- service: mqtt.publish
data_template:
topic: '{{ ''homeassistant/binary_sensor/door_state'' + trigger.payload_json.RfReceived.Data[:5]
+ ''/config'' }}'
payload: "{\n \"name\": \"{{ 'Door/Window State ' + trigger.payload_json.RfReceived.Data[:5]}}\"\
,\n \"stat_t\": \"~DOOR_STATE\",\n \"device_class\": \"door\",\n \"uniq_id\"\
: \"{{ 'State-' + trigger.payload_json.RfReceived.Data[:5]}}\",\n \"device\"\
: {\n \"identifiers\": [\n \"{{trigger.payload_json.RfReceived.Data[:5]}}\"\
\n ]\n },\n \"~\": \"{{ trigger.payload_json.RfReceived.Data[:5] + '/tele/'\
\ }}\"\n}"
retain: true
- service: input_boolean.turn_off
entity_id: input_boolean.door_sensor_discovery
id: 2535483654
- alias: door_sensor_data
trigger:
platform: mqtt
topic: rfbridge/tele/RESULT
condition:
condition: and
conditions:
- condition: template
value_template: '{{trigger.payload_json.RfReceived.Sync | int > 13800 }}'
- condition: or
conditions:
- condition: template
value_template: '{{trigger.payload_json.RfReceived.Data[-1] == "A" }}'
- condition: template
value_template: '{{trigger.payload_json.RfReceived.Data[-1] == "E" }}'
- condition: template
value_template: '{{trigger.payload_json.RfReceived.Data[-1] == "6" }}'
action:
- service: mqtt.publish
data_template:
topic: '{{ trigger.payload_json.RfReceived.Data[:5] + ''/tele/DOOR_STATE'' }}'
payload: "\n{% if trigger.payload_json.RfReceived.Data[-1] == \"A\" %}\n ON\n\
{% elif trigger.payload_json.RfReceived.Data[-1] == \"E\" %}\n OFF\n{% endif\
\ %}"
retain: true
- service: mqtt.publish
data_template:
topic: '{{ trigger.payload_json.RfReceived.Data[:5] + ''/tele/BATT_STATE'' }}'
payload: "\n{% if trigger.payload_json.RfReceived.Data[-1] == \"6\" %}\n ON\n\
{% else %}\n OFF\n{% endif %}"
retain: true
id: 8648374648
Hope this is useful! I’d love to hear any comments or ways to improve upon it!