feat(webui): live-update topology fan tiles without a page reload

Each fan tile carries data-fan / data-ceil / data-measured and a small
script polls /api/metrics/latest every 5s — the metrics collector's own
sampling period, served from memory with no extra BMC call — updating
each tile's spin rate, duty fill and tooltip in place. Polling faster
would only re-read identical numbers; sampling the BMC faster would
choke it under load. FanReading gains json tags for the endpoint.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VHG21rgTUiR1G3qFHTVmN
This commit is contained in:
Mikhail Chusavitin
2026-09-04 12:09:37 +03:00
co-authored by Claude Sonnet 5
parent d8b05069e0
commit a4853a0a4f
3 changed files with 51 additions and 6 deletions
+7
View File
@@ -206,6 +206,13 @@ func TestTopoPageRendersCoolingFansAsFlexRow(t *testing.T) {
if !strings.Contains(body, "ceiling not measured") {
t.Fatalf("topo fan tooltip should note the ceiling is unmeasured: %s", body)
}
// Live-update: each tile is addressable and the poll script is present.
if n := strings.Count(body, `class="topo-fan-tile"`); n != 2 {
t.Fatalf("expected 2 addressable fan tiles, got %d", n)
}
if !strings.Contains(body, `data-fan="FAN1"`) || !strings.Contains(body, "/api/metrics/latest") {
t.Fatalf("topo fan row missing live-update wiring: %s", body)
}
// Component-detail fallback endpoint must resolve the "fan" type.
rec2 := httptest.NewRecorder()