Home IO Control
ESPHome add-on for IO-Homecontrol devices
Loading...
Searching...
No Matches
proto_heating.h File Reference

Pure codec for the private register protocol of 2W heaters (CMD_WRITE_PRIVATE 0x20). More...

#include "proto_frame.h"
#include <cmath>
#include <cstddef>
#include <cstdint>
Include dependency graph for proto_heating.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  esphome::home_io_control::HeatingReadings
 What the hub has read from one heater so far. More...

Namespaces

namespace  esphome
namespace  esphome::home_io_control

Enumerations

enum class  esphome::home_io_control::HeatingFunction : uint8_t {
  esphome::home_io_control::POWER_ON , esphome::home_io_control::SET_TEMPERATURE , esphome::home_io_control::SET_MODE , esphome::home_io_control::SET_PRESENCE ,
  esphome::home_io_control::SET_OPEN_WINDOW_DETECTION , esphome::home_io_control::MIDNIGHT_SYNC , esphome::home_io_control::ROOM_TEMPERATURE , esphome::home_io_control::REGULATOR_STATE ,
  esphome::home_io_control::MAX_SETPOINT , esphome::home_io_control::WINDOW_OPEN , esphome::home_io_control::TOWEL_MODE , esphome::home_io_control::TEMPORARY_STATE ,
  esphome::home_io_control::WORKING_RATE , esphome::home_io_control::TEMPERATURE_IN_FORCE , esphome::home_io_control::ECO_SETBACK , esphome::home_io_control::NIGHT_LIGHT ,
  esphome::home_io_control::NIGHT_LIGHT_BRIGHTNESS
}
 Registers and functions of a 2W heater, one row of the descriptor table each. More...
enum class  esphome::home_io_control::HeatingMode : uint8_t {
  esphome::home_io_control::AUTO = 0x00 , esphome::home_io_control::MANUAL = 0x01 , esphome::home_io_control::PROG = 0x02 , esphome::home_io_control::EXTERNAL_SETPOINT = 0x03 ,
  esphome::home_io_control::OFF = 0x04
}
 Operating modes of the mode register (HeatingFunction::SET_MODE). More...
enum class  esphome::home_io_control::TowelDryerMode : uint8_t { esphome::home_io_control::OFF = 0x00 , esphome::home_io_control::AUTO = 0x01 , esphome::home_io_control::PROG = 0x02 , esphome::home_io_control::MANUAL = 0x03 }
 Modes of a towel dryer's mode register (HeatingFunction::TOWEL_MODE). More...
enum class  esphome::home_io_control::HeatingTemporaryState : uint8_t { esphome::home_io_control::NONE = 0x00 , esphome::home_io_control::BOOST = 0x01 , esphome::home_io_control::DRYING = 0x02 }
 Temporary states of a towel dryer (HeatingFunction::TEMPORARY_STATE): a timed run on top of the mode, which the mode register does not show. More...
enum class  esphome::home_io_control::HeatingRegulatorState : uint8_t { esphome::home_io_control::NONE = 0x00 , esphome::home_io_control::STANDBY = 0x01 , esphome::home_io_control::HEATING = 0x02 }
 Regulator states of the regulator register (HeatingFunction::REGULATOR_STATE). More...

Functions

const char * esphome::home_io_control::heating_function_name (HeatingFunction fn)
 Stable lowercase name for a heating function ("power_on", "set_temperature", ...).
bool esphome::home_io_control::heating_function_is_writable (HeatingFunction fn)
 Whether the register behind a function can be written.
bool esphome::home_io_control::heating_function_is_readable (HeatingFunction fn)
 Whether the register behind a function can be read.
bool esphome::home_io_control::heating_function_register (HeatingFunction fn, uint8_t &register_low)
 Low byte of the 0x01xx register behind a function.
bool esphome::home_io_control::heating_reply_echoes_register (const IoFrame &reply, uint8_t reg_hi, uint8_t reg_lo)
 Is this frame a register reply that echoes a request for this register?
size_t esphome::home_io_control::encode_heating_write (HeatingFunction fn, float value, uint8_t out[HEATING_PAYLOAD_MAX_SIZE])
 Encode a write ("set") of one register into a CMD_WRITE_PRIVATE (0x20) payload.
size_t esphome::home_io_control::encode_heating_read (HeatingFunction fn, uint8_t out[HEATING_PAYLOAD_MAX_SIZE])
 Encode a read ("get") of one register into a CMD_WRITE_PRIVATE (0x20) payload.
size_t esphome::home_io_control::encode_heating_register_read (uint8_t reg_hi, uint8_t reg_lo, uint8_t out[HEATING_PAYLOAD_MAX_SIZE])
 Encode a read ("get") of an arbitrary register into a CMD_WRITE_PRIVATE (0x20) payload.
