import asyncio from tasks import ATask from components import AHeater from ws.message import MsgIo from utils.value import ChangedInteger class HeaterTask(ATask): def __init__(self, heater_device: AHeater, interval, msg_handler: MsgIo): ATask.__init__(self, interval) self.heater = heater_device self.interval = interval self.msg_handler = msg_handler msg_handler.set_recv_handler(self.recv) self.power_soll = 0 self.pulse_counter = 0 def actor(self, y): self.power_soll = max(0, 250 + self.heater.get_power_max() * y) def on_changed_active(self, is_activated): asyncio.create_task(self.send({'Activate': int(is_activated)})) def on_changed_power(self, power): asyncio.create_task(self.send({'Power': power})) async def recv(self, data): print(data) for pair in data.items(): if 'Power' in pair[0]: self.power_soll = pair[1] if 'Activate' in pair[0]: self.heater.activate(bool(pair[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()}}}) 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) 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) 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()) 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) self.heater.process() await asyncio.sleep(self.interval)