Cat Flap

Product ID = 6

Cat Flap advantages:

  • Runs on AA batteries which are typically cheaper,
  • Lock modes are separate from curfew mode, so curfew can be set along with lock in/out which isn't supported on Pet Door as either you have curfews or locked state.
  • Support for four curfew times, pet door only supports one.
  • Support for dual scan, so scans to let animal out as well as in. Pet door does not have the ability to scan pet on the inside as there is no antenna coil on the interior side.
  • Because of dual scan you can set lock state of a particular cat to indoor only when others can exit.

Disadvantages:

  • Does not support re-chargable batteries unlike the Pet Door.
  • Cannot change curfews without the app
  • Custom modes can be changed via the buttons but not documented
  • No LCD to see state

Common Messages

All the non-Pet Door devices have common messages

All the non Pet Door devices have a consistent messaging format with the message types 126 and 127.

Type Feeder Cat Flap Poseidon Description
00 :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: Acknowledgement Command Message to Status Message
01 :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: Get Command Message to retrieve message state
07 :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: Set Time Command Message to set device time
09 :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: Device settings parameters
0b :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: 0b Boot Status Message
0c :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: Battery Status Message
10 :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: 10 Boot Status Message
11 :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: Tag Provision Command Message to Status Message
12 :heavy_check_mark: Set Cat Flap Curfew Command message
13 :heavy_check_mark: Cat Movement through cat flap status message
17 :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: 17 Unknown message
18 :heavy_check_mark: Feeding status message
0d :heavy_check_mark: Cat Flap Curfew Status messages
0d :heavy_check_mark: Zero Feeder Scales
1b :heavy_check_mark: Drinking status message

126 Messages

These are the status message where multiple messages can all be sent in a single payload from the device. Directly after the 126 the message length in hex, then the message type, and the payload. At the end of the payload an additional message can be sent. Again the length then message type until the end of the payload. The first byte after the timestamp is the same hub counter message as already talked about 0xx0 above. That is consistent for all messages.

This means a message can look like:

tttttttt 0010 126 0d 09 00 01 00 9f cc 42 59 0c 02 00 00 00
   |      |    |  |  |     --+-- -----+-----  | +----------
   |      |    |  |  |       |        |       | +- Bowl Count = 2
   |      |    |  |  |       |        |       +--- SubType = C
   |      |    |  |  |       |        +----------- Timestamp
   |      |    |  |  |       +-------------------- Counter
   |      |    |  |  +---------------------------- Message Type
   |      |    |  +------------------------------- Length
   |      |    +---------------------------------- Message Type 126
   |      +--------------------------------------- Hub Counter Status Message
   +---------------------------------------------- Hub UTC Hex Timestamp

The above secnario the message is a single message length is 0d bytes long. The message type is a 09 and the payload is 00 01 00 9f cc 42 59 0c 02 00 00 00.

tttttttt 0xx0 126 0d 09 00 01 00 9f cc 42 59 0c 02 00 00 00 0d 09 00 02 00 9f cc 42 59 0a 88 13 00 00

Similar to the above, the first message is the same message above, the second message is also 0d bytes long and a message type 09 with the payload 00 02 00 9f cc 42 59 0a 88 13 00 00.

127 Messages

The 127 messages are command messages either sent from the cloud service to change something, such as locking the cat flap or provisioning a new tag to the device. Because they are command messages they will always be 1000, but they are a single message so do not include the length so you need to just know how long the message you want to send is and just start with the message type immedateily after 127 ie

tttttttt 1000 127 09 00 01 00 9f cc 42 59 0c 01 00 00 00
   |      |    |  |     --+-- -----+-----  | +----------
   |      |    |  |       |        |       | +- Bowl Count = 1
   |      |    |  |       |        |       +--- SubType = C
   |      |    |  |       |        +----------- Timestamp
   |      |    |  |       +-------------------- Counter
   |      |    |  +---------------------------- Message Type
   |      |    +------------------------------- Message Type 126
   |      +------------------------------------ Command Message
   +------------------------------------------- Hub UTC Hex Timestamp

The above is setting the Bowl Count to 1.

Message Counter

