diff --git a/src/main/java/a8k/app/service/background/SensorDataUpdateService.java b/src/main/java/a8k/app/service/background/SensorDataUpdateService.java index 95465de..6abd475 100644 --- a/src/main/java/a8k/app/service/background/SensorDataUpdateService.java +++ b/src/main/java/a8k/app/service/background/SensorDataUpdateService.java @@ -1,6 +1,11 @@ package a8k.app.service.background; import a8k.OS; +import a8k.app.hardware.driver.InputDetectDriver; +import a8k.app.hardware.driver.OutputIOCtrlDriver; +import a8k.app.hardware.type.InputIOId; +import a8k.app.hardware.type.OutputIOId; +import a8k.app.service.statemgr.AppWarningFlagStateMgr; import a8k.app.type.DeviceRunMode; import a8k.app.type.TemperatureRecordPoint; import a8k.app.type.error.AppError; @@ -29,6 +34,8 @@ public class SensorDataUpdateService { private final OptScanModuleStateMgr optScanModuleStateMgr; private final AppEventBusService appEventBusService; private final A8kCanBusService canBus; + private final OutputIOCtrlDriver outputIOCtrlDriver; + private final InputDetectDriver inputDetectDriver; Thread updateThread = null; Boolean workingFlag = true; @@ -127,26 +134,16 @@ public class SensorDataUpdateService { try { - OptScanModuleStateEnum optScanModuleState = optScanModuleStateMgr.getOptScanModule().getState(); - if (!optScanModuleState.equals(OptScanModuleStateEnum.EMPTY)) { - gStateMgrService.getSensorState().setWasteBinFullFlag(false); - OS.forceSleep(1000); - continue; - } - - // canBus.setIOState(IOId.RecycleBinOverflowPPSPowerCtrl, true); - // OS.forceSleep(10);//等待光栅电源稳定 - // Boolean wasteBinFullFlag = canBus.getIOState(IOId.RecycleBinOverflowPPS); - // canBus.setIOState(IOId.RecycleBinOverflowPPSPowerCtrl, false); - // gStateMgrService.getSensorState().setWasteBinFullFlag(wasteBinFullFlag); + Boolean wasteBinFullFlag = inputDetectDriver.getIOState(InputIOId.RecycleBinOverflowPPS); + gStateMgrService.updateWasteBinFullFlag(wasteBinFullFlag); OS.forceSleep(100); Double incubateBoxTemp = temperatureControlDriver.readIncubateBoxTemperature(); - gStateMgrService.getSensorState().setIncubateBoxTemperature((int) (incubateBoxTemp + 0.5)); + gStateMgrService.updateIncubateBoxTemperature((int) (incubateBoxTemp + 0.5)); addIncubateBoxTemperatureCurve(incubateBoxTemp); Double pbtemp = temperatureControlDriver.readPlateBoxTemperature(); - gStateMgrService.getSensorState().setPboxTemperature((int) (pbtemp + 0.5)); + gStateMgrService.updatePboxTemperature((int) (pbtemp + 0.5)); addPlateBoxTemperatureCurve(pbtemp); log.debug("IncubateBoxTemperature: {}, PlateBoxTemperature: {}", incubateBoxTemp, pbtemp); diff --git a/src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrService.java b/src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrService.java index d43a373..77e6150 100644 --- a/src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrService.java +++ b/src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrService.java @@ -139,23 +139,23 @@ public class LiquidOperationCtrService { } - public void pirceLittleBuffer(PreReactionPos pos) throws AppException { + public void pierceThrough(PreReactionPos pos) throws AppException { // 取TIP tipOperationCtrlModule.tryTakeTip(); ZAppChecker.check(pipetteCtrlDriverV2.readTipState(), A8kEcode.CODEERROR, "未检测到TIP"); - Pos3d pircePos; + Pos3d piercePos; ContainerCpyId containerCpyId; if (pos.type.equals(LittleBottleConsumableType.ProbeSubstance)) { - pircePos = hbotLittleBSPosMgr.getProbeSubstancePiercePos(pos.group, pos.index); + piercePos = hbotLittleBSPosMgr.getProbeSubstancePiercePos(pos.group, pos.index); containerCpyId = ContainerCpyId.DetectSubstancesCup; } else { - pircePos = hbotLittleBSPosMgr.getLittleBSPiercePos(pos.group, pos.index); + piercePos = hbotLittleBSPosMgr.getLittleBSPiercePos(pos.group, pos.index); containerCpyId = ContainerCpyId.LittleBufferCup; } - hbotMoveExCtrlService.moveToXY(pircePos); - pipetteCtrlDriverV2.pierceThroughBlock(containerCpyId, pircePos.z); + hbotMoveExCtrlService.moveToXY(piercePos); + pipetteCtrlDriverV2.pierceThroughBlock(containerCpyId, piercePos.z); } @@ -281,14 +281,16 @@ public class LiquidOperationCtrService { )); } - public void dropLiquidToReactionPlate() throws AppException { + public void dropLiquidToReactionPlate(boolean reposition) throws AppException { log.info("dropLiquidToReactionPlate"); Pos3d dropLiquidPos = hbotFixedPosParamMgr.getDropLiquidPos(); - UISender.txInfoMsg(log, "移动到预先反应位置:%s", dropLiquidPos); - hbotMoveExCtrlService.moveToXY(dropLiquidPos); + if (reposition) { + UISender.txInfoMsg(log, "移动到预先反应位置:%s", dropLiquidPos); + hbotMoveExCtrlService.moveToXY(dropLiquidPos); + } UISender.txInfoMsg(log, "分配到反应板位置"); pipetteCtrlDriverV2.distributeAllBlock(new DistribuAllParam( diff --git a/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java b/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java index c8c36dc..6929647 100644 --- a/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java +++ b/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java @@ -79,6 +79,7 @@ public class AppDeviceInitCtrlService { private final StepMotorCtrlDriver stepMotorCtrlDriver; private final PipetteCtrlDriverV2 pipetteCtrlDriverV2; private final ModuleEnableCtrlDriver moduleEnableCtrlDriver; + private final OutputIOCtrlDriver outputIOCtrlDriver; // // Service @@ -250,6 +251,9 @@ public class AppDeviceInitCtrlService { //hbot快速归零 hbotMoveExCtrlService.moveQuickToZero(); + //打开废料仓满溢检测光栅 + outputIOCtrlDriver.setIOState(OutputIOId.RecycleBinOverflowPPSPowerCtrl, true); + gstate.setDeviceInited(true); gstate.clearFatalError(); diff --git a/src/main/java/a8k/app/service/module/InFeedingCtrlModule.java b/src/main/java/a8k/app/service/module/InFeedingCtrlModule.java index 99fd93e..896c4f9 100644 --- a/src/main/java/a8k/app/service/module/InFeedingCtrlModule.java +++ b/src/main/java/a8k/app/service/module/InFeedingCtrlModule.java @@ -26,6 +26,7 @@ import a8k.app.type.a8k.state.TubeHolderInfo; import a8k.app.type.a8k.state.TubeInfo; import a8k.app.type.a8k.state.enumtype.TubeHolderState; import a8k.app.type.appevent.AppWarningNotifyEvent; +import a8k.app.type.error.AppError; import a8k.app.type.exception.AppException; import a8k.app.type.misc.TubeHolderScanResult; import a8k.app.type.ui.TubeHolderSetting; @@ -115,12 +116,21 @@ public class InFeedingCtrlModule { continue; } + if (appWarningFlagStateMgr.isFlagNotTrigger(AppWarningFlagType.WasteBinFull)) { + if (gStateMgrService.getSensorState().getWasteBinFullFlag()) { + appWarningFlagStateMgr.setFlagState(AppWarningFlagType.WasteBinFull, new AppError(A8kEcode.APPE_OUTFEED_AREA_IS_FULL)); + appEventBusService.pushEvent(new AppWarningNotifyEvent(new AppError(A8kEcode.APPE_OUTFEED_AREA_IS_FULL))); + continue; + } + } + //检查出料区是否满 && 出料 if (appWarningFlagStateMgr.isFlagNotTrigger(AppWarningFlagType.OutfeedAreaIsFull)) { if ((!tubeStateMgr.getTubeholderState().equals(TubeHolderState.IDLE) && tubeStateMgr.isAllTubeInTubeholderHasBeenProcessed())//存在尚未处理的试管架 || (tubeStateMgr.getTubeholderState().equals(TubeHolderState.IDLE) && !tubeFeedingCtrlService.isTubeholderChannelEmpty()) //试管架通道不为空 ) { ejectTubeHolder(); + continue; } } @@ -128,6 +138,7 @@ public class InFeedingCtrlModule { if (appWarningFlagStateMgr.isFlagNotTrigger(AppWarningFlagType.ConsumeNotEnoughError) && appWarningFlagStateMgr.isFlagNotTrigger(AppWarningFlagType.TipNotEnoughError) && appWarningFlagStateMgr.isFlagNotTrigger(AppWarningFlagType.InfeedError) + && appWarningFlagStateMgr.isFlagNotTrigger(AppWarningFlagType.WasteBinFull) ) { if (tubeStateMgr.getTubeholderState().equals(TubeHolderState.IDLE)) { //如果入料通道光电被触发 diff --git a/src/main/java/a8k/app/service/module/SamplePreProcessModule.java b/src/main/java/a8k/app/service/module/SamplePreProcessModule.java index 103b30a..a77470d 100644 --- a/src/main/java/a8k/app/service/module/SamplePreProcessModule.java +++ b/src/main/java/a8k/app/service/module/SamplePreProcessModule.java @@ -125,9 +125,8 @@ public class SamplePreProcessModule { if (state.isPauseFlag()) continue; - if (state.fatalFlag) { + if (state.fatalFlag) continue; - } if (preReactionStateMgr.isHasReactionCompleted()) { processPreReactionCompletedGrid(preReactionStateMgr.getReactionCompletedPos()); @@ -141,8 +140,8 @@ public class SamplePreProcessModule { if (isHasEnoughIncubationIDLEPos) { processTube(tubePosInfo); //假装已经处理了试管架 - // tubeStateMgrService.pendTube(tubePosInfo.isEmergency, tubePosInfo.tubeIndex); - // tubeStateMgrService.changeTubeStateToProcessComplete(); + //tubeStateMgrService.pendTube(tubePosInfo.isEmergency, tubePosInfo.tubeIndex); + //tubeStateMgrService.changeTubeStateToProcessComplete(); continue; } } @@ -169,7 +168,7 @@ public class SamplePreProcessModule { incubationPlateCtrlModule.dropLiquidAndStartIncubating( preReactionGrid.bindIncubatorPos, - () -> docmd("滴入反应液到孵育盘", liquidOperationCtrService::dropLiquidToReactionPlate), + () -> docmd("滴入反应液到孵育盘", () -> liquidOperationCtrService.dropLiquidToReactionPlate(true)), projBuildInInfo.reactionPlateIncubationTimeMin * 60 ); } @@ -305,7 +304,7 @@ public class SamplePreProcessModule { } case SampleAndBS -> { Assert.notNull(preReactionPos, "preReactionPos != null"); - docmd("刺破小瓶缓冲液", () -> liquidOperationCtrService.pirceLittleBuffer(preReactionPos)); + docmd("刺破小瓶缓冲液", () -> liquidOperationCtrService.pierceThrough(preReactionPos)); } case SampleOnly -> { //取TIP @@ -342,7 +341,7 @@ public class SamplePreProcessModule { incubationPlateCtrlModule.dropLiquidAndStartIncubating( cxt.getIncubatorPos(), () -> { - docmd("滴入反应液到孵育盘", liquidOperationCtrService::dropLiquidToReactionPlate); + docmd("滴入反应液到孵育盘", () -> liquidOperationCtrService.dropLiquidToReactionPlate(true)); }, cxt.getProjBuildinInfo().reactionPlateIncubationTimeMin * 60 ); @@ -360,7 +359,7 @@ public class SamplePreProcessModule { case SampleOnly -> { incubationPlateCtrlModule.dropLiquidAndStartIncubating( cxt.getIncubatorPos(), - () -> docmd("取反应液到孵育盘", liquidOperationCtrService::dropLiquidToReactionPlate), + () -> docmd("取反应液到孵育盘", () -> liquidOperationCtrService.dropLiquidToReactionPlate(true)), cxt.getProjBuildinInfo().reactionPlateIncubationTimeMin * 60 ); UISender.txInfoMsg(log, "开始孵育"); diff --git a/src/main/java/a8k/app/service/statemgr/AppWarningFlagStateMgr.java b/src/main/java/a8k/app/service/statemgr/AppWarningFlagStateMgr.java index 66463f2..0b7f637 100644 --- a/src/main/java/a8k/app/service/statemgr/AppWarningFlagStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/AppWarningFlagStateMgr.java @@ -139,6 +139,10 @@ public class AppWarningFlagStateMgr { stateVersion++; } + synchronized public boolean isFlagTrigger(AppWarningFlagType flagType) { + return !isFlagNotTrigger(flagType); + } + synchronized public boolean isFlagNotTrigger(AppWarningFlagType flagType) { for (DeviceWarningFlagState flagState : deviceWarningFlagState.states) { if (flagState.keyName.equals(flagType.name())) { diff --git a/src/main/java/a8k/app/service/statemgr/GStateMgrService.java b/src/main/java/a8k/app/service/statemgr/GStateMgrService.java index fd181ea..ed6e68b 100644 --- a/src/main/java/a8k/app/service/statemgr/GStateMgrService.java +++ b/src/main/java/a8k/app/service/statemgr/GStateMgrService.java @@ -47,6 +47,19 @@ public class GStateMgrService { return this.gState.sensorState; } + public void updatePboxTemperature(Integer val) { + gState.sensorState.setPboxTemperature(val); + } + + public void updateIncubateBoxTemperature(Integer val) { + gState.sensorState.setIncubateBoxTemperature(val); + } + + public void updateWasteBinFullFlag(Boolean val) { + gState.sensorState.setWasteBinFullFlag(val); + } + + public synchronized void setSensorState(SensorState sensorState) { this.gState.sensorState = sensorState; } 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 8ccbc3c..3be45f1 100644 --- a/src/main/java/a8k/extui/page/test/verification/P34LiquidOperationTestPage.java +++ b/src/main/java/a8k/extui/page/test/verification/P34LiquidOperationTestPage.java @@ -46,21 +46,48 @@ public class P34LiquidOperationTestPage { liquidOperationCtrService.takeLargeBottleBufferLiquidToProbeSubstance(from, topos, ul); } - public void takeSampleOnly(A8kSamplePos from, Integer ul) throws AppException { - liquidOperationCtrService.takeSample(from, ul); - } - public void pirceLittleBuffer(ConsumableGroup toGroup, Integer toIndex) throws AppException { + public void pierceLittleBuffer(ConsumableGroup toGroup, Integer toIndex) throws AppException { PreReactionPos pos = new PreReactionPos(LittleBottleConsumableType.BufferSolution, toGroup, toIndex); - liquidOperationCtrService.pirceLittleBuffer(pos); + liquidOperationCtrService.pierceThrough(pos); + } + + public void pierceProbeSubstance(ConsumableGroup toGroup, Integer toIndex) throws AppException { + PreReactionPos pos = new PreReactionPos(LittleBottleConsumableType.ProbeSubstance, toGroup, toIndex); + liquidOperationCtrService.pierceThrough(pos); } public void dropLiquidToReactionPlate(IncubatorPos pos) throws AppException { turnableMoveCtrlService.trunableMoveToDropLiquidPos(pos); - liquidOperationCtrService.dropLiquidToReactionPlate(); + liquidOperationCtrService.dropLiquidToReactionPlate(true); + } + + public void takeSample(A8kSamplePos from, Integer ul) throws AppException { + liquidOperationCtrService.takeSample(from, ul); + } + + public void dropSampleToProbeSubstance(ConsumableGroup toGroup, Integer toIndex) throws AppException { + PreReactionPos pos = new PreReactionPos(LittleBottleConsumableType.ProbeSubstance, toGroup, toIndex); + liquidOperationCtrService.distributeSampleToPreReactionPos(pos, true, true); } + public void aspiratePreReactionLiquidFromProbeSubstance(ConsumableGroup fromGroup, Integer fromIndex) throws AppException { + PreReactionPos pos = new PreReactionPos(LittleBottleConsumableType.ProbeSubstance, fromGroup, fromIndex); + liquidOperationCtrService.takePreReactionLiquid(pos, true); + } + + public void dropSampleToSmallBufferPos(ConsumableGroup toGroup, Integer toIndex) throws AppException { + PreReactionPos pos = new PreReactionPos(LittleBottleConsumableType.ProbeSubstance, toGroup, toIndex); + liquidOperationCtrService.distributeSampleToPreReactionPos(pos, true, true); + } + + public void aspiratePreReactionLiquidFromSmallBufferPos(ConsumableGroup fromGroup, Integer fromIndex) throws AppException { + PreReactionPos pos = new PreReactionPos(LittleBottleConsumableType.ProbeSubstance, fromGroup, fromIndex); + liquidOperationCtrService.takePreReactionLiquid(pos, true); + } + + @PostConstruct void init() { ExtUIPageCfg cfg = extApiPageMgr.newPage(this); @@ -68,19 +95,18 @@ public class P34LiquidOperationTestPage { cfg.addFunction("取Tip", this::takeTip); cfg.addFunction("丢Tip", this::dropTip); cfg.newGroup("液体操作-大瓶缓冲液/探测物质"); + cfg.addFunction("刺破", this::pierceProbeSubstance); cfg.addFunction("取大瓶缓冲液到探测物质位置", this::takeLargeBottleBufferLiquidToProbeSubstance); - // cfg.addFunction("取样品到探测物质位置", this::takeSampleToProbeSubstance); - // cfg.addFunction("取反应液", this::takePreReactionLiquidFromProbeSubstance); - cfg.addFunction("滴反应液到反应板上", this::dropLiquidToReactionPlate); + cfg.addFunction("取样品", this::takeSample); + cfg.addFunction("放样品", this::dropSampleToProbeSubstance); + cfg.addFunction("取混合液", this::aspiratePreReactionLiquidFromProbeSubstance); + cfg.addFunction("滴入反应板", this::dropLiquidToReactionPlate); cfg.newGroup("液体操作-小瓶缓冲液"); - cfg.addFunction("刺小瓶缓冲液", this::pirceLittleBuffer); - // cfg.addFunction("取样品到小瓶缓冲液", this::takeSampleToLittleBuffer); - // cfg.addFunction("取反应液", this::takePreReactionLiquidFromSmallBottleBuffer); - cfg.addFunction("滴反应液到反应板上", this::dropLiquidToReactionPlate); - cfg.newGroup("其他"); - cfg.addFunction("取样本(Only)", this::takeSampleOnly); - - + cfg.addFunction("刺破", this::pierceLittleBuffer); + cfg.addFunction("取样品", this::takeSample); + cfg.addFunction("放样品", this::dropSampleToSmallBufferPos); + cfg.addFunction("取混合液", this::aspiratePreReactionLiquidFromSmallBufferPos); + cfg.addFunction("滴入反应板", this::dropLiquidToReactionPlate); extApiPageMgr.addPage(cfg); }