Pot.__init__ now only takes dt; set_plant_params() and set_ambient_temperature()
must be called before process(), which now raises RuntimeError if either is
missing instead of silently computing on whatever the constructor happened to
default to. set_ambient_temperature() only seeds the plant's starting
temperature the first time it's called, so changing ambient mid-run still
can't clobber an in-progress simulated temperature. Updates all callers
(server/brewpi.py, TempController(Smith)'s two internal models,
SudForecastEstimator, and the plant/pid/sud demo scripts) to call the setters
right after construction.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkkuG48uHFCGKe6dPSERFk
brewpi.py passed a literal 20 as theta_amb to Pot, and
temp_controller_smith.py's two internal Pot models (and every demo's
Pot/TempController instantiation) silently relied on Pot's default of
20 instead. Add a top-level ambient_temperature key to
config.json(.templ/.sim), thread it through brewpi.py into both the
real plant and the Smith predictor's models via a new theta_amb param
on TempController, and make the demos pass it explicitly too.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
[Sensor] - replace TempSensorSim's hardcoded k_noise with configurable
temp_offset/variance, accept **kwargs on Max31865 too so both sensors
share a constructor signature usable from TempSensorFactory.create()
[Temp Controller] - low-pass filter the backward-difference heat-rate
estimate (alpha=0.1) in both temp_controller.py and
temp_controller_smith.py instead of using the raw, noisy derivative
[Pot] - drop kn from demo_pot.py's params, matching the unused-field
removal already made to pot.py itself
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>