taligentx / dscKeybusInterface

An Arduino/esp8266/esp32 library to directly interface with DSC security systems.
GNU General Public License v3.0
497 stars 125 forks source link

Decoding 0x16 cmd for 4/6-digit user codes, modules and keypad tampers #166

Open kricon opened 3 years ago

kricon commented 3 years ago

Thanks for creating and developing this project, I was amazed when first saw it year ago, but just now got time to get into the testing and write here. Im not new into electronic and microcontrollers, I had some programming experinces but never used github before and I'm pretty new when it comes to Arduino/IoT (this is my first time using/coding on arduino).

I have some panels (PC5020, PC1565-2P, PC585) and modules (RF5132 v5, PC5104, few PC5108) available for testing and giving feedback if needed to help further development because as I see it has not been tested with PC5020 before and also wireless/hardwired expanders is a thing in development nowadays.

As I use 6-digit code, using KeybusReader 0x16 cmd is showing unknown data, so I gave my shot at decoding protocol:

21:22:35.004 ->   345.09: 00010110 0 00001110 00100011 11100101 00101100 [0x16] PC1555MX | Zone wiring: NC | *8 programming (pc585, 4digit)
21:11:10.080 ->   753.67: 00010110 0 00001110 00110010 11100101 00111011 [0x16] Unknown panel | Zone wiring: NC | *8 programming (pc5020, 4digit)
21:12:19.999 ->   823.58: 00010110 0 00001110 00110010 11101101 01000011 [0x16] Unknown panel | Zone wiring: NC | Unrecognized data (pc5020, 6digit)
21:21:12.830 ->   262.91: 00010110 0 00001110 00100011 11101101 00110100 [0x16] PC1555MX | Zone wiring: NC | Unrecognized data (pc585, 6digit)

This is using master branch. If I use expander branch, PC5020 is identified as PC5005 panel. If I figured correctly, when byte 4, bit5 bit3 is true, system uses 6-digit codes, _and true status scrambles byte 4 sum for "switch (panelData[4] >> 2)"_. Its probably easy to fix it, but I give look and as for now I dont have enough knowledge to do it by myself.

I wonder is anybody decoded left-right buttons from LCD keypads? If not, maybe I can get my hands on one and look at serial output. Blynk really lack possibility to scroll left/right on lcd to view troubles, alarm memory and so on.

Im planning to use this project with Blynk for remotely monitor and control of my DSC panel in holiday house, which have wired and wireless expansions and I would like to be able to monitor as much data as possible so Im willing to help in reporting/decoding protocol as much as I can.

I have to thanks @Dilbert66 for helping me about script-typo which caused zone tamper being misreported and for recent updates on decoding pc5108/pc5208/rf5132 modules aswell as decoding memory buffer and trouble statuses which would be really nice If possible to implement it so I could, for example, find out if my system report zone sensor low battery (which often does as in winter there is freezing temperatures) or view memory buffer somehow.

It would be great if all that new findings will be included in new build (I see that @taligentx plans soon to revisit code, merge some things and hopefully release new version main branch. I'm testing PC5020 v3.2 and as for now, it works nicely so it can be added to list of supported panels.

Dilbert66 commented 3 years ago

Make the changes below to have your panel identified. Yours sends 0x32 in byte3 (which is your panel version)

Actually, you have found a good thing here. Byte 3 is not as initially thought. Byte 3 is the panel version number. I have a different panel with version 4.6 and I have 0x46. Good. Now we have good way to identify panel version but we still need to identify panel type.

Edit: I agree with you that it seems that bit 3 of byte4 is a 6 digit code indicator. The code below will need to be modified to represent that.
for example your panel 5010 sends for byte4: 11101101. So we break it down to assumed sections: bits4567(1110 ) bit3(1) bit2(1) bits01( 01)
It is assumed that bits01 are the termination type. bit2 - unknown bit3 - assumed 4/6 digit code type bits4567 - unknown at this time

//0x16 processing: 
 //this should now be:
 stream->print(F("Panel version: "));
 stream->print(panelData[3],HEX);

/*
    switch (panelData[3]) {  //this is the panel version.  Not panel model
      case 0x10: stream->print(F("PC5015 ")); break;
      case 0x11: stream->print(F("PC5016 ")); break;
      case 0x22: stream->print(F("PC1565 ")); break;
      case 0x23: stream->print(F("PC1555MX/PC585 ")); break; //make this change to add pc585 in the description
      case 0x32: stream->print(F("PC5020 ")); break; // add this line to identify your panel correctly
      case 0x41: stream->print(F("PC1832 ")); break;
      case 0x42: stream->print(F("PC1864 ")); break;
      default: stream->print(F("Unknown panel ")); break;
    }
*/
    switch (panelData[4] & 0x03) {
      case 0x01: stream->print(F("| Zone wiring: NC ")); break;
      case 0x02: stream->print(F("| Zone wiring: EOL ")); break;
      case 0x03: stream->print(F("| Zone wiring: DEOL ")); break;
    }

    switch (panelData[4] >> 2) {
      case 0x2C: stream->print(F("| Armed")); break;
      case 0x2D: stream->print(F("| Interval 4m")); break;
      case 0x34: stream->print(F("| Exit installer programming")); break;
      case 0x39: stream->print(F("| Installer programming")); break;  //this was your first 5020 example (4digit)
      case 0x3B: stream->print(F("| Installer programming")); break; //add this line for your 2nd example (6digit), please note what the operation was at the time you saw this 016.
      case 0x3C: stream->print(F("| Armed, Exit *8 +15s, Power-on +2m")); break;
      case 0x3D: stream->print(F("| Interval 4m")); break;
      default: stream->print(F("| Unknown data")); break;
    }
  }
kricon commented 3 years ago

Im slowly learning a little, now I understand the "switch (panelData[4] >> 2)" line and bit shifting thing. Its all clear now, sorry if I confused you.

This is what I have tested and verified for now:

    switch (panelData[4] >> 2) {
      case 0x2C: stream->print(F("| Armed")); break;
      case 0x2E: stream->print(F("| 6 digits code | Armed")); break; //NOT TESTED (I dont know how to get it) but I suppose its correct as every other was hex+2 for 6digits.
      case 0x2D: stream->print(F("| Interval 4m")); break;
      case 0x2F: stream->print(F("| 6 digits code | Interval 4m")); break; //I got this while system disarmed
      case 0x34: stream->print(F("| Exit *8 programming")); break;
      case 0x36: stream->print(F("| 6 digits code | Exit *8 programming")); break;
      case 0x39: stream->print(F("| *8 programming")); break;
      case 0x3B: stream->print(F("| 6 digits code | *8 programming")); break;
      case 0x3C: stream->print(F("| Armed, Exit *8 +15s, Power-on +2m")); break; //EDIT2: got this while disarmed
      case 0x3E: stream->print(F("| 6 digits code | Armed, Exit *8 +15s, Power-on +2m")); break;
      case 0x3D: stream->print(F("| Interval 4m")); break;
      case 0x3F: stream->print(F("| 6 digits code | Interval 4m")); break; //I got this while system was armed EDIT: just got it now, system disarmed. So I think it have nothing in common with arm status as I have predicted.
      default: stream->print(F("| Unrecognized data")); break;
    }

I'm glad I was able to help a little with protocol decoding, I hope I'll learn more and as well decode some more. I agree with you about panel versions, I was puzzled why 1555MX and 585 v2.3 have same hex. Also 5005&5020 from expander branch. I have some v4.5, v4.2, v2.2 panels but we agree its panel version, not model, so no more testing required. Is it possible to extract just bit3 like its separate for zone resistor options, so we dont have every line doubled for 4dig and 6dig?

