Some hardware links on this page are affiliate links. As an Amazon Associate I earn from qualifying purchases. We may earn a commission if you buy through them, at no extra cost to you. See the affiliate disclosure.
A wall button that only exposes on / off is not a Hue remote. This workflow treats any binary_sensor as a press: a short tap runs one action list, a hold past a threshold runs another. It does not need device-specific short / hold events. Mash protection is mode: restart — a new press cancels the wait from the last one, so a bouncing reed does not enqueue both a short and a long.
Entity ids and action lists are blueprint inputs. Do not publish a live switch name.
This is the press primitive. Button scene cycling is the “walk a scene list” pack that sits on top of short versus long.
What problem it solves
You want two behaviours from one dry contact or GPIO — tap for one thing, hold for another — without firmware that already emits click events, and without a chatter of duplicate runs when the contact bounces.
How it works
- Trigger on press — the binary sensor goes
on(button down, reed closed, input pulled). That is the only trigger. Release is handled inside the action. - Wait for release or timeout —
wait_for_triggeronto: "off"withtimeout= the long-press threshold (pack default 1.0 s) andcontinue_on_timeout: true. - Decide — if the wait timed out (
wait.triggeris none), the contact is still held: run the long action list. If the wait caught theoff, it was a tap: run the short action list. Long therefore fires at the threshold while still held, not on release. That is the Papouch-style timing. - Spam protection — automation
mode: restart,max_exceeded: silent. A secondonbefore the wait finishes aborts the first run. You get at most one short or one long per press, not a queue. - Actions are yours — each branch is an action selector (
light.toggle, a scene, a script). The blueprint does not own lights; it only classifies the press.
A sensor that stays on for minutes (a door left open) will fire long once at the threshold. Use this pack for momentary contacts, not for “door has been open for a minute” alerts — that is nagging repeatable alert.
Hardware notes
- ESPHome GPIO. Momentary to GND,
pullup,inverted: true. Any spare pin on a node you already have. Adddelayed_on_off: 20msso mechanical bounce does not look like two presses. - Reed / dry contact. Same binary sensor. A latching reed used as a “button” works if you close-and-open it; a door you leave open will take the long path.
- Papouch-class I/O. A Quido (or any module that exposes each input as a HA
binary_sensor) is the original target. The blueprint does not care about the brand. - No extra hub. If the entity already flips in Developer Tools, this is YAML only.
Snippet
The pack ships a blueprint. Inputs replace real entity ids:
mode: restart
max_exceeded: silent
trigger:
- platform: state
entity_id: !input button_sensor
to: "on"
action:
- wait_for_trigger:
- platform: state
entity_id: !input button_sensor
to: "off"
timeout: !input long_press_time
continue_on_timeout: true
- choose:
- conditions:
- condition: template
value_template: "{{ wait.trigger == none }}"
sequence: !input long_press_action
- conditions:
- condition: template
value_template: "{{ wait.trigger != none }}"
sequence: !input short_press_action
Optional ESPHome button (credentials stay in secrets.yaml):
substitutions:
friendly_name: Utility button
button_pin: GPIO0
binary_sensor:
- platform: gpio
pin:
number: ${button_pin}
mode: INPUT_PULLUP
inverted: true
name: Press
filters:
- delayed_on_off: 20ms
Setup outline
- Confirm the binary sensor goes
onwhile held andoffwhen released (Developer Tools). Invert in ESPHome or a template helper if it is backwards. - Import the blueprint. Pick the sensor, set the threshold (1.0 s is a good start), fill short and long actions.
- Test: tap under the threshold → short only; hold past it → long only, and long fires before you let go; mash twice quickly → one classified press, not a pile.
Troubleshooting
- Short and long both fire. A second automation is also watching the same sensor, or the long action toggles something that retriggers this blueprint. One instance per contact.
- Everything is long. Threshold is shorter than your fastest tap, or the contact never returns to
off(stuck reed, inverted GPIO). Watch the state while you click. - Everything is short. Threshold is longer than you are willing to hold, or
continue_on_timeoutis missing so a hold stops the automation instead of taking the long branch. - GPIO double-taps. Bounce. Add
delayed_on_offon the ESPHome sensor; do not fight it in the blueprint. - Door contact fires long every time you leave it open. Correct for this pattern. Use a different automation for “left open”; this pack is for momentary presses.
Credits
Based on the community blueprint Papouch Short/Long Press for Any Binary Sensor. This write-up is an original overview of the wait-for-release-or-timeout pattern with restart-mode spam protection.