diff --git a/src/main/java/a8k/app/constant/OptConstant.java b/src/main/java/a8k/app/constant/OptConstant.java index 824f25c..135f87e 100644 --- a/src/main/java/a8k/app/constant/OptConstant.java +++ b/src/main/java/a8k/app/constant/OptConstant.java @@ -1,10 +1,8 @@ package a8k.app.constant; public class OptConstant { - static public final Integer FOPT_LASTER_GAIN = 100; - static public final Integer TOPT_LASTER_GAIN = 100; - static public final Integer OPT_F_RESULT_TOLERATE = 700; + static public final Integer OPT_F_RESULT_TOLERATE = 300; static public final Integer OPT_T_RESULT_TOLERATE = 700; - static public final Integer OPT_T_TARGE_VAL = 2300; - static public final Integer OPT_F_TARGE_VAL = 2000; + static public final Integer OPT_T_TARGET_VAL = 2300; + static public final Integer OPT_F_TARGET_VAL = 3600; } 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 8a8e8b0..d543730 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.engineer.service.state.TubeholderExSettingMgr; import a8k.app.engineer.service.utils.BeforeDoEngineerActionChecker; import a8k.app.hardware.type.A8kEcode; +import a8k.app.service.data.ProjInfoMgrService; import a8k.app.service.mainctrl.MainFlowCtrlScheduler; import a8k.app.service.mainctrl.TubeHolderSettingMgrService; import a8k.app.service.statemgr.*; @@ -32,6 +33,7 @@ public class ExperimentConsistencyTestingService { final private TubeHolderSettingMgrService tubeHolderSettingMgrService; final private TubeholderExSettingMgr tubeholderExSettingMgr; final private MainFlowCtrlScheduler mainFlowCtrlScheduler; + final private ProjInfoMgrService projInfoMgrService; /** * 开始测试 @@ -59,6 +61,7 @@ public class ExperimentConsistencyTestingService { } } + /* * 核对耗材数量是否足够 */ @@ -68,9 +71,10 @@ public class ExperimentConsistencyTestingService { testTotalTimes += tubeholderExSettingMgr.getTubeExConfig().tubeExConfigs.get(tubeSetting.tubeIndex).repeatTimes; } } - if (consumablesMgrService.getConsumableNum(1/*hscrp项目*/) < testTotalTimes) { + Integer consumableNum = consumablesMgrService.getConsumableNum(projInfoMgrService.getProjBuildInInfo(1)); + if (consumableNum < testTotalTimes) { throw AppException.of(A8kEcode.APPE_CONSUME_NOT_ENOUGH, - String.format("反应板,当前剩余:%d,需要:%d", consumablesMgrService.getConsumableNum(1), testTotalTimes)); + String.format("反应板,当前剩余:%d,需要:%d",consumableNum, testTotalTimes)); } if (!consumablesMgrService.isHasEnoughTips((int) (testTotalTimes * 1.2))) { throw AppException.of(A8kEcode.APPE_TIP_NOT_ENOUGH, diff --git a/src/main/java/a8k/app/service/lowerctrl/OptScanModuleCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/OptScanModuleLowerCtrlService.java similarity index 96% rename from src/main/java/a8k/app/service/lowerctrl/OptScanModuleCtrlService.java rename to src/main/java/a8k/app/service/lowerctrl/OptScanModuleLowerCtrlService.java index 34d5c7a..abfa9da 100644 --- a/src/main/java/a8k/app/service/lowerctrl/OptScanModuleCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/OptScanModuleLowerCtrlService.java @@ -26,13 +26,13 @@ import java.util.Date; @Component @Slf4j -public class OptScanModuleCtrlService { +public class OptScanModuleLowerCtrlService { static final Integer overtime = 10000; /** * 光学增益自动调整器 */ - public class A8kOptGainAdjuster { + public static class A8kOptGainAdjuster { public Double suggestGain; public Boolean scanAgain; public Integer maxval; @@ -138,8 +138,6 @@ public class OptScanModuleCtrlService { A8kOptGainAdjuster gainAdjuster = new A8kOptGainAdjuster(); - // A8kOptType optType = optcfg.optType; - double scanRealGain = 0; int scanRawGain = 0; @@ -171,9 +169,9 @@ public class OptScanModuleCtrlService { Integer targetVal = 0; Integer tolerate = 0; if (optType == A8kOptType.TOPT) { - targetVal = OptConstant.OPT_T_TARGE_VAL; + targetVal = OptConstant.OPT_T_TARGET_VAL; } else if (optType == A8kOptType.FOPT) { - targetVal = OptConstant.OPT_F_TARGE_VAL; + targetVal = OptConstant.OPT_F_TARGET_VAL; } if (optType == A8kOptType.TOPT) { @@ -185,7 +183,7 @@ public class OptScanModuleCtrlService { //Adjustment gainAdjuster.process(result, scanRealGain, targetVal, tolerate); - log.info("adjuct {}", i); + log.info("adjust {}", i); log.info(" target : {}->{}", targetVal, targetVal + tolerate); log.info(" suggestGain : {}", gainAdjuster.suggestGain); log.info(" scanAgain : {}", gainAdjuster.scanAgain); diff --git a/src/main/java/a8k/app/service/lowerctrl/TubePreProcesModuleCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/TubePreProcessModuleCtrlService.java similarity index 97% rename from src/main/java/a8k/app/service/lowerctrl/TubePreProcesModuleCtrlService.java rename to src/main/java/a8k/app/service/lowerctrl/TubePreProcessModuleCtrlService.java index e370421..20c0ee1 100644 --- a/src/main/java/a8k/app/service/lowerctrl/TubePreProcesModuleCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/TubePreProcessModuleCtrlService.java @@ -16,8 +16,8 @@ import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor -public class TubePreProcesModuleCtrlService { - static Logger logger = LoggerFactory.getLogger(TubePreProcesModuleCtrlService.class); +public class TubePreProcessModuleCtrlService { + static Logger logger = LoggerFactory.getLogger(TubePreProcessModuleCtrlService.class); private final TubePreProcesPosParamMgr tubePreProcesPosParamMgr; diff --git a/src/main/java/a8k/app/service/lowerctrl/TubePreProcessModuleExCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/TubePreProcessModuleExCtrlService.java index 04edd03..0e33fa5 100644 --- a/src/main/java/a8k/app/service/lowerctrl/TubePreProcessModuleExCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/TubePreProcessModuleExCtrlService.java @@ -27,9 +27,9 @@ public class TubePreProcessModuleExCtrlService { } private final MiniServoDriver miniServoDriver; - private final StepMotorCtrlDriver stepMotorCtrlDriver; - private final TubePreProcesModuleCtrlService tubePreProcesModuleCtrlService; - private final TubePreProcesPosParamMgr tubePreProcesPosParamMgr; + private final StepMotorCtrlDriver stepMotorCtrlDriver; + private final TubePreProcessModuleCtrlService tubePreProcessModuleCtrlService; + private final TubePreProcesPosParamMgr tubePreProcesPosParamMgr; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++ // PRIVATE // ++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -66,7 +66,7 @@ public class TubePreProcessModuleExCtrlService { throw AppException.of(A8kEcode.LOW_EXT_ERROR_MOTOR_AT_WRONG_POS, MId.ShakeModGripperYSV); } - tubePreProcesModuleCtrlService.clampingMReleaseTube(); + tubePreProcessModuleCtrlService.clampingMReleaseTube(); //夹爪没有零位置 // if (!ZEQ.IntEq(miniServoDriver.miniServoReadPos(MiniServoMId.ShakeModGripperSV), MiniServoConstant.getZeroPos(MiniServoMId.ShakeModGripperSV), 30)) { @@ -82,71 +82,71 @@ public class TubePreProcessModuleExCtrlService { // Reset some motor // //试管夹紧移动到终点位置 - tubePreProcesModuleCtrlService.clampingMReleaseTube(); + tubePreProcessModuleCtrlService.clampingMReleaseTube(); //试管摇匀移动到90度 - tubePreProcesModuleCtrlService.shakeMMoveTo90(); + tubePreProcessModuleCtrlService.shakeMMoveTo90(); // //Y轴移动到取试管位置 - tubePreProcesModuleCtrlService.YSVMoveToTakeTubePos(); + tubePreProcessModuleCtrlService.YSVMoveToTakeTubePos(); //取试管 - tubePreProcesModuleCtrlService.takeTubeFromTubeholder(isHTube); + tubePreProcessModuleCtrlService.takeTubeFromTubeholder(isHTube); //Y轴移动到摇匀位 - tubePreProcesModuleCtrlService.YSVMoveToShakePos(); + tubePreProcessModuleCtrlService.YSVMoveToShakePos(); //Z轴下移动到摇匀位放试管的位置 - tubePreProcesModuleCtrlService.zMotorMoveToShakeTubePos(0); + tubePreProcessModuleCtrlService.zMotorMoveToShakeTubePos(0); //夹紧试管 - tubePreProcesModuleCtrlService.clampingMclampTube(); + tubePreProcessModuleCtrlService.clampingMclampTube(); //松开夹爪,放置试管 - tubePreProcesModuleCtrlService.gripperSVOpen(); + tubePreProcessModuleCtrlService.gripperSVOpen(); //Z轴上移动到零位 - tubePreProcesModuleCtrlService.zMotorMoveToZeroQuick(); + tubePreProcessModuleCtrlService.zMotorMoveToZeroQuick(); //Y轴移动到零位 - tubePreProcesModuleCtrlService.YSVMoveToStandyPos(); + tubePreProcessModuleCtrlService.YSVMoveToStandyPos(); progress = PROGRESS.TAKE_TUBE; } public void shakeTube(Integer shakeDegree, Integer times) throws AppException { log.info("摇匀试管 {} {}", shakeDegree, times); - tubePreProcesModuleCtrlService.shakeMShake(shakeDegree, times); + tubePreProcessModuleCtrlService.shakeMShake(shakeDegree, times); progress = PROGRESS.SHAKE_TUBE; } public void takeTubeCap() throws AppException { log.info("取试管帽"); //Y移动到取试管帽位置 - tubePreProcesModuleCtrlService.YSVMoveToShakePos(); + tubePreProcessModuleCtrlService.YSVMoveToShakePos(); //Z下移动到取试管帽位置 - tubePreProcesModuleCtrlService.zMotorMoveToShakeTubePos(15);//1.5mm + tubePreProcessModuleCtrlService.zMotorMoveToShakeTubePos(15);//1.5mm //闭合夹爪 - tubePreProcesModuleCtrlService.gripperSVClampTube(); + tubePreProcessModuleCtrlService.gripperSVClampTube(); stepMotorCtrlDriver.moveByBlock(StepMotorMId.ShakeModGripperZM, -50, StepMotorSpeedLevel.LOW); //Z上移动到零位 - tubePreProcesModuleCtrlService.zMotorMoveToZeroQuick(); + tubePreProcessModuleCtrlService.zMotorMoveToZeroQuick(); //Y移动到待机位 - tubePreProcesModuleCtrlService.YSVMoveToStandyPos(); + tubePreProcessModuleCtrlService.YSVMoveToStandyPos(); progress = PROGRESS.TAKE_CAP; } public void putbakTubeCapAndPutbakTubeToTubeHolder() throws AppException { //移动Y轴到方式管的位置 - tubePreProcesModuleCtrlService.YSVMoveToShakePos(); + tubePreProcessModuleCtrlService.YSVMoveToShakePos(); // 盖盖子 - tubePreProcesModuleCtrlService.zMotorMoveToPutCapPos(); + tubePreProcessModuleCtrlService.zMotorMoveToPutCapPos(); //释放试管 - tubePreProcesModuleCtrlService.clampingMReleaseTube(); + tubePreProcessModuleCtrlService.clampingMReleaseTube(); //Z轴上移动到零位 - tubePreProcesModuleCtrlService.zMotorMoveToZeroQuick(); + tubePreProcessModuleCtrlService.zMotorMoveToZeroQuick(); //Y轴移动到取试管的位置 - tubePreProcesModuleCtrlService.YSVMoveToTakeTubePos(); + tubePreProcessModuleCtrlService.YSVMoveToTakeTubePos(); //移动到放试管的位置 - tubePreProcesModuleCtrlService.zMotorMoveToTakeHBakTubePos(isHTube); + tubePreProcessModuleCtrlService.zMotorMoveToTakeHBakTubePos(isHTube); //打开夹爪 - tubePreProcesModuleCtrlService.gripperSVOpen(); + tubePreProcessModuleCtrlService.gripperSVOpen(); //设备快速归零 - tubePreProcesModuleCtrlService.moveToZeroQuick(); + tubePreProcessModuleCtrlService.moveToZeroQuick(); // miniServoDriver.miniServoMoveToZeroBlock(MiniServoMId.ShakeModLiftingSV); progress = PROGRESS.PUT_BAK_TUBE; @@ -159,23 +159,23 @@ public class TubePreProcessModuleExCtrlService { return; } else if (progress.equals(PROGRESS.TAKE_TUBE) || progress.equals(PROGRESS.SHAKE_TUBE)) { //Y移动到取试管帽位置 - tubePreProcesModuleCtrlService.YSVMoveToShakePos(); + tubePreProcessModuleCtrlService.YSVMoveToShakePos(); //Z下移动到取试管帽位置 - tubePreProcesModuleCtrlService.zMotorMoveToShakeTubePos(15); + tubePreProcessModuleCtrlService.zMotorMoveToShakeTubePos(15); //闭合夹爪 - tubePreProcesModuleCtrlService.gripperSVClampTube(); + tubePreProcessModuleCtrlService.gripperSVClampTube(); //释放试管 - tubePreProcesModuleCtrlService.clampingMReleaseTube(); + tubePreProcessModuleCtrlService.clampingMReleaseTube(); //Z上移动到零位 - tubePreProcesModuleCtrlService.zMotorMoveToZeroQuick(); + tubePreProcessModuleCtrlService.zMotorMoveToZeroQuick(); //Y轴移动到取试管的位置 - tubePreProcesModuleCtrlService.YSVMoveToTakeTubePos(); + tubePreProcessModuleCtrlService.YSVMoveToTakeTubePos(); //移动到放试管的位置 - tubePreProcesModuleCtrlService.zMotorMoveToTakeHBakTubePos(isHTube); + tubePreProcessModuleCtrlService.zMotorMoveToTakeHBakTubePos(isHTube); //打开夹爪 - tubePreProcesModuleCtrlService.gripperSVOpen(); + tubePreProcessModuleCtrlService.gripperSVOpen(); //设备快速归零 - tubePreProcesModuleCtrlService.moveToZeroQuick(); + tubePreProcessModuleCtrlService.moveToZeroQuick(); miniServoDriver.miniServoMoveToZeroBlock(MiniServoMId.ShakeModLiftingSV); diff --git a/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java b/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java index 6929647..76f7731 100644 --- a/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java +++ b/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java @@ -6,7 +6,7 @@ import a8k.app.service.appsetup.A8kSubModuleRegInitService; import a8k.app.service.lowerctrl.HbotMoveCtrlService; import a8k.app.service.lowerctrl.HbotMoveExCtrlService; import a8k.app.service.lowerctrl.TubeFeedingCtrlService; -import a8k.app.service.lowerctrl.TubePreProcesModuleCtrlService; +import a8k.app.service.lowerctrl.TubePreProcessModuleCtrlService; import a8k.app.type.exception.AppException; import a8k.app.type.ui.ZAppPromopt; import a8k.app.type.ui.ZAppPromoptFormsItem; @@ -84,9 +84,9 @@ public class AppDeviceInitCtrlService { // // Service // - private final TubeFeedingCtrlService tubeFeedingCtrlService; - private final TubePreProcesModuleCtrlService tubePreProcesModuleCtrlService; - private final HbotMoveExCtrlService hbotMoveExCtrlService; + private final TubeFeedingCtrlService tubeFeedingCtrlService; + private final TubePreProcessModuleCtrlService tubePreProcessModuleCtrlService; + private final HbotMoveExCtrlService hbotMoveExCtrlService; private final HbotMoveCtrlService hbotMoveCtrlService; private final A8kSubModuleRegInitService a8kSubModuleRegInitService; @@ -285,7 +285,7 @@ public class AppDeviceInitCtrlService { log.info("摇匀模组摇匀电机回零"); stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.ShakeModShakeM); log.info("摇匀模组摇匀电机摆动90度"); - tubePreProcesModuleCtrlService.shakeMMoveTo90(); + tubePreProcessModuleCtrlService.shakeMMoveTo90(); log.info("入料平移电机回零"); stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.FeedingModXM); //板夹仓初始化 diff --git a/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java b/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java index 4d53ff3..5315439 100644 --- a/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java +++ b/src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java @@ -4,6 +4,8 @@ import a8k.OS; import a8k.app.engineer.service.state.EngineerModeStateMgrService; import a8k.app.engineer.service.type.EngineerWorkState; import a8k.app.service.ctrlmodule.TipOperationCtrlModule; +import a8k.app.service.lowerctrl.OptScanModuleLowerCtrlService; +import a8k.app.service.lowerctrl.TubeFeedingCtrlService; import a8k.app.service.module.*; import a8k.app.service.statemgr.*; import a8k.app.type.DeviceRunMode; @@ -50,6 +52,10 @@ public class MainFlowCtrlScheduler { private final AppEventBusService appEventBusService; private final PreReactionStateMgr preReactionStateMgr; + + private final OptScanModuleLowerCtrlService optScanModuleLowerCtrlService; + private final TubeFeedingCtrlService tubeFeedingCtrlService; + private ZWorkThread workThread; Runnable onStop; @@ -209,6 +215,13 @@ public class MainFlowCtrlScheduler { appEventBusService.pushEvent(ZAppPromoptFactory.buildAppPromoptEvent(appError)); } } + //清空正在处理的试管架 + try { + tubeStateMgr.resetAll(); + tubeFeedingCtrlService.ejectTubeHolder(); + } catch (AppException e) { + appEventBusService.pushEvent(ZAppPromoptFactory.buildAppPromoptEvent(e)); + } log.info("MainFlowCtrlScheduler work thread stopped"); var onStop = this.onStop; diff --git a/src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java b/src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java index 20eef36..94f9de7 100644 --- a/src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java +++ b/src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java @@ -3,7 +3,7 @@ package a8k.app.service.module; import a8k.OS; import a8k.app.engineer.service.type.A8kCmdRunnable; import a8k.app.factory.AppErrorFactory; -import a8k.app.service.lowerctrl.OptScanModuleCtrlService; +import a8k.app.service.lowerctrl.OptScanModuleLowerCtrlService; import a8k.app.service.lowerctrl.PlateBoxCtrlService; import a8k.app.service.lowerctrl.TurnableMoveCtrlService; import a8k.app.service.statemgr.GStateMgrService; @@ -64,14 +64,14 @@ public class IncubationPlateCtrlModule { // //状态 // - private final GStateMgrService gStateMgrService; - private final IncubationPlateStateMgr incubationPlateStateMgr; - private final OptScanModuleStateMgr optScanModuleStateMgr; + private final GStateMgrService gStateMgrService; + private final IncubationPlateStateMgr incubationPlateStateMgr; + private final OptScanModuleStateMgr optScanModuleStateMgr; // // 控制 // - private final OptScanModuleCtrlService optScanModuleCtrlService; - private final PlateBoxCtrlService plateBoxCtrlService; + private final OptScanModuleLowerCtrlService optScanModuleLowerCtrlService; + private final PlateBoxCtrlService plateBoxCtrlService; private final Object hardwareLock = new Object(); @@ -154,10 +154,13 @@ public class IncubationPlateCtrlModule { if (tankPos != null && optScanModuleStateMgr.isEmpty()) { //拉取反应板到光学模组 docmd("拉取反应板到光学模块",// - () -> optScanModuleCtrlService.pullPlate(tankPos.getPos())); + () -> optScanModuleLowerCtrlService.pullPlate(tankPos.getPos())); //设置光学模组状态 - optScanModuleStateMgr.syncProjInfo(tankPos.projBuildinInfo, tankPos.projExtInfoCard); - optScanModuleStateMgr.changeOptScanModuleStateToPlateIsReady(tankPos.projInfo, tankPos.toSampleInfo()); + optScanModuleStateMgr.changeOptScanModuleStateToPlateIsReady( + tankPos.cxtId, + tankPos.getSampleInfo(), + tankPos.projBuildinInfo, + tankPos.projExtInfoCard); //复位孵育盘状态 incubationPlateStateMgr.resetIncubatorPos(tankPos.getPos()); continue; @@ -177,8 +180,8 @@ public class IncubationPlateCtrlModule { var errorTank = incubationPlateStateMgr.getErrorPlate(); docmd("处理异常反应板", // () -> { - optScanModuleCtrlService.pullPlate(errorTank.getPos()); - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.pullPlate(errorTank.getPos()); + optScanModuleLowerCtrlService.dropPlate(); }); incubationPlateStateMgr.resetIncubatorPos(errorTank.getPos()); } @@ -188,8 +191,8 @@ public class IncubationPlateCtrlModule { if (notClearedTank != null && optScanModuleStateMgr.isEmpty()) { //清空孵育盘 docmd("强制清空反应板", () -> { - optScanModuleCtrlService.pullPlate(notClearedTank.getPos()); - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.pullPlate(notClearedTank.getPos()); + optScanModuleLowerCtrlService.dropPlate(); }); incubationPlateStateMgr.setIncubationPosCleared(notClearedTank.getPos()); continue; @@ -200,6 +203,20 @@ public class IncubationPlateCtrlModule { state.setFatalAppError(AppErrorFactory.exceptionToAppError(e)); } } + synchronized (hardwareLock) { + try { + var allNotFreeTanks = incubationPlateStateMgr.getAllNotFreeIncubationSubTanks(); + for (var incubationSubTank : allNotFreeTanks) { + optScanModuleLowerCtrlService.pullPlate(incubationSubTank.getPos()); + optScanModuleLowerCtrlService.dropPlate(); + incubationPlateStateMgr.resetIncubatorPos(incubationSubTank.getPos()); + } + } catch (Exception e) { + log.error("TurntableAndOptScannerCtrlModule work thread stop error", e); + state.setFatalAppError(AppErrorFactory.exceptionToAppError(e)); + } + } + state.isWorking = false; } diff --git a/src/main/java/a8k/app/service/module/OptScanCtrlModule.java b/src/main/java/a8k/app/service/module/OptScanCtrlModule.java index 198b096..d83bfe3 100644 --- a/src/main/java/a8k/app/service/module/OptScanCtrlModule.java +++ b/src/main/java/a8k/app/service/module/OptScanCtrlModule.java @@ -7,9 +7,10 @@ import a8k.app.factory.AppErrorFactory; import a8k.app.factory.FakeReactionResultFactory; import a8k.app.optalgo.A8kPeakAnalyzer; import a8k.app.service.data.ReactionRecordMgrService; -import a8k.app.service.lowerctrl.OptScanModuleCtrlService; +import a8k.app.service.lowerctrl.OptScanModuleLowerCtrlService; import a8k.app.service.statemgr.GStateMgrService; import a8k.app.service.statemgr.OptScanModuleStateMgr; +import a8k.app.service.statemgr.ProjectCxtMgr; import a8k.app.service.utils.UISender; import a8k.app.type.DeviceRunMode; import a8k.app.type.a8k.opt.A8kOptType; @@ -58,16 +59,17 @@ public class OptScanCtrlModule { // //状态 // - private final GStateMgrService gStateMgrService; - private final OptScanModuleStateMgr optScanModuleStateMgr; + private final GStateMgrService gStateMgrService; + private final OptScanModuleStateMgr optScanModuleStateMgr; + private final ProjectCxtMgr projectCxtMgr; // // 数据库 // - private final ReactionRecordMgrService reactionRecordMgrService; + private final ReactionRecordMgrService reactionRecordMgrService; // // 控制 // - private final OptScanModuleCtrlService optScanModuleCtrlService; + private final OptScanModuleLowerCtrlService optScanModuleLowerCtrlService; private final Object hardwareLock = new Object(); @@ -113,9 +115,10 @@ public class OptScanCtrlModule { } if (!optScanModuleStateMgr.isCleared()) { - docmd("清除光学扫描模块状态", () -> optScanModuleCtrlService.dropPlate()); + docmd("清除光学扫描模块状态", optScanModuleLowerCtrlService::dropPlate); optScanModuleStateMgr.setCleared(true); optScanModuleStateMgr.changeOptScanModuleStateToEmpty(); + } if (optScanModuleStateMgr.isPlateIsReady()) { @@ -123,7 +126,8 @@ public class OptScanCtrlModule { results = null; docmd("扫描反应板", this::doOptScan, this::doOptScanVirtual); - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.dropPlate(); + projectCxtMgr.clearCxt(optScanModuleStateMgr.getOptScanModule().getCxtId()); optScanModuleStateMgr.changeOptScanModuleStateToEmpty(); } } @@ -158,7 +162,7 @@ public class OptScanCtrlModule { }; if (optScanResult == null) { - optScanResult = optScanModuleCtrlService.optScan(projInfo.buildIn, i); + optScanResult = optScanModuleLowerCtrlService.optScan(projInfo.buildIn, i); switch (optType) { case TOPT -> tOptScanResults = optScanResult; case FOPT -> fOptScanResults = optScanResult; diff --git a/src/main/java/a8k/app/service/module/SamplePreProcessModule.java b/src/main/java/a8k/app/service/module/SamplePreProcessModule.java index a77470d..e361dac 100644 --- a/src/main/java/a8k/app/service/module/SamplePreProcessModule.java +++ b/src/main/java/a8k/app/service/module/SamplePreProcessModule.java @@ -152,6 +152,8 @@ public class SamplePreProcessModule { state.setFatalAppError(AppErrorFactory.exceptionToAppError(e)); } } + + state.isWorking = false; } @@ -164,13 +166,16 @@ public class SamplePreProcessModule { log.info("处理预反应完成的格子: {}:{}", preReactionGrid.group, preReactionGrid.posIndex); docmd("取预反应液", () -> liquidOperationCtrService.takePreReactionLiquid(preReactionPos, true)); + preReactionStateMgr.changeReactionGridStateToUsed(preReactionPos); + incubationPlateCtrlModule.dropLiquidAndStartIncubating( preReactionGrid.bindIncubatorPos, () -> docmd("滴入反应液到孵育盘", () -> liquidOperationCtrService.dropLiquidToReactionPlate(true)), projBuildInInfo.reactionPlateIncubationTimeMin * 60 ); + docmd("丢TIP", tipOperationCtrlModule::dropTip); } @@ -189,9 +194,12 @@ public class SamplePreProcessModule { Tube tube = tubeStateMgrService.getCurProcessingTube(); Assert.isTrue(tube != null, "tube != null"); for (var cxt : tube.getPreProcessContexts()) { - var incubatorPos = incubationPlateStateMgr.takeOneIncubationIDLEPos((IncubatorPos pos) -> - incubationPlateStateMgr.syncCxtInfo(pos, cxt.getSampleInfo(), cxt.getProjBuildinInfo(), cxt.getProjExtInfoCard(), cxt.getConsumableInfo()) - ); + var incubatorPos = incubationPlateStateMgr.takeOneIncubationIDLEPos( + cxt.getCxtId(), + cxt.getSampleInfo(), + cxt.getProjBuildinInfo(), + cxt.getProjExtInfoCard(), + cxt.getConsumableInfo()); tubeStateMgrService.setTubeCxtIncubationPos(cxt, incubatorPos); consumablesMgrService.useReserveConsumable(cxt.getConsumableInfo()); } @@ -293,6 +301,9 @@ public class SamplePreProcessModule { liquidOperationCtrService.setProjContext(cxt.getProjBuildinInfo(), cxt.getProjExtInfoCard()); + /* + * 预处理 + */ switch (reactionFlowType) { case SampleAndBSAndProbeSubstance -> { UISender.txInfoMsg(log, "取大瓶缓冲液到探测物质中"); @@ -301,6 +312,7 @@ public class SamplePreProcessModule { Assert.notNull(largeBufferPos, "largeBufferPos != null"); Assert.notNull(preReactionPos, "preReactionPos != null"); docmd("取大瓶缓冲液", () -> liquidOperationCtrService.takeLargeBottleBufferLiquidToProbeSubstance(largeBufferPos, preReactionPos, largeBSVolume)); + docmd("取TIP", tipOperationCtrlModule::tryTakeTip); } case SampleAndBS -> { Assert.notNull(preReactionPos, "preReactionPos != null"); @@ -312,30 +324,45 @@ public class SamplePreProcessModule { } } + //等待样品,摇匀完成 sampleIsReadyCondition.waitTrue(); + + // //取样本到小缓冲瓶或者探测物质 + // docmd("取样", () -> liquidOperationCtrService.takeSample(samplePos, sampleVol)); + // //远离取样位置,移动到下一个动作的位置 + // switch (reactionFlowType) { case SampleAndBSAndProbeSubstance, SampleAndBS -> docmd(String.format("移动到预反应位置%s", preReactionPos), () -> hbotMoveExCtrlService.moveToPreReactionPosXY(preReactionPos)); case SampleOnly -> docmd("移动到滴定位", hbotMoveExCtrlService::moveToDropLiquidPosXY); } + // //如果当前项目是这个试管的最后一个项目,则在这里之后,就不再需要样本了,摇匀模组就可以回收样本了 + // if (finalCxt) { sampleProcessFinishedCondition.setReady(); } + // + // 放入样本到指定位置 + // switch (reactionFlowType) { - case SampleAndBSAndProbeSubstance, SampleAndBS -> { + // + // SampleAndBSAndProbeSubstance,SampleAndBS 两种反应流程需要<样本>和<缓冲液>混合后再滴入到<反应板>上 + //如果混合后立即滴入到反应板上,则在这里直接处理,否则稍后再处理. + // + case SampleAndBSAndProbeSubstance, SampleAndBS -> { if (projBuildInInfo.getMixedLiquidPreReactionTimeMin() == 0) { docmd("分配样本到预反应位", () -> liquidOperationCtrService.distributeSampleToPreReactionPos(preReactionPos, false, false)); docmd("取预反应液", () -> liquidOperationCtrService.takePreReactionLiquid(preReactionPos, false)); - preReactionStateMgr.syncGridInfo(preReactionPos, tube, tube.getPos()); + preReactionStateMgr.syncGridInfo(preReactionPos, tube, cxt); preReactionStateMgr.changeReactionGridStateToUsed(preReactionPos); incubationPlateCtrlModule.dropLiquidAndStartIncubating( @@ -345,17 +372,24 @@ public class SamplePreProcessModule { }, cxt.getProjBuildinInfo().reactionPlateIncubationTimeMin * 60 ); + docmd("丢TIP", tipOperationCtrlModule::dropTip); + } else { /* * 有些项目 样本和缓冲液混合后,需要先反应一定时间后,才开始孵育 */ docmd("分配样本到预反应位置", () -> liquidOperationCtrService.distributeSampleToPreReactionPos(preReactionPos, false, true)); - preReactionStateMgr.syncGridInfo(preReactionPos, tube, tube.getPos()); + preReactionStateMgr.syncGridInfo(preReactionPos, tube, cxt); preReactionStateMgr.changeReactionGridStateToReacting(preReactionPos, projBuildInInfo.getMixedLiquidPreReactionTimeMin() * 60L); + docmd("丢TIP", tipOperationCtrlModule::dropTip); + } } + // + // SampleOnly 无需混合缓冲液,直接滴入到反应板上即可. + // case SampleOnly -> { incubationPlateCtrlModule.dropLiquidAndStartIncubating( cxt.getIncubatorPos(), @@ -363,6 +397,7 @@ public class SamplePreProcessModule { cxt.getProjBuildinInfo().reactionPlateIncubationTimeMin * 60 ); UISender.txInfoMsg(log, "开始孵育"); + docmd("丢TIP", tipOperationCtrlModule::dropTip); } } } diff --git a/src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java b/src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java index 67338f5..4218316 100644 --- a/src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java +++ b/src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java @@ -1,5 +1,6 @@ package a8k.app.service.statemgr; +import a8k.app.dao.type.combination.ProjBuildInInfo; import a8k.app.factory.FakeA8kConsumableContainerFactory; import a8k.app.service.statemgr.consumables_mgr.LarBottleContainerStateMgr; import a8k.app.service.statemgr.consumables_mgr.LittBottleContainerStateMgr; @@ -126,12 +127,21 @@ public class ConsumablesMgrService { } - synchronized public Integer getConsumableNum(Integer projId) { - return minVal( - reactionPlateContainerStateMgr.getConsumableNum(projId), - littBottleContainerStateMgr.getConsumableNum(projId), - larBottleContainerStateMgr.getConsumableNum(projId) - ); + synchronized public Integer getConsumableNum(ProjBuildInInfo projBuildInInfo) { + return switch (projBuildInInfo.getReactionFlowType()) { + case SampleAndBS -> minVal( + reactionPlateContainerStateMgr.getConsumableNum(projBuildInInfo.getProjId()), + littBottleContainerStateMgr.getConsumableNum(projBuildInInfo.getProjId()) + ); + case SampleAndBSAndProbeSubstance -> minVal( + reactionPlateContainerStateMgr.getConsumableNum(projBuildInInfo.getProjId()), + littBottleContainerStateMgr.getConsumableNum(projBuildInInfo.getProjId()), + larBottleContainerStateMgr.getConsumableNum(projBuildInInfo.getProjId()) + ); + + case SampleOnly -> reactionPlateContainerStateMgr.getConsumableNum(projBuildInInfo.getProjId()); + }; + } diff --git a/src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java b/src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java index fa950c7..911e9a7 100644 --- a/src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java @@ -150,14 +150,34 @@ public class IncubationPlateStateMgr { return null; } - synchronized public IncubatorPos takeOneIncubationIDLEPos(SyncState syncState) { - var subtanks = incubationPlate.subtanks; + synchronized public IncubatorPos takeOneIncubationIDLEPos( + String cxtId, + SampleInfo sampleInfo, + ProjBuildInInfo projBuildinInfo, + ProjExtInfoCard projExtInfoCard, + ConsumableInfo consumableInfo) { + var subtanks = incubationPlate.subtanks; for (IncubationSubTank subtank : subtanks) { if (subtank.state.equals(IncubationSubTankState.EMPTY) && subtank.getHasCleared()) { subtank.state = IncubationSubTankState.RESERVED; log.info("孵育盘[{}] 状态->预定", subtank.getPos()); - syncState.syncState(subtank.getPos()); + + subtank.sampleId = sampleInfo.sampleId; + subtank.bloodType = sampleInfo.bloodType; + subtank.sampleBarcode = sampleInfo.sampleBarcode; + subtank.userid = sampleInfo.userid; + subtank.isEmergency = sampleInfo.isEmergency; + subtank.cxtId = cxtId; + + subtank.projBuildinInfo = projBuildinInfo; + subtank.projExtInfoCard = projExtInfoCard; + subtank.lotId = projExtInfoCard.lotId; + subtank.projId = projBuildinInfo.projId; + subtank.projInfo = ProjInfoUtils.buildProjBrefInfo(projBuildinInfo); + + subtank.consumableInfo = consumableInfo; + return subtank.getPos(); } } @@ -223,25 +243,8 @@ public class IncubationPlateStateMgr { } } - // synchronized public void syncSampleInfo(IncubatorPos pos,) { - // var subtanks = incubationPlate.subtanks; - // subtanks[pos.off].sampleId = sampleInfo.sampleId; - // subtanks[pos.off].bloodType = sampleInfo.bloodType; - // subtanks[pos.off].sampleBarcode = sampleInfo.sampleBarcode; - // subtanks[pos.off].userid = sampleInfo.userid; - // subtanks[pos.off].isEmergency = sampleInfo.isEmergency; - // } - // - // synchronized public void syncProjInfo(IncubatorPos pos, ProjBuildInInfo projBuildinInfo, ProjExtInfoCard projExtInfoCard) { - // var subtanks = incubationPlate.subtanks; - // subtanks[pos.off].projBuildinInfo = projBuildinInfo; - // subtanks[pos.off].projExtInfoCard = projExtInfoCard; - // subtanks[pos.off].lotId = projExtInfoCard.lotId; - // subtanks[pos.off].projId = projBuildinInfo.projId; - // subtanks[pos.off].projInfo = ProjInfoUtils.buildProjBrefInfo(projBuildinInfo); - // } - - synchronized public void syncCxtInfo(IncubatorPos pos, SampleInfo sampleInfo, ProjBuildInInfo projBuildinInfo, ProjExtInfoCard projExtInfoCard, ConsumableInfo consumableInfo) { + + synchronized public void syncCxtInfo(IncubatorPos pos, String cxtId, SampleInfo sampleInfo, ProjBuildInInfo projBuildinInfo, ProjExtInfoCard projExtInfoCard, ConsumableInfo consumableInfo) { var subtanks = incubationPlate.subtanks; subtanks[pos.off].sampleId = sampleInfo.sampleId; @@ -249,6 +252,7 @@ public class IncubationPlateStateMgr { subtanks[pos.off].sampleBarcode = sampleInfo.sampleBarcode; subtanks[pos.off].userid = sampleInfo.userid; subtanks[pos.off].isEmergency = sampleInfo.isEmergency; + subtanks[pos.off].cxtId = cxtId; subtanks[pos.off].projBuildinInfo = projBuildinInfo; subtanks[pos.off].projExtInfoCard = projExtInfoCard; diff --git a/src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java b/src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java index 06564bd..2585d68 100644 --- a/src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java @@ -1,5 +1,6 @@ package a8k.app.service.statemgr; +import a8k.app.service.utils.ProjInfoUtils; import a8k.app.type.DeviceRunMode; import a8k.app.type.a8k.BloodType; import a8k.app.type.a8k.state.OptScanModuleState; @@ -66,24 +67,23 @@ public class OptScanModuleStateMgr { log.info("光学模块: 状态->空闲"); } - synchronized public void changeOptScanModuleStateToPlateIsReady(ProjBriefInfo projBriefInfo, SampleInfo sampleInfo) { + synchronized public void changeOptScanModuleStateToPlateIsReady(String cxtid, SampleInfo sampleInfo, ProjBuildInInfo projBuildinInfo, ProjExtInfoCard projExtInfoCard) { optScanModule.state = OptScanModuleStateEnum.PLATE_IS_READY; optScanModule.setBloodType(sampleInfo.bloodType); optScanModule.setSampleBarcode(sampleInfo.sampleBarcode); optScanModule.setUserid(sampleInfo.userid); - optScanModule.setProjInfo(projBriefInfo); + optScanModule.setProjInfo(ProjInfoUtils.buildProjBrefInfo(projBuildinInfo)); optScanModule.setSampleId(sampleInfo.sampleId); optScanModule.setIsEmergency(sampleInfo.isEmergency); - optScanModule.setProjId(projBriefInfo.projId); - log.info("光学模块:状态->反应板准备就绪 {}", sampleInfo); - } - - synchronized public void syncProjInfo(ProjBuildInInfo projBuildinInfo, ProjExtInfoCard projExtInfoCard) { + optScanModule.setProjId(projBuildinInfo.projId); optScanModule.setProjBuildinInfo(projBuildinInfo); optScanModule.setProjExtInfoCard(projExtInfoCard); optScanModule.setLotId(projExtInfoCard.lotId); + optScanModule.setCxtId(cxtid); + log.info("光学模块:状态->反应板准备就绪 {}", sampleInfo); } + synchronized public void changeOptScanModuleStateToScanning() { log.info("光学模块: 状态->开始扫描"); optScanModule.state = OptScanModuleStateEnum.SCANNING; diff --git a/src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java b/src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java index 09607cc..769a97e 100644 --- a/src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java @@ -11,6 +11,7 @@ import a8k.app.type.a8k.ConsumableGroup; import a8k.app.type.a8k.LittleBottleConsumableType; import a8k.app.type.a8k.container.LittBottleConsumablesInfo; import a8k.app.type.a8k.pos.PreReactionPos; +import a8k.app.type.a8k.state.ProjectPreProcessContext; import a8k.app.type.a8k.state.SampleInfo; import a8k.app.type.a8k.state.Tube; import a8k.app.type.exception.AppException; @@ -147,14 +148,15 @@ public class PreReactionStateMgr { return null; } - public synchronized void syncGridInfo(PreReactionPos preReactionPos, Tube fromTube, Integer off) { + public synchronized void syncGridInfo(PreReactionPos preReactionPos, Tube fromTube, ProjectPreProcessContext cxt) { PreReactionGridGroup gridGroup = getPreReactionGridGroup(preReactionPos.group); Assert.notNull(gridGroup, "gridGroup != null"); var grid = gridGroup.grids.get(preReactionPos.index); - grid.projBuildinInfo = fromTube.getPreProcessContexts().get(off).getProjBuildinInfo(); - grid.projExtInfoCard = fromTube.getPreProcessContexts().get(off).getProjExtInfoCard(); + grid.projBuildinInfo = cxt.getProjBuildinInfo(); + grid.projExtInfoCard = cxt.getProjExtInfoCard(); grid.sampleInfo = fromTube.getSampleInfo(); - grid.bindIncubatorPos = fromTube.getPreProcessContexts().get(off).getIncubatorPos(); + grid.bindIncubatorPos = cxt.getIncubatorPos(); + grid.cxtId = cxt.getCxtId(); gridGroup.version++; } @@ -248,6 +250,7 @@ public class PreReactionStateMgr { grid.reactionRemainingTime = 0L; grid.totalReactionTime = 0L; grid.bindIncubatorPos = null; + grid.cxtId = ""; grid.sampleInfo = new SampleInfo(); grid.projBuildinInfo = null; grid.projExtInfoCard = null; diff --git a/src/main/java/a8k/app/service/statemgr/ProjectCxtMgr.java b/src/main/java/a8k/app/service/statemgr/ProjectCxtMgr.java new file mode 100644 index 0000000..a96cb01 --- /dev/null +++ b/src/main/java/a8k/app/service/statemgr/ProjectCxtMgr.java @@ -0,0 +1,42 @@ +package a8k.app.service.statemgr; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +@RequiredArgsConstructor +@Slf4j +public class ProjectCxtMgr { + static public class ProjectCxt { + public Map cxtMap; + } + + Map projectCxtMap; + + synchronized public Object getCxtValue(String cxtId, String key) { + ProjectCxt projectCxt = projectCxtMap.get(cxtId); + if (projectCxt == null) { + return null; + } + return projectCxt.cxtMap.get(key); + } + + synchronized public void setCxtValue(String cxtId, String key, Object value) { + ProjectCxt projectCxt = projectCxtMap.get(cxtId); + if (projectCxt == null) { + projectCxt = new ProjectCxt(); + projectCxtMap.put(cxtId, projectCxt); + } + projectCxt.cxtMap.put(key, value); + } + + synchronized public void clearCxt(String cxtId) { + ProjectCxt projectCxt = projectCxtMap.get(cxtId); + if (projectCxt != null) { + projectCxtMap.remove(cxtId); + } + } +} diff --git a/src/main/java/a8k/app/service/statemgr/consumables_mgr/LarBottleContainerStateMgr.java b/src/main/java/a8k/app/service/statemgr/consumables_mgr/LarBottleContainerStateMgr.java index 756c8ba..083ff93 100644 --- a/src/main/java/a8k/app/service/statemgr/consumables_mgr/LarBottleContainerStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/consumables_mgr/LarBottleContainerStateMgr.java @@ -14,12 +14,13 @@ import org.springframework.util.Assert; @Slf4j @RequiredArgsConstructor public class LarBottleContainerStateMgr { - public LarBottleContainer[] containers = new LarBottleContainer[AppConstant.CONSUMABLE_CHANNEL_NUM]; + public final LarBottleContainer[] containers = new LarBottleContainer[AppConstant.CONSUMABLE_CHANNEL_NUM]; @PostConstruct void init() { for (int i = 0; i < containers.length; i++) { containers[i] = new LarBottleContainer(); + containers[i].group = ConsumableGroup.of(i); } } diff --git a/src/main/java/a8k/app/service/statemgr/consumables_mgr/LittBottleContainerStateMgr.java b/src/main/java/a8k/app/service/statemgr/consumables_mgr/LittBottleContainerStateMgr.java index fb865f0..addcec6 100644 --- a/src/main/java/a8k/app/service/statemgr/consumables_mgr/LittBottleContainerStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/consumables_mgr/LittBottleContainerStateMgr.java @@ -22,6 +22,8 @@ public class LittBottleContainerStateMgr { void init() { for (int i = 0; i < containers.length; i++) { containers[i] = new LittBottleContainer(); + containers[i].group = ConsumableGroup.of(i); + } } diff --git a/src/main/java/a8k/app/service/statemgr/consumables_mgr/ReactionPlateContainerStateMgr.java b/src/main/java/a8k/app/service/statemgr/consumables_mgr/ReactionPlateContainerStateMgr.java index da300d5..e5b63c9 100644 --- a/src/main/java/a8k/app/service/statemgr/consumables_mgr/ReactionPlateContainerStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/consumables_mgr/ReactionPlateContainerStateMgr.java @@ -21,7 +21,8 @@ public class ReactionPlateContainerStateMgr { @PostConstruct void init() { for (int i = 0; i < containers.length; i++) { - containers[i] = new ReactionPlateContainer(); + containers[i] = new ReactionPlateContainer(); + containers[i].group = ConsumableGroup.of(i); } } diff --git a/src/main/java/a8k/app/service/statemgr/consumables_mgr/TipStateMgr.java b/src/main/java/a8k/app/service/statemgr/consumables_mgr/TipStateMgr.java index 51fd938..1e029af 100644 --- a/src/main/java/a8k/app/service/statemgr/consumables_mgr/TipStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/consumables_mgr/TipStateMgr.java @@ -25,6 +25,7 @@ public class TipStateMgr { for (int i = 0; i < tips.length; i++) { tips[i] = new TipContainer(); tips[i].tipNum = 0; + tips[i].tipGroupPos = TipGroupPos.fromInt(i); } } diff --git a/src/main/java/a8k/app/type/PreReactionGrid.java b/src/main/java/a8k/app/type/PreReactionGrid.java index 335583b..095ee33 100644 --- a/src/main/java/a8k/app/type/PreReactionGrid.java +++ b/src/main/java/a8k/app/type/PreReactionGrid.java @@ -33,6 +33,7 @@ public class PreReactionGrid implements Serializable { public ProjExtInfoCard projExtInfoCard; public Integer projId = 0; public IncubatorPos bindIncubatorPos; + public String cxtId = ""; PreReactionGrid(ConsumableGroup group, Integer posIndex) { this.group = group; diff --git a/src/main/java/a8k/app/type/a8k/container/A8kConsumableContainer.java b/src/main/java/a8k/app/type/a8k/container/A8kConsumableContainer.java index 798a26f..e48d849 100644 --- a/src/main/java/a8k/app/type/a8k/container/A8kConsumableContainer.java +++ b/src/main/java/a8k/app/type/a8k/container/A8kConsumableContainer.java @@ -1,6 +1,8 @@ package a8k.app.type.a8k.container; import a8k.app.constant.AppConstant; +import a8k.app.type.a8k.ConsumableGroup; +import a8k.app.type.a8k.pos.TipGroupPos; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; @@ -24,15 +26,20 @@ public class A8kConsumableContainer implements Serializable { for (int i = 0; i < tips.length; i++) { tips[i] = new TipContainer(); tips[i].tipNum = 0; + tips[i].tipGroupPos = TipGroupPos.fromInt(i); + } for (int i = 0; i < reactionPlateGroup.length; i++) { reactionPlateGroup[i] = new ReactionPlateContainer(); + reactionPlateGroup[i].group = ConsumableGroup.of(i); } for (int i = 0; i < littBottleGroup.length; i++) { littBottleGroup[i] = new LittBottleContainer(); + littBottleGroup[i].group = ConsumableGroup.of(i); } for (int i = 0; i < larBottleGroup.length; i++) { larBottleGroup[i] = new LarBottleContainer(); + larBottleGroup[i].group = ConsumableGroup.of(i); } } diff --git a/src/main/java/a8k/app/type/a8k/container/LarBottleContainer.java b/src/main/java/a8k/app/type/a8k/container/LarBottleContainer.java index d2f312a..7e80e82 100644 --- a/src/main/java/a8k/app/type/a8k/container/LarBottleContainer.java +++ b/src/main/java/a8k/app/type/a8k/container/LarBottleContainer.java @@ -1,5 +1,6 @@ package a8k.app.type.a8k.container; +import a8k.app.type.a8k.ConsumableGroup; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; @@ -24,6 +25,8 @@ public class LarBottleContainer implements Serializable { @Schema(description = "预留数量") public Integer reserveNum = 0; + public ConsumableGroup group; + public LarBottleContainer() { isInstall = false; @@ -35,8 +38,8 @@ public class LarBottleContainer implements Serializable { this.projShortName = projShortName; this.lotId = lotId; this.color = color; - this.num = num; - isInstall = true; + this.num = num; + isInstall = true; } } diff --git a/src/main/java/a8k/app/type/a8k/container/LittBottleContainer.java b/src/main/java/a8k/app/type/a8k/container/LittBottleContainer.java index bebdbe0..22818a1 100644 --- a/src/main/java/a8k/app/type/a8k/container/LittBottleContainer.java +++ b/src/main/java/a8k/app/type/a8k/container/LittBottleContainer.java @@ -1,6 +1,7 @@ package a8k.app.type.a8k.container; import a8k.app.constant.AppConstant; +import a8k.app.type.a8k.ConsumableGroup; import a8k.app.type.a8k.LittleBottleConsumableType; import io.swagger.v3.oas.annotations.media.Schema; @@ -25,7 +26,8 @@ public class LittBottleContainer implements Serializable { @Schema(description = "预留数量") public Integer reserveNum = 0; - public Boolean isInstall = false; + public Boolean isInstall = false; + public ConsumableGroup group; public LittBottleContainer() { isInstall = false; diff --git a/src/main/java/a8k/app/type/a8k/container/ReactionPlateContainer.java b/src/main/java/a8k/app/type/a8k/container/ReactionPlateContainer.java index 088bb2b..b996b20 100644 --- a/src/main/java/a8k/app/type/a8k/container/ReactionPlateContainer.java +++ b/src/main/java/a8k/app/type/a8k/container/ReactionPlateContainer.java @@ -1,5 +1,6 @@ package a8k.app.type.a8k.container; +import a8k.app.type.a8k.ConsumableGroup; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; @@ -22,6 +23,8 @@ public class ReactionPlateContainer implements Serializable { @Schema(description = "耗材是否加载") public Boolean isInstall = false; + public ConsumableGroup group; + public ReactionPlateContainer() { } diff --git a/src/main/java/a8k/app/type/a8k/container/TipContainer.java b/src/main/java/a8k/app/type/a8k/container/TipContainer.java index 2566a75..117082f 100644 --- a/src/main/java/a8k/app/type/a8k/container/TipContainer.java +++ b/src/main/java/a8k/app/type/a8k/container/TipContainer.java @@ -1,11 +1,13 @@ package a8k.app.type.a8k.container; +import a8k.app.type.a8k.pos.TipGroupPos; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; public class TipContainer implements Serializable { @Schema(description = "tip剩余可用数量") - public Integer tipNum = 0;//剩余可用数量 - public Integer totalNum = 120;//总数量 + public Integer tipNum = 0;//剩余可用数量 + public Integer totalNum = 120;//总数量 + public TipGroupPos tipGroupPos; } diff --git a/src/main/java/a8k/app/type/a8k/state/IncubationSubTank.java b/src/main/java/a8k/app/type/a8k/state/IncubationSubTank.java index 22ff9c3..065d7b1 100644 --- a/src/main/java/a8k/app/type/a8k/state/IncubationSubTank.java +++ b/src/main/java/a8k/app/type/a8k/state/IncubationSubTank.java @@ -3,7 +3,6 @@ package a8k.app.type.a8k.state; import a8k.app.type.a8k.pos.ConsumableInfo; import a8k.app.type.a8k.state.enumtype.IncubationSubTankState; import a8k.app.type.a8k.pos.IncubatorPos; -import a8k.app.type.appevent.AppPromptEvent; import a8k.app.type.error.AppError; import a8k.app.type.a8k.BloodType; import a8k.app.type.a8k.proj.ProjBriefInfo; @@ -16,8 +15,6 @@ import lombok.Getter; import lombok.Setter; import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; @Getter public class IncubationSubTank implements Serializable { @@ -67,7 +64,7 @@ public class IncubationSubTank implements Serializable { @Setter @Schema(description = "错误信息,用来标识当前孵育盘的错误信息,例如推出的反应板夹有问题") - public AppError error = null; + public AppError error = null; public ZAppPromopt errorInfo = null; //错误提示 @@ -77,6 +74,8 @@ public class IncubationSubTank implements Serializable { public ConsumableInfo consumableInfo; + public String cxtId; + public IncubationSubTank(IncubatorPos pos) { this.pos = pos; } @@ -93,7 +92,7 @@ public class IncubationSubTank implements Serializable { error = null; } - public SampleInfo toSampleInfo() { + public SampleInfo getSampleInfo() { SampleInfo sampleInfo = new SampleInfo(); sampleInfo.bloodType = bloodType; sampleInfo.sampleBarcode = sampleBarcode; diff --git a/src/main/java/a8k/app/type/a8k/state/OptScanModuleState.java b/src/main/java/a8k/app/type/a8k/state/OptScanModuleState.java index 4946651..8498f37 100644 --- a/src/main/java/a8k/app/type/a8k/state/OptScanModuleState.java +++ b/src/main/java/a8k/app/type/a8k/state/OptScanModuleState.java @@ -42,6 +42,7 @@ public class OptScanModuleState implements Serializable { ProjBuildInInfo projBuildinInfo; Boolean cleared = false; //是否被清空过 + String cxtId; @JsonIgnore public SampleInfo getSampleInfo() { @@ -55,6 +56,4 @@ public class OptScanModuleState implements Serializable { } - - } diff --git a/src/main/java/a8k/app/type/a8k/state/Tube.java b/src/main/java/a8k/app/type/a8k/state/Tube.java index 0a7397a..1a82268 100644 --- a/src/main/java/a8k/app/type/a8k/state/Tube.java +++ b/src/main/java/a8k/app/type/a8k/state/Tube.java @@ -45,7 +45,7 @@ public class Tube implements Serializable { @Schema(description = "样本处理的错误信息") AppError error = null; ZAppPromopt errorInfo = null; //错误提示 - + @JsonIgnore List preProcessContexts = new ArrayList<>(); //预处理上下文 @JsonIgnore A8kTubeHolderType tubeHolderType = null; diff --git a/src/main/java/a8k/extui/page/extapp/A8kOptVerification.java b/src/main/java/a8k/extui/page/extapp/A8kOptVerification.java index 5a8b6da..d064637 100644 --- a/src/main/java/a8k/extui/page/extapp/A8kOptVerification.java +++ b/src/main/java/a8k/extui/page/extapp/A8kOptVerification.java @@ -17,7 +17,7 @@ import a8k.extui.mgr.ExtApiPageMgr; import a8k.extui.type.ExtUIPageCfg; import a8k.app.service.data.FileMgrService; import a8k.app.service.data.ProjInfoMgrService; -import a8k.app.service.lowerctrl.OptScanModuleCtrlService; +import a8k.app.service.lowerctrl.OptScanModuleLowerCtrlService; import a8k.app.service.lowerctrl.PlateBoxCtrlService; import a8k.extui.type.ret.A8kScanCurve; import a8k.app.type.a8k.opt.A8kOptType; @@ -41,9 +41,9 @@ public class A8kOptVerification { AppDeviceInitCtrlService appDeviceInitCtrlService; @Resource - PlateBoxCtrlService plateBoxCtrlService; + PlateBoxCtrlService plateBoxCtrlService; @Resource - OptScanModuleCtrlService optScanModuleCtrlService; + OptScanModuleLowerCtrlService optScanModuleLowerCtrlService; @Resource ProjInfoMgrService projInfoMgrService; @@ -155,11 +155,11 @@ public class A8kOptVerification { } public void pushOnePlateToOptModule() throws AppException { - optScanModuleCtrlService.dropPlate(); - optScanModuleCtrlService.pullPlate(IncubatorPos.SPACE01); - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.dropPlate(); + optScanModuleLowerCtrlService.pullPlate(IncubatorPos.SPACE01); + optScanModuleLowerCtrlService.dropPlate(); plateBoxCtrlService.pushPlateQuick(ConsumableGroup.CG1, IncubatorPos.SPACE01); - optScanModuleCtrlService.pullPlate(IncubatorPos.SPACE01); + optScanModuleLowerCtrlService.pullPlate(IncubatorPos.SPACE01); } @@ -173,7 +173,7 @@ public class A8kOptVerification { for (int i = 0; i < projInfo.optcfg.size(); i++) { OptScanResult scanResult = getOptScanResult(projInfo.optcfg.get(i).optType); if (scanResult == null) { - scanResult = optScanModuleCtrlService.optScan(projInfo, i, autoAmpl); + scanResult = optScanModuleLowerCtrlService.optScan(projInfo, i, autoAmpl); } generateOptReport(projInfo, i, scanResult); } @@ -214,7 +214,7 @@ public class A8kOptVerification { } public void dropPlate() throws AppException { - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.dropPlate(); } public A8kScanCurve getScanCurveT() throws AppException { @@ -259,11 +259,11 @@ public class A8kOptVerification { throw AppException.ofSimplePrompt("请插入项目ID卡"); } - optScanModuleCtrlService.forceDropPlate(IncubatorPos.SPACE01); + optScanModuleLowerCtrlService.forceDropPlate(IncubatorPos.SPACE01); plateBoxCtrlService.pushPlateQuick(ConsumableGroup.CG1, IncubatorPos.SPACE01); - optScanModuleCtrlService.pullPlate(IncubatorPos.SPACE01); + optScanModuleLowerCtrlService.pullPlate(IncubatorPos.SPACE01); doOptScan(autoAmpl); computeResult(); - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.dropPlate(); } } diff --git a/src/main/java/a8k/extui/page/extapp/OptModuleParamCalibration.java b/src/main/java/a8k/extui/page/extapp/OptModuleParamCalibration.java index ac77e82..abde863 100644 --- a/src/main/java/a8k/extui/page/extapp/OptModuleParamCalibration.java +++ b/src/main/java/a8k/extui/page/extapp/OptModuleParamCalibration.java @@ -10,7 +10,7 @@ import a8k.extui.factory.A8kScanCurveFactory; import a8k.extui.mgr.ExtApiPageMgr; import a8k.extui.type.ret.A8kScanCurve; import a8k.extui.type.ExtApiStatu; -import a8k.app.service.lowerctrl.OptScanModuleCtrlService; +import a8k.app.service.lowerctrl.OptScanModuleLowerCtrlService; import a8k.app.service.lowerctrl.PlateBoxCtrlService; import a8k.app.service.param.optparam.OptModuleExtParamsMgr; import a8k.app.type.param.optpos.OptModuleExtParam; @@ -43,9 +43,9 @@ import java.util.Map; public class OptModuleParamCalibration { private final OptModuleExtParamsMgr optModuleExtParamsMgr; - private final PlateBoxCtrlService plateBoxCtrlService; - private final OptScanModuleCtrlService optScanModuleCtrlService; - private final ProjInfoMgrService projInfoMgrService; + private final PlateBoxCtrlService plateBoxCtrlService; + private final OptScanModuleLowerCtrlService optScanModuleLowerCtrlService; + private final ProjInfoMgrService projInfoMgrService; @ExtApiStatu(name = "", group = "F光学参数", order = 1) @@ -78,18 +78,18 @@ public class OptModuleParamCalibration { public void pushOnePlateToOptModule() throws AppException { //先清空当前通道 - optScanModuleCtrlService.dropPlate(); - optScanModuleCtrlService.pullPlate(IncubatorPos.SPACE01); - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.dropPlate(); + optScanModuleLowerCtrlService.pullPlate(IncubatorPos.SPACE01); + optScanModuleLowerCtrlService.dropPlate(); //推板到光学模组 plateBoxCtrlService.pushPlateQuick(ConsumableGroup.CG1, IncubatorPos.SPACE01); - optScanModuleCtrlService.pullPlate(IncubatorPos.SPACE01); + optScanModuleLowerCtrlService.pullPlate(IncubatorPos.SPACE01); } public void dropPlate() throws AppException { - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.dropPlate(); } A8kScanCurve FCurveCache = null; @@ -129,7 +129,7 @@ public class OptModuleParamCalibration { Double scanGain = optModuleExtParamsMgr.getScanGain(A8kOptType.FOPT); Integer rawScanGain = OptGainConvert.scanerToRawGain(A8kOptType.FOPT, scanGain); Integer rawLasterGain = optModuleExtParamsMgr.getOptLasterRawGain(A8kOptType.FOPT); - var result = optScanModuleCtrlService.startOptScan(A8kOptType.FOPT, rawLasterGain, rawScanGain); + var result = optScanModuleLowerCtrlService.startOptScan(A8kOptType.FOPT, rawLasterGain, rawScanGain); FCurveCache = A8kScanCurveFactory.createScanCurve1200Point(result); return FCurveCache; } @@ -167,7 +167,7 @@ public class OptModuleParamCalibration { Integer rawScanGain = OptGainConvert.scanerToRawGain(A8kOptType.TOPT, scanGain); Integer rawLasterGain = optModuleExtParamsMgr.getOptLasterRawGain(A8kOptType.TOPT); - var result = optScanModuleCtrlService.startOptScan(A8kOptType.TOPT, rawLasterGain, rawScanGain); + var result = optScanModuleLowerCtrlService.startOptScan(A8kOptType.TOPT, rawLasterGain, rawScanGain); TCurveCache = A8kScanCurveFactory.createScanCurve1200Point(result); return TCurveCache; } @@ -181,7 +181,7 @@ public class OptModuleParamCalibration { public A8kOptPeakInfo doOptScan(Integer projId, Integer subProjIndex) throws AppException { ProjBuildInInfo projBuildinInfo = projInfoMgrService.getProjBuildInInfo(projId); - var result = optScanModuleCtrlService.optScan(projBuildinInfo, subProjIndex); + var result = optScanModuleLowerCtrlService.optScan(projBuildinInfo, subProjIndex); optScanCurve = A8kScanCurveFactory.createScanCurve1200Point(result.rawData.rawData); return result.analysResult; } diff --git a/src/main/java/a8k/extui/page/test/verification/P31ReactionPlatesTransmitPosVerificationPage.java b/src/main/java/a8k/extui/page/test/verification/P31ReactionPlatesTransmitPosVerificationPage.java index 40ab784..e582fde 100644 --- a/src/main/java/a8k/extui/page/test/verification/P31ReactionPlatesTransmitPosVerificationPage.java +++ b/src/main/java/a8k/extui/page/test/verification/P31ReactionPlatesTransmitPosVerificationPage.java @@ -27,11 +27,11 @@ public class P31ReactionPlatesTransmitPosVerificationPage { @Resource TurnableMoveCtrlService turnableMoveCtrlService; @Resource - PlateBoxCtrlService plateBoxCtrlService; + PlateBoxCtrlService plateBoxCtrlService; @Resource - OptScanModuleCtrlService optScanModuleCtrlService; + OptScanModuleLowerCtrlService optScanModuleLowerCtrlService; @Resource - HbotMoveCtrlService hbotMoveCtrlService; + HbotMoveCtrlService hbotMoveCtrlService; @Resource HbotMoveExCtrlService hbotMoveExCtrlService; @@ -49,11 +49,11 @@ public class P31ReactionPlatesTransmitPosVerificationPage { } public void trunableMoveToPullPos(IncubatorPos index) throws AppException { - optScanModuleCtrlService.pullPlate(index); + optScanModuleLowerCtrlService.pullPlate(index); } public void dropPlate() throws AppException { - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.dropPlate(); } public void trunableMoveToDropLiquidPos(IncubatorPos index) throws AppException { @@ -63,8 +63,8 @@ public class P31ReactionPlatesTransmitPosVerificationPage { public void pushOneAndRemove(ConsumableGroup PBCh, IncubatorPos incubatorPos) throws AppException { plateBoxCtrlService.pushPlateQuick(PBCh, incubatorPos); - optScanModuleCtrlService.pullPlate(incubatorPos); - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.pullPlate(incubatorPos); + optScanModuleLowerCtrlService.dropPlate(); } public void pushAllAndRemoveAll() throws AppException { @@ -90,8 +90,8 @@ public class P31ReactionPlatesTransmitPosVerificationPage { public void removeAllIncubator() throws AppException { for (var space : IncubatorPos.values()) { - optScanModuleCtrlService.pullPlate(space); - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.pullPlate(space); + optScanModuleLowerCtrlService.dropPlate(); } } diff --git a/src/main/java/a8k/extui/page/test/verification/P34LiquidOperationTestPage.java b/src/main/java/a8k/extui/page/test/verification/P34LiquidOperationTestPage.java index 3be45f1..1e48511 100644 --- a/src/main/java/a8k/extui/page/test/verification/P34LiquidOperationTestPage.java +++ b/src/main/java/a8k/extui/page/test/verification/P34LiquidOperationTestPage.java @@ -29,6 +29,7 @@ public class P34LiquidOperationTestPage { @Resource ExtApiPageMgr extApiPageMgr; + Boolean autoDropTip = true; // 是否自动丢弃Tip // // 液体操作 @@ -41,7 +42,12 @@ public class P34LiquidOperationTestPage { tipOperationCtrlModule.dropTip(); } + synchronized public void setAutoDropTip(Boolean autoDropTip) { + this.autoDropTip = autoDropTip; + } + public void takeLargeBottleBufferLiquidToProbeSubstance(LargeBufferPos from, ConsumableGroup group, Integer index, Integer ul) throws AppException { + tryDropTip(); PreReactionPos topos = new PreReactionPos(LittleBottleConsumableType.ProbeSubstance, group, index); liquidOperationCtrService.takeLargeBottleBufferLiquidToProbeSubstance(from, topos, ul); } @@ -64,6 +70,7 @@ public class P34LiquidOperationTestPage { } public void takeSample(A8kSamplePos from, Integer ul) throws AppException { + tryDropTip(); liquidOperationCtrService.takeSample(from, ul); } @@ -87,6 +94,18 @@ public class P34LiquidOperationTestPage { liquidOperationCtrService.takePreReactionLiquid(pos, true); } + public void tryDropTip() { + if (autoDropTip) { + try { + if (tipOperationCtrlModule.isHasTip()) + tipOperationCtrlModule.dropTip(); + } catch (AppException e) { + log.error("自动丢弃Tip失败", e); + } + + } + } + @PostConstruct void init() { @@ -94,6 +113,8 @@ public class P34LiquidOperationTestPage { cfg.newGroup("液体操作-通用"); cfg.addFunction("取Tip", this::takeTip); cfg.addFunction("丢Tip", this::dropTip); + cfg.addFunction("设置自动丢弃Tip", this::setAutoDropTip) + .setParamVal("autoDropTip", () -> autoDropTip); cfg.newGroup("液体操作-大瓶缓冲液/探测物质"); cfg.addFunction("刺破", this::pierceProbeSubstance); cfg.addFunction("取大瓶缓冲液到探测物质位置", this::takeLargeBottleBufferLiquidToProbeSubstance); diff --git a/src/main/java/a8k/extui/page/test/verification/P50VerificationScriptPage.java b/src/main/java/a8k/extui/page/test/verification/P50VerificationScriptPage.java index 6975160..cef0d63 100644 --- a/src/main/java/a8k/extui/page/test/verification/P50VerificationScriptPage.java +++ b/src/main/java/a8k/extui/page/test/verification/P50VerificationScriptPage.java @@ -31,9 +31,9 @@ public class P50VerificationScriptPage { @Resource - PlateBoxCtrlService plateBoxCtrlService; + PlateBoxCtrlService plateBoxCtrlService; @Resource - OptScanModuleCtrlService optScanModuleCtrlService; + OptScanModuleLowerCtrlService optScanModuleLowerCtrlService; @Resource @@ -94,8 +94,8 @@ public class P50VerificationScriptPage { private void pushOneAndRemove(ConsumableGroup PBCh, IncubatorPos incubatorPos) throws AppException { plateBoxCtrlService.pushPlateQuick(PBCh, incubatorPos); - optScanModuleCtrlService.pullPlate(incubatorPos); - optScanModuleCtrlService.dropPlate(); + optScanModuleLowerCtrlService.pullPlate(incubatorPos); + optScanModuleLowerCtrlService.dropPlate(); } public void verifyPlateTransmit() throws AppException { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1819e99..0ffe1bc 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,15 +1,17 @@ -# server.port: 8082 +#server.port: 8082 +#iflytophald.ip: 127.0.0.1 +#device.runmode: "VirtualMode" + server.port: 80 +device.runmode: "RealMode" +iflytophald.ip: 192.168.8.10 + a8k.enableTemperatureCtrl: false -# device.runmode: "VirtualMode" -device.runmode: "RealMode" device.enableCanBus: true # ip: 192.168.8.10 -iflytophald.ip: 192.168.8.10 -# iflytophald.ip: 127.0.0.1 iflytophald.cmdch.port: 19004 iflytophald.datach.port: 19005