Dilbert66 commented 3 years ago

With the arduino you can easily use the bitRead function:

 if (bitRead(panelData[4],3))
        stream->print(F("| 6 digit code ");
    else
        stream->print(F("| 4 digit code ");

Alternatively, you can "and" it:

    if (panelData[4] & 0x08) 
        stream->print(F("| 6 digit code ");
    else
        stream->print(F("| 4 digit code ");

The problem is that the other bits will also have to be identified as well.

taligentx commented 3 years ago

Hi @kricon,

Thanks for creating and developing this project (...) I have some panels (PC5020, PC1565-2P, PC585) and modules (RF5132 v5, PC5104, few PC5108) available for testing and giving feedback if needed to help further development (...)

Glad it's of use! And yes, testing with the panels and modules would be great - the example sketches cover common use cases and at this point the develop branch should be fully functional with all partitions, zones, and commonly used status states, but there's always room for bugs.

If I figured correctly, when byte 4, bit5 bit3 is true, system uses 6-digit codes

Actually, you have found a good thing here. Byte 3 is not as initially thought. Byte 3 is the panel version number. I have a different panel with version 4.6 and I have 0x46. Good. Now we have good way to identify panel version but we still need to identify panel type.

Looks good, I've updated the 0x16 decoding to indicate the code length and panel versions (at least, the versions I've seen so far listed on DSC's website for different panel models). It's interesting that DSC is using the literal hexadecimal code to match up with the panel version rather than using the decimal value.

I've also removed the rest of the decoding for byte 4 (handled by switch (panelData[4] >> 2)) - those were notes to help narrow down when bits changed during different events, but with the code length bit worked out, the rest of the decoding isn't as relevant.

Looking at it now, byte 4 bit 4 flips when in *8 programming (need to see if it flips in other scenarios) - it may a signal for other keypads to disable themselves to avoid disrupting programming. Byte 4 bits 2, 5, 6, 7 remain unknown.

Before:
21:22:35.004 ->   345.09: 00010110 0 00001110 00100011 11100101 00101100 [0x16] PC1555MX | Zone wiring: NC | *8 programming (pc585, 4digit)
21:11:10.080 ->   753.67: 00010110 0 00001110 00110010 11100101 00111011 [0x16] Unknown panel | Zone wiring: NC | *8 programming (pc5020, 4digit)
21:12:19.999 ->   823.58: 00010110 0 00001110 00110010 11101101 01000011 [0x16] Unknown panel | Zone wiring: NC | Unrecognized data (pc5020, 6digit)
21:21:12.830 ->   262.91: 00010110 0 00001110 00100011 11101101 00110100 [0x16] PC1555MX | Zone wiring: NC | Unrecognized data (pc585, 6digit)

After:
21:22:35.004 ->   345.09: 00010110 0 00001110 00100011 11100101 00101100 [0x16] Panel version: v2.3 | Zone wiring: NC | Code length: 4 digits | *8 programming: yes 
21:11:10.080 ->   753.67: 00010110 0 00001110 00110010 11100101 00111011 [0x16] Panel version: v3.2 | Zone wiring: NC | Code length: 4 digits | *8 programming: yes 
21:12:19.999 ->   823.58: 00010110 0 00001110 00110010 11101101 01000011 [0x16] Panel version: v3.2 | Zone wiring: NC | Code length: 6 digits | *8 programming: yes 
21:21:12.830 ->   262.91: 00010110 0 00001110 00100011 11101101 00110100 [0x16] Panel version: v2.3 | Zone wiring: NC | Code length: 6 digits | *8 programming: yes 

I wonder is anybody decoded left-right buttons from LCD keypads? If not, maybe I can get my hands on one and look at serial output. Blynk really lack possibility to scroll left/right on lcd to view troubles, alarm memory and so on.

LCD keypads send out the same keypress code for both of the <> buttons, the Keybus data doesn't show any difference between them - it seems to be a placeholder to indicate that a key was pressed, but the panel takes no action in response. See issue #34 - the LCD keypads seem to operate with an autonomous UI, with navigation and logic handled by the keypad and then only sending the necessary data to the panel.

Currently, the Blynk sketch directly sends key presses and directly displays the partition status message as sent in the panel status commands 0x05, etc. To operate like the LCD keypads, the Blynk sketch would need to have the navigation logic built into the sketch itself to emulate the LCD keypad - it should be possible and seems like a good project, but not currently implemented (PRs welcome as always).

(...) I would like to be able to monitor as much data as possible so Im willing to help in reporting/decoding protocol as much as I can.

At this point it's mostly a matter of figuring out what Keybus data is useful when integrating into other software (Home Assistant, HomeKit, etc) and provides value to warrant the additional memory usage. The Status sketch shows all states that are currently monitored and stored in memory by the library for use by sketches, if there's a particular status you are interested in but is not currently tracked by the library, you can implement the status tracking in the sketch itself - described in dscKeybusInterface.h:

    // panelData[] and moduleData[] store panel and keypad data in an array: command [0], stop bit by itself [1],
    // followed by the remaining data.  These can be accessed directly in the sketch to get data that is not already
    // tracked in the library.  See dscKeybusPrintData.cpp for the currently known DSC commands and data.
    //
    // panelData[] example:
    //   Byte 0     Byte 2   Byte 3   Byte 4   Byte 5
    //   00000101 0 10000001 00000001 10010001 11000111 [0x05] Status lights: Ready Backlight | Partition ready
    //            ^ Byte 1 (stop bit)
    static byte panelData[dscReadSize];
    static volatile byte moduleData[dscReadSize];

    // status[] and lights[] store the current status message and LED state for each partition.  These can be accessed
    // directly in the sketch to get data that is not already tracked in the library.  See printPanelMessages() and
    // printPanelLights() in dscKeybusPrintData.cpp to see how this data translates to the status message and LED status.
    byte status[dscPartitions];
    byte lights[dscPartitions];

For example, I'll be looking into seeing which platforms can show battery status for a zone sensor, that would be a good reason to add the wireless battery decoding from @Dilbert66 as a tracked status (currently it is decoded by KeybusReader but not stored in memory as a tracked status).

Dilbert66 commented 3 years ago

currently, I'm only able to access the specific battery level of zones by sending a *27## to the panel on initial start and retrieving it from the 0A (sent in response to the menu option to show active lights) cmd as such in the esphome component sketch:

        if (dsc.panelData[0]==0x0A && dsc.panelData[3]==0xBA) { //low battery zones
            for (byte panelByte = 4; panelByte < 8; panelByte++) {
                    for (byte zoneBit = 0; zoneBit < 8; zoneBit++) {
                        zone = zoneBit + ((panelByte-4) *  8);
                        if (bitRead(dsc.panelData[panelByte],zoneBit)) {
                            if (zone < MAXZONES)
                                zoneStatus[zone].batteryLow=true;
                        } else  if (zone < MAXZONES)
                                    zoneStatus[zone].batteryLow=false;
                    }
            }
        }

After that, I monitor the module cmd41 response and decode the levels there. Not the easiest way. I have not seen a specific cmd yet that the panel sends for detailed battery state like this such as the 0x27 cmd for zones.

kricon commented 3 years ago

Glad it's of use! And yes, testing with the panels and modules would be great - the example sketches cover common use cases and at this point the develop branch should be fully functional with all partitions, zones, and commonly used status states, but there's always room for bugs.

I have tested and logged some still unknown data, mostly related to module tampers which hopefully might be helpful and implemented. Soon I'll get my hands on PC5204 supervised power supply with relays module so I'll report KeypadReader logs here in various states with that module to decode that aswell.

RF5132 case and wall tampers:

04:49:23.763 ->  5000.03: 11111111 1 11111111 11111111 11111110 11111111 [Module/0x05] Unknown module notification //pc585 v2.3 rf5132 v5.0
04:10:20.221 ->  2656.42: 11111111 1 11111111 11111111 11111110 11111111 11111111 11111111 11111111 11111111 [Module/0x05] Unknown module notification //pc5020 v3.2 rf5132 v5.0
04:49:23.902 ->  5000.15: 01001100 0 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 [0x4C] Keybus query //pc585 v3.2 rf5132 v5.0
04:10:20.358 ->  2656.57: 01001100 0 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 [0x4C] Keybus query //pc5020 rf5132 v5.0
04:49:23.902 ->  5000.14: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 00111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //rf5132 tamper on pc585
04:49:31.276 ->  5007.51: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 11001111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //rf5132 restore on pc585
04:10:20.358 ->  2656.57: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 00111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //rf5132 tamper on pc5020
04:10:55.505 ->  2691.71: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 11001111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //rf5132 tamper restore on pc5020
04:10:20.497 ->  2656.70: 10100101 0 00100000 00101010 01100000 10111111 01000010 11111111 01001111 [0xA5] 2020.10.19 00:47 | Unknown data :6 //rf5132 wall tamper on pc5020
04:10:55.642 ->  2691.85: 10100101 0 00100000 00101010 01100000 10111111 01000001 11111111 01001110 [0xA5] 2020.10.19 00:47 | Unknown data :6 //rf5132 wall restore on pc5020
04:25:15.867 ->  3552.09: 10100101 0 00100000 00101010 10100100 01011011 01000010 11111111 00101111 [0xA5] 2020.10.21 04:22 | Unknown data :6 //rf5132 case tamper on pc5020
04:25:18.059 ->  3554.27: 10100101 0 00100000 00101010 10100100 01011011 01000001 11111111 00101110 [0xA5] 2020.10.21 04:22 | Unknown data :6 //rf5132 case restore on pc5020
04:10:20.705 ->  2656.90: 11101011 0 00000000 00100000 00101010 01100000 10111100 00000011 01000010 11111111 10010101 [0xEB] 2020.10.19 00:47 | Unknown data :8 //rf5132 wall tamper on pc5020
04:10:55.850 ->  2692.05: 11101011 0 00000000 00100000 00101010 01100000 10111100 00000011 01000001 11111111 10010100 [0xEB] 2020.10.19 00:47 | Unknown data :8 //rf5132 wall restore on pc5020
04:25:16.075 ->  3552.28: 11101011 0 00000000 00100000 00101010 10100100 01011000 00000011 01000010 11111111 01110101 [0xEB] 2020.10.21 04:22 | Unknown data :8 //rf5132 case tamper on pc5020
04:25:18.231 ->  3554.47: 11101011 0 00000000 00100000 00101010 10100100 01011000 00000011 01000001 11111111 01110100 [0xEB] 2020.10.21 04:22 | Unknown data :8 //rf5132 case restore on pc5020

PC5108 wired expander 1-7 tampers:

06:15:13.866 -> 10150.20: 11111111 1 11111111 11111111 11111110 11111111 11111111 11111111 11111111 11111111 [Module/0x05] Unknown module notification //common for all
06:15:14.005 -> 10150.36: 01001100 0 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 [0x4C] Keybus query //common for all
06:15:14.040 -> 10150.36: 11111111 1 11111111 11111111 11111111 11110000 00111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //9-16 tamper
06:15:25.329 -> 10161.68: 11111111 1 11111111 11111111 11111111 11110000 11001111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //9-16 restore
06:10:01.440 ->  9837.76: 11111111 1 11111111 11111111 11111111 11110000 11110011 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //17-24 tamper
06:10:10.503 ->  9846.83: 11111111 1 11111111 11111111 11111111 11110000 11111100 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //17-24 restore
06:08:31.995 ->  9748.33: 11111111 1 11111111 11111111 11111111 11110000 11111111 00111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //25-32 tamper
06:09:08.079 ->  9784.40: 11111111 1 11111111 11111111 11111111 11110000 11111111 11001111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //25-32 restore
18:46:06.720 ->  2687.59: 11111111 1 11111111 11111111 11111111 11110000 11111111 11110011 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //33-40 tamper
18:46:10.876 ->  2691.75: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111100 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //33-40 restore
18:48:34.231 ->  2835.08: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 00111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //41-48 tamper
18:48:37.873 ->  2838.72: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11001111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //41-48 restore
18:53:23.844 ->  3124.71: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11110011 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //49-57 tamper
18:53:27.635 ->  3128.49: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111100 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //49-57 restore
19:46:19.690 ->  6300.62: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00111111 11111111 [Module/0x4C] Unrecognized data //58-64 tamper
19:46:23.915 ->  6304.83: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11001111 11111111 [Module/0x4C] Unrecognized data //58-64 restore
06:15:14.179 -> 10150.52: 10100101 0 00100000 00101010 11000110 00101011 00111011 11111111 00011010 [0xA5] 2020.10.22 06:10 | Unknown data :6 //9-16 tamper
06:15:25.499 -> 10161.85: 10100101 0 00100000 00101010 11000110 00101011 00110101 11111111 00010100 [0xA5] 2020.10.22 06:10 | Unknown data :6 //9-16 restore
06:10:01.577 ->  9837.93: 10100101 0 00100000 00101010 11000110 00011011 00111100 11111111 00001011 [0xA5] 2020.10.22 06:06 | Unknown data :6 //17-24 tamper
06:10:10.642 ->  9846.96: 10100101 0 00100000 00101010 11000110 00011011 00110110 11111111 00000101 [0xA5] 2020.10.22 06:06 | Unknown data :6 //17-24 restore
06:08:32.135 ->  9748.48: 10100101 0 00100000 00101010 11000110 00010111 00111101 11111111 00001000 [0xA5] 2020.10.22 06:05 | Unknown data :6 //25-32 tamper
06:09:08.217 ->  9784.54: 10100101 0 00100000 00101010 11000110 00010111 00110111 11111111 00000010 [0xA5] 2020.10.22 06:05 | Unknown data :6 //25-32 restore
18:46:06.856 ->  2687.71: 10100101 0 00100000 00101010 11000000 00010111 00111110 00000000 00000100 [0xA5] 2020.10.22 00:05 | Unknown data :6 //33-40 tamper
18:46:10.977 ->  2691.86: 10100101 0 00100000 00101010 11000000 00010111 00111000 00000000 11111110 [0xA5] 2020.10.22 00:05 | Unknown data :6 //33-40 restore
18:48:34.335 ->  2835.20: 10100101 0 00100000 00101010 11000000 00011111 00111111 11111111 00001100 [0xA5] 2020.10.22 00:07 | Unknown data :6 //41-48 tamper
18:48:38.010 ->  2838.86: 10100101 0 00100000 00101010 11000000 00011111 00111001 11111111 00000110 [0xA5] 2020.10.22 00:07 | Unknown data :6 //41-48 restore
18:53:23.948 ->  3124.83: 10100101 0 00100000 00101010 11000000 00101111 01000000 11111111 00011101 [0xA5] 2020.10.22 00:11 | Unknown data :6 //49-57 tamper
18:53:27.739 ->  3128.62: 10100101 0 00100000 00101010 11000000 00101111 00111010 11111111 00010111 [0xA5] 2020.10.22 00:11 | Unknown data :6 //49-57 restore
19:46:19.827 ->  6300.75: 10100101 0 00100000 00101010 11000000 11011111 01010010 11111111 11011111 [0xA5] 2020.10.22 00:55 | Unknown data :6 //58-64 tamper
19:46:24.052 ->  6304.98: 10100101 0 00100000 00101010 11000000 11011111 01010001 11111111 11011110 [0xA5] 2020.10.22 00:55 | Unknown data :6 //58-64 restore
06:15:14.385 -> 10150.72: 11101011 0 00000000 00100000 00101010 11000110 00101000 00000011 00111011 11111111 01100000 [0xEB] 2020.10.22 06:10 | Unknown data :8 //9-16 tamper
06:15:25.707 -> 10162.04: 11101011 0 00000000 00100000 00101010 11000110 00101000 00000011 00110101 11111111 01011010 [0xEB] 2020.10.22 06:10 | Unknown data :8 //9-16 restore
06:10:01.782 ->  9838.13: 11101011 0 00000000 00100000 00101010 11000110 00011000 00000011 00111100 11111111 01010001 [0xEB] 2020.10.22 06:06 | Unknown data :8 //17-24 tamper
06:10:10.816 ->  9847.16: 11101011 0 00000000 00100000 00101010 11000110 00011000 00000011 00110110 11111111 01001011 [0xEB] 2020.10.22 06:06 | Unknown data :8 //17-24 restore
06:08:32.338 ->  9748.67: 11101011 0 00000000 00100000 00101010 11000110 00010100 00000011 00111101 11111111 01001110 [0xEB] 2020.10.22 06:05 | Unknown data :8 //25-32 tamper
06:09:08.388 ->  9784.74: 11101011 0 00000000 00100000 00101010 11000110 00010100 00000011 00110111 11111111 01001000 [0xEB] 2020.10.22 06:05 | Unknown data :8 //25-32 restore
18:46:07.200 ->  2688.07: 11101011 0 00000000 00100000 00101010 11000000 00010100 00000011 00111110 00000000 01001010 [0xEB] 2020.10.22 00:05 | Unknown data :8 //33-40 tamper
18:46:11.386 ->  2692.25: 11101011 0 00000000 00100000 00101010 11000000 00010100 00000011 00111000 00000000 01000100 [0xEB] 2020.10.22 00:05 | Unknown data :8 //33-40 restore
18:48:34.543 ->  2835.41: 11101011 0 00000000 00100000 00101010 11000000 00011100 00000011 00111111 11111111 01010010 [0xEB] 2020.10.22 00:07 | Unknown data :8 //41-48 tamper
18:48:38.182 ->  2839.06: 11101011 0 00000000 00100000 00101010 11000000 00011100 00000011 00111001 11111111 01001100 [0xEB] 2020.10.22 00:07 | Unknown data :8 //41-48 restore
18:53:24.190 ->  3125.05: 11101011 0 00000000 00100000 00101010 11000000 00101100 00000011 01000000 11111111 01100011 [0xEB] 2020.10.22 00:11 | Unknown data :8 //49-57 tamper
18:53:27.945 ->  3128.82: 11101011 0 00000000 00100000 00101010 11000000 00101100 00000011 00111010 11111111 01011101 [0xEB] 2020.10.22 00:11 | Unknown data :8 //49-57 restore
19:46:19.999 ->  6300.94: 11101011 0 00000000 00100000 00101010 11000000 11011100 00000011 01010010 11111111 00100101 [0xEB] 2020.10.22 00:55 | Unknown data :8 //58-64 tamper
19:46:24.258 ->  6305.18: 11101011 0 00000000 00100000 00101010 11000000 11011100 00000011 01010001 11111111 00100100 [0xEB] 2020.10.22 00:55 | Unknown data :8 //58-64 restore

Keypad tampers (pk55xx have tamper contacts by default. On lcd/pc55xx keypads you need to solder button, 10k and 47k ohm resistors. Fun fact: pc5508 can be "transformed" to pc5516 or pc5532 with just adding leds, resoldering pnp transistors and adding some resistors):

18:24:45.339 ->  1406.20: 11111111 1 11111111 11111111 11111110 11111111 [Module/0x05] Unknown module notification //pc585 keypad tamper common for all slots and states
18:24:45.443 ->  1406.30: 01001100 0 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 [0x4C] Keybus query //pc585 common for all slots and states
18:24:45.476 ->  1406.30: 11111111 1 00111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad tamper slot 1
18:24:46.649 ->  1407.48: 11111111 1 11001111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad restore slot 1
18:25:36.650 ->  1457.48: 11111111 1 11110011 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad tamper slot 2
18:25:37.690 ->  1458.52: 11111111 1 11111100 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad restore slot 2
18:27:28.423 ->  1569.27: 11111111 1 11111111 00111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad tamper slot 3
18:27:30.218 ->  1571.06: 11111111 1 11111111 11001111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad restore slot 3
18:28:44.519 ->  1645.35: 11111111 1 11111111 11110011 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad tamper slot 4
18:28:46.029 ->  1646.86: 11111111 1 11111111 11111100 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad restore slot 4
18:29:38.026 ->  1698.85: 11111111 1 11111111 11111111 00111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad tamper slot 5
18:29:39.540 ->  1700.37: 11111111 1 11111111 11111111 11001111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad restore slot 5
18:31:48.580 ->  1829.42: 11111111 1 11111111 11111111 11110011 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad tamper slot 6
18:31:49.987 ->  1830.83: 11111111 1 11111111 11111111 11111100 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad restore slot 6
18:32:45.639 ->  1886.48: 11111111 1 11111111 11111111 11111111 00111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad tamper slot 7
18:32:47.469 ->  1888.32: 11111111 1 11111111 11111111 11111111 11001111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad restore slot 7
18:33:39.188 ->  1940.02: 11111111 1 11111111 11111111 11111111 11110011 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad tamper slot 7
18:33:40.398 ->  1941.25: 11111111 1 11111111 11111111 11111111 11111100 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //keypad restore slot 8
18:41:12.897 ->  2393.76: 11111111 1 11111111 11111111 11111111 11110011 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //tamper slot 8 on pc5020
18:41:14.486 ->  2395.35: 11111111 1 11111111 11111111 11111111 11111100 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //restore slot 8 on pc5020

Looks good, I've updated the 0x16 decoding to indicate the code length and panel versions (at least, the versions I've seen so far listed on DSC's website for different panel models). It's interesting that DSC is using the literal hexadecimal code to match up with the panel version rather than using the decimal value.

To be honest, I more preferred the way @Dilbert66 did it. One simple line, directly printing hex-value (without decimals). Absolutely useful, future-proof (with possible new DSC panel versions, instead of showing "unknown version") and it saves memory space. Even DSC keypads themselfs show panel version that way, without decimals: Section [900]: Panel Version Displayed Section [900]: Display Panel Version. The system will display the version of the control panel (for example, [0460] indicates panel version 4.60). By the way, you forgot the version 3.1, which was common in PC5020 (v3.11 to be exact). I give look in DLS V and DLS 2002, didnt saw any more versions you might forgot. Only saw a User Manual for v2.7 PC5015 and v4.3 pc1616/1832/1864 but thats all, no installer, no any other info about their existence (maybe just versions with minor regional differences).

I've also removed the rest of the decoding for byte 4 (handled by switch (panelData[4] >> 2)) - those were notes to help narrow down when bits changed during different events, but with the code length bit worked out, the rest of the decoding isn't as relevant.

Having 4/6 digit code lenght decoded, maybe It's possible to make Unlocker sketch automatically setting itself to finding 4 or 6 digit installer code.

Looking at it now, byte 4 bit 4 flips when in *8 programming (need to see if it flips in other scenarios) - it may a signal for other keypads to disable themselves to avoid disrupting programming. Byte 4 bits 2, 5, 6, 7 remain unknown.

I think I saw some bits flipped when I was setting some options programming, not sure. I'll check it again when I have time. About 0x16 byte 4, I wonder if it changes when using panels which support zone doubling, like PC585 V2.4ZD or PC1404 V1.

LCD keypads send out the same keypress code for both of the <> buttons, the Keybus data doesn't show any difference between them - it seems to be a placeholder to indicate that a key was pressed, but the panel takes no action in response. See issue #34 - the LCD keypads seem to operate with an autonomous UI, with navigation and logic handled by the keypad and then only sending the necessary data to the panel.

I should say PK5501 LCD keypad instead of just saying LCD keypad (I have PK5500 and LCD5500 keypads). I saw #34 and comment where you suspected that PK5501 probably have different output for left/right keys and thats the reason why I asked should I try to get a PK5501 LCD keypad. But im almost certain the output will be same, as non-alphanumeric symbol LCD keypads show even less informations. So think I understand it now - LCD keypads have own UI and after pressing left/right it reads status from memory buffer, about alarm memory, troubles etc. Googling confirmed it: "The LCD keypad has a Micro which has preprogrammed key sequences to make the interface more user friendly. The actual serial protocol is still the same as the regular led keypads."

At this point it's mostly a matter of figuring out what Keybus data is useful when integrating into other software (Home Assistant, HomeKit, etc) and provides value to warrant the additional memory usage. The Status sketch shows all states that are currently monitored and stored in memory by the library for use by sketches, if there's a particular status you are interested in but is not currently tracked by the library, you can implement the status tracking in the sketch itself - described in dscKeybusInterface.h:

Well, if <> buttons isnt easily doable in Blynk, what about implementing what @taligentx say in issue #103 and updating Blynk sketch with it? So it will be possible to view and do programmings directly from Blynk, like it is on LED keypads, and eventually avoiding the need for keypad at all? I have verified that panel can work fine without any keypad just with Blynk, even manage to program some things blindly. I think alot of upgrading things can be done into Blynk sketch (for example, that zone leds represent options 1-8 in programming like it is on LED keypads, and instead *3 leds blink we can change color of that zone) but I dont have enough knowledge yet to implement it myself, it doesnt sound too hard to do it so I'm doing some unlucky trial-and-errors regarding that. Even if it isnt easily possible to have zone lights represent same things as in LED keypads (because AFAIK Blynk uses zone open status, not zone status lights), we can create 8 new virtual pins for 1-8 programming/memory leds - 8 more leds in Blynk project wont hurt anything and everybody can customize widgets how they want.

For example, I'll be looking into seeing which platforms can show battery status for a zone sensor, that would be a good reason to add the wireless battery decoding from @Dilbert66 as a tracked status (currently it is decoded by KeybusReader but not stored in memory as a tracked status).

Is it possible to represent zone low battery status in Blynk by changing zone led color, like we do when zone is in alarm? For example, virtual leds in blynk: Zone status led not lit = everything good, zone closed (like it is now) Zone status led yellow = zone low battery (addition hopefully easy to implement) Zone status led green = zone open (like it is now) Zone status led red = zone in alarm (like it is now) Zone status led blue = programming (representing 1-8 options in programming) Zone status led purple = zone light blinking (viewing alarm memory) Maybe also use upper LCD line to show last status message (like for example: zone X tamper, zone X low battery or even programming options 1-8, not showing partition number whole time - its useless as selected partition is indicated just under LCD itself).

I have to thanks @Dilbert66 for helping me about script-typo which caused zone tamper being misreported and for recent updates on decoding pc5108/pc5208/rf5132 modules aswell as decoding memory buffer and trouble statuses which would be really nice If possible to implement it

In first post here, I made mystake saying wrong #155 PR author, so Im also thankful to @BriceDet for decripting event buffer.

kricon commented 3 years ago

I saw it and like the new version-identifing you made in new version. What about the other suggestions, for blynk and unlocker sketches? Will you include new tamper data I decoded for PC5108, keypad slots and PC5204 modules in cmd 0x4C, 0xEB, 0xA5? If needed I can check data again on another panels (PC1832) but I think its obvious what bits are for which conditions on which zones.

I took data output from PC5204 for tamper, supervision on output1 (didnt try other ones as manual says its not supervised), battery and AC power trouble:

PC5204 tamper condition and restoral:

03:13:08.772 ->   539.86: 11111111 1 11111111 11111111 11111110 11111111 11111111 11111111 11111111 11111111 [Module/0x05] Unknown module notification //identical pc5204 for tamper/restore
03:13:08.913 ->   540.01: 01001100 0 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 [0x4C] Keybus query //pc5204 same for tamper and restore
03:13:08.913 ->   540.02: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 11111111 00111111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //pc5204 tamper
03:13:11.772 ->   542.88: 11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 11111111 11001111 11111111 11111111 11111111 11111111 [Module/0x4C] Unrecognized data //pc5204 restore
03:13:09.054 ->   540.15: 10100101 0 00100000 00101011 00000011 00101111 01000110 11111111 01100111 [0xA5] 2020.10.24 03:11 | Unknown data :6 //pc5204 tamper
03:13:11.913 ->   543.04: 10100101 0 00100000 00101011 00000011 00101111 01000101 11111111 01100110 [0xA5] 2020.10.24 03:11 | Unknown data :6 //pc5204 restore
03:13:09.241 ->   540.34: 11101011 0 00000000 00100000 00101011 00000011 00101100 00000011 01000110 11111111 10101101 [0xEB] 2020.10.24 03:11 | Unknown data :8 //pc5204 tamper
03:13:12.147 ->   543.23: 11101011 0 00000000 00100000 00101011 00000011 00101100 00000011 01000101 11111111 10101100 [0xEB] 2020.10.24 03:11 | Unknown data :8 //pc5204 restore

PC5204 battery trouble and restore

03:27:00.547 ->  1371.65: 11111111 1 11111111 11111111 11111111 11011111 11111111 11111111 11111111 11111111 [Module/0x05] //pc5204 identical for battery trouble and restore
03:27:00.687 ->  1371.81: 01011000 0 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 [0x58] Keybus query //indentical for all
03:27:00.687 ->  1371.81: 11111111 1 11110011 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x58] Unrecognized data //pc5204 battery trouble
03:31:15.216 ->  1626.33: 11111111 1 11111100 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x58] Unrecognized data //pc5204 battery restore
03:27:00.781 ->  1371.91: 10100101 0 00100000 00101011 00000011 01011111 10110100 11111111 00000101 [0xA5] 2020.10.24 03:23 | Unknown data :6 //pc5204 battery trouble
03:31:15.310 ->  1626.43: 10100101 0 00100000 00101011 00000011 01101011 10110011 11111111 00010000 [0xA5] 2020.10.24 03:26 | Unknown data :6 //pc5204 battery restore
03:27:00.875 ->  1371.99: 11001110 0 00100000 01011111 10110100 00000000 00000000 00000001 [0xCE] Unknown data //pc5204 battery trouble
03:31:15.404 ->  1626.51: 11001110 0 00100000 01101011 10110011 00000000 00000000 00001100 [0xCE] Unknown data //pc5204 battery restore
03:27:01.062 ->  1372.18: 11101011 0 00000000 00100000 00101011 00000011 01011100 00000011 10110100 11111111 01001011 [0xEB] 2020.10.24 03:23 | Unknown data :8 //pc5204 battery trouble
03:31:15.591 ->  1626.71: 11101011 0 00000000 00100000 00101011 00000011 01101000 00000011 10110011 11111111 01010110 [0xEB] 2020.10.24 03:26 | Unknown data :8 //pc5204 battery restore

PC5204 AC power trouble

03:33:50.184 ->  1781.31: 11111111 1 11111111 11111111 11111111 11011111 11111111 11111111 11111111 11111111 [Module/0x05]  //pc5204 power failure while tamper condition present
03:37:02.182 ->  1973.30: 01011000 0 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 [0x58] Keybus query //pc5204 power failure
03:37:02.182 ->  1973.30: 11111111 1 00111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x58] Unrecognized data //pc5204 power failure
03:37:08.182 ->  1979.30: 11111111 1 11001111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x58] Unrecognized data //pc5204 power restore

