Long and short button pressing automation

Hey guys, I have a couple of puls buttons throughout my house and want to add an extra layer to them.

Im activating scenes when the button inputs switch from off to on.
But now I want to add a second automation to them, when pressed longer than 1 second.

This works, but there’s an unwanted side effect.

Lets say input 1 short pressed activates scene 1.
And long press activates scene 2

now when another scene is activated (e.g. scene 3) and I long press it will first activate scene 1 and then 2.

I tried adding a wait timer before activating, but that just overrules the long press as the short press scene gets activated after the await time expires.

short press automation:

alias: Puls 1 kort
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.pulslinks1
    from: "off"
    to: "on"
condition: []
action:
  - service: scene.turn_on
    target:
      entity_id: scene.verlichting
    metadata: {}
mode: single

long press automation:

alias: Puls 1 Lang
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.pulslinks1
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: 1
condition: []
action:
  - service: scene.turn_on
    target:
      entity_id: scene.verlichting_uit
    metadata: {}
mode: single

Try putting the 1 second delay as a condition instead of in the trigger for the scene 2 automation.

But that won’t solve the issue with the scene 1 automation always triggering before scene 2 automation.

I’m not sure how or if you can prevent that.

I don’t think you can solve that.
I’m just thinking out loud now. Perhaps using a history stats sensor?
It will probably cause a delay from pressing to action but that could give something perhaps.
Or click and double click using a history stats count sensor? But that will also cause a delay

Is it possible to halt an automation from start and only fire, when a certain condition is met?

e.g. this automation: button is pushed, wait for it to be released, then execute 1 of two actions depending on the time it was pushed? if/ then/ else

Perhaps that is possible.
Trigger on state off then.
If you add a history stats sensor with the time “on” the past two seconds.
As action, add a choose with history stats > 1 or < 1 as condition.

Assuming “on” = currently pressed and “off” = released, most likely both long and short should be triggered as:

from:on
to:off

then condition on

{{ trigger.to_state.last_updated - trigger.from_state.last_updated  > as_timedelta("00:00:01") }}

to determine if it was a short or long press.

Yes, this is the solution.
Is it possible to add a maximum time to this, so it executes after 1,5/2 seconds?

Now when you long press, you can, e.g., long press indefinitely.
I think it would “feel” better when you see the scene change while pressing the button. That way you know you’ve pressed long enough.

Use something like your original logic for the long press and what I posted for the short press.

1 Like

It took me awhile, because I was thinking way too difficult. I was also trying to activate the long press buttons with an alteration of your code.
I did not understand your last post correctly…

What I did now, obviously, is use your code for the short press (less then 1 sec and on to off)
and for the long press just simply, activate when pressed, from off to on for 1 second.)

Works like a charm!

Thanks again @jerrm !

1 Like

Hey jba, could you please share your working code. I try to solve the same problem (long and short press). A working example would be finde. Thank you.

I will try to asap, when I’m back from holiday!

Sorry, been awhile, but I hope its still helpfull:
Example yaml automation for short press, this automation executes a scene when the button is pushed and released within 1 second.

alias: Puls 1 kort (Lampen Zacht, Hue Aan)
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.pulslinks1
    from: "on"
    to: "off"
condition:
  - condition: template
    value_template: >-
      {{ trigger.to_state.last_updated - trigger.from_state.last_updated  <
      as_timedelta("00:00:01") }}
action:
  - service: scene.turn_on
    target:
      entity_id: scene.verlichting_zacht_hue_aan
    metadata: {}
mode: single

This automation is for when the same button is held for longer than a second:

alias: Puls 1 Lang (Alles uit)
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.pulslinks1
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: 1
    from: "off"
condition: []
action:
  - service: scene.turn_on
    target:
      entity_id: scene.verlichting_uit
    metadata: {}
mode: single

1 Like

Thanks a lot for this help. Here’s my version with multiple times in the same automation:

alias: ESPHome Space Heater Right Button Click
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.esphome_space_heater_right_button
    to: "off"
    from: "on"
condition: []
action:
  - choose:
      - conditions:
          - condition: template
            value_template: >-
              {{ trigger.to_state.last_updated -
              trigger.from_state.last_updated  <= as_timedelta("00:00:01") }}
        sequence:
          - service: light.toggle
            metadata: {}
            data: {}
            target:
              entity_id: light.ceiling_light
      - conditions:
          - condition: template
            value_template: >-
              {{ (trigger.to_state.last_updated -
              trigger.from_state.last_updated  > as_timedelta("00:00:01")) and
              (trigger.to_state.last_updated - trigger.from_state.last_updated 
              < as_timedelta("00:00:10")) }}
        sequence:
          - service: light.toggle
            metadata: {}
            data: {}
            target:
              entity_id: light.floodlight
      - conditions:
          - condition: template
            value_template: >-
              {{ trigger.to_state.last_updated -
              trigger.from_state.last_updated  >= as_timedelta("00:00:10") }}
        sequence:
          - service: light.toggle
            metadata: {}
            data: {}
            target:
              area_id: timos_zimmer
mode: single
2 Likes

Hi,

Is it possible to make it a blueprint?

Thanks,

John.

Just some unsorted thoughts…

Since the trigger is a binary_sensor it’s state can be only „on“ or „off“. That’s why I think it is not needed to use the „from:“ part here.

In addition I would believe it could be only one automation triggered by „to: off“ and then using the „choose“ action to decide how long the press was. This would also give the option to have not only short and long presses but also very long presses and very, very long and so on.

Been using it for more than a year now, never had any problems or the need to expand on it.
But I think your right, the “from” isn’t necessarily needed.

A binary sensor can have other states like Unknown and Unavailable, so it’s better to leave the from: part there to avoid unwanted triggers.

2 Likes

Why do you want to make it a blueprint?
The code is pretty straight forward?

blueprints are always preferable. less things that can go wrong, even if its just indentation or some benign bs