From 68fec4cd3d5e96bebbaa5ece4fff396cdc1741d2 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Sun, 29 Sep 2024 14:33:51 +0800 Subject: [PATCH] update --- doc/代码框架.md | 241 +++++++++++++++++++++ .../extapi/pagecontrol/ExtApiTabConfig.java | 3 +- src/main/java/a8k/optalgo/OptAlgo.java | 7 + src/main/java/a8k/optalgo/type/OptAlgoError.java | 9 + src/main/java/a8k/optalgo/type/OptAlgoResult.java | 14 ++ src/main/java/a8k/optalgo/type/PeakInfo.java | 11 + .../service/app/AppA8kDeviceStateMgrService.java | 53 +++++ .../a8k/service/app/AppConsumablesMgrService.java | 3 +- .../service/app/AppDeviceInitializationModule.java | 3 +- .../service/app/AppSampleFormulaMgrService.java | 130 +++++++++++ .../a8k/service/app/SampleFormulaMgrService.java | 130 ----------- .../service/app/appstate/AppStateMgrService.java | 52 ----- .../a8k/service/appctrl/AppCoreCtrlService.java | 105 +++++++++ src/main/java/a8k/service/appctrl/AppRunTask.java | 89 ++++++++ src/main/java/a8k/service/appstate/A8kState.java | 28 +++ .../appstate/type/EmergencyPosRunState.java | 14 ++ .../appstate/type/IncubationPlateStatus.java | 5 + .../service/appstate/type/ReactingPlateState.java | 21 ++ .../a8k/service/appstate/type/SampleState.java | 9 + .../a8k/service/appstate/type/TubeHolderState.java | 16 ++ .../a8k/service/bak_appbase/A8kDeviceState.java | 26 --- .../bak_appbase/progress/TubeHolderProgress.java | 6 +- .../bak_appbase/runstate/EmergencyPosRunState.java | 14 -- .../runstate/ReactingPlateRunState.java | 22 -- .../bak_appbase/runstate/TubeHolderRunState.java | 20 -- .../service/bak_appbase/runstate/TubeRunState.java | 9 - .../a8k/type/exception/ActionBreakException.java | 4 - .../java/a8k/type/exception/AppPauseException.java | 4 + 28 files changed, 763 insertions(+), 285 deletions(-) create mode 100644 doc/代码框架.md create mode 100644 src/main/java/a8k/optalgo/OptAlgo.java create mode 100644 src/main/java/a8k/optalgo/type/OptAlgoError.java create mode 100644 src/main/java/a8k/optalgo/type/OptAlgoResult.java create mode 100644 src/main/java/a8k/optalgo/type/PeakInfo.java create mode 100644 src/main/java/a8k/service/app/AppA8kDeviceStateMgrService.java create mode 100644 src/main/java/a8k/service/app/AppSampleFormulaMgrService.java delete mode 100644 src/main/java/a8k/service/app/SampleFormulaMgrService.java delete mode 100644 src/main/java/a8k/service/app/appstate/AppStateMgrService.java create mode 100644 src/main/java/a8k/service/appctrl/AppCoreCtrlService.java create mode 100644 src/main/java/a8k/service/appctrl/AppRunTask.java create mode 100644 src/main/java/a8k/service/appstate/A8kState.java create mode 100644 src/main/java/a8k/service/appstate/type/EmergencyPosRunState.java create mode 100644 src/main/java/a8k/service/appstate/type/IncubationPlateStatus.java create mode 100644 src/main/java/a8k/service/appstate/type/ReactingPlateState.java create mode 100644 src/main/java/a8k/service/appstate/type/SampleState.java create mode 100644 src/main/java/a8k/service/appstate/type/TubeHolderState.java delete mode 100644 src/main/java/a8k/service/bak_appbase/A8kDeviceState.java delete mode 100644 src/main/java/a8k/service/bak_appbase/runstate/EmergencyPosRunState.java delete mode 100644 src/main/java/a8k/service/bak_appbase/runstate/ReactingPlateRunState.java delete mode 100644 src/main/java/a8k/service/bak_appbase/runstate/TubeHolderRunState.java delete mode 100644 src/main/java/a8k/service/bak_appbase/runstate/TubeRunState.java delete mode 100644 src/main/java/a8k/type/exception/ActionBreakException.java create mode 100644 src/main/java/a8k/type/exception/AppPauseException.java diff --git a/doc/代码框架.md b/doc/代码框架.md new file mode 100644 index 0000000..0e95eab --- /dev/null +++ b/doc/代码框架.md @@ -0,0 +1,241 @@ + /* + * + * while(!isWaitingForStop()){ + * if(当前样本处理完成){ + * if(入料口有样本){ + * 扫描样本 && 判断耗材是否充足 + * 如果耗材不足, + * 提示用户(抛出提示事件), + * 暂停设备(退出线程(抛出pause异常)) + * 如果扫描样本有误 + * 提示用户 + * 暂停设备 + * } + * } + * else{ + * 处理样本 + * } + * } + * + * try{ + * + * }catch(PauseException e){ + * //pauseSelf + * //抛出事件 + * } + * + * if(event){ + * pauseSampleProcessThread(); + * } + * + */ + + +经验: + 动作与赋值分开 + 当一组动作完全执行完之后,再赋值给状态,这样就可以使得动作在执行过程中任意时间点都可以被打断。 + + +while(true){ + TubeCfg cfg = getTubeCfg(i); + moveTubeHolderProcessPos + if(tubeType == xxx) + takeTube + shakeTube(times,degree) + takeHap + move + else if(){ + ... + + } + pausePoint; +} + +问题: + 有两种暂停状态: + 一种是复位势暂停。 + 一种是保持现状势暂停。(前提是循环中) + + pause/stop + + +动作划分为状态机 + scan{ + . + . + . + . + } + + + 状态机->enter + 状态机->enter + + +{ + IDLE + { + if(state.eq(wokring)){ + state.changeTo(scanPrepare) + } + + } + + SCANPREPARE + { + enterState + exitState + + if(ioTrigger){ + moveTubeHolderTo + waitForIoTrigger + changeStateTo(scanTubeHolderType) + if(error){ + changeStateToError + } + } + } + SCANHODLER + { + move + scan + + + + } + SCAN + + PAUSE + { + + } + + +} + + +``` +用户PAUSE --> 暂停,恢复,全局状态的变更。 +遇到错误 --> 通知,记录,清空工作位。无需恢复。 +状态机 --> + 修改全局状态。 + 记录。 + 执行动作。 + + + +前端接口: + pause; + continue; + + +全局都有哪些状态? +1. 类似于配置, + 初始化 + 运行过程中修改(前端提交) + +2. 运行过程控制,记录当前设备运行到哪一步,以便执行下一步。 + + +步骤与暂停之间的关系。 + 步骤与恢复? + + +步骤与停止之间的关系。 + + 步骤 + 步骤 + 步骤 + 步骤 + 步骤 + 暂停 + 步骤 + +---------------------------------------------- +每一步都有几种处理方法 + 1. firstEnter + checkCondition是否满足 + 2. finalExit + 3. loop + 4. pause + 5. continue + + waitting_for_take_sample + +pause + stepPause; + stepContinue; + +stop + + +协作? + 全局状态 + + + +{ + + take_tip + take_xxx + put_xxx + waitting_for + onPause{ + .... + } + onStop{ + ... + } + + pauseCondtion{ + ... + } +} + +{ + pause... +} + +pause_point + +``` + + +``` +服务的提供者, +服务的使用者, + +相互配合呢? + + triggerHasTakeSample + doNext + + +---处理--- + | | + | --搬运--(等待) + | | +扫描与预处理(等待) 抛出事件。 + + +机械臂 + takeSampleEnd + +---------------------------- +暂停: + waitingForPause,不需要弹出,只有单次循环结束 +停止: + break? +异常: + exception? + + +第一假如需要允许暂停,则需要将步骤进行拆分,暂停点作为一步。 + + +机械动作的暂停,涉及到,暂停和暂停恢复,不能简单的在代码中添加一个pause就可以的。 + + + + +``` \ No newline at end of file diff --git a/src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java b/src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java index 4f37d2e..a39d502 100644 --- a/src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java +++ b/src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java @@ -13,8 +13,9 @@ public enum ExtApiTabConfig { AppDeviceInitializationModule("应用.初始化", true), //OK AppConsumablesMgrService("应用.耗材扫描", true), AppStateMgrService("应用.设备状态管理", true), - SampleFormulaMgrService("应用.配方管理", true), + AppSampleFormulaMgrService("应用.配方管理", true), AppCtrlService("应用.设备控制", true), + AppCoreCtrlService("应用.核心控制", true), Hbot2DCodeScanPosMgrService("参数.Hbot二维码扫描坐标参数", true), UtilsProjectColorAllocer("工具.项目颜色分配", true), diff --git a/src/main/java/a8k/optalgo/OptAlgo.java b/src/main/java/a8k/optalgo/OptAlgo.java new file mode 100644 index 0000000..9f88157 --- /dev/null +++ b/src/main/java/a8k/optalgo/OptAlgo.java @@ -0,0 +1,7 @@ +package a8k.optalgo; + +public class OptAlgo { + + + +} diff --git a/src/main/java/a8k/optalgo/type/OptAlgoError.java b/src/main/java/a8k/optalgo/type/OptAlgoError.java new file mode 100644 index 0000000..1e8bdc7 --- /dev/null +++ b/src/main/java/a8k/optalgo/type/OptAlgoError.java @@ -0,0 +1,9 @@ +package a8k.optalgo.type; + +public enum OptAlgoError { + Success, + LostPeak, + LostPeakStart, + LostPeakEnd, +} + diff --git a/src/main/java/a8k/optalgo/type/OptAlgoResult.java b/src/main/java/a8k/optalgo/type/OptAlgoResult.java new file mode 100644 index 0000000..df72ba5 --- /dev/null +++ b/src/main/java/a8k/optalgo/type/OptAlgoResult.java @@ -0,0 +1,14 @@ +package a8k.optalgo.type; + +import java.util.List; + +public class OptAlgoResult { + // vector ogigin_val; // 1200 + // vector supper_val; // 原始数据,线性填充,1200*5=6000 + // vector supper_median_val; // supper_val 窗口平滑滤波,6000 + // vector supper_smooth_sub_val; // supper_smooth_val 均值压缩,6000/6=1000 + public Float[] ogiginVal; + public Float[] supperVal; + public Float[] supperMedianVal; + public Float[] supperSmoothSubVal; +} diff --git a/src/main/java/a8k/optalgo/type/PeakInfo.java b/src/main/java/a8k/optalgo/type/PeakInfo.java new file mode 100644 index 0000000..5d5a951 --- /dev/null +++ b/src/main/java/a8k/optalgo/type/PeakInfo.java @@ -0,0 +1,11 @@ +package a8k.optalgo.type; + +public class PeakInfo { + public Boolean findPeak; + public Float peakFullArea; + public Float peakBaseLineArea; + public Float area; + public Integer peakPos; + public Integer peakStartPos; + public Integer peakEndPos; +} diff --git a/src/main/java/a8k/service/app/AppA8kDeviceStateMgrService.java b/src/main/java/a8k/service/app/AppA8kDeviceStateMgrService.java new file mode 100644 index 0000000..9ad393b --- /dev/null +++ b/src/main/java/a8k/service/app/AppA8kDeviceStateMgrService.java @@ -0,0 +1,53 @@ +package a8k.service.app; + +import a8k.controler.extapi.utils.ExtApiTab; +import a8k.controler.extapi.utils.ExtApiFn; +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.service.appstate.A8kState; +import a8k.service.bak_appbase.progress.TubeHolderProgress; +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.AppStateMgrService) +public class AppA8kDeviceStateMgrService { + public static final Logger logger = LoggerFactory.getLogger(AppA8kDeviceStateMgrService.class); + + static class ORDER { + static final int getDeviceState = 1; + } + + public A8kState deviceState = new A8kState(); + + @PostConstruct + public void init() { + } + + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // EXPOSED API + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + @ExtApiFn(name = "获取设备状态", order = ORDER.getDeviceState) + public A8kState getDeviceState() { + return deviceState; + } + + public Boolean isDeviceInited() { + return deviceState.deviceInited; + } + + public void setDeviceInited(Boolean deviceInited) { + deviceState.deviceInited = deviceInited; + } + + + public TubeHolderProgress getTubeHolderProgress() { + return deviceState.tubeHolderProgress; + } + + public void setTubeHolderProgress(TubeHolderProgress tubeHolderProgress) { + deviceState.tubeHolderProgress = tubeHolderProgress; + } +} diff --git a/src/main/java/a8k/service/app/AppConsumablesMgrService.java b/src/main/java/a8k/service/app/AppConsumablesMgrService.java index 3b75785..6995f45 100644 --- a/src/main/java/a8k/service/app/AppConsumablesMgrService.java +++ b/src/main/java/a8k/service/app/AppConsumablesMgrService.java @@ -12,7 +12,6 @@ import a8k.controler.extapi.utils.ExtApiTab; import a8k.controler.extapi.utils.ExtApiFn; import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; import a8k.service.app.app_consumables_mgr_service.ConsumableState; -import a8k.service.app.appstate.AppStateMgrService; import a8k.type.cfg.Pos2d; import a8k.type.exception.AppException; import a8k.type.projecttype.A8kReactionFlowType; @@ -47,7 +46,7 @@ public class AppConsumablesMgrService { ActionReactorService ar; @Resource - AppStateMgrService stateMgrService; + AppA8kDeviceStateMgrService stateMgrService; @Resource Hbot2DCodeScanPosMgrService hbotScanPos; diff --git a/src/main/java/a8k/service/app/AppDeviceInitializationModule.java b/src/main/java/a8k/service/app/AppDeviceInitializationModule.java index f5655e3..e1e912b 100644 --- a/src/main/java/a8k/service/app/AppDeviceInitializationModule.java +++ b/src/main/java/a8k/service/app/AppDeviceInitializationModule.java @@ -7,7 +7,6 @@ import a8k.hardware.A8kCanBusService; import a8k.hardware.type.a8kcanprotocol.A8kEcode; import a8k.hardware.type.a8kcanprotocol.IOId; import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.service.app.appstate.AppStateMgrService; import a8k.baseservice.ActionReactorService; import a8k.service.app.app_device_initialization_module.checkpoint.CheckPointType; import a8k.service.app.app_device_initialization_module.checkpoint.CheckResult; @@ -33,7 +32,7 @@ public class AppDeviceInitializationModule { A8kCanBusService canBus; @Resource - AppStateMgrService stateMgrService; + AppA8kDeviceStateMgrService stateMgrService; Integer actionOvertime = 10000; diff --git a/src/main/java/a8k/service/app/AppSampleFormulaMgrService.java b/src/main/java/a8k/service/app/AppSampleFormulaMgrService.java new file mode 100644 index 0000000..fffabe2 --- /dev/null +++ b/src/main/java/a8k/service/app/AppSampleFormulaMgrService.java @@ -0,0 +1,130 @@ +package a8k.service.app; + +import a8k.type.appret.AppRet; +import a8k.controler.extapi.utils.ExtApiTab; +import a8k.controler.extapi.utils.ExtApiFn; +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.type.sample_formula_mgr.A8kDeviceSampleCfg; +import a8k.type.type.BloodType; +import a8k.type.sample_formula_mgr.SampleFormula; +import a8k.type.sample_formula_mgr.SampleTubeHolderCfg; +import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import org.springframework.stereotype.Component; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.AppSampleFormulaMgrService) +public class AppSampleFormulaMgrService { + A8kDeviceSampleCfg deviceCfg = new A8kDeviceSampleCfg(); + + static class ORDER { + static final int getA8kDeviceCfg = 1; + static final int addCfg = 2; + static final int removeCfg = 3; + static final int activeCfg = 4; + static final int updateTubeUsrCfg = 5; + static final int clearTubeProjectCfg = 6; + static final int addTubeProjectCode = 7; + static final int setTubeBloodType = 8; + static final int getEmergencyCfg = 9; + static final int addEmergencyCfg = 10; + } + + private SampleTubeHolderCfg dbFindCfg(String tubeHolderCfgUUID) { + for (SampleTubeHolderCfg cfg : deviceCfg.cfgs) { + if (cfg.uuid.equals(tubeHolderCfgUUID)) { + return cfg; + } + } + return null; + } + + private void dbRemoveCfg(String tubeHolderCfgUUID) { + deviceCfg.cfgs.removeIf(cfg -> cfg.uuid.equals(tubeHolderCfgUUID)); + } + + private SampleFormula dbFindTubeCfg(String tubeHolderCfgUUID, Integer tubeIndex) { + SampleTubeHolderCfg cfg = dbFindCfg(tubeHolderCfgUUID); + if (cfg == null) { + return null; + } + return cfg.tubeCfgs.get(tubeIndex); + } + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // EXTERNAL API + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + @ExtApiFn(name = "获取设备配置", group = "基础", order = ORDER.getA8kDeviceCfg) + public A8kDeviceSampleCfg getA8kDeviceCfg() { + return deviceCfg; + } + + @ExtApiFn(name = "添加<试管架>配置", group = "试管架", order = ORDER.addCfg) + public AppRet addCfg() { + SampleTubeHolderCfg cfg = new SampleTubeHolderCfg(); + deviceCfg.cfgs.add(cfg); + return AppRet.success(cfg); + } + + @ExtApiFn(name = "删除<试管架>配置", group = "试管架", order = ORDER.removeCfg) + public AppRet removeCfg(String tubeHolderCfgUUID) { + dbRemoveCfg(tubeHolderCfgUUID); + return AppRet.success(); + } + + @ExtApiFn(name = "激活<试管架>配置", group = "试管架", order = ORDER.activeCfg) + public AppRet activeCfg(String tubeHolderCfgUUID, Boolean active) { + SampleTubeHolderCfg cfg = dbFindCfg(tubeHolderCfgUUID); + if (cfg == null) { + return AppRet.fail(A8kEcode.TubeHolderCfgNotExist.index); + } + cfg.active = active; + return AppRet.success(); + } + + @ExtApiFn(name = "修改<试管>用户信息配置", group = "试管", order = ORDER.updateTubeUsrCfg) + public AppRet updateTubeUsrCfg(String uuid, Integer tubeIndex, String udpid, String barcodeid) { + SampleTubeHolderCfg cfg = dbFindCfg(uuid); + assert cfg != null; + cfg.tubeCfgs.get(tubeIndex).barcodeid = barcodeid; + cfg.tubeCfgs.get(tubeIndex).udpid = udpid; + return AppRet.success(cfg.tubeCfgs.get(tubeIndex)); + } + + @ExtApiFn(name = "清除<试管>项目信息", group = "试管", order = ORDER.clearTubeProjectCfg) + public AppRet clearTubeProjectCfg(String uuid, Integer tubeIndex) { + SampleTubeHolderCfg cfg = dbFindCfg(uuid); + assert cfg != null; + cfg.tubeCfgs.get(tubeIndex).bindProjIndex.clear(); + cfg.tubeCfgs.get(tubeIndex).bloodType = BloodType.WHOLE_BLOOD; + return AppRet.success(cfg.tubeCfgs.get(tubeIndex)); + } + + @ExtApiFn(name = "添加<试管>项目信息", group = "试管", order = ORDER.addTubeProjectCode) + public AppRet addTubeProjectCode(String uuid, Integer tubeIndex, Integer projIndex) { + SampleTubeHolderCfg cfg = dbFindCfg(uuid); + assert cfg != null; + SampleFormula tubeCfg = new SampleFormula(); + tubeCfg.bindProjIndex.add(projIndex); + cfg.tubeCfgs.add(tubeCfg); + return AppRet.success(tubeCfg); + } + + @ExtApiFn(name = "设置<试管>血型", group = "试管", order = ORDER.setTubeBloodType) + public AppRet setTubeBloodType(String uuid, Integer tubeIndex, BloodType bloodType) { + SampleFormula tubeCfg = dbFindTubeCfg(uuid, tubeIndex); + assert tubeCfg != null; + tubeCfg.bloodType = bloodType; + return AppRet.success(); + } + + // @ExtApiFn(name = "获取<急诊位>配置", group = "急诊位", order = ORDER.getEmergencyCfg) + // public AppRet getEmergencyCfg() { + // return AppRet.success(deviceCfg.emergencyCfg); + // } + + // @ExtApiFn(name = "添加<急诊位>配置", group = "急诊位", order = ORDER.addEmergencyCfg) + // public AppRet addEmergencyCfg(EmergencyCfg cfg) { + // deviceCfg.emergencyCfg = cfg; + // return AppRet.success(deviceCfg.emergencyCfg); + // } +} diff --git a/src/main/java/a8k/service/app/SampleFormulaMgrService.java b/src/main/java/a8k/service/app/SampleFormulaMgrService.java deleted file mode 100644 index 1b512c4..0000000 --- a/src/main/java/a8k/service/app/SampleFormulaMgrService.java +++ /dev/null @@ -1,130 +0,0 @@ -package a8k.service.app; - -import a8k.type.appret.AppRet; -import a8k.controler.extapi.utils.ExtApiTab; -import a8k.controler.extapi.utils.ExtApiFn; -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.type.sample_formula_mgr.A8kDeviceSampleCfg; -import a8k.type.type.BloodType; -import a8k.type.sample_formula_mgr.SampleFormula; -import a8k.type.sample_formula_mgr.SampleTubeHolderCfg; -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import org.springframework.stereotype.Component; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.SampleFormulaMgrService) -public class SampleFormulaMgrService { - A8kDeviceSampleCfg deviceCfg = new A8kDeviceSampleCfg(); - - static class ORDER { - static final int getA8kDeviceCfg = 1; - static final int addCfg = 2; - static final int removeCfg = 3; - static final int activeCfg = 4; - static final int updateTubeUsrCfg = 5; - static final int clearTubeProjectCfg = 6; - static final int addTubeProjectCode = 7; - static final int setTubeBloodType = 8; - static final int getEmergencyCfg = 9; - static final int addEmergencyCfg = 10; - } - - private SampleTubeHolderCfg dbFindCfg(String tubeHolderCfgUUID) { - for (SampleTubeHolderCfg cfg : deviceCfg.cfgs) { - if (cfg.uuid.equals(tubeHolderCfgUUID)) { - return cfg; - } - } - return null; - } - - private void dbRemoveCfg(String tubeHolderCfgUUID) { - deviceCfg.cfgs.removeIf(cfg -> cfg.uuid.equals(tubeHolderCfgUUID)); - } - - private SampleFormula dbFindTubeCfg(String tubeHolderCfgUUID, Integer tubeIndex) { - SampleTubeHolderCfg cfg = dbFindCfg(tubeHolderCfgUUID); - if (cfg == null) { - return null; - } - return cfg.tubeCfgs.get(tubeIndex); - } - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // EXTERNAL API - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - @ExtApiFn(name = "获取设备配置", group = "基础", order = ORDER.getA8kDeviceCfg) - public A8kDeviceSampleCfg getA8kDeviceCfg() { - return deviceCfg; - } - - @ExtApiFn(name = "添加<试管架>配置", group = "试管架", order = ORDER.addCfg) - public AppRet addCfg() { - SampleTubeHolderCfg cfg = new SampleTubeHolderCfg(); - deviceCfg.cfgs.add(cfg); - return AppRet.success(cfg); - } - - @ExtApiFn(name = "删除<试管架>配置", group = "试管架", order = ORDER.removeCfg) - public AppRet removeCfg(String tubeHolderCfgUUID) { - dbRemoveCfg(tubeHolderCfgUUID); - return AppRet.success(); - } - - @ExtApiFn(name = "激活<试管架>配置", group = "试管架", order = ORDER.activeCfg) - public AppRet activeCfg(String tubeHolderCfgUUID, Boolean active) { - SampleTubeHolderCfg cfg = dbFindCfg(tubeHolderCfgUUID); - if (cfg == null) { - return AppRet.fail(A8kEcode.TubeHolderCfgNotExist.index); - } - cfg.active = active; - return AppRet.success(); - } - - @ExtApiFn(name = "修改<试管>用户信息配置", group = "试管", order = ORDER.updateTubeUsrCfg) - public AppRet updateTubeUsrCfg(String uuid, Integer tubeIndex, String udpid, String barcodeid) { - SampleTubeHolderCfg cfg = dbFindCfg(uuid); - assert cfg != null; - cfg.tubeCfgs.get(tubeIndex).barcodeid = barcodeid; - cfg.tubeCfgs.get(tubeIndex).udpid = udpid; - return AppRet.success(cfg.tubeCfgs.get(tubeIndex)); - } - - @ExtApiFn(name = "清除<试管>项目信息", group = "试管", order = ORDER.clearTubeProjectCfg) - public AppRet clearTubeProjectCfg(String uuid, Integer tubeIndex) { - SampleTubeHolderCfg cfg = dbFindCfg(uuid); - assert cfg != null; - cfg.tubeCfgs.get(tubeIndex).bindProjIndex.clear(); - cfg.tubeCfgs.get(tubeIndex).bloodType = BloodType.WHOLE_BLOOD; - return AppRet.success(cfg.tubeCfgs.get(tubeIndex)); - } - - @ExtApiFn(name = "添加<试管>项目信息", group = "试管", order = ORDER.addTubeProjectCode) - public AppRet addTubeProjectCode(String uuid, Integer tubeIndex, Integer projIndex) { - SampleTubeHolderCfg cfg = dbFindCfg(uuid); - assert cfg != null; - SampleFormula tubeCfg = new SampleFormula(); - tubeCfg.bindProjIndex.add(projIndex); - cfg.tubeCfgs.add(tubeCfg); - return AppRet.success(tubeCfg); - } - - @ExtApiFn(name = "设置<试管>血型", group = "试管", order = ORDER.setTubeBloodType) - public AppRet setTubeBloodType(String uuid, Integer tubeIndex, BloodType bloodType) { - SampleFormula tubeCfg = dbFindTubeCfg(uuid, tubeIndex); - assert tubeCfg != null; - tubeCfg.bloodType = bloodType; - return AppRet.success(); - } - - // @ExtApiFn(name = "获取<急诊位>配置", group = "急诊位", order = ORDER.getEmergencyCfg) - // public AppRet getEmergencyCfg() { - // return AppRet.success(deviceCfg.emergencyCfg); - // } - - // @ExtApiFn(name = "添加<急诊位>配置", group = "急诊位", order = ORDER.addEmergencyCfg) - // public AppRet addEmergencyCfg(EmergencyCfg cfg) { - // deviceCfg.emergencyCfg = cfg; - // return AppRet.success(deviceCfg.emergencyCfg); - // } -} diff --git a/src/main/java/a8k/service/app/appstate/AppStateMgrService.java b/src/main/java/a8k/service/app/appstate/AppStateMgrService.java deleted file mode 100644 index fb29ff9..0000000 --- a/src/main/java/a8k/service/app/appstate/AppStateMgrService.java +++ /dev/null @@ -1,52 +0,0 @@ -package a8k.service.app.appstate; - -import a8k.controler.extapi.utils.ExtApiTab; -import a8k.controler.extapi.utils.ExtApiFn; -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.service.bak_appbase.A8kDeviceState; -import jakarta.annotation.PostConstruct; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.AppStateMgrService) -public class AppStateMgrService { - public static final Logger logger = LoggerFactory.getLogger(AppStateMgrService.class); - - static class ORDER { - static final int getDeviceState = 1; - } - - public A8kDeviceState deviceState = new A8kDeviceState(); - - @PostConstruct - public void init() { - } - - - // public void setConsumable(ConsumableState cig) { - // deviceState.consumable = cig; - // } - // - // public ConsumableState getConsumable() { - // return deviceState.consumable; - // } - - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // EXPOSED API - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - @ExtApiFn(name = "获取设备状态", order = ORDER.getDeviceState) - public A8kDeviceState getDeviceState() { - return deviceState; - } - - public Boolean isDeviceInited() { - return deviceState.deviceInited; - } - - public void setDeviceInited(Boolean deviceInited) { - deviceState.deviceInited = deviceInited; - } -} diff --git a/src/main/java/a8k/service/appctrl/AppCoreCtrlService.java b/src/main/java/a8k/service/appctrl/AppCoreCtrlService.java new file mode 100644 index 0000000..62201b1 --- /dev/null +++ b/src/main/java/a8k/service/appctrl/AppCoreCtrlService.java @@ -0,0 +1,105 @@ +package a8k.service.appctrl; + +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.controler.extapi.utils.ExtApiTab; +import a8k.service.app.AppA8kDeviceStateMgrService; +import a8k.service.bak_appbase.progress.TubeHolderProgress; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +@ExtApiTab(cfg = ExtApiTabConfig.AppCoreCtrlService) +@Component +public class AppCoreCtrlService { + + @Resource + AppA8kDeviceStateMgrService sms; + + AppRunTask sampleScanAndPreProcessThread; + AppRunTask sampleProcessThread; + AppRunTask incubationPlateCtrlThread; + AppRunTask plateClampResultScanThread; + + + @PostConstruct + void init() { + sampleScanAndPreProcessThread = new AppRunTask(); + sampleProcessThread = new AppRunTask(); + incubationPlateCtrlThread = new AppRunTask(); + plateClampResultScanThread = new AppRunTask(); + + sampleScanAndPreProcessThread.init(this::sampleScanAndPreProcessThreadWorkFn); + + } + + public void startWork() { + //启动所有线程 + // setGState,notify + } + + public void pauseWork() { + //暂停掉 入料和样本处理线程 + // setGstate,notify + // waitForStop + // waitForStop + // + } + + public void continueWork() { + //继续入料和样本处理线程 + //setGState + //notify + } + + public void stopWork() { + //停止所有线程 + //setGState + //notify + //waitForStop + } + + /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * PRIV 私有方法 + *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + + private void doSampleScanAndPreProcessThreadWorkFn() { + AppRunTask appRunTask = sampleScanAndPreProcessThread; + while (!appRunTask.isWaitingForStop()) { + //试管架处理状态-空闲 + if (sms.getTubeHolderProgress().equals(TubeHolderProgress.Idle)) { + } else if (sms.getTubeHolderProgress().equals(TubeHolderProgress.Processing)) { + } else if (sms.getTubeHolderProgress().equals(TubeHolderProgress.Scaning)) { + } + } + /* + * + * motorRun + * waitForTrigger + * scanTubeHolderType + * pausePoint() + * for(int i < 6){ + * scanTubeAndAssignTubeCfg; + * pausePoint(){throw PauseException;} + * } + * assignTubeCfg(); + * + * 用户暂停 + * 程序出错主动暂停 + * + * // pause + * + */ + + + } + + private void sampleScanAndPreProcessThreadWorkFn() { + try { + doSampleScanAndPreProcessThreadWorkFn(); + } catch (Exception ignored) { + + } + } + + +} diff --git a/src/main/java/a8k/service/appctrl/AppRunTask.java b/src/main/java/a8k/service/appctrl/AppRunTask.java new file mode 100644 index 0000000..f8e67f5 --- /dev/null +++ b/src/main/java/a8k/service/appctrl/AppRunTask.java @@ -0,0 +1,89 @@ +package a8k.service.appctrl; + + +public class AppRunTask { + + Thread workThread; + Runnable task; + + Boolean ctrlState = false; + Boolean runState = false; + + public AppRunTask() { + + } + + public void init(Runnable task) { + this.task = task; + this.workThread = new Thread(this::work); + this.workThread.start(); + } + + + private void work() { + while (true) { + if (ctrlState) { + runState = true; + if (task != null) + task.run(); + runState = false; + } else { + sleep(500); + } + } + } + + public Boolean isWaitingForStop() { + return !ctrlState; + } + + + /** + * 启动线程 + */ + public void start() { + ctrlState = true; + this.task.notify(); + } + + /** + * 停止线程 + */ + public void stop() { + ctrlState = false; + } + + /** + * 等待线程停止 + */ + public void waitForStop() { + while (runState) { + sleep(10); + } + } + + + /** + * 睡眠 + * @param mills 毫秒 + */ + public void sleep(Integer mills) { + try { + Thread.sleep(mills); + } catch (InterruptedException ignored) { + } + } + + /** + * 强制睡眠,不会被打断 + * @param mills 毫秒 + */ + public void forceSleep(Integer mills) { + int end = mills + (int) System.currentTimeMillis(); + while (System.currentTimeMillis() < end) { + sleep(50); + } + } + + +} diff --git a/src/main/java/a8k/service/appstate/A8kState.java b/src/main/java/a8k/service/appstate/A8kState.java new file mode 100644 index 0000000..0dba326 --- /dev/null +++ b/src/main/java/a8k/service/appstate/A8kState.java @@ -0,0 +1,28 @@ +package a8k.service.appstate; + +import a8k.service.appstate.type.*; +import a8k.service.bak_appbase.progress.TubeHolderProgress; + +import java.util.List; + +public class A8kState { + public TubeHolderProgress tubeHolderProgress = TubeHolderProgress.Idle; + + + //当前正在被处理的试管架状态 + public TubeHolderState tubeHolderState = new TubeHolderState(); + //急诊为状态 + public EmergencyPosRunState emergencyPosRunState = new EmergencyPosRunState(); + //孵育盘状态 + public IncubationPlateStatus incubationPlateStatus = new IncubationPlateStatus(); + //温度 + public Integer temperature = 25; + //设备是否初始化过 + public Boolean deviceInited = false; + + //所有样本的状态(包含本次开机已经处理过的样本的状态) + public List sampleStates; + //所有反应盘的状态(包含本次开机已经处理过的反应盘的状态) + public List reactingPlateStates; + +} diff --git a/src/main/java/a8k/service/appstate/type/EmergencyPosRunState.java b/src/main/java/a8k/service/appstate/type/EmergencyPosRunState.java new file mode 100644 index 0000000..f56633f --- /dev/null +++ b/src/main/java/a8k/service/appstate/type/EmergencyPosRunState.java @@ -0,0 +1,14 @@ +package a8k.service.appstate.type; + +import a8k.type.sampleinfo.SampleInfo; +import a8k.service.bak_appbase.result.ReactionResult; +import a8k.service.bak_appbase.progress.EmergencySampleProgress; + +public class EmergencyPosRunState { + //急诊位状态 + public EmergencySampleProgress emergencySampleProgress = EmergencySampleProgress.IDLE; + //样本位状态 + SampleInfo sampleState = new SampleInfo(); //绑定的样本运行状态 + //急诊位反应结果 + public ReactionResult emergencyResult = new ReactionResult(); +} diff --git a/src/main/java/a8k/service/appstate/type/IncubationPlateStatus.java b/src/main/java/a8k/service/appstate/type/IncubationPlateStatus.java new file mode 100644 index 0000000..8cfb593 --- /dev/null +++ b/src/main/java/a8k/service/appstate/type/IncubationPlateStatus.java @@ -0,0 +1,5 @@ +package a8k.service.appstate.type; + +public class IncubationPlateStatus { + public ReactingPlateState[] plateStates = new ReactingPlateState[20]; +} diff --git a/src/main/java/a8k/service/appstate/type/ReactingPlateState.java b/src/main/java/a8k/service/appstate/type/ReactingPlateState.java new file mode 100644 index 0000000..ce6e7c4 --- /dev/null +++ b/src/main/java/a8k/service/appstate/type/ReactingPlateState.java @@ -0,0 +1,21 @@ +package a8k.service.appstate.type; + +import a8k.service.bak_appbase.result.ReactionResult; +import a8k.type.sampleinfo.SampleInfo; +import a8k.service.bak_appbase.progress.ReactionPlateProgress; + +import java.util.Date; + +public class ReactingPlateState { + String uuid; + ReactionPlateProgress progress; //孵育盘状态 + + String sampleUUID; //样本UUID 系统自动生成 + String projectId; //项目id + + Integer incubationPos; //孵育盘中的位置 0->19 + Date startIncubatedTime; //开始孵育时间 + Integer targetIncubatedTimeS; //目标孵育时间 + + ReactionResult reactionResult; //反应结果 +} diff --git a/src/main/java/a8k/service/appstate/type/SampleState.java b/src/main/java/a8k/service/appstate/type/SampleState.java new file mode 100644 index 0000000..042105f --- /dev/null +++ b/src/main/java/a8k/service/appstate/type/SampleState.java @@ -0,0 +1,9 @@ +package a8k.service.appstate.type; + +import a8k.type.sampleinfo.SampleInfo; +import a8k.service.bak_appbase.progress.TubeProcessProgress; + +public class SampleState { + public TubeProcessProgress tubeProcessProgress = TubeProcessProgress.EMPTY; //样本运行状态 + public SampleInfo bindSample = new SampleInfo(); //绑定的样本运行状态 +} diff --git a/src/main/java/a8k/service/appstate/type/TubeHolderState.java b/src/main/java/a8k/service/appstate/type/TubeHolderState.java new file mode 100644 index 0000000..adab774 --- /dev/null +++ b/src/main/java/a8k/service/appstate/type/TubeHolderState.java @@ -0,0 +1,16 @@ +package a8k.service.appstate.type; + +import a8k.type.type.A8kTubeType; +import a8k.type.type.BloodType; +import a8k.service.bak_appbase.progress.TubeHolderProgress; + +public class TubeHolderState { + public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //管子类型 + public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型 + + //样本状态 + public SampleState[] sampleStates = new SampleState[10]; + + public TubeHolderProgress tubeHolderProgress = TubeHolderProgress.Idle; //管子状态 + public Integer processingTubeIndex = -1; //当前正在被处理的试管索引 +} diff --git a/src/main/java/a8k/service/bak_appbase/A8kDeviceState.java b/src/main/java/a8k/service/bak_appbase/A8kDeviceState.java deleted file mode 100644 index 54c77a0..0000000 --- a/src/main/java/a8k/service/bak_appbase/A8kDeviceState.java +++ /dev/null @@ -1,26 +0,0 @@ -package a8k.service.bak_appbase; - -import a8k.service.app.app_consumables_mgr_service.ConsumableState; -import a8k.service.bak_appbase.runstate.ReactingPlateRunState; -import a8k.service.bak_appbase.runstate.EmergencyPosRunState; -import a8k.service.bak_appbase.runstate.TubeHolderRunState; - -import java.util.List; - -public class A8kDeviceState { - //耗材状态 - public ConsumableState consumable = new ConsumableState(); - //急诊为状态 - public EmergencyPosRunState emergencyPosRunState = new EmergencyPosRunState(); - //正在孵育的任务状态 - public List incubatingPlateStates = null; - //当前正在被处理的试管架状态 - public TubeHolderRunState tubeHolderRunState = new TubeHolderRunState(); - //温度 - public Integer temperature = 25; - - - public Boolean deviceInited = false; //设备是否初始化过 - public Boolean devicePoweredOffNormally = false; //设备是否正常关机 - -} diff --git a/src/main/java/a8k/service/bak_appbase/progress/TubeHolderProgress.java b/src/main/java/a8k/service/bak_appbase/progress/TubeHolderProgress.java index 9fe0fc0..de0dca4 100644 --- a/src/main/java/a8k/service/bak_appbase/progress/TubeHolderProgress.java +++ b/src/main/java/a8k/service/bak_appbase/progress/TubeHolderProgress.java @@ -1,7 +1,7 @@ package a8k.service.bak_appbase.progress; public enum TubeHolderProgress { - TubeHolderStateIdle, //空闲 - TubeHolderStateProcessing, //处理中 - TubeHolderStateProcessed, //处理完成 + Idle, //空闲 + Processing, //处理中 + Scaning, //处理中 } diff --git a/src/main/java/a8k/service/bak_appbase/runstate/EmergencyPosRunState.java b/src/main/java/a8k/service/bak_appbase/runstate/EmergencyPosRunState.java deleted file mode 100644 index 4589382..0000000 --- a/src/main/java/a8k/service/bak_appbase/runstate/EmergencyPosRunState.java +++ /dev/null @@ -1,14 +0,0 @@ -package a8k.service.bak_appbase.runstate; - -import a8k.type.sampleinfo.SampleInfo; -import a8k.service.bak_appbase.result.ReactionResult; -import a8k.service.bak_appbase.progress.EmergencySampleProgress; - -public class EmergencyPosRunState { - //急诊位状态 - public EmergencySampleProgress emergencySampleProgress = EmergencySampleProgress.IDLE; - // - SampleInfo bindSample = new SampleInfo(); //绑定的样本运行状态 - //急诊位反应结果 - public ReactionResult emergencyResult = new ReactionResult(); -} diff --git a/src/main/java/a8k/service/bak_appbase/runstate/ReactingPlateRunState.java b/src/main/java/a8k/service/bak_appbase/runstate/ReactingPlateRunState.java deleted file mode 100644 index e121b4d..0000000 --- a/src/main/java/a8k/service/bak_appbase/runstate/ReactingPlateRunState.java +++ /dev/null @@ -1,22 +0,0 @@ -package a8k.service.bak_appbase.runstate; - -import a8k.service.bak_appbase.result.ReactionResult; -import a8k.type.sampleinfo.SampleInfo; -import a8k.service.bak_appbase.progress.ReactionPlateProgress; - -import java.util.Date; - -public class ReactingPlateRunState { - ReactionPlateProgress progress; //孵育盘状态 - - String sampleUUID; //样本UUID 系统自动生成 - String projectId; //项目id - - SampleInfo bindSample; //绑定的样本运行状态 - - Integer incubationPos; //孵育盘中的位置 0->19 - Date startIncubatedTime; //开始孵育时间 - Integer targetIncubatedTimeS; //目标孵育时间 - - ReactionResult reactionResult; //反应结果 -} diff --git a/src/main/java/a8k/service/bak_appbase/runstate/TubeHolderRunState.java b/src/main/java/a8k/service/bak_appbase/runstate/TubeHolderRunState.java deleted file mode 100644 index 8b27288..0000000 --- a/src/main/java/a8k/service/bak_appbase/runstate/TubeHolderRunState.java +++ /dev/null @@ -1,20 +0,0 @@ -package a8k.service.bak_appbase.runstate; - -import a8k.type.type.A8kTubeType; -import a8k.type.type.BloodType; -import a8k.service.bak_appbase.progress.TubeHolderProgress; - -public class TubeHolderRunState { - public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型 - public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //管子类型 - public TubeHolderProgress tubeHolderProgress = TubeHolderProgress.TubeHolderStateIdle; //管子状态 - public TubeRunState[] tubeRunStates = new TubeRunState[10]; //管子 - public Integer processingTubeIndex = -1; //当前正在被处理的试管索引 - - public TubeHolderRunState() { - for (int i = 0; i < tubeRunStates.length; i++) { - tubeRunStates[i] = new TubeRunState(); - } - processingTubeIndex = 1; - } -} diff --git a/src/main/java/a8k/service/bak_appbase/runstate/TubeRunState.java b/src/main/java/a8k/service/bak_appbase/runstate/TubeRunState.java deleted file mode 100644 index c116959..0000000 --- a/src/main/java/a8k/service/bak_appbase/runstate/TubeRunState.java +++ /dev/null @@ -1,9 +0,0 @@ -package a8k.service.bak_appbase.runstate; - -import a8k.type.sampleinfo.SampleInfo; -import a8k.service.bak_appbase.progress.TubeProcessProgress; - -public class TubeRunState { - public TubeProcessProgress tubeProcessProgress = TubeProcessProgress.EMPTY; //样本运行状态 - public SampleInfo bindSample = new SampleInfo(); //绑定的样本运行状态 -} diff --git a/src/main/java/a8k/type/exception/ActionBreakException.java b/src/main/java/a8k/type/exception/ActionBreakException.java deleted file mode 100644 index 84da98e..0000000 --- a/src/main/java/a8k/type/exception/ActionBreakException.java +++ /dev/null @@ -1,4 +0,0 @@ -package a8k.type.exception; - -public class ActionBreakException extends Exception { -} diff --git a/src/main/java/a8k/type/exception/AppPauseException.java b/src/main/java/a8k/type/exception/AppPauseException.java new file mode 100644 index 0000000..97c9dfa --- /dev/null +++ b/src/main/java/a8k/type/exception/AppPauseException.java @@ -0,0 +1,4 @@ +package a8k.type.exception; + +public class AppPauseException extends Exception { +}