Sonoff RF Bridge. Strategies for receiving data

  • Setting up the python_script integration is easier than configuring a binary_sensor (just add python_script: to configuration.yaml and done).

  • Creating a sub-directory is a basic computer skill and an insignificant step.


On the subject of restarting Home Assistant, there is a way to create MQTT Sensors and Binary_Sensors (and other entities) without restarting and that’s to use MQTT Discovery. To enable it, just add discovery: true to MQTT’s configuration.

For example, to create this binary_sensor via MQTT Discovery:

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

you can use an MQTT client, like MQTT Explorer, to publish this payload (as a retained message):

{"name": "Bathroom Door",
 "state_topic": "home/sensor1", 
 "device_class": "door"}

to this topic:

homeassistant/binary_sensor/bathroom_door/config

Home Assistant will immediately create the binary_sensor and it will be visible in Developer Tools > States as well as Configuration > Entities (all without having to restart Home Assistant).

NOTE: If you add the unique_id option (with some unique value), then the binary_sensor can also be edited in Configuration > Entities and will be listed in MQTT Integrations.

{"name": "Bathroom Door",
 "state_topic": "home/sensor1", 
 "device_class": "door",
 "unique_id": "abc123xyz"}

Ideally, you would be able to publish this using Developer Tools > MQTT > Publish. However, it currently doesn’t offer the ability to publish the payload as a retained message (which is important for preserving the discovery topic).

1 Like

You can use developer tools -> services -> mqtt.publish to set the retain flag

1 Like

I totally agree with you, python_script setup is very easy, but for some people it may not be as easy as for us. It also add another configuration file to manage, which for some people (not me) may add another level of difficulty or point of failure in their setup.

As for MQTT auto-discovery, I was aware of that but I prefer to kept it off (but nice tutorial). I personally prefer to manually control all my configuration files and topic access right of my MQTT broker for security purpose (but this is another subject).

Like I said before, the goal was just to provide another way to proceed and an educational example of script usage.

yeah, let’s keep it that way as I see both script and python_script equally standard in HA and in the end of the day it’s down to one’s preferences/abilities what to choose to do a particular task.
I have several scripts in my setup and about 3 times more python_scripts mainly because the latter allows for writing proper code without repeating as it’s impossible to use global variables in Jinja templates… on the other hand, there is no wait_template equivalent for python_script :wink:

Good point! That’s a far better option that using Developer Tools > MQTT > Publish.

Screenshot from 2020-04-06 17-20-41

One could optionally create a script containing all the entities that one wishes to generate via MQTT Discovery. Should the MQTT Broker every lose its database (i.e. all discovery topics and their retained messages are lost), running the script would quickly re-publish all the discovery topics.

Example:

#script:
  create_entities:
    alias: Create entities via MQTT Discovery
    sequence:
      - service: mqtt.publish
        data:
          topic: homeassistant/binary_sensor/bathroom_door/config
          payload: '{"name": "Bathroom Door", "state_topic": "home/sensor1", "device_class": "door", "unique_id": "abc123xyz"}'
          retain: true
      - service: mqtt.publish
        data:
          topic: homeassistant/binary_sensor/hallway_motion/config
          payload: '{"name": "Hallway Motion", "state_topic": "home/sensor2", "device_class": "motion", "off_delay": 5, "unique_id": "jkl789mno"}'
          retain: true

1 Like

It’s driving me nuts…

I’ve been working hard to adapt your second strategy (demultiplexer) to my Sonoff RF Bridge to no avail.

My Bridge is flashed with Espurna firm, direct hack option. https://github.com/xoseperez/espurna/wiki/Hardware-Itead-Sonoff-RF-Bridge---Direct-Hack It’s working great

Referring to sensors, Espurna can publish MQTT https://github.com/xoseperez/espurna/wiki/RFBRIDGE in two ways.

A- A payload string Ex: “C001016118005699BB”
B- A json payload string like:

{ "rfin": "C001016118005699BB", "time": "2020-04-10 11:44:44", "mac": "C4:5F:77:A2:87:C8", "host": "Sonoff-RF-Bridge-1", "ip": "10.12.16.130", "id": 8 }

I prefer option A, which reduces RF traffic.

In HA I’ve set a RF-Bridge sensor: “sensor.espurna_rf_bridge_1” which takes state from incoming RF by using value_template:

