Envisalink integration. Things users should know about it

In the past I had made some updates to the upstream python library used by the integration, in order to add additional features. I am now doing the same thing to the integration component, such as supporting the new vacation arm mode. I will list other changes in another post when I get them working.

HOWEVER, I have noticed some things that are either incorrect or could lead to unexpected behavior when auditing the code.

The good:
The integration documentation lists the alarm_keypress function working on DSC and probably on Honeywell. Well, internally ALL the other functions use the keypress function to send commands to the panel, so it is definitely working. Also you can for sure send more than 6 characters at least for Honeywell panels, there does not actually seem to be a defined limit anywhere for those. An example is a zone bypass, CODE615 is the 7 character sequence to bypass zone 15, and that indeed works.

It should be mentioned the Honeywell panels expect a minimum 2 second delay between sending different sequences of commands to the panel, so if you need to toggle a connected relay, you cannot do it for less than 2 seconds, for example, a toggle of relay 11 is a set of 8 character sequences CODE#711 and CODE#811, but since they need to be different commands, the min 2s delay must be inserted before the 2nd sequence.

The bad:
alarm_trigger does not appear to send the trigger to the specified keypad for Honeywell, but rather the keypad for partition 1, this is hard coded in the library. If you are using multiple partitions, and P2 is set up for say, medical alerts, and you try to trigger it, it will trigger the alarm on P1 instead. In houses/apartments where the partitions are set up for different families or individuals, this can cause problems, potentially serious. The DSC code does not specify a partition at all, I am not sure if that is the correct behavior.

For Honeywell, the library internal partition status codes are not correct for ARMED_MAX and ARMED_INSTANT. Because of this arming MAX does not report the partition status internally at all, and arming INSTANT or NIGHT reports as ARMED_MAX. There is a similar issue in the integration code, where the night arm state is reported solely by the 0-entry delay flag being true. This will be true for MAX and INSTANT arming only, so the integration reports the wrong state 100% of the time if one of those 3 arming modes is used.

The state attribute armed_bypass actually reports the presence of a bypassed zone on Honeywell, regardless of arming status. I will submit a fix to the upstream lib to remove ‘armed_’. The DSC code does not even reference this, and I am not sure it applies.

The ugly:
the panic_type for alarm_trigger is also hardcoded in the library, but it may not match your keypad if you have Honeywell. This means if I try to trigger the default Police type, instead it triggers Fire. This is because the the trigger function in the library maps the type to a signal letter representing the A-C panic keys… and those are defined during panel program. The lib maps Fire,Ambulance,Police to A,B,C. If you need the correct trigger, send the correct keypress to the partition as a letter. DSC keypads have their panic types fixed and the library appears correct for them.

The arming code for the library function arm_night_partition is listed as 7, but this is actually the code for INSTANT arming. What this means is that if you call the function to NIGHT-STAY arm the panel, you INSTANT arm instead, and any night zones which would trigger the alarm remain unarmed. Additionally, NIGHT-STAY arming should include an entry delay, but INSTANT does not, as per its namesake referring to the 0-entry delay, so if somebody comes home at night, and they open the door… the alarm goes off immediately. The correct arming code for night mode is 33. I will also be submitting upstream fixes for this.


But wait, there’s more!

Concerning night arming, the Envisalink library abstracts the night arming into a command code sent to the panel the virtual keypad provided by the device, as it does with pretty much every command. But the DSC and Honeywell panels do night arming differently, both in how commands are entered on the keypad, and how the night arming functions on the panel. The Honeywell library client sends a set of virtual keypresses, whereas the DSC client sends a specific arm command (032).

DSC panels use night arm as an exclusion of zones, whereas Honewell panels as an addition of zones. Each type of panel has the option to program a night zone list. When a Honeywell panel is armed in stay vs night mode, all interior zones are unsecured for stay, but zones in the night zone list are secured for night. When a DSC panel is armed in stay vs night mode, all interior zones are unsecured for stay, but all interior zones NOT in the night zone are secured for night. Both systems secure the interior zones when armed away.

