Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

on_multi_click timings: allow one timing to cancel others #985

Closed
leo-b opened this issue Nov 6, 2020 · 3 comments · Fixed by esphome/esphome#6744
Closed

on_multi_click timings: allow one timing to cancel others #985

leo-b opened this issue Nov 6, 2020 · 3 comments · Fixed by esphome/esphome#6744
Labels

Comments

@leo-b
Copy link

leo-b commented Nov 6, 2020

Describe the problem you have/What new integration you would like

When multiple on_multi_click binary sensor timings are defined and a click-sequence is pressed, several multi click trigger candidates may still be valid at a given time because their timing pattern is still met but not yet complete.

If one multi-click timing sequence is complete and valid, it would be great if there would be a way to cancel other timings that may still be pending (incomplete) in order to prevent them from firing.

E.g. an optional - priority setting in - timing (at the same level of - ON and - OFF) could be used to cancel all other pending incomplete multi_click timings with a lower priority. As a probably more light-weight alternative, a - cancel_others option would also be sufficient.

This would allow much more flexible timings.

Please describe your use case for this integration and alternatives you've tried:

E.g. the example in the documentation https://esphome.io/components/binary_sensor/index.html#on-multi-click has to use different OFF timings to differentiate.
In my use case, I'd like to fire button actions during button press without having to wait for a certain time of button release.

Additional context

I am currently trying to achieve the same using a global button_cooldown variable that is set by the first timing that fires and checked by subsequent timings that I want to invalidate if the first one had fired. However this is quite cumbersome and error prone.

@trapacampo
Copy link

trapacampo commented Nov 18, 2023

Please add this feature!

My use case is a little different. In my home all switches are click type, but when you push and clicks the state holds.
If you don't push it again is gona be ON forever if you push it again is gona stay OFF forever.

I tried to program on multiclick action but without this kind of feature is almost imposible to make it work, because when I push it 2 times for example to do a double click action then OFF state is hold and single click is triggered too.

You can check in this verbose log:

[13:30:05][D][binary_sensor:036]: 'shelly-luces-despacho Switch': Sending state OFF
[13:30:05][V][binary_sensor.automation:035]: Multi Click: action not started because first level does not match!
[13:30:05][V][binary_sensor.automation:025]: START min=2000 max=4294967294
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:035]: Multi Click: action not started because first level does not match!
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:035]: Multi Click: action not started because first level does not match!
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:035]: Multi Click: action not started because first level does not match!
[13:30:05][V][binary_sensor.automation:035]: Multi Click: action not started because first level does not match!
[13:30:05][W][component:214]: Component gpio.binary_sensor took a long time for an operation (0.07 s).
[13:30:05][W][component:215]: Components should block for at most 20-30ms.
[13:30:05][D][binary_sensor:036]: 'shelly-luces-despacho Switch': Sending state ON
[13:30:05][V][binary_sensor.automation:025]: START min=2000 max=4294967294
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 8000 ms...
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:062]: C i=1 min=1000
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:054]: A i=1 min=0 max=1000
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][W][component:214]: Component gpio.binary_sensor took a long time for an operation (0.08 s).
[13:30:05][W][component:215]: Components should block for at most 20-30ms.
[13:30:06][V][binary_sensor.automation:096]: Multi Click: You waited too long to RELEASE.
[13:30:06][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 4000 ms...
[13:30:06][V][binary_sensor.automation:102]: Multi Click: Hooray, multi click is valid. Triggering!
[13:30:06][D][main:155]: shelly-luces-despacho double click
[13:30:06][V][text_sensor:013]: 'ude-syd-contact': Received new state double
[13:30:06][D][text_sensor:064]: 'ude-syd-contact': Sending state 'double'
[13:30:06][V][binary_sensor.automation:096]: Multi Click: You waited too long to RELEASE.
[13:30:06][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 4000 ms...
[13:30:06][V][binary_sensor.automation:096]: Multi Click: You waited too long to RELEASE.
[13:30:06][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 4000 ms...
[13:30:06][V][binary_sensor.automation:096]: Multi Click: You waited too long to RELEASE.
[13:30:06][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 4000 ms...
[13:30:06][V][binary_sensor.automation:096]: Multi Click: You waited too long to RELEASE.
[13:30:06][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 4000 ms...
[13:30:06][V][text_sensor:013]: 'ude-syd-contact': Received new state 
[13:30:06][D][text_sensor:064]: 'ude-syd-contact': Sending state ''
[13:30:07][V][binary_sensor.automation:102]: Multi Click: Hooray, multi click is valid. Triggering!
[13:30:07][D][main:623]: shelly-luces-despacho single click
[13:30:07][V][text_sensor:013]: 'ude-syd-contact': Received new state single
[13:30:07][D][text_sensor:064]: 'ude-syd-contact': Sending state 'single'
[13:30:07][V][text_sensor:013]: 'ude-syd-contact': Received new state 
[13:30:07][D][text_sensor:064]: 'ude-syd-contact': Sending state ''
[13:30:10][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.
[13:30:10][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.
[13:30:10][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.
[13:30:10][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.
[13:30:10][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.
[13:30:13][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.

This is the code (ignore the invalidation_cooldown, just trying [for me invalidation cooldown when one trigger success would make more sense]):

on_multi_click:
      # single click
      - timing:
          - ON for at least 2s
        then:
          - if:
              condition:
                and:
                  - wifi.connected:
                  - api.connected:
              # single click in case wifi and api are conncected
              then:
                - logger.log: "${device_name} single click"
                - text_sensor.template.publish:
                    id: ude_syd_contact
                    state: !lambda 'return "single";'
              # toggle relay in case either wifi or api are not connected
              else:
                - switch.toggle: "relay"
        invalid_cooldown: 8s
      # single click
      - timing:
          - OFF for at least 2s
        then:
          - if:
              condition:
                and:
                  - wifi.connected:
                  - api.connected:
              # single click in case wifi and api are conncected
              then:
                - logger.log: "${device_name} single click"
                - text_sensor.template.publish:
                    id: ude_syd_contact
                    state: !lambda 'return "single";'
              # toggle relay in case either wifi or api are not connected
              else:
                - switch.toggle: "relay"
        invalid_cooldown: 8s
      # double click
      - timing:
          - ON for at most 1s
          - OFF for at least 1s
        then:
          - if:
              condition:
                and:
                  - wifi.connected:
                  - api.connected:
              # double click in case wifi and api are conncected
              then:
                - logger.log: "${device_name} double click"
                - text_sensor.template.publish:
                    id: ude_syd_contact
                    state: !lambda 'return "double";'
              # toggle relay in case either wifi or api are not connected
              else:
                - switch.toggle: "relay"
        invalid_cooldown: 4s
      # double click
      - timing:
          - OFF for at most 1s
          - ON for at least 1s
        then:
          - if:
              condition:
                and:
                  - wifi.connected:
                  - api.connected:
              # double click in case wifi and api are conncected
              then:
                - logger.log: "${device_name} double click"
                - text_sensor.template.publish:
                    id: ude_syd_contact
                    state: !lambda 'return "double";'
              # toggle relay in case either wifi or api are not connected
              else:
                - switch.toggle: "relay"
        invalid_cooldown: 4s

Thank you in advance.

@Greali
Copy link

Greali commented Jan 1, 2024

Please add this feature!

My use case is a little different. In my home all switches are click type, but when you push and clicks the state holds. If you don't push it again is gona be ON forever if you push it again is gona stay OFF forever.

I tried to program on multiclick action but without this kind of feature is almost imposible to make it work, because when I push it 2 times for example to do a double click action then OFF state is hold and single click is triggered too.

You can check in this verbose log:

[13:30:05][D][binary_sensor:036]: 'shelly-luces-despacho Switch': Sending state OFF
[13:30:05][V][binary_sensor.automation:035]: Multi Click: action not started because first level does not match!
[13:30:05][V][binary_sensor.automation:025]: START min=2000 max=4294967294
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:035]: Multi Click: action not started because first level does not match!
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:035]: Multi Click: action not started because first level does not match!
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:035]: Multi Click: action not started because first level does not match!
[13:30:05][V][binary_sensor.automation:035]: Multi Click: action not started because first level does not match!
[13:30:05][W][component:214]: Component gpio.binary_sensor took a long time for an operation (0.07 s).
[13:30:05][W][component:215]: Components should block for at most 20-30ms.
[13:30:05][D][binary_sensor:036]: 'shelly-luces-despacho Switch': Sending state ON
[13:30:05][V][binary_sensor.automation:025]: START min=2000 max=4294967294
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 8000 ms...
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:062]: C i=1 min=1000
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:054]: A i=1 min=0 max=1000
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][V][binary_sensor.automation:025]: START min=0 max=1000
[13:30:05][V][binary_sensor.automation:026]: Multi Click: Starting multi click action!
[13:30:05][W][component:214]: Component gpio.binary_sensor took a long time for an operation (0.08 s).
[13:30:05][W][component:215]: Components should block for at most 20-30ms.
[13:30:06][V][binary_sensor.automation:096]: Multi Click: You waited too long to RELEASE.
[13:30:06][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 4000 ms...
[13:30:06][V][binary_sensor.automation:102]: Multi Click: Hooray, multi click is valid. Triggering!
[13:30:06][D][main:155]: shelly-luces-despacho double click
[13:30:06][V][text_sensor:013]: 'ude-syd-contact': Received new state double
[13:30:06][D][text_sensor:064]: 'ude-syd-contact': Sending state 'double'
[13:30:06][V][binary_sensor.automation:096]: Multi Click: You waited too long to RELEASE.
[13:30:06][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 4000 ms...
[13:30:06][V][binary_sensor.automation:096]: Multi Click: You waited too long to RELEASE.
[13:30:06][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 4000 ms...
[13:30:06][V][binary_sensor.automation:096]: Multi Click: You waited too long to RELEASE.
[13:30:06][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 4000 ms...
[13:30:06][V][binary_sensor.automation:096]: Multi Click: You waited too long to RELEASE.
[13:30:06][V][binary_sensor.automation:072]: Multi Click: Invalid length of press, starting cooldown of 4000 ms...
[13:30:06][V][text_sensor:013]: 'ude-syd-contact': Received new state 
[13:30:06][D][text_sensor:064]: 'ude-syd-contact': Sending state ''
[13:30:07][V][binary_sensor.automation:102]: Multi Click: Hooray, multi click is valid. Triggering!
[13:30:07][D][main:623]: shelly-luces-despacho single click
[13:30:07][V][text_sensor:013]: 'ude-syd-contact': Received new state single
[13:30:07][D][text_sensor:064]: 'ude-syd-contact': Sending state 'single'
[13:30:07][V][text_sensor:013]: 'ude-syd-contact': Received new state 
[13:30:07][D][text_sensor:064]: 'ude-syd-contact': Sending state ''
[13:30:10][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.
[13:30:10][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.
[13:30:10][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.
[13:30:10][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.
[13:30:10][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.
[13:30:13][V][binary_sensor.automation:075]: Multi Click: Cooldown ended, matching is now enabled again.

This is the code (ignore the invalidation_cooldown, just trying [for me invalidation cooldown when one trigger success would make more sense]):

on_multi_click:
      # single click
      - timing:
          - ON for at least 2s
        then:
          - if:
              condition:
                and:
                  - wifi.connected:
                  - api.connected:
              # single click in case wifi and api are conncected
              then:
                - logger.log: "${device_name} single click"
                - text_sensor.template.publish:
                    id: ude_syd_contact
                    state: !lambda 'return "single";'
              # toggle relay in case either wifi or api are not connected
              else:
                - switch.toggle: "relay"
        invalid_cooldown: 8s
      # single click
      - timing:
          - OFF for at least 2s
        then:
          - if:
              condition:
                and:
                  - wifi.connected:
                  - api.connected:
              # single click in case wifi and api are conncected
              then:
                - logger.log: "${device_name} single click"
                - text_sensor.template.publish:
                    id: ude_syd_contact
                    state: !lambda 'return "single";'
              # toggle relay in case either wifi or api are not connected
              else:
                - switch.toggle: "relay"
        invalid_cooldown: 8s
      # double click
      - timing:
          - ON for at most 1s
          - OFF for at least 1s
        then:
          - if:
              condition:
                and:
                  - wifi.connected:
                  - api.connected:
              # double click in case wifi and api are conncected
              then:
                - logger.log: "${device_name} double click"
                - text_sensor.template.publish:
                    id: ude_syd_contact
                    state: !lambda 'return "double";'
              # toggle relay in case either wifi or api are not connected
              else:
                - switch.toggle: "relay"
        invalid_cooldown: 4s
      # double click
      - timing:
          - OFF for at most 1s
          - ON for at least 1s
        then:
          - if:
              condition:
                and:
                  - wifi.connected:
                  - api.connected:
              # double click in case wifi and api are conncected
              then:
                - logger.log: "${device_name} double click"
                - text_sensor.template.publish:
                    id: ude_syd_contact
                    state: !lambda 'return "double";'
              # toggle relay in case either wifi or api are not connected
              else:
                - switch.toggle: "relay"
        invalid_cooldown: 4s

Thank you in advance.

I have it working now.
Just changed my automations to react when changes from none to single/double.
I had to change this:
Screenshot_20240101-020141

To:
Screenshot_20240101-020305

@lbilger
Copy link

lbilger commented May 14, 2024

I need something similar, only I don't want all other timings to be cancelled, but just one specific timing. I found that this can be done with a very small change to the codebase.

I added one method called cancel to MultiClickTrigger which basically does the same as the is_not_valid timeout. Then I can assign an id to the trigger I want to cancel using trigger_id and call cancel on it in a lambda in the then part of the other trigger, like

id(id_of_trigger_to_be_cancelled).cancel();

The only downside is that I can do this only on triggers that have been defined above the line with the lambda, so it could currently not be used to e.g. have triggers mutually cancel each other. Currently I can't think of a use case for this either, but maybe there is one. Also, it means you are not free regarding the order of the triggers in your YAML. So if somebody can point me in the right direction to fix this (e.g. by changing code generation to declare all the id-variables first), I would be grateful.

I will create a pull request with my small change, maybe it will also help someone else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants