Venus OS service that discovers and manages Hughes Power Watchdog surge protectors via Bluetooth Low Energy.
A single-process Venus OS service that scans BLE for Power Watchdog devices and presents them as dimmable switches in the Venus OS switches pane. When a device is enabled, the service connects to it via BLE and publishes L1/L2 AC voltage, current, power, energy, and frequency to the Venus OS D-Bus.
Only one Power Watchdog device may be active at a time. Enabling a device automatically disables any previously active one. Each device's switch includes a slider to control the polling interval (100ms-10000ms).
Supports role assignment as a grid meter, generator meter, or PV inverter
meter. Settings (role, custom name, position, polling interval) are
persisted via com.victronenergy.settings and survive reboots.
Supports both 30A (single-line) and 50A (dual-line L1+L2) Power Watchdog models, including gen1 (BT-only) and gen2 (WiFi+BT) hardware.
Overview dashboard — Power Watchdog reporting as the grid meter (178W across L1+L2), with AC Loads, Essential Loads, DC Loads, battery, and inverter status all visible:
Power Watchdog device detail — per-phase AC voltage, current, power, and cumulative energy totals:
Switch panel — Discovery toggle, system setting overrides, and the per-device polling interval slider (shown at 500ms):
dbus-power-watchdog.py (single process — discovery + BLE + grid service)
├─ Registers as com.victronenergy.switch.power_watchdog
├─ Discovery toggle in Venus OS switches pane
├─ Per-device dimmable switches (on/off + polling interval slider)
├─ "Report AC Input Loads" system toggle (HasAcInLoads)
├─ "Use Inverter Metering" system toggle (RunWithoutGridMeter)
└─ When a device is enabled:
├─ Connects via bleak-connection-manager (BCM)
│ ├─ Cross-process scan locking (fcntl.flock)
│ ├─ Cache-first scanning (BlueZ D-Bus cache before StartDiscovery)
│ ├─ Pre-scan adapter health checks (detects stale BlueZ state)
│ ├─ Adapter rotation and score-based selection
│ └─ ConnectionWatchdog for dead connection detection
└─ Registers com.victronenergy.grid.power_watchdog_{mac_id}
Only one device may be active at a time. Enabling a second device
automatically disables the first. power_watchdog_device.py is retained
as a standalone fallback for manual use.
- Line 1: Voltage (V), Current (A), Power (W), Energy (kWh), Frequency (Hz)
- Line 2: Voltage (V), Current (A), Power (W), Energy (kWh), Frequency (Hz)
- Combined: Total Power (W), Total Current (A), Average Voltage (V), Total Energy (kWh)
- Error Code: 0-9 (see Hughes documentation)
Each enabled device registers as com.victronenergy.grid.power_watchdog_{mac}
(or genset/pvinverter depending on role).
| Path | Description |
|---|---|
/Role |
Current role (writable: grid, pvinverter, genset) |
/AllowedRoles |
Available roles |
/Position |
PV inverter position (writable, only used when role=pvinverter) |
/CustomName |
User-defined name (writable, persisted) |
/NrOfPhases |
Number of phases (1 or 2, auto-detected) |
/RefreshTime |
Measurement interval in milliseconds |
/Ac/L1/* |
Line 1 measurements |
/Ac/L2/* |
Line 2 measurements (50A models) |
/Ac/Power |
Total AC power (W) |
/ErrorCode |
Current error code |
The service scans BLE for two naming patterns:
| Generation | BLE Name Pattern | Example |
|---|---|---|
| Gen2 (WiFi+BT) | WD_{type}_{serial} |
WD_E7_aabbccddeeff |
| Gen1 (BT-only) | PM{S|D}... (19 chars) |
PMD... (50A), PMS... (30A) |
Scanning handles BLE InProgress errors with retry and adapter rotation.
- Venus OS >= 3.x (Cerbo GX or similar)
- Hughes Power Watchdog with Bluetooth (gen1 or gen2)
- BLE adapter available on the GX device (one or two HCI adapters)
- Python 3 (included with Venus OS)
- Git (for cloning; the installer will install it via
opkgif needed)
All BLE dependencies are vendored as git submodules in ext/ — no pip
installs or external package management required:
| Submodule | Purpose |
|---|---|
velib_python |
Victron D-Bus service helper library |
bleak |
Cross-platform BLE client library |
bleak-retry-connector |
Connection retry logic with exponential backoff |
bleak-connection-manager |
BLE connection lifecycle manager (scan locking, adapter rotation, health checks) |
bluetooth-adapters |
HCI adapter enumeration |
aiooui |
OUI (MAC vendor) lookups |
ssh root@<cerbo-ip> "curl -fsSL https://raw.githubusercontent.com/TechBlueprints/dbus-power-watchdog/main/install.sh | bash"ssh root@<cerbo-ip>
cd /data/apps
git clone --recurse-submodules https://github.com/TechBlueprints/dbus-power-watchdog.git
cd dbus-power-watchdog
bash enable.shIf you cloned without --recurse-submodules, initialize them manually:
git submodule update --init --recursive- Install the service (see above)
- Open the Venus OS Remote Console or VRM
- Navigate to Settings > I/O > Switches (or the device list)
- Find "Power Watchdog Manager" and enable Device Discovery
- Discovered Power Watchdog devices will appear as dimmable switches
- Enable a device to start reading AC data (only one may be active at a time)
- Use the slider to adjust the polling interval (100ms-10000ms)
- The device will appear as a grid meter (or genset/pvinverter after role change)
The Power Watchdog Manager pane exposes additional controls beyond the discovery toggle. Each discovered device has its own polling interval slider (see below), and two system-level toggles affect how Venus OS interprets your system topology.
Persistent setting: /Settings/Devices/power_watchdog/Device_{mac_id}/PollIntervalMs
Default: 5000ms (slider position 50)
Each discovered Power Watchdog device appears as a dimmable switch (Type 2) in the Venus OS switches pane. The switch has two controls:
- State (on/off): Enables or disables the BLE connection for this device
- Dimming (slider 1-100): Controls the polling interval
Each slider step is 100ms:
| Slider | Interval | Notes |
|---|---|---|
| 1 | 100ms | Fastest; highest BLE traffic |
| 50 | 5000ms | Default; good balance of responsiveness and efficiency |
| 100 | 10000ms | Slowest; lowest BLE overhead |
The switch name label updates in real-time to show the current interval,
e.g. WD_E7_aabbccddeeff (5000ms).
Slider changes are debounced by 5 seconds before taking effect. This prevents rapid GUI dragging from causing excessive BLE rescheduling. The interval is persisted per device and restored on reboot.
D-Bus setting: /Settings/SystemSetup/HasAcInLoads
Default: ON (1)
Tells Venus OS that there are loads wired between the grid meter and the
inverter's AC input. When enabled, dbus-systemcalc-py calculates
/Ac/ConsumptionOnInput as the difference between the grid meter reading
and the inverter AC-in reading, and publishes it separately from
/Ac/ConsumptionOnOutput.
| Setting | Cerbo GUI | VRM Portal |
|---|---|---|
| ON | Shows separate "AC Loads" (input-side) and "Essential Loads" (output-side) tiles | "AC Loads" tile shows input-side consumption instead of "-" |
| OFF | Shows a single "AC Loads" tile using total /Ac/Consumption |
"AC Loads" tile shows "-" (blank) |
Recommendation: Leave ON if you have any loads between the Power Watchdog and the inverter (e.g., shore power outlets, HVAC). Turn OFF for the simplest display if the Power Watchdog is wired directly to the inverter with nothing in between.
D-Bus setting: /Settings/CGwacs/RunWithoutGridMeter
Default: OFF (0)
Controls whether Venus OS uses the external grid meter (Power Watchdog) or the inverter's internal metering for system calculations.
| Setting | Behavior | VRM Portal |
|---|---|---|
| OFF (default) | Power Watchdog is the authoritative grid meter; system calculations use its readings | Shows "Essential Loads" / "Non-Essential Loads" layout; DC Loads tile is hidden (known VRM limitation) |
| ON | Inverter internal metering is authoritative; Power Watchdog readings are display-only | Shows standard layout with "DC Loads" tile visible; Power Watchdog data still appears but is not used for system calculations |
Recommendation: Leave OFF for accurate grid metering. Only turn ON if you specifically need DC Loads visible on the VRM portal and accept that the Power Watchdog's readings become informational rather than authoritative.
The VRM portal (vrm.victronenergy.com) is a closed-source application with
rendering logic that differs from the local Cerbo GUI and the
venus-html5-app.
When an external grid meter is active (RunWithoutGridMeter = 0), VRM uses
an ESS-style layout that:
- Hides the DC Loads tile entirely (even though
/Dc/System/Poweris correctly published on D-Bus) - Splits consumption into Essential Loads (AC output) and Non-Essential Loads (AC input) instead of showing a single AC Loads value
This is a known, long-standing VRM limitation
based on an old design assumption that systems with external grid meters
do not have DC loads. It affects all external grid meter drivers, including
Victron-maintained ones like dbus-cgwacs and dbus-shelly. We filed
venus#1590 to track
this with Victron.
The local Cerbo GUI and venus-html5-app (used on MFDs) render correctly
in all configurations -- they show DC Loads whenever /Dc/System/Power has
a value, and use /Ac/Consumption for AC Loads without the ESS split.
No D-Bus workaround exists; the fix requires a VRM portal UI change by Victron Energy.
The Power Watchdog publishes BLE error codes (0-9) to /ErrorCode on its
grid service. However, the Venus OS GUI (ListAcInError.qml) only
displays the error code row for two hard-coded product IDs:
- Fronius PV Inverter (
0xA142) — shows the raw error code number - Carlo Gavazzi Energy Meter (
0xB002) — shows a translated message
For any other ProductId, the error row is hidden entirely.
As a workaround, this service sets its /ProductId to 0xA142 (Fronius).
The Fronius code path simply displays the raw error number, which is the
correct behavior for our use case. This only affects the error display
logic in ListAcInError.qml — no other GUI components use the Fronius
product ID for conditional behavior.
We have submitted a pull request to victronenergy/gui-v2 to make error
code display generic for all energy meters:
gui-v2#2816.
Once that PR is accepted, we will switch to a dedicated product ID and
remove this workaround.
Optional: copy config.default.ini to config.ini to customize:
[DEFAULT]
scan_interval = 60
bluetooth_adapters = hci0,hci1
reconnect_delay = 10
reconnect_max_delay = 120The polling interval is configured per-device via the GUI slider (see above) and is not in the config file. All other configuration is optional. By default the service auto-detects adapters and uses sensible defaults.
svc -u /service/dbus-power-watchdog # Start
svc -d /service/dbus-power-watchdog # Stop
svc -t /service/dbus-power-watchdog # Restart
svstat /service/dbus-power-watchdog # Status
tail -f /var/log/dbus-power-watchdog/current | tai64nlocal # Logs- BLE protocol based on prior open-source work by spbrogan and tango2590
- Venus OS D-Bus integration patterns from dbus-ble-advertisements
This project includes velib_python
by Victron Energy BV, located in ext/velib_python/. It is licensed under the
MIT License:
Copyright (c) 2014 Victron Energy BV
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
The full MIT license text is available at ext/velib_python/LICENSE.
Apache License 2.0 - see LICENSE


