A GTK3 system-tray monitor for CPU, RAM, every GPU and disk/NAS I/O, plus a live
"Mission Control" HTML dashboard that the tray writes to ~/Desktop/DASHBOARD.html.
-
Auto-detects every GPU on the machine, any vendor, any count — no card names or indexes are hardcoded, so plugging a card in or pulling one out is picked up on the next tick without touching the code.
-
Per-vendor load sources, chosen from what the kernel/driver actually exposes:
Board Load source NVIDIA NVML ( libnvidia-ml.so.1) via ctypes; falls back tonvidia-smiAMD ( amdgpu)/sys/class/drm/cardN/device/gpu_busy_percentIntel ( xe/i915)DRM fdinfo engine counters (busy cycles vs total cycles, or busy ns) anything else fdinfo if present, otherwise the card is still listed with the stats that do exist -
Expandable dashboard cards (
<details>/<summary>): collapsed each card shows the load bar, temperature and wattage; expanded it carries every temperature sensor the driver publishes, power (and cap), fan, clocks, voltages, per-engine load and device identity. Open/closed state is kept inlocalStorage, so it survives a page refresh. -
Consistent cards: every GPU card carries the same sections and row labels, and a metric a driver does not publish says
n/arather than vanishing — the 780M has no fan sensor, so it showsFan: n/anext to cards that show a real reading. Only genuine hardware differences remain: sensor count, vendor clock names, engine counters. Vendor extras (voltage rails, Intel GT idle state, the NVIDIA thermal limits) are appended to the shared rows. -
Toolbar controls: text size (
A-/A+, 85–150 %, plusReset) and a light/dark switch. Every size in the stylesheet is in rem, so the text, the load bars and the padding scale together. The stylesheet is driven by custom properties, so a theme switch is a variable swap on<html>. -
Honest telemetry: a figure the driver does not publish is shown as
n/aand explained, never invented. Intel VRAM size is read from the Vulkan device-local heap (validated againstnvidia-smi'smemory.total); Intel VRAM usage is summed over DRM clients and labelled as such, becausexeexposes no device-wide memory counter. -
Storage cards for local disks plus
/mntand/mediamounts, with per-device read/write rates.
python3-gi,gir1.2-ayatanaappindicator3-0.1,python3-psutil- Optional:
vulkaninfo(VRAM size for boards whose driver publishes none, e.g. Intelxe),lspci(friendly card names) - A graphical session: the script needs
DISPLAY/WAYLAND_DISPLAYandDBUS_SESSION_BUS_ADDRESS.
Run it with the system python3. It needs the distro gi module, which a
project virtualenv does not have.
install -m 0755 resource_monitor.py ~/scripts/resource_monitor.py
install -m 0755 packaging/nate-systray ~/.local/bin/nate-systray
install -m 0644 packaging/nate-systray.desktop ~/.local/share/applications/
install -m 0644 packaging/nate-systray.autostart.desktop ~/.config/autostart/nate-systray.desktop
update-desktop-database ~/.local/share/applicationsThen either launch it from the app grid, run nate-systray, or let the
autostart entry bring it up at login. The tray menu has "Open Mission Control
(Web)" and "Exit Monitor".
packaging/nate-systray is a wrapper that refuses to start a second icon,
prefers the live script and falls back to the bundled binary, logs to
~/.local/state/nate-systray.log, and needs a graphical session.
python3 test_gpu_detect.pySelf-contained offline suite (no GUI interaction): card enumeration, per-vendor
load sources, the cycle-ratio and nanosecond load maths against synthetic
fixtures, Vulkan parsing (including a cross-check that the number for an NVIDIA
card equals nvidia-smi), n/a-vs-zero semantics, dashboard structure and
idempotency (no duplicated regions, stable file size), the expanded-card panel
contents, the theme/text-size controls, and per-card row/section parity.
The dashboard is a static file rewritten every 2 seconds; the browser shows
whatever it last loaded, so refresh to re-read values. Card expand state, text
size and theme all persist across refreshes where the browser allows
localStorage on file:// URLs (Firefox does), and the theme and text size are
applied by a <head> script before first paint so there is no flash of the
wrong theme.
The monitor owns the whole <style> block plus the two marked <script> blocks
and the toolbar; those are regenerated on startup, so hand edits there will be
overwritten. The card/table markup outside them is preserved.
resource_monitor.py tray app + dashboard writer
test_gpu_detect.py offline verification suite
packaging/ launcher wrapper + desktop entries
bin/resource_monitor prebuilt standalone binary (see note below)
bin/resource_monitor is a PyInstaller build and is stale — it predates the
multi-GPU work. Rebuild with pyinstaller resource_monitor.spec when a fresh
standalone binary is wanted.