Zigbee2MQTT - Sync Keypad and Alarm Control Panel States

This Blueprint allows the synchronisation of an alarm control panel with a Zigbee2MQTT keypad. This means that the status of the alarm control panel is transmitted to the keypad and vice versa.

Supportes Devices

Blueprint Overview

Step 1: Import the Blueprint

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

blueprint:
  name: PIN-Keypads for Zigbee2MQTT
  description: "This Blueprint allows the synchronisation of an alarm control panel with a Zigbee2MQTT keypad. This means that the status of the alarm control panel is transmitted to the keypad and vice versa. Additionally, you can set a custom action for two wrong PINs. This way you can perform actions by entering specific wrong PINs."
  domain: automation
  input:
    z2m_keypad_path:
        name: MQTT State Topic of your Zigbee2MQTT Keypad
        description: "The State Topic is composed of your Zigbee2MQTT base_topic (see your Z2M Addon Configuration) and the Friendly Name of your keypad in Z2M. Example: zigbee2mqtt/Keypad"
    z2m_keypad_path_set:
        name: MQTT Set Topic of your Zigbee2MQTT Keypad
        description: "This is the same as your State Topic, with the addition of /set. Example: zigbee2mqtt/Keypad/set"
    pin:
        name: Pincode
        description: "The valid pin code to be accepted as correct by your alarm system. Example: 1234"
    control_panel:
        name: Control Panel
        description: "An alarm control panel. Example: https://www.home-assistant.io/integrations/manual"
        default: []
        selector:
            entity:
                domain: alarm_control_panel
    action_arming:
        name: Action Arming
        description: "An action to be performed when the alarm panel changes to the arming state."
        default: []
        selector:
            action: {}
    action_armed_home:
        name: Action Armed Home
        description: "An action to be performed when the alarm panel changes to the armed home state."
        default: []
        selector:
            action: {}
    action_armed_away:
        name: Action Armed Away
        description: "An action to be performed when the alarm panel changes to the armed away state."
        default: []
        selector:
            action: {}
    action_disarmed:
        name: Action Disarmed
        description: "An action to be performed when the alarm panel changes to the disarmed state."
        default: []
        selector:
            action: {}
    action_pending:
        name: Action Pending
        description: "An action to be performed when the alarm panel changes to the pending state."
        default: []
        selector:
            action: {}
    action_panic:
        name: Action Panic
        description: "An action to be performed when the panic / SOS button of the keypad is pressed."
        default: []
        selector:
            action: {}
    custpin1:
        name: Custom PIN 1
        default: 0000
        description: "A custom PIN to trigger a custom action. Example: 0000"
    action_cust1:
        name: Action Custom 1
        description: "An action to be performed when custom PIN 1 ist entered."
        default: []
        selector:
            action: {}
    custpin2:
        name: Custom PIN 2
        default: 1111
        description: "A custom PIN to trigger a custom action. Example: 1111"
    action_cust2:
        name: Action Custom 2
        description: "An action to be performed when custom PIN 2 ist entered."
        default: []
        selector:
            action: {}

variables:
  pin_var: !input 'pin'
  pin_var_cust1: !input 'custpin1'
  pin_var_cust2: !input 'custpin2'

trigger:
  - platform: state
    entity_id: !input 'control_panel'
    to: arming
    id: panel_arming
  - platform: state
    entity_id: !input 'control_panel'
    to: armed_home
    id: panel_armed_home
  - platform: state
    entity_id: !input 'control_panel'
    to: disarmed
    id: panel_disarmed
  - platform: state
    entity_id: !input 'control_panel'
    to: armed_away
    id: panel_armed_away
  - platform: state
    entity_id: !input 'control_panel'
    to: pending
    id: panel_pending
  - platform: mqtt
    topic: !input z2m_keypad_path
    id: keypad_mqtt
      
condition: []
    