PC5204 supervised output 1 trouble

03:52:16.456 ->  2887.61: 11111111 1 11111111 11111111 11111111 11011111 11111111 11111111 11111111 11111111 [Module/0x05] //pc5204 supervised output1 trouble/restore, same if tamper condition present
03:52:16.643 ->  2887.78: 01011000 0 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 [0x58] Keybus query //pc5204 supervised output1, same as above
03:52:16.643 ->  2887.78: 11111111 1 11111111 11110011 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x58] Unrecognized data //pc5204 supervised output1 trouble
03:53:19.643 ->  2950.75: 11111111 1 11111111 11111100 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x58] Unrecognized data //pc5204 supervised output1 restore
03:52:16.737 ->  2887.87: 10100101 0 00100000 00101011 00000011 10110011 10111000 11111111 01011101 [0xA5] 2020.10.24 03:44 | Unknown data :6 //pc5204 supervised output1 trouble
03:53:19.690 ->  2950.84: 10100101 0 00100000 00101011 00000011 10110111 10110111 11111111 01100000 [0xA5] 2020.10.24 03:45 | Unknown data :6 //pc5204 supervised output1 restore
03:52:16.784 ->  2887.94: 11001110 0 00100000 10110011 10111000 00000000 00000000 01011001 [0xCE] Unknown data //pc5204 supervised output1 trouble
03:53:19.784 ->  2950.92: 11001110 0 00100000 10110111 10110111 00000000 00000000 01011100 [0xCE] Unknown data //pc5204 supervised output1 restore
03:52:17.018 ->  2888.14: 11101011 0 00000000 00100000 00101011 00000011 10110000 00000011 10111000 11111111 10100011 [0xEB] 2020.10.24 03:44 | Unknown data :8 //pc5204 supervised output1 trouble
03:53:19.971 ->  2951.11: 11101011 0 00000000 00100000 00101011 00000011 10110100 00000011 10110111 11111111 10100110 [0xEB] 2020.10.24 03:45 | Unknown data :8 //pc5204 supervised output1 restore
taligentx commented 3 years ago

