Browse Source

Updates application version and fixes bugs

Updates the application version to B80.CN.01.00.10.

Adds 'SampleCnt' to the DeviceStatistic enum.

Adds 'assetId' field to ReactionRecord for factory serial number.

Improves error handling for step motor lost steps, logging the lost step value.

Adds a lost step register to RegIndex and StepMotorRegIndex.

Enhances ID card reader logic to trigger read card on Springboot loading completed, and passes a flag determining if push mount event occurs.

Prevents temperature control from starting in virtual mode.

Updates temperature synchronization to reflect target temperatures in virtual mode and introduces TemperatureState enum to reflect actual temperature status.

Exports reaction records to LIS automatically if configured.

Refactors optical module control logic and adds new positions for improved plate handling.

Corrects turntable movement control logic and addresses gear clearance issues.

Adds SpringbootLoadingCompletedEvent to handle post-startup tasks.
master
zhaohe 3 days ago
parent
commit
ac505aa54f
  1. BIN
      appresource/db/appbak.db
  2. 8
      src/main/java/a8k/BoditechA800Application.java
  3. 2
      src/main/java/a8k/app/constant/AppVersion.java
  4. 1
      src/main/java/a8k/app/dao/type/db/DeviceStatistic.java
  5. 4
      src/main/java/a8k/app/dao/type/db/ReactionRecord.java
  6. 13
      src/main/java/a8k/app/iflytophald/driver/A8kCanBusBaseDriver.java
  7. 2
      src/main/java/a8k/app/iflytophald/type/protocol/RegIndex.java
  8. 1
      src/main/java/a8k/app/iflytophald/type/protocol/StepMotorRegIndex.java
  9. 19
      src/main/java/a8k/app/service/background/ProjIDCardCtrlAndMonitorService.java
  10. 6
      src/main/java/a8k/app/service/background/TemperatureCtrlService.java
  11. 25
      src/main/java/a8k/app/service/background/TemperatureSyncService.java
  12. 22
      src/main/java/a8k/app/service/data/ReactionRecordMgrService.java
  13. 45
      src/main/java/a8k/app/service/lis/LisCommunicationService.java
  14. 16
      src/main/java/a8k/app/service/lowerctrl/OptScanModuleLowerCtrlService.java
  15. 3
      src/main/java/a8k/app/service/lowerctrl/PlateBoxCtrlService.java
  16. 96
      src/main/java/a8k/app/service/lowerctrl/TurntableMoveCtrlService.java
  17. 2
      src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java
  18. 24
      src/main/java/a8k/app/service/param/optparam/OptModuleParamsMgr.java
  19. 9
      src/main/java/a8k/app/service/statemgr/GStateMgrService.java
  20. 26
      src/main/java/a8k/app/service/statemgr/TubeStateMgr.java
  21. 4
      src/main/java/a8k/app/service/virtualstate/generator/TubeVirtualStateGenerator.java
  22. 10
      src/main/java/a8k/app/service/virtualstate/generator/VirtualIncubationPlateStateGenerator.java
  23. 2
      src/main/java/a8k/app/service/virtualstate/generator/VirtualPreReactionGridGroupStateGenerator.java
  24. 10
      src/main/java/a8k/app/service/virtualstate/generator/VirtualSensorStateGenerator.java
  25. 5
      src/main/java/a8k/app/type/TemperatureState.java
  26. 34
      src/main/java/a8k/app/type/a8k/state/SensorState.java
  27. 10
      src/main/java/a8k/app/type/appevent/SpringbootLoadingCompletedEvent.java
  28. 8
      src/main/java/a8k/app/type/param/optpos/OptModuleParam.java
  29. 4
      src/main/java/a8k/app/type/ui/ZAppErrorStackInfo.java
  30. 4
      src/main/java/a8k/app/type/ui/ZAppPromptFormsItem.java
  31. 6
      src/main/java/a8k/app/utils/ZSqlite.java
  32. 89
      src/main/java/a8k/app/utils/ZSqliteJdbcHelper.java
  33. 29
      src/main/java/a8k/extui/page/extsetting/pos_calibration/P04ReactionPlatesTransmitControlerCalibrationPage.java
  34. 9
      src/main/java/a8k/extui/page/factory/opt/OptModuleParamCalibration.java
  35. 6
      src/main/java/a8k/extui/page/factory/verification/P31ReactionPlatesTransmitPosVerificationPage.java
  36. 2
      src/main/java/a8k/extui/page/factory/verification/P34LiquidOperationTestPage.java
  37. 22
      src/main/resources/application.yml

BIN
appresource/db/appbak.db

8
src/main/java/a8k/BoditechA800Application.java