Directly after the message type is a 00, then a two byte little endian byte counter which counts from 0 to 65534 before cycling back to 0. This is so the cloud knows the current state of the devices and if messages are lost as if the hub is offline or disconnected from the internet none of the messsages are retained. Typical messages: There is also a send a retrive counter, which are generated and increment independently. As each end have their own sent counter

tttttttt 0xx0 126 09 01 00 01 00 9e cc 42 59 11 11 - Device Counter = 1
tttttttt 1000 127 01 00 02 f2 9e cc 42 59 11 11 - Cloud Counter = F202 = 61954

Message Timestamp

After the counter is a 4 byte timestamp of the event. This is used by the device to set the time of it, and report back the timestamp of the device if there is any skew. The time is stored in UTC, but instead of using the UTC Timestamp they have their own custom rolled timestamp using bitwise operators as shown below which bits are converted into numbers. This is calculated in function devicetimestamp in message.py

def devicetimestamp(hexts, time_zone, tz_format):
    """ Convert device hex timestamp into something human readable """
    timestamp_int = int.from_bytes(hexts, byteorder='little')
    year = int(f'20{timestamp_int >> 26:02}')  # Year - 6 Bits, prepending 20 for 4 digit year
    month = timestamp_int >> 22 & 0xf          # Month - 4 Bits
    day = timestamp_int >> 17 & 0x1f           # Day - 5 Bits
    hour = timestamp_int >> 12 & 0x1f          # Hour - 5 Bits
    minute = timestamp_int >> 6 & 0x3f         # Minute - 6 Bits
    second = timestamp_int & 0x3f              # Second - 6 Bits

Example Conversion

Using the example timestamp `9e cc 42 59` 
9e cc 42 59 -> Little Endian -> 5942CC9E -> Integer = 1497549982
1497549982 -> Binary 01011001010000101100110010011110
First 6 Bits 010110 -> 22 Year, so prepent 20 to 2022.
Next 4 Bits 0101 -> 5 Month
Next 5 Bits 00001 -> 1 Day
Next 5 Bits 01100 -> 12 Hour
Next 6 Bits 110010 -> 50 Minute
Next 6 Bits 011110 -> 30 Second
UTC Time = 2022-05-01 12:50:30

And since this is UTC time, it needs to be converted into local time.

Acknowledgement

Message Type: 00 Message Length: 07

Every status message needs to be acknowledged back using a 127 and a message type of 00 once it has been processed by the other end. This is sent with the same send counter, but the timestamp of the sending host, and include the message type and two bytes of 00 ie 01 00 00 being acknowledged.

Hub to Cloud -> tttttttt 0xx0 126 07 01 00 02 11 9e cc 42 59 11 22 33 44 55
Cloud to Hub -> tttttttt 1000 127 00 00 02 11 9f cc 42 59 01 00 00

Get State

Message Type: 01 Message Length = N/A as Command only, and varaible length.

To retrieve the current status of a message type a 01 command message is sent to the device.

Cloud to Hub -> tttttttt 1000 127 01 00 01 00 9f cc 42 59 09 00 ff  # Boot message 09
Cloud to Hub -> tttttttt 1000 127 01 00 02 00 9f cc 42 59 0b 00     # Unknown 0b
Cloud to Hub -> tttttttt 1000 127 01 00 03 00 9f cc 42 59 0c 00     # Battery state
Cloud to Hub -> tttttttt 1000 127 01 00 04 00 9f cc 42 59 0d 00     # Lock state
Cloud to Hub -> tttttttt 1000 127 01 00 05 00 9f cc 42 59 10 00     # Boot message 10
Cloud to Hub -> tttttttt 1000 127 01 00 06 00 9f cc 42 59 11 00 ff  # Tag provisioned
Cloud to Hub -> tttttttt 1000 127 01 00 07 00 9f cc 42 59 12 00     # Curfew state
Cloud to Hub -> tttttttt 1000 127 01 00 08 00 9f cc 42 59 17 00 00  # Boot message 17
Cloud to Hub -> tttttttt 1000 127 01 00 09 00 9f cc 42 59 1b 00     # Water state

Set Device Time

Message Type: 07