currently, I'm only able to access the specific battery level of zones by sending a *27## to the panel on initial start and retrieving it from the 0A (sent in response to the menu option to show active lights) cmd as such in the esphome component sketch: After that, I monitor the module cmd41 response and decode the levels there. Not the easiest way. I have not seen a specific cmd yet that the panel sends for detailed battery state like this such as the 0x27 cmd for zones.

@Dilbert66 Thanks for the code! It'll be handy to get the example sketches updated for the home automations that can use the battery level data.

I have tested and logged some still unknown data, mostly related to module tampers which hopefully might be helpful and implemented.

@kricon Thanks for the extensive testing and detailed logs! Very useful - now that there's some more flash space available for Arduino/AVR, I've implemented decoding for the data you've provided. It's nice to have a better idea of the 0x4C and 0x58 queries, these were previously unknown - 0x4C appears to be a module tamper query, and 0x58 appears to be a module status query.

Updated decoding for the module response to the 0x05, 0x1B status commands - there are still a few gaps (likely used for other module types):

 *  Module data during panel commands 0x05, 0x1B: Panel status
 *  Structure decoding: *incomplete
 *  Content decoding: *incomplete
 *
 *  Byte 2: Partition 1 keypad keys
 *  Byte 3: Partition 2 keypad keys
 *  Byte 4 bit 0: Module tamper notification
 *  Byte 4 bit 1-2: Unknown
 *  Byte 4 bit 3: Wireless module battery notification
 *  Byte 4 bit 4: Zone expander slot 11 notification
 *  Byte 4 bit 5: Zone expander slot 10 notification
 *  Byte 4 bit 6: Zone expander slot 9 notification
 *  Byte 4 bit 7: Unknown
 *  Byte 5 bit 0-1: Unknown
 *  Byte 5 bit 2: Keypad zone status notification
 *  Byte 5 bit 3-4: Unknown
 *  Byte 5 bit 5: Module status notification
 *  Byte 5 bit 6-7: Unknown
 *
 *  00000101 0 10000001 00000001 10010001 11000111 [0x05] Partition 1: Ready Backlight - Partition ready | Partition 2: disabled
 *  11111111 1 00000101 11111111 11111111 11111111 [Module/0x05] Partition 1 Key: 1
 *  11111111 1 11111111 11111111 10111111 11111111 [Module/0x05] Zone expander notification: Slot 9
 *  11111111 1 11111111 11111111 11011111 11111111 [Module/0x05] Zone expander notification: Slot 10
 *  11111111 1 11111111 11111111 11101111 11111111 [Module/0x05] Zone expander notification: Slot 11
 *  11111111 1 11111111 11111111 11110111 11111111 [Module/0x05] Wireless module battery notification
 *  11111111 1 11111111 11111111 11111110 11111111 [Module/0x05] Module tamper notification  // Panel responds with 0x4C Module tamper query
 *  11111111 1 11111111 11111111 11111111 11011111 [Module/0x05] Module status notification  // Panel responds with 0x58 Module status query
 *  11111111 1 11111111 11111111 11111111 11111011 [Module/0x05] Keypad zone notification    // Panel responds with 0xD5 Keypad zone query

