craftbeerpi4-pione/core/controller/step_controller.py

186 lines
5 KiB
Python
Raw Normal View History

2018-12-03 22:16:03 +01:00
import asyncio
2018-12-16 21:42:47 +01:00
import time
2019-01-02 00:48:36 +01:00
2018-12-29 00:27:19 +01:00
from cbpi_api import *
2019-01-02 00:48:36 +01:00
2018-12-08 14:21:00 +01:00
from core.controller.crud_controller import CRUDController
from core.database.model import StepModel
2018-12-03 22:16:03 +01:00
2018-12-08 14:21:00 +01:00
2019-01-02 21:20:44 +01:00
class StepController(CRUDController):
2018-12-09 22:20:33 +01:00
'''
The Step Controller. This controller is responsible to start and stop the brewing steps.
'''
2018-12-08 14:21:00 +01:00
model = StepModel
2018-11-29 21:59:08 +01:00
2018-12-03 22:16:03 +01:00
def __init__(self, cbpi):
2018-12-08 14:21:00 +01:00
super(StepController, self).__init__(cbpi)
2018-12-03 22:16:03 +01:00
self.cbpi = cbpi
2018-12-05 07:31:12 +01:00
self.current_task = None
2018-12-03 22:16:03 +01:00
self.types = {}
self.current_step = None
2019-01-02 00:48:36 +01:00
self.current_job = None
2019-01-02 21:20:44 +01:00
self.cbpi.register(self)
2018-11-29 21:59:08 +01:00
2018-12-15 00:01:37 +01:00
2018-12-03 22:16:03 +01:00
async def init(self):
2018-12-09 22:20:33 +01:00
'''
Initializer of the the Step Controller.
:return:
'''
2018-12-08 14:21:00 +01:00
await super(StepController, self).init()
2018-12-29 00:27:19 +01:00
2018-12-16 21:42:47 +01:00
step = await self.model.get_by_state('A')
# We have an active step
if step is not None:
2018-12-29 00:27:19 +01:00
2018-12-16 21:42:47 +01:00
# get the type
step_type = self.types.get(step.type)
if step_type is None:
# step type not found. cant restart step
return
if step.stepstate is not None:
cfg = step.stepstate.copy()
else:
cfg = {}
cfg.update(dict(cbpi=self.cbpi, id=step.id, managed_fields=self._get_manged_fields_as_array(step_type)))
self.current_step = step_type["class"](**cfg)
2019-01-01 15:35:35 +01:00
self.current_job = await self.cbpi.job.start_job(self.current_step.run(), step.name, "step")
2018-11-29 21:59:08 +01:00
2018-12-07 23:57:32 +01:00
@on_event("step/action")
2018-12-13 21:45:33 +01:00
async def handle_action(self, action, **kwargs):
2018-12-09 22:20:33 +01:00
'''
Event Handler for "step/action".
It invokes the provided method name on the current step
:param action: the method name which will be invoked
:param kwargs:
:return: None
'''
if self.current_step is not None:
self.current_step.__getattribute__(action)()
2018-12-09 22:20:33 +01:00
2018-12-07 23:57:32 +01:00
@on_event("step/next")
2018-12-13 21:45:33 +01:00
async def handle_next(self, **kwargs):
2018-12-09 22:20:33 +01:00
'''
Event Handler for "step/next".
It start the next step
:param kwargs:
:return: None
'''
2018-12-07 23:57:32 +01:00
if self.current_step is not None:
self.current_step.next()
pass
2018-12-03 22:16:03 +01:00
@on_event("step/reset")
2018-12-13 21:45:33 +01:00
async def handle_reset(self, **kwargs):
2018-12-09 22:20:33 +01:00
'''
Event Handler for "step/reset".
Resets the current step
:param kwargs:
:return: None
'''
2018-12-05 07:31:12 +01:00
if self.current_step is not None:
2019-01-02 00:48:36 +01:00
await self.stop()
self.is_stopping = True
2018-12-03 22:16:03 +01:00
2019-01-02 00:48:36 +01:00
await self.model.reset_all_steps()
2018-12-15 00:01:37 +01:00
@on_event("job/step/done")
async def handle_step_done(self, topic, **kwargs):
2018-12-09 22:20:33 +01:00
'''
Event Handler for "step/+/done".
Starts the next step
:param topic:
:param kwargs:
:return:
'''
2018-12-15 00:01:37 +01:00
2018-12-16 21:42:47 +01:00
if self.cbpi.shutdown:
return
2018-12-29 00:27:19 +01:00
2018-12-15 00:01:37 +01:00
self.cache[self.current_step.id].state = "D"
step_id = self.current_step.id
self.current_step = None
2019-01-02 00:48:36 +01:00
if self.is_stopping is not True:
await self.start()
2018-12-05 07:31:12 +01:00
2019-01-02 00:48:36 +01:00
self.is_stopping = False
2018-12-05 07:31:12 +01:00
2018-12-09 22:20:33 +01:00
def _get_manged_fields_as_array(self, type_cfg):
2018-12-29 00:27:19 +01:00
2018-12-05 07:31:12 +01:00
result = []
for f in type_cfg.get("properties"):
result.append(f.get("name"))
return result
2018-12-03 22:16:03 +01:00
2019-01-02 00:48:36 +01:00
def is_running(self):
if self.current_step is not None:
return True
else:
return False
@on_event("step/start")
async def start(self, future, **kwargs):
2018-12-03 22:16:03 +01:00
2018-12-09 22:20:33 +01:00
'''
Start the first step
:return:None
'''
2018-12-03 22:16:03 +01:00
if self.current_step is None:
loop = asyncio.get_event_loop()
open_step = False
2018-12-15 00:01:37 +01:00
2018-12-16 21:42:47 +01:00
inactive = await self.model.get_by_state("I")
active = await self.model.get_by_state("A")
if active is not None:
active.state = 'D'
active.end = int(time.time())
# self.stop_step()
self.current_step = None
await self.model.update(**active.__dict__)
if inactive is not None:
step_type = self.types["CustomStepCBPi"]
2018-12-15 00:01:37 +01:00
2018-12-16 21:42:47 +01:00
config = dict(cbpi=self.cbpi, id=inactive.id, name=inactive.name, managed_fields=self._get_manged_fields_as_array(step_type))
self.current_step = step_type["class"](**config)
2018-12-15 00:01:37 +01:00
2018-12-16 21:42:47 +01:00
inactive.state = 'A'
inactive.stepstate = inactive.config
inactive.start = int(time.time())
await self.model.update(**inactive.__dict__)
2019-01-01 15:35:35 +01:00
self.current_job = await self.cbpi.job.start_job(self.current_step.run(), inactive.name, "step")
2018-12-16 21:42:47 +01:00
else:
2018-12-13 21:45:33 +01:00
await self.cbpi.bus.fire("step/berwing/finished")
2018-12-09 22:20:33 +01:00
2019-01-02 00:48:36 +01:00
future.set_result(True)
@on_event("step/stop")
async def stop(self, **kwargs):
if self.current_job is not None:
self.is_stopping = True
await self.current_job.close()
await self.model.reset_all_steps()