From 608c7103f56418aa47dedbceb8178c6df5c97104 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Wed, 30 Oct 2024 20:37:28 +0800 Subject: [PATCH] update --- .../appctrl/mainflowctrl/CondtionMgrService.java | 2 +- .../action/DO_FINISH_TUBE_PROCESS.java | 2 +- .../action/DO_PROCESS_ERROR_PLATE.java | 4 +- .../app/appctrl/mainflowctrl/action/DO_START.java | 2 +- .../app/appctrl/mainflowctrl/action/DO_STOP.java | 2 +- .../mainflowctrl/action/PLATE_OPT_SCAN.java | 12 ++- .../action/PROCESS_INCUBATE_COMPLETED_PLATE.java | 2 +- .../action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java | 30 ++++-- .../action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java | 2 +- .../mainflowctrl/action/SEQ4_PRE_PROCESS.java | 44 +++----- .../appctrl/mainflowctrl/action/SEQ5_PROCESS.java | 2 +- .../mainflowctrl/action/SEQ6_POST_PROCESS.java | 26 +++-- .../mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java | 2 +- .../appctrl/mainflowctrl/base/A8kStepAction.java | 2 +- .../ctrlservice/DeviceInitCtrlService.java | 4 +- .../ctrlservice/OptScanModuleCtrlService.java | 18 +++- .../a8k/service/test/MainflowCtrlTestService.java | 117 +++++++++++++-------- .../java/a8k/service/test/state/TestModeState.java | 15 ++- .../java/a8k/service/test/state/VirtualDevice.java | 9 +- .../java/a8k/type/exception/MutiAppException.java | 8 ++ .../java/a8k/utils/ActionParallerExceutor.java | 51 +++++++++ src/main/java/a8k/utils/AppExceptionUtils.java | 15 +++ 22 files changed, 241 insertions(+), 130 deletions(-) create mode 100644 src/main/java/a8k/utils/ActionParallerExceutor.java create mode 100644 src/main/java/a8k/utils/AppExceptionUtils.java 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 6574628..0abad15 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java @@ -40,7 +40,7 @@ public class CondtionMgrService { public Boolean getTubeholderEnterPosPPS() { //入料通道是否为空 - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { return virtualDevice.isTubeHolderReady(); } try { diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java index d053473..8917afe 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java @@ -73,7 +73,7 @@ public class DO_FINISH_TUBE_PROCESS extends A8kStepAction { } void resetHbotAndShakeModule() throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("处理错误试管", 2); virtualDevice.doVirtualThings("复位摇匀模组", 2); virtualDevice.doVirtualThings("复位HBOT", 2); 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 aaea4e4..2afbe15 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 @@ -59,7 +59,7 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction { void doEjectErrorPlate(IncubationSubTank errorTank) throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("推出板夹 From " + errorTank.toString()); return; } @@ -68,7 +68,7 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction { } void doDropErrorPlate() throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("丢弃板夹"); return; } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_START.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_START.java index 9ac25ea..9145966 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_START.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_START.java @@ -51,7 +51,7 @@ public class DO_START extends A8kStepAction { @Override public void doaction() throws AppException { mfcs.workStateChangeFlag = false; - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("弹出试管架"); return; } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_STOP.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_STOP.java index 344110f..356ec1c 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_STOP.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_STOP.java @@ -66,7 +66,7 @@ public class DO_STOP extends A8kStepAction { } void doClearDevice() throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("清空设备", 1); return; } 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 851926d..10d1f0b 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 @@ -75,19 +75,21 @@ public class PLATE_OPT_SCAN extends A8kStepAction { List doOptScanXX(ProjProcessContext cxt) throws AppException { List reactionResults = new ArrayList<>(); - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("扫描板夹", 2); return FakeReactionResultFactory.build(cxt.projCfg); } //扫描反应板并获取结果 - OptAnalyzeContext optCxt = new OptAnalyzeContext(cxt.projCfg, cxt.bloodType); - optScanModuleCtrlService.doOptScan(optCxt); + if (testModeState.getEnableOptScan()) { + OptAnalyzeContext optCxt = new OptAnalyzeContext(cxt.projCfg, cxt.bloodType); + optScanModuleCtrlService.doOptScan(optCxt); + reactionResults = optCxt.result; + } + //丢板 optScanModuleCtrlService.dropPlate(); - - reactionResults = optCxt.result; return reactionResults; } 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 ef6f159..6fc2f35 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 @@ -68,7 +68,7 @@ public class PROCESS_INCUBATE_COMPLETED_PLATE extends A8kStepAction { void doEjectPlate(IncubationSubTank tank) throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings(String.format("推出反应板夹从%s到光学模组", tank.getPos())); return; } 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 5e789cc..26d91a4 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 @@ -51,13 +51,13 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { } @Resource - GStateService gstate; + GStateService gstate; @Resource - TestModeState testModeState; + TestModeState testModeState; @Resource - VirtualDevice virtualDevice; + VirtualDevice virtualDevice; @Resource - AppEventBusService ebus; + AppEventBusService ebus; @Resource CondtionMgrService cmgr; @@ -76,20 +76,28 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { // TubeHolderScanResult doScanHolder() throws AppException { + TubeHolderScanResult result; - if (!testModeState.isVirtualDeviceEnable()) { - result = stc.scanTubeHodler(); - if(testModeState.getVirtualTubeScanResult()){ - result = virtualDevice.getTubeHolderScanResult(); - } - } else { + + /* + * 如果使能了虚拟设备,那么直接返回虚拟设备的扫描结果 + */ + if (virtualDevice.isEnable()) { result = virtualDevice.takeTubeHolderScanResult(); + } else { + result = stc.scanTubeHodler(); } + + //如果测试模式设置好了试管扫描结果,那么直接使用虚拟扫描结果 + if (testModeState.getVirtualTubeScanResult() != null) { + result = testModeState.getVirtualTubeScanResult(); + } + return result; } void doEjectHodler() throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("弹出试管架"); return; } 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 671918c..47047ba 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 @@ -66,7 +66,7 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction { // void moveToNextTube(Integer tubeIndex) throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("移动到下一个试管"); } else { tubeFeedingCtrlService.moveTubeToPreProcessPos(tubeIndex); 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 c61790b..5e30770 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 @@ -72,7 +72,9 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { @Resource CondtionMgrService cms; - ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); + // ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); + + ActionParallerExceutor actionParallerExceutor = new ActionParallerExceutor(); @PostConstruct @@ -84,7 +86,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { * @throws AppException 异常 */ void prepareReactionPlate() throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("准备反应板夹", 2); return; } @@ -102,7 +104,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { * @throws AppException 异常 */ void shakeAndTakeCap() throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("摇匀并取盖", 2); return; } @@ -129,7 +131,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { * @throws AppException exception */ void hbotPrepareTip() throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("准备Hbot Tip", 2); return; } @@ -152,34 +154,16 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { // projectProcessContextMgrService.startTubePreProcessing(); - 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 exceptions = new java.util.ArrayList<>(List.of()); - List errors = new java.util.ArrayList<>(List.of()); - try { - exceptions.add(doPrepareReactionPlateFuture.get()); - exceptions.add(doShakeAndTakeCapFuture.get()); - exceptions.add(doHbotPrepareTipFuture.get()); - } catch (InterruptedException | ExecutionException ignored) { - } - exceptions.removeIf(Objects::isNull); - exceptions.forEach(e -> errors.add(e.getError())); + actionParallerExceutor.submit(this::prepareReactionPlate); + actionParallerExceutor.submit(this::shakeAndTakeCap); + actionParallerExceutor.submit(this::hbotPrepareTip); + + var mutiAppException = actionParallerExceutor.waitAll(); //如果依然有错误,将试管状态设置为错误,同时抛出异常 - if (!errors.isEmpty()) { - projectProcessContextMgrService.changeTubeStateToError(gstate.getCurProcessingTube(), errors); - logger.error("准备工作出现错误:{}", errors); - throw ebuilder.buildMutiErrorAppException(exceptions); + if (!mutiAppException.bindExceptions.isEmpty()) { + projectProcessContextMgrService.changeTubeStateToError(gstate.getCurProcessingTube(), mutiAppException.getErrors()); + throw mutiAppException; } projectProcessContextMgrService.tubePreProcessingOK(); } 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 014a5a8..bdc019a 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 @@ -73,7 +73,7 @@ public class SEQ5_PROCESS extends A8kStepAction { ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(), tube.getProjIds().get(projProcessOff)); A8kReactionFlowType type = cxt.projCfg.projectInfo.reactionFlowType; - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("处理样本(准备反应板,取tip,摇匀,脱帽)", 5); return; } 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 f6e238d..fb49a39 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 @@ -1,6 +1,9 @@ package a8k.service.app.appctrl.mainflowctrl.action; +import a8k.service.app.devicectrl.ctrlservice.PipetteGunCtrlService; import a8k.service.app.devicectrl.ctrlservice.TubePreProcesCtrlService; +import a8k.service.app.devicectrl.driver.PipetteCtrlDriver; +import a8k.utils.ActionParallerExceutor; import a8k.utils.AppExceptionBuilder; import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; import a8k.service.app.appctrl.mainflowctrl.base.A8kActionStepType; @@ -36,11 +39,13 @@ public class SEQ6_POST_PROCESS extends A8kStepAction { } @Resource - GStateService gstate; + GStateService gstate; @Resource - TestModeState testModeState; + TestModeState testModeState; @Resource - VirtualDevice virtualDevice; + VirtualDevice virtualDevice; + @Resource + PipetteCtrlDriver pipetteCtrlDriver; @Resource AppExceptionBuilder ebuilder; @@ -54,7 +59,7 @@ public class SEQ6_POST_PROCESS extends A8kStepAction { CondtionMgrService cms; - ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); + ActionParallerExceutor actionParallerExceutor = new ActionParallerExceutor(); DeviceWorkState state; @@ -65,10 +70,19 @@ public class SEQ6_POST_PROCESS extends A8kStepAction { } void doAction() throws AppException { - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("后处理样本", 3); } - tubePreProcesCtrlService.resteModule(); + + actionParallerExceutor.submit(() -> pipetteCtrlDriver.lldPrepareBlock()); + actionParallerExceutor.submit(() -> tubePreProcesCtrlService.resteModule()); + + var mutiAppException = actionParallerExceutor.waitAll(); + + if (!mutiAppException.bindExceptions.isEmpty()) { + projectProcessContextMgrService.changeTubeStateToError(gstate.getCurProcessingTube(), mutiAppException.getErrors()); + throw mutiAppException; + } } 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 06f9bde..f59e512 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 @@ -51,7 +51,7 @@ public class SEQ7_EJECT_TUBEHOLDER extends A8kStepAction { } @Override public void doaction() throws AppException { - if (!testModeState.isVirtualDeviceEnable()) { + if (!virtualDevice.isEnable()) { tubeFeedingCtrlService.ejectTubeHolder(); tubeFeedingCtrlService.moveTubeRackMoveToEnterPos(); } else { 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 a7a0d42..599364b 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 @@ -34,7 +34,7 @@ public class A8kStepAction { } public Boolean isAllowsParallelRunning() { - return false; + return true; } public String logCxtState() { diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java index 52c4dc6..fbb6092 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java @@ -92,7 +92,7 @@ public class DeviceInitCtrlService { List doDeviceMoveToZero() throws AppException { List results = checkBeforeInitDevice(); - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("初始化设备", 3); gstate.setDeviceInited(true); return results; @@ -155,7 +155,7 @@ public class DeviceInitCtrlService { result.typechinfo = checkPoint.typechinfo; // - if (testModeState.isVirtualDeviceEnable()) { + if (virtualDevice.isEnable()) { result.pass = true; } else { result.pass = checkPoint.checkfn.check(); diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java index cef3a28..c38062b 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java @@ -51,7 +51,6 @@ public class OptScanModuleCtrlService { TurnableMoveCtrlService turnableMoveCtrlService; - public void pullPlate(IncubatorPos turntablePosIndex) throws AppException { turnableMoveCtrlService.trunableMoveToPullPos(turntablePosIndex); stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerScandbyPos(), overtime); @@ -67,7 +66,7 @@ public class OptScanModuleCtrlService { public Integer[] startOptScan(A8kOptType optType, Integer rawScanGain) throws AppException { - Integer forwardScanPos = optModuleExtParamsMgr.getOptScanStartPos(optType); + Integer forwardScanPos = optModuleExtParamsMgr.getOptScanStartPos(optType); Integer backwardScanPos = forwardScanPos - 1200; // Double scanGain = optModuleExtParamsMgr.getScanGain(optType); // Integer rawScanGain = OptGainConvert.scanerToRawGain(optType, scanGain); @@ -171,8 +170,17 @@ public class OptScanModuleCtrlService { optCxt.fOptCfg = OptParamGetter.getFOptCfg(optCxt.pcfg); optCxt.tOptCfg = OptParamGetter.getTOptCfg(optCxt.pcfg); - tryDoOptScan(optCxt, A8kOptType.FOPT); - tryDoOptScan(optCxt, A8kOptType.TOPT); + Assert.isTrue(optCxt.fOptCfg != null || optCxt.tOptCfg != null, "optcfg is null"); + + if (optCxt.fOptCfg != null) { + tryDoOptScan(optCxt, A8kOptType.FOPT); + } + + if (optCxt.tOptCfg != null) { + tryDoOptScan(optCxt, A8kOptType.TOPT); + } + + for (int i = 0; i < optCxt.pcfg.projOptConfigList.size(); i++) { try { ReactionResult result = A8kOptXComputer.computeResult(optCxt, i); @@ -184,4 +192,6 @@ public class OptScanModuleCtrlService { } } } + + } diff --git a/src/main/java/a8k/service/test/MainflowCtrlTestService.java b/src/main/java/a8k/service/test/MainflowCtrlTestService.java index 37d7eaa..ac59cfb 100644 --- a/src/main/java/a8k/service/test/MainflowCtrlTestService.java +++ b/src/main/java/a8k/service/test/MainflowCtrlTestService.java @@ -17,6 +17,7 @@ import a8k.service.test.fakeproj.FAKE_PROJ_01; import a8k.service.test.fakeproj.FakeProjInfo; import a8k.service.test.fakeproj.FakeProjInfoFactory; import a8k.service.test.state.TestModeState; +import a8k.service.test.state.VirtualDevice; import a8k.service.test.type.MainFlowCtrlTestCaseType; import a8k.type.ConsumableGroup; import a8k.type.ConsumablesScanReport; @@ -43,12 +44,14 @@ public class MainflowCtrlTestService { @Resource - TestModeState testModeState; + TestModeState testModeState; + @Resource + VirtualDevice virtualDevice; // // StateService // @Resource - ConsumablesMgrService consumablesMgrService; + ConsumablesMgrService consumablesMgrService; @Resource AppConsumablesScanService appConsumablesScanService; @Resource @@ -60,11 +63,11 @@ public class MainflowCtrlTestService { // DB // @Resource - A8kProjIdCardDao a8KProjIdCardDao; + A8kProjIdCardDao a8KProjIdCardDao; @Resource - A8kProjInfoDao a8KProjInfoDao; + A8kProjInfoDao a8KProjInfoDao; @Resource - A8kProjOptConfigDao a8KProjOptConfigDao; + A8kProjOptConfigDao a8KProjOptConfigDao; // // Ctrl @@ -87,7 +90,7 @@ public class MainflowCtrlTestService { void LoadingConsumablesDirectly(ConsumableGroup group, FakeProjInfo fake) { var result = new ConsumablesScanReport(); - result.lotId = fake.lotId; + result.lotId = fake.lotId; result.chNum = group.off; result.projId = fake.projId; result.report = ConsumablesScanReportErrorType.PASS; @@ -95,12 +98,12 @@ public class MainflowCtrlTestService { consumablesMgrService.setTipNum(TipGroup.GROUP0, AppConstant.TIP_NUM); } - TubeHolderScanResult createScanResult(A8kTubeHolderType type, Integer tubeNum) { + TubeHolderScanResult createScanResult(A8kTubeHolderType type, Boolean htube, Integer tubeNum) { TubeHolderScanResult scanResult = new TubeHolderScanResult(); scanResult.tubeHolderType = type.scanCode; for (int i = 0; i < scanResult.tube.length; i++) { if (i < tubeNum) - scanResult.tube[i] = new TubesScanResult(true, true, ""); + scanResult.tube[i] = new TubesScanResult(true, htube, ""); else scanResult.tube[i] = new TubesScanResult(false, false, ""); } @@ -109,8 +112,8 @@ public class MainflowCtrlTestService { TubeHolderSetting createOneActiveTubeHolderSetting(A8kTubeHolderType type, Integer tubeNum, List projId) { TubeHolderSetting setting = new TubeHolderSetting(); -// setting.tubeHolderType = type; - setting.active = true; + // setting.tubeHolderType = type; + setting.active = true; for (int i = 0; i < setting.tubeSettings.length; i++) { if (i < tubeNum) { setting.tubeSettings[i].userid = "FAUID" + i; @@ -121,10 +124,42 @@ public class MainflowCtrlTestService { } - // SIMPLE_TEST - private List DO_SIMPLE_TEST() throws AppException { - log.info("DO_SIMPLE_TEST"); + // + // 测试配置 + // + @ExtApiFn(name = "获取测试模式配置", group = "测试模式", order = 100) + synchronized public TestModeState getTestModeState() { + return testModeState; + } + + @ExtApiFn(name = "使能无校验模式", group = "测试模式", order = 103) + public void setNoCheck(Boolean noCheck) { + testModeState.setNoCheckMode(noCheck); + } + + @ExtApiFn(name = "使能光学检查", group = "测试模式", order = 103) + public void setEnableOptScan(Boolean enable) { + testModeState.setEnableOptScan(enable); + } + + + // + // 测试用例 + // + + @ExtApiFn(name = "设备初始化", order = 200) + public Object deviceInit() throws AppException { + List checkResults = appDeviceCtrlService.initDevice(); + for (CheckResult checkResult : checkResults) { + if (!checkResult.pass) { + return checkResults; + } + } + return checkResults; + } + void stopAndWaittingForDeviceStop() { + log.info("doSimpleTest"); //停止工作 if (!gstate.getDeviceWorkState().workState.equals(A8kWorkState.IDLE)) { appDeviceCtrlService.stopWork(); @@ -133,51 +168,41 @@ public class MainflowCtrlTestService { OS.forceSleep(1000); } } + } + + @ExtApiFn(name = "执行一次简单的测试(无试管测试)", order = 200) + public String doSimpleTest(Boolean isHTube, Integer tubeNum) throws AppException { + if (tubeNum <= 0) { + throw AppException.of("试管数量必须大于0"); + } + stopAndWaittingForDeviceStop(); //清空项目的数据库配置 resetProjDB(); + + //设置虚拟耗材,只有一个高试管 + testModeState.setVirtualTubeScanResult(createScanResult(A8kTubeHolderType.BloodTube, isHTube, tubeNum)); + //无校验模式 + testModeState.setNoCheckMode(true); + //无光学检查 + testModeState.setEnableOptScan(false); + + //添加项目信息 addProjInfo(FAKE_PROJ_01.class); //设置耗材状态,假定已经扫描过耗材 LoadingConsumablesDirectly(ConsumableGroup.GROUP0, new FAKE_PROJ_01()); //设置试管架扫描信息,全部设置成高试管 - var scanResult = createScanResult(A8kTubeHolderType.BloodTube, 1); - testModeState.getVirtualDevice().setTubeScanResult(scanResult); - //设置试管架配置信息 appTubeSettingMgrService.removeAllTubeSetting(); - TubeHolderSetting setting = createOneActiveTubeHolderSetting(A8kTubeHolderType.BloodTube, 1, List.of(new FAKE_PROJ_01().projId)); - appTubeSettingMgrService.newTubeHolderSetting(setting); - - //开始工作 - appDeviceCtrlService.startWork(); - return null; - } - - @ExtApiFn(name = "设备初始化", order = 1) - public Object deviceInit() throws AppException { - List checkResults = appDeviceCtrlService.initDevice(); - for (CheckResult checkResult : checkResults) { - if (!checkResult.pass) { - return checkResults; - } - } - return checkResults; - } - @ExtApiFn(name = "开始测试", order = 2) - public Object startTest(MainFlowCtrlTestCaseType castType, Boolean virtualDevice, Boolean virtualTubeScanResult, Boolean noCheck) throws AppException { - if (gstate.isWorking()) { - throw new AppException(new AECodeError("设备正在工作中,请先停止工作")); + for (int i = 0; i < 3; i++) { + TubeHolderSetting setting = createOneActiveTubeHolderSetting(A8kTubeHolderType.BloodTube, tubeNum, List.of(new FAKE_PROJ_01().projId)); + appTubeSettingMgrService.newTubeHolderSetting(setting); } - testModeState.getVirtualDevice().setEnableVirtualDevice(virtualDevice); - testModeState.setNoCheckMode(noCheck); - testModeState.setVirtualTubeScanResult(virtualTubeScanResult); - - if (Objects.requireNonNull(castType) == MainFlowCtrlTestCaseType.SIMPLE_TEST) { - return DO_SIMPLE_TEST(); - } - return null; + //开始工作 + appDeviceCtrlService.startWork(); + return "开始测试"; } diff --git a/src/main/java/a8k/service/test/state/TestModeState.java b/src/main/java/a8k/service/test/state/TestModeState.java index fa41a8f..9b33fed 100644 --- a/src/main/java/a8k/service/test/state/TestModeState.java +++ b/src/main/java/a8k/service/test/state/TestModeState.java @@ -1,5 +1,7 @@ package a8k.service.test.state; +import a8k.type.TubeHolderScanResult; +import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.annotation.Resource; import lombok.Data; import org.springframework.stereotype.Component; @@ -8,14 +10,9 @@ import org.springframework.stereotype.Component; @Data public class TestModeState { - @Resource - VirtualDevice virtualDevice; - Boolean noCheckMode = false; - Boolean virtualTubeScanResult; - - - public Boolean isVirtualDeviceEnable() { - return virtualDevice.isEnable(); - } + Boolean noCheckMode = false; //无校验模式 + Boolean enableOptScan = true; //是否使能光学扫描 +// @JsonIgnore + TubeHolderScanResult virtualTubeScanResult = null; // 虚拟管架扫描结果 } diff --git a/src/main/java/a8k/service/test/state/VirtualDevice.java b/src/main/java/a8k/service/test/state/VirtualDevice.java index ece6c1e..9ffa94f 100644 --- a/src/main/java/a8k/service/test/state/VirtualDevice.java +++ b/src/main/java/a8k/service/test/state/VirtualDevice.java @@ -41,13 +41,9 @@ public class VirtualDevice { TubeHolderScanResult tubeScanResult = null; public TubeHolderScanResult takeTubeHolderScanResult() { - var cache = tubeScanResult; + var ret = tubeScanResult; tubeScanResult = null; - return cache; - } - - public TubeHolderScanResult getTubeHolderScanResult() { - return tubeScanResult; + return ret; } public Boolean isTubeHolderReady() { @@ -78,6 +74,7 @@ public class VirtualDevice { doVirtualThings(msg, 1); } + public void doVirtualThings(String msg, Integer time) { log.info("doSomeThings: {}", msg); OS.forceSleep(3000); diff --git a/src/main/java/a8k/type/exception/MutiAppException.java b/src/main/java/a8k/type/exception/MutiAppException.java index 86dadbc..8669e9f 100644 --- a/src/main/java/a8k/type/exception/MutiAppException.java +++ b/src/main/java/a8k/type/exception/MutiAppException.java @@ -1,6 +1,9 @@ package a8k.type.exception; import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.type.ecode.AppError; +import a8k.utils.AppExceptionUtils; +import com.fasterxml.jackson.annotation.JsonIgnore; import java.util.List; @@ -11,4 +14,9 @@ public class MutiAppException extends AppException { super(A8kEcode.MUTI_APPEXCEPTIONS); bindExceptions = exceptions; } + + @JsonIgnore + public List getErrors() { + return AppExceptionUtils.toAppErrorList(bindExceptions); + } } diff --git a/src/main/java/a8k/utils/ActionParallerExceutor.java b/src/main/java/a8k/utils/ActionParallerExceutor.java new file mode 100644 index 0000000..d3fb9a8 --- /dev/null +++ b/src/main/java/a8k/utils/ActionParallerExceutor.java @@ -0,0 +1,51 @@ +package a8k.utils; + +import a8k.OS; +import a8k.type.ecode.AppError; +import a8k.type.exception.AppException; +import a8k.type.exception.MutiAppException; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.*; + +public class ActionParallerExceutor { + ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); + List> futures = new ArrayList<>(); + + // 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)); + + + public void submit(ZFnCall.Fn fn) { + var future = executor.submit(() -> ZFnCall.callfn(fn)); + futures.add(future); + } + + public MutiAppException waitAll() { + futures.forEach(this::wait); + List exceptions = new java.util.ArrayList<>(List.of()); + try { + for (Future future : futures) { + exceptions.add(future.get()); + } + } catch (InterruptedException | ExecutionException ignored) { + } + exceptions.removeIf(Objects::isNull); + return new MutiAppException(exceptions); + // List errors = new java.util.ArrayList<>(List.of()); + // exceptions.forEach(e -> errors.add(e.getError())); + } + + + void wait(Future future) { + while (!future.isDone()) { + OS.forceSleep(100); + } + } + +} diff --git a/src/main/java/a8k/utils/AppExceptionUtils.java b/src/main/java/a8k/utils/AppExceptionUtils.java new file mode 100644 index 0000000..0d33ad6 --- /dev/null +++ b/src/main/java/a8k/utils/AppExceptionUtils.java @@ -0,0 +1,15 @@ +package a8k.utils; + +import a8k.type.ecode.AppError; +import a8k.type.exception.AppException; + +import java.util.List; + +public class AppExceptionUtils { + + public static List toAppErrorList(List exceptions) { + List errors = new java.util.ArrayList<>(List.of()); + exceptions.forEach(e -> errors.add(e.getError())); + return errors; + } +}