Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pi Monitor

A lightweight dashboard for monitoring Raspberry Pis on your network. Dark mode UI, runs in Docker.

Features

  • CPU, memory, disk, uptime, and temperature monitoring
  • Per-volume disk breakdown with labeled mount points and usage bars
  • Docker container status - auto-detected, shows running/stopped/paused with uptime and image version
  • Image update checks - the agent compares local image digests against the registry (the same check docker compose pull does) and flags containers with a newer image available
  • Software RAID status - auto-detected from /proc/mdstat, shows the [UUUU] device map per array, flags degraded arrays and missing slots, and tracks rebuild/scrub progress
  • Pi model auto-detection - reads hardware model and RAM from the Pi
  • Home Assistant support - polls the HA REST API for Pis running HAOS (no agent needed)
  • Volume labels - give friendly names to ugly mount paths in the config
  • Auto-refresh dashboard updates every 10 seconds

Architecture

  • Dashboard - Docker container running a FastAPI server with a dark-mode web UI (port 8080)
  • Agent - Tiny Python script on each Pi, exposes metrics over HTTP (port 9101). No heavy dependencies, just psutil
  • OpenWrt agent - A stdlib-only variant for routers, exposes the same metrics on port 9101 without psutil, systemd, or Docker
  • Home Assistant - For Pis running HAOS (locked-down OS), polls the HA REST API instead

Quick Start

1. Set up the agent on each normal Pi

Copy the agent/ folder to each Pi and run:

cd agent
sudo bash install.sh

This installs a systemd service that starts automatically on boot.

Verify it's working:

curl http://localhost:9101/metrics

Note: If psutil is already installed, the script skips the pip install. If the Pi has Docker, the agent auto-detects it and reports container status (the systemd service gets the docker group automatically).

About update checks: the agent checks registries in a background thread, once at startup and every 6 hours after. It only sends HEAD requests for manifest digests, so nothing is downloaded and Docker Hub does not count them against pull rate limits. Public registries (Docker Hub, ghcr.io, lscr.io, quay.io) work anonymously; private images, locally built images, and digest-pinned tags show no update indicator. The version shown is the image tag, falling back to the image's org.opencontainers.image.version label when the tag is just latest.

2. Set up the agent on OpenWrt routers

OpenWrt is a different world than a Pi: no systemd, no psutil, and flash space measured in megabytes. So there's a separate agent in agent-openwrt/ that reads everything straight from /proc and serves the same JSON on port 9101. The only thing it needs on the router is the Python interpreter.

Copy the agent-openwrt/ folder to the router (over SSH with scp) and run:

sh install.sh

The installer pulls python3-light if Python isn't already there (via apk on OpenWrt 24.10+, or opkg on older releases), drops the agent in /usr/lib/pi-monitor-agent/, and registers a procd service so it survives reboots.

It also lists the router's IP addresses and asks which one to serve on:

Which address should the agent listen on?
Pick your LAN address. Do NOT pick your WAN/internet address.
  1) 192.168.1.1 (br-lan)
  2) 203.0.113.45 (eth1)
Enter number [1]:

Pick your LAN address. The agent binds only to that address, so it is never reachable from the internet, even if your firewall is misconfigured. The choice is saved to /etc/pi-monitor-agent.conf, so it sticks across reboots. To set it without the prompt (for scripted installs), pass the IP as an argument: sh install.sh 192.168.1.1. If the address is ever left unset, the agent falls back to the LAN IP from UCI and, failing that, to loopback. It never binds 0.0.0.0.

Verify it's working:

curl http://localhost:9101/metrics

