# Home Assistant Integration Guide This controller presents the Ballu AC to Home Assistant as a standard Zigbee **ZCL Thermostat** device. Home Assistant talks to it through a Zigbee coordinator running either ZHA or Zigbee2MQTT — no custom integration is needed beyond the device pairing. ## 1. What the Device Exposes The firmware implements a ZCL Thermostat cluster server (`src/zigbee_zcl.c`) with these attributes: | ZCL attribute | Type | Meaning | | :-- | :-- | :-- | | `local_temperature` | int16, 0.01°C | Current indoor temperature read from the AC | | `system_mode` | uint8 | Operating mode (see mapping below) | `system_mode` values (as exposed on the Zigbee side): | Value | Mode | | :-- | :-- | | 0 | Off | | 1 | Auto | | 3 | Cool | | 4 | Heat | Internally these map to MideaUART modes via the integration layer (`integration_layer_map_zcl_to_midea_mode`); MideaUART additionally supports Dry, Fan, Sleep, and Turbo (`src/midea_protocol.h`). ## 2. Pairing 1. Put the Zigbee coordinator into permit-join mode (ZHA: *Add device*; Zigbee2MQTT: *Permit join*). 2. Power on the ESP32-C6 controller; it joins as a Zigbee end device / router. 3. The device appears with a Thermostat entity exposing current temperature and a mode selector. ## 3. Home Assistant Climate Entity Once paired, ZHA/Zigbee2MQTT automatically create a `climate.*` entity backed by the Thermostat cluster. Example resulting entity state: ```yaml climate.ballu_ac: current_temperature: 24.5 # from local_temperature (2450 * 0.01°C) hvac_mode: cool # from system_mode = 3 temperature: 25.0 # target setpoint ``` ### Setting mode and temperature (Lovelace / service call) ```yaml # Turn on cooling at 25°C service: climate.set_temperature target: entity_id: climate.ballu_ac data: hvac_mode: cool temperature: 25 ``` ```yaml # Switch to heating service: climate.set_hvac_mode target: entity_id: climate.ballu_ac data: hvac_mode: heat ``` ```yaml # Turn the unit off service: climate.set_hvac_mode target: entity_id: climate.ballu_ac data: hvac_mode: "off" ``` ## 4. Example Automations Cool the room when it gets warm: ```yaml automation: - alias: "Cool bedroom when hot" trigger: - platform: numeric_state entity_id: climate.ballu_ac attribute: current_temperature above: 27 action: - service: climate.set_temperature target: entity_id: climate.ballu_ac data: hvac_mode: cool temperature: 24 ``` Turn the AC off when everyone leaves: ```yaml automation: - alias: "AC off when away" trigger: - platform: state entity_id: group.family to: "not_home" action: - service: climate.set_hvac_mode target: entity_id: climate.ballu_ac data: hvac_mode: "off" ``` ## 5. Zigbee2MQTT Notes If using Zigbee2MQTT, the device publishes to `zigbee2mqtt/` with a JSON payload containing `local_temperature` and `system_mode`. Publish a command like: ```json { "system_mode": "cool", "occupied_heating_setpoint": 2500 } ``` Setpoints in raw ZCL are in 0.01°C units (2500 = 25.0°C), matching the firmware's temperature representation. ## 6. Status Reporting & Faults - The controller polls the AC on a configurable interval (default 5000 ms, `status_monitor_config_t.poll_interval_ms`) and updates `local_temperature` / `system_mode` accordingly. - If the AC reports a non-zero `error_code` or `alarm_mask`, the status monitor latches a fault (`status_monitor_has_fault`) and the app controller reports unhealthy (`app_controller_is_healthy`). - A communication watchdog triggers automatic reset/recovery (`app_controller_recover_if_needed`) if polling fails repeatedly. See `docs/zcl_hvac.md` for the full ZCL Thermostat cluster reference and `docs/hardware_connection_diagram.md` for wiring.