Commit Graph
14 Commits
Author SHA1 Message Date
jens de92559e31 added two new suds 2026-06-22 12:48:37 +02:00
jens df2be52298 Fix GuiTest.json: was neither small nor fast
Two compounding problems, found by actually running it:
- pot_mass=1/water_mass=1 (~2kg) is far lighter than the mass the real
  PID gains are tuned for (~30kg, matching the real recipes) - same
  heater power swings a 2kg pot far faster than the gains expect,
  causing massive overshoot (24 -> 37.5 instead of holding at 24).
  Fixed by using the same realistic mass as sud_0010.json/sud_0020.json.
- The overshoot then needed a passive cooldown back down to the next
  step's target - independent of any declared rate, governed by the
  plant's L/C time constant (~350 min here), regardless of mass.
  Removed the (now unnecessary, since the overshoot is gone) explicit
  cooldown step too.

Predicted/actual duration drops from ~408 min to ~18-21 min - verified
both via components/sud_forecast.py's estimator and a live run against
the real server (reaches DONE, no controller chattering).
2026-06-21 17:11:09 +02:00
jens cce662b794 Add sude/GuiTest.json - small, fast schedule for exercising the GUI
6 steps covering a plain ramp, a wait-for-confirm step, a plain hold,
a combined ramp+hold (up), a combined ramp+hold (down, exercises
COOL), and a final confirm - all small temperature deltas and 1-minute
holds so a full run finishes in well under a minute at typical warp
factors, for quickly cycling through Load/Start/Pause/Stop/restart
scenarios without waiting through a real brew.
2026-06-21 16:15:22 +02:00
jens 33195ff3cb sude: lower Einmaischen ramp rate from 1.8 to 1.5 °C/min 2026-06-21 14:59:22 +02:00
jens 194156f244 Move Sud step's target temperature from ramp.temp to step.temperature
A step's target temperature applies to the whole step (it's what a
ramp ramps to and what a hold then holds at), not just its ramp phase
- promote it from a nested "ramp": {"temp": ...} to a step-level
"temperature" field, defaulted like descr/grain_mass/etc. Updates all
consumers (Sud._build_step, SudTask, the GUI's forecast estimator,
demo_sud.py) and migrates sude/sud_0010.json and the README.
2026-06-21 09:47:45 +02:00
jens 9bd9889cb0 Allow a Sud step to combine a ramp and a hold
A step can now carry both 'ramp' and 'hold': it ramps to the target
temp, then holds there for the given duration, instead of needing two
separate schedule entries. Sud.temp_reached() switches such a step
from its ramp phase into its hold phase in place (re-firing the
step-changed callback so SudTask/demo_sud re-apply the hold's stirrer
settings); user_wait_for_continue still applies once the whole step -
both phases - is done.

Merges sud_0010.json's three ramp/hold pairs into combined steps.
2026-06-21 09:01:04 +02:00
jens 0e27c66fc7 Round-trip sud_0010.json through Sud.upload()/download()
Reformats it to json.dump()'s standard 2-space-free, ensure_ascii
output (from exercising the new upload feature against the real
schedule) and adds the matching downloaded copy. No schedule content
changed.
2026-06-20 22:43:17 +02:00
jensandClaude Sonnet 4.6 ac0f13897c Plot the Sud demo's plant M/C over the run
Adds a third figure tracking plant.M/plant.C alongside the existing
temperature/state plots, making the per-step mass changes (malt going
in, water boiling off) visible.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgR9tPaSzFkAwRAUyeaaCD
2026-06-20 07:56:28 +02:00
jensandClaude Sonnet 4.6 241a796ffa Make grain_mass/water_mass per-step and re-derive plant params on change
grain_mass and water_mass now live on each step (defaulted from
default.step) instead of being fixed for the whole brew, since both
change over a mash (malt going in, water boiling off).
Sud.derive_plant_params() takes them as arguments so it can be
recomputed per step; the demo re-applies the resulting M/C to both the
real plant and the controller's Smith-predictor model on every step
change via the new Pot.set_thermal_params()/
TempController.set_model_params().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgR9tPaSzFkAwRAUyeaaCD
2026-06-20 07:45:42 +02:00
jensandClaude Sonnet 4.6 123318ac85 Redesign Sud schedule format: separate ramp/hold keys with defaults
Steps now declare a "ramp" or "hold" key instead of a flat "type", and
unspecified fields (including nested stirrer settings) fall back to a
new top-level default.step structure. Stirrer config is now
interval_time/on_ratio, mapping directly onto AStirrer's cycle
time/duty cycle instead of separate on/off durations. Update
components/sud.py, tasks/sud.py, the Sud demo, sude/sud_0010.json, and
the README to match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgR9tPaSzFkAwRAUyeaaCD
2026-06-20 07:20:52 +02:00
jensandClaude Sonnet 4.6 b6551c6433 Derive Pot's M/C from pot/grain/water mass instead of hardcoding them
Add Sud.derive_plant_params(), which combines pot_mass/pot_material/
grain_mass/water_mass into a single lumped (mass, specific heat) pair
using approximate specific-heat constants for water, grain, and (by a
small material lookup table) the pot itself. demo_sud.py now builds
its plant_params from this instead of hardcoded C/M values, keeping
L/Td as the only manually-tuned plant parameters.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 19:34:15 +02:00
jensandClaude Sonnet 4.6 ace5054983 Update sample hold durations to realistic second values
Now that duration is correctly read as seconds, bump the sample
schedule's hold steps from the placeholder 30-40s to more realistic
200-400s.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 19:17:57 +02:00
jensandClaude Sonnet 4.6 b33f89a569 Adapt Sud/SudTask/demo to the new flat heat/hold schedule schema
sude/sud_0010.json moved from a list of combined ramp+hold+wait
"Rasten" with global stirrer constants to a flat "schedule" list of
explicit {"type": "heat"|"hold", ...} steps, each carrying its own
stirrer_speed/stirrer_time_on/stirrer_time_off and an optional
user_wait_for_continue (+ user_message).

- components/sud.py: Sud now tracks the current `step` instead of
  `rast`; "heat" steps enter RAMPING (advanced externally via
  temp_reached()), "hold" steps enter HOLDING and count down
  `duration` minutes (0 if omitted). Either step type can pause in
  WAIT_USER via user_wait_for_continue, surfaced through the new
  user_message attribute.
- tasks/sud.py: SudTask only pushes theta_soll/heatrate_soll on
  "heat" steps, converts each step's stirrer_time_on/off into a
  duty_cycle/cycle_time on every step change (replacing the old
  state-based RAMPING/HOLDING stirrer switching), and broadcasts
  user_message changes. Stirring is now fully schedule-driven instead
  of implicitly stopped on WAIT_USER/DONE (DONE still stops it, since
  there's no step left to read settings from).
- scripts/demos/sud/demo_sud.py: mirrors the same step-driven wiring.
- README's Mash schedules section rewritten for the new schema.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 19:09:43 +02:00
jens 4955fb073e - added sud #10 2022-06-30 18:31:05 +02:00