Refresh README and design-backlog docs against current code
Both TODO.md backlogs and the README's architecture section still described the Kalman-filter/heat-diffusion design that's since been replaced by the delay-line Pot model and Kalman-free Smith predictor. Check off the items that rewrite already fixed (heat-loss units, transport delay vs. single-pole lag, three-Kalman-tuning), note how the kn/sensor-noise item was resolved differently than proposed, and add newly-spotted issues: brewpi.py wiring set_model_power unconditionally (breaks pid_type "Normal"), kalman.py being dead code in production, stale Kalman/kn keys in the config templates, and debug print()s left in Pot.process(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+50
-28
@@ -1,15 +1,26 @@
|
||||
# components/pid design backlog
|
||||
|
||||
Findings from a design review, not yet acted on. See git history on
|
||||
`claude_refactor` for items already fixed (Smith predictor's delay
|
||||
correction enabled, the two TempController classes deduplicated into
|
||||
`temp_controller_base.py`).
|
||||
Findings from a design review, refreshed against the current state of
|
||||
`master` after the Kalman-filter removal and Smith-predictor rewrite (see
|
||||
git history for `temp_controller.py`/`temp_controller_smith.py`).
|
||||
|
||||
- [x] **FSM thresholds aren't configurable.** Moved into an optional
|
||||
`TempCtrl.Thresholds` config section (`HoldIdle`, `HoldHeat`,
|
||||
`IdleHeat`, `IdleHold`, `HeatHold`, `HeatIdle`), merged over
|
||||
`DEFAULT_THRESHOLDS` in `tc_constants.py` so existing configs without
|
||||
the section keep working unchanged.
|
||||
`DEFAULT_THRESHOLDS` (now in `temp_controller_base.py`, formerly
|
||||
`tc_constants.py`) so existing configs without the section keep
|
||||
working unchanged.
|
||||
|
||||
- [x] **matplotlib imported at module level in production code.**
|
||||
`temp_controller.py`, `temp_controller_smith.py`, and `kalman.py`
|
||||
used to `from matplotlib.pyplot import ...` just to support their
|
||||
`__main__` self-test plots. The plotting demos (and `kalman_eval.py`)
|
||||
moved to `scripts/demos/pid/demo_*.py`; production modules no longer
|
||||
import matplotlib.
|
||||
|
||||
- [x] **Three Kalman filters share one tuning.** No longer applicable:
|
||||
`temp_controller_smith.py` was rewritten to drop Kalman filtering
|
||||
entirely (see below), so there's no shared tuning to split anymore.
|
||||
|
||||
- [ ] **`Pid.scale()` is a gain-scheduling hack, not anti-windup.**
|
||||
`pid.py`'s `scale(k)` multiplies every gain by `1/heatrate_soll_set`
|
||||
@@ -18,30 +29,41 @@ correction enabled, the two TempController classes deduplicated into
|
||||
a few lines below. `self.k` also never resets in `reset()`, so a
|
||||
stale scale factor can survive a state-transition reset. Consider
|
||||
moving this scheduling logic out of the generic `Pid` class and into
|
||||
the temp controller, and resetting `k` in `reset()`.
|
||||
the temp controller, and resetting `k` in `reset()`. Still present.
|
||||
|
||||
- [ ] **Three Kalman filters share one tuning.** In
|
||||
`temp_controller_smith.py`, `kalman_model`, `kalman_model_delay`,
|
||||
and `kalman_plant` are all constructed with the same
|
||||
`params['Kalman']` despite tracking signals with different noise
|
||||
characteristics. Allow independent `var_P`/`var_Q`/`var_R` per
|
||||
filter in config.
|
||||
- [ ] **No automated tests.** `tests/components/pid/` was added once
|
||||
(stdlib `unittest`, no pytest) covering FSM transitions, anti-windup
|
||||
clamping, and Kalman convergence, but was removed again before the
|
||||
Kalman-filter removal/Smith rewrite, so none of the current
|
||||
`temp_controller*.py` behavior (backward-difference + low-pass
|
||||
filtered heat rate, the two-model Smith correction) has test
|
||||
coverage. This drives a physical heater — worth re-adding.
|
||||
|
||||
- [ ] **matplotlib imported at module level in production code.**
|
||||
`temp_controller.py`, `temp_controller_smith.py`, and `kalman.py`
|
||||
all `from matplotlib.pyplot import ...` just to support their
|
||||
`__main__` self-test plots, which couples the live server's import
|
||||
graph (and its dependency list) to a GUI plotting library it never
|
||||
uses at runtime. Move the plotting demos into separate scripts.
|
||||
|
||||
- [ ] **No automated tests.** The `__main__` blocks (and
|
||||
`kalman_eval.py`) are manual, eyeballed-plot harnesses. Add
|
||||
regression tests for FSM transitions, anti-windup clamping, and
|
||||
Kalman convergence — this code drives a physical heater.
|
||||
- [ ] **`set_model_power` isn't defined on every controller, but
|
||||
`brewpi.py` wires it unconditionally.** `brewpi.py` always does
|
||||
`heater.set_on_changed("power_set", tc.set_model_power)` regardless
|
||||
of `Controller.pid_type`. Only `temp_controller_smith.py` (the Smith
|
||||
predictor) defines `set_model_power`; `temp_controller.py` (`"Normal"`)
|
||||
does not, so starting the server with `"pid_type": "Normal"` crashes
|
||||
at wiring time with `AttributeError: 'TempController' object has no
|
||||
attribute 'set_model_power'`. Either add a no-op `set_model_power` to
|
||||
`TempControllerBase`, or only wire it when the configured controller
|
||||
actually exposes a model to feed.
|
||||
|
||||
- [ ] **Config access is unchecked `dict[key]` everywhere.**
|
||||
`params['Kalman']`, `model_params['gain']`, etc., throughout, with
|
||||
no schema validation at load time. We already hit this bug class
|
||||
once (`config.json.sim`'s `gain`/`Model` nesting mismatch). A small
|
||||
`params['Hold']`, `model_params['gain']`, etc., throughout, with no
|
||||
schema validation at load time. We already hit this bug class once
|
||||
(`config.json.sim`'s `gain`/`Model` nesting mismatch). A small
|
||||
schema/dataclass validation layer at config-load would surface
|
||||
errors immediately instead of mid-`__init__`.
|
||||
errors immediately instead of mid-`__init__` — and would have caught
|
||||
the dead `TempCtrl.Kalman` / `Model.kn` / `Plant.kn` keys still
|
||||
sitting in `config.json.templ` and `config.json.sim` (harmless today
|
||||
since extra keys are just ignored, but nothing reads them anymore
|
||||
after the Kalman/`kn` removal — see `components/plant/TODO.md`).
|
||||
|
||||
- [ ] **`kalman.py` is now dead code in production.** Neither
|
||||
`temp_controller.py` nor `temp_controller_smith.py` uses `Kalman`
|
||||
anymore; the only remaining references are
|
||||
`scripts/demos/pid/demo_kalman.py` and `demo_kalman_eval.py`. Decide
|
||||
whether to keep it as a documented standalone filtering example or
|
||||
delete it along with the demos.
|
||||
|
||||
Reference in New Issue
Block a user