From dce7084929c74ed9b368d903558ba36e3ee89364 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Sun, 22 Dec 2024 18:49:45 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=83=A8=E5=88=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../a8k/app/a8ktype/exception/AppException.java | 4 + .../api/v1/app/data/A8kProjectCardControler.java | 13 +- .../java/a8k/app/dao/db/A8kProjExtInfoCardDao.java | 3 + .../a8k/app/factory/FakeReactionResultFactory.java | 22 +++ .../app/hardware/basedriver/A8kCanBusService.java | 2 +- .../background/BackgroudProcessCtrlService.java | 6 +- .../background/ProjIDCardDectorService.java | 106 --------------- .../service/background/TemperatureCtrlService.java | 2 +- .../app/service/data/ProjIdCardInfoMgrService.java | 22 +-- .../lowerctrl/ConsumablesScanCtrlService.java | 54 +++++--- .../service/lowerctrl/DeviceInitCtrlService.java | 2 +- .../service/lowerctrl/HbotMoveExCtrlService.java | 16 ++- .../lowerctrl/LiquidOperationCtrlService.java | 39 +++++- .../lowerctrl/ProjIDCardCtrlAndMonitorService.java | 120 +++++++++++++++++ .../service/lowerctrl/TubeFeedingCtrlService.java | 147 +++++++++++---------- .../action/DO_FINISH_TUBE_PROCESS.java | 2 +- .../action/DO_PROCESS_ERROR_PLATE.java | 4 +- .../mainflowctrl/action/PLATE_OPT_SCAN.java | 8 +- .../action/PROCESS_INCUBATE_COMPLETED_PLATE.java | 2 +- .../action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java | 25 ++-- .../action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java | 2 +- .../mainctrl/mainflowctrl/action/SEQ5_PROCESS.java | 4 +- .../mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java | 4 +- .../processer/MainFlowStateChangeProcesser.java | 2 +- .../a8k/app/service/statemgr/GStateMgrService.java | 41 +++++- src/main/java/a8k/app/utils/ZAppChecker.java | 8 +- .../extui/page/test/MainflowCtrlTestService.java | 65 ++++----- .../page/test/VirtualDeviceSimulationTest.java | 16 +-- src/main/java/a8k/teststate/TestModeState.java | 18 +++ .../java/a8k/teststate/TestStateMgrService.java | 25 ++-- src/main/java/a8k/teststate/VirtualDevice.java | 40 ++++++ .../factory/FakeReactionResultFactory.java | 22 --- .../java/a8k/teststate/state/TestModeState.java | 22 --- .../java/a8k/teststate/state/VirtualDevice.java | 93 ------------- 34 files changed, 500 insertions(+), 461 deletions(-) create mode 100644 src/main/java/a8k/app/factory/FakeReactionResultFactory.java delete mode 100644 src/main/java/a8k/app/service/background/ProjIDCardDectorService.java create mode 100644 src/main/java/a8k/app/service/lowerctrl/ProjIDCardCtrlAndMonitorService.java create mode 100644 src/main/java/a8k/teststate/TestModeState.java create mode 100644 src/main/java/a8k/teststate/VirtualDevice.java delete mode 100644 src/main/java/a8k/teststate/factory/FakeReactionResultFactory.java delete mode 100644 src/main/java/a8k/teststate/state/TestModeState.java delete mode 100644 src/main/java/a8k/teststate/state/VirtualDevice.java diff --git a/src/main/java/a8k/app/a8ktype/exception/AppException.java b/src/main/java/a8k/app/a8ktype/exception/AppException.java index 705caf8..2534298 100644 --- a/src/main/java/a8k/app/a8ktype/exception/AppException.java +++ b/src/main/java/a8k/app/a8ktype/exception/AppException.java @@ -32,6 +32,10 @@ public class AppException extends Exception { return new AppException(new AEHardwareError(errorCode, mid, cmdId)); } + public static AppException of(A8kEcode errorCode) { + return new AppException(new AppError(errorCode)); + } + public static AppException of(A8kEcode errorCode, MId mid) { return new AppException(new AEHardwareError(errorCode, mid, null)); } diff --git a/src/main/java/a8k/app/controler/api/v1/app/data/A8kProjectCardControler.java b/src/main/java/a8k/app/controler/api/v1/app/data/A8kProjectCardControler.java index 4756e1d..05859a0 100644 --- a/src/main/java/a8k/app/controler/api/v1/app/data/A8kProjectCardControler.java +++ b/src/main/java/a8k/app/controler/api/v1/app/data/A8kProjectCardControler.java @@ -1,5 +1,7 @@ package a8k.app.controler.api.v1.app.data; +import a8k.app.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.app.service.lowerctrl.ProjIDCardCtrlAndMonitorService; import a8k.app.service.data.ProjIdCardInfoMgrService; import a8k.app.service.statemgr.GStateMgrService; import a8k.app.dao.db.type.A8kProjInfoCardBreif; @@ -28,10 +30,18 @@ public class A8kProjectCardControler { @Resource ProjIdCardInfoMgrService projIdCardInfoMgrService; + @Resource + ProjIDCardCtrlAndMonitorService projIDCardCtrlAndMonitorService; + + @Operation(summary = "读取已挂载的A8k项目信息卡") @PostMapping("/readMountedCardInfo") public ApiRet readMountedCardInfo() throws AppException { - return ApiRet.success(projIdCardInfoMgrService.readMountedIDCardInfo()); + var mountedIdCardInfo = projIDCardCtrlAndMonitorService.getMountedIdCardInfo(); + if (mountedIdCardInfo == null) { + throw AppException.of(A8kEcode.APPE_A8K_ID_CARD_NOT_MOUNTED); + } + return ApiRet.success(mountedIdCardInfo.toBreif()); } @Operation(summary = "保存已挂载的A8k项目信息卡") @@ -62,5 +72,4 @@ public class A8kProjectCardControler { } - } diff --git a/src/main/java/a8k/app/dao/db/A8kProjExtInfoCardDao.java b/src/main/java/a8k/app/dao/db/A8kProjExtInfoCardDao.java index 0582c0d..f489a7e 100644 --- a/src/main/java/a8k/app/dao/db/A8kProjExtInfoCardDao.java +++ b/src/main/java/a8k/app/dao/db/A8kProjExtInfoCardDao.java @@ -36,6 +36,9 @@ public class A8kProjExtInfoCardDao extends ZSqlite { * @param idcardinfo idcardinfo */ public void addIdCard(ProjExtInfoCard idcardinfo) { + if (idcardinfo == null) { + return; + } //查找是否有相同的lotName,如果则更新 ProjExtInfoCard old = getByLotId(idcardinfo.lotId); if (old != null) { diff --git a/src/main/java/a8k/app/factory/FakeReactionResultFactory.java b/src/main/java/a8k/app/factory/FakeReactionResultFactory.java new file mode 100644 index 0000000..d794879 --- /dev/null +++ b/src/main/java/a8k/app/factory/FakeReactionResultFactory.java @@ -0,0 +1,22 @@ +package a8k.app.factory; + +import a8k.app.dao.db.type.a8kidcard.zenum.A8kResultUnit; +import a8k.app.a8ktype.type.ReactionResult; +import a8k.app.utils.ProjInfo; + +import java.util.ArrayList; +import java.util.List; + +public class FakeReactionResultFactory { + public static List build(ProjInfo projcfg) { + List resultList = new ArrayList<>(); + + for (int i = 0; i < projcfg.projOptInfoList.size(); i++) { + ReactionResult result = new ReactionResult("HSCRP xxxxx", "HC", 11.11, 22.22, 33.33, A8kResultUnit.ngPml, A8kResultUnit.ngPdl, A8kResultUnit.iuPml); + resultList.add(result); + } + + return resultList; + } + +} diff --git a/src/main/java/a8k/app/hardware/basedriver/A8kCanBusService.java b/src/main/java/a8k/app/hardware/basedriver/A8kCanBusService.java index 69e2290..b7f050c 100644 --- a/src/main/java/a8k/app/hardware/basedriver/A8kCanBusService.java +++ b/src/main/java/a8k/app/hardware/basedriver/A8kCanBusService.java @@ -2,7 +2,7 @@ package a8k.app.hardware.basedriver; import a8k.app.a8ktype.appevent.A8kCanBusOnConnectEvent; import a8k.app.hardware.type.regindex.RegIndex; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.type.PlateInfo; import a8k.app.hardware.type.a8kcanprotocol.*; import a8k.app.hardware.type.a8kcanprotocol.MId; diff --git a/src/main/java/a8k/app/service/background/BackgroudProcessCtrlService.java b/src/main/java/a8k/app/service/background/BackgroudProcessCtrlService.java index 625de79..1f6c9a8 100644 --- a/src/main/java/a8k/app/service/background/BackgroudProcessCtrlService.java +++ b/src/main/java/a8k/app/service/background/BackgroudProcessCtrlService.java @@ -1,11 +1,7 @@ package a8k.app.service.background; -import a8k.extui.mgr.ExtApiPageMgr; -import a8k.extui.type.ExtUIPageCfg; -import a8k.app.service.data.ProjIdCardInfoMgrService; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.exception.AppException; -import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import org.springframework.stereotype.Component; diff --git a/src/main/java/a8k/app/service/background/ProjIDCardDectorService.java b/src/main/java/a8k/app/service/background/ProjIDCardDectorService.java deleted file mode 100644 index d089bc1..0000000 --- a/src/main/java/a8k/app/service/background/ProjIDCardDectorService.java +++ /dev/null @@ -1,106 +0,0 @@ -package a8k.app.service.background; - - -import a8k.app.service.statemgr.GStateMgrService; -import a8k.app.a8ktype.appevent.*; -import a8k.app.hardware.type.regindex.RegIndex; -import a8k.app.dao.db.type.ProjExtInfoCard; -import a8k.teststate.state.VirtualDevice; -import a8k.app.a8ktype.exception.AppException; -import a8k.app.service.bases.AppEventBusService; -import a8k.app.hardware.basedriver.A8kCanBusService; -import a8k.app.hardware.type.a8kcanprotocol.*; -import a8k.app.a8kproj.A8kIdCardDataParseService; -import a8k.app.utils.ZWorkQueue; -import jakarta.annotation.PostConstruct; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - - -@Component -@Slf4j -public class ProjIDCardDectorService { - - @Resource - GStateMgrService gstate; - @Resource - VirtualDevice virtualDevice; - - - @Resource - A8kCanBusService canBus; - @Resource - AppEventBusService eventBus; - @Resource - A8kIdCardDataParseService idCardDataParseService; - - // //预设项目信息 - ZWorkQueue workQueue = new ZWorkQueue(2, 1); - - @PostConstruct - public void init() { - eventBus.regListener(this::onAppEvent); - } - - void readIDCard() { - if (virtualDevice.isEnable()) { - if (virtualDevice.isMountIdCard()) { - var mountedIdCardInfo = virtualDevice.getMountIdCard(); - gstate.setMountedIdCardInfo(mountedIdCardInfo); - eventBus.pushEvent(new AppIDCardMountEvent(mountedIdCardInfo)); - } - return; - } - - //读取ID卡信息 - byte[] data = null; - try { - data = canBus.a8kIdcardReaderReadRaw(); - log.info("ID卡信息:{}", A8kIdCardDataParseService.dumpByte(data, 10)); - } catch (AppException ignored) { - } - - //解析ID卡信息 - try { - ProjExtInfoCard mountedIdCardInfo = idCardDataParseService.parseAndCheck(data); - gstate.setMountedIdCardInfo(mountedIdCardInfo); - eventBus.pushEvent(new AppIDCardMountEvent(mountedIdCardInfo)); - } catch (AppException e) { - eventBus.pushEvent(new A8kErrorsPromptEvent(e.error)); - } - - - } - - private Boolean idCardStatus() { - try { - return canBus.moduleGetReg(MId.A8kIdCardReader, RegIndex.kreg_id_card_reader_is_online) == 1; - } catch (AppException ignored) { - } - return false; - } - - /** - * 事件总线事件处理 - * @param event e - */ - public void onAppEvent(AppEvent event) { - if (event instanceof A8kHardwareReport canPacket) { - A8kPacket packet = canPacket.getReportPacket(); - CmdId cmdId = CmdId.valueOf(packet.getCmdId()); - if (CmdId.event_a8000_idcard_online.equals(cmdId)) { - log.info("插入ID卡"); - workQueue.addTask(this::readIDCard); - } else if (CmdId.event_a8000_idcard_offline.equals(cmdId)) { - eventBus.pushEvent(new AppIDCardUnmountEvent()); - log.info("拔出ID卡"); - } - } else if (event instanceof A8kCanBusOnConnectEvent canPacket) { - if (idCardStatus()) { - log.info("ID卡读卡器在线"); - workQueue.addTask(this::readIDCard); - } - } - } -} diff --git a/src/main/java/a8k/app/service/background/TemperatureCtrlService.java b/src/main/java/a8k/app/service/background/TemperatureCtrlService.java index 9f096cf..00e0d25 100644 --- a/src/main/java/a8k/app/service/background/TemperatureCtrlService.java +++ b/src/main/java/a8k/app/service/background/TemperatureCtrlService.java @@ -4,7 +4,7 @@ package a8k.app.service.background; import a8k.app.service.setting.AppSettingsMgrService; import a8k.app.hardware.driver.TemperatureControlDriver; import a8k.app.dao.db.type.AppSetting; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.exception.AppException; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; diff --git a/src/main/java/a8k/app/service/data/ProjIdCardInfoMgrService.java b/src/main/java/a8k/app/service/data/ProjIdCardInfoMgrService.java index 674dafb..ef87162 100644 --- a/src/main/java/a8k/app/service/data/ProjIdCardInfoMgrService.java +++ b/src/main/java/a8k/app/service/data/ProjIdCardInfoMgrService.java @@ -2,12 +2,11 @@ package a8k.app.service.data; import a8k.app.dao.db.A8kProjExtInfoCardDao; -import a8k.app.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.app.service.lowerctrl.ProjIDCardCtrlAndMonitorService; import a8k.app.service.statemgr.GStateMgrService; import a8k.app.dao.db.type.A8kProjInfoCardBreif; import a8k.app.dao.db.type.ProjExtInfoCard; import a8k.app.a8ktype.db.CommonPage; -import a8k.app.a8ktype.exception.AppException; import jakarta.annotation.Resource; import org.springframework.stereotype.Component; @@ -20,25 +19,14 @@ public class ProjIdCardInfoMgrService { GStateMgrService gstate; @Resource + ProjIDCardCtrlAndMonitorService projIDCardCtrlAndMonitorService; + + @Resource A8kProjExtInfoCardDao a8KProjExtInfoCardDao; - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // ID卡管理 - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - public A8kProjInfoCardBreif readMountedIDCardInfo() throws AppException { - if (gstate.getMountedIdCardInfo() == null) { - throw new AppException(A8kEcode.APPE_A8K_ID_CARD_NOT_MOUNTED); - } - return gstate.getMountedIdCardInfo().toBreif(); - } - public void saveMountedProjInfoCard() { - a8KProjExtInfoCardDao.addIdCard(gstate.getMountedIdCardInfo()); - } - - public Boolean getMountedProjInfoCardState() { - return gstate.getMountedIdCardInfo() != null; + a8KProjExtInfoCardDao.addIdCard(projIDCardCtrlAndMonitorService.getMountedIdCardInfo()); } public void delete(int id) { diff --git a/src/main/java/a8k/app/service/lowerctrl/ConsumablesScanCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/ConsumablesScanCtrlService.java index c1ac486..d0f77f1 100644 --- a/src/main/java/a8k/app/service/lowerctrl/ConsumablesScanCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/ConsumablesScanCtrlService.java @@ -2,7 +2,7 @@ package a8k.app.service.lowerctrl; import a8k.app.hardware.driver.CodeScanerDriver; import a8k.app.service.param.Hbot2DCodeScanParamMgr; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.type.ConsumableOneChRawResult; import a8k.app.a8ktype.type.ConsumableScanRawResult; import a8k.app.a8ktype.device.Pos2d; @@ -22,30 +22,21 @@ public class ConsumablesScanCtrlService { @Resource HbotMoveCtrlService hbot; + // + // VIRTUAL + // - public String scanPB(int ch) throws AppException { - Pos2d pos = hbotScanPos.getPBScanPosX(ch); - hbotMoveTo(pos); - return scan2dCode(); - - } - - public String scanLittBS(int ch) throws AppException { - Pos2d pos = hbotScanPos.getLittBSX(ch); - hbotMoveTo(pos); - return scan2dCode(); - } - - public String scanLarBS(int ch) throws AppException { - Pos2d pos = hbotScanPos.getLarBSX(ch); - hbotMoveTo(pos); - return scan2dCode(); + ConsumableScanRawResult virtualConsumablesScanRawResult = new ConsumableScanRawResult(); + synchronized public void setVirtualConsumablesScanResult(Integer ch, ConsumableOneChRawResult result) { + virtualConsumablesScanRawResult.ch[ch] = result; } - + // + // PUBLIC + // public ConsumableScanRawResult doScanConsumablesAction() throws AppException { if (virtualDevice.isEnable()) { - return virtualDevice.getConsumablesScanRawResult(); + return virtualConsumablesScanRawResult; } ConsumableScanRawResult result = new ConsumableScanRawResult(); @@ -78,7 +69,7 @@ public class ConsumablesScanCtrlService { public ConsumableOneChRawResult doScanOneCh(Integer ch) throws AppException { if (virtualDevice.isEnable()) { - return virtualDevice.getConsumablesScanResult(ch); + return virtualConsumablesScanRawResult.ch[ch]; } ConsumableOneChRawResult result = new ConsumableOneChRawResult(ch); @@ -88,6 +79,7 @@ public class ConsumablesScanCtrlService { return result; } + // // PRIVATE // @@ -99,4 +91,24 @@ public class ConsumablesScanCtrlService { return codeScaner.pipetteModCodeScannerScanCode(); } + public String scanPB(int ch) throws AppException { + Pos2d pos = hbotScanPos.getPBScanPosX(ch); + hbotMoveTo(pos); + return scan2dCode(); + + } + + public String scanLittBS(int ch) throws AppException { + Pos2d pos = hbotScanPos.getLittBSX(ch); + hbotMoveTo(pos); + return scan2dCode(); + } + + public String scanLarBS(int ch) throws AppException { + Pos2d pos = hbotScanPos.getLarBSX(ch); + hbotMoveTo(pos); + return scan2dCode(); + } + + } diff --git a/src/main/java/a8k/app/service/lowerctrl/DeviceInitCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/DeviceInitCtrlService.java index c64a567..5efc1db 100644 --- a/src/main/java/a8k/app/service/lowerctrl/DeviceInitCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/DeviceInitCtrlService.java @@ -10,7 +10,7 @@ import a8k.app.hardware.driver.type.StepMotorMId; import a8k.app.hardware.extdriver.MotorEnableExDriver; import a8k.app.service.bases.AppEventBusService; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.others.CheckPointType; import a8k.app.a8ktype.others.checkpoint.CheckResult; import a8k.app.a8ktype.others.checkpoint.Checkpoint; diff --git a/src/main/java/a8k/app/service/lowerctrl/HbotMoveExCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/HbotMoveExCtrlService.java index 90087af..9bedf11 100644 --- a/src/main/java/a8k/app/service/lowerctrl/HbotMoveExCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/HbotMoveExCtrlService.java @@ -127,6 +127,18 @@ public class HbotMoveExCtrlService { hbotMoveCtrlService.hbotMoveTo(hbotFixedPosParamMgr.getDropLiquidPos()); } + + public void moveTo(Pos3d pos) throws AppException { + hbotMoveCtrlService.hbotMoveTo(pos); + } + + public void moveToXY(Pos3d pos) throws AppException { + pos.z = 0; + hbotMoveCtrlService.hbotMoveTo(pos); + } + + + /** * 移动到取样位置 * @param pos 取样位置 @@ -190,10 +202,6 @@ public class HbotMoveExCtrlService { } - public void moveTo(Pos3d pos) throws AppException { - hbotMoveCtrlService.hbotMoveTo(pos); - } - public void moveQuickToZero() throws AppException { log.info("Hbot快速归零"); hbotMoveCtrlService.hbotMoveTo(new Pos3d(0, 0, 0)); diff --git a/src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrlService.java index 02a6bad..1e60fab 100644 --- a/src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrlService.java @@ -2,10 +2,13 @@ package a8k.app.service.lowerctrl; import a8k.app.a8ktype.device.ConsumableIndex; +import a8k.app.a8ktype.device.Pos3d; +import a8k.app.hardware.type.LldType; import a8k.app.hardware.type.a8kcanprotocol.A8kEcode; import a8k.app.hardware.driver.PipetteCtrlDriver; import a8k.app.a8ktype.device.ConsumableGroup; import a8k.app.a8ktype.exception.AppException; +import a8k.app.service.exparam.HbotConsumableParamMgr; import a8k.app.utils.ZAppChecker; import jakarta.annotation.Resource; import org.springframework.stereotype.Component; @@ -37,6 +40,12 @@ public class LiquidOperationCtrlService { // // 吸吐混匀 + static public final Integer lldZmotorVmax = 50; + static public final Integer lldGunPumpVmax = 50; + + + + /* * CTRL-SERVICE */ @@ -48,7 +57,8 @@ public class LiquidOperationCtrlService { /* * PARAM-MGR */ - + @Resource + HbotConsumableParamMgr hbotConsumableParamMgr; private void pumpMoveTo(Integer pumpvmax, Double ul) throws AppException { pipetteCtrlDriver.liquidOperationClearParams(); @@ -64,12 +74,22 @@ public class LiquidOperationCtrlService { pipetteCtrlDriver.liquidOperationFreshParams(); pipetteCtrlDriver.pipettePumpMoveTo(0.0); - pipetteCtrlDriver.pipettePumpMoveTo(50.0); + } - pipetteCtrlDriver.pipettePumpMoveTo(0.0); - pipetteCtrlDriver.pipettePumpMoveTo(50.0); + private void ldd(Integer startpos, Integer maxpos, Integer p_threshold) throws AppException { + pipetteCtrlDriver.liquidOperationClearParams(); + pipetteCtrlDriver.liquidOperationSetGunRunParams(14, 14, 0, 1000, lldGunPumpVmax); + pipetteCtrlDriver.liquidOperationSetZMotorRunParams(0, maxpos, lldZmotorVmax); + pipetteCtrlDriver.liquidOperationFreshParams(); + + pipetteCtrlDriver.pipetteLld(LldType.kplld, 0, p_threshold); } + // + // + // + // + // /** * 取大瓶缓冲液到探测物质位置 @@ -83,13 +103,22 @@ public class LiquidOperationCtrlService { // 检查是否有TIP ZAppChecker.check(pipetteCtrlDriver.isHasTip(), A8kEcode.CODEERROR, "未检测到TIP"); + Pos3d toPos = hbotConsumableParamMgr.getLargeBufferSamplePos(fromGroup); //移动到大瓶缓冲液的位置 - hbotMoveExCtrlService.moveToLargeBSSamplePosXY(fromGroup); + hbotMoveExCtrlService.moveToXY(toPos); //清空tip中的液体和空气,同时预先吸入部分空气,以便后续清空由于lld吸入的液体,提高lld的准确性 lddprepare(); //移动到lld准备位置 + ldd(0, 1000, 0); + if (pipetteCtrlDriver.lldIsDetectLiquid()) { + + } + //TODO: 处理耗材不足的问题 + // 抛通知 ---> 前端显示 + // 抛异常 ---> 中断流程 ---> 处理错误 ---> 前端提示错误 ---> 设置标志位 + // 设置标志位 ---> 防止再次启动 } } diff --git a/src/main/java/a8k/app/service/lowerctrl/ProjIDCardCtrlAndMonitorService.java b/src/main/java/a8k/app/service/lowerctrl/ProjIDCardCtrlAndMonitorService.java new file mode 100644 index 0000000..2c9a1cb --- /dev/null +++ b/src/main/java/a8k/app/service/lowerctrl/ProjIDCardCtrlAndMonitorService.java @@ -0,0 +1,120 @@ +package a8k.app.service.lowerctrl; + + +import a8k.app.service.statemgr.GStateMgrService; +import a8k.app.a8ktype.appevent.*; +import a8k.app.hardware.type.regindex.RegIndex; +import a8k.app.dao.db.type.ProjExtInfoCard; +import a8k.app.a8ktype.exception.AppException; +import a8k.app.service.bases.AppEventBusService; +import a8k.app.hardware.basedriver.A8kCanBusService; +import a8k.app.hardware.type.a8kcanprotocol.*; +import a8k.app.a8kproj.A8kIdCardDataParseService; +import a8k.app.utils.ZWorkQueue; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 项目ID卡管理服务 + * + */ + +@Component +@Slf4j +public class ProjIDCardCtrlAndMonitorService { + @Resource + A8kCanBusService canBus; + @Resource + AppEventBusService eventBus; + @Resource + A8kIdCardDataParseService idCardDataParseService; + + + ZWorkQueue workQueue = new ZWorkQueue(2, 1); + ProjExtInfoCard mountedIdCardInfo; + + + @PostConstruct + synchronized public void init() { + eventBus.regListener(this::onAppEvent); + } + + synchronized public ProjExtInfoCard getMountedIdCardInfo() { + return mountedIdCardInfo; + } + + // + // VIRTUAL + // + + /** + * 设置虚拟挂载的ID卡信息 + * @param mountedIdCardInfo 挂载的ID卡信息 + */ + synchronized public void setVirtualMountedIdCardInfo(ProjExtInfoCard mountedIdCardInfo) { + if (mountedIdCardInfo == null) { + this.mountedIdCardInfo = null; + eventBus.pushEvent(new AppIDCardUnmountEvent()); + } else { + this.mountedIdCardInfo = mountedIdCardInfo; + eventBus.pushEvent(new AppIDCardMountEvent(mountedIdCardInfo)); + } + } + + // + // PRIVATE + // + + /** + * 事件总线事件处理 + * @param event e + */ + private void onAppEvent(AppEvent event) { + if (event instanceof A8kHardwareReport canPacket) { + A8kPacket packet = canPacket.getReportPacket(); + CmdId cmdId = CmdId.valueOf(packet.getCmdId()); + if (CmdId.event_a8000_idcard_online.equals(cmdId)) { + log.info("插入ID卡"); + workQueue.addTask(this::readIDCard); + } else if (CmdId.event_a8000_idcard_offline.equals(cmdId)) { + eventBus.pushEvent(new AppIDCardUnmountEvent()); + log.info("拔出ID卡"); + } + } else if (event instanceof A8kCanBusOnConnectEvent canPacket) { + if (idCardStatus()) { + log.info("ID卡读卡器在线"); + workQueue.addTask(this::readIDCard); + } + } + } + + private void readIDCard() { + //读取ID卡信息 + byte[] data = null; + try { + data = canBus.a8kIdcardReaderReadRaw(); + log.info("ID卡信息:{}", A8kIdCardDataParseService.dumpByte(data, 10)); + } catch (AppException ignored) { + } + + //解析ID卡信息 + try { + mountedIdCardInfo = idCardDataParseService.parseAndCheck(data); + eventBus.pushEvent(new AppIDCardMountEvent(mountedIdCardInfo)); + } catch (AppException e) { + eventBus.pushEvent(new A8kErrorsPromptEvent(e.error)); + } + } + + private Boolean idCardStatus() { + try { + return canBus.moduleGetReg(MId.A8kIdCardReader, RegIndex.kreg_id_card_reader_is_online) == 1; + } catch (AppException ignored) { + } + return false; + } + + +} diff --git a/src/main/java/a8k/app/service/lowerctrl/TubeFeedingCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/TubeFeedingCtrlService.java index 437c8ec..614c607 100644 --- a/src/main/java/a8k/app/service/lowerctrl/TubeFeedingCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/TubeFeedingCtrlService.java @@ -29,15 +29,6 @@ public class TubeFeedingCtrlService { static Integer outfeedOvertime = 10000; static Integer scanOvertime = 3000; - static class ORDER { - static final int moveTubeRackToExitPos = 1; - static final int moveTubeRackToScanPos = 2; - static final int moveTubeToScanPosAndScan = 3; - static final int moveTubeToAltitJudgXPos = 4; - static final int judgeTubeExist = 5; - - } - @Resource AppEventBusService ebus; @Resource @@ -54,51 +45,6 @@ public class TubeFeedingCtrlService { StepMotorCtrlDriver stepMotorCtrlDriver; - private Boolean isTubeExist() throws AppException { - return canBus.getIOState(IOId.TubeExistPPS); - } - - private Boolean isTubeRackInEnterPos() throws AppException { - return canBus.getIOState(IOId.InfeedPPS); - } - - private Boolean isTubeRackInExitPos() throws AppException { - return canBus.getIOState(IOId.OutfeedPPS); - } - - private Boolean isHighTube() throws AppException { - return canBus.getIOState(IOId.TubeHeightPPS); - } - - - /** - * 移动试管到扫码位置 - * @param tubeIndex 试管索引 - */ - private void moveTubeToScanPos(Integer tubeIndex) throws AppException { - tubeFeedingExCtrlService.scanClampModClamp(); - tubeFeedingExCtrlService.moveTubeRackTo(stp.getTubeScanPos(tubeIndex), TargetPosMeasureDirection.NEGATIVE, false); - } - - /** - * 移动<试管架>到试管架扫码位置 - */ - private void moveTubeRackToScanPos() throws AppException { - tubeFeedingExCtrlService.moveTubeRackTo(stp.getTubeHolderScanXPos(), TargetPosMeasureDirection.POSITIVE, false); - } - - - public Boolean getTHchOuterPPS() throws AppException { - return canBus.getIOState(IOId.THChOuterPPS); - } - - public Boolean getTHchInterPPS() throws AppException { - return canBus.getIOState(IOId.THChInterPPS); - } - /*========================================================================================= - * 片段 - *========================================================================================*/ - /** * 移动试管架到入口位置 */ @@ -176,6 +122,24 @@ public class TubeFeedingCtrlService { } } + + /** + * 移动试管到扫码位置,并扫码 + * @param tubeIndex 试管索引 + */ + private String moveTubeToScanPosAndScan(Integer tubeIndex) throws AppException { + moveTubeToScanPos(tubeIndex); + try { + tubeFeedingExCtrlService.scanClampModClamp(); + miniServoDriver.miniServoRotateWithTorque(MiniServoMId.ShakeModTubeScanerRotateSV, stp.getTubeScanServoTorque()); + return codeScaner.feedingModScannerModCodeScannerScanCode(scanOvertime); + } finally { + miniServoDriver.moduleStop(MiniServoMId.ShakeModTubeScanerRotateSV); + tubeFeedingExCtrlService.scanClampModRelease(); + } + } + + /** * 移动试管架到扫码并扫码 */ @@ -192,26 +156,12 @@ public class TubeFeedingCtrlService { } return result; } + + // // 试管移动 // - /** - * 移动试管到扫码位置,并扫码 - * @param tubeIndex 试管索引 - */ - public String moveTubeToScanPosAndScan(Integer tubeIndex) throws AppException { - moveTubeToScanPos(tubeIndex); - try { - tubeFeedingExCtrlService.scanClampModClamp(); - miniServoDriver.miniServoRotateWithTorque(MiniServoMId.ShakeModTubeScanerRotateSV, stp.getTubeScanServoTorque()); - return codeScaner.feedingModScannerModCodeScannerScanCode(scanOvertime); - } finally { - miniServoDriver.moduleStop(MiniServoMId.ShakeModTubeScanerRotateSV); - tubeFeedingExCtrlService.scanClampModRelease(); - } - } - public Boolean tubeXChannelIsEmpty() throws AppException { return !getTHchInterPPS() && !getTHchOuterPPS(); } @@ -286,5 +236,62 @@ public class TubeFeedingCtrlService { return result; } + // + // VIRTUAL + // + + TubeHolderScanResult virtualTubeScanResult = null; + + synchronized public void setVirtualTubeScanResult(TubeHolderScanResult scanResult) { + virtualTubeScanResult = scanResult; + } + + synchronized public TubeHolderScanResult takeVirtualTubeScanResult() { + var ret = virtualTubeScanResult; + virtualTubeScanResult = null; + return ret; + } + + synchronized public Boolean isVirtualTubeHolderReady() { + return virtualTubeScanResult != null; + } + + + // + // PRIVATE + // + private Boolean isTubeExist() throws AppException { + return canBus.getIOState(IOId.TubeExistPPS); + } + + private Boolean isHighTube() throws AppException { + return canBus.getIOState(IOId.TubeHeightPPS); + } + + + /** + * 移动试管到扫码位置 + * @param tubeIndex 试管索引 + */ + private void moveTubeToScanPos(Integer tubeIndex) throws AppException { + tubeFeedingExCtrlService.scanClampModClamp(); + tubeFeedingExCtrlService.moveTubeRackTo(stp.getTubeScanPos(tubeIndex), TargetPosMeasureDirection.NEGATIVE, false); + } + + /** + * 移动<试管架>到试管架扫码位置 + */ + private void moveTubeRackToScanPos() throws AppException { + tubeFeedingExCtrlService.moveTubeRackTo(stp.getTubeHolderScanXPos(), TargetPosMeasureDirection.POSITIVE, false); + } + + + private Boolean getTHchOuterPPS() throws AppException { + return canBus.getIOState(IOId.THChOuterPPS); + } + + private Boolean getTHchInterPPS() throws AppException { + return canBus.getIOState(IOId.THChInterPPS); + } } diff --git a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java index 6daee2d..8516dfc 100644 --- a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java +++ b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java @@ -13,7 +13,7 @@ import a8k.app.a8ktype.state.enumtype.TubeState; import a8k.app.service.lowerctrl.HbotMoveExCtrlService; import a8k.app.service.lowerctrl.TubePreProcesModuleExCtrlService; import a8k.app.service.mainctrl.erroranalyzer.ErrorAnalyzer; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.error.AppError; import a8k.app.a8ktype.exception.AppException; import jakarta.annotation.Resource; diff --git a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java index 6dcda3f..300fabe 100644 --- a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java +++ b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java @@ -11,8 +11,8 @@ import a8k.app.service.statemgr.OptScanModuleStateMgrService; import a8k.app.service.statemgr.ProjectContextMgrService; import a8k.app.a8ktype.state.IncubationSubTank; import a8k.app.service.lowerctrl.OptScanModuleCtrlService; -import a8k.teststate.state.TestModeState; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.TestModeState; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.error.AppError; import a8k.app.a8ktype.exception.AppException; import a8k.app.utils.ZList; diff --git a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/PLATE_OPT_SCAN.java b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/PLATE_OPT_SCAN.java index 09d6236..01c184d 100644 --- a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/PLATE_OPT_SCAN.java +++ b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/PLATE_OPT_SCAN.java @@ -14,9 +14,9 @@ import a8k.app.service.statemgr.ProjectContextMgrService; import a8k.app.a8ktype.state.ProjectTaskContext; import a8k.app.service.lowerctrl.OptScanModuleCtrlService; import a8k.app.dao.db.type.a8kidcard.zenum.A8kOptType; -import a8k.teststate.state.TestModeState; -import a8k.teststate.state.VirtualDevice; -import a8k.teststate.factory.FakeReactionResultFactory; +import a8k.teststate.TestModeState; +import a8k.teststate.VirtualDevice; +import a8k.app.factory.FakeReactionResultFactory; import a8k.app.a8ktype.type.ReactionResult; import a8k.app.a8ktype.error.AppError; import a8k.app.a8ktype.exception.AppException; @@ -81,7 +81,7 @@ public class PLATE_OPT_SCAN extends A8kStepAction { } //扫描反应板并获取结果 - if (testModeState.getDisableOptScan()) { + if (gstate.getDisableOptScan()) { optScanModuleCtrlService.dropPlate(); return reactionResults; } diff --git a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java index c8f0baf..8db674c 100644 --- a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java +++ b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java @@ -11,7 +11,7 @@ import a8k.app.service.statemgr.ProjectContextMgrService; import a8k.app.a8ktype.state.IncubationSubTank; import a8k.app.a8ktype.state.ProjectTaskContext; import a8k.app.service.lowerctrl.OptScanModuleCtrlService; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.error.AppError; import a8k.app.a8ktype.exception.AppException; import a8k.app.utils.ProjInfoUtils; diff --git a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java index ee94dde..0a15399 100644 --- a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java +++ b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java @@ -18,8 +18,8 @@ import a8k.app.a8ktype.state.enumtype.TubeState; import a8k.app.service.lowerctrl.TubeFeedingCtrlService; import a8k.app.service.bases.AppEventBusService; import a8k.app.a8ktype.appevent.AppWarningNotifyEvent; -import a8k.teststate.state.TestModeState; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.TestModeState; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.type.TubeHolderScanResult; import a8k.app.a8ktype.error.AETubeError; import a8k.app.a8ktype.error.AppError; @@ -86,7 +86,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { public Boolean getTubeholderEnterPosPPS() { //入料通道是否为空 if (virtualDevice.isEnable()) { - return virtualDevice.isTubeHolderReady(); + return stc.isVirtualTubeHolderReady(); } try { return canBus.getIOState(IOId.InfeedPPS); @@ -190,19 +190,20 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { * 如果使能了虚拟设备,那么直接返回虚拟设备的扫描结果 */ if (virtualDevice.isEnable()) { - result = virtualDevice.takeTubeHolderScanResult(); + result = stc.takeVirtualTubeScanResult(); } else { result = stc.scanTubeHodler(); - } - //如果测试模式设置好了试管扫描结果,那么直接使用虚拟扫描结果 - if (testModeState.getVirtualTubeScanResult() != null) { - if (!virtualDevice.isEnable() && result != null && result.isHasTubeInIt()) { - throw AppException.ofAECodeError("试管架中有试管,但是测试模式中设置了虚拟试管扫描结果"); + //如果测试模式设置好了试管扫描结果,那么直接使用虚拟扫描结果 + var virresult = stc.takeVirtualTubeScanResult(); + if (virresult != null) { + if (result.isHasTubeInIt()) + throw AppException.ofAECodeError("试管架中有试管,但是测试模式中设置了虚拟试管扫描结果"); + result = virresult; } - result = testModeState.getVirtualTubeScanResult(); } + return result; } @@ -236,7 +237,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { //扫描试管架 try ( - var rseult = publicAreaResourceMgr.apply(this.getClass(),PublicAreaResource.TubeSampleProcessAndTubeChannelArea) + var rseult = publicAreaResourceMgr.apply(this.getClass(), PublicAreaResource.TubeSampleProcessAndTubeChannelArea) ) { scanResult = doScanHolder(); if (scanResult == null) { @@ -254,7 +255,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { if (tubeholder == null) { logger.warn("结果解析异常"); try ( - var rseult = publicAreaResourceMgr.apply(this.getClass(),PublicAreaResource.TubeSampleProcessAndTubeChannelArea) + var rseult = publicAreaResourceMgr.apply(this.getClass(), PublicAreaResource.TubeSampleProcessAndTubeChannelArea) ) { doEjectHodler(); } catch (AppException e) { diff --git a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java index aed2a93..e7d9544 100644 --- a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java +++ b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java @@ -7,7 +7,7 @@ import a8k.app.service.mainctrl.mainflowctrl.base.A8kStepAction; import a8k.app.service.mainctrl.mainflowctrl.base.MainFlowProcesser; import a8k.app.service.statemgr.TubeStateMgrService; import a8k.app.service.lowerctrl.TubeFeedingCtrlService; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.error.AppError; import a8k.app.a8ktype.exception.AppException; import a8k.app.utils.ZList; diff --git a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ5_PROCESS.java b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ5_PROCESS.java index 84dc55a..76e5766 100644 --- a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ5_PROCESS.java +++ b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ5_PROCESS.java @@ -23,8 +23,8 @@ import a8k.app.service.param.HbotSamplePosParamMgr; import a8k.app.a8ktype.param.A8kSamplePos; import a8k.app.service.mainctrl.erroranalyzer.ErrorAnalyzer; import a8k.app.dao.db.type.a8kidcard.zenum.A8kReactionFlowType; -import a8k.teststate.state.TestModeState; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.TestModeState; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.device.ConsumableGroup; import a8k.app.a8ktype.device.IncubatorPos; import a8k.app.a8ktype.error.AECodeError; diff --git a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java index d073ff5..720338d 100644 --- a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java +++ b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java @@ -8,8 +8,8 @@ import a8k.app.service.mainctrl.mainflowctrl.base.MainFlowProcesser; import a8k.app.service.statemgr.GStateMgrService; import a8k.app.service.statemgr.TubeStateMgrService; import a8k.app.service.lowerctrl.TubeFeedingCtrlService; -import a8k.teststate.state.TestModeState; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.TestModeState; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.error.AppError; import a8k.app.a8ktype.exception.AppException; import a8k.app.utils.ZList; diff --git a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/processer/MainFlowStateChangeProcesser.java b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/processer/MainFlowStateChangeProcesser.java index d4bc731..00aa39c 100644 --- a/src/main/java/a8k/app/service/mainctrl/mainflowctrl/processer/MainFlowStateChangeProcesser.java +++ b/src/main/java/a8k/app/service/mainctrl/mainflowctrl/processer/MainFlowStateChangeProcesser.java @@ -10,7 +10,7 @@ import a8k.app.a8ktype.state.enumtype.IncubationSubTankState; import a8k.app.service.lowerctrl.HbotMoveExCtrlService; import a8k.app.service.lowerctrl.OptScanModuleCtrlService; import a8k.app.service.lowerctrl.TubeFeedingCtrlService; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.exception.AppException; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/a8k/app/service/statemgr/GStateMgrService.java b/src/main/java/a8k/app/service/statemgr/GStateMgrService.java index 3a8e29a..05ebfc4 100644 --- a/src/main/java/a8k/app/service/statemgr/GStateMgrService.java +++ b/src/main/java/a8k/app/service/statemgr/GStateMgrService.java @@ -2,7 +2,6 @@ package a8k.app.service.statemgr; import a8k.app.constant.AppConstant; import a8k.app.a8ktype.state.SensorState; -import a8k.app.dao.db.type.ProjExtInfoCard; import lombok.Data; import org.springframework.stereotype.Component; @@ -10,20 +9,48 @@ import org.springframework.stereotype.Component; @Data public class GStateMgrService { //设备是否初始化过 - private Boolean deviceInited = false; + private Boolean deviceInited = false; + private Boolean noCheckMode = false; //无校验模式 + private Boolean disableOptScan = false; //是否使能光学扫描 + // - private String appVersion = AppConstant.APP_VERSION; - private String mcuVersion = "NOTSET"; - private String sn = "NOTSET"; + private String appVersion = AppConstant.APP_VERSION; + private String mcuVersion = "NOTSET"; + private String sn = "NOTSET"; + + + SensorState sensorState = new SensorState(); - SensorState sensorState = new SensorState(); - ProjExtInfoCard mountedIdCardInfo; public Boolean isDeviceInited() { return deviceInited; } + public synchronized SensorState getSensorState() { return sensorState; } + public synchronized void setSensorState(SensorState sensorState) { + this.sensorState = sensorState; + } + + public synchronized void setDeviceInited(Boolean deviceInited) { + this.deviceInited = deviceInited; + } + + public Boolean isNoCheckMode() { + return noCheckMode; + } + + public synchronized void setNoCheckMode(Boolean noCheckMode) { + this.noCheckMode = noCheckMode; + } + + public Boolean isDisableOptScan() { + return disableOptScan; + } + + public synchronized void setDisableOptScan(Boolean disableOptScan) { + this.disableOptScan = disableOptScan; + } } diff --git a/src/main/java/a8k/app/utils/ZAppChecker.java b/src/main/java/a8k/app/utils/ZAppChecker.java index d25ae4d..0d02b34 100644 --- a/src/main/java/a8k/app/utils/ZAppChecker.java +++ b/src/main/java/a8k/app/utils/ZAppChecker.java @@ -2,7 +2,8 @@ package a8k.app.utils; import a8k.app.factory.AppExceptionFactory; import a8k.app.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.teststate.state.TestModeState; +import a8k.app.service.statemgr.GStateMgrService; +import a8k.teststate.TestModeState; import a8k.app.a8ktype.error.AppError; import a8k.app.a8ktype.exception.AppException; import jakarta.annotation.Resource; @@ -18,12 +19,15 @@ public class ZAppChecker { AppExceptionFactory ebuilder; @Resource + GStateMgrService gstate; + + @Resource TestModeState testModeState; public void checkTakeTip(Boolean takeTipOk) throws AppException { if (!takeTipOk) { - if (testModeState.getNoCheckMode()) { + if (gstate.getNoCheckMode()) { log.info("take tip fail, but in no check mode, ignore it"); return; } diff --git a/src/main/java/a8k/extui/page/test/MainflowCtrlTestService.java b/src/main/java/a8k/extui/page/test/MainflowCtrlTestService.java index fd09f33..5e00a9f 100644 --- a/src/main/java/a8k/extui/page/test/MainflowCtrlTestService.java +++ b/src/main/java/a8k/extui/page/test/MainflowCtrlTestService.java @@ -8,8 +8,8 @@ import a8k.app.constant.AppConstant; import a8k.app.dao.db.A8kProjExtInfoCardDao; import a8k.app.dao.db.ProjOptInfoDao; import a8k.app.dao.db.ProjectBaseInfoDao; +import a8k.app.service.lowerctrl.TubeFeedingCtrlService; import a8k.app.service.statemgr.*; -import a8k.extui.type.ExtApiFn; import a8k.app.service.mainctrl.AppConsumablesScanService; import a8k.app.service.mainctrl.AppDeviceCtrlService; import a8k.app.service.mainctrl.AppTubeSettingMgrService; @@ -24,8 +24,8 @@ import a8k.app.service.lowerctrl.OptScanModuleCtrlService; import a8k.app.hardware.driver.StepMotorCtrlDriver; import a8k.app.hardware.driver.type.StepMotorMId; import a8k.app.hardware.extdriver.MotorEnableExDriver; -import a8k.teststate.state.TestModeState; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.TestModeState; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.type.*; import a8k.app.a8ktype.others.checkpoint.CheckResult; import a8k.app.a8ktype.error.ConsumablesScanReportErrorType; @@ -38,7 +38,6 @@ import a8k.app.a8ktype.device.TipGroup; import a8k.app.utils.ZList; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; @@ -46,11 +45,6 @@ import java.util.List; @Component @Slf4j public class MainflowCtrlTestService { - - @Resource - TestModeState testModeState; - @Resource - VirtualDevice virtualDevice; // // StateService // @@ -85,17 +79,19 @@ public class MainflowCtrlTestService { // Ctrl // @Resource - AppDeviceCtrlService appDeviceCtrlService; + AppDeviceCtrlService appDeviceCtrlService; @Resource - MotorEnableExDriver motorEnableExDriver; + MotorEnableExDriver motorEnableExDriver; @Resource - StepMotorCtrlDriver stepMotorCtrlDriver; + StepMotorCtrlDriver stepMotorCtrlDriver; @Resource - OptScanModuleCtrlService optScanModuleCtrlService; + OptScanModuleCtrlService optScanModuleCtrlService; @Resource - MainFlowCtrlScheduler mainFlowCtrlScheduler; + MainFlowCtrlScheduler mainFlowCtrlScheduler; @Resource - DeviceInitCtrlService deviceInitCtrlService; + DeviceInitCtrlService deviceInitCtrlService; + @Resource + TubeFeedingCtrlService tubeFeedingCtrlService; void resetProjDB() { a8KProjExtInfoCardDao.deleteAll(); @@ -153,18 +149,16 @@ public class MainflowCtrlTestService { // 测试配置 // - synchronized public TestModeState getTestModeState() { - return testModeState; - } + public void setNoCheck(Boolean noCheck) { - testModeState.setNoCheckMode(noCheck); + gstate.setNoCheckMode(noCheck); } public void setEnableOptScan(Boolean enable) { - testModeState.setDisableOptScan(enable); + gstate.setDisableOptScan(enable); } // @@ -315,10 +309,9 @@ public class MainflowCtrlTestService { public String doSimpleTest(Boolean isHTube, Integer tubeNum) throws AppException { regFakeProjInfo(); //设置虚拟耗材,只有一个高试管,无校验模式,无光学检查 - testModeState.resetAll(); - testModeState.setVirtualTubeScanResult(createScanResult(A8kTubeHolderType.BloodTube, isHTube, tubeNum)); - testModeState.setNoCheckMode(true); - testModeState.setDisableOptScan(true); + tubeFeedingCtrlService.setVirtualTubeScanResult(createScanResult(A8kTubeHolderType.BloodTube, isHTube, tubeNum)); + gstate.setNoCheckMode(true); + gstate.setDisableOptScan(true); doOnceSimpleTest(new FAKE_PROJ_01_FLOW1(), ConsumableGroup.CG1, tubeNum); return "开始测试"; } @@ -327,10 +320,9 @@ public class MainflowCtrlTestService { public String doSimpleTest2(Boolean isHTube, Integer tubeNum) throws AppException { regFakeProjInfo(); - testModeState.resetAll(); - testModeState.setVirtualTubeScanResult(createScanResult(A8kTubeHolderType.BloodTube, isHTube, tubeNum)); - testModeState.setNoCheckMode(true); - testModeState.setDisableOptScan(true); + tubeFeedingCtrlService.setVirtualTubeScanResult(createScanResult(A8kTubeHolderType.BloodTube, isHTube, tubeNum)); + gstate.setNoCheckMode(true); + gstate.setDisableOptScan(true); doOnceSimpleTest(new FAKE_PROJ_02_FLOW2(), ConsumableGroup.CG2, tubeNum); return "开始测试"; } @@ -339,9 +331,8 @@ public class MainflowCtrlTestService { public String doSimpleTest3() throws AppException { regFakeProjInfo(); //设置虚拟耗材,只有一个高试管,无校验模式,无光学检查 - testModeState.resetAll(); - testModeState.setNoCheckMode(false); - testModeState.setDisableOptScan(true); + gstate.setNoCheckMode(false); + gstate.setDisableOptScan(true); doOnceSimpleTest(new FAKE_PROJ_01_FLOW1(), ConsumableGroup.CG1, 10); return "开始测试"; } @@ -349,9 +340,8 @@ public class MainflowCtrlTestService { public String doSimpleTest4() throws AppException { regFakeProjInfo(); - testModeState.resetAll(); - testModeState.setNoCheckMode(true); - testModeState.setDisableOptScan(true); + gstate.setNoCheckMode(true); + gstate.setDisableOptScan(true); doOnceSimpleTest(new FAKE_PROJ_02_FLOW2(), ConsumableGroup.CG2, 10); return "开始测试"; } @@ -360,10 +350,9 @@ public class MainflowCtrlTestService { public String doSimpleTest5() throws AppException { regFakeProjInfo(); - testModeState.resetAll(); - testModeState.setVirtualTubeScanResult(createScanResult(A8kTubeHolderType.BloodTube, true, 10)); - testModeState.setNoCheckMode(true); - testModeState.setDisableOptScan(true); + tubeFeedingCtrlService.setVirtualTubeScanResult(createScanResult(A8kTubeHolderType.BloodTube, true, 10)); + gstate.setNoCheckMode(true); + gstate.setDisableOptScan(true); gstate.setDeviceInited(true); diff --git a/src/main/java/a8k/extui/page/test/VirtualDeviceSimulationTest.java b/src/main/java/a8k/extui/page/test/VirtualDeviceSimulationTest.java index 94adf5a..5d147fe 100644 --- a/src/main/java/a8k/extui/page/test/VirtualDeviceSimulationTest.java +++ b/src/main/java/a8k/extui/page/test/VirtualDeviceSimulationTest.java @@ -3,12 +3,11 @@ package a8k.extui.page.test; import a8k.SpringBootBeanUtil; import a8k.app.a8kproj.fakeproj.*; import a8k.app.dao.db.ReactionRecordDao; +import a8k.app.service.lowerctrl.ProjIDCardCtrlAndMonitorService; import a8k.extui.mgr.ExtApiPageMgr; import a8k.extui.type.ExtUIPageCfg; import a8k.app.factory.ZAppPromoptFactory; import a8k.app.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.app.service.mainctrl.AppDeviceCtrlService; -import a8k.app.service.mainctrl.AppTubeSettingMgrService; import a8k.app.service.mainctrl.mainflowctrl.base.A8kActionStepType; import a8k.app.service.mainctrl.mainflowctrl.base.AppActionErrorContext; import a8k.app.service.statemgr.GStateMgrService; @@ -19,7 +18,7 @@ import a8k.app.dao.db.type.ProjExtInfoCard; import a8k.app.dao.db.type.ReactionResultRecord; import a8k.app.dao.db.type.a8kidcard.zenum.A8kResultUnit; import a8k.teststate.TestStateMgrService; -import a8k.teststate.state.VirtualDevice; +import a8k.teststate.VirtualDevice; import a8k.app.a8ktype.type.ConsumableOneChRawResult; import a8k.app.a8ktype.type.ReactionResult; import a8k.app.a8ktype.error.*; @@ -28,7 +27,6 @@ import a8k.app.a8ktype.opttype.ReactionResultStatus; import a8k.app.a8ktype.device.A8kTubeHolderType; import a8k.app.a8ktype.device.BloodType; import a8k.app.a8ktype.ui.ZAppPromopt; -import a8k.app.factory.A8kPacketFactory; import a8k.app.utils.ZDateUtils; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; @@ -55,6 +53,10 @@ public class VirtualDeviceSimulationTest { @Resource ExtApiPageMgr extApiPageMgr; + + @Resource + ProjIDCardCtrlAndMonitorService projIDCardCtrlAndMonitorService; + @PostConstruct void init() { ExtUIPageCfg page = new ExtUIPageCfg(this); @@ -102,13 +104,11 @@ public class VirtualDeviceSimulationTest { public void insertVirtualIdCard() { ProjExtInfoCard idCardInfo = new FAKE_PROJ_01_FLOW1().buildProjCardInfo(); - virtualDevice.setMountIdCard(idCardInfo); - eventBus.pushEvent(new A8kHardwareReport(A8kPacketFactory.build_event_a8000_idcard_online())); + projIDCardCtrlAndMonitorService.setVirtualMountedIdCardInfo(idCardInfo); } public void removeVirtualIdCard() { - virtualDevice.setMountIdCard(null); - eventBus.pushEvent(new A8kHardwareReport(A8kPacketFactory.build_event_a8000_idcard_offline())); + projIDCardCtrlAndMonitorService.setVirtualMountedIdCardInfo(null); } public void insertVirtualBloodTubeHolder() { diff --git a/src/main/java/a8k/teststate/TestModeState.java b/src/main/java/a8k/teststate/TestModeState.java new file mode 100644 index 0000000..ef3e190 --- /dev/null +++ b/src/main/java/a8k/teststate/TestModeState.java @@ -0,0 +1,18 @@ +package a8k.teststate; + +import a8k.app.a8ktype.type.TubeHolderScanResult; +import lombok.Data; +import org.springframework.stereotype.Component; + +@Component +@Data +public class TestModeState { + +// Boolean noCheckMode = false; //无校验模式 +// Boolean disableOptScan = false; //是否使能光学扫描 + +// public void resetAll() { + // noCheckMode = false; + // disableOptScan = false; + // } +} diff --git a/src/main/java/a8k/teststate/TestStateMgrService.java b/src/main/java/a8k/teststate/TestStateMgrService.java index b19c815..d8bc9d9 100644 --- a/src/main/java/a8k/teststate/TestStateMgrService.java +++ b/src/main/java/a8k/teststate/TestStateMgrService.java @@ -10,8 +10,9 @@ import a8k.app.a8ktype.type.ConsumableOneChRawResult; import a8k.app.a8ktype.type.TubeHolderScanResult; import a8k.app.a8ktype.type.TubesScanResult; import a8k.app.a8ktype.device.A8kTubeHolderType; +import a8k.app.service.lowerctrl.ConsumablesScanCtrlService; +import a8k.app.service.lowerctrl.TubeFeedingCtrlService; import a8k.app.utils.ReactionPlate2DCodeHelper; -import a8k.teststate.state.VirtualDevice; import jakarta.annotation.Resource; import org.springframework.stereotype.Component; @@ -27,6 +28,10 @@ public class TestStateMgrService { @Resource ProjectBaseInfoDao projectBaseInfoDao; + @Resource + TubeFeedingCtrlService tubeFeedingCtrlService; + @Resource + ConsumablesScanCtrlService consumablesScanCtrlService; public void addProjInfo(Class projClass) { projectBaseInfoDao.add(FakeProjInfoFactory.buildProjectInfo(projClass)); @@ -64,22 +69,22 @@ public class TestStateMgrService { } public void insertVirtualBloodTubeHolder(TubeHolderScanResult scanResult) { - virtualDevice.setTubeScanResult(scanResult); + tubeFeedingCtrlService.setVirtualTubeScanResult(scanResult); } public void initConsumablesScanResultTable() { for (int i = 0; i < AppConstant.CONSUMABLE_CHANNEL_NUM; i++) { - virtualDevice.setConsumablesScanResult(i, new ConsumableOneChRawResult(i)); + consumablesScanCtrlService.setVirtualConsumablesScanResult(i, new ConsumableOneChRawResult(i)); } } public void insertVirtualConsumable(int ch, String lotId) { ConsumableOneChRawResult consumable = new ConsumableOneChRawResult(ch); - consumable.larBSScanResult = lotId; - consumable.littBSScanResult = lotId; - consumable.PBScanResult = ReactionPlate2DCodeHelper.build2DCode(lotId); -// virtualDevice.getConsumablesScanResultTable()[consumable.chNum] = consumable; - virtualDevice.setConsumablesScanResult(consumable.chNum, consumable); + consumable.larBSScanResult = lotId; + consumable.littBSScanResult = lotId; + consumable.PBScanResult = ReactionPlate2DCodeHelper.build2DCode(lotId); + // virtualDevice.getConsumablesScanResultTable()[consumable.chNum] = consumable; + consumablesScanCtrlService.setVirtualConsumablesScanResult(consumable.chNum, consumable); } public ConsumableOneChRawResult buildConsumable(int ch, String lotId) { @@ -91,12 +96,12 @@ public class TestStateMgrService { } public void insertVirtualConsumable(ConsumableOneChRawResult consumable) { - virtualDevice.setConsumablesScanResult(consumable.chNum, consumable); + consumablesScanCtrlService.setVirtualConsumablesScanResult(consumable.chNum, consumable); } public void removeVirtualConsumable(int ch) { ConsumableOneChRawResult consumable = new ConsumableOneChRawResult(ch); - virtualDevice.setConsumablesScanResult(consumable.chNum, consumable); + consumablesScanCtrlService.setVirtualConsumablesScanResult(consumable.chNum, consumable); } } diff --git a/src/main/java/a8k/teststate/VirtualDevice.java b/src/main/java/a8k/teststate/VirtualDevice.java new file mode 100644 index 0000000..d19a996 --- /dev/null +++ b/src/main/java/a8k/teststate/VirtualDevice.java @@ -0,0 +1,40 @@ +package a8k.teststate; + +import a8k.OS; +import a8k.app.dao.db.type.ProjExtInfoCard; +import a8k.app.a8ktype.type.ConsumableOneChRawResult; +import a8k.app.a8ktype.type.ConsumableScanRawResult; +import a8k.app.a8ktype.type.TubeHolderScanResult; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class VirtualDevice { + @Value("${VirtualDevice.enableVirtualDevice:true}") + Boolean enableVirtualDevice; + + synchronized public Boolean isEnable() { + return enableVirtualDevice; + } + + synchronized public void setEnableVirtualDevice(Boolean enable) { + this.enableVirtualDevice = enable; + } + + // + // Action + // + public void doVirtualThings(String msg) { + for (int i = 0; i < 3; i++) { + log.info("DO {}[{}%] ", msg, i / 3.0 * 100); + OS.forceSleep(1000); + } + log.info("{} done", msg); + } + + +} diff --git a/src/main/java/a8k/teststate/factory/FakeReactionResultFactory.java b/src/main/java/a8k/teststate/factory/FakeReactionResultFactory.java deleted file mode 100644 index a456210..0000000 --- a/src/main/java/a8k/teststate/factory/FakeReactionResultFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -package a8k.teststate.factory; - -import a8k.app.dao.db.type.a8kidcard.zenum.A8kResultUnit; -import a8k.app.a8ktype.type.ReactionResult; -import a8k.app.utils.ProjInfo; - -import java.util.ArrayList; -import java.util.List; - -public class FakeReactionResultFactory { - public static List build(ProjInfo projcfg) { - List resultList = new ArrayList<>(); - - for (int i = 0; i < projcfg.projOptInfoList.size(); i++) { - ReactionResult result = new ReactionResult("HSCRP xxxxx", "HC", 11.11, 22.22, 33.33, A8kResultUnit.ngPml, A8kResultUnit.ngPdl, A8kResultUnit.iuPml); - resultList.add(result); - } - - return resultList; - } - -} diff --git a/src/main/java/a8k/teststate/state/TestModeState.java b/src/main/java/a8k/teststate/state/TestModeState.java deleted file mode 100644 index 4db25cd..0000000 --- a/src/main/java/a8k/teststate/state/TestModeState.java +++ /dev/null @@ -1,22 +0,0 @@ -package a8k.teststate.state; - -import a8k.app.a8ktype.type.TubeHolderScanResult; -import lombok.Data; -import org.springframework.stereotype.Component; - -@Component -@Data -public class TestModeState { - - Boolean noCheckMode = false; //无校验模式 - Boolean disableOptScan = false; //是否使能光学扫描 - - // @JsonIgnore - TubeHolderScanResult virtualTubeScanResult = null; // 虚拟管架扫描结果 - - public void resetAll() { - noCheckMode = false; - disableOptScan = false; - virtualTubeScanResult = null; - } -} diff --git a/src/main/java/a8k/teststate/state/VirtualDevice.java b/src/main/java/a8k/teststate/state/VirtualDevice.java deleted file mode 100644 index f4968fd..0000000 --- a/src/main/java/a8k/teststate/state/VirtualDevice.java +++ /dev/null @@ -1,93 +0,0 @@ -package a8k.teststate.state; - -import a8k.OS; -import a8k.app.dao.db.type.ProjExtInfoCard; -import a8k.app.a8ktype.type.ConsumableOneChRawResult; -import a8k.app.a8ktype.type.ConsumableScanRawResult; -import a8k.app.a8ktype.type.TubeHolderScanResult; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -public class VirtualDevice { - - // - // 挂载的ID卡 - // - - @Setter - @Getter - ProjExtInfoCard mountIdCard; - - public Boolean isMountIdCard() { - return mountIdCard != null; - } - - - // - // 是否启用虚拟设备 - // - - @Value("${VirtualDevice.enableVirtualDevice:true}") - @Setter - Boolean enableVirtualDevice; - - public Boolean isEnable() { - return enableVirtualDevice; - } - - // - // 虚拟试管架 - // - @Setter - TubeHolderScanResult tubeScanResult = null; - - public TubeHolderScanResult takeTubeHolderScanResult() { - var ret = tubeScanResult; - tubeScanResult = null; - return ret; - } - - public Boolean isTubeHolderReady() { - return tubeScanResult != null; - } - - - // - // 虚拟试耗材扫描结果 - // - - ConsumableOneChRawResult[] consumablesScanResultTable = new ConsumableOneChRawResult[6]; - - public ConsumableOneChRawResult getConsumablesScanResult(Integer ch) { - return consumablesScanResultTable[ch]; - } - - public void setConsumablesScanResult(Integer ch, ConsumableOneChRawResult result) { - consumablesScanResultTable[ch] = result; - } - - public ConsumableScanRawResult getConsumablesScanRawResult() { - var ret = new ConsumableScanRawResult(); - ret.ch = consumablesScanResultTable; - return ret; - } - - - // - // Action - // - public void doVirtualThings(String msg) { - for (int i = 0; i < 3; i++) { - log.info("DO {}[{}%] ", msg, i / 3.0 * 100); - OS.forceSleep(1000); - } - log.info("{} done", msg); - } - - -}