Skip to content

Add alarm zones#57

Open
mellis wants to merge 2 commits intolawtancool:masterfrom
mellis:alarm-zones
Open

Add alarm zones#57
mellis wants to merge 2 commits intolawtancool:masterfrom
mellis:alarm-zones

Conversation

@mellis
Copy link

@mellis mellis commented Mar 2, 2026

This adds access to alarm/security system zones, e.g. door, window, smoke, etc binary sensors. The existing binary sensors I believe is for sensors which are exposed as items/devices. In my system these zones are exposed as part of the alarm panel and their status is queried using the commands endpoint for the item.

I did some light sanity tests on my own system and was able to query my zone + states and see zone changes correctly with one of the contact sensors I used for testing.

Note: I used Claude Code to help write this.

mellis added 2 commits March 1, 2026 20:40
This adds access to alarm/security system zones, e.g. door, window,
smoke, etc binary sensors
@davidrecordon
Copy link
Contributor

This is a nice addition — alarm zone support has been a gap in pyControl4. I don't personally have a security panel to test with, but I wanted to share some observations from research I've been doing into the Control4 API.

I wasn't able to find GET_ZONE_LIST or GET_OPEN_ZONE_LIST in the Snap One Security Proxy Protocol docs — the documented command for retrieving zone data appears to be GET_ALL_ZONE_INFO (a panel-level command). Those docs describe the Lua driver-side proxy protocol rather than the Director REST API directly, so we're extrapolating a bit — but the REST API commands have generally mapped closely to what's documented there. I'm curious which alarm panel/driver you're running, since these could be commands specific to that driver rather than universal across all security panel types.

One thing that might be worth exploring is the approach hass-control4 takes in its binary_sensor.py — it retrieves zone info via get_item_setup() and then parses panel_setup["all_zones"]["zone_info"] from the response. Since GET_SETUP is already implemented in pyControl4's director.py and seems to work across different panel types, it could be a more portable foundation. Something like:

setup = await self.director.get_item_setup(self.item_id)
if "panel_setup" in setup:
    return setup["panel_setup"].get("all_zones", {}).get("zone_info", [])

A couple of smaller things I noticed:

  • COLD = 16 doesn't appear in the Snap One DriverWorks Fundamentals sensor type list (which goes 0–15, ending at GARAGE_DOOR). Where did you encounter that type? Might be worth a comment noting it's not in the official list.
  • The test fixtures include fields like room_id, room_name, is_bypassed, is_chimeable, and can_control that aren't in the official ALL_ZONES_INFO schema (which only specifies id, name, type_id, partitions, can_bypass, is_open). Not a problem if your panel returns them, but worth noting they may be driver-specific.

@mellis
Copy link
Author

mellis commented Mar 3, 2026

I wasn't able to find GET_ZONE_LIST or GET_OPEN_ZONE_LIST in the Snap One Security Proxy Protocol docs — the documented command for retrieving zone data appears to be GET_ALL_ZONE_INFO (a panel-level command). Those docs describe the Lua driver-side proxy protocol rather than the Director REST API directly, so we're extrapolating a bit — but the REST API commands have generally mapped closely to what's documented there. I'm curious which alarm panel/driver you're running, since these could be commands specific to that driver rather than universal across all security panel types.

The ones I used came from reverse engineering of the mobile app. I didn't look at the public driver docs or see references to GET_ALL_ZONE_INFO but I could test it out to see if it works as well, assuming we'd prefer to stick to what's available publicly when possible.

One thing that might be worth exploring is the approach hass-control4 takes in its binary_sensor.py — it retrieves zone info via get_item_setup() and then parses panel_setup["all_zones"]["zone_info"] from the response. Since GET_SETUP is already implemented in pyControl4's director.py and seems to work across different panel types, it could be a more portable foundation. Something like:

setup = await self.director.get_item_setup(self.item_id)
if "panel_setup" in setup:
    return setup["panel_setup"].get("all_zones", {}).get("zone_info", [])

Oh interesting, I hadn't looked too closely at the hass repo yet and mine was behind it looks like. I'll take a look more closely hopefully later this week and see.

A couple of smaller things I noticed:

  • COLD = 16 doesn't appear in the Snap One DriverWorks Fundamentals sensor type list (which goes 0–15, ending at GARAGE_DOOR). Where did you encounter that type? Might be worth a comment noting it's not in the official list.

These values came from reverse engineering of the app. The only zone types in my system I can directly test are contact sensor, exterior door, exterior window and fire sensor (I'm probably not going to test this last one but I can query its current state okay 😅). If we'd prefer to be cautious about what we add without a system to validate it on we could probably just not code in zone type information or only the limited set I can test and treat others are unknown? It's probably not super important to get a complete list here since one can remap it to a different entity type in HA if necessary before support is added to reclassify it in the integration?

  • The test fixtures include fields like room_id, room_name, is_bypassed, is_chimeable, and can_control that aren't in the official ALL_ZONES_INFO schema (which only specifies id, name, type_id, partitions, can_bypass, is_open). Not a problem if your panel returns them, but worth noting they may be driver-specific.

I'll take a look at this again and probably clean some of this up since I don't think it's all needed.

@davidrecordon
Copy link
Contributor

I think it's a space where what works is more important than what's documented given that there aren't official API docs for this side of things :) But I find those official Snap docs useful to at least inspire things to test along the way!

I'd defer to @lawtancool on being cautious versus extrapolating since I also don't have an alarm system connected to Control4. But his HASS implementation is definitely worth learning from.

Thanks again for writing and sharing all of this code!

@johnpg
Copy link
Contributor

johnpg commented Mar 10, 2026

@mellis you mentioned reverse engineering the Control4 app. How are you doing this? SSL proxy and sniffing the network traffic or something else? I'm very curious how media changes are transmitted to the app. We currently have to poll for changes, and I'd like to get that via the websocket instead. But so far, I've not found a way to do it. I'd also love to see if there's any support for listening to keypad events.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants