diff --git a/appresource/db/appbak.db b/appresource/db/appbak.db new file mode 100644 index 0000000..a58e652 Binary files /dev/null and b/appresource/db/appbak.db differ diff --git a/src/main/java/a8k/BoditechA800Application.java b/src/main/java/a8k/BoditechA800Application.java index aea0cc4..57f9366 100644 --- a/src/main/java/a8k/BoditechA800Application.java +++ b/src/main/java/a8k/BoditechA800Application.java @@ -1,7 +1,10 @@ package a8k; +import a8k.app.service.background.AppEventBusService; import a8k.app.type.DeviceRunMode; +import a8k.app.type.appevent.AppEvent; +import a8k.app.type.appevent.SpringbootLoadingCompletedEvent; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; @@ -20,6 +23,7 @@ public class BoditechA800Application implements ApplicationListener actionOvertime) { diff --git a/src/main/java/a8k/app/iflytophald/type/protocol/RegIndex.java b/src/main/java/a8k/app/iflytophald/type/protocol/RegIndex.java index 5ce484b..86b549b 100644 --- a/src/main/java/a8k/app/iflytophald/type/protocol/RegIndex.java +++ b/src/main/java/a8k/app/iflytophald/type/protocol/RegIndex.java @@ -195,6 +195,8 @@ public enum RegIndex { kreg_step_motor_is_enable(10102), // 是否使能 kreg_step_motor_dpos(10103), // 执行完上一条指令后的相对位移 kreg_step_motor_has_move_zero(10104), // 是否回零 + kreg_step_motor_lost_step(10105), // 丢失步数 + // kreg_step_motor_shift(10150), // x偏移 kreg_step_motor_shaft(10151), // x轴是否反转 kreg_step_motor_one_circle_pulse(10152), // x轴一圈脉冲数 diff --git a/src/main/java/a8k/app/iflytophald/type/protocol/StepMotorRegIndex.java b/src/main/java/a8k/app/iflytophald/type/protocol/StepMotorRegIndex.java index 9dac8d4..b5d923e 100644 --- a/src/main/java/a8k/app/iflytophald/type/protocol/StepMotorRegIndex.java +++ b/src/main/java/a8k/app/iflytophald/type/protocol/StepMotorRegIndex.java @@ -8,6 +8,7 @@ public enum StepMotorRegIndex { kreg_step_motor_is_enable(RegIndex.kreg_step_motor_is_enable), // 是否使能 kreg_step_motor_dpos(RegIndex.kreg_step_motor_dpos), // 执行完上一条指令后的相对位移 kreg_step_motor_has_move_zero(RegIndex.kreg_step_motor_has_move_zero), // 是否已经移动到零点 + kreg_step_motor_lost_step(RegIndex.kreg_step_motor_lost_step), // 是否已经移动到零点 // kreg_step_motor_shift(RegIndex.kreg_step_motor_shift), // x偏移 kreg_step_motor_shaft(RegIndex.kreg_step_motor_shaft), // x轴是否反转 kreg_step_motor_one_circle_pulse(RegIndex.kreg_step_motor_one_circle_pulse), // x轴一圈脉冲数 diff --git a/src/main/java/a8k/app/service/background/ProjIDCardCtrlAndMonitorService.java b/src/main/java/a8k/app/service/background/ProjIDCardCtrlAndMonitorService.java index 91be467..3a9867a 100644 --- a/src/main/java/a8k/app/service/background/ProjIDCardCtrlAndMonitorService.java +++ b/src/main/java/a8k/app/service/background/ProjIDCardCtrlAndMonitorService.java @@ -18,6 +18,7 @@ import a8k.app.utils.ZWorkQueue; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.stereotype.Component; /** @@ -28,6 +29,7 @@ import org.springframework.stereotype.Component; @Component @Slf4j @RequiredArgsConstructor +@EnableScheduling public class ProjIDCardCtrlAndMonitorService { private final A8kCanBusBaseDriver canBus; @@ -83,21 +85,21 @@ public class ProjIDCardCtrlAndMonitorService { CmdId cmdId = CmdId.valueOf(packet.getCmdId()); if (CmdId.event_a8000_idcard_online.equals(cmdId)) { log.info("插入ID卡"); - workQueue.addTask(this::readIDCard); + workQueue.addTask(() -> this.readIDCard(true)); } else if (CmdId.event_a8000_idcard_offline.equals(cmdId)) { this.mountedIdCardInfo = null; eventBus.pushEvent(new AppIDCardUnmountEvent()); log.info("拔出ID卡"); } - } else if (event instanceof AppDeviceInitSucEvent appDeviceInitializeSuc) { - // if (idCardStatus()) { - // log.info("ID卡读卡器在线"); - // workQueue.addTask(this::readIDCard); - // } + } else if (event instanceof SpringbootLoadingCompletedEvent) { + if (idCardStatus()) { + log.info("ID卡读卡器在线"); + workQueue.addTask(() -> this.readIDCard(false)); + } } } - private void readIDCard() { + private void readIDCard(boolean pushMountEvent) { //读取ID卡信息 byte[] data = null; try { @@ -113,7 +115,8 @@ public class ProjIDCardCtrlAndMonitorService { mountedIdCardInfo = idCardDataParseService.parseAndCheck(data); ProjBuildInInfo buildinInfo = projInfoMgrService.getProjBuildInInfo(mountedIdCardInfo.projId); mountedIdCardInfo.color = buildinInfo.color; - eventBus.pushEvent(new AppIDCardMountEvent(mountedIdCardInfo)); + if (pushMountEvent) + eventBus.pushEvent(new AppIDCardMountEvent(mountedIdCardInfo)); } catch (AppException e) { diff --git a/src/main/java/a8k/app/service/background/TemperatureCtrlService.java b/src/main/java/a8k/app/service/background/TemperatureCtrlService.java index eb8729d..047d5fb 100644 --- a/src/main/java/a8k/app/service/background/TemperatureCtrlService.java +++ b/src/main/java/a8k/app/service/background/TemperatureCtrlService.java @@ -4,6 +4,8 @@ package a8k.app.service.background; import a8k.app.iflytophald.driver.WaterTemperatureControllerDriver; import a8k.app.iflytophald.type.protocol.TemperatureControlerMid; import a8k.app.service.setting.AppSettingsMgrService; +import a8k.app.service.statemgr.GStateMgrService; +import a8k.app.type.DeviceRunMode; import a8k.app.type.exception.AppException; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; @@ -18,6 +20,7 @@ public class TemperatureCtrlService { private final WaterTemperatureControllerDriver waterTemperatureControllerDriver; private final AppSettingsMgrService appSettingsMgrService; + private final GStateMgrService gStateMgrService; @Value("${a8k.enableTemperatureCtrl}") Boolean enableTemperatureCtrl = true; @@ -32,6 +35,9 @@ public class TemperatureCtrlService { if (!enableTemperatureCtrl) { return; } + if (!gStateMgrService.isInMode(DeviceRunMode.RealMode)) { + return; + } workingFlag = true; var deviceSetting = appSettingsMgrService.getDeviceSetting(); waterTemperatureControllerDriver.startHearting(TemperatureControlerMid.IncubatorTCM, deviceSetting.getIncubateBoxTemperature().doubleValue()); diff --git a/src/main/java/a8k/app/service/background/TemperatureSyncService.java b/src/main/java/a8k/app/service/background/TemperatureSyncService.java index c0b031c..cce7701 100644 --- a/src/main/java/a8k/app/service/background/TemperatureSyncService.java +++ b/src/main/java/a8k/app/service/background/TemperatureSyncService.java @@ -14,6 +14,7 @@ import a8k.app.service.statemgr.OptScanModuleStateMgr; import a8k.app.type.AppFlagKey; import a8k.app.type.DeviceRunMode; import a8k.app.type.TemperatureRecordPoint; +import a8k.app.type.TemperatureState; import a8k.app.type.error.AppError; import a8k.app.type.exception.AppException; import jakarta.annotation.PostConstruct; @@ -102,36 +103,46 @@ public class TemperatureSyncService { } if (!gStateMgrService.isInMode(DeviceRunMode.RealMode)) { + double pbtempTarget = (double) appSettingsMgrService.getDeviceSetting().getPlateBoxTemperature(); + double incubateBoxTempTarget = (double) appSettingsMgrService.getDeviceSetting().getIncubateBoxTemperature(); + + gStateMgrService.updateIncubateBoxTemperature((int) incubateBoxTempTarget, TemperatureState.Ready); + gStateMgrService.updatePboxTemperature((int) pbtempTarget, TemperatureState.Ready); + return; } try { Double incubateBoxTemp = waterTemperatureControllerDriver.readTemperature(TemperatureControlerMid.IncubatorTCM); double incubateBoxTempTarget = (double) appSettingsMgrService.getDeviceSetting().getIncubateBoxTemperature(); - gStateMgrService.updateIncubateBoxTemperature((int) (incubateBoxTemp + 0.5), isTempReady(incubateBoxTemp, incubateBoxTempTarget)); + gStateMgrService.updateIncubateBoxTemperature((int) (incubateBoxTemp + 0.5), getTempState(incubateBoxTemp, incubateBoxTempTarget)); addIncubateBoxTemperatureCurve(incubateBoxTemp); } catch (AppException e) { addIncubateBoxTemperatureCurve(0.0); - gStateMgrService.updateIncubateBoxTemperature(0, false); + gStateMgrService.updateIncubateBoxTemperature(0, TemperatureState.Low); log.warn("Failed to read incubate box temperature: {}", e.getMessage()); } try { Double pbtemp = waterTemperatureControllerDriver.readTemperature(TemperatureControlerMid.PlatesBoxTCM); double pbtempTarget = (double) appSettingsMgrService.getDeviceSetting().getPlateBoxTemperature(); - gStateMgrService.updatePboxTemperature((int) (pbtemp + 0.5), isTempReady(pbtemp, pbtempTarget)); + gStateMgrService.updatePboxTemperature((int) (pbtemp + 0.5), getTempState(pbtemp, pbtempTarget)); } catch (AppException e) { addPlateBoxTemperatureCurve(0.0); - gStateMgrService.updatePboxTemperature(0, false); + gStateMgrService.updatePboxTemperature(0, TemperatureState.Low); log.warn("Failed to read plate box temperature: {}", e.getMessage()); } } - private boolean isTempReady(double nowtemp, double targettemp) { + private TemperatureState getTempState(double nowtemp, double targettemp) { //TODO:改成可配置 if (Math.abs(nowtemp - targettemp) < 1) { - return true; + return TemperatureState.Ready; + } else if (nowtemp < targettemp) { + return TemperatureState.Low; + } else if (nowtemp > targettemp) { + return TemperatureState.High; } - return false; + return TemperatureState.Ready; } } diff --git a/src/main/java/a8k/app/service/data/ReactionRecordMgrService.java b/src/main/java/a8k/app/service/data/ReactionRecordMgrService.java index 67d0680..f110f5d 100644 --- a/src/main/java/a8k/app/service/data/ReactionRecordMgrService.java +++ b/src/main/java/a8k/app/service/data/ReactionRecordMgrService.java @@ -4,6 +4,8 @@ import a8k.app.dao.ReactionReportDao; import a8k.app.dao.type.common.CommonPage; import a8k.app.dao.type.db.ReactionRecord; import a8k.app.service.background.AppEventBusService; +import a8k.app.service.lis.LisCommunicationService; +import a8k.app.service.setting.AppSettingsMgrService; import a8k.app.service.statemgr.GStateMgrService; import a8k.app.type.a8k.opt.OptScanResult; import a8k.app.type.a8k.proj.ProjInfo; @@ -25,10 +27,13 @@ import java.util.List; public class ReactionRecordMgrService { - private final ReactionReportDao reactionReportDao; - private final AppUserMgrService appUserMgrService; - private final GStateMgrService gstate; - private final AppEventBusService appEventBusService; + private final ReactionReportDao reactionReportDao; + private final AppUserMgrService appUserMgrService; + private final GStateMgrService gstate; + private final AppEventBusService appEventBusService; + private final LisCommunicationService lisCommunicationService; + private final AppSettingsMgrService appSettingsMgrService; + @PostConstruct public void init() { @@ -61,6 +66,7 @@ public class ReactionRecordMgrService { record.appVersion = gstate.getAppVersion(); record.mcuVersion = gstate.getMcuVersion(); record.sn = gstate.getSn(); + record.assetId = gstate.getAssetId(); record.subProjNum = reactionResults.size(); record.projInfoIdCardVersion = projInfo.ext.updateChipVersion; record.projInfo = projInfo; @@ -70,6 +76,11 @@ public class ReactionRecordMgrService { record = reactionReportDao.add(record); log.info("addRecord: {}", ZJsonHelper.objectToJson(record)); appEventBusService.pushEvent(new AppNewReactionRecordEvent(record)); + + if (appSettingsMgrService.getLISSetting().lisAutoExport) { + lisCommunicationService.reportReactionRecord(record); + } + } @@ -92,7 +103,8 @@ public class ReactionRecordMgrService { public void exportRecordByLIS(Integer id) { ReactionRecord record = reactionReportDao.findById(id); - log.info("exportRecord: {}", ZJsonHelper.objToPrettyJson(record)); + // log.info("exportRecord: {}", ZJsonHelper.objToPrettyJson(record)); + lisCommunicationService.reportReactionRecord(record); } public void deleteRecord(Integer id) { diff --git a/src/main/java/a8k/app/service/lis/LisCommunicationService.java b/src/main/java/a8k/app/service/lis/LisCommunicationService.java index 3bbbed2..b180b1e 100644 --- a/src/main/java/a8k/app/service/lis/LisCommunicationService.java +++ b/src/main/java/a8k/app/service/lis/LisCommunicationService.java @@ -3,8 +3,11 @@ package a8k.app.service.lis; import a8k.app.iflytophald.channel.LisUartCommunicationChannel; import a8k.app.dao.type.db.LISSetting; import a8k.app.dao.type.db.ReactionRecord; +import a8k.app.service.background.AppEventBusService; import a8k.app.service.setting.AppSettingsMgrService; import a8k.app.service.utils.UISender; +import a8k.app.type.appevent.AppEvent; +import a8k.app.type.appevent.AppNewReactionRecordEvent; import a8k.app.type.exception.AppException; import a8k.app.type.lis.LISDirectionTypeEnum; import a8k.app.type.lis.LISIFType; @@ -22,6 +25,7 @@ import org.springframework.stereotype.Component; public class LisCommunicationService { private final AppSettingsMgrService appSettingsMgrService; private final LisUartCommunicationChannel lisUartCommunicationChannel; + private final AppEventBusService appEventBusService; private LISSetting setting; @@ -30,8 +34,28 @@ public class LisCommunicationService { @Value("${lis.enable}") public Boolean lisEnable = true; + //AppNewReactionRecordEvent + @PostConstruct + void init() { + log.info("LisCommunicationService init"); + if (!lisEnable) { + log.warn("LIS communication is disabled by configuration."); + return; + } + setting = appSettingsMgrService.getLISSetting(); + doUpdateLisSetting(); + + // appEventBusService.regListener((AppEvent event) -> { + // if (event instanceof AppNewReactionRecordEvent newReactionRecordEvent) { + // if (setting.lisAutoExport) { + // reportReactionRecord(newReactionRecordEvent.reactionRecord); + // } + // } + // }); + } + public void updateLisSetting(LISSetting lisSetting) { if (!lisEnable) { log.warn("LIS communication is disabled by configuration, ignore updateLisSetting"); @@ -62,12 +86,12 @@ public class LisCommunicationService { * 上报失败无须向上返回异常, 静默处理即可 */ if (lisChannel == null) { + log.warn("LIS channel is null, cannot report reaction record."); return; } - if (!setting.lisAutoExport) { - return; - } - + // if (!setting.lisAutoExport) { + // return; + // } if (!lisChannel.isConnected()) { log.warn("LIS channel is not connected, cannot report reaction record."); return; @@ -76,22 +100,11 @@ public class LisCommunicationService { lisChannel.reportReactionRecord(reactionRecord); } catch (AppException e) { log.warn("LIS 上报失败: {}", e.getMessage(), e); - UISender.txWarnMsg("LIS 上报记录 %s 失败, %s", reactionRecord.sampleUserid,e.getMessage()); + UISender.txWarnMsg("LIS 上报记录 %s 失败, %s", reactionRecord.sampleUserid, e.getMessage()); } } - @PostConstruct - public void init() { - log.info("LisCommunicationService init"); - if (!lisEnable) { - log.warn("LIS communication is disabled by configuration."); - return; - } - setting = appSettingsMgrService.getLISSetting(); - doUpdateLisSetting(); - } - // // !!!构建新的通道 // diff --git a/src/main/java/a8k/app/service/lowerctrl/OptScanModuleLowerCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/OptScanModuleLowerCtrlService.java index 8b60124..df0e4de 100644 --- a/src/main/java/a8k/app/service/lowerctrl/OptScanModuleLowerCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/OptScanModuleLowerCtrlService.java @@ -18,7 +18,6 @@ import a8k.app.type.a8k.pos.IncubatorPos; import a8k.app.type.exception.AppException; import a8k.app.dao.type.combination.ProjBuildInInfo; import a8k.app.iflytophald.utils.OptGainConvert; -import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -93,9 +92,16 @@ public class OptScanModuleLowerCtrlService { try { a8kCanBusBaseDriver.lockAction(); - turntableMoveCtrlService.trunableMoveToPullPos(turntablePosIndex); - stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerScandbyPos()); - stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModPullM, optModuleParamsMgr.getPullerTargetPos()); + turntableMoveCtrlService.turntableMoveToPullPos(turntablePosIndex); + /* + *@desc + * 这里之所以不一次性拉到位, 是因为送检的那个产品结构上有遐思 + * 如果直接拉,会因为阻力太大,电机拉不动. + */ + stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerStandbyPos()); + stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModPullM, optModuleParamsMgr.getOptModuleEntryPos()); + stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerHoldPos()); + stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModPullM, optModuleParamsMgr.getOptModuleScanPos()); stepMotorCtrlDriver.stepMotorEasyMoveToZeroPointQuickBlock(StepMotorMId.OptModPullM); } finally { a8kCanBusBaseDriver.unlockAction(); @@ -106,7 +112,7 @@ public class OptScanModuleLowerCtrlService { public void dropPlate() throws AppException { stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerDropPos()); stepMotorCtrlDriver.stepMotorEasyMoveToZeroPointQuickBlock(StepMotorMId.OptModScannerM); - stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerScandbyPos()); + stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerStandbyPos()); } public void forceDropPlate(IncubatorPos turntablePosIndex) throws AppException { diff --git a/src/main/java/a8k/app/service/lowerctrl/PlateBoxCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/PlateBoxCtrlService.java index 51934af..7a5a19f 100644 --- a/src/main/java/a8k/app/service/lowerctrl/PlateBoxCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/PlateBoxCtrlService.java @@ -7,7 +7,6 @@ import a8k.app.service.param.pos.PlatesBoxPosParamMgr; import a8k.app.type.a8k.ConsumableGroup; import a8k.app.type.a8k.pos.IncubatorPos; import a8k.app.type.exception.AppException; -import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -29,7 +28,7 @@ public class PlateBoxCtrlService { a8kCanBus.lockAction(); try { - turntableMoveCtrlService.trunableMoveToPushPos(turntablePosIndex); + turntableMoveCtrlService.turntableMoveToPushPos(turntablePosIndex); stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.PlatesBoxYM, platesBoxPosParamMgr.getChXPos(PBCh.off)); stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.PlatesBoxPusherM, platesBoxPosParamMgr.getPushEndXPos()); stepMotorCtrlDriver.stepMotorEasyMoveToZeroPointQuickBlock(StepMotorMId.PlatesBoxPusherM); diff --git a/src/main/java/a8k/app/service/lowerctrl/TurntableMoveCtrlService.java b/src/main/java/a8k/app/service/lowerctrl/TurntableMoveCtrlService.java index 68c3791..c36ea27 100644 --- a/src/main/java/a8k/app/service/lowerctrl/TurntableMoveCtrlService.java +++ b/src/main/java/a8k/app/service/lowerctrl/TurntableMoveCtrlService.java @@ -19,13 +19,15 @@ import org.springframework.stereotype.Component; @Slf4j @RequiredArgsConstructor public class TurntableMoveCtrlService { - static final Integer overtime = 10000; - private final A8kCanBusBaseDriver canBus; + private final StepMotorCtrlDriver stepMotorCtrlDriver; private final TurntablePosParamMgr turntablePosParamMgr; private final InputDetectDriver inputDetectDriver; + private Integer moveCnt = 0; + + private void checkBeforeMoveTurntable() throws AppException { //板夹仓卡板检测 if (inputDetectDriver.getIOState(InputIOId.IncubationPlateInletStuckPPS)) { @@ -91,52 +93,90 @@ public class TurntableMoveCtrlService { } - - private void trunableMoveTo(Integer pos) throws AppException { + private void priTurntableMoveTo(Integer targetPos) throws AppException { checkBeforeMoveTurntable(); //限制pos在 0--> 36000之间 - int nowPos = stepMotorCtrlDriver.stepMotorReadPos(StepMotorMId.IncubatorRotateCtrlM); - int dTargetPos = MinRotationAngle.minRotationAngle(nowPos, pos, 36000); - int targetPos = dTargetPos + nowPos; - - log.info("to:{} now:{} dpos:{} targetPos:{}", pos, nowPos, dTargetPos, targetPos); + int nowPos = stepMotorCtrlDriver.stepMotorReadPos(StepMotorMId.IncubatorRotateCtrlM); + int dTargetPos = MinRotationAngle.minRotationAngle(nowPos, targetPos, 36000); + int finalTargetPos = dTargetPos + nowPos; + log.info("now:{} to:{}", nowPos, finalTargetPos); //先移动半个间距,用来检测是否发生卡板 - if (nowPos < targetPos) { - stepMotorCtrlDriver.stepMotorEasyMoveByBlock(StepMotorMId.IncubatorRotateCtrlM, turntablePosParamMgr.getPosSpacing()); - } else if (nowPos > targetPos) { - stepMotorCtrlDriver.stepMotorEasyMoveByBlock(StepMotorMId.IncubatorRotateCtrlM, -turntablePosParamMgr.getPosSpacing()); + if (nowPos < finalTargetPos) { + stepMotorCtrlDriver.stepMotorEasyMoveByBlock(StepMotorMId.IncubatorRotateCtrlM, turntablePosParamMgr.getPosSpacing() / 2); + } else if (nowPos > finalTargetPos) { + stepMotorCtrlDriver.stepMotorEasyMoveByBlock(StepMotorMId.IncubatorRotateCtrlM, -turntablePosParamMgr.getPosSpacing() / 2); } //解决齿轮间隙的问题 - if (nowPos < targetPos) { - stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.IncubatorRotateCtrlM, targetPos); + if (nowPos < finalTargetPos) { + stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.IncubatorRotateCtrlM, finalTargetPos); } else { - stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.IncubatorRotateCtrlM, targetPos - 300/**/); - stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.IncubatorRotateCtrlM, targetPos); + stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.IncubatorRotateCtrlM, finalTargetPos - 300/**/); + stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.IncubatorRotateCtrlM, finalTargetPos); } + } + private void turntableMoveTo(Integer targetPos) throws AppException { + if (moveCnt >= 10) { + priTurntableMoveTo(0); + stepMotorCtrlDriver.stepMotorEasyMoveToZeroPointQuickBlock(StepMotorMId.IncubatorRotateCtrlM); + moveCnt = 0; + } + priTurntableMoveTo(targetPos); + moveCnt++; - int afterRunNowPos = stepMotorCtrlDriver.stepMotorReadPos(StepMotorMId.IncubatorRotateCtrlM); - afterRunNowPos = afterRunNowPos % 36000; - if (afterRunNowPos < 0) - afterRunNowPos = afterRunNowPos + 36000; - stepMotorCtrlDriver.setCurrentPos(StepMotorMId.IncubatorRotateCtrlM, afterRunNowPos); } - public void trunableMoveToPushPos(IncubatorPos index) throws AppException { - trunableMoveTo(turntablePosParamMgr.getPushPos0() + index.off * turntablePosParamMgr.getPosSpacing()); +// private void trunableMoveTo(Integer pos) throws AppException { +// checkBeforeMoveTurntable(); +// //限制pos在 0--> 36000之间 +// +// int nowPos = stepMotorCtrlDriver.stepMotorReadPos(StepMotorMId.IncubatorRotateCtrlM); +// int dTargetPos = MinRotationAngle.minRotationAngle(nowPos, pos, 36000); +// int targetPos = dTargetPos + nowPos; +// +// log.info("to:{} now:{} dpos:{} targetPos:{}", pos, nowPos, dTargetPos, targetPos); +// +// +// //先移动半个间距,用来检测是否发生卡板 +// if (nowPos < targetPos) { +// stepMotorCtrlDriver.stepMotorEasyMoveByBlock(StepMotorMId.IncubatorRotateCtrlM, turntablePosParamMgr.getPosSpacing() / 2); +// } else if (nowPos > targetPos) { +// stepMotorCtrlDriver.stepMotorEasyMoveByBlock(StepMotorMId.IncubatorRotateCtrlM, -turntablePosParamMgr.getPosSpacing() / 2); +// } +// +// //解决齿轮间隙的问题 +// if (nowPos < targetPos) { +// stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.IncubatorRotateCtrlM, targetPos); +// } else { +// stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.IncubatorRotateCtrlM, targetPos - 300/**/); +// stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.IncubatorRotateCtrlM, targetPos); +// } +// +// +// int afterRunNowPos = stepMotorCtrlDriver.stepMotorReadPos(StepMotorMId.IncubatorRotateCtrlM); +// afterRunNowPos = afterRunNowPos % 36000; +// if (afterRunNowPos < 0) +// afterRunNowPos = afterRunNowPos + 36000; +// stepMotorCtrlDriver.setCurrentPos(StepMotorMId.IncubatorRotateCtrlM, afterRunNowPos); +// +// } + + public void turntableMoveToPushPos(IncubatorPos index) throws AppException { + turntableMoveTo(turntablePosParamMgr.getPushPos0() + index.off * turntablePosParamMgr.getPosSpacing()); } - public void trunableMoveToPullPos(IncubatorPos index) throws AppException { - trunableMoveTo(turntablePosParamMgr.getPullPos0() + index.off * turntablePosParamMgr.getPosSpacing()); + public void turntableMoveToPullPos(IncubatorPos index) throws AppException { + turntableMoveTo(turntablePosParamMgr.getPullPos0() + index.off * turntablePosParamMgr.getPosSpacing()); + } - public void trunableMoveToDropLiquidPos(IncubatorPos index) throws AppException { - trunableMoveTo(turntablePosParamMgr.getDropLiquidPos0() + index.off * turntablePosParamMgr.getPosSpacing()); + public void turntableMoveToDropLiquidPos(IncubatorPos index) throws AppException { + turntableMoveTo(turntablePosParamMgr.getDropLiquidPos0() + index.off * turntablePosParamMgr.getPosSpacing()); } diff --git a/src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java b/src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java index 42b37cd..0994cec 100644 --- a/src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java +++ b/src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java @@ -120,7 +120,7 @@ public class IncubationPlateCtrlModule { incubationPlateStateMgr.setIncubationToWaitingForDropState(tank.pos); } - docmd("拉取反应板到滴定位", () -> turntableMoveCtrlService.trunableMoveToDropLiquidPos(incubatorPos)); + docmd("拉取反应板到滴定位", () -> turntableMoveCtrlService.turntableMoveToDropLiquidPos(incubatorPos)); dropLiquidAction.run(); UISender.txInfoMsg(log, "开始孵育"); incubationPlateStateMgr.startIncubating(incubatorPos, System.currentTimeMillis(), incubatedTimeSec); diff --git a/src/main/java/a8k/app/service/param/optparam/OptModuleParamsMgr.java b/src/main/java/a8k/app/service/param/optparam/OptModuleParamsMgr.java index 01fe919..949fbb8 100644 --- a/src/main/java/a8k/app/service/param/optparam/OptModuleParamsMgr.java +++ b/src/main/java/a8k/app/service/param/optparam/OptModuleParamsMgr.java @@ -19,13 +19,15 @@ public class OptModuleParamsMgr extends ParamMgr { @PostConstruct void initialize() { for (OptModuleParam pos : OptModuleParam.values()) { - initParam(pos, pos.chName, pos.type); + initParam(pos, pos.chName, pos.type,0); } //校验参数类型 - getPullerTargetPos(); + getOptModuleScanPos(); getOptScanerDropPos(); - getOptScanerScandbyPos(); + getOptScanerStandbyPos(); + getOptScanerHoldPos(); + getOptModuleEntryPos(); } @@ -34,16 +36,24 @@ public class OptModuleParamsMgr extends ParamMgr { } - public Integer getPullerTargetPos() { - return getParam(OptModuleParam.PullerTargetPos, Integer.class); + public Integer getOptModuleScanPos() { + return getParam(OptModuleParam.OptModuleScanPos, Integer.class); + } + + public Integer getOptModuleEntryPos() { + return getParam(OptModuleParam.OptModuleEntryPos, Integer.class); } public Integer getOptScanerDropPos() { return getParam(OptModuleParam.OptScanerDropPos, Integer.class); } - public Integer getOptScanerScandbyPos() { - return getParam(OptModuleParam.OptScanerScandbyPos, Integer.class); + public Integer getOptScanerStandbyPos() { + return getParam(OptModuleParam.OptScanerStandbyPos, Integer.class); + } + + public Integer getOptScanerHoldPos() { + return getParam(OptModuleParam.OptScanerHoldPos, Integer.class); } } diff --git a/src/main/java/a8k/app/service/statemgr/GStateMgrService.java b/src/main/java/a8k/app/service/statemgr/GStateMgrService.java index 859f61d..7032c97 100644 --- a/src/main/java/a8k/app/service/statemgr/GStateMgrService.java +++ b/src/main/java/a8k/app/service/statemgr/GStateMgrService.java @@ -5,6 +5,7 @@ import a8k.app.service.virtualstate.DeviceVirtualStateMgrService; import a8k.app.type.BoardVersions; import a8k.app.type.DeviceRunMode; import a8k.app.type.GState; +import a8k.app.type.TemperatureState; import a8k.app.type.error.AppError; import a8k.app.type.exception.AppException; import a8k.app.type.a8k.state.SensorState; @@ -44,14 +45,14 @@ public class GStateMgrService { return this.gState.sensorState; } - public void updatePboxTemperature(Integer val, Boolean isReady) { + public void updatePboxTemperature(Integer val, TemperatureState state) { gState.sensorState.setPboxTemperature(val); - gState.sensorState.setPboxTemperatureReady(isReady); + gState.sensorState.setPboxTemperatureState(state); } - public void updateIncubateBoxTemperature(Integer val, Boolean isReady) { + public void updateIncubateBoxTemperature(Integer val, TemperatureState state) { gState.sensorState.setIncubateBoxTemperature(val); - gState.sensorState.setIncubateBoxTemperatureReady(isReady); + gState.sensorState.setIncubateBoxTemperatureState(state); } public void updateWasteBinFullFlag(Boolean val) { diff --git a/src/main/java/a8k/app/service/statemgr/TubeStateMgr.java b/src/main/java/a8k/app/service/statemgr/TubeStateMgr.java index 7646b3a..fe76b73 100644 --- a/src/main/java/a8k/app/service/statemgr/TubeStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/TubeStateMgr.java @@ -156,9 +156,6 @@ public class TubeStateMgr { String sampleId = newSample(tube); tube.setSampleId(sampleId); - if (tube.getUserid() == null || tube.getUserid().isEmpty()) { - tube.setUserid(sampleId); - } Integer off = 0; for (Integer projId : tube.getProjIds()) { @@ -443,15 +440,20 @@ public class TubeStateMgr { Integer cnt = 0; Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); - if (isEmergency) { - cnt = deviceStatisticDao.get(DeviceStatistic.StatisticType.EmergencyTubeCnt, date); - sampleid = String.format("%s_%sE", sdf.format(date), cnt); - deviceStatisticDao.setCnt(DeviceStatistic.StatisticType.EmergencyTubeCnt, date, cnt + 1); - } else { - cnt = deviceStatisticDao.get(DeviceStatistic.StatisticType.TubeHolderCnt, date); - sampleid = String.format("%s_%d%02d", sdf.format(date), cnt, tubePos); - deviceStatisticDao.setCnt(DeviceStatistic.StatisticType.TubeHolderCnt, date, cnt + 1); - } + // if (isEmergency) { + // cnt = deviceStatisticDao.get(DeviceStatistic.StatisticType.EmergencyTubeCnt, date); + // sampleid = String.format("%s_%sE", sdf.format(date), cnt); + // deviceStatisticDao.setCnt(DeviceStatistic.StatisticType.EmergencyTubeCnt, date, cnt + 1); + // } else { + // cnt = deviceStatisticDao.get(DeviceStatistic.StatisticType.TubeHolderCnt, date); + // sampleid = String.format("%s_%d%02d", sdf.format(date), cnt, tubePos); + // deviceStatisticDao.setCnt(DeviceStatistic.StatisticType.TubeHolderCnt, date, cnt + 1); + // } + // + cnt = deviceStatisticDao.get(DeviceStatistic.StatisticType.SampleCnt, date); + sampleid = String.format("%s_%d%03d", sdf.format(date), cnt, tubePos); + deviceStatisticDao.setCnt(DeviceStatistic.StatisticType.SampleCnt, date, cnt + 1); + return sampleid; } diff --git a/src/main/java/a8k/app/service/virtualstate/generator/TubeVirtualStateGenerator.java b/src/main/java/a8k/app/service/virtualstate/generator/TubeVirtualStateGenerator.java index 6d22b1b..f18c362 100644 --- a/src/main/java/a8k/app/service/virtualstate/generator/TubeVirtualStateGenerator.java +++ b/src/main/java/a8k/app/service/virtualstate/generator/TubeVirtualStateGenerator.java @@ -81,10 +81,10 @@ public class TubeVirtualStateGenerator { private Tube createFakeTube(Integer pos) { Tube tube = new Tube(pos); - tube.setSampleId("250109_001E0" + pos); + tube.setSampleId(String.format("250109_%03d", pos)); tube.setBloodType(BloodType.WHOLE_BLOOD); tube.setSampleBarcode("112334455667"); - tube.setUserid(String.format("250109_%dE", pos)); + tube.setUserid(String.format("UID_ABC_%03d", pos)); switch (pos) { case 1 -> tube.setState(TubeState.EMPTY); diff --git a/src/main/java/a8k/app/service/virtualstate/generator/VirtualIncubationPlateStateGenerator.java b/src/main/java/a8k/app/service/virtualstate/generator/VirtualIncubationPlateStateGenerator.java index 9e60aa2..597838f 100644 --- a/src/main/java/a8k/app/service/virtualstate/generator/VirtualIncubationPlateStateGenerator.java +++ b/src/main/java/a8k/app/service/virtualstate/generator/VirtualIncubationPlateStateGenerator.java @@ -109,21 +109,23 @@ public class VirtualIncubationPlateStateGenerator { return incubationPlate; } + Integer cnt = 0; + private void assignSubTankState(IncubationSubTank subtank) { + subtank.sampleInfo = new SampleInfo( "250109_001E01", 0, false, false, BloodType.WHOLE_BLOOD, "B3A7KK8DKF", "250109_001E" ); - subtank.sampleInfo.bloodType = BloodType.WHOLE_BLOOD; - subtank.sampleInfo.sampleBarcode = "112334455667"; - subtank.sampleInfo.userid = "250109_001E"; + subtank.sampleInfo.sampleBarcode = "BAR112334455667"; + subtank.sampleInfo.userid = String.format("UID_ABC_%03d",subtank.pos.off); subtank.projInfo = new ProjBriefInfo(); subtank.projInfo.projId = 1; subtank.projInfo.projName = "hsCRP"; subtank.projInfo.projShortName = "CA"; subtank.projInfo.color = "#DC143C"; - subtank.sampleInfo.sampleId = "250109_001E01"; + subtank.sampleInfo.sampleId = String.format("250901_%03d",subtank.pos.off); subtank.projId = 1; subtank.lotId = "CA123456"; subtank.isEmergency = false; diff --git a/src/main/java/a8k/app/service/virtualstate/generator/VirtualPreReactionGridGroupStateGenerator.java b/src/main/java/a8k/app/service/virtualstate/generator/VirtualPreReactionGridGroupStateGenerator.java index cfba0cf..edef403 100644 --- a/src/main/java/a8k/app/service/virtualstate/generator/VirtualPreReactionGridGroupStateGenerator.java +++ b/src/main/java/a8k/app/service/virtualstate/generator/VirtualPreReactionGridGroupStateGenerator.java @@ -85,10 +85,12 @@ public class VirtualPreReactionGridGroupStateGenerator { case 2 -> { gridGroup.grids.get(i).state = PreReactionGrid.State.REACTION_COMPLETED; gridGroup.grids.get(i).sampleInfo.userid = "UID123"; + gridGroup.grids.get(i).sampleInfo.sampleId = "250809_001"; } case 3 -> { gridGroup.grids.get(i).state = PreReactionGrid.State.REACTING; gridGroup.grids.get(i).sampleInfo.userid = "UID123"; + gridGroup.grids.get(i).sampleInfo.sampleId = "250809_001"; gridGroup.grids.get(i).reactionRemainingTime = 3 * 60L; } case 4 -> { diff --git a/src/main/java/a8k/app/service/virtualstate/generator/VirtualSensorStateGenerator.java b/src/main/java/a8k/app/service/virtualstate/generator/VirtualSensorStateGenerator.java index 702b588..14f03c5 100644 --- a/src/main/java/a8k/app/service/virtualstate/generator/VirtualSensorStateGenerator.java +++ b/src/main/java/a8k/app/service/virtualstate/generator/VirtualSensorStateGenerator.java @@ -1,6 +1,7 @@ package a8k.app.service.virtualstate.generator; import a8k.app.service.virtualstate.VirtualStateModeMgr; +import a8k.app.type.TemperatureState; import a8k.app.type.a8k.state.DeviceWorkState; import a8k.app.type.a8k.state.SensorState; import a8k.app.type.a8k.state.enumtype.A8kWorkState; @@ -43,8 +44,9 @@ public class VirtualSensorStateGenerator { sensorState.setIncubateBoxTemperature(25); sensorState.setWasteBinFullFlag(false); cnt++; - sensorState.setIncubateBoxTemperatureReady(cnt % 2 == 0); //每次调用切换一次状态 - sensorState.setPboxTemperatureReady(cnt % 2 == 0); //每次调用切换一次状态 + + sensorState.setIncubateBoxTemperatureState(TemperatureState.values()[cnt % TemperatureState.values().length]); //每次调用切换一次状态 + sensorState.setPboxTemperatureState(TemperatureState.Low); //每次调用切换一次状态 return sensorState; } @@ -53,8 +55,8 @@ public class VirtualSensorStateGenerator { sensorState.setPboxTemperature(25); sensorState.setIncubateBoxTemperature(25); sensorState.setWasteBinFullFlag(false); - sensorState.setIncubateBoxTemperatureReady(true); //每次调用切换一次状态 - sensorState.setPboxTemperatureReady(true); //每次调用切换一次状态 + sensorState.setIncubateBoxTemperatureState(TemperatureState.Ready); //每次调用切换一次状态 + sensorState.setPboxTemperatureState(TemperatureState.Ready); //每次调用切换一次状态 return sensorState; } } diff --git a/src/main/java/a8k/app/type/TemperatureState.java b/src/main/java/a8k/app/type/TemperatureState.java new file mode 100644 index 0000000..586fde9 --- /dev/null +++ b/src/main/java/a8k/app/type/TemperatureState.java @@ -0,0 +1,5 @@ +package a8k.app.type; + +public enum TemperatureState { + Ready, High, Low, +} diff --git a/src/main/java/a8k/app/type/a8k/state/SensorState.java b/src/main/java/a8k/app/type/a8k/state/SensorState.java index 732d9f5..9c223bf 100644 --- a/src/main/java/a8k/app/type/a8k/state/SensorState.java +++ b/src/main/java/a8k/app/type/a8k/state/SensorState.java @@ -1,19 +1,23 @@ package a8k.app.type.a8k.state; +import a8k.app.type.TemperatureState; import io.swagger.v3.oas.annotations.media.Schema; public class SensorState { + + @Schema(description = "板夹仓温度") - Integer pboxTemperature = 25; + Integer pboxTemperature = 25; + @Schema(description = "板夹仓温度状态") + TemperatureState pboxTemperatureState = TemperatureState.Ready; @Schema(description = "孵育盒温度") - Integer incubateBoxTemperature = 25; + Integer incubateBoxTemperature = 25; + @Schema(description = "孵育盒温度状态") + TemperatureState incubateBoxTemperatureState = TemperatureState.Ready; + @Schema(description = "废液桶满标志") - Boolean wasteBinFullFlag = false; - @Schema(description = "板夹仓温度是否就绪") - Boolean pboxTemperatureReady = false; - @Schema(description = "孵育盒温度是否就绪") - Boolean incubateBoxTemperatureReady = false; + Boolean wasteBinFullFlag = false; public synchronized Integer getPboxTemperature() { @@ -24,20 +28,20 @@ public class SensorState { this.pboxTemperature = pboxTemperature; } - public synchronized Boolean getPboxTemperatureReady() { - return pboxTemperatureReady; + public synchronized TemperatureState getPboxTemperatureState() { + return pboxTemperatureState; } - public synchronized void setPboxTemperatureReady(Boolean pboxTemperatureReady) { - this.pboxTemperatureReady = pboxTemperatureReady; + public synchronized void setPboxTemperatureState(TemperatureState pboxTemperatureState) { + this.pboxTemperatureState = pboxTemperatureState; } - public synchronized Boolean getIncubateBoxTemperatureReady() { - return incubateBoxTemperatureReady; + public synchronized TemperatureState getIncubateBoxTemperatureState() { + return incubateBoxTemperatureState; } - public synchronized void setIncubateBoxTemperatureReady(Boolean incubateBoxTemperatureReady) { - this.incubateBoxTemperatureReady = incubateBoxTemperatureReady; + public synchronized void setIncubateBoxTemperatureState(TemperatureState incubateBoxTemperatureState) { + this.incubateBoxTemperatureState = incubateBoxTemperatureState; } public synchronized Integer getIncubateBoxTemperature() { diff --git a/src/main/java/a8k/app/type/appevent/SpringbootLoadingCompletedEvent.java b/src/main/java/a8k/app/type/appevent/SpringbootLoadingCompletedEvent.java new file mode 100644 index 0000000..756b8ff --- /dev/null +++ b/src/main/java/a8k/app/type/appevent/SpringbootLoadingCompletedEvent.java @@ -0,0 +1,10 @@ +package a8k.app.type.appevent; + +import a8k.app.type.ui.ZAppPromopt; + +public class SpringbootLoadingCompletedEvent extends AppEvent { + public SpringbootLoadingCompletedEvent() { + super(SpringbootLoadingCompletedEvent.class.getSimpleName()); + } + +} diff --git a/src/main/java/a8k/app/type/param/optpos/OptModuleParam.java b/src/main/java/a8k/app/type/param/optpos/OptModuleParam.java index ca97806..4ca022d 100644 --- a/src/main/java/a8k/app/type/param/optpos/OptModuleParam.java +++ b/src/main/java/a8k/app/type/param/optpos/OptModuleParam.java @@ -1,11 +1,13 @@ package a8k.app.type.param.optpos; public enum OptModuleParam { - PullerTargetPos("拉板目标位置", Integer.class), + OptModuleScanPos("光学模组扫描位", Integer.class), + OptModuleEntryPos("光学模组入口位置", Integer.class), OptScanerDropPos("丢板坐标", Integer.class), - OptScanerScandbyPos("扫描待机位", Integer.class), + OptScanerStandbyPos("扫描待机位", Integer.class), + OptScanerHoldPos("扫描夹紧起始位", Integer.class), ; - public final String chName; + public final String chName; public final Class type; OptModuleParam(String chName, Class type) { diff --git a/src/main/java/a8k/app/type/ui/ZAppErrorStackInfo.java b/src/main/java/a8k/app/type/ui/ZAppErrorStackInfo.java index db88744..b829e97 100644 --- a/src/main/java/a8k/app/type/ui/ZAppErrorStackInfo.java +++ b/src/main/java/a8k/app/type/ui/ZAppErrorStackInfo.java @@ -1,5 +1,7 @@ package a8k.app.type.ui; -public class ZAppErrorStackInfo { +import java.io.Serializable; + +public class ZAppErrorStackInfo implements Serializable { public String[] stackTraceElements; } diff --git a/src/main/java/a8k/app/type/ui/ZAppPromptFormsItem.java b/src/main/java/a8k/app/type/ui/ZAppPromptFormsItem.java index 1a1857e..57b1f32 100644 --- a/src/main/java/a8k/app/type/ui/ZAppPromptFormsItem.java +++ b/src/main/java/a8k/app/type/ui/ZAppPromptFormsItem.java @@ -1,6 +1,8 @@ package a8k.app.type.ui; -public class ZAppPromptFormsItem { +import java.io.Serializable; + +public class ZAppPromptFormsItem implements Serializable { public String name; public String description; diff --git a/src/main/java/a8k/app/utils/ZSqlite.java b/src/main/java/a8k/app/utils/ZSqlite.java index 1bb008e..a399b51 100644 --- a/src/main/java/a8k/app/utils/ZSqlite.java +++ b/src/main/java/a8k/app/utils/ZSqlite.java @@ -20,11 +20,11 @@ public class ZSqlite { public ZSqlite() { } - public void init(JdbcTemplate jdbcTemplate, String tableName, Class tClass, boolean foreceCreate) { + public void init(JdbcTemplate jdbcTemplate, String tableName, Class tClass, boolean forceCreate) { this.tableName = tableName; this.tClass = tClass; this.jdbcTemplate = jdbcTemplate; - if (foreceCreate) { + if (forceCreate) { this.forceDeleteTable(); } @@ -32,6 +32,8 @@ public class ZSqlite { this.createTable(); tryInitDBData(); } + ZSqliteJdbcHelper.fixTable(jdbcTemplate, tableName, tClass); + } public void init(JdbcTemplate jdbcTemplate, String tableName, Class tClass) { diff --git a/src/main/java/a8k/app/utils/ZSqliteJdbcHelper.java b/src/main/java/a8k/app/utils/ZSqliteJdbcHelper.java index 3db6206..4e18c99 100644 --- a/src/main/java/a8k/app/utils/ZSqliteJdbcHelper.java +++ b/src/main/java/a8k/app/utils/ZSqliteJdbcHelper.java @@ -7,16 +7,16 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.PreparedStatementCreatorFactory; import org.springframework.jdbc.support.GeneratedKeyHolder; import javax.lang.model.element.TypeElement; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; +import java.lang.reflect.*; +import java.sql.Connection; +import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.text.SimpleDateFormat; @@ -24,8 +24,8 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +@Slf4j public class ZSqliteJdbcHelper { - static Logger logger = org.slf4j.LoggerFactory.getLogger(ZSqliteJdbcHelper.class); static public boolean isTableExist(JdbcTemplate jdbcTemplate, String tableName) { String sql = "select * from sqlite_master where type = 'table' and name = '" + tableName + "';"; @@ -46,29 +46,70 @@ public class ZSqliteJdbcHelper { } } + static public void fixTable(JdbcTemplate jdbcTemplate, String tableName, Class tClass) { + //如果类中有字段在表中不存在,则添加该字段 + // 获取数据库连接 + jdbcTemplate.execute((Connection connection) -> { + try { + // 获取表的元数据 + DatabaseMetaData metaData = connection.getMetaData(); + ResultSet columns = metaData.getColumns(null, null, tableName, null); + + // 收集已存在的列名 + List existingColumns = new ArrayList<>(); + while (columns.next()) { + existingColumns.add(columns.getString("COLUMN_NAME")); + } + columns.close(); + + // 检查类的每个字段 + for (Field field : tClass.getDeclaredFields()) { + String columnName = field.getName(); + + // 如果字段不在表中,则添加 + if (!existingColumns.contains(columnName)) { + String sqlType = getSqlType(field.getType()); + String alterSql = String.format("ALTER TABLE %s ADD COLUMN %s %s", tableName, columnName, sqlType); + jdbcTemplate.execute(alterSql); + log.info("Added column: {} with type: {}", columnName, sqlType); + } + } + } catch (SQLException e) { + throw new RuntimeException("Failed to fix table " + tableName, e); + } + return null; + }); + + } + + // 将Java类型映射到SQLite类型 + private static String getSqlType(Class type) { + if (type == String.class) { + return "text"; + } else if (type == int.class || type == Integer.class) { + return "integer"; + } else if (type == long.class || type == Long.class) { + return "integer"; + } else if (type == float.class || type == Float.class) { + return "real"; + } else if (type == double.class || type == Double.class) { + return "real"; + } else if (type == boolean.class || type == Boolean.class) { + return "integer"; // SQLite用0和1表示布尔值 + } else { + return "TEXT"; // 默认类型 + } + } + static public void createTable(JdbcTemplate jdbcTemplate, String tableName, Class tClass) { StringBuilder sql = new StringBuilder("create table " + tableName + " ("); - Boolean hasId = false; - for (java.lang.reflect.Field field : tClass.getDeclaredFields()) { + boolean hasId = false; + for (Field field : tClass.getDeclaredFields()) { if (field.getName().equals("id")) { hasId = true; } sql.append(" '").append(field.getName()).append("' "); - if (field.getType().equals(Integer.class) || field.getType().equals(int.class)) { - sql.append("integer,"); - } else if (field.getType().equals(Double.class) || field.getType().equals(Float.class)) { - sql.append("real,"); - } else if (field.getType().equals(Boolean.class)) { - sql.append("integer,"); - } else if (field.getType().equals(String.class)) { - sql.append("text,"); - } else if (field.getType().equals(Date.class)) { - sql.append("text,"); - } else if (field.getType().isEnum()) { - sql.append("text,"); - } else { - sql.append("text,"); - } + sql.append(String.format("%s,", getSqlType(field.getType()))); } if (!hasId) { throw new RuntimeException("id field not found in class " + tClass.getName()); @@ -111,7 +152,7 @@ public class ZSqliteJdbcHelper { try { String val = rs.getString(field.getName()); if (val != null && !val.isEmpty()) { - // logger.info("val: {}", val); + // log.info("val: {}", val); field.set(obj, objectMapper.readTree(val)); } else { field.set(obj, null); @@ -214,7 +255,7 @@ public class ZSqliteJdbcHelper { args.add(objectMapper.writeValueAsString(field.get(obj))); } } catch (IllegalAccessException | JsonProcessingException e) { - logger.error("", e); + log.error("", e); args.add(null); } } diff --git a/src/main/java/a8k/extui/page/extsetting/pos_calibration/P04ReactionPlatesTransmitControlerCalibrationPage.java b/src/main/java/a8k/extui/page/extsetting/pos_calibration/P04ReactionPlatesTransmitControlerCalibrationPage.java index 8c90fd7..6b50aa8 100644 --- a/src/main/java/a8k/extui/page/extsetting/pos_calibration/P04ReactionPlatesTransmitControlerCalibrationPage.java +++ b/src/main/java/a8k/extui/page/extsetting/pos_calibration/P04ReactionPlatesTransmitControlerCalibrationPage.java @@ -60,18 +60,26 @@ public class P04ReactionPlatesTransmitControlerCalibrationPage { platesBoxPosParamMgr.setPushEndXPos(pos); } - public void OptModulePosMgr_setPullerTargetPos(Integer pos) { - optModuleParamsMgr.setOptParam(OptModuleParam.PullerTargetPos, pos); + public void OptModulePosMgr_setOptModuleScanPos(Integer pos) { + optModuleParamsMgr.setOptParam(OptModuleParam.OptModuleScanPos, pos); } + public void OptModulePosMgr_setOptModuleEntryPos(Integer pos) { + optModuleParamsMgr.setOptParam(OptModuleParam.OptModuleEntryPos, pos); + } public void OptModulePosMgr_setOptScanerDropPos(Integer pos) { optModuleParamsMgr.setOptParam(OptModuleParam.OptScanerDropPos, pos); } + // OptScanerStandbyPos("扫描待机位", Integer.class), + // OptScanerHoldPos("扫描夹紧起始位", Integer.class), + public void OptModulePosMgr_setOptScanerStandbyPos(Integer pos) { + optModuleParamsMgr.setOptParam(OptModuleParam.OptScanerStandbyPos, pos); + } - public void OptModulePosMgr_setOptScanerScandbyPos(Integer pos) { - optModuleParamsMgr.setOptParam(OptModuleParam.OptScanerScandbyPos, pos); + public void OptModulePosMgr_setOptScanerHoldPos(Integer pos) { + optModuleParamsMgr.setOptParam(OptModuleParam.OptScanerHoldPos, pos); } @@ -102,12 +110,17 @@ public class P04ReactionPlatesTransmitControlerCalibrationPage { .setParamVal("pos", () -> platesBoxPosParamMgr.getPushEndXPos()); page.newGroup("光学模组基础坐标.校准"); - page.addFunction("设置<拉板>目标位置", this::OptModulePosMgr_setPullerTargetPos) - .setParamVal("pos", () -> optModuleParamsMgr.getPullerTargetPos()); + page.addFunction("设置<拉板>光学模组扫描位置", this::OptModulePosMgr_setOptModuleScanPos) + .setParamVal("pos", () -> optModuleParamsMgr.getOptModuleScanPos()); + page.addFunction("设置<拉板>光学模组入口位置", this::OptModulePosMgr_setOptModuleEntryPos) + .setParamVal("pos", () -> optModuleParamsMgr.getOptModuleEntryPos()); + page.addFunction("设置<光学扫描器>扫描待机位", this::OptModulePosMgr_setOptScanerStandbyPos) + .setParamVal("pos", () -> optModuleParamsMgr.getOptScanerStandbyPos()); + page.addFunction("设置<光学扫描器>夹紧起始位", this::OptModulePosMgr_setOptScanerHoldPos) + .setParamVal("pos", () -> optModuleParamsMgr.getOptScanerHoldPos()); page.addFunction("设置<光学扫描器>丢板坐标", this::OptModulePosMgr_setOptScanerDropPos) .setParamVal("pos", () -> optModuleParamsMgr.getOptScanerDropPos()); - page.addFunction("设置<光学扫描器>扫描待机位", this::OptModulePosMgr_setOptScanerScandbyPos) - .setParamVal("pos", () -> optModuleParamsMgr.getOptScanerScandbyPos()); + extApiPageMgr.addPage(page); } diff --git a/src/main/java/a8k/extui/page/factory/opt/OptModuleParamCalibration.java b/src/main/java/a8k/extui/page/factory/opt/OptModuleParamCalibration.java index 1a4a228..88fb780 100644 --- a/src/main/java/a8k/extui/page/factory/opt/OptModuleParamCalibration.java +++ b/src/main/java/a8k/extui/page/factory/opt/OptModuleParamCalibration.java @@ -42,7 +42,7 @@ import java.util.Map; @RequiredArgsConstructor public class OptModuleParamCalibration { - private final OptModuleExtParamsMgr optModuleExtParamsMgr; + private final OptModuleExtParamsMgr optModuleExtParamsMgr; private final PlateBoxCtrlService plateBoxCtrlService; private final OptScanModuleLowerCtrlService optScanModuleLowerCtrlService; private final ProjInfoMgrService projInfoMgrService; @@ -87,6 +87,10 @@ public class OptModuleParamCalibration { optScanModuleLowerCtrlService.pullPlate(IncubatorPos.SPACE01); } + public void pullPlateToOptModule(IncubatorPos pos) throws AppException { + optScanModuleLowerCtrlService.pullPlate(pos); + } + public void dropPlate() throws AppException { optScanModuleLowerCtrlService.dropPlate(); @@ -199,7 +203,8 @@ public class OptModuleParamCalibration { var page = extApiPageMgr.newPage(this); page.newGroup("基础"); - page.addFunction("推板到光学模组", this::pushOnePlateToOptModule); + page.addFunction("从板夹仓推板到光学模组", this::pushOnePlateToOptModule); + page.addFunction("拉板到光学模组", this::pullPlateToOptModule); page.addFunction("丢板", this::dropPlate); page.newGroup("F光学"); diff --git a/src/main/java/a8k/extui/page/factory/verification/P31ReactionPlatesTransmitPosVerificationPage.java b/src/main/java/a8k/extui/page/factory/verification/P31ReactionPlatesTransmitPosVerificationPage.java index 11cd68c..5f34420 100644 --- a/src/main/java/a8k/extui/page/factory/verification/P31ReactionPlatesTransmitPosVerificationPage.java +++ b/src/main/java/a8k/extui/page/factory/verification/P31ReactionPlatesTransmitPosVerificationPage.java @@ -57,15 +57,15 @@ public class P31ReactionPlatesTransmitPosVerificationPage { } public void turntableMoveToDropLiquidPos(IncubatorPos index) throws AppException { - turntableMoveCtrlService.trunableMoveToDropLiquidPos(index); + turntableMoveCtrlService.turntableMoveToDropLiquidPos(index); } public void turntableMoveToPullPos(IncubatorPos index) throws AppException { - turntableMoveCtrlService.trunableMoveToPullPos(index); + turntableMoveCtrlService.turntableMoveToPullPos(index); } public void turntableMoveToPushPos(IncubatorPos index) throws AppException { - turntableMoveCtrlService.trunableMoveToPushPos(index); + turntableMoveCtrlService.turntableMoveToPushPos(index); } diff --git a/src/main/java/a8k/extui/page/factory/verification/P34LiquidOperationTestPage.java b/src/main/java/a8k/extui/page/factory/verification/P34LiquidOperationTestPage.java index 57ae3b5..19fc62d 100644 --- a/src/main/java/a8k/extui/page/factory/verification/P34LiquidOperationTestPage.java +++ b/src/main/java/a8k/extui/page/factory/verification/P34LiquidOperationTestPage.java @@ -65,7 +65,7 @@ public class P34LiquidOperationTestPage { public void dropLiquidToReactionPlate(IncubatorPos pos) throws AppException { - turntableMoveCtrlService.trunableMoveToDropLiquidPos(pos); + turntableMoveCtrlService.turntableMoveToDropLiquidPos(pos); liquidOperationCtrService.dropLiquidToReactionPlate(true); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f4b7fac..649a168 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,17 +1,17 @@ #WEB虚拟后端 -#server.port: 80 -#iflytophald.ip: 127.0.0.1 -#iflytophald.enable: false -#device.runmode: "VirtualStateGenerateMode" -#lis.enable: false - -#PC调试 server.port: 80 -device.runmode: "RealMode" -iflytophald.ip: 192.168.8.10 -iflytophald.enable: true +iflytophald.ip: 127.0.0.1 +iflytophald.enable: false +device.runmode: "VirtualStateGenerateMode" lis.enable: false +#PC调试 +#server.port: 80 +#device.runmode: "RealMode" +#iflytophald.ip: 192.168.8.10 +#iflytophald.enable: true +#lis.enable: true + #硬件测试 #server.port: 8082 #iflytophald.ip: 192.168.8.10 @@ -26,7 +26,7 @@ lis.enable: false # -a8k.enableTemperatureCtrl: false +a8k.enableTemperatureCtrl: true # ip: 192.168.8.10