Updated decoding for the module response to a 0x4C module tamper query:

 *  Module data during panel command 0x4C: Module tamper query
 *  Structure decoding: *incomplete
 *  Content decoding: *incomplete
 *
 *  Byte 2-5 bit 0-1: Keypad slot 2,4,6,8 tamper restore
 *  Byte 2-5 bit 2-3: Keypad slot 2,4,6,8 tamper
 *  Byte 2-5 bit 4-5: Keypad slot 1,3,5,7 tamper restore
 *  Byte 2-5 bit 6-7: Keypad slot 1,3,5,7 tamper
 *  Byte 5: 0xF0 during a module tamper
 *  Byte 6-8 bit 0-1: Module slot 10,12,14 tamper restore
 *  Byte 6-8 bit 2-3: Module slot 10,12,14 tamper
 *  Byte 6-8 bit 4-5: Module slot 9,11,13 tamper restore
 *  Byte 6-8 bit 6-7: Module slot 9,11,13 tamper
 *  Byte 9 bit 0-3: Unknown
 *  Byte 9 bit 4-5: RF5132 tamper restore
 *  Byte 9 bit 6-7: RF5132 tamper
 *  Byte 10 bit 0-3: Unknown
 *  Byte 10 bit 4-5: PC5204 tamper restore
 *  Byte 10 bit 6-7: PC5204 tamper
 *  Byte 11: Unknown
 *  Byte 12: Unknown
 *  Byte 13 bit 0-3: Unknown
 *  Byte 13 bit 4-5: Module slot 16 tamper restore
 *  Byte 13 bit 6-7: Module slot 16 tamper
 *  Byte 14: Unknown
 *
 *  01001100 0 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 [0x4C] Module tamper query
 *  11111111 1 00111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Keypad tamper: Slot 1
 *  11111111 1 11111111 11111111 11111111 11110000 11001111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [Module/0x4C] Module tamper restored: Slot 9
 *  11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00111111 11111111 [Module/0x4C] Module tamper: Slot 16
 *  11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 00111111 11111111 11111111 11111111 [Module/0x4C] RF5132: Tamper
 *  11111111 1 11111111 11111111 11111111 11110000 11111111 11111111 11111111 11111111 00111111 11111111 11111111 11111111 11111111 [Module/0x4C] PC5204: Tamper

