ESPHome has a new duco component for Duco heat recovery ventilation units. It was merged into the development branch on 23 October 2026 together with its documentation, so it should ship in ESPHome 2026.11. Pieter Kokx opened the pull request in December 2024, and it took almost two years and a rewrite to current ESPHome conventions before it went in.

The component talks to the box over UART using the same protocol as Duco's own Connectivity Board, so the board is not needed. It was developed and tested on a DucoBox Energy Comfort D325. The documentation says users report it working on other DucoBox Energy and Focus models and on the DucoBox Silent 2.0, but it may not work on every Duco system.

Wiring

The D325 has a 12-pin connector on its main board. Pin 8 (the box's RX) goes to the TX pin of the ESP board, pin 9 (the box's TX) goes to RX, and the grounds are joined. The UART runs at 57600 baud, 8N1, and ESPHome now checks those settings when it validates the config.

The connector also supplies 3.3 V and 5 V, enough to power the ESP board. The documentation warns against plugging in USB while the board is powered from the box: on many boards that ties the USB supply to the box's supply. Disconnect the 3.3 V or 5 V wire before flashing over USB and leave the ground connected.

What you can control and read

  • A select sets the ventilation mode: automatic, manual levels 1-3 for 15, 30 or 45 minutes, levels 1-3 until changed, and a low "house empty" mode.
  • A number sets the comfort temperature from 10.0 to 25.5 °C in 0.1 °C steps.
  • Sensors report the flow level, the time left in the current mode, the remaining filter time, the bypass and the box's four air temperatures (outdoor, supply, indoor exhaust and outdoor exhaust).
  • CO2, humidity and temperature come from Duco's own room sensors attached to the box, each read by its node address.

To find those addresses, discovery: {} asks each address in turn, starting 16 seconds after boot, and lists the nodes it found in the config dump after about two minutes. The component can also set the box's clock from an ESPHome time source every 15 minutes by default. The documentation has a warning here: the remaining filter time is computed from that clock, so setting it to a time in the past lowers the remaining filter time.

Leaner than the first version

The update before merging replaced eight sensor classes with one table-driven sensor and dropped per-message heap allocation. For the test config, that saved about 400-470 bytes of static RAM and about 8 KB of flash on both ESP8266 and ESP32. An integration test now runs the component against a simulated Duco box. A request that gets no answer sets a warning on the component until the node answers again, and an unknown mode is logged instead of being shown as automatic.

Since the box is controlled directly over a wire, nothing here depends on Duco's cloud or app. Anyone who already wired in an early version of this code as an external component should note that the send_wait_time option is gone; it never did anything.