From f178e13b8d233140b300936d725e0df17b03c657 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Thu, 10 Oct 2024 10:47:08 +0800 Subject: [PATCH] update --- app.db | Bin 225280 -> 225280 bytes .../service/app/appctrl/AppDeviceCtrlService.java | 11 ++ .../a8k/service/app/appctrl/CheckPointType.java | 10 ++ .../app/appctrl/ConsumablesScanService.java | 116 +++++++++----- .../service/app/appctrl/DeviceInitCtrlService.java | 21 +-- .../appctrl/mainflowctrl/CondtionMgrService.java | 8 +- .../app/devicedriver/ctrl/ConsumablesScanCtrl.java | 32 +--- .../java/a8k/service/db/A8kProjInfoDBService.java | 4 + .../a8k/service/db/A8kProjOptConfigDBService.java | 13 ++ .../a8k/service/debug/AppDebugHelperService.java | 171 ++++++++++++++++++++- .../java/a8k/service/debug/FakeTubeHolder.java | 8 + .../service/debug/fakeprojinfo/FakeProjInfo.java | 32 ++-- src/main/java/a8k/type/ConsumableOneChResult.java | 13 ++ .../java/a8k/type/ConsumableScanRawResult.java | 11 ++ .../a8k/type/consumables/ConsumablesErrorType.java | 18 +++ .../java/a8k/type/consumables/ScanResultState.java | 20 --- src/main/java/a8k/utils/ReactionPlate2DCode.java | 10 +- .../java/a8k/utils/ReactionPlate2DCodeHelper.java | 41 +++++ .../java/a8k/utils/ReactionPlate2DCodeParser.java | 32 ---- 19 files changed, 415 insertions(+), 156 deletions(-) create mode 100644 src/main/java/a8k/service/app/appctrl/CheckPointType.java create mode 100644 src/main/java/a8k/service/debug/FakeTubeHolder.java create mode 100644 src/main/java/a8k/type/ConsumableOneChResult.java create mode 100644 src/main/java/a8k/type/ConsumableScanRawResult.java create mode 100644 src/main/java/a8k/type/consumables/ConsumablesErrorType.java delete mode 100644 src/main/java/a8k/type/consumables/ScanResultState.java create mode 100644 src/main/java/a8k/utils/ReactionPlate2DCodeHelper.java delete mode 100644 src/main/java/a8k/utils/ReactionPlate2DCodeParser.java diff --git a/app.db b/app.db index b7ef66ae88ade08302168d5e75d8abedc8b07a84..782e2f3e4baad68eebe9b3b38d90adcaada0c8eb 100644 GIT binary patch delta 991 zcma))&ui0Q9EaccO;S@`-gmRhS}cRLQYupLO`0Yt+hOTjV~<%Hf0o*cJ9ro>8^dE4 zMe*qV2X7(>LyLD0{t+s>dDDvs?&RA@OVgAg$tS#*=lQ;QKkvb@a&WA?x^O<10RUJ$ zCJ*NMept~_E)({j_u>0KdQBEn7yUw=edbq!{GtQR8HA`d7dZb~NRhO zfP5tTM8iMvTiiJ+tX;zcFGT<>$R(AaJS>+WT$yTm(s_@1evi7~v-@cG$-Uiep;K%X zD@DfR7rPysRy31VbV|G1-loKjOR_pKrbear=qL%pV7@|}QAnfWxq>I5m}_VV+>nv8 zlT8T!y62Aev}17EpES^n1VtAh;HSZ+C8s&ALIToRIX~G*bO)kOk22@d|9W0LMt=c! C9pyp* delta 196 zcmZp8z}xVEcY>6Vcnt#sgE checkBeforeInitDevice() throws AppException { + if (appDebugHelperService.isDebug()) { + return appDebugHelperService.checkBeforeInitDevice(); + } return deviceInitializationModule.checkBeforeInitDevice(); } @ExtApiFn(name = "设备初始化(阻塞接口)", group = "设备初始化") public void initDevice() throws AppException { + if (appDebugHelperService.isDebug()) { + gstate.setDeviceInited(true); + return; + } deviceInitializationModule.deviceMoveToZero(); } diff --git a/src/main/java/a8k/service/app/appctrl/CheckPointType.java b/src/main/java/a8k/service/app/appctrl/CheckPointType.java new file mode 100644 index 0000000..1595b5b --- /dev/null +++ b/src/main/java/a8k/service/app/appctrl/CheckPointType.java @@ -0,0 +1,10 @@ +package a8k.service.app.appctrl; + +public enum CheckPointType { + CHECK_TUBE_XCHANNEL_IS_EMPTY,//入料通道是否为空 + CHECK_PLATE_BOX_IS_COVER,//板夹仓盖子是否盖着 + CHECK_PLATE_STUCK_DETECTOR_SENSOR_IS_TRIGGER,//板夹仓卡板检测 + CHECK_PULLERM_IS_IN_ZEROPOS,//检查拉杆电机是否在零点位置 + CHECK_PUSHERM_IN_IN_ZEROPOS,//检查推杆电机是否在零点位置 + CHECK_RECYCLE_BIN_IS_OVERFLOW,//检查垃圾箱是否满 +} diff --git a/src/main/java/a8k/service/app/appctrl/ConsumablesScanService.java b/src/main/java/a8k/service/app/appctrl/ConsumablesScanService.java index 2c9f9f4..dfa59b3 100644 --- a/src/main/java/a8k/service/app/appctrl/ConsumablesScanService.java +++ b/src/main/java/a8k/service/app/appctrl/ConsumablesScanService.java @@ -7,18 +7,22 @@ import a8k.service.app.appstate.GStateService; import a8k.service.app.devicedriver.ctrl.ConsumablesScanCtrl; import a8k.service.db.type.A8kProjOptConfig; import a8k.service.db.type.A8kProjectInfo; +import a8k.service.debug.AppDebugHelperService; import a8k.type.ConsumableGroup; +import a8k.type.ConsumableOneChResult; +import a8k.type.ConsumableScanRawResult; import a8k.type.consumables.LarBSGroup; import a8k.type.consumables.LittBSGroup; import a8k.type.consumables.ReactionPlateGroup; -import a8k.type.consumables.ScanResultState; +import a8k.type.consumables.ConsumablesErrorType; import a8k.type.exception.AppException; import a8k.service.db.type.a8kidcard.zenum.A8kReactionFlowType; import a8k.service.db.type.A8kIdCardInfo; import a8k.utils.ReactionPlate2DCode; -import a8k.utils.ReactionPlate2DCodeParser; +import a8k.utils.ReactionPlate2DCodeHelper; import jakarta.annotation.Resource; import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Date; @@ -27,13 +31,15 @@ import java.util.Map; @Component public class ConsumablesScanService { - static Logger logger = org.slf4j.LoggerFactory.getLogger(ConsumablesScanService.class); + static Logger logger = org.slf4j.LoggerFactory.getLogger(ConsumablesScanService.class); + @Autowired + private AppDebugHelperService appDebugHelperService; public static class ConsumablesScanResult { - public Integer chNum; - public ScanResultState state; - public Integer projIndex; - public String lotId; + public Integer chNum; + public ConsumablesErrorType state; + public Integer projIndex; + public String lotId; } @@ -43,6 +49,8 @@ public class ConsumablesScanService { AppProjInfoMgrService appProjMgr; @Resource ConsumablesScanCtrl scanCtrlService; + @Resource + AppDebugHelperService appDebugHelper; /** * 解析扫描结果,返回耗材扫描结果 @@ -51,92 +59,111 @@ public class ConsumablesScanService { * @param rawResult 原始扫描结果 * @return 耗材扫描结果 */ - ConsumablesScanResult parseScanResult(Integer ch, ConsumablesScanCtrl.OneChResult rawResult) throws AppException { + ConsumablesScanResult parseScanResult(Integer ch, ConsumableOneChResult rawResult) throws AppException { ConsumablesScanResult ret = new ConsumablesScanResult(); ret.chNum = ch; if (rawResult.larBSScanResult == null && rawResult.littBSScanResult == null && rawResult.PBScanResult == null) { - ret.state = ScanResultState.Empty; + ret.state = ConsumablesErrorType.EMPTY; return ret; } if (rawResult.PBScanResult == null) { - ret.state = ScanResultState.LostReactionPlate; + ret.state = ConsumablesErrorType.MISS_REACTION_PLATE; return ret; } //解析板夹二维码 - ReactionPlate2DCode rp2dcode = ReactionPlate2DCodeParser.parse(rawResult.PBScanResult); - - //检查耗材是否过期 - if (rp2dcode.expDate.before(new Date())) { - ret.state = ScanResultState.ConsumableExpired; - return ret; - } + ReactionPlate2DCode rp2dcode = ReactionPlate2DCodeHelper.parse(rawResult.PBScanResult); + // //检查耗材是否过期 + // if (rp2dcode.expDate.before(new Date())) { + // ret.state = ScanResultState.EXPIRED; + // return ret; + // } //检查项目ID卡是否存在 A8kIdCardInfo a8kIdCardInfo = appProjMgr.getA8kIdCardInfoByLotId(rp2dcode.lotId); if (a8kIdCardInfo == null) { - ret.state = ScanResultState.NoMatchingProjIDCardFound; + logger.warn("未找到匹配的项目ID卡,LotID:{}", rp2dcode.lotId); + ret.state = ConsumablesErrorType.MISS_IDCARD; return ret; } - + if (a8kIdCardInfo.expiryDate.before(new Date())) { + logger.warn("耗材过期,LotID:{}", rp2dcode.lotId); + ret.state = ConsumablesErrorType.EXPIRED; + return ret; + } //检查项目信息是否存在 - A8kProjectInfo projInfo = appProjMgr.getProjInfoByProjIndex(rp2dcode.projIndex); + A8kProjectInfo projInfo = appProjMgr.getProjInfoByProjIndex(a8kIdCardInfo.projIndex); if (projInfo == null) { - ret.state = ScanResultState.UnSupportProj; + logger.error("当前项目不支持,项目ID:{}", a8kIdCardInfo.projIndex); + ret.state = ConsumablesErrorType.UN_SUPPORT_PROJ; return ret; } Integer subProjNum = projInfo.subProjNum; if (subProjNum == null || subProjNum <= 0) { - logger.error("项目信息不完整,项目ID:{},子项目数量为零", rp2dcode.projIndex); - ret.state = ScanResultState.CodeErrorProjInfoIsError; + logger.error("项目信息不完整,项目ID:{},子项目数量为零", a8kIdCardInfo.projIndex); + ret.state = ConsumablesErrorType.CODE_ERROR_PROJINFO_IS_ERROR; return ret; } - List projOptConfigList = appProjMgr.getProjOptConfigListByProjIndex(rp2dcode.projIndex); + List projOptConfigList = appProjMgr.getProjOptConfigListByProjIndex(a8kIdCardInfo.projIndex); if (projOptConfigList == null || projOptConfigList.size() != subProjNum) { - logger.error("项目操作配置信息不完整,项目ID:{},缺少光学配置", rp2dcode.projIndex); - ret.state = ScanResultState.CodeErrorProjInfoIsError; + logger.error("项目操作配置信息不完整,项目ID:{},缺少光学配置", a8kIdCardInfo.projIndex); + ret.state = ConsumablesErrorType.CODE_ERROR_PROJINFO_IS_ERROR; return ret; } //通过项目ID卡获取项目需要的耗材 - A8kReactionFlowType reactionType = appProjMgr.getA8kReactionFlowTypeByProjIndex(rp2dcode.projIndex); + A8kReactionFlowType reactionType = appProjMgr.getA8kReactionFlowTypeByProjIndex(a8kIdCardInfo.projIndex); if (reactionType == null) { - ret.state = ScanResultState.CodeErrorProjInfoIsInComplete; + ret.state = ConsumablesErrorType.CODE_ERROR_PROJINFO_IS_ERROR; return ret; } if (reactionType.equals(A8kReactionFlowType.FlowType1)) { //校验小瓶缓冲液,小瓶缓冲液+样本 if (rawResult.littBSScanResult == null) { - ret.state = ScanResultState.LostLittSB; + ret.state = ConsumablesErrorType.MISS_LITTSB; + return ret; + } + + if (!rawResult.littBSScanResult.equals(rp2dcode.lotId)) { + ret.state = ConsumablesErrorType.LITTSB_LOTID_MISMATCH; return ret; } + } else if (reactionType.equals(A8kReactionFlowType.FlowType2)) { // 校验大瓶缓冲液,大瓶缓冲液+小瓶缓冲液+样本 if (rawResult.larBSScanResult == null) { - ret.state = ScanResultState.LostLarBS; + ret.state = ConsumablesErrorType.MISS_LARBS; return ret; } + + if (!rawResult.larBSScanResult.equals(rp2dcode.lotId)) { + ret.state = ConsumablesErrorType.LARBS_LOTID_MISMATCH; + return ret; + } + + } else { throw new RuntimeException("未知的反应流程类型"); } ret.lotId = rp2dcode.lotId; - ret.projIndex = rp2dcode.projIndex; + ret.projIndex = a8kIdCardInfo.projIndex; + ret.state = ConsumablesErrorType.PASS; return ret; } void LoadingConsumables(Integer ch, ConsumablesScanResult result) { var cState = gstate.getConsumableState(); assert ch.equals(result.chNum); - if (result.state != ScanResultState.PASS) { + if (result.state != ConsumablesErrorType.PASS) { return; } @@ -169,7 +196,14 @@ public class ConsumablesScanService { } List scanResult = new java.util.ArrayList<>(); //执行扫描耗材动作 - var scanRawResult = scanCtrlService.doScanConsumablesAction(); + ConsumableScanRawResult scanRawResult; + if (appDebugHelper.isDebug()) { + scanRawResult = appDebugHelper.scanConsumable(); + } else { + scanRawResult = scanCtrlService.doScanConsumablesAction(); + } + + //解析扫描结果 for (int i = 0; i < 6; i++) { var result = parseScanResult(i, scanRawResult.ch[i]); @@ -179,7 +213,7 @@ public class ConsumablesScanService { var cState = gstate.getConsumableState(); //加载耗材 for (int i = 0; i < cState.reactionPlateGroup.length; i++) { - if (scanResult.get(i).state == ScanResultState.PASS) { + if (scanResult.get(i).state == ConsumablesErrorType.PASS) { LoadingConsumables(i, scanResult.get(i)); } } @@ -196,11 +230,15 @@ public class ConsumablesScanService { throw new AppException(A8kEcode.DeviceNotInited); } - Integer chNum = group.off; - - var scanResult = scanCtrlService.doScanOneCh(chNum); - var result = parseScanResult(chNum, scanResult); - if (result.state != ScanResultState.PASS) { + Integer chNum = group.off; + ConsumableOneChResult scanResult; + if (appDebugHelper.isDebug()) { + scanResult = appDebugHelper.scanOneCH(chNum); + } else { + scanResult = scanCtrlService.doScanOneCh(chNum); + } + var result = parseScanResult(chNum, scanResult); + if (result.state != ConsumablesErrorType.PASS) { LoadingConsumables(chNum, result); } Map ret = new java.util.HashMap<>(); diff --git a/src/main/java/a8k/service/app/appctrl/DeviceInitCtrlService.java b/src/main/java/a8k/service/app/appctrl/DeviceInitCtrlService.java index 1198782..2f4fad4 100644 --- a/src/main/java/a8k/service/app/appctrl/DeviceInitCtrlService.java +++ b/src/main/java/a8k/service/app/appctrl/DeviceInitCtrlService.java @@ -19,15 +19,6 @@ import java.util.List; @Component public class DeviceInitCtrlService { - public enum CheckPointType { - CheckTubeXChannelIsEmpty,//入料通道是否为空 - CheckPlateBoxIsCover,//板夹仓盖子是否盖着 - CheckPlateStuckDetectorSensorIsTrigger,//板夹仓卡板检测 - CheckPullerMInZeroPos,//检查拉杆电机是否在零点位置 - CheckPusherMInZeroPos,//检查推杆电机是否在零点位置 - CheckRecycleBinIsOverflow,//检查垃圾箱是否满 - } - @Resource ActionReactorService ar; @@ -45,17 +36,17 @@ public class DeviceInitCtrlService { @PostConstruct void init() { checkPoints.add(new Checkpoint("入料通道是否为空",// - CheckPointType.CheckPlateBoxIsCover, () -> !canBus.getIOState(IOId.THChInterPPS) && !canBus.getIOState(IOId.THChOuterPPS))); + CheckPointType.CHECK_PLATE_BOX_IS_COVER, () -> !canBus.getIOState(IOId.THChInterPPS) && !canBus.getIOState(IOId.THChOuterPPS))); checkPoints.add(new Checkpoint("板夹仓盖子是否盖着",// - CheckPointType.CheckPlateBoxIsCover, () -> canBus.getIOState(IOId.PlateBoxCoverClosurePPS))); + CheckPointType.CHECK_PLATE_BOX_IS_COVER, () -> canBus.getIOState(IOId.PlateBoxCoverClosurePPS))); checkPoints.add(new Checkpoint("板夹仓卡板检测",// - CheckPointType.CheckPlateStuckDetectorSensorIsTrigger, () -> !canBus.getIOState(IOId.PlateBoxPlateStuckPPS))); + CheckPointType.CHECK_PLATE_STUCK_DETECTOR_SENSOR_IS_TRIGGER, () -> !canBus.getIOState(IOId.PlateBoxPlateStuckPPS))); checkPoints.add(new Checkpoint("检查拉杆电机是否在零点位置",// - CheckPointType.CheckPullerMInZeroPos, () -> canBus.getIOState(IOId.PullerMZeroPPS))); + CheckPointType.CHECK_PULLERM_IS_IN_ZEROPOS, () -> canBus.getIOState(IOId.PullerMZeroPPS))); checkPoints.add(new Checkpoint("检查推杆电机是否在零点位置",// - CheckPointType.CheckPusherMInZeroPos, () -> canBus.getIOState(IOId.PusherMZeroPPS))); + CheckPointType.CHECK_PUSHERM_IN_IN_ZEROPOS, () -> canBus.getIOState(IOId.PusherMZeroPPS))); checkPoints.add(new Checkpoint("检查垃圾箱是否满",// - CheckPointType.CheckRecycleBinIsOverflow, () -> !canBus.getIOState(IOId.RecycleBinOverflowPPS))); + CheckPointType.CHECK_RECYCLE_BIN_IS_OVERFLOW, () -> !canBus.getIOState(IOId.RecycleBinOverflowPPS))); } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java index 244de68..d7ae85a 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java @@ -9,6 +9,8 @@ import a8k.service.app.appstate.type.Tube; import a8k.service.app.appstate.type.state.A8kWorkState; import a8k.service.app.appstate.type.state.TubeHolderState; import a8k.service.app.appstate.type.state.TubeState; +import a8k.service.debug.AppDebugHelperService; +import freemarker.debug.impl.DebuggerService; import jakarta.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,11 +33,15 @@ public class CondtionMgrService { @Resource OptScanModuleStateMgrService optScanModuleStateMgrService; + @Resource + AppDebugHelperService appDebugHelper; + Boolean getTubeholderEnterPosPPS() { //入料通道是否为空 + try { return canBus.getIOState(IOId.InfeedPPS); } catch (Exception e) { - logger.error("getTubeholderEnterPosPPS error", e); + logger.error("getTubeholderEnterPosPPS error", e); return false; } } diff --git a/src/main/java/a8k/service/app/devicedriver/ctrl/ConsumablesScanCtrl.java b/src/main/java/a8k/service/app/devicedriver/ctrl/ConsumablesScanCtrl.java index 26fbde5..6f32ea0 100644 --- a/src/main/java/a8k/service/app/devicedriver/ctrl/ConsumablesScanCtrl.java +++ b/src/main/java/a8k/service/app/devicedriver/ctrl/ConsumablesScanCtrl.java @@ -7,6 +7,8 @@ import a8k.extapi_controler.utils.ExtApiTab; import a8k.hardware.type.a8kcanprotocol.A8kEcode; import a8k.service.app.appstate.GStateService; import a8k.service.app.devicedriver.param.Hbot2DCodeScanPos; +import a8k.type.ConsumableOneChResult; +import a8k.type.ConsumableScanRawResult; import a8k.type.cfg.Pos2d; import a8k.type.exception.AppException; import jakarta.annotation.Resource; @@ -16,28 +18,6 @@ import org.springframework.stereotype.Component; @ExtApiTab(cfg = ExtApiTabConfig.HbotControlService) public class ConsumablesScanCtrl { - public static class ScanRawResult { - public OneChResult[] ch = new OneChResult[6]; - - public ScanRawResult() { - for (int i = 0; i < 6; i++) { - ch[i] = new OneChResult(i); - } - } - } - - public static class OneChResult { - - public Integer chNum; - public String PBScanResult = ""; - public String littBSScanResult = ""; - public String larBSScanResult = ""; - - OneChResult(int chNum) { - this.chNum = chNum; - } - } - @Resource ActionReactorService ar; @@ -82,11 +62,11 @@ public class ConsumablesScanCtrl { @ExtApiFn(name = "扫描耗材") - public ScanRawResult doScanConsumablesAction() throws AppException { + public ConsumableScanRawResult doScanConsumablesAction() throws AppException { if (!stateMgrService.isDeviceInited()) { throw new AppException(A8kEcode.DeviceNotInited); } - ScanRawResult result = new ScanRawResult(); + ConsumableScanRawResult result = new ConsumableScanRawResult(); for (int i = 0; i < 6; i++) { int finalI = i; ar.dosome("扫描耗材-板夹0", () -> result.ch[finalI].PBScanResult = scanPB(finalI)); @@ -119,8 +99,8 @@ public class ConsumablesScanCtrl { } @ExtApiFn(name = "扫描单个耗材") - public OneChResult doScanOneCh(Integer ch) throws AppException { - OneChResult result = new OneChResult(ch); + public ConsumableOneChResult doScanOneCh(Integer ch) throws AppException { + ConsumableOneChResult result = new ConsumableOneChResult(ch); ar.dosome("扫描耗材-板夹0", () -> result.PBScanResult = scanPB(ch)); ar.dosome("扫描耗材-小瓶缓冲液", () -> result.littBSScanResult = scanLittBS(ch)); ar.dosome("扫描耗材-大瓶缓冲液", () -> result.larBSScanResult = scanLarBS(ch)); diff --git a/src/main/java/a8k/service/db/A8kProjInfoDBService.java b/src/main/java/a8k/service/db/A8kProjInfoDBService.java index 62c92c2..b182a8c 100644 --- a/src/main/java/a8k/service/db/A8kProjInfoDBService.java +++ b/src/main/java/a8k/service/db/A8kProjInfoDBService.java @@ -34,6 +34,9 @@ public class A8kProjInfoDBService { @Resource UtilsProjectColorAllocer utilsProjectColorAllocer; + @Resource + A8kProjOptConfigDBService a8kProjOptConfigDBService; + @PostConstruct void init() { @@ -46,6 +49,7 @@ public class A8kProjInfoDBService { for (A8kProjectInfo pi : pilist) { add(pi); } +// a8kProjOptConfigDBService.add(); } else { if (!ZSqliteJdbcHelper.isTableExist(jdbcTemplate, tableName)) { ZSqliteJdbcHelper.createTable(jdbcTemplate, tableName, tClass); diff --git a/src/main/java/a8k/service/db/A8kProjOptConfigDBService.java b/src/main/java/a8k/service/db/A8kProjOptConfigDBService.java index 0de5af7..b8ea3fd 100644 --- a/src/main/java/a8k/service/db/A8kProjOptConfigDBService.java +++ b/src/main/java/a8k/service/db/A8kProjOptConfigDBService.java @@ -2,7 +2,9 @@ package a8k.service.db; import a8k.service.app.appdata.UtilsProjectColorAllocer; import a8k.service.db.type.A8kProjOptConfig; +import a8k.service.debug.AppDebugHelperService; import a8k.utils.ZSqliteJdbcHelper; +import freemarker.debug.impl.DebuggerService; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import lombok.SneakyThrows; @@ -27,8 +29,19 @@ public class A8kProjOptConfigDBService { @Resource UtilsProjectColorAllocer colorAllocer; + @Resource + AppDebugHelperService appDebugHelper; + @PostConstruct void init() { + if (appDebugHelper.isDebug()) { + ZSqliteJdbcHelper.deleteTable(jdbcTemplate, tableName); + ZSqliteJdbcHelper.createTable(jdbcTemplate, tableName, tClass); + for (A8kProjOptConfig a8kProjOptConfig : appDebugHelper.getMockProjOptConfigList()) { + ZSqliteJdbcHelper.addObj(jdbcTemplate, tableName, tClass, a8kProjOptConfig); + } + } + if (!ZSqliteJdbcHelper.isTableExist(jdbcTemplate, tableName)) { ZSqliteJdbcHelper.createTable(jdbcTemplate, tableName, tClass); } diff --git a/src/main/java/a8k/service/debug/AppDebugHelperService.java b/src/main/java/a8k/service/debug/AppDebugHelperService.java index a2d3ade..b5f96a9 100644 --- a/src/main/java/a8k/service/debug/AppDebugHelperService.java +++ b/src/main/java/a8k/service/debug/AppDebugHelperService.java @@ -1,18 +1,33 @@ package a8k.service.debug; +import a8k.SpringBootBeanUtil; import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; import a8k.extapi_controler.utils.ExtApiFn; import a8k.extapi_controler.utils.ExtApiTab; +import a8k.service.app.appctrl.CheckPointType; import a8k.service.bases.AppEventBusService; import a8k.service.bases.appevent.A8kHardwareReport; +import a8k.service.db.A8kProjIdCardDBService; +import a8k.service.db.A8kProjInfoDBService; import a8k.service.db.type.A8kIdCardInfo; +import a8k.service.db.type.A8kProjOptConfig; import a8k.service.db.type.A8kProjectInfo; import a8k.service.debug.fakeprojinfo.*; +import a8k.type.ConsumableGroup; +import a8k.type.ConsumableOneChResult; +import a8k.type.ConsumableScanRawResult; +import a8k.type.checkpoint.CheckResult; +import a8k.type.checkpoint.Checkpoint; +import a8k.type.consumables.ConsumablesErrorType; +import a8k.type.exception.AppException; import a8k.utils.A8kPacketBuilder; +import a8k.utils.ReactionPlate2DCodeHelper; +import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import org.springframework.stereotype.Component; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; @Component @@ -38,6 +53,16 @@ public class AppDebugHelperService { FakeProjInfo mountIdcard; + String[] consumables = new String[6]; + ConsumablesErrorType[] consumablesErrorType = new ConsumablesErrorType[6]; + + + @PostConstruct + void init() { + Arrays.fill(consumables, ""); + Arrays.fill(consumablesErrorType, ConsumablesErrorType.PASS); + } + public Boolean isDebug() { return debugFlag; @@ -47,7 +72,7 @@ public class AppDebugHelperService { // 模拟用户行为 // - @ExtApiFn(name = "插入ID卡", group = "A8KID卡模式", order = 1) + @ExtApiFn(name = "插入ID卡", group = "A8KID卡.操作模拟", order = 1) public void insertVirtualIDCard(A8kVirtualProjIDCard idcard) { if (idcard == A8kVirtualProjIDCard.P01_hsCRR) { mountIdcard = p01_hscrr; @@ -65,13 +90,67 @@ public class AppDebugHelperService { eventBus.pushEvent(new A8kHardwareReport(A8kPacketBuilder.build_event_a8000_idcard_online())); } - @ExtApiFn(name = "移除ID卡", group = "A8KID卡模式", order = 2) + @ExtApiFn(name = "移除ID卡", group = "A8KID卡.操作模拟", order = 2) public void removeVirtualIDCard() { mountIdcard = null; eventBus.pushEvent(new A8kHardwareReport(A8kPacketBuilder.build_event_a8000_idcard_offline())); } + @ExtApiFn(name = "保存所有ID信息到数据库中", group = "A8KID卡.操作模拟", order = 3) + public void saveAllIDCard() { + A8kProjIdCardDBService service = SpringBootBeanUtil.getBean(A8kProjIdCardDBService.class); + service.addIdCard(p01_hscrr.buildA8kIDCardInfo()); + service.addIdCard(p02_pct.buildA8kIDCardInfo()); + service.addIdCard(p03_tsh.buildA8kIDCardInfo()); + service.addIdCard(p05_t3.buildA8kIDCardInfo()); + service.addIdCard(p06_t4.buildA8kIDCardInfo()); + service.addIdCard(p22_pctAndHsCRP.buildA8kIDCardInfo()); + } + + // public Boolean isHasVirtualTube + + + @ExtApiFn(name = "插入一个通道耗材", group = "A8K耗材.操作模拟", order = 1) + public void putConsumableToCH(ConsumableGroup ch, A8kVirtualProjIDCard proj, ConsumablesErrorType errorType) { + consumablesErrorType[ch.off] = errorType; + if (proj == A8kVirtualProjIDCard.P01_hsCRR) { + consumables[ch.off] = p01_hscrr.lotId; + } else if (proj == A8kVirtualProjIDCard.P02_PCT) { + consumables[ch.off] = p02_pct.lotId; + } else if (proj == A8kVirtualProjIDCard.P03_TSH) { + consumables[ch.off] = p03_tsh.lotId; + } else if (proj == A8kVirtualProjIDCard.P05_T3) { + consumables[ch.off] = p05_t3.lotId; + } else if (proj == A8kVirtualProjIDCard.P06_T4) { + consumables[ch.off] = p06_t4.lotId; + } else if (proj == A8kVirtualProjIDCard.P22_PCTAndHsCRP) { + consumables[ch.off] = p22_pctAndHsCRP.lotId; + } + } + + @ExtApiFn(name = "插入六组正确的耗材", group = "A8K耗材.操作模拟", order = 2) + public void putRightConsumable() { + putConsumableToCH(ConsumableGroup.GROUP1, A8kVirtualProjIDCard.P01_hsCRR, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP2, A8kVirtualProjIDCard.P02_PCT, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP3, A8kVirtualProjIDCard.P03_TSH, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP4, A8kVirtualProjIDCard.P05_T3, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP5, A8kVirtualProjIDCard.P06_T4, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP6, A8kVirtualProjIDCard.P22_PCTAndHsCRP, ConsumablesErrorType.PASS); + } + + + @ExtApiFn(name = "移除一个通道耗材", group = "A8K耗材.操作模拟", order = 3) + public void removeConsumableFromCH(ConsumableGroup ch) { + consumables[ch.off] = ""; + } + + @ExtApiFn(name = "移除所有耗材", group = "A8K耗材.操作模拟", order = 4) + public void removeAllConsumable() { + Arrays.fill(consumables, ""); + } + + //InterUse public Boolean getVirtualIDCard() { return mountIdcard != null; } @@ -95,4 +174,92 @@ public class AppDebugHelperService { return projInfoList; } + public List getMockProjOptConfigList() { + List projOptConfigList = new ArrayList<>(); + projOptConfigList.addAll(p01_hscrr.buildA8kProjOptConfigList()); + projOptConfigList.addAll(p02_pct.buildA8kProjOptConfigList()); + projOptConfigList.addAll(p03_tsh.buildA8kProjOptConfigList()); + projOptConfigList.addAll(p05_t3.buildA8kProjOptConfigList()); + projOptConfigList.addAll(p06_t4.buildA8kProjOptConfigList()); + projOptConfigList.addAll(p22_pctAndHsCRP.buildA8kProjOptConfigList()); + return projOptConfigList; + } + + + public ConsumableOneChResult scanOneCH(Integer ch) { + ConsumableOneChResult result = new ConsumableOneChResult(ch); + switch (consumablesErrorType[ch]) { + case PASS: //通过 + result.larBSScanResult = consumables[ch]; + result.littBSScanResult = consumables[ch]; + result.PBScanResult = ReactionPlate2DCodeHelper.build2DCode(consumables[ch]); + return result; + case EMPTY://空 + return result; + case EXPIRED: //耗材过期 + result.larBSScanResult = consumables[ch]; + result.littBSScanResult = consumables[ch]; + result.PBScanResult = ReactionPlate2DCodeHelper.build2DCode(consumables[ch]); + return result; + case MISS_REACTION_PLATE: //没有反应板夹 + result.larBSScanResult = consumables[ch]; + result.littBSScanResult = consumables[ch]; + return result; + case MISS_LITTSB: //缺少小缓冲液 + result.PBScanResult = ReactionPlate2DCodeHelper.build2DCode(consumables[ch]); + return result; + case MISS_LARBS: //缺少大缓冲液 + result.PBScanResult = ReactionPlate2DCodeHelper.build2DCode(consumables[ch]); + return result; + case MISS_IDCARD://未找到匹配的项目ID卡 + result.PBScanResult = ReactionPlate2DCodeHelper.build2DCode("EEEEEEEE"); + return result; + case LITTSB_LOTID_MISMATCH://小缓冲液批号不匹配 + result.larBSScanResult = "EEEEEE"; + result.littBSScanResult = "EEEEEE"; + result.PBScanResult = ReactionPlate2DCodeHelper.build2DCode(consumables[ch]); + return result; + case LARBS_LOTID_MISMATCH://大缓冲液批号不匹配 + result.larBSScanResult = "EEEEEE"; + result.littBSScanResult = "EEEEEE"; + result.PBScanResult = ReactionPlate2DCodeHelper.build2DCode(consumables[ch]); + return result; + case CODE_ERROR_PROJINFO_IS_ERROR://代码错误,项目信息异常 + return result; + case UN_SUPPORT_PROJ://不支持的项目 + return result; + } + return result; + } + + public ConsumableScanRawResult scanConsumable() { + ConsumableScanRawResult result = new ConsumableScanRawResult(); + for (int i = 0; i < 6; i++) { + result.ch[i] = (scanOneCH(i)); + } + return result; + } + + + public List checkBeforeInitDevice() throws AppException { + List checkPoints = new ArrayList<>(); + List resultss = new java.util.ArrayList<>(); + + checkPoints.add(new Checkpoint("入料通道是否为空", CheckPointType.CHECK_PLATE_BOX_IS_COVER, () -> true)); + checkPoints.add(new Checkpoint("板夹仓盖子是否盖着", CheckPointType.CHECK_PLATE_BOX_IS_COVER, () -> true)); + checkPoints.add(new Checkpoint("板夹仓卡板检测", CheckPointType.CHECK_PLATE_STUCK_DETECTOR_SENSOR_IS_TRIGGER, () -> true)); + checkPoints.add(new Checkpoint("检查拉杆电机是否在零点位置", CheckPointType.CHECK_PULLERM_IS_IN_ZEROPOS, () -> true)); + checkPoints.add(new Checkpoint("检查推杆电机是否在零点位置", CheckPointType.CHECK_PUSHERM_IN_IN_ZEROPOS, () -> true)); + checkPoints.add(new Checkpoint("检查垃圾箱是否满", CheckPointType.CHECK_RECYCLE_BIN_IS_OVERFLOW, () -> true)); + + + for (Checkpoint checkPoint : checkPoints) { + CheckResult result = new CheckResult(); + result.type = checkPoint.type; + result.typechinfo = checkPoint.typechinfo; + result.pass = checkPoint.checkfn.check(); + resultss.add(result); + } + return resultss; + } } diff --git a/src/main/java/a8k/service/debug/FakeTubeHolder.java b/src/main/java/a8k/service/debug/FakeTubeHolder.java new file mode 100644 index 0000000..b1b0806 --- /dev/null +++ b/src/main/java/a8k/service/debug/FakeTubeHolder.java @@ -0,0 +1,8 @@ +package a8k.service.debug; + +import a8k.service.app.appstate.type.TubeHolder; + +public class FakeTubeHolder { + + TubeHolder tubeHolder = new TubeHolder(); +} diff --git a/src/main/java/a8k/service/debug/fakeprojinfo/FakeProjInfo.java b/src/main/java/a8k/service/debug/fakeprojinfo/FakeProjInfo.java index 8a7ab82..48e9759 100644 --- a/src/main/java/a8k/service/debug/fakeprojinfo/FakeProjInfo.java +++ b/src/main/java/a8k/service/debug/fakeprojinfo/FakeProjInfo.java @@ -18,22 +18,22 @@ import java.util.List; public class FakeProjInfo { - String projName = "FakeProjInfo"; - String lotId = "FakeProjInfo"; - Integer projIndex = 1; - Integer updateChipVersion = 5; - Integer subProjNum = 1; - String projShortName = "CA"; - Integer reactionTemperature = 25; - String color; - A8kReactionFlowType reactionFlowType = A8kReactionFlowType.FlowType1; - Integer wBloodSampleVolUl = 10; - Integer serumSampleVolUl = 10; - Integer shakeTimes = 5; - Integer bigBufferSampleUl = 0; - Integer mixLiquidAspirMixingCnt = 3; - Integer reactionPlateIncubationTimeMin = 3; - Integer reactionPlateDropletVolUl = 75; + public String projName = "FakeProjInfo"; + public String lotId = "FakeProjInfo"; + public Integer projIndex = 1; + public Integer updateChipVersion = 5; + public Integer subProjNum = 1; + public String projShortName = "CA"; + public Integer reactionTemperature = 25; + public String color; + public A8kReactionFlowType reactionFlowType = A8kReactionFlowType.FlowType1; + public Integer wBloodSampleVolUl = 10; + public Integer serumSampleVolUl = 10; + public Integer shakeTimes = 5; + public Integer bigBufferSampleUl = 0; + public Integer mixLiquidAspirMixingCnt = 3; + public Integer reactionPlateIncubationTimeMin = 3; + public Integer reactionPlateDropletVolUl = 75; public A8kIdCardInfo buildA8kIDCardInfo() { diff --git a/src/main/java/a8k/type/ConsumableOneChResult.java b/src/main/java/a8k/type/ConsumableOneChResult.java new file mode 100644 index 0000000..f1c8f67 --- /dev/null +++ b/src/main/java/a8k/type/ConsumableOneChResult.java @@ -0,0 +1,13 @@ +package a8k.type; + +public class ConsumableOneChResult { + + public Integer chNum; + public String PBScanResult = ""; + public String littBSScanResult = ""; + public String larBSScanResult = ""; + + public ConsumableOneChResult(int chNum) { + this.chNum = chNum; + } +} diff --git a/src/main/java/a8k/type/ConsumableScanRawResult.java b/src/main/java/a8k/type/ConsumableScanRawResult.java new file mode 100644 index 0000000..ce43d5d --- /dev/null +++ b/src/main/java/a8k/type/ConsumableScanRawResult.java @@ -0,0 +1,11 @@ +package a8k.type; + +public class ConsumableScanRawResult { + public ConsumableOneChResult[] ch = new ConsumableOneChResult[6]; + + public ConsumableScanRawResult() { + for (int i = 0; i < 6; i++) { + ch[i] = new ConsumableOneChResult(i); + } + } +} diff --git a/src/main/java/a8k/type/consumables/ConsumablesErrorType.java b/src/main/java/a8k/type/consumables/ConsumablesErrorType.java new file mode 100644 index 0000000..bbbfb4d --- /dev/null +++ b/src/main/java/a8k/type/consumables/ConsumablesErrorType.java @@ -0,0 +1,18 @@ +package a8k.type.consumables; + +public enum ConsumablesErrorType { + PASS, //通过 + EMPTY,//空 + EXPIRED, //耗材过期 + + MISS_REACTION_PLATE, //没有反应板夹 + MISS_LITTSB, //缺少小缓冲液 + MISS_LARBS, //缺少大缓冲液 + MISS_IDCARD,//未找到匹配的项目ID卡 + + LITTSB_LOTID_MISMATCH,//小缓冲液批号不匹配 + LARBS_LOTID_MISMATCH,//大缓冲液批号不匹配 + + CODE_ERROR_PROJINFO_IS_ERROR,//代码错误,项目信息异常 + UN_SUPPORT_PROJ,//不支持的项目 +} diff --git a/src/main/java/a8k/type/consumables/ScanResultState.java b/src/main/java/a8k/type/consumables/ScanResultState.java deleted file mode 100644 index 207201d..0000000 --- a/src/main/java/a8k/type/consumables/ScanResultState.java +++ /dev/null @@ -1,20 +0,0 @@ -package a8k.type.consumables; - -public enum ScanResultState { - PASS, //通过 - Empty,//空 - - LostReactionPlate, //丢弃反应板 - ConsumableExpired, //耗材过期 - - LostLittSB, //缺少小缓冲液 - LittSBLotIdIsNotMatch,//小缓冲液批号不匹配 - LostLarBS, //缺少大缓冲液 - LarBSLotIdIsNotMatch,//大缓冲液批号不匹配 - - NoMatchingProjIDCardFound,//未找到匹配的项目ID卡 - IDCardProjInfoIsNotCompleted,//ID卡信息缺失 - CodeErrorProjInfoIsInComplete,//项目信息不全 - CodeErrorProjInfoIsError,//项目信息不全 - UnSupportProj,//不支持的项目 -} diff --git a/src/main/java/a8k/utils/ReactionPlate2DCode.java b/src/main/java/a8k/utils/ReactionPlate2DCode.java index 3c04811..d9c4eec 100644 --- a/src/main/java/a8k/utils/ReactionPlate2DCode.java +++ b/src/main/java/a8k/utils/ReactionPlate2DCode.java @@ -3,9 +3,9 @@ package a8k.utils; import java.util.Date; public class ReactionPlate2DCode { - public Integer projIndex; - public String lotId; - public Date expDate; - public Integer ID0 = 0; - public Integer ID1 = 0; + Integer projIndex; + public String lotId; + Date expDate; + Integer ID0 = 0; + Integer ID1 = 0; } diff --git a/src/main/java/a8k/utils/ReactionPlate2DCodeHelper.java b/src/main/java/a8k/utils/ReactionPlate2DCodeHelper.java new file mode 100644 index 0000000..633a70d --- /dev/null +++ b/src/main/java/a8k/utils/ReactionPlate2DCodeHelper.java @@ -0,0 +1,41 @@ +package a8k.utils; + +import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.type.exception.AppException; + +import java.text.ParseException; +import java.text.SimpleDateFormat; + +public class ReactionPlate2DCodeHelper { + // 1||CAGGB66U||2024.03.26||1083||06 + static public ReactionPlate2DCode parse(String code) throws AppException { + String[] parts = code.split("\\|\\|"); + ReactionPlate2DCode ret = new ReactionPlate2DCode(); + if (parts.length != 5) { + throw new AppException(A8kEcode.A8kPlate2DCodeFormatError); + } + ret.projIndex = Integer.parseInt(parts[0]); + ret.lotId = parts[1]; + // 2024.03.26 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd"); + try { + ret.expDate = sdf.parse(parts[2]); + } catch (ParseException e) { + throw new AppException(A8kEcode.A8kPlate2DCodeFormatError); + } + ret.ID0 = Integer.parseInt(parts[3]); + ret.ID1 = Integer.parseInt(parts[4]); + return ret; + } + + public static String build2DCode(ReactionPlate2DCode code) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd"); + return code.projIndex + "||" + code.lotId + "||" + sdf.format(code.expDate) + "||" + code.ID0 + "||" + code.ID1; + } + + public static String build2DCode(String lotid) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd"); + return "1||" + lotid + "||" + sdf.format(new java.util.Date()) + "||" + 0 + "||" + 0; + } + +} diff --git a/src/main/java/a8k/utils/ReactionPlate2DCodeParser.java b/src/main/java/a8k/utils/ReactionPlate2DCodeParser.java deleted file mode 100644 index 3cc5350..0000000 --- a/src/main/java/a8k/utils/ReactionPlate2DCodeParser.java +++ /dev/null @@ -1,32 +0,0 @@ -package a8k.utils; - -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.type.exception.AppException; - -import java.text.ParseException; -import java.text.SimpleDateFormat; - -public class ReactionPlate2DCodeParser { - // 1||CAGGB66U||2024.03.26||1083||06 - static public ReactionPlate2DCode parse(String code) throws AppException { - String[] parts = code.split("\\|\\|"); - ReactionPlate2DCode ret = new ReactionPlate2DCode(); - if (parts.length != 5) { - throw new AppException(A8kEcode.A8kPlate2DCodeFormatError); - } - ret.projIndex = Integer.parseInt(parts[0]); - ret.lotId = parts[1]; - // 2024.03.26 - SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd"); - try { - ret.expDate = sdf.parse(parts[2]); - } catch (ParseException e) { - throw new AppException(A8kEcode.A8kPlate2DCodeFormatError); - } - ret.ID0 = Integer.parseInt(parts[3]); - ret.ID1 = Integer.parseInt(parts[4]); - return ret; - } - - -}