diff --git a/app.db b/app.db index c2281b1..e7f5075 100644 Binary files a/app.db and b/app.db differ diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java index 4ebb9df..a3798e3 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java @@ -48,9 +48,6 @@ public class CondtionMgrService { } } - public Boolean isNoMoreTubeToBeProcessed() { - return !gstate.getTubeHolder().isHasTubeToBeProcessed(); - } public Boolean isCanDoAction() { return gstate.mainFlowCtrlState.workState.equals(A8kWorkState.WORKING) && !gstate.mainFlowCtrlState.errorFlag && !gstate.mainFlowCtrlState.workStateChangeFlag; @@ -72,7 +69,7 @@ public class CondtionMgrService { public Boolean isTimeToEnterNewTubeHolder() { Boolean cond0 = isCanDoAction(); //试管架处于空闲状态 - Boolean cond1 = gstate.getTubeHolder().state.equals(TubeHolderState.IDLE); + Boolean cond1 = gstate.getTubeHolder().getState().equals(TubeHolderState.IDLE); //入料通道是否为空 Boolean cond2 = getTubeholderEnterPosPPS(); return cond0 && cond1 && cond2; @@ -151,7 +148,14 @@ public class CondtionMgrService { Tube tube = gstate.getCurProcessingTube(); if (tube == null) return false; - return gstate.getEmergencyTubePos().tube.getState().equals(TubeState.ERROR); + return gstate.getCurProcessingTube().getState().equals(TubeState.ERROR); + } + + public Boolean isHasPostProcessedTube() { + Tube tube = gstate.getCurProcessingTube(); + if (tube == null) + return false; + return gstate.getCurProcessingTube().getState().equals(TubeState.POST_PROCESSED); } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java index 2441402..28574ec 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java @@ -12,6 +12,7 @@ import a8k.service.app.appstate.ResourceMgrService; import a8k.service.app.appstate.type.MainFlowCtrlState; import a8k.service.app.appstate.type.state.A8kWorkState; import a8k.type.exception.AppException; +import a8k.utils.ZStringUtils; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import org.slf4j.Logger; @@ -118,15 +119,18 @@ public class MainFlowCtrlScheduler { A8kErrorContext callFn(A8kStepAction key) { + logger.info("----------------------{}---------------------->", ZStringUtils.leftAlignStr(key.step.name(), '-', 35)); + logger.info("Relate {} ", key.logCxtState()); beforeDoWhat(key.step); try { - logger.info("执行动作:{} ++++++++++++++++++++", key.step); key.doaction(); - logger.info("执行动作完成:{} +++++++", key.step); return new A8kErrorContext(key.step, null); } catch (AppException appe) { return new A8kErrorContext(key.step, appe.error); + } finally { + logger.info("{}------<", ZStringUtils.leftAlignStr(key.step.name(), '-', 35)); } + } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java index 39165c6..76fd1a3 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java @@ -27,7 +27,7 @@ public class DO_CLEAR_ERROR_BEFORE_WORK extends A8kStepAction { } @Resource - GStateService gstate; + GStateService gstate; @Resource CondtionMgrService cms; @Resource @@ -65,4 +65,5 @@ public class DO_CLEAR_ERROR_BEFORE_WORK extends A8kStepAction { A8kPublicResourceType.PlatesBoxModule ); } + } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_TUBE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java similarity index 76% rename from src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_TUBE.java rename to src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java index 23101b2..3205bc0 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_TUBE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java @@ -26,11 +26,11 @@ import java.util.List; * 处理错误的试管 */ @Component -public class DO_PROCESS_ERROR_TUBE extends A8kStepAction { - static Logger logger = LoggerFactory.getLogger(DO_PROCESS_ERROR_TUBE.class); +public class DO_FINISH_TUBE_PROCESS extends A8kStepAction { + static Logger logger = LoggerFactory.getLogger(DO_FINISH_TUBE_PROCESS.class); - DO_PROCESS_ERROR_TUBE() { - super(A8kActionStepType.DO_PROCESS_ERROR_TUBE); + DO_FINISH_TUBE_PROCESS() { + super(A8kActionStepType.DO_FINISH_TUBE_PROCESS); } @Resource @@ -60,6 +60,10 @@ public class DO_PROCESS_ERROR_TUBE extends A8kStepAction { Tube tube = gstate.getCurProcessingTube(); assert tube != null; + if(tube.getState().equals(TubeState.POST_PROCESSED)){ + projectProcessContextMgrService.finishedTubeProcess(); + return; + } if (appDebugHelper.isDebug()) { logger.info("处理错误试管:{}", tube.getSampleId()); @@ -70,12 +74,12 @@ public class DO_PROCESS_ERROR_TUBE extends A8kStepAction { //复位HBOT OS.forceSleep(4000); } - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PROCESS_COMPLETE); + projectProcessContextMgrService.finishedTubeProcess(); } @Override public Boolean checkCondition() { Boolean cond1 = cms.isCanDoAction(); - Boolean cond2 = cms.isHasSomeErrorTubeToBeProcessed(); + Boolean cond2 = cms.isHasSomeErrorTubeToBeProcessed() || cms.isHasPostProcessedTube(); return cond1 && cond2; } @@ -85,4 +89,11 @@ public class DO_PROCESS_ERROR_TUBE extends A8kStepAction { A8kPublicResourceType.HBOT ); } + + @Override public String logCxtState() { + var tube = gstate.getCurProcessingTube(); + if (tube == null) + return ""; + return String.format("[sid: %s, tanpos: %s]", tube.getSampleId(), tube.getPos()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java index de1a6ed..68013cd 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java @@ -7,6 +7,7 @@ import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; import a8k.service.app.appstate.GStateService; import a8k.service.app.appstate.IncubationPlateStateMgrService; import a8k.service.app.appstate.OptScanModuleStateMgrService; +import a8k.service.app.appstate.ProjectProcessContextMgrService; import a8k.service.app.appstate.resource.A8kPublicResourceType; import a8k.service.app.appstate.type.IncubationSubTank; import a8k.service.app.appstate.type.MainFlowCtrlState; @@ -33,15 +34,17 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction { } @Resource - GStateService gstate; + GStateService gstate; @Resource - CondtionMgrService cms; + CondtionMgrService cms; @Resource - IncubationPlateStateMgrService incubationPlateStateMgrService; + IncubationPlateStateMgrService incubationPlateStateMgrService; @Resource - OptScanModuleStateMgrService optScanModuleStateMgrService; + OptScanModuleStateMgrService optScanModuleStateMgrService; @Resource - AppDebugHelperService appDebugHelperService; + AppDebugHelperService appDebugHelperService; + @Resource + ProjectProcessContextMgrService projectProcessContextMgrService; MainFlowCtrlState mfcs; @@ -68,8 +71,8 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction { OS.forceSleep(3000); } // - optScanModuleStateMgrService.newPlateToOptScanPos(errorTank); - optScanModuleStateMgrService.dropPlate(); + projectProcessContextMgrService.newPlateToOptScanPos(errorTank); + projectProcessContextMgrService.dropPlate(); incubationPlateStateMgrService.resetIncubatorPos(errorTank.getPos()); } } @@ -82,6 +85,14 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction { } @Override public List getResourceList() { - return List.of(); + return List.of(A8kPublicResourceType.OPTModule, A8kPublicResourceType.IncubationPlateModule); + } + + @Override public String logCxtState() { + var errorTank = incubationPlateStateMgrService.getErrorPlate(); + if (errorTank == null) { + return ""; + } + return String.format("[sid: %s, proj: %s tanpos: %s]", errorTank.getSampleId(), errorTank.getProjIndex(), errorTank.getPos()); } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_RESUME.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_RESUME.java index c15cbbe..c5e5b39 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_RESUME.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_RESUME.java @@ -47,4 +47,5 @@ public class DO_RESUME extends A8kStepAction { @Override public List getResourceList() { return List.of(); } + } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java index cd20628..f9de5de 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java @@ -66,20 +66,17 @@ public class PLATE_OPT_SCAN extends A8kStepAction { OptScanModule optScanModule = gstate.getOptScanModule(); ProjProcessContext ctx = projectProcessContextMgrService.getProjProcessContext(optScanModule.getSampleId(), optScanModule.getProjIndex()); - optScanModuleStateMgrService.startScanPlate(); + projectProcessContextMgrService.startScanPlate(); logger.info("扫描板夹"); //记录扫描结果 if (appDebugHelper.isDebug()) { - logger.info("VIRTUAL_DO.扫描板夹成功"); OS.forceSleep(3000); } else { - } //修改板夹状态 - - projectProcessContextMgrService.changeContextStateTo(optScanModule.getSampleId(), optScanModule.getProjIndex(), ProjProcessState.FINISH); - optScanModuleStateMgrService.dropPlate(); + projectProcessContextMgrService.dropPlate(); + projectProcessContextMgrService.finishProcessProj(optScanModule.getSampleId(), optScanModule.getProjIndex()); reactionRecordMgrService.addRecord(ctx, new ReactionResult(ReactionResultStatus.SUCCESS, "12.8 mg/L"), new ReactionResult(ReactionResultStatus.ERROR_RESULT_OUT_OF_RANGE, "")); @@ -96,4 +93,9 @@ public class PLATE_OPT_SCAN extends A8kStepAction { A8kPublicResourceType.OPTModule ); } + + @Override public String logCxtState() { + OptScanModule optScanModule = gstate.getOptScanModule(); + return String.format("[sid: %s, proj:%s ]", optScanModule.getSampleId(), optScanModule.getProjInfoStr()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java index ad63e88..6693522 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java @@ -7,9 +7,12 @@ import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; import a8k.service.app.appstate.GStateService; import a8k.service.app.appstate.IncubationPlateStateMgrService; import a8k.service.app.appstate.OptScanModuleStateMgrService; +import a8k.service.app.appstate.ProjectProcessContextMgrService; import a8k.service.app.appstate.resource.A8kPublicResourceType; +import a8k.service.app.appstate.type.IncubationPlate; import a8k.service.app.appstate.type.IncubationSubTank; import a8k.service.app.appstate.type.MainFlowCtrlState; +import a8k.service.app.appstate.type.ProjProcessContext; import a8k.service.app.appstate.type.state.IncubationSubTankState; import a8k.service.debug.AppDebugHelperService; import a8k.type.exception.AppException; @@ -33,15 +36,17 @@ public class PROCESS_INCUBATE_COMPLETED_PLATE extends A8kStepAction { } @Resource - GStateService gstate; + GStateService gstate; @Resource - CondtionMgrService cms; + CondtionMgrService cms; @Resource - IncubationPlateStateMgrService incubationPlateStateMgrService; + IncubationPlateStateMgrService incubationPlateStateMgrService; @Resource - OptScanModuleStateMgrService optScanModuleStateMgrService; + OptScanModuleStateMgrService optScanModuleStateMgrService; @Resource - AppDebugHelperService appDebugHelper; + AppDebugHelperService appDebugHelper; + @Resource + ProjectProcessContextMgrService projectProcessContextMgrService; MainFlowCtrlState mfcs; @@ -51,24 +56,27 @@ public class PROCESS_INCUBATE_COMPLETED_PLATE extends A8kStepAction { mfcs = gstate.mainFlowCtrlState; } + IncubationSubTank getToBeProcessedTank() { + return incubationPlateStateMgrService.getOneExpiredPlate(); + } + @Override public void doaction() throws AppException { - IncubationSubTank tank = incubationPlateStateMgrService.getOneExpiredPlate(); + IncubationSubTank tank = getToBeProcessedTank(); if (tank == null) { return; } if (appDebugHelper.isDebug()) { - logger.info("VIRTUAL_DO.推出板夹到光学模组,{}", tank.getPos()); OS.forceSleep(3000); } - optScanModuleStateMgrService.newPlateToOptScanPos(tank); + projectProcessContextMgrService.newPlateToOptScanPos(tank); incubationPlateStateMgrService.resetIncubatorPos(tank.getPos()); } @Override public Boolean checkCondition() { Boolean cond1 = cms.isCanDoAction(); - Boolean cond2 = incubationPlateStateMgrService.isHasExpiredPlate(); + Boolean cond2 = getToBeProcessedTank() != null; Boolean cond3 = optScanModuleStateMgrService.isEmpty(); return cond1 && cond2 && cond3; } @@ -79,4 +87,11 @@ public class PROCESS_INCUBATE_COMPLETED_PLATE extends A8kStepAction { A8kPublicResourceType.IncubationPlateModule ); } + + @Override public String logCxtState() { + IncubationSubTank tank = getToBeProcessedTank(); + if (tank == null) + return ""; + return String.format("[sid:%s, proj:%s tanpos:%s]", tank.getSampleId(), tank.getProjInfoStr(), tank.getPos()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java index 7425c4b..dfc3d18 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java @@ -5,7 +5,6 @@ import a8k.service.app.appstate.ProjectProcessContextMgrService; import a8k.service.app.appstate.type.Tube; import a8k.service.bases.AppEventBusService; import a8k.service.bases.appevent.AppWarningNotifyEvent; -import a8k.hardware.A8kCanBusService; import a8k.hardware.type.a8kcanprotocol.A8kEcode; import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; import a8k.service.app.appctrl.TubeSettingMgrService; @@ -187,7 +186,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { } } //设置试管架状态 - tubeholder.state = TubeHolderState.PROCESSING; + tubeholder.setState(TubeHolderState.PROCESSING); //删除之前的试管架配置 tubeSettingMgrService.removeTubeHolderSetting(setting); return tubeholder; @@ -226,7 +225,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { } logger.info("更新试管架状态"); - projectProcessContextMgrService.addNewTubeHolder(tubeholder); + projectProcessContextMgrService.newTubeHolder(tubeholder); } @Override public Boolean checkCondition() { diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java index 545fb0e..cbb0002 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java @@ -72,7 +72,6 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction { public void moveToNextTube(Integer tubeIndex) throws AppException { if (appDebugHelperService.isDebug()) { - logger.info("VIRTUAL.DO,移动到下一个试管:{}", tubeIndex); OS.forceSleep(1000); } else { sstc.moveTubeToPreProcessPos(tubeIndex); @@ -106,7 +105,7 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction { logger.info("处理下一个试管:{}", nextProcessTube.getSampleId()); moveToNextTube(nextTubeIndex); } - projectProcessContextMgrService.changeTubeStateToPending(nextProcessTube); + projectProcessContextMgrService.pendingTube(nextProcessTube); } @Override public Boolean checkCondition() { diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java index 1bd9c60..9903671 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java @@ -57,10 +57,11 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { @Override public void doaction() throws AppException { Tube tube = gstate.getCurProcessingTube(); + projectProcessContextMgrService.startPrepareRecourseOK(); assert tube != null; - boolean applyConsumable = projectProcessContextMgrService.takeConsumable(tube); - boolean applyTips = applyConsumable && projectProcessContextMgrService.takeTip(tube); - boolean applyIncubatorPos = applyTips && projectProcessContextMgrService.takeIncubatorPos(tube); + boolean applyConsumable = projectProcessContextMgrService.takeResourceConsumable(tube); + boolean applyTips = applyConsumable && projectProcessContextMgrService.takeResourceTip(tube); + boolean applyIncubatorPos = applyTips && projectProcessContextMgrService.takeResourceIncubatorPos(tube); if (!applyConsumable) { for (Integer projIndex : tube.getProjIndex()) { @@ -82,12 +83,12 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { assert applyIncubatorPos; logger.info("Tube:{} 申请资源成功", tube.getSampleId()); - boolean assProjInfoSuc = projectProcessContextMgrService.checkAndAssignProjInfo(tube); + boolean assProjInfoSuc = projectProcessContextMgrService.prepareProjInfoData(tube); assert assProjInfoSuc; //创建项目处理上下文 - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.RESOURCE_IS_READY); + projectProcessContextMgrService.prepareRecourseOK(); logger.info("apply resource ok"); } @@ -98,4 +99,12 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { @Override public List getResourceList() { return List.of(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()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java index 344d4ce..b605bd4 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java @@ -161,6 +161,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { // 2.取tip头 // 3.摇匀,脱帽 // + projectProcessContextMgrService.startTubePreProcessing(); Tube tube = gstate.getCurProcessingTube(); //准备反应板夹 @@ -187,10 +188,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { throw ebuilder.buildMutiErrorAppException(errors); } - projectProcessContextMgrService.changeContextStateTo(gstate.getCurProcessingTube(), ProjProcessState.PROCESS); - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PRE_PROCESSED); - projectProcessContextMgrService.changeTubeAssociatedReactionPlateStateTo(gstate.getCurProcessingTube(), IncubationSubTankState.WAITING_FOR_DROP); - logger.info("pre process success"); + projectProcessContextMgrService.tubePreProcessingOK(); } @@ -215,4 +213,12 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { 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()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java index 8eb2785..2667044 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java @@ -9,6 +9,7 @@ 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.MainFlowCtrlState; +import a8k.service.app.appstate.type.ProjProcessContext; import a8k.service.app.appstate.type.Tube; import a8k.service.app.appstate.type.state.TubeState; import a8k.type.exception.AppException; @@ -23,9 +24,9 @@ import java.util.concurrent.*; /** * - * 核对物料资源是否足够 - * TUBE - * TO_BE_PROCESSED --> PRE_PROCESSING + * 核对物料资源是否足够 + * TUBE + * TO_BE_PROCESSED --> PRE_PROCESSING */ @Component public class SEQ5_PROCESS extends A8kStepAction { @@ -36,17 +37,16 @@ public class SEQ5_PROCESS extends A8kStepAction { } @Resource - GStateService gstate; + GStateService gstate; @Resource - AppExceptionBuilder ebuilder; + AppExceptionBuilder ebuilder; @Resource - IncubationPlateStateMgrService incubationPlateStateMgrService; + IncubationPlateStateMgrService incubationPlateStateMgrService; @Resource - CondtionMgrService cms; + CondtionMgrService cms; @Resource ProjectProcessContextMgrService projectProcessContextMgrService; - MainFlowCtrlState state; @PostConstruct @@ -54,41 +54,54 @@ public class SEQ5_PROCESS extends A8kStepAction { state = gstate.mainFlowCtrlState; } - @Override public void doaction() throws AppException { + @Override + public void doaction() throws AppException { // - // 1.准备3份反应板夹 - // 2.取tip头 - // 3.摇匀,脱帽 + // 1.准备3份反应板夹 + // 2.取tip头 + // 3.摇匀,脱帽 // - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PROCESSING); - - Tube tube = gstate.getCurProcessingTube(); - logger.info("处理试管 {}", tube.getSampleId()); + var tube = gstate.getCurProcessingTube(); + projectProcessContextMgrService.startProcessTube(); OS.forceSleep(3000); - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PROCESSED); - projectProcessContextMgrService.changeTubeAssociatedReactionPlateStateToINCUBATING(gstate.getCurProcessingTube()); - projectProcessContextMgrService.changeContextStateTo(gstate.getCurProcessingTube(), ProjProcessState.INCUBATING); - } + List projList = tube.getProjIndex(); + for (Integer projIndex : projList) { + ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(), + projIndex); + projectProcessContextMgrService.startIncubating(cxt); + } + projectProcessContextMgrService.processIngTubeOK(); + } - @Override public Boolean checkCondition() { + @Override + public Boolean checkCondition() { return cms.isTimeToProcessTube(); } - @Override public List getResourceList() { + @Override + public List getResourceList() { return List.of( A8kPublicResourceType.IncubationPlateModule, A8kPublicResourceType.HBOT, - A8kPublicResourceType.CurTubeProcessToken - ); + A8kPublicResourceType.CurTubeProcessToken); } // - // UTILS + // 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()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java index 3112520..cd889e1 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java @@ -60,10 +60,9 @@ public class SEQ6_POST_PROCESS extends A8kStepAction { } @Override public void doaction() throws AppException { - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.POST_PROCESSING); - Tube tube = gstate.getCurProcessingTube(); + projectProcessContextMgrService.postProcessTube(); OS.forceSleep(3000); - projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.POST_PROCESSED); + projectProcessContextMgrService.postProcessTubeOK(); } @Override public Boolean checkCondition() { @@ -88,4 +87,12 @@ public class SEQ6_POST_PROCESS extends A8kStepAction { 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()); + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java index d5a158f..f4c0052 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java @@ -49,18 +49,18 @@ public class SEQ7_EJECT_TUBEHOLDER extends A8kStepAction { SST_HControler.ejectTubeHolder(); SST_HControler.moveTubeRackMoveToEnterPos(); } else { - logger.info("VIRTUAL.DO:弹出试管架"); } - gstate.getTubeHolder().state = TubeHolderState.IDLE; + gstate.getTubeHolder().setState(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; + Boolean cond2 = gstate.getTubeHolder().getState().equals(TubeHolderState.PROCESSING); + Boolean cond3 = cms.isCurTubeProcessCompleted(); + Boolean cond4 = !cms.isHasSometubesToBeProcessed(); + return cond1 && cond2 && cond3 && cond4; } @Override public List getResourceList() { diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kActionStepType.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kActionStepType.java index cfa70b3..2b60f0b 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kActionStepType.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kActionStepType.java @@ -23,6 +23,6 @@ public enum A8kActionStepType { //Error DO_CLEAR_ERROR_BEFORE_WORK,//在启动前,清除错误 - DO_PROCESS_ERROR_TUBE,//处理异常的样本 + DO_FINISH_TUBE_PROCESS,//处理异常的样本 DO_PROCESS_ERROR_PLATE,//处理异常的孵育盘 } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kStepAction.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kStepAction.java index 579a26e..7c2fda4 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kStepAction.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kStepAction.java @@ -37,4 +37,8 @@ public class A8kStepAction { return true; } + public String logCxtState() { + return ""; + } + } diff --git a/src/main/java/a8k/service/app/appstate/EmergencySamplePosStateMgrService.java b/src/main/java/a8k/service/app/appstate/EmergencySamplePosStateMgrService.java index 910447d..a92f0a4 100644 --- a/src/main/java/a8k/service/app/appstate/EmergencySamplePosStateMgrService.java +++ b/src/main/java/a8k/service/app/appstate/EmergencySamplePosStateMgrService.java @@ -79,7 +79,7 @@ public class EmergencySamplePosStateMgrService { tube.setProjInfo(projInfo); tube.setState(TubeState.TO_BE_PROCESSED); - projectProcessContextMgrService.addNewEmergencyTubeHolder(tube); + projectProcessContextMgrService.newEmergencyTube(tube); logger.info("添加紧急样本设置成功 {}", ZJsonHelper.objectToJson(tube)); } else if (tube.getState().equals(TubeState.TO_BE_PROCESSED)) { projectProcessContextMgrService.updateEmergencyTubeCfg(userid, sampleBarcode, bloodType, projInfo); diff --git a/src/main/java/a8k/service/app/appstate/GStateService.java b/src/main/java/a8k/service/app/appstate/GStateService.java index 08c1d06..7e880bc 100644 --- a/src/main/java/a8k/service/app/appstate/GStateService.java +++ b/src/main/java/a8k/service/app/appstate/GStateService.java @@ -60,8 +60,8 @@ public class GStateService { return consumableState; } - public synchronized void setTubeHolder(TubeHolder state) { - this.tubeHolder = state; + public synchronized void setTubeHolder(TubeHolder tubeHolder) { + this.tubeHolder = tubeHolder; } public synchronized TubeHolder getTubeHolder() { @@ -72,8 +72,4 @@ public class GStateService { return mainFlowCtrlState.workState.equals(A8kWorkState.WORKING); } - public TubeHolderState getTubeHolderState() { - return tubeHolder.state; - } - } diff --git a/src/main/java/a8k/service/app/appstate/OptScanModuleStateMgrService.java b/src/main/java/a8k/service/app/appstate/OptScanModuleStateMgrService.java index 938d150..d767b94 100644 --- a/src/main/java/a8k/service/app/appstate/OptScanModuleStateMgrService.java +++ b/src/main/java/a8k/service/app/appstate/OptScanModuleStateMgrService.java @@ -13,21 +13,6 @@ public class OptScanModuleStateMgrService { @Resource GStateService gstate; - synchronized public void newPlateToOptScanPos(IncubationSubTank tank) { - OptScanModule optScanModule = gstate.getOptScanModule(); - optScanModule.state = OptScanModuleState.PLATE_IS_READY; - optScanModule.syncCfg(tank); - } - - synchronized public void dropPlate() { - OptScanModule optScanModule = gstate.getOptScanModule(); - optScanModule.state = OptScanModuleState.EMPTY; - } - - synchronized public void startScanPlate() { - OptScanModule optScanModule = gstate.getOptScanModule(); - optScanModule.state = OptScanModuleState.SCANNING; - } synchronized public Boolean isEmpty() { OptScanModule optScanModule = gstate.getOptScanModule(); diff --git a/src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java b/src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java index 6619d43..577bd9b 100644 --- a/src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java +++ b/src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java @@ -1,14 +1,15 @@ package a8k.service.app.appstate; import a8k.service.app.appdata.AppProjInfoMgrService; -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.appstate.type.*; import a8k.service.app.appstate.type.state.IncubationSubTankState; +import a8k.service.app.appstate.type.state.OptScanModuleState; import a8k.service.app.appstate.type.state.ProjProcessState; import a8k.service.app.appstate.type.state.TubeState; +import a8k.service.db.DeviceStatisticDBService; import a8k.service.db.SampleRecordDBService; import a8k.service.db.type.SampleRecord; +import a8k.service.db.type.StatisticType; import a8k.service.db.type.a8kidcard.zenum.A8kReactionFlowType; import a8k.type.ecode.AppError; import a8k.type.type.BloodType; @@ -36,44 +37,56 @@ public class ProjectProcessContextMgrService { IncubationPlateStateMgrService incubationPlateStateMgrService; @Resource AppProjInfoMgrService appProjInfoMgrService; + @Resource + DeviceStatisticDBService deviceStatisticDBService; List contexts = new ArrayList<>(); - private String generateSampleId(Integer tubePos, Boolean isEmergency) { + private String priGenerateSampleId(Integer tubePos, Boolean isEmergency) { String sampleid = ""; - Integer cnt = sampleRecordDBService.getRecordCntToday(); + Integer cnt = 0; Date date = new Date(); + if (isEmergency) { + cnt = deviceStatisticDBService.get(StatisticType.EmergencyTubeCnt); + } else { + cnt = deviceStatisticDBService.get(StatisticType.TubeHolderCnt); + } + SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); if (isEmergency) { sampleid = String.format("%s_%sE", sdf.format(date), cnt); } else { - sampleid = String.format("%s_%s", sdf.format(date), cnt); + sampleid = String.format("%s_%d%02d", sdf.format(date), cnt, tubePos + 1); } return sampleid; } - public void newSample(Tube tube) { - SampleRecord sampleRecord = new SampleRecord(); - sampleRecord.sampleid = generateSampleId(tube.getPos(), tube.getIsEmergency()); - sampleRecord.createDate = new Date(); - sampleRecord.bloodType = tube.getBloodType(); - sampleRecord.isEmergency = tube.getIsEmergency(); - sampleRecord.sampleBarcode = tube.getSampleBarcode(); - sampleRecord.userid = tube.getUserid(); - sampleRecord.projIndex = tube.getProjIndex(); - tube.setSampleId(sampleRecord.sampleid); - sampleRecordDBService.add(sampleRecord); + void priChangeReactionPlateStateTo(Tube tube, IncubationSubTankState state) { + var incubationState = gstate.getIncubationPlate(); + var subtanks = incubationState.subtanks; + List cxts = getTubeAssociatedProjContext(tube.getSampleId()); + for (ProjProcessContext cxt : cxts) { + subtanks[cxt.incubatorPos.off].state = state; + } + } + + void finishProcessProj(Tube tube, ProjProcessState state) { + List cxts = getTubeAssociatedProjContext(tube.getSampleId()); + for (ProjProcessContext cxt : cxts) { + cxt.state = state; + } } - private void newProjProcessContext(Tube tube) { + private void priNewProjProcessContext(Tube tube) { List projInfos = tube.getProjInfo(); for (ProjBriefInfo projInfo : projInfos) { ProjProcessContext projProcessContext = new ProjProcessContext(); projProcessContext.sampleId = tube.getSampleId(); + projProcessContext.state = ProjProcessState.INIT; projProcessContext.projIndex = projInfo.projIndex; projProcessContext.isHighTube = tube.getIsHighTube(); projProcessContext.isEmergency = tube.getIsEmergency(); @@ -89,7 +102,22 @@ public class ProjectProcessContextMgrService { } } - private void removeProjProcessContext(String sampleId) { + + public void priNewSample(Tube tube) { + SampleRecord sampleRecord = new SampleRecord(); + sampleRecord.sampleid = priGenerateSampleId(tube.getPos(), tube.getIsEmergency()); + sampleRecord.createDate = new Date(); + sampleRecord.bloodType = tube.getBloodType(); + sampleRecord.isEmergency = tube.getIsEmergency(); + sampleRecord.sampleBarcode = tube.getSampleBarcode(); + sampleRecord.userid = tube.getUserid(); + sampleRecord.projIndex = tube.getProjIndex(); + tube.setSampleId(sampleRecord.sampleid); + sampleRecordDBService.add(sampleRecord); + } + + + private void priRemoveProjProcessContext(String sampleId) { for (ProjProcessContext context : contexts) { if (context.sampleId.equals(sampleId)) { contexts.remove(context); @@ -144,17 +172,25 @@ public class ProjectProcessContextMgrService { * 添加新的试管架 * @param tubeholder 试管架 */ - synchronized public void addNewTubeHolder(TubeHolder tubeholder) { + synchronized public void newTubeHolder(TubeHolder tubeholder) { + deviceStatisticDBService.add(StatisticType.TubeHolderCnt, 1); + logger.info("添加新的试管架"); for (Tube tube : tubeholder.tubes) { - newSample(tube); - newProjProcessContext(tube); + if (tube.getState().equals(TubeState.EMPTY)) { + continue; + } + priNewSample(tube); + priNewProjProcessContext(tube); + logger.info(" 试管ID:{}", tube.getSampleId()); } gstate.setTubeHolder(tubeholder); } - synchronized public void addNewEmergencyTubeHolder(Tube tube) { - newSample(tube); - newProjProcessContext(tube); + synchronized public void newEmergencyTube(Tube tube) { + deviceStatisticDBService.add(StatisticType.EmergencyTubeCnt, 1); + priNewSample(tube); + priNewProjProcessContext(tube); + logger.info("添加新的急诊试管,试管ID:{}", tube.getSampleId()); } synchronized public void updateEmergencyTubeCfg(String userid, String sampleBarcode, BloodType bloodType, List projInfo) { @@ -165,8 +201,9 @@ public class ProjectProcessContextMgrService { tube.setSampleBarcode(sampleBarcode); tube.setProjInfo(projInfo); - removeProjProcessContext(tube.getSampleId()); - newProjProcessContext(tube); + priRemoveProjProcessContext(tube.getSampleId()); + priNewProjProcessContext(tube); + logger.info("更新急诊试管配置,试管ID:{}", tube.getSampleId()); } @@ -174,7 +211,23 @@ public class ProjectProcessContextMgrService { // List incubatorPoss = incubationPlateStateMgrService.takeIncubationIDLEPos(projs.size()); // List tips = consumablesMgrService.takeTip(projInfos.get(i).reactionFlowType); - synchronized public Boolean takeConsumable(Tube tube) { + + synchronized public void pendingTube(Tube tube) { + /** + * 挂起试管 + * @param nextProcessTube 下一个处理的试管 + */ + gstate.curProcessingTube = tube; + gstate.getCurProcessingTube().setState(TubeState.PENDING); + finishProcessProj(tube, ProjProcessState.PENDING); + } + + + synchronized public void startPrepareRecourseOK() { + } + + + synchronized public Boolean takeResourceConsumable(Tube tube) { for (Integer projIndex : tube.getProjIndex()) { ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex); assert cxt != null; @@ -186,7 +239,7 @@ public class ProjectProcessContextMgrService { return true; } - synchronized public Boolean takeIncubatorPos(Tube tube) { + synchronized public Boolean takeResourceIncubatorPos(Tube tube) { var incubationState = gstate.getIncubationPlate(); var subtanks = incubationState.subtanks; for (Integer projIndex : tube.getProjIndex()) { @@ -202,7 +255,7 @@ public class ProjectProcessContextMgrService { return true; } - synchronized public Boolean takeTip(Tube tube) { + synchronized public Boolean takeResourceTip(Tube tube) { for (Integer projIndex : tube.getProjIndex()) { ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex); assert cxt != null; @@ -215,19 +268,6 @@ public class ProjectProcessContextMgrService { return true; } - synchronized public Boolean checkAndAssignProjInfo(Tube tube) { - for (Integer projIndex : tube.getProjIndex()) { - ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex); - assert cxt != null; - cxt.projCfg = appProjInfoMgrService.getProjCfgByProjIndex(cxt.consumable.lotId); - if (cxt.projCfg == null) { - return false; - } - } - return true; - - } - synchronized public void bakAllTubeAResource(Tube tube) { for (Integer projIndex : tube.getProjIndex()) { ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex); @@ -247,28 +287,89 @@ public class ProjectProcessContextMgrService { } } - synchronized public void changeCurrentTubeStateTo(TubeState state) { - gstate.getCurProcessingTube().setState(state); + + synchronized public Boolean prepareProjInfoData(Tube tube) { + for (Integer projIndex : tube.getProjIndex()) { + ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex); + assert cxt != null; + cxt.projCfg = appProjInfoMgrService.getProjCfgByProjIndex(cxt.consumable.lotId); + if (cxt.projCfg == null) { + return false; + } + } + return true; } - synchronized public void changeTubeStateToPending(Tube tube) { - /** - * 挂起试管 - * @param nextProcessTube 下一个处理的试管 - */ - gstate.curProcessingTube = tube; - changeCurrentTubeStateTo(TubeState.PENDING); - changeContextStateTo(tube, ProjProcessState.PENDING); + synchronized public void prepareRecourseOK() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.RESOURCE_IS_READY); + finishProcessProj(tube, ProjProcessState.PROCESS); + } + synchronized public void startTubePreProcessing() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.PRE_PROCESSING); } - synchronized public void changeTubeAssociatedReactionPlateStateTo(Tube tube, IncubationSubTankState state) { - var incubationState = gstate.getIncubationPlate(); - var subtanks = incubationState.subtanks; - List cxts = getTubeAssociatedProjContext(tube.getSampleId()); - for (ProjProcessContext cxt : cxts) { - subtanks[cxt.incubatorPos.off].state = state; - } + synchronized public void tubePreProcessingOK() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.PRE_PROCESSED); + priChangeReactionPlateStateTo(tube, IncubationSubTankState.WAITING_FOR_DROP); + } + + + synchronized public void startProcessTube() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.PROCESSING); + } + + synchronized public void startIncubating(ProjProcessContext cxt) { + var subtanks = gstate.getIncubationPlate().subtanks; + cxt.state = ProjProcessState.INCUBATING; + subtanks[cxt.incubatorPos.off].state = IncubationSubTankState.INCUBATING; + subtanks[cxt.incubatorPos.off].startIncubatedTime = System.currentTimeMillis(); + subtanks[cxt.incubatorPos.off].incubatedTimeSec = cxt.projCfg.getReactionPlateIncubationTimeMin() * 60; + logger.info("{} 开始孵育,开始时间:{},孵育时间:{}s", subtanks[cxt.incubatorPos.off].getPos(), subtanks[cxt.incubatorPos.off].startIncubatedTime, + subtanks[cxt.incubatorPos.off].incubatedTimeSec); + } + + synchronized public void processIngTubeOK() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.PROCESSED); + } + + + synchronized public void postProcessTube() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.POST_PROCESSING); + } + + synchronized public void postProcessTubeOK() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.POST_PROCESSED); + } + + + synchronized public void newPlateToOptScanPos(IncubationSubTank tank) { + OptScanModule optScanModule = gstate.getOptScanModule(); + optScanModule.state = OptScanModuleState.PLATE_IS_READY; + optScanModule.syncCfg(tank); + } + + synchronized public void dropPlate() { + OptScanModule optScanModule = gstate.getOptScanModule(); + optScanModule.state = OptScanModuleState.EMPTY; + } + + synchronized public void startScanPlate() { + OptScanModule optScanModule = gstate.getOptScanModule(); + optScanModule.state = OptScanModuleState.SCANNING; + } + + synchronized public void finishProcessProj(String sampleId, Integer projIndex) { + ProjProcessContext cxt = getProjProcessContext(sampleId, projIndex); + assert cxt != null; + cxt.state = ProjProcessState.FINISH; } @@ -277,42 +378,24 @@ public class ProjectProcessContextMgrService { var subtanks = incubationState.subtanks; List cxts = getTubeAssociatedProjContext(tube.getSampleId()); - //设置 - changeCurrentTubeStateTo(TubeState.ERROR); + //设置试管状态为Error + gstate.getCurProcessingTube().setState(TubeState.ERROR); tube.setErrors(errors); + for (ProjProcessContext cxt : cxts) { - cxt.state = ProjProcessState.ERROR; - cxt.errors = errors; + //设置cxt状态为ERROR + cxt.state = ProjProcessState.ERROR; + cxt.errors = errors; + + //设置孵育子槽状态为ERROR subtanks[cxt.incubatorPos.off].state = IncubationSubTankState.ERROR; subtanks[cxt.incubatorPos.off].errors = errors; } } - - synchronized public void changeTubeAssociatedReactionPlateStateToINCUBATING(Tube tube) { - var incubationState = gstate.getIncubationPlate(); - var subtanks = incubationState.subtanks; - List cxts = getTubeAssociatedProjContext(tube.getSampleId()); - for (ProjProcessContext cxt : cxts) { - cxt.state = ProjProcessState.INCUBATING; - subtanks[cxt.incubatorPos.off].state = IncubationSubTankState.INCUBATING; - subtanks[cxt.incubatorPos.off].startIncubatedTime = System.currentTimeMillis(); - subtanks[cxt.incubatorPos.off].incubatedTimeSec = cxt.projCfg.getReactionPlateIncubationTimeMin() * 60; - logger.info("{} 开始孵育,开始时间:{},孵育时间:{}s", subtanks[cxt.incubatorPos.off].getPos(), subtanks[cxt.incubatorPos.off].startIncubatedTime, - subtanks[cxt.incubatorPos.off].incubatedTimeSec); - } + synchronized public void finishedTubeProcess() { + Tube tube = gstate.getCurProcessingTube(); + tube.setState(TubeState.PROCESS_COMPLETE); } - synchronized public void changeContextStateTo(Tube tube, ProjProcessState state) { - List cxts = getTubeAssociatedProjContext(tube.getSampleId()); - for (ProjProcessContext cxt : cxts) { - cxt.state = state; - } - } - - synchronized public void changeContextStateTo(String sampleId, Integer projIndex, ProjProcessState state) { - ProjProcessContext cxt = getProjProcessContext(sampleId, projIndex); - assert cxt != null; - cxt.state = state; - } } diff --git a/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java b/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java index 7b0fb09..1a39f70 100644 --- a/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java +++ b/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java @@ -63,5 +63,12 @@ public class IncubationSubTank { errors.clear(); } + public String getProjInfoStr() { + if (projInfo == null) { + return "null"; + } + return String.format("%s(%d)", projInfo.projShotName, projInfo.projIndex); + } + } diff --git a/src/main/java/a8k/service/app/appstate/type/OptScanModule.java b/src/main/java/a8k/service/app/appstate/type/OptScanModule.java index 5b702f7..f107686 100644 --- a/src/main/java/a8k/service/app/appstate/type/OptScanModule.java +++ b/src/main/java/a8k/service/app/appstate/type/OptScanModule.java @@ -29,6 +29,11 @@ public class OptScanModule { this.isErrorPlate = tank.state.equals(IncubationSubTankState.ERROR); } - + public String getProjInfoStr() { + if (projInfo == null) { + return "null"; + } + return String.format("%s(%d)", projInfo.projShotName, projInfo.projIndex); + } } diff --git a/src/main/java/a8k/service/app/appstate/type/Tube.java b/src/main/java/a8k/service/app/appstate/type/Tube.java index 50836f7..a9152c2 100644 --- a/src/main/java/a8k/service/app/appstate/type/Tube.java +++ b/src/main/java/a8k/service/app/appstate/type/Tube.java @@ -32,10 +32,17 @@ public class Tube { return ProjBriefInfo.toPorjIndex(projInfo); } + public List getProjIndexStrList(){ + List projIndexStrList = new ArrayList<>(); + for (ProjBriefInfo info : projInfo) { + projIndexStrList.add(info.projShotName); + } + return projIndexStrList; + } + Tube(Integer pos) { - // ProjBriefInfo info = new ProjBriefInfo(1,"hscrp","CA","#FF0000"); - // projInfo.add(info); - // projInfo.add(info); - // projInfo.add(info); + this.pos = pos; } + + } diff --git a/src/main/java/a8k/service/app/appstate/type/TubeHolder.java b/src/main/java/a8k/service/app/appstate/type/TubeHolder.java index 48ee347..c0a5a43 100644 --- a/src/main/java/a8k/service/app/appstate/type/TubeHolder.java +++ b/src/main/java/a8k/service/app/appstate/type/TubeHolder.java @@ -3,11 +3,15 @@ package a8k.service.app.appstate.type; import a8k.service.app.appstate.type.state.TubeHolderState; import a8k.service.app.appstate.type.state.TubeState; import a8k.type.type.A8kTubeHolderType; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +@Data public class TubeHolder { public A8kTubeHolderType tubeHolderType = A8kTubeHolderType.BloodTube; //试管架类型 public Tube[] tubes = new Tube[10]; - public TubeHolderState state = TubeHolderState.IDLE; //处理状态 + TubeHolderState state = TubeHolderState.IDLE; //处理状态 public TubeHolder() { for (int i = 0; i < tubes.length; i++) { diff --git a/src/main/java/a8k/service/app/appstate/type/state/ProjProcessState.java b/src/main/java/a8k/service/app/appstate/type/state/ProjProcessState.java index 65f8160..a8c39c0 100644 --- a/src/main/java/a8k/service/app/appstate/type/state/ProjProcessState.java +++ b/src/main/java/a8k/service/app/appstate/type/state/ProjProcessState.java @@ -3,7 +3,6 @@ package a8k.service.app.appstate.type.state; public enum ProjProcessState { INIT, PENDING, - PREPARE_RESOUCE, PROCESS, INCUBATING, OPTSCAN, diff --git a/src/main/java/a8k/service/db/DeviceStatisticDBService.java b/src/main/java/a8k/service/db/DeviceStatisticDBService.java new file mode 100644 index 0000000..0167d8b --- /dev/null +++ b/src/main/java/a8k/service/db/DeviceStatisticDBService.java @@ -0,0 +1,88 @@ +package a8k.service.db; + +import a8k.service.app.appdata.UtilsProjectColorAllocer; +import a8k.service.db.type.DeviceStatistic; +import a8k.service.db.type.StatisticType; +import a8k.service.debug.AppDebugHelperService; +import a8k.utils.DateUtil; +import a8k.utils.ZDateUtils; +import a8k.utils.ZSqliteJdbcHelper; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.SneakyThrows; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; + +import java.sql.ResultSet; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +@Component +public class DeviceStatisticDBService { + private static final Logger logger = LoggerFactory.getLogger(DeviceStatisticDBService.class); + private static final String tableName = "zapp_a8k_statistic"; + private static Class tClass = DeviceStatistic.class; + + + @Resource + JdbcTemplate jdbcTemplate; + + @PostConstruct + void init() { + if (!ZSqliteJdbcHelper.isTableExist(jdbcTemplate, tableName)) { + ZSqliteJdbcHelper.createTable(jdbcTemplate, tableName, tClass); + } + } + + @SneakyThrows private DeviceStatistic rowMapper(ResultSet rs, int rowNum) { + return (DeviceStatistic) ZSqliteJdbcHelper.rowMapper(rs, tClass); + } + + public T queryForObject(String sql, RowMapper rowMapper, @Nullable Object... args) { + try { + return jdbcTemplate.queryForObject(sql, rowMapper, args); + } catch (Exception e) { + logger.error("queryForObject error: {}", e.getMessage()); + return null; + } + } + + public void add(StatisticType statisticType, Integer cnt) { + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + String today = sdf.format(now); + + List statisticList = jdbcTemplate.query("select * from " + tableName + " where statisticDate = ? and statisticType = ?", this::rowMapper, today, statisticType); + + if (statisticList.isEmpty()) { + DeviceStatistic statistic = new DeviceStatistic(); + statistic.statisticDate = today; + statistic.statisticType = statisticType; + statistic.cnt = cnt; + ZSqliteJdbcHelper.addObj(jdbcTemplate, tableName, tClass, statistic); + } else { + DeviceStatistic statistic = statisticList.get(0); + statistic.cnt += cnt; + ZSqliteJdbcHelper.updateObj(jdbcTemplate, tableName, tClass, statistic); + } + } + + public Integer get(StatisticType type) { + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + String today = sdf.format(now); + + List statisticList = jdbcTemplate.query("select * from " + tableName + " where statisticDate = ? and statisticType = ?", this::rowMapper, today, type); + if (statisticList.isEmpty()) { + return 0; + } else { + return statisticList.get(0).cnt; + } + } + +} diff --git a/src/main/java/a8k/service/db/type/DeviceStatistic.java b/src/main/java/a8k/service/db/type/DeviceStatistic.java new file mode 100644 index 0000000..1ea95f2 --- /dev/null +++ b/src/main/java/a8k/service/db/type/DeviceStatistic.java @@ -0,0 +1,10 @@ +package a8k.service.db.type; + +import java.util.Date; + +public class DeviceStatistic { + public int id; + public String statisticDate; + public StatisticType statisticType; + public Integer cnt; +} diff --git a/src/main/java/a8k/service/db/type/StatisticType.java b/src/main/java/a8k/service/db/type/StatisticType.java new file mode 100644 index 0000000..5615e01 --- /dev/null +++ b/src/main/java/a8k/service/db/type/StatisticType.java @@ -0,0 +1,6 @@ +package a8k.service.db.type; + +public enum StatisticType { + TubeHolderCnt, + EmergencyTubeCnt, +} diff --git a/src/main/java/a8k/utils/ZSqliteJdbcHelper.java b/src/main/java/a8k/utils/ZSqliteJdbcHelper.java index ed181b0..355f148 100644 --- a/src/main/java/a8k/utils/ZSqliteJdbcHelper.java +++ b/src/main/java/a8k/utils/ZSqliteJdbcHelper.java @@ -38,7 +38,13 @@ public class ZSqliteJdbcHelper { static public void createTable(JdbcTemplate jdbcTemplate, String tableName, Class tClass) { StringBuilder sql = new StringBuilder("create table " + tableName + " ("); + Boolean hasId = false; for (java.lang.reflect.Field field : tClass.getDeclaredFields()) { + if (field.getName().equals("id")) { + hasId = true; + } + + sql.append(" '").append(field.getName()).append("' "); if (field.getType().equals(Integer.class) || field.getType().equals(int.class)) { sql.append("integer,"); @@ -56,6 +62,10 @@ public class ZSqliteJdbcHelper { sql.append("text,"); } } + if(!hasId) { + throw new RuntimeException("id field not found in class " + tClass.getName()); + } + sql.append(" PRIMARY KEY ('id' DESC));"); jdbcTemplate.execute(sql.toString()); } diff --git a/src/main/java/a8k/utils/ZStringUtils.java b/src/main/java/a8k/utils/ZStringUtils.java new file mode 100644 index 0000000..a8ba2da --- /dev/null +++ b/src/main/java/a8k/utils/ZStringUtils.java @@ -0,0 +1,46 @@ +package a8k.utils; + +public class ZStringUtils { + static public String centerStr(String str, Character c, int len) { + if (str == null || str.length() >= len) { + return str; + } + int left = (len - str.length()) / 2; + int right = len - str.length() - left; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < left; i++) { + sb.append(c); + } + sb.append(str); + for (int i = 0; i < right; i++) { + sb.append(c); + } + return sb.toString(); + } + + static public String rightAlignStr(String str, Character c, int len) { + if (str == null || str.length() >= len) { + return str; + } + int right = len - str.length(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < right; i++) { + sb.append(c); + } + sb.append(str); + return sb.toString(); + } + + static public String leftAlignStr(String str, Character c, int len) { + if (str == null || str.length() >= len) { + return str; + } + int left = len - str.length(); + StringBuilder sb = new StringBuilder(); + sb.append(str); + for (int i = 0; i < left; i++) { + sb.append(c); + } + return sb.toString(); + } +}