@ -1,7 +1,10 @@
package a8k; package a8k;
import a8k.app.service.background.AppEventBusService;
import a8k.app.type.DeviceRunMode; import a8k.app.type.DeviceRunMode;
import a8k.app.type.appevent.AppEvent;
import a8k.app.type.appevent.SpringbootLoadingCompletedEvent;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
@ -20,6 +23,7 @@ public class BoditechA800Application implements ApplicationListener<ContextRefre
@Resource @Resource
private Environment env; private Environment env;
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(BoditechA800Application.class, args); SpringApplication.run(BoditechA800Application.class, args);
} }
@ -27,6 +31,10 @@ public class BoditechA800Application implements ApplicationListener<ContextRefre
@Override @Override
public void onApplicationEvent(ContextRefreshedEvent event) { public void onApplicationEvent(ContextRefreshedEvent event) {
log.info("Springboot加载完成"); log.info("Springboot加载完成");
AppEventBusService eventBusService = event.getApplicationContext().getBean(AppEventBusService.class);
eventBusService.pushEvent(new SpringbootLoadingCompletedEvent());
String os = System.getProperty("os.name").toLowerCase(); String os = System.getProperty("os.name").toLowerCase();
if (os.contains("windows")) { if (os.contains("windows")) {
if (null == event.getApplicationContext().getParent()) { if (null == event.getApplicationContext().getParent()) {

2
src/main/java/a8k/app/constant/AppVersion.java

@ -1,5 +1,5 @@
package a8k.app.constant; package a8k.app.constant;
public class AppVersion { public class AppVersion {
public static final String APP_VERSION = "B80.CN.01.00.08";
public static final String APP_VERSION = "B80.CN.01.00.10";
} }

1
src/main/java/a8k/app/dao/type/db/DeviceStatistic.java

@ -4,6 +4,7 @@ public class DeviceStatistic {
public enum StatisticType { public enum StatisticType {
TubeHolderCnt, TubeHolderCnt,
EmergencyTubeCnt, EmergencyTubeCnt,
SampleCnt;
} }
public int id; public int id;

4
src/main/java/a8k/app/dao/type/db/ReactionRecord.java

@ -140,8 +140,10 @@ public class ReactionRecord implements Serializable { //记录单个反应板的
public String appVersion;//上层应用版本 public String appVersion;//上层应用版本
@Schema(description = "MCU软件版本") @Schema(description = "MCU软件版本")
public String mcuVersion; // MCU软件版本 public String mcuVersion; // MCU软件版本
@Schema(description = "仪器序列号")
@Schema(description = "仪器序列号-工程序列号")
public String sn; // 仪器序列号 public String sn; // 仪器序列号
@Schema(description = "出厂序列号")
public String assetId; // 出厂序列号
public Integer subProjNum = 0; //子项目数量 public Integer subProjNum = 0; //子项目数量

13
src/main/java/a8k/app/iflytophald/driver/A8kCanBusBaseDriver.java

@ -237,8 +237,17 @@ public class A8kCanBusBaseDriver {
if (statue == ModuleStatus.IDLE) { if (statue == ModuleStatus.IDLE) {
break; break;
} else if (statue == ModuleStatus.ERROR) { } else if (statue == ModuleStatus.ERROR) {
log.error("{} waiting for action {} , catch error {}, detail ecode {}", mid, action, moduleGetError(mid), moduleGetDetailError(mid));
throw AppException.of(new AEHardwareError(moduleGetError(mid), mid, action));
A8kEcode ecode = moduleGetError(mid);
Integer detailError = moduleGetDetailError(mid);
if (ecode.equals(A8kEcode.LOW_ERROR_STEP_MOTOR_LOST_STEP)) {
Integer lostStep = moduleGetReg(mid, RegIndex.kreg_step_motor_lost_step);
log.error("{} waiting for action {} , catch error {}, lost step {}", mid, action, ecode, lostStep);
} else {
log.error("{} waiting for action {} , catch error {}, detail ecode {}", mid, action, ecode, detailError);
}
throw AppException.of(new AEHardwareError(ecode, mid, action));
} }
long now = OS.getMonotonicClockTimestamp(); long now = OS.getMonotonicClockTimestamp();
if (now - startedAt > actionOvertime) { if (now - startedAt > actionOvertime) {

2
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_is_enable(10102), // 是否使能
kreg_step_motor_dpos(10103), // 执行完上一条指令后的相对位移 kreg_step_motor_dpos(10103), // 执行完上一条指令后的相对位移
kreg_step_motor_has_move_zero(10104), // 是否回零 kreg_step_motor_has_move_zero(10104), // 是否回零
kreg_step_motor_lost_step(10105), // 丢失步数
// kreg_step_motor_shift(10150), // x偏移 // kreg_step_motor_shift(10150), // x偏移
kreg_step_motor_shaft(10151), // x轴是否反转 kreg_step_motor_shaft(10151), // x轴是否反转
kreg_step_motor_one_circle_pulse(10152), // x轴一圈脉冲数 kreg_step_motor_one_circle_pulse(10152), // x轴一圈脉冲数

1
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_is_enable(RegIndex.kreg_step_motor_is_enable), // 是否使能
kreg_step_motor_dpos(RegIndex.kreg_step_motor_dpos), // 执行完上一条指令后的相对位移 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_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_shift(RegIndex.kreg_step_motor_shift), // x偏移
kreg_step_motor_shaft(RegIndex.kreg_step_motor_shaft), // 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轴一圈脉冲数 kreg_step_motor_one_circle_pulse(RegIndex.kreg_step_motor_one_circle_pulse), // x轴一圈脉冲数

19
src/main/java/a8k/app/service/background/ProjIDCardCtrlAndMonitorService.java

@ -18,6 +18,7 @@ import a8k.app.utils.ZWorkQueue;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
@ -28,6 +29,7 @@ import org.springframework.stereotype.Component;
@Component @Component
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@EnableScheduling
public class ProjIDCardCtrlAndMonitorService { public class ProjIDCardCtrlAndMonitorService {
private final A8kCanBusBaseDriver canBus; private final A8kCanBusBaseDriver canBus;
@ -83,21 +85,21 @@ public class ProjIDCardCtrlAndMonitorService {
CmdId cmdId = CmdId.valueOf(packet.getCmdId()); CmdId cmdId = CmdId.valueOf(packet.getCmdId());
if (CmdId.event_a8000_idcard_online.equals(cmdId)) { if (CmdId.event_a8000_idcard_online.equals(cmdId)) {
log.info("插入ID卡"); log.info("插入ID卡");
workQueue.addTask(this::readIDCard);
workQueue.addTask(() -> this.readIDCard(true));
} else if (CmdId.event_a8000_idcard_offline.equals(cmdId)) { } else if (CmdId.event_a8000_idcard_offline.equals(cmdId)) {
this.mountedIdCardInfo = null; this.mountedIdCardInfo = null;
eventBus.pushEvent(new AppIDCardUnmountEvent()); eventBus.pushEvent(new AppIDCardUnmountEvent());
log.info("拔出ID卡"); 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卡信息 //读取ID卡信息
byte[] data = null; byte[] data = null;
try { try {
@ -113,7 +115,8 @@ public class ProjIDCardCtrlAndMonitorService {
mountedIdCardInfo = idCardDataParseService.parseAndCheck(data); mountedIdCardInfo = idCardDataParseService.parseAndCheck(data);
ProjBuildInInfo buildinInfo = projInfoMgrService.getProjBuildInInfo(mountedIdCardInfo.projId); ProjBuildInInfo buildinInfo = projInfoMgrService.getProjBuildInInfo(mountedIdCardInfo.projId);
mountedIdCardInfo.color = buildinInfo.color; mountedIdCardInfo.color = buildinInfo.color;
eventBus.pushEvent(new AppIDCardMountEvent(mountedIdCardInfo));
if (pushMountEvent)
eventBus.pushEvent(new AppIDCardMountEvent(mountedIdCardInfo));
} catch (AppException e) { } catch (AppException e) {

6
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.driver.WaterTemperatureControllerDriver;
import a8k.app.iflytophald.type.protocol.TemperatureControlerMid; import a8k.app.iflytophald.type.protocol.TemperatureControlerMid;
import a8k.app.service.setting.AppSettingsMgrService; import a8k.app.service.setting.AppSettingsMgrService;
import a8k.app.service.statemgr.GStateMgrService;
import a8k.app.type.DeviceRunMode;
import a8k.app.type.exception.AppException; import a8k.app.type.exception.AppException;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -18,6 +20,7 @@ public class TemperatureCtrlService {
private final WaterTemperatureControllerDriver waterTemperatureControllerDriver; private final WaterTemperatureControllerDriver waterTemperatureControllerDriver;
private final AppSettingsMgrService appSettingsMgrService; private final AppSettingsMgrService appSettingsMgrService;
private final GStateMgrService gStateMgrService;
@Value("${a8k.enableTemperatureCtrl}") @Value("${a8k.enableTemperatureCtrl}")
Boolean enableTemperatureCtrl = true; Boolean enableTemperatureCtrl = true;
@ -32,6 +35,9 @@ public class TemperatureCtrlService {
if (!enableTemperatureCtrl) { if (!enableTemperatureCtrl) {
return; return;
} }
if (!gStateMgrService.isInMode(DeviceRunMode.RealMode)) {
return;
}
workingFlag = true; workingFlag = true;
var deviceSetting = appSettingsMgrService.getDeviceSetting(); var deviceSetting = appSettingsMgrService.getDeviceSetting();
waterTemperatureControllerDriver.startHearting(TemperatureControlerMid.IncubatorTCM, deviceSetting.getIncubateBoxTemperature().doubleValue()); waterTemperatureControllerDriver.startHearting(TemperatureControlerMid.IncubatorTCM, deviceSetting.getIncubateBoxTemperature().doubleValue());

25
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.AppFlagKey;
import a8k.app.type.DeviceRunMode; import a8k.app.type.DeviceRunMode;
import a8k.app.type.TemperatureRecordPoint; import a8k.app.type.TemperatureRecordPoint;
import a8k.app.type.TemperatureState;
import a8k.app.type.error.AppError; import a8k.app.type.error.AppError;
import a8k.app.type.exception.AppException; import a8k.app.type.exception.AppException;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
@ -102,36 +103,46 @@ public class TemperatureSyncService {
} }
if (!gStateMgrService.isInMode(DeviceRunMode.RealMode)) { 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; return;
} }
try { try {
Double incubateBoxTemp = waterTemperatureControllerDriver.readTemperature(TemperatureControlerMid.IncubatorTCM); Double incubateBoxTemp = waterTemperatureControllerDriver.readTemperature(TemperatureControlerMid.IncubatorTCM);
double incubateBoxTempTarget = (double) appSettingsMgrService.getDeviceSetting().getIncubateBoxTemperature(); 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); addIncubateBoxTemperatureCurve(incubateBoxTemp);
} catch (AppException e) { } catch (AppException e) {
addIncubateBoxTemperatureCurve(0.0); addIncubateBoxTemperatureCurve(0.0);
gStateMgrService.updateIncubateBoxTemperature(0, false);
gStateMgrService.updateIncubateBoxTemperature(0, TemperatureState.Low);
log.warn("Failed to read incubate box temperature: {}", e.getMessage()); log.warn("Failed to read incubate box temperature: {}", e.getMessage());
} }
try { try {
Double pbtemp = waterTemperatureControllerDriver.readTemperature(TemperatureControlerMid.PlatesBoxTCM); Double pbtemp = waterTemperatureControllerDriver.readTemperature(TemperatureControlerMid.PlatesBoxTCM);
double pbtempTarget = (double) appSettingsMgrService.getDeviceSetting().getPlateBoxTemperature(); 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) { } catch (AppException e) {
addPlateBoxTemperatureCurve(0.0); addPlateBoxTemperatureCurve(0.0);
gStateMgrService.updatePboxTemperature(0, false);
gStateMgrService.updatePboxTemperature(0, TemperatureState.Low);
log.warn("Failed to read plate box temperature: {}", e.getMessage()); 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:改成可配置 //TODO:改成可配置
if (Math.abs(nowtemp - targettemp) < 1) { 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;
} }
} }

22
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.common.CommonPage;
import a8k.app.dao.type.db.ReactionRecord; import a8k.app.dao.type.db.ReactionRecord;
import a8k.app.service.background.AppEventBusService; 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.service.statemgr.GStateMgrService;
import a8k.app.type.a8k.opt.OptScanResult; import a8k.app.type.a8k.opt.OptScanResult;
import a8k.app.type.a8k.proj.ProjInfo; import a8k.app.type.a8k.proj.ProjInfo;
@ -25,10 +27,13 @@ import java.util.List;
public class ReactionRecordMgrService { 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 @PostConstruct
public void init() { public void init() {
@ -61,6 +66,7 @@ public class ReactionRecordMgrService {
record.appVersion = gstate.getAppVersion(); record.appVersion = gstate.getAppVersion();
record.mcuVersion = gstate.getMcuVersion(); record.mcuVersion = gstate.getMcuVersion();
record.sn = gstate.getSn(); record.sn = gstate.getSn();
record.assetId = gstate.getAssetId();
record.subProjNum = reactionResults.size(); record.subProjNum = reactionResults.size();
record.projInfoIdCardVersion = projInfo.ext.updateChipVersion; record.projInfoIdCardVersion = projInfo.ext.updateChipVersion;
record.projInfo = projInfo; record.projInfo = projInfo;
@ -70,6 +76,11 @@ public class ReactionRecordMgrService {
record = reactionReportDao.add(record); record = reactionReportDao.add(record);
log.info("addRecord: {}", ZJsonHelper.objectToJson(record)); log.info("addRecord: {}", ZJsonHelper.objectToJson(record));
appEventBusService.pushEvent(new AppNewReactionRecordEvent(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) { public void exportRecordByLIS(Integer id) {
ReactionRecord record = reactionReportDao.findById(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) { public void deleteRecord(Integer id) {

45
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.iflytophald.channel.LisUartCommunicationChannel;
import a8k.app.dao.type.db.LISSetting; import a8k.app.dao.type.db.LISSetting;
import a8k.app.dao.type.db.ReactionRecord; import a8k.app.dao.type.db.ReactionRecord;
import a8k.app.service.background.AppEventBusService;
import a8k.app.service.setting.AppSettingsMgrService; import a8k.app.service.setting.AppSettingsMgrService;
import a8k.app.service.utils.UISender; 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.exception.AppException;
import a8k.app.type.lis.LISDirectionTypeEnum; import a8k.app.type.lis.LISDirectionTypeEnum;
import a8k.app.type.lis.LISIFType; import a8k.app.type.lis.LISIFType;
@ -22,6 +25,7 @@ import org.springframework.stereotype.Component;
public class LisCommunicationService { public class LisCommunicationService {
private final AppSettingsMgrService appSettingsMgrService; private final AppSettingsMgrService appSettingsMgrService;
private final LisUartCommunicationChannel lisUartCommunicationChannel; private final LisUartCommunicationChannel lisUartCommunicationChannel;
private final AppEventBusService appEventBusService;
private LISSetting setting; private LISSetting setting;
@ -30,8 +34,28 @@ public class LisCommunicationService {
@Value("${lis.enable}") @Value("${lis.enable}")
public Boolean lisEnable = true; 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) { public void updateLisSetting(LISSetting lisSetting) {
if (!lisEnable) { if (!lisEnable) {
log.warn("LIS communication is disabled by configuration, ignore updateLisSetting"); log.warn("LIS communication is disabled by configuration, ignore updateLisSetting");
@ -62,12 +86,12 @@ public class LisCommunicationService {
* 上报失败无须向上返回异常, 静默处理即可 * 上报失败无须向上返回异常, 静默处理即可
*/ */
if (lisChannel == null) { if (lisChannel == null) {
log.warn("LIS channel is null, cannot report reaction record.");
return; return;
} }
if (!setting.lisAutoExport) {
return;
}
// if (!setting.lisAutoExport) {
// return;
// }
if (!lisChannel.isConnected()) { if (!lisChannel.isConnected()) {
log.warn("LIS channel is not connected, cannot report reaction record."); log.warn("LIS channel is not connected, cannot report reaction record.");
return; return;
@ -76,22 +100,11 @@ public class LisCommunicationService {
lisChannel.reportReactionRecord(reactionRecord); lisChannel.reportReactionRecord(reactionRecord);
} catch (AppException e) { } catch (AppException e) {
log.warn("LIS 上报失败: {}", e.getMessage(), 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();
}
// //
// !!!构建新的通道 // !!!构建新的通道
// //

16
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.type.exception.AppException;
import a8k.app.dao.type.combination.ProjBuildInInfo; import a8k.app.dao.type.combination.ProjBuildInInfo;
import a8k.app.iflytophald.utils.OptGainConvert; import a8k.app.iflytophald.utils.OptGainConvert;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -93,9 +92,16 @@ public class OptScanModuleLowerCtrlService {
try { try {
a8kCanBusBaseDriver.lockAction(); 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); stepMotorCtrlDriver.stepMotorEasyMoveToZeroPointQuickBlock(StepMotorMId.OptModPullM);
} finally { } finally {
a8kCanBusBaseDriver.unlockAction(); a8kCanBusBaseDriver.unlockAction();
@ -106,7 +112,7 @@ public class OptScanModuleLowerCtrlService {
public void dropPlate() throws AppException { public void dropPlate() throws AppException {
stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerDropPos()); stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerDropPos());
stepMotorCtrlDriver.stepMotorEasyMoveToZeroPointQuickBlock(StepMotorMId.OptModScannerM); stepMotorCtrlDriver.stepMotorEasyMoveToZeroPointQuickBlock(StepMotorMId.OptModScannerM);
stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerScandbyPos());
stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerStandbyPos());
} }
public void forceDropPlate(IncubatorPos turntablePosIndex) throws AppException { public void forceDropPlate(IncubatorPos turntablePosIndex) throws AppException {

3
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.ConsumableGroup;
import a8k.app.type.a8k.pos.IncubatorPos; import a8k.app.type.a8k.pos.IncubatorPos;
import a8k.app.type.exception.AppException; import a8k.app.type.exception.AppException;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -29,7 +28,7 @@ public class PlateBoxCtrlService {
a8kCanBus.lockAction(); a8kCanBus.lockAction();
try { try {
turntableMoveCtrlService.trunableMoveToPushPos(turntablePosIndex);
turntableMoveCtrlService.turntableMoveToPushPos(turntablePosIndex);
stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.PlatesBoxYM, platesBoxPosParamMgr.getChXPos(PBCh.off)); stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.PlatesBoxYM, platesBoxPosParamMgr.getChXPos(PBCh.off));
stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.PlatesBoxPusherM, platesBoxPosParamMgr.getPushEndXPos()); stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.PlatesBoxPusherM, platesBoxPosParamMgr.getPushEndXPos());
stepMotorCtrlDriver.stepMotorEasyMoveToZeroPointQuickBlock(StepMotorMId.PlatesBoxPusherM); stepMotorCtrlDriver.stepMotorEasyMoveToZeroPointQuickBlock(StepMotorMId.PlatesBoxPusherM);

96
src/main/java/a8k/app/service/lowerctrl/TurntableMoveCtrlService.java

@ -19,13 +19,15 @@ import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
public class TurntableMoveCtrlService { public class TurntableMoveCtrlService {
static final Integer overtime = 10000;
private final A8kCanBusBaseDriver canBus;
private final StepMotorCtrlDriver stepMotorCtrlDriver; private final StepMotorCtrlDriver stepMotorCtrlDriver;
private final TurntablePosParamMgr turntablePosParamMgr; private final TurntablePosParamMgr turntablePosParamMgr;
private final InputDetectDriver inputDetectDriver; private final InputDetectDriver inputDetectDriver;
private Integer moveCnt = 0;
private void checkBeforeMoveTurntable() throws AppException { private void checkBeforeMoveTurntable() throws AppException {
//板夹仓卡板检测 //板夹仓卡板检测
if (inputDetectDriver.getIOState(InputIOId.IncubationPlateInletStuckPPS)) { 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(); checkBeforeMoveTurntable();
//限制pos在 0--> 36000之间 //限制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 { } 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());
} }

2
src/main/java/a8k/app/service/module/IncubationPlateCtrlModule.java

@ -120,7 +120,7 @@ public class IncubationPlateCtrlModule {
incubationPlateStateMgr.setIncubationToWaitingForDropState(tank.pos); incubationPlateStateMgr.setIncubationToWaitingForDropState(tank.pos);
} }
docmd("拉取反应板到滴定位", () -> turntableMoveCtrlService.trunableMoveToDropLiquidPos(incubatorPos));
docmd("拉取反应板到滴定位", () -> turntableMoveCtrlService.turntableMoveToDropLiquidPos(incubatorPos));
dropLiquidAction.run(); dropLiquidAction.run();
UISender.txInfoMsg(log, "开始孵育"); UISender.txInfoMsg(log, "开始孵育");
incubationPlateStateMgr.startIncubating(incubatorPos, System.currentTimeMillis(), incubatedTimeSec); incubationPlateStateMgr.startIncubating(incubatorPos, System.currentTimeMillis(), incubatedTimeSec);

24
src/main/java/a8k/app/service/param/optparam/OptModuleParamsMgr.java

@ -19,13 +19,15 @@ public class OptModuleParamsMgr extends ParamMgr {
@PostConstruct @PostConstruct
void initialize() { void initialize() {
for (OptModuleParam pos : OptModuleParam.values()) { for (OptModuleParam pos : OptModuleParam.values()) {
initParam(pos, pos.chName, pos.type);
initParam(pos, pos.chName, pos.type,0);
} }
//校验参数类型 //校验参数类型
getPullerTargetPos();
getOptModuleScanPos();
getOptScanerDropPos(); 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() { public Integer getOptScanerDropPos() {
return getParam(OptModuleParam.OptScanerDropPos, Integer.class); 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);
} }
} }

9
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.BoardVersions;
import a8k.app.type.DeviceRunMode; import a8k.app.type.DeviceRunMode;
import a8k.app.type.GState; import a8k.app.type.GState;
import a8k.app.type.TemperatureState;
import a8k.app.type.error.AppError; import a8k.app.type.error.AppError;
import a8k.app.type.exception.AppException; import a8k.app.type.exception.AppException;
import a8k.app.type.a8k.state.SensorState; import a8k.app.type.a8k.state.SensorState;
@ -44,14 +45,14 @@ public class GStateMgrService {
return this.gState.sensorState; return this.gState.sensorState;
} }
public void updatePboxTemperature(Integer val, Boolean isReady) {
public void updatePboxTemperature(Integer val, TemperatureState state) {
gState.sensorState.setPboxTemperature(val); 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.setIncubateBoxTemperature(val);
gState.sensorState.setIncubateBoxTemperatureReady(isReady);
gState.sensorState.setIncubateBoxTemperatureState(state);
} }
public void updateWasteBinFullFlag(Boolean val) { public void updateWasteBinFullFlag(Boolean val) {

26
src/main/java/a8k/app/service/statemgr/TubeStateMgr.java

@ -156,9 +156,6 @@ public class TubeStateMgr {
String sampleId = newSample(tube); String sampleId = newSample(tube);
tube.setSampleId(sampleId); tube.setSampleId(sampleId);
if (tube.getUserid() == null || tube.getUserid().isEmpty()) {
tube.setUserid(sampleId);
}
Integer off = 0; Integer off = 0;
for (Integer projId : tube.getProjIds()) { for (Integer projId : tube.getProjIds()) {
@ -443,15 +440,20 @@ public class TubeStateMgr {
Integer cnt = 0; Integer cnt = 0;
Date date = new Date(); Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); 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; return sampleid;
} }

4
src/main/java/a8k/app/service/virtualstate/generator/TubeVirtualStateGenerator.java

@ -81,10 +81,10 @@ public class TubeVirtualStateGenerator {
private Tube createFakeTube(Integer pos) { private Tube createFakeTube(Integer pos) {
Tube tube = new Tube(pos); Tube tube = new Tube(pos);
tube.setSampleId("250109_001E0" + pos);
tube.setSampleId(String.format("250109_%03d", pos));
tube.setBloodType(BloodType.WHOLE_BLOOD); tube.setBloodType(BloodType.WHOLE_BLOOD);
tube.setSampleBarcode("112334455667"); tube.setSampleBarcode("112334455667");
tube.setUserid(String.format("250109_%dE", pos));
tube.setUserid(String.format("UID_ABC_%03d", pos));
switch (pos) { switch (pos) {
case 1 -> tube.setState(TubeState.EMPTY); case 1 -> tube.setState(TubeState.EMPTY);

10
src/main/java/a8k/app/service/virtualstate/generator/VirtualIncubationPlateStateGenerator.java

@ -109,21 +109,23 @@ public class VirtualIncubationPlateStateGenerator {
return incubationPlate; return incubationPlate;
} }
Integer cnt = 0;
private void assignSubTankState(IncubationSubTank subtank) { private void assignSubTankState(IncubationSubTank subtank) {
subtank.sampleInfo = new SampleInfo( subtank.sampleInfo = new SampleInfo(
"250109_001E01", 0, false, false, BloodType.WHOLE_BLOOD, "B3A7KK8DKF", "250109_001E" "250109_001E01", 0, false, false, BloodType.WHOLE_BLOOD, "B3A7KK8DKF", "250109_001E"
); );
subtank.sampleInfo.bloodType = BloodType.WHOLE_BLOOD; 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 = new ProjBriefInfo();
subtank.projInfo.projId = 1; subtank.projInfo.projId = 1;
subtank.projInfo.projName = "hsCRP"; subtank.projInfo.projName = "hsCRP";
subtank.projInfo.projShortName = "CA"; subtank.projInfo.projShortName = "CA";
subtank.projInfo.color = "#DC143C"; subtank.projInfo.color = "#DC143C";
subtank.sampleInfo.sampleId = "250109_001E01";
subtank.sampleInfo.sampleId = String.format("250901_%03d",subtank.pos.off);
subtank.projId = 1; subtank.projId = 1;
subtank.lotId = "CA123456"; subtank.lotId = "CA123456";
subtank.isEmergency = false; subtank.isEmergency = false;

2
src/main/java/a8k/app/service/virtualstate/generator/VirtualPreReactionGridGroupStateGenerator.java

@ -85,10 +85,12 @@ public class VirtualPreReactionGridGroupStateGenerator {
case 2 -> { case 2 -> {
gridGroup.grids.get(i).state = PreReactionGrid.State.REACTION_COMPLETED; gridGroup.grids.get(i).state = PreReactionGrid.State.REACTION_COMPLETED;
gridGroup.grids.get(i).sampleInfo.userid = "UID123"; gridGroup.grids.get(i).sampleInfo.userid = "UID123";
gridGroup.grids.get(i).sampleInfo.sampleId = "250809_001";
} }
case 3 -> { case 3 -> {
gridGroup.grids.get(i).state = PreReactionGrid.State.REACTING; gridGroup.grids.get(i).state = PreReactionGrid.State.REACTING;
gridGroup.grids.get(i).sampleInfo.userid = "UID123"; gridGroup.grids.get(i).sampleInfo.userid = "UID123";
gridGroup.grids.get(i).sampleInfo.sampleId = "250809_001";
gridGroup.grids.get(i).reactionRemainingTime = 3 * 60L; gridGroup.grids.get(i).reactionRemainingTime = 3 * 60L;
} }
case 4 -> { case 4 -> {

10
src/main/java/a8k/app/service/virtualstate/generator/VirtualSensorStateGenerator.java

@ -1,6 +1,7 @@
package a8k.app.service.virtualstate.generator; package a8k.app.service.virtualstate.generator;
import a8k.app.service.virtualstate.VirtualStateModeMgr; import a8k.app.service.virtualstate.VirtualStateModeMgr;
import a8k.app.type.TemperatureState;
import a8k.app.type.a8k.state.DeviceWorkState; import a8k.app.type.a8k.state.DeviceWorkState;
import a8k.app.type.a8k.state.SensorState; import a8k.app.type.a8k.state.SensorState;
import a8k.app.type.a8k.state.enumtype.A8kWorkState; import a8k.app.type.a8k.state.enumtype.A8kWorkState;
@ -43,8 +44,9 @@ public class VirtualSensorStateGenerator {
sensorState.setIncubateBoxTemperature(25); sensorState.setIncubateBoxTemperature(25);
sensorState.setWasteBinFullFlag(false); sensorState.setWasteBinFullFlag(false);
cnt++; 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; return sensorState;
} }
@ -53,8 +55,8 @@ public class VirtualSensorStateGenerator {
sensorState.setPboxTemperature(25); sensorState.setPboxTemperature(25);
sensorState.setIncubateBoxTemperature(25); sensorState.setIncubateBoxTemperature(25);
sensorState.setWasteBinFullFlag(false); sensorState.setWasteBinFullFlag(false);
sensorState.setIncubateBoxTemperatureReady(true); //每次调用切换一次状态
sensorState.setPboxTemperatureReady(true); //每次调用切换一次状态
sensorState.setIncubateBoxTemperatureState(TemperatureState.Ready); //每次调用切换一次状态
sensorState.setPboxTemperatureState(TemperatureState.Ready); //每次调用切换一次状态
return sensorState; return sensorState;
} }
} }

5
src/main/java/a8k/app/type/TemperatureState.java

@ -0,0 +1,5 @@
package a8k.app.type;
public enum TemperatureState {
Ready, High, Low,
}

34
src/main/java/a8k/app/type/a8k/state/SensorState.java

@ -1,19 +1,23 @@
package a8k.app.type.a8k.state; package a8k.app.type.a8k.state;
import a8k.app.type.TemperatureState;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
public class SensorState { public class SensorState {
@Schema(description = "板夹仓温度") @Schema(description = "板夹仓温度")
Integer pboxTemperature = 25;
Integer pboxTemperature = 25;
@Schema(description = "板夹仓温度状态")
TemperatureState pboxTemperatureState = TemperatureState.Ready;
@Schema(description = "孵育盒温度") @Schema(description = "孵育盒温度")
Integer incubateBoxTemperature = 25;
Integer incubateBoxTemperature = 25;
@Schema(description = "孵育盒温度状态")
TemperatureState incubateBoxTemperatureState = TemperatureState.Ready;
@Schema(description = "废液桶满标志") @Schema(description = "废液桶满标志")
Boolean wasteBinFullFlag = false;
@Schema(description = "板夹仓温度是否就绪")
Boolean pboxTemperatureReady = false;
@Schema(description = "孵育盒温度是否就绪")
Boolean incubateBoxTemperatureReady = false;
Boolean wasteBinFullFlag = false;
public synchronized Integer getPboxTemperature() { public synchronized Integer getPboxTemperature() {
@ -24,20 +28,20 @@ public class SensorState {
this.pboxTemperature = pboxTemperature; 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() { public synchronized Integer getIncubateBoxTemperature() {

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

8
src/main/java/a8k/app/type/param/optpos/OptModuleParam.java

@ -1,11 +1,13 @@
package a8k.app.type.param.optpos; package a8k.app.type.param.optpos;
public enum OptModuleParam { public enum OptModuleParam {
PullerTargetPos("拉板目标位置", Integer.class),
OptModuleScanPos("光学模组扫描位", Integer.class),
OptModuleEntryPos("光学模组入口位置", Integer.class),
OptScanerDropPos("丢板坐标", 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; public final Class<?> type;
OptModuleParam(String chName, Class<?> type) { OptModuleParam(String chName, Class<?> type) {

4
src/main/java/a8k/app/type/ui/ZAppErrorStackInfo.java

@ -1,5 +1,7 @@
package a8k.app.type.ui; package a8k.app.type.ui;
public class ZAppErrorStackInfo {
import java.io.Serializable;
public class ZAppErrorStackInfo implements Serializable {
public String[] stackTraceElements; public String[] stackTraceElements;
} }

4
src/main/java/a8k/app/type/ui/ZAppPromptFormsItem.java

@ -1,6 +1,8 @@
package a8k.app.type.ui; package a8k.app.type.ui;
public class ZAppPromptFormsItem {
import java.io.Serializable;
public class ZAppPromptFormsItem implements Serializable {
public String name; public String name;
public String description; public String description;

6
src/main/java/a8k/app/utils/ZSqlite.java

@ -20,11 +20,11 @@ public class ZSqlite<T> {
public ZSqlite() { public ZSqlite() {
} }
public void init(JdbcTemplate jdbcTemplate, String tableName, Class<T> tClass, boolean foreceCreate) {
public void init(JdbcTemplate jdbcTemplate, String tableName, Class<T> tClass, boolean forceCreate) {
this.tableName = tableName; this.tableName = tableName;
this.tClass = tClass; this.tClass = tClass;
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
if (foreceCreate) {
if (forceCreate) {
this.forceDeleteTable(); this.forceDeleteTable();
} }
@ -32,6 +32,8 @@ public class ZSqlite<T> {
this.createTable(); this.createTable();
tryInitDBData(); tryInitDBData();
} }
ZSqliteJdbcHelper.fixTable(jdbcTemplate, tableName, tClass);
} }
public void init(JdbcTemplate jdbcTemplate, String tableName, Class<T> tClass) { public void init(JdbcTemplate jdbcTemplate, String tableName, Class<T> tClass) {

89
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.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreatorFactory; import org.springframework.jdbc.core.PreparedStatementCreatorFactory;
import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.GeneratedKeyHolder;
import javax.lang.model.element.TypeElement; 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.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -24,8 +24,8 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@Slf4j
public class ZSqliteJdbcHelper { public class ZSqliteJdbcHelper {
static Logger logger = org.slf4j.LoggerFactory.getLogger(ZSqliteJdbcHelper.class);
static public boolean isTableExist(JdbcTemplate jdbcTemplate, String tableName) { static public boolean isTableExist(JdbcTemplate jdbcTemplate, String tableName) {
String sql = "select * from sqlite_master where type = 'table' and name = '" + 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<String> 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) { static public void createTable(JdbcTemplate jdbcTemplate, String tableName, Class<?> tClass) {
StringBuilder sql = new StringBuilder("create table " + tableName + " ("); 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")) { if (field.getName().equals("id")) {
hasId = true; hasId = true;
} }
sql.append(" '").append(field.getName()).append("' "); 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) { if (!hasId) {
throw new RuntimeException("id field not found in class " + tClass.getName()); throw new RuntimeException("id field not found in class " + tClass.getName());
@ -111,7 +152,7 @@ public class ZSqliteJdbcHelper {
try { try {
String val = rs.getString(field.getName()); String val = rs.getString(field.getName());
if (val != null && !val.isEmpty()) { if (val != null && !val.isEmpty()) {
// logger.info("val: {}", val);
// log.info("val: {}", val);
field.set(obj, objectMapper.readTree(val)); field.set(obj, objectMapper.readTree(val));
} else { } else {
field.set(obj, null); field.set(obj, null);
@ -214,7 +255,7 @@ public class ZSqliteJdbcHelper {
args.add(objectMapper.writeValueAsString(field.get(obj))); args.add(objectMapper.writeValueAsString(field.get(obj)));
} }
} catch (IllegalAccessException | JsonProcessingException e) { } catch (IllegalAccessException | JsonProcessingException e) {
logger.error("", e);
log.error("", e);
args.add(null); args.add(null);
} }
} }

29
src/main/java/a8k/extui/page/extsetting/pos_calibration/P04ReactionPlatesTransmitControlerCalibrationPage.java

@ -60,18 +60,26 @@ public class P04ReactionPlatesTransmitControlerCalibrationPage {
platesBoxPosParamMgr.setPushEndXPos(pos); 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) { public void OptModulePosMgr_setOptScanerDropPos(Integer pos) {
optModuleParamsMgr.setOptParam(OptModuleParam.OptScanerDropPos, 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()); .setParamVal("pos", () -> platesBoxPosParamMgr.getPushEndXPos());
page.newGroup("光学模组基础坐标.校准"); 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) page.addFunction("设置<光学扫描器>丢板坐标", this::OptModulePosMgr_setOptScanerDropPos)
.setParamVal("pos", () -> optModuleParamsMgr.getOptScanerDropPos()); .setParamVal("pos", () -> optModuleParamsMgr.getOptScanerDropPos());
page.addFunction("设置<光学扫描器>扫描待机位", this::OptModulePosMgr_setOptScanerScandbyPos)
.setParamVal("pos", () -> optModuleParamsMgr.getOptScanerScandbyPos());
extApiPageMgr.addPage(page); extApiPageMgr.addPage(page);
} }

9
src/main/java/a8k/extui/page/factory/opt/OptModuleParamCalibration.java

@ -42,7 +42,7 @@ import java.util.Map;
@RequiredArgsConstructor @RequiredArgsConstructor
public class OptModuleParamCalibration { public class OptModuleParamCalibration {
private final OptModuleExtParamsMgr optModuleExtParamsMgr;
private final OptModuleExtParamsMgr optModuleExtParamsMgr;
private final PlateBoxCtrlService plateBoxCtrlService; private final PlateBoxCtrlService plateBoxCtrlService;
private final OptScanModuleLowerCtrlService optScanModuleLowerCtrlService; private final OptScanModuleLowerCtrlService optScanModuleLowerCtrlService;
private final ProjInfoMgrService projInfoMgrService; private final ProjInfoMgrService projInfoMgrService;
@ -87,6 +87,10 @@ public class OptModuleParamCalibration {
optScanModuleLowerCtrlService.pullPlate(IncubatorPos.SPACE01); optScanModuleLowerCtrlService.pullPlate(IncubatorPos.SPACE01);
} }
public void pullPlateToOptModule(IncubatorPos pos) throws AppException {
optScanModuleLowerCtrlService.pullPlate(pos);
}
public void dropPlate() throws AppException { public void dropPlate() throws AppException {
optScanModuleLowerCtrlService.dropPlate(); optScanModuleLowerCtrlService.dropPlate();
@ -199,7 +203,8 @@ public class OptModuleParamCalibration {
var page = extApiPageMgr.newPage(this); var page = extApiPageMgr.newPage(this);
page.newGroup("基础"); page.newGroup("基础");
page.addFunction("推板到光学模组", this::pushOnePlateToOptModule);
page.addFunction("从板夹仓推板到光学模组", this::pushOnePlateToOptModule);
page.addFunction("拉板到光学模组", this::pullPlateToOptModule);
page.addFunction("丢板", this::dropPlate); page.addFunction("丢板", this::dropPlate);
page.newGroup("F光学"); page.newGroup("F光学");

6
src/main/java/a8k/extui/page/factory/verification/P31ReactionPlatesTransmitPosVerificationPage.java

@ -57,15 +57,15 @@ public class P31ReactionPlatesTransmitPosVerificationPage {
} }
public void turntableMoveToDropLiquidPos(IncubatorPos index) throws AppException { public void turntableMoveToDropLiquidPos(IncubatorPos index) throws AppException {
turntableMoveCtrlService.trunableMoveToDropLiquidPos(index);
turntableMoveCtrlService.turntableMoveToDropLiquidPos(index);
} }
public void turntableMoveToPullPos(IncubatorPos index) throws AppException { public void turntableMoveToPullPos(IncubatorPos index) throws AppException {
turntableMoveCtrlService.trunableMoveToPullPos(index);
turntableMoveCtrlService.turntableMoveToPullPos(index);
} }
public void turntableMoveToPushPos(IncubatorPos index) throws AppException { public void turntableMoveToPushPos(IncubatorPos index) throws AppException {
turntableMoveCtrlService.trunableMoveToPushPos(index);
turntableMoveCtrlService.turntableMoveToPushPos(index);
} }

2
src/main/java/a8k/extui/page/factory/verification/P34LiquidOperationTestPage.java

@ -65,7 +65,7 @@ public class P34LiquidOperationTestPage {
public void dropLiquidToReactionPlate(IncubatorPos pos) throws AppException { public void dropLiquidToReactionPlate(IncubatorPos pos) throws AppException {
turntableMoveCtrlService.trunableMoveToDropLiquidPos(pos);
turntableMoveCtrlService.turntableMoveToDropLiquidPos(pos);
liquidOperationCtrService.dropLiquidToReactionPlate(true); liquidOperationCtrService.dropLiquidToReactionPlate(true);
} }

22
src/main/resources/application.yml

@ -1,17 +1,17 @@
#WEB虚拟后端 #WEB虚拟后端
#server.port: 80
#iflytophald.ip: 127.0.0.1
#iflytophald.enable: false
#device.runmode: "VirtualStateGenerateMode"
#lis.enable: false
#PC调试
server.port: 80 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 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 #server.port: 8082
#iflytophald.ip: 192.168.8.10 #iflytophald.ip: 192.168.8.10
@ -26,7 +26,7 @@ lis.enable: false
# #
a8k.enableTemperatureCtrl: false
a8k.enableTemperatureCtrl: true
# ip: 192.168.8.10 # ip: 192.168.8.10

Loading…
Cancel
Save