Browse Source

update

tags/v0
zhaohe 10 months ago
parent
commit
2c277343be
  1. 32
      README.md
  2. 1
      src/main/java/a8k/baseservice/appeventbus/appevent/AppIDCardMountEvent.java
  3. 4
      src/main/java/a8k/baseservice/appeventbus/appevent/AppWarningNotifyEvent.java
  4. 2
      src/main/java/a8k/service/appdata/AppFrontEndEventRouter.java
  5. 6
      src/main/java/a8k/service/appdevicectrl/AppDeviceCtrlService.java
  6. 15
      src/main/java/a8k/service/appdevicectrl/MainFlowCtrlService.java
  7. 5
      src/main/java/a8k/service/appdevicectrl/action/A8kActionStepType.java
  8. 6
      src/main/java/a8k/service/appdevicectrl/action/A8kStepAction.java
  9. 44
      src/main/java/a8k/service/appdevicectrl/action/DO_CHECK_THE_QUANTITY_OF_CONSUMABLES.java
  10. 4
      src/main/java/a8k/service/appdevicectrl/action/DO_EJECT_TUBEHOLDER.java
  11. 20
      src/main/java/a8k/service/appdevicectrl/action/DO_ENTER_TUBEHOLDER_AND_SCAN.java
  12. 5
      src/main/java/a8k/service/appdevicectrl/action/DO_PAUSE.java
  13. 15
      src/main/java/a8k/service/appdevicectrl/action/DO_START.java
  14. 5
      src/main/java/a8k/service/appdevicectrl/action/DO_STOP.java
  15. 115
      src/main/java/a8k/service/appdevicectrl/action/DO_SWITCH_TO_THE_NEXT_TUBE.java
  16. 25
      src/main/java/a8k/service/appdevicectrl/scheduler/MainFlowCtrlScheduler.java
  17. 5
      src/main/java/a8k/service/appstate/AppA8kGStateService.java
  18. 5
      src/main/java/a8k/service/appstate/type/TubeHolderState.java
  19. 10
      src/main/java/a8k/service/appstate/type/TubeState.java
  20. 1
      src/main/java/a8k/service/appstate/type/state/TubeHolderProcessState.java
  21. 18
      src/main/java/a8k/service/bak_appbase/progress/TubeProcessState.java
  22. 3
      src/main/java/a8k/type/type/A8kTubeHolderType.java

32
README.md

