From 580bdd899a2f56980be87125fa668ab3930eb6f8 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Sun, 27 Feb 2022 18:45:57 +0100 Subject: [PATCH] Autostart active or stopped step with orignila endtime --- cbpi/__init__.py | 2 +- cbpi/api/dataclasses.py | 5 +-- cbpi/api/step.py | 6 ++- cbpi/controller/fermentation_controller.py | 29 +++++++++--- cbpi/extension/FermentationStep/__init__.py | 50 +++++++++++++++------ setup.py | 2 + 6 files changed, 70 insertions(+), 24 deletions(-) diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 0f430d9..a04b728 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1 +1 @@ -__version__ = "4.0.2.0.a4" +__version__ = "4.0.2.0.a5" diff --git a/cbpi/api/dataclasses.py b/cbpi/api/dataclasses.py index 2cb1477..996d13b 100644 --- a/cbpi/api/dataclasses.py +++ b/cbpi/api/dataclasses.py @@ -162,8 +162,7 @@ class FermenterStep: props: Props = Props() type: str = None status: StepState = StepState.INITIAL - #Add end data as unixtime to setp when active - #step_end: float = 0 + endtime: int = 0 # endtime if step is active and timer is running instance: str = None step: dict = None @@ -171,7 +170,7 @@ class FermenterStep: return "name={} props={}, type={}, instance={}".format(self.name, self.props, self.type, self.instance) def to_dict(self): msg = self.instance.summary if self.instance is not None else "" - return dict(id=self.id, name=self.name, state_text=msg, type=self.type, status=self.status.value, props=self.props.to_dict()) + return dict(id=self.id, name=self.name, state_text=msg, type=self.type, status=self.status.value, endtime = self.endtime, props=self.props.to_dict()) diff --git a/cbpi/api/step.py b/cbpi/api/step.py index e14e292..7c20378 100644 --- a/cbpi/api/step.py +++ b/cbpi/api/step.py @@ -136,6 +136,7 @@ class CBPiFermentationStep(CBPiBase): self.timer = None self._done_callback = on_done self.props = props + self.endtime = int(step.get("endtime")) self.cancel_reason: StepResult = None self.summary = "" self.task = None @@ -187,8 +188,11 @@ class CBPiFermentationStep(CBPiBase): async def on_props_update(self, props): self.props = {**self.props, **props} + async def update_endtime(self): + await self.cbpi.fermenter.update_endtime(self.fermenter.id, self.id, self.endtime) + async def save_props(self): - await self.cbpi.step.save() + self.cbpi.fermenter.save() async def push_update(self): self.cbpi.fermenter.push_update(self.update_key) diff --git a/cbpi/controller/fermentation_controller.py b/cbpi/controller/fermentation_controller.py index 3744ea7..c3e5392 100644 --- a/cbpi/controller/fermentation_controller.py +++ b/cbpi/controller/fermentation_controller.py @@ -156,8 +156,11 @@ class FermentationController: name = item.get("name") props = Props(item.get("props")) status = StepState(item.get("status", "I")) + endtime = int(item.get("endtime", 0)) if status == StepState.ACTIVE: status = StepState("S") + if status != StepState.STOP: + endtime = 0 type = item.get("type") try: @@ -168,10 +171,11 @@ class FermentationController: logging.warning("Failed to create step instance %s - %s" % (id, e)) instance = None - step = FermenterStep(id=id, name=name, fermenter=fermenter, props=props, type=type, status=status, instance=instance) + step = FermenterStep(id=id, name=name, fermenter=fermenter, props=props, type=type, status=status, endtime=endtime, instance=instance) return step def _done(self, step_instance, result, fermenter): + logging.info(result) step_instance.step["status"] = "D" self.save() if result == StepResult.NEXT: @@ -299,7 +303,7 @@ class FermentationController: self.push_update() def save(self): - data = dict(data=list(map(lambda item: item.to_dict(), self.data))) + data = dict(data=list(map(lambda item: item.to_dict(), self.data))) with open(self.path, "w") as file: json.dump(data, file, indent=4, sort_keys=True) @@ -385,6 +389,17 @@ class FermentationController: def _find_step_by_id(self, data, id): return next((item for item in data if item.id == id), None) + async def update_endtime(self, id, stepid, endtime): + try: + item = self._find_by_id(id) + step = self._find_step_by_id(item.steps, stepid) + step.endtime = int(endtime) + self.save() + self.push_update("fermenterstepupdate") + except Exception as e: + self.logger.error(e) + + async def start(self, id): self.logger.info("Start {}".format(id)) try: @@ -397,9 +412,12 @@ class FermentationController: step = self._find_by_status(item.steps, StepState.STOP) if step is not None: + endtime = step.endtime await step.instance.start() logging.info("Restarting step {}".format(step.name)) - step.status = StepState.ACTIVE + if endtime != 0: + logging.info("Need to change timer") + step.status = StepState.ACTIVE self.save() self.push_update("fermenterstepupdate") return @@ -422,8 +440,8 @@ class FermentationController: try: item = self._find_by_id(id) step = self._find_by_status(item.steps, StepState.ACTIVE) - logging.info(step) - logging.info(step.status) + #logging.info(step) + #logging.info(step.status) if step != None: logging.info("CALLING STOP STEP") try: @@ -514,6 +532,7 @@ class FermentationController: try: await step.instance.stop() step.status = StepState.INITIAL + step.endtime = 0 except Exception as e: self.logger.error(e) self.save() diff --git a/cbpi/extension/FermentationStep/__init__.py b/cbpi/extension/FermentationStep/__init__.py index bb7b051..aec282f 100644 --- a/cbpi/extension/FermentationStep/__init__.py +++ b/cbpi/extension/FermentationStep/__init__.py @@ -134,7 +134,7 @@ class FermenterTargetTempStep(CBPiFermentationStep): if (self.fermenter.instance is None or self.fermenter.instance.state == False) and (auto_state is True): await self.cbpi.fermenter.toggle(self.fermenter.id) elif (self.fermenter.instance.state == True) and (auto_state is False): - await self.fermenter.instance.stop() + await self.cbpi.fermenter.toggle(self.fermenter.id) await self.push_update() except Exception as e: @@ -155,18 +155,20 @@ class FermenterStep(CBPiFermentationStep): self.cbpi.notify(self.name, 'Timer started', NotificationType.INFO) self.timer.start() self.timer.is_running = True + self.endtime = time.time() + self.fermentationtime + await self.update_endtime() estimated_completion_time = datetime.fromtimestamp(time.time()+ self.fermentationtime) self.cbpi.notify(self.name, 'Timer started. Estimated completion: {}'.format(estimated_completion_time.strftime("%d.%m, %H:%M")), NotificationType.INFO) else: self.cbpi.notify(self.name, 'Timer is already running', NotificationType.WARNING) - @action("Add 5 Minutes to Timer", []) - async def add_timer(self): - if self.timer.is_running == True: - self.cbpi.notify(self.name, '5 Minutes added', NotificationType.INFO) - await self.timer.add(300) - else: - self.cbpi.notify(self.name, 'Timer must be running to add time', NotificationType.WARNING) + #@action("Add 5 Minutes to Timer", []) + #async def add_timer(self): + # if self.timer.is_running == True: + # self.cbpi.notify(self.name, '5 Minutes added', NotificationType.INFO) + # await self.timer.add(300) + # else: + # self.cbpi.notify(self.name, 'Timer must be running to add time', NotificationType.WARNING) async def on_timer_done(self,timer): @@ -174,6 +176,8 @@ class FermenterStep(CBPiFermentationStep): self.fermenter.target_temp = 0 if self.AutoMode == True: await self.setAutoMode(False) + #self.endtime = 0 + #await self.update_endtime() self.cbpi.notify(self.name, 'Step finished', NotificationType.SUCCESS) await self.next(self.fermenter.id) return StepResult.DONE @@ -184,10 +188,16 @@ class FermenterStep(CBPiFermentationStep): await self.push_update() async def on_start(self): - timeD=int(self.props.get("TimerD", 0)) - timeH=int(self.props.get("TimerH", 0)) - timeM=int(self.props.get("TimerM", 0)) - self.fermentationtime=(timeM+(60*timeH)+(1440*timeD)) *60 + if self.endtime == 0: + + timeD=int(self.props.get("TimerD", 0)) + timeH=int(self.props.get("TimerH", 0)) + timeM=int(self.props.get("TimerM", 0)) + self.fermentationtime=(timeM+(60*timeH)+(1440*timeD)) *60 + else: + self.fermentationtime = self.endtime - time.time() + + self.AutoMode = True if self.props.get("AutoMode", "No") == "Yes" else False self.starttemp= self.get_sensor_value(self.props.get("Sensor", None)).get("value") @@ -198,13 +208,19 @@ class FermenterStep(CBPiFermentationStep): await self.push_update() if self.fermenter is not None and self.timer is None: + logging.info("Set Timer") self.timer = Timer(self.fermentationtime ,on_update=self.on_timer_update, on_done=self.on_timer_done) elif self.fermenter is not None: try: if self.timer.is_running == True: self.timer.start() + self.endtime = time.time() + self.fermentationtime + await self.update_endtime() except: pass + if self.endtime != 0 and self.timer is not None: + self.timer.start() + self.timer.is_running = True self.summary = "Waiting for Target Temp" await self.push_update() @@ -218,6 +234,8 @@ class FermenterStep(CBPiFermentationStep): async def reset(self): self.timer = Timer(self.fermentationtime ,on_update=self.on_timer_update, on_done=self.on_timer_done) + self.endtime = 0 + await self.update_endtime() async def run(self): if self.fermenter.target_temp >= self.starttemp: @@ -228,6 +246,8 @@ class FermenterStep(CBPiFermentationStep): if sensor_value >= self.fermenter.target_temp and self.timer.is_running is not True: self.timer.start() self.timer.is_running = True + self.endtime = time.time() + self.fermentationtime + await self.update_endtime() estimated_completion_time = datetime.fromtimestamp(time.time()+ self.fermentationtime) self.cbpi.notify(self.name, 'Timer started. Estimated completion: {}'.format(estimated_completion_time.strftime("%d.%m, %H:%M")), NotificationType.INFO) elif self.fermenter.target_temp <= self.starttemp: @@ -238,6 +258,8 @@ class FermenterStep(CBPiFermentationStep): if sensor_value <= self.fermenter.target_temp and self.timer.is_running is not True: self.timer.start() self.timer.is_running = True + self.endtime = time.time() + self.fermentationtime + await self.update_endtime() estimated_completion_time = datetime.fromtimestamp(time.time()+ self.fermentationtime) self.cbpi.notify(self.name, 'Timer started. Estimated completion: {}'.format(estimated_completion_time.strftime("%d.%m, %H:%M")), NotificationType.INFO) @@ -248,7 +270,7 @@ class FermenterStep(CBPiFermentationStep): if (self.fermenter.instance is None or self.fermenter.instance.state == False) and (auto_state is True): await self.cbpi.fermenter.toggle(self.fermenter.id) elif (self.fermenter.instance.state == True) and (auto_state is False): - await self.fermenter.instance.stop() + await self.cbpi.fermenter.toggle(self.fermenter.id) await self.push_update() except Exception as e: @@ -304,4 +326,4 @@ def setup(cbpi): cbpi.plugin.register("FermenterNotificationStep", FermenterNotificationStep) cbpi.plugin.register("FermenterTargetTempStep", FermenterTargetTempStep) cbpi.plugin.register("FermenterStep", FermenterStep) - cbpi.plugin.register("FermenterWaitStep", FermenterWaitStep) \ No newline at end of file + #cbpi.plugin.register("FermenterWaitStep", FermenterWaitStep) \ No newline at end of file diff --git a/setup.py b/setup.py index cbce4c1..30b3446 100644 --- a/setup.py +++ b/setup.py @@ -47,6 +47,8 @@ setup(name='cbpi', 'tabulate==0.8.7', 'asyncio-mqtt', 'psutil==5.8.0', + 'colorama==0.4.4', + 'PyInquirer==1.0.3', 'cbpi4ui', 'importlib_metadata'] + ( ['RPi.GPIO==0.7.1'] if raspberrypi else [] ) +