使用说明
kpidash
A fullscreen KPI dashboard for Raspberry Pi 5, built with LVGL and Redis. Displays real-time health, telemetry, activities, repo status, and fortune messages for multiple client machines — Linux and Windows.
Note: this project is centered around building the dashboard I want; it's not a "general purpose dashboard creation tool". I had an RPi 5 and a spare 4K monitor and specific information I wanted to be able to glance at.
That said, I do think there is some goodness here for others wanting to do something similar...the decision to put a Redis server on the RPi and use that for communication is a big win for me.
Dashboard layout
┌─────────────────────────────────────────────┐
│ Client cards (health LED, CPU/RAM/disk) │
├────────────────────┬────────────────────────┤
│ Activities │ Repo Status │
├────────────────────┴────────────────────────┤
│ Fortune │
└─────────────────────────────────────────────┘
Quick start
1. Clone
git clone --recurse-submodules <repo-url>
cd kpidash
2. Cross-compile for Pi 5
# Install cross toolchain (Ubuntu/Debian)
sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu cmake pkg-config
# Sync Pi sysroot (replace rpi53 with your Pi hostname/IP)
SYSROOT=$HOME/pi5-sysroot && mkdir -p $SYSROOT
rsync -avz --rsync-path="sudo rsync" ken@rpi53:/lib/aarch64-linux-gnu $SYSROOT/lib/
rsync -avz --rsync-path="sudo rsync" ken@rpi53:/usr/lib/aarch64-linux-gnu $SYSROOT/usr/lib/
rsync -avz ken@rpi53:/usr/include $SYSROOT/usr/
# Build
cmake -B build-pi -DCMAKE_TOOLCHAIN_FILE=cmake/aarch64-toolchain.cmake
cmake --build build-pi --target kpidash -j$(nproc)
# Deploy
rsync -az build-pi/kpidash ken@rpi53:~/kpidash
3. Run on Pi 5
# DRM requires root (or video group membership); -E preserves REDISCLI_AUTH.
# On rpi53 the password comes from the host's one copy rather than your shell:
set -a; . /etc/khomelab/secrets.env; set +a # needs group khomelab
sudo -E ./kpidash
Running it by hand like this is for debugging. The installed service reads the same file itself — see ops/rpi53/dashboard/.
4. Start a client daemon (Linux or Windows)
cd clients/kpidash-client
uv sync # Python 3.13 venv, see .python-version
uv run kpidash-client daemon start
See clients/kpidash-client/README.md for config file setup.
Configuration (dashboard)
| Environment Variable | Default | Description |
|---|---|---|
KPIDASH_REDIS_HOST |
127.0.0.1 |
Redis host |
KPIDASH_REDIS_PORT |
6379 |
Redis port |
REDISCLI_AUTH |
(none) | Redis password — must be in env when using sudo -E. One copy per host in /etc/khomelab/secrets.env; the service reads it with EnvironmentFile= |
KPIDASH_DRM_DEV |
/dev/dri/card1 |
DRM device (card1 = vc4 GPU on Pi 5) |
KPIDASH_MAX_CLIENTS |
16 |
Max tracked clients |
KPIDASH_ACTIVITY_MAX |
10 |
Max activities shown |
KPIDASH_LOG_FILE |
/var/log/kpidash/kpidash.log |
Log path written to Redis |
KPIDASH_STATE_FILE |
/var/lib/kpidash/admitted |
Hosts that have published at least once, one per line. Loaded at startup so a host that is down across a restart still shows a red card instead of no card; written only when the set grows. Missing or corrupt = start empty |
KPIDASH_PRIORITY_CLIENTS |
(none) | Comma-separated hostnames; displayed first in listed order, never evicted from registry |
Native unit tests (no hardware required)
just check
Equivalent to, and the project's CI gate:
cmake -B build-tests -DTESTS_ONLY=ON
cmake --build build-tests
ctest --test-dir build-tests --output-on-failure
TESTS_ONLY=ON skips the dashboard binary and its LVGL/DRM dependencies, so
this needs no Pi, no sysroot and no submodule checkout.
Python clients
| Package | Purpose | Docs |
|---|---|---|
clients/kpidash-client |
Telemetry daemon + CLI (Linux, Windows) | README |
clients/kpidash-mcp |
MCP server for AI agent activity reporting | README |
Both packages are managed with uv and pinned to Python 3.13.
Project structure
kpidash/
├── CMakeLists.txt # CMake 3.22+, hiredis, cJSON, libdrm, LVGL
├── lv_conf.h # LVGL configuration
├── cmake/
│ └── aarch64-toolchain.cmake # Cross-compile toolchain for Pi 5
├── fonts/
│ ├── generate.sh # lv_font_conv: Montserrat Bold 14-48px + NF icons
│ ├── lv_font_custom.h # Extern declarations for generated bold fonts
│ ├── lv_font_montserrat_bold_*.c # Generated font sources (7 sizes)
│ └── ttf/ # Source TTF files (Montserrat-Bold, SymbolsNerdFont)
├── src/
│ ├── main.c # Entry: config, LVGL init, DRM, poll timers
│ ├── config.{h,c} # Environment variable parsing
│ ├── registry.{h,c} # In-memory client state (mutex-protected)
│ ├── redis.{h,c} # hiredis poll cycle + cJSON parsing
│ ├── status.{h,c} # Status message FIFO queue
│ ├── fortune.{h,c} # fortune popen + pushed-fortune override
│ ├── ui.{h,c} # Screen layout + Redis error overlay
│ ├── protocol.h # Redis key macros + compile-time constants
│ └── widgets/
│ ├── client_card.{h,c} # Per-client arc gauge card (CPU/RAM/GPU/disks)
│ ├── activities.{h,c} # Activity table with live elapsed timers
│ ├── repo_status.{h,c} # Repo card grid (branch/dirty/age indicators)
│ ├── fortune.{h,c} # Fortune text label
│ ├── status_bar.{h,c} # Bottom status bar
│ ├── dev_grid.{h,c} # Pixel grid overlay (dev command)
│ ├── dev_textsize.{h,c} # Font size reference panel (dev command)
│ └── dev_graph.{h,c} # 5-series time-series chart (dev command)
├── tests/
│ ├── test_config.c # ctest: config env-var parsing
│ └── test_redis_json.c # ctest: Redis JSON parsing helpers
├── clients/
│ ├── kpidash-client/ # Python 3.13 daemon + CLI
│ └── kpidash-mcp/ # Python 3.13 MCP server
├── scripts/
│ └── load_test.py # 8-client concurrent write stress test
├── lib/
│ └── lvgl/ # LVGL v9.2.2 (git submodule)
├── sprints/ # One record per PR-sized unit of work
│ ├── 001-mvp-dashboard/ # Early sprints: spec, plan, tasks, contracts
│ ├── 013-service-card-polish.md # Later sprints: one narrative file
│ └── planning/roadmap.md # Now / Next / Later
└── docs/
├── ARCHITECTURE.md # System design and component diagram
├── CLIENT-PROTOCOL.md # Redis key/value schema reference
└── HANDOFF-CROSSCOMPILE.md # Cross-compilation guide
Requirements
- Pi 5: Debian 13 (Trixie), Redis 7.x,
fortunepackage - Pi packages:
libdrm-dev libpng-dev libcjson-dev libhiredis-dev libfreetype-dev libinput-dev libxkbcommon-dev redis-server fortune - Cross-compile host: Ubuntu 22.04+ x86_64, GCC aarch64 toolchain, CMake 3.22+
- Python clients: Python 3.13 via uv
