03 · Integration
Writing for Venus OS
Conventions shared by every service in this ecosystem. Follow them and validate service discovery, numeric path types, freshness and resource use against the target firmware.
D-Bus service naming
Venus OS discovers services by their bus name. The pattern:
com.victronenergy.<type>.<suffix>
com.victronenergy.battery.jbd_mqtt # dbus-mqtt-battery
com.victronenergy.pvinverter.tasmota # dbus-tasmota-pv
com.victronenergy.grid.esphome_ct # dbus-esphome-grid-sensor
com.victronenergy.acload.emporia_vue_1 # dbus-emporia-vue, one per channel
com.victronenergy.temperature.inverter_climate_<identity> # inverter-climate
Pick <type> from what Venus OS already understands — battery,
pvinverter, grid, acload, solarcharger, temperature. A wrong
type means the GX ignores your service no matter how correct the paths are.
Paths every service should publish
| Path | Meaning |
|---|---|
| /ProductId, /ProductName | Identity shown in the device list |
| /Connected | Source availability; report 0 when required inputs are unavailable |
| /Status or /ErrorCode | Fault visibility without opening logs |
| Type-specific values | e.g. /Dc/0/Voltage, /Ac/Power, /Soc |
Native thermostat controls
inverter-climate publishes /Temperature in Celsius with /TemperatureType = 3 (room). Its identity suffix is a stable hash, and its optional /SwitchableOutput/0 temperature slider and /SwitchableOutput/1 Heat/Off selector belong to the same device. GUI v2 and VRM Remote Console use those standard controls without a GUI patch.
Manual commands are opt-in, validated against fresh HA capabilities and journaled before dispatch. The D-Bus thread only queues requests; HA I/O runs outside it. Readback reflects HA observations, and uncertain commands are not replayed after restart. See the complete D-Bus contract and installation guide.
MQTT contracts
Native Venus telemetry uses N/<portal-id>/<service>/<instance>/<path>; read requests use R/<portal-id>/.... Raw ESPHome/Tasmota sensor topics and application inverter/state use separate schemas. Use the publisher's README and a real portal ID. Do not assume a universal victron/# namespace.
Native installation contract
/data/service-name/
service/service-name/run
service/service-name/log/run
application files and local configuration
/service/service-name -> /data/service-name/service/service-name
Recreate the link from /data/rc.local before any early exit. Use svc and svstat, preserve service directory inodes on updates, and install dependencies before stopping the service. Firmware replaces rootfs files; keep persistent state under /data. See the installation guide and the service template.
D-Bus value contract
Register all required paths before publishing the service name. Publish numeric values as numbers and unavailable measurements using the standard invalid value, not fabricated zero. Apply MQTT-thread updates on the GLib loop. Prefer batched ItemsChanged signals and bounded reconnection with backoff. A /BatteryCapacity string caused the stock VRM logger to crash in the September 2026 audit.
Rules that keep the fleet debuggable
- Log to stdout/stderr — multilog writes it to the configured bounded log directory; never background yourself.
- Reconnect loops with backoff — MQTT and D-Bus drop during GX reboots; treat disconnects as normal.
- One service, one job. Translation, decision-making, and audit live in separate processes (see architecture).
- Verify control integration. No governance or event-log service was running on the audited GX. Repository availability alone does not prove that live writes are mediated or audited. Inspect the deployed controller and validate each accepted D-Bus write.
- Source availability matters. dbus-ev reads Mercedes or Home Assistant and publishes to D-Bus; its integrated charger requires the Mercedes backend. inverter-control consumes D-Bus values. Mark unavailable source data correctly during outages and consult the migration guide before replacing the archived standalone charger.
- Daemontools logging. Services like dbus-tasmota-pv use the multilog daemontools pair for log rotation; others use stdout capture. Check each repo's service/run for the pattern.