Simple Keypad PIN Actions - Zigbee2MQTT

First published blueprint for me so be gentle. I have wanted to replace my RF garage door keypad for a few years. Came across the Xfinity style (XHK1-UE) keypads and thought it to be a good fit. Obviously they are not IP rated for outdoor use but I have come up with another solution to keep it dry.

I found Stefan’s blueprint for syncing these keypads to an alarm panel definition in HA where he also had a few custom PIN action functions. I did not need the alarm panel sync for my use case so I used his custom PIN code and expanded it to support eight codes.

I have only tested this with Xfinity XHK1-UE but I presume it will work with other similar keypads supported in Z2M.

Github Repo Here

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

blueprint:
  name: Simple Keypad Code Actions
  description: This blueprint simply takes 4 digit codes from zigbee keypads and executes an action. Eight pin/action pairs are defined but this can easily be expanded. Based on original blueprint from AndrejDelany.
  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'
      default: zigbee2mqtt/Keypad
    custpin1:
      name: Custom PIN 1
      default: 0
      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 is entered.
      default: []
      selector:
        action: {}
    custpin2:
      name: Custom PIN 2
      default: []
      description: 'A custom PIN to trigger a custom action. Example: 0000'
    action_cust2:
      name: Action Custom 2
      description: An action to be performed when custom PIN 2 is entered.
      default: []
      selector:
        action: {}
    custpin3:
      name: Custom PIN 3
      default: 0
      description: 'A custom PIN to trigger a custom action. Example: 0000'
    action_cust3:
      name: Action Custom 3
      description: An action to be performed when custom PIN 3 is entered.
      default: []
      selector:
        action: {}
    custpin4:
      name: Custom PIN 4
      default: []
      description: 'A custom PIN to trigger a custom action. Example: 0000'
    action_cust4:
      name: Action Custom 4
      description: An action to be performed when custom PIN 4 is entered.
      default: []
      selector:
        action: {}
    custpin5:
      name: Custom PIN 5
      default: 0
      description: 'A custom PIN to trigger a custom action. Example: 0000'
    action_cust5:
      name: Action Custom 5
      description: An action to be performed when custom PIN 5 is entered.
      default: []
      selector:
        action: {}
    custpin6:
      name: Custom PIN 6
      default: []
      description: 'A custom PIN to trigger a custom action. Example: 0000'
    action_cust6:
      name: Action Custom 6
      description: An action to be performed when custom PIN 6 is entered.
      default: []
      selector:
        action: {}
    custpin7:
      name: Custom PIN 
      default: 0
      description: 'A custom PIN to trigger a custom action. Example: 0000'
    action_cust7:
      name: Action Custom 7
      description: An action to be performed when custom PIN 7 is entered.
      default: []
      selector:
        action: {}
    custpin8:
      name: Custom PIN 8
      default: []
      description: 'A custom PIN to trigger a custom action. Example: 0000'
    action_cust8:
      name: Action Custom 8
      description: An action to be performed when custom PIN 8 is entered.
      default: []
      selector:
        action: {}
  source_url: https://community.home-assistant.io/t/zigbee2mqtt-sync-keypad-and-with-alarm-control-panel-states/345311
variables:
  pin_var_cust1: !input custpin1
  pin_var_cust2: !input custpin2
  pin_var_cust3: !input custpin3
  pin_var_cust4: !input custpin4
  pin_var_cust5: !input custpin5
  pin_var_cust6: !input custpin6
  pin_var_cust7: !input custpin7
  pin_var_cust8: !input custpin8
trigger:
- platform: mqtt
  topic: !input z2m_keypad_path
  id: keypad_mqtt
condition: []
action:
- choose:
  - 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_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_transaction != null and
            trigger.payload_json.action_code == pin_var_cust3 }}'
        sequence:
        - choose:
          default: !input action_cust3
    - choose:
      - conditions:
        - condition: template
          value_template: '{{ trigger.payload_json.action_transaction != null and
            trigger.payload_json.action_code == pin_var_cust4 }}'
        sequence:
        - choose:
          default: !input action_cust4
    - choose:
      - conditions:
        - condition: template
          value_template: '{{ trigger.payload_json.action_transaction != null and
            trigger.payload_json.action_code == pin_var_cust5 }}'
        sequence:
        - choose:
          default: !input action_cust5
    - choose:
      - conditions:
        - condition: template
          value_template: '{{ trigger.payload_json.action_transaction != null and
            trigger.payload_json.action_code == pin_var_cust6 }}'
        sequence:
        - choose:
          default: !input action_cust6
    - choose:
      - conditions:
        - condition: template
          value_template: '{{ trigger.payload_json.action_transaction != null and
            trigger.payload_json.action_code == pin_var_cust7 }}'
        sequence:
        - choose:
          default: !input action_cust7
    - choose:
      - conditions:
        - condition: template
          value_template: '{{ trigger.payload_json.action_transaction != null and
            trigger.payload_json.action_code == pin_var_cust8 }}'
        sequence:
        - choose:
          default: !input action_cust8
      default: []
  default: []
mode: restart

1 Like

I don’t have the hardware, but looking at your design as a BP writer I do have a question / suggestion.

Does anything bad happen when they key in the wrong or not matching code?
I see defaults default to nothing, and conditions are blank. Does this handle unknown codes OK? I mean without a log error or something? Always good to cover the what-if’s which prevent customer problems down the line.

To close the loop I might suggest adding either a condition that checks the code value you get from the trigger to see that it’s valid and it’s one of the codes you are looking for, or you do something with the default to tell the operator the code is not valid. Often Z2M devices send wake-up triggers or sleep triggers and this can spam logs. I know the cube remotes do that.

Sample condition statement here:
https://github.com/SirGoodenough/HA_Blueprints/blob/c05d6fb431c1d84cb145c7d6dd5ffe5a60b1d9e2/Automations/Zigbee2MQTT-Xiaomi_Cube_Controller_MQTT_Triggered.yaml#L763.

Otherwise looks good to me. Good idea to help the community.

I have tested invalid code and it definitely flows to default. I’ll add an action to the default branch so a notification or other action can be taken.

This device seems to be pretty quiet in the Z2M logs until some expose changes. Most often the temp sensor that actually seems fairly accurate.

The other thing I would like to do for my use case is have a central repo like secrets.yaml for codes that my Alarmo panel, z-wave locks, and this controller look up.

I will dig into your conditions in the cube blueprint and see if there is something I might be able to simplify.

I haven’t tried !secrets in BP’s, but I suspect the user might be able to use them without your intervention. You would have to test it. You are pulling the pin in as text so it might work.

If so, it could just be a suggestion in your top post and the description.