Then add the router to server/config.yaml as a normal agent host (same type: agent block as a Pi). The model auto-detects from /tmp/sysinfo/model, disk reports the writable overlay plus any USB storage, and CPU temperature shows up on hardware that has a thermal sensor (many routers don't, in which case it reads null).

Note: a firmware upgrade (sysupgrade) wipes /usr, so rerun install.sh after flashing new OpenWrt.

3. Set up the Home Assistant Pi

No agent install needed. Instead:

  1. In Home Assistant, add the System Monitor integration:

    • Settings -> Devices & Services -> Add Integration -> System Monitor
    • Enable these sensors (they may be disabled by default):
      • sensor.system_monitor_processor_use
      • sensor.system_monitor_memory_usage
      • sensor.system_monitor_disk_usage
      • sensor.system_monitor_disk_use
      • sensor.system_monitor_processor_temperature
      • sensor.system_monitor_last_boot
  2. Generate a Long-Lived Access Token:

    • Click your profile (bottom-left) -> Long-Lived Access Tokens -> Create Token
    • Copy the token
  3. Add it to server/config.yaml (see below)

Note: HA OS reports temperature in Fahrenheit - the dashboard converts to Celsius automatically.

4. Configure and run the dashboard

Edit server/config.yaml with your Pi IPs and HA token:

poll_interval: 30

# Optional: friendly names for volume mount paths
volume_labels:
  "/srv/dev-disk-by-uuid-xxxxxxxx": "NAS-Storage"

hosts:
  - name: "Pi 1"
    type: agent
    host: "192.168.1.100"
    port: 9101

  - name: "Home Assistant"
    type: homeassistant
    host: "192.168.1.102"
    port: 8123
    access_token: "YOUR_TOKEN_HERE"
    ssl: false
    model: "Pi 4 (8GB)"

Then start the dashboard:

docker compose up -d

Open http://localhost:8080 in your browser.

Changing the dashboard port

If port 8080 is already in use, change the left side of the port mapping in docker-compose.yml:

ports:
  - "9090:8080"

Updating config

The config file is mounted as a volume, so you can edit server/config.yaml without rebuilding. Changes take effect within the poll interval (30 seconds by default).

If you change the Python code or HTML, rebuild:

docker compose up -d --build

Updating the agent

After updating agent/pi_agent.py, copy it to each Pi and restart:

sudo cp pi_agent.py /opt/pi-monitor-agent/pi_agent.py
sudo systemctl restart pi-monitor-agent

Software RAID

Hosts with mdadm arrays get a RAID section automatically. The agent parses /proc/mdstat, which is world-readable, so no extra privileges or config are needed. Hosts without md arrays omit the section entirely.

Each array shows its device map the same way /proc/mdstat does:

  • [UUUU] 4/4 in green - every member present
  • [UU_U] 3/4 in red, with degraded · slot 2 missing - the position of the _ is the raid slot with no device in it
  • A yellow progress bar during recovery, resync, or reshape, with percent complete and estimated time left
  • A blue progress bar during check or repair, the monthly checkarray scrub, which is informational rather than a fault

The dashboard is a status display, not an alerting system. It shows a degraded array only while you happen to be looking at it. Pair it with mdadm --monitor (via MAILADDR or a PROGRAM hook in /etc/mdadm/mdadm.conf) so a dropped disk actively notifies you.

Monitoring the Docker host Pi

You can monitor the Pi running the dashboard itself. Install the agent on it and use the Pi's LAN IP in config.yaml (not localhost, since the dashboard runs inside Docker).

Uninstalling the agent

On each Pi:

sudo systemctl stop pi-monitor-agent
sudo systemctl disable pi-monitor-agent
sudo rm /etc/systemd/system/pi-monitor-agent.service
sudo rm -rf /opt/pi-monitor-agent

On an OpenWrt router:

/etc/init.d/pi-monitor-agent stop
/etc/init.d/pi-monitor-agent disable
rm /etc/init.d/pi-monitor-agent
rm -rf /usr/lib/pi-monitor-agent

Tech Stack

  • Dashboard: Python, FastAPI, vanilla HTML/CSS/JS
  • Agent: Python, psutil (Pi) or stdlib-only reading /proc (OpenWrt)
  • Deployment: Docker

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages