Commit Graph
66 Commits
Author SHA1 Message Date
jensandClaude Sonnet 5 0877e7754b fix: guard HeaterHendi/StirrerPololu1376 activate() against comm errors
Live-testing on the brewpi Pi found that a connected-but-unresponsive
device (e.g. the hendi sitting in its ungraceful-disconnect lockout, see
docs/hendi_lockout_findings.md) crashed the whole server: activate() -
called both from HeaterTask's `with device.open():` and from a client's
Connect/Disconnect command - raised uncaught, escaping the gathered task
and killing the entire asyncio.gather in TaskManager.start().

activate()/is_activated()/process() on both real actors now catch comm
exceptions and self-heal via disconnect() (the same path a genuine
unplug already takes), instead of letting the exception propagate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YaPLuRPpyjWcwhMvCvpHCL
2026-07-03 19:39:07 +02:00
jensandClaude Sonnet 5 f20e617d81 feat: add connect/disconnect status for real heater/stirrer hardware
Heater and Stirrer can be real serial hardware (hendi, Pololu1376), but
there was no connection concept at all - the constructors opened the
port and crashed the whole server if the device was missing, with no
way to see connection status or firmware version and no way to
reconnect without a restart.

Adds an observable Connectable mixin (components/connectable.py) shared
by AHeater/AStirrer; real devices defer opening the serial port to an
explicit connect(), auto-connect on server startup, and surface
Connected/FirmwareVersion/Simulated plus manual Connect/Disconnect over
the web GUI. Heating/stirring and Sud Start are all gated on connection
state, and a disconnect mid-brew force-stops the run via the same path
as a manual Stop.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YaPLuRPpyjWcwhMvCvpHCL
2026-07-03 19:18:59 +02:00
jensandClaude Sonnet 5 75a886950c refactor: collect hendi firmware images under firmware/hendi_ctrl/
Moves components/actor/HendiCtrl.srec (v1.12) alongside the v1.14/
v1.15 images gathered during lockout testing, all under one versioned
naming scheme (hendi_ctrl_0112/0114/0115.srec) instead of scattered
across the repo root and components/actor/.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GpePKZiEZWbGo9HrfuML6U
2026-07-02 18:58:32 +02:00
jensandClaude Sonnet 5 5bc278e875 feat: add --debug tracing to hendi_ctrl_app.py, document v1.16 fix
HendiCtrl.cmd() previously raised a bare "Communication error" for any
non-OK response, discarding the firmware's actual reply. It now
includes the raw echo/answer bytes, and --debug prints every
request/response. Using this, the rejected R1 during lockout turned
out to be an explicit "ERR:Invalid state" reply, not a timeout.

Also flashed and retested v1.16: plain reconnect (no --reset) now
recovers from the lockout reliably (4/4 trials), fixing the
intermittent behavior seen on v1.15.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GpePKZiEZWbGo9HrfuML6U
2026-07-02 18:44:00 +02:00
jensandClaude Sonnet 5 5522b9c491 refactor: move hendiCtrl.py's main() into scripts/hendi_ctrl_app.py
hendiCtrl.py is now import-only. The new CLI app exposes serial
port/baudrate, version/capability info, converter test, heater test,
and firmware update as separate flags, instead of one fixed script.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GpePKZiEZWbGo9HrfuML6U
2026-07-02 17:02:21 +02:00
jens 1bcabb0ccc added firmware info to hendi and motor driver 2026-07-02 16:33:37 +02:00
jensandClaude Sonnet 4.6 0495e177c4 refactor: replace plant_name with per-component type keys in config
PlantFactory.create() no longer takes plant_name; sim vs real is derived
from Heater.type. StirrerFactory is wired from Stirrer.type. HeaterFactory
registry key lowercased to "hendi" to match config. Controller.plant_name
removed from both config templates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 19:31:39 +02:00
jens 801e9809a6 hendiCtrl: fixed graceful close 2026-06-30 18:59:33 +02:00
jensandClaude Sonnet 4.6 5751d26873 server: graceful Ctrl-C shutdown; HendiCtrl closes connection cleanly
On KeyboardInterrupt, brewpi.py cancels all asyncio tasks (letting
HeaterTask's `with device.open()` finally block run), then calls
heater.close() as belt-and-suspenders before closing the event loop.

On shutdown HeaterHendi.activate(False) now sets the switch to 0 instead
of disabling remote control, so the Hendi stays in remote mode at 0 W
rather than dropping back to its local panel state.  HendiCtrl.close()
does the same (setSwitch(0)) then closes the serial port.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 18:26:54 +02:00
jens 29dd5267a9 - fixed hendiCtrl exceptions 2026-06-30 17:05:43 +02:00
jens 8ca4e4d803 fixed duplicate class declaration 2026-06-30 16:38:51 +02:00
jens 6547478d00 HendiCtrl: better Exceptions 2026-06-30 16:22:06 +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 740fe8eee9 Remove debug prints from HeaterFactory
print(**kwargs) crashes at runtime since print doesn't accept
arbitrary keyword arguments. Both debug lines were leftover scaffolding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tqxrk8uj4M3w3d3eXm3xK8
2026-06-25 20:17:42 +02:00
jensandClaude Sonnet 4.6 ca0a014ffb Remove leftover debug prints from StirrerSim and TempControllerBase
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgR9tPaSzFkAwRAUyeaaCD
2026-06-20 07:29:02 +02:00
jens bd63f2648c - refactored hendi_ctrl
- fixed hend_heater
- added workaround for typedDict and Python < v3.8
2021-10-19 06:32:45 +01:00
jens 9b997b8348 - generalized heaters 2021-10-18 14:32:56 +02:00
jens f085e74c53 - stirrer: removed status logs 2021-10-02 12:36:48 +02:00
jens cf40a49af4 - changed import
- changed shebang
2021-10-02 10:12:54 +01:00
jens bf019733b2 - added abstarct PID APid
- added PidFactory
- use variable args for factory
2021-10-02 11:10:43 +02:00
jens 0843f1d87a - Pololu1376: take enums as variable id
- stirrerPololu1376: Make for robust against motor cable plug
2021-08-12 20:13:47 +01:00
jens ebd5d4cd5e - added dignostic vars
- make print_vars a method
2021-08-12 09:48:06 +02:00
jens a95f5195d1 - made on-methods private
- added AStirrer::_on_process() for monitoring
2021-08-12 09:32:02 +02:00
jens 71b5ac848f - refactored 2021-08-11 18:00:35 +02:00
jens 4cb8089c06 - fixed stirrerpololu1376.py 2021-08-11 17:59:07 +02:00
jens 6196f944c6 - use new Pololu driver 2021-08-11 17:49:37 +02:00
jens a291c654c8 - formatted 2021-08-11 17:36:47 +02:00
jens 593b003cd9 - added separation line 2021-08-11 16:34:02 +01:00
jens 89112777e3 - fixed variable display 2021-08-11 16:24:42 +01:00
jens 7a8368d9b9 - read variables 2021-08-11 15:59:06 +01:00
jens 11f3ff6743 - improved commands 2021-08-11 15:16:30 +01:00
jens 3299b47def - parse responses improved with exceptions 2021-08-11 16:15:21 +02:00
jens afd63c6505 - parse responses 2021-08-11 16:07:24 +02:00
jens 5322854e9a - added Pololu 1376 driver 2021-08-11 15:57:58 +02:00
jens 3a8445fce1 - ommit dt 2020-12-22 11:14:21 +01:00
jens d777a955a4 - refactored dt 2020-12-22 10:26:56 +01:00
jens a20de855ac - set heater power to zero at startup 2020-12-19 16:47:01 +01:00
jens 4908936728 - fixed heater sim power 2020-12-18 19:30:31 +01:00
jens c8660ca60e - fixed hendi power 2020-12-18 17:03:17 +01:00
jens 1cfcd76c0b - fixed hendi power 2020-12-18 16:37:37 +01:00
jens 4e508c86c5 - redefine activate method
- for task introduced open() conext method
2020-12-18 15:58:02 +01:00
jens a3510ffe8f - hendi: remote enable on activate 2020-12-17 21:57:02 +01:00
jens 850ad6c88c - hendi: remote enable on activate 2020-12-17 21:53:28 +01:00
jens eb9d7f5159 - fixed init order 2020-12-17 21:48:41 +01:00
jens 3b059181c5 - import hendiCtrl 2020-12-17 21:46:23 +01:00
jens 292d946393 - fixed hendi power 2020-12-17 21:39:09 +01:00
jens 7650acd808 - Pololu1376 doesn't accept fractional speeds 2020-12-17 19:06:28 +01:00
jens 3e0dd029e7 - fixed stirrer set speed after activate 2020-12-17 18:10:00 +01:00
jens 67ec9e6e07 Fixed stirrer beahvior 2020-12-17 17:01:46 +00:00
jens 4c4373d49a - fixed stirrer test 2020-12-17 17:50:58 +01:00