Inside the Hisense H-NET Protocol: A Reverse Engineering Journey – Part 1


This article documents the reverse engineering process of the Hisense H-NET protocol, used by certain heat pump systems for internal communication between the indoor controller and the outdoor unit. My goal was to understand the structure of this protocol and pave the way for custom integration with Home Assistant. The unit I analyzed, the AHZ-080HCDS1, is not supported by any official or community-developed integration. The system is composed of a monobloc outdoor unit and an indoor remote controller which communicates over a two wire interface where power and data are carried on a single pair of wires: this is what Hisense calls H-NET wiring system.

Hisense AHZ-080HCDS1 with indoor controller

A closer inspection of the controller PCB revealed they’re using an MM1192 HBS transceiver: the H-NET protocol is indeed based on the Home Bus System at least at the physical layer. Who wants to dive deeper into the standard a good place to start could be this introduction from Analog Devices. Datasheet at hand I decided to tap into the data in and data out lines and take a look at them with a logic analyzer. Using Sigrok Pulse was pretty straightforward to figure out the transmission speed which turned out to be 9600 bps.

Indoor controller

After countless hours of messing around and capturing data this is what I figured out: at the lowest level this is what a data frame looks like:

SOURCE ADDRESSCONTROL BYTEMESSAGE LENGTH (len)PAYLOADCHECKSUM
xxxxxxxx … xxxx
1 Byte1 Byte1 Byte(len – 4 ) Byte1 Byte

Messages are broadcasted on the bus: there is indeed no destination address I could find. In my case the indoor controller address is 0x21 and the outdoor unit is 0x12. The control byte is used to acknowledge requests made on the bus: in this case the frame is composed only of the source address followed by a 0x06.

SOURCE ADDRESSCONTROL BYTE
0x120x06
ACK message sent from 0x12

During my captures I never stumbled upon a NAK packet but I am confident the control byte could change to 0x15 — the standard ASCII code for NAK, as opposed to 0x06 which stands for ACK. This could lead to a retransmission of the corrupted message but it is just my guess. The message length is the total number of bytes transmitted, checksum included. The last byte is used for error detection and is computed using a simple XOR-based algorithm: the checksum starts with a 0x00 seed, performs a sequential XOR over all data bytes, and applies a final XOR with the source address. To figure out this I collected a good number of packets (~ 50) and I wrote a script to check with the most common checksum algorithms. Below is an implementation of the matching one in python :

The communication seems to be always started from the indoor controller. Let’s talk about which data is actually transmitted: there is a 7 byte common header composed by a 1 byte MSG TYPE field, 5 consecutive 0x01 bytes and a 1 byte OPCODE that defines the operation/data structure of the message. These messages are sent approximately every 30 seconds. Let’s analyze the following message exchange: the indoor controller sends a status update, and the outdoor unit replies with a similar message.

SRCCTRLLENMSG TYPEOPCODEOPERATION CMDWATER SET TEMPOPERATION MODEDHW SET TEMPPOOL SET TEMPCYCLE SELECTIONINDOOR TEMP 1AMB1 SET TEMP???????
INDOOR TEMP 2
AMB 1 ENABLEYYYYMONTHDAYHHMMSSCHECKSUM
0x210481111110xB1xx1xxxxxxxxxx0xxxxxx00xx000xxxxxxxxxxxxxx000000xx
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
Status update from indoor controller

MSG TYPE appears to be set to 2 for requests and 1 for status updates. The OPCODE in this case is 0xB1.

OPERATION CMD can have the following values:

  • 0x04 AUTO MODE – CYCLE OFF
  • 0x05 AUTO MODE – CYCLE ON
  • 0x08 COOLING MODE – CYCLE OFF
  • 0x09 COOLING MODE – CYCLE ON
  • 0x64 HEATING MODE – CYCLE OFF
  • 0x65 HEATING MODE – CYCLE ON.
HEATING MODECOOLING MODEAUTO MODECYCLE ENABLE
01000001
MSBLSB
Heating mode with Cycle ON OPERATION CMD byte ( 0x65 )

OPERATION MODE byte is set as :

  • 0x00 in COOLING MODE
  • 0x14 in HEATING MODE
  • 0x28 in AUTO MODE

CYCLE SELECTION is set as 0x01 when CYCLE 1 is selected, 0x02 when CYCLE 2 is selected and 0x03 when CYCLE 1 and CYCLE 2 are selected

CYCLE 2CYCLE 1
00000001
MSBLSB
Cycle 1 selection ( 0b00000001 )

After the indoor controller status update is sent the outdoor unit acknowledge the message and replies with the following:

SRCCTRLLENMSG TYPEOPCODEOPERATIONPUMP STATUSWATER SET TEMP?DHW SET TEMPPOOL SET TEMP???????????????????????????????CHECKSUM
0x120481111110xB1xxxxxxxxxxxxxx0xxxxxx00xx000xxxxxxxxxxxxxx000000xx
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

SRCCTRLLENMSG TYPEOPCODECHECKSUM
0x210112111110xB50xBD

A 0xB5 request is followed by a 0xB6 reply. While many data fields remain unknown or are likely unused, some interesting information can still be extracted.

SRCCTRLLENMSG TYPEOPCODE?WATER IN TEMPWATER OUT TEMP1EXCHANGER OUT TEMP??WATER OUT TEMP2??????????????????????TEMP GAS UITEMP LIQUID UI??TEMP AMBTEMP AMB AVG????????????????????WATER FLOWWATER SPEEDEXHAUST TEMPLIQUID EVAPORATION TEMP??????CHECKSUM
0x120761111110xB60xxxxxx129129xx12912912912920208222060508243601294500605555xxxx24129xxxxxx0003800000000001291291291290xxxxxxxx03662600xx
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576

The next request is similar to the first one but with a different opcode.

SRCCTRLLENMSG TYPEOPCODECHECKSUM
0x210112111110xB70xBF

It follows a shorter reply from the outdoor unit:

SRCCTRLLENMSG TYPEOPCODE???????????INVERTER FREQUENCY?EVOCURRENT????CHECKSUM
0x120301111110xB81718000012919131100xx0xxxx02000xx
123456789101112131415161718192021222324252627282930

This concludes the first part of the exploration into the Hisense H-NET protocol. In future articles, I’ll explore the possibility of injecting custom commands, developing a working Home Assistant integration, and reverse engineering the message exchange during the controller’s startup phase.


Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *