From 0495e177c4ecfe6ffb467bf19cc2d2104cd700d5 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Tue, 30 Jun 2026 19:31:39 +0200 Subject: [PATCH] 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 --- components/actor/heaterFactory.py | 2 +- components/plant/plant_factory.py | 40 ++++++++++++++----------------- config-real.json.tpl | 1 - config-sim.json.tpl | 7 ++---- server/brewpi.py | 17 ++++++------- 5 files changed, 28 insertions(+), 39 deletions(-) diff --git a/components/actor/heaterFactory.py b/components/actor/heaterFactory.py index 59d0521..c5be150 100644 --- a/components/actor/heaterFactory.py +++ b/components/actor/heaterFactory.py @@ -4,5 +4,5 @@ from components.factory import ComponentFactory, _lazy class HeaterFactory(ComponentFactory): _registry = { "sim": _lazy("components.actor.heater_sim", "HeaterSim"), - "Hendi": _lazy("components.actor.heater_hendi", "HeaterHendi"), + "hendi": _lazy("components.actor.heater_hendi", "HeaterHendi"), } diff --git a/components/plant/plant_factory.py b/components/plant/plant_factory.py index 9404a14..1ecec0c 100644 --- a/components/plant/plant_factory.py +++ b/components/plant/plant_factory.py @@ -5,33 +5,29 @@ from components.plant.pot_real import PotReal class PlantFactory: - """Builds the heater/pot/sensor trio together, as one consistent rig, - rather than each picked independently via its own *_name config key - - sim and real hardware are never actually mixed and matched in - practice, so Controller.plant_name alone now decides all three (see - server/brewpi.py). + """Builds the heater/pot/sensor trio together as one consistent rig. - Delegates the actual construction to HeaterFactory/TempSensorFactory - rather than importing HeaterHendi/TempSensor_max31865 directly, so - those classes' hardware-only deps (spidev, pyserial) stay lazily - imported - only actually needed when plant_name picks the real rig.""" + Each component's type comes from its own config section (Heater.type, + TempSensor.type) rather than a single plant_name key. The heater type + determines sim vs real: sim gets Pot (modelled plant) and TempSensorSim; + anything else gets PotReal and whatever TempSensor.type names. + + Delegates to HeaterFactory/TempSensorFactory so hardware-only deps + (spidev, pyserial) stay lazily imported.""" @staticmethod - def create(plant_name, dt, heater_config, sensor_config=None): + def create(dt, heater_config, sensor_config=None): sensor_config = sensor_config or {} - if "sim" in plant_name: - heater = HeaterFactory.create("sim", heater_config) - pot = Pot(dt) - sensor_type = sensor_config.get('type', 'sim') - sensor_params = {k: v for k, v in sensor_config.items() if k != 'type'} - sensor_params.setdefault('temp_offset', -0.15) - sensor_params.setdefault('sigma', 0.05) - sensor = TempSensorFactory.create(sensor_type, **sensor_params) - return heater, pot, sensor + heater_type = heater_config.get('type', 'sim') + plant_sim = (heater_type == 'sim') - heater = HeaterFactory.create("Hendi", heater_config) - pot = PotReal() + heater = HeaterFactory.create(heater_type, heater_config) + pot = Pot(dt) if plant_sim else PotReal() + + sensor_type = sensor_config.get('type', 'sim') sensor_params = {k: v for k, v in sensor_config.items() if k != 'type'} sensor_params.setdefault('temp_offset', -0.15) - sensor = TempSensorFactory.create("max31865", **sensor_params) + if plant_sim: + sensor_params.setdefault('sigma', 0.05) + sensor = TempSensorFactory.create(sensor_type, **sensor_params) return heater, pot, sensor diff --git a/config-real.json.tpl b/config-real.json.tpl index f463cd8..8fa8fbf 100644 --- a/config-real.json.tpl +++ b/config-real.json.tpl @@ -1,7 +1,6 @@ { "ambient_temperature": 20, "Controller" : { - "plant_name": "real", "pid_type": "Smith" }, "TempCtrl": { diff --git a/config-sim.json.tpl b/config-sim.json.tpl index 627d2c1..db62fb8 100644 --- a/config-sim.json.tpl +++ b/config-sim.json.tpl @@ -1,7 +1,6 @@ { "ambient_temperature": 20, "Controller" : { - "plant_name": "sim", "pid_type": "Smith" }, "TempCtrl": { @@ -34,12 +33,10 @@ } }, "Heater": { - "port": "/dev/ttyUSB0", - "speed": "115200" + "type": "sim" }, "Stirrer": { - "port": "/dev/ttyACM0", - "speed": "115200" + "type": "sim" }, "TempSensor": { "type": "sim", diff --git a/server/brewpi.py b/server/brewpi.py index 32a0e18..bf09af1 100755 --- a/server/brewpi.py +++ b/server/brewpi.py @@ -77,20 +77,17 @@ if __name__ == '__main__': DT = args.dt DT_TASK = 1.0 / args.sim_warp_factor theta_amb = config['ambient_temperature'] - plant_sim = "sim" in config['Controller']['plant_name'] + plant_sim = config['Heater'].get('type', 'sim') == 'sim' # 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() - # Heater/Pot/Sensor - built together as one consistent rig by a single - # Controller.plant_name, rather than three independently-named - # components that in practice are never actually mixed and matched - # (see components/plant/plant_factory.py): "sim" gets HeaterSim/Pot - # (the modeled plant)/TempSensorSim; anything else gets HeaterHendi/ - # PotReal (no model - the real kettle does its own physics)/ - # TempSensor_max31865. - heater, pot, sensor = PlantFactory.create(config['Controller']['plant_name'], DT, config['Heater'], config.get('TempSensor', {})) + # Heater/Pot/Sensor - built together as one consistent rig; each + # component's type comes from its own config section. Heater.type==sim + # gets HeaterSim/Pot (the modelled plant)/TempSensorSim; anything else + # (e.g. hendi) gets HeaterHendi/PotReal/whatever TempSensor.type names. + heater, pot, sensor = PlantFactory.create(DT, config['Heater'], config.get('TempSensor', {})) sensor_task = TempSensorTask(sensor, DT_TASK, dispatcher.msgio_get("Sensor")) taskmgr.add(sensor_task) @@ -123,7 +120,7 @@ if __name__ == '__main__': taskmgr.add(tc_task) # Stirrer - stirrer = StirrerFactory.create(config['Controller']['stirrer_name'], DT, config['Stirrer']) + stirrer = StirrerFactory.create(config['Stirrer']['type'], DT, config['Stirrer']) stirrer_task = StirrerTask(stirrer, DT_TASK, dispatcher.msgio_get("Stirrer")) taskmgr.add(stirrer_task)