# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Common Development Commands The project is plain C compiled with `gcc` and tested with the vendored Unity framework (see `Makefile`). There is no ESP-IDF dependency for the host build/test flow; the firmware entry point in `src/main.c` is excluded from test binaries via the `UNIT_TEST` define. 1. **Build (host)**: `make build` - Compiles all `src/*.c` into `build/app` 2. **Run all tests**: `make test` - Builds and runs every Unity test suite 3. **Single Test**: `make test-` - e.g. `make test-app-controller`, `make test-midea-protocol`, `make test-uart`, `make test-zigbee-zcl`, `make test-integration-layer`, `make test-status-monitor` 4. **Clean**: `make clean` - Removes `build/` and compiled test binaries 5. **Help**: `make help` - Lists all available targets > Note: `make upload`/`make debug` (flashing to real ESP32-C6 hardware) are > hardware steps performed with the ESP-IDF toolchain and are not part of the > host test flow. ## Code Architecture The system implements a layered architecture, top to bottom. Each layer is a `src/.c` + `.h` pair with a matching `test/_test.c` suite: 1. **Application Controller** (`app_controller.c/h`, entry: `main.c`) - Owns every subsystem and wires the two end-to-end data flows. - Command path: HA → Zigbee → Integration → UART → AC. - Feedback path: AC → UART → Status → Integration → Zigbee → HA. - Provides reset/recovery, health check, and the firmware service loop. 2. **Integration Layer** (`integration_layer.c/h`) - Bridges Zigbee ZCL and MideaUART: maps `system_mode` ↔ MideaUART modes, converts temperatures, enforces 50ms command spacing / rate limiting. 3. **Zigbee ZCL Cluster** (`zigbee_zcl.c/h`) - ZCL Thermostat cluster server: `local_temperature`, `system_mode`, and weekly schedule command handling. 4. **Status Monitor** (`status_monitor.c/h`) - Periodic AC status polling, ZCL attribute mapping, fault detection (`error_code` / `alarm_mask`), and the communication watchdog. 5. **MideaUART Protocol** (`midea_protocol.c/h`) - `midea_control_t` / `midea_status_t` structures and encode/decode of AC frames; timing helpers (50ms command spacing). 6. **UART Driver** (`uart_driver.c/h`) - Hardware abstraction for ESP32-C6 UART: init at 9600 baud 8N1, send/receive with timeout handling. ## Development Notes - Protocol implementation must strictly follow MideaUART specifications. - UART runs at 9600 baud 8N1; MideaUART commands are spaced at least 50ms apart (`command_spacing_ms`, default 50 in `app_controller`/`integration_layer`). - Testing should focus on edge cases for time-sensitive operations. - Tests link every `src/*.c` together, so exactly one `main()` may exist per test binary — the firmware `main()` in `src/main.c` is guarded by `#ifndef UNIT_TEST`. - MideaUART reference implementation: https://github.com/dudanov/MideaUART ## Zigbee ZCL HVAC Integration (Thermostat Cluster) ### 1. Core Zigbee Cluster Attributes - `local_temperature` (int16_t): Current measured temperature (0.01°C resolution) - `system_mode` (uint8_t): Current system mode - 0x00: Off, 0x01: Auto, 0x03: Cooling, 0x04: Heating - 0x08: Dry, 0x09: Sleep - `local_temperature_display`: Display temperature value for UI ### 2. HVAC System Types - Supports standard HVAC modes: Cooling, Heating, Heat Pump (Cooling + Heating) - Configuration constants: - `EZB_ZCL_HVAC_SYSTEM_TYPE_CONFIGURATION_COOLING_SYSTEM_STAGE = 0x03` ### 3. Temperature Control - ZCL `local_temperature` / target temperature are in 0.01°C units (int16_t). - MideaUART `target_temp` is also stored in 0.01°C units (`* 100`), so the integration layer passes the value through (see `integration_layer_convert_zcl_temperature`). - The MideaUART setter takes Celsius as a float: `midea_control_set_temperature(&control, 25.0f)` for a 25°C target. - Command structure (actual C API): ```c midea_control_t control; midea_control_init(&control); midea_control_set_mode(&control, MODE_COOL); // MideaUART cool mode midea_control_set_temperature(&control, 25.0f);// 25°C target integration_layer_send_midea_command(&layer, &control); ``` ### 4. Schedule Management - Support weekly schedule setting/clearing through Zigbee cluster commands - Convert schedule entries to MideaUART Control scheduling parameters ### 5. Status Monitoring Integration - Monitor `AlarmMask` for hardware failures - Track `ACErrorCode` for system fault detection - Implement status callbacks for UI updates ### 6. Mode Mapping (ZCL ↔ MideaUART) ZCL `system_mode` and MideaUART `midea_mode_t` use different numeric values; the integration layer translates between them (`integration_layer_map_zcl_to_midea_mode` / `integration_layer_map_midea_to_zcl_mode`): | ZCL system_mode | MideaUART midea_mode_t | | :-- | :-- | | 0 Off | MODE_OFF (0) | | 1 Auto | MODE_AUTO (3) | | 3 Cool | MODE_COOL (1) | | 4 Heat | MODE_HEAT (2) | `midea_mode_t` additionally defines MODE_DRY (4), MODE_FAN (5), MODE_SLEEP (6), MODE_TURBO (7). See `src/midea_protocol.h` for the authoritative enum. ### 7. Mapping Example (feedback path) ```c // An AC status frame decoded to midea_status_t is mapped to ZCL attributes // and pushed into the cluster for Home Assistant to read: zcl_thermostat_attrs_t attrs; status_monitor_map_to_zcl(&status, &attrs); zigbee_zcl_set_local_temperature(attrs.local_temperature); zigbee_zcl_set_system_mode(attrs.system_mode); ``` This documentation covers both the core Midea UART protocol for device communication and the Zigbee ZCL thermostat cluster integration for smart home control. ## Additional Documentation - `docs/protocol.md` — MideaUART protocol details - `docs/zcl_hvac.md` — Zigbee ZCL Thermostat cluster details - `docs/hardware_connection_diagram.md` — ESP32-C6 ↔ Ballu AC wiring diagram - `docs/home_assistant_integration.md` — Home Assistant usage examples - `docs/Hardware integration guide.md` — ESP32-C6 hardware integration (RU) - `docs/Build system details.md` — Build system and dependencies