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 <noreply@anthropic.com>
This commit is contained in:
@@ -4,5 +4,5 @@ from components.factory import ComponentFactory, _lazy
|
|||||||
class HeaterFactory(ComponentFactory):
|
class HeaterFactory(ComponentFactory):
|
||||||
_registry = {
|
_registry = {
|
||||||
"sim": _lazy("components.actor.heater_sim", "HeaterSim"),
|
"sim": _lazy("components.actor.heater_sim", "HeaterSim"),
|
||||||
"Hendi": _lazy("components.actor.heater_hendi", "HeaterHendi"),
|
"hendi": _lazy("components.actor.heater_hendi", "HeaterHendi"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,33 +5,29 @@ from components.plant.pot_real import PotReal
|
|||||||
|
|
||||||
|
|
||||||
class PlantFactory:
|
class PlantFactory:
|
||||||
"""Builds the heater/pot/sensor trio together, as one consistent rig,
|
"""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).
|
|
||||||
|
|
||||||
Delegates the actual construction to HeaterFactory/TempSensorFactory
|
Each component's type comes from its own config section (Heater.type,
|
||||||
rather than importing HeaterHendi/TempSensor_max31865 directly, so
|
TempSensor.type) rather than a single plant_name key. The heater type
|
||||||
those classes' hardware-only deps (spidev, pyserial) stay lazily
|
determines sim vs real: sim gets Pot (modelled plant) and TempSensorSim;
|
||||||
imported - only actually needed when plant_name picks the real rig."""
|
anything else gets PotReal and whatever TempSensor.type names.
|
||||||
|
|
||||||
|
Delegates to HeaterFactory/TempSensorFactory so hardware-only deps
|
||||||
|
(spidev, pyserial) stay lazily imported."""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(plant_name, dt, heater_config, sensor_config=None):
|
def create(dt, heater_config, sensor_config=None):
|
||||||
sensor_config = sensor_config or {}
|
sensor_config = sensor_config or {}
|
||||||
if "sim" in plant_name:
|
heater_type = heater_config.get('type', 'sim')
|
||||||
heater = HeaterFactory.create("sim", heater_config)
|
plant_sim = (heater_type == 'sim')
|
||||||
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 = HeaterFactory.create("Hendi", heater_config)
|
heater = HeaterFactory.create(heater_type, heater_config)
|
||||||
pot = PotReal()
|
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 = {k: v for k, v in sensor_config.items() if k != 'type'}
|
||||||
sensor_params.setdefault('temp_offset', -0.15)
|
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
|
return heater, pot, sensor
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ambient_temperature": 20,
|
"ambient_temperature": 20,
|
||||||
"Controller" : {
|
"Controller" : {
|
||||||
"plant_name": "real",
|
|
||||||
"pid_type": "Smith"
|
"pid_type": "Smith"
|
||||||
},
|
},
|
||||||
"TempCtrl": {
|
"TempCtrl": {
|
||||||
|
|||||||
+2
-5
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ambient_temperature": 20,
|
"ambient_temperature": 20,
|
||||||
"Controller" : {
|
"Controller" : {
|
||||||
"plant_name": "sim",
|
|
||||||
"pid_type": "Smith"
|
"pid_type": "Smith"
|
||||||
},
|
},
|
||||||
"TempCtrl": {
|
"TempCtrl": {
|
||||||
@@ -34,12 +33,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Heater": {
|
"Heater": {
|
||||||
"port": "/dev/ttyUSB0",
|
"type": "sim"
|
||||||
"speed": "115200"
|
|
||||||
},
|
},
|
||||||
"Stirrer": {
|
"Stirrer": {
|
||||||
"port": "/dev/ttyACM0",
|
"type": "sim"
|
||||||
"speed": "115200"
|
|
||||||
},
|
},
|
||||||
"TempSensor": {
|
"TempSensor": {
|
||||||
"type": "sim",
|
"type": "sim",
|
||||||
|
|||||||
+7
-10
@@ -77,20 +77,17 @@ if __name__ == '__main__':
|
|||||||
DT = args.dt
|
DT = args.dt
|
||||||
DT_TASK = 1.0 / args.sim_warp_factor
|
DT_TASK = 1.0 / args.sim_warp_factor
|
||||||
theta_amb = config['ambient_temperature']
|
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
|
# Mash schedule - starts out empty; a client loads one of sude/*.json's
|
||||||
# several schedules onto it later (see components/sud.py's Sud).
|
# several schedules onto it later (see components/sud.py's Sud).
|
||||||
sud = Sud()
|
sud = Sud()
|
||||||
|
|
||||||
# Heater/Pot/Sensor - built together as one consistent rig by a single
|
# Heater/Pot/Sensor - built together as one consistent rig; each
|
||||||
# Controller.plant_name, rather than three independently-named
|
# component's type comes from its own config section. Heater.type==sim
|
||||||
# components that in practice are never actually mixed and matched
|
# gets HeaterSim/Pot (the modelled plant)/TempSensorSim; anything else
|
||||||
# (see components/plant/plant_factory.py): "sim" gets HeaterSim/Pot
|
# (e.g. hendi) gets HeaterHendi/PotReal/whatever TempSensor.type names.
|
||||||
# (the modeled plant)/TempSensorSim; anything else gets HeaterHendi/
|
heater, pot, sensor = PlantFactory.create(DT, config['Heater'], config.get('TempSensor', {}))
|
||||||
# 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', {}))
|
|
||||||
|
|
||||||
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)
|
||||||
@@ -123,7 +120,7 @@ if __name__ == '__main__':
|
|||||||
taskmgr.add(tc_task)
|
taskmgr.add(tc_task)
|
||||||
|
|
||||||
# Stirrer
|
# 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"))
|
stirrer_task = StirrerTask(stirrer, DT_TASK, dispatcher.msgio_get("Stirrer"))
|
||||||
taskmgr.add(stirrer_task)
|
taskmgr.add(stirrer_task)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user