From 02c77469e9b0726226f1eab57432051413d1fa34 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Wed, 31 Jul 2024 17:22:11 +0800 Subject: [PATCH] update --- src/main/java/a8k/appbase/A8kTubeType.java | 17 -- src/main/java/a8k/appbase/AppEventListener.java | 7 - .../java/a8k/appbase/sampleinfo/SampleInfo.java | 12 ++ src/main/java/a8k/appbase/type/A8kTubeType.java | 17 ++ src/main/java/a8k/appbase/type/BloodType.java | 6 + src/main/java/a8k/service/FrontEndEventRouter.java | 2 +- .../java/a8k/service/appbase/A8kDeviceState.java | 28 +++ .../appbase/progress/EmergencySampleProgress.java | 8 + .../appbase/progress/ReactionPlateProgress.java | 17 ++ .../appbase/progress/TubeHolderProgress.java | 7 + .../appbase/progress/TubeProcessProgress.java | 18 ++ .../a8k/service/appbase/result/ReactionResult.java | 13 ++ .../appbase/runstate/EmergencyPosRunState.java | 14 ++ .../appbase/runstate/ReactingPlateRunState.java | 22 +++ .../appbase/runstate/TubeHolderRunState.java | 20 ++ .../a8k/service/appbase/runstate/TubeRunState.java | 12 ++ .../java/a8k/service/appcfgs/A8kDeviceCfg.java | 12 -- .../service/appcfgs/A8kDeviceCfgMgrService.java | 34 ++-- .../a8k/service/appcfgs/base/A8kDeviceCfg.java | 10 + .../a8k/service/appcfgs/base/EmergencyCfg.java | 19 ++ .../a8k/service/appcfgs/base/SampleTubeCfg.java | 15 ++ .../service/appcfgs/base/SampleTubeHolderCfg.java | 23 +++ .../appconsumable/AppConsumableMgrService.java | 44 +++++ .../appconsumable/base/ConsumableItemGroup.java | 19 ++ .../service/appconsumable/base/ReactantItem.java | 16 ++ .../service/appconsumable/base/TipGroupInfo.java | 5 + .../java/a8k/service/appctrl/AppCtrlService.java | 53 +++++ .../appctrl/DeviceInitializationCtrlService.java | 215 +++++++++++++++++++++ .../service/appctrl/DeviceShutdowCtrlService.java | 8 + .../service/appctrl/DeviceShutdownCtrlService.java | 11 ++ .../service/appeventbus/AppEventBusService.java | 1 - .../a8k/service/appeventbus/AppEventListener.java | 7 + .../a8k/service/appstate/AppStateMgrService.java | 41 ++++ src/main/java/a8k/service/base/A8kDeviceState.java | 35 ---- src/main/java/a8k/service/base/BloodType.java | 6 - .../base/consumable/ConsumableItemGroup.java | 10 - .../a8k/service/base/consumable/ReactantItem.java | 16 -- .../a8k/service/base/consumable/TipGroupInfo.java | 5 - .../java/a8k/service/base/plate/PlateState.java | 12 -- .../a8k/service/base/plate/ReactingPlateState.java | 23 --- .../base/reaction_result/ReactionResult.java | 13 -- .../a8k/service/base/sample/EmergencyPosState.java | 7 - .../service/base/sample/EmergencySampleInfo.java | 6 - .../java/a8k/service/base/sample/SampleInfo.java | 9 - src/main/java/a8k/service/base/sample/Tube.java | 8 - .../java/a8k/service/base/sample/TubeHolder.java | 12 -- .../a8k/service/base/sample/TubeHolderState.java | 7 - .../java/a8k/service/base/sample/TubeState.java | 18 -- .../a8k/service/base/samplecfg/SampleTubeCfg.java | 17 -- .../base/samplecfg/SampleTubeHolderCfg.java | 24 --- .../a8k/service/ctrl_service/AppCtrlService.java | 78 -------- .../ctrl_service/ConsumableLoadingService.java | 22 --- .../DeviceInitializationCtrlService.java | 215 --------------------- .../ctrl_service/DeviceShutdowCtrlService.java | 8 - .../ctrl_service/DeviceShutdownCtrlService.java | 9 - .../SamplesPreProcessModuleCtrlService.java | 2 +- .../hardware/canbus/A8kModParamInitializer.java | 2 +- .../service/project_mgr/ProjectItemMgrService.java | 27 +-- .../java/a8k/service/state_service/A8kState.java | 5 - .../java/a8k/service/state_service/A8kStateDB.java | 17 -- .../service/state_service/A8kStateMgrService.java | 37 ---- zhaohe_app.db | Bin 192512 -> 0 bytes 62 files changed, 721 insertions(+), 682 deletions(-) delete mode 100644 src/main/java/a8k/appbase/A8kTubeType.java delete mode 100644 src/main/java/a8k/appbase/AppEventListener.java create mode 100644 src/main/java/a8k/appbase/sampleinfo/SampleInfo.java create mode 100644 src/main/java/a8k/appbase/type/A8kTubeType.java create mode 100644 src/main/java/a8k/appbase/type/BloodType.java create mode 100644 src/main/java/a8k/service/appbase/A8kDeviceState.java create mode 100644 src/main/java/a8k/service/appbase/progress/EmergencySampleProgress.java create mode 100644 src/main/java/a8k/service/appbase/progress/ReactionPlateProgress.java create mode 100644 src/main/java/a8k/service/appbase/progress/TubeHolderProgress.java create mode 100644 src/main/java/a8k/service/appbase/progress/TubeProcessProgress.java create mode 100644 src/main/java/a8k/service/appbase/result/ReactionResult.java create mode 100644 src/main/java/a8k/service/appbase/runstate/EmergencyPosRunState.java create mode 100644 src/main/java/a8k/service/appbase/runstate/ReactingPlateRunState.java create mode 100644 src/main/java/a8k/service/appbase/runstate/TubeHolderRunState.java create mode 100644 src/main/java/a8k/service/appbase/runstate/TubeRunState.java delete mode 100644 src/main/java/a8k/service/appcfgs/A8kDeviceCfg.java create mode 100644 src/main/java/a8k/service/appcfgs/base/A8kDeviceCfg.java create mode 100644 src/main/java/a8k/service/appcfgs/base/EmergencyCfg.java create mode 100644 src/main/java/a8k/service/appcfgs/base/SampleTubeCfg.java create mode 100644 src/main/java/a8k/service/appcfgs/base/SampleTubeHolderCfg.java create mode 100644 src/main/java/a8k/service/appconsumable/AppConsumableMgrService.java create mode 100644 src/main/java/a8k/service/appconsumable/base/ConsumableItemGroup.java create mode 100644 src/main/java/a8k/service/appconsumable/base/ReactantItem.java create mode 100644 src/main/java/a8k/service/appconsumable/base/TipGroupInfo.java create mode 100644 src/main/java/a8k/service/appctrl/AppCtrlService.java create mode 100644 src/main/java/a8k/service/appctrl/DeviceInitializationCtrlService.java create mode 100644 src/main/java/a8k/service/appctrl/DeviceShutdowCtrlService.java create mode 100644 src/main/java/a8k/service/appctrl/DeviceShutdownCtrlService.java create mode 100644 src/main/java/a8k/service/appeventbus/AppEventListener.java create mode 100644 src/main/java/a8k/service/appstate/AppStateMgrService.java delete mode 100644 src/main/java/a8k/service/base/A8kDeviceState.java delete mode 100644 src/main/java/a8k/service/base/BloodType.java delete mode 100644 src/main/java/a8k/service/base/consumable/ConsumableItemGroup.java delete mode 100644 src/main/java/a8k/service/base/consumable/ReactantItem.java delete mode 100644 src/main/java/a8k/service/base/consumable/TipGroupInfo.java delete mode 100644 src/main/java/a8k/service/base/plate/PlateState.java delete mode 100644 src/main/java/a8k/service/base/plate/ReactingPlateState.java delete mode 100644 src/main/java/a8k/service/base/reaction_result/ReactionResult.java delete mode 100644 src/main/java/a8k/service/base/sample/EmergencyPosState.java delete mode 100644 src/main/java/a8k/service/base/sample/EmergencySampleInfo.java delete mode 100644 src/main/java/a8k/service/base/sample/SampleInfo.java delete mode 100644 src/main/java/a8k/service/base/sample/Tube.java delete mode 100644 src/main/java/a8k/service/base/sample/TubeHolder.java delete mode 100644 src/main/java/a8k/service/base/sample/TubeHolderState.java delete mode 100644 src/main/java/a8k/service/base/sample/TubeState.java delete mode 100644 src/main/java/a8k/service/base/samplecfg/SampleTubeCfg.java delete mode 100644 src/main/java/a8k/service/base/samplecfg/SampleTubeHolderCfg.java delete mode 100644 src/main/java/a8k/service/ctrl_service/AppCtrlService.java delete mode 100644 src/main/java/a8k/service/ctrl_service/ConsumableLoadingService.java delete mode 100644 src/main/java/a8k/service/ctrl_service/DeviceInitializationCtrlService.java delete mode 100644 src/main/java/a8k/service/ctrl_service/DeviceShutdowCtrlService.java delete mode 100644 src/main/java/a8k/service/ctrl_service/DeviceShutdownCtrlService.java delete mode 100644 src/main/java/a8k/service/state_service/A8kState.java delete mode 100644 src/main/java/a8k/service/state_service/A8kStateDB.java delete mode 100644 src/main/java/a8k/service/state_service/A8kStateMgrService.java delete mode 100644 zhaohe_app.db diff --git a/src/main/java/a8k/appbase/A8kTubeType.java b/src/main/java/a8k/appbase/A8kTubeType.java deleted file mode 100644 index b0a32e3..0000000 --- a/src/main/java/a8k/appbase/A8kTubeType.java +++ /dev/null @@ -1,17 +0,0 @@ -package a8k.appbase; - - -public enum A8kTubeType { - - BloodTube("0000"), //全血试管 - ShortBloodTube("0000"), //全血试管 - MiniTube("1111"), //迷你试管 - MiniBlood("2222"), //阳普管 - BulletTube1P5("5555"),//子弹头试管1.5mL - BulletTube0P5("4444"); //子弹头试管0.5mL - - final public String scanCode; - A8kTubeType(String scanCode) { - this.scanCode = scanCode; - } -} diff --git a/src/main/java/a8k/appbase/AppEventListener.java b/src/main/java/a8k/appbase/AppEventListener.java deleted file mode 100644 index e7ff6c2..0000000 --- a/src/main/java/a8k/appbase/AppEventListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package a8k.appbase; - -import a8k.service.appeventbus.appevent.AppEvent; - -public interface AppEventListener { - public void onAppEvent(AppEvent event); -} diff --git a/src/main/java/a8k/appbase/sampleinfo/SampleInfo.java b/src/main/java/a8k/appbase/sampleinfo/SampleInfo.java new file mode 100644 index 0000000..47c44b3 --- /dev/null +++ b/src/main/java/a8k/appbase/sampleinfo/SampleInfo.java @@ -0,0 +1,12 @@ +package a8k.appbase.sampleinfo; + +import a8k.appbase.type.BloodType; + +import java.util.List; + +public class SampleInfo { + public String udpid; //用户输入的样本ID,不做逻辑,只做展示 + public String barcodeid; //用于请求用户信息的条码ID + public List projectCodes = null; //项目代码 + public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型 +} diff --git a/src/main/java/a8k/appbase/type/A8kTubeType.java b/src/main/java/a8k/appbase/type/A8kTubeType.java new file mode 100644 index 0000000..603249a --- /dev/null +++ b/src/main/java/a8k/appbase/type/A8kTubeType.java @@ -0,0 +1,17 @@ +package a8k.appbase.type; + + +public enum A8kTubeType { + + BloodTube("0000"), //全血试管 + ShortBloodTube("0000"), //全血试管 + MiniTube("1111"), //迷你试管 + MiniBlood("2222"), //阳普管 + BulletTube1P5("5555"),//子弹头试管1.5mL + BulletTube0P5("4444"); //子弹头试管0.5mL + + final public String scanCode; + A8kTubeType(String scanCode) { + this.scanCode = scanCode; + } +} diff --git a/src/main/java/a8k/appbase/type/BloodType.java b/src/main/java/a8k/appbase/type/BloodType.java new file mode 100644 index 0000000..b2e4846 --- /dev/null +++ b/src/main/java/a8k/appbase/type/BloodType.java @@ -0,0 +1,6 @@ +package a8k.appbase.type; + +public enum BloodType { + WHOLE_BLOOD, + SERUM; +} diff --git a/src/main/java/a8k/service/FrontEndEventRouter.java b/src/main/java/a8k/service/FrontEndEventRouter.java index 090fb2b..b6467f3 100644 --- a/src/main/java/a8k/service/FrontEndEventRouter.java +++ b/src/main/java/a8k/service/FrontEndEventRouter.java @@ -1,6 +1,6 @@ package a8k.service; -import a8k.appbase.AppEventListener; +import a8k.service.appeventbus.AppEventListener; import a8k.appbase.appret.AppRet; import a8k.controler.engineer.utils.EngineerPageTab; import a8k.controler.engineer.utils.EnginnerPageAction; diff --git a/src/main/java/a8k/service/appbase/A8kDeviceState.java b/src/main/java/a8k/service/appbase/A8kDeviceState.java new file mode 100644 index 0000000..90a7b4b --- /dev/null +++ b/src/main/java/a8k/service/appbase/A8kDeviceState.java @@ -0,0 +1,28 @@ +package a8k.service.appbase; + +import a8k.db.ProjectInfo; +import a8k.service.appconsumable.base.ConsumableItemGroup; +import a8k.service.appbase.runstate.ReactingPlateRunState; +import a8k.service.appbase.runstate.EmergencyPosRunState; +import a8k.service.appbase.runstate.TubeHolderRunState; + +import java.util.List; + +public class A8kDeviceState { + //耗材状态 + public ConsumableItemGroup consumable = new ConsumableItemGroup(); + //急诊为状态 + public EmergencyPosRunState emergencyPosRunState = new EmergencyPosRunState(); + //正在孵育的任务状态 + public List incubatingPlateStates = null; + //当前正在被处理的试管架状态 + public TubeHolderRunState tubeHolderRunState = new TubeHolderRunState(); + //温度 + public Integer temperature = 25; + //当前ID卡信息 + public ProjectInfo curIdCardInfo = null; + + Boolean deviceInited = false; //设备是否初始化过 + Boolean devicePoweredOffNormally = false; //设备是否正常关机 + +} diff --git a/src/main/java/a8k/service/appbase/progress/EmergencySampleProgress.java b/src/main/java/a8k/service/appbase/progress/EmergencySampleProgress.java new file mode 100644 index 0000000..a7206e5 --- /dev/null +++ b/src/main/java/a8k/service/appbase/progress/EmergencySampleProgress.java @@ -0,0 +1,8 @@ +package a8k.service.appbase.progress; + +public enum EmergencySampleProgress { + IDLE,// + WAITING_SAMPLE,// + PROCESSING,// + PROCESS_COMPLETE,// +} diff --git a/src/main/java/a8k/service/appbase/progress/ReactionPlateProgress.java b/src/main/java/a8k/service/appbase/progress/ReactionPlateProgress.java new file mode 100644 index 0000000..59384e2 --- /dev/null +++ b/src/main/java/a8k/service/appbase/progress/ReactionPlateProgress.java @@ -0,0 +1,17 @@ +package a8k.service.appbase.progress; + +//反应板条状态 +public enum ReactionPlateProgress { + //板夹仓中 + InThePlateBox, + //等待滴液 + WaitingForDrip, + //赋予中 + Incubating, + //孵育完成 + Incubated, + //孵育异常 + IncubateError, + //板条码异常 + PlateCodeError, +} diff --git a/src/main/java/a8k/service/appbase/progress/TubeHolderProgress.java b/src/main/java/a8k/service/appbase/progress/TubeHolderProgress.java new file mode 100644 index 0000000..261cef5 --- /dev/null +++ b/src/main/java/a8k/service/appbase/progress/TubeHolderProgress.java @@ -0,0 +1,7 @@ +package a8k.service.appbase.progress; + +public enum TubeHolderProgress { + TubeHolderStateIdle, //空闲 + TubeHolderStateProcessing, //处理中 + TubeHolderStateProcessed, //处理完成 +} diff --git a/src/main/java/a8k/service/appbase/progress/TubeProcessProgress.java b/src/main/java/a8k/service/appbase/progress/TubeProcessProgress.java new file mode 100644 index 0000000..4e739ba --- /dev/null +++ b/src/main/java/a8k/service/appbase/progress/TubeProcessProgress.java @@ -0,0 +1,18 @@ +package a8k.service.appbase.progress; + +public enum TubeProcessProgress { + //空 + EMPTY, + //待处理 + READY, + //预处理中 + PRE_PROCESSING, + //待采样 + TO_BE_SAMPLED, + //采样中 + SAMPLING, + //采样完成 + SAMPLED, + //处理完成 + PROCESS_COMPLETE, +} diff --git a/src/main/java/a8k/service/appbase/result/ReactionResult.java b/src/main/java/a8k/service/appbase/result/ReactionResult.java new file mode 100644 index 0000000..33dacad --- /dev/null +++ b/src/main/java/a8k/service/appbase/result/ReactionResult.java @@ -0,0 +1,13 @@ +package a8k.service.appbase.result; + +public class ReactionResult { + + public Boolean result0Error; + public Boolean result1Error; + public Boolean result2Error; + + public String result0; + public String result1; + public String result2; + +} diff --git a/src/main/java/a8k/service/appbase/runstate/EmergencyPosRunState.java b/src/main/java/a8k/service/appbase/runstate/EmergencyPosRunState.java new file mode 100644 index 0000000..f650df4 --- /dev/null +++ b/src/main/java/a8k/service/appbase/runstate/EmergencyPosRunState.java @@ -0,0 +1,14 @@ +package a8k.service.appbase.runstate; + +import a8k.appbase.sampleinfo.SampleInfo; +import a8k.service.appbase.result.ReactionResult; +import a8k.service.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/appbase/runstate/ReactingPlateRunState.java b/src/main/java/a8k/service/appbase/runstate/ReactingPlateRunState.java new file mode 100644 index 0000000..db7aa99 --- /dev/null +++ b/src/main/java/a8k/service/appbase/runstate/ReactingPlateRunState.java @@ -0,0 +1,22 @@ +package a8k.service.appbase.runstate; + +import a8k.service.appbase.result.ReactionResult; +import a8k.appbase.sampleinfo.SampleInfo; +import a8k.service.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/appbase/runstate/TubeHolderRunState.java b/src/main/java/a8k/service/appbase/runstate/TubeHolderRunState.java new file mode 100644 index 0000000..612bc83 --- /dev/null +++ b/src/main/java/a8k/service/appbase/runstate/TubeHolderRunState.java @@ -0,0 +1,20 @@ +package a8k.service.appbase.runstate; + +import a8k.appbase.type.A8kTubeType; +import a8k.appbase.type.BloodType; +import a8k.service.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/appbase/runstate/TubeRunState.java b/src/main/java/a8k/service/appbase/runstate/TubeRunState.java new file mode 100644 index 0000000..e5bc326 --- /dev/null +++ b/src/main/java/a8k/service/appbase/runstate/TubeRunState.java @@ -0,0 +1,12 @@ +package a8k.service.appbase.runstate; + +import a8k.appbase.sampleinfo.SampleInfo; +import a8k.appbase.type.BloodType; +import a8k.service.appbase.progress.TubeProcessProgress; + +import java.util.List; + +public class TubeRunState { + public TubeProcessProgress tubeProcessProgress = TubeProcessProgress.EMPTY; //样本运行状态 + public SampleInfo bindSample = new SampleInfo(); //绑定的样本运行状态 +} diff --git a/src/main/java/a8k/service/appcfgs/A8kDeviceCfg.java b/src/main/java/a8k/service/appcfgs/A8kDeviceCfg.java deleted file mode 100644 index e1f377d..0000000 --- a/src/main/java/a8k/service/appcfgs/A8kDeviceCfg.java +++ /dev/null @@ -1,12 +0,0 @@ -package a8k.service.appcfgs; - -import a8k.service.base.samplecfg.SampleTubeHolderCfg; - -import java.util.ArrayList; -import java.util.List; - -public class A8kDeviceCfg { - //配置 - public List cfgs = new ArrayList<>(); - -} diff --git a/src/main/java/a8k/service/appcfgs/A8kDeviceCfgMgrService.java b/src/main/java/a8k/service/appcfgs/A8kDeviceCfgMgrService.java index 5bdb7ed..acf9f48 100644 --- a/src/main/java/a8k/service/appcfgs/A8kDeviceCfgMgrService.java +++ b/src/main/java/a8k/service/appcfgs/A8kDeviceCfgMgrService.java @@ -3,9 +3,11 @@ package a8k.service.appcfgs; import a8k.appbase.appret.AppRet; import a8k.controler.engineer.utils.EngineerPageTab; import a8k.controler.engineer.utils.EnginnerPageAction; -import a8k.service.base.BloodType; -import a8k.service.base.samplecfg.SampleTubeCfg; -import a8k.service.base.samplecfg.SampleTubeHolderCfg; +import a8k.service.appcfgs.base.A8kDeviceCfg; +import a8k.service.appcfgs.base.EmergencyCfg; +import a8k.appbase.type.BloodType; +import a8k.service.appcfgs.base.SampleTubeCfg; +import a8k.service.appcfgs.base.SampleTubeHolderCfg; import a8k.service.hardware.canbus.protocol.A8kEcode; import org.springframework.stereotype.Component; @@ -37,26 +39,26 @@ public class A8kDeviceCfgMgrService { } - @EnginnerPageAction(name = "获取设备配置",group = "基础",groupOrder = 1) + @EnginnerPageAction(name = "获取设备配置", group = "基础", groupOrder = 1) public A8kDeviceCfg getA8kDeviceCfg() { return deviceCfg; } - @EnginnerPageAction(name = "添加<试管架>配置",group = "试管架",groupOrder = 2) + @EnginnerPageAction(name = "添加<试管架>配置", group = "试管架", groupOrder = 2) public AppRet addCfg() { SampleTubeHolderCfg cfg = new SampleTubeHolderCfg(); deviceCfg.cfgs.add(cfg); return AppRet.success(cfg); } - @EnginnerPageAction(name = "删除<试管架>配置",group = "试管架") + @EnginnerPageAction(name = "删除<试管架>配置", group = "试管架") public AppRet removeCfg(String tubeHolderCfgUUID) { dbRemoveCfg(tubeHolderCfgUUID); return AppRet.success(); } - @EnginnerPageAction(name = "激活<试管架>配置",group = "试管架") + @EnginnerPageAction(name = "激活<试管架>配置", group = "试管架") public AppRet activeCfg(String tubeHolderCfgUUID, Boolean active) { SampleTubeHolderCfg cfg = dbFindCfg(tubeHolderCfgUUID); if (cfg == null) { @@ -67,7 +69,7 @@ public class A8kDeviceCfgMgrService { } - @EnginnerPageAction(name = "修改<试管>用户信息配置",group = "试管",groupOrder = 3) + @EnginnerPageAction(name = "修改<试管>用户信息配置", group = "试管", groupOrder = 3) public AppRet updateTubeUsrCfg(String uuid, Integer tubeIndex, String udpid, String barcodeid) { SampleTubeHolderCfg cfg = dbFindCfg(uuid); assert cfg != null; @@ -77,7 +79,7 @@ public class A8kDeviceCfgMgrService { } - @EnginnerPageAction(name = "清除<试管>项目信息",group = "试管") + @EnginnerPageAction(name = "清除<试管>项目信息", group = "试管") public AppRet clearTubeProjectCfg(String uuid, Integer tubeIndex) { SampleTubeHolderCfg cfg = dbFindCfg(uuid); assert cfg != null; @@ -86,7 +88,7 @@ public class A8kDeviceCfgMgrService { return AppRet.success(cfg.tubeCfgs.get(tubeIndex)); } - @EnginnerPageAction(name = "添加<试管>项目信息",group = "试管") + @EnginnerPageAction(name = "添加<试管>项目信息", group = "试管") public AppRet addTubeProjectCode(String uuid, Integer tubeIndex, String pjc) { SampleTubeHolderCfg cfg = dbFindCfg(uuid); assert cfg != null; @@ -96,7 +98,7 @@ public class A8kDeviceCfgMgrService { return AppRet.success(tubeCfg); } - @EnginnerPageAction(name = "设置<试管>血型",group = "试管") + @EnginnerPageAction(name = "设置<试管>血型", group = "试管") public AppRet setTubeBloodType(String uuid, Integer tubeIndex, BloodType bloodType) { SampleTubeCfg tubeCfg = dbFindTubeCfg(uuid, tubeIndex); assert tubeCfg != null; @@ -104,4 +106,14 @@ public class A8kDeviceCfgMgrService { return AppRet.success(); } + @EnginnerPageAction(name = "获取<急诊位>配置", group = "急诊位", groupOrder = 4) + public AppRet getEmergencyCfg() { + return AppRet.success(deviceCfg.emergencyCfg); + } + + @EnginnerPageAction(name = "添加<急诊位>配置", group = "急诊位") + public AppRet addEmergencyCfg(EmergencyCfg cfg) { + deviceCfg.emergencyCfg = cfg; + return AppRet.success(deviceCfg.emergencyCfg); + } } diff --git a/src/main/java/a8k/service/appcfgs/base/A8kDeviceCfg.java b/src/main/java/a8k/service/appcfgs/base/A8kDeviceCfg.java new file mode 100644 index 0000000..3e30b5b --- /dev/null +++ b/src/main/java/a8k/service/appcfgs/base/A8kDeviceCfg.java @@ -0,0 +1,10 @@ +package a8k.service.appcfgs.base; + +import java.util.ArrayList; +import java.util.List; + +public class A8kDeviceCfg { + //配置 + public List cfgs = new ArrayList<>(); + public EmergencyCfg emergencyCfg = null; +} diff --git a/src/main/java/a8k/service/appcfgs/base/EmergencyCfg.java b/src/main/java/a8k/service/appcfgs/base/EmergencyCfg.java new file mode 100644 index 0000000..7679ae7 --- /dev/null +++ b/src/main/java/a8k/service/appcfgs/base/EmergencyCfg.java @@ -0,0 +1,19 @@ +package a8k.service.appcfgs.base; + +import a8k.appbase.type.BloodType; + +import java.util.List; + +public class EmergencyCfg { + public String udpid; //用户输入的样本ID,不做逻辑,只做展示 + public String barcodeid; //用于请求用户信息的条码ID + public List projectCodes; //项目编码,用于查找项目相关信息 + public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型 + + public String projectCodes0; + public String projectCodes1; + public String projectCodes2; + public String projectCodes3; + public String projectCodes4; + public String projectCodes5; +} diff --git a/src/main/java/a8k/service/appcfgs/base/SampleTubeCfg.java b/src/main/java/a8k/service/appcfgs/base/SampleTubeCfg.java new file mode 100644 index 0000000..0db00e6 --- /dev/null +++ b/src/main/java/a8k/service/appcfgs/base/SampleTubeCfg.java @@ -0,0 +1,15 @@ +package a8k.service.appcfgs.base; + +import a8k.appbase.type.BloodType; + +import java.util.List; + +public class SampleTubeCfg { + public String tubeHolderUUID; + public int tubeIndex; + + public String udpid; //用户输入的样本ID,不做逻辑,只做展示 + public String barcodeid; //用于请求用户信息的条码ID + public List projectCodes; //项目编码,用于查找项目相关信息 + public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型 +} diff --git a/src/main/java/a8k/service/appcfgs/base/SampleTubeHolderCfg.java b/src/main/java/a8k/service/appcfgs/base/SampleTubeHolderCfg.java new file mode 100644 index 0000000..2da9d61 --- /dev/null +++ b/src/main/java/a8k/service/appcfgs/base/SampleTubeHolderCfg.java @@ -0,0 +1,23 @@ +package a8k.service.appcfgs.base; + +import a8k.appbase.type.A8kTubeType; + +import java.util.ArrayList; +import java.util.UUID; + +public class SampleTubeHolderCfg { + public String uuid = UUID.randomUUID().toString(); //唯一标识 + public Boolean active = false;//是否激活 + public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //试管架类型 + public ArrayList tubeCfgs = new ArrayList<>(); //试管配置 + public Integer index = 0;//试管架索引 + + public SampleTubeHolderCfg() { + for (int i = 0; i < 10; i++) { + var tubeCfg = new SampleTubeCfg(); + tubeCfg.tubeHolderUUID = uuid; + tubeCfg.tubeIndex = i; + tubeCfgs.add(tubeCfg); + } + } +} diff --git a/src/main/java/a8k/service/appconsumable/AppConsumableMgrService.java b/src/main/java/a8k/service/appconsumable/AppConsumableMgrService.java new file mode 100644 index 0000000..15d06fa --- /dev/null +++ b/src/main/java/a8k/service/appconsumable/AppConsumableMgrService.java @@ -0,0 +1,44 @@ +package a8k.service.appconsumable; + +import a8k.appbase.appret.AppRet; +import a8k.controler.engineer.utils.EngineerPageTab; +import a8k.controler.engineer.utils.EnginnerPageAction; +import a8k.service.ProjectColorAllocer; +import a8k.service.appconsumable.base.ConsumableItemGroup; +import a8k.service.appconsumable.base.ReactantItem; +import a8k.service.appconsumable.base.TipGroupInfo; +import a8k.service.appstate.AppStateMgrService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +@EngineerPageTab(name = "AppConsumableMgrService") +@Component +public class AppConsumableMgrService { + + @Resource + ProjectColorAllocer projectColorAllocer; + + @Resource + AppStateMgrService stateMgrService; + + //扫描耗材 + @EnginnerPageAction(name = "扫描耗材") + public AppRet scanningConsumables() { + ConsumableItemGroup var = new ConsumableItemGroup(); + for (int i = 0; i < 6; i++) { + var.reactantItems[i] = new ReactantItem(); + var.reactantItems[i].projId = "PROJECT_" + i; + var.reactantItems[i].lotVal = "LOT_" + i; + var.reactantItems[i].color = projectColorAllocer.getProjectColor(var.reactantItems[i].projId); + var.reactantItems[i].hasDetectionMaterial = i % 2 == 0; + var.reactantItems[i].hasSmallBufferBottle = i % 2 == 1; + var.reactantItems[i].hasLargeBufferBottle = i % 2 == 0; + + } + var.tip[0] = new TipGroupInfo(); + var.tip[1] = new TipGroupInfo(); + var.tip[2] = new TipGroupInfo(); + stateMgrService.setConsumable(var); + return AppRet.success(var); + } +} diff --git a/src/main/java/a8k/service/appconsumable/base/ConsumableItemGroup.java b/src/main/java/a8k/service/appconsumable/base/ConsumableItemGroup.java new file mode 100644 index 0000000..0971b23 --- /dev/null +++ b/src/main/java/a8k/service/appconsumable/base/ConsumableItemGroup.java @@ -0,0 +1,19 @@ +package a8k.service.appconsumable.base; + +import java.util.Date; + +public class ConsumableItemGroup { + + public Date scanDate = new Date(); + public ReactantItem[] reactantItems = new ReactantItem[6]; + public TipGroupInfo[] tip = new TipGroupInfo[3]; + + public ConsumableItemGroup() { + for (int i = 0; i < reactantItems.length; i++) { + reactantItems[i] = new ReactantItem(); + } + for (int i = 0; i < tip.length; i++) { + tip[i] = new TipGroupInfo(); + } + } +} diff --git a/src/main/java/a8k/service/appconsumable/base/ReactantItem.java b/src/main/java/a8k/service/appconsumable/base/ReactantItem.java new file mode 100644 index 0000000..1151b38 --- /dev/null +++ b/src/main/java/a8k/service/appconsumable/base/ReactantItem.java @@ -0,0 +1,16 @@ +package a8k.service.appconsumable.base; + +//反应物,诸如反应板夹,小瓶缓冲液,大瓶缓冲液... +public class ReactantItem { + + public String projId; //项目ID + public String lotVal; //批次号 + public String color; //颜色 + + public Integer num = 0; //数量 + public Boolean hasPlateClip = false; //是否有反应板夹 always true + public Boolean hasLargeBufferBottle = false; //是否有大瓶缓冲液 + public Boolean hasSmallBufferBottle = false; //是否有小瓶缓冲液 + public Boolean hasDetectionMaterial = false; //是否有探测物质 + +} diff --git a/src/main/java/a8k/service/appconsumable/base/TipGroupInfo.java b/src/main/java/a8k/service/appconsumable/base/TipGroupInfo.java new file mode 100644 index 0000000..18dd975 --- /dev/null +++ b/src/main/java/a8k/service/appconsumable/base/TipGroupInfo.java @@ -0,0 +1,5 @@ +package a8k.service.appconsumable.base; + +public class TipGroupInfo { + public Integer tipNum = 0;//剩余可用数量 +} diff --git a/src/main/java/a8k/service/appctrl/AppCtrlService.java b/src/main/java/a8k/service/appctrl/AppCtrlService.java new file mode 100644 index 0000000..55c008f --- /dev/null +++ b/src/main/java/a8k/service/appctrl/AppCtrlService.java @@ -0,0 +1,53 @@ +package a8k.service.appctrl; + +import a8k.appbase.appret.AppRet; +import a8k.controler.engineer.utils.EngineerPageTab; +import a8k.controler.engineer.utils.EnginnerPageAction; +import org.springframework.stereotype.Component; + +@EngineerPageTab(name = "AppCtrlService") +@Component +public class AppCtrlService { + + + + + @EnginnerPageAction(name = "初始化设备") + public AppRet initDevice() { + return AppRet.success(); + + } + + //启动 + @EnginnerPageAction(name = "启动") + public AppRet startProcess() { + return AppRet.success(); + } + + //暂停 + @EnginnerPageAction(name = "暂停") + public AppRet pauseProcess() { + return AppRet.success(); + } + + //急停 + @EnginnerPageAction(name = "急停") + public AppRet forceStopProcess() { + return AppRet.success(); + } + + //停止 + @EnginnerPageAction(name = "停止") + public AppRet stopProcess() { + return AppRet.success(); + } + + //关机 + @EnginnerPageAction(name = "关机") + public AppRet shutdown() { + return AppRet.success(); + } + + + +} diff --git a/src/main/java/a8k/service/appctrl/DeviceInitializationCtrlService.java b/src/main/java/a8k/service/appctrl/DeviceInitializationCtrlService.java new file mode 100644 index 0000000..0700987 --- /dev/null +++ b/src/main/java/a8k/service/appctrl/DeviceInitializationCtrlService.java @@ -0,0 +1,215 @@ +package a8k.service.appctrl; + +import a8k.service.hardware.canbus.protocol.A8kEcode; +import a8k.service.hardware.canbus.protocol.IOId; +import a8k.service.hardware.canbus.protocol.MId; +import a8k.appbase.HardwareException; +import a8k.appbase.appret.AppRet; +import a8k.service.hardware.canbus.A8kCanBusService; +import a8k.service.hardware.CommonHardwareOpeartion; +import a8k.service.hardware.SamplesPreProcessModuleCtrlService; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseBody; + + +@Controller +public class DeviceInitializationCtrlService { + public static final Logger logger = LoggerFactory.getLogger(DeviceInitializationCtrlService.class); + + + final Integer actionOvertime = 5000; + + @Resource + A8kCanBusService canBus; + + @Resource + CommonHardwareOpeartion commonHardOpera; + + @Resource + SamplesPreProcessModuleCtrlService samplesPreProcessModuleCtrlService; + + + @PostMapping("/api/DeviceInitializationCtrlService/initializeDevice") + @ResponseBody + public AppRet initializeDevice() throws HardwareException, InterruptedException { + logger.info("Initializing device ..."); + boolean initSuc = false; + try { + /* + * 复位思路 + * 硬件初始化: + * 检查 + * 复位 + * 清空耗材 + */ + + AppRet ecode; + //硬件光电初始化 + logger.info("hardwareStaticInit"); + ecode = hardwareStaticInit(); + if (!ecode.isSuccess()) { + return ecode; + } + + //检查设备状态 + logger.info("checkDeviceState"); + ecode = checkDeviceState(); + if (!ecode.isSuccess()) { + return ecode; + } + + // 复位设备 + logger.info("moveMotorToZero"); + ecode = moveMotorToZero(); + if (!ecode.isSuccess()) { + return ecode; + } + // 清空耗材 + + initSuc = true; + // throw new RuntimeException("test"); + + + } finally { + if (!initSuc) { + try { + canBus.stepMotorEnable(MId.ShakeModClampingM, 1); + canBus.stepMotorEasyMoveBy(MId.ShakeModClampingM, 2); + canBus.waitForMod(MId.ShakeModClampingM, actionOvertime); + commonHardOpera.forceStopAndDisableAllMOtor(); + } catch (HardwareException | InterruptedException ignored) { + } + } + } + + logger.info("Device initialization completed"); + return AppRet.success(); + } + + + private AppRet hardwareStaticInit() throws HardwareException, InterruptedException { + /* + * 硬件初始化: + * 1.使能所有舵机 + * 2.打开必要的电源 + * 3.使能所有电机 + */ + + commonHardOpera.enableAllMotor(); + + //打开必要的电源 + canBus.setIOState(IOId.RecycleBinOverflowPPSPowerCtrl, true); + + //其他 + // 试管夹紧电机打开一点,好方便有试管夹住的时,突然断电时,将试管取出 + canBus.stepMotorEasyMoveBy(MId.ShakeModClampingM, 2); + canBus.waitForMod(MId.ShakeModClampingM, actionOvertime); + return AppRet.success(); + } + + private AppRet checkDeviceState() throws HardwareException { + //试管平移通道是否有障碍 + if (canBus.getIOState(IOId.THChInterPPS) || canBus.getIOState(IOId.THChOuterPPS)) { + logger.warn("THChInterPPS or THChOuterPPS is trigger"); + // throw new HardwareException(MId.A8kIdCardReaderBoard, A8kEcode.PlateStuckDetectorSensorTrigger); + return AppRet.fail(A8kEcode.TubeXChannelIsNotEmpty); + } + + //板夹仓盖子是否盖上 + if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) { + logger.warn("PlateBoxCoverClosure is open"); + return AppRet.fail(A8kEcode.PlateBoxNotCover); + } + + //板夹仓卡板检测 + if (canBus.getIOState(IOId.PlateBoxPlateStuckPPS)) { + logger.warn("PlateBoxPlateStuckPPS is trigger"); + return AppRet.fail(A8kEcode.PlateStuckDetectorSensorTrigger); + } + + //检查钩板电机是否处于终点位置 + if (!canBus.getIOState(IOId.PullerMZeroPPS)) { + logger.warn("PullerM is not in zero pos"); + return AppRet.fail(A8kEcode.PullerMInitPosError); + } + + //检查板夹仓光电是否处于起点位置 + if (!canBus.getIOState(IOId.PusherMZeroPPS)) { + logger.warn("PusherM is not in zero pos"); + return AppRet.fail(A8kEcode.PusherMInitPosError); + } + //板夹仓光电 + if (canBus.getIOState(IOId.RecycleBinOverflowPPS)) { + logger.warn("RecycleBinOverflow is trigger"); + return AppRet.fail(A8kEcode.RecycleBinOverflow); + } + + return AppRet.success(); + } + + private AppRet moveMotorToZero() throws HardwareException, InterruptedException { + + //进出料初始化 + // canBus.stepMotorEasyMoveToZero(MId.FeedingModInfeedM); + // canBus.waitForMod(MId.FeedingModInfeedM, actionOvertime); + canBus.stepMotorEasyMoveToZero(MId.FeedingModXM); + canBus.waitForMod(MId.FeedingModXM, actionOvertime); + // canBus.stepMotorEasyMoveToZero(MId.FeedingModOutfeedM); + // canBus.waitForMod(MId.FeedingModOutfeedM, actionOvertime); + + //摇匀模组初始化 + + + + canBus.miniServoMoveTo(MId.ShakeModTubeScanerClampingSV, 10); + canBus.waitForMod(MId.ShakeModTubeScanerClampingSV, actionOvertime); + canBus.miniServoMoveTo(MId.ShakeModGripperSV, 10); + canBus.waitForMod(MId.ShakeModGripperSV, actionOvertime); + canBus.miniServoMoveTo(MId.ShakeModGripperYSV, 10); + canBus.waitForMod(MId.ShakeModGripperYSV, actionOvertime); + + canBus.stepMotorEasyMoveToZero(MId.ShakeModClampingM); + canBus.waitForMod(MId.ShakeModClampingM, actionOvertime); + canBus.stepMotorEasyMoveToZero(MId.ShakeModGripperZM); + canBus.waitForMod(MId.ShakeModGripperZM, actionOvertime); + canBus.stepMotorEasyMoveToZero(MId.ShakeModShakeM); + canBus.waitForMod(MId.ShakeModShakeM, actionOvertime); + + canBus.stepMotorEasyMoveTo(MId.ShakeModShakeM,90); + + //canBus.miniServoMoveTo(MId.ShakeModTubeScanerRotateSV, 1800); + + //板夹仓初始化 + canBus.stepMotorEasyMoveToZero(MId.PlatesBoxYM); + canBus.waitForMod(MId.PlatesBoxYM, actionOvertime); + canBus.stepMotorEasyMoveToZero(MId.PlatesBoxPusherM); + canBus.waitForMod(MId.PlatesBoxPusherM, actionOvertime); + + //光学模组初始化 + canBus.stepMotorEasyMoveToZero(MId.OptModPullM); + canBus.waitForMod(MId.OptModPullM, actionOvertime); + canBus.stepMotorEasyMoveToZero(MId.OptModScannerM); + canBus.waitForMod(MId.OptModScannerM, actionOvertime); + + //HBot初始化 + canBus.hbotMoveToZero(MId.HbotM); + canBus.waitForMod(MId.HbotM, actionOvertime); + canBus.stepMotorEasyMoveToZero(MId.PipetteModZM); + canBus.waitForMod(MId.PipetteModZM, actionOvertime); + + //转盘归零 + canBus.stepMotorEasyMoveToZero(MId.IncubatorRotateCtrlM); + canBus.waitForMod(MId.IncubatorRotateCtrlM, actionOvertime); + + + //canBus.waitForMod(MId.ShakeModGripperZM, actionOvertime); + + return AppRet.success(); + } + + +} diff --git a/src/main/java/a8k/service/appctrl/DeviceShutdowCtrlService.java b/src/main/java/a8k/service/appctrl/DeviceShutdowCtrlService.java new file mode 100644 index 0000000..8fc0c8d --- /dev/null +++ b/src/main/java/a8k/service/appctrl/DeviceShutdowCtrlService.java @@ -0,0 +1,8 @@ +package a8k.service.appctrl; + +import org.springframework.stereotype.Component; + +@Component +public class DeviceShutdowCtrlService { + +} diff --git a/src/main/java/a8k/service/appctrl/DeviceShutdownCtrlService.java b/src/main/java/a8k/service/appctrl/DeviceShutdownCtrlService.java new file mode 100644 index 0000000..9374f5c --- /dev/null +++ b/src/main/java/a8k/service/appctrl/DeviceShutdownCtrlService.java @@ -0,0 +1,11 @@ +package a8k.service.appctrl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class DeviceShutdownCtrlService { + public static final Logger logger = LoggerFactory.getLogger(DeviceShutdownCtrlService.class); + +} diff --git a/src/main/java/a8k/service/appeventbus/AppEventBusService.java b/src/main/java/a8k/service/appeventbus/AppEventBusService.java index bcbce25..2aa0061 100644 --- a/src/main/java/a8k/service/appeventbus/AppEventBusService.java +++ b/src/main/java/a8k/service/appeventbus/AppEventBusService.java @@ -1,6 +1,5 @@ package a8k.service.appeventbus; -import a8k.appbase.AppEventListener; import a8k.service.appeventbus.appevent.AppEvent; import jakarta.annotation.PostConstruct; import org.slf4j.Logger; diff --git a/src/main/java/a8k/service/appeventbus/AppEventListener.java b/src/main/java/a8k/service/appeventbus/AppEventListener.java new file mode 100644 index 0000000..48f0fdc --- /dev/null +++ b/src/main/java/a8k/service/appeventbus/AppEventListener.java @@ -0,0 +1,7 @@ +package a8k.service.appeventbus; + +import a8k.service.appeventbus.appevent.AppEvent; + +public interface AppEventListener { + public void onAppEvent(AppEvent event); +} diff --git a/src/main/java/a8k/service/appstate/AppStateMgrService.java b/src/main/java/a8k/service/appstate/AppStateMgrService.java new file mode 100644 index 0000000..2e19806 --- /dev/null +++ b/src/main/java/a8k/service/appstate/AppStateMgrService.java @@ -0,0 +1,41 @@ +package a8k.service.appstate; + +import a8k.controler.engineer.utils.EngineerPageTab; +import a8k.controler.engineer.utils.EnginnerPageAction; +import a8k.db.ProjectInfo; +import a8k.service.appconsumable.base.ConsumableItemGroup; +import a8k.service.appbase.A8kDeviceState; +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +@EngineerPageTab(name = "A8kStateMgrService") +public class AppStateMgrService { + /* + * 该服务约定: + * 1. 前端只能读取该服务中的状态,不能设置,设置只能通过其他服务进行设置 + */ + + public static final Logger logger = LoggerFactory.getLogger(AppStateMgrService.class); + public A8kDeviceState deviceState = new A8kDeviceState(); + + @PostConstruct + public void init() { + } + + @EnginnerPageAction(name = "获取设备状态") + public A8kDeviceState getDeviceState() { + return deviceState; + } + + public void setCurrentIdCardInfo(ProjectInfo projectInfo) { + deviceState.curIdCardInfo = projectInfo; + } + + public void setConsumable(ConsumableItemGroup cig) { + deviceState.consumable = cig; + } + +} diff --git a/src/main/java/a8k/service/base/A8kDeviceState.java b/src/main/java/a8k/service/base/A8kDeviceState.java deleted file mode 100644 index 69373fc..0000000 --- a/src/main/java/a8k/service/base/A8kDeviceState.java +++ /dev/null @@ -1,35 +0,0 @@ -package a8k.service.base; - -import a8k.db.ProjectInfo; -import a8k.service.base.consumable.ConsumableItemGroup; -import a8k.service.base.plate.ReactingPlateState; -import a8k.service.base.reaction_result.ReactionResult; -import a8k.service.base.sample.EmergencyPosState; -import a8k.service.base.sample.SampleInfo; -import a8k.service.base.sample.TubeHolder; -import a8k.service.base.samplecfg.SampleTubeHolderCfg; - -import java.util.ArrayList; -import java.util.List; - -public class A8kDeviceState { - //耗材 - public ConsumableItemGroup consumableItemGroup = null; - //急诊位状态 - public EmergencyPosState emergencyPosState = EmergencyPosState.IDLE; - //急诊位样本信息 - public SampleInfo emergencySampleInfo = null; - //急诊位反应结果 - public ReactionResult emergencyResult = null; - //正在孵育的任务状态 - public List incubatingPlateStates = null; - //当前正在被处理的试管架状态 - public TubeHolder processingTubeHolder = null; - //温度 - public Integer temperature; - //当前ID卡信息 - public ProjectInfo curIdCardInfo = null; - - Boolean deviceInited = false; //设备是否初始化过 - Boolean devicePoweredOffNormally = false; //设备是否正常关机 -} diff --git a/src/main/java/a8k/service/base/BloodType.java b/src/main/java/a8k/service/base/BloodType.java deleted file mode 100644 index 965d1a0..0000000 --- a/src/main/java/a8k/service/base/BloodType.java +++ /dev/null @@ -1,6 +0,0 @@ -package a8k.service.base; - -public enum BloodType { - WHOLE_BLOOD, - SERUM; -} diff --git a/src/main/java/a8k/service/base/consumable/ConsumableItemGroup.java b/src/main/java/a8k/service/base/consumable/ConsumableItemGroup.java deleted file mode 100644 index 02b2bb2..0000000 --- a/src/main/java/a8k/service/base/consumable/ConsumableItemGroup.java +++ /dev/null @@ -1,10 +0,0 @@ -package a8k.service.base.consumable; - -import java.util.Date; - -public class ConsumableItemGroup { - - public Date scanDate = new Date(); - public ReactantItem[] reactantItems = new ReactantItem[6]; - public TipGroupInfo[] tip = new TipGroupInfo[3]; -} diff --git a/src/main/java/a8k/service/base/consumable/ReactantItem.java b/src/main/java/a8k/service/base/consumable/ReactantItem.java deleted file mode 100644 index e6027ba..0000000 --- a/src/main/java/a8k/service/base/consumable/ReactantItem.java +++ /dev/null @@ -1,16 +0,0 @@ -package a8k.service.base.consumable; - -//反应物,诸如反应板夹,小瓶缓冲液,大瓶缓冲液... -public class ReactantItem { - - public String projId; //项目ID - public String lotVal; //批次号 - public String color; //颜色 - - public Integer num = 0; //数量 - public Boolean hasPlateClip = false; //是否有反应板夹 always true - public Boolean hasLargeBufferBottle = false; //是否有大瓶缓冲液 - public Boolean hasSmallBufferBottle = false; //是否有小瓶缓冲液 - public Boolean hasDetectionMaterial = false; //是否有探测物质 - -} diff --git a/src/main/java/a8k/service/base/consumable/TipGroupInfo.java b/src/main/java/a8k/service/base/consumable/TipGroupInfo.java deleted file mode 100644 index 2c07a99..0000000 --- a/src/main/java/a8k/service/base/consumable/TipGroupInfo.java +++ /dev/null @@ -1,5 +0,0 @@ -package a8k.service.base.consumable; - -public class TipGroupInfo { - public Integer tipNum = 0;//剩余可用数量 -} diff --git a/src/main/java/a8k/service/base/plate/PlateState.java b/src/main/java/a8k/service/base/plate/PlateState.java deleted file mode 100644 index 4e72696..0000000 --- a/src/main/java/a8k/service/base/plate/PlateState.java +++ /dev/null @@ -1,12 +0,0 @@ -package a8k.service.base.plate; - -public enum PlateState { - //赋予中 - Incubating, - //孵育完成 - Incubated, - //孵育异常 - IncubateError, - //板条码异常 - PlateCodeError, -} diff --git a/src/main/java/a8k/service/base/plate/ReactingPlateState.java b/src/main/java/a8k/service/base/plate/ReactingPlateState.java deleted file mode 100644 index e6ec8de..0000000 --- a/src/main/java/a8k/service/base/plate/ReactingPlateState.java +++ /dev/null @@ -1,23 +0,0 @@ -package a8k.service.base.plate; - -import a8k.service.base.reaction_result.ReactionResult; -import a8k.service.base.sample.SampleInfo; -import a8k.service.base.sample.Tube; - -import java.util.Date; - -public class ReactingPlateState { - - String sampleUUID; //样本UUID 系统自动生成 - String projectId;//项目id - - SampleInfo bindSample; //绑定的样本运行状态 - - Integer incubationPos; //孵育盘中的位置 0->19 - Date startIncubatedTime; //开始孵育时间 - Integer targetIncubatedTimeS; //目标孵育时间 - - PlateState plateState; //孵育盘状态 - - ReactionResult reactionResult; //反应结果 -} diff --git a/src/main/java/a8k/service/base/reaction_result/ReactionResult.java b/src/main/java/a8k/service/base/reaction_result/ReactionResult.java deleted file mode 100644 index 4dce008..0000000 --- a/src/main/java/a8k/service/base/reaction_result/ReactionResult.java +++ /dev/null @@ -1,13 +0,0 @@ -package a8k.service.base.reaction_result; - -public class ReactionResult { - - Boolean result0Error; - Boolean result1Error; - Boolean result2Error; - - String result0; - String result1; - String result2; - -} diff --git a/src/main/java/a8k/service/base/sample/EmergencyPosState.java b/src/main/java/a8k/service/base/sample/EmergencyPosState.java deleted file mode 100644 index 0eae39f..0000000 --- a/src/main/java/a8k/service/base/sample/EmergencyPosState.java +++ /dev/null @@ -1,7 +0,0 @@ -package a8k.service.base.sample; - -public enum EmergencyPosState { - IDLE,// - PROCESSING,// - PROCESS_COMPLETE,// -} diff --git a/src/main/java/a8k/service/base/sample/EmergencySampleInfo.java b/src/main/java/a8k/service/base/sample/EmergencySampleInfo.java deleted file mode 100644 index 0c90999..0000000 --- a/src/main/java/a8k/service/base/sample/EmergencySampleInfo.java +++ /dev/null @@ -1,6 +0,0 @@ -package a8k.service.base.sample; - -public class EmergencySampleInfo { - - -} diff --git a/src/main/java/a8k/service/base/sample/SampleInfo.java b/src/main/java/a8k/service/base/sample/SampleInfo.java deleted file mode 100644 index 000aa1b..0000000 --- a/src/main/java/a8k/service/base/sample/SampleInfo.java +++ /dev/null @@ -1,9 +0,0 @@ -package a8k.service.base.sample; - -import a8k.appbase.A8kTubeType; - -import java.util.List; - -public class SampleInfo { - -} diff --git a/src/main/java/a8k/service/base/sample/Tube.java b/src/main/java/a8k/service/base/sample/Tube.java deleted file mode 100644 index 86fc734..0000000 --- a/src/main/java/a8k/service/base/sample/Tube.java +++ /dev/null @@ -1,8 +0,0 @@ -package a8k.service.base.sample; - -import a8k.appbase.A8kTubeType; - -public class Tube { - TubeState tubeState = TubeState.EMPTY; //样本运行状态 - SampleInfo sampleInfo; //样本信息 -} diff --git a/src/main/java/a8k/service/base/sample/TubeHolder.java b/src/main/java/a8k/service/base/sample/TubeHolder.java deleted file mode 100644 index 39b97ba..0000000 --- a/src/main/java/a8k/service/base/sample/TubeHolder.java +++ /dev/null @@ -1,12 +0,0 @@ -package a8k.service.base.sample; - -import a8k.appbase.A8kTubeType; -import a8k.service.base.BloodType; - -public class TubeHolder { - public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型 - public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //管子类型 - public TubeHolderState tubeHolderState = TubeHolderState.TubeHolderStateIdle; //管子状态 - public Tube[] tubes = new Tube[10]; //管子 - public Integer processingTubeIndex = -1; //当前管子索引 -} diff --git a/src/main/java/a8k/service/base/sample/TubeHolderState.java b/src/main/java/a8k/service/base/sample/TubeHolderState.java deleted file mode 100644 index 4c61c43..0000000 --- a/src/main/java/a8k/service/base/sample/TubeHolderState.java +++ /dev/null @@ -1,7 +0,0 @@ -package a8k.service.base.sample; - -public enum TubeHolderState { - TubeHolderStateIdle, //空闲 - TubeHolderStateProcessing, //处理中 - TubeHolderStateProcessed, //处理完成 -} diff --git a/src/main/java/a8k/service/base/sample/TubeState.java b/src/main/java/a8k/service/base/sample/TubeState.java deleted file mode 100644 index c48b320..0000000 --- a/src/main/java/a8k/service/base/sample/TubeState.java +++ /dev/null @@ -1,18 +0,0 @@ -package a8k.service.base.sample; - -public enum TubeState { - //空 - EMPTY, - //待处理 - READY, - //预处理中 - PRE_PROCESSING, - //待采样 - TO_BE_SAMPLED, - //采样中 - SAMPLING, - //采样完成 - SAMPLED, - //处理完成 - PROCESS_COMPLETE, -} diff --git a/src/main/java/a8k/service/base/samplecfg/SampleTubeCfg.java b/src/main/java/a8k/service/base/samplecfg/SampleTubeCfg.java deleted file mode 100644 index 3b25d63..0000000 --- a/src/main/java/a8k/service/base/samplecfg/SampleTubeCfg.java +++ /dev/null @@ -1,17 +0,0 @@ -package a8k.service.base.samplecfg; - -import a8k.service.base.BloodType; -import a8k.service.base.sample.SampleInfo; - -import java.util.List; -import java.util.UUID; - -public class SampleTubeCfg { - public String tubeHolderUUID; - public int tubeIndex; - - public String udpid; //用户输入的样本ID,不做逻辑,只做展示 - public String barcodeid; //用于请求用户信息的条码ID - public List projectCodes; //项目编码,用于查找项目相关信息 - public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型 -} diff --git a/src/main/java/a8k/service/base/samplecfg/SampleTubeHolderCfg.java b/src/main/java/a8k/service/base/samplecfg/SampleTubeHolderCfg.java deleted file mode 100644 index ceb0bad..0000000 --- a/src/main/java/a8k/service/base/samplecfg/SampleTubeHolderCfg.java +++ /dev/null @@ -1,24 +0,0 @@ -package a8k.service.base.samplecfg; - -import a8k.appbase.A8kTubeType; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -public class SampleTubeHolderCfg { - public String uuid = UUID.randomUUID().toString(); //唯一标识 - public Boolean active = false;//是否激活 - public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //试管架类型 - public ArrayList tubeCfgs = new ArrayList<>(); //试管配置 - public Integer index = 0;//试管架索引 - - public SampleTubeHolderCfg() { - for (int i = 0; i < 10; i++) { - var tubeCfg = new SampleTubeCfg(); - tubeCfg.tubeHolderUUID = uuid; - tubeCfg.tubeIndex = i; - tubeCfgs.add(tubeCfg); - } - } -} diff --git a/src/main/java/a8k/service/ctrl_service/AppCtrlService.java b/src/main/java/a8k/service/ctrl_service/AppCtrlService.java deleted file mode 100644 index d1afd28..0000000 --- a/src/main/java/a8k/service/ctrl_service/AppCtrlService.java +++ /dev/null @@ -1,78 +0,0 @@ -package a8k.service.ctrl_service; - -import a8k.appbase.appret.AppRet; -import a8k.controler.engineer.utils.EngineerPageTab; -import a8k.controler.engineer.utils.EnginnerPageAction; -import a8k.service.ProjectColorAllocer; -import a8k.service.base.consumable.ConsumableItemGroup; -import a8k.service.base.consumable.ReactantItem; -import a8k.service.base.consumable.TipGroupInfo; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Component; - -@EngineerPageTab(name = "AppCtrlService") -@Component -public class AppCtrlService { - - - @Resource - ProjectColorAllocer projectColorAllocer; - - - @EnginnerPageAction(name = "初始化设备") - public AppRet initDevice() { - return AppRet.success(); - - } - - //启动 - @EnginnerPageAction(name = "启动") - public AppRet startProcess() { - return AppRet.success(); - } - - //暂停 - @EnginnerPageAction(name = "暂停") - public AppRet pauseProcess() { - return AppRet.success(); - } - - //急停 - @EnginnerPageAction(name = "急停") - public AppRet forceStopProcess() { - return AppRet.success(); - } - - //停止 - @EnginnerPageAction(name = "停止") - public AppRet stopProcess() { - return AppRet.success(); - } - - //关机 - @EnginnerPageAction(name = "关机") - public AppRet shutdown() { - return AppRet.success(); - } - - - //扫描耗材 - @EnginnerPageAction(name = "扫描耗材") - public AppRet scanningConsumables() { - ConsumableItemGroup var = new ConsumableItemGroup(); - for (int i = 0; i < 6; i++) { - var.reactantItems[i] = new ReactantItem(); - var.reactantItems[i].projId = "PROJECT_" + i; - var.reactantItems[i].lotVal = "LOT_" + i; - var.reactantItems[i].color = projectColorAllocer.getProjectColor(var.reactantItems[i].projId); - var.reactantItems[i].hasDetectionMaterial = i % 2 == 0; - var.reactantItems[i].hasSmallBufferBottle = i % 2 == 1; - var.reactantItems[i].hasLargeBufferBottle = i % 2 == 0; - - } - var.tip[0] = new TipGroupInfo(); - var.tip[1] = new TipGroupInfo(); - var.tip[2] = new TipGroupInfo(); - return AppRet.success(var); - } -} diff --git a/src/main/java/a8k/service/ctrl_service/ConsumableLoadingService.java b/src/main/java/a8k/service/ctrl_service/ConsumableLoadingService.java deleted file mode 100644 index a585435..0000000 --- a/src/main/java/a8k/service/ctrl_service/ConsumableLoadingService.java +++ /dev/null @@ -1,22 +0,0 @@ -package a8k.service.ctrl_service; - -import jakarta.annotation.PostConstruct; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -public class ConsumableLoadingService implements Runnable { - public static final Logger LOG = LoggerFactory.getLogger(ConsumableLoadingService.class); - - @Override - public void run() { - - } - - @PostConstruct - public void init(){ - //启动线程实例 - } - -} diff --git a/src/main/java/a8k/service/ctrl_service/DeviceInitializationCtrlService.java b/src/main/java/a8k/service/ctrl_service/DeviceInitializationCtrlService.java deleted file mode 100644 index 6df12d6..0000000 --- a/src/main/java/a8k/service/ctrl_service/DeviceInitializationCtrlService.java +++ /dev/null @@ -1,215 +0,0 @@ -package a8k.service.ctrl_service; - -import a8k.service.hardware.canbus.protocol.A8kEcode; -import a8k.service.hardware.canbus.protocol.IOId; -import a8k.service.hardware.canbus.protocol.MId; -import a8k.appbase.HardwareException; -import a8k.appbase.appret.AppRet; -import a8k.service.hardware.canbus.A8kCanBusService; -import a8k.service.hardware.CommonHardwareOpeartion; -import a8k.service.hardware.SamplesPreProcessModuleCtrlService; -import jakarta.annotation.Resource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.ResponseBody; - - -@Controller -public class DeviceInitializationCtrlService { - public static final Logger logger = LoggerFactory.getLogger(DeviceInitializationCtrlService.class); - - - final Integer actionOvertime = 5000; - - @Resource - A8kCanBusService canBus; - - @Resource - CommonHardwareOpeartion commonHardOpera; - - @Resource - SamplesPreProcessModuleCtrlService samplesPreProcessModuleCtrlService; - - - @PostMapping("/api/DeviceInitializationCtrlService/initializeDevice") - @ResponseBody - public AppRet initializeDevice() throws HardwareException, InterruptedException { - logger.info("Initializing device ..."); - boolean initSuc = false; - try { - /* - * 复位思路 - * 硬件初始化: - * 检查 - * 复位 - * 清空耗材 - */ - - AppRet ecode; - //硬件光电初始化 - logger.info("hardwareStaticInit"); - ecode = hardwareStaticInit(); - if (!ecode.isSuccess()) { - return ecode; - } - - //检查设备状态 - logger.info("checkDeviceState"); - ecode = checkDeviceState(); - if (!ecode.isSuccess()) { - return ecode; - } - - // 复位设备 - logger.info("moveMotorToZero"); - ecode = moveMotorToZero(); - if (!ecode.isSuccess()) { - return ecode; - } - // 清空耗材 - - initSuc = true; - // throw new RuntimeException("test"); - - - } finally { - if (!initSuc) { - try { - canBus.stepMotorEnable(MId.ShakeModClampingM, 1); - canBus.stepMotorEasyMoveBy(MId.ShakeModClampingM, 2); - canBus.waitForMod(MId.ShakeModClampingM, actionOvertime); - commonHardOpera.forceStopAndDisableAllMOtor(); - } catch (HardwareException | InterruptedException ignored) { - } - } - } - - logger.info("Device initialization completed"); - return AppRet.success(); - } - - - private AppRet hardwareStaticInit() throws HardwareException, InterruptedException { - /* - * 硬件初始化: - * 1.使能所有舵机 - * 2.打开必要的电源 - * 3.使能所有电机 - */ - - commonHardOpera.enableAllMotor(); - - //打开必要的电源 - canBus.setIOState(IOId.RecycleBinOverflowPPSPowerCtrl, true); - - //其他 - // 试管夹紧电机打开一点,好方便有试管夹住的时,突然断电时,将试管取出 - canBus.stepMotorEasyMoveBy(MId.ShakeModClampingM, 2); - canBus.waitForMod(MId.ShakeModClampingM, actionOvertime); - return AppRet.success(); - } - - private AppRet checkDeviceState() throws HardwareException { - //试管平移通道是否有障碍 - if (canBus.getIOState(IOId.THChInterPPS) || canBus.getIOState(IOId.THChOuterPPS)) { - logger.warn("THChInterPPS or THChOuterPPS is trigger"); - // throw new HardwareException(MId.A8kIdCardReaderBoard, A8kEcode.PlateStuckDetectorSensorTrigger); - return AppRet.fail(A8kEcode.TubeXChannelIsNotEmpty); - } - - //板夹仓盖子是否盖上 - if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) { - logger.warn("PlateBoxCoverClosure is open"); - return AppRet.fail(A8kEcode.PlateBoxNotCover); - } - - //板夹仓卡板检测 - if (canBus.getIOState(IOId.PlateBoxPlateStuckPPS)) { - logger.warn("PlateBoxPlateStuckPPS is trigger"); - return AppRet.fail(A8kEcode.PlateStuckDetectorSensorTrigger); - } - - //检查钩板电机是否处于终点位置 - if (!canBus.getIOState(IOId.PullerMZeroPPS)) { - logger.warn("PullerM is not in zero pos"); - return AppRet.fail(A8kEcode.PullerMInitPosError); - } - - //检查板夹仓光电是否处于起点位置 - if (!canBus.getIOState(IOId.PusherMZeroPPS)) { - logger.warn("PusherM is not in zero pos"); - return AppRet.fail(A8kEcode.PusherMInitPosError); - } - //板夹仓光电 - if (canBus.getIOState(IOId.RecycleBinOverflowPPS)) { - logger.warn("RecycleBinOverflow is trigger"); - return AppRet.fail(A8kEcode.RecycleBinOverflow); - } - - return AppRet.success(); - } - - private AppRet moveMotorToZero() throws HardwareException, InterruptedException { - - //进出料初始化 - // canBus.stepMotorEasyMoveToZero(MId.FeedingModInfeedM); - // canBus.waitForMod(MId.FeedingModInfeedM, actionOvertime); - canBus.stepMotorEasyMoveToZero(MId.FeedingModXM); - canBus.waitForMod(MId.FeedingModXM, actionOvertime); - // canBus.stepMotorEasyMoveToZero(MId.FeedingModOutfeedM); - // canBus.waitForMod(MId.FeedingModOutfeedM, actionOvertime); - - //摇匀模组初始化 - - - - canBus.miniServoMoveTo(MId.ShakeModTubeScanerClampingSV, 10); - canBus.waitForMod(MId.ShakeModTubeScanerClampingSV, actionOvertime); - canBus.miniServoMoveTo(MId.ShakeModGripperSV, 10); - canBus.waitForMod(MId.ShakeModGripperSV, actionOvertime); - canBus.miniServoMoveTo(MId.ShakeModGripperYSV, 10); - canBus.waitForMod(MId.ShakeModGripperYSV, actionOvertime); - - canBus.stepMotorEasyMoveToZero(MId.ShakeModClampingM); - canBus.waitForMod(MId.ShakeModClampingM, actionOvertime); - canBus.stepMotorEasyMoveToZero(MId.ShakeModGripperZM); - canBus.waitForMod(MId.ShakeModGripperZM, actionOvertime); - canBus.stepMotorEasyMoveToZero(MId.ShakeModShakeM); - canBus.waitForMod(MId.ShakeModShakeM, actionOvertime); - - canBus.stepMotorEasyMoveTo(MId.ShakeModShakeM,90); - - //canBus.miniServoMoveTo(MId.ShakeModTubeScanerRotateSV, 1800); - - //板夹仓初始化 - canBus.stepMotorEasyMoveToZero(MId.PlatesBoxYM); - canBus.waitForMod(MId.PlatesBoxYM, actionOvertime); - canBus.stepMotorEasyMoveToZero(MId.PlatesBoxPusherM); - canBus.waitForMod(MId.PlatesBoxPusherM, actionOvertime); - - //光学模组初始化 - canBus.stepMotorEasyMoveToZero(MId.OptModPullM); - canBus.waitForMod(MId.OptModPullM, actionOvertime); - canBus.stepMotorEasyMoveToZero(MId.OptModScannerM); - canBus.waitForMod(MId.OptModScannerM, actionOvertime); - - //HBot初始化 - canBus.hbotMoveToZero(MId.HbotM); - canBus.waitForMod(MId.HbotM, actionOvertime); - canBus.stepMotorEasyMoveToZero(MId.PipetteModZM); - canBus.waitForMod(MId.PipetteModZM, actionOvertime); - - //转盘归零 - canBus.stepMotorEasyMoveToZero(MId.IncubatorRotateCtrlM); - canBus.waitForMod(MId.IncubatorRotateCtrlM, actionOvertime); - - - //canBus.waitForMod(MId.ShakeModGripperZM, actionOvertime); - - return AppRet.success(); - } - - -} diff --git a/src/main/java/a8k/service/ctrl_service/DeviceShutdowCtrlService.java b/src/main/java/a8k/service/ctrl_service/DeviceShutdowCtrlService.java deleted file mode 100644 index c210612..0000000 --- a/src/main/java/a8k/service/ctrl_service/DeviceShutdowCtrlService.java +++ /dev/null @@ -1,8 +0,0 @@ -package a8k.service.ctrl_service; - -import org.springframework.stereotype.Component; - -@Component -public class DeviceShutdowCtrlService { - -} diff --git a/src/main/java/a8k/service/ctrl_service/DeviceShutdownCtrlService.java b/src/main/java/a8k/service/ctrl_service/DeviceShutdownCtrlService.java deleted file mode 100644 index b5484c2..0000000 --- a/src/main/java/a8k/service/ctrl_service/DeviceShutdownCtrlService.java +++ /dev/null @@ -1,9 +0,0 @@ -package a8k.service.ctrl_service; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeviceShutdownCtrlService { - public static final Logger logger = LoggerFactory.getLogger(DeviceInitializationCtrlService.class); - -} diff --git a/src/main/java/a8k/service/hardware/SamplesPreProcessModuleCtrlService.java b/src/main/java/a8k/service/hardware/SamplesPreProcessModuleCtrlService.java index ac6a9c9..6ed80f7 100644 --- a/src/main/java/a8k/service/hardware/SamplesPreProcessModuleCtrlService.java +++ b/src/main/java/a8k/service/hardware/SamplesPreProcessModuleCtrlService.java @@ -3,7 +3,7 @@ package a8k.service.hardware; import a8k.controler.engineer.utils.*; import a8k.service.hardware.canbus.protocol.A8kEcode; import a8k.service.hardware.canbus.protocol.MId; -import a8k.appbase.A8kTubeType; +import a8k.appbase.type.A8kTubeType; import a8k.appbase.HardwareException; import a8k.appbase.appret.AppRet; import a8k.service.hardware.canbus.A8kCanBusService; diff --git a/src/main/java/a8k/service/hardware/canbus/A8kModParamInitializer.java b/src/main/java/a8k/service/hardware/canbus/A8kModParamInitializer.java index 940da0e..df05dbf 100644 --- a/src/main/java/a8k/service/hardware/canbus/A8kModParamInitializer.java +++ b/src/main/java/a8k/service/hardware/canbus/A8kModParamInitializer.java @@ -3,7 +3,7 @@ package a8k.service.hardware.canbus; import a8k.service.appeventbus.AppEventBusService; import a8k.service.appeventbus.appevent.A8kCanBusOnConnectEvent; import a8k.service.appeventbus.appevent.AppEvent; -import a8k.appbase.AppEventListener; +import a8k.service.appeventbus.AppEventListener; import a8k.appbase.HardwareException; import a8k.service.hardware.canbus.custom_param_mgr.ModCustomParamId; import a8k.service.hardware.canbus.custom_param_mgr.A8kModCustomParamMgr; diff --git a/src/main/java/a8k/service/project_mgr/ProjectItemMgrService.java b/src/main/java/a8k/service/project_mgr/ProjectItemMgrService.java index b90ab9b..0f77ead 100644 --- a/src/main/java/a8k/service/project_mgr/ProjectItemMgrService.java +++ b/src/main/java/a8k/service/project_mgr/ProjectItemMgrService.java @@ -1,7 +1,7 @@ package a8k.service.project_mgr; -import a8k.appbase.AppEventListener; +import a8k.service.appeventbus.AppEventListener; import a8k.appbase.HardwareException; import a8k.appbase.ProjectInfoSimple; import a8k.appbase.appret.AppRet; @@ -9,6 +9,7 @@ import a8k.controler.engineer.utils.EngineerPageTab; import a8k.controler.engineer.utils.EnginnerPageAction; import a8k.db.ProjectInfo; import a8k.service.appeventbus.AppEventBusService; +import a8k.service.appeventbus.appevent.A8kCanBusOnConnectEvent; import a8k.service.appeventbus.appevent.A8kHardwareReport; import a8k.service.appeventbus.appevent.AppEvent; import a8k.service.hardware.canbus.A8kCanBusService; @@ -16,7 +17,7 @@ import a8k.service.hardware.canbus.protocol.A8kPacket; import a8k.service.hardware.canbus.protocol.CmdId; import a8k.service.hardware.canbus.protocol.MId; import a8k.service.hardware.canbus.protocol.RegIndex; -import a8k.service.state_service.A8kStateMgrService; +import a8k.service.appstate.AppStateMgrService; import a8k.utils.wq.ZWorkQueue; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; @@ -28,7 +29,7 @@ import java.util.List; import java.util.Map; @Component -@EngineerPageTab(name = "ProjectItemMgr") +@EngineerPageTab(name = "ProjectItemMgrService") public class ProjectItemMgrService implements AppEventListener { static Logger logger = org.slf4j.LoggerFactory.getLogger(ProjectItemMgrService.class); @@ -39,20 +40,13 @@ public class ProjectItemMgrService implements AppEventListener { AppEventBusService eventBus; @Resource - A8kStateMgrService stateMgr; + AppStateMgrService stateMgr; ZWorkQueue workQueue = new ZWorkQueue(2, 1); @PostConstruct public void init() { - try { - if (canBus.moduleGetReg(MId.A8kIdCardReader, RegIndex.kreg_id_card_reader_is_online) == 1) { - logger.info("ID卡读卡器在线"); - workQueue.addTask(this::readIDCard); - } - } catch (HardwareException e) { - throw new RuntimeException(e); - } + eventBus.regListener(this); } @@ -66,6 +60,15 @@ public class ProjectItemMgrService implements AppEventListener { } else if (CmdId.event_a8000_idcard_offline.equals(cmdId)) { logger.info("拔出ID卡"); } + } else if (event instanceof A8kCanBusOnConnectEvent canPacket) { + try { + if (canBus.moduleGetReg(MId.A8kIdCardReader, RegIndex.kreg_id_card_reader_is_online) == 1) { + logger.info("ID卡读卡器在线"); + workQueue.addTask(this::readIDCard); + } + } catch (HardwareException e) { + throw new RuntimeException(e); + } } } diff --git a/src/main/java/a8k/service/state_service/A8kState.java b/src/main/java/a8k/service/state_service/A8kState.java deleted file mode 100644 index dea242a..0000000 --- a/src/main/java/a8k/service/state_service/A8kState.java +++ /dev/null @@ -1,5 +0,0 @@ -package a8k.service.state_service; - -public class A8kState { - public Boolean devicePoweredOffNormally = false; //设备是否正常关机 -} diff --git a/src/main/java/a8k/service/state_service/A8kStateDB.java b/src/main/java/a8k/service/state_service/A8kStateDB.java deleted file mode 100644 index 720d535..0000000 --- a/src/main/java/a8k/service/state_service/A8kStateDB.java +++ /dev/null @@ -1,17 +0,0 @@ -package a8k.service.state_service; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.iflytop.uf.UfActiveRecord; -import com.iflytop.uf.UfActiveRecordField; - -public class A8kStateDB extends UfActiveRecord { - - @UfActiveRecordField - public String stateJson; //A8k状态Json - - public static String getTableName() { - return "A8kStateDB" + "Table"; - } - -} diff --git a/src/main/java/a8k/service/state_service/A8kStateMgrService.java b/src/main/java/a8k/service/state_service/A8kStateMgrService.java deleted file mode 100644 index 4af8c93..0000000 --- a/src/main/java/a8k/service/state_service/A8kStateMgrService.java +++ /dev/null @@ -1,37 +0,0 @@ -package a8k.service.state_service; - -import a8k.controler.engineer.utils.EngineerPageTab; -import a8k.controler.engineer.utils.EnginnerPageAction; -import a8k.db.ProjectInfo; -import a8k.service.base.A8kDeviceState; -import jakarta.annotation.PostConstruct; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -@EngineerPageTab(name = "A8kStateMgrService") -public class A8kStateMgrService { - /* - * 该服务约定: - * 1. 前端只能读取该服务中的状态,不能设置,设置只能通过其他服务进行设置 - */ - - public static final Logger logger = LoggerFactory.getLogger(A8kStateMgrService.class); - public A8kDeviceState deviceState = new A8kDeviceState(); - - @PostConstruct - public void init() { - } - - @EnginnerPageAction(name = "获取设备状态") - public A8kDeviceState getDeviceState() { - return deviceState; - } - - public void setCurrentIdCardInfo(ProjectInfo projectInfo) { - deviceState.curIdCardInfo = projectInfo; - } - - -} diff --git a/zhaohe_app.db b/zhaohe_app.db deleted file mode 100644 index cc5fe5578cae937f1ff870d5a4f2ce03b51d7ee7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 192512 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 aUH|$1d$+uy0zWDS2SbmFm&M^DxBoBl`4r^<