Updated decoding for the module response to a 0x58 module status query:

 *  Module data during panel command 0x58: Module status query
 *  Structure decoding: *incomplete
 *  Content decoding: *incomplete
 *
 *  Byte 2 bit 0-1: PC5204 battery restored
 *  Byte 2 bit 2-3: PC5204 battery trouble
 *  Byte 2 bit 4-5: PC5204 AC power restored
 *  Byte 2 bit 6-7: PC5204 AC power trouble
 *  Byte 3 bit 0-1: PC5204 output 1 restored
 *  Byte 3 bit 2-3: PC5204 output 1 trouble
 *  Byte 3 bit 4-7: Unknown
 *  Byte 4: Unknown
 *  Byte 5: Unknown
 *
 *  Later generation panels:
 *  Byte 6: Unknown
 *  Byte 7: Unknown
 *  Byte 8: Unknown
 *  Byte 9: Unknown
 *  Byte 10: Unknown
 *  Byte 11: Unknown
 *  Byte 12: Unknown
 *  Byte 13: Unknown
 *
 *  11111111 1 11111111 11111111 11111111 11011111 [Module/0x05] Module status notification
 *  01011000 0 10101010 10101010 10101010 10101010 [0x58] Module status query
 *  11111111 1 11111100 11111111 11111111 11111111 [Module/0x58] PC5204: Battery restored
 *  11111111 1 11111111 11110011 11111111 11111111 [Module/0x58] PC5204: Output 1 trouble

