Files
controller-wisetopdataserver/python/biopro/project/project.py
T

263 lines
9.0 KiB
Python
Raw Normal View History

2022-02-07 20:27:30 +08:00
import sys
import json
import threading
2022-04-17 23:05:21 +08:00
2022-04-16 10:50:37 +08:00
from time import time, sleep
2022-02-12 00:21:27 +08:00
from datetime import datetime
2022-02-17 20:35:36 +08:00
from collections import deque
2022-04-17 23:05:21 +08:00
from copy import copy
from uuid import uuid4
from .task import Task
from .task_manager import TaskManager
from .instruction import Instruction
2022-02-25 20:54:58 +08:00
from biopro.device.manager import DeviceManager
from biopro.text import *
2022-04-16 10:50:37 +08:00
2022-04-17 23:05:21 +08:00
key_list = {
'deviceList': 'device',
}
2022-02-07 20:27:30 +08:00
class Project(threading.Thread):
2022-02-25 20:54:58 +08:00
def __init__(self, project, device_manager: DeviceManager, mqttThread = None, name="project"):
2022-02-07 20:27:30 +08:00
super(Project, self).__init__(name = name)
self._project = project
2022-02-25 20:54:58 +08:00
self._device_manager = device_manager
2022-02-07 20:27:30 +08:00
self._mqtt_thread = mqttThread
self._time_interval = 0.1
2022-02-12 00:21:27 +08:00
self._start_time = None
2022-04-17 23:05:21 +08:00
self._end_time = None
self._id = None
self._uuid = str(uuid4())
2022-04-17 23:05:21 +08:00
self._name = None
self._desc = None
self._device = None
self._complete_device = []
self._status = 0
2022-02-08 20:12:44 +08:00
2022-04-16 10:50:37 +08:00
self._instruction_set = Instruction()
2022-04-17 23:05:21 +08:00
self._stop_flag = False
self._task_manager = None
2022-04-17 23:05:21 +08:00
self.setup_project(project)
self.setup_device(self._device)
def setup_project(self, project):
for (key, value) in project.items():
if key in key_list.keys():
key = key_list[key]
2022-04-27 13:24:31 +08:00
if key == 'task':
self._task_manager = TaskManager(project['task'])
elif key == 'uuid':
pass
2022-04-17 23:05:21 +08:00
else:
setattr(self, key, value)
def setup_device(self, device_list):
for device in device_list:
complete_device = self._device_manager.get_device(device['connectDevice']['device_address'])
self._complete_device.append(complete_device)
2022-02-14 19:19:54 +08:00
2022-02-07 20:27:30 +08:00
@property
2022-04-17 23:05:21 +08:00
def id(self) -> int:
return self._id
@id.setter
def id(self, new_id):
self._id = new_id
2022-02-08 20:12:44 +08:00
@property
2022-04-17 23:05:21 +08:00
def uuid(self) -> str:
return self._uuid
@uuid.setter
def uuid(self, new_uuid):
self._uuid = new_uuid
2022-02-08 20:12:44 +08:00
@property
2022-04-17 23:05:21 +08:00
def name(self) -> str:
return self._name
@name.setter
def name(self, new_name):
self._name = new_name
2022-02-07 20:27:30 +08:00
@property
2022-04-17 23:05:21 +08:00
def desc(self) -> str:
return self._desc
@desc.setter
def desc(self, new_desc):
self._desc = new_desc
@property
def status(self) -> str:
return self._status
@status.setter
def status(self, new_status):
self._status = new_status
2022-02-07 20:27:30 +08:00
@property
2022-04-17 23:05:21 +08:00
def device(self) -> list:
return self._device
@device.setter
def device(self, new_device):
self._device = new_device
@property
def task_list(self):
return self._task_manager.export_task_list
2022-03-02 18:13:02 +08:00
@property
def mqtt_thread(self):
return self._mqtt_thread
@property
def running_task(self):
return self._task_manager.running_task
2022-02-17 20:35:36 +08:00
def run(self):
self._status = 1
2022-04-16 10:50:37 +08:00
self._start_time = time()
self.mqtt_thread.broadcast_command('project:' + self._name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
2022-04-17 23:05:21 +08:00
while not self._stop_flag :
2022-04-16 10:50:37 +08:00
# check running task first
2022-04-08 11:17:07 +08:00
delay_time = 0
2022-04-16 10:50:37 +08:00
check_list = copy(self._task_manager.check_list)
2022-04-16 10:50:37 +08:00
for task in check_list:
if task != None:
now = time()
# print('round task', task.name)
# print('running task', self._task_manager.running_task.name, self._task_manager.running_task.status)
# if self._task_manager.prev_task != None:
# print('previous_task', self._task_manager.prev_task.name, self._task_manager.prev_task.status)
match_condition_list = task.check_condition(
project_start_time = self._start_time,
delay_time = delay_time,
running_task= self._task_manager.running_task,
2022-08-16 11:34:47 +08:00
previous_task = self._task_manager.prev_task,
self_task = task
)
# print('match_condition_list', match_condition_list)
for condition in match_condition_list:
# print('\ncondition.type: ', condition.type)
match_action_list = task.get_match_action(condition.id)
# print('match_action_list', match_action_list)
for action in match_action_list:
# print('action type', action.type)
# print('match_action_list len: ', len(match_action_list))
if action.type == 'start' and task.status != 1:
self._task_manager.set_running_task(task)
2022-08-16 11:34:47 +08:00
# Trace
self.mqtt_thread.broadcast_command('project:task ' + task.name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
2022-08-17 11:50:22 +08:00
elif action.type == 'cycle' and task.status != 1:
2022-08-18 17:39:59 +08:00
# TODO: directly goto next without swich cycle as running task
""" if task._cycle_count < task._cycle - 1:
task._cycle_count += 1
cycle_target = self._task_manager.task_list[task._cycle_next - 1] # TODO: not sure deep or shallow
cycle_target.reset()
task = cycle_target """
2022-08-17 11:50:22 +08:00
self._task_manager.set_running_task(task)
elif action.type == 'stop' and len(self._task_manager.running_task.parameter_set) == 0:
self.mqtt_thread.broadcast_command('project:task ' + str(self._task_manager.running_task.name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
self._task_manager.running_task.stop()
elif action.type == 'idle':
self._task_manager.running_task.stop()
device = self._complete_device[action.target]
task_info = task.get_task_info(action)
instruction_set = getattr(self._instruction_set, action.type, None)
# print('instruction_set', instruction_set, '\n', action.type)
# if instruction_set != None and task.cycle == -1:
if instruction_set != None and len(task.parameter_set) > 0:
for instruction in instruction_set:
args = list(map(lambda arg: task_info[arg], instruction['arguments']))
threading.Thread(target=getattr(device, instruction['method'])(*args))
delay_time += (time() - now)
2022-04-16 10:50:37 +08:00
2022-04-17 23:05:21 +08:00
# check task not running then stop
if self.check_running_task_not_run() == True:
2022-08-17 11:50:22 +08:00
if self._task_manager.running_task.cycle == -1:
self.mqtt_thread.broadcast_command('project:task ' + str(self._task_manager.running_task.name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
2022-04-16 10:50:37 +08:00
self._task_manager.running_task.stop()
# self._task_manager.set_running_task(task)
2022-04-17 23:05:21 +08:00
# check project done then close project
2022-04-16 10:50:37 +08:00
if self.check_project_done() == True:
print('project stop at', datetime.now())
2022-04-16 10:50:37 +08:00
self.close()
2022-04-17 23:05:21 +08:00
if self._time_interval - delay_time > 0:
sleep(self._time_interval - delay_time)
def pause(self):
# TODO
pass
def stop(self):
self._task_manager.running_task.stop()
self.mqtt_thread.broadcast_command('project:task ' + str(self._task_manager.running_task.name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
self._status = 2
self._end_time = time()
self._stop_flag = True
self.mqtt_thread.broadcast_command('project:project ' + str(self._name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
2022-04-17 23:05:21 +08:00
def close(self):
self._status = 2
2022-04-17 23:05:21 +08:00
self._end_time = time()
self._stop_flag = True
self.mqtt_thread.broadcast_command('project:project ' + str(self._name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
2022-04-17 23:05:21 +08:00
2022-04-16 10:50:37 +08:00
def check_project_done(self):
for task in self._task_manager.task_list:
2022-04-17 23:05:21 +08:00
# if task never start or still task is running then reject
2022-04-16 10:50:37 +08:00
if task.status == 1 or task.status == -1:
return False
return True
def set_content(self, content):
self.running_task.button_trigger = True
2022-04-17 23:05:21 +08:00
def check_running_task_not_run(self):
# if no running task
if self._task_manager.running_task == None:
return False
for key in self._task_manager.running_task.action:
# print('action key', key, self._task_manager.running_task, self._task_manager.running_task.action[key])
if len(self._task_manager.running_task.parameter_set) == 0 and self._task_manager.running_task.action[key]['type'] == 'stop':
return False
if len(self._task_manager.running_task.parameter_set) == 0 and self._task_manager.running_task.action[key]['type'] == 'idle':
return False
for device in self._task_manager.running_task.device:
2022-04-17 23:05:21 +08:00
if self._complete_device[device].status == 1:
2022-04-16 10:50:37 +08:00
return False
2022-04-17 23:05:21 +08:00
return True
def as_json(self):
2022-08-10 14:03:04 +08:00
running_task = None
if self._task_manager.running_task is not None:
running_task = self._task_manager.running_task.as_json()
data = {
2022-04-17 23:05:21 +08:00
'id': self._id,
'name': self._name,
'uuid': self._uuid,
'desc': self._desc,
'status': self._status,
'device': self._device,
'task': self.task_list,
2022-08-10 14:03:04 +08:00
'running_task': running_task
2022-04-17 23:05:21 +08:00
}
return data