feat: autotune PSU capacity from the same full-load run as fan ceilings
Extract the fan peak-tracking into observedPeakStore (observe max under load, hold >= minHold to reject spikes, round, persist JSON) and add a second instance for PSU draw (psu-observation.json, keyed by PSU ordinal). Fed from samplePSUPower like fans are from sampleFanSpeeds, so any full-load run refines it — the Fan Ceiling Check (which also samples PSU power at a slow cadence off its loop and writes psu_<i>_peak_w), a burn, thermal cycling, and the 5s web metrics collector. /topo PSU cards now scale the load fill by wattage_w when the BMC reports it, else by the observed peak draw — marked "~N% load". This MSI stand's BMC gives only instantaneous input power, so the observed peak is the only capacity figure available. Fan behaviour is unchanged (tests exercise updateFanObservation / estimateFanDutyCyclePctFromObservation / ResolveFanMaxRPM through the new store). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VHG21rgTUiR1G3qFHTVmN
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
e713504fc9
commit
7ed652c5b1
@@ -57,10 +57,33 @@ The `fan` SAT test (`platform.RunFanCheck`, formerly the unwired
|
||||
fan rose meaningfully above baseline, declare the ceiling found and stop —
|
||||
**success**. `MaxLoadSec` (default 900 s) is a hard cap; hitting it is also
|
||||
success (the highest RPM seen is still recorded).
|
||||
4. Persist each peak through the existing `updateFanObservation` path
|
||||
4. Persist each peak through `updateFanObservation`
|
||||
(`/var/log/bee-sat/fan-observation.json`), which is what `ResolveFanMaxRPM`
|
||||
reads.
|
||||
|
||||
## The observed-peak store (autotune primitive)
|
||||
|
||||
`platform.observedPeakStore` (`observed_peaks.go`) is the shared mechanism:
|
||||
observe the max value per key while the box is under load, require a candidate
|
||||
to hold ≥ `minHold` before it sticks (rejects spikes), round up, persist to a
|
||||
`{"<jsonKey>": {key: peak}}` JSON file. Two instances:
|
||||
|
||||
- `fanPeaks` → `fan-observation.json` `max_rpm`, keyed by fan name, round-up 1000.
|
||||
- `psuPeaks` → `psu-observation.json` `max_w`, keyed by **PSU ordinal**, round-up 50.
|
||||
|
||||
Both are fed from the ordinary telemetry paths — `sampleFanSpeeds` and
|
||||
`samplePSUPower` call `update*Observation` — so **any** full-load run refines
|
||||
them: the Fan Ceiling Check itself, a burn, thermal cycling, power
|
||||
calibration, and the 5 s web metrics collector while any of those run. There
|
||||
is no separate "PSU autotune" test: the fan check's max-CPU+GPU load is
|
||||
already the right moment to observe peak PSU draw, and it samples PSU power at
|
||||
a slow cadence off its own loop (`psu_<i>_peak_w` in the summary).
|
||||
|
||||
This exists because BMCs like the MSI stand's report only instantaneous PSU
|
||||
input power, no nameplate rating. `/topo` PSU cards scale the load fill by the
|
||||
real `wattage_w` when present, otherwise by `ObservedPSUMaxW()` — marked as an
|
||||
estimate (`~N% load`).
|
||||
|
||||
## Verdict mapping
|
||||
|
||||
- A fan reading **0 RPM**, or IPMI status **cr/nr**, while under full load →
|
||||
|
||||
Reference in New Issue
Block a user