action:
  - choose:
      - conditions:
          - condition: trigger
            id: panel_arming
        sequence:
          - choose:
              - conditions:
                  - condition: state
                    entity_id: !input 'control_panel'
                    state: armed_home
                    attribute: next_state
                sequence:
                  - service: mqtt.publish
                    data:
                      topic: !input 'z2m_keypad_path_set'
                      payload: |-
                        {
                         "arm_mode": 
                          {
                           "mode": "arm_day_zones"
                          }
                        }
              - conditions:
                  - condition: state
                    entity_id: !input 'control_panel'
                    state: armed_away
                    attribute: next_state
                sequence:
                  - service: mqtt.publish
                    data:
                      topic: !input 'z2m_keypad_path_set'
                      payload: |-
                        {
                         "arm_mode": 
                          {
                           "mode": "exit_delay"
                          }
                        }
            default: []
          - choose:
            default: !input 'action_arming'
      - conditions:
          - condition: trigger
            id: panel_armed_away
        sequence:
          - service: mqtt.publish
            data:
              topic: !input 'z2m_keypad_path_set'
              payload: |-
                {
                 "arm_mode": 
                  {
                   "mode": "arm_all_zones"
                  }
                }
          - choose:
            default: !input 'action_armed_away'
      - conditions:
          - condition: trigger
            id: panel_disarmed
        sequence:
          - service: mqtt.publish
            data:
              topic: !input 'z2m_keypad_path_set'
              payload: |-
                {
                 "arm_mode": 
                  {
                    "mode": "disarm"
                  }
                }
          - choose:
            default: !input 'action_disarmed'
      - conditions:
          - condition: trigger
            id: panel_armed_home
        sequence:
          - service: mqtt.publish
            data:
              topic: !input 'z2m_keypad_path_set'
              payload: |-
                {
                 "arm_mode": 
                  {
                   "mode": "arm_day_zones"
                  }
                }
          - choose:
            default: !input 'action_armed_home'
      - conditions:
          - condition: trigger
            id: panel_pending
        sequence:
          - choose:
            default: !input 'action_pending'
      - conditions:
          - condition: trigger
            id: keypad_mqtt
        sequence:
          - choose:
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ trigger.payload_json.action_transaction != null and
                      trigger.payload_json.action_code == pin_var }}
                sequence:
                  - service: mqtt.publish
                    data:
                      topic: !input 'z2m_keypad_path_set'
                      payload: |-
                        {
                         "arm_mode": 
                          {
                            "transaction": "{{ trigger.payload_json.action_transaction }}",
                            "mode": "{{ trigger.payload_json.action }}"
                          }
                        }
          - choose:
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ trigger.payload_json.action_transaction != null and
                      trigger.payload_json.action_code == pin_var_cust1 }}
                sequence:
                  - choose:
                    default: !input 'action_cust1'
          - choose:
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ trigger.payload_json.action_transaction != null and
                      trigger.payload_json.action_code == pin_var_cust2 }}
                sequence:
                  - choose:
                    default: !input 'action_cust2'
          - choose:
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ trigger.payload_json.action_code == pin_var and
                      trigger.payload_json.action == "arm_all_zones" }}
                sequence:
                  - service: alarm_control_panel.alarm_arm_away
                    target:
                      entity_id: !input 'control_panel'
                    data:
                      code: !input 'pin'
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ trigger.payload_json.action_code == pin_var and
                      trigger.payload_json.action == "arm_day_zones" }}
                sequence:
                  - service: alarm_control_panel.alarm_arm_home
                    target:
                      entity_id: !input 'control_panel'
                    data:
                      code: !input 'pin'
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ trigger.payload_json.action_code == pin_var and
                      trigger.payload_json.action == "disarm" }}
                sequence:
                  - service: alarm_control_panel.alarm_disarm
                    target:
                      entity_id: !input 'control_panel'
                    data:
                      code: !input 'pin'
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ trigger.payload_json.action == "panic" }}
                sequence:
                  - choose:
                    default: !input 'action_panic'
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ trigger.payload_json.action_code != pin_var and
                      trigger.payload_json.action_code | int(-1) != -1 }}
                sequence:
                  - service: mqtt.publish
                    data:
                      topic: !input 'z2m_keypad_path_set'
                      payload: |-
                        {
                         "arm_mode": 
                          {
                           "transaction": "{{ trigger.payload_json.action_transaction }}",
                           "mode": "invalid_code"
                          }
                        }
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ trigger.payload_json.action == None }}
                sequence:
                  - choose:
                      - conditions:
                          - condition: state
                            entity_id: !input 'control_panel'
                            state: armed_away
                        sequence:
                          - service: mqtt.publish
                            data:
                              topic: !input 'z2m_keypad_path_set'
                              payload: |-
                                {
                                 "arm_mode": 
                                  {
                                   "mode": "arm_all_zones"
                                  }
                                }
                      - conditions:
                          - condition: state
                            entity_id: !input 'control_panel'
                            state: armed_home
                        sequence:
                          - service: mqtt.publish
                            data:
                              topic: !input 'z2m_keypad_path_set'
                              payload: |-
                                {
                                 "arm_mode": 
                                  {
                                   "mode": "arm_day_zones"
                                  }
                                }
                      - conditions:
                          - condition: state
                            entity_id: !input 'control_panel'
                            state: disarmed
                        sequence:
                          - service: mqtt.publish
                            data:
                              topic: !input 'z2m_keypad_path_set'
                              payload: |-
                                {
                                 "arm_mode": 
                                  {
                                   "mode": "disarm"
                                  }
                                }
                      - conditions:
                          - condition: state
                            entity_id: !input 'control_panel'
                            state: arming
                          - condition: state
                            entity_id: !input 'control_panel'
                            state: armed_home
                            attribute: next_state
                        sequence:
                          - service: mqtt.publish
                            data:
                              topic: !input 'z2m_keypad_path_set'
                              payload: |-
                                {
                                 "arm_mode": 
                                  {
                                   "mode": "arm_day_zones"
                                  }
                                }
                      - conditions:
                          - condition: state
                            entity_id: !input 'control_panel'
                            state: arming
                          - condition: state
                            entity_id: !input 'control_panel'
                            state: armed_away
                            attribute: next_state
                        sequence:
                          - service: mqtt.publish
                            data:
                              topic: !input 'z2m_keypad_path_set'
                              payload: |-
                                {
                                 "arm_mode": 
                                  {
                                   "mode": "arm_all_zones"
                                  }
                                }
            default: []
    default: []
      

