I’d like to see an example of such condition.
But looks like it doesn’t work.
I’d like to see an example of such condition.
But looks like it doesn’t work.
Before trying the complicated fix, try the easy one first. Change mode to single and see if it stops the endless looping.
Each message represents a blocked (re)trigger. However, I am surprised by the quantity of re-triggers that were blocked. Changing the value of just one input_number shouldn’t produce that many, unless some of the re-triggers are being processed so the blocking isn’t 100% effective.
I guess you will need to use a condition to ignore all MQTT triggers whose payload is identical to the corresponding input_number’s existing value.
@ All,
Can anyone help with the presentation of the code? I don’t understand where the error is in my example for conditions.
I’ve retracted my previous statement because now I’m not so certain it represents what’s actually happening here.
I’ve tested and confirmed that the following automation behaves the way you want.
- id: '1634116488690'
alias: Slider value
description: ''
trigger:
- platform: state
entity_id:
- input_number.vestibule_light_brightness
- input_number.vestibule_light_stay_time
- input_number.vestibule_light_up_time
- input_number.vestibule_light_down_time
- platform: mqtt
topic: /devices/state/iot0
value_template: '{{ value_json }}'
condition: []
action:
- choose:
- conditions: "{{ trigger.platform == 'state' }}"
sequence:
- service: mqtt.publish
data:
topic: /devices/cmd/iot0
payload: '{"{{ trigger.to_state.object_id[16:] }}":{{states(trigger.entity_id) | int(0)}} }'
default:
- variables:
property: '{{ (trigger.payload_json.keys() | list)[0] }}'
entity: 'input_number.vestibule_light_{{ property }}'
val: '{{ trigger.payload_json[property] | int(0) }}'
- condition: template
value_template: "{{ val != states(entity) | int(0) }}"
- service: input_number.set_value
target:
entity_id: '{{ entity }}'
data:
value: '{{ val }}'
mode: queued
max: 10
/devices/cmd/iot0
./devices/state/iot0
is used to set the corresponding input_number but only if the payload’s value is not the same as the input_number’s current value.Automation tries to iterate over each key when triggered with a JSON string:
{"up_time": 13, "down_time": 14, "stay_time": 15, "brightness": 60, "always_on": false, "always_off": false. , "mov_det": true, "dev_state": false}
Can only the required keys be specified?
And it looks like this only works for the first key, not every required key in the JSON string.
That’s correct, it only uses the first key because, if you check all the posts in this thread, none of them explained the received data’s format. The only clue to its format was the template used to publish a payload and it contains just one key:
'{"brightness":{{states(''input_number.vestibule_light_brightness'') | int}}}'
Now that I know the format of the received JSON payload, that it contains multiple keys, I can modify the automation.
The problem with your original example is that it contains four MQTT Triggers subscribed to the same topic. For every one payload received, the automation is triggered four times.
It should use one MQTT Trigger and processes all four of the desired keys in the received JSON payload.
Is there anything else I should know about this device before I modify the automation? For example, when you publish {"brightness": 50}
to it, what does it respond with? Does it respond with JSON containing multiple keys or just one key (for brightness
)?
Sorry about that. I thought I could get by with “little blood”.
When the slider value is changed and published to the CMD topic, the device responds to STATE topic with a single key containing current value of changed parameter.
BTW, current version of automation tries to access to input_number.always_on, for example, when it is even not an input number, but switch. That’s why i am asking to specify required keys only.
I don’t understand what you explained. Neither your version of the automation or mine has input_number.always_on
in its State Trigger. How does either automation have “access” to that input_number?
I’m getting such warnings with yours automation from this post when the device pushed complete JSON string at starts up.
2021-11-24 09:23:57 WARNING (MainThread) [homeassistant.helpers.service] Unable to find referenced entities input_number.vestibule_light_always_on
Ok, the warning message concerns input_number.vestibule_light_always_on
and not what you said: input_number.always_on
.
The automation I posted was developed before I knew the JSON payload can contain multiple keys. It references the input_number entity using the key’s name. There’s no corresponding input_number for the always_on
key so that’s why it caused the warning message.
Only thing I don’t understand is why it used always_on
because that’s not the first key. The template is designed to use the first key but always_on
is the fifth key. Perhaps one of the payloads it received contained always_on
as the first key? There appears to be something else going on here.
The complete payload looks like it was mentioned in my previous post.
There are warnings for other keys, like always_off and etc.
I think it may triggered by single key JSON string, like {“always_off”:true}
So, if possible - could you modify automation to test, please?
What would make the device report a single key like always_off
? Earlier you said
There’s no slider for always_off
so this automation never publishes a payload like {"always_on": false}
so why would the device respond with that payload?
I don’t mind modifying the automation if I have a clear understanding of how the device behaves (what it sends and when and why it sends it). Without a clear understanding, I don’t want to invest my time repeatedly redesigning the automation to adapt to missing information about the device’s behavior.
If you want my help you will need to provide examples of the payloads the device can send/receive for various events. So far all I know is:
Will it send a multi-key payload for any other reason? For example, when it receives a multi-key payload?
Does each multi-key payload always contain the same number of keys or can it vary? For example, if it receives a three-key payload, does it respond with a three-key payload, or three payloads containing one key, or one payload containing all possible keys?
The “multi-key payload” has a fixed size (8 keys) and the same key order. It dispatches only when the device starts up.
The device can process a JSON string with multiple keys, but a JSON string with one changed key is sent in response.
What I mean:
This is a kind of feedback.
I haven’t tested it very well.
There is also one more line of fixed size, which is sent by the device every time the state of the motion sensor and light sensor changes):
{"mov_det": true, "dev_state": false}
I thought just to bind to known keys and ignore others… I don’t know how to implement it in HA.
This version only handles payloads containing a single key and the key must be one of the four keys in ['brightness', 'stay_time', 'up_time', 'down_time']
.
It ignores payloads containing more than one key. Yes, that means it will ignore the startup payload containing 8 keys.
Supporting that 8-key payload is more time and effort than I currently feel like investing. The challenge it presents is that each one of the 4 keys within the 8-key payload must be compared to the value of their corresponding input_number and then only the ones (if any) that are not the same value should be published to /devices/cmd/iot0
. It’s not an impossible task, just more work than I have free time to offer at this point in time.
- id: '1634116488690'
alias: Slider value
description: ''
trigger:
- platform: state
entity_id:
- input_number.vestibule_light_brightness
- input_number.vestibule_light_stay_time
- input_number.vestibule_light_up_time
- input_number.vestibule_light_down_time
- platform: mqtt
topic: /devices/state/iot0
value_template: '{{ value_json }}'
condition: []
action:
- variables:
valid_keys: ['brightness', 'stay_time', 'up_time', 'down_time']
- choose:
- conditions: "{{ trigger.platform == 'state' }}"
sequence:
- service: mqtt.publish
data:
topic: /devices/cmd/iot0
payload: '{"{{ trigger.to_state.object_id[16:] }}":{{states(trigger.entity_id) | int(0)}} }'
- conditions:
- "{{ trigger.platform == 'mqtt' }}"
- "{{ trigger.payload_json.keys() | list | count == 1 }}"
- "{{ (trigger.payload_json.keys() | list)[0] in valid_keys }}"
sequence:
- variables:
property: '{{ (trigger.payload_json.keys() | list)[0] }}'
entity: 'input_number.vestibule_light_{{ property }}'
val: '{{ trigger.payload_json[property] | int(0) }}'
- condition: template
value_template: "{{ val != states(entity) | int(0) }}"
- service: input_number.set_value
target:
entity_id: '{{ entity }}'
data:
value: '{{ val }}'
mode: queued
max: 10
The following version is designed to handled a payload containing any number of keys. Whether the payload contains one key or many keys, only the four desired keys are processed:
['brightness', 'stay_time', 'up_time', 'down_time']
- alias: Slider value
id: '1634116488690'
description: ''
trigger:
- platform: state
entity_id:
- input_number.vestibule_light_brightness
- input_number.vestibule_light_stay_time
- input_number.vestibule_light_up_time
- input_number.vestibule_light_down_time
- platform: mqtt
topic: /devices/state/iot0
value_template: '{{ value_json }}'
condition: []
action:
- choose:
- conditions: "{{ trigger.platform == 'state' }}"
sequence:
- service: mqtt.publish
data:
topic: /devices/cmd/iot0
payload: '{"{{ trigger.to_state.object_id[16:] }}": {{states(trigger.entity_id) | int(0)}} }'
default:
- variables:
valid_keys: ['brightness', 'stay_time', 'up_time', 'down_time']
all_keys: '{{ trigger.payload_json.keys() | list }}'
- repeat:
count: '{{ all_keys | count }}'
sequence:
- condition: template
value_template: '{{ all_keys[repeat.index-1] in valid_keys }}'
- variables:
property: '{{ all_keys[repeat.index-1] }}'
entity: 'input_number.vestibule_light_{{ property }}'
val: '{{ trigger.payload_json[property] | int(0) }}'
- condition: template
value_template: '{{ val != states(entity) | int(0) }}'
- service: input_number.set_value
target:
entity_id: '{{ entity }}'
data:
value: '{{ val }}'
mode: queued
max: 10
Try it out and let me know if it works and/or if it needs additional improvements.