homebridge-ducobox-energy-comfort
v0.1.0
Published
Homebridge plugin for DUCO Energy Comfort ventilation systems via Modbus TCP
Maintainers
Readme
homebridge-ducobox-energy-comfort
Homebridge plugin for DUCO Energy Comfort ventilation systems via Modbus TCP.
Connects to a DucoBox Energy Comfort unit through the DUCO Connectivity Board and exposes ventilation controls, temperature sensors, air quality data, and more to Apple HomeKit.
Features
- Ventilation control -- Auto, Not at Home, Manual (3 levels), Permanent (3 levels) as separate HomeKit services
- 4 temperature sensors -- Outdoor Air (ODA), Supply Air (SUP), Extract Air (ETA), Exhaust Air (EHA)
- Humidity sensor -- Relative humidity from the box sensor
- CO2 sensor -- CO2 level with configurable alert threshold
- Air quality sensor -- Derived from both RH-based and CO2-based quality (worst of both)
- Filter maintenance -- Filter status and remaining life percentage
- Auto-discovered node accessories -- Room sensors, control valves, and other DUCO network components each appear as separate HomeKit accessories
- Weather station support -- Outdoor temperature and rain detection (as contact sensor)
Requirements
- Node.js ^20.18.0 or ^22.10.0
- Homebridge ^1.8.0 or ^2.0.0-beta.0
- DucoBox Energy Comfort with a DUCO Connectivity Board (Modbus TCP enabled on port 502)
Installation
Via Homebridge UI
Search for homebridge-ducobox-energy-comfort in the Homebridge UI plugin search.
Via command line
npm install -g homebridge-ducobox-energy-comfortInstall from source on a Raspberry Pi
To install an unreleased or modified version of this plugin on a Raspberry Pi running Homebridge:
# On the Raspberry Pi
git clone https://github.com/wavermeulen/homebridge-ducobox-energy-comfort.git
cd homebridge-ducobox-energy-comfort
npm install
npm run build
# Install into Homebridge's global plugin directory
sudo npm install -g .After installation, restart Homebridge:
sudo systemctl restart homebridgeTo update after pulling new changes:
cd homebridge-ducobox-energy-comfort
git pull
npm install
npm run build
sudo npm install -g .
sudo systemctl restart homebridgeTo uninstall:
sudo npm uninstall -g homebridge-ducobox-energy-comfort
sudo systemctl restart homebridgeConfiguration
Add the platform to your Homebridge config.json:
{
"platforms": [
{
"platform": "DucoBoxEnergyComfort",
"name": "DucoBox Energy Comfort",
"host": "192.168.1.100",
"port": 502,
"slaveId": 1,
"pollInterval": 10,
"registerOffset": 0,
"co2Threshold": 1000,
"filterLifeDays": 365,
"excludeNodes": []
}
]
}Configuration options
| Option | Required | Default | Description |
|--------|----------|---------|-------------|
| host | Yes | -- | IP address of the DUCO Connectivity Board |
| port | No | 502 | Modbus TCP port |
| slaveId | No | 1 | Modbus slave address (1-247) |
| pollInterval | No | 10 | Polling interval in seconds (minimum 5) |
| registerOffset | No | 0 | Modbus address offset. Set to 1 if the plugin reads incorrect values (see Register Offset) |
| co2Threshold | No | 1000 | CO2 level (ppm) above which the sensor triggers an alert |
| filterLifeDays | No | 365 | Total expected filter life in days, used to calculate the filter life percentage |
| excludeNodes | No | [] | Array of node numbers (1-143) to exclude from auto-discovery |
Local Development Setup
Prerequisites
node --version # Must be ^20.18.0 or ^22.10.0
npm --version # Comes with Node.js1. Clone and build
git clone https://github.com/wavermeulen/homebridge-ducobox-energy-comfort.git
cd homebridge-ducobox-energy-comfort
npm install
npm run build
npm run lint
npm test2. Install Homebridge for development
If you don't have Homebridge installed globally:
npm install -g homebridge3. Create a development Homebridge config
Create ~/.homebridge/config.json:
{
"bridge": {
"name": "Homebridge Dev",
"username": "CC:22:3D:E3:CE:30",
"port": 51826,
"pin": "031-45-154"
},
"platforms": [
{
"platform": "DucoBoxEnergyComfort",
"name": "DucoBox Energy Comfort",
"host": "192.168.1.100",
"port": 502
}
]
}Replace 192.168.1.100 with your DucoBox's actual IP, or 127.0.0.1 if using the Modbus simulator (see below).
4. Link the plugin
Option A -- Using npm link:
# In the plugin directory
npm run build
npm link
# Then link it into Homebridge's global modules
npm link homebridge-ducobox-energy-comfortOption B -- Using Homebridge's -P flag (recommended for development):
No linking needed. Just point Homebridge at the plugin directory:
homebridge -D -P /path/to/homebridge-ducobox-energy-comfort5. Start Homebridge
# With -P flag (loads plugin from path, no npm link needed)
homebridge -D -P /path/to/homebridge-ducobox-energy-comfort
# Or if using npm link
homebridge -DThe -D flag enables debug logging, which shows Modbus register reads and all characteristic updates.
6. Development workflow
Run the TypeScript compiler in watch mode in one terminal:
npm run watchThen restart Homebridge after each rebuild to pick up changes. When using the -P flag, Homebridge loads from dist/ directly, so a rebuild + restart is all you need.
7. Testing without hardware -- Modbus TCP simulator
If you don't have a physical DucoBox, you can run a Modbus TCP simulator that serves fake register values. The project's modbus-serial dependency includes a ServerTCP class for this.
Create a file called simulator.mjs in the project root:
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const ModbusRTU = require('modbus-serial');
const vector = {
getInputRegister: (addr) => {
const values = {
// Node presence: node 1 is present (bit 0)
0x0000: 0x0001,
// System temperatures (value / 10 = degrees C)
0x0020: 85, // ODA: 8.5 C
0x0021: 210, // SUP: 21.0 C
0x0022: 225, // ETA: 22.5 C
0x0023: 95, // EHA: 9.5 C
// API version and remaining writes
0x0030: 250, // API v2.5
0x0031: 195, // 195 writes remaining
// DucoBox parameters
0x0100: 17, // System type: DucoBox
0x0103: 75, // Flow rate: 75%
0x0104: 85, // Air quality RH: 85% (good)
0x0105: 70, // Air quality CO2: 70% (temporarily acceptable)
0x0106: 0, // Ventilation status: OK
0x0107: 280, // Filter remaining: 280 days
0x0108: 0, // Filter status: OK
0x0109: 52, // Humidity: 52%
0x0110: 850, // CO2: 850 ppm
// Node 1 parameters (humidity room sensor)
0x0100: 17, // (box system type, shared address space)
0x0109: 52, // (box humidity, shared address space)
};
return values[addr] ?? 0;
},
getHoldingRegister: (addr) => {
const values = {
0x0100: 0, // Ventilation mode: AUTO
};
return values[addr] ?? 0;
},
setRegister: (addr, value) => {
console.log(`Write holding register ${addr.toString(16).padStart(4, '0')} = ${value}`);
},
};
const server = new ModbusRTU.ServerTCP(vector, {
host: '0.0.0.0',
port: 502,
unitID: 1,
});
server.on('socketError', (err) => console.error('Socket error:', err));
console.log('Modbus TCP simulator running on port 502');
console.log('Press Ctrl+C to stop');Run the simulator (requires root/sudo for port 502):
sudo node simulator.mjsOr use a non-privileged port (e.g., 5020) and set "port": 5020 in your Homebridge config:
# Edit the simulator to use port 5020, then:
node simulator.mjsThen start Homebridge pointing at 127.0.0.1:
homebridge -D -P /path/to/homebridge-ducobox-energy-comfortRunning tests
npm test # Run all tests once
npm run test:watch # Run tests in watch mode (re-runs on file changes)Register Offset
Some DUCO Modbus implementations use a register address offset of 1 compared to the documentation. If the plugin connects but reads incorrect or zero values, try setting "registerOffset": 1 in your config.
This can also be configured via the DUCO Installation App, the Duco Network Tool, or the DucoBox display menu under CONFIG > Modbus > RegOffs.
HomeKit Services Reference
Main DucoBox accessory
| Service | Type | Description | |---------|------|-------------| | Auto | Switch | Toggle automatic ventilation mode | | Not at Home | Switch | Toggle not-at-home (reduced) ventilation mode | | Manual | Fan | Manual ventilation at 3 speed levels (33/67/100%) | | Permanent | Fan | Permanent ventilation at 3 speed levels (33/67/100%) | | Outdoor Air | Temperature Sensor | Air temperature entering the unit from outside | | Supply Air | Temperature Sensor | Air temperature supplied to the home | | Extract Air | Temperature Sensor | Air temperature extracted from the home | | Exhaust Air | Temperature Sensor | Air temperature exhausted to outside | | Humidity | Humidity Sensor | Relative humidity measured by the box sensor | | CO2 | Carbon Dioxide Sensor | CO2 level with configurable alert threshold | | Air Quality | Air Quality Sensor | Combined RH and CO2 air quality assessment | | Filter | Filter Maintenance | Filter status and remaining life percentage |
Per-node accessories (auto-discovered)
Nodes on the DUCO network (room sensors, control valves, etc.) are automatically discovered and appear as separate accessories with services appropriate to their type.
Troubleshooting
"Failed to connect to DucoBox" / ECONNREFUSED
- Verify the DucoBox IP address is correct and reachable (
ping 192.168.1.100) - Ensure Modbus TCP is enabled on the DUCO Connectivity Board (port 502)
- Check that no firewall is blocking TCP port 502
Sensors show 0 or incorrect values
- Try setting
"registerOffset": 1in your config - Verify the Modbus address is correct in the DUCO Installation App or Network Tool
"Write throttled" / "Daily write limit reached"
- The DucoBox limits writes to 200 per day per zone, with a minimum of 2 seconds between writes
- The plugin enforces these limits and logs warnings when throttled
- Check register 0031 for the remaining write count (visible in debug logs)
Node accessories not appearing
- Ensure nodes are properly commissioned in the DUCO network
- Check Homebridge debug logs for "Discovered N nodes" messages
- Verify the node number is not in the
excludeNodesconfig array
License
Apache-2.0