@ -140,3 +140,35 @@ TODO:
取样与反应服务
```
```
DO_ENTER_TUBEHOLDER_AND_SCAN(入料)
-> 修改试管架状态为READY
DO_
DO_CHECK_TUBE_IS_OK_TO_PROCESS(检查试管是否可以被处理,如果检查不合格,则不切换状态)
-> 修改试管状态为PROCESSING
DO_SAMPLE_PRE_PROCESS_A(摇匀+脱帽)
->set DO_SAMPLE_PRE_PROCESS_A doneFlag
DO_PREPARE_REACTION_PLATE(推入反应板到孵育盘中)
->set DO_PREPARE_REACTION_PLATE doneFlag
DO_PREPARE_PREPARE_PROCESS(HBOT为处理样本做准备)
->set DO_PREPARE_PREPARE_PROCESS doneFlag
DO_TAKE_SAMPLE_AND_PROCESS(处理样本,取样....)
->set DO_TAKE_SAMPLE_AND_PROCESS doneFlag
--> DO_SAMPLE_PRE_PROCESS_B(盖帽,样本复位)
->set DO_SAMPLE_PRE_PROCESS_B doneFlag
DO_PUSH_REACTION_PLATE(推出反应板)
DO_OPT_SCAN
```

1
src/main/java/a8k/baseservice/appeventbus/appevent/AppIDCardMountEvent.java

@ -10,4 +10,5 @@ public class AppIDCardMountEvent extends AppEvent {
super(AppIDCardMountEvent.class.getSimpleName());
this.projectInfo = projectInfo;
}
}

4
src/main/java/a8k/baseservice/appeventbus/appevent/AppWarningNotifyEvent.java

@ -17,4 +17,8 @@ public class AppWarningNotifyEvent extends AppEvent {
this(ecode.index);
}
public String toString() {
return String.format("%s", errorCodeStr);
}
}

2
src/main/java/a8k/service/appdata/AppFrontEndEventRouter.java

@ -66,7 +66,7 @@ public class AppFrontEndEventRouter implements AppEventListener {
}
appEventQueue.add(event);
if (appEventQueue.size() >= 10) {
if (appEventQueue.size() >= 20) {
logger.warn("too many events in queue, drop some");
pollAppEventFromQueue();
}

6
src/main/java/a8k/service/appdevicectrl/AppDeviceCtrlService.java

@ -4,6 +4,7 @@ import a8k.controler.extapi.pagecontrol.ExtApiTabConfig;
import a8k.controler.extapi.utils.ExtApiFn;
import a8k.controler.extapi.utils.ExtApiTab;
import a8k.service.appdevicectrl.action.A8kStepAction;
import a8k.service.appstate.type.TubeHolderState;
import a8k.type.checkpoint.CheckResult;
import a8k.service.appstate.AppA8kGStateService;
import a8k.service.appstate.type.state.A8kWorkState;
@ -96,6 +97,11 @@ public class AppDeviceCtrlService {
return mainFlowCtrlSampleScanService.getA8kStepActionList();
}
@ExtApiFn(name = "获取正在处理的试管架状态", group = "设备状态")
public TubeHolderState getTubeHolderState() {
return gstate.getTubeHolderState();
}
@ExtApiFn(name = "获取设备状态(调试使用)", group = "设备状态")
public AppA8kGStateService getGState() {
return gstate;

15
src/main/java/a8k/service/appdevicectrl/MainFlowCtrlService.java

@ -43,11 +43,14 @@ public class MainFlowCtrlService {
scheduler.regEcodePostProcesser(this::postPorcessA8kEcode);
scheduler.regFn(SpringBootBeanUtil.getBean(DO_START.class));
scheduler.regFn(SpringBootBeanUtil.getBean(DO_STOP.class));
scheduler.regFn(SpringBootBeanUtil.getBean(DO_PAUSE.class));
scheduler.regFn(SpringBootBeanUtil.getBean(DO_ENTER_TUBEHOLDER_AND_SCAN.class));
scheduler.regFn(SpringBootBeanUtil.getBean(DO_EJECT_TUBEHOLDER.class));
logger.info("className {}",DO_STOP.class.getName());
for (A8kActionStepType actionType : A8kActionStepType.values()) {
if (actionType.equals(A8kActionStepType.DO_CLEAR_ERROR)) {
continue;
}
A8kStepAction action = SpringBootBeanUtil.getBean(actionType.name(), A8kStepAction.class);
scheduler.regFn(action);
}
//启动调度
scheduler.startScheduler();
@ -61,7 +64,7 @@ public class MainFlowCtrlService {
scheduler.setClearErrorPendingFlag();
}
public List<A8kStepAction> getA8kStepActionList(){
public List<A8kStepAction> getA8kStepActionList() {
return scheduler.getA8kStepActionList();
}

5
src/main/java/a8k/service/appdevicectrl/action/A8kActionStepType.java

@ -7,6 +7,11 @@ public enum A8kActionStepType {
DO_ENTER_TUBEHOLDER_AND_SCAN, //入料并扫描
DO_EJECT_TUBEHOLDER,//弹出试管架
DO_SWITCH_TO_THE_NEXT_TUBE,//切换到下一个试管
DO_CHECK_THE_QUANTITY_OF_CONSUMABLES,//Check the quantity of consumables,核对耗材数量
//特殊动作无需注册成类型
DO_CLEAR_ERROR,//清除错误

6
src/main/java/a8k/service/appdevicectrl/action/A8kStepAction.java

@ -8,10 +8,10 @@ import java.util.List;
public class A8kStepAction {
public A8kActionStepType step;
public A8kActionStepType step = null;
A8kStepAction(A8kActionStepType step) {
this.step = step;
A8kStepAction() {
this.step = A8kActionStepType.valueOf(this.getClass().getSimpleName());
}

44
src/main/java/a8k/service/appdevicectrl/action/DO_CHECK_THE_QUANTITY_OF_CONSUMABLES.java

@ -0,0 +1,44 @@
package a8k.service.appdevicectrl.action;
import a8k.service.appstate.AppA8kGStateService;
import a8k.service.appstate.resource.A8kPublicResourceType;
import a8k.service.appstate.type.state.A8kWorkState;
import a8k.service.appstate.type.state.TubeHolderProcessState;
import a8k.type.exception.AppException;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 检查耗材是否充足
*/
@Component
public class DO_CHECK_THE_QUANTITY_OF_CONSUMABLES extends A8kStepAction {
static Logger logger = LoggerFactory.getLogger(DO_CHECK_THE_QUANTITY_OF_CONSUMABLES.class);
@Resource
AppA8kGStateService gstate;
@PostConstruct
void init() {
}
@Override public void doaction() throws AppException {
}
@Override public Boolean checkCondition() {
return false;
}
@Override public List<A8kPublicResourceType> getDeplyResourceList() {
return List.of();
}
}

4
src/main/java/a8k/service/appdevicectrl/action/DO_EJECT_TUBEHOLDER.java

@ -34,10 +34,6 @@ public class DO_EJECT_TUBEHOLDER extends A8kStepAction {
}
public DO_EJECT_TUBEHOLDER() {
super(A8kActionStepType.DO_EJECT_TUBEHOLDER);
}
@Override public void doaction() throws AppException {
stc.ejectTubeHolder();

20
src/main/java/a8k/service/appdevicectrl/action/DO_ENTER_TUBEHOLDER_AND_SCAN.java

@ -65,10 +65,6 @@ public class DO_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction {
mfcs = gstate.mainFlowCtrlState;
}
DO_ENTER_TUBEHOLDER_AND_SCAN() {
super(A8kActionStepType.DO_ENTER_TUBEHOLDER_AND_SCAN);
}
SampleScanResult scanTubeHodler() throws AppException {
SampleScanResult result = new SampleScanResult();
@ -111,9 +107,8 @@ public class DO_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction {
logger.info("扫描试管{}完成,{}", i, tubesScanResult[i]);
}
//处理扫描结果
// state.tubeHolderState.isReady = true;
if (!hasTube) {
logger.error("不支持的试管架类型");
logger.error("试管架中没有试管");
ebus.pushEvent(new AppWarningNotifyEvent(A8kEcode.TubeHolderTypeIsNotSupport));
stc.ejectTubeHolder();
return null;
@ -130,6 +125,9 @@ public class DO_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction {
//获取试管架类型
A8kTubeHolderType tubeHolderType = A8kTubeHolderType.of(scanResult.tubeHolderType);
if (tubeHolderType == null) {
logger.error("不支持的试管架类型");
ebus.pushEvent(new AppWarningNotifyEvent(A8kEcode.TubeHolderTypeIsNotSupport));
stc.ejectTubeHolder();
return null;
}
@ -178,7 +176,7 @@ public class DO_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction {
//设置试管架状态
state.processState = TubeHolderProcessState.READY;
state.processState = TubeHolderProcessState.PROCESSING;
state.processingTubeIndex = -1;
//删除之前的试管架配置
appTubeSettingMgrService.removeTubeHolderSetting(setting);
@ -194,22 +192,20 @@ public class DO_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction {
@Override public void doaction() throws AppException {
//扫描试管架信息
logger.info("开始扫描试管架");
var scanResult = scanTubeHodler();
if (scanResult == null) {
logger.warn("没有试管,弹出试管架");
ebus.pushEvent(new AppWarningNotifyEvent(A8kEcode.NoTubeInHolder));
stc.ejectTubeHolder();
return;
}
//解析扫描结果
logger.info("解析扫描结果");
TubeHolderState state = parseScanResult(scanResult);
if (state == null) {
return;
}
//更新试管架状态
logger.info("更新试管架状态");
gstate.setTubeHolderState(state);
}
@Override public Boolean checkCondition() {

5
src/main/java/a8k/service/appdevicectrl/action/DO_PAUSE.java

@ -26,11 +26,6 @@ public class DO_PAUSE extends A8kStepAction {
}
public DO_PAUSE() {
super(A8kActionStepType.DO_START);
}
@Override public void doaction() throws AppException {
gstate.mainFlowCtrlState.workState = A8kWorkState.PAUSE;
}

15
src/main/java/a8k/service/appdevicectrl/action/DO_START.java

@ -1,6 +1,7 @@
package a8k.service.appdevicectrl.action;
import a8k.service.appstate.AppA8kGStateService;
import a8k.service.appstate.AppResourceMgrService;
import a8k.service.appstate.MainFlowCtrlState;
import a8k.service.appstate.resource.A8kPublicResourceType;
import a8k.service.appstate.type.state.A8kWorkState;
@ -23,18 +24,20 @@ public class DO_START extends A8kStepAction {
@Resource
AppA8kGStateService gstate;
@PostConstruct
void init() {
@Resource
SampleScanTransportCtrl sstc;
}
@PostConstruct
void init() {
public DO_START() {
super(A8kActionStepType.DO_START);
}
@Override public void doaction() throws AppException {
if (gstate.mainFlowCtrlState.workState.equals(A8kWorkState.IDLE)) {
sstc.ejectTubeHolder();
}
gstate.mainFlowCtrlState.workState = A8kWorkState.WORKING;
}
@ -45,6 +48,6 @@ public class DO_START extends A8kStepAction {
}
@Override public List<A8kPublicResourceType> getDeplyResourceList() {
return List.of();
return List.of(A8kPublicResourceType.SampleTransferXMotor);
}
}

5
src/main/java/a8k/service/appdevicectrl/action/DO_STOP.java

@ -23,11 +23,6 @@ public class DO_STOP extends A8kStepAction {
void init() {
}
public DO_STOP() {
super(A8kActionStepType.DO_START);
}
@Override public void doaction() throws AppException {
gstate.mainFlowCtrlState.workState = A8kWorkState.IDLE;
}

115
src/main/java/a8k/service/appdevicectrl/action/DO_SWITCH_TO_THE_NEXT_TUBE.java

@ -0,0 +1,115 @@
package a8k.service.appdevicectrl.action;
import a8k.service.appstate.AppA8kGStateService;
import a8k.service.appstate.resource.A8kPublicResourceType;
import a8k.service.appstate.type.TubeHolderState;
import a8k.service.appstate.type.TubeState;
import a8k.service.appstate.type.state.A8kWorkState;
import a8k.service.appstate.type.state.TubeHolderProcessState;
import a8k.service.bak_appbase.progress.TubeProcessState;
import a8k.service.devicedriver.ctrl.SampleScanTransportCtrl;
import a8k.type.exception.AppException;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 切换下一个试管
*/
@Component
public class DO_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction {
static Logger logger = LoggerFactory.getLogger(DO_SWITCH_TO_THE_NEXT_TUBE.class);
@Resource
AppA8kGStateService gstate;
@Resource
SampleScanTransportCtrl sstc;
@PostConstruct
void init() {
}
@Override public void doaction() throws AppException {
/*
* 1. 将下一个试管移动到预处理位
* 2. 如果当前试管是最后一个试管则设置试管架状态为处理完成
*/
TubeHolderState state = gstate.getTubeHolderState();
int nowTubeIndex = state.processingTubeIndex;
int nextTubeIndex = nowTubeIndex + 1;
if (nextTubeIndex >= 10) {
logger.info("当前试管架处理完成");
state.processState = TubeHolderProcessState.PROCESS_FINISHED;
return;
}
assert state.tubeStates.length == 10;
nextTubeIndex = -1;
for (int i = nowTubeIndex + 1; i < 10; i++) {
TubeState tubeState = state.tubeStates[i];
if (!tubeState.isTubeExist) {
continue;
}
nextTubeIndex = i;
break;
}
if (nextTubeIndex == -1) {
logger.info("当前试管架处理完成");
state.processState = TubeHolderProcessState.PROCESS_FINISHED;
return;
}
sstc.moveTubeToPreProcessPos(nextTubeIndex);
state.processingTubeIndex = nextTubeIndex;
}
boolean con1;
boolean con1_11;
boolean con1_12;
boolean con1_21;
@Override public Boolean checkCondition() {
/*
*1. 设备工作中
* 1.1 试管架正在处理中
* 1.2 当前Index=-1
*
* 2.1 当前试管处理完成
*
*/
var mainFlowCtrlState = gstate.mainFlowCtrlState;
Integer curTubeIndex = gstate.getTubeHolderState().processingTubeIndex;
con1 = mainFlowCtrlState.workState.equals(A8kWorkState.WORKING);
con1_11 = gstate.getTubeHolderState().processState.equals(TubeHolderProcessState.PROCESSING);
con1_12 = curTubeIndex == -1;
con1_21 = false;
if (curTubeIndex >= 0) {
con1_21 = gstate.getTubeHolderState().tubeStates[curTubeIndex].state.equals(TubeProcessState.PROCESS_COMPLETE);
}
return con1 && (con1_11 && con1_12 || con1_21);
}
public List<Boolean> getConectionList() {
return List.of(con1, con1_11, con1_12, con1_21);
}
@Override public List<A8kPublicResourceType> getDeplyResourceList() {
return List.of(A8kPublicResourceType.SampleTransferXMotor);
}
}

25
src/main/java/a8k/service/appdevicectrl/scheduler/MainFlowCtrlScheduler.java

@ -17,6 +17,8 @@ import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
@ -116,15 +118,17 @@ public class MainFlowCtrlScheduler {
List<A8kActionStepType> dowhatList = new ArrayList<>();
for (A8kStepAction action : stepActionList) {
// Boolean cond = appCondtionMgrService.checkCondtion(action.getCondtions());
Boolean cond = action.checkCondition();
Boolean relayResourceSuc = appResourceMgrService.applyForResources(this, action.getDeplyResourceList());
if (cond && relayResourceSuc) {
dowhatList.add(action.step);
if (action.checkCondition()) {
Boolean relayResourceSuc = appResourceMgrService.applyForResources(this, action.getDeplyResourceList());
if (relayResourceSuc) {
dowhatList.add(action.step);
}
}
}
return dowhatList;
}
@ -229,7 +233,16 @@ public class MainFlowCtrlScheduler {
OS.forceSleep(800);
} else {
List<A8kActionStepType> dowhatList = guessWhatToDo();
List<A8kActionStepType> dowhatList;
try {
dowhatList = guessWhatToDo();
} catch (Exception e) {
appResourceMgrService.releaseAllResource(this);
OS.forceSleep(800);
continue;
}
List<Future<A8kEcodeContext>> futureList = new ArrayList<>();
for (A8kActionStepType dowhat : dowhatList) {
var future = executor.submit(() -> callFn(dowhat));

5
src/main/java/a8k/service/appstate/AppA8kGStateService.java

@ -34,11 +34,6 @@ public class AppA8kGStateService {
EmergencyPosRunState emergencyPosRunState = new EmergencyPosRunState();
//孵育盘状态
IncubationPlateStatus incubationPlateStatus = new IncubationPlateStatus();
//所有样本的状态包含本次开机已经处理过的样本的状态
List<TubeState> tubeStates;
//所有反应盘的状态(包含本次开机已经处理过的反应盘的状态)
List<ReactingPlateState> reactingPlateStates;
//耗材状态
ConsumableState consumableState = new ConsumableState();

5
src/main/java/a8k/service/appstate/type/TubeHolderState.java

@ -11,5 +11,10 @@ public class TubeHolderState {
public TubeHolderProcessState processState = TubeHolderProcessState.IDLE; //处理状态
public Integer processingTubeIndex = -1; //当前正在被处理的试管索引
public TubeHolderState() {
for (int i = 0; i < tubeStates.length; i++) {
tubeStates[i] = new TubeState();
}
}
}

10
src/main/java/a8k/service/appstate/type/TubeState.java

@ -10,11 +10,11 @@ public class TubeState {
public Boolean isHighTube = false;
public Boolean isTubeExist = false;
public BloodType bloodType = BloodType.WHOLE_BLOOD; //血液类型
public String sampleBarcode; //用于请求用户信息的条码ID
public String userid; //用户输入的样本ID不做逻辑只做展示
public List<Integer> projIndex = new ArrayList<>(); //项目代码
public BloodType bloodType = BloodType.WHOLE_BLOOD; //血液类型
public String sampleBarcode = ""; //用于请求用户信息的条码ID
public String userid = ""; //用户输入的样本ID不做逻辑只做展示
public List<Integer> projIndex = new ArrayList<>(); //项目代码
//
public TubeProcessState state = TubeProcessState.PREPARE; //样本被处理的状态
public TubeProcessState state = TubeProcessState.TO_BE_PROCESSED; //样本被处理的状态
}

1
src/main/java/a8k/service/appstate/type/state/TubeHolderProcessState.java

@ -2,7 +2,6 @@ package a8k.service.appstate.type.state;
public enum TubeHolderProcessState {
IDLE, //没有试管架
READY, //扫描完试管架并且赋值好所有的试管架信息
PROCESSING, //正在处理试管架
PROCESS_FINISHED, //试管架处理完成但试管架并没有被取走
}

18
src/main/java/a8k/service/bak_appbase/progress/TubeProcessState.java

@ -2,17 +2,9 @@ package a8k.service.bak_appbase.progress;
public enum TubeProcessState {
//
PREPARE,
//待处理
READY,
//预处理中
PRE_PROCESSING,
//待采样
TO_BE_SAMPLED,
//采样中
SAMPLING,
//采样完成
SAMPLED,
//处理完成
PROCESS_COMPLETE,
TO_BE_PROCESSED,//待处理
PRE_PROCESSING, //预处理
PROCESSING,//预处理
POST_PROCESSING, //后处理
PROCESS_COMPLETE,//处理完成
}

3
src/main/java/a8k/type/type/A8kTubeHolderType.java

@ -17,6 +17,9 @@ public enum A8kTubeHolderType {
}
public static A8kTubeHolderType of(String scanCode) {
//scanCode 移除\r
scanCode = scanCode.replace("\r", "");
for (A8kTubeHolderType t : A8kTubeHolderType.values()) {
if (t.scanCode.equals(scanCode)) {
return t;

Loading…
Cancel
Save