From c474418a371bdfc4a866a1a1dd6ee2151ea55422 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Tue, 8 Oct 2024 14:44:13 +0800 Subject: [PATCH] update --- .../a8k/service/appctrl/CondtionMgrService.java | 130 +++++++++++++++++ .../a8k/service/appctrl/MainFlowCtrlService.java | 3 +- .../java/a8k/service/appctrl/action/DO_PAUSE.java | 50 ------- .../java/a8k/service/appctrl/action/DO_RESUME.java | 46 ------ .../java/a8k/service/appctrl/action/DO_START.java | 54 ------- .../java/a8k/service/appctrl/action/DO_STOP.java | 47 ------- .../appctrl/action/base/A8kActionStepType.java | 14 +- .../a8k/service/appctrl/action/ctrl/DO_PAUSE.java | 50 +++++++ .../a8k/service/appctrl/action/ctrl/DO_RESUME.java | 46 ++++++ .../a8k/service/appctrl/action/ctrl/DO_START.java | 54 +++++++ .../a8k/service/appctrl/action/ctrl/DO_STOP.java | 47 +++++++ .../action/mainflow/DO_EJECT_TUBEHOLDER.java | 58 -------- .../mainflow/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java | 27 +--- .../mainflow/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java | 16 ++- .../action/mainflow/SEQ3_APPLAY_RESOURCE.java | 22 ++- .../appctrl/action/mainflow/SEQ4_PRE_PROCESS.java | 156 +++++++++------------ .../appctrl/action/mainflow/SEQ5_PROCESS.java | 96 +++++++++++++ .../appctrl/action/mainflow/SEQ6_POST_PROCESS.java | 95 +++++++++++++ .../action/mainflow/SEQ7_EJECT_TUBEHOLDER.java | 61 ++++++++ .../appctrl/scheduler/MainFlowCtrlScheduler.java | 7 - .../java/a8k/service/appstate/GStateService.java | 2 + .../appstate/IncubationPlateMgrService.java | 29 ++++ .../appstate/TubeProcessContextMgrService.java | 6 +- .../appstate/TubeProcessStateMgrService.java | 7 +- .../service/appstate/type/IncubationSubTank.java | 3 + .../service/appstate/type/ProjProcessContext.java | 1 + src/main/java/a8k/service/appstate/type/Tube.java | 3 +- .../a8k/service/appstate/type/state/TubeState.java | 1 + 28 files changed, 720 insertions(+), 411 deletions(-) create mode 100644 src/main/java/a8k/service/appctrl/CondtionMgrService.java delete mode 100644 src/main/java/a8k/service/appctrl/action/DO_PAUSE.java delete mode 100644 src/main/java/a8k/service/appctrl/action/DO_RESUME.java delete mode 100644 src/main/java/a8k/service/appctrl/action/DO_START.java delete mode 100644 src/main/java/a8k/service/appctrl/action/DO_STOP.java create mode 100644 src/main/java/a8k/service/appctrl/action/ctrl/DO_PAUSE.java create mode 100644 src/main/java/a8k/service/appctrl/action/ctrl/DO_RESUME.java create mode 100644 src/main/java/a8k/service/appctrl/action/ctrl/DO_START.java create mode 100644 src/main/java/a8k/service/appctrl/action/ctrl/DO_STOP.java delete mode 100644 src/main/java/a8k/service/appctrl/action/mainflow/DO_EJECT_TUBEHOLDER.java create mode 100644 src/main/java/a8k/service/appctrl/action/mainflow/SEQ5_PROCESS.java create mode 100644 src/main/java/a8k/service/appctrl/action/mainflow/SEQ6_POST_PROCESS.java create mode 100644 src/main/java/a8k/service/appctrl/action/mainflow/SEQ7_EJECT_TUBEHOLDER.java diff --git a/src/main/java/a8k/service/appctrl/CondtionMgrService.java b/src/main/java/a8k/service/appctrl/CondtionMgrService.java new file mode 100644 index 0000000..8a498f6 --- /dev/null +++ b/src/main/java/a8k/service/appctrl/CondtionMgrService.java @@ -0,0 +1,130 @@ +package a8k.service.appctrl; + +import a8k.hardware.A8kCanBusService; +import a8k.hardware.type.a8kcanprotocol.IOId; +import a8k.service.appstate.GStateService; +import a8k.service.appstate.IncubationPlateMgrService; +import a8k.service.appstate.type.Tube; +import a8k.service.appstate.type.state.A8kWorkState; +import a8k.service.appstate.type.state.TubeHolderState; +import a8k.service.appstate.type.state.TubeState; +import a8k.type.exception.AppException; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + + +@Component +public class CondtionMgrService { + static Logger logger = LoggerFactory.getLogger(CondtionMgrService.class); + + @Resource + GStateService gstate; + + @Resource + A8kCanBusService canBus; + + @Resource + IncubationPlateMgrService incubationPlateMgrService; + + Boolean getTubeholderEnterPosPPS() { //入料通道是否为空 + try { + return canBus.getIOState(IOId.InfeedPPS); + } catch (Exception e) { + logger.error("getTubeholderEnterPosPPS error", e); + return false; + } + } + + public Boolean isNoMoreTubeToBeProcessed() { + return !gstate.getTubeHolder().isHasTubeToBeProcessed(); + } + + public Boolean isCanDoAction() { + return gstate.mainFlowCtrlState.workState.equals(A8kWorkState.WORKING) && !gstate.mainFlowCtrlState.errorFlag; + } + + + public Boolean isHasSometubesToBeProcessed() { + return gstate.getTubeHolder().isHasTubeToBeProcessed() || gstate.getEmergencyTubePos().tube.state.equals(TubeState.TO_BE_PROCESSED); + } + + public Boolean isCurTubeProcessCompleted() { + return gstate.getCurProcessingTube() == null || gstate.getCurProcessingTube().state.equals(TubeState.PROCESS_COMPLETE); + } + + public Boolean isTimeToEnterNewTubeHolder() { + Boolean cond0 = isCanDoAction(); + //试管架处于空闲状态 + Boolean cond1 = gstate.getTubeHolder().state.equals(TubeHolderState.IDLE); + //入料通道是否为空 + Boolean cond2 = getTubeholderEnterPosPPS(); + return cond0 && cond1 && cond2; + } + + public Boolean isTimeToSwitchNextTube() { + Boolean cond0 = isCanDoAction(); + //当前试管处理完成 + Boolean cond1 = isCurTubeProcessCompleted(); + //有待处理的试管 + Boolean cond2 = isHasSometubesToBeProcessed(); + return cond0 && cond1 && cond2; + } + + public Boolean isTimeToProcessPendingTube() { + Tube tube = gstate.getCurProcessingTube(); + if (tube == null) + return false; + + //当前正在工作 + Boolean cond1 = isCanDoAction(); + //没有试管在处理 或者 当前试管处理完成 + Boolean cond2 = tube.state.equals(TubeState.PENDING); + //急诊有待处理的试管,或者试管架正在处理 + Boolean cond3 = incubationPlateMgrService.isHasEnoughIncubationIDLEPos(tube.projIndex.size()); + return cond1 && cond2 && cond3; + } + + public Boolean isTimeToPreProcessTube() { + Tube tube = gstate.getCurProcessingTube(); + if (tube == null) + return false; + + //当前正在工作 + Boolean cond1 = isCanDoAction(); + //没有试管在处理 或者 当前试管处理完成 + Boolean cond2 = tube.state.equals(TubeState.RESOURCE_IS_READY); + //急诊有待处理的试管,或者试管架正在处理 + Boolean cond3 = incubationPlateMgrService.isHasEnoughIncubationIDLEPos(tube.projIndex.size()); + return cond1 && cond2 && cond3; + } + + public Boolean isTimeToProcessTube() { + Tube tube = gstate.getCurProcessingTube(); + if (tube == null) + return false; + + //当前正在工作 + Boolean cond1 = isCanDoAction(); + //没有试管在处理 或者 当前试管处理完成 + Boolean cond2 = tube.state.equals(TubeState.PRE_PROCESSED); + //急诊有待处理的试管,或者试管架正在处理 + Boolean cond3 = incubationPlateMgrService.isHasEnoughIncubationIDLEPos(tube.projIndex.size()); + return cond1 && cond2 && cond3; + } + + public Boolean isTimeToPostProcessTube() { + Tube tube = gstate.getCurProcessingTube(); + if (tube == null) + return false; + + //当前正在工作 + Boolean cond1 = isCanDoAction(); + //没有试管在处理 或者 当前试管处理完成 + Boolean cond2 = tube.state.equals(TubeState.PROCESSED); + //急诊有待处理的试管,或者试管架正在处理 + Boolean cond3 = incubationPlateMgrService.isHasEnoughIncubationIDLEPos(tube.projIndex.size()); + return cond1 && cond2 && cond3; + } +} diff --git a/src/main/java/a8k/service/appctrl/MainFlowCtrlService.java b/src/main/java/a8k/service/appctrl/MainFlowCtrlService.java index 0df42fb..4c03283 100644 --- a/src/main/java/a8k/service/appctrl/MainFlowCtrlService.java +++ b/src/main/java/a8k/service/appctrl/MainFlowCtrlService.java @@ -1,8 +1,8 @@ package a8k.service.appctrl; -import a8k.service.appctrl.action.*; import a8k.service.appctrl.action.base.A8kActionStepType; import a8k.service.appctrl.action.base.A8kStepAction; +import a8k.service.appctrl.action.ctrl.DO_STOP; import a8k.service.appctrl.scheduler.MainFlowCtrlScheduler; import a8k.service.appctrl.type.A8kErrorContext; import a8k.service.appstate.GStateService; @@ -16,7 +16,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import java.util.Arrays; import java.util.List; @Component diff --git a/src/main/java/a8k/service/appctrl/action/DO_PAUSE.java b/src/main/java/a8k/service/appctrl/action/DO_PAUSE.java deleted file mode 100644 index 54b94d0..0000000 --- a/src/main/java/a8k/service/appctrl/action/DO_PAUSE.java +++ /dev/null @@ -1,50 +0,0 @@ -package a8k.service.appctrl.action; - -import a8k.service.appctrl.action.base.A8kActionStepType; -import a8k.service.appctrl.action.base.A8kStepAction; -import a8k.service.appstate.GStateService; -import a8k.service.appstate.resource.A8kPublicResourceType; -import a8k.service.appstate.type.state.A8kWorkState; -import a8k.service.devicedriver.ctrl.SampleScanTransportCtrl; -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; - -@Component -public class DO_PAUSE extends A8kStepAction { - static Logger logger = LoggerFactory.getLogger(DO_PAUSE.class); - - DO_PAUSE() { - super(A8kActionStepType.DO_PAUSE); - } - - @Resource - GStateService gstate; - - @Resource - SampleScanTransportCtrl sampleScanTransportCtrl; - - @PostConstruct - void init() { - } - - @Override public void doaction() throws AppException { - gstate.mainFlowCtrlState.workStateChangeFlag = false; - } - - @Override public Boolean checkCondition() { - Boolean cond1 = gstate.mainFlowCtrlState.workStateChangeFlag; - Boolean cond2 = gstate.mainFlowCtrlState.lastWorkState.equals(A8kWorkState.WORKING); - Boolean cond3 = gstate.mainFlowCtrlState.workState.equals(A8kWorkState.PAUSE); - return cond1 & cond2 & cond3; - } - - @Override public List getResourceList() { - return List.of(); - } -} diff --git a/src/main/java/a8k/service/appctrl/action/DO_RESUME.java b/src/main/java/a8k/service/appctrl/action/DO_RESUME.java deleted file mode 100644 index c7f370a..0000000 --- a/src/main/java/a8k/service/appctrl/action/DO_RESUME.java +++ /dev/null @@ -1,46 +0,0 @@ -package a8k.service.appctrl.action; - -import a8k.service.appctrl.action.base.A8kActionStepType; -import a8k.service.appctrl.action.base.A8kStepAction; -import a8k.service.appstate.GStateService; -import a8k.service.appstate.resource.A8kPublicResourceType; -import a8k.service.appstate.type.state.A8kWorkState; -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; - -@Component -public class DO_RESUME extends A8kStepAction { - static Logger logger = LoggerFactory.getLogger(DO_RESUME.class); - - DO_RESUME() { - super(A8kActionStepType.DO_STOP); - } - - @Resource - GStateService gstate; - - @PostConstruct - void init() { - } - - @Override public void doaction() throws AppException { - gstate.mainFlowCtrlState.workStateChangeFlag = false; - } - - @Override public Boolean checkCondition() { - Boolean cond1 = gstate.mainFlowCtrlState.workStateChangeFlag; - Boolean cond2 = gstate.mainFlowCtrlState.lastWorkState.equals(A8kWorkState.PAUSE); - Boolean cond3 = gstate.mainFlowCtrlState.workState.equals(A8kWorkState.WORKING); - return cond1 & cond2 & cond3; - } - - @Override public List getResourceList() { - return List.of(); - } -} diff --git a/src/main/java/a8k/service/appctrl/action/DO_START.java b/src/main/java/a8k/service/appctrl/action/DO_START.java deleted file mode 100644 index a26f132..0000000 --- a/src/main/java/a8k/service/appctrl/action/DO_START.java +++ /dev/null @@ -1,54 +0,0 @@ -package a8k.service.appctrl.action; - -import a8k.service.appctrl.action.base.A8kActionStepType; -import a8k.service.appctrl.action.base.A8kStepAction; -import a8k.service.appstate.GStateService; -import a8k.service.appstate.resource.A8kPublicResourceType; -import a8k.service.appstate.type.state.A8kWorkState; -import a8k.service.devicedriver.ctrl.SampleScanTransportCtrl; -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; - -@Component -public class DO_START extends A8kStepAction { - static Logger logger = LoggerFactory.getLogger(DO_START.class); - - DO_START() { - super(A8kActionStepType.DO_START); - } - - @Resource - GStateService gstate; - - @Resource - SampleScanTransportCtrl sampleScanTransportCtrl; - - - @PostConstruct - void init() { - - } - - - @Override public void doaction() throws AppException { - gstate.mainFlowCtrlState.workStateChangeFlag = false; - sampleScanTransportCtrl.ejectTubeHolder(); - } - - @Override public Boolean checkCondition() { - Boolean cond1 = gstate.mainFlowCtrlState.workStateChangeFlag; - Boolean cond2 = gstate.mainFlowCtrlState.lastWorkState.equals(A8kWorkState.IDLE); - Boolean cond3 = gstate.mainFlowCtrlState.workState.equals(A8kWorkState.WORKING); - return cond1 & cond2 & cond3; - } - - @Override public List getResourceList() { - return List.of(A8kPublicResourceType.SampleTransferXMotor); - } -} diff --git a/src/main/java/a8k/service/appctrl/action/DO_STOP.java b/src/main/java/a8k/service/appctrl/action/DO_STOP.java deleted file mode 100644 index 8c4c1a1..0000000 --- a/src/main/java/a8k/service/appctrl/action/DO_STOP.java +++ /dev/null @@ -1,47 +0,0 @@ -package a8k.service.appctrl.action; - -import a8k.service.appctrl.action.base.A8kActionStepType; -import a8k.service.appctrl.action.base.A8kStepAction; -import a8k.service.appstate.GStateService; -import a8k.service.appstate.resource.A8kPublicResourceType; -import a8k.service.appstate.type.state.A8kWorkState; -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; - -@Component -public class DO_STOP extends A8kStepAction { - static Logger logger = LoggerFactory.getLogger(DO_STOP.class); - - DO_STOP() { - super(A8kActionStepType.DO_STOP); - } - - @Resource - GStateService gstate; - - @PostConstruct - void init() { - } - - - @Override public void doaction() throws AppException { - gstate.mainFlowCtrlState.workStateChangeFlag = false; - } - - @Override public Boolean checkCondition() { - Boolean cond1 = gstate.mainFlowCtrlState.workStateChangeFlag; - Boolean cond2 = gstate.mainFlowCtrlState.lastWorkState.equals(A8kWorkState.WORKING) || gstate.mainFlowCtrlState.lastWorkState.equals(A8kWorkState.PAUSE); - Boolean cond3 = gstate.mainFlowCtrlState.workState.equals(A8kWorkState.IDLE); - return cond1 & cond2 & cond3; - } - - @Override public List getResourceList() { - return List.of(); - } -} diff --git a/src/main/java/a8k/service/appctrl/action/base/A8kActionStepType.java b/src/main/java/a8k/service/appctrl/action/base/A8kActionStepType.java index be35eda..51142b6 100644 --- a/src/main/java/a8k/service/appctrl/action/base/A8kActionStepType.java +++ b/src/main/java/a8k/service/appctrl/action/base/A8kActionStepType.java @@ -5,18 +5,16 @@ public enum A8kActionStepType { DO_PAUSE,//暂停 DO_STOP, //停止 DO_RESUME,//恢复 + DO_CLEAR_ERROR,//清除错误,特殊动作,无需注册成类型 + //mainflow SEQ1_ENTER_TUBEHOLDER_AND_SCAN, //入料并扫描 SEQ2_SWITCH_TO_THE_NEXT_TUBE,// 切换到下一个试管 SEQ3_APPLAY_RESOURCE,//申请资源 SEQ4_PRE_PROCESS, + SEQ5_PROCESS, + SEQ6_POST_PROCESS, + SEQ7_EJECT_TUBEHOLDER, //弹出试管架 - // SEQ4_PROCESS, - // SEQ5_POS_PROCESS_TUBE, - - - DO_EJECT_TUBEHOLDER, //弹出试管架 - - //特殊动作,无需注册成类型 - DO_CLEAR_ERROR,//清除错误 + // } diff --git a/src/main/java/a8k/service/appctrl/action/ctrl/DO_PAUSE.java b/src/main/java/a8k/service/appctrl/action/ctrl/DO_PAUSE.java new file mode 100644 index 0000000..c82d1e2 --- /dev/null +++ b/src/main/java/a8k/service/appctrl/action/ctrl/DO_PAUSE.java @@ -0,0 +1,50 @@ +package a8k.service.appctrl.action.ctrl; + +import a8k.service.appctrl.action.base.A8kActionStepType; +import a8k.service.appctrl.action.base.A8kStepAction; +import a8k.service.appstate.GStateService; +import a8k.service.appstate.resource.A8kPublicResourceType; +import a8k.service.appstate.type.state.A8kWorkState; +import a8k.service.devicedriver.ctrl.SampleScanTransportCtrl; +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; + +@Component +public class DO_PAUSE extends A8kStepAction { + static Logger logger = LoggerFactory.getLogger(DO_PAUSE.class); + + DO_PAUSE() { + super(A8kActionStepType.DO_PAUSE); + } + + @Resource + GStateService gstate; + + @Resource + SampleScanTransportCtrl sampleScanTransportCtrl; + + @PostConstruct + void init() { + } + + @Override public void doaction() throws AppException { + gstate.mainFlowCtrlState.workStateChangeFlag = false; + } + + @Override public Boolean checkCondition() { + Boolean cond1 = gstate.mainFlowCtrlState.workStateChangeFlag; + Boolean cond2 = gstate.mainFlowCtrlState.lastWorkState.equals(A8kWorkState.WORKING); + Boolean cond3 = gstate.mainFlowCtrlState.workState.equals(A8kWorkState.PAUSE); + return cond1 & cond2 & cond3; + } + + @Override public List getResourceList() { + return List.of(); + } +} diff --git a/src/main/java/a8k/service/appctrl/action/ctrl/DO_RESUME.java b/src/main/java/a8k/service/appctrl/action/ctrl/DO_RESUME.java new file mode 100644 index 0000000..d4a6cf6 --- /dev/null +++ b/src/main/java/a8k/service/appctrl/action/ctrl/DO_RESUME.java @@ -0,0 +1,46 @@ +package a8k.service.appctrl.action.ctrl; + +import a8k.service.appctrl.action.base.A8kActionStepType; +import a8k.service.appctrl.action.base.A8kStepAction; +import a8k.service.appstate.GStateService; +import a8k.service.appstate.resource.A8kPublicResourceType; +import a8k.service.appstate.type.state.A8kWorkState; +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; + +@Component +public class DO_RESUME extends A8kStepAction { + static Logger logger = LoggerFactory.getLogger(DO_RESUME.class); + + DO_RESUME() { + super(A8kActionStepType.DO_RESUME); + } + + @Resource + GStateService gstate; + + @PostConstruct + void init() { + } + + @Override public void doaction() throws AppException { + gstate.mainFlowCtrlState.workStateChangeFlag = false; + } + + @Override public Boolean checkCondition() { + Boolean cond1 = gstate.mainFlowCtrlState.workStateChangeFlag; + Boolean cond2 = gstate.mainFlowCtrlState.lastWorkState.equals(A8kWorkState.PAUSE); + Boolean cond3 = gstate.mainFlowCtrlState.workState.equals(A8kWorkState.WORKING); + return cond1 & cond2 & cond3; + } + + @Override public List getResourceList() { + return List.of(); + } +} diff --git a/src/main/java/a8k/service/appctrl/action/ctrl/DO_START.java b/src/main/java/a8k/service/appctrl/action/ctrl/DO_START.java new file mode 100644 index 0000000..5af4213 --- /dev/null +++ b/src/main/java/a8k/service/appctrl/action/ctrl/DO_START.java @@ -0,0 +1,54 @@ +package a8k.service.appctrl.action.ctrl; + +import a8k.service.appctrl.action.base.A8kActionStepType; +import a8k.service.appctrl.action.base.A8kStepAction; +import a8k.service.appstate.GStateService; +import a8k.service.appstate.resource.A8kPublicResourceType; +import a8k.service.appstate.type.state.A8kWorkState; +import a8k.service.devicedriver.ctrl.SampleScanTransportCtrl; +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; + +@Component +public class DO_START extends A8kStepAction { + static Logger logger = LoggerFactory.getLogger(DO_START.class); + + DO_START() { + super(A8kActionStepType.DO_START); + } + + @Resource + GStateService gstate; + + @Resource + SampleScanTransportCtrl sampleScanTransportCtrl; + + + @PostConstruct + void init() { + + } + + + @Override public void doaction() throws AppException { + gstate.mainFlowCtrlState.workStateChangeFlag = false; + sampleScanTransportCtrl.ejectTubeHolder(); + } + + @Override public Boolean checkCondition() { + Boolean cond1 = gstate.mainFlowCtrlState.workStateChangeFlag; + Boolean cond2 = gstate.mainFlowCtrlState.lastWorkState.equals(A8kWorkState.IDLE); + Boolean cond3 = gstate.mainFlowCtrlState.workState.equals(A8kWorkState.WORKING); + return cond1 & cond2 & cond3; + } + + @Override public List getResourceList() { + return List.of(A8kPublicResourceType.SampleTransferXMotor); + } +} diff --git a/src/main/java/a8k/service/appctrl/action/ctrl/DO_STOP.java b/src/main/java/a8k/service/appctrl/action/ctrl/DO_STOP.java new file mode 100644 index 0000000..b4064bb --- /dev/null +++ b/src/main/java/a8k/service/appctrl/action/ctrl/DO_STOP.java @@ -0,0 +1,47 @@ +package a8k.service.appctrl.action.ctrl; + +import a8k.service.appctrl.action.base.A8kActionStepType; +import a8k.service.appctrl.action.base.A8kStepAction; +import a8k.service.appstate.GStateService; +import a8k.service.appstate.resource.A8kPublicResourceType; +import a8k.service.appstate.type.state.A8kWorkState; +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; + +@Component +public class DO_STOP extends A8kStepAction { + static Logger logger = LoggerFactory.getLogger(DO_STOP.class); + + DO_STOP() { + super(A8kActionStepType.DO_STOP); + } + + @Resource + GStateService gstate; + + @PostConstruct + void init() { + } + + + @Override public void doaction() throws AppException { + gstate.mainFlowCtrlState.workStateChangeFlag = false; + } + + @Override public Boolean checkCondition() { + Boolean cond1 = gstate.mainFlowCtrlState.workStateChangeFlag; + Boolean cond2 = gstate.mainFlowCtrlState.lastWorkState.equals(A8kWorkState.WORKING) || gstate.mainFlowCtrlState.lastWorkState.equals(A8kWorkState.PAUSE); + Boolean cond3 = gstate.mainFlowCtrlState.workState.equals(A8kWorkState.IDLE); + return cond1 & cond2 & cond3; + } + + @Override public List getResourceList() { + return List.of(); + } +} diff --git a/src/main/java/a8k/service/appctrl/action/mainflow/DO_EJECT_TUBEHOLDER.java b/src/main/java/a8k/service/appctrl/action/mainflow/DO_EJECT_TUBEHOLDER.java deleted file mode 100644 index e327806..0000000 --- a/src/main/java/a8k/service/appctrl/action/mainflow/DO_EJECT_TUBEHOLDER.java +++ /dev/null @@ -1,58 +0,0 @@ -package a8k.service.appctrl.action.mainflow; - -import a8k.service.appctrl.action.base.A8kActionStepType; -import a8k.service.appctrl.action.base.A8kStepAction; -import a8k.service.appstate.GStateService; -import a8k.service.appstate.type.MainFlowCtrlState; -import a8k.service.appstate.resource.A8kPublicResourceType; -import a8k.service.appstate.type.state.A8kWorkState; -import a8k.service.appstate.type.state.TubeHolderState; -import a8k.service.devicedriver.ctrl.SampleScanTransportCtrl; -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; - -@Component -public class DO_EJECT_TUBEHOLDER extends A8kStepAction { - static Logger logger = LoggerFactory.getLogger(DO_EJECT_TUBEHOLDER.class); - - DO_EJECT_TUBEHOLDER() { - super(A8kActionStepType.DO_EJECT_TUBEHOLDER); - } - - @Resource - GStateService gstate; - @Resource - SampleScanTransportCtrl stc; - - MainFlowCtrlState mfcs; - - - @PostConstruct - void init() { - mfcs = gstate.mainFlowCtrlState; - } - - @Override public void doaction() throws AppException { - stc.ejectTubeHolder(); - stc.moveTubeRackMoveToEnterPos(); - gstate.getTubeHolder().state = TubeHolderState.IDLE; - } - - @Override public Boolean checkCondition() { - //处于工作状态,试管架已经处于空闲状态,入料光电被触发 - Boolean cond1 = mfcs.workState.equals(A8kWorkState.WORKING); - Boolean cond2 = gstate.getTubeHolder().state.equals(TubeHolderState.PROCESSING); - Boolean cond3 = !gstate.getTubeHolder().isHasTubeToBeProcessed(); - return cond1 & cond2 & cond3; - } - - @Override public List getResourceList() { - return List.of(A8kPublicResourceType.SampleTransferXMotor); - } -} diff --git a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java index 8d8deca..dc51979 100644 --- a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java +++ b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java @@ -5,6 +5,7 @@ import a8k.baseservice.appeventbus.appevent.AppWarningNotifyEvent; import a8k.hardware.A8kCanBusService; import a8k.hardware.type.a8kcanprotocol.A8kEcode; import a8k.hardware.type.a8kcanprotocol.IOId; +import a8k.service.appctrl.CondtionMgrService; import a8k.service.appdata.AppSampleRecordMgrService; import a8k.service.appctrl.AppTubeSettingMgrService; import a8k.service.appctrl.action.base.A8kActionStepType; @@ -64,6 +65,8 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { @Resource GStateService gstate; @Resource + CondtionMgrService cmgr; + @Resource SampleScanTransportCtrl stc; @Resource AppEventBusService ebus; @@ -74,14 +77,6 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { @Resource TubeProcessContextMgrService tubeProcessContextMgrService; - MainFlowCtrlState mfcs; - - - @PostConstruct - void init() { - mfcs = gstate.mainFlowCtrlState; - } - SampleScanResult scanTubeHodler() throws AppException { SampleScanResult result = new SampleScanResult(); @@ -225,13 +220,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { } @Override public Boolean checkCondition() { - //处于工作状态 - Boolean cond1 = gstate.isWorking(); - //试管架处于空闲状态 - Boolean cond2 = gstate.getTubeHolder().state.equals(TubeHolderState.IDLE); - //入料通道是否为空 - Boolean cond3 = getTubeholderEnterPosPPS(); - return cond1 && cond2 && cond3; + return cmgr.isTimeToEnterNewTubeHolder(); } @Override public List getResourceList() { @@ -265,13 +254,5 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { tryUpdateGroupId = true; } - Boolean getTubeholderEnterPosPPS() { //入料通道是否为空 - try { - return canBus.getIOState(IOId.InfeedPPS); - } catch (AppException e) { - logger.error("getTubeholderEnterPosPPS error", e); - return false; - } - } } diff --git a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java index 19be978..fc1043c 100644 --- a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java +++ b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java @@ -1,9 +1,11 @@ package a8k.service.appctrl.action.mainflow; +import a8k.service.appctrl.CondtionMgrService; import a8k.service.appctrl.action.base.A8kActionStepType; import a8k.service.appctrl.action.base.A8kStepAction; import a8k.service.appstate.*; import a8k.service.appstate.resource.A8kPublicResourceType; +import a8k.service.appstate.type.MainFlowCtrlState; import a8k.service.appstate.type.TubeHolder; import a8k.service.appstate.type.Tube; import a8k.service.appstate.type.state.TubeState; @@ -38,9 +40,15 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction { SampleScanTransportCtrl sstc; @Resource TubeProcessStateMgrService tubeProcessStateMgrService; + @Resource + CondtionMgrService cms; + + + MainFlowCtrlState state; @PostConstruct void init() { + state = gstate.mainFlowCtrlState; } int moveToNextTube() { @@ -89,13 +97,7 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction { } @Override public Boolean checkCondition() { - //当前正在工作 - Boolean cond1 = gstate.isWorking(); - //没有试管在处理 或者 当前试管处理完成 - Boolean cond2 = gstate.getCurProcessingTube() == null || gstate.getCurProcessingTube().state.equals(TubeState.PROCESS_COMPLETE); - //急诊有待处理的试管,或者试管架正在处理 - Boolean cond3 = gstate.getTubeHolder().isHasTubeToBeProcessed() || gstate.getEmergencyTubePos().tube.state.equals(TubeState.TO_BE_PROCESSED); - return cond1 && cond2 && cond3; + return cms.isTimeToSwitchNextTube(); } @Override public List getResourceList() { diff --git a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ3_APPLAY_RESOURCE.java b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ3_APPLAY_RESOURCE.java index 1dcd7ea..32d3be6 100644 --- a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ3_APPLAY_RESOURCE.java +++ b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ3_APPLAY_RESOURCE.java @@ -2,13 +2,14 @@ package a8k.service.appctrl.action.mainflow; import a8k.baseservice.AppExceptionBuilder; import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.service.appctrl.CondtionMgrService; import a8k.service.appdata.AppProjInfoMgrService; import a8k.service.appctrl.action.base.A8kActionStepType; import a8k.service.appctrl.action.base.A8kStepAction; import a8k.service.appstate.*; import a8k.service.appstate.resource.A8kPublicResourceType; +import a8k.service.appstate.type.MainFlowCtrlState; import a8k.service.appstate.type.Tube; -import a8k.service.appstate.type.state.TubeState; import a8k.type.Consumable; import a8k.type.IncubatorPos; import a8k.type.TipPos; @@ -51,10 +52,15 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { AppProjInfoMgrService appProjInfoMgrService; //项目信息管理 @Resource TubeProcessStateMgrService tubeProcessStateMgrService; //试管处理状态管理 + @Resource + CondtionMgrService cms; + + MainFlowCtrlState state; @PostConstruct void init() { + state = gstate.mainFlowCtrlState; } @Override public void doaction() throws AppException { @@ -106,22 +112,12 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { tipPos.add(tips); } //创建项目处理上下文 - tubeProcessStateMgrService.startProcessTube(a8kIdCardInfo, consumables, tipPos, incubatorPoss); + tubeProcessStateMgrService.setTubeResourceIsReady(a8kIdCardInfo, consumables, tipPos, incubatorPoss); logger.info("apply resource ok"); } @Override public Boolean checkCondition() { - Tube tube = gstate.getCurProcessingTube(); - if (tube == null) - return false; - - //当前正在工作 - Boolean cond1 = gstate.isWorking(); - //没有试管在处理 或者 当前试管处理完成 - Boolean cond2 = tube.state.equals(TubeState.PENDING); - //急诊有待处理的试管,或者试管架正在处理 - Boolean cond3 = incubationPlateMgrService.isHasEnoughIncubationIDLEPos(tube.projIndex.size()); - return cond1 && cond2 && cond3; + return cms.isTimeToProcessPendingTube(); } @Override public List getResourceList() { diff --git a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ4_PRE_PROCESS.java b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ4_PRE_PROCESS.java index c9d981e..90606a4 100644 --- a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ4_PRE_PROCESS.java +++ b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ4_PRE_PROCESS.java @@ -1,22 +1,24 @@ package a8k.service.appctrl.action.mainflow; import a8k.OS; +import a8k.service.appctrl.CondtionMgrService; import a8k.service.appdata.AppProjInfoMgrService; import a8k.baseservice.AppExceptionBuilder; import a8k.baseservice.appeventbus.AppEventBusService; import a8k.service.appctrl.action.base.A8kActionStepType; import a8k.service.appctrl.action.base.A8kStepAction; -import a8k.service.appstate.ConsumablesMgrService; -import a8k.service.appstate.GStateService; -import a8k.service.appstate.IncubationPlateMgrService; -import a8k.service.appstate.TubeProcessContextMgrService; +import a8k.service.appstate.*; import a8k.service.appstate.resource.A8kPublicResourceType; +import a8k.service.appstate.type.MainFlowCtrlState; +import a8k.service.appstate.type.Tube; import a8k.service.appstate.type.state.TubeState; import a8k.service.devicedriver.ctrl.HbotControlService; import a8k.service.devicedriver.ctrl.ReactionPlatesTransmitCtrl; import a8k.service.devicedriver.ctrl.SampleScanTransportCtrl; import a8k.service.devicedriver.ctrl.SamplesPreProcesCtrl; +import a8k.type.ecode.AppError; import a8k.type.exception.AppException; +import a8k.utils.ZFnCall; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import org.slf4j.Logger; @@ -24,6 +26,7 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.List; +import java.util.Objects; import java.util.concurrent.*; /** @@ -50,8 +53,6 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { @Resource ConsumablesMgrService consumablesMgrService; - @Resource - IncubationPlateMgrService incubationPlateMgrService; @Resource AppProjInfoMgrService appProjInfoMgrService; @@ -74,6 +75,15 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { @Resource HbotControlService hbotControlService; + @Resource + TubeProcessStateMgrService tubeProcessStateMgrService; + + @Resource + IncubationPlateMgrService incubationPlateMgrService; + + @Resource + CondtionMgrService cms; + ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); @@ -81,12 +91,16 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { void init() { } - /** * 推出反应板夹 * @throws AppException 异常 */ void prepareReactionPlate() throws AppException { + if (gstate.debugMode) { + logger.info("prepareReactionPlate"); + OS.forceSleep(1000); + return; + } // Tube tube = gstate.getCurProcessingTube(); // List projIndex = tube.projIndex; // List incubatorPos = tube.incubatorPos; @@ -97,6 +111,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { // reactionPlatesTransmitCtrl.pushPlate(bindConsumablesCh.get(i), incubatorPos.get(i)); // tank.state = IncubationSubTankState.WAITING_FOR_DROP; // } + } /** @@ -104,6 +119,12 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { * @throws AppException */ void shakeAndTakeCap() throws AppException { + if (gstate.debugMode) { + logger.info("shakeAndTakeCap"); + OS.forceSleep(1000); + return; + } + // Tube tube = gstate.getCurProcessingTube(); // if (tube.isEmergency) { // //如果事急诊位则什么也不做 @@ -120,9 +141,15 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { // samplesPreProcesCtrl.takeTubeAndJudgeTubeExist(tube.isHighTube); // samplesPreProcesCtrl.shakeTube(45, 5); // samplesPreProcesCtrl.takeTubeCap(); + OS.forceSleep(1000); } void hbotPrepareTip() throws AppException { + if (gstate.debugMode) { + logger.info("hbotPrepareTip"); + OS.forceSleep(1000); + return; + } // Tube tube = gstate.getCurProcessingTube(); // // hbotControlService.takeTip(); // TipPos tippos = consumablesMgrService.takeNextTipPosAndSetUsed(); @@ -138,66 +165,9 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { // } // // logger.info("takeTip success"); + OS.forceSleep(1000); } - // @Override public void doaction() throws AppException { - // Tube tube = gstate.getCurProcessingTube(); - // //构建样本和耗材绑定关系 - // List bindConsumableCH = new ArrayList<>(); - // List consumablePosIndexList = new ArrayList<>(); - // List incubatorPosList = new ArrayList<>(); - // for (Integer projIndex : tube.projIndex) { - // ConsumableGroup chNum = consumablesMgrService.getChannelNumByProjIndex(projIndex); - // Integer consumablePosIndex = consumablesMgrService.allocConsumable(chNum); - // - // - // if (chNum == null) { - // logger.error("apply consumable failed, projIndex:{}", projIndex); - // throw ebuilder.buildAppCodeErrorException("预处理阶段,申请耗材失败"); - // } - // if (consumablePosIndex == null) { - // logger.error("alloc consumable failed, projIndex:{}", projIndex); - // throw ebuilder.buildAppCodeErrorException("预处理阶段,申请耗材失败x"); - // } - // bindConsumableCH.add(chNum); - // consumablePosIndexList.add(consumablePosIndex); - // incubatorPosList = gstate.getIncubationPlate().getEmptyPosList(tube.projIndex.size()); - // } - // tube.bindConsumablesCh = bindConsumableCH; - // tube.consumablePos = consumablePosIndexList; - // tube.incubatorPos = incubatorPosList; - // - // tubeProcessContextMgrService.updateTubeContext(tube);//更新样本上下文 - // - // //检测反应板是否有空位 - // if (gstate.getIncubationPlate().getEmptyPosNum() < tube.projIndex.size()) { - // throw ebuilder.buildAppCodeErrorException("预处理阶段,反应板空位不足"); - // } - // - // //准备反应板夹 - // var doPrepareReactionPlateFuture = executor.submit(() -> ZFnCall.callfn(this::prepareReactionPlate)); - // //摇匀并取盖 - // var doShakeAndTakeCapFuture = executor.submit(() -> ZFnCall.callfn(this::shakeAndTakeCap)); - // //准备Hbot Tip - // var doHbotPrepareTipFuture = executor.submit(() -> ZFnCall.callfn(this::hbotPrepareTip)); - // - // wait(doPrepareReactionPlateFuture); - // wait(doShakeAndTakeCapFuture); - // wait(doHbotPrepareTipFuture); - // - // List errors = new java.util.ArrayList<>(List.of()); - // try { - // errors.add(doPrepareReactionPlateFuture.get()); - // errors.add(doShakeAndTakeCapFuture.get()); - // errors.add(doHbotPrepareTipFuture.get()); - // } catch (InterruptedException | ExecutionException ignored) { - // } - // errors.removeIf(Objects::isNull); - // if (!errors.isEmpty()) { - // throw ebuilder.buildMutiErrorAppException(errors); - // } - // } - @Override public void doaction() throws AppException { // // 1.准备3份反应板夹 @@ -205,44 +175,46 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { // 3.摇匀,脱帽 // + Tube tube = gstate.getCurProcessingTube(); + //准备反应板夹 + var doPrepareReactionPlateFuture = executor.submit(() -> ZFnCall.callfn(this::prepareReactionPlate)); + //摇匀并取盖 + var doShakeAndTakeCapFuture = executor.submit(() -> ZFnCall.callfn(this::shakeAndTakeCap)); + //准备Hbot Tip + var doHbotPrepareTipFuture = executor.submit(() -> ZFnCall.callfn(this::hbotPrepareTip)); + + wait(doPrepareReactionPlateFuture); + wait(doShakeAndTakeCapFuture); + wait(doHbotPrepareTipFuture); + + List errors = new java.util.ArrayList<>(List.of()); + try { + errors.add(doPrepareReactionPlateFuture.get()); + errors.add(doShakeAndTakeCapFuture.get()); + errors.add(doHbotPrepareTipFuture.get()); + } catch (InterruptedException | ExecutionException ignored) { + } + errors.removeIf(Objects::isNull); + if (!errors.isEmpty()) { + throw ebuilder.buildMutiErrorAppException(errors); + } - - // List tipPos - // consumablesMgrService.getChannelNumByProjIndex(projIndex); - - - // - // 计算需要执行的动作 - // - - // - // 执行动作 - // - - // - // 赋值状态 - // - - // - // 恢复状态 - // - + tubeProcessStateMgrService.setCurTubeState(TubeState.PRE_PROCESSED); + incubationPlateMgrService.waitingForDrop(tube); + logger.info("pre process success"); } @Override public Boolean checkCondition() { - //当前正在工作 - Boolean cond1 = gstate.isWorking(); - //有需要进行预处理的样本 - Boolean cond2 = gstate.getCurProcessingTube() != null && gstate.getCurProcessingTube().state.equals(TubeState.PRE_PROCESSING); - return cond1 && cond2; + return cms.isTimeToPreProcessTube(); } @Override public List getResourceList() { return List.of( A8kPublicResourceType.IncubationPlateMotor, A8kPublicResourceType.PlatesBoxMotor, - A8kPublicResourceType.HBOT + A8kPublicResourceType.HBOT, + A8kPublicResourceType.CurTubeProcessToken ); } diff --git a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ5_PROCESS.java b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ5_PROCESS.java new file mode 100644 index 0000000..584d72b --- /dev/null +++ b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ5_PROCESS.java @@ -0,0 +1,96 @@ +package a8k.service.appctrl.action.mainflow; + +import a8k.OS; +import a8k.baseservice.AppExceptionBuilder; +import a8k.service.appctrl.CondtionMgrService; +import a8k.service.appctrl.action.base.A8kActionStepType; +import a8k.service.appctrl.action.base.A8kStepAction; +import a8k.service.appstate.*; +import a8k.service.appstate.resource.A8kPublicResourceType; +import a8k.service.appstate.type.MainFlowCtrlState; +import a8k.service.appstate.type.Tube; +import a8k.service.appstate.type.state.TubeState; +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.*; + +/** + * + * 核对物料资源是否足够 + * TUBE + * TO_BE_PROCESSED --> PRE_PROCESSING + */ +@Component +public class SEQ5_PROCESS extends A8kStepAction { + static Logger logger = LoggerFactory.getLogger(SEQ5_PROCESS.class); + + SEQ5_PROCESS() { + super(A8kActionStepType.SEQ5_PROCESS); + } + + @Resource + GStateService gstate; + + @Resource + AppExceptionBuilder ebuilder; + + @Resource + TubeProcessStateMgrService tubeProcessStateMgrService; + + @Resource + IncubationPlateMgrService incubationPlateMgrService; + + @Resource + CondtionMgrService cms; + + + MainFlowCtrlState state; + + @PostConstruct + void init() { + state = gstate.mainFlowCtrlState; + } + + @Override public void doaction() throws AppException { + // + // 1.准备3份反应板夹 + // 2.取tip头 + // 3.摇匀,脱帽 + // + tubeProcessStateMgrService.setCurTubeState(TubeState.PROCESSING); + Tube tube = gstate.getCurProcessingTube(); + OS.forceSleep(3000); + tubeProcessStateMgrService.setCurTubeState(TubeState.PROCESSED); + incubationPlateMgrService.startIncubating(tube); + logger.info("pre process success"); + } + + + @Override public Boolean checkCondition() { + return cms.isTimeToProcessTube(); + } + + @Override public List getResourceList() { + return List.of( + A8kPublicResourceType.IncubationPlateMotor, + A8kPublicResourceType.HBOT, + A8kPublicResourceType.CurTubeProcessToken + ); + } + + // + // UTILS + // + + void wait(Future future) { + while (!future.isDone()) { + OS.forceSleep(100); + } + } +} diff --git a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ6_POST_PROCESS.java b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ6_POST_PROCESS.java new file mode 100644 index 0000000..eab4b97 --- /dev/null +++ b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ6_POST_PROCESS.java @@ -0,0 +1,95 @@ +package a8k.service.appctrl.action.mainflow; + +import a8k.OS; +import a8k.baseservice.AppExceptionBuilder; +import a8k.service.appctrl.CondtionMgrService; +import a8k.service.appctrl.action.base.A8kActionStepType; +import a8k.service.appctrl.action.base.A8kStepAction; +import a8k.service.appstate.*; +import a8k.service.appstate.resource.A8kPublicResourceType; +import a8k.service.appstate.type.MainFlowCtrlState; +import a8k.service.appstate.type.Tube; +import a8k.service.appstate.type.state.TubeState; +import a8k.type.ecode.AppError; +import a8k.type.exception.AppException; +import a8k.utils.ZFnCall; +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.*; + +/** + * + * 核对物料资源是否足够 + * TUBE + * TO_BE_PROCESSED --> PRE_PROCESSING + */ +@Component +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 + AppExceptionBuilder ebuilder; + + @Resource + TubeProcessStateMgrService tubeProcessStateMgrService; + + @Resource + IncubationPlateMgrService incubationPlateMgrService; + + @Resource + CondtionMgrService cms; + + + ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); + + + MainFlowCtrlState state; + + @PostConstruct + void init() { + state = gstate.mainFlowCtrlState; + } + + @Override public void doaction() throws AppException { + tubeProcessStateMgrService.setCurTubeState(TubeState.POST_PROCESSING); + Tube tube = gstate.getCurProcessingTube(); + OS.forceSleep(3000); + tubeProcessStateMgrService.setCurTubeState(TubeState.POST_PROCESSED); + } + + @Override public Boolean checkCondition() { + return cms.isTimeToPostProcessTube(); + } + + @Override public List getResourceList() { + return List.of( + A8kPublicResourceType.IncubationPlateMotor, + A8kPublicResourceType.PlatesBoxMotor, + A8kPublicResourceType.HBOT, + A8kPublicResourceType.CurTubeProcessToken + ); + } + + // + // UTILS + // + + void wait(Future future) { + while (!future.isDone()) { + OS.forceSleep(100); + } + } +} diff --git a/src/main/java/a8k/service/appctrl/action/mainflow/SEQ7_EJECT_TUBEHOLDER.java b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ7_EJECT_TUBEHOLDER.java new file mode 100644 index 0000000..5e40c7b --- /dev/null +++ b/src/main/java/a8k/service/appctrl/action/mainflow/SEQ7_EJECT_TUBEHOLDER.java @@ -0,0 +1,61 @@ +package a8k.service.appctrl.action.mainflow; + +import a8k.service.appctrl.CondtionMgrService; +import a8k.service.appctrl.action.base.A8kActionStepType; +import a8k.service.appctrl.action.base.A8kStepAction; +import a8k.service.appstate.GStateService; +import a8k.service.appstate.type.MainFlowCtrlState; +import a8k.service.appstate.resource.A8kPublicResourceType; +import a8k.service.appstate.type.state.A8kWorkState; +import a8k.service.appstate.type.state.TubeHolderState; +import a8k.service.devicedriver.ctrl.SampleScanTransportCtrl; +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; + +@Component +public class SEQ7_EJECT_TUBEHOLDER extends A8kStepAction { + static Logger logger = LoggerFactory.getLogger(SEQ7_EJECT_TUBEHOLDER.class); + + SEQ7_EJECT_TUBEHOLDER() { + super(A8kActionStepType.SEQ7_EJECT_TUBEHOLDER); + } + + @Resource + GStateService gstate; + @Resource + SampleScanTransportCtrl stc; + + MainFlowCtrlState state; + + @Resource + CondtionMgrService cms; + + @PostConstruct + void init() { + state = gstate.mainFlowCtrlState; + } + + @Override public void doaction() throws AppException { + stc.ejectTubeHolder(); + stc.moveTubeRackMoveToEnterPos(); + gstate.getTubeHolder().state = TubeHolderState.IDLE; + } + + @Override public Boolean checkCondition() { + //处于工作状态,试管架已经处于空闲状态,入料光电被触发 + Boolean cond1 = cms.isCanDoAction(); + Boolean cond2 = gstate.getTubeHolder().state.equals(TubeHolderState.PROCESSING); + Boolean cond3 = cms.isNoMoreTubeToBeProcessed(); + return cond1 & cond2 & cond3; + } + + @Override public List getResourceList() { + return List.of(A8kPublicResourceType.SampleTransferXMotor); + } +} diff --git a/src/main/java/a8k/service/appctrl/scheduler/MainFlowCtrlScheduler.java b/src/main/java/a8k/service/appctrl/scheduler/MainFlowCtrlScheduler.java index 16882a2..93de5c8 100644 --- a/src/main/java/a8k/service/appctrl/scheduler/MainFlowCtrlScheduler.java +++ b/src/main/java/a8k/service/appctrl/scheduler/MainFlowCtrlScheduler.java @@ -60,8 +60,6 @@ public class MainFlowCtrlScheduler { A8kEcodePostProcesser ecodePostProcesser; A8kEcodeClearProcesser ecodeClearProcesser; - Boolean clearErrorPendingFlag = false; //清除错误请求标志 - List stepActionList = new ArrayList<>(); @PostConstruct @@ -270,11 +268,6 @@ public class MainFlowCtrlScheduler { while (workThread.isAlive()) { if (state.fatalErrorFlag) { OS.forceSleep(800); - } else if (clearErrorPendingFlag) { - clearError(); - OS.forceSleep(800); - } else if (state.errorFlag) { - OS.forceSleep(800); } else { doActions(guessWhatToDo()); OS.forceSleep(800); diff --git a/src/main/java/a8k/service/appstate/GStateService.java b/src/main/java/a8k/service/appstate/GStateService.java index 94bc5d4..5c1d93d 100644 --- a/src/main/java/a8k/service/appstate/GStateService.java +++ b/src/main/java/a8k/service/appstate/GStateService.java @@ -44,6 +44,8 @@ public class GStateService { //当前正在处理的试管 Tube curProcessingTube = null; + public Boolean debugMode = true; + //主流程控制状态 public MainFlowCtrlState mainFlowCtrlState = new MainFlowCtrlState(); diff --git a/src/main/java/a8k/service/appstate/IncubationPlateMgrService.java b/src/main/java/a8k/service/appstate/IncubationPlateMgrService.java index f201fbf..bfdc762 100644 --- a/src/main/java/a8k/service/appstate/IncubationPlateMgrService.java +++ b/src/main/java/a8k/service/appstate/IncubationPlateMgrService.java @@ -4,6 +4,8 @@ import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; import a8k.controler.extapi.utils.ExtApiTab; import a8k.hardware.type.a8kcanprotocol.A8kEcode; import a8k.service.appstate.type.IncubationSubTank; +import a8k.service.appstate.type.ProjProcessContext; +import a8k.service.appstate.type.Tube; import a8k.service.appstate.type.state.IncubationSubTankState; import a8k.type.IncubatorPos; import jakarta.annotation.Resource; @@ -55,6 +57,7 @@ public class IncubationPlateMgrService { return ret; } + synchronized public void setIncubationPlateState(IncubatorPos pos, IncubationSubTankState state) { var incubationState = gstate.getIncubationPlate(); var subtanks = incubationState.subtanks; @@ -73,6 +76,32 @@ public class IncubationPlateMgrService { } } + + synchronized public void waitingForDrop(Tube tube) { + var incubationState = gstate.getIncubationPlate(); + var subtanks = incubationState.subtanks; + + for (ProjProcessContext context : tube.projProcessContexts) { + subtanks[context.incubatorPos.off].state = IncubationSubTankState.WAITING_FOR_DROP; + subtanks[context.incubatorPos.off].projProcessContxt = context; + subtanks[context.incubatorPos.off].bloodType = tube.bloodType; + subtanks[context.incubatorPos.off].sampleBarcode = tube.sampleBarcode; + subtanks[context.incubatorPos.off].userid = tube.userid; + subtanks[context.incubatorPos.off].projIndex = context.projIndex; + subtanks[context.incubatorPos.off].projName = context.projName; + } + } + + synchronized public void startIncubating(Tube tube){ + var incubationState = gstate.getIncubationPlate(); + var subtanks = incubationState.subtanks; + + for (ProjProcessContext context : tube.projProcessContexts) { + subtanks[context.incubatorPos.off].state = IncubationSubTankState.INCUBATING; + } + + } + synchronized public void setIncubationPlateStateError(IncubatorPos pos, A8kEcode ecode) { var incubationState = gstate.getIncubationPlate(); var subtanks = incubationState.subtanks; diff --git a/src/main/java/a8k/service/appstate/TubeProcessContextMgrService.java b/src/main/java/a8k/service/appstate/TubeProcessContextMgrService.java index 51c6cb0..46a0949 100644 --- a/src/main/java/a8k/service/appstate/TubeProcessContextMgrService.java +++ b/src/main/java/a8k/service/appstate/TubeProcessContextMgrService.java @@ -122,9 +122,11 @@ public class TubeProcessContextMgrService { } - synchronized public void createProjProcessContext(@NotNull Tube tube, @NotNull A8kIdCardInfo idCardInfo,@NotNull Consumable consumable, @NotNull List tipPos, @NotNull IncubatorPos incubatorPos) { + synchronized public void createProjProcessContext(@NotNull Tube tube, @NotNull A8kIdCardInfo idCardInfo, @NotNull Consumable consumable, @NotNull List tipPos, + @NotNull IncubatorPos incubatorPos) { ProjProcessContext context = new ProjProcessContext(); context.projIndex = idCardInfo.projIndex; + context.projName = idCardInfo.projName; context.a8kIdCardInfo = idCardInfo; context.consumable = consumable; context.incubatorPos = incubatorPos; @@ -134,4 +136,6 @@ public class TubeProcessContextMgrService { tube.projProcessContexts.add(context); } + + } diff --git a/src/main/java/a8k/service/appstate/TubeProcessStateMgrService.java b/src/main/java/a8k/service/appstate/TubeProcessStateMgrService.java index 4802c42..19b784f 100644 --- a/src/main/java/a8k/service/appstate/TubeProcessStateMgrService.java +++ b/src/main/java/a8k/service/appstate/TubeProcessStateMgrService.java @@ -20,20 +20,23 @@ public class TubeProcessStateMgrService { @Resource TubeProcessContextMgrService tubeProcessContextMgrService; + + synchronized public void setCurTubeState(TubeState state) { Tube tube = gstate.getCurProcessingTube(); assert tube != null; + tube.state = state; } - synchronized public void startProcessTube(@NotNull List idCardInfo, @NotNull List consumable, @NotNull List> tipPos, + synchronized public void setTubeResourceIsReady(@NotNull List idCardInfo, @NotNull List consumable, @NotNull List> tipPos, @NotNull List incubatorPos) { Tube tube = gstate.getCurProcessingTube(); assert tube != null; for (int i = 0; i < tube.projIndex.size(); i++) { tubeProcessContextMgrService.createProjProcessContext(tube, idCardInfo.get(i), consumable.get(i), tipPos.get(i), incubatorPos.get(i)); } - tube.state = TubeState.PRE_PROCESSING; + tube.state = TubeState.RESOURCE_IS_READY; } synchronized public void pendingTube(Tube tube) { diff --git a/src/main/java/a8k/service/appstate/type/IncubationSubTank.java b/src/main/java/a8k/service/appstate/type/IncubationSubTank.java index 6cb550e..b5a6cbd 100644 --- a/src/main/java/a8k/service/appstate/type/IncubationSubTank.java +++ b/src/main/java/a8k/service/appstate/type/IncubationSubTank.java @@ -21,6 +21,9 @@ public class IncubationSubTank { public Integer projIndex = 0; //项目代码 public String projName = ""; //项目名称 + // + public ProjProcessContext projProcessContxt; + //孵育时间 public Date startIncubatedTime; //开始孵育时间 public Integer targetIncubatedTimeS; //目标孵育时间 diff --git a/src/main/java/a8k/service/appstate/type/ProjProcessContext.java b/src/main/java/a8k/service/appstate/type/ProjProcessContext.java index f692a4e..14b62f4 100644 --- a/src/main/java/a8k/service/appstate/type/ProjProcessContext.java +++ b/src/main/java/a8k/service/appstate/type/ProjProcessContext.java @@ -12,6 +12,7 @@ public class ProjProcessContext { public String sampleId; //样本ID-系统生成-唯一标识一个样本 public Integer projIndex;//项目代码 + public String projName; public A8kIdCardInfo a8kIdCardInfo;//a8k卡信息 public Consumable consumable;//耗材绑定的通道号 public IncubatorPos incubatorPos;//孵育位置 diff --git a/src/main/java/a8k/service/appstate/type/Tube.java b/src/main/java/a8k/service/appstate/type/Tube.java index 4e692db..b868631 100644 --- a/src/main/java/a8k/service/appstate/type/Tube.java +++ b/src/main/java/a8k/service/appstate/type/Tube.java @@ -19,10 +19,11 @@ public class Tube { public String sampleBarcode = ""; //用于请求用户信息的条码ID public String userid = ""; //用户输入的样本ID,不做逻辑,只做展示 public List projIndex = new ArrayList<>(); //项目代码 + public List projName = new ArrayList<>(); //项目名称 // public TubeState state = TubeState.EMPTY; //样本被处理的状态 public List projProcessContexts; - public A8kEcode ecode = null; + public A8kEcode ecode = null; } diff --git a/src/main/java/a8k/service/appstate/type/state/TubeState.java b/src/main/java/a8k/service/appstate/type/state/TubeState.java index 9966083..a93f868 100644 --- a/src/main/java/a8k/service/appstate/type/state/TubeState.java +++ b/src/main/java/a8k/service/appstate/type/state/TubeState.java @@ -7,6 +7,7 @@ public enum TubeState { EMPTY,//空 TO_BE_PROCESSED,//待处理 PENDING,//挂起的试管,即下一个被处理的试管 + RESOURCE_IS_READY,//资源准备好 PRE_PROCESSING, //预处理 PRE_PROCESSED, //预处理结束 PROCESSING,//处理