mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-09 17:07:43 +01:00
"fermentation controller pre version. Not ready to use"
This commit is contained in:
parent
fb2793eb85
commit
70469adc49
8 changed files with 471 additions and 14 deletions
|
@ -1 +1 @@
|
||||||
__version__ = "4.0.0.33"
|
__version__ = "4.0.0.34"
|
|
@ -2,7 +2,8 @@ from cbpi.api.config import ConfigType
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from cbpi.api.step import StepState
|
from cbpi.api.step import StepState
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass, field
|
||||||
|
from typing import List
|
||||||
|
|
||||||
class Props:
|
class Props:
|
||||||
|
|
||||||
|
@ -96,11 +97,13 @@ class Kettle:
|
||||||
if self.instance is not None:
|
if self.instance is not None:
|
||||||
|
|
||||||
state = self.instance.state
|
state = self.instance.state
|
||||||
print("READ STATE", state)
|
|
||||||
else:
|
else:
|
||||||
state = False
|
state = False
|
||||||
return dict(id=self.id, name=self.name, state=state, target_temp=self.target_temp, heater=self.heater, agitator=self.agitator, sensor=self.sensor, type=self.type, props=self.props.to_dict())
|
return dict(id=self.id, name=self.name, state=state, target_temp=self.target_temp, heater=self.heater, agitator=self.agitator, sensor=self.sensor, type=self.type, props=self.props.to_dict())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Step:
|
class Step:
|
||||||
id: str = None
|
id: str = None
|
||||||
|
@ -115,7 +118,37 @@ class Step:
|
||||||
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, props=self.props.to_dict())
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Fermenter:
|
||||||
|
id: str = None
|
||||||
|
name: str = None
|
||||||
|
brewname: str = None
|
||||||
|
props: Props = Props()
|
||||||
|
target_temp: int = 0
|
||||||
|
steps: List[Step]= field(default_factory=list)
|
||||||
|
def __str__(self):
|
||||||
|
return "id={} name={} brewname={} props={} temp={} steps={}".format(self.id, self.name, self.brewname, self.props, self.target_temp, self.steps)
|
||||||
|
def to_dict(self):
|
||||||
|
steps = list(map(lambda item: item.to_dict(), self.steps))
|
||||||
|
return dict(id=self.id, name=self.name, target_temp=self.target_temp, steps=steps, props=self.props.to_dict() if self.props is not None else None)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FermenterStep:
|
||||||
|
id: str = None
|
||||||
|
name: str = None
|
||||||
|
fermenter: Fermenter = None
|
||||||
|
props: Props = Props()
|
||||||
|
type: str = None
|
||||||
|
status: StepState = StepState.INITIAL
|
||||||
|
instance: str = None
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
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, props=self.props.to_dict())
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import logging
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
|
||||||
from cbpi.api.base import CBPiBase
|
from cbpi.api.base import CBPiBase
|
||||||
|
@ -7,6 +8,11 @@ __all__ = ["StepResult", "StepState", "StepMove", "CBPiStep"]
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
logging.basicConfig(format='%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
|
||||||
|
datefmt='%Y-%m-%d:%H:%M:%S',
|
||||||
|
level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class StepResult(Enum):
|
class StepResult(Enum):
|
||||||
STOP = 1
|
STOP = 1
|
||||||
|
@ -39,12 +45,20 @@ class CBPiStep(CBPiBase):
|
||||||
self.props = props
|
self.props = props
|
||||||
self.cancel_reason: StepResult = None
|
self.cancel_reason: StepResult = None
|
||||||
self.summary = ""
|
self.summary = ""
|
||||||
|
self.task = None
|
||||||
self.running: bool = False
|
self.running: bool = False
|
||||||
|
self.logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def _done(self, task):
|
def _done(self, task):
|
||||||
self._done_callback(self, task.result())
|
if self._done_callback is not None:
|
||||||
|
try:
|
||||||
|
result = task.result()
|
||||||
|
self._done_callback(self, result)
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(e)
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
|
self.logger.info("Start {}".format(self.name))
|
||||||
self.running = True
|
self.running = True
|
||||||
self.task = asyncio.create_task(self._run())
|
self.task = asyncio.create_task(self._run())
|
||||||
self.task.add_done_callback(self._done)
|
self.task.add_done_callback(self._done)
|
||||||
|
@ -58,11 +72,12 @@ class CBPiStep(CBPiBase):
|
||||||
async def stop(self):
|
async def stop(self):
|
||||||
try:
|
try:
|
||||||
self.running = False
|
self.running = False
|
||||||
|
if self.task is not None and self.task.done() is False:
|
||||||
self.cancel_reason = StepResult.STOP
|
self.cancel_reason = StepResult.STOP
|
||||||
self.task.cancel()
|
self.task.cancel()
|
||||||
await self.task
|
await self.task
|
||||||
except:
|
except Exception as e:
|
||||||
pass
|
self.logger.error(e)
|
||||||
|
|
||||||
async def reset(self):
|
async def reset(self):
|
||||||
pass
|
pass
|
||||||
|
@ -100,3 +115,9 @@ 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
|
||||||
|
super().__init__(cbpi, step.id, step.name, props, on_done)
|
287
cbpi/controller/fermentation_controller.py
Normal file
287
cbpi/controller/fermentation_controller.py
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import cbpi
|
||||||
|
import copy
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import os.path
|
||||||
|
from os import listdir
|
||||||
|
from os.path import isfile, join
|
||||||
|
import shortuuid
|
||||||
|
from cbpi.api.dataclasses import Fermenter, FermenterStep, Props, Step
|
||||||
|
from tabulate import tabulate
|
||||||
|
import sys, os
|
||||||
|
from ..api.step import CBPiStep, StepMove, StepResult, StepState
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
logging.basicConfig(format='%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
|
||||||
|
datefmt='%Y-%m-%d:%H:%M:%S',
|
||||||
|
level=logging.INFO)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
async def run(self):
|
||||||
|
while True:
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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 FermenationController:
|
||||||
|
|
||||||
|
def __init__(self, cbpi):
|
||||||
|
self.cbpi = cbpi
|
||||||
|
self.logger = logging.getLogger(__name__)
|
||||||
|
self.path = os.path.join(".", 'config', "fermenter_data.json")
|
||||||
|
self._loop = asyncio.get_event_loop()
|
||||||
|
self.data = {}
|
||||||
|
self.types = {}
|
||||||
|
self.cbpi.app.on_cleanup.append(self.shutdown)
|
||||||
|
|
||||||
|
async def shutdown(self, app=None):
|
||||||
|
self.save()
|
||||||
|
for fermenter in self.data:
|
||||||
|
self.logger.info("Shutdown {}".format(fermenter.name))
|
||||||
|
for step in fermenter.steps:
|
||||||
|
try:
|
||||||
|
self.logger.info("Stop {}".format(step.name))
|
||||||
|
await step.instance.stop()
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(e)
|
||||||
|
|
||||||
|
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:
|
||||||
|
d = json.load(json_file)
|
||||||
|
self.data = list(map(lambda item: self._create(item), d))
|
||||||
|
|
||||||
|
def _create_step(self, fermenter, item):
|
||||||
|
id = item.get("id")
|
||||||
|
name = item.get("name")
|
||||||
|
status = StepState(item.get("status", "I"))
|
||||||
|
type = item.get("type")
|
||||||
|
|
||||||
|
type_cfg = self.types.get(type)
|
||||||
|
if type_cfg is not None:
|
||||||
|
inst = type_cfg.get("class")()
|
||||||
|
print(inst)
|
||||||
|
|
||||||
|
step = FermenterStep(id=id, name=name, type=type, status=status, instance=None, fermenter=fermenter)
|
||||||
|
step.instance = FermentStep( self.cbpi, step, self._done)
|
||||||
|
return step
|
||||||
|
|
||||||
|
def _done(self, step_instance, result):
|
||||||
|
|
||||||
|
step_instance.step.status = StepState.DONE
|
||||||
|
self.save()
|
||||||
|
if result == StepResult.NEXT:
|
||||||
|
asyncio.create_task(self.start(step_instance.step.fermenter.id))
|
||||||
|
|
||||||
|
def _create(self, data):
|
||||||
|
id = data.get("id")
|
||||||
|
name = data.get("name")
|
||||||
|
brewname = data.get("brewname")
|
||||||
|
props = Props(data.get("props", {}))
|
||||||
|
fermenter = Fermenter(id, name, brewname, props, 0)
|
||||||
|
fermenter.steps = list(map(lambda item: self._create_step(fermenter, item), data.get("steps", [])))
|
||||||
|
return fermenter
|
||||||
|
|
||||||
|
def _find_by_id(self, id):
|
||||||
|
return next((item for item in self.data if item.id == id), None)
|
||||||
|
|
||||||
|
async def init(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def get_all(self):
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
async def get(self, id: str ):
|
||||||
|
return self._find_by_id(id)
|
||||||
|
|
||||||
|
async def create(self, data: Fermenter ):
|
||||||
|
data.id = shortuuid.uuid()
|
||||||
|
self.data.append(data)
|
||||||
|
self.save()
|
||||||
|
return data
|
||||||
|
|
||||||
|
async def update(self, item: Fermenter ):
|
||||||
|
|
||||||
|
def _update(old_item: Fermenter, item: Fermenter):
|
||||||
|
old_item.name = item.name
|
||||||
|
old_item.brewname = item.brewname
|
||||||
|
old_item.props = item.props
|
||||||
|
old_item.target_temp = item.target_temp
|
||||||
|
return old_item
|
||||||
|
|
||||||
|
self.data = list(map(lambda old: _update(old, item) if old.id == item.id else old, self.data))
|
||||||
|
self.save()
|
||||||
|
return item
|
||||||
|
|
||||||
|
async def delete(self, id: str ):
|
||||||
|
item = self._find_by_id(id)
|
||||||
|
self.data = list(filter(lambda item: item.id != id, self.data))
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
with open(self.path, "w") as file:
|
||||||
|
json.dump(list(map(lambda item: item.to_dict(), self.data)), file, indent=4, sort_keys=True)
|
||||||
|
|
||||||
|
async def create_step(self, id, step: Step):
|
||||||
|
try:
|
||||||
|
step.id = shortuuid.uuid()
|
||||||
|
item = self._find_by_id(id)
|
||||||
|
|
||||||
|
step.instance = FermentStep( self.cbpi, step.id, step.name, None, self._done)
|
||||||
|
|
||||||
|
item.steps.append(step)
|
||||||
|
self.save()
|
||||||
|
return step
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(e)
|
||||||
|
|
||||||
|
async def update_step(self, id, step):
|
||||||
|
item = self._find_by_id(id)
|
||||||
|
item = list(map(lambda old: item if old.id == step.id else old, item.steps))
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
async def delete_step(self, id, stepid):
|
||||||
|
item = self._find_by_id(id)
|
||||||
|
item.steps = list(filter(lambda item: item.id != stepid, item.steps))
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def _find_by_status(self, data, status):
|
||||||
|
return next((item for item in data if item.status == status), None)
|
||||||
|
|
||||||
|
def _find_step_by_id(self, data, id):
|
||||||
|
return next((item for item in data if item.id == id), None)
|
||||||
|
|
||||||
|
async def start(self, id):
|
||||||
|
self.logger.info("Start")
|
||||||
|
try:
|
||||||
|
item = self._find_by_id(id)
|
||||||
|
step = self._find_by_status(item.steps, StepState.INITIAL)
|
||||||
|
|
||||||
|
if step is None:
|
||||||
|
self.logger.info("No futher step to start")
|
||||||
|
|
||||||
|
await step.instance.start()
|
||||||
|
step.status = StepState.ACTIVE
|
||||||
|
self.save()
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(e)
|
||||||
|
|
||||||
|
async def stop(self, id):
|
||||||
|
try:
|
||||||
|
item = self._find_by_id(id)
|
||||||
|
step = self._find_by_status(item.steps, StepState.ACTIVE)
|
||||||
|
await step.instance.stop()
|
||||||
|
step.status = StepState.STOP
|
||||||
|
self.save()
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(e)
|
||||||
|
|
||||||
|
|
||||||
|
async def next(self, id):
|
||||||
|
self.logger.info("Next {} ".format(id))
|
||||||
|
try:
|
||||||
|
item = self._find_by_id(id)
|
||||||
|
step = self._find_by_status(item.steps, StepState.ACTIVE)
|
||||||
|
await step.instance.next()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(e)
|
||||||
|
|
||||||
|
|
||||||
|
async def reset(self, id):
|
||||||
|
self.logger.info("Reset")
|
||||||
|
try:
|
||||||
|
item = self._find_by_id(id)
|
||||||
|
for step in item.steps:
|
||||||
|
self.logger.info("Stopping Step {} {}".format(step.name, step.id))
|
||||||
|
try:
|
||||||
|
await step.instance.stop()
|
||||||
|
step.status = StepState.INITIAL
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(e)
|
||||||
|
self.save()
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(e)
|
||||||
|
|
||||||
|
async def move_step(self, fermenter_id, step_id, direction):
|
||||||
|
try:
|
||||||
|
fermenter = self._find_by_id(fermenter_id)
|
||||||
|
index = next((i for i, item in enumerate(fermenter.steps) if item.id == step_id), None)
|
||||||
|
if index == None:
|
||||||
|
return
|
||||||
|
if index == 0 and direction == -1:
|
||||||
|
return
|
||||||
|
if index == len(fermenter.steps)-1 and direction == 1:
|
||||||
|
return
|
||||||
|
|
||||||
|
fermenter.steps[index], fermenter.steps[index+direction] = fermenter.steps[index+direction], fermenter.steps[index]
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(e)
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ class StepController:
|
||||||
self.basic_data = {}
|
self.basic_data = {}
|
||||||
self.step = None
|
self.step = None
|
||||||
self.types = {}
|
self.types = {}
|
||||||
|
|
||||||
self.cbpi.app.on_cleanup.append(self.shutdown)
|
self.cbpi.app.on_cleanup.append(self.shutdown)
|
||||||
|
|
||||||
async def init(self):
|
async def init(self):
|
||||||
|
@ -225,7 +224,7 @@ class StepController:
|
||||||
for p in self.profile:
|
for p in self.profile:
|
||||||
instance = p.instance
|
instance = p.instance
|
||||||
# Stopping all running task
|
# Stopping all running task
|
||||||
if instance.task != None and instance.task.done() is False:
|
if hasattr(instance, "task") and instance.task != None and instance.task.done() is False:
|
||||||
logging.info("Stop Step")
|
logging.info("Stop Step")
|
||||||
await instance.stop()
|
await instance.stop()
|
||||||
await instance.task
|
await instance.task
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
from unittest.mock import MagicMock, Mock
|
||||||
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
|
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
|
||||||
from cbpi.craftbeerpi import CraftBeerPi
|
from cbpi.craftbeerpi import CraftBeerPi
|
||||||
|
|
||||||
|
|
116
tests/test_fermenter.py
Normal file
116
tests/test_fermenter.py
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
import asyncio
|
||||||
|
from cbpi.api.dataclasses import Fermenter, FermenterStep, Props, Step
|
||||||
|
import logging
|
||||||
|
from unittest import mock
|
||||||
|
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
|
||||||
|
from cbpi.craftbeerpi import CraftBeerPi
|
||||||
|
from cbpi.controller.fermentation_controller import FermenationController
|
||||||
|
import unittest
|
||||||
|
import json
|
||||||
|
from aiohttp import web
|
||||||
|
from unittest.mock import MagicMock, Mock
|
||||||
|
logging.basicConfig(level=logging.INFO,
|
||||||
|
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s')
|
||||||
|
|
||||||
|
|
||||||
|
class FermenterTest(AioHTTPTestCase):
|
||||||
|
|
||||||
|
async def get_application(self):
|
||||||
|
app = web.Application()
|
||||||
|
return app
|
||||||
|
|
||||||
|
def create_file(self):
|
||||||
|
|
||||||
|
data = [
|
||||||
|
{
|
||||||
|
"id": "f1",
|
||||||
|
"name": "Fermenter1",
|
||||||
|
"props": {},
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"id": "f1s1",
|
||||||
|
"name": "Step1",
|
||||||
|
"props": {},
|
||||||
|
"state_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": "T2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f1s2",
|
||||||
|
"name": "Step2",
|
||||||
|
"props": {},
|
||||||
|
"state_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": "T1"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"target_temp": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f2",
|
||||||
|
"name": "Fermenter2",
|
||||||
|
"props": {},
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"id": "f2s1",
|
||||||
|
"name": "Step1",
|
||||||
|
"props": {},
|
||||||
|
"state_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": "T1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f2s2",
|
||||||
|
"name": "Step2",
|
||||||
|
"props": {},
|
||||||
|
"state_text": "",
|
||||||
|
"status": "I",
|
||||||
|
"type": "T2"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"target_temp": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
with open("./config/fermenter_data.json", "w") as file:
|
||||||
|
json.dump(data, file, indent=4, sort_keys=True)
|
||||||
|
|
||||||
|
|
||||||
|
@unittest_run_loop
|
||||||
|
async def test_actor_mock(self):
|
||||||
|
self.create_file()
|
||||||
|
mock = Mock()
|
||||||
|
f = FermenationController(mock)
|
||||||
|
|
||||||
|
f.types = {
|
||||||
|
"T1": {"name": "T2", "class": FermenterStep, "properties": [], "actions": []},
|
||||||
|
"T2": {"name": "T2", "class": FermenterStep, "properties": [], "actions": []}
|
||||||
|
}
|
||||||
|
await f.load()
|
||||||
|
#ferm = Fermenter(name="Maneul")
|
||||||
|
# item = await f.create(ferm)
|
||||||
|
# await f.create_step(item.id, Step(name="Manuel"))
|
||||||
|
# await f.delete(item.id)
|
||||||
|
|
||||||
|
item = await f.get("f1")
|
||||||
|
|
||||||
|
await f.start("f1")
|
||||||
|
await f.start("f2")
|
||||||
|
await asyncio.sleep(3)
|
||||||
|
# await f.create_step(item.id, Step(name="MANUEL", props=Props()))
|
||||||
|
|
||||||
|
#await f.start(item.id)
|
||||||
|
#await asyncio.sleep(1)
|
||||||
|
#await f.next(item.id)
|
||||||
|
#await asyncio.sleep(1)
|
||||||
|
#await f.next(item.id)
|
||||||
|
#await asyncio.sleep(1)
|
||||||
|
#await f.next(item.id)
|
||||||
|
#await asyncio.sleep(1)
|
||||||
|
#await f.move_step("f1", "f1s1", 1)
|
||||||
|
# await f.reset(item.id)
|
||||||
|
await f.shutdown()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
|
@ -225,7 +225,7 @@ class StepController:
|
||||||
for p in self.profile:
|
for p in self.profile:
|
||||||
instance = p.instance
|
instance = p.instance
|
||||||
# Stopping all running task
|
# Stopping all running task
|
||||||
if instance.task != None and instance.task.done() is False:
|
if hasattr(instance, "task") and instance.task != None and instance.task.done() is False:
|
||||||
logging.info("Stop Step")
|
logging.info("Stop Step")
|
||||||
await instance.stop()
|
await instance.stop()
|
||||||
await instance.task
|
await instance.task
|
||||||
|
|
Loading…
Reference in a new issue