Protocol exploration (3)

Post date: Nov 10, 2019 7:21:33 PM

Outlet command

The messages going from PowerChute to the UPS have a variable length, as opposed to the messages from the UPS that are always 19 bytes. By toggling the outlet from PowerCute, for example, the following message is sent to the UPS:

Turn off outlet

71 08 02 41 04 5b e3

Turn on outlet

71 08 02 41 22 1f 02

We can derive again the message ID (0x71) at byte 0, and a data length at byte 2. Then the 2-byte data follows (0x41 0x04). The last two bytes are the Fletcher 8-bit checksum applied on all the earlier bytes.

Byte 1 corresponds to the offset of the parameter in the data of the message of the same ID that was previously sent by the UPS to the PC.

Most likely this specific data, to switch the outlet, is some kind of bitfield. To turn off the outlet, bit 1 is unset, and bit 2 and 5 are set, and vice versa.

Outlet status

The status of the outlet is mirrored in message ID 0x72, again a bitfield. Following states are identified:

  • Bit 0: Unknown
  • Bit 1: Outlet on
  • Bit 2: Outlet off
  • Bit 3: Rebooting in progress
  • Bit 4: Shutdown in progress
  • Bit 5: Unknown
  • Bit 6: Outlet overloaded
  • Bit 7: Outlet will be switched on
  • Bit 8: Outlet will be switched off
  • Bit 9: Waiting for AC input
  • Bit 10: Waiting on minimum runtime (UPS is charging and output will be turned on when runtime is high enough)
  • Bit 11 and onwards: Unknown

Progress

In the meantime I also got (I believe) a step closer to generating a valid challenge, based on the first byte of the header and the 14-byte serial number. The challenge consists of 4 bytes, for example:

7e 0c 04 3d e7 0d fe a8 97

7e 0c 04 70 67 89 4c 9a 29

7e 0c 04 83 a7 18 01 25 08

7e 0c 04 4d 3e 9b 60 90 59

For now, I use PowerChute to pass the challenge, then kill the service and continue communicating using my Python script. If you don't kill PowerChute, it will send a message to 'reset' the UPS link upon exit.