value_template: > {% if not value %} "No data" {% endif %} {{ value[-6:] }}

Because only last 6 values don’t change for each state device. Rest are timing values.

I can check sensor.espurna_rf_bridge_1 changing state: 5699BB 749D55 and so on.

Now, back to problem. Second strategy set. I can see automation is triggered when MQTT is incoming or when sensor.espurna_rf_bridge_1 state changed. Both work. No problem to trigger rfbridge_demux.py. If I mod python script from p = data.get(‘payload’) to p= 5699BB, PIR sensor is triggered. So, rfbridge_demux.py is working too.

To tell in short, what I can’t achieve is an automation, action, data_template to parse data to rfbridge_demux.py. In spite I’m not skilled in Jinja nor python, I’ve tried playing handreds of no working femplates, including json templates, Ex:

{% set temp_json = { "data": states('sensor.espurna_rf_bridge_1') } %}

But I really can´t get it.

I tried with B too, setting Espurna to publish json format and using it to parse rfin 3 last bytes to the script but I couldn’t get a data_template either.

Please, can somebody help me to parse right value to rfbridge_demux.py?

I assume you’re having hard time changing rfbridge_demultiplexer automation.
If you’re using payload string (your option A), you need to extract data from payload, that’s it:

payload: '{{ trigger.payload[-6:] }}'

Hi, thanks.
No, it doesn’t work. I just tried.
I think "data.get(‘payload’) should expect a json to extract “data” value. But no python skill at all.

what does that mean?
by the way, quotes around the template are not single ones - use single/double quotes.

Sorry. My fault.
I mean I tried your suggested data_template and it didn’t work.
Beside that, if you look into rfbridge_demux.py code, you’ll find:
p = data.get(‘payload’)
Which I guess is to extract value data from json payload parsed to rfbridge_demux.py, but I’m not sure at all.

I think you don’t understand me. There is no such thing “it does not work”.
Imagine yourself seeing a doctor because you’re unwell. He asks you various question to understand what’s the reason but all you say to him is “I AM UNWELL, PLEASE HELP ME”.
Please read this before we carry on.

It gets a payload variable that HA put into special data dictionary used to pass service data to python_scripts. That payload variable is formed when HA finds payload: blah inside service data (data or data_template).

I’m really grateful to you for helping me
I know my English isn’t as good as I would like.
I thought I was understanding you and doing my best summarizing the problem.
Please, let me try again.

Running Hassio. Docker. DSM ( Synology)
HA 0.108.2

arch x86_64
dev false
docker true
hassio true
os_name Linux
os_version 4.4.59+
python_version 3.7.7
timezone Europe/Madrid
version 0.108.2
virtualenv false

Configuration:

From my automations.yaml

- id: '1586546570081'
  alias: RF Topic MQTT desmultiplexación
  description: ''
  trigger:
  - platform: mqtt
    topic: Piso/Sonoff-RF-Bridge-1/rfin
  condition: []
  action:
  - data:
      data_template:
        payload: '{{ trigger.payload[-6:] }}'
    service: python_script.rfbridge_demux

rfbridge_demux.py

d = { '8349AA':['PIR_hacia_entrada','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)

From binary_sensors.yaml

  - platform: mqtt
    name: "PIR_hacia_entrada"
    state_topic: "home/PIR_hacia_entrada"
    device_class: motion
    off_delay: 5

My Try:

I Published MQTT 8888888888349AA on topic: Piso/Sonoff-RF-Bridge-1/rfin

From UI Reg:

16:35:29 ESPURNA RF-Bridge-1-C44F33A287C4 RFIN changed to unknown
16:35:27 RF Topic MQTT desmultiplexación has been triggered
16:34:48 RF Topic MQTT desmultiplexación turned off

No Error on log

Please, tell me if you need more info.

Your RF Topic MQTT desmultiplexación is incorrect: you should not use data_template inside data.
Here’s the right one

- id: '1586546570081'
  alias: RF Topic MQTT desmultiplexación
  description: ''
  trigger:
  - platform: mqtt
    topic: Piso/Sonoff-RF-Bridge-1/rfin
  condition: []
  action:
  - service: python_script.rfbridge_demux
    data_template:
      payload: '{{ trigger.payload[-6:] }}'
1 Like

Good Lord!
Kudos to AhmadK!
It´s working!

18:00:39 PIR_hacia_cocina cleared (no motion detected)
18:00:35 ESPURNA RF-Bridge-1-C44F33A287C4 RFIN changed to unknown
18:00:33 PIR_hacia_cocina detected motion
18:00:33 RF Topic MQTT desmultiplexación has been triggered
18:00:25 RF Topic MQTT desmultiplexación turned off

Five days trying hard all sort of data_templates and never realized Jinja was adding -data by itself!

Thanks, thanks, thanks a lot!

?

Sorry. I’m HA newbie.
If I set action by User UI, it changed on YAML edit mode. Added data.action YAML action

Ex: Two actions per picture. First as YAML mode. Second picture seen as User UI.
I did them on User UI. On YAML mode, data: was added.

For future reference, it’s not “Jinja” that’s adding anything. It’s the editor in the UI.

You friends and “Corona” home time are teaching us intense mode.
Keep on jour job, please.

Congratulations!
next time please post your config instead of explaining what you did. also, post code and not images.

I have played around with Strategy 2 which works well as many others have said. However, I was wondering if it might be possible to modify the Python script to publish sensor values rather than binary values which would significantly reduce the number of entities needed for multi-button remotes.

I currently have this:

d = { '9D4899':['level-1','ON','false'],
      'DAC012':['leak-g1','ON','false'],
      'AAAAAA':['battery-g1','ON','false'],
      'C2C112':['leak-g2','ON','false'],
      'BBBBBB':['battery-g2','ON','false'],
      '88C212':['leak-g3','ON','false'],
      '88C22D':['battery-g3','ON','false'],
      '25C112':['leak-g4','ON','false'],
      '25C12D':['battery-g4','ON','false'],
      'BB5DFD':['doorbell-1','ON','false'],
      'EBA782':['doorbell-2','ON','false'],
      '7DE426':['doorswitch-1','ON','false'],
      'ED600E':['motion-1','ON','false'],
      'CEF526':['motion-2','ON','false'],
      'DF9BE1':['remote-1a','ON','false'],
      'DF9BE2':['remote-1b','ON','false'],
      'DF9BE4':['remote-1c','ON','false'],
      'DF9BE8':['remote-1d','ON','false'],      
      'A051B4':['remote-2a','ON','false'],
      'A051B2':['remote-2b','ON','false'],
      'A051B1':['remote-2c','ON','false'],
      'A051B8':['remote-2d','ON','false'],       
      'E140C8':['remote-3a','ON','false'],
      'E140C4':['remote-3b','ON','false'],
      'E140C2':['remote-3c','ON','false'],
      'E140C1':['remote-3d','ON','false'], 
      'E140CC':['remote-3e','ON','false'],
      'E140C9':['remote-3f','ON','false'],
      'E140C5':['remote-3g','ON','false'],
      'E140C3':['remote-3h','ON','false']      
    }

And I would like to achieve something like the following:

      'E140C8':['remote-3','Button A','false'],
      'E140C4':['remote-3','Button B','false'],
      'E140C2':['remote-3','Button C','false'],
      'E140C1':['remote-3','Button D','false'], 
      'E140CC':['remote-3','Button E','false'],
      'E140C9':['remote-3','Button F','false'],
      'E140C5':['remote-3','Button G','false'],
      'E140C3':['remote-3','Button H','false']

My current code to achieve this in a single sensor template is this:

- platform: mqtt
  name: 'Remote3'     # Sonoff 8 button white Remote
  state_topic: 'tele/RFbridge01/RESULT'
  expire_after: 2
  value_template: >-
    {% if   value_json.RfReceived.Data == 'E140C8' %} Button A
    {% elif value_json.RfReceived.Data == 'E140C4' %} Button B
    {% elif value_json.RfReceived.Data == 'E140C2' %} Button C
    {% elif value_json.RfReceived.Data == 'E140C1' %} Button D
    {% elif value_json.RfReceived.Data == 'E140CC' %} Button E
    {% elif value_json.RfReceived.Data == 'E140C9' %} Button F
    {% elif value_json.RfReceived.Data == 'E140C5' %} Button G
    {% elif value_json.RfReceived.Data == 'E140C3' %} Button H
    {% else %} Unknown
    {% endif %}

I currently use two 4-button remote and an 8-button remote, a solution like this would reduce the number of entities required from 16 to 3.

Cheers!