- refactored tasks

This commit is contained in:
jens
2020-12-17 14:45:43 +01:00
parent 5f1a8a94e0
commit fb37750ec7
7 changed files with 250 additions and 223 deletions
+5 -223
View File
@@ -1,234 +1,17 @@
import asyncio import asyncio
import abc
import json import json
from ws.server.ws_server_multi_user import WsServerMultiUser from ws.server.ws_server_multi_user import WsServerMultiUser
from components import ATemperatureSensor, AHeater, AStirrer
from components.sensor import TempSensorFactory from components.sensor import TempSensorFactory
from components.pid import TempController from components.pid import TempController
from components.plant import Pot, APlant from components.plant import Pot
from components.actor import HeaterFactory from components.actor import HeaterFactory
from ws.message import MsgIo, MessageDispatcher from tasks import TaskManager
from utils.value import ChangedFloat, ChangedInteger from ws.message import MessageDispatcher
from utils.value import ChangedFloat
from tasks import TempSensorTask, HeaterTask, PotTask, TcTask
DT_CTRL = 0.1 DT_CTRL = 0.1
class ATask:
def __init__(self, interval):
self.interval = interval
@abc.abstractmethod
def on_process(self):
pass
class TempSensorTask(ATask):
def __init__(self, sensor: ATemperatureSensor, interval, msg_handler: MsgIo):
ATask.__init__(self, interval)
self.msg_handler = msg_handler
msg_handler.set_recv_handler(self.recv)
self.sensor = sensor
def on_temp_changed(self, value):
asyncio.create_task(self.send({'Temp': value}))
async def recv(self, data):
print(data)
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))
temp = ChangedFloat(self.on_temp_changed, prec=1)
self.sensor.set_on_changed("temp", temp.set)
while True:
self.sensor.process()
await asyncio.sleep(self.interval)
class HeaterTask(ATask):
def __init__(self, heater: AHeater, interval, msg_handler: MsgIo):
ATask.__init__(self, interval)
self.heater = heater
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)
class PotTask(ATask):
def __init__(self, pot: APlant, interval, msg_handler: MsgIo):
ATask.__init__(self, interval)
self.msg_handler = msg_handler
msg_handler.set_recv_handler(self.recv)
self.plant = pot
def on_changed_power(self, value):
asyncio.create_task(self.send({'Power': value}))
def on_changed_temp(self, value):
asyncio.create_task(self.send({'Temp': value}))
async def recv(self, data):
print(data)
for key in data:
print(key)
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))
self.plant.set_on_changed('power_actual', ChangedInteger(self.on_changed_power).set)
self.plant.set_on_changed('temp', ChangedFloat(self.on_changed_temp, prec=1).set)
while True:
self.plant.process()
await asyncio.sleep(self.interval)
class TcTask(ATask):
def __init__(self, tc: TempController, interval, msg_handler: MsgIo):
ATask.__init__(self, interval)
self.tc = tc
self.msg_handler = msg_handler
msg_handler.set_recv_handler(self.recv)
def on_state_changed(self, value):
print ("State change to {}".format(value))
asyncio.create_task(self.send({'State': str(value)}))
def on_temp_soll_changed(self, value):
print ("Temp soll change to {}".format(value))
asyncio.create_task(self.send({'Soll': {'Temp': value}}))
def on_rate_soll_curr_changed(self, value):
print ("Rate soll change to {}".format(value))
asyncio.create_task(self.send({'Soll': {'Rate': {'Current': value}}}))
def on_rate_soll_set_changed(self, value):
print ("Rate soll change to {}".format(value))
asyncio.create_task(self.send({'Soll': {'Rate': {'Set': value}}}))
def on_temp_ist_changed(self, value):
print ("Temp ist change to {}".format(value))
asyncio.create_task(self.send({'Ist': {'Temp': value}}))
def on_rate_ist_changed(self, value):
print ("Rate ist change to {}".format(value))
asyncio.create_task(self.send({'Ist': {'Rate': value}}))
async def recv(self, msg):
print(msg)
for key in msg.keys():
if 'Soll' in key:
submsg = msg['Soll']
for subkey in submsg.keys():
if 'Temp' in subkey:
self.tc.set_theta_soll(submsg['Temp'])
if 'Rate' in subkey:
self.tc.set_heatrate_soll(submsg['Rate'])
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))
self.tc.set_on_changed('state', self.on_state_changed)
self.tc.set_on_changed('theta_ist', ChangedFloat(self.on_temp_ist_changed, prec=1).set)
self.tc.set_on_changed('heatrate_ist', ChangedFloat(self.on_rate_ist_changed, prec=1).set)
self.tc.set_on_changed('theta_soll_set', ChangedFloat(self.on_temp_soll_changed, prec=1).set)
self.tc.set_on_changed('heatrate_soll', ChangedFloat(self.on_rate_soll_curr_changed, prec=1).set)
self.tc.set_on_changed('heatrate_soll_set', ChangedFloat(self.on_rate_soll_set_changed, prec=1).set)
self.tc.set_theta_soll(20.0)
self.tc.set_heatrate_soll(1.0)
while True:
self.tc.process()
await asyncio.sleep(self.interval)
class TaskManager:
def __init__(self):
self.tasks = []
def add(self, task: ATask):
self.tasks.append(task)
def start(self):
funcs = []
for task in self.tasks:
funcs.append(task.on_process())
return asyncio.gather(*funcs)
async def asleep(time):
await asyncio.sleep(time)
if __name__ == '__main__': if __name__ == '__main__':
config = json.load(open("config.json")) config = json.load(open("config.json"))
dispatcher = MessageDispatcher() dispatcher = MessageDispatcher()
@@ -268,4 +51,3 @@ if __name__ == '__main__':
h_server = server.listen("0.0.0.0", 8765) h_server = server.listen("0.0.0.0", 8765)
asyncio.gather(h_dispatcher, h_server) asyncio.gather(h_dispatcher, h_server)
server.run_forever() server.run_forever()
+5
View File
@@ -0,0 +1,5 @@
from tasks.task import *
from tasks.tempsensor import *
from tasks.heater import *
from tasks.pot import *
from tasks.tempctrl import *
+74
View File
@@ -0,0 +1,74 @@
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)
+39
View File
@@ -0,0 +1,39 @@
import asyncio
from tasks import ATask
from components.plant import APlant
from ws.message import MsgIo
from utils.value import ChangedInteger, ChangedFloat
class PotTask(ATask):
def __init__(self, pot: APlant, interval, msg_handler: MsgIo):
ATask.__init__(self, interval)
self.msg_handler = msg_handler
msg_handler.set_recv_handler(self.recv)
self.plant = pot
def on_changed_power(self, value):
asyncio.create_task(self.send({'Power': value}))
def on_changed_temp(self, value):
asyncio.create_task(self.send({'Temp': value}))
async def recv(self, data):
print(data)
for key in data:
print(key)
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))
self.plant.set_on_changed('power_actual', ChangedInteger(self.on_changed_power).set)
self.plant.set_on_changed('temp', ChangedFloat(self.on_changed_temp, prec=1).set)
while True:
self.plant.process()
await asyncio.sleep(self.interval)
+26
View File
@@ -0,0 +1,26 @@
import abc
import asyncio
class ATask:
def __init__(self, interval):
self.interval = interval
@abc.abstractmethod
def on_process(self):
pass
class TaskManager:
def __init__(self):
self.tasks = []
def add(self, task: ATask):
self.tasks.append(task)
def start(self):
funcs = []
for task in self.tasks:
funcs.append(task.on_process())
return asyncio.gather(*funcs)
+70
View File
@@ -0,0 +1,70 @@
import asyncio
from tasks import ATask
from components.pid import TempController
from utils.value import ChangedFloat
from ws.message import MsgIo
class TcTask(ATask):
def __init__(self, tc: TempController, interval, msg_handler: MsgIo):
ATask.__init__(self, interval)
self.tc = tc
self.msg_handler = msg_handler
msg_handler.set_recv_handler(self.recv)
def on_state_changed(self, value):
print ("State change to {}".format(value))
asyncio.create_task(self.send({'State': str(value)}))
def on_temp_soll_changed(self, value):
print ("Temp soll change to {}".format(value))
asyncio.create_task(self.send({'Soll': {'Temp': value}}))
def on_rate_soll_curr_changed(self, value):
print ("Rate soll change to {}".format(value))
asyncio.create_task(self.send({'Soll': {'Rate': {'Current': value}}}))
def on_rate_soll_set_changed(self, value):
print ("Rate soll change to {}".format(value))
asyncio.create_task(self.send({'Soll': {'Rate': {'Set': value}}}))
def on_temp_ist_changed(self, value):
print ("Temp ist change to {}".format(value))
asyncio.create_task(self.send({'Ist': {'Temp': value}}))
def on_rate_ist_changed(self, value):
print ("Rate ist change to {}".format(value))
asyncio.create_task(self.send({'Ist': {'Rate': value}}))
async def recv(self, msg):
print(msg)
for key in msg.keys():
if 'Soll' in key:
submsg = msg['Soll']
for subkey in submsg.keys():
if 'Temp' in subkey:
self.tc.set_theta_soll(submsg['Temp'])
if 'Rate' in subkey:
self.tc.set_heatrate_soll(submsg['Rate'])
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))
self.tc.set_on_changed('state', self.on_state_changed)
self.tc.set_on_changed('theta_ist', ChangedFloat(self.on_temp_ist_changed, prec=1).set)
self.tc.set_on_changed('heatrate_ist', ChangedFloat(self.on_rate_ist_changed, prec=1).set)
self.tc.set_on_changed('theta_soll_set', ChangedFloat(self.on_temp_soll_changed, prec=1).set)
self.tc.set_on_changed('heatrate_soll', ChangedFloat(self.on_rate_soll_curr_changed, prec=1).set)
self.tc.set_on_changed('heatrate_soll_set', ChangedFloat(self.on_rate_soll_set_changed, prec=1).set)
self.tc.set_theta_soll(20.0)
self.tc.set_heatrate_soll(1.0)
while True:
self.tc.process()
await asyncio.sleep(self.interval)
+31
View File
@@ -0,0 +1,31 @@
import asyncio
from tasks import ATask
from components import ATemperatureSensor
from utils.value import ChangedFloat
from ws.message import MsgIo
class TempSensorTask(ATask):
def __init__(self, sensor_device: ATemperatureSensor, interval, msg_handler: MsgIo):
ATask.__init__(self, interval)
self.msg_handler = msg_handler
msg_handler.set_recv_handler(self.recv)
self.sensor = sensor_device
def on_temp_changed(self, value):
asyncio.create_task(self.send({'Temp': value}))
async def recv(self, data):
print(data)
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))
temp = ChangedFloat(self.on_temp_changed, prec=1)
self.sensor.set_on_changed("temp", temp.set)
while True:
self.sensor.process()
await asyncio.sleep(self.interval)