Updated decoding for panel status commands: 0xA5, 0xCE, 0xEB:

10100101 0 00100000 00101010 11000110 00101011 00111011 11111111 00011010 [0xA5] 2020.10.22 06:10 | Module tamper: Slot 9
11101011 0 00000000 00100000 00101010 10100100 01011000 00000011 01000001 11111111 01110100 [0xEB] 2020.10.21 04:22 | RF5132: Tamper restored
10100101 0 00100000 00101011 00000011 00101111 01000110 11111111 01100111 [0xA5] 2020.10.24 03:11 | PC5204: Tamper

Having 4/6 digit code lenght decoded, maybe It's possible to make Unlocker sketch automatically setting itself to finding 4 or 6 digit installer code.

Should be straightforward, added to the TODO list.

About 0x16 byte 4, I wonder if it changes when using panels which support zone doubling, like PC585 V2.4ZD or PC1404 V1.

That'd be a good test, I haven't seen Keybus data with zone doubling yet.

So it will be possible to view and do programmings directly from Blynk, like it is on LED keypads, and eventually avoiding the need for keypad at all? (...) Is it possible to represent zone low battery status in Blynk by changing zone led color, like we do when zone is in alarm?

This makes sense as the path forward for the web UI and Blynk sketch, it's become clear there are enough folks that would find full keypad emulation useful. Bumping up priority for this feature.

I'll keep this issue open as there's likely quite a bit more left to decode for these commands - thanks for the contributions!

taligentx commented 3 years ago

@kricon - Do you happen to have any logs showing the PC5204 outputs being activated/deactivated? I suspect this is in the 0x87 PGM output command (perhaps byte 3, bit 4-7) but haven't been able to check it out.

Current 0x87 decoding - byte 2 is likely wrong and not "Bell on", it's probably PGM3/PC5208 output 1 (bit 0) - PGM10/PC5208 output 8 (bit 7):

 *  0x87: Panel PGM outputs
 *  CRC: yes
 *  Structure decoding: *incomplete
 *  Content decoding: *incomplete
 *
 *  Byte 2, 11111111: Bell on
 *  Byte 2 bit 0: PGM 3 status
 *  Byte 2 bit 1: PGM 4 status
 *  Byte 2 bit 2-7: Unknown
 *  Byte 3 bit 0: PGM 1 status
 *  Byte 3 bit 1: PGM 2 status
 *  Byte 3 bit 2-7: Unknown
 *  Byte 4: CRC
 *
 *  10000111 0 00000000 00000000 10000111 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 off | PGM4 off
 *  10000111 0 00000000 00000001 10001000 [0x87] Panel output: Bell off | PGM1 on | PGM2 off | PGM3 off | PGM4 off
 *  10000111 0 00000000 00001000 10001111 [0x87] Panel output: Bell off | Unknown data | PGM3 off | PGM4 off
 *  10000111 0 00000001 00000011 10001011 [0x87] Panel output: Bell off | PGM1 on | PGM2 on | PGM3 on | PGM4 off
 *  10000111 0 00010001 00000010 10011010 [0x87] Panel output: Bell off | PGM1 off | PGM2 on | PGM3 on | PGM4 off
 *  10000111 0 00010011 11110011 10001101 [0x87] Panel output: Bell off | PGM1 on | PGM2 on | PGM3 on | PGM4 on
 *  10000111 0 00010011 00000000 10011010 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 on | PGM4 on
 *  10000111 0 11111111 11110000 01110110 [0x87] Panel output: Bell on | PGM1 off | PGM2 off
 *  10000111 0 11111111 11110010 01111000 [0x87] Panel output: Bell on | PGM1 off | PGM2 on
kricon commented 3 years ago

Sure I can output the logs! Actually, I wanted to test that when I get my hands on PK5500 because it have PGM output which can be assigned to any PGM 1-14 (and it even have two more PGMs: 15 Local PGM Pulse and 16 Local PGM Toggle).

I also wanted to suggest ability to see PGM status in example sketches, for example in Home Assistance (device_class garage_door?) and Blynk (virtual port for led, its easy to add/customize widgets for own needs), as I have PGMs controlling some lights on the house and it could aswell be used to control garage doors and many other things but impossible to see PGM on/off status even from keypad itself (even event buffer just says Command O/P 1)! Having PGM output connected into Zone input with Non-Alarm definition is possibility but why consume Zones (and LCD keypads will scroll thru that zone like its open when PGM output is off) when it can be made easier internally?

I've verified PGMs 11-14 by connecting LEDs to outputs 1-4 of PC5204 which was connected onto keybus. But then idea came on my mind: why would you need an PGM expansion connected to see PGM data which panel outputs to keybus? If PC5208 can read keybus and follow the PGMs, it can also keybusreader even without PC5208 connected onto keybus. That proved to be correct so I set *7 CMD O/P 1-4 for PGMs 11-14, then for 3-6 and lastly 7-10:

03:14:36.296 ->  2244.42: 10000111 0 00000000 00010000 10010111 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 off | PGM4 off //pgm enabled:11
03:14:38.333 ->  2246.46: 10000111 0 00000000 00110000 10110111 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 off | PGM4 off //pgm enabled:11,12
03:14:40.366 ->  2248.49: 10000111 0 00000000 01110000 11110111 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 off | PGM4 off //pgm enabled:11,12,13
03:14:42.120 ->  2250.23: 10000111 0 00000000 11110000 01110111 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 off | PGM4 off //pgm enabled:11,12,13,14
03:18:15.181 ->  2462.96: 10000111 0 00000001 00000000 10001000 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 on | PGM4 off //pgm enabled:3
03:18:18.929 ->  2466.72: 10000111 0 00000011 00000000 10001010 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 on | PGM4 on  //pgm enabled:3,4
03:18:21.549 ->  2469.34: 10000111 0 00000111 00000000 10001110 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 on | PGM4 on  //pgm enabled:3,4,5
03:18:24.448 ->  2472.22: 10000111 0 00001111 00000000 10010110 [0x87] Panel output: Bell off | PGM1 off | PGM2 off              //pgm enabled:3,4,5,6
03:23:20.446 ->  2767.77: 10000111 0 00010000 00000000 10010111 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 off | PGM4 off //pgm enabled:7
03:23:22.581 ->  2769.90: 10000111 0 00110000 00000000 10110111 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 off | PGM4 off //pgm enabled:7,8
03:23:24.166 ->  2771.48: 10000111 0 01110000 00000000 11110111 [0x87] Panel output: Bell off | PGM1 off | PGM2 off | PGM3 off | PGM4 off //pgm enabled:7,8,9
03:23:25.714 ->  2773.05: 10000111 0 11110000 00000000 01110111 [0x87] Panel output: Bell on | PGM1 off | PGM2 off | PGM3 off | PGM4 off  //pgm enabled:7,8,9,10

