Skip to content

Instantly share code, notes, and snippets.

@MarkWattTech
Created August 25, 2025 10:47
Show Gist options
  • Select an option

  • Save MarkWattTech/d9bf68718d88fa20dbc0921470079b23 to your computer and use it in GitHub Desktop.

Select an option

Save MarkWattTech/d9bf68718d88fa20dbc0921470079b23 to your computer and use it in GitHub Desktop.
haab_keypad_button_router.yaml
blueprint:
name: HAAB Keypad Button Router (v5 with guards)
description: >
Routes `esphome.keypad_event` by Page (1–4) and Button (1–4).
Optional guards:
• Limit handling to a specific keypad (device selector).
• Only run actions when a Screen Awake binary_sensor is ON.
domain: automation
input:
# --- Optional guards ---
guard_limit_device:
name: Limit to a specific keypad
description: Only handle events from the selected keypad device.
default: false
selector:
boolean: {}
limit_to_device:
name: Keypad device (optional)
description: >
Pick the ESPHome keypad device this automation should listen to.
Only used if "Limit to a specific keypad" is enabled.
default: null
selector:
device: {} # <-- device selector (not an entity selector)
guard_screen_awake:
name: Require "Screen Awake" to run
description: >
If enabled, actions only run when the selected binary_sensor is ON.
default: false
selector:
boolean: {}
screen_awake_entity:
name: Screen Awake entity (optional)
description: >
The ESPHome binary_sensor that mirrors display state (ON = awake).
Only used if the guard above is enabled.
default: null
selector:
entity:
domain: binary_sensor
# --- Actions for each Page×Button ---
p1b1: { name: P1 — Button 1, default: [], selector: { action: {} } }
p1b2: { name: P1 — Button 2, default: [], selector: { action: {} } }
p1b3: { name: P1 — Button 3, default: [], selector: { action: {} } }
p1b4: { name: P1 — Button 4, default: [], selector: { action: {} } }
p2b1: { name: P2 — Button 1, default: [], selector: { action: {} } }
p2b2: { name: P2 — Button 2, default: [], selector: { action: {} } }
p2b3: { name: P2 — Button 3, default: [], selector: { action: {} } }
p2b4: { name: P2 — Button 4, default: [], selector: { action: {} } }
p3b1: { name: P3 — Button 1, default: [], selector: { action: {} } }
p3b2: { name: P3 — Button 2, default: [], selector: { action: {} } }
p3b3: { name: P3 — Button 3, default: [], selector: { action: {} } }
p3b4: { name: P3 — Button 4, default: [], selector: { action: {} } }
p4b1: { name: P4 — Button 1, default: [], selector: { action: {} } }
p4b2: { name: P4 — Button 2, default: [], selector: { action: {} } }
p4b3: { name: P4 — Button 3, default: [], selector: { action: {} } }
p4b4: { name: P4 — Button 4, default: [], selector: { action: {} } }
mode: queued
max_exceeded: silent
trigger:
- platform: event
event_type: esphome.keypad_event
variables:
# Pull guard inputs into variables (device selectors resolve to a device_id string)
require_device: !input guard_limit_device
required_device_id: !input limit_to_device
require_awake: !input guard_screen_awake
awake_entity: !input screen_awake_entity
condition:
# 1) Click type must be 'single'
- condition: template
alias: "Click must be 'single'"
value_template: "{{ (trigger.event.data.click | string) | lower == 'single' }}"
# 2) If device guard enabled, device_id must match
- condition: or
alias: "Device guard"
conditions:
- condition: template
value_template: "{{ not require_device }}"
- condition: template
value_template: "{{ (trigger.event.data.device_id | string) == (required_device_id | string) }}"
# 3) If screen guard enabled, screen must be ON
- condition: or
alias: "Screen awake guard"
conditions:
- condition: template
value_template: "{{ not require_awake }}"
- condition: state
entity_id: !input screen_awake_entity
state: "on"
action:
- choose:
# ===== PAGE 1 =====
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '1'
and (trigger.event.data.button | string) == '1' }}
sequence: !input p1b1
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '1'
and (trigger.event.data.button | string) == '2' }}
sequence: !input p1b2
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '1'
and (trigger.event.data.button | string) == '3' }}
sequence: !input p1b3
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '1'
and (trigger.event.data.button | string) == '4' }}
sequence: !input p1b4
# ===== PAGE 2 =====
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '2'
and (trigger.event.data.button | string) == '1' }}
sequence: !input p2b1
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '2'
and (trigger.event.data.button | string) == '2' }}
sequence: !input p2b2
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '2'
and (trigger.event.data.button | string) == '3' }}
sequence: !input p2b3
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '2'
and (trigger.event.data.button | string) == '4' }}
sequence: !input p2b4
# ===== PAGE 3 =====
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '3'
and (trigger.event.data.button | string) == '1' }}
sequence: !input p3b1
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '3'
and (trigger.event.data.button | string) == '2' }}
sequence: !input p3b2
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '3'
and (trigger.event.data.button | string) == '3' }}
sequence: !input p3b3
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '3'
and (trigger.event.data.button | string) == '4' }}
sequence: !input p3b4
# ===== PAGE 4 =====
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '4'
and (trigger.event.data.button | string) == '1' }}
sequence: !input p4b1
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '4'
and (trigger.event.data.button | string) == '2' }}
sequence: !input p4b2
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '4'
and (trigger.event.data.button | string) == '3' }}
sequence: !input p4b3
- conditions:
- condition: template
value_template: >-
{{ (trigger.event.data.page | string) == '4'
and (trigger.event.data.button | string) == '4' }}
sequence: !input p4b4
default: []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment