How to do single AND double click on a switch in automation

I have a simble switch and I want to be able to do stuff on both single and double clicks/tabs. I have the double click working, but when I try to do a single click it gets triggered on the first click of the double click - I can’t figure out how to avoid this

Any ideas??

This is the double click:

alias: My Click Situation

trigger:
  - platform: device
    domain: mqtt
    device_id: 51c91a63f296806cf37c90e00a715de3
    type: action
    subtype: "on"
    discovery_id: 0x3425b4fffe9d83d1 action_on
    id: up-single

condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - up-single
        sequence:
          - wait_for_trigger:
              - platform: device
                domain: mqtt
                device_id: 51c91a63f296806cf37c90e00a715de3
                type: action
                subtype: "on"
                discovery_id: 0x3425b4fffe9d83d1 action_on
            timeout:
              hours: 0
              minutes: 0
              seconds: 0
              milliseconds: 900
            continue_on_timeout: false
          - type: toggle
            device_id: 18a419f7c948d86f7c827bf9340d8c90
            entity_id: 514e3d3612ee5d593069462f2c1f48c3
            domain: switch

    default: []
mode: single

1 Like

You can’t avoid it; your automation is designed to trigger for a single-click.

A “double-click” is just two consecutive single-clicks with less than a second between the two.

Your automation is designed to trigger on a single-click then wait (for up to 900ms) for another single-click. If the second single-click is not received within 900ms, then it wasn’t a double-click but simply a single-click.

You can determine if the wait_for_trigger detected the second single-click or timed out by checking the wait variable.

BTW, you should add the max_exceeded option to your automation like this:

max_exceeded: silent

Hi Taras,

Thanks for taking the time!
I’m not sure I understand - are you saying that it can not be done (period) or are you merely saying that with the code I provided it can not be done?

I can throw away the code and start over if there is another way.

Can you elaborate?

I did; review what I wrote.

Hi Taras,

Thanks - I got it.
Posting the code if it can help anyone else:

choose:
  - conditions:
      - condition: trigger
        id:
          - up-single
    sequence:
      - wait_for_trigger:
          - platform: device
            domain: mqtt
            device_id: 51c91a63f296806cf37c90e00a715de3
            type: action
            subtype: "on"
            discovery_id: 0x3425b4fffe9d83d1 action_on
        timeout:
          hours: 0
          minutes: 0
          seconds: 1
          milliseconds: 0
        continue_on_timeout: true
      - if:
          - condition: template
            value_template: "{{  wait.trigger == none }}"
        then:
           << HERE GOES SINGLE CLICK ACTIONS >>
        else:
           << HERE GOES DOUBLE CLICK ACTIONS >>   
5 Likes

You’re welcome!

Please consider marking my post above with the Solution tag. It will automatically place a check-mark next to the topic’s title which signals to other users that this topic has been resolved. This helps users find answers to similar questions.

For more information about the Solution tag, refer to guideline 21 in the FAQ.

I was notified that you marked my post with the Solution tag.

image

However, when I examine this topic, it appears that you decided to undo that and marked your own post instead. What changed your mind?

Thank you both for this example. @123 gave the solution on how to do it, but ultimately, I found the post with the full example clearer and directly usable as the solution.
It’s easy to support triple clicks and more with this method by just nesting the wait_for_trigger, I love it. :heart_eyes:

1 Like

For future reference, the point of the Solution tag is to identify the response post that supplies the answer to the question/problem described in the topic’s first post. Only on very rare occasions does a topic author actually solve their own problem.

The solution is to check the wait variable. Without that concept, kaninfod’s automation would remain faulty. FWIW, I also made a second recommendation that kaninfod overlooked to implement in his post.

If every person asking a question always marked their own post as the Solution, it would appear that everyone ultimately solves their own problem (even if they didn’t think of the actual solution). That’s not how the Solution tag was meant to be used.

After 5 years of helping thousands of users, I have found that the majority comply with the guideline on their own or shortly after it’s purpose is explained to them. Only a small minority continue to misinterpret or ignore it. A very small number even abuse it by copying a suggested example verbatim just so they can mark their own post with the Solution tag.

1 Like

I think you take it too personally, there’s clearly no harm here.

As you quote the guidelines, one could consider that you helped the author to find the solution by giving him/her pointers, but you did not provide the complete solution to the question of the topic. The precise answer is

      - if:
          - condition: template
            value_template: "{{  wait.trigger == none }}"
        then:
           << HERE GOES SINGLE CLICK ACTIONS >>
        else:
           << HERE GOES DOUBLE CLICK ACTIONS >>

i.e., checking that the wait variable was “none”, so in that case, marking his/her answer as valid seems acceptable.

I’ve sent you a coffee, I feel that’s a more valuable support than a forum statistic.

1 Like

No compliance either.


Kaninfod started this topic because he did not know how to solve the problem. He then used the suggested solution (check the state of the wait variable) so guideline 21 applies, not 19.

