diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 6468dfe..bb49fd2 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1 +1 @@ -__version__ = "4.0.0.18" \ No newline at end of file +__version__ = "4.0.0.19" \ No newline at end of file diff --git a/cbpi/api/base.py b/cbpi/api/base.py index 47830a7..d56ef43 100644 --- a/cbpi/api/base.py +++ b/cbpi/api/base.py @@ -23,6 +23,9 @@ class CBPiBase(metaclass=ABCMeta): def get_kettle(self,id): return self.cbpi.kettle.find_by_id(id) + def get_kettle_target_temp(self,id): + return self.cbpi.kettle.find_by_id(id).get("target_temp") + async def set_target_temp(self,id, temp): await self.cbpi.kettle.set_target_temp(id, temp) diff --git a/cbpi/api/kettle_logic.py b/cbpi/api/kettle_logic.py index f4a6af9..be183a1 100644 --- a/cbpi/api/kettle_logic.py +++ b/cbpi/api/kettle_logic.py @@ -1,3 +1,4 @@ +from cbpi.api.base import CBPiBase from cbpi.api.extension import CBPiExtension from abc import ABCMeta import logging @@ -5,23 +6,18 @@ import asyncio -class CBPiKettleLogic(metaclass=ABCMeta): +class CBPiKettleLogic(CBPiBase, metaclass=ABCMeta): def __init__(self, cbpi, id, props): self.cbpi = cbpi self.id = id self.props = props - self.logger = logging.getLogger(__file__) - self.data_logger = None self.state = False self.running = False def init(self): pass - def log_data(self, value): - self.cbpi.log.log_data(self.id, value) - async def run(self): self.state = True while self.running: @@ -35,22 +31,5 @@ class CBPiKettleLogic(metaclass=ABCMeta): self.running = True async def stop(self): - self.running = False - - async def on(self, power): - ''' - Code to switch the actor on. Power is provided as integer value - - :param power: power value between 0 and 100 - :return: None - ''' - pass - - async def off(self): - - ''' - Code to switch the actor off - - :return: None - ''' - pass + self.task.cancel() + await self.task diff --git a/cbpi/controller/basic_controller.py b/cbpi/controller/basic_controller.py index 22ae342..89a0273 100644 --- a/cbpi/controller/basic_controller.py +++ b/cbpi/controller/basic_controller.py @@ -74,7 +74,9 @@ class BasicController: item = self.find_by_id(id) instance = item.get("instance") await instance.stop() + print("STOP ACTION") await instance.task + print("STOP ACTION", instance) await self.push_udpate() except Exception as e: logging.error("{} Cant stop {} - {}".format(self.name, id, e)) diff --git a/cbpi/controller/notification_controller.py b/cbpi/controller/notification_controller.py index 16577d9..93f79db 100644 --- a/cbpi/controller/notification_controller.py +++ b/cbpi/controller/notification_controller.py @@ -16,7 +16,6 @@ class NotificationController(object): self.cbpi.register(self) - @on_event(topic="notification/#") - async def _on_event(self, key, message, type=None, **kwargs): - self.cbpi.ws.send(dict(key=message)) + async def notify(self, key, message, type=None): + self.cbpi.ws.send(dict(topic="notifiaction", type=type, message=message)) diff --git a/cbpi/extension/dummylogic/__init__.py b/cbpi/extension/dummylogic/__init__.py deleted file mode 100644 index 9933f74..0000000 --- a/cbpi/extension/dummylogic/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -import asyncio - -from cbpi.api import * - -@parameters([]) -class CustomLogic(CBPiKettleLogic): - - async def run(self): - self.state = True - while self.running: - await asyncio.sleep(1) - self.state = False - - - -def setup(cbpi): - - ''' - This method is called by the server during startup - Here you need to register your plugins at the server - - :param cbpi: the cbpi core - :return: - ''' - - cbpi.plugin.register("CustomKettleLogic", CustomLogic) diff --git a/cbpi/extension/dummysensor/__init__.py b/cbpi/extension/dummysensor/__init__.py index 32a6bf2..2453799 100644 --- a/cbpi/extension/dummysensor/__init__.py +++ b/cbpi/extension/dummysensor/__init__.py @@ -15,17 +15,7 @@ class CustomSensor(CBPiSensor): self.value = 0 - @action(key="Test", parameters=[]) - async def action1(self, **kwargs): - print("ACTION!", kwargs) - @action(key="Test1", parameters=[]) - async def action2(self, **kwargs): - print("ACTION!", kwargs) - - @action(key="Test2", parameters=[]) - async def action3(self, **kwargs): - print("ACTION!", kwargs) async def run(self): diff --git a/cbpi/extension/hysteresis/__init__.py b/cbpi/extension/hysteresis/__init__.py new file mode 100644 index 0000000..613f410 --- /dev/null +++ b/cbpi/extension/hysteresis/__init__.py @@ -0,0 +1,51 @@ +import asyncio +from asyncio import tasks +import logging +from cbpi.api import * + +@parameters([Property.Number(label="OffsetOn", configurable=True, description="Offset below target temp when heater should switched on"), + Property.Number(label="OffsetOff", configurable=True, description="Offset below target temp when heater should switched off")]) +class Hysteresis(CBPiKettleLogic): + + + async def stop(self): + self.task.cancel() + await self.task + + async def run(self): + try: + self.offset_on = float(self.props.get("OffsetOn", 0)) + self.offset_off = float(self.props.get("OffsetOff", 0)) + self.kettle = self.get_kettle(self.id) + self.heater = self.kettle.get("heater") + logging.info("CustomLogic {} {} {} {}".format(self.offset_on, self.offset_off, self.id, self.heater)) + while True: + sensor_value = self.get_sensor_value(self.kettle.get("sensor")).get("value") + target_temp = self.get_kettle_target_temp("oHxKz3z5RjbsxfSz6KUgov") + if sensor_value < target_temp - self.offset_on: + await self.actor_on(self.heater) + elif sensor_value >= target_temp - self.offset_off: + await self.actor_off(self.heater) + await asyncio.sleep(1) + + except asyncio.CancelledError as e: + pass + except Exception as e: + logging.error("CustomLogic Error {}".format(e)) + finally: + self.running = False + await self.actor_off(self.heater) + + + +def setup(cbpi): + + ''' + This method is called by the server during startup + Here you need to register your plugins at the server + + :param cbpi: the cbpi core + :return: + ''' + + cbpi.plugin.register("Hysteresis", Hysteresis) diff --git a/cbpi/extension/dummylogic/config.yaml b/cbpi/extension/hysteresis/config.yaml similarity index 100% rename from cbpi/extension/dummylogic/config.yaml rename to cbpi/extension/hysteresis/config.yaml diff --git a/config/cbpi_dashboard_1.json b/config/cbpi_dashboard_1.json index 6f54656..476f7bd 100644 --- a/config/cbpi_dashboard_1.json +++ b/config/cbpi_dashboard_1.json @@ -64,6 +64,17 @@ "type": "Steps", "x": 595, "y": 50 + }, + { + "id": "9dfc216e-21d7-44af-b10f-cf4158144134", + "name": "KettleControl", + "props": { + "kettle": "oHxKz3z5RjbsxfSz6KUgov", + "orientation": "vertical" + }, + "type": "KettleControl", + "x": 70, + "y": 80 } ], "pathes": [ diff --git a/config/kettle.json b/config/kettle.json index 3ba49a4..b7e96a9 100644 --- a/config/kettle.json +++ b/config/kettle.json @@ -1,15 +1,18 @@ { "data": [ { - "agitator": "EsmZwWi9Qp3bzmXqq7N3Ly", + "agitator": "YwGzXvWMpmbLb6XobesL8n", "heater": "EsmZwWi9Qp3bzmXqq7N3Ly", "id": "oHxKz3z5RjbsxfSz6KUgov", "name": "MashTun", - "props": {}, - "sensor": "8ohkXvFA9UrkHLsxQL38wu", + "props": { + "OffsetOff": "23", + "OffsetOn": "22" + }, + "sensor": "RedQfuxfy4mYe6PwioY95y", "state": {}, - "target_temp": 45, - "type": "CustomKettleLogic" + "target_temp": 73, + "type": "Hysteresis" } ] } \ No newline at end of file diff --git a/config/step_data.json b/config/step_data.json index bd1b5bf..a2f2056 100644 --- a/config/step_data.json +++ b/config/step_data.json @@ -23,7 +23,7 @@ "Temp": "2", "Timer": "5" }, - "status": "D", + "status": "P", "type": "ActorStep" } ] diff --git a/sample.py b/sample.py deleted file mode 100644 index 88baf2c..0000000 --- a/sample.py +++ /dev/null @@ -1,8 +0,0 @@ -import math - - - -timerTime = 3661 - - -print(format_time(timerTime)) \ No newline at end of file