Import as a Home Assistant blueprint using:
- Blueprint address: https://gist.githubusercontent.com/e7d/b361111875dc9db79ecb5da9ce2c75f9/raw/KEPZB-110-for-Alarmo.yaml
- Blueprint path: e7d/KEPZB-110-for-Alarmo
Import as a Home Assistant blueprint using:
| blueprint: | |
| name: Keypad Frient (KEPZB-110) for Alarmo | |
| description: > | |
| Manage multiple PIN codes to arm and disarm an alarm using the Frient Keypad, | |
| synchronizing the state with an Alarmo central or other alarm panel.<br> | |
| You will need to create the same PIN codes in Alarmo, which also supports RFID badges. | |
| domain: automation | |
| input: | |
| keypad: | |
| name: Frient Keypad | |
| description: > | |
| The Frient KEPZB-110 keypad device.<br> | |
| Must be paired via ZHA integration. | |
| selector: | |
| device: | |
| integration: zha | |
| alarm_panel: | |
| name: Alarm Panel | |
| description: > | |
| The Frient alarm control panel entity. | |
| selector: | |
| entity: | |
| domain: alarm_control_panel | |
| mirror_alarm_panel: | |
| name: Alarm Panel to Mirror | |
| description: > | |
| The alarm panel to sync with the Frient keypad (e.g., Alarmo).<br> | |
| State changes on this panel will be mirrored to the Frient keypad and vice versa. | |
| default: alarm_control_panel.alarmo | |
| selector: | |
| entity: | |
| domain: alarm_control_panel | |
| pin_list: | |
| name: Valid PIN Codes | |
| description: > | |
| List of valid PIN codes for arming and disarming, separated by semicolons (;).<br> | |
| Example: 1234;5678;9012 | |
| default: "" | |
| selector: | |
| text: {} | |
| rfid_list: | |
| name: RFID List | |
| description: > | |
| A list of valid RFID identifiers accepted by the keypad, separated by semicolons (;).<br> | |
| Example: ABC123;DEF456 | |
| default: "" | |
| selector: | |
| text: {} | |
| default_pin: | |
| name: Default PIN Code for Frient Keypad | |
| description: > | |
| The default PIN code used to control the Frient alarm panel internally.<br> | |
| This is sent when syncing state from the mirrored panel back to the Frient keypad. | |
| default: "" | |
| selector: | |
| text: {} | |
| mirror_default_pin: | |
| name: Default PIN Code for Mirrored Alarm | |
| description: > | |
| The default PIN code used when forwarding commands to the mirrored alarm panel.<br> | |
| Used as a fallback when no code is provided by the keypad event. | |
| default: "" | |
| selector: | |
| text: {} | |
| trigger: | |
| - platform: event | |
| event_type: zha_event | |
| event_data: | |
| device_id: !input keypad | |
| command: arm | |
| id: keypad_event | |
| - platform: state | |
| entity_id: !input mirror_alarm_panel | |
| id: alarmo_state_change | |
| variables: | |
| pin_list_raw: !input pin_list | |
| pin_list: "{{ pin_list_raw.split(';') | reject('eq', '') | list }}" | |
| rfid_list_raw: !input rfid_list | |
| rfid_list: "{{ rfid_list_raw.split(';') | reject('eq', '') | list }}" | |
| mirror_default_pin: !input mirror_default_pin | |
| default_pin: !input default_pin | |
| alarm_panel: !input alarm_panel | |
| mirror_alarm_panel_entity: !input mirror_alarm_panel | |
| event_code: > | |
| {{ (trigger.event.data.args.code | default('')) | string if trigger.id == 'keypad_event' else '' }} | |
| event_arm_mode: > | |
| {{ trigger.event.data.args.arm_mode | default(-1) | int if trigger.id == 'keypad_event' else -1 }} | |
| code_to_send: > | |
| {{ event_code if event_code != '' else mirror_default_pin }} | |
| is_valid_pin: > | |
| {{ (event_code | string) in pin_list if pin_list | length > 0 else true }} | |
| is_valid_rfid: > | |
| {{ event_code in rfid_list if rfid_list | length > 0 else false }} | |
| is_authorized: > | |
| {{ is_valid_pin or is_valid_rfid or event_code == '' }} | |
| action: | |
| - choose: | |
| # ══════════════════════════════════════════════ | |
| # ── Keypad Event: forward to mirrored panel ── | |
| # ══════════════════════════════════════════════ | |
| - conditions: | |
| - condition: trigger | |
| id: keypad_event | |
| sequence: | |
| # ── Circuit breaker: ignore echo from mirror sync ── | |
| - condition: template | |
| alias: "Circuit breaker: ignore default_pin echo from mirror sync" | |
| value_template: "{{ event_code != default_pin }}" | |
| - choose: | |
| # ── Unauthorized code ── | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ not is_authorized }}" | |
| sequence: [] | |
| # ── Disarm (arm_mode 0) ── | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ event_arm_mode == 0 and is_authorized }}" | |
| - condition: not | |
| conditions: | |
| - condition: state | |
| entity_id: !input mirror_alarm_panel | |
| state: "disarmed" | |
| sequence: | |
| - service: alarm_control_panel.alarm_disarm | |
| target: | |
| entity_id: !input alarm_panel | |
| data: | |
| code: "{{ code_to_send }}" | |
| - service: alarm_control_panel.alarm_disarm | |
| target: | |
| entity_id: !input mirror_alarm_panel | |
| data: | |
| code: "{{ code_to_send }}" | |
| # ── Arm Home (arm_mode 1) ── | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ event_arm_mode == 1 and is_authorized }}" | |
| - condition: not | |
| conditions: | |
| - condition: state | |
| entity_id: !input mirror_alarm_panel | |
| state: "armed_home" | |
| sequence: | |
| - service: alarm_control_panel.alarm_arm_home | |
| target: | |
| entity_id: !input alarm_panel | |
| data: | |
| code: "{{ code_to_send }}" | |
| - service: alarm_control_panel.alarm_arm_home | |
| target: | |
| entity_id: !input mirror_alarm_panel | |
| data: | |
| code: "{{ code_to_send }}" | |
| # ── Arm Night (arm_mode 2) ── | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ event_arm_mode == 2 and is_authorized }}" | |
| - condition: not | |
| conditions: | |
| - condition: state | |
| entity_id: !input mirror_alarm_panel | |
| state: "armed_night" | |
| sequence: | |
| - service: alarm_control_panel.alarm_arm_night | |
| target: | |
| entity_id: !input alarm_panel | |
| data: | |
| code: "{{ code_to_send }}" | |
| - service: alarm_control_panel.alarm_arm_night | |
| target: | |
| entity_id: !input mirror_alarm_panel | |
| data: | |
| code: "{{ code_to_send }}" | |
| # ── Arm Away (arm_mode 3) ── | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ event_arm_mode == 3 and is_authorized }}" | |
| - condition: not | |
| conditions: | |
| - condition: state | |
| entity_id: !input mirror_alarm_panel | |
| state: "armed_away" | |
| sequence: | |
| - service: alarm_control_panel.alarm_arm_away | |
| target: | |
| entity_id: !input alarm_panel | |
| data: | |
| code: "{{ code_to_send }}" | |
| - service: alarm_control_panel.alarm_arm_away | |
| target: | |
| entity_id: !input mirror_alarm_panel | |
| data: | |
| code: "{{ code_to_send }}" | |
| # ══════════════════════════════════════════════════════════ | |
| # ── Alarmo State Change: mirror back to Frient keypad ──── | |
| # ══════════════════════════════════════════════════════════ | |
| - conditions: | |
| - condition: trigger | |
| id: alarmo_state_change | |
| - condition: template | |
| value_template: > | |
| {{ trigger.to_state.context.parent_id != this.context.id }} | |
| sequence: | |
| - condition: template | |
| value_template: "{{ states(alarm_panel) != trigger.to_state.state }}" | |
| - choose: | |
| # ── Mirror: Disarmed ── | |
| - conditions: | |
| - condition: state | |
| entity_id: !input mirror_alarm_panel | |
| state: "disarmed" | |
| sequence: | |
| - service: alarm_control_panel.alarm_disarm | |
| target: | |
| entity_id: !input alarm_panel | |
| data: | |
| code: !input default_pin | |
| # ── Mirror: Armed Home ── | |
| - conditions: | |
| - condition: state | |
| entity_id: !input mirror_alarm_panel | |
| state: "armed_home" | |
| sequence: | |
| - service: alarm_control_panel.alarm_arm_home | |
| target: | |
| entity_id: !input alarm_panel | |
| data: | |
| code: !input default_pin | |
| # ── Mirror: Armed Night ── | |
| - conditions: | |
| - condition: state | |
| entity_id: !input mirror_alarm_panel | |
| state: "armed_night" | |
| sequence: | |
| - service: alarm_control_panel.alarm_arm_night | |
| target: | |
| entity_id: !input alarm_panel | |
| data: | |
| code: !input default_pin | |
| # ── Mirror: Armed Away ── | |
| - conditions: | |
| - condition: state | |
| entity_id: !input mirror_alarm_panel | |
| state: "armed_away" | |
| sequence: | |
| - service: alarm_control_panel.alarm_arm_away | |
| target: | |
| entity_id: !input alarm_panel | |
| data: | |
| code: !input default_pin | |
| # ── Mirror: Triggered ── | |
| - conditions: | |
| - condition: state | |
| entity_id: !input mirror_alarm_panel | |
| state: "triggered" | |
| sequence: | |
| - service: alarm_control_panel.alarm_trigger | |
| target: | |
| entity_id: !input alarm_panel | |
| default: [] | |
| mode: single |