mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-12-22 21:44:57 +01:00
further changes to support fermentersteps - WIP
This commit is contained in:
parent
286198fcd1
commit
36329fb533
7 changed files with 419 additions and 86 deletions
|
@ -1 +1 @@
|
||||||
__version__ = "4.0.1.18.a4"
|
__version__ = "4.0.1.18.a5"
|
||||||
|
|
|
@ -162,6 +162,7 @@ class FermenterStep:
|
||||||
type: str = None
|
type: str = None
|
||||||
status: StepState = StepState.INITIAL
|
status: StepState = StepState.INITIAL
|
||||||
instance: str = None
|
instance: str = None
|
||||||
|
step: dict = None
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "name={} props={}, type={}, instance={}".format(self.name, self.props, self.type, self.instance)
|
return "name={} props={}, type={}, instance={}".format(self.name, self.props, self.type, self.instance)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
import cbpi
|
||||||
|
|
||||||
from cbpi.api.base import CBPiBase
|
from cbpi.api.base import CBPiBase
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ class CBPiStep(CBPiBase):
|
||||||
self.task.cancel()
|
self.task.cancel()
|
||||||
await self.task
|
await self.task
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
logging.error(e)
|
||||||
|
|
||||||
async def reset(self):
|
async def reset(self):
|
||||||
pass
|
pass
|
||||||
|
@ -116,8 +117,100 @@ class CBPiStep(CBPiBase):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "name={} props={}, type={}".format(self.name, self.props, self.__class__.__name__)
|
return "name={} props={}, type={}".format(self.name, self.props, self.__class__.__name__)
|
||||||
|
|
||||||
class CBPiFermentationStep(CBPiStep):
|
#class CBPiFermentationStep(CBPiStep):
|
||||||
|
|
||||||
|
# def __init__(self, cbpi, fermenter, step, props, on_done) -> None:
|
||||||
|
# self.fermenter = fermenter
|
||||||
|
# id = step.get("id")
|
||||||
|
# name=step.get("name")
|
||||||
|
# self.step=step
|
||||||
|
# super().__init__(cbpi, id, name, props, on_done)
|
||||||
|
|
||||||
|
class CBPiFermentationStep(CBPiBase):
|
||||||
|
|
||||||
def __init__(self, cbpi, fermenter, step, props, on_done) -> None:
|
def __init__(self, cbpi, fermenter, step, props, on_done) -> None:
|
||||||
self.fermenter = fermenter
|
self.fermenter = fermenter
|
||||||
super().__init__(cbpi, step.id, step.name, props, on_done)
|
self.name = step.get("name")
|
||||||
|
self.cbpi = cbpi
|
||||||
|
self.id = step.get("id")
|
||||||
|
self.timer = None
|
||||||
|
self._done_callback = on_done
|
||||||
|
self.props = props
|
||||||
|
self.cancel_reason: StepResult = None
|
||||||
|
self.summary = ""
|
||||||
|
self.task = None
|
||||||
|
self.running: bool = False
|
||||||
|
self.logger = logging.getLogger(__name__)
|
||||||
|
self.step = step
|
||||||
|
self.update_key="fermenterstepupdate"
|
||||||
|
|
||||||
|
def _done(self, task):
|
||||||
|
if self._done_callback is not None:
|
||||||
|
try:
|
||||||
|
result = task.result()
|
||||||
|
logging.info(result)
|
||||||
|
logging.info(self.fermenter.id)
|
||||||
|
fermenter=self.fermenter.id
|
||||||
|
self._done_callback(self, result, fermenter)
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(e)
|
||||||
|
|
||||||
|
async def start(self):
|
||||||
|
self.logger.info("Start {}".format(self.name))
|
||||||
|
self.running = True
|
||||||
|
self.task = asyncio.create_task(self._run())
|
||||||
|
self.task.add_done_callback(self._done)
|
||||||
|
|
||||||
|
async def next(self):
|
||||||
|
self.running = False
|
||||||
|
self.cancel_reason = StepResult.NEXT
|
||||||
|
self.task.cancel()
|
||||||
|
await self.task
|
||||||
|
|
||||||
|
async def stop(self):
|
||||||
|
try:
|
||||||
|
self.running = False
|
||||||
|
if self.task is not None and self.task.done() is False:
|
||||||
|
self.cancel_reason = StepResult.STOP
|
||||||
|
logging.info(self.cancel_reason)
|
||||||
|
self.task.cancel()
|
||||||
|
await self.task
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(e)
|
||||||
|
|
||||||
|
async def reset(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def on_props_update(self, props):
|
||||||
|
self.props = {**self.props, **props}
|
||||||
|
|
||||||
|
async def save_props(self):
|
||||||
|
await self.cbpi.step.save()
|
||||||
|
|
||||||
|
async def push_update(self):
|
||||||
|
self.cbpi.fermenter.push_update(self.update_key)
|
||||||
|
|
||||||
|
async def on_start(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def on_stop(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _run(self):
|
||||||
|
try:
|
||||||
|
await self.on_start()
|
||||||
|
await self.run()
|
||||||
|
self.cancel_reason = StepResult.DONE
|
||||||
|
except asyncio.CancelledError as e:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
await self.on_stop()
|
||||||
|
|
||||||
|
return self.cancel_reason
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
async def run(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "name={} props={}, type={}".format(self.name, self.props, self.__class__.__name__)
|
|
@ -1,3 +1,4 @@
|
||||||
|
from abc import abstractmethod
|
||||||
import asyncio
|
import asyncio
|
||||||
import cbpi
|
import cbpi
|
||||||
import copy
|
import copy
|
||||||
|
@ -34,14 +35,19 @@ class FermentStep:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
async def run(self):
|
async def run(self):
|
||||||
while True:
|
while self.running:
|
||||||
|
logging.info(self.step)
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
pass
|
||||||
|
|
||||||
async def _run(self):
|
async def _run(self):
|
||||||
try:
|
try:
|
||||||
await self.on_start()
|
await self.step.instance.on_start()
|
||||||
await self.run()
|
await self.step.instance.run()
|
||||||
|
#await self.on_start()
|
||||||
|
#await self.run()
|
||||||
self.cancel_reason = StepResult.DONE
|
self.cancel_reason = StepResult.DONE
|
||||||
except asyncio.CancelledError as e:
|
except asyncio.CancelledError as e:
|
||||||
pass
|
pass
|
||||||
|
@ -109,18 +115,6 @@ class FermentationController:
|
||||||
destfile = os.path.join(".", 'config', "fermenter_data.json")
|
destfile = os.path.join(".", 'config', "fermenter_data.json")
|
||||||
json.dump(data,open(destfile,'w'),indent=4, sort_keys=True)
|
json.dump(data,open(destfile,'w'),indent=4, sort_keys=True)
|
||||||
|
|
||||||
def push_update(self, key="fermenterupdate", fermentersteps=None):
|
|
||||||
|
|
||||||
if key == self.update_key:
|
|
||||||
self.cbpi.ws.send(dict(topic=key, data=list(map(lambda item: item.to_dict(), self.data))))
|
|
||||||
#self.cbpi.push_update("cbpi/{}".format(self.update_key), list(map(lambda item: item.to_dict(), self.data)))
|
|
||||||
|
|
||||||
for item in self.data:
|
|
||||||
self.cbpi.push_update("cbpi/{}/{}".format(self.update_key,item.id), item.to_dict())
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.cbpi.ws.send(dict(topic=key, data=fermentersteps))
|
|
||||||
|
|
||||||
async def shutdown(self, app=None):
|
async def shutdown(self, app=None):
|
||||||
self.save()
|
self.save()
|
||||||
for fermenter in self.data:
|
for fermenter in self.data:
|
||||||
|
@ -149,21 +143,27 @@ class FermentationController:
|
||||||
status = StepState(item.get("status", "I"))
|
status = StepState(item.get("status", "I"))
|
||||||
type = item.get("type")
|
type = item.get("type")
|
||||||
|
|
||||||
type_cfg = self.types.get(type)
|
try:
|
||||||
if type_cfg is not None:
|
type_cfg = self.steptypes.get(type)
|
||||||
inst = type_cfg.get("class")()
|
clazz = type_cfg.get("class")
|
||||||
print(inst)
|
instance = clazz(self.cbpi, fermenter, item, props, self._done)
|
||||||
|
except Exception as e:
|
||||||
|
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=None)
|
step = FermenterStep(id=id, name=name, fermenter=fermenter, props=props, type=type, status=status, instance=instance)
|
||||||
step.instance = FermentStep( self.cbpi, step, self._done)
|
#logging.info(step)
|
||||||
|
#logging.info(step.status)
|
||||||
return step
|
return step
|
||||||
|
|
||||||
def _done(self, step_instance, result):
|
def _done(self, step_instance, result, fermenter):
|
||||||
|
step_instance.step["status"] = "D"
|
||||||
step_instance.step.status = StepState.DONE
|
|
||||||
self.save()
|
self.save()
|
||||||
|
logging.info(step_instance)
|
||||||
|
logging.info(step_instance.step)
|
||||||
|
logging.info(fermenter)
|
||||||
if result == StepResult.NEXT:
|
if result == StepResult.NEXT:
|
||||||
asyncio.create_task(self.start(step_instance.step.fermenter.id))
|
asyncio.create_task(self.start(fermenter))
|
||||||
|
|
||||||
def _create(self, data):
|
def _create(self, data):
|
||||||
try:
|
try:
|
||||||
|
@ -283,44 +283,80 @@ class FermentationController:
|
||||||
with open(self.path, "w") as file:
|
with open(self.path, "w") as file:
|
||||||
json.dump(data, file, indent=4, sort_keys=True)
|
json.dump(data, file, indent=4, sort_keys=True)
|
||||||
|
|
||||||
async def create_step(self, id, step: Step):
|
async def create_step(self, id, item):
|
||||||
try:
|
try:
|
||||||
step.id = shortuuid.uuid()
|
stepid = shortuuid.uuid()
|
||||||
item = self._find_by_id(id)
|
props = item.get("props")
|
||||||
|
status = StepState("I")
|
||||||
|
type = item.get("type")
|
||||||
|
name = item.get("name")
|
||||||
|
props = Props(item.get("props"))
|
||||||
|
fermenter = self._find_by_id(id)
|
||||||
|
|
||||||
step.instance = FermentStep( self.cbpi, step, self._done)
|
try:
|
||||||
|
type_cfg = self.steptypes.get(type)
|
||||||
|
clazz = type_cfg.get("class")
|
||||||
|
instance = clazz(self.cbpi, fermenter, item, props, self._done)
|
||||||
|
except Exception as e:
|
||||||
|
logging.warning("Failed to create step instance %s - %s" % (id, e))
|
||||||
|
instance = None
|
||||||
|
step = FermenterStep(id=stepid, name=name, fermenter=fermenter, props=props, type=type, status=status, instance=instance)
|
||||||
|
|
||||||
item.steps.append(step)
|
|
||||||
|
|
||||||
|
fermenter.steps.append(step)
|
||||||
self.save()
|
self.save()
|
||||||
fermentersteps=self.get_fermenter_steps()
|
self.push_update("fermenterstepupdate")
|
||||||
self.push_update("fermenterstepupdate", fermentersteps)
|
|
||||||
return step
|
return step
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
|
||||||
async def update_step(self, id, step: FermenterStep):
|
async def update_step(self, id, item):
|
||||||
item = self._find_by_id(id)
|
fermenter = self._find_by_id(id)
|
||||||
item.steps = list(map(lambda old: step if old.id == step.id else old, item.steps))
|
stepid = item.get("id")
|
||||||
self.save()
|
props = item.get("props")
|
||||||
fermentersteps=self.get_fermenter_steps()
|
status = StepState("I")
|
||||||
self.push_update("fermenterstepupdate", fermentersteps)
|
type = item.get("type")
|
||||||
|
#logging.info(type)
|
||||||
|
name = item.get("name")
|
||||||
|
props = Props(item.get("props"))
|
||||||
|
|
||||||
|
logging.info("update step")
|
||||||
|
try:
|
||||||
|
type_cfg = self.steptypes.get(type)
|
||||||
|
#logging.info(type_cfg)
|
||||||
|
clazz = type_cfg.get("class")
|
||||||
|
#logging.info(clazz)
|
||||||
|
instance = clazz(self.cbpi, fermenter, item, props, self._done)
|
||||||
|
except Exception as e:
|
||||||
|
logging.warning("Failed to create step instance %s - %s " % (item.id, e))
|
||||||
|
instance = None
|
||||||
|
step = FermenterStep(id=stepid, name=name, fermenter=fermenter, props=props, type=type, status=status, instance=instance)
|
||||||
|
#logging.info(step)
|
||||||
|
#logging.info(fermenter.steps)
|
||||||
|
try:
|
||||||
|
fermenter.steps = list(map(lambda old: step if old.id == step.id else old, fermenter.steps))
|
||||||
|
except Exception as e:
|
||||||
|
logging.info(e)
|
||||||
|
#logging.info(fermenter.steps)
|
||||||
|
self.save()
|
||||||
|
#logging.info("SAVEUPDATE")
|
||||||
|
|
||||||
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
async def delete_step(self, id, stepid):
|
async def delete_step(self, id, stepid):
|
||||||
item = self._find_by_id(id)
|
item = self._find_by_id(id)
|
||||||
# might require later check if step is active
|
# might require later check if step is active
|
||||||
item.steps = list(filter(lambda item: item.id != stepid, item.steps))
|
item.steps = list(filter(lambda item: item.id != stepid, item.steps))
|
||||||
self.save()
|
self.save()
|
||||||
fermentersteps=self.get_fermenter_steps()
|
self.push_update("fermenterstepupdate")
|
||||||
self.push_update("fermenterstepupdate", fermentersteps)
|
|
||||||
|
|
||||||
async def clearsteps(self, id):
|
async def clearsteps(self, id):
|
||||||
item = self._find_by_id(id)
|
item = self._find_by_id(id)
|
||||||
# might require later check if step is active
|
# might require later check if step is active
|
||||||
item.steps = []
|
item.steps = []
|
||||||
self.save()
|
self.save()
|
||||||
fermentersteps=self.get_fermenter_steps()
|
self.push_update("fermenterstepupdate")
|
||||||
self.push_update("fermenterstepupdate", fermentersteps)
|
|
||||||
|
|
||||||
|
|
||||||
def _find_by_status(self, data, status):
|
def _find_by_status(self, data, status):
|
||||||
|
@ -330,17 +366,34 @@ class FermentationController:
|
||||||
return next((item for item in data if item.id == id), None)
|
return next((item for item in data if item.id == id), None)
|
||||||
|
|
||||||
async def start(self, id):
|
async def start(self, id):
|
||||||
self.logger.info("Start")
|
self.logger.info("Start {}".format(id))
|
||||||
try:
|
try:
|
||||||
item = self._find_by_id(id)
|
item = self._find_by_id(id)
|
||||||
step = self._find_by_status(item.steps, StepState.INITIAL)
|
|
||||||
|
|
||||||
|
step = self._find_by_status(item.steps, StepState.ACTIVE)
|
||||||
|
if step is not None:
|
||||||
|
logging.error("Steps already running")
|
||||||
|
return
|
||||||
|
|
||||||
|
step = self._find_by_status(item.steps, StepState.STOP)
|
||||||
|
if step is not None:
|
||||||
|
await step.instance.start()
|
||||||
|
logging.info("Restarting step {}".format(step.name))
|
||||||
|
step.status = StepState.ACTIVE
|
||||||
|
self.save()
|
||||||
|
self.push_update("fermenterstepupdate")
|
||||||
|
return
|
||||||
|
|
||||||
|
step = self._find_by_status(item.steps, StepState.INITIAL)
|
||||||
|
logging.info(step)
|
||||||
if step is None:
|
if step is None:
|
||||||
self.logger.info("No futher step to start")
|
self.logger.info("No futher step to start")
|
||||||
else:
|
else:
|
||||||
await step.instance.start()
|
await step.instance.start()
|
||||||
|
logging.info("Starting step {}".format(step.name))
|
||||||
step.status = StepState.ACTIVE
|
step.status = StepState.ACTIVE
|
||||||
self.save()
|
self.save()
|
||||||
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
@ -349,9 +402,19 @@ class FermentationController:
|
||||||
try:
|
try:
|
||||||
item = self._find_by_id(id)
|
item = self._find_by_id(id)
|
||||||
step = self._find_by_status(item.steps, StepState.ACTIVE)
|
step = self._find_by_status(item.steps, StepState.ACTIVE)
|
||||||
|
logging.info(step)
|
||||||
|
logging.info(step.status)
|
||||||
|
if step != None:
|
||||||
|
logging.info("CALLING STOP STEP")
|
||||||
|
try:
|
||||||
await step.instance.stop()
|
await step.instance.stop()
|
||||||
step.status = StepState.STOP
|
step.status = StepState.STOP
|
||||||
self.save()
|
self.save()
|
||||||
|
except Exception as e:
|
||||||
|
logging.error("Failed to stop fermenterstep - Id: %s" % step.id)
|
||||||
|
|
||||||
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
|
||||||
|
@ -396,9 +459,28 @@ class FermentationController:
|
||||||
self.logger.info("Next {} ".format(id))
|
self.logger.info("Next {} ".format(id))
|
||||||
try:
|
try:
|
||||||
item = self._find_by_id(id)
|
item = self._find_by_id(id)
|
||||||
|
logging.info(item)
|
||||||
step = self._find_by_status(item.steps, StepState.ACTIVE)
|
step = self._find_by_status(item.steps, StepState.ACTIVE)
|
||||||
|
logging.info(step)
|
||||||
|
if step is not None:
|
||||||
|
if step.instance is not None:
|
||||||
|
step.status = StepState.DONE
|
||||||
await step.instance.next()
|
await step.instance.next()
|
||||||
|
|
||||||
|
step = self._find_by_status(item.steps, StepState.STOP)
|
||||||
|
logging.info(step)
|
||||||
|
if step is not None:
|
||||||
|
if step.instance is not None:
|
||||||
|
logging.info(step)
|
||||||
|
step.status = StepState.DONE
|
||||||
|
logging.info(step)
|
||||||
|
self.save()
|
||||||
|
await self.start(id)
|
||||||
|
else:
|
||||||
|
logging.info("No Step is running")
|
||||||
|
|
||||||
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
|
||||||
|
@ -415,6 +497,8 @@ class FermentationController:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
self.save()
|
self.save()
|
||||||
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
|
||||||
|
@ -436,3 +520,17 @@ class FermentationController:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
|
||||||
|
def push_update(self, key="fermenterupdate"):
|
||||||
|
|
||||||
|
if key == self.update_key:
|
||||||
|
self.cbpi.ws.send(dict(topic=key, data=list(map(lambda item: item.to_dict(), self.data))))
|
||||||
|
#self.cbpi.push_update("cbpi/{}".format(self.update_key), list(map(lambda item: item.to_dict(), self.data)))
|
||||||
|
|
||||||
|
for item in self.data:
|
||||||
|
self.cbpi.push_update("cbpi/{}/{}".format(self.update_key,item.id), item.to_dict())
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
#logging.info("FERMENTERSTEPUPDATE {}".format(key))
|
||||||
|
fermentersteps=self.get_fermenter_steps()
|
||||||
|
self.cbpi.ws.send(dict(topic=key, data=fermentersteps))
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ class StepController:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.warning("Failed to create step instance %s - %s" % (id, e))
|
logging.warning("Failed to create step instance %s - %s" % (id, e))
|
||||||
instance = None
|
instance = None
|
||||||
|
step=Step(id, name, type=type, status=status, instance=instance, props=props )
|
||||||
return Step(id, name, type=type, status=status, instance=instance, props=props )
|
return step
|
||||||
|
|
||||||
|
|
||||||
def load(self, startActive=False):
|
def load(self, startActive=False):
|
||||||
|
|
|
@ -62,13 +62,13 @@ class FermenterNotificationStep(CBPiFermentationStep):
|
||||||
|
|
||||||
@parameters([Property.Number(label="Temp", configurable=True),
|
@parameters([Property.Number(label="Temp", configurable=True),
|
||||||
Property.Sensor(label="Sensor"),
|
Property.Sensor(label="Sensor"),
|
||||||
Property.Fermenter(label="Fermenter"),
|
|
||||||
Property.Text(label="Notification",configurable = True, description = "Text for notification when Temp is reached"),
|
Property.Text(label="Notification",configurable = True, description = "Text for notification when Temp is reached"),
|
||||||
Property.Select(label="AutoMode",options=["Yes","No"], description="Switch Fermenterlogic automatically on and off -> Yes")])
|
Property.Select(label="AutoMode",options=["Yes","No"], description="Switch Fermenterlogic automatically on and off -> Yes")])
|
||||||
class FermenterTargetTempStep(CBPiFermentationStep):
|
class FermenterTargetTempStep(CBPiFermentationStep):
|
||||||
|
|
||||||
async def NextStep(self, **kwargs):
|
async def NextStep(self, **kwargs):
|
||||||
await self.next()
|
return StepResult.DONE
|
||||||
|
#await self.next(self.fermenter)
|
||||||
|
|
||||||
async def on_timer_done(self,timer):
|
async def on_timer_done(self,timer):
|
||||||
self.summary = ""
|
self.summary = ""
|
||||||
|
@ -76,20 +76,21 @@ class FermenterTargetTempStep(CBPiFermentationStep):
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
if self.AutoMode == True:
|
if self.AutoMode == True:
|
||||||
await self.setAutoMode(False)
|
await self.setAutoMode(False)
|
||||||
self.cbpi.notify(self.name, self.props.get("Notification","Target Temp reached. Please add malt and klick next to move on."), action=[NotificationAction("Next Step", self.NextStep)])
|
self.cbpi.notify(self.name, self.props.get("Notification","Target Temp reached. Please add malt and klick next to move on."))
|
||||||
|
await self.next()
|
||||||
|
|
||||||
async def on_timer_update(self,timer, seconds):
|
async def on_timer_update(self,timer, seconds):
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
async def on_start(self):
|
async def on_start(self):
|
||||||
self.AutoMode = True if self.props.get("AutoMode","No") == "Yes" else False
|
self.AutoMode = True if self.props.get("AutoMode","No") == "Yes" else False
|
||||||
self.fermenter=self.get_fermenter(self.props.get("Fermenter", None))
|
self.starttemp= self.get_sensor_value(self.props.get("Sensor", None)).get("value")
|
||||||
if self.fermenter is not None:
|
if self.fermenter is not None:
|
||||||
self.fermenter.target_temp = int(self.props.get("Temp", 0))
|
self.fermenter.target_temp = int(self.props.get("Temp", 0))
|
||||||
if self.AutoMode == True:
|
if self.AutoMode == True:
|
||||||
await self.setAutoMode(True)
|
await self.setAutoMode(True)
|
||||||
self.summary = "Waiting for Target Temp"
|
self.summary = "Waiting for Target Temp"
|
||||||
if self.cbpi.fermenter is not None and self.timer is None:
|
if self.fermenter is not None and self.timer is None:
|
||||||
self.timer = Timer(1 ,on_update=self.on_timer_update, on_done=self.on_timer_done)
|
self.timer = Timer(1 ,on_update=self.on_timer_update, on_done=self.on_timer_done)
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
|
@ -101,12 +102,20 @@ class FermenterTargetTempStep(CBPiFermentationStep):
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
|
if self.fermenter.target_temp >= self.starttemp:
|
||||||
while self.running == True:
|
while self.running == True:
|
||||||
await asyncio.sleep(1)
|
|
||||||
sensor_value = self.get_sensor_value(self.props.get("Sensor", None)).get("value")
|
sensor_value = self.get_sensor_value(self.props.get("Sensor", None)).get("value")
|
||||||
if sensor_value >= int(self.props.get("Temp",0)) and self.timer.is_running is not True:
|
if sensor_value >= int(self.props.get("Temp",0)) and self.timer.is_running is not True:
|
||||||
self.timer.start()
|
self.timer.start()
|
||||||
self.timer.is_running = True
|
self.timer.is_running = True
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
else:
|
||||||
|
while self.running == True:
|
||||||
|
sensor_value = self.get_sensor_value(self.props.get("Sensor", None)).get("value")
|
||||||
|
if sensor_value <= int(self.props.get("Temp",0)) and self.timer.is_running is not True:
|
||||||
|
self.timer.start()
|
||||||
|
self.timer.is_running = True
|
||||||
|
await asyncio.sleep(1)
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
return StepResult.DONE
|
return StepResult.DONE
|
||||||
|
|
||||||
|
@ -116,9 +125,9 @@ class FermenterTargetTempStep(CBPiFermentationStep):
|
||||||
async def setAutoMode(self, auto_state):
|
async def setAutoMode(self, auto_state):
|
||||||
try:
|
try:
|
||||||
if (self.fermenter.instance is None or self.fermenter.instance.state == False) and (auto_state is True):
|
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)
|
await self.fermenter.instance.toggle(self.fermenter.id)
|
||||||
elif (self.fermenter.instance.state == True) and (auto_state is False):
|
elif (self.fermenter.instance.state == True) and (auto_state is False):
|
||||||
await self.cbpi.fermenter.stop(self.fermenter.id)
|
await self.fermenter.instance.stop(self.fermenter.id)
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -128,7 +137,6 @@ class FermenterTargetTempStep(CBPiFermentationStep):
|
||||||
@parameters([Property.Number(label="Timer", description="Time in Minutes", configurable=True),
|
@parameters([Property.Number(label="Timer", description="Time in Minutes", configurable=True),
|
||||||
Property.Number(label="Temp", configurable=True),
|
Property.Number(label="Temp", configurable=True),
|
||||||
Property.Sensor(label="Sensor"),
|
Property.Sensor(label="Sensor"),
|
||||||
Property.Fermenter(label="Fermenter"),
|
|
||||||
Property.Select(label="AutoMode",options=["Yes","No"], description="Switch Fermenterlogic automatically on and off -> Yes")])
|
Property.Select(label="AutoMode",options=["Yes","No"], description="Switch Fermenterlogic automatically on and off -> Yes")])
|
||||||
class FermenterStep(CBPiFermentationStep):
|
class FermenterStep(CBPiFermentationStep):
|
||||||
|
|
||||||
|
@ -164,17 +172,18 @@ class FermenterStep(CBPiFermentationStep):
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
async def on_start(self):
|
async def on_start(self):
|
||||||
|
logging.info(self.fermenter)
|
||||||
self.AutoMode = True if self.props.get("AutoMode", "No") == "Yes" else False
|
self.AutoMode = True if self.props.get("AutoMode", "No") == "Yes" else False
|
||||||
self.fermenter=self.get_fermenter(self.props.Fermenter)
|
self.starttemp= self.get_sensor_value(self.props.get("Sensor", None)).get("value")
|
||||||
if self.fermenter is not None:
|
if self.fermenter is not None:
|
||||||
self.fermenter.target_temp = int(self.props.get("Temp", 0))
|
self.fermenter.target_temp = int(self.props.get("Temp", 0))
|
||||||
if self.AutoMode == True:
|
if self.AutoMode == True:
|
||||||
await self.setAutoMode(True)
|
await self.setAutoMode(True)
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
if self.cbpi.fermenter is not None and self.timer is None:
|
if self.fermenter is not None and self.timer is None:
|
||||||
self.timer = Timer(int(self.props.get("Timer",0)) *60 ,on_update=self.on_timer_update, on_done=self.on_timer_done)
|
self.timer = Timer(int(self.props.get("Timer",0)) *60 ,on_update=self.on_timer_update, on_done=self.on_timer_done)
|
||||||
elif self.cbpi.fermenter is not None:
|
elif self.fermenter is not None:
|
||||||
try:
|
try:
|
||||||
if self.timer.is_running == True:
|
if self.timer.is_running == True:
|
||||||
self.timer.start()
|
self.timer.start()
|
||||||
|
@ -195,6 +204,7 @@ class FermenterStep(CBPiFermentationStep):
|
||||||
self.timer = Timer(int(self.props.get("Timer",0)) *60 ,on_update=self.on_timer_update, on_done=self.on_timer_done)
|
self.timer = Timer(int(self.props.get("Timer",0)) *60 ,on_update=self.on_timer_update, on_done=self.on_timer_done)
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
|
if self.fermenter.target_temp >= self.starttemp:
|
||||||
while self.running == True:
|
while self.running == True:
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
sensor_value = self.get_sensor_value(self.props.get("Sensor", None)).get("value")
|
sensor_value = self.get_sensor_value(self.props.get("Sensor", None)).get("value")
|
||||||
|
@ -203,14 +213,24 @@ class FermenterStep(CBPiFermentationStep):
|
||||||
self.timer.is_running = True
|
self.timer.is_running = True
|
||||||
estimated_completion_time = datetime.fromtimestamp(time.time()+ (int(self.props.get("Timer",0)))*60)
|
estimated_completion_time = datetime.fromtimestamp(time.time()+ (int(self.props.get("Timer",0)))*60)
|
||||||
self.cbpi.notify(self.name, 'Timer started. Estimated completion: {}'.format(estimated_completion_time.strftime("%H:%M")), NotificationType.INFO)
|
self.cbpi.notify(self.name, 'Timer started. Estimated completion: {}'.format(estimated_completion_time.strftime("%H:%M")), NotificationType.INFO)
|
||||||
|
else:
|
||||||
|
while self.running == True:
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
sensor_value = self.get_sensor_value(self.props.get("Sensor", None)).get("value")
|
||||||
|
if sensor_value <= int(self.props.get("Temp",0)) and self.timer.is_running is not True:
|
||||||
|
self.timer.start()
|
||||||
|
self.timer.is_running = True
|
||||||
|
estimated_completion_time = datetime.fromtimestamp(time.time()+ (int(self.props.get("Timer",0)))*60)
|
||||||
|
self.cbpi.notify(self.name, 'Timer started. Estimated completion: {}'.format(estimated_completion_time.strftime("%H:%M")), NotificationType.INFO)
|
||||||
|
|
||||||
return StepResult.DONE
|
return StepResult.DONE
|
||||||
|
|
||||||
async def setAutoMode(self, auto_state):
|
async def setAutoMode(self, auto_state):
|
||||||
try:
|
try:
|
||||||
if (self.fermenter.instance is None or self.fermenter.instance.state == False) and (auto_state is True):
|
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)
|
await self.fermenter.instance.toggle(self.fermenter.id)
|
||||||
elif (self.fermenter.instance.state == True) and (auto_state is False):
|
elif (self.fermenter.instance.state == True) and (auto_state is False):
|
||||||
await self.cbpi.fermenter.stop(self.fermenter.id)
|
await self.fermenter.instance.stop(self.fermenter.id)
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
@ -313,8 +313,8 @@ class FermentationHttpEndpoints():
|
||||||
|
|
||||||
data = await request.json()
|
data = await request.json()
|
||||||
fermenterid= request.match_info['id']
|
fermenterid= request.match_info['id']
|
||||||
step = FermenterStep(name=data.get("name"), props=Props(data.get("props", {})), type=data.get("type"))
|
newstep = {"name": data.get("name"), "props": data.get("props", {}), "type": data.get("type")}
|
||||||
response_data = await self.controller.create_step(fermenterid,step)
|
response_data = await self.controller.create_step(fermenterid,newstep)
|
||||||
return web.json_response(data=response_data.to_dict())
|
return web.json_response(data=response_data.to_dict())
|
||||||
|
|
||||||
@request_mapping(path="/{fermenterid}/{stepid}", method="PUT", auth_required=False)
|
@request_mapping(path="/{fermenterid}/{stepid}", method="PUT", auth_required=False)
|
||||||
|
@ -352,8 +352,9 @@ class FermentationHttpEndpoints():
|
||||||
data = await request.json()
|
data = await request.json()
|
||||||
stepid = request.match_info['stepid']
|
stepid = request.match_info['stepid']
|
||||||
fermenterid = request.match_info['fermenterid']
|
fermenterid = request.match_info['fermenterid']
|
||||||
step = FermenterStep(stepid, data.get("name"), None, Props(data.get("props", {})), data.get("type"))
|
updatedstep = {"id": stepid, "name": data.get("name"), "props": data.get("props", {}), "type": data.get("type")}
|
||||||
await self.controller.update_step(fermenterid,step)
|
#step = FermenterStep(stepid, data.get("name"), None, Props(data.get("props", {})), data.get("type"))
|
||||||
|
await self.controller.update_step(fermenterid,updatedstep)
|
||||||
return web.Response(status=200)
|
return web.Response(status=200)
|
||||||
|
|
||||||
@request_mapping(path="/{fermenterid}/{stepid}", method="DELETE", auth_required=False)
|
@request_mapping(path="/{fermenterid}/{stepid}", method="DELETE", auth_required=False)
|
||||||
|
@ -463,3 +464,123 @@ class FermentationHttpEndpoints():
|
||||||
fermenterid= request.match_info['id']
|
fermenterid= request.match_info['id']
|
||||||
await self.controller.clearsteps(fermenterid)
|
await self.controller.clearsteps(fermenterid)
|
||||||
return web.Response(status=200)
|
return web.Response(status=200)
|
||||||
|
|
||||||
|
@request_mapping(path="/{id}/startstep", method="POST", auth_required=False)
|
||||||
|
async def http_start_steps(self, request):
|
||||||
|
|
||||||
|
"""
|
||||||
|
---
|
||||||
|
description: Start steps for Fermenter with fermenterid
|
||||||
|
tags:
|
||||||
|
- Fermenter
|
||||||
|
parameters:
|
||||||
|
- name: "id"
|
||||||
|
in: "path"
|
||||||
|
description: "Fermenter ID"
|
||||||
|
required: true
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: successful operation
|
||||||
|
"""
|
||||||
|
|
||||||
|
fermenterid= request.match_info['id']
|
||||||
|
await self.controller.start(fermenterid)
|
||||||
|
return web.Response(status=200)
|
||||||
|
|
||||||
|
@request_mapping(path="/{id}/stopstep", method="POST", auth_required=False)
|
||||||
|
async def http_stop_steps(self, request):
|
||||||
|
|
||||||
|
"""
|
||||||
|
---
|
||||||
|
description: Stop steps for Fermenter with fermenterid
|
||||||
|
tags:
|
||||||
|
- Fermenter
|
||||||
|
parameters:
|
||||||
|
- name: "id"
|
||||||
|
in: "path"
|
||||||
|
description: "Fermenter ID"
|
||||||
|
required: true
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: successful operation
|
||||||
|
"""
|
||||||
|
|
||||||
|
fermenterid= request.match_info['id']
|
||||||
|
await self.controller.stop(fermenterid)
|
||||||
|
return web.Response(status=200)
|
||||||
|
|
||||||
|
@request_mapping(path="/{id}/nextstep", method="POST", auth_required=False)
|
||||||
|
async def http_next_step(self, request):
|
||||||
|
|
||||||
|
"""
|
||||||
|
---
|
||||||
|
description: Stop steps for Fermenter with fermenterid
|
||||||
|
tags:
|
||||||
|
- Fermenter
|
||||||
|
parameters:
|
||||||
|
- name: "id"
|
||||||
|
in: "path"
|
||||||
|
description: "Fermenter ID"
|
||||||
|
required: true
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: successful operation
|
||||||
|
"""
|
||||||
|
|
||||||
|
fermenterid= request.match_info['id']
|
||||||
|
await self.controller.next(fermenterid)
|
||||||
|
return web.Response(status=200)
|
||||||
|
|
||||||
|
@request_mapping(path="/{id}/nextstep", method="POST", auth_required=False)
|
||||||
|
async def http_next_step(self, request):
|
||||||
|
|
||||||
|
"""
|
||||||
|
---
|
||||||
|
description: Triggers next step for Fermenter with fermenterid
|
||||||
|
tags:
|
||||||
|
- Fermenter
|
||||||
|
parameters:
|
||||||
|
- name: "id"
|
||||||
|
in: "path"
|
||||||
|
description: "Fermenter ID"
|
||||||
|
required: true
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: successful operation
|
||||||
|
"""
|
||||||
|
|
||||||
|
fermenterid= request.match_info['id']
|
||||||
|
await self.controller.next(fermenterid)
|
||||||
|
return web.Response(status=200)
|
||||||
|
|
||||||
|
@request_mapping(path="/{id}/reset", method="POST", auth_required=False)
|
||||||
|
async def http_reset(self, request):
|
||||||
|
|
||||||
|
"""
|
||||||
|
---
|
||||||
|
description: Resets step status for Fermenter with fermenterid
|
||||||
|
tags:
|
||||||
|
- Fermenter
|
||||||
|
parameters:
|
||||||
|
- name: "id"
|
||||||
|
in: "path"
|
||||||
|
description: "Fermenter ID"
|
||||||
|
required: true
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: successful operation
|
||||||
|
"""
|
||||||
|
|
||||||
|
fermenterid= request.match_info['id']
|
||||||
|
await self.controller.reset(fermenterid)
|
||||||
|
return web.Response(status=200)
|
Loading…
Reference in a new issue