$ show raomin/ESPAltherma
ESPAtherma is an embedded firmware application (PlatformIO/Arduino) for monitoring and basic control of Daikin Altherma heat pump systems via an ESP32 or ESP8266 microcontroller. In production, it connects to the heat pump's X10A serial port, queries specific register addresses (reverse-engineered Daikin I and S protocols), converts raw bytes into human-readable values using configurable label definitions, and publishes the data over MQTT to a Home Assistant instance. It also provides Home Assistant MQTT auto-discovery for seamless integration. The architecture is a single-threaded loop: setup reads model-specific definition files and MQTT/WiFi config, then repeatedly queries registers, converts data, and publishes to MQTT. Key entry points are `src/main.cpp`, `include/comm.h` (serial query), and `include/homeassistant.cpp` (discovery payload generation). External dependencies include PubSubClient, ArduinoJSON, and board-specific libraries (M5Unified for M5Stick). The project also includes reverse-engineering scripts, serial log dumps, and a heat pump emulator, making it a hybrid of embedded application and protocol research. However, the primary usage and codebase character are that of an IoT monitoring/control application.
The LLM identified 4 files worth highlighting for reuse:
Custom `Stream` subclass that mirrors all output to both the standard serial console and an MQTT topic (`espaltherma/log`). On M5StickC hardware it also updates the display. Encapsulates the dual-output pattern cleanly and can be reused in any embedded project requiring serial+MQS logging with minimal modification.
Implements the serial query/response logic for both Daikin I and S protocols. Handles request construction, response validation via CRC-16, dynamic response length parsing (first byte indicates length), and timeout management. The protocol is well-abstracted behind `queryRegistry()` and can be adapted to other CRC-based serial protocols by replacing the CRC polynomial and byte ordering.
Generates Home Assistant MQTT auto-discovery configuration payloads as streaming JSON, sending each entity's config as a separate MQTT message. This avoids buffering large JSON payloads on memory-constrained microcontrollers. The code iterates over the `LabelDef` array and creates sensor, binary_sensor, and diagnostic entities with proper units, device class, and value templates. The pattern is reusable for any MQTT-based IoT project integrating with Home Assistant.
Defines the `LabelDef` struct that stores a register address (block, offset), data type ID, byte length, scaling factor, and human-readable label. This struct is used throughout the codebase to convert raw register bytes into meaningful values. The pattern is highly reusable for any device with a register-based protocol (Modbus, etc.) and the array-based configuration enables compile-time selection of data points. The conversion logic in `converters.h` applies scaling and formatting based on the type ID.