feat(hardware): ESPHome Gree IR blaster (Wemos D1 Mini + Grove IR)
Native ESPHome gree climate component over the API, no MQTT/Broadlink/Tuya. HA on piha runs as a plain Docker container (not HAOS), so ESPHome is a manual docker compose run --rm invocation, not a managed service — device is deliberately not registered in hosts/piha/services.yaml.
This commit is contained in:
parent
4bfd6c4429
commit
423f871486
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -3,6 +3,10 @@
|
||||||
*.env
|
*.env
|
||||||
!*.env.example
|
!*.env.example
|
||||||
|
|
||||||
|
# ESPHome secrets
|
||||||
|
secrets.yaml
|
||||||
|
!secrets.yaml.example
|
||||||
|
|
||||||
# IDE artifacts
|
# IDE artifacts
|
||||||
.idea/
|
.idea/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
|
||||||
87
hardware/esp/ir-ac-ha-integration/README.md
Normal file
87
hardware/esp/ir-ac-ha-integration/README.md
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
# Gree IR Blaster
|
||||||
|
|
||||||
|
ESPHome firmware for a Wemos D1 Mini (ESP8266) driving a Gree air conditioner
|
||||||
|
over IR, exposed to Home Assistant via the native ESPHome API (no MQTT, no
|
||||||
|
Broadlink, no Tuya).
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
|
||||||
|
- Wemos D1 Mini (ESP8266)
|
||||||
|
- Grove IR Emitter
|
||||||
|
- Grove IR Receiver
|
||||||
|
|
||||||
|
### Wiring
|
||||||
|
|
||||||
|
| Grove module | Pin | Wemos D1 Mini |
|
||||||
|
|---|---|---|
|
||||||
|
| IR Emitter | SIG | D5 |
|
||||||
|
| IR Emitter | VCC | 5V |
|
||||||
|
| IR Emitter | GND | GND |
|
||||||
|
| IR Receiver | SIG | D6 |
|
||||||
|
| IR Receiver | VCC | **3V3** — not 5V, ESP8266 GPIO is not 5V-tolerant |
|
||||||
|
| IR Receiver | GND | GND |
|
||||||
|
|
||||||
|
## Home Assistant / deployment model
|
||||||
|
|
||||||
|
HA on piha runs as the `home-assistant:stable` Docker container, not HAOS, so
|
||||||
|
ESPHome is **not** installed as an add-on. It runs as a one-off container via
|
||||||
|
`docker compose run --rm` — there is no ESPHome daemon on piha. Compile/flash
|
||||||
|
is a manual, operator-triggered action; this device is intentionally **not**
|
||||||
|
registered in `hosts/piha/services.yaml`.
|
||||||
|
|
||||||
|
Once flashed, the device advertises itself via mDNS and shows up as a
|
||||||
|
discoverable ESPHome device in Home Assistant (Settings → Devices & Services
|
||||||
|
→ Add Integration → ESPHome).
|
||||||
|
|
||||||
|
## First flash (USB)
|
||||||
|
|
||||||
|
1. Copy `secrets.yaml.example` to `secrets.yaml` and fill in `wifi_ssid`,
|
||||||
|
`wifi_password`, `fallback_password`.
|
||||||
|
2. Wire the board as above and plug it into piha via USB.
|
||||||
|
3. Run:
|
||||||
|
```
|
||||||
|
./deploy.sh --usb
|
||||||
|
```
|
||||||
|
This flashes over `/dev/ttyUSB0`.
|
||||||
|
|
||||||
|
## Subsequent flashes (OTA)
|
||||||
|
|
||||||
|
Once the device is on WiFi, redeploy without `--usb`:
|
||||||
|
```
|
||||||
|
./deploy.sh
|
||||||
|
```
|
||||||
|
This runs `docker compose run --rm esphome run gree-ir-blaster.yaml`, which
|
||||||
|
flashes over the network via the ESPHome OTA protocol.
|
||||||
|
|
||||||
|
## Identifying the Gree protocol variant
|
||||||
|
|
||||||
|
The `climate: platform: gree` component needs a `model:` matching your AC's
|
||||||
|
remote protocol. `gree-ir-blaster.yaml` currently ships with `model: yan` as
|
||||||
|
a starting guess — this is **not verified** and must be confirmed against the
|
||||||
|
actual remote.
|
||||||
|
|
||||||
|
To identify the correct variant:
|
||||||
|
|
||||||
|
1. Flash the firmware and let the device boot (WiFi connected).
|
||||||
|
2. Tail the logs:
|
||||||
|
```
|
||||||
|
docker compose run --rm esphome logs gree-ir-blaster.yaml
|
||||||
|
```
|
||||||
|
3. Point the physical Gree remote at the Grove IR Receiver and press a button
|
||||||
|
(e.g. power on, or change temperature). `dump: all` on `remote_receiver`
|
||||||
|
causes ESPHome to log the raw/decoded IR data it captured.
|
||||||
|
4. Compare the decoded output against the known Gree variants supported by
|
||||||
|
ESPHome and pick the closest match:
|
||||||
|
- `generic`
|
||||||
|
- `yan`
|
||||||
|
- `yaa`
|
||||||
|
- `yac`
|
||||||
|
- `yac1fb9`
|
||||||
|
- `yx1ff`
|
||||||
|
- `yag`
|
||||||
|
5. Update `model:` in `gree-ir-blaster.yaml` to the matching variant, then
|
||||||
|
redeploy (`./deploy.sh`) and verify the AC responds correctly to commands
|
||||||
|
sent from Home Assistant (power, mode, temperature, fan speed).
|
||||||
|
|
||||||
|
If none of the variants behave correctly, capture the raw IR dumps and check
|
||||||
|
the ESPHome `gree` component issue tracker / docs for newer variants.
|
||||||
28
hardware/esp/ir-ac-ha-integration/deploy.sh
Executable file
28
hardware/esp/ir-ac-ha-integration/deploy.sh
Executable file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Manual deploy only — this device is not managed via hosts/piha/services.yaml.
|
||||||
|
# Run by hand on piha after wiring the board.
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
if [ ! -f secrets.yaml ]; then
|
||||||
|
echo "ERROR: secrets.yaml missing. Copy secrets.yaml.example to secrets.yaml and fill in wifi_ssid/wifi_password/fallback_password." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
USB=false
|
||||||
|
if [ "$1" = "--usb" ]; then
|
||||||
|
USB=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$USB" = true ]; then
|
||||||
|
if [ ! -e /dev/ttyUSB0 ]; then
|
||||||
|
echo "ERROR: /dev/ttyUSB0 not found. Plug in the board via USB for the first flash." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo ">>> First flash over USB (/dev/ttyUSB0)..."
|
||||||
|
docker compose run --rm --device /dev/ttyUSB0 esphome run gree-ir-blaster.yaml --device /dev/ttyUSB0
|
||||||
|
else
|
||||||
|
echo ">>> OTA flash over WiFi..."
|
||||||
|
docker compose run --rm esphome run gree-ir-blaster.yaml
|
||||||
|
fi
|
||||||
7
hardware/esp/ir-ac-ha-integration/docker-compose.yml
Normal file
7
hardware/esp/ir-ac-ha-integration/docker-compose.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Not a daemon — no `up -d`. ESPHome compiles/flashes and exits.
|
||||||
|
# Invoke via deploy.sh, which wraps `docker compose run --rm esphome ...`.
|
||||||
|
services:
|
||||||
|
esphome:
|
||||||
|
image: ghcr.io/esphome/esphome:stable
|
||||||
|
volumes:
|
||||||
|
- .:/config
|
||||||
31
hardware/esp/ir-ac-ha-integration/gree-ir-blaster.yaml
Normal file
31
hardware/esp/ir-ac-ha-integration/gree-ir-blaster.yaml
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
esphome:
|
||||||
|
name: gree-ir-blaster
|
||||||
|
friendly_name: Gree IR Blaster
|
||||||
|
esp8266:
|
||||||
|
board: d1_mini
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
ap:
|
||||||
|
ssid: "Gree-IR Fallback"
|
||||||
|
password: !secret fallback_password
|
||||||
|
logger:
|
||||||
|
api:
|
||||||
|
ota:
|
||||||
|
platform: esphome
|
||||||
|
remote_transmitter:
|
||||||
|
pin: D5
|
||||||
|
carrier_duty_percent: 50%
|
||||||
|
remote_receiver:
|
||||||
|
pin:
|
||||||
|
number: D6
|
||||||
|
inverted: true
|
||||||
|
mode:
|
||||||
|
input: true
|
||||||
|
pullup: true
|
||||||
|
dump: all
|
||||||
|
climate:
|
||||||
|
- platform: gree
|
||||||
|
name: "Klimatyzacja"
|
||||||
|
id: gree_ac
|
||||||
|
model: yan
|
||||||
5
hardware/esp/ir-ac-ha-integration/secrets.yaml.example
Normal file
5
hardware/esp/ir-ac-ha-integration/secrets.yaml.example
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Copy to secrets.yaml and fill in real values. secrets.yaml is gitignored —
|
||||||
|
# never commit it. Filled in manually on piha.
|
||||||
|
wifi_ssid: "your-wifi-ssid"
|
||||||
|
wifi_password: "your-wifi-password"
|
||||||
|
fallback_password: "your-fallback-ap-password"
|
||||||
Loading…
Reference in a new issue