Heater Command (0x20)
Signal ID: 0x20 | PID: 0x20 | Direction: Master → Slave
Unified command frame controlling all heater functions: room heating, water heating, ventilation, and energy source selection.
Frame Layout
Frame: C2 2B D0 FA 09 B3 E0 0F
│ │ │ │ │ │ │ └─ Byte 7: Usually 0x0F (?)
│ │ │ │ │ │ └──── Byte 6: Always 0xE0 (?)
│ │ │ │ │ └─────── Byte 5: Vent level + energy bitmap (✓)
│ │ │ │ └────────── Byte 4: Electric power level (✓)
│ │ │ └───────────── Byte 3: Fuel control (✓)
│ │ └──────────────── Byte 2: Water temperature level (✓)
│ └─────────────────── Byte 1: Water hot flag + Room heating (✓)
└────────────────────── Byte 0: Room temperature code (✓)
✓ = Confirmed ? = Unknown/Partially known
Byte 0: Room Temperature Code
Target room temperature encoded as a single byte.
Special: 0xAA = Off (no room heating)
Formula: code = (170 + (temp_celsius - 5) * 10) & 0xFF
| Temp (°C) | Code | Temp (°C) | Code |
|---|---|---|---|
| Off | 0xAA | 18 | 0x5E |
| 5 | 0xDC | 19 | 0x68 |
| 6 | 0xE6 | 20 | 0x72 |
| 7 | 0xF0 | 21 | 0x7C |
| 8 | 0xFA | 22 | 0x86 |
| 9 | 0x04 | 23 | 0x90 |
| 10 | 0x0E | 24 | 0x9A |
| 11 | 0x18 | 25 | 0xA4 |
| 12 | 0x22 | 26 | 0xAE |
| 13 | 0x2C | 27 | 0xB8 |
| 14 | 0x36 | 28 | 0xC2 |
| 15 | 0x40 | 29 | 0xCC |
| 16 | 0x4A | 30 | 0xD6 |
| 17 | 0x54 |
Decoding Example
Code 0x86 = 134 decimal
temp = ((134 - 170) & 0xFF) / 10 + 5
= (220) / 10 + 5
= 22 + 5 - 5 = 22°C
Byte 1: Control Flags
Byte 1 uses a base value of 0xAA with only bit 0 and bit 7 being modified. Bits 1-6 are always fixed.
Bit-Level Breakdown
Byte 1: 0x2B = 0b00101011
│││││││└─ Bit 0: Room heating enable (✓)
││││││└── Bit 1: Fixed (1)
│││││└─── Bit 2: Fixed (0)
││││└──── Bit 3: Fixed (1)
│││└───── Bit 4: Fixed (0)
││└────── Bit 5: Fixed (1)
│└─────── Bit 6: Fixed (0)
└──────── Bit 7: Water hot flag (INVERTED!) (✓)
Bit 0: Heating Enable
heating_enabled = (byte1 & 0x01) != 0
| Value | Meaning |
|---|---|
0 | Room heating OFF |
1 | Room heating ON |
Bit 7: Water Temperature Level Flag
Note: This bit indicates the water temperature level, not a simple boiler on/off. It is inverted - 0 means Hot (60°C), 1 means Off or Eco (40°C).
water_hot = (byte1 & 0x80) == 0
| Value | Meaning |
|---|---|
0 | Water Hot (60°C) |
1 | Water Off or Eco (40°C) |
Observed behavior:
- Water Off: bit 7 = 1
- Water Eco (40°C): bit 7 = 1
- Water Hot (60°C): bit 7 = 0
Bits 1-6: Fixed Pattern
Bits 1-6 are always 0b010101 (inherited from base value 0xAA). They are never modified.
Common Byte 1 Values
| Value | Binary | Water Temp | Room Heating |
|---|---|---|---|
0xAA | 1010 1010 | Off/Eco | OFF |
0xAB | 1010 1011 | Off/Eco | ON |
0x2A | 0010 1010 | Hot | OFF |
0x2B | 0010 1011 | Hot | ON |
Byte 2: Water Temperature Level
Target water temperature setting.
| Value | Level | Temperature |
|---|---|---|
0xAA | Off | Water heating disabled |
0xC3 | Eco | ~40°C |
0xD0 | Hot | ~60°C |
Note: Bytes 1 and 2 work together for water temperature:
- Off: byte 2 =
0xAA, byte 1 bit 7 = 1 (0xAAor0xAB) - Eco (40°C): byte 2 =
0xC3, byte 1 bit 7 = 1 (0xAAor0xAB) - Hot (60°C): byte 2 =
0xD0, byte 1 bit 7 = 0 (0x2Aor0x2B)
Byte 3: Fuel Control
Enables or disables fuel-based heating (gas or diesel).
| Value | Meaning |
|---|---|
0x00 | Fuel disabled |
0xFA | Fuel enabled |
Byte 4: Electric Power Level
Sets the electric heating element power limit.
| Value | Power | Watts |
|---|---|---|
0x00 | Off | 0W |
0x09 | Level 1 | 900W |
0x12 | Level 2 | 1800W |
Note: Value appears to be power in 100W units (0x09 = 9 = 900W, 0x12 = 18 = 1800W).
Byte 5: Ventilation Level + Energy Bitmap
Byte 5: 0xB3 = 0b10110011
││││││││
││││││└┴─ Bits 0-1: Energy source bitmap (✓)
││││└┴─── Bits 2-3: Reserved (always 0) (✓)
└┴┴┴───── Bits 4-7: Ventilation level (✓)
Bits 0-1: Energy Source Bitmap
Mirrors the fuel and electric settings from bytes 3 and 4.
| Bits | Binary | Energy Source |
|---|---|---|
0x0 | 00 | None (off) |
0x1 | 01 | Fuel only |
0x2 | 10 | Electric only |
0x3 | 11 | Mix (fuel + electric) |
Bits 2-3: Reserved
Always 0 in all observed frames and implementations. Purpose unknown, likely reserved for future use.
Bits 4-7: Ventilation Level (Upper Nibble)
| Nibble | Level | Description |
|---|---|---|
0x0 | Off | No ventilation |
0x1 | Level 1 | Lowest manual |
0x2 | Level 2 | |
0x3 | Level 3 | |
0x4 | Level 4 | |
0x5 | Level 5 | |
0x6 | Level 6 | |
0x7 | Level 7 | |
0x8 | Level 8 | |
0x9 | Level 9 | |
0xA | Level 10 | Highest manual |
0xB | Eco | Automatic/Comfort mode |
0xC | ? | Not documented, possibly undefined |
0xD | High | High-speed/Boost mode |
Note: Manual ventilation levels (1-10) can be used when heating is off. Eco and High are typically used with active heating. Value 0xC has not been observed in any implementation.
Bytes 6-7: Constant/Unknown (Partially Confirmed)
| Byte | Value | Status |
|---|---|---|
| 6 | 0xE0 | Always constant (✓) |
| 7 | 0x0F | Usually constant, but 0x00 observed in some frames (?) |
Observations
- Byte 6 (
0xE0): Confirmed constant across all implementations and observed frames. - Byte 7 (
0x0F): Usually0x0F, but one test case intruma-drivershows0x00. This might indicate:- Device-specific variation
- Protocol version indicator
- Reserved/unused field
Example Frames
Everything Off
AA AA AA 00 00 00 E0 0F
│ │ │ │ │ │
│ │ │ │ │ └─ Vent: Off, Energy: None
│ │ │ │ └──── Electric: Off
│ │ │ └─────── Fuel: Disabled
│ │ └────────── Water: Off
│ └───────────── Flags: Boiler OFF, Heating OFF
└──────────────── Room: Off
Fuel Only, Vent Level 2
AA AA AA FA 00 21 E0 0F
│ │ │ │ │ │
│ │ │ │ │ └─ Vent: Level 2 (0x2), Energy: Fuel (0x1)
│ │ │ │ └──── Electric: Off
│ │ │ └─────── Fuel: Enabled
│ │ └────────── Water: Off
│ └───────────── Flags: Boiler OFF, Heating OFF
└──────────────── Room: Off
Room Heat 28°C, Fuel Only, Comfort Fan
C2 AB AA FA 00 B1 E0 0F
│ │ │ │ │ │
│ │ │ │ │ └─ Vent: Comfort (0xB), Energy: Fuel (0x1)
│ │ │ │ └──── Electric: Off
│ │ │ └─────── Fuel: Enabled
│ │ └────────── Water: Off
│ └───────────── Flags: Boiler OFF, Heating ON
└──────────────── Room: 28°C
Room Heat 28°C, Water Hot, Fuel Only, Comfort Fan
C2 2B D0 FA 00 B1 E0 0F
│ │ │ │ │ │
│ │ │ │ │ └─ Vent: Comfort (0xB), Energy: Fuel (0x1)
│ │ │ │ └──── Electric: Off
│ │ │ └─────── Fuel: Enabled
│ │ └────────── Water: Hot (60°C)
│ └───────────── Flags: Boiler ON, Heating ON
└──────────────── Room: 28°C
Room Heat 28°C, Water Hot, Mix Mode (900W), Comfort Fan
C2 2B D0 FA 09 B3 E0 0F
│ │ │ │ │ │
│ │ │ │ │ └─ Vent: Comfort (0xB), Energy: Mix (0x3)
│ │ │ │ └──── Electric: 900W
│ │ │ └─────── Fuel: Enabled
│ │ └────────── Water: Hot (60°C)
│ └───────────── Flags: Boiler ON, Heating ON
└──────────────── Room: 28°C
Water Boost Only (No Room Heat)
Water boost is water heating without room ventilation. The fan stays off since no warm air needs to be distributed.
AA 2A D0 FA 00 01 E0 0F
│ │ │ │ │ │
│ │ │ │ │ └─ Vent: Off (0x0), Energy: Fuel (0x1)
│ │ │ │ └──── Electric: Off
│ │ │ └─────── Fuel: Enabled
│ │ └────────── Water: Hot (60°C)
│ └───────────── Flags: Water Hot, Heating OFF
└──────────────── Room: Off
Note: Water boost is identical to water hot - the difference is that room heating is disabled, so the fan doesn’t run. This allows all heating energy to go to the water tank.
Initial Filling (Room 30°C, Fuel, Comfort)
D6 AB AA FA 00 B1 E0 0F
│ │ │ │ │ │
│ │ │ │ │ └─ Vent: Comfort (0xB), Energy: Fuel (0x1)
│ │ │ │ └──── Electric: Off
│ │ │ └─────── Fuel: Enabled
│ │ └────────── Water: Off
│ └───────────── Flags: Boiler OFF, Heating ON
└──────────────── Room: 30°C
State Dependencies
Water Boost Mode
Water boost is a display-side concept, not a separate protocol flag. It is derived from the combination of settings:
water_boost = water_temp == Hot AND NOT room_heating_enabled
When water boost is active:
- Water is heated to 60°C (Hot)
- Room heating is disabled (byte 0 =
0xAA, byte 1 bit 0 = 0) - Fan stays off (byte 5 upper nibble =
0x0) - All heating energy goes to the water tank
The heater sees the same command as “Water Hot” - the behavioral difference is that without room heating, the fan doesn’t run.
Energy Source Bitmap Calculation
The energy bitmap in byte 5 (bits 0-1) should mirror bytes 3 and 4:
bitmap = 0
if fuel_enabled:
bitmap |= 0x01
if electric_power > 0:
bitmap |= 0x02
Ventilation Modes
- Off (0x0): No ventilation - used for water-only heating
- Manual Levels (1-10): Can be used independently of heating
- Eco/Comfort (0xB): Automatic mode, typically used with active room heating
- High (0xD): High-speed ventilation