It appears to me that the original code behind that abstraction was designed to make the function for night arming work more similar for both panels, the DSC code actual calls the MAX arming function for night mode, just like the Honeywell code calls the INSTANT arming function. Interestingly, I have no idea how to MAX arm from a regular keypad… or from the code either, since it actually INSTANT arms the panel! Thats right, night arming either system from the library will INSTANT arm the panel.

I am not 100% sure, but I do not think you can just night arm a DSC panel with a single function, I think you need to arm it as home first, since it appears the command code sequence has an identical prefix to the zone bypass function. That means that in order to correctly night arm a DSC panel, you need to arm as stay, wait for it to become armed, then arm as night. I am not sure how the library will handle that, if there are any Envisalink+DSC users reading this it would be nice if you could list you panel/keypad models, and confirm if that is how yours function.

If it does indeed work that way, the night arm function can set a flag, then when it becomes armed, it looks for that flag and sends the night arm sequence, then removes the flag. Disarming would also remove the flag.

I did find the documentation as to how the Envisalink gets bypass=true from the DSC panels, but the command is not referenced by the library, which is why it will not report zone bypass.


Using envisalink 4 w/ Home Assistant and Honeywell Vista 128bpt.
When I arm it, envisalink integration goes to pending and then incorrectly to disarmed. I tracked it down to the fact that i get this from pyenvisalink:

{‘alarm’: False, ‘alarm_in_memory’: False, ‘armed_away’: False, ‘ac_present’: True, ‘armed_bypass’: False, ‘chime’: False, ‘armed_zero_entry_delay’: False, ‘alarm_fire_zone’: False, ‘trouble’: False, ‘bat_trouble’: False, ‘ready’: False, ‘fire’: False, ‘armed_stay’: False, ‘alpha’: ‘N/A’, ‘beep’: False, ‘exit_delay’: False, ‘entry_delay’: False, ‘last_disarmed_by_user’: ‘’, ‘last_armed_by_user’: ‘’, ‘armed’: True}

NOTE: “armed” here is True not armed_away or armed_stay.

And the fact that HA integration does not check “armed” - just armed_away or armed_stay

All arming modes should be some extension of home or away

Home = home
Night = home + night zones
Instant = home + 0 entry delay
Away = away
Max = Away + 0 entry delay

Internally pyenvisalink SHOULD report at least armed_away or armed_stay in addition to armed, since the EVL reports the keypad status as armed_away OR armed_stay (not as armed), then pyenvisalink also sets armed as true based on the partition status code, which is also one of the 4 arming states (night reports as home)

So if armed=true, one of the others HAS to be true, which is what the HA code is expecting, and that should work. I sounds like something is wrong in pyenvisalink for you… what arming mode were you using?

Nice collection of info. Here’s some random observations I’ve had after integrating a Honeywell Vista 21-IP with Envisalink 4 here:

I have noticed a kludgy way to distinguish STAY from NIGHT-STAY on an armed panel, at least in my configuration. The state attributes of sensor.p1_keypad are identical, except that in NIGHT-STAY, beep is 'unknown' whereas in STAY (and all other modes) it’s 'off' (unless the touchpad is actually beeping).

The following two JINJA2 expressions will capture the top and bottom lines of the alphanumeric display respectively:

{{ states('sensor.p1_keypad')|batch(16)|reverse|last|join|replace(' ',' ')|replace('*','\*') }}
{{ states('sensor.p1_keypad')|batch(16)|reverse|first|join|replace(' ',' ')|replace('*','\*') }}

Using the top expression as input (sensor.alarm_p1_display_top), this will evaluate to True if Night-Stay mode is active, and is more reliable:

{{ states('sensor.alarm_p1_display_top')|regex_search('NIGHT-STAY',ignorecase=true) }}

Similarly, since exit_delay never seems to switch to True, you can derive whether it’s active from the bottom line, as well as determining how many seconds until the delay ends:

friendly_name: 'P1 Alarm Exit Delay'
value_template: >-
  {{ states('sensor.alarm_p1_display_bottom')|replace(' ',' ')|regex_search('may exit now', ignorecase=true) }}