Kaninfod originally did mark my post with the Solution tag but then promptly switched it to his own post. I was curious to know why but he hasn’t replied despite the fact he is still actively reading and posting.

I abandoned this topic as a lost cause until you replied.

Adhering to the guidelines makes this community forum run smoothly. Complying with guideline 21 is a benefit to all users (not just the topic’s author or the person who devised the solution). In this particular case, the topic is short but others can be very long; identifying the correct Solution post saves time for other users searching for answers. Marking the correct post with the Solution tag is a good habit to develop.

Thank you.

1 Like

It’s easy to support triple clicks and more with this method by just nesting the wait_for_trigger

Could you please provide an example of this nesting? I’m (still) having issues to wrap my head around how this ‘lambda’ or ‘template’ code works, and an example for instance with triple clicking, would help me a lot.
Thank you.

Sure,

The idea is the following:

1) First event, wait 500 ms for another click
  a) If - Nothing happened -> Single click
  b) Else - Another click happened
    2) Wait 500 ms for another click
       a) If - Nothing happened -> Double click
       b) Else - Another click happened --> Triple click
          (if you support max 3 clicks, you can immediately trigger it,
           otherwise, wait again for the trigger)

You can “nest” indefinitely wait_for_trigger actions like this.

Here’s a example with triple-click support.
Be sure to use continue_on_timeout for wait_for_trigger

alias: Multi-clicks automation
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.button
    to: press
condition: []
action:
  - wait_for_trigger:
      - platform: state
        entity_id:
          - sensor.button
        to: press
    timeout:
      hours: 0
      minutes: 0
      seconds: 0
      milliseconds: 500
    continue_on_timeout: true
  - if:
      - condition: template
        value_template: "{{  wait.trigger == none }}"
    then:
          # Single click action
    else:
      - wait_for_trigger:
          - platform: state
            entity_id:
              - sensor.button
            to: press
        timeout:
          hours: 0
          minutes: 0
          seconds: 0
          milliseconds: 500
        continue_on_timeout: true
      - if:
          - condition: template
            value_template: "{{  wait.trigger == none }}"
        then:
          # Double click action
        else:
          # Triple click action
mode: single
max_exceeded: silent
1 Like

Thank you so much for the example code. I totally follow you with the pseudeo-code, or “idea” as you put it, but the actual code introduced a number of syntax statements I was not familiar with previously. I will have a closer look into the documentation for those syntaxes; your example has provided for an excellent starting point for me.
Thanks again for taking the time to explain and provide guidance. Much appreciated!

1 Like

You’re welcome. :slight_smile:

You can also have a look at blueprints, some of them could already do the job depending on what you want to do:

Isn’t this completely different to the tag “switch” that’s attached to the thread? AFAIK a switch can only be turned off and on, not “pressed” and “released”. So whats the solution for an actual switch? Phind was not able to make any sense of it.

A push switch is a type of switch: Push switch - Wikipedia

Did you have a look at the link above?

  name: Multi Click Button
  author: AntonH
  description: |
    **Version 1.1**
    Allows multi-click actions to take place on a button.
    Upon reaching the number of required clicks, it executes user defined actions.

    There are 3 entity types supported:
      - button
      - input_button
      - switch

I realize this topic is a bit old, but just came to the surface. I simply use two automations, one for click, and one for double click. Never ran into any of these problems. Maybe ane easier solution? Idk. Could also be the type of button. I’m using aqara zigbee buttons.

The blueprint you linked to sadly did not work in my case. It was not triggering when i needed it to. However, i got a automation to work thanks to @codeinprogress on the HomeAssistant Discord server:

alias: Bathroom Space Heater Socket Double Press Timer
description: >-
  Turns off the bathroom space heater socket after 30 minutes if it was turned
  on within 3 seconds of being turned off physically
trigger:
  - platform: state
    entity_id:
      - switch.bathroom_space_heater_socket_switch
    to:
      - "on"
      - "off"
condition:
  - condition: template
    value_template: >-
      {{ trigger.to_state.context.id != none and
      trigger.to_state.context.parent_id == none and
      trigger.to_state.context.user_id == none }}
action:
  - wait_for_trigger:
      - platform: state
        entity_id:
          - switch.bathroom_space_heater_socket_switch
        from:
          - "off"
          - "on"
        to:
          - "on"
          - "off"
    timeout:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
    continue_on_timeout: false
  - parallel:
      - service: button.press
        metadata: {}
        data: {}
        target:
          entity_id: button.bathroom_space_heater_socket_identify
        enabled: false
      - service: notify.blus_notify_devices
        metadata: {}
        data:
          message: Bathroom Space Heater Socket Double Press Timer
      - delay:
          hours: 0
          minutes: 30
          seconds: 0
          milliseconds: 0
  - service: switch.turn_off
    target:
      entity_id:
        - switch.bathroom_space_heater_socket_switch
    data: {}
mode: single