Envisalink Honeywell Scripts: Find installer code & Bypass all Zones

The following are two scripts I created to solve needs I had for Honeywell Vista Alarm installations.

  1. Bypass All Zones - Sends a single bypass command to the panel which includes all zones in fault.
  2. Find installer code - This scripts will find your installer code by looping through a user defined range of possible four-digit codes.

Bypass All Zones

Objective: Create a script which generates a numeric string to bypass all active (triggered) zones on a Honeywell alarm panel, using the Envisalink integration via envisalink.alarm_keypress service.

Why: Honeywell panels don’t support a single command to bypass all zones like DSC, but multiple zone ids can be bypassed with a single command.

I read that the Envisalink.keypress service is limited to 6 characters, but I have not found that to be the case.

Steps:

  • Query all binary_sensors with “zone” as a secondary attribute, and identify those with a state of “on”
  • Create a numeric string concatenating the alarm code, followed by the number ‘6’, followed by a list of zone id’s from the sensors in ‘on’ state (zone id is an attribute for Envisalink sensors). Single digit zone id’s are appended with a ‘0’ prefix so they are entered as two digits in the string.

Considerations

  • Confirm that you don’t have any other entities with the zone attribute besides those that belong to Envisalink sensors.
  • Change the notify service and alarm_control_panel entity name with values for your instance.
  • Because scripts can’t read the secrets.yaml file, this script uses a template sensor whose state = !secrets alarm_user_code. You will nee to add your alarm_user_code into your secrets.yaml and create a similar sensor, or replace the secret reference with your user code directly.
  • The notify service operations aren’t necessary, but they are helpful when initially testing to ensure each step is working as expected.
alias: Bypass All Faulted Zones
sequence:
  - service: notify.notify
    data:
      message: "Generating zone string..."
  - variables:
      zone_numbers: []
      sensor_index: 0
  - repeat:
      until:
        condition: template
        value_template: "{{ sensor_index >= states.binary_sensor | selectattr('attributes.device', 'eq', 'envisalink') | selectattr('state', 'eq', 'on') | list | count }}"
      sequence:
        - variables:
            sensor: "{{ states.binary_sensor | selectattr('attributes.device', 'eq', 'envisalink') | selectattr('state', 'eq', 'on') | list | [sensor_index] | first }}"
        - choose:
            - conditions:
                - condition: template
                  value_template: "{{ sensor.attributes.zone is defined }}"
              sequence:
                - service: notify.notify
                  data:
                    message: "Adding zone {{ sensor.attributes.zone }} to the list."
                - service: variable.set
                  data:
                    variable: zone_numbers
                    value: "{{ zone_numbers + [sensor.attributes.zone | string] }}"
                - service: variable.set
                  data:
                    variable: sensor_index
                    value: "{{ sensor_index + 1 }}"
  - service: notify.notify
    data:
      message: "Generated zone numbers: {{ zone_numbers }}"
  - service: envisalink.alarm_keypress
    data:
      entity_id: alarm_control_panel.home_alarm
      keypress: {{ [states('sensor.alarm_user_code'), '6', zone_numbers_str] | join('')
        }}

–

Brute Force Installer Code

Objective: To gain access to programming mode through brute force attempts, where the user is in possession of the disarm code.

Why: Typically Honewell users can use the backdoor method to gain access to programming mode, but in edge cases this is not possible. The backdoor method requires the user to press * and # simultaneously on a keypad during the first 45 seconds after power cycling the panel. In my case, all the keypads at this location were Tuxedo touch keypads which are powered by the panel, and take > 45 seconds to boot up themselves, making it impossible to use them for this purpose. I didn’t want to purchase another keypad, and I don’t know if the keypress service can submit and hold two presses simultaneously (if you know, please tell us how!).

Overview:

  • This script attempts to enter programming mode by trying four-digit codes in a range of your choosing (0-9999) and submits them in a string followed by 800 (eg. 0000800).
  • It then waits the number of seconds specified in your delay helper before reading the state of the keypad which will indicate whether programming mode has been accessed (e.g. Installer Code 20), if the state has changed to something else, or if nothing has happened.
  • If nothing happens, then the script will try the next code. After every three tries it will submit a disarm command to prevent the keypad from going into a 15 minute lockout after too many (~30) keypresses without a valid code.
  • If the state of the alarm changes to anything other than ‘Ready to Arm’ or message about a zone ‘fault’, then it will stop the script and notify you of the new state of the alarm. This is to avoid triggering an alarm or changing a setting on either the alarm or the keypad.
  • If programming mode is accessed, the script will then notify the user of it’s success and include the last code tried. It will then automatically exit programming mode with *99.

Requirements:

  1. Three input_number helpers and one input_boolean.
  • Code Finder Start (0-9999)
  • Code Finder End (0-9999)
  • Code Finder Delay (seconds)
  • Code Finder Stop (boolean used to indicate loop status and stop the loop)
  1. Change notify service to your preference
  2. Add your alarm user code to your secrets file and reference it with a template sensor.

