Add a simulation-based Sud forecast, computed server-side
New components/sud_forecast.py: SudForecastEstimator simulates a whole
schedule with the same kind of plant/controller (and the same
configured params - ambient, plant params, pid_type, TempCtrl gains,
heater max power) the server uses for real, by driving a throwaway
Sud/Pot/controller trio through it exactly as tasks/sud.py's SudTask
would. It's pure CPU-bound iteration (no real time/IO), so a multi-
hour brew simulates in well under a second.
tasks/sud.py: SudTask now takes an optional forecast_estimator and
sends its result ({'Forecast': {'T': ..., 'Theta': ...}}) on the Sud
channel after every successful Save/Load, run in a worker thread via
run_in_executor so the ~100-500ms simulation doesn't stall the other
tasks. server/brewpi.py constructs one with the real server's config
and wires it in; AmbientTemp changes update it too.
client/brewpi_gui.py: the quick naive show_schedule() estimate (drawn
immediately on Load, before the server's simulation finishes) is now
superseded by show_precomputed_course() once the Forecast message
arrives - only while not actively running, so it doesn't fight the
dynamic re-anchored view.
Verified: matches a standalone run of the estimator (177 min for
sude/sud_0010.json) and replaces the old naive 164 min estimate live
within a couple seconds of loading.
This commit is contained in:
+8
-1
@@ -12,6 +12,7 @@ from components.pid import PidFactory
|
||||
from components.plant import Pot
|
||||
from components.actor import HeaterFactory, StirrerFactory
|
||||
from components.sud import Sud
|
||||
from components.sud_forecast import SudForecastEstimator
|
||||
from tasks import TaskManager, TempSensorTask, HeaterTask, PotTask, TcTask, StirrerTask, TracerTask, SudTask
|
||||
from tracer import Tracer
|
||||
|
||||
@@ -103,7 +104,12 @@ if __name__ == '__main__':
|
||||
# Mash schedule - starts out empty; a client loads one of sude/*.json's
|
||||
# several schedules onto it later (see components/sud.py's Sud).
|
||||
sud = Sud()
|
||||
taskmgr.add(SudTask(sud, tc, stirrer, pot, DT, DT_TASK, dispatcher.msgio_get("Sud")))
|
||||
# Predicts how long a loaded schedule will actually take, by simulating
|
||||
# it with the same kind of plant/controller (and params) as above -
|
||||
# see components/sud_forecast.py.
|
||||
forecast_estimator = SudForecastEstimator(
|
||||
DT, theta_amb, DEFAULT_PLANT_PARAMS, config['Controller']['pid_type'], config['TempCtrl'], heater.get_power_max())
|
||||
taskmgr.add(SudTask(sud, tc, stirrer, pot, DT, DT_TASK, dispatcher.msgio_get("Sud"), forecast_estimator))
|
||||
|
||||
# Tracer
|
||||
taskmgr.add(TracerTask(sensor, heater, tc, trace_tc, DT_TASK_TRACER, dispatcher.msgio_get("Tracer")))
|
||||
@@ -141,6 +147,7 @@ if __name__ == '__main__':
|
||||
pot.set_ambient_temperature(theta_amb)
|
||||
if hasattr(tc, 'set_ambient_temperature'):
|
||||
tc.set_ambient_temperature(theta_amb)
|
||||
forecast_estimator.set_ambient_temperature(theta_amb)
|
||||
await msg_system.send({'AmbientTemp': theta_amb})
|
||||
msg_system.set_recv_handler(on_system_recv)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user