8 changed files with 799 additions and 472 deletions
-
400src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java
-
278src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java
-
260src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java
-
302src/main/java/a8k/service/app/appctrl/mainflowctrl/actionv2/SEQ5_PROCESS.java
-
4src/main/java/a8k/service/app/appstate/type/Tube.java
-
15src/main/java/a8k/type/exception/ZAppInterruptException.java
-
1src/main/java/a8k/utils/ActionParallerExceutor.java
-
11src/main/java/a8k/utils/ZFnCall.java
@ -1,200 +1,200 @@ |
|||
package a8k.service.app.appctrl.mainflowctrl.action; |
|||
|
|||
import a8k.OS; |
|||
import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; |
|||
|
|||
import a8k.service.app.appstate.type.ProjProcessContext; |
|||
import a8k.service.app.appstate.type.TubeHolder; |
|||
import a8k.service.app.devicectrl.ctrlservice.*; |
|||
import a8k.service.app.devicectrl.script.DeviceCtrlScripter; |
|||
import a8k.type.IncubatorPos; |
|||
import a8k.type.type.A8kTubeHolderType; |
|||
import a8k.utils.*; |
|||
import a8k.service.app.appctrl.mainflowctrl.base.A8kActionStepType; |
|||
import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; |
|||
import a8k.service.app.appstate.*; |
|||
import a8k.service.app.appstate.resource.A8kPublicResourceType; |
|||
import a8k.service.app.appstate.type.Tube; |
|||
import a8k.type.ecode.AppError; |
|||
import a8k.type.exception.AppException; |
|||
import jakarta.annotation.PostConstruct; |
|||
import jakarta.annotation.Resource; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.List; |
|||
import java.util.Objects; |
|||
import java.util.concurrent.*; |
|||
|
|||
import a8k.service.test.state.TestModeState; |
|||
import a8k.service.test.state.VirtualDevice; |
|||
import org.springframework.util.Assert; |
|||
|
|||
/** |
|||
* |
|||
* |
|||
* 处理前的准备工作 |
|||
* 1.取试管到摇匀位,并摇匀完成(全血试管) |
|||
* 2.取tip头 |
|||
* 3.孵育盘取反应板夹 |
|||
* |
|||
*/ |
|||
public class SEQ4_PRE_PROCESS extends A8kStepAction { |
|||
static Logger logger = LoggerFactory.getLogger(SEQ4_PRE_PROCESS.class); |
|||
|
|||
SEQ4_PRE_PROCESS() { |
|||
super(A8kActionStepType.SEQ4_PRE_PROCESS); |
|||
} |
|||
|
|||
@Resource |
|||
GStateService gstate; |
|||
@Resource |
|||
TestModeState testModeState; |
|||
@Resource |
|||
VirtualDevice virtualDevice; |
|||
|
|||
@Resource |
|||
AppExceptionBuilder ebuilder; |
|||
@Resource |
|||
ProjectProcessContextMgrService projectProcessContextMgrService; |
|||
|
|||
@Resource |
|||
PlateBoxCtrlService plateBoxCtrlService; |
|||
@Resource |
|||
TubePreProcesCtrlService tubePreProcesCtrlService; |
|||
@Resource |
|||
PipetteGunCtrlService pipetteGunCtrlService; |
|||
@Resource |
|||
DeviceCtrlScripter deviceCtrlScripter; |
|||
|
|||
@Resource |
|||
CondtionMgrService cms; |
|||
|
|||
// ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); |
|||
|
|||
ActionParallerExceutor actionParallerExceutor = new ActionParallerExceutor(); |
|||
|
|||
|
|||
@PostConstruct |
|||
void init() { |
|||
} |
|||
|
|||
/** |
|||
* 推出反应板夹到孵育盘 |
|||
* @throws AppException 异常 |
|||
*/ |
|||
void prepareReactionPlate() throws AppException { |
|||
if (virtualDevice.isEnable()) { |
|||
virtualDevice.doVirtualThings("准备反应板夹", 2); |
|||
return; |
|||
} |
|||
Tube tube = gstate.getCurProcessingTube(); |
|||
List<ProjProcessContext> cxts = projectProcessContextMgrService.getTubeAssociatedProjContext(tube.getSampleId()); |
|||
|
|||
for (ProjProcessContext cxt : cxts) { |
|||
IncubatorPos incubatorPos = cxt.incubatorPos; |
|||
plateBoxCtrlService.pushPlateQuick(cxt.consumable.getGroup(), incubatorPos); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 取试管,摇匀,取帽 |
|||
* @throws AppException 异常 |
|||
*/ |
|||
void shakeAndTakeCap() throws AppException { |
|||
if (virtualDevice.isEnable()) { |
|||
virtualDevice.doVirtualThings("摇匀并取盖", 2); |
|||
return; |
|||
} |
|||
|
|||
Tube tube = gstate.getCurProcessingTube(); |
|||
TubeHolder tubeHolder = gstate.getTubeHolder(); |
|||
Boolean isHighTube = tube.getIsHighTube(); |
|||
|
|||
if (!tube.getIsEmergency() && tubeHolder.tubeHolderType.equals(A8kTubeHolderType.BloodTube)) { |
|||
Integer shakeTimes = ProjProcessContextUtils.getShakeTimes(tube); |
|||
logger.info("摇匀次数 :{}", shakeTimes); |
|||
logger.info("试管架类型 :{}", tubeHolder.tubeHolderType); |
|||
logger.info("是否高位试管:{}", isHighTube); |
|||
tubePreProcesCtrlService.takeTubeFromTubeholderToShakePos(isHighTube); |
|||
tubePreProcesCtrlService.shakeTube(45, shakeTimes); |
|||
tubePreProcesCtrlService.takeTubeCap(); |
|||
} else { |
|||
logger.info("不是全血试管,不需要摇匀"); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 取一个tip头 |
|||
* @throws AppException exception |
|||
*/ |
|||
void hbotPrepareTip() throws AppException { |
|||
if (virtualDevice.isEnable()) { |
|||
virtualDevice.doVirtualThings("准备Hbot Tip", 2); |
|||
return; |
|||
} |
|||
//准备第一个项目的tip头 |
|||
List<ProjProcessContext> cxts = projectProcessContextMgrService.getTubeAssociatedProjContext(gstate.getCurProcessingTube().getSampleId()); |
|||
Assert.isTrue(!cxts.isEmpty(), "项目上下文不能为空"); |
|||
ProjProcessContext cxt = cxts.get(0); |
|||
/* |
|||
* 此处预先做好第一个项目的准备工作 |
|||
*/ |
|||
deviceCtrlScripter.doSampleProcessPrepare(cxt); |
|||
} |
|||
|
|||
|
|||
@Override public void doaction() throws AppException { |
|||
// |
|||
// 1.准备3份反应板夹 |
|||
// 2.取tip头 |
|||
// 3.摇匀,脱帽 |
|||
// |
|||
projectProcessContextMgrService.startTubePreProcessing(); |
|||
|
|||
actionParallerExceutor.submit(this::prepareReactionPlate); |
|||
actionParallerExceutor.submit(this::shakeAndTakeCap); |
|||
actionParallerExceutor.submit(this::hbotPrepareTip); |
|||
|
|||
var mutiAppException = actionParallerExceutor.waitAll(); |
|||
|
|||
//如果依然有错误,将试管状态设置为错误,同时抛出异常 |
|||
if (mutiAppException != null) { |
|||
projectProcessContextMgrService.changeTubeStateToError(gstate.getCurProcessingTube(), mutiAppException.getErrors()); |
|||
throw mutiAppException; |
|||
} |
|||
projectProcessContextMgrService.tubePreProcessingOK(); |
|||
} |
|||
|
|||
|
|||
@Override public Boolean checkCondition() { |
|||
return cms.isTimeToPreProcessTube(); |
|||
} |
|||
|
|||
@Override public List<A8kPublicResourceType> getResourceList() { |
|||
return List.of( |
|||
A8kPublicResourceType.IncubationPlateModule, |
|||
A8kPublicResourceType.PlatesBoxModule, |
|||
A8kPublicResourceType.HBOT, |
|||
A8kPublicResourceType.CurTubeProcessToken |
|||
); |
|||
} |
|||
// |
|||
// UTILS |
|||
// |
|||
|
|||
void wait(Future<?> future) { |
|||
while (!future.isDone()) { |
|||
OS.forceSleep(100); |
|||
} |
|||
} |
|||
|
|||
@Override public String logCxtState() { |
|||
var tube = gstate.getCurProcessingTube(); |
|||
if (tube == null) { |
|||
return ""; |
|||
} |
|||
return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList()); |
|||
} |
|||
} |
|||
//package a8k.service.app.appctrl.mainflowctrl.action; |
|||
// |
|||
//import a8k.OS; |
|||
//import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; |
|||
// |
|||
//import a8k.service.app.appstate.type.ProjProcessContext; |
|||
//import a8k.service.app.appstate.type.TubeHolder; |
|||
//import a8k.service.app.devicectrl.ctrlservice.*; |
|||
//import a8k.service.app.devicectrl.script.DeviceCtrlScripter; |
|||
//import a8k.type.IncubatorPos; |
|||
//import a8k.type.type.A8kTubeHolderType; |
|||
//import a8k.utils.*; |
|||
//import a8k.service.app.appctrl.mainflowctrl.base.A8kActionStepType; |
|||
//import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; |
|||
//import a8k.service.app.appstate.*; |
|||
//import a8k.service.app.appstate.resource.A8kPublicResourceType; |
|||
//import a8k.service.app.appstate.type.Tube; |
|||
//import a8k.type.ecode.AppError; |
|||
//import a8k.type.exception.AppException; |
|||
//import jakarta.annotation.PostConstruct; |
|||
//import jakarta.annotation.Resource; |
|||
//import org.slf4j.Logger; |
|||
//import org.slf4j.LoggerFactory; |
|||
//import org.springframework.stereotype.Component; |
|||
// |
|||
//import java.util.List; |
|||
//import java.util.Objects; |
|||
//import java.util.concurrent.*; |
|||
// |
|||
//import a8k.service.test.state.TestModeState; |
|||
//import a8k.service.test.state.VirtualDevice; |
|||
//import org.springframework.util.Assert; |
|||
// |
|||
///** |
|||
// * |
|||
// * |
|||
// * 处理前的准备工作 |
|||
// * 1.取试管到摇匀位,并摇匀完成(全血试管) |
|||
// * 2.取tip头 |
|||
// * 3.孵育盘取反应板夹 |
|||
// * |
|||
// */ |
|||
//public class SEQ4_PRE_PROCESS extends A8kStepAction { |
|||
// static Logger logger = LoggerFactory.getLogger(SEQ4_PRE_PROCESS.class); |
|||
// |
|||
// SEQ4_PRE_PROCESS() { |
|||
// super(A8kActionStepType.SEQ4_PRE_PROCESS); |
|||
// } |
|||
// |
|||
// @Resource |
|||
// GStateService gstate; |
|||
// @Resource |
|||
// TestModeState testModeState; |
|||
// @Resource |
|||
// VirtualDevice virtualDevice; |
|||
// |
|||
// @Resource |
|||
// AppExceptionBuilder ebuilder; |
|||
// @Resource |
|||
// ProjectProcessContextMgrService projectProcessContextMgrService; |
|||
// |
|||
// @Resource |
|||
// PlateBoxCtrlService plateBoxCtrlService; |
|||
// @Resource |
|||
// TubePreProcesCtrlService tubePreProcesCtrlService; |
|||
// @Resource |
|||
// PipetteGunCtrlService pipetteGunCtrlService; |
|||
// @Resource |
|||
// DeviceCtrlScripter deviceCtrlScripter; |
|||
// |
|||
// @Resource |
|||
// CondtionMgrService cms; |
|||
// |
|||
// // ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); |
|||
// |
|||
// ActionParallerExceutor actionParallerExceutor = new ActionParallerExceutor(); |
|||
// |
|||
// |
|||
// @PostConstruct |
|||
// void init() { |
|||
// } |
|||
// |
|||
// /** |
|||
// * 推出反应板夹到孵育盘 |
|||
// * @throws AppException 异常 |
|||
// */ |
|||
// void prepareReactionPlate() throws AppException { |
|||
// if (virtualDevice.isEnable()) { |
|||
// virtualDevice.doVirtualThings("准备反应板夹", 2); |
|||
// return; |
|||
// } |
|||
// Tube tube = gstate.getCurProcessingTube(); |
|||
// List<ProjProcessContext> cxts = projectProcessContextMgrService.getTubeAssociatedProjContext(tube.getSampleId()); |
|||
// |
|||
// for (ProjProcessContext cxt : cxts) { |
|||
// IncubatorPos incubatorPos = cxt.incubatorPos; |
|||
// plateBoxCtrlService.pushPlateQuick(cxt.consumable.getGroup(), incubatorPos); |
|||
// } |
|||
// } |
|||
// |
|||
// /** |
|||
// * 取试管,摇匀,取帽 |
|||
// * @throws AppException 异常 |
|||
// */ |
|||
// void shakeAndTakeCap() throws AppException { |
|||
// if (virtualDevice.isEnable()) { |
|||
// virtualDevice.doVirtualThings("摇匀并取盖", 2); |
|||
// return; |
|||
// } |
|||
// |
|||
// Tube tube = gstate.getCurProcessingTube(); |
|||
// TubeHolder tubeHolder = gstate.getTubeHolder(); |
|||
// Boolean isHighTube = tube.getIsHighTube(); |
|||
// |
|||
// if (!tube.getIsEmergency() && tubeHolder.tubeHolderType.equals(A8kTubeHolderType.BloodTube)) { |
|||
// Integer shakeTimes = ProjProcessContextUtils.getShakeTimes(tube); |
|||
// logger.info("摇匀次数 :{}", shakeTimes); |
|||
// logger.info("试管架类型 :{}", tubeHolder.tubeHolderType); |
|||
// logger.info("是否高位试管:{}", isHighTube); |
|||
// tubePreProcesCtrlService.takeTubeFromTubeholderToShakePos(isHighTube); |
|||
// tubePreProcesCtrlService.shakeTube(45, shakeTimes); |
|||
// tubePreProcesCtrlService.takeTubeCap(); |
|||
// } else { |
|||
// logger.info("不是全血试管,不需要摇匀"); |
|||
// } |
|||
// } |
|||
// |
|||
// /** |
|||
// * 取一个tip头 |
|||
// * @throws AppException exception |
|||
// */ |
|||
// void hbotPrepareTip() throws AppException { |
|||
// if (virtualDevice.isEnable()) { |
|||
// virtualDevice.doVirtualThings("准备Hbot Tip", 2); |
|||
// return; |
|||
// } |
|||
// //准备第一个项目的tip头 |
|||
// List<ProjProcessContext> cxts = projectProcessContextMgrService.getTubeAssociatedProjContext(gstate.getCurProcessingTube().getSampleId()); |
|||
// Assert.isTrue(!cxts.isEmpty(), "项目上下文不能为空"); |
|||
// ProjProcessContext cxt = cxts.get(0); |
|||
// /* |
|||
// * 此处预先做好第一个项目的准备工作 |
|||
// */ |
|||
// deviceCtrlScripter.doSampleProcessPrepare(cxt); |
|||
// } |
|||
// |
|||
// |
|||
// @Override public void doaction() throws AppException { |
|||
// // |
|||
// // 1.准备3份反应板夹 |
|||
// // 2.取tip头 |
|||
// // 3.摇匀,脱帽 |
|||
// // |
|||
// projectProcessContextMgrService.startTubePreProcessing(); |
|||
// |
|||
// actionParallerExceutor.submit(this::prepareReactionPlate); |
|||
// actionParallerExceutor.submit(this::shakeAndTakeCap); |
|||
// actionParallerExceutor.submit(this::hbotPrepareTip); |
|||
// |
|||
// var mutiAppException = actionParallerExceutor.waitAll(); |
|||
// |
|||
// //如果依然有错误,将试管状态设置为错误,同时抛出异常 |
|||
// if (mutiAppException != null) { |
|||
// projectProcessContextMgrService.changeTubeStateToError(gstate.getCurProcessingTube(), mutiAppException.getErrors()); |
|||
// throw mutiAppException; |
|||
// } |
|||
// projectProcessContextMgrService.tubePreProcessingOK(); |
|||
// } |
|||
// |
|||
// |
|||
// @Override public Boolean checkCondition() { |
|||
// return cms.isTimeToPreProcessTube(); |
|||
// } |
|||
// |
|||
// @Override public List<A8kPublicResourceType> getResourceList() { |
|||
// return List.of( |
|||
// A8kPublicResourceType.IncubationPlateModule, |
|||
// A8kPublicResourceType.PlatesBoxModule, |
|||
// A8kPublicResourceType.HBOT, |
|||
// A8kPublicResourceType.CurTubeProcessToken |
|||
// ); |
|||
// } |
|||
// // |
|||
// // UTILS |
|||
// // |
|||
// |
|||
// void wait(Future<?> future) { |
|||
// while (!future.isDone()) { |
|||
// OS.forceSleep(100); |
|||
// } |
|||
// } |
|||
// |
|||
// @Override public String logCxtState() { |
|||
// var tube = gstate.getCurProcessingTube(); |
|||
// if (tube == null) { |
|||
// return ""; |
|||
// } |
|||
// return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList()); |
|||
// } |
|||
//} |
@ -1,139 +1,139 @@ |
|||
package a8k.service.app.appctrl.mainflowctrl.action; |
|||
|
|||
import a8k.service.app.devicectrl.ctrlservice.PipetteGunCtrlService; |
|||
import a8k.service.app.devicectrl.script.DeviceCtrlScripter; |
|||
import a8k.service.dao.type.a8kidcard.zenum.A8kReactionFlowType; |
|||
import a8k.utils.AppExceptionBuilder; |
|||
import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; |
|||
import a8k.service.app.appctrl.mainflowctrl.base.A8kActionStepType; |
|||
import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; |
|||
import a8k.service.app.appstate.*; |
|||
import a8k.service.app.appstate.resource.A8kPublicResourceType; |
|||
import a8k.service.app.appstate.type.DeviceWorkState; |
|||
import a8k.service.app.appstate.type.ProjProcessContext; |
|||
import a8k.type.exception.AppException; |
|||
import jakarta.annotation.PostConstruct; |
|||
import jakarta.annotation.Resource; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.List; |
|||
|
|||
import a8k.service.test.state.TestModeState; |
|||
import a8k.service.test.state.VirtualDevice; |
|||
|
|||
/** |
|||
* |
|||
* 核对物料资源是否足够 |
|||
* TUBE |
|||
* TO_BE_PROCESSED --> PRE_PROCESSING |
|||
*/ |
|||
public class SEQ5_PROCESS extends A8kStepAction { |
|||
static Logger logger = LoggerFactory.getLogger(SEQ5_PROCESS.class); |
|||
|
|||
SEQ5_PROCESS() { |
|||
super(A8kActionStepType.SEQ5_PROCESS); |
|||
} |
|||
|
|||
@Resource |
|||
GStateService gstate; |
|||
@Resource |
|||
TestModeState testModeState; |
|||
@Resource |
|||
VirtualDevice virtualDevice; |
|||
|
|||
|
|||
@Resource |
|||
AppExceptionBuilder ebuilder; |
|||
@Resource |
|||
IncubationPlateStateMgrService incubationPlateStateMgrService; |
|||
@Resource |
|||
CondtionMgrService cms; |
|||
@Resource |
|||
ProjectProcessContextMgrService projectProcessContextMgrService; |
|||
|
|||
@Resource |
|||
PipetteGunCtrlService pipetteGunCtrlService; |
|||
@Resource |
|||
DeviceCtrlScripter deviceCtrlScripter; |
|||
|
|||
DeviceWorkState state; |
|||
|
|||
@PostConstruct |
|||
void init() { |
|||
state = gstate.deviceWorkState; |
|||
} |
|||
|
|||
|
|||
void doAction() throws AppException { |
|||
var tube = gstate.getCurProcessingTube(); |
|||
Integer projProcessOff = tube.getProjProcessOff(); |
|||
ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(), tube.getProjIds().get(projProcessOff)); |
|||
A8kReactionFlowType type = cxt.projInfoContext.projInfo.reactionFlowType; |
|||
|
|||
if (virtualDevice.isEnable()) { |
|||
virtualDevice.doVirtualThings("处理样本(准备反应板,取tip,摇匀,脱帽)", 5); |
|||
return; |
|||
} |
|||
|
|||
if (projProcessOff != 0) { //第一个项目的部分动作已经在前面完成 |
|||
deviceCtrlScripter.doSampleProcessPrepare(cxt); |
|||
} |
|||
|
|||
deviceCtrlScripter.doSampleProcess(cxt); |
|||
|
|||
if (projProcessOff + 1 != tube.getProjIds().size()) { |
|||
deviceCtrlScripter.doSampleProcessPostProcess(cxt); |
|||
} |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public void doaction() throws AppException { |
|||
|
|||
var tube = gstate.getCurProcessingTube(); |
|||
Integer projProcessOff = tube.getProjProcessOff(); |
|||
logger.info("处理 样本:{} 第X个项目:{}", tube.getSampleId(), projProcessOff); |
|||
ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(), tube.getProjIds().get(projProcessOff)); |
|||
|
|||
if (projProcessOff == 0) { |
|||
projectProcessContextMgrService.startProcessTube(); |
|||
} |
|||
|
|||
// |
|||
// 执行待执行的动作 |
|||
// |
|||
doAction(); |
|||
|
|||
projectProcessContextMgrService.startIncubating(cxt); |
|||
if (projProcessOff + 1 < tube.getProjIds().size()) { |
|||
tube.setProjProcessOff(projProcessOff + 1); |
|||
} else { |
|||
projectProcessContextMgrService.processIngTubeOK(); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public Boolean checkCondition() { |
|||
return cms.isTimeToProcessTube(); |
|||
} |
|||
|
|||
@Override |
|||
public List<A8kPublicResourceType> getResourceList() { |
|||
return List.of( |
|||
A8kPublicResourceType.IncubationPlateModule, |
|||
A8kPublicResourceType.HBOT, |
|||
A8kPublicResourceType.CurTubeProcessToken); |
|||
} |
|||
|
|||
|
|||
@Override |
|||
public String logCxtState() { |
|||
var tube = gstate.getCurProcessingTube(); |
|||
if (tube == null) { |
|||
return ""; |
|||
} |
|||
return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList()); |
|||
} |
|||
} |
|||
//package a8k.service.app.appctrl.mainflowctrl.action; |
|||
// |
|||
//import a8k.service.app.devicectrl.ctrlservice.PipetteGunCtrlService; |
|||
//import a8k.service.app.devicectrl.script.DeviceCtrlScripter; |
|||
//import a8k.service.dao.type.a8kidcard.zenum.A8kReactionFlowType; |
|||
//import a8k.utils.AppExceptionBuilder; |
|||
//import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; |
|||
//import a8k.service.app.appctrl.mainflowctrl.base.A8kActionStepType; |
|||
//import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; |
|||
//import a8k.service.app.appstate.*; |
|||
//import a8k.service.app.appstate.resource.A8kPublicResourceType; |
|||
//import a8k.service.app.appstate.type.DeviceWorkState; |
|||
//import a8k.service.app.appstate.type.ProjProcessContext; |
|||
//import a8k.type.exception.AppException; |
|||
//import jakarta.annotation.PostConstruct; |
|||
//import jakarta.annotation.Resource; |
|||
//import org.slf4j.Logger; |
|||
//import org.slf4j.LoggerFactory; |
|||
//import org.springframework.stereotype.Component; |
|||
// |
|||
//import java.util.List; |
|||
// |
|||
//import a8k.service.test.state.TestModeState; |
|||
//import a8k.service.test.state.VirtualDevice; |
|||
// |
|||
///** |
|||
// * |
|||
// * 核对物料资源是否足够 |
|||
// * TUBE |
|||
// * TO_BE_PROCESSED --> PRE_PROCESSING |
|||
// */ |
|||
//public class SEQ5_PROCESS extends A8kStepAction { |
|||
// static Logger logger = LoggerFactory.getLogger(SEQ5_PROCESS.class); |
|||
// |
|||
// SEQ5_PROCESS() { |
|||
// super(A8kActionStepType.SEQ5_PROCESS); |
|||
// } |
|||
// |
|||
// @Resource |
|||
// GStateService gstate; |
|||
// @Resource |
|||
// TestModeState testModeState; |
|||
// @Resource |
|||
// VirtualDevice virtualDevice; |
|||
// |
|||
// |
|||
// @Resource |
|||
// AppExceptionBuilder ebuilder; |
|||
// @Resource |
|||
// IncubationPlateStateMgrService incubationPlateStateMgrService; |
|||
// @Resource |
|||
// CondtionMgrService cms; |
|||
// @Resource |
|||
// ProjectProcessContextMgrService projectProcessContextMgrService; |
|||
// |
|||
// @Resource |
|||
// PipetteGunCtrlService pipetteGunCtrlService; |
|||
// @Resource |
|||
// DeviceCtrlScripter deviceCtrlScripter; |
|||
// |
|||
// DeviceWorkState state; |
|||
// |
|||
// @PostConstruct |
|||
// void init() { |
|||
// state = gstate.deviceWorkState; |
|||
// } |
|||
// |
|||
// |
|||
// void doAction() throws AppException { |
|||
// var tube = gstate.getCurProcessingTube(); |
|||
//// Integer projProcessOff = tube.getProjProcessOff(); |
|||
// ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(), tube.getProjIds().get(projProcessOff)); |
|||
// A8kReactionFlowType type = cxt.projInfoContext.projInfo.reactionFlowType; |
|||
// |
|||
// if (virtualDevice.isEnable()) { |
|||
// virtualDevice.doVirtualThings("处理样本(准备反应板,取tip,摇匀,脱帽)", 5); |
|||
// return; |
|||
// } |
|||
// |
|||
// if (projProcessOff != 0) { //第一个项目的部分动作已经在前面完成 |
|||
// deviceCtrlScripter.doSampleProcessPrepare(cxt); |
|||
// } |
|||
// |
|||
// deviceCtrlScripter.doSampleProcess(cxt); |
|||
// |
|||
// if (projProcessOff + 1 != tube.getProjIds().size()) { |
|||
// deviceCtrlScripter.doSampleProcessPostProcess(cxt); |
|||
// } |
|||
// |
|||
// } |
|||
// |
|||
// @Override |
|||
// public void doaction() throws AppException { |
|||
// |
|||
// var tube = gstate.getCurProcessingTube(); |
|||
// Integer projProcessOff = tube.getProjProcessOff(); |
|||
// logger.info("处理 样本:{} 第X个项目:{}", tube.getSampleId(), projProcessOff); |
|||
// ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(), tube.getProjIds().get(projProcessOff)); |
|||
// |
|||
// if (projProcessOff == 0) { |
|||
// projectProcessContextMgrService.startProcessTube(); |
|||
// } |
|||
// |
|||
// // |
|||
// // 执行待执行的动作 |
|||
// // |
|||
// doAction(); |
|||
// |
|||
// projectProcessContextMgrService.startIncubating(cxt); |
|||
// if (projProcessOff + 1 < tube.getProjIds().size()) { |
|||
// tube.setProjProcessOff(projProcessOff + 1); |
|||
// } else { |
|||
// projectProcessContextMgrService.processIngTubeOK(); |
|||
// } |
|||
// } |
|||
// |
|||
// @Override |
|||
// public Boolean checkCondition() { |
|||
// return cms.isTimeToProcessTube(); |
|||
// } |
|||
// |
|||
// @Override |
|||
// public List<A8kPublicResourceType> getResourceList() { |
|||
// return List.of( |
|||
// A8kPublicResourceType.IncubationPlateModule, |
|||
// A8kPublicResourceType.HBOT, |
|||
// A8kPublicResourceType.CurTubeProcessToken); |
|||
// } |
|||
// |
|||
// |
|||
// @Override |
|||
// public String logCxtState() { |
|||
// var tube = gstate.getCurProcessingTube(); |
|||
// if (tube == null) { |
|||
// return ""; |
|||
// } |
|||
// return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList()); |
|||
// } |
|||
//} |
@ -1,130 +1,130 @@ |
|||
package a8k.service.app.appctrl.mainflowctrl.action; |
|||
|
|||
import a8k.service.app.appstate.type.ProjProcessContext; |
|||
import a8k.service.app.devicectrl.ctrlservice.PipetteGunCtrlService; |
|||
import a8k.service.app.devicectrl.ctrlservice.TubePreProcesCtrlService; |
|||
import a8k.service.app.devicectrl.driver.PipetteCtrlDriver; |
|||
import a8k.service.app.devicectrl.script.DeviceCtrlScripter; |
|||
import a8k.utils.ActionParallerExceutor; |
|||
import a8k.utils.AppExceptionBuilder; |
|||
import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; |
|||
import a8k.service.app.appctrl.mainflowctrl.base.A8kActionStepType; |
|||
import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; |
|||
import a8k.service.app.appstate.*; |
|||
import a8k.service.app.appstate.resource.A8kPublicResourceType; |
|||
import a8k.service.app.appstate.type.DeviceWorkState; |
|||
import a8k.type.exception.AppException; |
|||
import jakarta.annotation.PostConstruct; |
|||
import jakarta.annotation.Resource; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.List; |
|||
import java.util.concurrent.*; |
|||
|
|||
import a8k.service.test.state.TestModeState; |
|||
import a8k.service.test.state.VirtualDevice; |
|||
|
|||
/** |
|||
* |
|||
* 核对物料资源是否足够 |
|||
* TUBE |
|||
* TO_BE_PROCESSED --> PRE_PROCESSING |
|||
*/ |
|||
public class SEQ6_POST_PROCESS extends A8kStepAction { |
|||
static Logger logger = LoggerFactory.getLogger(SEQ6_POST_PROCESS.class); |
|||
|
|||
SEQ6_POST_PROCESS() { |
|||
super(A8kActionStepType.SEQ6_POST_PROCESS); |
|||
} |
|||
|
|||
@Resource |
|||
GStateService gstate; |
|||
@Resource |
|||
TestModeState testModeState; |
|||
@Resource |
|||
VirtualDevice virtualDevice; |
|||
@Resource |
|||
PipetteCtrlDriver pipetteCtrlDriver; |
|||
|
|||
@Resource |
|||
AppExceptionBuilder ebuilder; |
|||
|
|||
@Resource |
|||
TubePreProcesCtrlService tubePreProcesCtrlService; |
|||
|
|||
@Resource |
|||
ProjectProcessContextMgrService projectProcessContextMgrService; |
|||
@Resource |
|||
CondtionMgrService cms; |
|||
@Resource |
|||
DeviceCtrlScripter deviceCtrlScripter; |
|||
|
|||
|
|||
ActionParallerExceutor actionParallerExceutor = new ActionParallerExceutor(); |
|||
|
|||
|
|||
DeviceWorkState state; |
|||
|
|||
@PostConstruct |
|||
void init() { |
|||
state = gstate.deviceWorkState; |
|||
} |
|||
|
|||
|
|||
void tubePostProcess() throws AppException { |
|||
var tube = gstate.getCurProcessingTube(); |
|||
Integer projProcessOff = tube.getProjProcessOff(); |
|||
ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(), tube.getProjIds().get(projProcessOff)); |
|||
deviceCtrlScripter.doSampleProcessPostProcess(cxt); |
|||
} |
|||
|
|||
void doAction() throws AppException { |
|||
if (virtualDevice.isEnable()) { |
|||
virtualDevice.doVirtualThings("后处理样本", 3); |
|||
} |
|||
|
|||
actionParallerExceutor.submit(this::tubePostProcess); |
|||
actionParallerExceutor.submit(() -> tubePreProcesCtrlService.resteModule()); |
|||
|
|||
var mutiAppException = actionParallerExceutor.waitAll(); |
|||
|
|||
if (mutiAppException != null) { |
|||
projectProcessContextMgrService.changeTubeStateToError(gstate.getCurProcessingTube(), mutiAppException.getErrors()); |
|||
throw mutiAppException; |
|||
} |
|||
|
|||
} |
|||
|
|||
@Override public void doaction() throws AppException { |
|||
projectProcessContextMgrService.postProcessTube(); |
|||
doAction(); |
|||
projectProcessContextMgrService.postProcessTubeOK(); |
|||
} |
|||
|
|||
@Override public Boolean checkCondition() { |
|||
return cms.isTimeToPostProcessTube(); |
|||
} |
|||
|
|||
@Override public List<A8kPublicResourceType> getResourceList() { |
|||
return List.of( |
|||
A8kPublicResourceType.PlatesBoxModule, |
|||
A8kPublicResourceType.HBOT, |
|||
A8kPublicResourceType.IncubationPlateModule, |
|||
A8kPublicResourceType.CurTubeProcessToken |
|||
); |
|||
} |
|||
|
|||
// |
|||
// UTILS |
|||
// |
|||
|
|||
@Override public String logCxtState() { |
|||
var tube = gstate.getCurProcessingTube(); |
|||
if (tube == null) { |
|||
return ""; |
|||
} |
|||
return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList()); |
|||
} |
|||
} |
|||
//package a8k.service.app.appctrl.mainflowctrl.action; |
|||
// |
|||
//import a8k.service.app.appstate.type.ProjProcessContext; |
|||
//import a8k.service.app.devicectrl.ctrlservice.PipetteGunCtrlService; |
|||
//import a8k.service.app.devicectrl.ctrlservice.TubePreProcesCtrlService; |
|||
//import a8k.service.app.devicectrl.driver.PipetteCtrlDriver; |
|||
//import a8k.service.app.devicectrl.script.DeviceCtrlScripter; |
|||
//import a8k.utils.ActionParallerExceutor; |
|||
//import a8k.utils.AppExceptionBuilder; |
|||
//import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; |
|||
//import a8k.service.app.appctrl.mainflowctrl.base.A8kActionStepType; |
|||
//import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; |
|||
//import a8k.service.app.appstate.*; |
|||
//import a8k.service.app.appstate.resource.A8kPublicResourceType; |
|||
//import a8k.service.app.appstate.type.DeviceWorkState; |
|||
//import a8k.type.exception.AppException; |
|||
//import jakarta.annotation.PostConstruct; |
|||
//import jakarta.annotation.Resource; |
|||
//import org.slf4j.Logger; |
|||
//import org.slf4j.LoggerFactory; |
|||
//import org.springframework.stereotype.Component; |
|||
// |
|||
//import java.util.List; |
|||
//import java.util.concurrent.*; |
|||
// |
|||
//import a8k.service.test.state.TestModeState; |
|||
//import a8k.service.test.state.VirtualDevice; |
|||
// |
|||
///** |
|||
// * |
|||
// * 核对物料资源是否足够 |
|||
// * TUBE |
|||
// * TO_BE_PROCESSED --> PRE_PROCESSING |
|||
// */ |
|||
//public class SEQ6_POST_PROCESS extends A8kStepAction { |
|||
// static Logger logger = LoggerFactory.getLogger(SEQ6_POST_PROCESS.class); |
|||
// |
|||
// SEQ6_POST_PROCESS() { |
|||
// super(A8kActionStepType.SEQ6_POST_PROCESS); |
|||
// } |
|||
// |
|||
// @Resource |
|||
// GStateService gstate; |
|||
// @Resource |
|||
// TestModeState testModeState; |
|||
// @Resource |
|||
// VirtualDevice virtualDevice; |
|||
// @Resource |
|||
// PipetteCtrlDriver pipetteCtrlDriver; |
|||
// |
|||
// @Resource |
|||
// AppExceptionBuilder ebuilder; |
|||
// |
|||
// @Resource |
|||
// TubePreProcesCtrlService tubePreProcesCtrlService; |
|||
// |
|||
// @Resource |
|||
// ProjectProcessContextMgrService projectProcessContextMgrService; |
|||
// @Resource |
|||
// CondtionMgrService cms; |
|||
// @Resource |
|||
// DeviceCtrlScripter deviceCtrlScripter; |
|||
// |
|||
// |
|||
// ActionParallerExceutor actionParallerExceutor = new ActionParallerExceutor(); |
|||
// |
|||
// |
|||
// DeviceWorkState state; |
|||
// |
|||
// @PostConstruct |
|||
// void init() { |
|||
// state = gstate.deviceWorkState; |
|||
// } |
|||
// |
|||
// |
|||
// void tubePostProcess() throws AppException { |
|||
// var tube = gstate.getCurProcessingTube(); |
|||
// Integer projProcessOff = tube.getProjProcessOff(); |
|||
// ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(), tube.getProjIds().get(projProcessOff)); |
|||
// deviceCtrlScripter.doSampleProcessPostProcess(cxt); |
|||
// } |
|||
// |
|||
// void doAction() throws AppException { |
|||
// if (virtualDevice.isEnable()) { |
|||
// virtualDevice.doVirtualThings("后处理样本", 3); |
|||
// } |
|||
// |
|||
// actionParallerExceutor.submit(this::tubePostProcess); |
|||
// actionParallerExceutor.submit(() -> tubePreProcesCtrlService.resteModule()); |
|||
// |
|||
// var mutiAppException = actionParallerExceutor.waitAll(); |
|||
// |
|||
// if (mutiAppException != null) { |
|||
// projectProcessContextMgrService.changeTubeStateToError(gstate.getCurProcessingTube(), mutiAppException.getErrors()); |
|||
// throw mutiAppException; |
|||
// } |
|||
// |
|||
// } |
|||
// |
|||
// @Override public void doaction() throws AppException { |
|||
// projectProcessContextMgrService.postProcessTube(); |
|||
// doAction(); |
|||
// projectProcessContextMgrService.postProcessTubeOK(); |
|||
// } |
|||
// |
|||
// @Override public Boolean checkCondition() { |
|||
// return cms.isTimeToPostProcessTube(); |
|||
// } |
|||
// |
|||
// @Override public List<A8kPublicResourceType> getResourceList() { |
|||
// return List.of( |
|||
// A8kPublicResourceType.PlatesBoxModule, |
|||
// A8kPublicResourceType.HBOT, |
|||
// A8kPublicResourceType.IncubationPlateModule, |
|||
// A8kPublicResourceType.CurTubeProcessToken |
|||
// ); |
|||
// } |
|||
// |
|||
// // |
|||
// // UTILS |
|||
// // |
|||
// |
|||
// @Override public String logCxtState() { |
|||
// var tube = gstate.getCurProcessingTube(); |
|||
// if (tube == null) { |
|||
// return ""; |
|||
// } |
|||
// return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList()); |
|||
// } |
|||
//} |
@ -0,0 +1,302 @@ |
|||
package a8k.service.app.appctrl.mainflowctrl.actionv2; |
|||
|
|||
import a8k.OS; |
|||
import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; |
|||
import a8k.service.app.appctrl.mainflowctrl.ResourceMgrServiceV2; |
|||
import a8k.service.app.appctrl.mainflowctrl.base.A8kActionStepType; |
|||
import a8k.service.app.appctrl.mainflowctrl.base.A8kStepActionV2; |
|||
import a8k.service.app.appctrl.mainflowctrl.base.MainFlowProcesser; |
|||
import a8k.service.app.appstate.GStateService; |
|||
import a8k.service.app.appstate.IncubationPlateStateMgrService; |
|||
import a8k.service.app.appstate.ProjectProcessContextMgrService; |
|||
import a8k.service.app.appstate.type.ProjProcessContext; |
|||
import a8k.service.app.appstate.type.Tube; |
|||
import a8k.service.app.appstate.type.TubeHolder; |
|||
import a8k.service.app.devicectrl.ctrlservice.PipetteGunCtrlService; |
|||
import a8k.service.app.devicectrl.ctrlservice.PlateBoxCtrlService; |
|||
import a8k.service.app.devicectrl.ctrlservice.TubePreProcesCtrlService; |
|||
import a8k.service.app.devicectrl.script.DeviceCtrlScripter; |
|||
import a8k.service.dao.type.a8kidcard.zenum.A8kReactionFlowType; |
|||
import a8k.service.test.PosMeasureUtils; |
|||
import a8k.service.test.state.TestModeState; |
|||
import a8k.service.test.state.VirtualDevice; |
|||
import a8k.type.IncubatorPos; |
|||
import a8k.type.ecode.AppError; |
|||
import a8k.type.exception.AppException; |
|||
import a8k.type.exception.ZAppInterruptException; |
|||
import a8k.type.type.A8kTubeHolderType; |
|||
import a8k.utils.AppExceptionBuilder; |
|||
import a8k.utils.ProjProcessContextUtils; |
|||
import jakarta.annotation.Resource; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.util.Assert; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.Objects; |
|||
import java.util.concurrent.*; |
|||
|
|||
@Component |
|||
@MainFlowProcesser |
|||
@Slf4j |
|||
public class SEQ5_PROCESS extends A8kStepActionV2 { |
|||
static Logger logger = LoggerFactory.getLogger(SEQ5_PROCESS.class); |
|||
@Autowired |
|||
private PosMeasureUtils posMeasureUtils; |
|||
|
|||
SEQ5_PROCESS() { |
|||
super(A8kActionStepType.PROCESS_INCUBATE_COMPLETED_PLATE); |
|||
} |
|||
|
|||
public interface Fn { |
|||
void call() throws AppException; |
|||
} |
|||
|
|||
@Resource |
|||
GStateService gstate; |
|||
@Resource |
|||
TestModeState testModeState; |
|||
@Resource |
|||
VirtualDevice virtualDevice; |
|||
|
|||
@Resource |
|||
AppExceptionBuilder ebuilder; |
|||
@Resource |
|||
IncubationPlateStateMgrService incubationPlateStateMgrService; |
|||
@Resource |
|||
CondtionMgrService cms; |
|||
@Resource |
|||
ProjectProcessContextMgrService projectProcessContextMgrService; |
|||
|
|||
@Resource |
|||
PipetteGunCtrlService pipetteGunCtrlService; |
|||
@Resource |
|||
DeviceCtrlScripter deviceCtrlScripter; |
|||
@Resource |
|||
ResourceMgrServiceV2 resourceMgrServiceV2; |
|||
@Resource |
|||
PlateBoxCtrlService plateBoxCtrlService; |
|||
@Resource |
|||
TubePreProcesCtrlService tubePreProcesCtrlService; |
|||
// |
|||
// 取试管 取反应板夹 预处理 |
|||
// 摇匀 处理 |
|||
// 脱帽 等待样本准备OK |
|||
// 待机 取反应样本 |
|||
// 等待试管处理完成 |
|||
// |
|||
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); |
|||
List<Future<AppError>> futures = new ArrayList<>(); |
|||
|
|||
|
|||
Boolean reactionPlateReady = false; |
|||
Boolean sampleIsReady = false; |
|||
Boolean sampleProcessFinished = false; |
|||
Boolean errorFlag = false; |
|||
|
|||
|
|||
void waittingForReactionPlateReady() throws ZAppInterruptException { |
|||
while (!reactionPlateReady) { |
|||
OS.forceSleep(100); |
|||
if (errorFlag) { |
|||
throw new ZAppInterruptException(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void waittingForSampleIsReady() throws ZAppInterruptException { |
|||
while (!sampleIsReady) { |
|||
OS.forceSleep(100); |
|||
if (errorFlag) { |
|||
throw new ZAppInterruptException(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void waittingForSampleProcessFinished() throws ZAppInterruptException { |
|||
while (!sampleProcessFinished) { |
|||
OS.forceSleep(100); |
|||
if (errorFlag) { |
|||
throw new ZAppInterruptException(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
void samplePrepare() throws AppException, ZAppInterruptException { |
|||
if (virtualDevice.isEnable()) { |
|||
virtualDevice.doVirtualThings("摇匀并取盖", 2); |
|||
sampleIsReady = true; |
|||
waittingForSampleProcessFinished(); |
|||
virtualDevice.doVirtualThings("放回试管", 2); |
|||
return; |
|||
} |
|||
|
|||
Tube tube = gstate.getCurProcessingTube(); |
|||
TubeHolder tubeHolder = gstate.getTubeHolder(); |
|||
Boolean isHighTube = tube.getIsHighTube(); |
|||
|
|||
/* |
|||
* 样本预处理 |
|||
*/ |
|||
if (!tube.getIsEmergency() && tubeHolder.tubeHolderType.equals(A8kTubeHolderType.BloodTube)) { |
|||
Integer shakeTimes = ProjProcessContextUtils.getShakeTimes(tube); |
|||
logger.info("摇匀次数 :{}", shakeTimes); |
|||
logger.info("试管架类型 :{}", tubeHolder.tubeHolderType); |
|||
logger.info("是否高位试管:{}", isHighTube); |
|||
tubePreProcesCtrlService.takeTubeFromTubeholderToShakePos(isHighTube); |
|||
tubePreProcesCtrlService.shakeTube(45, shakeTimes); |
|||
tubePreProcesCtrlService.takeTubeCap(); |
|||
} else { |
|||
logger.info("不是全血试管,不需要摇匀"); |
|||
} |
|||
|
|||
sampleIsReady = true; |
|||
waittingForSampleProcessFinished(); |
|||
|
|||
//样本后处理 |
|||
tubePreProcesCtrlService.resteModule(); |
|||
} |
|||
|
|||
|
|||
void paltePrepare() throws AppException, ZAppInterruptException { |
|||
// |
|||
// VIRTUAL |
|||
// |
|||
if (virtualDevice.isEnable()) { |
|||
virtualDevice.doVirtualThings("准备反应板夹", 2); |
|||
reactionPlateReady = true; |
|||
return; |
|||
} |
|||
|
|||
// |
|||
// REAL |
|||
// |
|||
|
|||
Tube tube = gstate.getCurProcessingTube(); |
|||
List<ProjProcessContext> cxts = projectProcessContextMgrService.getTubeAssociatedProjContext(tube.getSampleId()); |
|||
|
|||
for (ProjProcessContext cxt : cxts) { |
|||
IncubatorPos incubatorPos = cxt.incubatorPos; |
|||
plateBoxCtrlService.pushPlateQuick(cxt.consumable.getGroup(), incubatorPos); |
|||
} |
|||
reactionPlateReady = true; |
|||
} |
|||
|
|||
|
|||
void sampleProcess() throws AppException, ZAppInterruptException { |
|||
if (virtualDevice.isEnable()) { |
|||
virtualDevice.doVirtualThings("准备Hbot Tip", 2); |
|||
waittingForSampleIsReady(); |
|||
virtualDevice.doVirtualThings("处理样本", 2); |
|||
sampleProcessFinished = true; |
|||
return; |
|||
} |
|||
//准备第一个项目的tip头 |
|||
List<ProjProcessContext> cxts = projectProcessContextMgrService.getTubeAssociatedProjContext(gstate.getCurProcessingTube().getSampleId()); |
|||
Assert.isTrue(!cxts.isEmpty(), "项目上下文不能为空"); |
|||
|
|||
for (ProjProcessContext cxt : cxts) { |
|||
deviceCtrlScripter.doSampleProcessPrepare(cxt); |
|||
waittingForSampleIsReady(); |
|||
deviceCtrlScripter.doSampleProcess(cxt); |
|||
deviceCtrlScripter.doSampleProcessPostProcess(cxt); |
|||
} |
|||
sampleProcessFinished = true; |
|||
} |
|||
|
|||
public Boolean isReady() { |
|||
return true; |
|||
} |
|||
|
|||
@Override public String logCxtState() { |
|||
return ""; |
|||
} |
|||
|
|||
|
|||
public void beforeDoAction() { |
|||
reactionPlateReady = false; |
|||
sampleIsReady = false; |
|||
sampleProcessFinished = false; |
|||
errorFlag = false; |
|||
} |
|||
|
|||
|
|||
List<AppError> wait(List<Future<AppError>> futures) { |
|||
for (var future : futures) { |
|||
while (!future.isDone()) { |
|||
OS.forceSleep(100); |
|||
} |
|||
} |
|||
|
|||
List<AppError> errors = new ArrayList<>(); |
|||
for (var future : futures) { |
|||
try { |
|||
errors.add(future.get()); |
|||
} catch (InterruptedException | ExecutionException ignored) { |
|||
} |
|||
} |
|||
errors.removeIf(Objects::isNull); |
|||
return errors; |
|||
} |
|||
|
|||
@Override public List<AppError> doAction() { |
|||
var future1 = executor.submit(() -> { |
|||
try { |
|||
sampleProcess(); |
|||
} catch (AppException e) { |
|||
logger.error("error", e); |
|||
errorFlag = true; |
|||
return e.error; |
|||
} catch (ZAppInterruptException ignored) { |
|||
} |
|||
return null; |
|||
}); |
|||
var future2 = executor.submit(() -> { |
|||
try { |
|||
paltePrepare(); |
|||
} catch (AppException e) { |
|||
logger.error("error", e); |
|||
errorFlag = true; |
|||
return e.error; |
|||
} catch (ZAppInterruptException ignored) { |
|||
} |
|||
return null; |
|||
}); |
|||
var future3 = executor.submit(() -> { |
|||
try { |
|||
samplePrepare(); |
|||
} catch (AppException e) { |
|||
logger.error("error", e); |
|||
errorFlag = true; |
|||
return e.error; |
|||
} catch (ZAppInterruptException ignored) { |
|||
} |
|||
return null; |
|||
}); |
|||
|
|||
futures.add(future1); |
|||
futures.add(future2); |
|||
futures.add(future3); |
|||
|
|||
return wait(futures); |
|||
} |
|||
|
|||
/** |
|||
* 动作处理完成后的处理(串行),一般用于修改状态 |
|||
*/ |
|||
@Override |
|||
public List<AppError> afterDoAction(List<AppError> errors) { |
|||
if (!errors.isEmpty()) { |
|||
return errors; |
|||
} |
|||
projectProcessContextMgrService.tubePreProcessingOK(); |
|||
projectProcessContextMgrService.processIngTubeOK(); |
|||
projectProcessContextMgrService.postProcessTubeOK(); |
|||
return List.of(); |
|||
} |
|||
} |
@ -0,0 +1,15 @@ |
|||
package a8k.type.exception; |
|||
|
|||
import a8k.hardware.type.a8kcanprotocol.A8kEcode; |
|||
import a8k.hardware.type.a8kcanprotocol.CmdId; |
|||
import a8k.hardware.type.a8kcanprotocol.MId; |
|||
import a8k.type.ecode.AECommonError; |
|||
import a8k.type.ecode.AEHardwareError; |
|||
import a8k.type.ecode.AppError; |
|||
import lombok.Getter; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
@Slf4j |
|||
@Getter |
|||
public class ZAppInterruptException extends Exception { |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue