feat(webui): show PSU load as a fill on the topology PSU card

Same idea as the fan duty-cycle fill: a bar rising from the bottom of
each PSU card for draw / nameplate rating, live-updated on the shared
5s /api/metrics/latest poll. Drawn only when the rating (wattage_w) is
known — a raw wattage with nothing to scale against is not a load
figure, so BMCs that report only input power (e.g. this MSI stand) keep
showing the plain watts. Detail line becomes "<v> V · <draw> / <rating> W
· <n>% load" when both are present.

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:37:59 +03:00
co-authored by Claude Sonnet 5
parent 59271fa674
commit e713504fc9
2 changed files with 68 additions and 23 deletions
+9 -2
View File
@@ -93,6 +93,7 @@ func TestTopoPageRendersArbitraryPSUAndFirmwareCountsAsFlexRows(t *testing.T) {
failStatus := "Critical"
watt := 3000
volt := 230.0
draw := 1500.0
var psus []schema.HardwarePowerSupply
for i := 0; i < 6; i++ {
@@ -101,11 +102,13 @@ func TestTopoPageRendersArbitraryPSUAndFirmwareCountsAsFlexRows(t *testing.T) {
if i == 3 {
st = failStatus
}
d := draw
psus = append(psus, schema.HardwarePowerSupply{
HardwareComponentStatus: schema.HardwareComponentStatus{Status: &st},
Slot: &slot,
WattageW: &watt,
InputVoltage: &volt,
InputPowerW: &d,
})
}
@@ -147,8 +150,12 @@ func TestTopoPageRendersArbitraryPSUAndFirmwareCountsAsFlexRows(t *testing.T) {
strings.Count(body, `onclick="openComponentDetail(&#39;psu&#39;)"`); n != 6 {
t.Fatalf("expected one clickable card per PSU (6), got %d", n)
}
if !strings.Contains(body, "230 V · 3000 W rated") {
t.Fatalf("PSU card missing voltage/power line: %s", body)
if !strings.Contains(body, "230 V · 1500 / 3000 W · 50% load") {
t.Fatalf("PSU card missing voltage / draw / load line: %s", body)
}
// Load fill (draw/rating) is drawn, same idea as the fan duty fill.
if !strings.Contains(body, `class="topo-psu-fill"`) || !strings.Contains(body, "height:50%") {
t.Fatalf("PSU card missing load fill: %s", body)
}
// The one failed PSU is coloured red on its own (crit token) and labelled.
if !strings.Contains(body, "var(--crit-bg)") || !strings.Contains(body, "CRITICAL") {