Considerations

  • The script will stop as soon as the keypad displays anything containing anything other than “Ready to Arm” or “Fault”, so the alarm must be in a disarmed state when this runs. I’d recommend bypassing any triggered sensors to be safe.
  • All the keypads function differently WRT how and when they make noise. I found that whenever the keypad was locked out it would chime loudly. You’re more likely to run into this if you use a lower delay threshold. The keypads also beep when a successful disarm command is sent, so one or more keypads will beep after every three failed attempts (several times per minute) to access programming. Typically you can turn these chimes off, but the processes is different for each model.
alias: Brute Force Installer Code 
sequence:
  - service: notify.pushover
    data:
      message: Starting loop code entry...
  - service: input_boolean.turn_off
    entity_id: input_boolean.stop_code_loop
  - repeat:
      count: >-
        {{ (states('input_number.code_finder_stop') | int) -
        (states('input_number.code_finder_start') | int) + 1 }}
      sequence:
        - condition: state
          entity_id: input_boolean.stop_code_loop
          state: "off"
        - service: envisalink.alarm_keypress
          data:
            entity_id: alarm_control_panel.home_alarm
            keypress: >-
              {{ '%04d' | format(states('input_number.code_finder_start') | int
              + repeat.index - 1) }}800
        - delay:
            seconds: "{{ states('input_number.code_finder_delay') | int }}"
        - choose:
            - conditions:
                - condition: template
                  value_template: >-
                    {{ 'installer code' in
                    states('sensor.home_alarm_keypad')|lower() }}
              sequence:
                - service: notify.pushover
                  data:
                    message: >-
                      Installer code found: {{ '%04d' |
                      format(states('input_number.code_finder_start') | int +
                      repeat.index - 1) }}
                - service: input_boolean.turn_on
                  entity_id: input_boolean.stop_code_loop
                - delay:
                    seconds: 4
                - service: envisalink.alarm_keypress
                  data:
                    entity_id: alarm_control_panel.home_alarm
                    keypress: "*99"
            - conditions:
                - condition: template
                  value_template: >-
                    {{ not 'ready to arm' in
                    states('sensor.home_alarm_keypad')|lower() and not 'fault'
                    in states('sensor.home_alarm_keypad')|lower() }}
              sequence:
                - service: notify.pushover
                  data:
                    message: >-
                      Alarm state changed: {{ states('sensor.home_alarm_keypad')
                      }}
                - service: input_boolean.turn_on
                  entity_id: input_boolean.stop_code_loop
        - condition: template
          value_template: "{{ repeat.index % 3 == 0 }}"
        - service: alarm_control_panel.alarm_disarm
          data:
            code: "{{ states('sensor.alarm_user_code') }}"
          target:
            entity_id: alarm_control_panel.home_alarm
        - delay:
            seconds: 3
  - service: notify.pushover
    data:
      message: All codes tried or loop stopped.
1 Like

For more information on how to find the installer code for:
Honeywell panels: Possible to set up a new Honeywell Vista 20p using new EVL4 instead of keypad? - EyezOn Forum

DSC panels: EVL 4, DSC and lost installer code - hacking my own system - Page 6 - EyezOn Forum

Still room for improvement. Just ran this on a different install, and it found the code after 8k+ tries. However, the code it sent in the notification was one digit larger than the actual code. Could probably tweak the script a bit more, but it works!

If you use this and the code found doesn’t work, then try the preceding number or two.

So I take it that if you had to make a custom script that the Envisalink does not bypass zones automatically anymore?

Perhaps Envisalink can bypass zones from it’s app, but I don’t use it and am doing everything from HA. The behaviors are also different between DSC and Honeywell. TMK DSC does have a bypass-all command, but Honeywell does not. That said, I’m definitely not a subject matter expert on Honeywell or Envisalink, if you know a better means, please share.

My older Honeywell Vista panel had an option to enable “last-digit+1” as the duress code. So if my code was 1234 but I entered 1235 to disarm it, it would disarm the system AND trigger a silent police alarm.

If you got a hit on 1235 and found that code 1234 worked, it might have hiccuped during the test of 1234 but you got lucky due to the secret duress code. And you might have triggered a silent alarm.

It sounds like you’re talking about the Alarm code as opposed to the Installer code. My post above is in reference to finding the installer code, which requires the script to regularly submit the disarm code. Unless the installer code offers a similar +1 function, which I doubt it does, then I don’t think this would be an issue.
That said, I’d suggest disconnecting the panel from any phone or other outbound connections before brute forcing anything, just to be safe.

How do you trigger that scripts? I want to bypass before arming the alarm. Sorry I am new to HA.

For the bypass-all script, you could create a button on a dashboard that calls the script, or a helper to toggle it.

I did this with a button (tile card) inside of a conditional card, so the Bypass All button only shows when the alarm is disarmed and there are faults (open doors, etc.). While you can do this with the UI, my dashboard YAML for the conditional card is below.

      - type: conditional
        conditions:
          - entity: sensor.alarm_fault
            state: 'True'
          - entity: alarm_control_panel.house
            state: disarmed
        card:
          type: tile
          name: Bypass All Zones
          icon: mdi:arrow-decision-outline
          tap_action:
            action: call-service
            service: script.turn_on
            target:
              entity_id: script.1692240797289
            data: {}
          entity: script.1692240797289
          vertical: false
          hide_state: true
1 Like