Zigbee2MQTT - Sync Keypad and Alarm Control Panel States

Thanks. I have this keypad Universal Electronics Inc XHK1-UE control via MQTT | Zigbee2MQTT

It does have support for : disarm , arm_day_zones , arm_night_zones , arm_all_zones , invalid_code , not_ready , already_disarmed

Please check what action is triggered on the button that is not working for you. You can use the Zigbee2MQTT log to do so.

MQTT publish: topic 'zigbee2mqtt/Alarm Keypad', payload '{"action":"arm_night_zones","action_code":"1234","action_transaction":39,"action_zone":23,"battery":100,"battery_low":true,"contact":true,"linkquality":90,"occupancy":true,"presence":null,"tamper":false,"temperature":21,"voltage":5300}'

That is the line from the log

Okay, then you’re out of luck with this blueprint, unfortunately. The keypads I use can only switch between two armed modes, not three.

Of course, if you want to, you can work your way in and add the third mode to the blueprint. Contributions are always welcome.

Sounds great. The blue print does work great for me, just the one button doesn’t work using it. I will try to figure out what to change to make it work and then share it. Thanks so much, this is what I always wanted and a big reason I switched from deconz.

Working great with my Technicolor XHK1-TC (Technicolor XHK1-TC control via MQTT | Zigbee2MQTT).
Modified the blueprint since it was missing arm_night_zones.

blueprint:
  name: Alarmo Keypad Sync with nightmode
  description: Keypad sync with Alarmo added nightmode
  domain: automation

  input:
    state_topic:
      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"
      selector:
        text:
    set_topic:
      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"
      selector:
        text:
    entity:
      name: Alarmo entity
      description: "An alarm control panel entity from alarmo."
      selector:
        entity:
          domain: alarm_control_panel
          integration: alarmo

trigger:
  - platform: state
    entity_id: !input entity
    to: disarmed
    id: to_state_disarmed
  - platform: state
    entity_id: !input entity
    to: armed_home
    id: to_state_armed_home
  - platform: state
    entity_id: !input entity
    to: armed_night
    id: to_state_armed_night
  - platform: state
    entity_id: !input entity
    to: armed_away
    id: to_state_armed_away
  - platform: state
    entity_id: !input entity
    to: arming
    id: to_state_arming
  - platform: state
    entity_id: !input entity
    to: pending
    id: to_state_pending
  - platform: state
    entity_id: !input entity
    to: triggered
    id: to_state_triggered
  - platform: mqtt
    topic: !input state_topic
    id: keypad_command
  - platform: event
    event_type: alarmo_failed_to_arm
    id: event_arm_failure
  - platform: event
    event_type: alarmo_command_success
    id: event_command_success
condition: []

action:
  - choose:
      - conditions:
          - condition: trigger
            id: to_state_disarmed
        sequence:
          - service: mqtt.publish
            data_template:
              topic: !input set_topic
              payload: |-
                {
                  "arm_mode": 
                  {
                    "mode": "disarm"
                  }
                }
      - conditions:
          - condition: trigger
            id: to_state_armed_home
        sequence:
          - service: mqtt.publish
            data_template:
              topic: !input set_topic
              payload: |-
                {
                  "arm_mode": 
                  {
                    "mode": "arm_day_zones"
                  }
                }
      - conditions:
          - condition: trigger
            id: to_state_armed_night
        sequence:
          - service: mqtt.publish
            data_template:
              topic: !input set_topic
              payload: |-
                {
                  "arm_mode": 
                  {
                    "mode": "arm_night_zones"
                  }
                }
      - conditions:
          - condition: trigger
            id: to_state_armed_away
        sequence:
          - service: mqtt.publish
            data_template:
              topic: !input set_topic
              payload: |-
                {
                  "arm_mode": 
                  {
                    "mode": "arm_all_zones"
                  }
                }
      - conditions:
          - condition: trigger
            id: to_state_arming
        sequence:
          - service: mqtt.publish
            data_template:
              topic: !input set_topic
              payload: |-
                {
                  "arm_mode": 
                  {
                    "mode": "exit_delay"
                  }
                }
      - conditions:
          - condition: trigger
            id: to_state_pending
        sequence:
          - service: mqtt.publish
            data_template:
              topic: !input set_topic
              payload: |-
                {
                  "arm_mode": 
                  {
                    "mode": "entry_delay"
                  }
                }
      - conditions:
          - condition: trigger
            id: to_state_triggered
        sequence:
          - service: mqtt.publish
            data_template:
              topic: !input set_topic
              payload: |-
                {
                  "arm_mode": 
                  {
                    "mode": "in_alarm"
                  }
                }
      - conditions:
          - condition: trigger
            id: keypad_command
        sequence:
          - choose:
              - conditions:
                  - condition: template
                    value_template: '{{ trigger.payload_json.action == "disarm"  }}'
                sequence:
                  - service: alarmo.disarm
                    data:
                      entity_id: !input entity
                      code: "{{ trigger.payload_json.action_code }}"
                      context_id: "{{ trigger.payload_json.action_transaction }}"
              - conditions:
                  - condition: template
                    value_template: '{{ trigger.payload_json.action == "arm_all_zones"  }}'
                sequence:
                  - service: alarmo.arm
                    data:
                      entity_id: !input entity
                      mode: away
                      code: "{{ trigger.payload_json.action_code }}"
                      context_id: "{{ trigger.payload_json.action_transaction }}"
              - conditions:
                  - condition: template
                    value_template: '{{ trigger.payload_json.action == "arm_day_zones"  }}'
                sequence:
                  - service: alarmo.arm
                    data:
                      entity_id: !input entity
                      mode: home
                      code: "{{ trigger.payload_json.action_code }}"
                      context_id: "{{ trigger.payload_json.action_transaction }}"
              - conditions:
                  - condition: template
                    value_template: '{{ trigger.payload_json.action == "arm_night_zones"  }}'
                sequence:
                  - service: alarmo.arm
                    data:
                      entity_id: !input entity
                      mode: night
                      code: "{{ trigger.payload_json.action_code }}"
                      context_id: "{{ trigger.payload_json.action_transaction }}"
      - conditions:
          - condition: trigger
            id: event_arm_failure
        sequence:
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.event.data.reason == 'invalid_code' }}"
                sequence:
                  - service: mqtt.publish
                    data_template:
                      topic: !input set_topic
                      payload: |-
                        {
                          "arm_mode": 
                          {
                            "transaction": {{ trigger.event.data.context_id }},
                            "mode": "invalid_code"
                          }
                        }
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.event.data.reason == 'open_sensors' }}"
                sequence:
                  - service: mqtt.publish
                    data_template:
                      topic: !input set_topic
                      payload: |-
                        {
                          "arm_mode": 
                          {
                            "transaction": {{ trigger.event.data.context_id }},
                            "mode": "not_ready"
                          }
                        }
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.event.data.reason == 'not_allowed' }}"
                  - condition: template
                    value_template: "{{ trigger.event.data.command|lower == 'disarm' }}"
                sequence:
                  - service: mqtt.publish
                    data_template:
                      topic: !input set_topic
                      payload: |-
                        {
                          "arm_mode": 
                          {
                            "transaction": {{ trigger.event.data.context_id }},
                            "mode": "already_disarmed"
                          }
                        }
      - conditions:
          - condition: trigger
            id: event_command_success
        sequence:
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.event.data.action == 'arm' }}"
                  - condition: template
                    value_template: "{{ trigger.event.data.context_id != null }}"
                  - condition: template
                    value_template: "{{ trigger.event.data.mode == 'away' }}"
                sequence:
                  - service: mqtt.publish
                    data_template:
                      topic: !input set_topic
                      payload: |-
                        {
                          "arm_mode": 
                          {
                            "transaction": {{ trigger.event.data.context_id }},
                            "mode": "arm_all_zones"
                          }
                        }
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.event.data.action == 'arm' }}"
                  - condition: template
                    value_template: "{{ trigger.event.data.context_id != null }}"
                  - condition: template
                    value_template: "{{ trigger.event.data.mode == 'home' }}"
                sequence:
                  - service: mqtt.publish
                    data_template:
                      topic: !input set_topic
                      payload: |-
                        {
                          "arm_mode": 
                          {
                            "transaction": {{ trigger.event.data.context_id }},
                            "mode": "arm_day_zones"
                          }
                        }
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.event.data.action == 'arm' }}"
                  - condition: template
                    value_template: "{{ trigger.event.data.context_id != null }}"
                  - condition: template
                    value_template: "{{ trigger.event.data.mode == 'night' }}"
                sequence:
                  - service: mqtt.publish
                    data_template:
                      topic: !input set_topic
                      payload: |-
                        {
                          "arm_mode": 
                          {
                            "transaction": {{ trigger.event.data.context_id }},
                            "mode": "arm_night_zones"
                          }
                        }
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.event.data.action == 'disarm' }}"
                  - condition: template
                    value_template: "{{ trigger.event.data.context_id != null }}"
                sequence:
                  - service: mqtt.publish
                    data_template:
                      topic: !input set_topic
                      payload: |-
                        {
                          "arm_mode": 
                          {
                            "transaction": {{ trigger.event.data.context_id }},
                            "mode": "disarm"
                          }
                        }
mode: parallel
max: 10
1 Like

Hi Paolo.
I have the same Develco Keypad and I’ve managed to get it working with this blueprint.
When armed and disarmed the keypad gives feedback with a ‘Beep’. If I have a arm delay, the keypad is not beeping during the countdown. It this the same for you?

Did you get this to work with more than one code?
If so, can you share how you did this?
Thanks :slight_smile:

I ended up using alarmo and then I made these automations to control the keypad.

I use two keypad so this can be done much simpler.

1 Like

Awesome!
Thanks for your help :slight_smile:

Have you figured it out? I am at the same spot right now. Everything works except the arm_night_zones.

if you are a moron like me scratching your head thinking you have it setup perfectly. please check for upper/lower case naming you have set!

my friendly name was set to keypad and in the blueprint i had zigbee2mqqt/Keypad

renamed zigbee friendly name to Keypad and suprise suprise it now works!

Can I ask how you got this to work? The keypad paired fine. It seems to communicate with the automation in that it triggers it, and it seems to get responses back. If I arm the alarm, the keypad gets the message and glows red. If I run the actions in the blueprint by hand, it arms or disarms the alarm (using alarmo). But the keypad will never arm or disarm the alarm. The trace always looks the same (Option 6 executed). It seems like it is very nearly working, but some detail is wrong. Any help appreciated.

UPDATE: OK, I figured out that I needed to add another 4-digit code to Alarmo for the keypad. I made it the same as the keypad code, so not sure if it because they are the same, or because it needed to be 4 digits, or because it just needed to be a new slot. But now it works. alarm_night_zones is not working, so might try the modifications of @Tykan to the blueprint.

Great work @AndrejDelany ! Thank you for sharing.

I tried @Tykan 's modification, but it lacked some of the features of the original, so I modded the original instead. All I did was add the night arming feature available on both Alarmo and the Xfinity XHK1-UE keypad. Using this blueprint, you could easily program this button on the keypad to do some other function on your alarm panel, like arm vacation. It is a trivial change to @AndrejDelany 's original blueprint, so I will just add it here.

blueprint:
  name: PIN-Keypads for Zigbee2MQTT including Xfinity XHK1-UE
  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.
  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
          multiple: false
    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_night:
      name: Action Armed Night
      description: An action to be performed when the alarm panel changes to the armed
        away 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: {}
  source_url: https://community.home-assistant.io/t/zigbee2mqtt-sync-keypad-and-with-alarm-control-panel-states/345311
variables:
  pin_var: !input pin
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: armed_night
  id: panel_armed_night
- 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_template:
            topic: !input z2m_keypad_path_set
            payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_day_zones\"\n  }\n}"
      - conditions:
        - condition: state
          entity_id: !input control_panel
          state: armed_night
          attribute: next_state
        sequence:
        - service: mqtt.publish
          data_template:
            topic: !input z2m_keypad_path_set
            payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_night_zones\"\n  }\n}"
      - conditions:
        - condition: state
          entity_id: !input control_panel
          state: armed_away
          attribute: next_state
        sequence:
        - service: mqtt.publish
          data_template:
            topic: !input z2m_keypad_path_set
            payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"exit_delay\"\n  }\n}"
      default: []
    - choose:
      default: !input action_arming
  - conditions:
    - condition: trigger
      id: panel_armed_away
    sequence:
    - service: mqtt.publish
      data_template:
        topic: !input z2m_keypad_path_set
        payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_all_zones\"\n  }\n}"
    - choose:
      default: !input action_armed_away
  - conditions:
    - condition: trigger
      id: panel_disarmed
    sequence:
    - service: mqtt.publish
      data_template:
        topic: !input z2m_keypad_path_set
        payload: "{\n \"arm_mode\": \n  {\n    \"mode\": \"disarm\"\n  }\n}"
    - choose:
      default: !input action_disarmed
  - conditions:
    - condition: trigger
      id: panel_armed_home
    sequence:
    - service: mqtt.publish
      data_template:
        topic: !input z2m_keypad_path_set
        payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_day_zones\"\n  }\n}"
    - choose:
      default: !input action_armed_home
  - conditions:
    - condition: trigger
      id: panel_armed_night
    sequence:
    - service: mqtt.publish
      data_template:
        topic: !input z2m_keypad_path_set
        payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_night_zones\"\n  }\n}"
    - choose:
      default: !input action_armed_night
  - 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_template:
            topic: !input z2m_keypad_path_set
            payload: "{\n \"arm_mode\": \n  {\n    \"transaction\": \"{{ trigger.payload_json.action_transaction
              }}\",\n    \"mode\": \"{{ trigger.payload_json.action }}\"\n  }\n}"
    - 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_night_zones" }}'
        sequence:
        - service: alarm_control_panel.alarm_arm_night
          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_template:
            topic: !input z2m_keypad_path_set
            payload: "{\n \"arm_mode\": \n  {\n   \"transaction\": \"{{ trigger.payload_json.action_transaction
              }}\",\n   \"mode\": \"invalid_code\"\n  }\n}"
      - 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_template:
                topic: !input z2m_keypad_path_set
                payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_all_zones\"\n
                  \ }\n}"
          - conditions:
            - condition: state
              entity_id: !input control_panel
              state: armed_home
            sequence:
            - service: mqtt.publish
              data_template:
                topic: !input z2m_keypad_path_set
                payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_day_zones\"\n
                  \ }\n}"
          - conditions:
            - condition: state
              entity_id: !input control_panel
              state: armed_night
            sequence:
            - service: mqtt.publish
              data_template:
                topic: !input z2m_keypad_path_set
                payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_night_zones\"\n
                  \ }\n}"
          - conditions:
            - condition: state
              entity_id: !input control_panel
              state: disarmed
            sequence:
            - service: mqtt.publish
              data_template:
                topic: !input z2m_keypad_path_set
                payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"disarm\"\n  }\n}"
          - 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_template:
                topic: !input z2m_keypad_path_set
                payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_day_zones\"\n
                  \ }\n}"
          - conditions:
            - condition: state
              entity_id: !input control_panel
              state: arming
            - condition: state
              entity_id: !input control_panel
              state: armed_night
              attribute: next_state
            sequence:
            - service: mqtt.publish
              data_template:
                topic: !input z2m_keypad_path_set
                payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_night_zones\"\n
                  \ }\n}"
          - 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_template:
                topic: !input z2m_keypad_path_set
                payload: "{\n \"arm_mode\": \n  {\n   \"mode\": \"arm_all_zones\"\n
                  \ }\n}"
      default: []
  default: []
mode: parallel
max: 10

1 Like

I’m having trouble importing this and keep getting

No valid blueprint found in the topic. Blueprint syntax blocks need to be marked as YAML or no syntax
any suggestions?

I have tried editing it as an automation directly but struggling as my yaml skills are rather limited.

Did you check in the blueprints/automation/AndrejDelany folder to see if you have the yaml file there? You might need to restart HA.

Good luck.

1 Like

Wasn’t there so I created it and the blueprint is now available, haven’t got it working exactly as I wanted but at least I now have something to work with.

Many thanks for helping me out :+1:
.
And obviously many thanks to @AndrejDelany for the blueprint :+1:

Is there any way to extend this Blueprint to support additional usage of codes - i.e. 8888 = turn off the lights, 7777 = open my garage door

I love this idea! Will have a look into it, but don’t expect it to happen right now as I’m on vacation.

Thanks - Enjoy!