From 6f338a3d5c3e5b64977c12567433126f0341428d Mon Sep 17 00:00:00 2001 From: zhaohe Date: Sat, 9 Nov 2024 10:48:31 +0800 Subject: [PATCH] update --- src/main/java/a8k/OS.java | 17 +-- .../api/v1/app/assistant/ApiRetTestControler.java | 15 -- .../pagecontrol/ExtApiTabConfig.java | 1 - src/main/java/a8k/hardware/A8kCanBusService.java | 9 +- .../a8k/hardware/type/a8kcanprotocol/A8kEcode.java | 163 ++++++++++----------- .../app/appctrl/AppTubeSettingMgrService.java | 20 ++- .../mainflowctrl/MainFlowCtrlScheduler.java | 4 +- .../mainflowctrl/action/PLATE_OPT_SCAN.java | 4 +- .../action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java | 2 +- .../mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java | 13 +- .../appctrl/mainflowctrl/action/SEQ5_PROCESS.java | 64 +++++--- .../app/appdata/ReactionRecordMgrService.java | 6 +- .../statemgr/IncubationPlateStateMgrService.java | 25 +++- .../statemgr/ProjectContextMgrService.java | 24 +-- .../app/appstate/statemgr/TubeStateMgrService.java | 11 +- .../app/appstate/type/IncubationSubTank.java | 12 +- .../service/app/appstate/type/ProjectContext.java | 117 --------------- .../app/appstate/type/ProjectTaskContext.java | 117 +++++++++++++++ .../ctrlservice/ConsumablesScanCtrlService.java | 1 - .../ctrlservice/DeviceInitCtrlService.java | 5 - .../devicectrl/ctrlservice/HbotCtrlService.java | 2 +- .../ctrlservice/OptScanModuleCtrlService.java | 3 - .../ctrlservice/PlateBoxCtrlService.java | 6 +- .../ctrlservice/TubePreProcesCtrlService.java | 4 +- .../ctrlservice/TurnableMoveCtrlService.java | 6 +- .../devicectrl/exdriver/HbotBaseMoveExDriver.java | 2 +- .../devicectrl/exdriver/TubeTransportExDriver.java | 4 +- .../calibration/OptModuleParamCalibration.java | 5 +- .../calibration/PipetteGunLLDParamCalibration.java | 2 +- .../param/ext_param_mgr/PipetteGunParamExMgr.java | 6 +- .../app/devicectrl/script/DeviceCtrlScripter.java | 20 ++- .../service/app/erroranalyzer/ErrorAnalyzer.java | 26 ++++ .../a8k/service/bases/ActionReactorService.java | 123 ---------------- .../a8k/service/test/MainflowCtrlTestService.java | 2 +- src/main/java/a8k/service/test/PipetteGunTest.java | 2 +- src/main/java/a8k/type/appret/ApiV1Ret.java | 4 +- src/main/java/a8k/type/appret/AppRetV1.java | 4 +- src/main/java/a8k/type/ecode/AECodeError.java | 30 +++- src/main/java/a8k/type/ecode/AECommonError.java | 13 -- .../a8k/type/ecode/AEUnkownExceptionError.java | 22 --- src/main/java/a8k/type/exception/AppException.java | 16 +- .../java/a8k/type/exception/MutiAppException.java | 22 --- .../a8k/type/exception/ZAppInterruptException.java | 7 - .../java/a8k/utils/ActionParallerExceutor.java | 53 ------- src/main/java/a8k/utils/AppExceptionBuilder.java | 1 - .../java/a8k/utils/ProjProcessContextUtils.java | 22 +-- src/main/java/a8k/utils/ZJsonHelper.java | 9 ++ 47 files changed, 417 insertions(+), 629 deletions(-) delete mode 100644 src/main/java/a8k/service/app/appstate/type/ProjectContext.java create mode 100644 src/main/java/a8k/service/app/appstate/type/ProjectTaskContext.java create mode 100644 src/main/java/a8k/service/app/erroranalyzer/ErrorAnalyzer.java delete mode 100644 src/main/java/a8k/service/bases/ActionReactorService.java delete mode 100644 src/main/java/a8k/type/ecode/AECommonError.java delete mode 100644 src/main/java/a8k/type/ecode/AEUnkownExceptionError.java delete mode 100644 src/main/java/a8k/type/exception/MutiAppException.java delete mode 100644 src/main/java/a8k/utils/ActionParallerExceutor.java diff --git a/src/main/java/a8k/OS.java b/src/main/java/a8k/OS.java index c3ed119..3f24493 100644 --- a/src/main/java/a8k/OS.java +++ b/src/main/java/a8k/OS.java @@ -4,22 +4,11 @@ import a8k.hardware.type.a8kcanprotocol.A8kEcode; import a8k.type.exception.AppException; public class OS { - public static void hsleep(int ms) throws AppException { - try { - Thread.sleep(ms); - } catch (InterruptedException e) { - throw new AppException(A8kEcode.OS_INTERRUPT); - } + public static void hsleep(int ms) { + forceSleep(ms); } public static void forceSleep(Integer mills) { -// int end = mills + (int) System.currentTimeMillis(); -// while (System.currentTimeMillis() < end) { -// try { -// threadSleep(50); -// } catch (InterruptedException ignored) { -// } -// } try { threadSleep(mills); } catch (InterruptedException e) { @@ -28,6 +17,6 @@ public class OS { } public static void threadSleep(Integer mills) throws InterruptedException { - Thread.sleep(mills); + Thread.sleep(mills); } } diff --git a/src/main/java/a8k/controler/api/v1/app/assistant/ApiRetTestControler.java b/src/main/java/a8k/controler/api/v1/app/assistant/ApiRetTestControler.java index bcb0826..8225ecd 100644 --- a/src/main/java/a8k/controler/api/v1/app/assistant/ApiRetTestControler.java +++ b/src/main/java/a8k/controler/api/v1/app/assistant/ApiRetTestControler.java @@ -42,13 +42,6 @@ public class ApiRetTestControler { ); } - @Operation(description = "获取通用错误返回值") - @PostMapping("getAppComonError") - public ApiV1Ret getAppComonError() { - return ApiV1Ret.fail(// - new AECommonError("和AppCodeError类似,只不过这个可能是一些通用错误,一般用户碰不到该错误,只是为了方便开发人员排查问题") - ); - } @Operation(description = "获取消耗不足错误返回值,此类错误需要前端提示用户缺少了哪个项目的耗材") @PostMapping("getConsumeNotEnoughError") @@ -66,12 +59,4 @@ public class ApiRetTestControler { ); } - @Operation(description = "获取未知异常错误,此错误发生在,当后台没有捕获到某些异常时,目的是为了辅助后端找到代码BUG,需要显示详细的栈信息") - @PostMapping("getUnkownExceptionError") - public ApiV1Ret getUnkownExceptionError() { - var exception = new AppException(A8kEcode.CODEERROR); - return ApiV1Ret.fail(// - new AEUnkownExceptionError(exception) - ); - } } diff --git a/src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java b/src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java index a457506..c6996c0 100644 --- a/src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java +++ b/src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java @@ -30,7 +30,6 @@ public enum ExtApiTabConfig { A8kPipetteCtrlModule("硬件驱动.移液枪测试", true), StepMotorCtrlDriver("硬件驱动.步进电机测试", false), - ActionReactorService("底层调试.单步调试", false),//OK HbotControlService("HbotControlService", false), TubeTubeFeedingModule("硬件控制.入料模块", false), diff --git a/src/main/java/a8k/hardware/A8kCanBusService.java b/src/main/java/a8k/hardware/A8kCanBusService.java index 5fce634..30b66f2 100644 --- a/src/main/java/a8k/hardware/A8kCanBusService.java +++ b/src/main/java/a8k/hardware/A8kCanBusService.java @@ -7,6 +7,7 @@ import a8k.type.PlateInfo; import a8k.hardware.custom_param_mgr.A8kModCustomParamMgr; import a8k.hardware.type.a8kcanprotocol.*; import a8k.hardware.type.a8kcanprotocol.MId; +import a8k.type.ecode.AECodeError; import a8k.type.ecode.AEHardwareError; import a8k.type.exception.AppException; import a8k.service.bases.appevent.A8kHardwareReport; @@ -166,7 +167,6 @@ public class A8kCanBusService { } - public void plateCodeScanerPushCardAndScan(MId id, Integer finalStopPos) throws AppException { callcmd(id.toInt(), CmdId.plate_code_scaner_push_card_and_scan.toInt(), finalStopPos); } @@ -307,7 +307,7 @@ public class A8kCanBusService { } else if (ioid.mtype == ModuleType.kmini_servo_motor_module) { return callcmd(ioid.mid.toInt(), CmdId.mini_servo_read_io_state.toInt(), ioid.ioIndex).getContentI32(0) != 0; } else { - throw AppException.of(new AEHardwareError(A8kEcode.CODEERROR_ILLEGAL_OPERATION, ioid.mid, null)); + throw new AppException(new AECodeError(String.format("IOID MODULE TYPE %s NOT SUPPORT", ioid.mtype))); } } @@ -328,8 +328,7 @@ public class A8kCanBusService { if (ioid.mtype == ModuleType.kboard) { callcmd(ioid.mid.toInt(), CmdId.extboard_write_outio.toInt(), ioid.ioIndex, val ? 1 : 0); } else { - // throw new AppException(ioid.mid, A8kEcode.IllegalOperation.index); - throw AppException.of(new AEHardwareError(A8kEcode.CODEERROR_ILLEGAL_OPERATION, ioid.mid, null)); + throw new AppException(new AECodeError("IOID MODULE TYPE %s NOT SUPPORT", ioid.mtype)); } } @@ -426,7 +425,7 @@ public class A8kCanBusService { CmdId cmdid = CmdId.valueOf(pack.getCmdId()); if (cmdid == null) { // throw new AppException(MId.valueOf(pack.getModuleId()), A8kEcode.CmdNotSupport.index); - throw AppException.of(new AEHardwareError(A8kEcode.CODEERROR_CMD_NOT_SUPPORT, MId.valueOf(pack.getModuleId()), null)); + throw AppException.of(new AEHardwareError(A8kEcode.LOW_EXT_ERROR_CMD_NOT_SUPPORT, MId.valueOf(pack.getModuleId()), null)); } if (debugFlag && pack.isTrace()) { String packstr = pack.toString(); diff --git a/src/main/java/a8k/hardware/type/a8kcanprotocol/A8kEcode.java b/src/main/java/a8k/hardware/type/a8kcanprotocol/A8kEcode.java index 075cff9..40606d4 100644 --- a/src/main/java/a8k/hardware/type/a8kcanprotocol/A8kEcode.java +++ b/src/main/java/a8k/hardware/type/a8kcanprotocol/A8kEcode.java @@ -1,88 +1,80 @@ package a8k.hardware.type.a8kcanprotocol; +/** + * 错误分类 + * 10, + * 为代码错误,代码没有BUG的情况下,这个错误时不会出现的,前端打印出错误,和错误携带的栈信息,方便产品维护时,非程序员能够提供详细的错误的信息。 + * + * + * + * + * + */ public enum A8kEcode { SUC(0), - MUTI_APPEXCEPTIONS(1),//内置,无需关心 - COMMON_ERROR(2),//通用错误,只需显示携带错误信息 - /* - * 代码错误,代码没有BUG的情况下,不应该出现的错误 - */ + // + // 代码错误,代码没有BUG的情况下,前端直接打印错误信息和栈信息即可 + // CODEERROR(10), //代码错误 - CODEERROR_GET_PARAM_FAIL(11), //代码错误,获取参数失败 - CODEERROR_PARSE_PARAM_FAIL(12), //代码错误,解析参数失败 - CODEERROR_UNKOWN_EXCEPTION(13), //代码错误,未知异常 - CODEERROR_UNKOWN_ERROR(14), //代码错误,未知错误 - CODEERROR_ILLEGAL_OPERATION(15),//代码错误,非法操作 - CODEERROR_PARAM_OUT_OF_RANGE(16), //代码错误,参数超出范围 - CODEERROR_CMD_NOT_SUPPORT(17), //代码错误,命令不支持 - CODEERROR_ZM_NOT_AT_ZERO_POS_WHEN_HBOT_TRY_MOVE(18),//Z轴电机不在Z轴位置 - CODEERROR_SHAKE_MOD_GRIPPER_ZMOTOR_NOT_IN_ZERO_POS(19), //摇匀模组Z轴向电机不在零点 - CODEERROR_MOTOR_NOT_IN_ZERO_POS(20),//电机不在零点 - CODEERROR_END(50), - - - /* - * 用户错误 - */ - USR_ALREADY_EXIST(100),//用户已存在 - USR_NOT_EXIT(101), //用户不存在 - USR_PASSWORD_ERROR(102),//用户密码错误 - - /* - * 业务流程中的错误,要求通过错误码能够定位到业务流中的哪个点发生的错误 - */ - APPE_PUT_TIP_FAIL(200),//丢弃tip失败 - APPE_TAKE_TIP_FAIL(201),//取tip失败 - APPE_PLATE_STUCK_DETECTOR_SENSOR_TRIGGER(202),//卡板检测传感器触发 - APPE_PULLERM_INIT_POS_ERROR(203),//初始化阶段,拉板电机处于错误位置(没有在零点) - APPE_PUSHERM_INIT_POS_ERROR(204),//初始化阶段,推板电机处于错误位置(没有在零点) - APPE_PULL_PLATE_FAIL(205),//推板失败 - APPE_SCAN_TIMEOUT(206),//扫描超时 - APPE_SCAN_TUBEHOLDER_TYPE_TIMEOUT(207),//扫描试管架类型超时 - APPE_TUBE_X_CHANNEL_IS_NOT_EMPTY(208),//试管架通道有异物 - APPE_INFEED_OVERTIME_FAIL(209),//入料超时失败 - APPE_EJECT_TUBEHOLDER_TIMEOUT(210),//弹出试管架超时 - APPE_PLATE_BOX_NOT_COVER(211),//板夹仓未盖 - APPE_RECYCLE_BIN_OVERFLOW(212),//废料箱满 - APPE_DEVICE_NOT_INITED(213), //设备未初始化 - APPE_A8K_ID_CARD_NOT_MOUNTED(214),//ID卡未挂载 - APPE_A8K_PLATE_2D_CODE_FORMAT_ERROR(215),//巴迪泰反应板2D码格式错误 - APPE_A8K_ID_CARD_LOT_ID_IS_EMPTY(216),//ID卡批号为空 - APPE_NO_TUBE_IN_HOLDER(217),//试管架中没有试管 - APPE_TUBE_HOLDER_SETTING_IS_LOCKED(218),//试管架设置被锁定 - APPE_TUBE_HOLDER_SETTING_NOT_FOUND(219),//试管架设置未找到 - APPE_TUBE_HOLDER_TYPE_IS_NOT_SUPPORT(220),//试管架类型不支持 - APPE_EMERGENCY_SAMPLE_IS_PROCESSING(221),//急诊样本正在处理中 + // + // 参数错误 + // + PE_PARAM_OUT_OF_RANGE(100),//参数超出范围 + // + // 用户错误 + // + USR_ALREADY_EXIST(110),//用户已存在 + USR_NOT_EXIT(111), //用户不存在 + USR_PASSWORD_ERROR(112),//用户密码错误 + // + // ID卡错误 + // + APPE_A8K_ID_CARD_NOT_MOUNTED(120), //ID卡未挂载 + // + // 试管配置管理服务相关错误码 + // + APPE_TUBE_HOLDER_SETTING_IS_LOCKED(130),//试管架设置被锁定,已锁定的,说明当前后台正在使用这个配置,是不允许修改 + // + // 急诊错误 + // + APPE_EMERGENCY_SAMPLE_IS_PROCESSING(141), //添加急诊样本失败,急诊样本还没有处理完成 (这个错误发生在前端,没有做好状态检测) + APPE_ADD_EMERGENCY_ACTION_IS_NOT_ALLOWED_WHEN_WORKING(142),//添加急诊样本失败,设备正在运行中 (这个错误发生在前端,没有做好状态检测) + // + // 业务流程中的错误 + // 1. 点击开始运行后,设备在运行过程中出现的错误 + // 2. 下面错误,中文情况下,直接显示注释信息即可 + // + //入料阶段错误 + APPE_SCAN_TUBEHOLDER_TYPE_TIMEOUT(200),//扫描试管架类型超时 + APPE_TUBE_HOLDER_TYPE_IS_NOT_SUPPORT(201),//试管架类型不支持 + APPE_INFEED_OVERTIME_FAIL(202),//入料超时失败 + + //样本处理过程中的错误 + APPE_PUT_TIP_FAIL(210),//丢弃Tip失败 + APPE_TAKE_TIP_FAIL(211),//取Tip失败 + + //出料阶段错误 + APPE_EJECT_TUBEHOLDER_TIMEOUT(220),//弹出试管架超时 + APPE_NO_TUBE_IN_HOLDER(221),//试管架中没有试管 APPE_CONSUME_NOT_ENOUGH(222),//耗材不足 APPE_TIP_NOT_ENOUGH(223),//tip不足 - APPE_TAKE_TUBE_FAIL(224),//取试管失败 - APPE_ACTION_IS_NOT_ALLOWED_WHEN_WORKING(228),//设备运行中下不允许执行该操作 - - - /** - * OS错误 - */ - OS_INTERRUPT(500),//Sleep被中断 - - APPE_A8K_PROJ_CARD_PARSE_ERROR(600), //ID卡解析错误 - APPE_A8K_PROJ_CARD_EXPIRYED(601), //ID卡过期 - APPE_A8K_PROJ_ID_IS_EMPTY(602), //项目ID为空 - APPE_A8K_PROJ_UNSUPPORTED(603), //项目不支持 - APPE_A8K_PROJ_INFO_IS_ERROR(604), //项目信息异常 - - /* - * 调试使用,无需关心 - */ - ACTION_REACTOR_SERVICE_BREAKBYUSR(900),// - TEST_SCRIP_ERROR_DEVICE_IS_BUSY(901), - - - //校验流程错误 + //运行中的公用错误 + APPE_A8K_PROJ_CARD_PARSE_ERROR(300), //ID卡解析错误 + APPE_A8K_PROJ_CARD_EXPIRYED(301), //ID卡过期 + APPE_A8K_PROJ_ID_IS_EMPTY(302), //项目ID为空 + APPE_A8K_PROJ_UNSUPPORTED(303), //项目不支持 + APPE_A8K_PROJ_INFO_IS_ERROR(304), //项目信息异常 + APPE_PULLERM_INIT_POS_ERROR(305), //初始化阶段,拉板电机没有处于零点位置 + APPE_PUSHERM_INIT_POS_ERROR(306), //初始化阶段,推板电机没有处于零点位置 + APPE_PLATE_STUCK_DETECTOR_SENSOR_TRIGGER(307), //卡板检测传感器触发 + APPE_TUBE_X_CHANNEL_IS_NOT_EMPTY(308), //试管架通道有异物 + APPE_PLATE_BOX_NOT_COVER(309), //板夹仓未盖 + APPE_DEVICE_NOT_INITED(310), //设备未初始化 // - // LowBoard 底层错误,按照字面意思翻译即可,或者不翻译,直接打印错误英文 + // LowBoard 底层错误,直接打印错误英文 // LOW_ERROR_HARDWARE_ERROR_START(1000), LOW_ERROR_BOARD_COMMON_ERROR(1001), @@ -159,8 +151,15 @@ public enum A8kEcode { LOW_ERROR_WATER_COOLING_TEMPERATURE_SENSOR_ERROR(1902), LOW_ERROR_WATER_COOLING_PUMP_IS_ERROR(1903), LOW_ERROR_WATER_COOLING_PELTER_IS_ERROR(1904), + // + // 底层扩展错误码,由java定义 + // + LOW_EXT_ERROR_UNKOWN_INDEX_ERROR(5000), //代码错误,未知错误 + LOW_EXT_ERROR_CMD_NOT_SUPPORT(5001), //代码错误,未知错误 + LOW_EXT_ERROR_MOTOR_AT_WRONG_POS(5002),//电机在错误的位置 ; + public final int index; public int rawindex = 0; @@ -168,9 +167,6 @@ public enum A8kEcode { this.index = index; } - public int toInt() { - return index; - } static public A8kEcode fromInt(int index) { for (var e : A8kEcode.values()) { @@ -178,18 +174,9 @@ public enum A8kEcode { return e; } } - A8kEcode.CODEERROR_UNKOWN_ERROR.rawindex = index; - return A8kEcode.CODEERROR_UNKOWN_ERROR; + A8kEcode.LOW_EXT_ERROR_UNKOWN_INDEX_ERROR.rawindex = index; + return A8kEcode.LOW_EXT_ERROR_UNKOWN_INDEX_ERROR; } - public static String toDisPlayString(int id) { - for (var e : A8kEcode.values()) { - if (e.index == id) { - return e.name(); - } - } - return String.format("unkown(%d)", id); - } - } diff --git a/src/main/java/a8k/service/app/appctrl/AppTubeSettingMgrService.java b/src/main/java/a8k/service/app/appctrl/AppTubeSettingMgrService.java index a7e4735..9683695 100644 --- a/src/main/java/a8k/service/app/appctrl/AppTubeSettingMgrService.java +++ b/src/main/java/a8k/service/app/appctrl/AppTubeSettingMgrService.java @@ -42,7 +42,7 @@ public class AppTubeSettingMgrService { private TubeHolderSetting getTubeHolderSettingAndCheckIsEditable(String uuid) throws AppException { TubeHolderSetting setting = getTubeHolderSetting(uuid); if (setting == null) { - throw new AppException(A8kEcode.APPE_TUBE_HOLDER_SETTING_NOT_FOUND); + return null; } if (setting.lock) { throw new AppException(A8kEcode.APPE_TUBE_HOLDER_SETTING_IS_LOCKED); @@ -71,21 +71,28 @@ public class AppTubeSettingMgrService { synchronized public void removeTubeHolderSetting(String uuid) throws AppException { logger.info("removeTubeHolderSetting {}", uuid); - getTubeHolderSettingAndCheckIsEditable(uuid); - tubeHolderSettings.removeIf(setting -> setting.uuid.equals(uuid)); + var setting = getTubeHolderSettingAndCheckIsEditable(uuid); + if (setting == null) + return; + tubeHolderSettings.remove(setting); } synchronized public void updateActiveState(String uuid, Boolean active) throws AppException { logger.info("tubeHodlerSettingSetActiveState {} {}", uuid, active); TubeHolderSetting setting = getTubeHolderSettingAndCheckIsEditable(uuid); - + if (setting == null) { + return; + } setting.active = active; } synchronized public void resetTubeSetting(String uuid, Integer tubeIndex) throws AppException { logger.info("resetTubeSetting {} {}", uuid, tubeIndex); TubeHolderSetting thSetting = getTubeHolderSettingAndCheckIsEditable(uuid); + if (thSetting == null) { + return; + } thSetting.tubeSettings[tubeIndex].reset(); } @@ -94,10 +101,11 @@ public class AppTubeSettingMgrService { logger.info("updateTubeSetting {} {}", uuid, setting); TubeHolderSetting thSetting = getTubeHolderSetting(uuid); if (thSetting == null) { - throw AppException.of("无效UUID"); + logger.warn("无效UUID"); + return; } if (setting.tubeIndex >= thSetting.tubeSettings.length) { - throw AppException.of("tubeIndex参数错误"); + throw AppException.ofAECodeError("tubeIndex参数错误"); } thSetting.tubeSettings[setting.tubeIndex] = setting; diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java index 0d2a881..d241e1e 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java @@ -8,7 +8,7 @@ import a8k.service.app.appstate.type.DeviceWorkState; import a8k.service.app.appstate.type.state.A8kWorkState; import a8k.service.bases.AppEventBusService; import a8k.service.bases.appevent.A8kEcodeContextListPromptEvent; -import a8k.type.ecode.AEUnkownExceptionError; +import a8k.type.ecode.AECodeError; import a8k.type.ecode.AppError; import a8k.type.exception.AppException; import jakarta.annotation.Resource; @@ -165,7 +165,7 @@ public class MainFlowCtrlScheduler implements ApplicationListener doOptScanXX(ProjectContext cxt) throws AppException { + List doOptScanXX(ProjectTaskContext cxt) throws AppException { List reactionResults = new ArrayList<>(); if (virtualDevice.isEnable()) { diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java index d9362c1..52bd90e 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java @@ -191,7 +191,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { //如果测试模式设置好了试管扫描结果,那么直接使用虚拟扫描结果 if (testModeState.getVirtualTubeScanResult() != null) { if (result != null && result.isHasTubeInIt()) { - throw AppException.of("试管架中有试管,但是测试模式中设置了虚拟试管扫描结果"); + throw AppException.ofAECodeError("试管架中有试管,但是测试模式中设置了虚拟试管扫描结果"); } result = testModeState.getVirtualTubeScanResult(); } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java index 2537e8e..73d86bd 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java @@ -7,7 +7,7 @@ import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction; import a8k.service.app.appctrl.mainflowctrl.base.MainFlowProcesser; import a8k.service.app.appdata.ProjInfoMgrService; import a8k.service.app.appstate.statemgr.*; -import a8k.service.app.appstate.type.ProjectContext; +import a8k.service.app.appstate.type.ProjectTaskContext; import a8k.service.app.appstate.type.Tube; import a8k.service.app.appstate.type.state.TubeState; import a8k.service.bases.AppEventBusService; @@ -18,11 +18,8 @@ import a8k.type.ecode.AEConsumeNotEnoughError; import a8k.type.ecode.AppError; import a8k.type.pos.Consumable; import a8k.type.pos.TipPos; -import a8k.utils.ProjBuildinInfo; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.Assert; @@ -140,8 +137,8 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { break; } - ProjExtInfoCard projInfo = projConfigMgrService.getProjExtInfoCard(consumable.getLotid()); - ProjectContext cxt = projectContextMgrService.findCxt(tube.getSampleId(), toDoProj.getProjId()); + ProjExtInfoCard projInfo = projConfigMgrService.getProjExtInfoCard(consumable.getLotid()); + ProjectTaskContext cxt = projectContextMgrService.findCxt(tube.getSampleId(), toDoProj.getProjId()); cxt.setConsumable(consumable); cxt.setTipPos(tipPos); cxt.setIncubatorPos(incubatorPos); @@ -153,12 +150,12 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { void backProjectResource(Tube tube) { for (var toDoProj : tube.getProjInfo()) { - ProjectContext cxt = projectContextMgrService.findCxt(tube.getSampleId(), toDoProj.getProjId()); + ProjectTaskContext cxt = projectContextMgrService.findCxt(tube.getSampleId(), toDoProj.getProjId()); backProjectResource(cxt); } } - void backProjectResource(ProjectContext cxt) { + void backProjectResource(ProjectTaskContext cxt) { var consumable = cxt.getConsumable(); var tipPos = cxt.getTipPos(); var incubatorPos = cxt.getIncubatorPos(); diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java index bcb9f6a..10dc887 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java @@ -7,13 +7,14 @@ import a8k.service.app.appctrl.mainflowctrl.base.*; import a8k.service.app.appstate.statemgr.IncubationPlateStateMgrService; import a8k.service.app.appstate.statemgr.ProjectContextMgrService; import a8k.service.app.appstate.statemgr.TubeStateMgrService; -import a8k.service.app.appstate.type.ProjectContext; +import a8k.service.app.appstate.type.ProjectTaskContext; import a8k.service.app.appstate.type.Tube; import a8k.service.app.appstate.type.TubeHolder; import a8k.service.app.appstate.type.state.TubeState; import a8k.service.app.devicectrl.ctrlservice.PlateBoxCtrlService; import a8k.service.app.devicectrl.ctrlservice.TubePreProcesCtrlService; import a8k.service.app.devicectrl.script.DeviceCtrlScripter; +import a8k.service.app.erroranalyzer.ErrorAnalyzer; import a8k.service.test.state.TestModeState; import a8k.service.test.state.VirtualDevice; import a8k.type.IncubatorPos; @@ -63,9 +64,9 @@ public class SEQ5_PROCESS extends A8kStepAction { // Base // @Resource - TestModeState testModeState; + TestModeState testModeState; @Resource - VirtualDevice virtualDevice; + VirtualDevice virtualDevice; // //State // @@ -76,16 +77,16 @@ public class SEQ5_PROCESS extends A8kStepAction { @Resource PublicAreaResourceMgr publicAreaResourceMgr; @Resource - TubeStateMgrService tubeStateMgrService; + TubeStateMgrService tubeStateMgrService; // // CtrlService // @Resource - DeviceCtrlScripter deviceCtrlScripter; + DeviceCtrlScripter deviceCtrlScripter; @Resource - PlateBoxCtrlService plateBoxCtrlService; + PlateBoxCtrlService plateBoxCtrlService; @Resource - TubePreProcesCtrlService tubePreProcesCtrlService; + TubePreProcesCtrlService tubePreProcesCtrlService; // @@ -101,6 +102,7 @@ public class SEQ5_PROCESS extends A8kStepAction { BoolCondition sampleIsReady = new BoolCondition(); BoolCondition sampleProcessFinished = new BoolCondition(); + //待设置状态的孵育盘 List incubationStateCache = new ArrayList<>(); @@ -126,18 +128,16 @@ public class SEQ5_PROCESS extends A8kStepAction { @Override public List doAction() { - if(virtualDevice.isEnable()){ - futures.add(doActionTask("sampleProcess", this::samplePrepareVirtual)); - futures.add(doActionTask("paltePrepare", this::paltePrepareVirtual)); - futures.add(doActionTask("sampleProcess", this::sampleProcessVirtual)); - }else{ - - futures.add(doActionTask("sampleProcess", this::samplePrepare)); - futures.add(doActionTask("paltePrepare", this::paltePrepare)); - futures.add(doActionTask("sampleProcess", this::sampleProcess)); - } - + if (virtualDevice.isEnable()) { + futures.add(doActionTask("sampleProcess", this::samplePrepareVirtual)); + futures.add(doActionTask("paltePrepare", this::paltePrepareVirtual)); + futures.add(doActionTask("sampleProcess", this::sampleProcessVirtual)); + } else { + futures.add(doActionTask("sampleProcess", this::samplePrepare)); + futures.add(doActionTask("paltePrepare", this::paltePrepare)); + futures.add(doActionTask("sampleProcess", this::sampleProcess)); + } return wait(futures); } @@ -146,10 +146,27 @@ public class SEQ5_PROCESS extends A8kStepAction { */ @Override public List afterDoAction(List errors) { + + Tube tube = tubeStateMgrService.getCurProcessingTube(); + List ctxs = projectContextMgrService.findCxts(tube.getSampleId()); + if (!errors.isEmpty()) { - return errors; + if (ErrorAnalyzer.isContainFatalError(errors)) { + return errors; + } + + for (ProjectTaskContext cxt : ctxs) { + incubationPlateStateMgrService.setIncubationToErrorState(cxt.getIncubatorPos(), errors); + } + tubeStateMgrService.changeTubeStateToError(errors); + return List.of(); } + + tubeStateMgrService.changeTubeStateToProcessed(); + for (IncubationStateCache cache : incubationStateCache) { + incubationPlateStateMgrService.startIncubating(cache.pos, cache.startIncubatedTime, cache.incubatedTimeSec); + } return List.of(); } @@ -233,9 +250,9 @@ public class SEQ5_PROCESS extends A8kStepAction { // REAL // - List cxts = projectContextMgrService.findCxts(tube.getSampleId()); + List cxts = projectContextMgrService.findCxts(tube.getSampleId()); - for (ProjectContext cxt : cxts) { + for (ProjectTaskContext cxt : cxts) { IncubatorPos incubatorPos = cxt.getIncubatorPos(); try ( @@ -245,7 +262,6 @@ public class SEQ5_PROCESS extends A8kStepAction { plateBoxCtrlService.pushPlateQuick(cxt.getConsumable().getGroup(), incubatorPos); } - reactionPlateReady.set(); } } @@ -256,14 +272,14 @@ public class SEQ5_PROCESS extends A8kStepAction { //准备第一个项目的tip头 - List cxts = projectContextMgrService.findCxts(tube.getSampleId()); + List cxts = projectContextMgrService.findCxts(tube.getSampleId()); Assert.isTrue(!cxts.isEmpty(), "项目上下文不能为空"); try ( var ignored = publicAreaResourceMgr.apply(PublicAreaResource.HbotArea); ) { - for (ProjectContext cxt : cxts) { + for (ProjectTaskContext cxt : cxts) { deviceCtrlScripter.doSampleProcessPrepare(cxt); sampleIsReady.waitTrue(); deviceCtrlScripter.doSampleProcess(cxt); diff --git a/src/main/java/a8k/service/app/appdata/ReactionRecordMgrService.java b/src/main/java/a8k/service/app/appdata/ReactionRecordMgrService.java index d506566..494d4e1 100644 --- a/src/main/java/a8k/service/app/appdata/ReactionRecordMgrService.java +++ b/src/main/java/a8k/service/app/appdata/ReactionRecordMgrService.java @@ -3,7 +3,7 @@ package a8k.service.app.appdata; import a8k.service.dao.ReactionRecordDao; import a8k.service.dao.type.ReactionResultRecord; import a8k.service.app.appstate.GStateService; -import a8k.service.app.appstate.type.ProjectContext; +import a8k.service.app.appstate.type.ProjectTaskContext; import a8k.type.ReactionResult; import a8k.type.db.CommonPage; import a8k.utils.ZJsonHelper; @@ -34,11 +34,11 @@ public class ReactionRecordMgrService { } - public void addRecord(ProjectContext projContext, List results) { + public void addRecord(ProjectTaskContext projContext, List results) { addRecord(projContext, results.toArray(new ReactionResult[0])); } - public void addRecord(ProjectContext projContext, ReactionResult... reactionResults) { + public void addRecord(ProjectTaskContext projContext, ReactionResult... reactionResults) { if (reactionResults == null || reactionResults.length == 0) { return; } diff --git a/src/main/java/a8k/service/app/appstate/statemgr/IncubationPlateStateMgrService.java b/src/main/java/a8k/service/app/appstate/statemgr/IncubationPlateStateMgrService.java index bac64bf..5ec2a96 100644 --- a/src/main/java/a8k/service/app/appstate/statemgr/IncubationPlateStateMgrService.java +++ b/src/main/java/a8k/service/app/appstate/statemgr/IncubationPlateStateMgrService.java @@ -3,14 +3,17 @@ package a8k.service.app.appstate.statemgr; import a8k.service.app.appstate.GStateService; import a8k.service.app.appstate.type.IncubationPlate; import a8k.service.app.appstate.type.IncubationSubTank; +import a8k.service.app.appstate.type.SampleInfo; import a8k.service.app.appstate.type.state.IncubationSubTankState; import a8k.type.IncubatorPos; +import a8k.type.ecode.AppError; import cn.hutool.core.util.ObjectUtil; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.Date; +import java.util.List; @Component @Slf4j @@ -105,6 +108,17 @@ public class IncubationPlateStateMgrService { } } + synchronized public void setIncubationToErrorState(IncubatorPos pos, List errors) { + var subtanks = incubationPlate.subtanks; + for (IncubationSubTank subtank : subtanks) { + if (subtank.getPos().equals(pos)) { + subtank.state = IncubationSubTankState.ERROR; + subtank.errors = errors; + break; + } + } + } + synchronized public void resetAll() { var subtanks = incubationPlate.subtanks; for (IncubationSubTank subtank : subtanks) { @@ -112,12 +126,17 @@ public class IncubationPlateStateMgrService { } } + synchronized public void syncSampleInfo(IncubatorPos pos,SampleInfo sampleInfo){ + var subtanks = incubationPlate.subtanks; + subtanks[pos.off] + + } - synchronized public void startIncubating(IncubatorPos pos, Integer incubationTimeMin) { + synchronized public void startIncubating(IncubatorPos pos, Long startIncubatedTime,Integer incubatedTimeSec) { var subtanks = incubationPlate.subtanks; subtanks[pos.off].state = IncubationSubTankState.INCUBATING; - subtanks[pos.off].startIncubatedTime = System.currentTimeMillis(); - subtanks[pos.off].incubatedTimeSec = incubationTimeMin * 60; + subtanks[pos.off].startIncubatedTime = startIncubatedTime; + subtanks[pos.off].incubatedTimeSec = incubatedTimeSec; log.info("{} 开始孵育,开始时间:{},孵育时间:{}s", subtanks[pos.off].getPos(), subtanks[pos.off].startIncubatedTime, subtanks[pos.off].incubatedTimeSec); } diff --git a/src/main/java/a8k/service/app/appstate/statemgr/ProjectContextMgrService.java b/src/main/java/a8k/service/app/appstate/statemgr/ProjectContextMgrService.java index 209cd93..113d743 100644 --- a/src/main/java/a8k/service/app/appstate/statemgr/ProjectContextMgrService.java +++ b/src/main/java/a8k/service/app/appstate/statemgr/ProjectContextMgrService.java @@ -27,11 +27,11 @@ public class ProjectContextMgrService { @Resource ConsumablesMgrService consumablesMgrService; - List contexts = new ArrayList<>(); + List contexts = new ArrayList<>(); private void priRemoveCxt(String sampleId) { - List toBeRemoved = new ArrayList<>(); - for (ProjectContext cxt : contexts) { + List toBeRemoved = new ArrayList<>(); + for (ProjectTaskContext cxt : contexts) { if (cxt.getSampleInfo().sampleId.equals(sampleId)) { log.info("移除项目处理上下文 sampleId:{} projId:{}", sampleId, cxt.getSampleInfo().projId); toBeRemoved.add(cxt); @@ -55,11 +55,11 @@ public class ProjectContextMgrService { sampleInfo.tubeHolderType = holder != null ? holder.getTubeHolderType() : null; - ProjectContext projectContext = new ProjectContext(String.format("S{}-P{}", tube.getSampleId(), projId), sampleInfo); - projectContext.setProjBuildinInfo(buildinInfo); + ProjectTaskContext projectTaskContext = new ProjectTaskContext(String.format("S{}-P{}", tube.getSampleId(), projId), sampleInfo); + projectTaskContext.setProjBuildinInfo(buildinInfo); - contexts.add(projectContext); - log.info("newProjCxt {}", ZJsonHelper.objectToJson(projectContext)); + contexts.add(projectTaskContext); + log.info("newProjCxt {}", ZJsonHelper.objectToJson(projectTaskContext)); } synchronized public void newCxt(TubeHolder holder, Tube tube, List buildinInfos) { @@ -86,8 +86,8 @@ public class ProjectContextMgrService { // // findCxt // - synchronized public ProjectContext findCxt(String sampleId, Integer projId) { - for (ProjectContext context : contexts) { + synchronized public ProjectTaskContext findCxt(String sampleId, Integer projId) { + for (ProjectTaskContext context : contexts) { SampleInfo sampleInfo = context.getSampleInfo(); if (sampleInfo.sampleId.equals(sampleId) && sampleInfo.projId.equals(projId)) { return context; @@ -96,9 +96,9 @@ public class ProjectContextMgrService { return null; } - synchronized public List findCxts(String sampleId) { - List ret = new ArrayList<>(); - for (ProjectContext context : contexts) { + synchronized public List findCxts(String sampleId) { + List ret = new ArrayList<>(); + for (ProjectTaskContext context : contexts) { SampleInfo sampleInfo = context.getSampleInfo(); if (sampleInfo.sampleId.equals(sampleId)) { ret.add(context); diff --git a/src/main/java/a8k/service/app/appstate/statemgr/TubeStateMgrService.java b/src/main/java/a8k/service/app/appstate/statemgr/TubeStateMgrService.java index 62ad141..bfc5db4 100644 --- a/src/main/java/a8k/service/app/appstate/statemgr/TubeStateMgrService.java +++ b/src/main/java/a8k/service/app/appstate/statemgr/TubeStateMgrService.java @@ -13,7 +13,7 @@ import a8k.service.dao.DeviceStatisticDao; import a8k.service.dao.SampleRecordDBDao; import a8k.service.dao.type.SampleRecord; import a8k.service.dao.type.StatisticType; -import a8k.type.ProjBriefInfo; +import a8k.type.ecode.AppError; import a8k.type.exception.AppException; import a8k.type.type.BloodType; import a8k.utils.ProjBuildinInfo; @@ -33,7 +33,7 @@ import java.util.List; @Slf4j public class TubeStateMgrService { @Resource - GStateService gstate; + GStateService gstate; @Resource ProjInfoMgrService projInfoMgrService; @Resource @@ -144,11 +144,11 @@ public class TubeStateMgrService { */ synchronized public void commitEmergencySampleSetting(String userid, String sampleBarcode, BloodType bloodType,// List projIds) throws AppException { - Tube tube = emergencyTubePos.tube; + Tube tube = emergencyTubePos.tube; List projBuildInInfos = new ArrayList<>(); if (deviceWorkStateMgrService.getDeviceWorkState().workState.equals(A8kWorkState.WORKING)) { - throw new AppException(A8kEcode.APPE_ACTION_IS_NOT_ALLOWED_WHEN_WORKING); + throw new AppException(A8kEcode.APPE_ADD_EMERGENCY_ACTION_IS_NOT_ALLOWED_WHEN_WORKING); } if (projIds.isEmpty()) { @@ -235,8 +235,9 @@ public class TubeStateMgrService { curProcessingTube.setState(TubeState.PROCESSED); } - synchronized public void changeTubeStateToError() { + synchronized public void changeTubeStateToError(List errors) { curProcessingTube.setState(TubeState.ERROR); + curProcessingTube.setErrors(errors); } synchronized public void changeTubeStateToProcessComplete() { diff --git a/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java b/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java index 68f61bc..1c109c7 100644 --- a/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java +++ b/src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java @@ -16,7 +16,7 @@ import java.util.ArrayList; import java.util.List; @Getter -public class IncubationSubTank implements Serializable { +public class IncubationSubTank implements Serializable { //位置 @Schema(description = "位置") IncubatorPos pos; @@ -34,6 +34,12 @@ public class IncubationSubTank implements Serializable { @Schema(description = "项目信息,用于显示") ProjBriefInfo projInfo = new ProjBriefInfo(); //项目信息 + + @Schema(description = "样本ID,系统内部使用(不显示)") + String sampleId = ""; + @Schema(description = "项目ID") + Integer projId = 0; + // //孵育时间 @Schema(description = "开始孵育时间(ms时间戳)") @@ -41,10 +47,6 @@ public class IncubationSubTank implements Serializable { @Schema(description = "目标孵育时间(s)") public Integer incubatedTimeSec = 0; //目标孵育时间 - @Schema(description = "样本ID,系统内部使用(不显示)") - String sampleId = ""; - @Schema(description = "项目ID") - Integer projId = 0; @Setter @Schema(description = "错误信息,用来标识当前孵育盘的错误信息,例如推出的反应板夹有问题") diff --git a/src/main/java/a8k/service/app/appstate/type/ProjectContext.java b/src/main/java/a8k/service/app/appstate/type/ProjectContext.java deleted file mode 100644 index 1b90e8d..0000000 --- a/src/main/java/a8k/service/app/appstate/type/ProjectContext.java +++ /dev/null @@ -1,117 +0,0 @@ -package a8k.service.app.appstate.type; - -import a8k.a8kproj.optalgo.type.OptScanResult; -import a8k.service.dao.type.ProjExtInfoCard; -import a8k.service.dao.type.a8kidcard.zenum.A8kOptType; -import a8k.type.IncubatorPos; -import a8k.type.pos.*; -import a8k.utils.ProjBuildinInfo; -import a8k.utils.ProjInfo; -import cn.hutool.core.util.ObjectUtil; - -import java.util.List; - -public class ProjectContext { - // 样本信息 - String cxtId; - SampleInfo sampleInfo = new SampleInfo(); - - // 项目信息,有分配耗材时,才会拿到具体的项目配置 - ProjBuildinInfo projBuildinInfo = null; - ProjExtInfoCard projExtInfoCard = null; - - - //资源信息 - Consumable consumable = null;//耗材信息 - List tipPos = null;//吸头位置 - IncubatorPos incubatorPos = null;//孵育位置 - - //光学扫描结果 - OptScanResult tOptScanResults = null; - OptScanResult fOptScanResults = null; - - - public ProjectContext(String cxtId, SampleInfo sampleInfo) { - this.cxtId = cxtId; - this.sampleInfo = sampleInfo; - } - - synchronized public void setProjBuildinInfo(ProjBuildinInfo projBuildinInfo) { - this.projBuildinInfo = projBuildinInfo; - } - - synchronized public void setProjInfoStorageCard(ProjExtInfoCard projExtInfoCard) { - this.projExtInfoCard = projExtInfoCard; - } - - synchronized public void setConsumable(Consumable consumable) { - this.consumable = consumable; - } - - synchronized public void setTipPos(List tipPos) { - this.tipPos = tipPos; - } - - synchronized public void setIncubatorPos(IncubatorPos incubatorPos) { - this.incubatorPos = incubatorPos; - } - - synchronized public Consumable getConsumable() { - return ObjectUtil.cloneByStream(consumable); - } - - synchronized public List getTipPos() { - return ObjectUtil.cloneByStream(tipPos); - } - - synchronized public IncubatorPos getIncubatorPos() { - return ObjectUtil.cloneByStream(incubatorPos); - } - - synchronized public void setSampleInfo(SampleInfo sampleInfo) { - this.sampleInfo = sampleInfo; - } - - synchronized public SampleInfo getSampleInfo() { - return ObjectUtil.cloneByStream(sampleInfo); - } - - synchronized public TipPos takeTip() { - if (tipPos == null || tipPos.isEmpty()) { - return null; - } - return tipPos.remove(0); - } - - - synchronized public OptScanResult getfOptScanResult(A8kOptType optType) { - return switch (optType) { - case TOPT -> tOptScanResults; - case FOPT -> fOptScanResults; - }; - } - - synchronized public void setOptScanResult(A8kOptType optType, OptScanResult optScanResult) { - switch (optType) { - case TOPT -> tOptScanResults = optScanResult; - case FOPT -> fOptScanResults = optScanResult; - } - } - - synchronized public ProjBuildinInfo getProjBuildinInfo() { - return this.projBuildinInfo; - } - - synchronized public ProjExtInfoCard getProjExtInfoCard() { - return this.projExtInfoCard; - } - - synchronized public ProjInfo getProjInfo() { - ProjInfo projInfo = new ProjInfo(); - projInfo.projBaseInfo = ObjectUtil.cloneByStream(projBuildinInfo.projBaseInfo); - projInfo.projOptInfoList = ObjectUtil.cloneByStream((projBuildinInfo.projOptInfos)); - projInfo.projExtInfoCard = ObjectUtil.cloneByStream((projExtInfoCard)); - return projInfo; - } -} - diff --git a/src/main/java/a8k/service/app/appstate/type/ProjectTaskContext.java b/src/main/java/a8k/service/app/appstate/type/ProjectTaskContext.java new file mode 100644 index 0000000..b14ebd9 --- /dev/null +++ b/src/main/java/a8k/service/app/appstate/type/ProjectTaskContext.java @@ -0,0 +1,117 @@ +package a8k.service.app.appstate.type; + +import a8k.a8kproj.optalgo.type.OptScanResult; +import a8k.service.dao.type.ProjExtInfoCard; +import a8k.service.dao.type.a8kidcard.zenum.A8kOptType; +import a8k.type.IncubatorPos; +import a8k.type.pos.*; +import a8k.utils.ProjBuildinInfo; +import a8k.utils.ProjInfo; +import cn.hutool.core.util.ObjectUtil; + +import java.util.List; + +public class ProjectTaskContext { + // 样本信息 + String cxtId; + SampleInfo sampleInfo = new SampleInfo(); + + // 项目信息,有分配耗材时,才会拿到具体的项目配置 + ProjBuildinInfo projBuildinInfo = null; + ProjExtInfoCard projExtInfoCard = null; + + + //资源信息 + Consumable consumable = null;//耗材信息 + List tipPos = null;//吸头位置 + IncubatorPos incubatorPos = null;//孵育位置 + + //光学扫描结果 + OptScanResult tOptScanResults = null; + OptScanResult fOptScanResults = null; + + + public ProjectTaskContext(String cxtId, SampleInfo sampleInfo) { + this.cxtId = cxtId; + this.sampleInfo = sampleInfo; + } + + synchronized public void setProjBuildinInfo(ProjBuildinInfo projBuildinInfo) { + this.projBuildinInfo = projBuildinInfo; + } + + synchronized public void setProjInfoStorageCard(ProjExtInfoCard projExtInfoCard) { + this.projExtInfoCard = projExtInfoCard; + } + + synchronized public void setConsumable(Consumable consumable) { + this.consumable = consumable; + } + + synchronized public void setTipPos(List tipPos) { + this.tipPos = tipPos; + } + + synchronized public void setIncubatorPos(IncubatorPos incubatorPos) { + this.incubatorPos = incubatorPos; + } + + synchronized public Consumable getConsumable() { + return ObjectUtil.cloneByStream(consumable); + } + + synchronized public List getTipPos() { + return ObjectUtil.cloneByStream(tipPos); + } + + synchronized public IncubatorPos getIncubatorPos() { + return ObjectUtil.cloneByStream(incubatorPos); + } + + synchronized public void setSampleInfo(SampleInfo sampleInfo) { + this.sampleInfo = sampleInfo; + } + + synchronized public SampleInfo getSampleInfo() { + return ObjectUtil.cloneByStream(sampleInfo); + } + + synchronized public TipPos takeTip() { + if (tipPos == null || tipPos.isEmpty()) { + return null; + } + return tipPos.remove(0); + } + + + synchronized public OptScanResult getfOptScanResult(A8kOptType optType) { + return switch (optType) { + case TOPT -> tOptScanResults; + case FOPT -> fOptScanResults; + }; + } + + synchronized public void setOptScanResult(A8kOptType optType, OptScanResult optScanResult) { + switch (optType) { + case TOPT -> tOptScanResults = optScanResult; + case FOPT -> fOptScanResults = optScanResult; + } + } + + synchronized public ProjBuildinInfo getProjBuildinInfo() { + return this.projBuildinInfo; + } + + synchronized public ProjExtInfoCard getProjExtInfoCard() { + return this.projExtInfoCard; + } + + synchronized public ProjInfo getProjInfo() { + ProjInfo projInfo = new ProjInfo(); + projInfo.projBaseInfo = ObjectUtil.cloneByStream(projBuildinInfo.projBaseInfo); + projInfo.projOptInfoList = ObjectUtil.cloneByStream((projBuildinInfo.projOptInfos)); + projInfo.projExtInfoCard = ObjectUtil.cloneByStream((projExtInfoCard)); + return projInfo; + } +} + diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/ConsumablesScanCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/ConsumablesScanCtrlService.java index d9d1598..809fc99 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/ConsumablesScanCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/ConsumablesScanCtrlService.java @@ -2,7 +2,6 @@ package a8k.service.app.devicectrl.ctrlservice; import a8k.service.app.devicectrl.exdriver.CodeScanerExDriver; import a8k.service.app.devicectrl.exdriver.HbotBaseMoveExDriver; -import a8k.service.bases.ActionReactorService; import a8k.service.app.devicectrl.param.param_mgr.Hbot2DCodeScanParamMgr; import a8k.service.test.state.VirtualDevice; import a8k.type.ConsumableOneChRawResult; diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java index 5804449..610d909 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java @@ -11,21 +11,16 @@ import a8k.service.app.devicectrl.driver.type.StepMotorMId; import a8k.service.app.devicectrl.exdriver.HbotBaseMoveExDriver; import a8k.service.app.devicectrl.exdriver.MotorEnableExDriver; import a8k.service.app.devicectrl.script.DeviceCtrlScripter; -import a8k.service.bases.ActionReactorService; -import a8k.service.test.state.TestModeState; import a8k.service.test.state.VirtualDevice; import a8k.type.CheckPointType; import a8k.type.checkpoint.CheckResult; import a8k.type.checkpoint.Checkpoint; import a8k.service.app.appstate.GStateService; -import a8k.service.app.devicectrl.driver.HbotDriver; import a8k.type.exception.AppException; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.ArrayList; diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/HbotCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/HbotCtrlService.java index d48fb33..ffbcd44 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/HbotCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/HbotCtrlService.java @@ -46,7 +46,7 @@ public class HbotCtrlService { public void checkTipIndex(TipGroup tipGroup, Integer index) throws AppException { if (index >= AppConstant.TIP_NUM) { - throw new AppException(A8kEcode.CODEERROR_PARAM_OUT_OF_RANGE); + throw new AppException(A8kEcode.PE_PARAM_OUT_OF_RANGE); } } diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java index 7b75b9a..11a2a15 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java @@ -11,7 +11,6 @@ import a8k.service.app.devicectrl.driver.type.OptModuleRegIndex; import a8k.service.app.devicectrl.driver.type.StepMotorMId; import a8k.service.app.devicectrl.param.param_mgr.OptModuleExtParamsMgr; import a8k.service.app.devicectrl.param.param_mgr.OptModuleParamsMgr; -import a8k.service.bases.ActionReactorService; import a8k.service.dao.type.OptRawScanData; import a8k.service.dao.type.ProjOptInfo; import a8k.service.dao.type.ProjectBaseInfo; @@ -36,8 +35,6 @@ public class OptScanModuleCtrlService { @Resource StepMotorCtrlDriver stepMotorCtrlDriver; @Resource - ActionReactorService actionReactor; - @Resource OptModuleDriver optModuleDriver; @Resource diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/PlateBoxCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/PlateBoxCtrlService.java index 0656f02..7e24187 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/PlateBoxCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/PlateBoxCtrlService.java @@ -1,11 +1,8 @@ package a8k.service.app.devicectrl.ctrlservice; -import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; -import a8k.extapi_controler.utils.ExtApiTab; import a8k.service.app.devicectrl.driver.StepMotorCtrlDriver; import a8k.service.app.devicectrl.driver.type.StepMotorMId; import a8k.service.app.devicectrl.param.param_mgr.PlatesBoxPosParamMgr; -import a8k.service.bases.ActionReactorService; import a8k.type.ConsumableGroup; import a8k.type.IncubatorPos; import a8k.type.exception.AppException; @@ -21,8 +18,7 @@ public class PlateBoxCtrlService { @Resource StepMotorCtrlDriver stepMotorCtrlDriver; - @Resource - ActionReactorService actionReactor; + @Resource diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/TubePreProcesCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/TubePreProcesCtrlService.java index 4689b39..24b82b9 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/TubePreProcesCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/TubePreProcesCtrlService.java @@ -55,12 +55,12 @@ public class TubePreProcesCtrlService { //Z轴在原点 if (!stepMotorCtrlDriver.stepMotorReadIoState(StepMotorMId.ShakeModGripperZM, 0)) { - throw AppException.of(A8kEcode.CODEERROR_MOTOR_NOT_IN_ZERO_POS, MId.ShakeModGripperZM); + throw AppException.of(A8kEcode.LOW_EXT_ERROR_MOTOR_AT_WRONG_POS, MId.ShakeModGripperZM); } //Y轴在零点附近 if (!ZEQ.IntEq(miniServoDriver.miniServoReadPos(MiniServoMId.ShakeModGripperYSV), MiniServoConstant.getZeroPos(MiniServoMId.ShakeModGripperYSV), 30)) { - throw AppException.of(A8kEcode.CODEERROR_MOTOR_NOT_IN_ZERO_POS, MId.ShakeModGripperYSV); + throw AppException.of(A8kEcode.LOW_EXT_ERROR_MOTOR_AT_WRONG_POS, MId.ShakeModGripperYSV); } tubePreProcesModuleExDriver.clampingMReleaseTube(); diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/TurnableMoveCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/TurnableMoveCtrlService.java index f626d25..4701fa0 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/TurnableMoveCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/TurnableMoveCtrlService.java @@ -1,11 +1,8 @@ package a8k.service.app.devicectrl.ctrlservice; -import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; -import a8k.extapi_controler.utils.ExtApiTab; import a8k.service.app.devicectrl.driver.StepMotorCtrlDriver; import a8k.service.app.devicectrl.driver.type.StepMotorMId; import a8k.service.app.devicectrl.param.param_mgr.TurntablePosParamMgr; -import a8k.service.bases.ActionReactorService; import a8k.type.IncubatorPos; import a8k.type.exception.AppException; import a8k.hardware.A8kCanBusService; @@ -26,8 +23,7 @@ public class TurnableMoveCtrlService { A8kCanBusService canBus; @Resource StepMotorCtrlDriver stepMotorCtrlDriver; - @Resource - ActionReactorService actionReactor; + @Resource TurntablePosParamMgr turntablePosParamMgr; diff --git a/src/main/java/a8k/service/app/devicectrl/exdriver/HbotBaseMoveExDriver.java b/src/main/java/a8k/service/app/devicectrl/exdriver/HbotBaseMoveExDriver.java index d893121..abe8962 100644 --- a/src/main/java/a8k/service/app/devicectrl/exdriver/HbotBaseMoveExDriver.java +++ b/src/main/java/a8k/service/app/devicectrl/exdriver/HbotBaseMoveExDriver.java @@ -69,7 +69,7 @@ public class HbotBaseMoveExDriver { pipetteCtrlDriver.zMotorMoveToZeroPointQuickBlock(); } if (!pipetteCtrlDriver.zAixsZeroPointIsTrigger()) { - throw new AppException(A8kEcode.CODEERROR_ZM_NOT_AT_ZERO_POS_WHEN_HBOT_TRY_MOVE); + throw new AppException(A8kEcode.LOW_EXT_ERROR_MOTOR_AT_WRONG_POS); } // HBot移动 diff --git a/src/main/java/a8k/service/app/devicectrl/exdriver/TubeTransportExDriver.java b/src/main/java/a8k/service/app/devicectrl/exdriver/TubeTransportExDriver.java index 2d6ba2a..40ee205 100644 --- a/src/main/java/a8k/service/app/devicectrl/exdriver/TubeTransportExDriver.java +++ b/src/main/java/a8k/service/app/devicectrl/exdriver/TubeTransportExDriver.java @@ -2,7 +2,6 @@ package a8k.service.app.devicectrl.exdriver; import a8k.OS; import a8k.constant.MiniServoConstant; -import a8k.extapi_controler.utils.ExtApiFn; import a8k.hardware.A8kCanBusService; import a8k.hardware.type.a8kcanprotocol.A8kEcode; import a8k.hardware.type.a8kcanprotocol.MId; @@ -10,7 +9,6 @@ import a8k.service.app.devicectrl.driver.MiniServoDriver; import a8k.service.app.devicectrl.driver.StepMotorCtrlDriver; import a8k.service.app.devicectrl.driver.type.MiniServoMId; import a8k.service.app.devicectrl.driver.type.StepMotorMId; -import a8k.service.app.devicectrl.param.param_mgr.TubeFeedingModuleParamMgr; import a8k.type.TargetPosMeasureDirection; import a8k.type.exception.AppException; import jakarta.annotation.Resource; @@ -43,7 +41,7 @@ public class TubeTransportExDriver { */ public void moveTubeRackTo(Integer pos, TargetPosMeasureDirection moveDiretion, Boolean moveToZero) throws AppException { if (!stepMotorCtrlDriver.stepMotorReadIoState(StepMotorMId.ShakeModGripperZM, 0)) { - throw new AppException(A8kEcode.CODEERROR_SHAKE_MOD_GRIPPER_ZMOTOR_NOT_IN_ZERO_POS); + throw new AppException(A8kEcode.LOW_EXT_ERROR_MOTOR_AT_WRONG_POS); } //打开扫码夹具 scanClampModRelease(); diff --git a/src/main/java/a8k/service/app/devicectrl/param/calibration/OptModuleParamCalibration.java b/src/main/java/a8k/service/app/devicectrl/param/calibration/OptModuleParamCalibration.java index aefa4a0..c3a1c86 100644 --- a/src/main/java/a8k/service/app/devicectrl/param/calibration/OptModuleParamCalibration.java +++ b/src/main/java/a8k/service/app/devicectrl/param/calibration/OptModuleParamCalibration.java @@ -14,6 +14,7 @@ import a8k.service.app.devicectrl.param.type.OptModuleExtParam; import a8k.service.dao.type.Parameter; import a8k.service.dao.type.a8kidcard.zenum.A8kOptType; import a8k.type.*; +import a8k.type.ecode.AECodeError; import a8k.type.exception.AppException; import a8k.utils.opt_gain_convert.OptGainConvert; import jakarta.annotation.Resource; @@ -147,7 +148,7 @@ public class OptModuleParamCalibration { @ExtApiFn(name = "设置F光学扫描偏移", group = "F光学", order = 300) public void setFOptScanShift(Integer shift) throws AppException { if (shift < 0) { - throw AppException.of("扫描偏移量必须大于0"); + throw AppException.ofAECodeError("扫描偏移量必须大于0"); } optModuleExtParamsMgr.setOptParam(OptModuleExtParam.FOptScanShift, shift); } @@ -178,7 +179,7 @@ public class OptModuleParamCalibration { @ExtApiFn(name = "设置T光学扫描偏移", group = "T光学", order = 400) public void setTOptScanShift(Integer shift) throws AppException { if (shift < 0) { - throw AppException.of("扫描偏移量必须大于0"); + throw AppException.ofAECodeError("扫描偏移量必须大于0"); } optModuleExtParamsMgr.setOptParam(OptModuleExtParam.TOptScanShift, shift); } diff --git a/src/main/java/a8k/service/app/devicectrl/param/calibration/PipetteGunLLDParamCalibration.java b/src/main/java/a8k/service/app/devicectrl/param/calibration/PipetteGunLLDParamCalibration.java index 1823fb2..d6f7159 100644 --- a/src/main/java/a8k/service/app/devicectrl/param/calibration/PipetteGunLLDParamCalibration.java +++ b/src/main/java/a8k/service/app/devicectrl/param/calibration/PipetteGunLLDParamCalibration.java @@ -87,7 +87,7 @@ public class PipetteGunLLDParamCalibration { @ExtApiFn(name = "LDD测量液体属性", group = "测试", order = 103) public Object lldCalibrate() throws AppException { if (lldStartPos > lldEndPos) { - throw AppException.of("开始位置大于结束位置"); + throw AppException.ofAECodeError("开始位置大于结束位置"); } pipetteCtrlDriver.zMotorEnable(1); diff --git a/src/main/java/a8k/service/app/devicectrl/param/ext_param_mgr/PipetteGunParamExMgr.java b/src/main/java/a8k/service/app/devicectrl/param/ext_param_mgr/PipetteGunParamExMgr.java index 5405f9f..93750e0 100644 --- a/src/main/java/a8k/service/app/devicectrl/param/ext_param_mgr/PipetteGunParamExMgr.java +++ b/src/main/java/a8k/service/app/devicectrl/param/ext_param_mgr/PipetteGunParamExMgr.java @@ -1,6 +1,6 @@ package a8k.service.app.devicectrl.param.ext_param_mgr; -import a8k.service.app.appstate.type.ProjectContext; +import a8k.service.app.appstate.type.ProjectTaskContext; import a8k.service.app.devicectrl.param.ext_param_mgr.base.PipetteGunBindActionType; import a8k.service.app.devicectrl.param.ext_param_mgr.base.LLDParamPack; import a8k.service.app.devicectrl.param.ext_param_mgr.base.LLFParamPack; @@ -42,7 +42,7 @@ public class PipetteGunParamExMgr { * @param cxt 上下文 * @return 液面探测相关参数 */ - public LLDParamPack getLLDParam(PipetteGunBindActionType type, ProjectContext cxt) { + public LLDParamPack getLLDParam(PipetteGunBindActionType type, ProjectTaskContext cxt) { LLDParamPack paramPack = null; switch (type) { case SAMPLE -> { @@ -81,7 +81,7 @@ public class PipetteGunParamExMgr { * @param cxt 上下文 * @return 液面跟随相关参数 */ - public LLFParamPack getLLFParam(PipetteGunBindActionType type, ProjectContext cxt) { + public LLFParamPack getLLFParam(PipetteGunBindActionType type, ProjectTaskContext cxt) { LLFParamPack paramPack = null; switch (type) { // 取样 diff --git a/src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java b/src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java index 9973881..518c881 100644 --- a/src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java +++ b/src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java @@ -1,6 +1,6 @@ package a8k.service.app.devicectrl.script; -import a8k.service.app.appstate.type.ProjectContext; +import a8k.service.app.appstate.type.ProjectTaskContext; import a8k.service.app.devicectrl.ctrlservice.HbotCtrlService; import a8k.service.app.devicectrl.ctrlservice.OptScanModuleCtrlService; import a8k.service.app.devicectrl.ctrlservice.TurnableMoveCtrlService; @@ -14,7 +14,6 @@ import a8k.service.app.devicectrl.param.ext_param_mgr.base.LLFParamPack; import a8k.service.app.devicectrl.param.param_mgr.HbotFixedPosParamMgr; import a8k.service.app.devicectrl.param.param_mgr.HbotSamplePosParamMgr; import a8k.service.app.devicectrl.param.type.A8kSamplePos; -import a8k.service.bases.ActionReactorService; import a8k.service.dao.type.a8kidcard.zenum.A8kReactionFlowType; import a8k.type.cfg.Pos3d; import a8k.type.exception.AppException; @@ -31,8 +30,7 @@ import org.springframework.util.Assert; @Slf4j public class DeviceCtrlScripter { - @Resource - ActionReactorService actionReactor; + @Resource PipetteCtrlDriver pipetteCtrlDriver; @Resource @@ -81,7 +79,7 @@ public class DeviceCtrlScripter { } - void distribute(PipetteGunBindActionType actionType, ProjectContext ctx, Integer ul) throws AppException { + void distribute(PipetteGunBindActionType actionType, ProjectTaskContext ctx, Integer ul) throws AppException { LLFParamPack llfParamPack = pipetteGunParamExMgr.getLLFParam(actionType, ctx); pipetteCtrlDriver.aspirateSetLlfVelocity(llfParamPack.llfVel); pipetteCtrlDriver.setLlfStartZ(llfParamPack.llfStartPos); @@ -89,7 +87,7 @@ public class DeviceCtrlScripter { pipetteCtrlDriver.aspirateBlock(-ul); } - void mix(PipetteGunBindActionType actionType, ProjectContext ctx, Integer ul, Integer times) throws AppException { + void mix(PipetteGunBindActionType actionType, ProjectTaskContext ctx, Integer ul, Integer times) throws AppException { LLFParamPack llfParamPack = pipetteGunParamExMgr.getLLFParam(actionType, ctx); pipetteCtrlDriver.aspirateSetLlfVelocity(llfParamPack.llfVel); pipetteCtrlDriver.setLlfStartZ(llfParamPack.llfStartPos); @@ -98,7 +96,7 @@ public class DeviceCtrlScripter { } - void aspirate(PipetteGunBindActionType actionType, ProjectContext ctx, Integer ul) throws AppException { + void aspirate(PipetteGunBindActionType actionType, ProjectTaskContext ctx, Integer ul) throws AppException { LLFParamPack llfParamPack = pipetteGunParamExMgr.getLLFParam(actionType, ctx); log.info("吸液 {} , llfvel {} , llfStartPos {} , llfEndPos {}", ul, llfParamPack.llfVel, llfParamPack.llfStartPos, llfParamPack.llfEndPos); @@ -109,7 +107,7 @@ public class DeviceCtrlScripter { } - void lld(PipetteGunBindActionType actionType, ProjectContext ctx) throws AppException { + void lld(PipetteGunBindActionType actionType, ProjectTaskContext ctx) throws AppException { pipetteCtrlDriver.lldPrepareBlock(); log.info("液面探测 {}", actionType); @@ -143,7 +141,7 @@ public class DeviceCtrlScripter { } - public void doSampleProcessPrepare(ProjectContext ctx) throws AppException { + public void doSampleProcessPrepare(ProjectTaskContext ctx) throws AppException { A8kReactionFlowType type = ctx.getProjBuildinInfo().getReactionFlowType(); if (type.equals(A8kReactionFlowType.FlowType1)) { log.info("样本预处理,刺破小瓶缓冲液"); @@ -208,7 +206,7 @@ public class DeviceCtrlScripter { } } - public void doSampleProcess(ProjectContext ctx) throws AppException { + public void doSampleProcess(ProjectTaskContext ctx) throws AppException { Integer sampleul = ProjProcessContextUtils.getSampleVol(ctx); Integer reactionul = ProjProcessContextUtils.getReactionPlateDropletVolUl(ctx); @@ -244,7 +242,7 @@ public class DeviceCtrlScripter { } - public void doSampleProcessPostProcess(ProjectContext ctx) throws AppException { + public void doSampleProcessPostProcess(ProjectTaskContext ctx) throws AppException { Integer sampleul = ProjProcessContextUtils.getSampleVol(ctx); Integer reactionul = ProjProcessContextUtils.getReactionPlateDropletVolUl(ctx); diff --git a/src/main/java/a8k/service/app/erroranalyzer/ErrorAnalyzer.java b/src/main/java/a8k/service/app/erroranalyzer/ErrorAnalyzer.java new file mode 100644 index 0000000..9e9a138 --- /dev/null +++ b/src/main/java/a8k/service/app/erroranalyzer/ErrorAnalyzer.java @@ -0,0 +1,26 @@ +package a8k.service.app.erroranalyzer; + +import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.type.ecode.AppError; + +import java.util.List; + +public class ErrorAnalyzer { + static public Boolean isFatalError(A8kEcode ecode) { + if (ecode.index >= A8kEcode.LOW_ERROR_HARDWARE_ERROR_START.index) { + //部分底层错误,属于非必须停机的错误 + return !ecode.equals(A8kEcode.LOW_ERROR_PIPETTE_ERROR_TIP_POP_ERROR) + && !ecode.equals(A8kEcode.LOW_ERROR_PIPETTE_ERROR_LLD_ERROR); + } + return false; + } + + static public Boolean isContainFatalError(List errors) { + for (AppError error : errors) { + if (isFatalError(error.code)) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/a8k/service/bases/ActionReactorService.java b/src/main/java/a8k/service/bases/ActionReactorService.java deleted file mode 100644 index 87ea7fa..0000000 --- a/src/main/java/a8k/service/bases/ActionReactorService.java +++ /dev/null @@ -1,123 +0,0 @@ -package a8k.service.bases; - -import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; -import a8k.extapi_controler.utils.ExtApiStatu; -import a8k.extapi_controler.utils.ExtApiFn; -import a8k.extapi_controler.utils.ExtApiTab; -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.type.ZFunction; -import a8k.type.exception.AppException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * 动作单步调试服务, - * 所有使用dosome接口的动作都可以被单步调试 - */ -@Component -@ExtApiTab(cfg = ExtApiTabConfig.ActionReactorService) -public class ActionReactorService { - public enum DoWhatNext { - DoNextAction, - ReDoAction, - } - - static Logger logger = LoggerFactory.getLogger(ActionReactorService.class); - - static class ORDER { - static final int doNextStep = 1; - static final int reDoStep = 2; - static final int breakAction = 3; - static final int fullSpeedRun = 6; - static final int singleStepRun = 7; - - } - - Boolean reDo = false; - Boolean doNext = false; - Boolean breakAction = false; - Boolean fullSpeedRun = true; - String curStep; - - - DoWhatNext breakpoint() throws AppException { - while (true) { - if (reDo) { - reDo = false; - return DoWhatNext.ReDoAction; - } - if (doNext) { - doNext = false; - return DoWhatNext.DoNextAction; - } - - if (breakAction) { - breakAction = false; - throw new AppException(A8kEcode.ACTION_REACTOR_SERVICE_BREAKBYUSR); - } - - if (fullSpeedRun) { - return DoWhatNext.DoNextAction; - } - - try { - Thread.sleep(100); - } catch (InterruptedException e) { - throw new AppException(A8kEcode.ACTION_REACTOR_SERVICE_BREAKBYUSR); - } - } - } - - - public void dosome(String mark, ZFunction action) throws AppException{ - while (true) { - logger.info("do {}", mark); - curStep = mark; - action.fn(); - DoWhatNext next = breakpoint(); - if (next == DoWhatNext.DoNextAction) { - break; - } - } - - curStep = ""; - } - - @ExtApiFn(name = "下一步", order = ORDER.doNextStep) - public void doNextStep() { - doNext = true; - } - - @ExtApiFn(name = "重新执行当前步骤", order = ORDER.reDoStep) - public void reDoStep() { - reDo = true; - } - - @ExtApiFn(name = "中断动作", order = ORDER.breakAction) - public void breakAction() { - breakAction = true; - } - - - @ExtApiFn(name = "全速模式", order = ORDER.fullSpeedRun) - public void fullSpeedRun() { - fullSpeedRun = true; - } - - @ExtApiFn(name = "单步模式", order = ORDER.singleStepRun) - public void singleStepRun() { - fullSpeedRun = false; - } - - @ExtApiStatu(name = "全速运行") - public Boolean getFullSpeedRun() { - return fullSpeedRun; - } - - @ExtApiStatu(name = "当前步骤") - public String getCurStep() { - return curStep; - } - -} diff --git a/src/main/java/a8k/service/test/MainflowCtrlTestService.java b/src/main/java/a8k/service/test/MainflowCtrlTestService.java index 31b11c7..7d55e0f 100644 --- a/src/main/java/a8k/service/test/MainflowCtrlTestService.java +++ b/src/main/java/a8k/service/test/MainflowCtrlTestService.java @@ -239,7 +239,7 @@ public class MainflowCtrlTestService { void doOnceSimpleTest(FakeProjInfo proj, ConsumableGroup consumablegroup, Integer tubeNum) throws AppException { if (tubeNum <= 0) { - throw AppException.of("试管数量必须大于0"); + throw AppException.ofAECodeError("试管数量必须大于0"); } gstate.setDeviceInited(true); diff --git a/src/main/java/a8k/service/test/PipetteGunTest.java b/src/main/java/a8k/service/test/PipetteGunTest.java index dc77e04..a75a1bf 100644 --- a/src/main/java/a8k/service/test/PipetteGunTest.java +++ b/src/main/java/a8k/service/test/PipetteGunTest.java @@ -85,7 +85,7 @@ public class PipetteGunTest { @ExtApiFn(name = "LDD测量液体属性", group = "测试", order = 103) public Object lldCalibrate() throws AppException { if (lldStartPos > lldEndPos) { - throw AppException.of("开始位置大于结束位置"); + throw AppException.ofAECodeError("开始位置大于结束位置"); } pipetteCtrlDriver.zMotorEnable(1); diff --git a/src/main/java/a8k/type/appret/ApiV1Ret.java b/src/main/java/a8k/type/appret/ApiV1Ret.java index ed19668..67be2c3 100644 --- a/src/main/java/a8k/type/appret/ApiV1Ret.java +++ b/src/main/java/a8k/type/appret/ApiV1Ret.java @@ -58,9 +58,9 @@ public class ApiV1Ret { if (e instanceof AppException hexcep) { r.data = hexcep.error; } else if (e instanceof ValidationException ex) { - r.data = new AECodeError(A8kEcode.CODEERROR_PARAM_OUT_OF_RANGE, ex.getLocalizedMessage()); + r.data = new AECodeError( ex.getLocalizedMessage()); } else if (e instanceof HandlerMethodValidationException validationE) { - r.data = new AECodeError(A8kEcode.CODEERROR_PARAM_OUT_OF_RANGE, validationE.getMessage()); + r.data = new AECodeError(validationE.getMessage()); } else { r.data = new AECodeError(e.getMessage()); } diff --git a/src/main/java/a8k/type/appret/AppRetV1.java b/src/main/java/a8k/type/appret/AppRetV1.java index 4ad68b7..de6a889 100644 --- a/src/main/java/a8k/type/appret/AppRetV1.java +++ b/src/main/java/a8k/type/appret/AppRetV1.java @@ -43,9 +43,9 @@ public class AppRetV1 { if (e instanceof AppException hexcep) { r.ecode = hexcep.error; } else if (e instanceof ValidationException ex) { - r.ecode = new AECodeError(A8kEcode.CODEERROR_PARAM_OUT_OF_RANGE, ex.getLocalizedMessage()); + r.ecode = new AECodeError( ex.getLocalizedMessage()); } else if (e instanceof HandlerMethodValidationException validationE) { - r.ecode = new AECodeError(A8kEcode.CODEERROR_PARAM_OUT_OF_RANGE, validationE.getMessage()); + r.ecode = new AECodeError( validationE.getMessage()); } else { r.ecode = new AECodeError(e.getMessage()); } diff --git a/src/main/java/a8k/type/ecode/AECodeError.java b/src/main/java/a8k/type/ecode/AECodeError.java index a1d3e84..2b4c240 100644 --- a/src/main/java/a8k/type/ecode/AECodeError.java +++ b/src/main/java/a8k/type/ecode/AECodeError.java @@ -1,17 +1,39 @@ package a8k.type.ecode; import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.type.exception.AppException; +import a8k.utils.ZJsonHelper; import io.swagger.v3.oas.annotations.media.Schema; public class AECodeError extends AppError { + @Schema(description = "异常栈信息") + public StackTraceElement[] stackTraceElements; + public AECodeError(String exmsg) { super(A8kEcode.CODEERROR); - this.exmsg = exmsg; + this.exmsg = exmsg; + stackTraceElements = Thread.currentThread().getStackTrace(); } - public AECodeError(A8kEcode ecode, String exmsg) { - super(ecode); - this.exmsg = exmsg; + public AECodeError(String fmt, Object... args) { + super(A8kEcode.CODEERROR); + this.exmsg = String.format(fmt, args); + stackTraceElements = Thread.currentThread().getStackTrace(); } + public AECodeError(Exception e) { + super(A8kEcode.CODEERROR); + this.exmsg = e.getMessage(); + stackTraceElements = e.getStackTrace(); + } + + public static void main(String[] args) { + try { + throw new Exception("test"); + } catch (Exception e) { + AECodeError aeCodeError = new AECodeError(e); + System.out.println(ZJsonHelper.objToPrettyJson(aeCodeError)); + } + + } } diff --git a/src/main/java/a8k/type/ecode/AECommonError.java b/src/main/java/a8k/type/ecode/AECommonError.java deleted file mode 100644 index 46b8e63..0000000 --- a/src/main/java/a8k/type/ecode/AECommonError.java +++ /dev/null @@ -1,13 +0,0 @@ -package a8k.type.ecode; - -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import io.swagger.v3.oas.annotations.media.Schema; - -public class AECommonError extends AppError { - public AECommonError(String exmsg) { - super(A8kEcode.COMMON_ERROR); - this.exmsg = exmsg; - } - - -} diff --git a/src/main/java/a8k/type/ecode/AEUnkownExceptionError.java b/src/main/java/a8k/type/ecode/AEUnkownExceptionError.java deleted file mode 100644 index 3e7406a..0000000 --- a/src/main/java/a8k/type/ecode/AEUnkownExceptionError.java +++ /dev/null @@ -1,22 +0,0 @@ -package a8k.type.ecode; - -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import io.swagger.v3.oas.annotations.media.Schema; - -import java.util.Arrays; - -public class AEUnkownExceptionError extends AppError { - @Schema(description = "异常描述") - public String decription; - @Schema(description = "异常栈信息") - public String stackTrace; - Exception exception; - - - public AEUnkownExceptionError(Exception exception) { - super(A8kEcode.CODEERROR_UNKOWN_EXCEPTION); - this.decription = exception.getMessage(); - this.stackTrace = Arrays.toString(exception.getStackTrace()); - this.exception = exception; - } -} diff --git a/src/main/java/a8k/type/exception/AppException.java b/src/main/java/a8k/type/exception/AppException.java index 766db85..01d4d70 100644 --- a/src/main/java/a8k/type/exception/AppException.java +++ b/src/main/java/a8k/type/exception/AppException.java @@ -3,7 +3,7 @@ package a8k.type.exception; import a8k.hardware.type.a8kcanprotocol.A8kEcode; import a8k.hardware.type.a8kcanprotocol.CmdId; import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.type.ecode.AECommonError; +import a8k.type.ecode.AECodeError; import a8k.type.ecode.AppError; import a8k.type.ecode.AEHardwareError; import lombok.Getter; @@ -35,23 +35,13 @@ public class AppException extends Exception { return new AppException(new AEHardwareError(errorCode, mid, null)); } - public static AppException of(AEHardwareError AEHardwareError) { return new AppException(AEHardwareError); } - public static AppException of(String message) { - return new AppException(new AECommonError(message)); + public static AppException ofAECodeError(String fmt, Object... args) { + return new AppException(new AECodeError(fmt, args)); } -// -// public void print() { -//// printStackTrace(); -// log.error("error {}",this.getMessage(), this); -//// log.error("exception {}", this.toString()); -//// for (StackTraceElement ste : this.getStackTrace()) { -//// log.error(ste.toString()); -//// } -// } } diff --git a/src/main/java/a8k/type/exception/MutiAppException.java b/src/main/java/a8k/type/exception/MutiAppException.java deleted file mode 100644 index 8669e9f..0000000 --- a/src/main/java/a8k/type/exception/MutiAppException.java +++ /dev/null @@ -1,22 +0,0 @@ -package a8k.type.exception; - -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.type.ecode.AppError; -import a8k.utils.AppExceptionUtils; -import com.fasterxml.jackson.annotation.JsonIgnore; - -import java.util.List; - -public class MutiAppException extends AppException { - public List bindExceptions; - - public MutiAppException(List exceptions) { - super(A8kEcode.MUTI_APPEXCEPTIONS); - bindExceptions = exceptions; - } - - @JsonIgnore - public List getErrors() { - return AppExceptionUtils.toAppErrorList(bindExceptions); - } -} diff --git a/src/main/java/a8k/type/exception/ZAppInterruptException.java b/src/main/java/a8k/type/exception/ZAppInterruptException.java index 6631f83..716c0f2 100644 --- a/src/main/java/a8k/type/exception/ZAppInterruptException.java +++ b/src/main/java/a8k/type/exception/ZAppInterruptException.java @@ -1,11 +1,4 @@ package a8k.type.exception; - -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.hardware.type.a8kcanprotocol.CmdId; -import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.type.ecode.AECommonError; -import a8k.type.ecode.AEHardwareError; -import a8k.type.ecode.AppError; import lombok.Getter; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/a8k/utils/ActionParallerExceutor.java b/src/main/java/a8k/utils/ActionParallerExceutor.java deleted file mode 100644 index f450877..0000000 --- a/src/main/java/a8k/utils/ActionParallerExceutor.java +++ /dev/null @@ -1,53 +0,0 @@ -package a8k.utils; - -import a8k.OS; -import a8k.type.exception.AppException; -import a8k.type.exception.MutiAppException; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.*; - -public class ActionParallerExceutor { - ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); - List> futures = new ArrayList<>(); - - // var doPrepareReactionPlateFuture = executor.submit(() -> ZFnCall.callfn(this::prepareReactionPlate)); - //摇匀并取盖 - // var doShakeAndTakeCapFuture = executor.submit(() -> ZFnCall.callfn(this::shakeAndTakeCap)); - //准备Hbot Tip - // var doHbotPrepareTipFuture = executor.submit(() -> ZFnCall.callfn(this::hbotPrepareTip)); - - - public void submit(ZFnCall.Fn fn) { - var future = executor.submit(() -> ZFnCall.callfn(fn)); - futures.add(future); - } - - public MutiAppException waitAll() { - futures.forEach(this::wait); - List exceptions = new java.util.ArrayList<>(List.of()); - try { - for (Future future : futures) { - exceptions.add(future.get()); - } - } catch (InterruptedException | ExecutionException ignored) { - } - exceptions.removeIf(Objects::isNull); - if (exceptions.isEmpty()) { - return null; - } - return new MutiAppException(exceptions); - // List errors = new java.util.ArrayList<>(List.of()); - // exceptions.forEach(e -> errors.add(e.getError())); - } - - - void wait(Future future) { - while (!future.isDone()) { - OS.forceSleep(100); - } - } - -} diff --git a/src/main/java/a8k/utils/AppExceptionBuilder.java b/src/main/java/a8k/utils/AppExceptionBuilder.java index 2db46ac..3a3c9f7 100644 --- a/src/main/java/a8k/utils/AppExceptionBuilder.java +++ b/src/main/java/a8k/utils/AppExceptionBuilder.java @@ -5,7 +5,6 @@ import a8k.type.ecode.AECodeError; import a8k.type.ecode.AppError; import a8k.type.ecode.AEConsumeNotEnoughError; import a8k.type.exception.AppException; -import a8k.type.exception.MutiAppException; import jakarta.annotation.Resource; import org.slf4j.Logger; import org.springframework.stereotype.Component; diff --git a/src/main/java/a8k/utils/ProjProcessContextUtils.java b/src/main/java/a8k/utils/ProjProcessContextUtils.java index 604230e..72ca918 100644 --- a/src/main/java/a8k/utils/ProjProcessContextUtils.java +++ b/src/main/java/a8k/utils/ProjProcessContextUtils.java @@ -2,7 +2,7 @@ package a8k.utils; import a8k.SpringBootBeanUtil; import a8k.service.app.appstate.statemgr.ProjectContextMgrService; -import a8k.service.app.appstate.type.ProjectContext; +import a8k.service.app.appstate.type.ProjectTaskContext; import a8k.service.app.appstate.type.Tube; import a8k.service.app.devicectrl.param.ext_param_mgr.HbotConsumableParamMgr; import a8k.service.app.devicectrl.param.type.A8kSamplePos; @@ -16,7 +16,7 @@ import java.util.List; public class ProjProcessContextUtils { - public static Integer getShakeTimes(List cxts) { + public static Integer getShakeTimes(List cxts) { int shakeTimes = 0; for (var cxt : cxts) { ProjInfo projCfg = cxt.getProjInfo(); @@ -36,11 +36,11 @@ public class ProjProcessContextUtils { } - public static Integer getTakeLargeBSVolume(ProjectContext ctx) { + public static Integer getTakeLargeBSVolume(ProjectTaskContext ctx) { return ctx.getProjInfo().projBaseInfo.bigBufferSampleUl; } - public static Boolean isDoMixTubeSample(ProjectContext ctx) { + public static Boolean isDoMixTubeSample(ProjectTaskContext ctx) { A8kTubeHolderType type = ctx.getSampleInfo().tubeHolderType; if (type == null) { return true; @@ -58,7 +58,7 @@ public class ProjProcessContextUtils { // public static Integer getShakeTimes(Tube tube) { ProjectContextMgrService service = SpringBootBeanUtil.getBean(ProjectContextMgrService.class); - List cxts = service.findCxts(tube.getSampleId()); + List cxts = service.findCxts(tube.getSampleId()); return getShakeTimes(cxts); } @@ -66,7 +66,7 @@ public class ProjProcessContextUtils { // // 试管混匀次数 // - public static Integer getTubeMixingCount(ProjectContext ctx) { + public static Integer getTubeMixingCount(ProjectTaskContext ctx) { var projCfg = ctx.getProjInfo(); var idcard = ctx.getProjExtInfoCard(); var defaultVal = projCfg.projBaseInfo; @@ -80,7 +80,7 @@ public class ProjProcessContextUtils { // // 混合液混匀次数 // - public static Integer getBSMixingCnt(ProjectContext ctx) { + public static Integer getBSMixingCnt(ProjectTaskContext ctx) { var projCfg = ctx.getProjInfo(); var idcard = ctx.getProjExtInfoCard(); var defaultVal = projCfg.projBaseInfo; @@ -94,7 +94,7 @@ public class ProjProcessContextUtils { // // 获取反混合液滴定体积 // - public static Integer getReactionPlateDropletVolUl(ProjectContext ctx) { + public static Integer getReactionPlateDropletVolUl(ProjectTaskContext ctx) { var projCfg = ctx.getProjInfo(); var idcard = ctx.getProjExtInfoCard(); var defaultVal = projCfg.projBaseInfo; @@ -108,7 +108,7 @@ public class ProjProcessContextUtils { // // 样本取样体积 // - public static Integer getSampleVol(ProjectContext ctx) { + public static Integer getSampleVol(ProjectTaskContext ctx) { var projCfg = ctx.getProjInfo(); var idcard = ctx.getProjExtInfoCard(); var defaultVal = projCfg.projBaseInfo; @@ -134,7 +134,7 @@ public class ProjProcessContextUtils { // 获取取样位置 // - static public A8kSamplePos getSamplePos(ProjectContext ctx) { + static public A8kSamplePos getSamplePos(ProjectTaskContext ctx) { Boolean isEmergency = ctx.getSampleInfo().isEmergency; Boolean isHighTube = ctx.getSampleInfo().isHighTube; A8kTubeHolderType tubeHolderType = ctx.getSampleInfo().tubeHolderType; @@ -165,7 +165,7 @@ public class ProjProcessContextUtils { } - static public Pos3d getReactionEndPos(ProjectContext ctx) { + static public Pos3d getReactionEndPos(ProjectTaskContext ctx) { HbotConsumableParamMgr hbotConsumableParamMgr = SpringBootBeanUtil.getBean(HbotConsumableParamMgr.class); A8kReactionFlowType type = ctx.getProjInfo().projBaseInfo.reactionFlowType; return switch (type) { diff --git a/src/main/java/a8k/utils/ZJsonHelper.java b/src/main/java/a8k/utils/ZJsonHelper.java index aa8378b..8115d6a 100644 --- a/src/main/java/a8k/utils/ZJsonHelper.java +++ b/src/main/java/a8k/utils/ZJsonHelper.java @@ -15,6 +15,15 @@ public class ZJsonHelper { } } + public static String objToPrettyJson(Object obj) { + ObjectMapper mapper = new ObjectMapper(); + try { + return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + public static ObjectNode createObjectNode() { return new ObjectMapper().createObjectNode(); }