An ESPHome component that connects an Östberg HERU ventilation unit to Home Assistant through the unit's own wireless link. An ESP8266 with an nRF905 radio acts as a second remote control, so no Modbus card or wiring into the unit is needed.
It is tested on a HERU 100 T EC (unit firmware 3.04, remote 3.08). Other HERU units with the same wireless remote probably work too.
| Entity | Type | Notes |
|---|---|---|
| Fan level | select | Min / Standard / Medium |
| Setpoint | number | 15–30 °C |
| Boost, Away, Overpressure | switch | State follows the unit, including changes made on the remote |
| Week timer | switch | While it runs, it decides the setpoint and fan level |
| Max fan (test) | switch | The service menu's fan test run at 85/100 %; ended automatically after 30 min |
| Outdoor, supply, extract, exhaust temperature | sensor | 0.1 °C |
| Supply and extract fan | sensor | rpm and % |
| Boost and overpressure duration | sensor | From the unit's settings |
| Summer cooling, supply air limits | sensor | Learned when the remote sends them (see below) |
| Radio timeouts, radio success rate | sensor | Link health |
The unit is polled every 10 s. Replies to the real remote's own polls are picked up as well. The remote keeps working as before.
- An ESP8266 board. A NodeMCU v3 is used here.
- An nRF905 module. Most cheap ones are tuned for 433 MHz; they work at 868 MHz, but with a range of a few metres. An 868/915 MHz module gives much more range. Either way, place the ESP close to the unit and check Radio success rate.
| nRF905 | NodeMCU | |
|---|---|---|
| VCC | 3V3 | Never 5 V / VIN |
| GND | G | |
| SCK | D5 | |
| MISO | D6 | |
| MOSI | D7 | |
| CSN | D8 | |
| DR | D0 | Pull-down in the config |
| CE | D1 | |
| TXEN | D2 | |
| PWR | D3 | |
| CD, AM, uCLK | not connected |
D3 and D8 are boot-strapping pins. If the board will not boot or flash with the module attached, disconnect CSN and PWR while flashing.
- Find the IDs in the remote's service menu under Manøverenhet: one for the remote and one for the unit.
- Copy
esphome/secrets.yaml.exampletoesphome/secrets.yamland fill it in. - In
esphome/heru.yaml, setrc_idandunit_id, and rename the entities if you like. - Build and flash:
or with Docker:
cd esphome esphome run heru.yamldocker run --rm -v "$PWD:/config" ghcr.io/esphome/esphome compile heru.yaml. - Check the log.
HERU (nRF905)should show no wiring error, andRadio success rateshould be near 100 %. If the unit does not answer, trychannel: 0x76.
To use the component from another ESPHome config without copying it:
external_components:
- source: github://mathiashagen/heru-esphome@main
components: [heru]- Service settings: summer cooling and the supply air limits live in a block the unit will not return on a read. The ESP learns it whenever the remote writes it and keeps it in flash. Until then these sensors are unknown. To fill them in, change any service-menu setting on the remote and change it back.
- Setpoint on the remote display: after a setpoint change from Home Assistant, the remote keeps showing its own value. The unit uses the new one.
- Week timer: while it runs, it decides the setpoint and fan level. Turn it off to control them manually.
- Max fan: uses the service-menu fan test run. It is ended after 30 min, when the switch is turned off, or when the EC vifte oppsett pages on the remote are left. If the ESP restarts while it runs, turn the switch on and off once.
The component logs every write from the remote and every byte that changes in the unit's replies. That is how most of docs/protocol.md was mapped: change something on the remote and read the log.
For experiments, you can add these actions to api: to send raw frames from Home Assistant. write_register can
change any setting on the unit, so leave it out of normal use.
api:
actions:
- action: write_register
variables: {reg: int, data: int[]}
then:
- lambda: id(heru_unit).write_raw(reg, data);
- action: read_register
variables: {cmd: int}
then:
- lambda: id(heru_unit).read_raw(cmd);The protocol helpers are header-only and have a host test with captured frames:
g++ -std=c++17 -Wall -Wextra -I esphome/components/heru test/test_protocol.cpp -o test_protocol && ./test_protocol
CI runs the test and compiles the ESPHome config on every push.
This started from JLFN/FTX-HERU. It was an Arduino sniffer and a Modbus TCP bridge that replayed captured remote packets, and it showed that the link is an nRF905 and gave the first frames to work from. That code is not included here. The frame format, CRC and registers were worked out from those frames and from captures on a HERU 100 T EC. This project is not affiliated with Östberg.
MIT, see LICENSE.