Browse Source

update

master
zhaohe 2 months ago
parent
commit
2f669e2378
  1. 8
      src/main/java/a8k/app/constant/OptConstant.java
  2. 8
      src/main/java/a8k/app/engineer/service/qatest/ExperimentConsistencyTestingService.java
  3. 12
      src/main/java/a8k/app/service/lowerctrl/OptScanModuleLowerCtrlService.java
  4. 4
      src/main/java/a8k/app/service/lowerctrl/TubePreProcessModuleCtrlService.java
  5. 74
      src/main/java/a8k/app/service/lowerctrl/TubePreProcessModuleExCtrlService.java
  6. 10
      src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java
  7. 13
      src/main/java/a8k/app/service/mainctrl/MainFlowCtrlScheduler.java
  8. 43
      src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java
  9. 20
      src/main/java/a8k/app/service/module/OptScanCtrlModule.java
  10. 47
      src/main/java/a8k/app/service/module/SamplePreProcessModule.java
  11. 22
      src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java
  12. 48
      src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java
  13. 14
      src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java
  14. 11
      src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java
  15. 42
      src/main/java/a8k/app/service/statemgr/ProjectCxtMgr.java
  16. 3
      src/main/java/a8k/app/service/statemgr/consumables_mgr/LarBottleContainerStateMgr.java
  17. 2
      src/main/java/a8k/app/service/statemgr/consumables_mgr/LittBottleContainerStateMgr.java
  18. 3
      src/main/java/a8k/app/service/statemgr/consumables_mgr/ReactionPlateContainerStateMgr.java
  19. 1
      src/main/java/a8k/app/service/statemgr/consumables_mgr/TipStateMgr.java
  20. 1
      src/main/java/a8k/app/type/PreReactionGrid.java
  21. 7
      src/main/java/a8k/app/type/a8k/container/A8kConsumableContainer.java
  22. 7
      src/main/java/a8k/app/type/a8k/container/LarBottleContainer.java
  23. 4
      src/main/java/a8k/app/type/a8k/container/LittBottleContainer.java
  24. 3
      src/main/java/a8k/app/type/a8k/container/ReactionPlateContainer.java
  25. 6
      src/main/java/a8k/app/type/a8k/container/TipContainer.java
  26. 9
      src/main/java/a8k/app/type/a8k/state/IncubationSubTank.java
  27. 3
      src/main/java/a8k/app/type/a8k/state/OptScanModuleState.java
  28. 2
      src/main/java/a8k/app/type/a8k/state/Tube.java
  29. 24
      src/main/java/a8k/extui/page/extapp/A8kOptVerification.java
  30. 24
      src/main/java/a8k/extui/page/extapp/OptModuleParamCalibration.java
  31. 18
      src/main/java/a8k/extui/page/test/verification/P31ReactionPlatesTransmitPosVerificationPage.java
  32. 21
      src/main/java/a8k/extui/page/test/verification/P34LiquidOperationTestPage.java
  33. 8
      src/main/java/a8k/extui/page/test/verification/P50VerificationScriptPage.java
  34. 12
      src/main/resources/application.yml

8
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;
}

8
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,

12
src/main/java/a8k/app/service/lowerctrl/OptScanModuleCtrlService.java → 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);

4
src/main/java/a8k/app/service/lowerctrl/TubePreProcesModuleCtrlService.java → 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;

74
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);

10
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);
//板夹仓初始化

13
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;

43
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;
}

20
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;

47
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);
}
}
}

22
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());
};
}

48
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;

14
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;

11
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;

42
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<String, Object> cxtMap;
}
Map<String, ProjectCxt> 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);
}
}
}

3
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);
}
}

2
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);
}
}

3
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);
}
}

1
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);
}
}

1
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;

7
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);
}
}

7
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;
}
}

4
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;

3
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() {
}

6
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;
}

9
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;

3
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 {
}
}

2
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<ProjectPreProcessContext> preProcessContexts = new ArrayList<>(); //预处理上下文
@JsonIgnore
A8kTubeHolderType tubeHolderType = null;

24
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();
}
}

24
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;
}

18
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();
}
}

21
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);

8
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 {

12
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

Loading…
Cancel
Save