size_t esphome::home_io_control::encode_heating_payload (HeatingFunction fn, float value, uint8_t out[HEATING_PAYLOAD_MAX_SIZE])
 Encode the function the heating_control action runs: a read for a read-only register, a write for every other.
bool esphome::home_io_control::decode_heating_reply (const IoFrame &reply, HeatingFunction fn, float &value)
 Decode the value a heater answered a register read or write with.

Variables

constexpr float esphome::home_io_control::HEATING_TEMP_MIN_C = 7.0F
 Lowest setpoint this codec will encode.
constexpr float esphome::home_io_control::HEATING_TEMP_MAX_C = 28.0F
 Highest setpoint this codec will encode.
constexpr size_t esphome::home_io_control::HEATING_PAYLOAD_MAX_SIZE = 6
 Largest payload any function produces: a set of a 16-bit value (4-byte header + 2 value bytes).
constexpr uint8_t esphome::home_io_control::HEATING_PAYLOAD_PREFIX = 0x0C
 Leading payload byte, common to every function.
constexpr uint8_t esphome::home_io_control::HEATING_REGISTER_HIGH_BYTE = 0x01
 Payload byte at index 2: the high byte of the 16-bit register number, constant 0x01.
constexpr uint8_t esphome::home_io_control::HEATING_DIRECTION_GET = 0x60
 Payload byte at index 1 of a read ("get") request.
constexpr uint8_t esphome::home_io_control::HEATING_DIRECTION_SET = 0x61
 Payload byte at index 1 of a write ("set") request.
constexpr int16_t esphome::home_io_control::HEATING_SENSOR_FAULT_RAW = -1
 Measured value in a reading when the heater reports a sensor fault (raw -1).
static constexpr float esphome::home_io_control::HEATING_TEMPERATURE_RANGE_MIN_C = -40.0F
 Default encoding range of a temperature main parameter, in degrees Celsius.
static constexpr float esphome::home_io_control::HEATING_TEMPERATURE_RANGE_MAX_C = 80.0F
 See HEATING_TEMPERATURE_RANGE_MIN_C.
constexpr uint8_t esphome::home_io_control::HEATING_NIGHT_LIGHT_BRIGHTNESS_MAX = 100
 Highest night light brightness (HeatingFunction::NIGHT_LIGHT_BRIGHTNESS): a percentage, so this value is full brightness.
constexpr size_t esphome::home_io_control::HEATING_REPLY_VALUE_OFFSET = 4
 Offset of the first value byte in a register reply: the four header bytes it echoes.
constexpr uint8_t esphome::home_io_control::HEATING_REGISTER_MODEL_NAME = 0x19
 Register 0x0119: the heater's model name, ASCII, not terminated ("ADELIS 2 DIGIT" on an Atlantic Adelis, corpus atlantic_adelis_probe_register_01_sweep).

Detailed Description

Pure codec for the private register protocol of 2W heaters (CMD_WRITE_PRIVATE 0x20).

A heater with an adjustable setpoint (node type 52, subtype 1) exposes its state as 16-bit registers 0x01xx, read with 0C 60 01 <reg> and written with 0C 61 01 <reg> <value>; the device answers with CMD_WRITE_PRIVATE_ACK (0x21) echoing the header, followed by the value. Values are little-endian. An Atlantic AGILIA IO radiator answers every read and write this way (tests/corpus/captures/exchange/atlantic_agilia_exchange_{status_read,setpoint_and_off_read_back,mode_read_back}.yaml, pinned by corpus_heating_test.cpp).

One descriptor table (HEATING_FUNCTIONS in the .cpp) lists every register this component uses: its access (read-only, read/write, write-only) and how its value is encoded. The same row drives the get payload, the set payload and the decoder of the reply, so a register is described exactly once. This module is pure: it does not touch a device record or the radio — proto_commands.h's create_write_private() frames a payload.

Confirmed on that radiator: the setpoint, mode (all four writable values), room temperature, regulator and maximum-setpoint registers. The presence register has been written and acknowledged, with no visible effect observed; the window and open-window-detection registers have only been read at rest.

An Atlantic Adelis towel dryer answers the same protocol and adds its own registers: its mode (0x0136), its temporary state (boost or drying, 0x013E), its working rate (0x0126), the temperature it holds right now (0x0137) and its eco setback (0x0104). They have been read on two units in every state (tests/corpus/captures/probe/atlantic_adelis_probe_*.yaml); writing 0x0136 and 0x013E is confirmed against the display, the others are read-only.

A Sauter Hekla heater adds a night light: on/off in register 0x0144 (01 / 00, read on a heater with the light on and off, and written as 0C 61 01 44 <value> by the heater's own Cozytouch controller) and, most likely, its brightness in 0x0142 (reads 100 with the light at full) (issue #222).

Definition in file proto_heating.h.