Command message to set the time of the device in UTC. As all the time is in UTC the device timestamp value needs to be set to UTC time.

Cloud to Hub -> tttttttt 1000 127 01 00 01 00 9f cc 42 59 00 00 00 00 07  # Sets the device time to 2022-05-01 12:50:30

Device settings messages

Message Type: 09 Messages Length: 0d

This is used for setting device settings. Such as custom modes and bowl counts for the feeder. The sub-type messages vary depending on the device and have a byte after the timestamp for the sub-type, then little endian 4 byte word for the value of the sub-type.

Status 09 Example:

0d 09 00 01 00 9f cc 42 59 0c 02 00 00 00
|  |     --+-- -----+-----  | -----+-----
|  |                        |    Bowl Count = 2
|  |                        +--- SubType = C
|  +---------------------------- Message Type
+------------------------------- Length

Boot Device Information

Message Type 0b

The boot device message length is 43 and the figured fields defined message

    elif value[0] == 0x0b:  # Status - Boot Device Information
        frame_response.Operation = "DeviceInfo"
        frame_response.Hardware = b2is(value[8:12])
        frame_response.Firmware = b2is(value[12:16])
        frame_response.EntityType = EntityType(value[64]).name
        frame_response.Val1 = b2is(value[16:20])        # **TODO Some value
        frame_response.HexTS = value[20:28].hex()
        frame_response.SerialHex = value[36:45].hex()  # **TODO Serial Number calc somehow

Battery Information

Message Type 0c Message length = 18

The battery information in the message

The 4 byte word after the timestamp is the battery value with 3 decimal places of accuracy as reported in the app.

126 18 0c 00 01 00 9f cc 42 59 b8 14 00 00 dd 0c 00 00 25 01 00 00 00 00 00 00

b8 14 00 00 -> Hex 14B8 -> Decimal 5304 / 1000 -> Battery voltage 5.304

Code:

    elif value[0] == 0x0c:  # Status - Battery state for four bytes
        frame_response.Operation = 'Battery'
        battery = str(round(int(b2is(value[8:12])) / 1000, 4))
        frame_response.Battery = battery
        frame_response.Value2 = str(int(b2is(value[12:16])))  # **TODO Not sure what this value is.
        frame_response.Value3 = str(int(b2is(value[16:20])))  # **TODO Or this one
        frame_response.BatteryTime = devicetimestamp(value[20:24], time_zone, '')  # **TODO Last time the time was set?

Some boot message

Message type: 10 Message length: 18

The Boot in the message No idea what is in the message.

Message 11 - Tag Provisioning

Message Length = 12

This is used to and and remove tags to the device. The Tag Calculation is completely different from the Pet Door as it is little endian. This is also used to set lock state on the Cat Flap on Tag 00.

Example Message:

126 12 11 00 01 00 9f cc 42 59 4a 2a 86 48 d7 f9 01 02 01 00
       |     --+-- -----+----- --------+-------- |  |  |  +- Always 0
       |                               |         |  |  +---- Tag Offset starting with 1
       |                               |         |  +------- Tag State, 02 = Normal
       |                               |         +---------- Tag Type `01` for FDX-B
       |                               +-------------------- Tag Value
       +---------------------------------------------------- Message Type 11

There are 2 types of tags:

  • Tag 01 is a FDX-B tag with the numbering xxx.xxxxxxxxxx decimal value 3 + 10 digits
  • Tag 03 is a HDX tag which is presented as 5 bytes of hex hhhhhhhhhh

FDX-B Tag Conversion:

4a 2a 86 48 d7 f9 -> Little endian hex F9D748862A4A -> Int 274703030037066
274703030037066 -> Binary 111110011101011101001000100001100010101001001010
First 10 Bytes are Country Code = 11111001110 = 999
38 Bytes are National Code = 1011101001000100001100010101001001010 = 100001000010
FDX-B Tag = 999.100001000010

HDX Tag:

11 22 33 44 55 00 -> Direct translation of the hex to the tag and the last byte is always 00

Tag State is either 02 for active/normal, 06 for disabled, or 03 if it is a CatFlap and the Tag is set to Keep In

