From 2911ac73268ba9d7603e5d13153c1ad511e1cbc4 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Sun, 8 Jun 2025 20:19:53 +0800 Subject: [PATCH] update --- .../ExperimentConsistencyTestingControler.java | 10 +- .../ExperimentConsistencyTestingService.java | 434 +-------------------- .../service/state/TubeholderExSettingMgr.java | 35 ++ .../service/mainctrl/MainFlowCtrlScheduler.java | 11 + .../mainctrl/TubeHolderSettingMgrService.java | 3 +- .../app/service/module/InFeedingCtrlModule.java | 28 +- 6 files changed, 92 insertions(+), 429 deletions(-) create mode 100644 src/main/java/a8k/app/engineer/service/state/TubeholderExSettingMgr.java diff --git a/src/main/java/a8k/app/controler/api/v1/engineer/ExperimentConsistencyTestingControler.java b/src/main/java/a8k/app/controler/api/v1/engineer/ExperimentConsistencyTestingControler.java index 867afee..e35f344 100644 --- a/src/main/java/a8k/app/controler/api/v1/engineer/ExperimentConsistencyTestingControler.java +++ b/src/main/java/a8k/app/controler/api/v1/engineer/ExperimentConsistencyTestingControler.java @@ -2,6 +2,7 @@ package a8k.app.controler.api.v1.engineer; import a8k.app.engineer.service.qatest.ExperimentConsistencyTestingService; +import a8k.app.engineer.service.state.TubeholderExSettingMgr; import a8k.app.engineer.service.type.TubeHolderExConfig; import a8k.app.type.exception.AppException; import a8k.app.type.ui.ApiRet; @@ -23,6 +24,7 @@ import org.springframework.web.bind.annotation.ResponseBody; @RequiredArgsConstructor public class ExperimentConsistencyTestingControler { private final ExperimentConsistencyTestingService experimentConsistencyTestingService; + private final TubeholderExSettingMgr tubeholderExSettingMgr; @Operation(summary = "开始测试(所有配置从应用获得)") @PostMapping("/startTest") @@ -33,15 +35,15 @@ public class ExperimentConsistencyTestingControler { @Operation(summary = "提交配置") @PostMapping("/submitConfig") - public ApiRet submitConfig(@RequestBody TubeHolderExConfig tubeHolderExConfig) { - experimentConsistencyTestingService.submitTubeExConfig(tubeHolderExConfig); + public ApiRet submitConfig(@RequestBody TubeHolderExConfig tubeHolderExConfig) { + tubeholderExSettingMgr.submitTubeExConfig(tubeHolderExConfig); return ApiRet.success(); } @Operation(summary = "获取配置") @PostMapping("/getConfig") - public ApiRet getConfig() { - TubeHolderExConfig tubeHolderExConfig = experimentConsistencyTestingService.getTubeExConfig(); + public ApiRet getConfig() { + TubeHolderExConfig tubeHolderExConfig = tubeholderExSettingMgr.getTubeExConfig(); return ApiRet.success(tubeHolderExConfig); } } diff --git a/src/main/java/a8k/app/engineer/service/qatest/ExperimentConsistencyTestingService.java b/src/main/java/a8k/app/engineer/service/qatest/ExperimentConsistencyTestingService.java index defe1c2..d796651 100644 --- a/src/main/java/a8k/app/engineer/service/qatest/ExperimentConsistencyTestingService.java +++ b/src/main/java/a8k/app/engineer/service/qatest/ExperimentConsistencyTestingService.java @@ -3,6 +3,7 @@ package a8k.app.engineer.service.qatest; import a8k.app.constant.AppConstant; import a8k.app.engineer.service.executor.EngineerModeActionExecutor; import a8k.app.engineer.service.state.EngineerModeStateMgrService; +import a8k.app.engineer.service.state.TubeholderExSettingMgr; import a8k.app.engineer.service.type.TubeHolderExConfig; import a8k.app.engineer.service.utils.BeforeDoEngineerActionChecker; import a8k.app.hardware.driver.OptModuleDriver; @@ -10,6 +11,7 @@ import a8k.app.hardware.type.A8kEcode; import a8k.app.service.data.ProjInfoMgrService; import a8k.app.service.data.ReactionRecordMgrService; import a8k.app.service.lowerctrl.*; +import a8k.app.service.mainctrl.MainFlowCtrlScheduler; import a8k.app.service.mainctrl.TubeHolderSettingMgrService; import a8k.app.service.lowerctrl.LiquidOperationCtrService; import a8k.app.service.module.TipOperationCtrlModule; @@ -35,75 +37,13 @@ import org.springframework.stereotype.Component; @Slf4j @RequiredArgsConstructor public class ExperimentConsistencyTestingService { - - // final private A8kTubeHolderType expectedTubeHolderType = A8kTubeHolderType.BulletTube1P5; - final private Integer expectedProjId = 1; - final private Integer takeSampleUl = 10; - - final private EngineerModeStateMgrService engineerModeStateMgrService; - - - final private EngineerModeActionExecutor actionExecutor; - - - /** - * 数据库 - */ - final private ProjInfoMgrService projInfoMgrService; - final private ReactionRecordMgrService reactionRecordMgrService; - - /* * 状态管理器 */ - final private DeviceWorkStateMgrService deviceWorkStateMgrService; final private ConsumablesMgrService consumablesMgrService; final private TubeHolderSettingMgrService tubeHolderSettingMgrService; - final private IncubationPlateStateMgr incubationPlateStateMgr; - final private OptScanModuleStateMgr optScanModuleStateMgr; - final private TubeStateMgr tubeStateMgrService; - final private GStateMgrService gStateMgrService; - - /* - * 控制器 - */ - final private TubePreProcesModuleCtrlService tubePreProcesModuleCtrlService; - final private TubeFeedingCtrlService tubeFeedingCtrlService; - final private TubePreProcessModuleExCtrlService tubePreProcessModuleExCtrlService; - final private OptScanModuleCtrlService optScanModuleCtrlService; - final private PlateBoxCtrlService plateBoxCtrlService; - final private TurnableMoveCtrlService turnableMoveCtrlService; - final private LiquidOperationCtrService liquidOperationCtrService; - final private HbotMoveExCtrlService hbotMoveExCtrlService; - private final OptModuleDriver optModuleDriver; - private final HbotMoveCtrlService hbotMoveCtrlService; - private final TipOperationCtrlModule tipOperationCtrlModule; - - private TubeHolderSetting curTubeHolderSetting; - private A8kSamplePos samplePos; - private TubeHolderExConfig tubeHolderExConfig = new TubeHolderExConfig(); - - synchronized public void submitTubeExConfig(TubeHolderExConfig tubeExTubeHolderExConfig) { - if (tubeExTubeHolderExConfig != null) { - this.tubeHolderExConfig = tubeExTubeHolderExConfig; - } - log.info("更新试管架配置 {}", ZJsonHelper.objectToJson(tubeHolderExConfig)); - } - - synchronized public TubeHolderExConfig getTubeExConfig() { - return tubeHolderExConfig; - } - - public Integer getRepeatTimes(Integer tubeoff) { - if (tubeoff < 0 || tubeoff >= AppConstant.TUBEHOLER_SIZE) { - throw new IllegalArgumentException("tubeoff is out of range"); - } - if (tubeoff >= tubeHolderExConfig.tubeExConfigs.size()) { - return 1; - } - return getTubeExConfig().tubeExConfigs.get(tubeoff).repeatTimes; - } - + final private TubeholderExSettingMgr tubeholderExSettingMgr; + final private MainFlowCtrlScheduler mainFlowCtrlScheduler; /** * 开始测试 @@ -137,7 +77,7 @@ public class ExperimentConsistencyTestingService { int testTotalTimes = 0; for (TubeSetting tubeSetting : tubeHolderSetting.tubeSettings) { for (Integer ignored : tubeSetting.projId) { - testTotalTimes += tubeHolderExConfig.tubeExConfigs.get(tubeSetting.tubeIndex).repeatTimes; + testTotalTimes += tubeholderExSettingMgr.getTubeExConfig().tubeExConfigs.get(tubeSetting.tubeIndex).repeatTimes; } } if (consumablesMgrService.getConsumableNum(1/*hscrp项目*/) < testTotalTimes) { @@ -151,363 +91,13 @@ public class ExperimentConsistencyTestingService { log.info("开始试剂实验一致性检测"); - curTubeHolderSetting = tubeHolderSetting; - // actionExecutor.start(this::action); + tubeholderExSettingMgr.setEnabled(true); + mainFlowCtrlScheduler.startWork(() -> { + log.info("试剂实验一致性检测工作线程结束"); + tubeholderExSettingMgr.setEnabled(false); + }); + } - // - // void docmd(String mark, A8kCmdRunnable runnable, A8kCmdRunnable virtualRunable) throws AppException { - // actionExecutor.sleep(2); - // actionExecutor.docmd(mark, runnable, virtualRunable); - // - // } - // - // void docmd(String mark, A8kCmdRunnable runnable) throws AppException { - // UISender.txInfoMsg(log, mark); - // actionExecutor.docmd(mark, runnable); - // } - // - // - // public void action() { - // - // try { - // doAction(); - // } catch (Exception e) { - // processException(e); - // } - // } - // - // public void processException(Exception e) { - // try { - // log.error("Catch exception: ", e); - // if (!(e instanceof EngineerTaskBreakException)) { - // UISender.txErrorPrompt(e); - // } - // // - // // Action - // // - // if (actionExecutor.isInRealMode()) { - // optScanModuleCtrlService.dropPlate(); - // tipOperationCtrlModule.dropTip(); - // tubeFeedingCtrlService.ejectTubeHolder(); - // List all = incubationPlateStateMgr.getAllNotFreeIncubationSubTanks(); - // for (IncubationSubTank notFreeTank : all) { - // optScanModuleCtrlService.pullPlate(notFreeTank.pos); - // optScanModuleCtrlService.dropPlate(); - // } - // } - // // - // // State - // // - // optScanModuleStateMgr.changeOptScanModuleStateToEmpty(); - // incubationPlateStateMgr.resetAll(); - // } catch (AppException ex) { - // log.error("Catch exception: ", e); - // UISender.txErrorPrompt(e); - // gStateMgrService.setFatalError(ex.error); - // } catch (Exception ex) { - // log.error("Catch exception: ", e); - // UISender.txErrorPrompt(e); - // gStateMgrService.setFatalError(new AppError(A8kEcode.SYS_EXCEPTION, ex.getMessage())); - // } - // - // } - // - // Boolean hasTubeHolder; - // TubeHolderScanResult scanResult; - // - // public void doAction() throws AppException { - // /* - // * 1. 核对是否存在试管配置是否只有一个 - // * 2. 核对耗材是否充足 - // * - // * - // * 1. 入料 - // * 2. 核对试管架类型 - // * - // * Loop - // * 1. 样本准备 - // * - // * Loop - // * 1. 检查孵育盘是否有空闲位(没有空闲位,则等待空闲位) - // * 2. 检查是否有孵育完成的样本 (有孵育完成的样本,则进行光学扫描) - // * 3. 入板 - // * 4. 取样 - // * 5. 预反应 - // * 6. 滴定 - // * - // * End: - // * 1. 等待所有反应板孵育完成 - // */ - // - // //入料 - // hasTubeHolder = false; - // docmd("入料", () -> { - // hasTubeHolder = tubeFeedingCtrlService.enterTubeHolder(); - // }, () -> hasTubeHolder = true); - // if (!hasTubeHolder) { - // throw AppException.of(A8kEcode.ERROR_OPERATION, "入料超时,未检测到试管架"); - // } - // - // //扫描试管架 - // scanResult = null; - // docmd("扫描试管架", () -> { - // scanResult = tubeFeedingCtrlService.scanTubeHodler(); - // }, () -> { - // scanResult = new TubeHolderScanResult(); - // for (int i = 0; i < curTubeHolderSetting.tubeSettings.length; i++) { - // scanResult.tube[i] = new TubeScanResult(); - // if (!curTubeHolderSetting.tubeSettings[i].projId.isEmpty()) { - // scanResult.tube[i].isTubeExist = true; - // } - // } - // }); - // //核对试管架信息 - // verifyTubeHolderSettingAndTubeHolderScanResult(curTubeHolderSetting, scanResult); - // // - // A8kTubeHolderType tubeHolderType = A8kTubeHolderType.of(scanResult.tubeHolderType); - // if (A8kTubeHolderType.BulletTube1P5.equals(tubeHolderType)) { - // samplePos = A8kSamplePos.Bulltube1P5Pos; - // } else if (A8kTubeHolderType.BulletTube0P5.equals(tubeHolderType)) { - // samplePos = A8kSamplePos.Bulltube0P5Pos; - // } else { - // throw AppException.of(A8kEcode.APPE_TUBE_HOLDER_TYPE_IS_NOT_SUPPORT, "请使用子弹头1.5ml或者子弹头0.5ml试管架"); - // } - // - // - // //构建试管架 - // // setTubeHolderDirect - // for (int tubeoff = 0; tubeoff < curTubeHolderSetting.tubeSettings.length; tubeoff++) { - // TubeSetting tubeSetting = curTubeHolderSetting.tubeSettings[tubeoff]; - // if (tubeSetting.projId.isEmpty()) { - // continue; - // } - // Assert.isTrue(scanResult.tube[tubeoff].isTubeExist, String.format("位置[%d]未放入是试管", tubeoff + 1)); - // - // //移动试管架到预处理位置 - // int finalTubeoff = tubeoff; - // UISender.txInfoMsg(log, "开始处理第%d个试管", finalTubeoff + 1); - // docmd("移动试管到处理位", () -> tubeFeedingCtrlService.moveTubeToPreProcessPos(finalTubeoff)); - // - // for (int j = 0; j < getRepeatTimes(tubeoff); j++) { - // - // //尝试处理孵育完成的反应板 - // incubationPlateProcess(false); - // ProjBuildInInfo projBuildinInfo = projInfoMgrService.getProjBuildInInfo(expectedProjId); - // - // //申请耗材 - // var consumableInfo = consumablesMgrService.reserveConsumable(projBuildinInfo.reactionFlowType, expectedProjId); - // if (consumableInfo == null) { - // throw AppException.of(A8kEcode.CODEERROR, "耗材不足?"); //理论上开始阶段已经核对过了耗材数量,此时应该不会不足 - // } - // consumablesMgrService.useReserveConsumable(consumableInfo); - // - // //构造项目信息 - // ProjExtInfoCard projExtInfoCard = projInfoMgrService.getProjExtInfoCard(consumableInfo.lotid); - // ProjBriefInfo projBriefInfo = ProjInfoUtils.buildProjBrefInfo(projBuildinInfo); - // - // Assert.notNull(projBuildinInfo, "projBuildInInfo is null"); - // Assert.notNull(projExtInfoCard, "projExtInfoCard is null"); - // - // //处理样本 - // Tube tube = new Tube(tubeoff); - // tube.setIsHighTube(false); - // tube.setIsEmergency(false); - // tube.setBloodType(tubeSetting.bloodType); - // tube.setSampleBarcode(tubeSetting.sampleBarcode); - // tube.setUserid(tubeSetting.userid); - // tube.setProjInfo(ZList.of(projBriefInfo)); - // tube.setProjIds(ZList.of(expectedProjId)); - // String sampleId = tubeStateMgrService.newSample(tube); - // tube.setSampleId(sampleId); - // - // - // //处理试管 - // processTube(tube, tubeoff, consumableInfo, tubeSetting); - // if (!tube.getErrors().isEmpty()) { - // log.warn("样本异常,跳过当前样本"); - // UISender.txErrorMsg(log, tube.getErrors().getFirst(), "样本异常,跳过当前样本"); - // break; - // } - // docmd("HBOT复位", hbotMoveExCtrlService::moveQuickToZero); - // } - // } - // tubeFeedingCtrlService.ejectTubeHolder(); - // - // incubationPlateProcess(true); - // incubationPlateStateMgr.resetAll(); - // UISender.txInfoPrompt(log, "试剂实验一致性检测完成"); - // } - // - // private void processTube(Tube tube, Integer offset, ConsumableInfo consumableInfo, TubeSetting tubeSetting) throws AppException { - // - // ProjBuildInInfo projBuildinInfo = projInfoMgrService.getProjBuildInInfo(expectedProjId); - // ProjExtInfoCard projExtInfoCard = projInfoMgrService.getProjExtInfoCard(consumableInfo.lotid); - // - // - // //拉取一个板夹到孵育盘 - // var freeIncubationPos = incubationPlateStateMgr.takeOneIncubationIDLEPos( - // (IncubatorPos pos) -> { - // incubationPlateStateMgr.syncProjInfo(pos, projBuildinInfo, projExtInfoCard); - // incubationPlateStateMgr.syncSampleInfo(pos, tube.getSampleInfo()); - // } - // ); - // - // //强制清空一下光学模组和孵育盘 - // // optScanModuleCtrlService.dropPlate(); - // // optScanModuleCtrlService.pullPlate(freeIncubationPos); - // // optScanModuleCtrlService.dropPlate(); - // - // docmd("丢反应板", optScanModuleCtrlService::dropPlate); - // docmd("拉取反应板", () -> optScanModuleCtrlService.pullPlate(freeIncubationPos)); - // docmd("丢反应板", optScanModuleCtrlService::dropPlate); - // - // - // // plateBoxCtrlService.pushPlateQuick(consumableInfo.group, freeIncubationPos); - // docmd("推入新的反应板", () -> plateBoxCtrlService.pushPlateQuick(consumableInfo.group, freeIncubationPos)); - // //移动当前板夹到滴定位 - // // turnableMoveCtrlService.trunableMoveToDropLiquidPos(freeIncubationPos); - // docmd("移动到滴定位", () -> turnableMoveCtrlService.trunableMoveToDropLiquidPos(freeIncubationPos)); - // - // - // docmd("样本处理", () -> { - // try { - // liquidOperationCtrService.setProjContext(projBuildinInfo, projExtInfoCard); - // var preProcessPos = new PreReactionPos(ConsumableType.SmallBottleBuffer, consumableInfo.group, consumableInfo.pos); - // //取tip - // tipOperationCtrlModule.tryTakeTip(() -> !actionExecutor.isStopping()); - // actionExecutor.sleep(1); - // //刺破缓冲液 - // hbotMoveExCtrlService.moveToLittleBufferPiercePos(consumableInfo.group, consumableInfo.pos); - // //取样品 - // Assert.isTrue(!samplePos.equals(A8kSamplePos.EmergencyTubePos), "samplePos cannot be EmergencyTubePos"); - // Assert.isTrue(!samplePos.equals(A8kSamplePos.BloodHTubePos), "samplePos cannot be BloodHTubePos"); - // Assert.isTrue(!samplePos.equals(A8kSamplePos.BloodSTubePos), "samplePos cannot be BloodSTubePos"); - // liquidOperationCtrService.takeSampleToPreReactionPos(samplePos, preProcessPos, takeSampleUl); - // actionExecutor.sleep(1); - // //取混合液到预反应位 - // liquidOperationCtrService.takePreReactionLiquid(preProcessPos); - // liquidOperationCtrService.dropLiquidToReactionPlate(); - // actionExecutor.sleep(1); - // incubationPlateStateMgr.startIncubating(freeIncubationPos, System.currentTimeMillis(), projBuildinInfo.reactionPlateIncubationTimeMin * 60); - // actionExecutor.sleep(1); - // } catch (AppException e) { - // if (e.getError().eq(A8kEcode.APPE_TAKE_SAMPLE_FAIL)) { - // hbotMoveExCtrlService.moveQuickToZero(); - // tube.setErrors(ZList.of(e.getError())); - // incubationPlateStateMgr.resetIncubatorPos(freeIncubationPos); - // //丢反应板 - // optScanModuleCtrlService.forceDropPlate(freeIncubationPos); - // UISender.txErrorMsg(log, e, "取样失败"); - // } else { - // throw e; - // } - // } - // }, () -> { - // incubationPlateStateMgr.startIncubating(freeIncubationPos, System.currentTimeMillis(), projBuildinInfo.reactionPlateIncubationTimeMin * 60); - // }); - // - // - // {//开始孵育 - // } - // } - // - // - // private void incubationPlateProcess(Boolean waittingForAll) throws AppException { - // do { - // IncubationSubTank tankPos = incubationPlateStateMgr.getOneExpiredPlate(); - // if (!waittingForAll) { - // if (incubationPlateStateMgr.isHasEnoughIncubationIDLEPos(1) && tankPos == null) { - // break; - // } - // } else { - // if (incubationPlateStateMgr.isAllIncubationSubTanksFree()) { - // break; - // } - // } - // - // if (tankPos != null) { - // - // //拉取反应板到光学模组 - // docmd("拉取反应板到光学模块", () -> {optScanModuleCtrlService.pullPlate(tankPos.getPos());}); - // - // //设置光学模组状态 - // optScanModuleStateMgr.changeOptScanModuleStateToPlateIsReady(tankPos.projInfo, tankPos.toSampleInfo()); - // optScanModuleStateMgr.syncProjInfo(tankPos.projBuildinInfo, tankPos.projExtInfoCard); - // //复位孵育盘状态 - // incubationPlateStateMgr.resetIncubatorPos(tankPos.getPos()); - // - // // - // //光学扫描 - // // - // - // //光学扫描 - // optScanModuleStateMgr.changeOptScanModuleStateToScanning(); - // doOptScan(); - // //丢板 - // - // docmd("丢弃反应板", optScanModuleCtrlService::dropPlate); - // - // optScanModuleStateMgr.changeOptScanModuleStateToEmpty(); - // } - // - // actionExecutor.sleep(100); - // } while (true); - // } - // - // private void doOptScan() throws AppException { - // /* - // * HsCrp只有一个项目 - // */ - // Assert.isTrue(Objects.equals(expectedProjId, 1), "1 != expectedProjId"); - // - // int subProjIndex = 0; - // - // A8kOptType optType = optScanModuleStateMgr.getOptScanModule().getProjBuildinInfo().getOptType(subProjIndex); - // var buildInInfo = optScanModuleStateMgr.getOptScanModule().getProjBuildinInfo(); - // SampleInfo sampleInfo = optScanModuleStateMgr.getOptScanModule().getSampleInfo(); - // ProjInfo projInfo = optScanModuleStateMgr.getOptScanModule().getProjInfo(); - // - // // a8kOptPeakInfo - // docmd("光学扫描", () -> { - // OptScanResult optScanResult = optScanModuleCtrlService.optScan(buildInInfo, subProjIndex); - // ReactionReport.ReactionResult result = A8kPeakAnalyzer.analysisPeakInfo(sampleInfo, projInfo, subProjIndex, optScanResult.analysResult); - // - // log.info("光学扫描结果: {}", result); - // reactionRecordMgrService.addRecord(optScanModuleStateMgr.getOptScanModule().getSampleInfo(), projInfo, ZList.of(optScanResult), ZList.of(result)); - // } - // , () -> { - // OS.hsleep(1000); - // } - // ); - // } - // - // - // - // /* - // * Utils - // */ - // - // private void verifyTubeHolderSettingAndTubeHolderScanResult(TubeHolderSetting tubeHolderSetting, TubeHolderScanResult scanResult) throws AppException { - // A8kTubeHolderType tubeHolderType = A8kTubeHolderType.of(scanResult.tubeHolderType); - // if (!tubeHolderType.equals(A8kTubeHolderType.BulletTube1P5) && !tubeHolderType.equals(A8kTubeHolderType.BulletTube0P5)) { - // throw AppException.of(A8kEcode.APPE_TUBE_HOLDER_TYPE_IS_NOT_SUPPORT, "请使用子弹头1.5ml或者子弹头0.5ml试管架"); - // } - // - // for (int i = 0; i < tubeHolderSetting.tubeSettings.length; i++) { - // TubeSetting tubeSetting = tubeHolderSetting.tubeSettings[i]; - // if (tubeSetting.projId.isEmpty() && !scanResult.tube[i].isTubeExist) { - // continue; - // } - // - // if (tubeSetting.projId.isEmpty()) { - // throw AppException.of(A8kEcode.APPE_TUBEHOLDER_SETTING_ERROR, String.format("试管[%d]缺少项目配置", i + 1)); - // } - // - // if (!scanResult.tube[i].isTubeExist) { - // throw AppException.of(A8kEcode.APPE_TUBEHOLDER_SETTING_ERROR, String.format("位置[%d]未放入是试管", i + 1)); - // } - // - // } - // } + } diff --git a/src/main/java/a8k/app/engineer/service/state/TubeholderExSettingMgr.java b/src/main/java/a8k/app/engineer/service/state/TubeholderExSettingMgr.java new file mode 100644 index 0000000..e4d119b --- /dev/null +++ b/src/main/java/a8k/app/engineer/service/state/TubeholderExSettingMgr.java @@ -0,0 +1,35 @@ +package a8k.app.engineer.service.state; + +import a8k.app.engineer.service.type.TubeHolderExConfig; +import a8k.app.utils.ZJsonHelper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +@Slf4j +public class TubeholderExSettingMgr { + private TubeHolderExConfig tubeHolderExConfig = new TubeHolderExConfig(); + private Boolean enabled = false; + + synchronized public void submitTubeExConfig(TubeHolderExConfig tubeExTubeHolderExConfig) { + if (tubeExTubeHolderExConfig != null) { + this.tubeHolderExConfig = tubeExTubeHolderExConfig; + } + log.info("更新试管架配置 {}", ZJsonHelper.objectToJson(tubeHolderExConfig)); + } + + synchronized public TubeHolderExConfig getTubeExConfig() { + return tubeHolderExConfig; + } + + synchronized public void setEnabled(Boolean enabled) { + this.enabled = enabled; + log.info("设置试管架配置使能状态 {}", enabled); + } + + synchronized public Boolean isEnabled() { + return enabled; + } +} diff --git a/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java b/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java index 6706bfa..c968bf4 100644 --- a/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java +++ b/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java @@ -51,6 +51,8 @@ public class MainFlowCtrlScheduler { private ZWorkThread workThread; + Runnable onStop; + @PostConstruct void init() { workThread = new ZWorkThread(); @@ -90,10 +92,15 @@ public class MainFlowCtrlScheduler { } synchronized public void startWork() throws AppException { + startWork(null); + } + + synchronized public void startWork(Runnable onStop) throws AppException { checkBeforeCall(); checkBeforeStartOrContinueWork(); deviceWorkStateMgrService.clearConsumeNotEnoughErrorFlag(); deviceWorkStateMgrService.setStartActionPending(A8kWorkTaskType.MainFlowTask, true); + this.onStop = onStop; workThread.start(this::workThreadFn); } @@ -207,6 +214,10 @@ public class MainFlowCtrlScheduler { } log.info("MainFlowCtrlScheduler work thread stopped"); + var onStop = this.onStop; + if (onStop != null) { + onStop.run(); + } } } diff --git a/src/main/java/a8k/app/service/mainctrl/TubeHolderSettingMgrService.java b/src/main/java/a8k/app/service/mainctrl/TubeHolderSettingMgrService.java index 8eb0213..af1e882 100644 --- a/src/main/java/a8k/app/service/mainctrl/TubeHolderSettingMgrService.java +++ b/src/main/java/a8k/app/service/mainctrl/TubeHolderSettingMgrService.java @@ -163,8 +163,7 @@ public class TubeHolderSettingMgrService { //锁定第一个激活的试管架配置 synchronized public TubeHolderSetting getThelastActiveTubeHolderSetting() { - for (int i = 0; i < tubeHolderSettings.size(); i++) { - TubeHolderSetting setting = tubeHolderSettings.get(i); + for (TubeHolderSetting setting : tubeHolderSettings) { if (setting.active) { return ObjectUtil.cloneByStream(setting); } diff --git a/src/main/java/a8k/app/service/module/InFeedingCtrlModule.java b/src/main/java/a8k/app/service/module/InFeedingCtrlModule.java index 6078cfa..4cdd966 100644 --- a/src/main/java/a8k/app/service/module/InFeedingCtrlModule.java +++ b/src/main/java/a8k/app/service/module/InFeedingCtrlModule.java @@ -2,7 +2,9 @@ package a8k.app.service.module; import a8k.OS; import a8k.app.dao.type.db.ReactionReport; +import a8k.app.engineer.service.state.TubeholderExSettingMgr; import a8k.app.engineer.service.type.A8kCmdRunnable; +import a8k.app.engineer.service.type.TubeHolderExConfig; import a8k.app.factory.AppErrorFactory; import a8k.app.hardware.driver.InputDetectDriver; import a8k.app.hardware.type.A8kEcode; @@ -51,6 +53,7 @@ public class InFeedingCtrlModule { private final TubeStateMgr tubeStateMgr; private final DeviceWorkStateMgrService deviceWorkStateMgrService; private final TubeHolderSettingMgrService tubeHolderSettingMgrService; + private final TubeholderExSettingMgr tubeholderExSettingMgr; // // 数据库 private final ProjInfoMgrService projInfoMgrService; @@ -116,9 +119,20 @@ public class InFeedingCtrlModule { // 或者软件推测有新的试管架 if (getTubeholderEnterPosPPS() || deviceWorkStateMgrService.isMayHaveNewTubeHolder()) { + + TubeHolderSetting tubeSetting = tubeHolderSettingMgrService.getThelastActiveTubeHolderSetting(); + log.info("获取试管架配置 {}", tubeSetting); scanTubeHolder(tubeSetting); - tubeHolderSettingMgrService.removeLockTubeHolderSetting(tubeSetting); + + if (tubeSetting != null) { + if (tubeholderExSettingMgr.isEnabled()) { + log.warn("使用试管架扩展配置,说明当前处于一致性测试模式,该模式下,试管架配置不会被删除"); + } else { + log.info("removeLockTubeHolderSetting {}", tubeSetting.uuid); + tubeHolderSettingMgrService.removeLockTubeHolderSetting(tubeSetting); + } + } } } @@ -179,6 +193,18 @@ public class InFeedingCtrlModule { tube.userid = (setting.tubeSettings[i].userid); tube.projIds = (setting.tubeSettings[i].projId); } + if (tubeholderExSettingMgr.isEnabled()) { + if (tube.projIds.size() == 1) { + int repeatNum = tubeholderExSettingMgr.getTubeExConfig().tubeExConfigs.get(i).repeatTimes; + for (int j = 0; j < repeatNum - 1; j++) { + tube.projIds.add(tube.projIds.get(0)); + log.info("试管{} 添加重复项目: {}", i, tube.projIds.get(0)); + } + } else { + log.warn("试管架扩展配置,只支持项目数量为1个的试管"); + } + } + // TODO:添加请求后台的代码 if (tube.projIds.isEmpty()) { log.warn("试管{}待做项目为空", i);