feat: full fan control — all fans or individual fans
The fan curve previously only controlled fan index 0; secondary fans
stayed on driver control. The curve can now target all fans (new
default) or any individual fan(s).
Backend:
- hal/fans.py: get_num_fans() via nvmlDeviceGetNumFans; get_fan_info()
returns per-fan speeds; set_fan_speed() accepts a fan index list
(None = all fans; all-fans mode is lenient toward driver-locked
fans, explicit lists are strict); reset_fan() restores all fans.
- server.py: per-GPU fan_targets state; the poller applies the curve to
all target fans and logs write failures (once per distinct error);
activation validates targets against the hardware (stale indices fall
back to all fans); POST /api/fans accepts fans, POST /api/fans/speed
accepts a fan index, GET /api/fans returns num_fans/fans/fan_targets.
- Persistence format is now {"curve": ..., "fans": ...}; legacy
bare-curve entries migrate to "all fans" at startup.
- Profiles save/apply fan_targets alongside fan_curve.
- MonitoringSample carries per-fan speeds for live gauges.
Frontend:
- Fans tab: All / Fan 1 / Fan 2 / ... selector with live per-fan %;
the selection is applied together with the curve.
- Live monitor: per-fan gauges with sparklines for multi-fan GPUs.
This commit is contained in:
1 parent
34a9bc6d6e
commit
6cb33187d3
12 files changed
+382
-77
No files matched your search
@@ -25,6 +25,7 @@ export interface MonitoringSample {
|
||||
temp_c: number | null;
|
||||
power_w: number | null;
|
||||
fan_pct: number | null;
|
||||
fans: (number | null)[] | null;
|
||||
pstate: number | null;
|
||||
pstate_label: string | null;
|
||||
mem_used_bytes: number | null;
|
||||
@@ -111,13 +112,22 @@ export interface FanPoint {
|
||||
fan_pct: number;
|
||||
}
|
||||
|
||||
export interface FanInfo {
|
||||
index: number;
|
||||
fan_pct: number | null;
|
||||
}
|
||||
|
||||
export interface FanState {
|
||||
fan_pct: number | null;
|
||||
fans: FanInfo[] | null;
|
||||
num_fans: number | null;
|
||||
fan_mode: "auto" | "curve" | null;
|
||||
min_fan_pct: number | null;
|
||||
max_fan_pct: number | null;
|
||||
curve: FanPoint[] | null;
|
||||
curve_active: boolean;
|
||||
// Fan indices controlled by the active curve; null = all fans.
|
||||
fan_targets: number[] | null;
|
||||
}
|
||||
|
||||
export interface ProfileData {
|
||||
@@ -127,4 +137,5 @@ export interface ProfileData {
|
||||
mem_offset_mhz: number | null;
|
||||
power_limit_w: number | null;
|
||||
fan_curve: FanPoint[] | null;
|
||||
fan_targets: number[] | null;
|
||||
}
|
||||
Reference in new issue
Block a user