iobroker.victron-gx
v0.9.0
Published
ioBroker adapter for Victron GX devices via local MQTT and Modbus
Readme
ioBroker Victron GX Adapter
This adapter connects ioBroker directly and locally to Victron Energy GX devices (Cerbo GX, Venus GX, Ekrano GX) – without any detour through Home Assistant or the VRM Cloud.
What does this adapter do?
Connects ioBroker directly and locally to Victron GX devices via the local MQTT protocol. Supports reading all device data and full ESS/inverter control via Modbus TCP.
- All device datapoints are discovered automatically and created as ioBroker states
- Control exclusively through the
control.*channel via Modbus TCP - Works with single-phase and three-phase systems
- Automatic Modbus Unit ID discovery
- Low RAM footprint: ~130 MB stable
- Virtual devices via Node-RED (
dbus-victron-virtual) are fully supported
Requirements
On the GX device:
- Enable MQTT:
Settings → Integrations → MQTT access → On - For Modbus control:
Settings → Integrations → Modbus TCP Server → Enabled - Write access:
Access level → Write access allowed
In ioBroker:
- Node.js >= 22
- Admin >= 7.7.28
Installation
Via ioBroker Admin (recommended)
Since this adapter is not yet in the official ioBroker repository, install it via the npm tab in the Admin interface:
- Open ioBroker Admin
- Go to Adapters
- Click the GitHub/Cat icon (top right)
- Select the npm tab
- Enter
iobroker.victron-gxand click Install
After installation
- Configure the instance:
- Enter IP address of GX device
- MQTT port:
1883(default) - Optional: Enable control (activates Modbus TCP and
control.*datapoints)
Note: Node.js >= 22 is required. If your ioBroker is running on Node.js 20, please update first.
Configuration

| Field | Description | |-------|-------------| | IP address of GX device | Local IP of Cerbo/Venus/Ekrano GX | | MQTT port | Default: 1883 | | MQTT username / password | Only if MQTT auth is configured on GX | | Enable control | Activates Modbus TCP control | | Modbus port | Default: 502 |
Supported Devices
The adapter automatically discovers all devices connected to the GX device:

| Device type | Description |
|-------------|-------------|
| battery | Battery systems (e.g. SerialBattery/LLT/JBD) |
| vebus | MultiPlus/Quattro inverters |
| grid | Grid meters (e.g. Shelly 3EM, Carlo Gavazzi) |
| pvinverter | PV inverters |
| acload | AC loads (incl. Shelly 1PM, with switchable output) |
| switch | Switchable outputs (Node-RED virtual switches, Shelly Pro3/Pro4/1PM, GX internal relay) |
| temperature | Temperature sensors |
| meteo | Weather stations |
| tank | Tank level sensors |
| system | System overview |
Object Structure

victron-gx.0
├── control.* → Control via Modbus TCP
├── devices.* → All discovered devices
│ ├── battery.*
│ ├── vebus.*
│ ├── grid.*
│ ├── pvinverter.*
│ ├── acload.<Group>.<Serial>.
│ │ ├── Ac.* → measurements (unchanged)
│ │ └── outputs.<N>. → switchable output, if the device has one (e.g. Shelly 1PM)
│ │ ├── State bool, writable
│ │ ├── Status bool, read-only
│ │ ├── Name / CustomName string
│ │ └── Group string
│ ├── switch.<Group>.<Serial>.
│ │ └── outputs.<N>. → one sub-channel per output (Node-RED: one, Shelly Pro3/4: up to four)
│ │ ├── State / Status / Name / CustomName / Group (same as above)
│ ├── temperature.*
│ ├── meteo.*
│ ├── tank.*
│ └── system.* → also carries outputs.0.* for the GX internal relay
├── overview.* → System overview (from system/0), read-only
└── info.* → Connection status<Group> is an optional intermediate folder – only present if a group name is configured for that channel/device. See Shelly Integration & Multi-Channel Support below for details.
Device List (Admin)

The Devices tab shows all discovered devices with type, serial number, name and number of datapoints. The list can be downloaded as a JSON file – useful for support requests.
Topic Catalog (Admin)

