# 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/<friendly_name>` 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.
