Arduino adapter communicates with the main controller (user interface), rather than the heat pump itself. Also, the program goes to great lengths to avoid bus collision with packets sent by other devices on the bus (by the heat pump, main controller, other external controllers). Yet be aware: hic sunt leones and you are on your own. No guarantees, use this program at your own risk. Remember that you can damage or destroy your (expensive) heat pump. Be careful and watch for errors in the web interface. I also recommend reading documentation provided by the author of the library: https://github.com/Arnold-n/P1P2Serial
Arduino acts as an external controller. It waits for a handshake packet (type 0x30) from the main Daikin controller (= user interface attached at the indoor unit), replies with response (packet type 0x30), and in the next round of request-response sends new data (commands) to the main controller.
These writeable packets have a specific structure:
- Header
- 1 byte indicating direction of the communication: request from master (0x00), response from slave (0x40)
- 1 byte slave address: 0xF0, 0xF1 external controller(s)
- 1 byte packet type: the packet type indicates what kind of data is transmitted in the payload
- Payload
- 2 bytes (little endian) parameter number
- 1 or 2 bytes (little endian) parameter value
- more parameter number-value pairs can be sent until the payload is full
- payload has a fixed length, so 0xFF is used to fill the empty space
- Checksum
- 1 byte CRC checksum
The program forms the packet itself, all you need to do is send the command (via UDP) using this format:
<packet type><parameter number><parameter value>
Remember that both parameter number and value use little endian bytes order.
Here are few examples of commands you can send via UDP or Serial:
35400001
= turn DHW on
35
: packet type 0x35
4000
: parameter number 40
01
: parameter value 1
360300D601
= set DHW setpoint to 47°C
36
: packet type 0x36
0300
: parameter number 03
D601
: parameter value 01D6 HEX = 470 DEC
360800F6FF
= set LWT setpoint deviation to -1°C
36
: packet type 0x36
0800
: parameter number 03
F6FF
: parameter value FFF6 HEX = -10 DEC
The P1P2 bus is much slower than UDP or Serial, therefore incoming commands are temporarily stored in a queue (circular buffer).
Daikin P1P2 protocol payload data format for Daikin Altherma Hybrid (perhaps all EHYHB(H/X) models) and Daikin Altherma LT (perhaps all EHV(H/X) models). Big thanks go to Arnold Niessen for his development of the P1P2 adapter and the P1P2Serial library. This document is based on reverse engineering and assumptions, so there may be mistakes and misunderstandings.
This document describes payload data of few selected writeable packet types (packet types 0x35, 0x36 and 0x3A) exchanged between the main controller (requests) and the external controller (responses).
Payload of these packets has specific structure, it contains pairs of parameter number (2 bytes) + parameter value (1 or 2 bytes). Parameter numbers and values use little endian bytes order. Since the payload length is fixed, each data packet can hold only a limited number of these number-value pairs. Empty space in the payload is filled with 0xFF.
The following data types were observed in the parameter values. Little endian bytes ordering is used in multi-byte data types:
Data type | Definition |
---|---|
u8 | unsigned 8-bit integer 0 .. 255 |
s16 | signed 16-bit integer -32768..32767 |
Explanation of s16 format: a temperature of 21.5°C is represented by the value of 215 in little endian format (0xD700). A temperature of -1°C is represented by the value of -10 in little endian format (0xF6FF).
Observations show that a few hundred parameters can be exchanged via packet types 0x3X, but only some of them are writeable. The following tables summarize all known writeable parameters for Daikin Altherma LT and Altherma Hybrid:
Parameter number | Description | Data type | Byte: description |
---|---|---|---|
03 | Silent mode | u8 | 0x00: off 0x01: on |
2F | LWT control | u8 | 0x00: off 0x01: on |
31 | Room temperature control | u8 | 0x00: off 0x01: on |
3A* | Heating/cooling | u8 | 0x01: heating 0x02: cooling |
40 | DHW control | u8 | 0x00: off 0x01: on |
48 | DHW boost | u8 | 0x00: off 0x01: on |
*not working correctly, use packet type 0x3A, parameter 4E instead
All temperature values in this table are in 0.1 °C resolution.
Parameter number | Description | Data type | Byte: description |
---|---|---|---|
00 | Room temperature setpoint | s16 | |
03 | DHW setpoint | s16 | |
06* | LWT setpoint (main zone) | s16 | |
08** | LWT setpoint deviation (main zone) | s16 | |
0B* | LWT setpoint (additional zone) | s16 | |
0D** | LWT setpoint deviation (additional zone) | s16 |
*applies only in Fixed LWT mode
**applies only in Weather dep. LWT mode
Parameter number | Description | Data type | Byte: description |
---|---|---|---|
00 | 12h/24h time format | u8 | 0x00: 12h time format 0x01: 24h time format |
31 | Enable holiday ?? | u8 | ?? |
3B | Decimal delimiter | u8 | 0x00: dot 0x01: comma |
3D | Flow units | u8 | 0x00: l/min 0x01: GPM |
3F | Temperature units | u8 | 0x00: °F 0x01: °C |
40 | Energy units | u8 | 0x00: kWh 0x01: MBtu |
4B | Daylight saving time | u8 | 0x00: manual 0x01: auto |
4C | Silent mode | u8 | 0x00: auto 0x01: off 0x02: on |
4D | Silent mode level | u8 | 0x00: level 1 0x01: level 2 0x02: level 3 |
4E | Operation mode | u8 | 0x00: heating 0x01: cooling 0x02: auto |
5B | Holiday | u8 | 0x00: off 0x01: on |
5E | Space heating schedule | u8 | 0x00: Predefined 1 0x01: Predefined 2 0x02: Predefined 3 0x03: User defined 1 0x04: User defined 2 0x05: User defined 3 0x06: No schedule |
5F | Space cooling schedule | u8 | 0x00: Predefined 1 0x01: Predefined 2 0x02: Predefined 3 0x03: User defined 1 0x04: No schedule |
64 | DHW schedule | u8 | 0x00: Predefined 1 0x01: Predefined 2 0x02: Predefined 3 0x03: User defined 1 0x04: No schedule |