The All Topics tab shows all MQTT topics that the GX device has sent since the last adapter start. Topics processed by the adapter are marked with ✓. The catalog can be downloaded as a JSON file.
Control
Virtual Switches (Node-RED)
Set State to true/false → MQTT write → GX → Node-RED → relay
ESS Grid Setpoint (simplest approach)
Write control.system.GridSetpoint [W]:
0→ zero feed-in (Victron ESS algorithm keeps grid at 0W)-3000→ feed 3000W into grid (battery discharges)+500→ draw 500W from grid (battery charges)
No keepalive needed – value is stored persistently.
ESS Live Setpoint (direct control)
Write control.inverter.AcPowerSetpoint [W]:
- Requires
control.system.EssMode = 3(External control) - The adapter resends the value every 800ms while it is ≠ 0 (Victron watchdog)
- Set to
0to return control to the Victron ESS algorithm
Disable Charge / Feed-In
control.inverter.DisableCharge = 1→ battery will not chargecontrol.inverter.DisableFeedIn = 1→ inverter will not feed into grid
DVCC Limits (requires DVCC enabled on GX)
control.system.DvccMaxChargeCurrent[A]: system-wide charge current limit (-1 = disabled)control.system.MaxDischargePower[W]: discharge power limit
Virtual Devices (Node-RED)
The adapter fully supports virtual devices created via Node-RED with the dbus-victron-virtual package:
- Virtual PV inverters
- Virtual AC loads
- Virtual switches (with group and individual name)
- Virtual temperature sensors
- Virtual weather stations
- Virtual tank sensors
Shelly Integration & Multi-Channel Support
Shelly devices connected to the GX (Cerbo/Venus/Ekrano) integration are now fully supported, alongside Node-RED virtual switches:
- Shelly Pro3 / Pro4: each physical device reports its channels as separate MQTT device instances that share the same serial number. The adapter automatically merges them into a single object tree (
devices.switch.<Group>.<Serial>.outputs.<0..3>.*). - Shelly 1PM: measurement values (
Ac.*) and the switchable output (outputs.0.*) live on the same device tree underdevices.acload.<Group>.<Serial>. - GX internal relay: the relay built into the GX device itself (
system/0) is now switchable underdevices.system.<Serial>.outputs.0.State, without any extra configuration.
All switchable outputs – regardless of device type – share the same sub-structure, so wildcard selectors work across your whole installation:
// Every switchable output, any device type, any group
'victron-gx.0.devices.*.*.*.outputs.*.State'
// Just the custom names, for a device overview
'victron-gx.0.devices.*.*.*.outputs.*.CustomName'⚠️ Breaking change (v0.9.x)
Switch outputs used to live directly under the device channel; they now live under an outputs.<N> sub-channel. Node-RED's output_1 is normalized to outputs.1:
| Old (v0.8.x) | New (v0.9.x) |
|---|---|
| devices.switch.<Group>.<Serial>.State | devices.switch.<Group>.<Serial>.outputs.1.State |
| devices.switch.<Group>.<Serial>.Status | devices.switch.<Group>.<Serial>.outputs.1.Status |
Update any scripts, Vis widgets, or Blockly rules that reference the old paths directly.
If you want to remove the leftover old objects, run this in the ioBroker CLI (the trailing loop works around the known "Invalid ID: undefined" error when deleting via the Admin UI):
iobroker object list | grep -oP 'victron-gx\.0\.devices\.switch\.[^.]+\.[^.]+\.(State|Status)$' \
| while read id; do iobroker object del "$id"; doneAuto-cleanup of orphaned channels (optional)
If you move a channel to a different group, disable a Shelly channel, or delete a Node-RED switch, its MQTT topic disappears – but the ioBroker objects stay behind. Enable Remove orphaned channels on startup (Main Settings tab, off by default) to have the adapter delete them automatically:
- Runs once per adapter start, only after ~30 seconds without a newly-discovered channel (so multi-channel devices like the Shelly Pro3, whose instances report in at slightly different times, aren't affected mid-startup).
- Only touches
outputs.<N>channels. Device-level metadata,Ac.*measurements, andoverview.*are never removed by this. - Leave it off if your devices are frequently offline – a channel that hasn't reported back yet by the time the sweep runs looks orphaned and would be deleted.
Changelog
0.9.0 (2026-07-19)
⚠️ BREAKING CHANGES
- Switch and AC-load outputs now live under
outputs.<N>.State/Statusinstead of directly at the device folder - Node-RED virtual switches: previously
.State, now.outputs.1.State - Anyone referencing these paths in Vis or scripts needs to update them
- Migration guide: see README section "Shelly integration & multi-channel support"
New: Shelly device integration
- Full multi-channel support for Shelly devices connected via Cerbo/Venus/Ekrano GX (via dbus-shelly bridge, Venus OS 3.60+)
- Tested with Shelly Plus series (Plus 1/1PM/2PM/Plug S), Shelly Plugs, Shelly Pro3 as switch, Shelly 1PM as acload
- Shelly PM devices: supported from model version 3 onward (in line with Victron's own compatibility list); older models are not supported by Victron's bridge and therefore also not reachable via this adapter
- Multi-instance merging: channels of one Shelly device are automatically merged into a single object tree via their common serial
- Shelly devices with measurement (e.g. 1PM as acload): measurement values and switchable output coexist on the same object
- GX internal relay (system/0) is now switchable as well
New: Extended AC-load datapoints
Ac.Power(total power)Ac.Energy.Reverse,Ac.L*.Energy.ReverseAc.L*.PowerFactor- Metadata:
Role,IsGenericEnergyMeter,PhaseSetting,ProductId
New: Cleanup toggle
- New option "Remove orphaned channels on startup" (default off)
- Cleans up leftover objects after group changes or channel deactivation
- Conservative: only removes objects whose serial is still active under another group (no data loss for offline devices)
- Available in all 11 UI languages
Fixes
- Object store race during parallel channel/state creation (previously caused occasional invalid-type objects invisible to the sweep)
- Group migration zombies are now removed (channel moved between groups at the GX)
- Instance tile IP address and web UI link now show the configured GX IP of the respective instance (previously showed server IP or IP from instance 0)
- Various smaller log and cosmetic fixes
0.8.10 (2026-07-04)
- Review fixes for official repository inclusion: English-only log messages, admin tabs and state labels; sanitized serial numbers in object IDs; completed news and localLinks translations; removed unused pollingInterval; docs cleanup; updated @iobroker/types to 7.2.2
0.8.9 (2026-07-02)
- chore: bump @iobroker/adapter-core to 3.4.1
0.8.8 (2026-06-14)
- Release 0.8.8
0.8.6 (2026-06-14)
- Fix: add Ac.Power to RELEVANT_PATHS for pvinverter, acload and grid devices
0.8.5 (2026-06-12)
- docs: add Ko-fi button and improved installation instructions
0.8.4 (2026-06-11)
- docs: add Ko-fi support badge
0.8.3 (2026-06-11)
- docs: improved installation instructions, added npm download badge
0.8.2 (2026-06-11)
- Fix: memory leak caused by stale device timer using native clearTimeout instead of this.clearTimeout; fix: topic catalog now only stores new topics instead of re-allocating on every MQTT message
0.8.1 (2026-06-10)
- Fix: remove invalid nodeVersion from io-package.json; add localLinks; add i18n for admin config
0.8.0 (2026-06-10)
- Topic Map and Topic Catalog as Admin tabs; dynamic device discovery without timer; Switch CustomName from Node-RED; Node.js >= 22, Admin >= 7.7.28 required
0.7.7 (2026-06-09)
- Add localLink to instance overview for direct GX access
0.7.5 – 0.7.6
- Fix: remove invalid supportedMessages from io-package.json
- Add localLink to instance overview for direct GX access
0.7.3 – 0.7.4
- Performance: static fast-path after 60s discovery reduces RAM to ~100MB stable
- Add meteo device support
- Fix temperature device (Humidity/Pressure)
- Fix CustomName for all devices
0.7.0 – 0.7.2
- Performance: state object cache reduces RAM from ~660MB to ~155MB
- Full i18n support for all state names
- Fix object structure (folder/channel hierarchy)
0.6.0
- Breaking:
ess.*renamed tocontrol.system.* control.inverter.*added- All device datapoints are strictly read-only
- AcPowerSetpoint keepalive every 800ms
0.1.0
- Complete read support for all device types
Older changelogs can be found there
License
MIT License
Copyright (c) 2026 Sefina-DS
