2026-03-02 14:29:58 +08:00
|
|
|
|
|
|
|
|
|
|
#!/opt/homebrew/bin/python3
|
|
|
|
|
|
# -*- coding:utf-8 -*-
|
|
|
|
|
|
import json
|
|
|
|
|
|
import tracemalloc
|
|
|
|
|
|
import gc
|
|
|
|
|
|
import time
|
|
|
|
|
|
import base64
|
|
|
|
|
|
from PyQt6 import *
|
|
|
|
|
|
from PyQt6.QtCore import *
|
|
|
|
|
|
from logs import log
|
|
|
|
|
|
from typing import Union
|
|
|
|
|
|
from inspect import isfunction
|
|
|
|
|
|
from common import common
|
|
|
|
|
|
from influxDB import influxdb
|
|
|
|
|
|
from logModel.logManager import logManager
|
|
|
|
|
|
from instructionModel.instructionModel import InstructionModel
|
|
|
|
|
|
from projectModel.projectManager import projectManager
|
|
|
|
|
|
from userModel.userManager import userManager
|
|
|
|
|
|
from taskModel.taskManager import taskManager
|
|
|
|
|
|
from taskInstructionModel.taskInstructionManager import taskInstructionManager
|
|
|
|
|
|
from taskModel.taskModel import TaskModel
|
|
|
|
|
|
from interfaceSession.interfaceManager import interfaceManager
|
|
|
|
|
|
|
|
|
|
|
|
class TaskActuator(QThread):
|
|
|
|
|
|
TASK = 0
|
|
|
|
|
|
VIRTUAL = 1
|
|
|
|
|
|
INSTRUCTION = 2
|
|
|
|
|
|
|
|
|
|
|
|
logMsg = pyqtSignal(dict)
|
|
|
|
|
|
updateProgress = pyqtSignal(str, int, int)
|
|
|
|
|
|
updateInstructProgress = pyqtSignal(str, int, int)
|
|
|
|
|
|
updateDetails = pyqtSignal(str, int, int)
|
|
|
|
|
|
executeFinished = pyqtSignal(str)
|
2026-04-17 15:31:41 +08:00
|
|
|
|
taskStop = pyqtSignal(str) # 添加任务停止信号
|
2026-03-02 14:29:58 +08:00
|
|
|
|
def __init__(self, id):
|
|
|
|
|
|
super().__init__()
|
|
|
|
|
|
self.currentIndex = 0
|
|
|
|
|
|
self.task_instruction_id = ""
|
|
|
|
|
|
self.instructionList = []
|
|
|
|
|
|
self.currentTask = None
|
|
|
|
|
|
self.parentId = ""
|
|
|
|
|
|
self.running_lock = QMutex() # 新增互斥锁
|
|
|
|
|
|
self.running = False
|
|
|
|
|
|
self.eventInfo = {}
|
|
|
|
|
|
self.subTaskActuator = None
|
|
|
|
|
|
self.taskScript = ""
|
|
|
|
|
|
self.type = TaskActuator.INSTRUCTION
|
|
|
|
|
|
self.id = str(id)
|
|
|
|
|
|
self.name = ""
|
|
|
|
|
|
self.taskInfo = {}
|
|
|
|
|
|
|
|
|
|
|
|
def onUpdateProgress(self, taskId, current, total):
|
|
|
|
|
|
self.updateProgress.emit(taskId, current, total)
|
|
|
|
|
|
|
|
|
|
|
|
def onUpdateDetails(self, taskId, current, total):
|
|
|
|
|
|
self.updateDetails.emit(taskId, current, total)
|
|
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
|
try:
|
|
|
|
|
|
tracemalloc.start()
|
|
|
|
|
|
loopStartTime = 0
|
|
|
|
|
|
currentInstruction = InstructionModel()
|
|
|
|
|
|
session = None
|
|
|
|
|
|
proId = projectManager.getCurrentProId()
|
|
|
|
|
|
proInfo = projectManager.getCurrentProInfo()
|
|
|
|
|
|
bucketName = "name" in proInfo and proInfo["name"] or "DEFAULT"
|
|
|
|
|
|
influxdb.create(bucketName)
|
|
|
|
|
|
operator = userManager.getCurrentUser()
|
|
|
|
|
|
if proId != None and proId != "":
|
|
|
|
|
|
projectManager.addHistory(proId, {
|
|
|
|
|
|
"event": "执行",
|
|
|
|
|
|
"type": self.type,
|
|
|
|
|
|
"name": self.name,
|
|
|
|
|
|
"operator": operator,
|
|
|
|
|
|
})
|
|
|
|
|
|
instructionListLength = len(self.instructionList)
|
|
|
|
|
|
|
|
|
|
|
|
if self.type == TaskActuator.TASK and instructionListLength > 0:
|
|
|
|
|
|
|
|
|
|
|
|
self.currentTask = TaskModel(self.taskInfo)
|
|
|
|
|
|
self.currentTask.setProInfo(proInfo)
|
|
|
|
|
|
self.currentTask.logMsg.connect(self.onLogMsg, type=Qt.ConnectionType.DirectConnection)
|
|
|
|
|
|
self.currentTask.updateProgress.connect(self.onUpdateProgress)
|
|
|
|
|
|
loop = int(self.taskInfo.get("loop", 1))
|
|
|
|
|
|
delay = float(int(self.taskInfo.get("delay",0))/1000)
|
2026-04-17 15:31:41 +08:00
|
|
|
|
taskIndex = 0
|
|
|
|
|
|
total = instructionListLength * loop
|
|
|
|
|
|
self.updateProgress.emit(self.id, 0, total)
|
|
|
|
|
|
self.updateDetails.emit(self.id, 0, total)
|
|
|
|
|
|
self.updateDetails.emit(self.parentId, 0, total)
|
2026-03-02 14:29:58 +08:00
|
|
|
|
self.currentTask.setTargetList(self.instructionList)
|
|
|
|
|
|
self.currentTask.start()
|
|
|
|
|
|
|
|
|
|
|
|
while not self.currentTask.isFinished and self.running:
|
|
|
|
|
|
if self.running == False:
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
self.currentTask.callBack(0)
|
|
|
|
|
|
self.currentIndex = 0
|
|
|
|
|
|
self.updateProgress.emit(self.id, 0, total)
|
2026-04-17 15:31:41 +08:00
|
|
|
|
# 新一轮循环开始,重置所有子指令进度
|
|
|
|
|
|
for resetIdx in range(instructionListLength):
|
|
|
|
|
|
resetInfo = self.instructionList[resetIdx]
|
|
|
|
|
|
reset_tid = str(resetInfo["id"]) or ""
|
|
|
|
|
|
reset_target_type = resetInfo["target_type"] or ""
|
|
|
|
|
|
reset_loop = "loop" in resetInfo and int(resetInfo["loop"]) or 1
|
|
|
|
|
|
self.updateDetails.emit(str(self.parentId) + reset_tid, 0, reset_loop)
|
2026-03-02 14:29:58 +08:00
|
|
|
|
# 执行任务
|
|
|
|
|
|
while not self.currentTask.isFinished and self.currentIndex < instructionListLength and self.running:
|
|
|
|
|
|
taskInstructionInfo = self.instructionList[self.currentIndex]
|
|
|
|
|
|
|
|
|
|
|
|
self.currentTask.setTargetId(taskInstructionInfo["target_id"])
|
|
|
|
|
|
self.currentTask.callBack(1)
|
|
|
|
|
|
task_instruction_id = str(taskInstructionInfo["id"]) or ""
|
|
|
|
|
|
target_id = str(taskInstructionInfo["target_id"]) or ""
|
|
|
|
|
|
target_type = taskInstructionInfo["target_type"] or ""
|
|
|
|
|
|
level = str(taskInstructionInfo["level"]) or ""
|
|
|
|
|
|
target_loop = "loop" in taskInstructionInfo and int(taskInstructionInfo["loop"]) or 1
|
|
|
|
|
|
target_delay = "delay" in taskInstructionInfo and float(int(taskInstructionInfo["delay"])/1000) or 0
|
|
|
|
|
|
if self.parentId == "":
|
|
|
|
|
|
self.parentId = self.id
|
|
|
|
|
|
|
|
|
|
|
|
if target_type == "instruction":
|
|
|
|
|
|
self.updateDetails.emit(str(self.parentId) + task_instruction_id, 0, target_loop)
|
|
|
|
|
|
|
|
|
|
|
|
for j in range(target_loop):
|
|
|
|
|
|
loopStartTime = time.time()
|
|
|
|
|
|
self.currentTask.callBack(2)
|
|
|
|
|
|
if self.currentTask.isFinished:
|
|
|
|
|
|
self.updateDetails.emit(str(self.parentId) + task_instruction_id, -1, -1)
|
|
|
|
|
|
break
|
|
|
|
|
|
if self.running == False:
|
|
|
|
|
|
self.updateDetails.emit(str(self.parentId) + task_instruction_id, -1, -1)
|
|
|
|
|
|
break
|
|
|
|
|
|
# 执行指令
|
|
|
|
|
|
currentInstruction.setInfo(taskInstructionInfo["instructionInfo"], taskInstructionInfo["target_param"])
|
|
|
|
|
|
currentInstruction.setProInfo(proInfo)
|
|
|
|
|
|
currentInstruction.setUserInfo(userManager.getCurrentUser())
|
|
|
|
|
|
currentInstruction.setDevInfo(taskInstructionInfo["device"])
|
|
|
|
|
|
interfaceInfos = interfaceManager.getInfo(taskInstructionInfo["interface"])
|
|
|
|
|
|
interfaceInfo = {}
|
|
|
|
|
|
if len(interfaceInfos) <= 0:
|
|
|
|
|
|
continue
|
|
|
|
|
|
interfaceInfo = interfaceInfos[0] #interface接口返回个数为1
|
|
|
|
|
|
currentInstruction.setInterfaceInfo(interfaceInfo)
|
|
|
|
|
|
session = interfaceManager.getSession(taskInstructionInfo["interface"])
|
|
|
|
|
|
try:
|
|
|
|
|
|
currentInstruction.logMsg.disconnect(self.onLogMsg)
|
|
|
|
|
|
currentInstruction.ioCtrl.disconnect(session.ioctrl)
|
|
|
|
|
|
currentInstruction.sendData.disconnect(session.send)
|
|
|
|
|
|
session.newDataArrive.disconnect(currentInstruction.dataHandler)
|
|
|
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
currentInstruction.logMsg.connect(self.onLogMsg, type=Qt.ConnectionType.DirectConnection)
|
|
|
|
|
|
currentInstruction.ioCtrl.connect(session.ioctrl, type=Qt.ConnectionType.DirectConnection)
|
|
|
|
|
|
currentInstruction.sendData.connect(session.send, type=Qt.ConnectionType.DirectConnection)
|
|
|
|
|
|
|
|
|
|
|
|
while not self.currentTask.isFinished and not session.lock() and self.running:
|
|
|
|
|
|
self.updateProgress.emit(self.id, int( self.currentIndex + int(taskIndex*instructionListLength)), total)
|
|
|
|
|
|
QThread.usleep(1)
|
|
|
|
|
|
session.newDataArrive.connect(currentInstruction.dataHandler, type=Qt.ConnectionType.DirectConnection)
|
|
|
|
|
|
currentInstruction.start()
|
|
|
|
|
|
while not self.currentTask.isFinished and not currentInstruction.isFinished and self.running:
|
|
|
|
|
|
self.updateProgress.emit(self.id, int( self.currentIndex + int(taskIndex*instructionListLength)), total)
|
|
|
|
|
|
currentInstruction.loop()
|
|
|
|
|
|
QThread.usleep(1)
|
|
|
|
|
|
|
|
|
|
|
|
self.updateDetails.emit(str(self.parentId) + task_instruction_id, j+1, target_loop)
|
|
|
|
|
|
#解除信号绑定
|
|
|
|
|
|
try:
|
|
|
|
|
|
currentInstruction.logMsg.disconnect(self.onLogMsg)
|
|
|
|
|
|
currentInstruction.ioCtrl.disconnect(session.ioctrl)
|
|
|
|
|
|
currentInstruction.sendData.disconnect(session.send)
|
|
|
|
|
|
session.newDataArrive.disconnect(currentInstruction.dataHandler)
|
|
|
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
|
|
|
session.unlock()
|
|
|
|
|
|
tmpTime = time.time()
|
|
|
|
|
|
if tmpTime < loopStartTime + target_delay:
|
|
|
|
|
|
time.sleep(target_delay - (tmpTime - loopStartTime))
|
|
|
|
|
|
|
|
|
|
|
|
# time.sleep(target_delay) 指令延时在指令内部处理
|
|
|
|
|
|
elif target_type == "task":
|
|
|
|
|
|
# 执行子任务
|
|
|
|
|
|
for j in range(target_loop):
|
|
|
|
|
|
if not self.running:
|
|
|
|
|
|
break
|
|
|
|
|
|
self.currentTask.callBack(5)
|
|
|
|
|
|
self.subTaskActuator = TaskActuator(target_id)
|
|
|
|
|
|
self.subTaskActuator.parentId = str(self.parentId) + task_instruction_id
|
|
|
|
|
|
self.subTaskActuator.task_instruction_id = str(self.parentId) + task_instruction_id
|
|
|
|
|
|
taskInfo = taskManager.getInfo(target_id)
|
|
|
|
|
|
taskInfo["params"] = taskInstructionInfo["target_param"]
|
|
|
|
|
|
taskInstructions = taskInstructionManager.getInfo(target_id)
|
|
|
|
|
|
common.getTaskDetails(taskInstructions)
|
|
|
|
|
|
self.subTaskActuator.updateDetails.connect(self.onUpdateDetails, type=Qt.ConnectionType.DirectConnection)
|
|
|
|
|
|
self.subTaskActuator.execute(taskInstructions, taskInfo)
|
|
|
|
|
|
self.subTaskActuator.wait()
|
|
|
|
|
|
self.currentTask.callBack(6)
|
|
|
|
|
|
time.sleep(target_delay)
|
|
|
|
|
|
|
|
|
|
|
|
# 子任务执行完毕
|
|
|
|
|
|
self.currentIndex += 1
|
|
|
|
|
|
if loop > 0:
|
|
|
|
|
|
if self.currentTask.isFinished:
|
|
|
|
|
|
self.updateProgress.emit(self.id,1,-1)
|
2026-04-17 15:31:41 +08:00
|
|
|
|
# 根节点完成后保持绿色完成状态(value=total, max=total)
|
|
|
|
|
|
self.updateDetails.emit(self.id, total, total)
|
2026-03-02 14:29:58 +08:00
|
|
|
|
elif self.running:
|
|
|
|
|
|
if self.task_instruction_id != "":
|
|
|
|
|
|
self.updateDetails.emit( self.task_instruction_id, int( self.currentIndex + int(taskIndex*instructionListLength)), total)
|
|
|
|
|
|
else:
|
|
|
|
|
|
self.updateDetails.emit(self.id, int( self.currentIndex + int(taskIndex*instructionListLength)), total)
|
|
|
|
|
|
self.updateProgress.emit(self.id, int( self.currentIndex + int(taskIndex*instructionListLength)), total)
|
|
|
|
|
|
|
|
|
|
|
|
taskIndex += 1
|
|
|
|
|
|
self.currentTask.next()
|
|
|
|
|
|
if loop > 1:
|
|
|
|
|
|
time.sleep(delay)
|
|
|
|
|
|
self.updateProgress.emit(str(self.taskInfo["id"]),1,-1)
|
|
|
|
|
|
currentInstruction.deleteLater()
|
|
|
|
|
|
|
|
|
|
|
|
elif self.type == TaskActuator.VIRTUAL and instructionListLength > 0:
|
|
|
|
|
|
session = None
|
|
|
|
|
|
currentInstruction = InstructionModel()
|
|
|
|
|
|
self.currentIndex = 0
|
|
|
|
|
|
total = instructionListLength
|
|
|
|
|
|
# 执行任务
|
|
|
|
|
|
while self.currentIndex < instructionListLength and self.running:
|
|
|
|
|
|
taskInstructionInfo = self.instructionList[self.currentIndex]
|
|
|
|
|
|
target_id = str(taskInstructionInfo["target_id"]) or ""
|
|
|
|
|
|
target_type = taskInstructionInfo["target_type"] or ""
|
|
|
|
|
|
target_loop = "loop" in taskInstructionInfo and int(taskInstructionInfo["loop"]) or 1
|
|
|
|
|
|
target_delay = "delay" in taskInstructionInfo and float(int(taskInstructionInfo["delay"])/1000) or 0
|
|
|
|
|
|
|
|
|
|
|
|
if target_type == "instruction":
|
|
|
|
|
|
for j in range(target_loop):
|
|
|
|
|
|
if self.running == False:
|
|
|
|
|
|
break
|
|
|
|
|
|
# 执行指令
|
|
|
|
|
|
currentInstruction.setInfo(taskInstructionInfo["instructionInfo"], taskInstructionInfo["target_param"])
|
|
|
|
|
|
currentInstruction.setProInfo(proInfo)
|
|
|
|
|
|
currentInstruction.setUserInfo(userManager.getCurrentUser())
|
|
|
|
|
|
currentInstruction.setDevInfo(taskInstructionInfo["device"])
|
|
|
|
|
|
interfaceInfos = interfaceManager.getInfo(taskInstructionInfo["interface"])
|
|
|
|
|
|
interfaceInfo = {}
|
|
|
|
|
|
if len(interfaceInfos) <= 0:
|
|
|
|
|
|
continue
|
|
|
|
|
|
interfaceInfo = interfaceInfos[0] #interface接口返回个数为1
|
|
|
|
|
|
currentInstruction.setInterfaceInfo(interfaceInfo)
|
|
|
|
|
|
session = interfaceManager.getSession(taskInstructionInfo["interface"])
|
|
|
|
|
|
try:
|
|
|
|
|
|
currentInstruction.logMsg.disconnect(self.onLogMsg)
|
|
|
|
|
|
currentInstruction.ioCtrl.disconnect(session.ioctrl)
|
|
|
|
|
|
currentInstruction.sendData.disconnect(session.send)
|
|
|
|
|
|
session.newDataArrive.disconnect(currentInstruction.dataHandler)
|
|
|
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
|
|
|
currentInstruction.logMsg.connect(self.onLogMsg, type=Qt.ConnectionType.UniqueConnection)
|
|
|
|
|
|
currentInstruction.ioCtrl.connect(session.ioctrl, type=Qt.ConnectionType.UniqueConnection)
|
|
|
|
|
|
currentInstruction.sendData.connect(session.send, type=Qt.ConnectionType.UniqueConnection)
|
|
|
|
|
|
|
|
|
|
|
|
while not session.lock() and self.running:
|
|
|
|
|
|
QThread.usleep(1)
|
|
|
|
|
|
session.newDataArrive.connect(currentInstruction.dataHandler, type=Qt.ConnectionType.DirectConnection)
|
|
|
|
|
|
currentInstruction.start()
|
|
|
|
|
|
|
|
|
|
|
|
while not currentInstruction.isFinished and self.running:
|
|
|
|
|
|
currentInstruction.loop()
|
|
|
|
|
|
QThread.usleep(1)
|
|
|
|
|
|
# 解除信号绑定
|
|
|
|
|
|
try:
|
|
|
|
|
|
currentInstruction.logMsg.disconnect(self.onLogMsg)
|
|
|
|
|
|
currentInstruction.ioCtrl.disconnect(session.ioctrl)
|
|
|
|
|
|
currentInstruction.sendData.disconnect(session.send)
|
|
|
|
|
|
session.newDataArrive.disconnect(currentInstruction.dataHandler)
|
|
|
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
|
|
|
session.unlock()
|
|
|
|
|
|
time.sleep(target_delay)
|
|
|
|
|
|
elif target_type == "task":
|
|
|
|
|
|
# 执行子任务
|
|
|
|
|
|
for j in range(target_loop):
|
|
|
|
|
|
self.subTaskActuator = TaskActuator(target_id)
|
|
|
|
|
|
taskInfo = taskManager.getInfo(target_id)
|
|
|
|
|
|
taskInstructions = taskInstructionManager.getInfo(target_id)
|
|
|
|
|
|
common.getTaskDetails(taskInstructions)
|
|
|
|
|
|
self.subTaskActuator.execute(taskInstructions, taskInfo)
|
|
|
|
|
|
self.subTaskActuator.wait()
|
|
|
|
|
|
time.sleep(target_delay)
|
|
|
|
|
|
# 子任务执行完毕
|
|
|
|
|
|
self.currentIndex += 1
|
|
|
|
|
|
currentInstruction.deleteLater()
|
|
|
|
|
|
elif self.type == TaskActuator.INSTRUCTION and instructionListLength == 1:
|
|
|
|
|
|
session = None
|
|
|
|
|
|
currentInstruction = InstructionModel()
|
|
|
|
|
|
taskInstructionInfo = self.instructionList[0]
|
|
|
|
|
|
target_id = str(taskInstructionInfo["target_id"]) or ""
|
|
|
|
|
|
target_type = taskInstructionInfo["target_type"] or ""
|
|
|
|
|
|
target_loop = "loop" in taskInstructionInfo and int(taskInstructionInfo["loop"]) or 1
|
|
|
|
|
|
target_delay = "delay" in taskInstructionInfo and float(int(taskInstructionInfo["delay"])/1000) or 0
|
|
|
|
|
|
if target_type == "instruction":
|
|
|
|
|
|
self.updateInstructProgress.emit(target_id, 0, target_loop)
|
|
|
|
|
|
for j in range(target_loop):
|
|
|
|
|
|
if self.running == False:
|
|
|
|
|
|
break
|
|
|
|
|
|
# 执行指令
|
|
|
|
|
|
currentInstruction.setInfo(taskInstructionInfo["instructionInfo"], taskInstructionInfo["target_param"])
|
|
|
|
|
|
currentInstruction.setProInfo(proInfo)
|
|
|
|
|
|
currentInstruction.setUserInfo(userManager.getCurrentUser())
|
|
|
|
|
|
currentInstruction.setDevInfo(taskInstructionInfo["device"])
|
|
|
|
|
|
interfaceInfos = interfaceManager.getInfo(taskInstructionInfo["interface"])
|
|
|
|
|
|
interfaceInfo = {}
|
|
|
|
|
|
if len(interfaceInfos) <= 0:
|
|
|
|
|
|
continue
|
|
|
|
|
|
interfaceInfo = interfaceInfos[0]
|
|
|
|
|
|
currentInstruction.setInterfaceInfo(interfaceInfo)
|
|
|
|
|
|
session = interfaceManager.getSession(taskInstructionInfo["interface"])
|
|
|
|
|
|
try:
|
|
|
|
|
|
currentInstruction.logMsg.disconnect(self.onLogMsg)
|
|
|
|
|
|
currentInstruction.ioCtrl.disconnect(session.ioctrl)
|
|
|
|
|
|
currentInstruction.sendData.disconnect(session.send)
|
|
|
|
|
|
session.newDataArrive.disconnect(currentInstruction.dataHandler)
|
|
|
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
|
|
|
currentInstruction.logMsg.connect(self.onLogMsg, type=Qt.ConnectionType.DirectConnection)
|
|
|
|
|
|
currentInstruction.ioCtrl.connect(session.ioctrl, type=Qt.ConnectionType.UniqueConnection)
|
|
|
|
|
|
currentInstruction.sendData.connect(session.send, type=Qt.ConnectionType.UniqueConnection)
|
|
|
|
|
|
while not session.lock() and self.running:
|
|
|
|
|
|
self.updateInstructProgress.emit(target_id, j, target_loop)
|
|
|
|
|
|
QThread.msleep(10)
|
|
|
|
|
|
session.newDataArrive.connect(currentInstruction.dataHandler, type=Qt.ConnectionType.DirectConnection)
|
|
|
|
|
|
currentInstruction.start()
|
|
|
|
|
|
while not currentInstruction.isFinished and self.running:
|
|
|
|
|
|
self.updateInstructProgress.emit(target_id, j, target_loop)
|
|
|
|
|
|
currentInstruction.loop()
|
|
|
|
|
|
QThread.msleep(10)
|
|
|
|
|
|
# 解除信号绑定
|
|
|
|
|
|
try:
|
|
|
|
|
|
currentInstruction.ioCtrl.disconnect(session.ioctrl)
|
|
|
|
|
|
currentInstruction.sendData.disconnect(session.send)
|
|
|
|
|
|
currentInstruction.logMsg.disconnect(self.onLogMsg)
|
|
|
|
|
|
session.newDataArrive.disconnect(currentInstruction.dataHandler)
|
|
|
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
|
|
|
session.unlock()
|
|
|
|
|
|
time.sleep(target_delay)
|
|
|
|
|
|
self.updateInstructProgress.emit(self.id,1,-1)
|
|
|
|
|
|
currentInstruction.deleteLater()
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
try:
|
|
|
|
|
|
common.showAlert.emit("EXEC错误", str(e), 0)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
log.info(str(e))
|
|
|
|
|
|
|
|
|
|
|
|
finally:
|
|
|
|
|
|
try:
|
|
|
|
|
|
currentInstruction.ioCtrl.disconnect(session.ioctrl)
|
|
|
|
|
|
currentInstruction.sendData.disconnect(session.send)
|
|
|
|
|
|
currentInstruction.logMsg.disconnect(self.onLogMsg)
|
|
|
|
|
|
session.newDataArrive.disconnect(currentInstruction.dataHandler)
|
|
|
|
|
|
session.unlock()
|
|
|
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
|
|
|
if proId != None and proId != "":
|
|
|
|
|
|
projectManager.addHistory(proId, {
|
|
|
|
|
|
"event": "结束",
|
|
|
|
|
|
"type": self.type,
|
|
|
|
|
|
"name": self.name,
|
|
|
|
|
|
"operator": operator,
|
|
|
|
|
|
})
|
|
|
|
|
|
self.updateInstructProgress.emit(self.id,1,-1)
|
|
|
|
|
|
self.updateProgress.emit(self.id,1,-1)
|
2026-04-17 15:31:41 +08:00
|
|
|
|
# 根节点完成后保持绿色完成状态
|
|
|
|
|
|
total = len(self.instructionList) * int(self.taskInfo.get("loop", 1))
|
|
|
|
|
|
self.updateDetails.emit(self.id, total, total)
|
2026-03-02 14:29:58 +08:00
|
|
|
|
self.executeFinished.emit(self.id)
|
|
|
|
|
|
self.quit()
|
|
|
|
|
|
# currentInstruction.deleteLater()
|
|
|
|
|
|
# currentInstruction = None
|
|
|
|
|
|
# gc.collect() # 手动触发垃圾回收
|
|
|
|
|
|
# snapshot = tracemalloc.take_snapshot()
|
|
|
|
|
|
|
|
|
|
|
|
# # 打印内存分配的前10条统计信息
|
|
|
|
|
|
# top_stats = snapshot.statistics('lineno')
|
|
|
|
|
|
# print("内存分配的前10行:")
|
|
|
|
|
|
# for stat in top_stats[:10]:
|
|
|
|
|
|
# print(stat)
|
|
|
|
|
|
|
|
|
|
|
|
def onLogMsg(self, data):
|
|
|
|
|
|
logManager.addLogMsg(data)
|
|
|
|
|
|
|
|
|
|
|
|
# 执行指令或者队列
|
|
|
|
|
|
def execute(self, target, taskInfo = {}):
|
|
|
|
|
|
if self.isRunning():
|
|
|
|
|
|
return False
|
|
|
|
|
|
self.running = True
|
|
|
|
|
|
|
|
|
|
|
|
if isinstance(target, list): #队列
|
|
|
|
|
|
self.instructionList = target
|
|
|
|
|
|
self.taskInfo = taskInfo
|
|
|
|
|
|
self.type = taskInfo.get("type", TaskActuator.TASK)
|
|
|
|
|
|
self.name = taskInfo.get("name", TaskActuator.TASK)
|
|
|
|
|
|
self.start()
|
|
|
|
|
|
return True
|
|
|
|
|
|
elif isinstance(target, dict): #指令
|
|
|
|
|
|
self.instructionList = []
|
|
|
|
|
|
self.name = target["instructionInfo"]["name"]
|
|
|
|
|
|
self.instructionList.append(target)
|
|
|
|
|
|
self.type = TaskActuator.INSTRUCTION
|
|
|
|
|
|
self.start()
|
|
|
|
|
|
return True
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def stopSub(self):
|
|
|
|
|
|
self.running_lock.lock()
|
|
|
|
|
|
self.running = False
|
|
|
|
|
|
self.running_lock.unlock()
|
|
|
|
|
|
# 停止子任务
|
|
|
|
|
|
if self.subTaskActuator and self.subTaskActuator.isRunning():
|
|
|
|
|
|
self.subTaskActuator.stopSub()
|
|
|
|
|
|
self.updateDetails.emit(str(self.parentId) , -1, -1)
|
|
|
|
|
|
|
|
|
|
|
|
self.quit()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def stop(self):
|
|
|
|
|
|
self.running_lock.lock()
|
|
|
|
|
|
self.running = False
|
|
|
|
|
|
self.running_lock.unlock()
|
|
|
|
|
|
# 停止子任务
|
|
|
|
|
|
if self.subTaskActuator and self.subTaskActuator.isRunning():
|
|
|
|
|
|
self.subTaskActuator.stopSub()
|
|
|
|
|
|
self.quit()
|
2026-04-17 15:31:41 +08:00
|
|
|
|
|
|
|
|
|
|
def forceStop(self):
|
|
|
|
|
|
"""强制立即停止任务(非阻塞)"""
|
|
|
|
|
|
# 1. 立即设置停止标志
|
|
|
|
|
|
self.running_lock.lock()
|
|
|
|
|
|
self.running = False
|
|
|
|
|
|
self.running_lock.unlock()
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 停止子任务
|
|
|
|
|
|
if self.subTaskActuator and self.subTaskActuator.isRunning():
|
|
|
|
|
|
self.subTaskActuator.forceStop()
|
|
|
|
|
|
|
|
|
|
|
|
# 3. 终止当前指令的执行
|
|
|
|
|
|
if self.currentTask and hasattr(self.currentTask, 'isFinished'):
|
|
|
|
|
|
self.currentTask.isFinished = True
|
|
|
|
|
|
|
|
|
|
|
|
# 4. 强制终止线程(不等待)
|
|
|
|
|
|
if self.isRunning():
|
|
|
|
|
|
self.terminate()
|
|
|
|
|
|
|
|
|
|
|
|
# 5. 发送停止信号
|
|
|
|
|
|
self.updateDetails.emit(self.id, -1, -1)
|
|
|
|
|
|
self.taskStop.emit(self.id)
|
|
|
|
|
|
|
|
|
|
|
|
log.info(f"任务 {self.id} 已强制停止")
|
2026-03-02 14:29:58 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defaultTaskActuator = TaskActuator("defaultTaskActuator")
|