Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Hive Alarm Keypad #2967

Merged
merged 14 commits into from
Aug 31, 2021
Merged

Conversation

robertalexa
Copy link
Contributor

@robertalexa robertalexa commented Aug 28, 2021

This is a continuation of Koenkk/zigbee2mqtt#8424

TIME SENSITIVE - I have purchased this item purely to provide support for it and I have no intention to keep it. My return date is 1st of September so I would appreciate if you could give me a hand with this @Koenkk @sjorge

I have a very rough initial support commit, most of the exposed attributes work, maybe even all, but I am unable to use the device, and I will explain further down. This is how it currently looks
image

My biggest issue is that the keypad becomes unresponsive after you press a button. That seems to be because the keypad wants a response after each command.

When you press any key, you initially get a command sent out

Zigbee2MQTT:debug 2021-08-28 19:17:52: Received Zigbee message from '0x000d6ffffec6dcc1', type 'commandGetPanelStatus', cluster 'ssIasAce', data '{}' from endpoint 1 with groupID 0

The keypad waits for a response, keypads do not beep anymore, the network icon flashes and then turns red.

I have also sniffed the packets, to the extent I was able to considering I didn't have motion sensors or door sensors to create an environment, and the Hive app doesn't allow me to arm the system with this.

Each command received from the keypad is always followed by a response. Here is a screenshot of the Response following the commandGetPanelStatus command, which is when you press a button from device sleep.

image

Please have a look at my code and tell me what I am doing wrong. (Guide me senpais!)

Also, here are my notes from the sniffing (I have not saved the sniff, just noted down what i saw important and took screenshots, but if needs be, i can sniff again)

https://www.leedarson.com/products/keypad

Binding: on cluster 0x0001
battery voltage 0x0020
8 bit unsigned integer
measured 2.9v

Button Press
IAS ACE:unknown 0x07 (0x05) dest endp 2 src end 1 cluster 0x0501 - acknowledgement request: true
Response Command "Default Response" 0x0b

Arm - Home - Fail
IAS ACE: Command Arm 0x00 dest endp 2 src endp 1 acknowledgement true - payload "Arm Mode: Arm Day/Home Zones Only (1)"
IAS ACEL Command Arm Response 0x00 ackn true - payload "Arm Notifications: Unknown (4)" - can't arm because stuff

Arm - Disarm - Success
IAS ACE: Command Arm 0x00 payload "Arm Mode: Disarm (0)"
IAS ACE: Command Arm Response 0x00 - payload "Arm Notifications: Unknown (6)" - technically good?

Arm - Away - Fail
IAS ACE: Command Arm 0x00 payload "Arm Mode: Arm All Zones (3)"
IAS ACEL Command Arm Response 0x00 ackn true - payload "Arm Notifications: Unknown (4)" - can't arm because stuff

Tamper
IAS Zone: Command Zone Status Change Notification (0x00)
ZoneStatus: 0x0034, Tamper, Supervision Reports, Restore Reports

Un-Tamper
IAS Zone: Command Zone Status Change Notification (0x00)
ZoneStatus: 0x0034, Tamper, Supervision Reports, Restore Reports

Panic from keypad
IAS ACE: Command Panic 0x04

Thanks guys!

@robertalexa robertalexa marked this pull request as draft August 28, 2021 19:34
@sjorge
Copy link
Sponsor Contributor

sjorge commented Aug 28, 2021

I'm not really sure as I haven't really read much of the IAS part of the spec, doing stuff in the onZigbeeEvent is probably indeed the way to go, but I think you need to add disableDefaultReponse: true to meta (https://github.com/Koenkk/zigbee-herdsman-converters/blob/5d165ef29206629690b70837fc8a8afee7178c3e/README.md)

To be able to send your own responses.

I also had a look on the ZA website and found this https://zigbeealliance.org/zigbee_products/keypad/ doesn't look 100% the same but I think it's the same device. And there is a compliance document available.

https://api.knack.com/v1/applications/54e658034b4f44e42fb18201/download/asset/5b64246cc03e9d03cc4b342d/pics_keypad.rar Looks to be just the absolute basic word docs about genBasic, genIdentity, genPower, and genOta so pretty useless as usual.

Below is probably the only really useful info:

      <cluster>
        <name>IAS Zone</name>
        <code>0x0500</code>
        <define>IAS_ZONE_CLUSTER</define>
        <attribute source="server" code="0x0000" define="ZONE_STATE" mandatory="true" name="zone state">TRUE</attribute>
        <attribute source="server" code="0x0001" define="ZONE_TYPE" mandatory="true" name="zone type">TRUE</attribute>
        <attribute source="server" code="0x0002" define="ZONE_STATUS" mandatory="true" name="zone status">TRUE</attribute>
        <attribute source="server" code="0x0010" define="IAS_CIE_ADDRESS" mandatory="true" name="IAS CIE address">TRUE</attribute>
        <attribute source="server" code="0x0011" define="ZONE_ID" mandatory="true" name="Zone ID">TRUE</attribute>
        <attribute source="server" code="0x0012" define="NUMBER_OF_ZONE_SENSITIVITY_LEVELS_SUPPORTED" mandatory="false" name="Number of Zone Sensitivity Levels Supported">FALSE</attribute>
        <attribute source="server" code="0x0013" define="CURRENT_ZONE_SENSITIVITY_LEVEL" mandatory="false" name="Current Zone Sensitivity Level">FALSE</attribute>
        <command receivedBy="server" code="0x00" name="ZoneEnrollResponse" mandatory="true">TRUE</command>
        <command receivedBy="server" code="0x01" name="InitiateNormalOperationMode" mandatory="false">FALSE</command>
        <command receivedby="server" code="0x02" name="InitiateTestMode" mandatory="false">FALSE</command>
        <command receivedBy="client" code="0x00" name="ZoneStatusChangeNotification" mandatory="true">TRUE</command>
        <command receivedBy="client" code="0x01" name="ZoneEnrollRequest" mandatory="true">TRUE</command>
      </cluster>

and

<cluster>
	<name>IAS ACE</name>
	<code>0x0501</code>
	<define>IAS_ACE_CLUSTER</define>
	<attribute source="server" code="0x0000" define="PANEL_STATUS" mandatory="true" name="panel status">FALSE</attribute>
	<command receivedBy="server" code="0x00" name="Arm" mandatory="true">FALSE</command>
	<command receivedBy="server" code="0x01" name="Bypass" mandatory="true">FALSE</command>
	<command receivedBy="server" code="0x02" name="Emergency" mandatory="true">FALSE</command>
	<command receivedBy="server" code="0x03" name="Fire" mandatory="true">FALSE</command>
	<command receivedBy="server" code="0x04" name="Panic" mandatory="true">FALSE</command>
	<command receivedBy="server" code="0x05" name="GetZoneIdMap" mandatory="true">FALSE</command>
	<command receivedBy="server" code="0x06" name="GetZoneInformation" mandatory="true">FALSE</command>
	<command receivedBy="server" code="0x07" name="GetPanelStatus" mandatory="true">FALSE</command>
	<command receivedBy="server" code="0x08" name="GetBypassedZoneList" mandatory="true">FALSE</command>
	<command receivedBy="server" code="0x09" name="GetZoneStatus" mandatory="true">FALSE</command>
	<command receivedBy="client" code="0x00" name="ArmResponse" mandatory="true">TRUE</command>
	<command receivedBy="client" code="0x01" name="GetZoneIdMapResponse" mandatory="true">TRUE</command>
	<command receivedBy="client" code="0x02" name="GetZoneInformationResponse" mandatory="true">TRUE</command>
	<command receivedBy="client" code="0x03" name="ZoneStatusChanged" mandatory="true">TRUE</command>
	<command receivedBy="client" code="0x04" name="PanelStatusChanged" mandatory="true">TRUE</command>
	<command receivedBy="client" code="0x05" name="GetPanelStatusResponse" mandatory="true">TRUE</command>
	<command receivedBy="client" code="0x06" name="SetBypassedZoneList" mandatory="true">TRUE</command>
	<command receivedBy="client" code="0x07" name="BypassResponse" mandatory="true">TRUE</command>
	<command receivedBy="client" code="0x08" name="GetZoneStatusResponse" mandatory="true">TRUE</command>
</cluster>

Page 511 of the v7 spec pdf does deal with IAS ACE it seems.

11174 8.3.2.3.6 Get Panel Status Command
11175 This command is used by ACE clients to request an update to the status (e.g., security system arm state) of the ACE
11176 server (i.e., the IAS CIE). This command is useful for battery-powered ACE clients with polling rates longer than the
11177 standard check-in rate.
11178 8.3.2.3.6.1 Payload Format
11179 There is no payload for the Get Panel Status command.
11180 8.3.2.3.6.2 Ef fect on Receipt
11181 On receipt of this command, the ACE server responds with the status of the security system. The IAS ACE server
11182 SHALL generate a Get Panel Status Response command.
```

So disabling the default respons and trying to send something back based on the spec might get you further.

@robertalexa
Copy link
Contributor Author

@sjorge Thanks for your input, yeah the device is made by the exact same company, but it doesn't seem to have motion detection, to turn on the keypad. Hive being cheap.

This is basically the same as
https://www.leedarson.com/products/keypad
or
https://www.amazon.co.uk/Linkind-Security-Starter-Control-Protection/dp/B07W4C3155

But rebranded. I am sure under the hood the firmware is fairly identical.

I will try the meta thing and see how that goes.

@robertalexa
Copy link
Contributor Author

@sjorge

I have some progress, but I have hit something that makes no sense to me, and I have a feeling doesn't work properly for other alarm keypads either. That being said, I need a second pair of eyes please.

There are a few other alarm keypads:
Centralite
image
Xfinity
image

They all manipulate a response for commandGetPanelStatus

The same code does not work for me, in my case, panelStatus is null. I have removed it from the if statement to get past it and it works, but it raises the next question.

Without that panelStatus, stored from a previous arming action, the keypad will always show the default state - unarmed. So far so clear.

Here is toZigbee:
image

Here is fromZigbee
image
image

So how or where is panelStatus set, as a result of an action.

Yes technically it would be set by toZigbee convertSet, but the expose for all the above mentioned devices is .STATE (so can't write to it from frontend, probably just via mqtt only, but that negates the usability of having correct exposes).

Secondly, how would that be initially set after pairing a device, cause if it isn't then the value will be null and the panelStatus command response will never enter the if statement.

PS: i do not need to use defaultResponse if i use .commandRequest (code shown in the above screenshots)

I know i am asking for quite some code following on your side, but please indulge me, cause I am questioning my understanding atm. So to rephrase my thoughts, i do not think that any of the other keypads actually shows the correct panel status because i do not see that value being set. Not unless it is set manually via mqtt command (impossible in Frontend) by someone that knows that it for some reason you need to pass an object and not a simple value. Because code says value.mode
image

@robertalexa
Copy link
Contributor Author

robertalexa commented Aug 28, 2021

I am now reading through the original PR for Centralite, but might be a tomorrow problem.
#1301

And the device documentation also shows that the set needs to be called externally.
https://www.zigbee2mqtt.io/devices/3400-D.html

I wonder if there is any reason why this can't be made into a functioning enum...?

@robertalexa
Copy link
Contributor Author

Scrap all of the above. The answer is to do confirmations over MQTT....

In the original PR the OP and Koen went through this and seems to have designed it this way. And it does make sense, since you need a 3rd party to decide, while z2m is just a data carrier in that sense.

I will run some more tests and probably be done with this soon :)

Thanks Jorge for opening my eyes about that spec. Made me understand better what i am looking, and then all of a sudden the code that I seeing for the other alarm keypads made sense!

@robertalexa
Copy link
Contributor Author

robertalexa commented Aug 29, 2021

@Koenkk I just found a bug that you have introduced as part of a refractor in commit c0e84ec

Initially you were using commons.js, which after adding support for Centralite Keypad looked like this.
https://github.com/sparky3387/zigbee-herdsman-converters/blob/cabdf7647c2b038652bb2261f60d66a866e9a0d9/converters/common.js

The important section is https://github.com/sparky3387/zigbee-herdsman-converters/blob/cabdf7647c2b038652bb2261f60d66a866e9a0d9/converters/common.js#L89

After the refractor toZigbee got changed:
image

The commons mode was replaced with constants mode, which do not match the ZCL standard. This is if transaction e.g. if this is a response rather than a set command.

The standard says:
image

As a result, I will add a new const called armNotification to include the expected responses with the correct keys, and update the above mentioned code.

I will do this tomorrow when i get a chance.

@robertalexa robertalexa marked this pull request as ready for review August 30, 2021 13:13
@robertalexa robertalexa changed the title WIP - Initial support for Hive Alarm Keypad Support for Hive Alarm Keypad Aug 30, 2021
converters/toZigbee.js Outdated Show resolved Hide resolved
@robertalexa
Copy link
Contributor Author

robertalexa commented Aug 30, 2021

@Koenkk @sjorge

I have made changes to patch the above mentioned bug with arm_mode constants vs what they should be when it is an arm Notification.

I have also made a few small changes to the other keypads already supported (Centralite and Xfinity) to expose all the relevants bits of info and the transaction. Exposing the transaction would make for a much easier automation flow for example in HA, when the transaction number would be an entity.

I will also add the relevant information in the product README page in z2m.io after the official release, and I will also review the Centralite and Xfinity too.

One such thing that needs changing in those docs is the following:
image

exit_delay is not a valid armNotification as per ZCL standard. It should technically be arm_all_zones

Let me know what you find/think

@sjorge
Copy link
Sponsor Contributor

sjorge commented Aug 30, 2021

I don't have any keypads to test with, but from reading the ZCL the changes make sense to me.

Copy link
Sponsor Contributor

@sjorge sjorge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@robertalexa
Copy link
Contributor Author

I don't have any keypads to test with, but from reading the ZCL the changes make sense to me.

I have tested all possible outcomes on mine, and the device behaves as expected.

With regards to my above post:

exit_delay is not a valid armNotification as per ZCL standard. It should technically be arm_all_zones

From the standard this would work in the following way:

  1. keypad, with correct pin, asks to arm_all_zones
  2. server confirms the action with transaction and armNotification arm_all_zones
  3. server sets the arm_mode to exit_delay. If the keypad is pressed now, the specific button (armed) will be flashing
  4. server waits the exit_delay time e.g. 30 seconds then sets the arm_mode to arm_all_zones

@robertalexa
Copy link
Contributor Author

robertalexa commented Aug 30, 2021

And saying that, I think the code (more like usage logic) is still wrong. But i need your feedback before I change it.

image

I am now inclined to think that armNotification should NOT update panelStatus at all.

That is because if you confirm the action like step 2., then whatever automation you use will use that attribute to decice the house is now armed. You open the door and you trigger the alarm.

Instead I think the proper use should be isNotification returns after the commandResponse, no matter the response.

Then the automation will change the armMode according to the rules, e.g. exit_delay if all was well.

Can you two please review my logic?

@robertalexa
Copy link
Contributor Author

Another commit to resolve the conflict with #2974
Also, I have sent the device back as a return, so I do not physically have it anymore.

It would be great if we could have a bit of a brain storm over my above comments.

My suggestion would be to replace:
image

with just return;

This way the armNotification does not actually set the alarm status global variable, as i do not think it should do. I think the server, and implicitly the automation engine (HA, node-red etc) should set the armMode immediately after sending the armNotification

I need your input before making such a decision because changing this will cause a "breaking change" in terms of usability and should be mentioned in the Release Notes? To basically point to user to an updated version of their device's documentation on z2m.io

@sjorge
Copy link
Sponsor Contributor

sjorge commented Aug 31, 2021

Can we read armMode from the device, say after a timeout?

@robertalexa
Copy link
Contributor Author

I think I know where your confusion might stem from? But I am not certain. You might be thinking of keyfobs rather than keypads.

Keyfobs should just set armMode, because they have no pin pad.

Which is reflected by this code from devices like Heiman, Linkind and Smart9
image

But this is defined at device level, which is ok :)

@Koenkk
Copy link
Owner

Koenkk commented Aug 31, 2021

because it can create issues, and it is not the correct behaviour.

Could you give an example of such issue?

@robertalexa
Copy link
Contributor Author

For the fix i did with constants:

  • invalid_code is a valid armNotification but an invalid armMode

For removing the leftover >3 condition

  • if keypad asks for arm_all_zones and server accepts the transaction via armNotification, the globalStore variable is set to arm_all_zones. This means the server (node-red) will enable the door sensors / motion sensors (this is a how it will be used in the real world example) which means when you open the door to leave you trigger the alarm.
    Instead, the armNotification should be arm_all_zones BUT without storing this value to globarStore variable. Then server (node-red) should send armMode exit_delay, count for the elapsed time (e.g. 30s) then send armMode arm_all_zones

This is the real world usage of how an alarm is meant to work. (I have a Ring alarm in the house so I understand the behaviour, but I am doing the legwork to get myself ready to move to my own zigbee one)

@Koenkk
Copy link
Owner

Koenkk commented Aug 31, 2021

I see, I'm fine with it, could you also make a PR to update the docs?

@robertalexa
Copy link
Contributor Author

@Koenkk I have pushed the commit with the relevant comments.

Yes I can update the documentation. Do you plan on releasing this change on tomorrow's release?

If so, I will wait until then for the documents to generate automatically and then do a PR for my Hive and the other keypads to update the "Notes" sections.

Does that work for you?

@Koenkk
Copy link
Owner

Koenkk commented Aug 31, 2021

Fine by me! Thanks both!

@Koenkk Koenkk merged commit 4391877 into Koenkk:master Aug 31, 2021
@robertalexa
Copy link
Contributor Author

Sounds good. Thanks @sjorge for putting up with my thought process

@sjorge
Copy link
Sponsor Contributor

sjorge commented Aug 31, 2021

Sounds good. Thanks @sjorge for putting up with my thought process

np, sometimes it helps :) just reading the ZCL and looking at the device responses can sure as hell be confusing at times 😆

@robertalexa
Copy link
Contributor Author

@Koenkk Do you mind please adding something in the Release Notes for keypad owners to keep an eye for an updated documentation?

@Koenkk
Copy link
Owner

Koenkk commented Aug 31, 2021

Would below be OK for you?

Improve handling of alarm arming, check your alarm documentation for updated procedure

@robertalexa
Copy link
Contributor Author

@Koenkk Use the term "keypad" somewhere in there. As realistically there is no alarm device, but rather a collection of them made to act as an alarm system.

Apart from that yes all good. I will do PRs as soon as the release is happening

@GSzabados
Copy link

@robertalexa, your change is really welcome, and as I see you have had a look on the PR #1873 before doing this one.

But the original PR incorporated the 30 seconds exit delay beeping as well. Are you planning to add that as well?

@robertalexa
Copy link
Contributor Author

robertalexa commented Sep 5, 2021

@GSzabados In the most recent code, I have not seen anything to do with 30 seconds delay, but i will look at the code one more time.

Anyway, zigbee2mqtt should not keep track of this value, nor should it be fixed to 30seconds.

The exit and entry delay should be tracked by the 3rd party automation solution (node-red for example). That is because people also need the option to decide how long they need, 10s, 30s 60s etc. Or even different values for exit and entry. e.g. entry is 30s and exit is only 15s.

So a healthy flow would be this: Koenkk/zigbee2mqtt#8630 (comment)

I hope this answers your question :)

@GSzabados
Copy link

I didn't meant actually 30 seconds, but these variables/constants.

const secondsRemain = value.secondsremain = 0;
const audibleNotif = value.audiblenotif = 0;
const alarmStatus = value.alarmstatus = 0;

@robertalexa
Copy link
Contributor Author

I think you are looking at very old code.

Code from the time i made my changes is
on device:
image

on toZigbee
image

Neither of those have been changed by me :)

@GSzabados
Copy link

Yes, I know, but the PR what I was mentioning would have brought the panelStatus as active option with those parameters as changeable. Your PR as armNotification could use those parameters, as the keypad should give audiable output for exit_delay, just as an example. Have a look on that PR. And there was another discussion about it as well. I cannot remember where.

I like the logic of the armNotification, makes sense. And solves some quirks with automations, but introduces other ones other places. If you do use HA, then maybe we should work on a Blueprint for these keypads on how to behave with an alarm server, like Alarmo.

@robertalexa
Copy link
Contributor Author

@GSzabados there is currently another chat about sounds, and it seems to be related to the command send.

Koenkk/zigbee2mqtt#8630 (comment)

But it is still tested. So maybe keep an eye on that thread too, regarding sounds.

I see your logic about making those variables passthrough. I can have a look at code and try to assist you if you want to have that sorted out.

Unfortunately i do not have the hive keypad anymore so i am unable to test anythinf any further. I bought it purely to support it in z2m and then returned and refunded it.

Ps. I spoke with Linkind and they said they will start selling the keypad as an individual product, rather than bundle, somete this month. I might be that i buy it and have a play with it.

@GSzabados
Copy link

@GSzabados there is currently another chat about sounds, and it seems to be related to the command send.

Koenkk/zigbee2mqtt#8630 (comment)

But it is still tested. So maybe keep an eye on that thread too, regarding sounds.

I see your logic about making those variables passthrough. I can have a look at code and try to assist you if you want to have that sorted out.

I not really fuss about that, but wanted to suggest, try to bring in @dettrick for the development. He had some great ideas there.

Otherwise the main problem for people to understand your new logic, is the missing alarm panel entity. There is no representation in HA what is the current status of the panel, unless you mirror your MQTT messages to a manual one.

@GSzabados
Copy link

Ps. I spoke with Linkind and they said they will start selling the keypad as an individual product, rather than bundle, somete this month. I might be that i buy it and have a play with it.

It is not so expensive in the kit and all the other bits are quite nice quality. Except the fact that everything has Linkind written on it with HUGE letters.

Otherwise, I just managed to re-purpose recently the Hub as well. It can be connected to HA as a Zigbee dongle through the network. I haven't managed to make the Siren work yet, but it is on my to-do list.

If interested, have a look here, I haven't made a write up yet, but the steps are quite straightforward:

zigpy/zigpy#796

@robertalexa
Copy link
Contributor Author

Otherwise the main problem for people to understand your new logic, is the missing alarm panel entity. There is no representation in HA what is the current status of the panel, unless you mirror your MQTT messages to a manual one.

Few mentions please, if you indulge me. The logic I have applied in my PR was purely to bring functionality in line with ZCL standards. I haven't tried to "create" my own "vision". So in that respect, I am a simple messenger learning about this as I go :)

With regards to the alarm panel status in HA, there was not a representation before in HA (unless I am missing something, please correct me if you know more), so I do not think I made things worse.

Personally I do not know if there is a better way of "hooking" things up to a HA alarm panel other than manual. But I am also not using HA for my automations, I do use HA but I use node-red for anything that I do. So if I was to set sth like that up, my HA alarm panel would be something not connected to anything, and just plug it into my node-red flows. I am saying that there is not a simple way purely because you need a "brain" to the operation. I am sure HA can do that natively, but I lack the knowledge about this topic to even pursue it. And as mentioned before, I do not have a zigbee alarm system, I use an out of the box RIng alarm (at least for now).

I hope this helps you better understand my position with regards to this alarm system thing haha :) (and my contribution)

@thecobra666
Copy link

This change resulted in the infinity keypad not beeping anymore when armed. Why did the logic change?

@robertalexa
Copy link
Contributor Author

@thecobra666 could you please have a read through this thread?

Koenkk/zigbee2mqtt#8630 (comment)

@burner-
Copy link

burner- commented May 9, 2024

Will someone still use hive keypad? Looks that support is broken but did it work at some point?

@PepYk
Copy link

PepYk commented Sep 7, 2024

My Hive Keypad001 ends up with an error when I press a button:
EventBus error 'OnEvent/deviceMessage': CommandResponse 0x000d6ffffec6ef0a/1 ssIasAce.getPanelStatusRsp({"secondsremain":0,"audiblenotif":0,"alarmstatus":0}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":1,"reservedBits":0,"writeUndiv":false}) failed (Parameter 'panelstatus' is missing)

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.

7 participants