diff --git a/components/actor/heater_hendi.py b/components/actor/heater_hendi.py index e7671e6..74e557b 100644 --- a/components/actor/heater_hendi.py +++ b/components/actor/heater_hendi.py @@ -7,7 +7,6 @@ class HeaterHendi(AHeater): AHeater.__init__(self) self.hendi = HendiCtrl(params['port'], params['speed']) self.power_set = self.get_power_min() - self.is_active = False self.power_eff = 0 def get_power_min(self): @@ -19,21 +18,21 @@ class HeaterHendi(AHeater): return caps['pwr_watts_max'] def activate(self, enable): - self.is_active = enable - if not self.hendi.isRemoteEnable(): - self.hendi.remoteEnable(1) - if enable: - self.hendi.setSwitch(1) + self.hendi.remoteEnable(1) else: - self.hendi.setSwitch(0) + self.hendi.remoteEnable(0) def is_activated(self): - s = self.hendi.getSwitch() + s = self.hendi.isRemoteEnable() return '1' in s def process(self): - power = self.power_set if self.is_active else 0 + power = self.power_set + if power == 0: + self.hendi.setSwitch(0) + else: + self.hendi.setSwitch(1) self.hendi.setPowerWatts(power) self.power_eff = self.hendi.getPowerWatts() @@ -41,5 +40,4 @@ class HeaterHendi(AHeater): self.power_set = max(self.get_power_min(), min(self.get_power_max(), power)) def get_power(self): - result = self.hendi.getPowerWatts() - return result + return self.power_eff diff --git a/components/actor/stirrerpololu1376.py b/components/actor/stirrerpololu1376.py index ba8ceaa..34e6560 100644 --- a/components/actor/stirrerpololu1376.py +++ b/components/actor/stirrerpololu1376.py @@ -47,15 +47,13 @@ class StirrerPololu1376(AStirrer): return self.speed return 0 - def on_activate(self, enable): + def activate(self, enable): + print("activate {}".format(enable)) if enable: self.ser_send("go") - self.set_speed(self.speed) else: self.ser_send("X") - print("on_activate {}".format(enable)) - def on_set_speed(self, speed): self.ser_send("F" + str(int(speed)) + "%") print("Set speed to {} %".format(speed)) diff --git a/components/actor/stirrersim.py b/components/actor/stirrersim.py index 06d7522..2ac7af4 100644 --- a/components/actor/stirrersim.py +++ b/components/actor/stirrersim.py @@ -6,11 +6,8 @@ class StirrerSim(AStirrer): def __init__(self, params): AStirrer.__init__(self, params['dt']) - def __del__(self): - self.activate(False) - - def on_activate(self, enable): - print("on_activate {}".format(enable)) + def activate(self, enable): + print("activate {}".format(enable)) def get_speed(self): if self.isOn and self.is_activated(): diff --git a/components/aheater.py b/components/aheater.py index c8fefe4..48de37b 100644 --- a/components/aheater.py +++ b/components/aheater.py @@ -1,5 +1,6 @@ import abc from utils.value import AttributeChange +from contextlib import contextmanager class AHeater(AttributeChange): @@ -14,6 +15,16 @@ class AHeater(AttributeChange): def get_power_max(self): pass + @contextmanager + def open(self): + try: + self.activate(True) + yield None + finally: + self.activate(False) + + return None + @abc.abstractmethod def activate(self, enable): return None diff --git a/components/aplant.py b/components/aplant.py index 6b13438..ca89e46 100644 --- a/components/aplant.py +++ b/components/aplant.py @@ -1,15 +1,30 @@ import abc from utils.value import AttributeChange +from contextlib import contextmanager class APlant(AttributeChange): def __init__(self): AttributeChange.__init__(self) + @contextmanager + def open(self): + try: + self.activate(True) + yield None + finally: + self.activate(False) + + return None + @abc.abstractmethod def activate(self, enable): return None + @abc.abstractmethod + def is_activated(self): + return None + @abc.abstractmethod def process(self): pass diff --git a/components/astirrer.py b/components/astirrer.py index 3ed13a7..687d1ea 100644 --- a/components/astirrer.py +++ b/components/astirrer.py @@ -1,5 +1,6 @@ import abc from utils.value import AttributeChange +from contextlib import contextmanager class AStirrer(AttributeChange): @@ -11,7 +12,6 @@ class AStirrer(AttributeChange): self.dutyCycle = 1 self.cycleCounter = 0 self.isOn = 1 - self.is_active = False def process(self): isOn = self.isOn @@ -51,14 +51,21 @@ class AStirrer(AttributeChange): def on_set_speed(self, speed): pass + @contextmanager + def open(self): + try: + self.activate(True) + yield None + finally: + self.activate(False) + + return None + @abc.abstractmethod - def on_activate(self, enable): + def activate(self, enable): pass - def activate(self, enable): - self.is_active = enable - self.on_activate(enable) - + @abc.abstractmethod def is_activated(self): - return self.is_active + pass diff --git a/components/plant/pot.py b/components/plant/pot.py index 18c740e..2e25c82 100644 --- a/components/plant/pot.py +++ b/components/plant/pot.py @@ -35,6 +35,9 @@ class Pot(APlant): leak = 1/self.M * self.L * (self.theta_amb - self.temp)/self.theta_amb self.temp += (self.power_actual / (self.M * self.C) + leak) * self.dt + def is_activated(self): + return True + def set_power(self, power): self.power_set = power diff --git a/tasks/heater.py b/tasks/heater.py index 43f2846..16ce4d1 100644 --- a/tasks/heater.py +++ b/tasks/heater.py @@ -6,10 +6,10 @@ from utils.value import ChangedInteger class HeaterTask(ATask): - def __init__(self, heater_device: AHeater, interval, msg_handler: MsgIo): + def __init__(self, device: AHeater, interval, msg_handler: MsgIo): ATask.__init__(self, interval) - self.heater = heater_device + self.device = device self.interval = interval self.msg_handler = msg_handler msg_handler.set_recv_handler(self.recv) @@ -17,7 +17,7 @@ class HeaterTask(ATask): self.pulse_counter = 0 def actor(self, y): - self.power_soll = max(0, 250 + self.heater.get_power_max() * y) + self.power_soll = max(0, 250 + self.device.get_power_max() * y) def on_changed_active(self, is_activated): asyncio.create_task(self.send({'Activate': int(is_activated)})) @@ -29,45 +29,42 @@ class HeaterTask(ATask): for pair in data.items(): if 'Power' in pair[0]: self.power_soll = pair[1] - if 'Activate' in pair[0]: - self.heater.activate(pair[1] == 1) async def send(self, data): await self.msg_handler.send(data) async def on_process(self): print("{}: Started with interval {} s".format(self.msg_handler.get_key(), self.interval)) - await self.send({'Capabilities': {'Power': {'Min': 0, 'Max': self.heater.get_power_max()}}}) + await self.send({'Capabilities': {'Power': {'Min': 0, 'Max': self.device.get_power_max()}}}) - self.heater.set_on_changed('is_active', ChangedInteger(self.on_changed_active).set) - self.heater.set_on_changed('power_eff', ChangedInteger(self.on_changed_power).set) - self.heater.activate(False) + self.device.set_on_changed('power_eff', ChangedInteger(self.on_changed_power).set) pulse_period_s = 1 pulse_period_count = pulse_period_s/self.interval - while True: - if self.power_soll < self.heater.get_power_min(): - self.heater.set_power(self.heater.get_power_min()) - self.heater.activate(False) - else: - self.heater.set_power(self.power_soll) - self.heater.activate(True) + with self.device.open(): + while True: + if self.power_soll < self.device.get_power_min(): + self.device.set_power(self.device.get_power_min()) + self.device.activate(False) + else: + self.device.set_power(self.power_soll) + self.device.activate(True) - on_count = pulse_period_count - if self.heater.get_power_min() > 0: - on_count = pulse_period_count*min(1, self.power_soll/self.heater.get_power_min()) + on_count = pulse_period_count + if self.device.get_power_min() > 0: + on_count = pulse_period_count*min(1, self.power_soll / self.device.get_power_min()) - self.pulse_counter += 1 - if self.pulse_counter >= pulse_period_count: - self.pulse_counter = 0 + self.pulse_counter += 1 + if self.pulse_counter >= pulse_period_count: + self.pulse_counter = 0 - if self.pulse_counter < on_count: - self.heater.activate(True) - else: - self.heater.activate(False) + if self.pulse_counter < on_count: + self.device.activate(True) + else: + self.device.activate(False) - self.heater.process() - await asyncio.sleep(self.interval) + self.device.process() + await asyncio.sleep(self.interval) diff --git a/tasks/stirrer.py b/tasks/stirrer.py index fa0d81c..43c4afa 100644 --- a/tasks/stirrer.py +++ b/tasks/stirrer.py @@ -21,9 +21,6 @@ class StirrerTask(ATask): def on_cycletime_changed(self, value): asyncio.create_task(self.send({'CycleTime': value})) - def on_changed_active(self, is_activated): - asyncio.create_task(self.send({'Activate': int(is_activated)})) - async def recv(self, data): for pair in data.items(): if 'Speed' in pair[0]: @@ -39,12 +36,12 @@ class StirrerTask(ATask): self.device.set_on_changed("speed", self.on_speed_changed) self.device.set_on_changed("dutyCycle", self.on_dutycycle_changed) self.device.set_on_changed("cycleTime", self.on_cycletime_changed) - self.device.set_on_changed('is_active', ChangedInteger(self.on_changed_active).set) self.device.set_speed(50.0) self.device.set_cycle_time(10.0) self.device.set_duty_cycle(1.0) - while True: - self.device.process() - await asyncio.sleep(self.interval) + with self.device.open(): + while True: + self.device.process() + await asyncio.sleep(self.interval)