mode: parallel
max: 10        

Step 2: Create an Alarm Control Panel

An example configuration could look like this:

alarm_control_panel:
   - platform: manual
     name: My Alarm Panel
     delay_time: 60
     arming_time: 60
     trigger_time: 120

For more information on how to configure an alarm panel have a look at the documentation. Alarm Panels provided by other integrations should work as well.

Step 3: Pair your Keypad in Zigbee2MQTT and check its configuration
You will need:

  • A successfully paired keypad in Zigbee2MQTT. Don’t panic if the keypads connection LED is still blinking. This is no issue and will be solved later.
  • Rename the Keypad in Zigbee2MQTT and remember its name.
  • Check the base_topic of Zigbee2MQTT you are using. You will find it in the addon configuration.

Step 4: Create a blueprint automation
Create an automation based on this blueprint and fill out all required fields.

If your alarm panel uses a pin code, it is important that the pin code of this automation is identical. Otherwise, this blueprint cannot change the status of the alarm panel.

The actions can be used to define additional actions that are executed when the state is changed. However, this is optional.

Step 5: Use your blueprint
You operate your keypad as follows: First press the button of the mode you want to set. Then enter the PIN. Finally, press the tick.

Changelog

  • 2021-10-09 - 15:00 - Inital Release
  • 2021-10-09 - 20:15 - Fixed handling of incorrect PINs
  • 2021-10-15 - 15:40 - Support for Alarm Panels with Pincodes
  • 2021-10-15 - 16:24 - Support for Panic/SOS-Button Actions
  • 2023-07-25 - 14:00 - Add support for two actions triggered by entering wrong PINs
  • 2023-07-26 - 13:30 - Updated data_template to data
18 Likes

Cool! Would be nice with an action for armed night as well! At least Centralite 3400 have this button.

The Zigbee specification distinguishes between arm_day_zones, arm_night_zones and arm_all_zones. Home Assistant only distinguishes between armed_away and armed_home.

Currently, this Blueprint maps arm_day_zones to armed_home and arm_all_zones to armed_away, as the named keypads only support these two modes.

Are you sure that the Centralite 3400-D also uses arm_night_zones internally? Can you show an MQTT message for this? Since I don’t have the device, I can’t experiment with it myself. Have you tried the blueprint with your device yet?

Well, my technical/programming skills are low but when arming night it sends mqtt message "action": "arm_night_zones". Don’t know how that is handled internally though.

Have tried the Blueprint, but I don’t get it working. Probably I am the one doing something wrong. Am using Alarmo as alarm panel. When using the correct code, which is setup in the blueprint as well as in Alarmo integration the Alarmo card shows that incorrect code has been used and the keypad beeps. When using an incorrect code nothing happens, neither in the alarmo card or no beeps or LEDs on the keypad.

Please try it with the manual alarm control panel (Step 2). Then we can find out, if it is an issue with alarm or with the keypad.