icon_template: >-
  {% if states('sensor.alarm_p1_display_bottom')|replace(' ',' ')|regex_search('may exit now', ignorecase=true) %} 
  {% else %}
  {% endif %}
  time_remaining: >-
    {% if states('sensor.alarm_p1_display_bottom')|replace(' ',' ')|regex_match('May Exit Now  ', ignorecase=true) %}
      {{ states('sensor.alarm_p1_display_bottom')|replace(' ',' ')|regex_replace(find='May Exit Now', replace='', ignorecase=true)|trim }}
    {% endif %}

(I’ve got a growing number of these binary_sensors written to try to make up for the shortfalls and idiosyncrasies of the Envisalink hardware.)

A fault state can be derived by the fact that it’s neither Armed nor Ready:

{{ not (state_attr('sensor.p1_keypad','armed_stay') or state_attr('sensor.p1_keypad','armed_away')) and not state_attr('sensor.p1_keypad','ready') }}

Interestingly, during an entry delay, armed goes to False but either armed_stay or armed_away remains set at True until the system is disarmed, depending on which mode was armed.

Since there’s no timer display on the keypad during an entry delay, best I’ve been able to come up with is to use an automation to start a timer when entry_delay switches to True. If you have different entry delays for different doors, you’ll need to incorporate a conditional that senses which door is open and/or unlocked to override the default timer duration.

As mentioned, using the built-in functions to arm “Night” actually arms “Instant” mode. Manually arming “Maximum” or “Instant” (using keypad input) also throws errors to the log (each three times):

2021-08-17 09:34:42 ERROR (MainThread) [homeassistant.util.logging] Exception in _update_callback when dispatching 'envisalink.partition_updated': ('',)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/envisalink/sensor.py", line 76, in _update_callback
    if partition is None or int(partition) == self._partition_number:
ValueError: invalid literal for int() with base 10: ''

2021-08-17 09:34:42 ERROR (MainThread) [homeassistant.util.logging] Exception in _update_callback when dispatching 'envisalink.partition_updated': ('',)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/envisalink/alarm_control_panel.py", line 129, in _update_callback
    if partition is None or int(partition) == self._partition_number:
ValueError: invalid literal for int() with base 10: ''

That is concerning, it appears to work on my 20p.

There is actually a built in “pending” control panel mode in the alarm control panel code, it just does not work with the envisalink integration, same with “arming” when there is an exit delay. I have that fixed in my testing code. But of course this uses the state of exit_delay for arming so that needs to work.

I have an idea why it MIGHT not work, are you using step arming?

I will probably get this fixed upstream since it is fixed in my dev branch

I will also keep looking into the night-stay situation, since that should be fixed in pyenvisalink for proper detection

1 Like

I’m not. Arming using either the built-in alarm function or keypresses (code + mode), either through the Envisilink integration or the physical keypad.


Exit delay (both before and after door opening):

(As you can see, I do have the exit beeps turned off, so I guess if something is relying on that to diagnose exit mode, it might be the culprit.)


Entry Delay:


I see, its because you are doing armed stay, not armed away, I also do not hear exit beeps with stay, only away, and the exit_delay being true only happens during the modes that have beeps (away and max).

I have the panel programmed not to beep for armed away either:

I have confirmed through experimentation that the EVL does not report the partition status code as 07 (delay in progress) without the beeps, my guess is internally it detects a beep value of 5 (slow continuous beeps) in order to report that code.

I think pyenvisalink can be EASILY modified to look for “May Exit Now” in the alpha code and report exit_delay as true, that should make it better for everyone and simplify the HA end for detecting that state.

I also captured some data on that unknown beep, the valid values are 0 to 5, and in night-stay it is reporting it is 10, along with instant for the arming mode (ARMED_MAX in current code).

I will brainstorm on how to properly parse that combination to get a working night arm status code of some kind, since the alpha and beep fields are part of a keypad update, and the partition status is a partition update, and looping the logic in the partition update requires the keypad update to occur first… and I am not sure if that happens or not.

