25c613c5cb331a30cd7dd645bbbd2b2eb7bf2c59
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e5a2af9821 |
feat(ui): dashboard polish, richer perf strip, transport-bar controls
Dashboard perf strip:
- Unified rack-module shell with hairline-divided cells (mockup parity)
replacing 3 separate perf cards. Cells auto-wrap to 2 rows of 4 on
widescreen; responsive breakpoints at 1100 / 760 / 480 px.
- Active Patches cell (first) shows running/total channel count plus up
to 4 live FPS readouts with channel-colored stripes; bottom-right
radial glow anchors the "live channel bank" corner.
- Total FPS cell — aggregate throughput across running targets, mono
"fps" unit suffix, session-peak-scaled sparkline with a 60 FPS floor.
- Devices cell — online/total count + per-device dot strip (green when
online with signal-glow, coral when offline, tooltip with name +
latency), fed from /devices/batch/states (added to the dashboard
batch poll).
- Value font uses clamp(1.8rem, 2.8vw, 2.8rem) + white-space: nowrap so
long readouts (RAM "18.9/31.8 GB", GPU "50% · 37°C") scale down
instead of wrapping.
- Sparklines anchor to the cell bottom via margin-top: auto so baselines
align across cells regardless of subtitle presence.
- App-load tag ("APP 3.1%") moved to a pinned top-right position per
card, accent-colored pill; replaces the subdued inline badge.
- Perf mode toggle (System / App / Both) triggers an immediate poll so
positioning updates without waiting for the next tick.
- Chart.js removed from perf-charts — inline SVG sparklines with
drop-shadow filter for the "lit instrument" feel. Chart.js still used
for per-target FPS charts via chart-utils (now owns the registration).
- Fixed history seed bug: app_ram is MB in the server history payload,
not percent — convert to percent using sample's ram_total before
pushing into _appHistory.ram. Skip seeding app_gpu_mem since the
history schema has no gpu_memory_total.
- Temperature card reveals with an explanatory hint when the backend
reports cpu_temp_hint_key (e.g. Windows without LibreHardwareMonitor)
instead of silently hiding; .perf-chart-card-hint neutralizes the big
display font so the message reads as plain body copy.
Transport bar:
- LED brand mark — 28 px, double-layer signal glow (0 22px + 0 8px),
brandPulse animation. Brand-stack wraps the title + version so
"LED GRAB" sits above "V0.3.0" on a single line each.
- Transport status chip — bigger (9/18 padding), mono uppercase,
inner+outer signal glow when .is-armed.
- Transport meta cells — Uptime (JS-local session ticker), CPU (app
CPU share), Mem (app RAM, G/M format) as stacked KEY/VALUE mono
readouts with hairline separators.
- New interactive Poll cell cycles through 1/2/5/10s presets on click;
replaces the range slider that used to live in the Dashboard toolbar
(it controlled the whole app, not just the Dashboard).
- Header icon buttons — hairline-bordered 30 px squares with channel-
glow on hover, replacing the pill container.
- Perf poll moved to global bootstrap so transport CPU / Mem stay live
across all tabs (was paused when leaving the Dashboard).
- Connection pip (#server-status) hidden; the brand mark itself turns
coral when offline via :has() selector on .header-title.
Dashboard cards:
- renderDashboardTarget now emits full rack-module markup with CH badge,
name, meta, LED cluster, 3-cell metric grid (FPS / Uptime / Errors),
and patch-label + stop button. Running cards get the signal-flow
strip at the bottom. data-fps-text / data-uptime-text / data-errors-
text hooks preserved so _updateRunningMetrics updates in place.
- LED count surfaced in the target card meta line (e.g. "LED · WLED ·
144 LED · GRADIENT") when the linked device reports led_count > 0.
- Integrations (HA + MQTT) picked up .mod-head markup — compact module
layout with online/offline patch indicator. Integration card stripe
uses the default signal color (not cyan or amber).
- Scene presets, sync clocks, automations gain the same compact module
treatment. Automations/scenes dropped into a dashboard-autostart-grid
so they share the visual language.
- Perf mode toggle, stream sub-tabs, cs-count / tree-count /
tab-badge / dashboard-section-count badges all use the mono
rectangular style with tabular-nums.
Command palette:
- Flat background (no gradient), channel-accent rule across the top,
mono placeholder / group headers / footer, active result gets a
channel-green left stripe.
Modals:
- Popover + backdrop get a stronger radial dim + 6 px blur.
- Per-modal-ID channel lanes (target→green, source→cyan, audio→magenta,
automation/scene→violet, settings→amber, confirm→coral) via --modal-ch
override.
- Modal header picks up a vertical channel stripe + hairline divider;
footer gets hairline top + subtle wash.
Components:
- Inputs use hairline borders + tabular-nums mono for number fields;
focus state has channel-green ring + soft glow.
- Buttons switch to mono-uppercase with signal-glow on primary,
coral-glow on danger, hairline border on secondary.
- Card background flattened — removed gradient wash in favor of solid
--lux-bg-1 for both dark (#0e1014) and light (#f6f8fb).
- Page background: pure black for dark, pure white for light.
Color-picker:
- Always detaches to <body> with fixed positioning when its swatch sits
inside an overflow: hidden / auto / clip ancestor (perf strip, modal
bodies, tree-dd panels). Prevents the popover getting clipped.
Settings modal:
- Remembers the last-opened tab via localStorage key
settings_active_tab; falls back to 'general' if the tab id no longer
exists. Explicit overrides (donation → about, update badge →
updates) still work because callers invoke switchSettingsTab after
openSettingsModal.
Microcopy:
- Sidebar / transport localization for en/ru/zh:
sidebar.workspaces · transport.meta.{uptime,cpu,mem,poll,poll_hint}
· transport.status.{ready,armed} · dashboard.perf.{active_patches,
total_fps,devices}
Backend (coordinated with frontend):
- /system/performance now returns cpu_temp_hint_key when no live CPU
temperature is available, so the Temperature card can render an
actionable explainer instead of being hidden. Frontend respects the
key via t() lookup.
Section headers:
- Underline switched from dashed to solid; channel-green accent rule
(40 px) on the left remains.
Build / tests:
- ruff clean on touched Python files.
- tsc --noEmit clean.
- Python metrics-provider tests: 18 passed.
- CSS bundle ~214 KB.
|
||
|
|
ecae05d00b |
feat(metrics): battery + thermal-zone readings with dashboard temp chart
Extends MetricsProvider with thermals() returning a ThermalSnapshot
(battery_percent, battery_temp_c, cpu_temp_c — all optional). Each
provider implements it independently:
- AndroidMetricsProvider reads /sys/class/power_supply/battery/{capacity,
temp} (battery temp is tenths of degC) and walks
/sys/class/thermal/thermal_zone*, filtering by zone type
(cpu/soc/tsens/core) so battery and skin sensors don't dominate the
reading. Rejects nonsense values like INT_MAX from buggy zones.
- PsutilMetricsProvider uses sensors_battery() and
sensors_temperatures() when present (Linux+laptops); no-ops on
Windows/macOS where psutil doesn't expose them.
- NullMetricsProvider returns the empty snapshot.
PerformanceResponse gains battery_percent / battery_temp_c / cpu_temp_c.
The metrics-history ring buffer also carries cpu_temp / battery_pct /
battery_temp per sample so the dashboard can graph them over time.
Frontend dashboard (perf-charts.ts) gets a new Temperature chart card,
hidden by default and revealed only after seed/poll confirms the
backend reports cpu_temp_c. Battery temperature shows inline as a
secondary badge. The GPU card now also hides entirely when the backend
reports gpu=null instead of showing an "unavailable" placeholder.
HOST_ONLY_KEYS prevents the System/App/Both toggle from flipping a
non-existent app dataset for temp.
Tests: 6 new for thermals (battery tenths-of-degC parsing, CPU zone
filtering, fallback when sensors absent, INT_MAX rejection); 18 metrics
tests total; full suite 733 passing.
|
||
|
|
546b24d015 |
refactor(metrics): MetricsProvider abstraction with Android /proc backend
Moves direct psutil.* calls behind a MetricsProvider Protocol so the codebase no longer needs ad-hoc `if psutil is not None` guards at every call site. Each provider lives in its own module under utils/metrics/: PsutilMetricsProvider for desktop, NullMetricsProvider as a zeroed fallback, AndroidMetricsProvider that reads /proc/stat, /proc/meminfo, /proc/self/stat, and /proc/self/status directly (psutil isn't available under Chaquopy). The Android provider tracks the previous CPU sample so cpu_percent() returns delta-based percentages matching psutil's interval=None semantics, and degrades to zeros when any /proc file is unreadable instead of crashing the dashboard. Factory get_metrics_provider() in utils/metrics/__init__.py picks Android > psutil > Null. api/routes/system.py and core/processing/metrics_history.py now go through the factory; psutil import is confined to one place. 12 new unit tests cover paren-in-comm parsing of /proc/self/stat, delta CPU%, missing-file resilience, and factory selection order. Full suite: 727 passing. |