1. No indicator that fan settings are saved in a profile ProfilePanel.tsx now shows a cyan fan icon next to a profile's name when it has a saved fan curve (tooltip: "Custom fan curve saved"), alongside the existing pts / W / MHz mem badges.
2. Fan curve not applied after server restart
Root cause: the active fan curve was in-memory only, so it was lost on every restart. Fan control is volatile (driver reverts to auto on reboot), so the curve now persists and is restored:
config.py: new fan_curves field (per-GPU, keyed by the same stable GPU ID as auto-load profiles).
cli.py: loads fan_curves from /etc/nvcurve/config.json at startup.
server.py: new _activate_fan_curve / _deactivate_fan_curve helpers set state, (re)start the poller, and persist/clear the curve. All fan-curve changes route through them, so persistence stays in sync (apply, reset, profile apply). On startup the lifespan re-applies each GPU's persisted curve (validated first), after the auto-load-profile path.
After a restart the fan-curve window shows the applied curve (Active) instead of Defaults.
3. No way to remove a point FanCurveEditor.tsx — removal existed but was nearly invisible. The chart remove button is now always faintly visible with an X glyph (red on hover); the table remove button is larger with a tooltip; added a hint line explaining add/remove.
Also includes a formatting pass over the two edited frontend files.
Fixes three fan-settings issues.
**1. No indicator that fan settings are saved in a profile**
`ProfilePanel.tsx` now shows a cyan fan icon next to a profile's name when it has a saved fan curve (tooltip: "Custom fan curve saved"), alongside the existing pts / W / MHz mem badges.
**2. Fan curve not applied after server restart**
Root cause: the active fan curve was in-memory only, so it was lost on every restart. Fan control is volatile (driver reverts to auto on reboot), so the curve now persists and is restored:
- `config.py`: new `fan_curves` field (per-GPU, keyed by the same stable GPU ID as auto-load profiles).
- `cli.py`: loads `fan_curves` from `/etc/nvcurve/config.json` at startup.
- `server.py`: new `_activate_fan_curve` / `_deactivate_fan_curve` helpers set state, (re)start the poller, and persist/clear the curve. All fan-curve changes route through them, so persistence stays in sync (apply, reset, profile apply). On startup the lifespan re-applies each GPU's persisted curve (validated first), after the auto-load-profile path.
After a restart the fan-curve window shows the applied curve (Active) instead of Defaults.
**3. No way to remove a point**
`FanCurveEditor.tsx` — removal existed but was nearly invisible. The chart remove button is now always faintly visible with an X glyph (red on hover); the table remove button is larger with a tooltip; added a hint line explaining add/remove.
Also includes a formatting pass over the two edited frontend files.
Verified: frontend builds cleanly (tsc + vite); backend imports cleanly; behavior confirmed on hardware.
Address three fan-settings issues:
1. Profile view: show a fan icon next to a profile's name when it has a
saved fan curve, so it's clear which profiles carry custom fans.
2. Fan curve persistence: the active fan curve was in-memory only and lost
on every server restart. It is now persisted per-GPU in
/etc/nvcurve/config.json (fan_curves) and re-applied at server startup,
so an applied curve survives restarts. All fan-curve state changes route
through _activate_fan_curve/_deactivate_fan_curve helpers that keep the
persisted state in sync (apply, reset, and profile apply).
3. Point removal: the fan-curve remove button was nearly invisible. The
chart remove control is now always faintly visible with an X glyph, the
table remove button is larger with a tooltip, and a hint line explains
how to add/remove points.
Also includes a formatting pass over the two edited frontend files.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes three fan-settings issues.
1. No indicator that fan settings are saved in a profile
ProfilePanel.tsxnow shows a cyan fan icon next to a profile's name when it has a saved fan curve (tooltip: "Custom fan curve saved"), alongside the existing pts / W / MHz mem badges.2. Fan curve not applied after server restart
Root cause: the active fan curve was in-memory only, so it was lost on every restart. Fan control is volatile (driver reverts to auto on reboot), so the curve now persists and is restored:
config.py: newfan_curvesfield (per-GPU, keyed by the same stable GPU ID as auto-load profiles).cli.py: loadsfan_curvesfrom/etc/nvcurve/config.jsonat startup.server.py: new_activate_fan_curve/_deactivate_fan_curvehelpers set state, (re)start the poller, and persist/clear the curve. All fan-curve changes route through them, so persistence stays in sync (apply, reset, profile apply). On startup the lifespan re-applies each GPU's persisted curve (validated first), after the auto-load-profile path.After a restart the fan-curve window shows the applied curve (Active) instead of Defaults.
3. No way to remove a point
FanCurveEditor.tsx— removal existed but was nearly invisible. The chart remove button is now always faintly visible with an X glyph (red on hover); the table remove button is larger with a tooltip; added a hint line explaining add/remove.Also includes a formatting pass over the two edited frontend files.
Verified: frontend builds cleanly (tsc + vite); backend imports cleanly; behavior confirmed on hardware.
✅ No issues found — changes look consistent with the stated intent. Ready to be merged.