Instantly share code, notes, and snippets.
Created
August 25, 2025 10:47
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save MarkWattTech/d9bf68718d88fa20dbc0921470079b23 to your computer and use it in GitHub Desktop.
haab_keypad_button_router.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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