Browse Source

update

tags/v0
zhaohe 10 months ago
parent
commit
7889a6fa0f
  1. 4
      src/main/java/a8k/baseservice/appeventbus/AppEventBusService.java
  2. 4
      src/main/java/a8k/baseservice/appeventbus/appevent/A8kErrorPromptEvent.java
  3. 15
      src/main/java/a8k/baseservice/appeventbus/appevent/AppWarningNotifyEvent.java
  4. 3
      src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java
  5. 23
      src/main/java/a8k/hardware/type/a8kcanprotocol/A8kEcode.java
  6. 63
      src/main/java/a8k/service/appctrl/AppContrlService.java
  7. 26
      src/main/java/a8k/service/appctrl/AppCtrlExceptionProcesser.java
  8. 193
      src/main/java/a8k/service/appctrl/AppCtrlSamplePreProcess.java
  9. 251
      src/main/java/a8k/service/appctrl/AppCtrlSampleScanService.java
  10. 4
      src/main/java/a8k/service/appctrl/ReactionPlateProcesser.java
  11. 11
      src/main/java/a8k/service/appctrl/type/AppCtrlServiceWorkState.java
  12. 17
      src/main/java/a8k/service/appstate/A8kState.java
  13. 1
      src/main/java/a8k/service/appstate/AppA8kStateService.java
  14. 59
      src/main/java/a8k/service/appstate/AppResourceMgrService.java
  15. 5
      src/main/java/a8k/service/appstate/resource/A8kPublicResourceType.java
  16. 5
      src/main/java/a8k/service/appstate/type/TubeHolderState.java
  17. 6
      src/main/java/a8k/service/appstate/type/state/A8kSamplePreProcessState.java
  18. 7
      src/main/java/a8k/service/appstate/type/state/A8kWorkState.java
  19. 11
      src/main/java/a8k/service/devicectrl/ctrl/SampleScanTransportCtrl.java
  20. 1
      src/main/java/a8k/type/exception/AppException.java

4
src/main/java/a8k/baseservice/appeventbus/AppEventBusService.java

@ -32,7 +32,7 @@ public class AppEventBusService implements ApplicationListener<ContextRefreshedE
public void pushEvent(AppEvent event) {
logger.info("pushEvent: {}", event.getClass().getSimpleName());
logger.info("pushEvent: {} {}", event.getClass().getSimpleName(), event);
eventQueue.add(event);
}
@ -48,7 +48,7 @@ public class AppEventBusService implements ApplicationListener<ContextRefreshedE
}
private void callOnEvent(AppEvent event) {
logger.info("Processing event: {}", event.getClass().getSimpleName());
// logger.info("Processing event: {}", event.getClass().getSimpleName());
for (AppEventListener listener : listeners) {
listener.onAppEvent(event);
}

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

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

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

@ -1,15 +1,20 @@
package a8k.baseservice.appeventbus.appevent;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
public class AppWarningNotifyEvent extends AppEvent {
String displayInfo;
public Integer errorCode;
public String errorCodeStr;
AppWarningNotifyEvent(String displayInfo) {
public AppWarningNotifyEvent(Integer errorCode) {
super(AppWarningNotifyEvent.class.getSimpleName());
this.displayInfo = displayInfo;
this.errorCode = errorCode;
this.errorCodeStr = A8kEcode.toDisPlayString(errorCode);
}
public String getDisplayInfo() {
return displayInfo;
public AppWarningNotifyEvent(A8kEcode ecode) {
this(ecode.index);
}
}

3
src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java

@ -16,8 +16,7 @@ public enum ExtApiTabConfig {
AppSampleFormulaMgrService("应用.配方管理", true),
AppCtrlService("应用.设备控制", true),
AppCoreCtrlService("应用.核心控制", true),
AppCtrlSamplePreProcess("应用控制.样本预处理", true),
AppCtrlSampleScanService("应用控制.样本扫描服务", true),
AppContrlService("应用控制", true),
Hbot2DCodeScanPos("参数.Hbot二维码扫描坐标参数", true),

23
src/main/java/a8k/hardware/type/a8kcanprotocol/A8kEcode.java

@ -2,13 +2,16 @@ package a8k.hardware.type.a8kcanprotocol;
public enum A8kEcode {
Success(0),
NoError(0),
/*
* 代码错误代码没有BUG的情况下不应该出现的错误
*/
CodeError(10),
CodeError_GetParamFail(11), //
CodeError_ParseParamFail(12), //
CodeError_UnkownException(13), //
CodeError_UnkownError(14), //
CodeError_End(19),
/*
@ -48,6 +51,8 @@ public enum A8kEcode {
A8kPlate2DCodeFormatError(133),//巴迪泰反应板2D码格式错误
A8kIsNotInIdleState(134),//设备不在空闲状态
A8kIdCardLotIdIsEmpty(135),//ID卡批号为空
NoTubeInHolder(136),//试管架中没有试管
AppFatalErrorTriggerClearErrorFail(137),//清除错误失败
/**
* 特殊服务错误码
@ -64,6 +69,8 @@ public enum A8kEcode {
//
// LowBoard
//
HardwareErrorStart(1000),
BoardCommonError(1001),
ParamOutOfRange(1102),
@ -150,7 +157,8 @@ public enum A8kEcode {
WaterCoolingPelterIsError(1904),
;
public int index;
public final int index;
public int unknownIndex = 0;
A8kEcode(int index) {
this.index = index;
@ -160,6 +168,17 @@ public enum A8kEcode {
return index;
}
static public A8kEcode fromInt(int index) {
for (var e : A8kEcode.values()) {
if (e.index == index) {
return e;
}
}
A8kEcode.CodeError_UnkownError.unknownIndex = index;
return A8kEcode.CodeError_UnkownError;
}
public static String toDisPlayString(int id) {
for (var e : A8kEcode.values()) {
if (e.index == id) {

63
src/main/java/a8k/service/appctrl/AppContrlService.java

@ -0,0 +1,63 @@
package a8k.service.appctrl;
import a8k.controler.extapi.pagecontrol.ExtApiTabConfig;
import a8k.controler.extapi.utils.ExtApiFn;
import a8k.controler.extapi.utils.ExtApiTab;
import a8k.service.appctrl.type.AppCtrlServiceWorkState;
import a8k.service.appstate.A8kState;
import a8k.service.appstate.AppA8kStateService;
import a8k.service.appstate.type.state.A8kWorkState;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
@Component
@ExtApiTab(cfg = ExtApiTabConfig.AppContrlService)
public class AppContrlService {
@Resource
AppA8kStateService a8kStateService;
@Resource
AppCtrlSampleScanService sampleScanService;
@ExtApiFn(name = "开始工作")
public void startWork() {
A8kState gstate = a8kStateService.getDeviceState();
gstate.workState = A8kWorkState.WORKING;
sampleScanService.setClearErrorPendingFlag();
}
@ExtApiFn(name = "停止工作")
public void stopWork() {
A8kState gstate = a8kStateService.getDeviceState();
gstate.workState = A8kWorkState.IDLE;
}
@ExtApiFn(name = "暂停工作")
public void pauseWork() {
A8kState gstate = a8kStateService.getDeviceState();
gstate.workState = A8kWorkState.PAUSE;
}
@ExtApiFn(name = "继续工作")
public void continueWork() {
A8kState gstate = a8kStateService.getDeviceState();
gstate.workState = A8kWorkState.WORKING;
sampleScanService.setClearErrorPendingFlag();
}
@ExtApiFn(name = "获取设备工作状态")
public ObjectNode getDeviceWorkState() {
ObjectMapper mapper = new ObjectMapper();
ObjectNode json = new ObjectNode(mapper.getNodeFactory());
json.put("sampleScanService", mapper.valueToTree(sampleScanService.getWorkState()));
json.put("globalWorkState", mapper.valueToTree(a8kStateService.getDeviceState().workState));
return json;
}
}

26
src/main/java/a8k/service/appctrl/AppCtrlExceptionProcesser.java

@ -1,26 +0,0 @@
package a8k.service.appctrl;
import a8k.baseservice.appeventbus.AppEventBusService;
import a8k.baseservice.appeventbus.appevent.A8kErrorPromptEvent;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.type.exception.AppException;
import a8k.utils.state_machine.AppStateMachine;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
@Component
public class AppCtrlExceptionProcesser {
@Resource
AppEventBusService ebus;
public void processException(AppStateMachine<?> sm, AppException e) {
if (e.getErrorCode().equals(A8kEcode.InfeedOvertimeFail.index)) {
sm.selfPause();
} else {
sm.selfStop();
}
ebus.pushEvent(new A8kErrorPromptEvent(e.getErrorCode()));
}
}

193
src/main/java/a8k/service/appctrl/AppCtrlSamplePreProcess.java

@ -1,193 +0,0 @@
package a8k.service.appctrl;
import a8k.baseservice.appeventbus.AppEventBusService;
import a8k.baseservice.appeventbus.appevent.A8kErrorPromptEvent;
import a8k.controler.extapi.pagecontrol.ExtApiTabConfig;
import a8k.controler.extapi.utils.ExtApiFn;
import a8k.controler.extapi.utils.ExtApiTab;
import a8k.hardware.A8kCanBusService;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.hardware.type.a8kcanprotocol.IOId;
import a8k.service.appstate.AppA8kStateService;
import a8k.service.devicectrl.ctrl.SampleScanTransportCtrl;
import a8k.service.devicectrl.ctrl.SamplesPreProcesCtrl;
import a8k.type.exception.AppException;
import a8k.utils.state_machine.AppStateMachine;
import a8k.utils.state_machine.type.event.*;
import a8k.utils.state_machine.type.event.base.AppStateMachineEvent;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@ExtApiTab(cfg = ExtApiTabConfig.AppCtrlSamplePreProcess)
@Component
public class AppCtrlSamplePreProcess {
static Logger logger = LoggerFactory.getLogger(AppCtrlSamplePreProcess.class);
public enum Step {
IDLE, //空闲
WaitNewTubeHolder, //等待试管架
EnterTubeHolder, //进料
ScanTubeHolderType,//扫描试管架类型
ScanTube,//扫描试管
PreProcessTube,//预处理样本
DisChargeTubeHolder,//出料
}
static class TubesScanResult {
Boolean isTubeExist = false;
Boolean isHighTube = false;
String tubeCode = null;
public String toString() {
return String.format("isTubeExist:%s,isHighTube:%s,tubeCode:%s", isTubeExist, isHighTube, tubeCode);
}
}
;
@Resource
AppA8kStateService sms;
@Resource
SamplesPreProcesCtrl sppc;
@Resource
SampleScanTransportCtrl stc;
@Resource
A8kCanBusService canBus;
@Resource
AppCtrlExceptionProcesser acep;
@Resource
AppEventBusService ebus;
AppStateMachine<Step> sm = new AppStateMachine<>(AppCtrlSamplePreProcess.class.getSimpleName());
TubesScanResult[] tubesScanResult = new TubesScanResult[10];
@PostConstruct
void init() {
sm.regIdleStateProcesser(Step.IDLE, this::processIDLE);
sm.regStateProcesser(Step.WaitNewTubeHolder, this::processWaitNewTubeHolder);
sm.regStateProcesser(Step.EnterTubeHolder, this::processEnterTubeHolder);
sm.regStateProcesser(Step.ScanTubeHolderType, this::processScanTubeHolderType);
sm.regStateProcesser(Step.ScanTube, this::processScanTube);
sm.regStateProcesser(Step.PreProcessTube, this::processPreProcessTube);
sm.regStateProcesser(Step.DisChargeTubeHolder, this::processDisChargeTubeHolder);
sm.startSchedule();
}
@ExtApiFn(name = "开始工作")
public void startWork() throws AppException {
if (sm.getCurrentState() != Step.IDLE) {
throw new AppException(A8kEcode.A8kIsNotInIdleState.index);
}
assert sm.getCurrentState() == Step.IDLE;
sm.changeState(Step.WaitNewTubeHolder);
}
public void pauseWork() {
sm.usrPause();
}
public void continueWork() {
sm.usrContinueDo();
}
public void stopWork() {
sm.usrStop();
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* PRIV 私有方法
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void processIDLE(AppStateMachineEvent event) {
// doNothing
}
//等待新的试管架
void processWaitNewTubeHolder(AppStateMachineEvent event) {
if (event instanceof PeriodicSchedulingEvent) {
try {
if (canBus.getIOState(IOId.InfeedPPS)) {
sm.changeState(Step.EnterTubeHolder);
}
} catch (AppException ignored) {
}
}
}
//进料
void processEnterTubeHolder(AppStateMachineEvent event) throws AppException {
if (event instanceof StateEnterEvent) {
Boolean enterSuc = stc.enterTubeHolder();
if (enterSuc) {
sm.changeState(Step.ScanTubeHolderType);
} else {
stc.ejectTubeHolderInEnterPos();
sm.selfPause();
ebus.pushEvent(new A8kErrorPromptEvent(A8kEcode.InfeedOvertimeFail));
}
} else if (event instanceof UsrContinueEvent) {
sm.changeState(Step.WaitNewTubeHolder);
}
}
//扫描试管架类型
void processScanTubeHolderType(AppStateMachineEvent event) throws AppException {
if (event instanceof StateEnterEvent) {
String result = stc.moveTubeRackToScanPosAndScan();
if (result.isEmpty()) {
logger.warn("扫描试管架类型失败");
stc.ejectTubeHolder();
ebus.pushEvent(new A8kErrorPromptEvent(A8kEcode.ScanTubeholderTypeTimeout));
}
logger.info("扫描试管架类型成功,{}", result);
} else if (event instanceof UsrContinueEvent) {
sm.changeState(Step.WaitNewTubeHolder);
}
}
//扫描试管编码高低试管试管有无
void processScanTube(AppStateMachineEvent event) throws AppException {
if (event instanceof StateEnterEvent) {
for (int i = 0; i < tubesScanResult.length; i++) {
Boolean isTubeExist = stc.moveAndjudgeTubeExist(i);
if (isTubeExist) {
tubesScanResult[i].isTubeExist = true;
tubesScanResult[i].isHighTube = stc.moveAndJudgeTubeAltit(i);
tubesScanResult[i].tubeCode = stc.moveTubeToScanPosAndScan(i);
}
logger.info("扫描试管{}完成,{}", i, tubesScanResult[i]);
}
Boolean suc = stc.ejectTubeHolder();
if (!suc) {
logger.warn("弹出试管架失败");
ebus.pushEvent(new A8kErrorPromptEvent(A8kEcode.EjectTubeholderTimeout));
sm.selfPause();
} else {
stc.moveTubeRackMoveToEnterPos();
sm.changeState(Step.PreProcessTube);
}
}
else if (event instanceof UsrContinueEvent) {
sm.changeState(Step.WaitNewTubeHolder);
}
}
void processPreProcessTube(AppStateMachineEvent event) {}
void processDisChargeTubeHolder(AppStateMachineEvent event) {}
}

251
src/main/java/a8k/service/appctrl/AppCtrlSampleScanService.java

@ -1,36 +1,39 @@
package a8k.service.appctrl;
import a8k.OS;
import a8k.baseservice.appeventbus.AppEventBusService;
import a8k.baseservice.appeventbus.appevent.A8kErrorPromptEvent;
import a8k.baseservice.appeventbus.appevent.AppWarningNotifyEvent;
import a8k.controler.extapi.pagecontrol.ExtApiTabConfig;
import a8k.controler.extapi.utils.ExtApiFn;
import a8k.controler.extapi.utils.ExtApiTab;
import a8k.hardware.A8kCanBusService;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.hardware.type.a8kcanprotocol.IOId;
import a8k.service.appctrl.type.AppCtrlServiceWorkState;
import a8k.service.appstate.A8kState;
import a8k.service.appstate.AppA8kStateService;
import a8k.service.appstate.type.state.A8kWorkState;
import a8k.service.devicectrl.ctrl.SampleScanTransportCtrl;
import a8k.service.devicectrl.ctrl.SamplesPreProcesCtrl;
import a8k.type.exception.AppException;
import a8k.utils.state_machine.AppStateMachine;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@ExtApiTab(cfg = ExtApiTabConfig.AppCtrlSamplePreProcess)
import java.lang.reflect.InvocationTargetException;
@Component
public class AppCtrlSampleScanService {
static Logger logger = LoggerFactory.getLogger(AppCtrlSampleScanService.class);
public enum Step {
IDLE, //空闲
WaitNewTubeHolder, //等待试管架
EnterTubeHolder, //进料
ScanTubeHolderType,//扫描试管架类型
ScanTube,//扫描试管
PreProcessTube,//预处理样本
DisChargeTubeHolder,//出料
public enum DOWAHT {
doNothing, //
doStartWork, //
doStopWork, //
doPauseWork,//
doEnterTubeHolderAndScan,// 进料扫描
doEjectTubeHolder,// 出料
doClearError,// 清除错误
;
}
static class TubesScanResult {
@ -43,85 +46,229 @@ public class AppCtrlSampleScanService {
}
}
;
@Resource
AppA8kStateService sms;
@Resource
SamplesPreProcesCtrl sppc;
AppA8kStateService appState;
@Resource
SampleScanTransportCtrl stc;
@Resource
A8kCanBusService canBus;
AppEventBusService ebus;
Thread workThread;
@Resource
AppCtrlExceptionProcesser acep;
@Resource
AppEventBusService ebus;
AppStateMachine<Step> sm = new AppStateMachine<>(AppCtrlSampleScanService.class.getSimpleName());
TubesScanResult[] tubesScanResult = new TubesScanResult[10];
A8kWorkState workState = A8kWorkState.IDLE; //工作状态
Boolean clearErrorPendingFlag = false; //清除错误请求标志
Boolean errorFlag = false; //错误标志
Boolean fatalErrorFlag = false; //致命错误标志
A8kEcode errorCode = A8kEcode.NoError; //错误码
@PostConstruct
void init() {
workThread = new Thread(this::threadLoopFn);
workThread.start();
}
void threadLoopFn() {
while (workThread.isAlive()) {
DOWAHT what = guessWhatToDo();
doWhat(what);
OS.forceSleep(100);
}
}
@ExtApiFn(name = "开始工作")
public void startWork() throws AppException {
void doWhat(DOWAHT what) {
//根据枚举字符串调用当前类中的同名方法
try {
if (what.equals(DOWAHT.doNothing)) {
return;
}
logger.info("do {}", what.name());
this.getClass().getMethod(what.name()).setAccessible(true);
this.getClass().getMethod(what.name()).invoke(this);
} catch (IllegalAccessException e) {
logger.warn("do {} fail,权限不足", what.name());
} catch (NoSuchMethodException e) {
logger.warn("do {} fail,未找到方法", what.name());
} catch (InvocationTargetException e) {
if (e.getCause() instanceof AppException appe) {
//处理异常
processA8kError(A8kEcode.fromInt(appe.getErrorCode()));
} else {
processA8kError(A8kEcode.CodeError_UnkownException);
}
}
}
//
// guessWhatToDo
//
DOWAHT guessWhatToDo() {
A8kState state = appState.getDeviceState();
A8kWorkState gWorkState = state.workState;
A8kWorkState localWorkState = workState;
if (errorFlag && clearErrorPendingFlag) {
return DOWAHT.doClearError;
}
//开始工作
if (!gWorkState.equals(localWorkState)) {
if (!errorFlag && gWorkState.equals(A8kWorkState.WORKING)) {
return DOWAHT.doStartWork;
}
if (gWorkState.equals(A8kWorkState.PAUSE)) {
return DOWAHT.doPauseWork;
}
if (gWorkState.equals(A8kWorkState.IDLE)) {
return DOWAHT.doStopWork;
}
}
if (errorFlag) {
return DOWAHT.doNothing;
}
if (localWorkState.equals(A8kWorkState.WORKING)) {
// 出料
if (state.tubeHolderState.isReady && state.tubeHolderState.isFinished) {
return DOWAHT.doEjectTubeHolder;
}
// 进料,扫描
if (!state.tubeHolderState.isReady) {
return DOWAHT.doEnterTubeHolderAndScan;
}
}
void sleep() {
return DOWAHT.doNothing;
}
void pausePoint() {
//
// DOFn
//
public void doNothing() {}
public void doStartWork() {
workState = A8kWorkState.WORKING;
}
public void doStopWork() {
workState = A8kWorkState.IDLE;
}
public void work() throws AppException {
//resetModule
public void doPauseWork() {
workState = A8kWorkState.PAUSE;
}
while (!canBus.getIOState(IOId.InfeedPPS)) {
public void doEnterTubeHolderAndScan() throws AppException {
//清空试管架
if (!stc.tubeXChannelIsEmpty()) {
stc.ejectTubeHolder();
}
//入料
logger.info("开始进料");
Boolean enterSuc = stc.enterTubeHolder();
if (!enterSuc) {
logger.warn("进料超时,从入料口,弹出试管架");
stc.ejectTubeHolderInEnterPos();
throw new AppException(A8kEcode.InfeedOvertimeFail.index);
}
//if 耗材不足
// throw new AppException(A8kEcode.InfeedOvertimeFail.index);
// selfpause
// waittingForContinue
//扫描试管架类型
String tubeType = stc.moveTubeRackToScanPosAndScan();
if (tubeType.isEmpty()) {
logger.warn("扫描试管架类型失败,弹出试管架");
stc.ejectTubeHolder();
throw new AppException(A8kEcode.ScanTubeholderTypeTimeout.index);
}
logger.info("扫描试管架类型成功,{}", tubeType);
//逐个扫描试管
TubesScanResult[] tubesScanResult = new TubesScanResult[10];
boolean hasTube = false;
for (int i = 0; i < tubesScanResult.length; i++) {
tubesScanResult[i] = new TubesScanResult();
Boolean isTubeExist = stc.moveAndjudgeTubeExist(i);
if (isTubeExist) {
hasTube = true;
tubesScanResult[i].isTubeExist = true;
tubesScanResult[i].isHighTube = stc.moveAndJudgeTubeAltit(i);
tubesScanResult[i].tubeCode = stc.moveTubeToScanPosAndScan(i);
} else {
tubesScanResult[i].isTubeExist = false;
}
logger.info("扫描试管{}完成,{}", i, tubesScanResult[i]);
}
//处理扫描结果
// state.tubeHolderState.isReady = true;
if (!hasTube) {
logger.warn("没有试管,弹出试管架");
ebus.pushEvent(new AppWarningNotifyEvent(A8kEcode.NoTubeInHolder.index));
stc.ejectTubeHolder();
}
// 设置全局试管架状态
}
public void onError(Integer depth, A8kEcode ecode) throws AppException {
if (depth >= 2) {
public void doEjectTubeHolder() {}
public void doClearError() throws AppException {
clearErrorPendingFlag = false;
/*
* clearError
*/
if (fatalErrorFlag) {
ebus.pushEvent(new A8kErrorPromptEvent(A8kEcode.AppFatalErrorTriggerClearErrorFail));
return;
}
if (ecode.equals(A8kEcode.InfeedOvertimeFail)) {
stc.ejectTubeHolderInEnterPos();
if (errorCode.equals(A8kEcode.EjectTubeholderTimeout)) {
stc.ejectTubeHolder();
stc.moveTubeRackMoveToEnterPos();
}
if (ecode.equals(A8kEcode.EjectTubeholderTimeout)) {
return;
errorCode = A8kEcode.NoError;
errorFlag = false;
}
void processA8kError(A8kEcode ecode) {
if (ecode.index > A8kEcode.HardwareErrorStart.index) {
fatalErrorFlag = true;
} else if (ecode.index > A8kEcode.CodeError.index && ecode.index < A8kEcode.CodeError_End.index) {
fatalErrorFlag = true;
}
//
ebus.pushEvent(new A8kErrorPromptEvent(ecode));
errorFlag = true;
errorCode = ecode;
}
/*
* Ext
*/
public void setClearErrorPendingFlag() {
clearErrorPendingFlag = true;
}
public void onFatalError(A8kEcode ecode) {
//
public AppCtrlServiceWorkState getWorkState() {
AppCtrlServiceWorkState ret = new AppCtrlServiceWorkState();
ret.workState = workState;
ret.errorFlag = errorFlag;
ret.fatalErrorFlag = fatalErrorFlag;
ret.errorCode = errorCode;
return ret;
}
}

4
src/main/java/a8k/service/appctrl/ReactionPlateProcesser.java

@ -17,7 +17,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@ExtApiTab(cfg = ExtApiTabConfig.AppCtrlSamplePreProcess)
@Component
public class ReactionPlateProcesser {
static Logger logger = LoggerFactory.getLogger(ReactionPlateProcesser.class);
@ -59,9 +58,6 @@ public class ReactionPlateProcesser {
@Resource
AppCtrlExceptionProcesser acep;
@Resource
AppEventBusService ebus;

11
src/main/java/a8k/service/appctrl/type/AppCtrlServiceWorkState.java

@ -0,0 +1,11 @@
package a8k.service.appctrl.type;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.service.appstate.type.state.A8kWorkState;
public class AppCtrlServiceWorkState {
public A8kWorkState workState = A8kWorkState.IDLE;
public Boolean errorFlag;
public Boolean fatalErrorFlag;
public A8kEcode errorCode;
}

17
src/main/java/a8k/service/appstate/A8kState.java

@ -1,6 +1,8 @@
package a8k.service.appstate;
import a8k.service.appstate.type.*;
import a8k.service.appstate.type.state.A8kSamplePreProcessState;
import a8k.service.appstate.type.state.A8kWorkState;
import a8k.service.bak_appbase.progress.TubeHolderProgress;
import java.util.List;
@ -8,17 +10,20 @@ import java.util.List;
public class A8kState {
public TubeHolderProgress tubeHolderProgress = TubeHolderProgress.Idle;
//温度
public Integer temperature = 25;
//设备是否初始化过
public Boolean deviceInited = false;
//设备工作状态标识位
public A8kWorkState workState = A8kWorkState.IDLE;
//当前正在被处理的试管架状态
public TubeHolderState tubeHolderState = new TubeHolderState();
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<SampleState> sampleStates;

1
src/main/java/a8k/service/appstate/AppA8kStateService.java

@ -41,7 +41,6 @@ public class AppA8kStateService {
deviceState.deviceInited = deviceInited;
}
public TubeHolderProgress getTubeHolderProgress() {
return deviceState.tubeHolderProgress;
}

59
src/main/java/a8k/service/appstate/AppResourceMgrService.java

@ -0,0 +1,59 @@
package a8k.service.appstate;
import a8k.service.appstate.resource.A8kPublicResourceType;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Vector;
@Component
public class AppResourceMgrService {
static public class Resource {
public A8kPublicResourceType type;
public Boolean state = false;
public Object ownerNow = null;
public Resource(A8kPublicResourceType type) {
this.type = type;
}
}
List<Resource> resources = new Vector<>();
@PostConstruct
public void init() {
for (A8kPublicResourceType type : A8kPublicResourceType.values()) {
resources.add(new Resource(type));
}
}
public Boolean applyForResource(Object applyer, A8kPublicResourceType type) {
for (Resource r : resources) {
if (r.type == type) {
if (r.state) {
return false;
}
r.state = true;
r.ownerNow = applyer;
return true;
}
}
return false;
}
public void releaseResource(Object applyer, A8kPublicResourceType type) {
for (Resource r : resources) {
if (r.type == type) {
if (r.ownerNow == applyer) {
r.state = false;
r.ownerNow = null;
}
}
}
}
}

5
src/main/java/a8k/service/appstate/resource/A8kPublicResourceType.java

@ -0,0 +1,5 @@
package a8k.service.appstate.resource;
public enum A8kPublicResourceType {
SampleTransferXMotor,//样本平移电机
}

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

@ -13,4 +13,9 @@ public class TubeHolderState {
public TubeHolderProgress tubeHolderProgress = TubeHolderProgress.Idle; //管子状态
public Integer processingTubeIndex = -1; //当前正在被处理的试管索引
public Boolean isReady = false; //是否准备好, 被AppCtrlSampleScanService 修改
public Boolean isProcessing = false; //是否正在处理
public Boolean isFinished = false; //是否处理完成
}

6
src/main/java/a8k/service/appstate/type/state/A8kSamplePreProcessState.java

@ -0,0 +1,6 @@
package a8k.service.appstate.type.state;
public enum A8kSamplePreProcessState {
PROCESSING,
IDLE,
}

7
src/main/java/a8k/service/appstate/type/state/A8kWorkState.java

@ -0,0 +1,7 @@
package a8k.service.appstate.type.state;
public enum A8kWorkState {
IDLE,
PAUSE,
WORKING,
}

11
src/main/java/a8k/service/devicectrl/ctrl/SampleScanTransportCtrl.java

@ -194,13 +194,13 @@ public class SampleScanTransportCtrl {
public void ejectTubeHolderInEnterPos() throws AppException {
canBus.stepMotorEasyRotate(MId.FeedingModInfeedM, 1);
OS.hsleep(5000);
OS.hsleep(3000);
canBus.stepMotorStop(MId.FeedingModInfeedM);
}
@ExtApiFn(name = "出料", group = "单步", order = ORDER.moveTubeRackToExitPos)
public Boolean ejectTubeHolder() throws AppException {
public void ejectTubeHolder() throws AppException {
moveTubeRackToExitPos();
try {
canBus.stepMotorEasyRotate(MId.FeedingModOutfeedM, 1);
@ -214,12 +214,11 @@ public class SampleScanTransportCtrl {
OS.hsleep(1000);
canBus.stepMotorStop(MId.FeedingModOutfeedM);
if (getTHchInterPPS() || getTHchOuterPPS()) {
return false;
throw new AppException(A8kEcode.EjectTubeholderTimeout.index);
}
} finally {
canBus.moduleStop(MId.FeedingModOutfeedM);
}
return true;
}
/**
@ -267,6 +266,10 @@ public class SampleScanTransportCtrl {
}
}
public Boolean tubeXChannelIsEmpty() throws AppException {
return !getTHchInterPPS() && !getTHchOuterPPS();
}
/**
* 移动试管到试管预处理的位置
* @param tubeIndex 试管索引

1
src/main/java/a8k/type/exception/AppException.java

@ -40,6 +40,7 @@ public class AppException extends Exception {
this.extmessage = extmessage;
}
public AppException(Integer ecode) {
super(String.format("Error code %s", ecode));
this.errorCode = ecode;

Loading…
Cancel
Save