Update README for v0.0.2 (touch-bar navigation)
Rewrites the README to match the navigation redesign in the last commit: - Status section reflects the touch-bar/scroll-section layout, replacing the outdated tab-based description - New Design Notes explain *why* navigation changed — untested touch-swipe fidelity on this hardware, and accessibility reasoning for the intended client base (small factories; many users may not have a full set of fingers/thumbs on either hand). Resistive touch and oversized, forgiving touch zones are framed as a deliberate choice, not a workaround, so the reasoning doesn't have to be reconstructed from memory later. - Known Issues trimmed to what's actually still open — the fixed items from the v0.0.1 review (unused import, dead sparkline, missing threshold colouring, stale class name) are removed; the Screen vs. Container note is reframed as intentional design, not a leftover - Roadmap updated with the touch-controller HID check (lsusb/dmesg/evtest) flagged during hardware research — some earlier Waveshare display revisions need a non-standard driver
This commit is contained in:
parent
4f8c4fa4b0
commit
45f63962f4
1 changed files with 122 additions and 68 deletions
212
README.md
212
README.md
|
|
@ -1,99 +1,153 @@
|
||||||
# server-monitor-dash
|
# server-monitor-dash
|
||||||
|
|
||||||
A case-mounted touchscreen monitoring dashboard for self-hosted AI/inference
|
A case-mounted touchscreen monitoring dashboard for Cervello Elettrico
|
||||||
servers, built with [Textual](https://textual.textualize.io/). CPU, GPU, and
|
servers — CPU, GPU, and memory telemetry rendered "supercar dash" style,
|
||||||
memory telemetry rendered "supercar dash" style — dense, glanceable, colour
|
built in Python with [Textual](https://github.com/Textualize/textual).
|
||||||
thresholded — rather than a plain systems-monitoring readout.
|
|
||||||
|
|
||||||
Runs directly under a TTY autologin session. No X, no display server, and no
|
|
||||||
GPU vendor lock-in for the interface itself (though GPU telemetry currently
|
|
||||||
assumes `nvidia-smi` — see **Status** below).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Why
|
## Status: v0.0.2 — functional dashboard, navigation redesigned
|
||||||
|
|
||||||
Most server monitoring tools are built for a terminal you're SSH'd into, not
|
The Dashboard section is fully functional — live per-core CPU, memory,
|
||||||
a small screen physically mounted in a case that someone actually looks at.
|
and GPU telemetry, refreshed once per second, with threshold-driven
|
||||||
This project is the opposite bet: build something that's genuinely nice to
|
colour (green → amber → red) applied consistently across every gauge.
|
||||||
glance at from across a room, on a 5" panel, on hardware that's otherwise
|
The **Request Assistance** and **Switch to X** sections are stubs,
|
||||||
running unattended.
|
wired for later completion.
|
||||||
|
|
||||||
## Features
|
Navigation moved from tabs to a fixed touch-bar sidebar with up/down
|
||||||
|
buttons controlling a scrollable stack of full-screen sections — see
|
||||||
|
Design Notes below for why.
|
||||||
|
|
||||||
- **Live telemetry**: per-core CPU utilization, memory usage, GPU
|
This is not yet a CE OS-compliant script (no test gates, no cleanup
|
||||||
temperature/utilization/power/fan speed
|
trap — see the CE OS Scripting Style Guide). It remains a prototype for
|
||||||
- **Threshold-driven colour** (green → amber → red) on key gauges, rather
|
iterating look, feel, and navigation, not a production deployment.
|
||||||
than flat, undifferentiated numbers
|
|
||||||
- **Rolling history sparkline** for GPU temperature trend
|
---
|
||||||
- **Idle-blank behaviour**: screen goes solid black after 15 minutes with no
|
|
||||||
touch/key input, to protect the physical panel from always-on burn-in over
|
|
||||||
years of continuous operation — any input wakes it immediately
|
|
||||||
- **Tabbed layout**: Dashboard (functional), Request Assistance and Switch to
|
|
||||||
X (stubs — see Roadmap)
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Python 3.9+
|
- Python 3.10+
|
||||||
- [Textual](https://textual.textualize.io/) (`pip install textual
|
- [Textual](https://github.com/Textualize/textual) —
|
||||||
--break-system-packages`, or via `pipx`)
|
`pip install textual --break-system-packages` (or via `pipx`)
|
||||||
- `nvidia-smi` on `PATH` for GPU telemetry (CPU/memory panels work without
|
- Linux with `/proc/stat` and `/proc/meminfo` (CPU/memory stats — no
|
||||||
it — GPU panel degrades gracefully to zero rather than crashing if
|
external dependency beyond the standard library for these)
|
||||||
`nvidia-smi` is unavailable or fails)
|
- `nvidia-smi` on `PATH`, for GPU telemetry (gracefully degrades to zero
|
||||||
|
values if absent or if the query fails)
|
||||||
|
|
||||||
## Running
|
Target hardware: a 5" case-mounted touchscreen, e.g. the Waveshare 5"
|
||||||
|
HDMI LCD (800×480, resistive touch). See Design Notes for why resistive
|
||||||
|
touch specifically shaped this interface's navigation model.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Running it
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 server_dash.py
|
python3 server_dash.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Intended to run under a dedicated, unprivileged monitoring user's autologin
|
Designed to run under a dedicated, unprivileged monitoring user's
|
||||||
TTY session — not as root, and not as the account used for anything else on
|
autologin session — no X server required for the dashboard itself. (The
|
||||||
the box.
|
**Switch to X** section, once wired up, is specifically for spinning up
|
||||||
|
X on demand for GPU tuning tools that do need it.)
|
||||||
## Status
|
|
||||||
|
|
||||||
This is an early, working prototype — the CPU/memory/GPU telemetry panel is
|
|
||||||
functional and tested; the two additional tabs are placeholders, not yet
|
|
||||||
implemented:
|
|
||||||
|
|
||||||
| Tab | Status |
|
|
||||||
|---|---|
|
|
||||||
| Dashboard | Working — live CPU/mem/GPU telemetry |
|
|
||||||
| Request Assistance | Stub — will send a scripted notification email |
|
|
||||||
| Switch to X | Stub — will invoke a narrowly-scoped, sudoers-gated VT switch to a separate login, for on-demand GPU tuning access via a real X session |
|
|
||||||
|
|
||||||
Not yet fully compliant with CE OS script conventions (no test gates, no
|
|
||||||
cleanup trap) — this is explicitly a prototype for iterating the interface
|
|
||||||
design, not a hardened production deployment. See the script's own header
|
|
||||||
comment for current detail.
|
|
||||||
|
|
||||||
## Design notes
|
|
||||||
|
|
||||||
- **GPU vendor**: currently NVIDIA-only via `nvidia-smi`. AMD/Intel GPU
|
|
||||||
support would need an equivalent backend behind the same `read_gpu_stats()`
|
|
||||||
interface — contributions welcome.
|
|
||||||
- **Colour thresholds** (`TEMP_THRESHOLDS`, `UTIL_THRESHOLDS` in-script) are
|
|
||||||
currently fixed defaults, not yet configurable per-deployment. Worth
|
|
||||||
externalizing to a config file if this is deployed across multiple
|
|
||||||
machines with different thermal profiles.
|
|
||||||
- **No hard dependency on a specific display size** — built for a 5"
|
|
||||||
case-mounted touchscreen, but Textual's layout should adapt reasonably to
|
|
||||||
other terminal sizes; untested on anything else so far.
|
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
- [ ] Wire up Request Assistance (scripted outbound email, hostname in body)
|
|
||||||
- [ ] Wire up Switch to X (sudoers-scoped `chvt` wrapper, see script comment)
|
|
||||||
- [ ] Externalize colour thresholds to a config file
|
|
||||||
- [ ] Bring up to full CE OS script compliance (test gates, cleanup trap)
|
|
||||||
- [ ] Consider a non-NVIDIA GPU backend
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
See [LICENSE](./LICENSE).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Built standing on the shoulders of billions of dwarves.*
|
## Design notes
|
||||||
*Created by John A. Hoeven with the ethical assistance of Claude AI.*
|
|
||||||
|
### Navigation: touch-bar, not tabs, not free-scroll
|
||||||
|
|
||||||
|
Earlier drafts used `TabbedContent`/`TabPane`. This was replaced with a
|
||||||
|
fixed-width touch-bar sidebar (up/down buttons) controlling a
|
||||||
|
`VerticalScroll` of `min-height: 100vh` sections, for two reasons:
|
||||||
|
|
||||||
|
- **Touch-swipe fidelity on this specific hardware was never verified.**
|
||||||
|
Button-triggered navigation (`scroll_to_widget()`) removes the
|
||||||
|
dependency entirely rather than hoping raw swipe gestures arrive
|
||||||
|
cleanly from this touchscreen.
|
||||||
|
- **The client base includes people who may not have a full set of
|
||||||
|
fingers or thumbs on either hand** (small-factory environments). Touch
|
||||||
|
zones are deliberately oversized — roughly thumb-width, half the
|
||||||
|
screen's height — with a forgiving click margin extending past the
|
||||||
|
visible coloured bar, so an imprecise touch from any part of a hand
|
||||||
|
still registers. This is tested and confirmed working in the
|
||||||
|
assembled app, not just assumed.
|
||||||
|
|
||||||
|
### Resistive touch is the right technology here, not a compromise
|
||||||
|
|
||||||
|
Capacitive touch requires conductive bare skin and doesn't reliably
|
||||||
|
register gloves, prosthetics, or some scarred/grafted skin. Resistive
|
||||||
|
touch responds to pressure from anything — a knuckle, a gloved finger,
|
||||||
|
a stylus, a partial hand. Given the intended client base, resistive
|
||||||
|
touch and generously-sized, forgiving touch zones are a deliberate
|
||||||
|
accessibility choice, not a lesser alternative to capacitive.
|
||||||
|
|
||||||
|
### Threshold colours
|
||||||
|
|
||||||
|
Green → amber → red follows the same instinct as a car's tachometer
|
||||||
|
redline. Current GPU temperature thresholds (65°C amber, 75°C red) are
|
||||||
|
based on empirically observed thermal-error thresholds on constrained
|
||||||
|
hardware in this project — not arbitrary numbers. Applied consistently
|
||||||
|
to every gauge (GPU temp and util, all CPU cores, memory) — not just
|
||||||
|
one readout.
|
||||||
|
|
||||||
|
### Data sources
|
||||||
|
|
||||||
|
- **GPU stats** via `nvidia-smi`, same parsing approach as this
|
||||||
|
project's thermal-logging script — no Python NVIDIA-bindings
|
||||||
|
dependency.
|
||||||
|
- **CPU/memory stats** are pure standard library (`/proc/stat`,
|
||||||
|
`/proc/meminfo`) — the same low-level mechanism `btop` itself uses
|
||||||
|
under the hood, reimplemented in Python.
|
||||||
|
|
||||||
|
### Idle-blank after 15 minutes
|
||||||
|
|
||||||
|
Any keypress or click resets the timer; timeout shows a solid black
|
||||||
|
screen. A deliberate longevity choice — protects the physical display
|
||||||
|
from years of always-on burn-in — not just a power-saving nicety.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Known issues
|
||||||
|
|
||||||
|
- `DashboardSection`, `RequestAssistanceSection`, and `SwitchToXSection`
|
||||||
|
are plain `Container`s, not `Screen`s — this is intentional (see
|
||||||
|
Design Notes in the code), not a leftover from the tab-based layout.
|
||||||
|
- Touch-bar width (currently 20 cells, visible bar 12 cells) was sized
|
||||||
|
by eye against real-world hand width, not calculated from the
|
||||||
|
display's physical dimensions — terminal UIs size in character cells,
|
||||||
|
not physical units, so this is expected to need on-hardware
|
||||||
|
calibration once mounted, not a precise spec.
|
||||||
|
- Raw touch-swipe (as opposed to button taps) has not been tested on
|
||||||
|
the actual touchscreen hardware — the design deliberately does not
|
||||||
|
depend on it working, but it hasn't been ruled in or out.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
- [ ] Wire up **Request Assistance** — scripted outbound email via
|
||||||
|
`smtplib` notifying the responsible admin, hostname included
|
||||||
|
automatically
|
||||||
|
- [ ] Wire up **Switch to X** — calls a narrowly-scoped, sudoers-gated
|
||||||
|
wrapper script that switches to a dedicated VT and drops to a
|
||||||
|
standard login prompt (password required) before X starts
|
||||||
|
- [ ] Confirm touch-bar sizing on real hardware once display is mounted
|
||||||
|
- [ ] Confirm touch controller reports as standard HID
|
||||||
|
(`lsusb`/`dmesg`/`evtest`) — some earlier Waveshare display
|
||||||
|
revisions used a non-standard protocol requiring a custom driver
|
||||||
|
- [ ] Bring the script up to full CE OS scripting style guide compliance
|
||||||
|
(test gates, cleanup handling)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Licence
|
||||||
|
|
||||||
|
The Unlicense — see [LICENSE](./LICENSE). Commercial use explicitly
|
||||||
|
permitted, no attribution required — though if this is useful to you,
|
||||||
|
consider a mention.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Built standing on the shoulders of billions of dwarves*
|
||||||
|
*Created by John A. Hoeven with the ethical assistance of Claude AI*
|
||||||
Loading…
Add table
Add a link
Reference in a new issue