|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Custom Home Assistant integration for controlling Gree-compatible air conditioners over the local network via UDP (port 7000). Distributed through HACS. Domain: `gree`, version 3.3.2. |
| 8 | + |
| 9 | +**Dependencies**: `pycryptodome` (AES encryption), `aiofiles` (async file I/O) |
| 10 | + |
| 11 | +## Development Notes |
| 12 | + |
| 13 | +- **No build system, test suite, or linting configuration exists.** There is no setup.py, pyproject.toml, pytest, flake8, or similar tooling. |
| 14 | +- All code lives under `custom_components/gree/`. There are no other source directories. |
| 15 | +- To test changes, copy `custom_components/gree/` into a Home Assistant installation's `custom_components/` directory and restart HA. |
| 16 | + |
| 17 | +## Architecture |
| 18 | + |
| 19 | +### Data Flow |
| 20 | + |
| 21 | +``` |
| 22 | +HA UI action → Entity method → GreeClimate.SendStateToAc() |
| 23 | + → AES encrypt → UDP packet to device:7000 → device response |
| 24 | + → AES decrypt → update _acOptions dict → update HA entity state |
| 25 | +
|
| 26 | +Polling: every 60s via async_update() → GreeGetValues() |
| 27 | +``` |
| 28 | + |
| 29 | +### Key Files |
| 30 | + |
| 31 | +| File | Purpose | |
| 32 | +|---|---| |
| 33 | +| `__init__.py` | Integration setup, YAML config schema, platform forwarding (climate/switch/number/select/sensor) | |
| 34 | +| `climate.py` | **Core file (912 lines)**. `GreeClimate(ClimateEntity)` — HVAC control, state polling, temperature handling, all AC commands | |
| 35 | +| `gree_protocol.py` | UDP communication, AES encryption (v1=ECB, v2=GCM), device discovery, key negotiation, retry logic (8 attempts with backoff) | |
| 36 | +| `config_flow.py` | UI config flow: discovery → encryption detection → device setup. Also handles options flow for runtime reconfiguration | |
| 37 | +| `const.py` | Protocol constants, mode mappings (Gree protocol values ↔ HA values), config option keys | |
| 38 | +| `helpers.py` | Temperature math: 0.5°C precision encoding (SetTem/TemRec), °F↔°C conversion, ±40°C sensor offset auto-detection (`TempOffsetResolver`) | |
| 39 | +| `entity.py` | `GreeEntity` base class, `GreeEntityDescription` dataclass | |
| 40 | +| `switch.py` | 12 toggle entities (x-fan, lights, health, sleep, power save, etc.) | |
| 41 | +| `sensor.py` | Outside temperature and room humidity sensors | |
| 42 | +| `number.py` | Target temperature step configuration entity | |
| 43 | +| `select.py` | External temperature sensor selection entity | |
| 44 | + |
| 45 | +### Encryption Protocol |
| 46 | + |
| 47 | +Two encryption versions exist: |
| 48 | +- **v1**: AES-128 ECB with generic key `a3K8Bx%2r8Y7#xDh` |
| 49 | +- **v2**: AES-128 GCM with device-specific key, fixed IV and AAD |
| 50 | + |
| 51 | +Encryption version is auto-detected during setup. The device key is retrieved via a handshake in `GetDeviceKey()`/`GetDeviceKeyGCM()`. |
| 52 | + |
| 53 | +### Temperature Handling |
| 54 | + |
| 55 | +The AC uses integer `SetTem` plus a `TemRec` bit for 0.5°C precision. Some devices report sensor temps with a +40°C offset. `TempOffsetResolver` auto-detects which mode the device uses based on observed temperature history. Fahrenheit support uses custom conversion functions (not simple formulas) due to protocol quirks. |
| 56 | + |
| 57 | +### Device State |
| 58 | + |
| 59 | +`GreeClimate._acOptions` dict tracks 19+ device properties: `Pow`, `Mod`, `SetTem`, `WdSpd`, `Air`, `Blo`, `Health`, `SwhSlp`, `Lig`, `SwUpDn`, `SwingLfRig`, `Quiet`, `Tur`, `StHt`, `TemUn`, `HeatCoolType`, `TemRec`, `SvSt`, `SlpMod`, and optionally `AntiDirectBlow`, `LigSen`, `OutEnvTem`, `TemSen`, `Buzzer_ON_OFF`. |
| 60 | + |
| 61 | +### Configuration |
| 62 | + |
| 63 | +Two config methods: UI config flow (recommended, with auto-discovery) and YAML import. See `manual-configuration.yaml` for YAML reference. Options flow allows runtime changes to available modes and sensor offset. |
| 64 | + |
| 65 | +### VRF Support |
| 66 | + |
| 67 | +VRF (Variable Refrigerant Flow) sub-units are addressed via MAC format `subMAC@mainMAC` and discovered through `get_subunits_list()`. |
0 commit comments