Tag Offset starts at 1, and supports up to 32 aka 1f tags on the device. Tag Offset 0 is used on the Cat Flap to set door locking state.

Cat Flap specific messages

Message 09 - Cat Flap settings messages

Messages Length = 0d

Setup Custom Modes

Custom modes can be setup on the device, or sent remotely. To do it locally press and hold BOTH the Settings Button on the left AND the Add Pet Button for 3 seconds until the indicator light comes on Solid Red. Then select the mode you want based on the LED then to activate the mode press and hold Settings Button for 3 seconds. If you don't do anything in 60 seconds it exits settings mode.

All custom modes are in settings registers on 09

Custom Mode Colour Name Description Youtube
04 Solid Red Extended Frequency To extend the frequency for detuned microchips https://www.youtube.com/watch?v=2BoMq6g0XMc or https://www.youtube.com/watch?v=BW_TWN5KAt4 or https://www.youtube.com/watch?v=Tc17W_zxowE
05 Solid Green Non Selective Exit Any cat can exit, only tagged cats can enter https://www.youtube.com/watch?v=G4MFkrmyDto
07 Solid Orange Metal :metal: :metal: Mode Resolve metal inteference issues either 0 or 2 https://www.youtube.com/watch?v=M4r-q2IVOSo or https://www.youtube.com/watch?v=VpDqvVTKjA0
08 Flashing Red Fast Locking Locking faster than usual https://www.youtube.com/watch?v=56xQspY5t5I
01 Flashing Green Double Chip Operating To extend the frequency for detuned microchips either 01 or 02 https://www.youtube.com/watch?v=P1prjghrsz4
?? Flashing Orance Fail Safe Unlock if the batteries fail https://www.youtube.com/watch?v=zP9KO98PiHw or https://www.youtube.com/watch?v=z36MukKUzDQ
N/A Flash Red & Green Erase All Custom Modes Clear all custom modes https://www.youtube.com/watch?v=Wohm9dXP8G0

Command 09 Settings Messages Example:

127 09 00 01 00 9f cc 42 59 04 00 00 00 00 - Disable Extended Frequency
127 09 00 01 00 9f cc 42 59 04 01 00 00 00 - Enable Extended Frequency
127 09 00 01 00 9f cc 42 59 05 00 00 00 00 - Disable Non Selective Exit
127 09 00 01 00 9f cc 42 59 05 01 00 00 00 - Enable Non Selective Exit
127 09 00 01 00 9f cc 42 59 07 00 00 00 00 - Disable Metal Mode
127 09 00 01 00 9f cc 42 59 07 02 00 00 00 - Enable Metal Mode
127 09 00 01 00 9f cc 42 59 08 00 00 00 00 - Disable Fast Lock
127 09 00 01 00 9f cc 42 59 08 01 00 00 00 - Enable Fast Lock
127 09 00 01 00 9f cc 42 59 01 01 00 00 00 - Disable Double Chip, I think this is more "allow one chip"
127 09 00 01 00 9f cc 42 59 01 02 00 00 00 - Enable Double Chip, and this "allow two chips"

Cat Flap Curfew Enabled

Message Type: 0d Message Length: 1e

These happen when the cat flap reports back on it's current status and the curfew is enabled. It doesn't send a message when the curfew lock state changes.

The lock state will either be 03 for on, or 06 for off so that means it is locked at this point in time or not.

126 1e 0d 00 a5 09 9f cc 42 59 40 4f fa 75 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 02 00 04 06
       +     --+-- -----+----- -----+-----                                                    +- Lock State
                                    +--------- No idea, could be a counter or something

Message 11 - Set Lock State and Cat Inside Only

Message Length = 12

This is a command message that sets the lock state of the whole cat flap and overrides all pets.

Example Message:

127 11 00 20 00 9f cc 42 59 00 00 00 00 00 00 07 05 00 02
    |     --+-- -----+----- --------+-------- |  |  |  +- Always 2 for Cat Flap State changes
    |                               |         |  |  +---- Tag Offset 0 - Cat Flap
    |                               |         |  +------- Lock State - 05 = Keepout
    |                               |         +---------- Tag Type always 07
    |                               +-------------------- Tag Value always zero's
    +---------------------------------------------------- Message Type 11

