config: seed plant params from Pot.water_mass at server startup
Sud._parse_data now falls through to pot_config for all hardware keys (mass, material, L, Td) — EMPTY_SUD no longer shadows them. brewpi.py seeds pot/tc plant params from Pot.water_mass on startup so the simulated plant is configured before any sud is loaded. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+4
-17
@@ -61,19 +61,6 @@ EMPTY_SUD = {
|
|||||||
'Name': '',
|
'Name': '',
|
||||||
'Description': '',
|
'Description': '',
|
||||||
'pot': {
|
'pot': {
|
||||||
'mass': 0,
|
|
||||||
'material': None,
|
|
||||||
# Pot energy loss coefficient [W/(kg*K)] and transport propagation
|
|
||||||
# delay [s] - see derive_plant_params(). Defaults match the generic
|
|
||||||
# values brewpi.py used to hardcode for every brew alike.
|
|
||||||
'L': 0.2,
|
|
||||||
'Td': 30,
|
|
||||||
# Initial grain_mass/water_mass - what's actually in the pot before
|
|
||||||
# the brew starts (e.g. water added but no malt yet), as opposed to
|
|
||||||
# default.step's pot.grain_mass/pot.water_mass, which is just inert
|
|
||||||
# template filler for steps that don't override it. Lets a caller
|
|
||||||
# derive starting plant params directly (see SudTask.recv()'s Load
|
|
||||||
# handler) without having to parse the first step out of the schedule.
|
|
||||||
'grain_mass': 0,
|
'grain_mass': 0,
|
||||||
'water_mass': 0,
|
'water_mass': 0,
|
||||||
},
|
},
|
||||||
@@ -123,10 +110,10 @@ class Sud(AttributeChange):
|
|||||||
pot_data = data.get('pot', {})
|
pot_data = data.get('pot', {})
|
||||||
pot_mass = pot_data.get('mass', pot_config.get('mass', 0))
|
pot_mass = pot_data.get('mass', pot_config.get('mass', 0))
|
||||||
pot_material = pot_data.get('material', pot_config.get('material'))
|
pot_material = pot_data.get('material', pot_config.get('material'))
|
||||||
L = pot_data.get('L', pot_config.get('L', EMPTY_SUD['pot']['L']))
|
L = pot_data.get('L', pot_config.get('L', 0.2))
|
||||||
Td = pot_data.get('Td', pot_config.get('Td', EMPTY_SUD['pot']['Td']))
|
Td = pot_data.get('Td', pot_config.get('Td', 30))
|
||||||
grain_mass = pot_data.get('grain_mass', EMPTY_SUD['pot']['grain_mass'])
|
grain_mass = pot_data.get('grain_mass', 0)
|
||||||
water_mass = pot_data.get('water_mass', EMPTY_SUD['pot']['water_mass'])
|
water_mass = pot_data.get('water_mass', 0)
|
||||||
|
|
||||||
return name, description, schedule, pot_mass, pot_material, L, Td, grain_mass, water_mass
|
return name, description, schedule, pot_mass, pot_material, L, Td, grain_mass, water_mass
|
||||||
|
|
||||||
|
|||||||
+10
-14
@@ -92,14 +92,6 @@ if __name__ == '__main__':
|
|||||||
sensor_task = TempSensorTask(sensor, DT_TASK, dispatcher.msgio_get("Sensor"))
|
sensor_task = TempSensorTask(sensor, DT_TASK, dispatcher.msgio_get("Sensor"))
|
||||||
taskmgr.add(sensor_task)
|
taskmgr.add(sensor_task)
|
||||||
|
|
||||||
# Pot - deliberately left without plant params (M/C/L/Td) here: a
|
|
||||||
# Sud's own doc is the only source for those now (see tasks/sud.py's
|
|
||||||
# SudTask.apply_plant_params(), called immediately on Load), so the
|
|
||||||
# simulated Pot stays inert (Pot.is_configured() is False, PotTask
|
|
||||||
# skips process() - see there) until one actually is loaded (PotReal
|
|
||||||
# just ignores this - see there). Ambient is independent of any Sud
|
|
||||||
# (a global setting, changeable live via the System channel - see
|
|
||||||
# on_system_recv() below), so it's set right away regardless.
|
|
||||||
pot.set_ambient_temperature(theta_amb)
|
pot.set_ambient_temperature(theta_amb)
|
||||||
taskmgr.add(PotTask(pot, DT_TASK, dispatcher.msgio_get("Pot")))
|
taskmgr.add(PotTask(pot, DT_TASK, dispatcher.msgio_get("Pot")))
|
||||||
|
|
||||||
@@ -107,18 +99,22 @@ if __name__ == '__main__':
|
|||||||
heater_task = HeaterTask(heater, DT_TASK, dispatcher.msgio_get("Heater"))
|
heater_task = HeaterTask(heater, DT_TASK, dispatcher.msgio_get("Heater"))
|
||||||
taskmgr.add(heater_task)
|
taskmgr.add(heater_task)
|
||||||
|
|
||||||
# Temperature Controller - PID gains are server/hardware-level
|
|
||||||
# config, independent of any Sud, so they're set right away; "Normal"
|
|
||||||
# has no internal model/ambient at all (see temp_controller.py vs.
|
|
||||||
# temp_controller_smith.py.), and Smith's model plant params are -
|
|
||||||
# like the real Pot's above - deliberately left unset here, only
|
|
||||||
# ever coming from a Sud's own doc.
|
|
||||||
tc = PidFactory.create(config['TempCtrl']['pid_type'], DT)
|
tc = PidFactory.create(config['TempCtrl']['pid_type'], DT)
|
||||||
tc.set_params(config['TempCtrl'])
|
tc.set_params(config['TempCtrl'])
|
||||||
tc.set_ambient_temperature(theta_amb)
|
tc.set_ambient_temperature(theta_amb)
|
||||||
tc_task = TcTask(tc, DT_TASK, dispatcher.msgio_get("TempCtrl"))
|
tc_task = TcTask(tc, DT_TASK, dispatcher.msgio_get("TempCtrl"))
|
||||||
taskmgr.add(tc_task)
|
taskmgr.add(tc_task)
|
||||||
|
|
||||||
|
# Seed plant params from config so pot/tc are configured before any sud
|
||||||
|
# is loaded - Pot.water_mass in config is how much water is already in
|
||||||
|
# the kettle at startup (e.g. strike water pre-filled). A loaded sud's
|
||||||
|
# own apply_plant_params() will override this on the first step.
|
||||||
|
startup_water = config.get('Pot', {}).get('water_mass', 0)
|
||||||
|
if startup_water > 0:
|
||||||
|
startup_params = sud.derive_plant_params(0, startup_water)
|
||||||
|
pot.set_plant_params(startup_params)
|
||||||
|
tc.set_model_plant_params(startup_params)
|
||||||
|
|
||||||
# Stirrer
|
# Stirrer
|
||||||
stirrer = StirrerFactory.create(config['Stirrer']['type'], DT, config['Stirrer'])
|
stirrer = StirrerFactory.create(config['Stirrer']['type'], DT, config['Stirrer'])
|
||||||
stirrer_task = StirrerTask(stirrer, DT_TASK, dispatcher.msgio_get("Stirrer"))
|
stirrer_task = StirrerTask(stirrer, DT_TASK, dispatcher.msgio_get("Stirrer"))
|
||||||
|
|||||||
Reference in New Issue
Block a user