Slider automation fix

Hello.

Could somebody tell me how to fix this automation for slider component?

The input sets the value, automation transmits through the mqtt. The mqtt trigger sees the change and tries to put it to the input, and again around.

As a result, i got a lot of warnings:
2021-11-23 13:51:30 WARNING (MainThread) [homeassistant.components.automation.slider_value] Slider value: Maximum number of runs exceeded

Possible option, if i understood correctly: somehow i need to compare the current value and the value received from mqtt in order to break the loop, i.e. current value != mqtt value.

Thanks.

You have created an endless loop because the automation effectively calls itself (endlessly).

You can try adding conditions that prevent publishing a value if it’s identical to the existing one. As an alternative, have you tried changing its mode to single? That blocks triggering if the automation is still busy servicing the previous request … but it might not effectively perform blocking here due to latency with the MQTT broker. Anyway, worth a try.

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.

After changing Queued mode to Single.

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.

:thinking:

@ 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
  • When an input_number changes state, its value is published as JSON payload to /devices/cmd/iot0.
  • A payload received via /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. :thinking:

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:

  • on startup it sends a multi-key payload
  • it responds with a single-key payload when it receives a single-key payload
  • it may send a single-key payload even if it doesn’t receive one

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:

  1. got {“key1”: 1, “key2”: 2, “key3”: 3}
  2. processed key1
    2.1) sent key1
  3. processed key2
    3.1) sent key2
    Etc.

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

@123
Hi.
Please, check PM when you will have some time.