You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

409 lines
19 KiB
Python

2 years ago
# -*- coding: UTF-8 -*-
"""
规程运行包括单步运行暂停恢复退出等操作
"""
# 运行规程,先确定要运行的规程或者用例组或者用例的id再定位到表里面的具体操作
from procedure.manage_procedure.models import (
Procedure, Usecase, UsecaseGroup,
RunResult, InitProcedure, StatisticalReport,
LoopRunResult
)
import json, sys
import threading
import uuid
import wx
from utils import core
from ui_dcs import ui_utils
from operation import init_operation, write_operation, read_operation
from time import strftime
from test.log_info import DCSLog, DCSLogType
class RunConfig(threading.Thread):
def __init__(self, run_type, value, run_action='run'):
"""
:param run_type:
可以传入usecase_number 或者 procedure_number 或者 usecase_group_name都是单独传入不能同时传入
:param value:
number
:param run_action:
'run'顺序执行 'debug' 单步执行
"""
self.sleep_time = 0.5
self.is_loop_run = False
self.run_interval = self.sleep_time + 2
threading.Thread.__init__(self)
self.__flag = threading.Event() # 用于暂停线程的标识
self.__flag.set() # 设置为True
self.__running = threading.Event() # 用于停止线程的标识
self.__running.set() # 将running设置为True
self.run_action = run_action
self.runPauseStatusToggle = 'run'
self.run_debug = True # 初始的单步运行状态
self.run_procedure_number = "" # 当前运行的规程编号
self.run_procedure_name = "" # 当前运行的规程名称
self.run_usecase_group_name = "" # 当前运行的用例组名字
self.run_usecase_number = "" # 当前运行的用例编号
self.run_operation_section = 0 # 当前规程运行的用例中具体段落的索引
self.run_text = "" # 运行中返回来的文本
self.run_big_sort_index = 0 # 运行的单步操作的index比如四个检查只一个单步操作
self.run_sort = 0 # 运行的单行操作的sort每个检查都有自己sort
self.run_result = True # 运行结果True 或者False
self.run_uuid = uuid.uuid1() # 运行时UID
self.run_is_complete = False
self.run_type = ""
self.start_delay_dict = {}
self.current_loop_list = []
self.run_type_map = 1
self.run_usecase_index = 0
self.continue_run = False
from dcs_io.iocontroller import IOController
self.io_controller = IOController()
self.io_controller.io_mapping.load_point_table(ui_utils.GetStaticPath("modbus_slave_simulator.xlsm"))
if run_type == "procedure_number":
self.procedure = Procedure.get(Procedure.number == value)
self.run_procedure_number = value
self.run_procedure_name = self.procedure.name
self.run_usecase_number = json.loads(self.procedure.usecase)[0]
self.run_usecase_obj = Usecase.get(Usecase.number == self.run_usecase_number)
self.run_type = "procedure"
self.run_type_map = 1
elif run_type == "usecase_group_name":
self.usecasegroup = UsecaseGroup.get(UsecaseGroup.id == value)
self.run_usecase_group_name = self.usecasegroup.name
self.run_usecase_number = json.loads(self.usecasegroup.usecase)[0]
self.run_usecase_obj = Usecase.get(Usecase.number == self.run_usecase_number)
self.run_type = "usecasegroup"
self.run_type_map = 2
elif run_type == "usecase_number":
self.usecase = Usecase.get(Usecase.number == value)
self.run_usecase_number = value
self.run_type = "usecase"
self.run_type_map = 3
else:
print "运行类型错误"
sys.exit(0)
# 终止列表重新运行配置
@classmethod
def rerun_config(cls, result_id):
result = RunResult.get(RunResult.id == result_id)
if result.procedure_number != "":
runconfig = cls("procedure_number", result.procedure_number, run_action='run')
elif result.usecase_group_name != "":
usecase_group_id = UsecaseGroup.get(UsecaseGroup.name == result.usecase_group_name).id
runconfig = cls("usecase_group_name", usecase_group_id, run_action='run')
else:
runconfig = None
runconfig.run_uuid = result.run_uuid
runconfig.run_usecase_number = result.usecase_number
runconfig.run_operation_section = result.operation_section
runconfig.run_usecase_index = result.run_usecase_index
runconfig.run_sort = result.section_sort
runconfig.run_usecase_obj = Usecase.get(Usecase.number == runconfig.run_usecase_number)
runconfig.run_big_sort_index = result.run_big_sort
runconfig.continue_run = True
runconfig.start()
runconfig.pause()
runconfig.run_debug = False
return runconfig
# 根据sort获取big_sort
def get_big_sort(self, run_usecase_obj, operation_section, section_sort):
operation = json.loads(run_usecase_obj.operation)
section = operation[operation_section]
big_section_sort = 0
for m in range(1, len(section)):
for i in range(1, len(section[m])):
if int(section[m][i]["sort"]) == section_sort:
return big_section_sort
big_section_sort = big_section_sort + 1
# 顺序运行的入口
def run(self):
if not InitProcedure.select().limit(1):
log = DCSLog(u'请导入初始化规程', DCSLogType.ERROR)
core.Client.Project.AddLog(log)
core.Client.setCurrentRun(None)
core.Client.RunDirty = True
return False
while self.__running.isSet():
self.__flag.wait() # 为True时立即返回, 为False时阻塞直到内部的标识位为True后返回
if self.run_type == "procedure":
self.run_procedure()
elif self.run_type == "usecasegroup":
self.run_usecase_group()
elif self.run_type == "usecase":
self.run_usecase()
else:
print "运行类型错误"
sys.exit(0)
def pause(self):
self.__flag.clear() # 设置为False, 让线程阻塞
self.runPauseStatusToggle = 'pause'
def resume(self):
self.__flag.set() # 设置为True, 让线程停止阻塞
self.runPauseStatusToggle = 'run'
def current_stop(self):
self.__flag.set() # 将线程从暂停状态恢复, 如果已经暂停的话
self.__running.clear() # 设置为False
from test.log_info import DCSLog, DCSLogType
name = u'%s-%s' % (self.run_procedure_number or self.run_usecase_number, self.run_usecase_group_name)
log = DCSLog(u'%s运行结束' % name, DCSLogType.DEFAULT)
core.Client.Project.AddLog(log)
del self
core.Client.setCurrentRun(None)
core.Client.RunDirty = True
def stop(self):
self.__flag.set() # 将线程从暂停状态恢复, 如果已经暂停的话
self.__running.clear() # 设置为False
self.join(1)
from test.log_info import DCSLog, DCSLogType
name = u'%s-%s' % (self.run_procedure_number or self.run_usecase_number, self.run_usecase_group_name)
log = DCSLog(u'%s运行结束' % name, DCSLogType.DEFAULT)
core.Client.Project.AddLog(log)
del self
core.Client.setCurrentRun(None)
core.Client.RunDirty = True
# 单步运行程序第一次调用判断run_debug的值进而决定是否起线程
def debug(self):
if self.run_debug == True:
self.start()
self.pause()
self.run_debug = False
else:
self.resume()
self.pause()
# 运行规程,顺序运行
def run_procedure(self):
if self.run_usecase_number == json.loads(
self.procedure.usecase)[0] and self.run_operation_section == 0 and self.run_big_sort_index == 0:
print "开始运行规程", self.procedure.name
core.Client.CurrentProcedureEditor.SetOperationsNumberValue(self.run_usecase_number, '', '')
self.run_usecase_operation(json.loads(self.run_usecase_obj.operation))
# 运行用例组,顺序运行
def run_usecase_group(self):
if self.run_usecase_number == json.loads(
self.usecasegroup.usecase)[0] and self.run_operation_section == 0 and self.run_big_sort_index == 0:
print "开始运行用例组", self.usecasegroup.name
core.Client.CurrentProcedureEditor.SetOperationsNumberValue(self.run_usecase_number, '', True)
self.run_usecase_operation(json.loads(self.run_usecase_obj.operation))
# 运行用例,顺序运行
def run_usecase(self):
print "运行的用例是", self.usecase.name
operation = json.loads(self.usecase.operation)
self.run_usecase_operation(operation)
# 运行用例大步操作集,顺序运行
def run_usecase_operation(self, operation):
if self.run_big_sort_index == 0:
tmp_number = u'%s-%s-%s' % (self.run_usecase_number, self.run_operation_section, 0)
core.Client.CurrentProcedureEditor.SetOperationsNumberValue(tmp_number, '', True)
section = operation[self.run_operation_section]
self.run_usecase_section(section)
# 运行操作集中的一个section
def run_usecase_section(self, section):
section_big_sort = section[self.run_big_sort_index]
if self.run_big_sort_index > 0:
self.run_usecase_sort(section_big_sort)
else:
self.run_big_sort_index += 1
# 运行单条指令
def run_usecase_sort(self, section_big_sort):
run_operation_result = self.run_operation(section_big_sort)
if (not core.Client.ContinueRunFalse) and (not self.is_loop_run):
while not run_operation_result :
retCode = wx.MessageBox(u'是否运行下一条操作',u'操作不通过,确认继续运行吗?', wx.YES_NO | wx.ICON_QUESTION)
if retCode == wx.YES:
break
run_operation_result = self.run_operation(section_big_sort)
# 如果运行的单步索引等于当前section的长度-1则将run_big_sort_index设为0位下一个section做准备
# 并且在此时需要将section的索引+1,如果section索引的值等于当前operation的长度-1则将run_operation_section设为0
self.run_big_sort_index += 1
tmp_operation = json.loads(self.run_usecase_obj.operation)
if self.run_big_sort_index == len(tmp_operation[self.run_operation_section]):
self.run_big_sort_index = 0
self.run_operation_section += 1
if self.run_operation_section == len(tmp_operation):
self.run_operation_section = 0
self.stop_run()
def run_operation(self, section_big_sort):
operate_map = {
"INIT": init_operation,
"WRITE": write_operation,
"READ": read_operation,
}
return operate_map.get(section_big_sort[0])(self, section_big_sort)
# 是否暂停当前运行的规程或者用例
def stop_run(self):
if self.run_type == "usecase":
RunResult.update(is_stop=False).where(RunResult.run_uuid == self.run_uuid).execute()
if not self.is_loop_run:
# 更新统计报表
self.save_statistical_report(self.run_usecase_number)
# 停止线程
self.current_stop()
else:
self.loop_init_config()
if self.run_type == "procedure":
# 判断是否还有下一个用例,如果没有就结束线程
# tmp_usecase_index = json.loads(self.procedure.usecase).index(self.run_usecase_number)
if self.run_usecase_index < len(json.loads(self.procedure.usecase)) - 1:
self.run_usecase_number = json.loads(self.procedure.usecase)[self.run_usecase_index + 1]
self.run_usecase_index += 1
self.run_usecase_obj = Usecase.get(Usecase.number == self.run_usecase_number)
else:
RunResult.update(is_stop=False).where(RunResult.run_uuid == self.run_uuid).execute()
if not self.is_loop_run:
# 更新统计报表
self.save_statistical_report(self.run_usecase_number)
# 停止线程
self.current_stop()
else:
self.loop_init_config()
if self.run_type == "usecasegroup":
# 判断是否还有下一个用例,如果没有就结束线程
# tmp_usecase_index = json.loads(self.usecasegroup.usecase).index(self.run_usecase_number)
if self.run_usecase_index < len(json.loads(self.usecasegroup.usecase)) - 1:
self.run_usecase_number = json.loads(self.usecasegroup.usecase)[self.run_usecase_index + 1]
self.run_usecase_index += 1
self.run_usecase_obj = Usecase.get(Usecase.number == self.run_usecase_number)
else:
RunResult.update(is_stop=False).where(RunResult.run_uuid == self.run_uuid).execute()
if not self.is_loop_run:
# 更新统计报表
self.save_statistical_report(self.run_usecase_group_name)
# 停止线程
self.current_stop()
else:
self.loop_init_config()
def save_statistical_report(self, name_or_number):
runResult = RunResult.select().where(RunResult.run_uuid == self.run_uuid)
pass_Result = RunResult.select().where(
(RunResult.run_uuid == self.run_uuid) & (RunResult.run_result == True))
statisticalReport = StatisticalReport()
statisticalReport.result_uuid = self.run_uuid
statisticalReport.report_type = self.run_type_map
statisticalReport.name_or_number = name_or_number
statisticalReport.start_time = runResult[0].run_time
statisticalReport.end_time = runResult[-1].run_time
a = float(len(pass_Result))
b = float(len(runResult))
statisticalReport.pass_rate = "%.2f%%" % (a / b * 100)
statisticalReport.operator = core.Client.User.username
statisticalReport.save()
# 存储运行结果
def save_run_result(self):
runresult = RunResult()
runresult.run_uuid = self.run_uuid
runresult.procedure_number = self.run_procedure_number
runresult.procedure_name = self.run_procedure_name
runresult.usecase_group_name = self.run_usecase_group_name
runresult.usecase_number = self.run_usecase_number
runresult.operation_section = self.run_operation_section
runresult.run_big_sort = self.run_big_sort_index
runresult.section_sort = self.run_sort
runresult.run_text = self.run_text
runresult.run_result = self.run_result
runresult.run_time = strftime("%Y-%m-%d %H:%M:%S")
runresult.run_type = self.run_type_map
runresult.run_usecase_index = self.run_usecase_index
# 如果usecase_number 、operation_section、section_sort都相同则是循环的操作
# 只需要更新即可,不能用保存
exist_runresult = RunResult.select().where(RunResult.run_uuid == runresult.run_uuid,
RunResult.usecase_number == runresult.usecase_number,
RunResult.operation_section == runresult.operation_section,
RunResult.section_sort == runresult.section_sort)
if exist_runresult.first() == None:
runresult.is_stop = True
runresult.save()
if exist_runresult.first() != None:
update_result = exist_runresult.first()
update_result.run_text = self.run_text
update_result.run_result = self.run_result
update_result.run_time = strftime("%Y-%m-%d %H:%M:%S")
runresult.is_stop = True
RunResult.update_obj(update_result)
def save_loop_result(self):
loopRunResult = LoopRunResult()
loopRunResult.run_uuid = self.run_uuid
loopRunResult.procedure_number = self.run_procedure_number
loopRunResult.procedure_name = self.run_procedure_name
loopRunResult.usecase_group_name = self.run_usecase_group_name
loopRunResult.usecase_number = self.run_usecase_number
loopRunResult.operation_section = self.run_operation_section
loopRunResult.run_big_sort = self.run_big_sort_index
loopRunResult.section_sort = self.run_sort
loopRunResult.run_text = self.run_text
loopRunResult.run_result = self.run_result
loopRunResult.run_time = strftime("%Y-%m-%d %H:%M:%S")
loopRunResult.run_type = self.run_type_map
loopRunResult.run_usecase_index = self.run_usecase_index
# 如果usecase_number 、operation_section、section_sort都相同则是循环的操作
# 只需要更新即可,不能用保存
exist_runresult = LoopRunResult.select().where(LoopRunResult.run_uuid == loopRunResult.run_uuid,
LoopRunResult.usecase_number == loopRunResult.usecase_number,
LoopRunResult.operation_section == loopRunResult.operation_section,
LoopRunResult.section_sort == loopRunResult.section_sort)
if exist_runresult.first() == None:
loopRunResult.is_stop = True
loopRunResult.save()
if exist_runresult.first() != None:
update_result = exist_runresult.first()
update_result.run_text = self.run_text
update_result.run_result = self.run_result
update_result.run_time = strftime("%Y-%m-%d %H:%M:%S")
loopRunResult.is_stop = True
LoopRunResult.update_obj(update_result)
# 重新设置循环运行的参数
def loop_init_config(self):
self.run_uuid = uuid.uuid1()
if self.run_type_map == 1:
self.run_usecase_number = json.loads(self.procedure.usecase)[0]
elif self.run_type_map == 2:
self.run_usecase_number = json.loads(self.usecasegroup.usecase)[0]
self.run_usecase_obj = Usecase.get(Usecase.number == self.run_usecase_number)
self.run_operation_section = 0 # 当前规程运行的用例中具体段落的索引
self.run_big_sort_index = 0 # 运行的单步操作的index比如四个检查只一个单步操作
self.run_sort = 0 # 运行的单行操作的sort每个检查都有自己sort
self.run_usecase_index = 0
# TODO 重置运行界面的参数
if core.Client.CurrentProcedureEditor:
core.Client.CurrentProcedureEditor.resetAll()
# if __name__ == "__main__":
# from utils import core
# core.Client.setDb('C:\\Users\\zhan\\Desktop\\dcs_pro\\p1\\.resources\\dcs.db')
# # core.Client.CurrentProcedureEditor.SetOperationsNumberValue(number, real_result, result_check)
# run = RunConfig("procedure_number", "TP3RPN01")
# run.start()
# # run.start_run() #顺序运行规程
# # run.step_run_procedure(1,1,1)
# # run.save_run_result()