feat: wireview pin-imbalance warning, per-pin rating bars, pin_imbalance_a

- Per-pin bar now scales against the 9.2 A per-pin rating (10 A full
  scale, red at/over rating) instead of the 55 A total connector OCP
- Debounced app-wide warning banner (visible on all tabs) when the
  current between two pins diverges by > 2 A for ~7 s - the signature
  of a bad pin contact that can overheat and melt the 12VHPWR
  connector; 5 s grace period after clearing
- New pin_imbalance_a sample field (max - min pin current) in both the
  serial and hwmon sample builders, plus frontend type
- Docs: README + WireView.md cover the warning and threshold; fresh
  screenshot with the new per-pin labels
- Tests: vitest setup + 9 unit tests for the debounce state machine;
  3 new backend checks for pin_imbalance_a
This commit is contained in:
ARIA committed 2026-10-03 22:13:13 +02:00
1 parent 92356d1409
commit b69b7502b3
14 files changed
+810 -18

No files matched your search

+22
View File
@@ -18,6 +18,7 @@ import { api, onUnauthorized } from "./api/client.js";
import { LoginScreen } from "./components/Auth/LoginScreen.js";
import { useCurveStore } from "./store/curveStore.js";
import { useWireview } from "./hooks/useWireview.js";
import { useWireviewImbalance } from "./hooks/useWireviewImbalance.js";
import { Toaster } from "sonner";
import { Loader, ChevronDown } from "lucide-react";
import { useState, useRef, useEffect } from "react";
@@ -98,6 +99,7 @@ function MainApp({
const { setCurve, activeProfile, setActiveProfile, selectedGpuIndex } =
useCurveStore();
const wireview = useWireview();
const wireImbalance = useWireviewImbalance(wireview.sample);
const [activeTab, setActiveTab] = useState<
"dashboard" | "curve" | "performance" | "fans" | "wireview"
@@ -171,6 +173,26 @@ function MainApp({
</div>
)}
{wireImbalance && (
<div className="bg-red-500/15 border-b-2 border-red-500 text-red-300 px-4 py-2.5 flex items-center justify-center gap-3 flex-wrap">
<span className="text-xl leading-none">⚠</span>
<span className="text-base font-bold">
WireView: current imbalance {wireImbalance.diff.toFixed(1)} A —
Pin {wireImbalance.hiPin} ({wireImbalance.maxI.toFixed(1)} A) vs
Pin {wireImbalance.loPin} ({wireImbalance.minI.toFixed(1)} A)
</span>
<span className="text-sm text-red-200/80">
Bad pin contact — reduce load, replace cable/adapter
</span>
<button
onClick={() => setActiveTab("wireview")}
className="text-sm font-semibold text-red-200 hover:text-white underline underline-offset-2"
>
View
</button>
</div>
)}
<main className="flex-1 p-4 flex flex-col gap-4 w-full max-w-[1600px] mx-auto">
{/* Tab Header and Profile Selector */}
<div className="flex justify-between items-end border-b border-zinc-800 pb-2">