docs: refresh README for this session's accumulated changes
- Architecture diagram: add client/user_config.py and components/sud_forecast.py; note the pid/ controllers' 4-state FSM (IDLE/HEAT/HOLD/COOL) and master enabled switch; expand the GUI client's description (ambient temp, controller enable, pot reset, Sud New/Load/Save/Start/Pause/Stop, forecast plot). - Mash schedules: document Start's restart-from-finished behavior, Pause's freeze-and-resume semantics, and the temperature controller's enabled lifecycle (SudTask owns it during a run, off by default otherwise, GUI checkbox for manual mode). - Fix sude/'s "heat"/"hold" wording to the actual "ramp"/"hold" keys; add matplotlib (demos-only) to the server requirements list. - Logging & analysis: mention the text log alongside the .mat traces.
This commit is contained in:
@@ -23,14 +23,33 @@ client/brewpi_gui.py PyQt5 desktop client (brewpi.ui) that connects
|
||||
to the server's WebSocket, displays live
|
||||
temperature/power/state, and lets the user set
|
||||
target temperature, heat rate, stirrer speed,
|
||||
and switch the heater/stirrer on or off.
|
||||
ambient temperature, and switch the heater/
|
||||
stirrer/temperature controller on or off (plus
|
||||
a "reset Pot to ambient" button, shown only
|
||||
when the server's plant is simulated) - plus
|
||||
Sud control (New/Load/Save/Start/Pause/Stop)
|
||||
and its forecast plot on the Automatic tab.
|
||||
client/user_config.py Small JSON-backed key/value store
|
||||
(~/.config/brewpi/gui.json) for GUI preferences
|
||||
that should survive restarts (last Sud file
|
||||
dialog directory, last ambient temperature) -
|
||||
distinct from the server's config.json and
|
||||
from sude/*.json schedules.
|
||||
|
||||
components/ Pluggable building blocks behind factories:
|
||||
pid/ temperature controllers: plain PID
|
||||
("Normal") or PID + Smith predictor
|
||||
("Smith", runs two internal pot models —
|
||||
one with the plant's transport delay, one
|
||||
without — to compensate for the dead time)
|
||||
without — to compensate for the dead time).
|
||||
Both are a 4-state FSM (IDLE/HEAT/HOLD/COOL)
|
||||
with a master enabled switch - IDLE means
|
||||
disabled (output forced to 0); COOL handles
|
||||
a target below the current temperature with
|
||||
its own gains, output forced to 0 only by
|
||||
the actuator that can't act on it (e.g. a
|
||||
heat-only heater), not by the controller
|
||||
assuming it can't cool
|
||||
plant/ pot thermal model (transport-delay line)
|
||||
used in simulation
|
||||
sensor/ temperature sensors: simulated, or a real
|
||||
@@ -42,6 +61,11 @@ components/ Pluggable building blocks behind factories:
|
||||
a client loads one of several sude/*.json
|
||||
schedules onto it and it drives the
|
||||
temperature controller from it
|
||||
sud_forecast.py predicts how long a loaded schedule will
|
||||
actually take by simulating it with the
|
||||
same kind of plant/controller (and params)
|
||||
as the real server - see "Forecast vs.
|
||||
actual duration" below
|
||||
|
||||
tasks/ Async tasks (one per component) that poll
|
||||
hardware/sim state at a fixed interval and
|
||||
@@ -63,7 +87,7 @@ scripts/demos/ Standalone, eyeballed-plot demos (matplotlib)
|
||||
`python -m scripts.demos.sud.demo_sud`.
|
||||
|
||||
sude/ Mash schedules ("Sud" = brew/wort), each a
|
||||
JSON list of "heat"/"hold" steps with target
|
||||
JSON list of "ramp"/"hold" steps with target
|
||||
temperature/heat rate or hold duration,
|
||||
per-step stirrer timing, and optional pause
|
||||
for user confirmation.
|
||||
@@ -92,8 +116,9 @@ commands back on (e.g. `{"TempCtrl": {"Soll": {"Temp": 65}}}`).
|
||||
## Requirements
|
||||
|
||||
- Python 3.8+
|
||||
- Server (`server/requirements.txt`): `numpy`, `scipy`, `websockets`, `dpath`,
|
||||
and `pyserial`/`spidev` if using real hardware backends.
|
||||
- Server (`server/requirements.txt`): `numpy`, `scipy`, `matplotlib` (only
|
||||
for `scripts/demos/*`, not the running server itself), `websockets`,
|
||||
`dpath`, and `pyserial`/`spidev` if using real hardware backends.
|
||||
- Client (`client/requirements.txt`): `PyQt5`.
|
||||
|
||||
Install with:
|
||||
@@ -183,11 +208,18 @@ controller's `theta_soll`/`heatrate_soll` from ramp steps (advancing once
|
||||
`on_ratio` map directly onto the stirrer's cycle time/duty cycle). It
|
||||
exposes progress (current step, remaining hold time, state, any
|
||||
`user_message`) on the `"Sud"` WebSocket channel and accepts
|
||||
`{"Sud": {"Start": true}}` to begin the schedule and
|
||||
`{"Sud": {"Confirm": true}}` to acknowledge a pause and move to the next
|
||||
step. With no schedule loaded (or all its steps run), it just sits idle -
|
||||
manual `theta_soll`/`heatrate_soll` control via the GUI works the same as
|
||||
ever.
|
||||
`{"Sud": {"Start": true}}` to begin the schedule (also restarts one that's
|
||||
already finished), `{"Sud": {"Pause": true}}` to freeze progress without
|
||||
losing it, and `{"Sud": {"Confirm": true}}` to acknowledge a pause and move
|
||||
to the next step.
|
||||
|
||||
The temperature controller has a master enabled switch (off by default -
|
||||
see `components/pid/temp_controller_base.py`): `SudTask` enables it for as
|
||||
long as a run is in progress (any state other than idle/finished) and
|
||||
disables it again - forcing the heater output to 0 - the moment it stops or
|
||||
finishes, handing control back to manual mode. The GUI's Manual tab has an
|
||||
"Enabled" checkbox for driving this directly outside of a Sud run; while
|
||||
disabled, its temperature/heat-rate setpoint controls are inactive.
|
||||
|
||||
### Forecast vs. actual duration
|
||||
|
||||
@@ -229,3 +261,8 @@ controller chatter in and out of `COOL` and never actually converge).
|
||||
(temperatures, heat rates, heater power) to `logs/*.mat` files, which can be
|
||||
loaded in MATLAB/Octave — see `results.m` and `results_tc.m` — to evaluate
|
||||
and tune the controller.
|
||||
|
||||
`server/brewpi.py` also mirrors everything it prints (every component's
|
||||
`print()`-based status/debug output) to a plain text log,
|
||||
`logs/brewpi.<timestamp>.log`, alongside the `.mat` traces - useful for
|
||||
post-mortems without needing to have been watching the console live.
|
||||
|
||||
Reference in New Issue
Block a user