A Home Assistant integration that turns a dumb ESPHome IR sender/receiver into a
full climate entity for air conditioners of many vendors — with all protocol
encoding/decoding done in Python, on the HA side.
The ESPHome node does nothing but transmit and receive raw IR. All the intelligence (building the full-state HVAC frame, checksums, decoding captured remote signals for auto-detection) lives in a pure-Python codec library that the integration consumes.
- HA 2026.4 shipped a native
infraredplatform with an emitter/consumer split, but it currently only does TVs — no climate, no multi-vendor HVAC database, no receive API. - SmartIR (the closest existing thing) is YAML-only, lookup-table based, not on the native platform, and has no auto-detect.
- ESPHome
climate_irworks well but runs the encoder on the device (the ESP isn't dumb) and is per-brand firmware, not HA-managed.
This project fills the gap the HA infrared maintainers explicitly said they want filled:
a climate consumer on the native infrared platform, configured from the HA UI, backed
by a bundled protocol database, optionally auto-detecting the unit from the original remote.
Original AC remote ──IR──▶ ESPHome receiver ──(raw code as HA entity/event)──▶ HA
│ decode → identify (auto-detect)
HA climate card ──set state──▶ infrared_climate integration ──encode(state)──▶ raw timings
│ │
pyhvac-ir (LGPL codec) infrared emitter (ESPHome) ──IR──▶ AC
pyhvac_ir/— pure-Python, LGPL codec library (future PyPI:pyhvac-ir). Ports the protocol knowledge from IRremoteESP8266, validated by differential testing against the original as an oracle.custom_components/infrared_climate/— the Apache-2.0 HA integration (aclimateconsumer on theinfraredplatform). HACS-installable now; targeted for HA core.oracle/— host build of IRremoteESP8266 + fixture generator that produces goldenstate → raw-timingsvectors with no AC hardware required.
infrared_climate is hardware-agnostic — it drives any emitter entity on HA's infrared
platform. The recommended blaster is ESPHome, which provides native emitter/receiver entities
via ir_rf_proxy (no bridge; long frames and
36.7 kHz carriers work, and the receiver enables auto-detect). See
examples/esphome/ for a ready-to-flash config
(Nedis WIFIRC10CBK). Tasmota IR devices can also be
used but need a provider bridge (they're on MQTT, not the infrared platform).
Planning complete. Path 1 in progress (see docs/ROADMAP.md).
| Doc | Purpose |
|---|---|
| docs/PLAN.md | Master plan: goals, the two paths, decision, sequencing |
| docs/RESEARCH.md | Verified findings + sources behind every decision |
| docs/ARCHITECTURE.md | Technical architecture, codec & integration design |
| docs/ROADMAP.md | Phased work breakdown with status |
| Subtree | License | Why |
|---|---|---|
pyhvac_ir/ |
LGPL (matches IRremoteESP8266) | It's a derivative port; LGPL keeps callers free |
custom_components/infrared_climate/ |
Apache-2.0 | Required for HA core; merely uses the LGPL lib |
oracle/ (our harness) |
Apache-2.0 | Original work; vendored IRremoteESP8266 stays LGPL |
A pure-Python LGPL library consumed by an Apache integration via normal import is a "work that uses the library" — the integration is unaffected. This is the standard HA-core dependency arrangement. See docs/RESEARCH.md.