mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-21 22:48:16 +01:00
Merge form dev branch
This commit is contained in:
commit
036e70e4bf
18 changed files with 220 additions and 239 deletions
|
@ -1 +1 @@
|
||||||
__version__ = "4.0.2.0.a8"
|
__version__ = "4.0.2.0.a19"
|
||||||
|
|
|
@ -131,7 +131,7 @@ class Fermenter:
|
||||||
brewname: str = None
|
brewname: str = None
|
||||||
description : str = None
|
description : str = None
|
||||||
props: Props = Props()
|
props: Props = Props()
|
||||||
target_temp: int = 0
|
target_temp: float = 0
|
||||||
type: str = None
|
type: str = None
|
||||||
steps: List[Step]= field(default_factory=list)
|
steps: List[Step]= field(default_factory=list)
|
||||||
instance: str = None
|
instance: str = None
|
||||||
|
@ -162,7 +162,7 @@ class FermenterStep:
|
||||||
props: Props = Props()
|
props: Props = Props()
|
||||||
type: str = None
|
type: str = None
|
||||||
status: StepState = StepState.INITIAL
|
status: StepState = StepState.INITIAL
|
||||||
endtime: int = 0 # endtime if step is active and timer is running
|
endtime: int = 0 # endtime if step is active and timer is running
|
||||||
instance: str = None
|
instance: str = None
|
||||||
step: dict = None
|
step: dict = None
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ class FermenterStep:
|
||||||
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)
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
msg = self.instance.summary if self.instance is not None else ""
|
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, endtime = self.endtime, 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())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -117,15 +117,6 @@ 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):
|
|
||||||
|
|
||||||
# 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):
|
class CBPiFermentationStep(CBPiBase):
|
||||||
|
|
||||||
def __init__(self, cbpi, fermenter, step, props, on_done) -> None:
|
def __init__(self, cbpi, fermenter, step, props, on_done) -> None:
|
||||||
|
@ -190,9 +181,9 @@ class CBPiFermentationStep(CBPiBase):
|
||||||
|
|
||||||
async def update_endtime(self):
|
async def update_endtime(self):
|
||||||
await self.cbpi.fermenter.update_endtime(self.fermenter.id, self.id, self.endtime)
|
await self.cbpi.fermenter.update_endtime(self.fermenter.id, self.id, self.endtime)
|
||||||
|
|
||||||
async def save_props(self):
|
async def save_props(self):
|
||||||
self.cbpi.fermenter.save()
|
self.cbpi.fermenter.save()
|
||||||
|
|
||||||
async def push_update(self):
|
async def push_update(self):
|
||||||
self.cbpi.fermenter.push_update(self.update_key)
|
self.cbpi.fermenter.push_update(self.update_key)
|
||||||
|
|
|
@ -22,7 +22,7 @@ class BasicController:
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
self.data = []
|
self.data = []
|
||||||
self.autostart = True
|
self.autostart = True
|
||||||
self._loop = asyncio.get_event_loop()
|
#self._loop = asyncio.get_event_loop()
|
||||||
self.path = os.path.join(".", 'config', file)
|
self.path = os.path.join(".", 'config', file)
|
||||||
self.cbpi.app.on_cleanup.append(self.shutdown)
|
self.cbpi.app.on_cleanup.append(self.shutdown)
|
||||||
|
|
||||||
|
@ -100,7 +100,8 @@ class BasicController:
|
||||||
|
|
||||||
await item.instance.start()
|
await item.instance.start()
|
||||||
item.instance.running = True
|
item.instance.running = True
|
||||||
item.instance.task = self._loop.create_task(item.instance._run())
|
item.instance.task = asyncio.get_event_loop().create_task(item.instance._run())
|
||||||
|
#item.instance.task = self._loop.create_task(item.instance._run())
|
||||||
|
|
||||||
logging.info("{} started {}".format(self.name, id))
|
logging.info("{} started {}".format(self.name, id))
|
||||||
|
|
||||||
|
|
|
@ -15,79 +15,7 @@ from cbpi.controller.basic_controller2 import BasicController
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
import sys, os
|
import sys, os
|
||||||
from ..api.step import CBPiStep, StepMove, StepResult, StepState, CBPiFermentationStep
|
from ..api.step import CBPiStep, StepMove, StepResult, StepState, CBPiFermentationStep
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FermentStep:
|
|
||||||
|
|
||||||
def __init__(self, cbpi, step, on_done) -> None:
|
|
||||||
self.cbpi = cbpi
|
|
||||||
self.logger = logging.getLogger(__name__)
|
|
||||||
self.step = step
|
|
||||||
self.props = step.props
|
|
||||||
self._done_callback = on_done
|
|
||||||
self.task = None
|
|
||||||
self.summary = ""
|
|
||||||
|
|
||||||
def _done(self, task):
|
|
||||||
if self._done_callback is not None:
|
|
||||||
try:
|
|
||||||
result = task.result()
|
|
||||||
self._done_callback(self, result)
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error(e)
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def run(self):
|
|
||||||
while self.running:
|
|
||||||
logging.info(self.step)
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def _run(self):
|
|
||||||
try:
|
|
||||||
await self.step.instance.on_start()
|
|
||||||
await self.step.instance.run()
|
|
||||||
#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
|
|
||||||
|
|
||||||
async def start(self):
|
|
||||||
self.logger.info("Start {}".format(self.step.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.logger.info("Stopping Task")
|
|
||||||
self.cancel_reason = StepResult.STOP
|
|
||||||
self.task.cancel()
|
|
||||||
await self.task
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.error(e)
|
|
||||||
|
|
||||||
async def on_start(self):
|
|
||||||
#self.props.hello = "WOOHOo"
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def on_stop(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class FermentationController:
|
class FermentationController:
|
||||||
|
|
||||||
def __init__(self, cbpi):
|
def __init__(self, cbpi):
|
||||||
|
@ -95,7 +23,6 @@ class FermentationController:
|
||||||
self.cbpi = cbpi
|
self.cbpi = cbpi
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
self.path = os.path.join(".", 'config', "fermenter_data.json")
|
self.path = os.path.join(".", 'config', "fermenter_data.json")
|
||||||
|
|
||||||
self.data = []
|
self.data = []
|
||||||
self.types = {}
|
self.types = {}
|
||||||
self.steptypes = {}
|
self.steptypes = {}
|
||||||
|
@ -127,6 +54,10 @@ class FermentationController:
|
||||||
for step in fermenter.steps:
|
for step in fermenter.steps:
|
||||||
try:
|
try:
|
||||||
self.logger.info("Stop {}".format(step.name))
|
self.logger.info("Stop {}".format(step.name))
|
||||||
|
try:
|
||||||
|
step.instance.shutdown = True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
await step.instance.stop()
|
await step.instance.stop()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
@ -136,15 +67,16 @@ class FermentationController:
|
||||||
for step in fermenter.steps:
|
for step in fermenter.steps:
|
||||||
try:
|
try:
|
||||||
self.logger.info("Stop {}".format(step.name))
|
self.logger.info("Stop {}".format(step.name))
|
||||||
|
try:
|
||||||
|
step.instance.shutdown = True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
await step.instance.stop()
|
await step.instance.stop()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
|
||||||
|
|
||||||
async def load(self):
|
async def load(self):
|
||||||
# if os.path.exists(self.path) is False:
|
|
||||||
# with open(self.path, "w") as file:
|
|
||||||
# json.dump(dict(basic={}, steps=[]), file, indent=4, sort_keys=True)
|
|
||||||
with open(self.path) as json_file:
|
with open(self.path) as json_file:
|
||||||
data = json.load(json_file)
|
data = json.load(json_file)
|
||||||
|
|
||||||
|
@ -155,12 +87,14 @@ class FermentationController:
|
||||||
id = item.get("id")
|
id = item.get("id")
|
||||||
name = item.get("name")
|
name = item.get("name")
|
||||||
props = Props(item.get("props"))
|
props = Props(item.get("props"))
|
||||||
|
try:
|
||||||
|
endtime = int(item.get("endtime", 0))
|
||||||
|
except:
|
||||||
|
endtime=0
|
||||||
|
|
||||||
status = StepState(item.get("status", "I"))
|
status = StepState(item.get("status", "I"))
|
||||||
endtime = int(item.get("endtime", 0))
|
|
||||||
if status == StepState.ACTIVE:
|
if status == StepState.ACTIVE:
|
||||||
status = StepState("S")
|
status = StepState("S")
|
||||||
if status != StepState.STOP:
|
|
||||||
endtime = 0
|
|
||||||
type = item.get("type")
|
type = item.get("type")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -221,7 +155,6 @@ class FermentationController:
|
||||||
|
|
||||||
def get_state(self):
|
def get_state(self):
|
||||||
if self.data == []:
|
if self.data == []:
|
||||||
#logging.info(self.data)
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return {"data": list(map(lambda x: x.to_dict(), self.data)), "types":self.get_types(), "steptypes":self.get_steptypes()}
|
return {"data": list(map(lambda x: x.to_dict(), self.data)), "types":self.get_types(), "steptypes":self.get_steptypes()}
|
||||||
|
@ -238,7 +171,6 @@ class FermentationController:
|
||||||
|
|
||||||
def get_fermenter_steps(self):
|
def get_fermenter_steps(self):
|
||||||
if self.data == []:
|
if self.data == []:
|
||||||
#logging.info(self.data)
|
|
||||||
pass
|
pass
|
||||||
fermentersteps=[]
|
fermentersteps=[]
|
||||||
steplist=list(map(lambda x: x.to_dict(), self.data))
|
steplist=list(map(lambda x: x.to_dict(), self.data))
|
||||||
|
@ -307,16 +239,16 @@ 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, item):
|
def create_step(self, id, item):
|
||||||
try:
|
try:
|
||||||
stepid = shortuuid.uuid()
|
stepid = shortuuid.uuid()
|
||||||
props = item.get("props")
|
item['id'] = stepid
|
||||||
status = StepState("I")
|
status = StepState("I")
|
||||||
type = item.get("type")
|
type = item.get("type")
|
||||||
name = item.get("name")
|
name = item.get("name")
|
||||||
|
endtime = item.get("endtime", 0)
|
||||||
props = Props(item.get("props"))
|
props = Props(item.get("props"))
|
||||||
fermenter = self._find_by_id(id)
|
fermenter = self._find_by_id(id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
type_cfg = self.steptypes.get(type)
|
type_cfg = self.steptypes.get(type)
|
||||||
clazz = type_cfg.get("class")
|
clazz = type_cfg.get("class")
|
||||||
|
@ -324,13 +256,8 @@ class FermentationController:
|
||||||
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 = FermenterStep(id=stepid, name=name, fermenter=fermenter, props=props, type=type, status=status, instance=instance)
|
step = FermenterStep(id=stepid, name=name, fermenter=fermenter, props=props, type=type, status=status, endtime=endtime, instance=instance)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fermenter.steps.append(step)
|
|
||||||
self.save()
|
|
||||||
self.push_update("fermenterstepupdate")
|
|
||||||
return step
|
return step
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
|
@ -341,30 +268,29 @@ class FermentationController:
|
||||||
props = item.get("props")
|
props = item.get("props")
|
||||||
status = StepState("I")
|
status = StepState("I")
|
||||||
type = item.get("type")
|
type = item.get("type")
|
||||||
#logging.info(type)
|
endtime = 0
|
||||||
name = item.get("name")
|
name = item.get("name")
|
||||||
props = Props(item.get("props"))
|
props = Props(item.get("props"))
|
||||||
|
|
||||||
logging.info("update step")
|
logging.info("update step")
|
||||||
try:
|
try:
|
||||||
type_cfg = self.steptypes.get(type)
|
type_cfg = self.steptypes.get(type)
|
||||||
#logging.info(type_cfg)
|
logging.info(type_cfg)
|
||||||
clazz = type_cfg.get("class")
|
clazz = type_cfg.get("class")
|
||||||
#logging.info(clazz)
|
logging.info(clazz)
|
||||||
instance = clazz(self.cbpi, fermenter, item, props, self._done)
|
instance = clazz(self.cbpi, fermenter, item, props, self._done)
|
||||||
|
logging.info(instance)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.warning("Failed to create step instance %s - %s " % (item.id, e))
|
logging.warning("Failed to create step instance %s - %s " % (item.id, e))
|
||||||
instance = None
|
instance = None
|
||||||
step = FermenterStep(id=stepid, name=name, fermenter=fermenter, props=props, type=type, status=status, instance=instance)
|
step = FermenterStep(id=stepid, name=name, fermenter=fermenter, props=props, type=type, status=status, endtime=endtime, instance=instance)
|
||||||
#logging.info(step)
|
|
||||||
#logging.info(fermenter.steps)
|
|
||||||
try:
|
try:
|
||||||
fermenter.steps = list(map(lambda old: step if old.id == step.id else old, fermenter.steps))
|
fermenter.steps = list(map(lambda old: step if old.id == step.id else old, fermenter.steps))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.info(e)
|
logging.info(e)
|
||||||
#logging.info(fermenter.steps)
|
|
||||||
self.save()
|
self.save()
|
||||||
#logging.info("SAVEUPDATE")
|
|
||||||
|
|
||||||
self.push_update("fermenterstepupdate")
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
|
@ -382,6 +308,15 @@ class FermentationController:
|
||||||
self.save()
|
self.save()
|
||||||
self.push_update("fermenterstepupdate")
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
def _find_by_status(self, data, status):
|
def _find_by_status(self, data, status):
|
||||||
return next((item for item in data if item.status == status), None)
|
return next((item for item in data if item.status == status), None)
|
||||||
|
@ -419,6 +354,7 @@ class FermentationController:
|
||||||
logging.info("Need to change timer")
|
logging.info("Need to change timer")
|
||||||
step.status = StepState.ACTIVE
|
step.status = StepState.ACTIVE
|
||||||
self.save()
|
self.save()
|
||||||
|
self.push_update()
|
||||||
self.push_update("fermenterstepupdate")
|
self.push_update("fermenterstepupdate")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -432,6 +368,7 @@ class FermentationController:
|
||||||
logging.info("Starting step {}".format(step.name))
|
logging.info("Starting step {}".format(step.name))
|
||||||
step.status = StepState.ACTIVE
|
step.status = StepState.ACTIVE
|
||||||
self.save()
|
self.save()
|
||||||
|
self.push_update()
|
||||||
self.push_update("fermenterstepupdate")
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -517,7 +454,7 @@ class FermentationController:
|
||||||
await self.start(id)
|
await self.start(id)
|
||||||
else:
|
else:
|
||||||
logging.info("No Step is running")
|
logging.info("No Step is running")
|
||||||
|
self.push_update()
|
||||||
self.push_update("fermenterstepupdate")
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -531,12 +468,14 @@ class FermentationController:
|
||||||
for step in item.steps:
|
for step in item.steps:
|
||||||
self.logger.info("Stopping Step {} {}".format(step.name, step.id))
|
self.logger.info("Stopping Step {} {}".format(step.name, step.id))
|
||||||
try:
|
try:
|
||||||
|
await step.instance.stop()
|
||||||
await step.instance.reset()
|
await step.instance.reset()
|
||||||
await step.instance.stop()
|
|
||||||
step.status = StepState.INITIAL
|
step.status = StepState.INITIAL
|
||||||
|
step.endtime = 0
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
self.save()
|
self.save()
|
||||||
|
self.push_update()
|
||||||
self.push_update("fermenterstepupdate")
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -555,6 +494,7 @@ class FermentationController:
|
||||||
|
|
||||||
fermenter.steps[index], fermenter.steps[index+direction] = fermenter.steps[index+direction], fermenter.steps[index]
|
fermenter.steps[index], fermenter.steps[index+direction] = fermenter.steps[index+direction], fermenter.steps[index]
|
||||||
self.save()
|
self.save()
|
||||||
|
self.push_update()
|
||||||
self.push_update("fermenterstepupdate")
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -564,15 +504,19 @@ class FermentationController:
|
||||||
|
|
||||||
if key == self.update_key:
|
if key == self.update_key:
|
||||||
self.cbpi.ws.send(dict(topic=key, data=list(map(lambda item: item.to_dict(), self.data))))
|
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:
|
for item in self.data:
|
||||||
self.cbpi.push_update("cbpi/{}/{}".format(self.update_key,item.id), item.to_dict())
|
self.cbpi.push_update("cbpi/{}/{}".format(self.update_key,item.id), item.to_dict())
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
#logging.info("FERMENTERSTEPUPDATE {}".format(key))
|
|
||||||
fermentersteps=self.get_fermenter_steps()
|
fermentersteps=self.get_fermenter_steps()
|
||||||
self.cbpi.ws.send(dict(topic=key, data=fermentersteps))
|
self.cbpi.ws.send(dict(topic=key, data=fermentersteps))
|
||||||
|
|
||||||
|
# send mqtt update for active femrentersteps
|
||||||
|
for fermenter in fermentersteps:
|
||||||
|
for step in fermenter['steps']:
|
||||||
|
if step['status'] == 'A':
|
||||||
|
self.cbpi.push_update("cbpi/{}/{}/{}".format(key,fermenter['id'],step['id']), step)
|
||||||
|
|
||||||
async def call_action(self, id, action, parameter) -> None:
|
async def call_action(self, id, action, parameter) -> None:
|
||||||
logging.info("FermenterStep Controller - call Action {} {}".format(id, action))
|
logging.info("FermenterStep Controller - call Action {} {}".format(id, action))
|
||||||
|
@ -582,8 +526,7 @@ class FermentationController:
|
||||||
await item.instance.__getattribute__(action)(**parameter)
|
await item.instance.__getattribute__(action)(**parameter)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("FermenterStep Controller - Failed to call action on {} {} {}".format(id, action, e))
|
logging.error("FermenterStep Controller - Failed to call action on {} {} {}".format(id, action, e))
|
||||||
|
|
||||||
# todo: Sensors may need to be removed when saving the recipe -> need to be replaced when assinging later to Fermenter with 'fermenter.sensor'
|
|
||||||
async def savetobook(self, fermenterid):
|
async def savetobook(self, fermenterid):
|
||||||
name = shortuuid.uuid()
|
name = shortuuid.uuid()
|
||||||
path = os.path.join(".", 'config', "fermenterrecipes", "{}.yaml".format(name))
|
path = os.path.join(".", 'config', "fermenterrecipes", "{}.yaml".format(name))
|
||||||
|
@ -591,7 +534,7 @@ class FermentationController:
|
||||||
try:
|
try:
|
||||||
brewname = fermenter.brewname
|
brewname = fermenter.brewname
|
||||||
description = fermenter.description
|
description = fermenter.description
|
||||||
# todo add escription at later point of time, once description has been added to fermenter dataclass
|
|
||||||
except:
|
except:
|
||||||
brewname = ""
|
brewname = ""
|
||||||
description = ""
|
description = ""
|
||||||
|
@ -605,20 +548,38 @@ class FermentationController:
|
||||||
with open(path, "w") as file:
|
with open(path, "w") as file:
|
||||||
yaml.dump(data, file)
|
yaml.dump(data, file)
|
||||||
|
|
||||||
async def load_recipe(self, data, fermenterid):
|
async def load_recipe(self, data, fermenterid, name):
|
||||||
try:
|
try:
|
||||||
await self.shutdown(None, fermenterid)
|
await self.shutdown(None, fermenterid)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
fermenter = self._find_by_id(fermenterid)
|
fermenter = self._find_by_id(fermenterid)
|
||||||
|
|
||||||
def add_runtime_data(item):
|
def add_runtime_data(item):
|
||||||
item["status"] = "I"
|
item["status"] = "I"
|
||||||
|
item["endtime"] = 0
|
||||||
item["id"] = shortuuid.uuid()
|
item["id"] = shortuuid.uuid()
|
||||||
item["props"]["Sensor"] = fermenter.sensor
|
item["props"]["Sensor"] = fermenter.sensor
|
||||||
|
|
||||||
list(map(lambda item: add_runtime_data(item), data.get("steps")))
|
list(map(lambda item: add_runtime_data(item), data.get("steps")))
|
||||||
fermenter.description = data['basic']['desc']
|
fermenter.description = data['basic']['desc']
|
||||||
fermenter.brewname = data['basic']['name']
|
if name is not None:
|
||||||
fermenter.steps=[]
|
fermenter.brewname = name
|
||||||
|
else:
|
||||||
|
fermenter.brewname = data['basic']['name']
|
||||||
await self.update(fermenter)
|
await self.update(fermenter)
|
||||||
|
fermenter.steps=[]
|
||||||
for item in data.get("steps"):
|
for item in data.get("steps"):
|
||||||
await self.create_step(fermenterid, item)
|
fermenter.steps.append(self.create_step(fermenterid, item))
|
||||||
|
|
||||||
|
self.save()
|
||||||
|
self.push_update("fermenterstepupdate")
|
||||||
|
|
||||||
|
async def add_step(self, fermenterid, newstep):
|
||||||
|
fermenter = self._find_by_id(fermenterid)
|
||||||
|
step = self.create_step(fermenterid, newstep)
|
||||||
|
fermenter.steps.append(step)
|
||||||
|
self.save()
|
||||||
|
self.push_update("fermenterstepupdate")
|
||||||
|
return step
|
||||||
|
|
|
@ -69,13 +69,13 @@ class FermenterRecipeController:
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
|
|
||||||
|
|
||||||
async def brew(self, name, fermenterid):
|
async def brew(self, recipeid, fermenterid, name):
|
||||||
|
|
||||||
recipe_path = os.path.join(".", 'config', "fermenterrecipes", "%s.yaml" % name)
|
recipe_path = os.path.join(".", 'config', "fermenterrecipes", "%s.yaml" % recipeid)
|
||||||
logging.info(recipe_path)
|
logging.info(recipe_path)
|
||||||
with open(recipe_path) as file:
|
with open(recipe_path) as file:
|
||||||
data = yaml.load(file, Loader=yaml.FullLoader)
|
data = yaml.load(file, Loader=yaml.FullLoader)
|
||||||
await self.cbpi.fermenter.load_recipe(data, fermenterid)
|
await self.cbpi.fermenter.load_recipe(data, fermenterid, name)
|
||||||
|
|
||||||
async def clone(self, id, new_name):
|
async def clone(self, id, new_name):
|
||||||
recipe_path = os.path.join(".", 'config', "fermenterrecipes", "%s.yaml" % id)
|
recipe_path = os.path.join(".", 'config', "fermenterrecipes", "%s.yaml" % id)
|
||||||
|
|
|
@ -20,7 +20,7 @@ class StepController:
|
||||||
self.cbpi = cbpi
|
self.cbpi = cbpi
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
self.path = os.path.join(".", 'config', "step_data.json")
|
self.path = os.path.join(".", 'config', "step_data.json")
|
||||||
self._loop = asyncio.get_event_loop()
|
#self._loop = asyncio.get_event_loop()
|
||||||
self.basic_data = {}
|
self.basic_data = {}
|
||||||
self.step = None
|
self.step = None
|
||||||
self.types = {}
|
self.types = {}
|
||||||
|
@ -68,8 +68,9 @@ class StepController:
|
||||||
self.profile = list(map(lambda item: self.create(item), self.profile))
|
self.profile = list(map(lambda item: self.create(item), self.profile))
|
||||||
if startActive is True:
|
if startActive is True:
|
||||||
active_step = self.find_by_status("A")
|
active_step = self.find_by_status("A")
|
||||||
if active_step is not None:
|
if active_step is not None:
|
||||||
self._loop.create_task(self.start_step(active_step))
|
asyncio.get_event_loop().create_task(self.start_step(active_step))
|
||||||
|
#self._loop.create_task(self.start_step(active_step))
|
||||||
|
|
||||||
async def add(self, item: Step):
|
async def add(self, item: Step):
|
||||||
logging.debug("Add step")
|
logging.debug("Add step")
|
||||||
|
|
|
@ -178,6 +178,8 @@ class SystemController:
|
||||||
mempercent = 0
|
mempercent = 0
|
||||||
eth0IP = "N/A"
|
eth0IP = "N/A"
|
||||||
wlan0IP = "N/A"
|
wlan0IP = "N/A"
|
||||||
|
eth0speed = "N/A"
|
||||||
|
wlan0speed = "N/A"
|
||||||
|
|
||||||
TEMP_UNIT=self.cbpi.config.get("TEMP_UNIT", "C")
|
TEMP_UNIT=self.cbpi.config.get("TEMP_UNIT", "C")
|
||||||
FAHRENHEIT = False if TEMP_UNIT == "C" else True
|
FAHRENHEIT = False if TEMP_UNIT == "C" else True
|
||||||
|
@ -225,12 +227,31 @@ class SystemController:
|
||||||
if str(addr.family) == "AddressFamily.AF_INET":
|
if str(addr.family) == "AddressFamily.AF_INET":
|
||||||
if addr.address:
|
if addr.address:
|
||||||
wlan0IP = addr.address
|
wlan0IP = addr.address
|
||||||
|
info = psutil.net_if_stats()
|
||||||
|
try:
|
||||||
|
for nic in info:
|
||||||
|
if nic == 'eth0':
|
||||||
|
if info[nic].isup == True:
|
||||||
|
if info[nic].speed:
|
||||||
|
eth0speed = info[nic].speed
|
||||||
|
else:
|
||||||
|
eth0speed = "down"
|
||||||
|
if nic == 'wlan0':
|
||||||
|
if info[nic].isup == True:
|
||||||
|
ratestring = os.popen('iwlist wlan0 rate | grep Rate').read()
|
||||||
|
start = ratestring.find("=") + 1
|
||||||
|
end = ratestring.find(" Mb/s")
|
||||||
|
wlan0speed = ratestring[start:end]
|
||||||
|
else:
|
||||||
|
wlan0speed = "down"
|
||||||
|
except Exception as e:
|
||||||
|
logging.info(e)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if system == "Windows":
|
if system == "Windows":
|
||||||
try:
|
try:
|
||||||
ethernet = psutil.net_if_addrs()
|
ethernet = psutil.net_if_addrs()
|
||||||
for nic, addrs in ethernet.items():
|
for nic, addrs in ethernet.items():
|
||||||
if nic == "Ethernet":
|
if nic == "Ethernet":
|
||||||
for addr in addrs:
|
for addr in addrs:
|
||||||
|
@ -242,6 +263,23 @@ class SystemController:
|
||||||
if str(addr.family) == "AddressFamily.AF_INET":
|
if str(addr.family) == "AddressFamily.AF_INET":
|
||||||
if addr.address:
|
if addr.address:
|
||||||
wlan0IP = addr.address
|
wlan0IP = addr.address
|
||||||
|
info = psutil.net_if_stats()
|
||||||
|
try:
|
||||||
|
for nic in info:
|
||||||
|
if nic == 'Ethernet':
|
||||||
|
if info[nic].isup == True:
|
||||||
|
if info[nic].speed:
|
||||||
|
eth0speed = info[nic].speed
|
||||||
|
else:
|
||||||
|
eth0speed = "down"
|
||||||
|
if nic == 'WLAN':
|
||||||
|
if info[nic].isup == True:
|
||||||
|
if info[nic].speed:
|
||||||
|
wlan0speed = info[nic].speed
|
||||||
|
else:
|
||||||
|
wlan0speed = "down"
|
||||||
|
except Exception as e:
|
||||||
|
logging.info(e)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -258,7 +296,9 @@ class SystemController:
|
||||||
'temp': temp,
|
'temp': temp,
|
||||||
'temp_unit': TEMP_UNIT,
|
'temp_unit': TEMP_UNIT,
|
||||||
'eth0': eth0IP,
|
'eth0': eth0IP,
|
||||||
'wlan0': wlan0IP}
|
'wlan0': wlan0IP,
|
||||||
|
'eth0speed': eth0speed,
|
||||||
|
'wlan0speed': wlan0speed}
|
||||||
return systeminfo
|
return systeminfo
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import sys
|
||||||
|
try:
|
||||||
|
from asyncio import set_event_loop_policy, WindowsSelectorEventLoopPolicy
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
import json
|
import json
|
||||||
from voluptuous.schema_builder import message
|
from voluptuous.schema_builder import message
|
||||||
from cbpi.api.dataclasses import NotificationType
|
from cbpi.api.dataclasses import NotificationType
|
||||||
|
@ -82,6 +87,11 @@ async def error_middleware(request, handler):
|
||||||
class CraftBeerPi:
|
class CraftBeerPi:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
|
operationsystem= sys.platform
|
||||||
|
if operationsystem.startswith('win'):
|
||||||
|
set_event_loop_policy(WindowsSelectorEventLoopPolicy())
|
||||||
|
|
||||||
self.path = os.sep.join(os.path.abspath(__file__).split(os.sep)[:-1]) # The path to the package dir
|
self.path = os.sep.join(os.path.abspath(__file__).split(os.sep)[:-1]) # The path to the package dir
|
||||||
|
|
||||||
self.version = __version__
|
self.version = __version__
|
||||||
|
|
|
@ -32,8 +32,9 @@ class FermenterNotificationStep(CBPiFermentationStep):
|
||||||
|
|
||||||
if self.AutoNext == True:
|
if self.AutoNext == True:
|
||||||
self.cbpi.notify(self.name, self.props.get("Notification",""), NotificationType.INFO)
|
self.cbpi.notify(self.name, self.props.get("Notification",""), NotificationType.INFO)
|
||||||
await self.next(self.fermenter.id)
|
if self.shutdown != True:
|
||||||
return StepResult.DONE
|
await self.next(self.fermenter.id)
|
||||||
|
return StepResult.DONE
|
||||||
else:
|
else:
|
||||||
self.cbpi.notify(self.name, self.props.get("Notification",""), NotificationType.INFO, action=[NotificationAction("Next Step", self.NextStep)])
|
self.cbpi.notify(self.name, self.props.get("Notification",""), NotificationType.INFO, action=[NotificationAction("Next Step", self.NextStep)])
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
@ -42,6 +43,7 @@ class FermenterNotificationStep(CBPiFermentationStep):
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
async def on_start(self):
|
async def on_start(self):
|
||||||
|
self.shutdown = False
|
||||||
self.summary=""
|
self.summary=""
|
||||||
self.AutoNext = False if self.props.get("AutoNext", "No") == "No" else True
|
self.AutoNext = False if self.props.get("AutoNext", "No") == "No" else True
|
||||||
if self.timer is None:
|
if self.timer is None:
|
||||||
|
@ -69,13 +71,12 @@ class FermenterNotificationStep(CBPiFermentationStep):
|
||||||
class FermenterTargetTempStep(CBPiFermentationStep):
|
class FermenterTargetTempStep(CBPiFermentationStep):
|
||||||
|
|
||||||
async def NextStep(self, **kwargs):
|
async def NextStep(self, **kwargs):
|
||||||
await self.next(self.fermenter.id)
|
if self.shutdown != True:
|
||||||
return StepResult.DONE
|
await self.next(self.fermenter.id)
|
||||||
|
return StepResult.DONE
|
||||||
|
|
||||||
|
|
||||||
async def on_timer_done(self,timer):
|
async def on_timer_done(self,timer):
|
||||||
self.summary = ""
|
self.summary = ""
|
||||||
#self.fermenter.target_temp = 0
|
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
if self.AutoMode == True:
|
if self.AutoMode == True:
|
||||||
await self.setAutoMode(False)
|
await self.setAutoMode(False)
|
||||||
|
@ -88,10 +89,10 @@ class FermenterTargetTempStep(CBPiFermentationStep):
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
async def on_start(self):
|
async def on_start(self):
|
||||||
|
self.shutdown = False
|
||||||
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.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 = float(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"
|
||||||
|
@ -107,6 +108,9 @@ class FermenterTargetTempStep(CBPiFermentationStep):
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
|
while self.get_sensor_value(self.props.get("Sensor", None)).get("value") > 900:
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
self.starttemp= self.get_sensor_value(self.props.get("Sensor", None)).get("value")
|
||||||
if self.fermenter.target_temp >= self.starttemp:
|
if self.fermenter.target_temp >= self.starttemp:
|
||||||
logging.info("warmup")
|
logging.info("warmup")
|
||||||
while self.running == True:
|
while self.running == True:
|
||||||
|
@ -128,6 +132,7 @@ class FermenterTargetTempStep(CBPiFermentationStep):
|
||||||
|
|
||||||
async def reset(self):
|
async def reset(self):
|
||||||
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)
|
||||||
|
self.timer.is_running == False
|
||||||
|
|
||||||
async def setAutoMode(self, auto_state):
|
async def setAutoMode(self, auto_state):
|
||||||
try:
|
try:
|
||||||
|
@ -162,13 +167,15 @@ class FermenterStep(CBPiFermentationStep):
|
||||||
else:
|
else:
|
||||||
self.cbpi.notify(self.name, 'Timer is already running', NotificationType.WARNING)
|
self.cbpi.notify(self.name, 'Timer is already running', NotificationType.WARNING)
|
||||||
|
|
||||||
#@action("Add 5 Minutes to Timer", [])
|
# @action("Add 1 Day to Timer", [])
|
||||||
#async def add_timer(self):
|
# async def add_timer(self):
|
||||||
# if self.timer.is_running == True:
|
# if self.timer.is_running == True:
|
||||||
# self.cbpi.notify(self.name, '5 Minutes added', NotificationType.INFO)
|
# self.cbpi.notify(self.name, '1 Day added', NotificationType.INFO)
|
||||||
# await self.timer.add(300)
|
# await self.timer.add(86400)
|
||||||
# else:
|
# self.endtime = self.endtime +86400
|
||||||
# self.cbpi.notify(self.name, 'Timer must be running to add time', NotificationType.WARNING)
|
# await self.update_endtime()
|
||||||
|
# else:
|
||||||
|
# self.cbpi.notify(self.name, 'Timer must be running to add time', NotificationType.WARNING)
|
||||||
|
|
||||||
|
|
||||||
async def on_timer_done(self,timer):
|
async def on_timer_done(self,timer):
|
||||||
|
@ -176,8 +183,9 @@ class FermenterStep(CBPiFermentationStep):
|
||||||
if self.AutoMode == True:
|
if self.AutoMode == True:
|
||||||
await self.setAutoMode(False)
|
await self.setAutoMode(False)
|
||||||
self.cbpi.notify(self.name, 'Step finished', NotificationType.SUCCESS)
|
self.cbpi.notify(self.name, 'Step finished', NotificationType.SUCCESS)
|
||||||
await self.next(self.fermenter.id)
|
if self.shutdown != True:
|
||||||
return StepResult.DONE
|
await self.next(self.fermenter.id)
|
||||||
|
return StepResult.DONE
|
||||||
|
|
||||||
|
|
||||||
async def on_timer_update(self,timer, seconds):
|
async def on_timer_update(self,timer, seconds):
|
||||||
|
@ -185,7 +193,8 @@ class FermenterStep(CBPiFermentationStep):
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
async def on_start(self):
|
async def on_start(self):
|
||||||
if self.endtime == 0:
|
self.shutdown = False
|
||||||
|
if self.endtime == 0:
|
||||||
timeD=int(self.props.get("TimerD", 0))
|
timeD=int(self.props.get("TimerD", 0))
|
||||||
timeH=int(self.props.get("TimerH", 0))
|
timeH=int(self.props.get("TimerH", 0))
|
||||||
timeM=int(self.props.get("TimerM", 0))
|
timeM=int(self.props.get("TimerM", 0))
|
||||||
|
@ -194,9 +203,8 @@ class FermenterStep(CBPiFermentationStep):
|
||||||
self.fermentationtime = self.endtime - time.time()
|
self.fermentationtime = self.endtime - time.time()
|
||||||
|
|
||||||
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.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 = float(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()
|
||||||
|
@ -217,6 +225,9 @@ class FermenterStep(CBPiFermentationStep):
|
||||||
if self.endtime != 0 and self.timer is not None and self.timer.is_running == False:
|
if self.endtime != 0 and self.timer is not None and self.timer.is_running == False:
|
||||||
self.timer.start()
|
self.timer.start()
|
||||||
self.timer.is_running = True
|
self.timer.is_running = True
|
||||||
|
estimated_completion_time = datetime.fromtimestamp(time.time()+ self.fermentationtime)
|
||||||
|
self.cbpi.notify(self.name, 'Timer restarted. Estimated completion: {}'.format(estimated_completion_time.strftime("%d.%m, %H:%M")), NotificationType.INFO)
|
||||||
|
|
||||||
|
|
||||||
self.summary = "Waiting for Target Temp"
|
self.summary = "Waiting for Target Temp"
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
@ -229,17 +240,19 @@ class FermenterStep(CBPiFermentationStep):
|
||||||
await self.push_update()
|
await self.push_update()
|
||||||
|
|
||||||
async def reset(self):
|
async def reset(self):
|
||||||
await self.timer.stop()
|
|
||||||
timeD=int(self.props.get("TimerD", 0))
|
timeD=int(self.props.get("TimerD", 0))
|
||||||
timeH=int(self.props.get("TimerH", 0))
|
timeH=int(self.props.get("TimerH", 0))
|
||||||
timeM=int(self.props.get("TimerM", 0))
|
timeM=int(self.props.get("TimerM", 0))
|
||||||
self.fermentationtime=(timeM+(60*timeH)+(1440*timeD)) *60
|
self.fermentationtime=(timeM+(60*timeH)+(1440*timeD)) *60
|
||||||
|
|
||||||
self.timer = Timer(self.fermentationtime ,on_update=self.on_timer_update, on_done=self.on_timer_done)
|
self.timer = Timer(self.fermentationtime ,on_update=self.on_timer_update, on_done=self.on_timer_done)
|
||||||
self.endtime = 0
|
self.endtime = 0
|
||||||
await self.update_endtime()
|
self.timer.is_running == False
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
|
while self.get_sensor_value(self.props.get("Sensor", None)).get("value") > 900:
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
self.starttemp= self.get_sensor_value(self.props.get("Sensor", None)).get("value")
|
||||||
|
|
||||||
if self.fermenter.target_temp >= self.starttemp:
|
if self.fermenter.target_temp >= self.starttemp:
|
||||||
logging.info("warmup")
|
logging.info("warmup")
|
||||||
while self.running == True:
|
while self.running == True:
|
||||||
|
@ -278,43 +291,6 @@ class FermenterStep(CBPiFermentationStep):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("Failed to switch on FermenterLogic {} {}".format(self.fermenter.id, e))
|
logging.error("Failed to switch on FermenterLogic {} {}".format(self.fermenter.id, e))
|
||||||
|
|
||||||
@parameters([Property.Number(label="TimerD", description="Timer Days", configurable=True),
|
|
||||||
Property.Number(label="TimerH", description="Timer Hours", configurable=True),
|
|
||||||
Property.Number(label="TimerM", description="Timer Minutes", configurable=True)
|
|
||||||
])
|
|
||||||
class FermenterWaitStep(CBPiFermentationStep):
|
|
||||||
|
|
||||||
async def on_timer_done(self, timer):
|
|
||||||
self.summary = ""
|
|
||||||
await self.next(self.fermenter.id)
|
|
||||||
return StepResult.DONE
|
|
||||||
|
|
||||||
async def on_timer_update(self, timer, seconds):
|
|
||||||
self.summary = Timer.format_time(seconds)
|
|
||||||
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.timer is None:
|
|
||||||
self.timer = Timer(self.fermentationtime, on_update=self.on_timer_update, on_done=self.on_timer_done)
|
|
||||||
self.timer.start()
|
|
||||||
|
|
||||||
async def on_stop(self):
|
|
||||||
await self.timer.stop()
|
|
||||||
self.summary = ""
|
|
||||||
await self.push_update()
|
|
||||||
|
|
||||||
async def reset(self):
|
|
||||||
self.timer = Timer(self.fermentationtime, on_update=self.on_timer_update, on_done=self.on_timer_done)
|
|
||||||
|
|
||||||
async def run(self):
|
|
||||||
while self.running == True:
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
return StepResult.DONE
|
|
||||||
|
|
||||||
def setup(cbpi):
|
def setup(cbpi):
|
||||||
'''
|
'''
|
||||||
|
@ -328,4 +304,3 @@ def setup(cbpi):
|
||||||
cbpi.plugin.register("FermenterNotificationStep", FermenterNotificationStep)
|
cbpi.plugin.register("FermenterNotificationStep", FermenterNotificationStep)
|
||||||
cbpi.plugin.register("FermenterTargetTempStep", FermenterTargetTempStep)
|
cbpi.plugin.register("FermenterTargetTempStep", FermenterTargetTempStep)
|
||||||
cbpi.plugin.register("FermenterStep", FermenterStep)
|
cbpi.plugin.register("FermenterStep", FermenterStep)
|
||||||
#cbpi.plugin.register("FermenterWaitStep", FermenterWaitStep)
|
|
|
@ -33,7 +33,7 @@ class FermenterAutostart(CBPiExtension):
|
||||||
try:
|
try:
|
||||||
if (self.fermenter.instance is None or self.fermenter.instance.state == False):
|
if (self.fermenter.instance is None or self.fermenter.instance.state == False):
|
||||||
await self.cbpi.fermenter.start(self.fermenter.id)
|
await self.cbpi.fermenter.start(self.fermenter.id)
|
||||||
logging.info("Successfully switched on Fermenterlogic for Fermenter {}".format(self.fermenter.id))
|
logging.info("Successfully switched on Ferenterlogic for Fermenter {}".format(self.fermenter.id))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("Failed to switch on FermenterLogic {} {}".format(self.fermenter.id, e))
|
logging.error("Failed to switch on FermenterLogic {} {}".format(self.fermenter.id, e))
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -10,7 +10,7 @@ logger = logging.getLogger(__name__)
|
||||||
try:
|
try:
|
||||||
import RPi.GPIO as GPIO
|
import RPi.GPIO as GPIO
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warning("Failed to load RPi.GPIO. Using Mock")
|
logger.warning("Failed to load RPi.GPIO. Using Mock instead")
|
||||||
MockRPi = MagicMock()
|
MockRPi = MagicMock()
|
||||||
modules = {
|
modules = {
|
||||||
"RPi": MockRPi,
|
"RPi": MockRPi,
|
||||||
|
|
|
@ -22,6 +22,8 @@ class MQTTActor(CBPiActor):
|
||||||
async def on_start(self):
|
async def on_start(self):
|
||||||
self.topic = self.props.get("Topic", None)
|
self.topic = self.props.get("Topic", None)
|
||||||
self.power = 100
|
self.power = 100
|
||||||
|
await self.off()
|
||||||
|
self.state = False
|
||||||
|
|
||||||
async def on(self, power=None):
|
async def on(self, power=None):
|
||||||
if power is not None:
|
if power is not None:
|
||||||
|
|
|
@ -18,7 +18,7 @@ class MQTTSensor(CBPiSensor):
|
||||||
if self.payload_text != None:
|
if self.payload_text != None:
|
||||||
self.payload_text = self.payload_text.split('.')
|
self.payload_text = self.payload_text.split('.')
|
||||||
self.mqtt_task = self.cbpi.satellite.subcribe(self.Topic, self.on_message)
|
self.mqtt_task = self.cbpi.satellite.subcribe(self.Topic, self.on_message)
|
||||||
self.value: int = 0
|
self.value: float = 999
|
||||||
|
|
||||||
async def on_message(self, message):
|
async def on_message(self, message):
|
||||||
val = json.loads(message)
|
val = json.loads(message)
|
||||||
|
|
|
@ -313,8 +313,8 @@ class FermentationHttpEndpoints():
|
||||||
|
|
||||||
data = await request.json()
|
data = await request.json()
|
||||||
fermenterid= request.match_info['id']
|
fermenterid= request.match_info['id']
|
||||||
newstep = {"name": data.get("name"), "props": data.get("props", {}), "type": data.get("type")}
|
newstep = {"name": data.get("name"), "props": data.get("props", {}), "endtime": 0, "type": data.get("type")}
|
||||||
response_data = await self.controller.create_step(fermenterid,newstep)
|
response_data = await self.controller.add_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,7 +352,7 @@ 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']
|
||||||
updatedstep = {"id": stepid, "name": data.get("name"), "props": data.get("props", {}), "type": data.get("type")}
|
updatedstep = {"id": stepid, "name": data.get("name"), "endtime": 0, "props": data.get("props", {}), "type": data.get("type")}
|
||||||
#step = FermenterStep(stepid, data.get("name"), None, Props(data.get("props", {})), data.get("type"))
|
#step = FermenterStep(stepid, data.get("name"), None, Props(data.get("props", {})), data.get("type"))
|
||||||
await self.controller.update_step(fermenterid,updatedstep)
|
await self.controller.update_step(fermenterid,updatedstep)
|
||||||
return web.Response(status=200)
|
return web.Response(status=200)
|
||||||
|
|
|
@ -117,7 +117,7 @@ class FermenterRecipeHttpEndpoints():
|
||||||
await self.controller.remove(name)
|
await self.controller.remove(name)
|
||||||
return web.Response(status=204)
|
return web.Response(status=204)
|
||||||
|
|
||||||
@request_mapping(path="/{name}/{fermenterid}/brew", method="POST", auth_required=False)
|
@request_mapping(path="/{recipeid}/{fermenterid}/{name}/brew", method="POST", auth_required=False)
|
||||||
async def http_brew(self, request):
|
async def http_brew(self, request):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -137,9 +137,10 @@ class FermenterRecipeHttpEndpoints():
|
||||||
"200":
|
"200":
|
||||||
description: successful operation
|
description: successful operation
|
||||||
"""
|
"""
|
||||||
|
recipeid = request.match_info['recipeid']
|
||||||
name = request.match_info['name']
|
name = request.match_info['name']
|
||||||
fermenterid = request.match_info['fermenterid']
|
fermenterid = request.match_info['fermenterid']
|
||||||
await self.controller.brew(name,fermenterid)
|
await self.controller.brew(recipeid,fermenterid,name)
|
||||||
return web.Response(status=204)
|
return web.Response(status=204)
|
||||||
|
|
||||||
@request_mapping(path="/{id}/clone", method="POST", auth_required=False)
|
@request_mapping(path="/{id}/clone", method="POST", auth_required=False)
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
aiohttp==3.7.4
|
aiohttp==3.8.1
|
||||||
aiohttp-auth==0.1.1
|
aiohttp-auth==0.1.1
|
||||||
aiohttp-route-decorator==0.1.4
|
aiohttp-route-decorator==0.1.4
|
||||||
aiohttp-security==0.4.0
|
aiohttp-security==0.4.0
|
||||||
aiohttp-session==2.9.0
|
aiohttp-session==2.11.0
|
||||||
aiohttp-swagger==1.0.15
|
aiohttp-swagger==1.0.16
|
||||||
aiojobs==0.3.0
|
aiojobs==1.0.0
|
||||||
aiosqlite==0.16.0
|
aiosqlite==0.17.0
|
||||||
cryptography==3.3.2
|
cryptography==36.0.1
|
||||||
requests==2.25.1
|
requests==2.27.1
|
||||||
voluptuous==0.12.1
|
voluptuous==0.12.2
|
||||||
pyfiglet==0.8.post1
|
pyfiglet==0.8.post1
|
||||||
pandas==1.4.0
|
pandas==1.4.1
|
||||||
shortuuid==1.0.1
|
shortuuid==1.0.8
|
||||||
tabulate==0.8.7
|
tabulate==0.8.9
|
||||||
numpy==1.22.0
|
numpy==1.22.2
|
||||||
cbpi4ui
|
cbpi4ui
|
||||||
click==7.1.2
|
click==8.0.4
|
||||||
importlib_metadata==4.8.2
|
importlib_metadata==4.11.1
|
||||||
asyncio-mqtt
|
asyncio-mqtt
|
||||||
psutil==5.8.0
|
psutil==5.9.0
|
||||||
zipp>=0.5
|
zipp>=0.5
|
||||||
PyInquirer==1.0.3
|
PyInquirer==1.0.3
|
||||||
colorama==0.4.4
|
colorama==0.4.4
|
37
setup.py
37
setup.py
|
@ -27,34 +27,33 @@ setup(name='cbpi',
|
||||||
'': ['*.txt', '*.rst', '*.yaml'],
|
'': ['*.txt', '*.rst', '*.yaml'],
|
||||||
'cbpi': ['*','*.txt', '*.rst', '*.yaml']},
|
'cbpi': ['*','*.txt', '*.rst', '*.yaml']},
|
||||||
|
|
||||||
python_requires='>=3',
|
python_requires='>=3.9',
|
||||||
|
|
||||||
install_requires=[
|
install_requires=[
|
||||||
"aiohttp==3.7.4",
|
"aiohttp==3.8.1",
|
||||||
"aiohttp-auth==0.1.1",
|
"aiohttp-auth==0.1.1",
|
||||||
"aiohttp-route-decorator==0.1.4",
|
"aiohttp-route-decorator==0.1.4",
|
||||||
"aiohttp-security==0.4.0",
|
"aiohttp-security==0.4.0",
|
||||||
"aiohttp-session==2.9.0",
|
"aiohttp-session==2.11.0",
|
||||||
"aiohttp-swagger==1.0.15",
|
"aiohttp-swagger==1.0.16",
|
||||||
"aiojobs==0.3.0",
|
"aiojobs==1.0.0 ",
|
||||||
"aiosqlite==0.16.0",
|
"aiosqlite==0.17.0",
|
||||||
"cryptography==3.3.2",
|
"cryptography==36.0.1",
|
||||||
"requests==2.25.1",
|
"requests==2.27.1",
|
||||||
"voluptuous==0.12.1",
|
"voluptuous==0.12.2",
|
||||||
"pyfiglet==0.8.post1",
|
"pyfiglet==0.8.post1",
|
||||||
'click==7.1.2',
|
'click==8.0.4',
|
||||||
'shortuuid==1.0.1',
|
'shortuuid==1.0.8',
|
||||||
'tabulate==0.8.7',
|
'tabulate==0.8.9',
|
||||||
'asyncio-mqtt',
|
'asyncio-mqtt',
|
||||||
'psutil==5.8.0',
|
|
||||||
'colorama==0.4.4',
|
|
||||||
'PyInquirer==1.0.3',
|
'PyInquirer==1.0.3',
|
||||||
|
'colorama==0.4.4',
|
||||||
|
'psutil==5.9.0',
|
||||||
'cbpi4ui',
|
'cbpi4ui',
|
||||||
'importlib_metadata'] + (
|
'importlib_metadata',
|
||||||
['RPi.GPIO==0.7.1'] if raspberrypi else [] ) +
|
'numpy==1.22.2',
|
||||||
(['numpy==1.22.0'] if (int(platform.python_version_tuple()[1]) >= 9) and (int(platform.python_version_tuple()[0]) == 3) else ['numpy==1.20.3'] ) +
|
'pandas==1.4.1'] + (
|
||||||
(['pandas==1.4.0'] if (int(platform.python_version_tuple()[1]) >= 9) and (int(platform.python_version_tuple()[0]) == 3) else ['pandas==1.1.5'] ),
|
['RPi.GPIO==0.7.1'] if raspberrypi else [] ),
|
||||||
|
|
||||||
|
|
||||||
dependency_links=[
|
dependency_links=[
|
||||||
'https://testpypi.python.org/pypi',
|
'https://testpypi.python.org/pypi',
|
||||||
|
|
Loading…
Reference in a new issue