aaand it turns out keypad updates are always after the partition update, so it has to be in the keypad code, which makes it a little messier, but I did get both the night stay reporting and the exit delay when there is no beeping to work, though a change to the integration is required to get it to report night stay correctly (among other things)

I also integrated an exit delay countdown timer into the state so it can be parsed as an attribute, with the other catch for the exit delay it only added 3 lines of code

1 Like

How do you integrate alarm_keypress. I don’t get sensor anywhere in my HA. I have Honeywell with envisalink configured in HA. I need to send ‘D’ on the keypad that I have linked with garage door open and close relay.

It is a service function:

service: envisalink.alarm_keypress
  keypress: '{{ keypress }}'
  entity_id: '{{ panel }}'

That is a template script, where keypress is the key string, “D” would be that, and panel is the alarm control panel entity

It worked :hugs:

 keypress: D
  entity_id: alarm_control_panel.partion_1

Thanks, now I just need to attach button to this service call that I can add to my panel.

Is there a way I can add custom button in my alarm panel:

type: alarm-panel
entity: alarm_control_panel.partion_1
  - arm_home
  - arm_away
action: call-service
service: envisalink.alarm_keypress
  keypress: D
  entity_id: alarm_control_panel.partion_1
target: {}
show_name: false
show_state: false
icon: mdi:garage
name: Alarm

As far as I know you cannot add custom buttons, I control the garage door relay by long pressing the garage door zone entity

Could you please provide example code ?

type: custom:stack-in-card
mode: vertical
  - type: entities
      - entity: binary_sensor.29_large_garage_door
        type: custom:multiple-entity-row
          attribute: last_tripped_time
          format: relative
        state_color: true
          action: call-service
          service: script.turn_on
            entity_id: script.script_toggle_garage_door_large
            text: Open large door ?

The garage door activation script checks to see if the alarm is armed first, so it wont set off the alarm. It is also single operation, so if it runs while already running it wont mess with the door, and it includes appropriate delays, so when the script ends, the garage door will for sure be opened or closed, unless there was some kind of error

1 Like


I can start a new thread, but I thought I’d try here first.

I have an EnvisaLink 4 board on my DSC panel. It works fine with HA as long as the Envisalerts Server ( status (using the GUI from the board’s IP) says the Internet-based server is “Online”.

At random times, this server goes offline and HA’s log shows the connection not established. I can reboot the board with a “http://192.168.x.y/3?A=2” link.

If I can’t get the vendor to tell me why this happens, can’t I make an automation that sends a HTTP request to reboot the board, along with the user/password? Or, even more slick would be an automation to detect the “OFFLINE” state of the internet connection, and reset the board then.

Have any of you noticed the same “off the air” issue with your board?

Can’t we just make the integration work locally, without contacting the server?

Interestingly, while communication with the DSC panel won’t allow HA to control the arming state, I can see the sensors that show movement, or door opening, even when the internet server is offline!

BTW, I’m using Firmware Version: 01.04.183.



A reboot request would probably be http://user:[email protected]/3?A=2

I have not seen any kind of comm error between HA and my EVL, I updated a few weeks to 1.4.182, and before and after the update I had no issues.

I have also not looked into if Envisalerts goes offline at any point, I am not using the service and without a comm error have had no reason to look into it. I have had internet connection issues on occasion a, so that does not seem to be the root cause… though it might be specific to the DSC firmware.

What kind of network hardware are you using?

1 Like

I fixed this by setting my EV4 to static addressing.

I don’t see anything about the DHCP server, but when a DHCP request comes in, the connection to the internet-based server is dropped. It seems to recover eventually, but Home Assistant can’t control the state of the alarm panel (DSC).

It’s possible that the internet service doesn’t expect a “few second max” delay in establishing the new connection. In fact, in an existing TCP session, there should be a number of retransmissions, with binary-backoff, before giving up on the flow.

Anyway, it’s nice to see my alarm and set and reset it as needed!



1 Like