Thanks for the blueprint @AndrejDelany! I also can’t get this to work, unfortunately. I have tried with Alarmo and a manual panel. I can see from MQTT explorer that the correct action is sent when the correct code is input into the keypad. I also got the same behaviour in Alarmo as @rindlerblabla, where it is clearly seeing the message, but indicates with a red flash in the Alarmo panel card that an incorrect code has been used. I’m using a Linkind ZS130000078. Happy to troubleshoot if I can!

Have you tried to use exactly the same manual alarm panel code as shown above (Step 2)?

If you used exactly the same config, please check the core logs, if there are any hints that night help us.

Thanks for your help @AndrejDelany, finally got it working!

Can you explain what the problem was? Maybe this will help others with the set-up.

Thanks for the reply. I had entered a “code: XXXX” into the configuration yaml code previously. When I remove that the manual alarm panel now works with the keypad, thank you.

However, it still won’t work with Alarmo, which I would prefer to use. Is there a way of changing the configuration in the Alarmo settings to get it to work?

Ah, okay. This Blueprint currently only supports alarm panels that do not use a code themselves. Does Alarmo use a code? Maybe I could fix that.

Can you take a look at the core logs to see what messages come up when you use the Blueprint together with Alarmo?

Yes, you use a code in the Alarmo settings, and can choose whether to use it for arming/disarming or both. It also allows different codes for different users. It also allows setting the alarm by MQTT, but I have that turned off currently.

In the logs I just see:
WARNING (MainThread) [custom_components.alarmo.alarm_control_panel] Wrong code provided.

Thanks

I just released a new version of this blueprint. Please try this new version with your alarmo panel. Keep in mind to use the same pincode with the blueprint and the alarmo panel.

It works perfectly, thank you so much!

hi @AndrejDelany, is there another way to get this blueprint? I don’t know whats happening but I cant donwload it, I got a TIMEOUT message, when I try another blueprints, most of them works, I don´t know why this is not available for me, Thanks
Can´t upload my printscreen to show you my problem

PS. I copied the yaml to a folder in config/blueprint/automation/AndrejDelany and it worked, I dont know if is the right way.

Hi everyone,

I’ve made another attempt to add better support for those Zigbee keypads and created a custom component (HACS supported).

It does very similar things.

You can give it a try: https://github.com/kvj/hass_transaction_alarm_panel

2 Likes

@AndrejDelany

Thank you for the blueprint, this is amazing.

I think my issue isn’t with your blueprint but with Zigbee2MQTT but not sure if you can help.
I can’t seem to pair the keypad.

I seem to get it to pair, and it shows up on the Zigbee Front End and Home Assistant, then then I get a red connection every time I try to touch it. I also get the below error messages in the log. I’ve tried 3 or 4 times but not luck…

Error ‘0x588e81fffe232ebe’ does not exist, skipping publish

Error Failed to configure ‘FrontDoorKeypad’, attempt 1 (Error: Bind 0x588e81fffe232ebe/1 genPowerCfg from ‘0x00212effff0745c9/1’ failed (waiting for response TIMEOUT) at DeconzAdapter.bind (/opt/zigbee2mqtt/node_modules/zigbee-herdsman/src/adapter/deconz/adapter/deconzAdapter.ts:757:19) at Endpoint.bind (/opt/zigbee2mqtt/node_modules/zigbee-herdsman/src/controller/model/endpoint.ts:500:13) at Object.bind (/opt/zigbee2mqtt/node_modules/zigbee-herdsman-converters/lib/reporting.js:33:9) at Object.configure (/opt/zigbee2mqtt/node_modules/zigbee-herdsman-converters/devices/linkind.js:29:13) at Configure.configure (/opt/zigbee2mqtt/lib/extension/configure.ts:119:13))

Error Entity ‘frontdoorkeypad’ is unknown

Could you please check, if the device interview has completed (last point in screenshot)?
Please also always use the same name for the device - case sensitive! As I see in your logs you are using frontdoorkeypad, FrontDoorKeypad and 0x588e81fffe232ebe.

So, interview has complete, but the device has never been “last seen” no matter what I do.
I sorted the device name issue last night so I don’t get that error any more, but still get the issue that the second I touch a button on the keypad I get solid green in battery, solid red in network with beeps.

I’m assuming i’m pairing correctly though by just pressing the reset button in?

If the pairing was successful, it should work if you use “KeypadFrontDoor” in the Blueprint in your case. Unfortunately I can’t provide general support for Zigbee2MQTT, I don’t know it well enough :frowning: