Thank you so much, this is exactly what I was looking for!
Off topic, sorry.
Your question is about how to interpret battery levels and is not what this topic is all about. Please create a separate topic. Thank you.
Hi Taras.
I can hardly believe that Iâve been using this since May 19, without issue. Such an excellent contribution to HA.
Are we any nearer to understanding the issue with 0.117? Iâm itching to upgrade but the demux is too valuable to me to risk it breaking.
Iâm on 0.117.6, and the demux still works flawless ?
Glad to hear it.
I have no idea why some users are experiencing unusual behavior with python 3.9. Given that Home Assistant is not yet using version 3.9, I have not invested much time in investigating the issue.
What I have done is explore how to incorporate the recent automation enhancements to eliminate the need for a python_script. In other words, the goal is to create a single ârfbridge_demultiplexerâ automation that operates without the use of the python_script integration.
Based on a few tests, I believe this achieves the goal:
- alias: 'rfbridge_demultiplexer'
mode: parallel
variables:
data: { '2C8D0A':['sensor1','ON','true'],
'2C8D0E':['sensor1','OFF','true'],
'E5D30E':['sensor2','ON','false'],
'30D8A0':['sensor3','ON','false'] }
trigger:
- platform: mqtt
topic: tele/RF_Bridge/RESULT
condition: '{{ trigger.payload_json is defined }}'
action:
- choose:
- conditions: '{{ trigger.payload_json.RfReceived.Data in data.keys() }}'
sequence:
- service: mqtt.publish
data:
topic: 'home/{{ data[trigger.payload_json.RfReceived.Data][0] }}'
payload: '{{ data[trigger.payload_json.RfReceived.Data][1] }}'
qos: 0
retain: '{{ data[trigger.payload_json.RfReceived.Data][2] }}'
default:
- service: mqtt.publish
data:
topic: 'home/unknown'
payload: '{{ trigger.payload_json.RfReceived.Data }}'
qos: 0
retain: false
- service: persistent_notification.create
data:
title: '<rfbridge_demux> Unknown RF code: {{ trigger.payload_json.RfReceived.Data }}'
message: '{{ now().timestamp()|timestamp_local() }}'
It was successfully tested with 0.117.5 with the default setting (true
) for the legacy_templates
option.
If at least two other people confirm it works for them, I will amend this threadâs first post and recommend using this automation (and deprecate the references to use a python_script).
EDIT 1
Added a Template Condition to reject received payloads that are not in JSON format.
EDIT 2
Inspired by Sagâs post below, added mode: queued
EDIT 3
Changed to mode: parallel
based on Sagâs post below.
Hi Taras,
Thanks indeed for your work. We really appreciate it.
Some of us use Espurna firmware on our RF Bridges. It works flawlessly. In spite Espurna can publish JSON messages, integration with Home Assistant is done using âMQTT platformâ, not âMQTT-JSON platformâ. Each message is sent to itâs own topic.
Your python script is working great with Espurna using a light ârfbridge_demultiplexerâ automation adaptation. Ie:
- id: '1586546570081'
alias: RF Topic MQTT desmultiplexaciĂłn
description: Distribuye MQTT recibidos de Espurna RF Bridge en varios topics
trigger:
- platform: mqtt
topic: home/Sonoff-RF-Bridge-1/rfin
- platform: mqtt
topic: home/Sonoff-RF-Bridge-2/rfin
condition: []
action:
- data_template:
payload: '{{ trigger.payload[-6:] }}'
service: python_script.rfbridge_demux
mode: queued
max: 10
What do you think would be our best adaptation to your new script?
I believe you should change the condition
so that it ensures the length of the payload is greater than a minimum amount (otherwise the slice [-6:]
may fail).
Other than that, I think wherever you see trigger.payload_json.RfReceived.Data
used in the automation, it should be replaced by trigger.payload[-6:]
.
BTW, your usage of mode: queued
is a good precaution so Iâve added it to my example (above).
Do you mean something like that?
condition: â{{ trigger.payload | string | length > 5 }}â
Edit:
IMHO this automation system is less responsive than python script. I tried quite a lot and when some sensors are activated in a short space of time, only first or two first really do. I changed queued mode to parallel and achieved better results.
If someone use Espurna software on RF bridge (not JSON), maybe my working automation could be useful:
- id: '1586546570081'
alias: RF Topic MQTT desmultiplexaciĂłn
description: Distribuye MQTT recibidos de Espurna RF Bridge en varios topics
trigger:
- platform: mqtt
topic: home/Sonoff-RF-Bridge-1/rfin
- platform: mqtt
topic: home/Sonoff-RF-Bridge-2/rfin
condition:
- condition: template
value_template: '{{ trigger.payload | string | length > 5 }}'
action:
- choose:
- conditions:
- condition: template
value_template: '{{ trigger.payload[-6:] in data.keys() }}'
sequence:
- service: mqtt.publish
data:
topic: home/{{ data[trigger.payload[-6:]][0] }}
payload: '{{ data[trigger.payload[-6:]][1] }}'
qos: 0
retain: '{{ data[trigger.payload[-6:]][2] }}'
default:
- service: mqtt.publish
data:
topic: home/unknown
payload: '{{ trigger.payload }}'
qos: 0
retain: false
- service: persistent_notification.create
data:
title: '<rfbridge_demux> Unknown RF code: {{ trigger.payload }}'
message: '{{ now().timestamp()|timestamp_local() }}'
variables:
data:
234567:
- Puerta_entrada
- 'ON'
- 'true'
123456:
- Puerta_entrada
- 'OFF'
- 'true'
987654:
- Batt_Puerta_entrada
- 'ON'
- 'true'
456789:
- PIR_hacia_entrada
- 'ON'
- 'false'
285683:
- PIR_hacia_cocina
- 'ON'
- 'false'
194628:
- PIR_pasillo
- 'ON'
- 'false'
394555:
- Detector_humo_cocina
- 'ON'
- 'false'
297634:
- Detector_humo_salon
- 'ON'
- 'false'
671299:
- Detector_humo_despacho
- 'ON'
- 'false'
999988:
- Detector_humo_dormitorio
- 'ON'
- 'false'
mode: parallel
max: 10
If just one more person confirms the new demultiplexer automation works, Iâll proceed to update the first post.
It works rather nice but as already mentioned there is a lag compared to python_script despite running automation in parallel mode. Mostly feelable with e.g. doorbells. Anyway it is OK but for now I continue using script.
Best, JR
Given that two out of three users report noticing a âlagâ, I think Iâll leave the first post as-is (i.e. use the python_script). If someone encounters a problem using the python_script, they have an alternative available (i.e. use the new â all-in-oneâ automation).
I have to admit Iâm surprised to hear the automation is slower than the python_script. I would have never imagined the performance difference would be so great that it would be detectable through observation and not even requiring any timing tests. Not sure why the automation is so much slower than the python_script.
About your new demultiplexer automation (thanks a lot!), I only had to change the initial condition because the original was not working; I changed to:
{{ data[trigger.payload_json.RfReceived.Data] != null }}
With this modification, itâs working pretty well, with no performance issues.
Best
This will fail to reject payloads that are not in JSON format:
{{ data[trigger.payload_json.RfReceived.Data] != null }}
If the received payload is an empty string or just any string thatâs not in JSON format, Home Assistant will report it as an error because the condition attempts to access keys (.RfReceived.Data) that donât exist.
Lag is not so big here. Itâs working nice in parallel mode, as I told.
Iâll continue with âall in oneâ for now. I like it and I need more time to evaluate.
Good job mate!
Iâm now only using the all in one automation in the parallel mode and works very well for me with no noticeable lag.
Thank you
Iâm now successfully using the demux on 0.118 without any changes.
Hi to all,
thanks a lot for the automation, now iâm using the Taras automation instead the python script.
all works fine, but when i receive a code tha is not present in the variables i receive an error:
2020-11-20 15:43:23 INFO (MainThread) [homeassistant.components.automation.alrm_rf_demux] [ALRM] RF demux: Choose at step 1: default: Running automation actions
2020-11-20 15:43:23 INFO (MainThread) [homeassistant.components.automation.alrm_rf_demux] [ALRM] RF demux: Choose at step 1: default: Executing step call service
2020-11-20 15:41:29 ERROR (MainThread) [homeassistant.components.automation.alrm_rf_demux] [ALRM] RF demux: Choose at step 1: default: Error executing script. Unexpected error for call_service at pos 1: Error rendering data template: UndefinedError: 'dict object' has no attribute 'RfReceived'
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 351, in async_render
render_result = compiled.render(kwargs)
File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 1090, in render
self.environment.handle_exception()
File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 832, in handle_exception
reraise(*rewrite_traceback_stack(source=source))
File "/usr/local/lib/python3.8/site-packages/jinja2/_compat.py", line 28, in reraise
raise value.with_traceback(tb)
File "<template>", line 1, in top-level template code
File "/usr/local/lib/python3.8/site-packages/jinja2/sandbox.py", line 407, in getattr
value = getattr(obj, attribute)
jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'RfReceived'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 144, in async_prepare_call_from_config
service_data.update(template.render_complex(config[conf], variables))
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 91, in render_complex
return {
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 92, in <dictcomp>
render_complex(key, variables): render_complex(item, variables)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 96, in render_complex
return value.async_render(variables)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 353, in async_render
raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: UndefinedError: 'dict object' has no attribute 'RfReceived'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 253, in _async_step
await getattr(
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 432, in _async_call_service_step
domain, service, service_data = async_prepare_call_from_config(
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 146, in async_prepare_call_from_config
raise HomeAssistantError(f"Error rendering data template: {ex}") from ex
homeassistant.exceptions.HomeAssistantError: Error rendering data template: UndefinedError: 'dict object' has no attribute 'RfReceived'
this my automation:
- alias: '[ALRM] RF demux nitghtoff'
mode: parallel
variables:
data: { '0xB24E54':['RC1_NIGHT','OFF','true'], # remote RC su Tasmota
'0x434454':['RC2_NIGHT','OFF','true'], # remote RC su Tasmota
# remote RC su OMG
'11685460':['RC1_NIGHT','OFF','true'],
'4408404':['RC2_NIGHT','OFF','true']
}
trigger:
- platform: mqtt
topic: tele/RF2/RESULT
- platform: mqtt
topic: tele/RF1/RESULT
- platform: mqtt
topic: home/OpenMQTTGateway_ESP8266_RF/433toMQTT
condition: '{{ trigger.payload_json is defined }}'
action:
- choose:
- conditions: '{{ trigger.payload_json.RfReceived.Data in data.keys() }}'
sequence:
- service: mqtt.publish
data:
topic: 'home/RF433/{{ data[trigger.payload_json.RfReceived.Data][0] }}'
payload: '{{ data[trigger.payload_json.RfReceived.Data][1] }}'
qos: 0
retain: '{{ data[trigger.payload_json.RfReceived.Data][2] }}'
default:
- service: mqtt.publish
data:
topic: 'home/unknown'
payload: '{{ trigger.payload_json.RfReceived.Data }}'
qos: 0
retain: false
BR
Actually, itâs a bit more severe than a non-existent code. The received payload fails to contain âRfReceivedâ. Thatâs what this error message is reporting:
UndefinedError: âdict objectâ has no attribute âRfReceivedâ
I suggest you enhance the condition so it ensures the payload contains the âRfReceivedâ key.
condition: >
{{ trigger.payload_json is defined and
trigger.payload_json.RfReceived is defined }}
EDIT
Correction. Replaced RFReceived
with RfReceived
.