The other specific setting along with Tag Provisioning is where the feature is you can set on a per-tag basis if the cat is to be kept inside only. This is set witht he Lock State byte on the tag.

Example Message:

127 11 00 01 00 9f cc 42 59 4a 2a 86 48 d7 f9 01 03 01 00
    |     --+-- -----+----- --------+-------- |  |  |  +- Always 0 for Cat Tag State
                                                 |  +---- Tag Offset 1
                                                 +------- Lock State - 03 = Keepin, or 02 for normal.

Message 12 - Set Curfew of Cat Flap

Message length = 33 or N/A as it's a command only.

Disable all curfews
1000 127 12 00 01 00 tt tt tt tt 00 00 00 00 00 00 07 00 00 00 42 00 00 00 42 00 06 00 00 42 00 00 00 42 00 06 00 00 42 00 00 00 42 00 06 00 00 42 00 00 00 42 00 06
         |     --+-- -----+-----                         ------------+------------- ------------+------------- ------------+------------- ------------+-------------
         |      CC   Timestamp                                       |                          |                          |                          +------------- Curfew 4
         |                                                           |                          |                          +---------------------------------------- Curfew 3
         |                                                           |                          +------------------------------------------------------------------- Curfew 2
         |                                                           +---------------------------------------------------------------------------------------------- Curfew 1
         +---------------------------------------------------------------------------------------------------------------------------------------------------------- Message 12

As you can set 4 curfews this is all sent in one message. Using the same Message Timestamp calculation and as always in UTC time as all times on the device are in UTC. But the message is sent in todays Date rather than some other artibrary date. And the HH:MM based on the UTC time to open / close and seconds set to 00. The last byte of the curfew is either 03 for enabled or 06 for disabled. If you change curfews on the app and have curfew 1,2,3 and remove curfew 2, then curfew 3 is replaced on curfew 2 and curfew 3 is blank. The message length always needs to be the same where all curfews are populated even if they are disabled.

Message 13 - Pet Movement through door

Message length = 1e

Similar to the Pet Door when a cat sticks their haed in, or goes through the cat flap this message is generated. It also generates status messages for whatever reason.

The Came in/out/looked in/out are fairly straightforward in the enum. The Status messages of 01 02 and 02 02 seem to happen very frequently, and no idea what they mean.

Example Cat Message

126 1e 13 00 22 00 9f cc 42 59 00 00 00 00 ba 11 00 00 02 00 4a 2a 86 48 d7 f9 01 05 25 01 00 00
       |     --+-- -----+-----             -----+----- --+-- --------+-------- |  |  +---------- 25 01, 28 01.. Unsure
       |                                        |        |           |         |  +------------- Unknown Counter
       |                                        |        |           |         +---------------- Tag Type
       |                                        |        |           +-------------------------- Tag that was detected
       |                                        |        +-------------------------------------- Pet Movement - Looked out
       |                                        +----------------------------------------------- Unknown Counter
       +---------------------------------------------------------------------------------------- Message 13

Example Status Message

126 1e 13 00 54 00 9f cc 42 59 00 00 00 00 42 16 01 00 01 02 00 00 00 00 00 00 00 39 28 01 00 00 1e 13 00 55 00 6e 90 a0 59 00 00 00 00 ca 01 00 00 02 02 00 00 00 00 00 00 00 39 28 01 00 00

Multi-message

126 1e 13 00 54 00 9f cc 42 59 00 00 00 00 42 16 01 00 01 02 00 00 00 00 00 00 00 39 28 01 00 00
    1e 13 00 55 00 9f cc 42 59 00 00 00 00 ca 01 00 00 02 02 00 00 00 00 00 00 00 39 28 01 00 00
       |     --+-- -----+-----             -----+----- --+-- --------+-------- |  |  +---------- 25 01, 28 01.. Unsure
       |                                        |        +-------------------------------------- Pet Movement Status, either 01 02 or 02 02
       |                                        +----------------------------------------------- Unknown Counter
       +---------------------------------------------------------------------------------------- Message 13