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

PathMeaning
/ProductId, /ProductNameIdentity shown in the device list
/ConnectedSource availability; report 0 when required inputs are unavailable
/Status or /ErrorCodeFault visibility without opening logs
Type-specific valuese.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.

Integration patterns and their deployment limitations →