I recently purchased both a v1 and v2 Ring Keypad to see if we could integrate them more closely with Indigo. First and foremost, the v2 keypad won't work reliably with Indigo because it seems to only support S2 Z-Wave security which Indigo doesn't yet support (it's a HUGE undertaking, which even other open source solutions have yet to do, but it is on our to do list for some future version).
I was fully intending to add direct support for the v1 keypad; unfortunately, now it seems to be unavailable (I guess I got lucky in getting one of the last ones), so it seems inappropriate to spend any significant time on it given that you can't easily buy one. In lieu of official support, I've put together this tutorial on how you can use the v1 keypad with Indigo's match raw packet event type.
How the v1 Keypad works
The v1 keypad works by sending packets to Indigo at various times when buttons are pressed. When you press a number key, it adds that key to a list. The keypad will continue to add numeric key presses to this list until one of several things happens:
- You stop pressing buttons and the timeout of 5 seconds (user adjustable via a config param) is up without pressing anything else.
- You press one of the non-numeric keys (Away, Disarm, Home, ✔️, and X).
- You press 8 numeric keys.
When the timeout period expires or you press the Away, Disarm, Home, ✔️, and X keys, the keypad will immediately send a message to Indigo indicating that the button has been pressed along with anything in its numeric key list. If you press one of those buttons without pressing any numeric keys first, it will just send an empty list (see below for details). If you enter 8 keys, it will immediately send a message formatted to look like 8 keys were pressed followed by the timeout period (like #1 above). Note that it's sent immediately following the 8th key press, so any other key you press after that starts the process over.
Each of these scenarios are cases you can catch using the Match Raw Packet event type in Indigo, allowing you complete flexibility in setting up your own codes to trigger any action(s) Indigo can perform. Neat, huh?
Z-Wave Packet Description
The complex part of this solution is how to construct the match bytes for use in the Match Raw Packet event type. Let's look at an example, then explain what each bytes are important and how to match those. If you press:
- Code: Select all
1-2-3-4-5-6-✔️
the messages you'll get from the keypad look something like this:
- Code: Select all
Z-Wave Debug RCVD nonceFetch: node 027
Z-Wave Debug SENT nonceReport: 01 11 00 13 1B 0A 98 80 26 92 6C E5 4D B3 68 2C 25 F5 A3
Z-Wave Debug RCVD nonceReport: 01 05 00 13 F5 00 1C (node ACK)
Z-Wave Debug . . nonceReport: requeuing 1 unsolicited packets
Z-Wave Debug RCVD encryptedPacket: 00 6F 01 01 02 00 00 (decrypted)
Z-Wave Debug RCVD requestReply1: 01 0C 00 04 00 1B 06 6F 01 01 02 00 00 FF (hex)
Z-Wave Debug RCVD nonceFetch: node 027
Z-Wave Debug SENT nonceReport: 01 11 00 13 1B 0A 98 80 26 92 6C E5 4D B3 68 2C 25 F6 A0
Z-Wave Debug RCVD nonceReport: 01 05 00 13 F6 00 1F (node ACK)
Z-Wave Debug RCVD encryptedPacket: 00 6F 01 02 02 02 06 31 32 33 34 35 36 (decrypted)
Z-Wave Debug RCVD requestReply1: 01 12 00 04 00 1B 0C 6F 01 02 02 02 06 31 32 33 34 35 36 FF (hex)
This is what you would see (with the Z-Wave debugging config option turned on) in the Event Log window. You only care about that last line, and more specifically the list of hexadecimal bytes:
- Code: Select all
01 12 00 04 00 1B 0C 6F 01 02 02 02 06 31 32 33 34 35 36 FF
If you look closely, you'll notice pretty quickly a pattern:
- Code: Select all
31 32 33 34 35 36
That looks suspiciously like the numbers you pressed (1 2 3 4 5 6). It is, in fact, the list of numbers you pressed directly before you pressed the ✔️ key - just added to 30 hexadecimal (usually written as 0x30). Further, if you look at the byte directly before it, you'll see that it's 0x06, which is the count of numbers that follow. This is the main pattern that you'll want to keep in mind as you construct your match bytes string.
Here is a summary of the full byte string and what's important:
- bytes 1-9: will always be: 01 ? 00 04 00 1B ? 6F 01 (the second and seventh bytes seem to vary, but it's not relevant to our matching logic)
- byte 10: sequence or something (also not relevant to our matching logic)
- byte 11: always: 02
- byte 12: 01=Timeout, 02=✔️(Checkmark), 03=Disarm, 05=Away, 06=Home, 19=X(Cancel)
- byte 13: count of bytes directly following - corresponding to the number of numeric keys pressed
- byte 14-22: (list of digits pressed up to 30=0, 39=9
- last byte: always FF
Given this summary, you can now fully decipher the byte list above, because the 12th byte is 0x02 - which represents the ✔️ key. There are 2 places where the data varies, but we don't care about those, so this is how you'd construct your match bytes (note the use of the 0x00 hexadecimal notation):
- Code: Select all
0x01 ? 0x00 0x04 0x00 0x1B ? 0x6F 0x01 ? 0x02 0x02 0x06 0x31 0x32 0x33 0x34 0x35 0x36 0xFF
The ? in the second and seventh locations will just ignore anything in those locations because they aren't relevant. Also, byte 10 should also match anything using the ? because it's not part of our matching logic. Byte 12 is 0x02, which will match the sequence end key if it's the ✔️ key. Byte 13 is 0x06, because the next 6 bytes will represent the numeric keys pressed.
Here's another example. If I press:
- Code: Select all
1-0-9-7
and just wait for the timeout (default of 5 seconds), this is what I'll see in the debug log:
- Code: Select all
Z-Wave Debug RCVD nonceFetch: node 027
Z-Wave Debug SENT nonceReport: 01 11 00 13 1B 0A 98 80 54 C8 3A 75 9A 36 2A D5 25 FE AF
Z-Wave Debug RCVD nonceReport: 01 05 00 13 FE 00 17 (node ACK)
Z-Wave Debug RCVD encryptedPacket: 00 6F 01 01 02 00 00 (decrypted)
Z-Wave Debug RCVD requestReply1: 01 0C 00 04 00 1B 06 6F 01 01 02 00 00 FF (hex)
Z-Wave Debug RCVD nonceFetch: node 027
Z-Wave Debug SENT nonceReport: 01 11 00 13 1B 0A 98 80 17 75 D1 6B 29 8C 7D 3B 25 FF 15
Z-Wave Debug RCVD nonceReport: 01 05 00 13 FF 00 16 (node ACK)
Z-Wave Debug RCVD encryptedPacket: 00 6F 01 02 02 01 04 31 30 39 37 (decrypted)
Z-Wave Debug RCVD requestReply1: 01 10 00 04 00 1B 0A 6F 01 02 02 01 04 31 30 39 37 FF (hex)
Again, the only line I'm interested in is the last line, and the bytes in it:
- Code: Select all
01 10 00 04 00 1B 0A 6F 01 02 02 01 04 31 30 39 37 FF
T 4 1 0 9 7
The T byte is 0x01 which represents the timeout ending sequence, followed by the count of numbers pressed (0x04), followed by each digit added to 0x30 hexadecimal. So, your match bytes would be:
- Code: Select all
0x01 ? 0x00 0x04 0x00 0x1B ? 0x6F 0x01 ? 0x02 0x01 0x04 0x34 0x30 0x39 0x37 0xFF
Another example. If you want to match the code 1097 followed by ANY sequence end (timeout, any non-numeric key), you would use this match bytes string:
- Code: Select all
0x01 ? 0x00 0x04 0x00 0x1B ? 0x6F 0x01 ? 0x02 ? 0x04 0x34 0x30 0x39 0x37 0xFF
Notice the ? in the 12th byte position - that means match any value, so it will match any of the possible sequence ending scenarios.
If you just want to catch any of the non-numeric keys (Away, Disarm, Home, ✔️, and X) without any digits, you can use the general pattern described above, but for the number of numeric keys you specify 0x00 directly followed by the end byte 0xFF. So, if you just want to catch a Home button press by itself:
- Code: Select all
0x01 ? 0x00 0x04 0x00 0x1B ? 0x6F 0x01 ? 0x02 0x06 0x00 0xFF
0x06 is the Home key, followed by 0x00 since there are not digits, followed by the end byte of 0xFF.
That's it! You can now catch codes and keypresses from your keypad to fire Indigo Events. Use this in conjunction with the Homegrown Security System wiki article to build your own alarm system in Indigo.