Little bug I noticed, when PGM output requires access code and after entering correct code, PGM output will activate like it should but it will log that Auto-arm was cancelled: 03:43:11.034 -> 3956.53: 10100101 0 00100000 01101101 01100011 10000001 00100110 00000000 00111100 [0xA5] 2020.11.11 03:32 | Partition 1 | Auto-arm cancelled by master code 40

Dilbert66 commented 3 years ago

If you want to see the Pgm data in a sketch, look at the array variable dsc.panelData[], when dsc.panelData[0]==0x87, the dsc.panelData[2] and dsc.panelData[3] bytes will have the pgm bit values.

taligentx commented 3 years ago

@kricon

I've verified PGMs 11-14 by connecting LEDs to outputs 1-4 of PC5204 which was connected onto keybus. But then idea came on my mind: why would you need an PGM expansion connected to see PGM data which panel outputs to keybus? If PC5208 can read keybus and follow the PGMs, it can also keybusreader even without PC5208 connected onto keybus. That proved to be correct so I set *7 CMD O/P 1-4 for PGMs 11-14, then for 3-6 and lastly 7-10:

Great, I've updated 0x87 as PGM outputs 1-14 and added a TODO item to track the PGM output status so sketches can follow the panel PGM outputs - byte 3 bits 2-3 are unknown but as you mentioned these may be PGM 15/16:

 *  0x87: PGM outputs
 *  CRC: yes
 *  Structure decoding: *incomplete
 *  Content decoding: *incomplete
 *
 *  Byte 2 bit 0: PGM 3
 *  Byte 2 bit 1: PGM 4
 *  Byte 2 bit 2: PGM 5
 *  Byte 2 bit 3: PGM 6
 *  Byte 2 bit 4: PGM 7
 *  Byte 2 bit 5: PGM 8
 *  Byte 2 bit 6: PGM 9
 *  Byte 2 bit 7: PGM 10
 *  Byte 3 bit 0: PGM 1
 *  Byte 3 bit 1: PGM 2
 *  Byte 3 bit 2-3: Unknown
 *  Byte 3 bit 4: PGM 11
 *  Byte 3 bit 5: PGM 12
 *  Byte 3 bit 6: PGM 13
 *  Byte 3 bit 7: PGM 14
 *  Byte 4: CRC
 *
 *  10000111 0 00000000 00000000 10000111 [0x87] PGM outputs enabled: none
 *  10000111 0 00000000 00000001 10001000 [0x87] PGM outputs enabled: 1
 *  10000111 0 00000001 00000011 10001011 [0x87] PGM outputs enabled: 1 2 3
 *  10000111 0 00010001 00000010 10011010 [0x87] PGM outputs enabled: 2 3 7
 *  10000111 0 00010011 00000000 10011010 [0x87] PGM outputs enabled: 3 4 7
 *  10000111 0 00010011 11110011 10001101 [0x87] PGM outputs enabled: 1 2 3 4 7 11 12 13 14
 *  10000111 0 11111111 11110000 01110110 [0x87] PGM outputs enabled: 3 4 5 6 7 8 9 10 11 12 13 14
 *  10000111 0 11111111 11110010 01111000 [0x87] PGM outputs enabled: 2 3 4 5 6 7 8 9 10 11 12 13 14
kricon commented 3 years ago

byte 3 bits 2-3 are unknown but as you mentioned these may be PGM 15/16

I didn't yet get a PK55XX (I think PGM15/16 are purely local on that keypads and dont send any data on keybus) but I did some testing and I've found that cmd 0x87 byte3 bit2 flips at midnight and bit3 flips when battery check is in progress on system&modules:

So yeah, 0x87 fully decoded. Even Section 701, option 3 from PC5020 pdf confirms it:

AC/DC Arming Inhibit with Battery Check Enabled. When an AC or DC trouble is present, the system will not arm. This includes Keypad, Keyswitch, Automatic, and Downloading Arming. If enabled and arming is attempted, the system will perform a System Battery check as well as a Battery Check on all peripheral modules supported by a backup battery.

  104.80: 10000111 0 00000000 00001000 10001111 [0x87] PGM outputs enabled: //battery check when arming with [703][3] ON
  272.71: 10000111 0 00000000 00000100 10001011 [0x87] PGM outputs enabled: //flips every midnight (module battery check)

Also, "Battery check in progress" message is decoded as 0x12:

 1252.40: 00000101 0 10010001 00010010 00010001 11000111 00010001 11000111 00010001 11000111 [0x05] Partition 1: Ready Trouble Backlight - Unknown data: 0x12 | Partition 2: disabled | Partition 3: disabled | Partition 4: disabled //before adding 0x12 to printPanelMessages
 4409.14: 00000101 0 10010001 00010010 00010001 11000111 10010001 01000000 00010001 11000111 [0x05] Partition 1: Ready Trouble Backlight - Battery check in progress | Partition 2: disabled | Partition 3: Ready Trouble Backlight - Keypad blanking | Partition 4: disabled

...and added a TODO item to track the PGM output status so sketches can follow the panel PGM outputs

I hope that programming leds/alam memory blink leds and wireless zones low battery color change for WebUI&Blynk sketch are aswell on TODO list, not just bumped-feature.

If you want to see the Pgm data in a sketch, look at the array variable dsc.panelData[], when dsc.panelData[0]==0x87, the dsc.panelData[2] and dsc.panelData[3] bytes will have the pgm bit values.

Thanks! I've got a bit more familar with code structure, doing some decoding and PRs. But not so much that I feel confident to try doing it by myself, atleast not yet.

taligentx commented 3 years ago

I also wanted to suggest ability to see PGM status in example sketches, for example in Home Assistance (device_class garage_door?)

I've added PGM 1-14 status processing and updated the Status sketch and the MQTT example sketches (HomeAssistant, Homebridge, and OpenHAB) to demonstrate how to access the PGM status. I've only tested with the PC1864 so this will need to be tested against the earlier generation of panels.

kricon commented 3 years ago

I'll add and test PGM status to Blynk (atleast, try to - it should be straightforward) when I'll be able to access my Blynk server which shouldn't be this year. But yeah, there isn't need to have 14 virtual pins if you're interested in only one or two pgm outputs so I won't update Blynk project examples. Reason why I want possibility to see PGM status is because each time after you exit installer programming menu, PGM's reset. So if PGM was enabled before, its now disabled - and im using it for a light outside the house so is nice to know PGM status remotely.

But I checked with status sketch and PC5020 and it seem to work fine. I've also tested with PC585 and PC1565-2P (which doesn't support PC5204/PC5208 pgm relay modules) and they doesn't send 0x87 cmd and thus won't work with them. I suppose that it will work with any panel that have support for PC5204 or PC5208 relay modules.