diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 35d7960..2665723 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1 +1 @@ -__version__ = "4.0.0.21" \ No newline at end of file +__version__ = "4.0.0.22" \ No newline at end of file diff --git a/cbpi/api/step.py b/cbpi/api/step.py index e42a456..5f9dab2 100644 --- a/cbpi/api/step.py +++ b/cbpi/api/step.py @@ -27,7 +27,7 @@ class StepState(Enum): class StepMove(Enum): UP=-1 - DONW=1 + DOWN=1 class CBPiStep(CBPiBase): diff --git a/cbpi/controller/step_controller.py b/cbpi/controller/step_controller.py index 7789751..c7b91a8 100644 --- a/cbpi/controller/step_controller.py +++ b/cbpi/controller/step_controller.py @@ -261,3 +261,11 @@ class StepController: self.basic_data = {**self.basic_data, **data,} await self.save() self.push_udpate() + + async def call_action(self, id, action, parameter) -> None: + logging.info("Step Controller - call all Action {} {}".format(id, action)) + try: + item = self.find_by_id(id) + await item.instance.__getattribute__(action)(**parameter) + except Exception as e: + logging.error("Step Controller -Faild to call action on {} {} {}".format(id, action, e)) \ No newline at end of file diff --git a/cbpi/extension/hysteresis/__init__.py b/cbpi/extension/hysteresis/__init__.py index 3ac2ea6..4b85d84 100644 --- a/cbpi/extension/hysteresis/__init__.py +++ b/cbpi/extension/hysteresis/__init__.py @@ -4,7 +4,7 @@ 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")]) + Property.Number(label="OffsetOff", configurable=True, description="Offset above target temp when heater should switched off")]) class Hysteresis(CBPiKettleLogic): async def run(self): @@ -13,18 +13,18 @@ class Hysteresis(CBPiKettleLogic): self.offset_off = float(self.props.get("OffsetOff", 0)) self.kettle = self.get_kettle(self.id) self.heater = self.kettle.heater - logging.info("CustomLogic {} {} {} {}".format(self.offset_on, self.offset_off, self.id, self.heater)) + logging.info("Hysteresis {} {} {} {}".format(self.offset_on, self.offset_off, self.id, self.heater)) + + + while True: - await self.actor_on(self.heater) - ''' + sensor_value = self.get_sensor_value(self.kettle.sensor).get("value") target_temp = self.get_kettle_target_temp(self.id) - if sensor_value < target_temp - self.offset_on: await self.actor_on(self.heater) - elif sensor_value >= target_temp - self.offset_off: + elif sensor_value >= target_temp + self.offset_off: await self.actor_off(self.heater) - ''' await asyncio.sleep(1) except asyncio.CancelledError as e: diff --git a/cbpi/extension/mashstep/__init__.py b/cbpi/extension/mashstep/__init__.py index 8843b7b..e2af218 100644 --- a/cbpi/extension/mashstep/__init__.py +++ b/cbpi/extension/mashstep/__init__.py @@ -23,7 +23,6 @@ class MashStep(CBPiStep): async def on_start(self): if self.timer is None: self.timer = Timer(10,on_update=self.on_timer_update, on_done=self.on_timer_done) - self.summary = "Waiting for Target Temp" await self.push_update() @@ -40,7 +39,7 @@ class MashStep(CBPiStep): await asyncio.sleep(1) sensor_value = self.get_sensor_value(self.props.Sensor) if sensor_value.get("value") >= int(self.props.Temp) and self.timer == None: - self.start_timer() + self.timer.start() return StepResult.DONE @parameters([Property.Number(label="Timer", description="Time in Minutes", configurable=True)]) @@ -104,6 +103,49 @@ class ActorStep(CBPiStep): await asyncio.sleep(1) return StepResult.DONE + +@parameters([Property.Number(label="Timer", description="Time in Minutes", configurable=True), + Property.Number(label="Temp", description="Boil temperature", configurable=True), + Property.Sensor(label="Sensor"), + Property.Kettle(label="Kettle")]) +class BoilStep(CBPiStep): + + async def on_timer_done(self,timer): + self.summary = "" + await self.next() + + async def on_timer_update(self,timer, seconds): + self.summary = Timer.format_time(seconds) + await self.push_update() + + async def on_start(self): + if self.timer is None: + self.timer = Timer(10,on_update=self.on_timer_update, on_done=self.on_timer_done) + + self.summary = "Waiting for Target Temp" + await self.push_update() + + async def on_stop(self): + await self.timer.stop() + self.summary = "" + await self.push_update() + + async def reset(self): + self.timer = Timer(10,on_update=self.on_timer_update, on_done=self.on_timer_done) + + @action("Start Timer", []) + async def star_timer(self): + self.cbpi.notify("Timer started") + self.timer.start() + + async def run(self): + while True: + await asyncio.sleep(1) + sensor_value = self.get_sensor_value(self.props.Sensor) + if sensor_value is not None and sensor_value.get("value") >= int(self.props.Temp) and self.timer == None: + self.timer.start() + return StepResult.DONE + def setup(cbpi): ''' This method is called by the server during startup @@ -113,6 +155,7 @@ def setup(cbpi): :return: ''' + cbpi.plugin.register("BoilStep", BoilStep) cbpi.plugin.register("WaitStep", WaitStep) cbpi.plugin.register("MashStep", MashStep) cbpi.plugin.register("ActorStep", ActorStep) diff --git a/cbpi/extension/mashstep/__init__.py.old b/cbpi/extension/mashstep/__init__.py.old deleted file mode 100644 index 8b2b53c..0000000 --- a/cbpi/extension/mashstep/__init__.py.old +++ /dev/null @@ -1,176 +0,0 @@ - -import asyncio -from cbpi.api.timer import Timer - -from cbpi.api import * -import logging - -@parameters([Property.Number(label="Timer", description="Time in Minutes", configurable=True), - Property.Number(label="Temp", configurable=True), - Property.Sensor(label="Sensor"), - Property.Kettle(label="Kettle")]) -class MashStep(CBPiStep): - - def __init__(self, cbpi, id, name, props): - super().__init__(cbpi, id, name, props) - self.timer = None - - def timer_done(self): - self.state_msg = "Done" - asyncio.create_task(self.next()) - - async def timer_update(self, seconds, time): - self.state_msg = "{}".format(time) - self.push_update() - - def start_timer(self): - if self.timer is None: - self.time = int(self.props.get("Timer", 0)) * 60 - self.timer = Timer(self.time, self.timer_done, self.timer_update) - self.timer.start() - - async def stop_timer(self): - if self.timer is not None: - await self.timer.stop() - self.state_msg = "{}".format(self.timer.get_time()) - - async def next(self): - if self.timer is not None: - await self.timer.stop() - self.state_msg = "" - await super().next() - - async def stop(self): - await super().stop() - await self.stop_timer() - - async def reset(self): - self.state_msg = "" - self.timer = None - await super().reset() - - async def execute(self): - if self.timer is None: - self.state_msg = "Waiting for Target Temp" - self.push_update() - else: - if self.timer is not None and self.timer.is_running() is False: - self.start_timer() - - while True: - await asyncio.sleep(1) - sensor_value = self.get_sensor_value(self.props.get("Sensor")) - if sensor_value.get("value") >= 2 and self.timer == None: - self.start_timer() - -@parameters([Property.Number(label="Timer", description="Time in Minutes", configurable=True)]) -class WaitStep(CBPiStep): - - def __init__(self, cbpi, id, name, props): - super().__init__(cbpi, id, name, props) - self.timer = None - - def timer_done(self): - self.state_msg = "Done" - - asyncio.create_task(self.next()) - - async def timer_update(self, seconds, time): - self.state_msg = "{}".format(time) - self.push_update() - - def start_timer(self): - if self.timer is None: - self.time = int(self.props.get("Timer", 0)) * 60 - self.timer = Timer(self.time, self.timer_done, self.timer_update) - self.timer.start() - - async def stop_timer(self): - if self.timer is not None: - await self.timer.stop() - self.state_msg = "{}".format(self.timer.get_time()) - - async def next(self): - if self.timer is not None: - await self.timer.stop() - self.state_msg = "" - await super().next() - - async def stop(self): - await super().stop() - await self.stop_timer() - - async def reset(self): - self.state_msg = "" - self.timer = None - await super().reset() - - async def execute(self): - self.start_timer() - while True: - await asyncio.sleep(1) - -@parameters([Property.Number(label="Timer", description="Time in Minutes", configurable=True), - Property.Actor(label="Actor")]) -class ActorStep(CBPiStep): - - def __init__(self, cbpi, id, name, props): - super().__init__(cbpi, id, name, props) - self.timer = None - - def timer_done(self): - self.state_msg = "Done" - asyncio.create_task(self.actor_off(self.actor_id)) - asyncio.create_task(self.next()) - - async def timer_update(self, seconds, time): - self.state_msg = "{}".format(time) - self.push_update() - - def start_timer(self): - if self.timer is None: - self.time = int(self.props.get("Timer", 0)) * 60 - self.timer = Timer(self.time, self.timer_done, self.timer_update) - self.timer.start() - - async def stop_timer(self): - if self.timer is not None: - await self.timer.stop() - self.state_msg = "{}".format(self.timer.get_time()) - - async def next(self): - if self.timer is not None: - await self.timer.stop() - self.state_msg = "" - await super().next() - - async def stop(self): - await super().stop() - await self.actor_off(self.actor_id) - await self.stop_timer() - - async def reset(self): - self.state_msg = "" - self.timer = None - await super().reset() - - async def execute(self): - self.start_timer() - self.actor_id = self.props.Actor - await self.actor_on(self.actor_id) - while True: - await asyncio.sleep(1) - -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("ActorStep", ActorStep) - cbpi.plugin.register("WaitStep", WaitStep) - cbpi.plugin.register("MashStep", MashStep) - diff --git a/cbpi/http_endpoints/http_step.py b/cbpi/http_endpoints/http_step.py index 00094e4..b58aae2 100644 --- a/cbpi/http_endpoints/http_step.py +++ b/cbpi/http_endpoints/http_step.py @@ -38,6 +38,7 @@ class StepHttpEndpoints(): tags: - Step parameters: + - in: body name: body description: Created an step @@ -214,4 +215,43 @@ class StepHttpEndpoints(): await self.controller.save_basic(data) return web.Response(status=204) - \ No newline at end of file + + @request_mapping(path="/action/{id}", method="POST", auth_required=False) + async def http_call_action(self, request): + """ + --- + description: Call action + tags: + - Step + parameters: + - name: "id" + in: "path" + description: "Step id" + required: true + type: "integer" + format: "int64" + - in: body + name: body + description: call action + required: false + schema: + type: object + properties: + action: + type: string + parameter: + type: "array" + items: + type: string + responses: + "204": + description: successful operation + """ + data = await request.json() + + id = request.match_info['id'] + await self.controller.call_action(id,data.get("action"), data.get("parameter",[])) + return web.Response(status=204) + + + \ No newline at end of file