From 7889a6fa0f9c13ede559a2934f86a48779acf433 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Tue, 1 Oct 2024 17:36:51 +0800 Subject: [PATCH] update --- .../appeventbus/AppEventBusService.java | 4 +- .../appeventbus/appevent/A8kErrorPromptEvent.java | 4 + .../appevent/AppWarningNotifyEvent.java | 15 +- .../extapi/pagecontrol/ExtApiTabConfig.java | 3 +- .../a8k/hardware/type/a8kcanprotocol/A8kEcode.java | 23 +- .../java/a8k/service/appctrl/AppContrlService.java | 63 ++++++ .../service/appctrl/AppCtrlExceptionProcesser.java | 26 --- .../service/appctrl/AppCtrlSamplePreProcess.java | 193 ---------------- .../service/appctrl/AppCtrlSampleScanService.java | 251 ++++++++++++++++----- .../service/appctrl/ReactionPlateProcesser.java | 4 - .../appctrl/type/AppCtrlServiceWorkState.java | 11 + src/main/java/a8k/service/appstate/A8kState.java | 17 +- .../a8k/service/appstate/AppA8kStateService.java | 1 - .../service/appstate/AppResourceMgrService.java | 59 +++++ .../appstate/resource/A8kPublicResourceType.java | 5 + .../a8k/service/appstate/type/TubeHolderState.java | 5 + .../type/state/A8kSamplePreProcessState.java | 6 + .../service/appstate/type/state/A8kWorkState.java | 7 + .../devicectrl/ctrl/SampleScanTransportCtrl.java | 11 +- src/main/java/a8k/type/exception/AppException.java | 1 + 20 files changed, 412 insertions(+), 297 deletions(-) create mode 100644 src/main/java/a8k/service/appctrl/AppContrlService.java delete mode 100644 src/main/java/a8k/service/appctrl/AppCtrlExceptionProcesser.java delete mode 100644 src/main/java/a8k/service/appctrl/AppCtrlSamplePreProcess.java create mode 100644 src/main/java/a8k/service/appctrl/type/AppCtrlServiceWorkState.java create mode 100644 src/main/java/a8k/service/appstate/AppResourceMgrService.java create mode 100644 src/main/java/a8k/service/appstate/resource/A8kPublicResourceType.java create mode 100644 src/main/java/a8k/service/appstate/type/state/A8kSamplePreProcessState.java create mode 100644 src/main/java/a8k/service/appstate/type/state/A8kWorkState.java diff --git a/src/main/java/a8k/baseservice/appeventbus/AppEventBusService.java b/src/main/java/a8k/baseservice/appeventbus/AppEventBusService.java index 07d16fd..efa51c0 100644 --- a/src/main/java/a8k/baseservice/appeventbus/AppEventBusService.java +++ b/src/main/java/a8k/baseservice/appeventbus/AppEventBusService.java @@ -32,7 +32,7 @@ public class AppEventBusService implements ApplicationListener sm, AppException e) { - if (e.getErrorCode().equals(A8kEcode.InfeedOvertimeFail.index)) { - sm.selfPause(); - } else { - sm.selfStop(); - } - ebus.pushEvent(new A8kErrorPromptEvent(e.getErrorCode())); - } -} diff --git a/src/main/java/a8k/service/appctrl/AppCtrlSamplePreProcess.java b/src/main/java/a8k/service/appctrl/AppCtrlSamplePreProcess.java deleted file mode 100644 index ae38944..0000000 --- a/src/main/java/a8k/service/appctrl/AppCtrlSamplePreProcess.java +++ /dev/null @@ -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 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) {} - - -} diff --git a/src/main/java/a8k/service/appctrl/AppCtrlSampleScanService.java b/src/main/java/a8k/service/appctrl/AppCtrlSampleScanService.java index 2f46c76..146f7f5 100644 --- a/src/main/java/a8k/service/appctrl/AppCtrlSampleScanService.java +++ b/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 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; } } diff --git a/src/main/java/a8k/service/appctrl/ReactionPlateProcesser.java b/src/main/java/a8k/service/appctrl/ReactionPlateProcesser.java index 432e30c..b40cc27 100644 --- a/src/main/java/a8k/service/appctrl/ReactionPlateProcesser.java +++ b/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; diff --git a/src/main/java/a8k/service/appctrl/type/AppCtrlServiceWorkState.java b/src/main/java/a8k/service/appctrl/type/AppCtrlServiceWorkState.java new file mode 100644 index 0000000..c7a20a2 --- /dev/null +++ b/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; +} diff --git a/src/main/java/a8k/service/appstate/A8kState.java b/src/main/java/a8k/service/appstate/A8kState.java index 0dba326..f6ed2cf 100644 --- a/src/main/java/a8k/service/appstate/A8kState.java +++ b/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 sampleStates; diff --git a/src/main/java/a8k/service/appstate/AppA8kStateService.java b/src/main/java/a8k/service/appstate/AppA8kStateService.java index 9a6ba6a..44313a2 100644 --- a/src/main/java/a8k/service/appstate/AppA8kStateService.java +++ b/src/main/java/a8k/service/appstate/AppA8kStateService.java @@ -41,7 +41,6 @@ public class AppA8kStateService { deviceState.deviceInited = deviceInited; } - public TubeHolderProgress getTubeHolderProgress() { return deviceState.tubeHolderProgress; } diff --git a/src/main/java/a8k/service/appstate/AppResourceMgrService.java b/src/main/java/a8k/service/appstate/AppResourceMgrService.java new file mode 100644 index 0000000..4689ebb --- /dev/null +++ b/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 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; + } + } + } + } + + +} diff --git a/src/main/java/a8k/service/appstate/resource/A8kPublicResourceType.java b/src/main/java/a8k/service/appstate/resource/A8kPublicResourceType.java new file mode 100644 index 0000000..b8730b5 --- /dev/null +++ b/src/main/java/a8k/service/appstate/resource/A8kPublicResourceType.java @@ -0,0 +1,5 @@ +package a8k.service.appstate.resource; + +public enum A8kPublicResourceType { + SampleTransferXMotor,//样本平移电机 +} diff --git a/src/main/java/a8k/service/appstate/type/TubeHolderState.java b/src/main/java/a8k/service/appstate/type/TubeHolderState.java index adab774..1e58bfb 100644 --- a/src/main/java/a8k/service/appstate/type/TubeHolderState.java +++ b/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; //是否处理完成 } diff --git a/src/main/java/a8k/service/appstate/type/state/A8kSamplePreProcessState.java b/src/main/java/a8k/service/appstate/type/state/A8kSamplePreProcessState.java new file mode 100644 index 0000000..6866343 --- /dev/null +++ b/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, +} diff --git a/src/main/java/a8k/service/appstate/type/state/A8kWorkState.java b/src/main/java/a8k/service/appstate/type/state/A8kWorkState.java new file mode 100644 index 0000000..c76c271 --- /dev/null +++ b/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, +} diff --git a/src/main/java/a8k/service/devicectrl/ctrl/SampleScanTransportCtrl.java b/src/main/java/a8k/service/devicectrl/ctrl/SampleScanTransportCtrl.java index 59a12ed..3c90490 100644 --- a/src/main/java/a8k/service/devicectrl/ctrl/SampleScanTransportCtrl.java +++ b/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 试管索引 diff --git a/src/main/java/a8k/type/exception/AppException.java b/src/main/java/a8k/type/exception/AppException.java index 880d7f7..a11febf 100644 --- a/src/main/java/a8k/type/exception/AppException.java +++ b/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;