Skip to content

MQTT Integration

Damien edited this page Oct 18, 2026 · 1 revision

📡 MQTT Integration

WattSeal can publish live sensor data to any MQTT broker, alongside or instead of the local database.

WattSeal --mqtt-addr <broker-ip>:<port>

Flags: --mqtt-id, --mqtt-unit, --mqtt-processes, --mqtt-user, --mqtt-pass, --mqtt-tls. See CLI Reference.

Topic root

The root you set with --mqtt-id (default wattseal_collector) always gets a machine ID appended, so multiple PCs can publish to the same broker without colliding: <mqtt-id>_<machine-id>.

All topics below are prefixed with this root, shown as <id>.

Topics

Topic Content Retained QoS
<id>/status online / offline (birth message / last will) ✅ 1
<id>/hardware_info Static hardware inventory, published once at startup ✅ 1
<id>/sensor_data/cpu CPU reading ❌ 0
<id>/sensor_data/ram RAM reading ❌ 0
<id>/sensor_data/disk Disk reading ❌ 0
<id>/sensor_data/network Network reading ❌ 0
<id>/sensor_data/total Aggregate system energy ❌ 0
<id>/sensor_data/processes Top-N processes, array ❌ 0
<id>/sensor_data/<gpu-name> One topic per GPU, named after the device (e.g. nvidia_geforce_rtx_3070__0), not a generic gpu topic ❌ 0

Sensor data publishes every second, at QoS 0, not retained.

Payload shape

Each message nests the sensor's own fields under its variant name, alongside a top-level total_energy that's cumulative since the collector started for each sensor. In the sensor fields, disk and network metrics are cumulative too but energy there is the delta since the last tick. The cumulative fields allow to reconstruct the total energy consumed over time, even if the collector restarts or the broker loses messages.

{
  "timestamp_ms": 1732000000000,
  "total_energy": 48231100,
  "CPU": {
    "total_energy": 4823110,
    "pp0_energy": 2100450,
    "pp1_energy": null,
    "dram_energy": null,
    "usage_percent": 23.4
  }
}

total_energy at the top level = running sum. CPU.total_energy = this tick's delta. Same pattern for GPU, Ram, Disk, Network, Total.

On the disk and network topics, read_bytes / written_bytes and downloaded_bytes / uploaded_bytes inside the nested object are also cumulative, same reasoning, so they work as HA total_increasing sensors directly.

The processes topic has no total_energy field (processes aren't individually summed) and nests an array:

{ "timestamp_ms": 1732000000000, "Processes": [ { "process_energy": 410233, "measured": { "app_name": "chrome", "process_cpu_usage": 12.1, "...": "..." } } ] }

Missing values are null, never omitted, so the schema per topic stays stable.

Units

Raw microjoules by default. --mqtt-unit wh converts every energy field (components and processes) to watt-hours before publishing.

Process publishing

--mqtt-processes capped:N (default capped:10) publishes the top N processes by energy. --mqtt-processes off disables the topic entirely.

Broker

Any standard broker works: Mosquitto, EMQX, Home Assistant's built-in broker. Auth via --mqtt-user/--mqtt-pass, TLS via --mqtt-tls.

Next: Home Assistant Integration.

Clone this wiki locally