Commit Graph
38 Commits
Author SHA1 Message Date
jens a1864a5257 log: route task/component status output through logging, not print()
AttributeChange (the common base of every ATask and component ABC) now
sets self.log = logging.getLogger(type(self).__name__), so components
no longer need to hand-type their own name into each message. Wired
logging.basicConfig() in server/brewpi.py with a bare "%(name)s:
%(message)s" formatter - Tee (see prior commit) still supplies the
"<date>T<time>:" prefix, so lines read "<date>T<time>:<component>:
<message>" without double-stamping, and third-party loggers
(websockets, asyncio) now get the same formatting for free.

Converted the print() call sites that were standing in for this in
tasks/ and components/ (leaving __main__ demo blocks and explicit
debug-dump helpers alone).
2026-07-10 22:00:04 +02:00
jensandClaude Sonnet 5 4b9a144b62 fix: temp sensor read failures could crash startup or permanently kill the task
Same bug class as the earlier heater fix: TempSensorTask.on_process()
called self.sensor.temperature() every tick with no exception handling
at all, and the constructor even called it once synchronously at
startup to prime the value. A read failure there would either crash
the whole server before the event loop started, or permanently kill
TempSensorTask's coroutine mid-run - nothing restarts a dead ATask, so
the sensor would never be read again for the rest of the process's
life.

TempSensor_max31865.temperature() now catches read failures and calls
a new reopen() (closes/reopens the spidev handle - the closest
equivalent to unplug/replug for a bus peripheral) instead of raising,
holding the last-known-good reading meanwhile. reopen() itself never
raises either, learned from HendiCtrl.disconnect() previously letting
a failure escape the same way. Belt-and-suspenders guards added at the
TempSensorTask level too, matching HeaterTask/StirrerTask.

Verified against a fake spidev: a read failure no longer raises,
reopen() is attempted automatically, and readings resume once the bus
responds again - even when reopen() itself also fails.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YaPLuRPpyjWcwhMvCvpHCL
2026-07-03 21:45:21 +02:00
jensandClaude Sonnet 5 698c019581 refactor: make ATemperatureSensor's temp observable directly on the sensor
TempSensorSim/TempSensor_max31865's temperature() now stores its
reading on self.temp, so ATemperatureSensor's inherited AttributeChange
(previously never triggered by anything) actually fires. TempSensorTask
no longer keeps its own shadow copy of the reading - it registers its
websocket-push callback on self.sensor directly and just drives the
read each tick; server/brewpi.py's TC-feeding registration moved from
sensor_task to sensor for the same reason.

Priming read happens before registering the callback (not after) since
all tasks are built synchronously at module level, before the asyncio
event loop starts - registering first would fire on_temp_changed's
asyncio.create_task() with no running loop.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GpePKZiEZWbGo9HrfuML6U
2026-07-02 22:03:50 +02:00
jensandClaude Sonnet 4.6 ca1953c9ee sensor: model real temp sensor noise in TempSensorSim
Replaces the opaque variance/√12 formula with two explicit noise components:

  sigma (default 0.05 °C) — white Gaussian noise, calibrated against the
  20260628T184903 Sud-0010 log (detrended hold-phase tick-to-tick std ≈ 0.053 °C).

  stirrer_sigma / stirrer_tau — optional AR(1) low-frequency component for
  stirrer-induced fluctuations (off by default); steady-state std equals
  stirrer_sigma, correlation time equals stirrer_tau ticks.

plant_factory.py updated to use sigma=0.05 instead of the old variance=0.01
(which gave std ≈ 0.003 °C — far too quiet).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 19:17:48 +02:00
jensandClaude Sonnet 4.6 f7355270c8 Extract shared factory dispatch into ComponentFactory base class
All four name-dispatch factories repeated the same if/elif lazy-import
pattern. Replace with a ComponentFactory base class holding a callable
registry and a _lazy() helper for the common import-and-construct case.
PlantFactory is an orchestrator, not a dispatcher, and is left as-is.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tqxrk8uj4M3w3d3eXm3xK8
2026-06-25 20:44:43 +02:00
jensandClaude Sonnet 4.6 17ca79da1a Simplify Pot: drop gain/theta params, seed initial temp from ambient
[Pot] - removed the gain (efficiency) factor and the separate
"theta" initial-temperature param; Pot now starts at theta_amb and
set_power()/get_power() operate on p_in directly. Added
set_ambient_temperature() for live ambient updates. Dropped the
now-unused "theta"/"gain" keys from Model/Plant in config.json.sim
and config.json.templ (also fixes a JSON syntax error in
config.json.templ: trailing commas left over after removing "gain"
made Model/Plant fail to parse).
[Sensor] - fix missing space in TempSensorSim.temperature()'s
offset/variance expression (cosmetic, no behavior change).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 18:32:28 +02:00
jensandClaude Sonnet 4.6 ac8de9da55 Add sensor variance config and smooth heat-rate estimate
[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>
2026-06-19 15:47:24 +02:00
jens fd99c548e1 - improved tempsensor exception 2021-10-19 11:50:27 +02:00
jens 04d93e0f98 - improved tempsensor exception 2021-10-19 11:48:34 +02:00
jens 3a5278c6b5 - improved tempsensor exception 2021-10-19 11:43:47 +02:00
jens a267e4004e - improved tempsensor exception 2021-10-19 11:42:52 +02:00
jens e07f9b4802 - preinitialize digits 2021-10-19 11:36:09 +02:00
jens 6e7f8c2c59 - removed AtemperatureSensor::process
- task is AttributeChange
- hareden against Tempsensor exceptions
2021-10-19 11:29:11 +02:00
jens 55315e268e - TempratureSensor: Sim ignores temp_offset 2021-10-12 16:36:53 +02:00
jens f7745f9814 - reactored 2021-10-02 11:05:07 +01:00
jens a05e460f73 - refactored 2021-10-02 11:01:12 +01:00
jens bf019733b2 - added abstarct PID APid
- added PidFactory
- use variable args for factory
2021-10-02 11:10:43 +02:00
jens 289ef47bb6 - changed gitignore
- make tempSensor Max31865 more robust against reading failures
- removed temp offset
2021-08-10 15:02:57 +01:00
jens ced04f184b Reduce debug log 2020-12-17 17:26:30 +00:00
jens 0cb958938f - added stirrer and hendi
- refactored
2020-12-16 16:52:32 +01:00
jens 834268c85e Improved Max31865 2020-12-15 11:11:25 +00:00
jens ad6ff61eba - added temp offset as argument 2020-12-14 20:18:17 +01:00
jens 7cac444424 Improved temp offset 2020-12-14 18:58:17 +00:00
jens 1ad33b488f - refactored temperature correction 2020-12-14 17:36:15 +01:00
jens 77dbca72ba - print out digits 2020-12-14 17:23:06 +01:00
jens 73b567363b - set temp offset to -1°C 2020-12-14 16:02:17 +01:00
jens 6b727e3ea4 Fixed Max31865 2020-12-14 08:42:27 +00:00
jens e2e6e24dcc - init base class 2020-12-14 09:39:54 +01:00
jens 6e1fb9702c Fixed import 2020-12-13 19:30:26 +01:00
jens 77649b3629 - fixed import of unknown modules 2020-12-13 19:23:53 +01:00
jens a74e1b573b - added max31865 2020-12-13 19:18:50 +01:00
jens 0633e464ca - refactored
- created TempSensorFactory
2020-12-13 16:21:08 +01:00
jens 5102ad935c - fixed water model 2020-11-29 19:12:17 +01:00
jens 135f2b6898 - cleaned up 2020-11-29 10:59:33 +01:00
jens 886d03deff - added AttributeChange 2020-11-29 10:56:43 +01:00
jens 625535d1fb - refactored 2020-11-28 11:52:11 +01:00
jens e867bd574e - fixed Kalman 2020-11-26 20:33:56 +01:00
jens 636070fd61 initial import 2020-11-24 18:34:47 +01:00