Fix HOLD<->COOL chattering caused by too-tight HoldCool threshold

HoldCool=0.1 was inherited from the pre-COOL-state era, where it meant
"eagerly give up active holding and coast" - harmless, since coasting
had no side effects. COOL is a real, actively-controlled state now
(its own pid_cool, reset on every entry), so a threshold this tight
relative to a real heater's discrete power steps (or even just sensor
noise) caused the system to flip in and out of COOL nearly every tick
once resting near a setpoint - resetting both pid_hold's and
pid_cool's integrators each time and never letting either actually
converge.

Confirmed via a full multi-task simulation (real Pot/Sensor/Heater/
TempCtrl tasks, not a simplified loop) of sude/sud_0010.json: 44+
TempCtrl state changes and the run not settling within hours at
HoldCool=0.1, dropping to 8 state changes and a clean 186.5 min finish
at HoldCool=1.0 (matching the other thresholds). This was the dominant
cause of real brews taking far longer than their nominal schedule
duration - not just a forecasting inaccuracy, an actual control-
quality bug.
This commit is contained in:
2026-06-21 16:38:59 +02:00
parent cce662b794
commit 1034765e31
2 changed files with 9 additions and 2 deletions
+8 -1
View File
@@ -4,7 +4,14 @@ import enum
DEFAULT_THRESHOLDS = { DEFAULT_THRESHOLDS = {
"HoldHeat": 1.0, "HoldHeat": 1.0,
"HoldCool": 0.1, # HoldCool used to be 0.1 ("eagerly give up and coast" made sense back
# when COOL meant nothing more than going idle - it's an active state
# with its own PID now, so a threshold this tight relative to a real
# heater's discrete power steps/sensor noise causes the system to
# chatter in and out of it every tick, resetting both pid_hold's and
# pid_cool's integrators each time and never letting either actually
# converge. Symmetric with the others instead.
"HoldCool": 1.0,
"HeatHold": 1.0, "HeatHold": 1.0,
"HeatCool": 1.0, "HeatCool": 1.0,
"CoolHold": 1.0, "CoolHold": 1.0,
+1 -1
View File
@@ -30,7 +30,7 @@
}, },
"Thresholds": { "Thresholds": {
"HoldHeat": 1.0, "HoldHeat": 1.0,
"HoldCool": 0.1, "HoldCool": 1.0,
"HeatHold": 1.0, "HeatHold": 1.0,
"HeatCool": 1.0, "HeatCool": 1.0,
"CoolHold": 1.0, "CoolHold": 1.0,