Browse Source

update

tags/v0
zhaohe 10 months ago
parent
commit
a50983aae5
  1. 22
      src/main/java/a8k/baseservice/AppExceptionBuilder.java
  2. 6
      src/main/java/a8k/baseservice/appeventbus/appevent/A8kEcodeContextListPromptEvent.java
  3. 10
      src/main/java/a8k/dbservice/A8kProjIdCardDBService.java
  4. 4
      src/main/java/a8k/service/appdata/AppProjConfigMgrService.java
  5. 35
      src/main/java/a8k/service/appdata/AppProjInfoMgrService.java
  6. 5
      src/main/java/a8k/service/appdevicectrl/AppConsumablesMgrService.java
  7. 22
      src/main/java/a8k/service/appdevicectrl/MainFlowCtrlService.java
  8. 1
      src/main/java/a8k/service/appdevicectrl/action/base/A8kActionStepType.java
  9. 44
      src/main/java/a8k/service/appdevicectrl/action/mainflow/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java
  10. 89
      src/main/java/a8k/service/appdevicectrl/action/mainflow/SEQ3_CHECK_THE_QUANTITY_OF_CONSUMABLES.java
  11. 38
      src/main/java/a8k/service/appdevicectrl/scheduler/MainFlowCtrlScheduler.java
  12. 7
      src/main/java/a8k/service/appdevicectrl/type/A8kErrorContext.java
  13. 4
      src/main/java/a8k/service/appstate/MainFlowCtrlState.java
  14. 13
      src/main/java/a8k/type/ecode/ConsumeNotEnoughError.java
  15. 4
      src/main/java/a8k/type/projecttype/a8kidcard/A8kIdCardInfo.java

22
src/main/java/a8k/baseservice/AppExceptionBuilder.java

@ -0,0 +1,22 @@
package a8k.baseservice;
import a8k.type.ecode.ConsumeNotEnoughError;
import a8k.type.exception.AppException;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import a8k.service.appdata.AppProjInfoMgrService;
@Component
public class AppExceptionBuilder {
@Resource
AppProjInfoMgrService projConfigMgrService;
public AppException buildConsumeNotEnoughError(Integer projIndex) {
String projName = projConfigMgrService.getProjNameByLotId(projIndex);
return new AppException(new ConsumeNotEnoughError(projName, projIndex));
}
}

6
src/main/java/a8k/baseservice/appeventbus/appevent/A8kEcodeContextListPromptEvent.java

@ -1,13 +1,13 @@
package a8k.baseservice.appeventbus.appevent;
import a8k.service.appdevicectrl.type.A8kEcodeContext;
import a8k.service.appdevicectrl.type.A8kErrorContext;
import java.util.List;
public class A8kEcodeContextListPromptEvent extends AppEvent {
List<A8kEcodeContext> ecodeList;
List<A8kErrorContext> ecodeList;
public A8kEcodeContextListPromptEvent(List<A8kEcodeContext> ecodeList) {
public A8kEcodeContextListPromptEvent(List<A8kErrorContext> ecodeList) {
super(A8kEcodeContextListPromptEvent.class.getSimpleName());
this.ecodeList = ecodeList;
}

10
src/main/java/a8k/dbservice/A8kProjIdCardDBService.java

@ -53,7 +53,7 @@ public class A8kProjIdCardDBService {
updateIdCard(old.id, idcardinfo);
return;
}
idcardinfo.color = colorAllocer.genRandomColor(idcardinfo.projIndex,idcardinfo.lotId);
idcardinfo.color = colorAllocer.genRandomColor(idcardinfo.projIndex, idcardinfo.lotId);
ZSqliteJdbcHelper.addObj(jdbcTemplate, tableName, tClass, idcardinfo);
}
@ -69,5 +69,13 @@ public class A8kProjIdCardDBService {
return null;
}
public A8kIdCardInfo getProjInfoByProjIndex(int projIndex) {
List<A8kIdCardInfo> list = jdbcTemplate.query("select * from " + tableName + " where projIndex = ?;", this::rowMapper, projIndex);
if (!list.isEmpty()) {
return list.get(0);
}
return null;
}
}

4
src/main/java/a8k/service/appdata/AppProjConfigMgrService.java

@ -1,4 +0,0 @@
package a8k.service.appdata;
public class AppProjConfigMgrService {
}

35
src/main/java/a8k/service/appdata/AppProjInfoMgrService.java

@ -44,11 +44,7 @@ public class AppProjInfoMgrService implements AppEventListener {
@Resource
A8kProjIdCardDBService a8kProjIdCardDBService;
//预设项目信息
@Resource
A8kPresetProjInfoDBService a8KPresetProjInfoDBService;
// //预设项目信息
A8kIdCardInfo mountedIdCardInfo;
ZWorkQueue workQueue = new ZWorkQueue(2, 1);
@ -129,25 +125,26 @@ public class AppProjInfoMgrService implements AppEventListener {
return a8kProjIdCardDBService.getAllIdCards();
}
@ExtApiFn(name = "获取预设项目信息", group = "预设项目信息")
public List<A8kPresetProjInfo> getPreSetProjInfo() {
return a8KPresetProjInfoDBService.getAll();
}
public A8kIdCardInfo getA8kIdCardInfoByLotId(String lotid) {
return a8kProjIdCardDBService.getIdCard(lotid);
}
public A8kReactionFlowType getA8kReactionFlowTypeByProjIndex(Integer projId) {
A8kPresetProjInfo info = a8KPresetProjInfoDBService.getByProjId(projId);
if (info == null) {
return null;
public String getProjNameByLotId(Integer projIndex) {
var idCard = a8kProjIdCardDBService.getProjInfoByProjIndex(projIndex);
if (idCard == null) {
return "未知项目";
}
if (info.reactionFlowType == null) {
return null;
}
return info.reactionFlowType;
return idCard.projName;
}
/**
* 通过项目索引获取流程
* @param projIndex 项目索引
* @return 流程
*/
public A8kReactionFlowType getA8kReactionFlowTypeByProjIndex(Integer projIndex) {
var projInfo = a8kProjIdCardDBService.getProjInfoByProjIndex(projIndex);
return projInfo.reactionFlowType;
}

5
src/main/java/a8k/service/appdevicectrl/AppConsumablesMgrService.java

@ -268,4 +268,9 @@ public class AppConsumablesMgrService {
return false;
}
synchronized public Boolean isHasEnoughConsumables(Integer projIndex) {
Integer total = getConsumableNum(projIndex);
return total >= 1;
}
}

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

@ -4,7 +4,7 @@ import a8k.service.appdevicectrl.action.*;
import a8k.service.appdevicectrl.action.base.A8kActionStepType;
import a8k.service.appdevicectrl.action.base.A8kStepAction;
import a8k.service.appdevicectrl.scheduler.MainFlowCtrlScheduler;
import a8k.service.appdevicectrl.type.A8kEcodeContext;
import a8k.service.appdevicectrl.type.A8kErrorContext;
import a8k.service.appstate.AppA8kGStateService;
import a8k.service.appstate.AppCondtionMgrService;
import com.iflytop.a800.SpringBootBeanUtil;
@ -45,14 +45,14 @@ public class MainFlowCtrlService {
scheduler.regEcodePostProcesser(this::postPorcessA8kEcode);
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);
// }
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();
@ -71,7 +71,7 @@ public class MainFlowCtrlService {
}
void postPorcessA8kEcode(List<A8kEcodeContext> ecodeList) {
void postPorcessA8kEcode(List<A8kErrorContext> ecodeList) {
}
/**
@ -79,7 +79,7 @@ public class MainFlowCtrlService {
* @param ecodeList
* @return
*/
Boolean clearErrorcodeBeforeContinueDo(List<A8kEcodeContext> ecodeList) {
Boolean clearErrorcodeBeforeContinueDo(List<A8kErrorContext> ecodeList) {
return true;
}

1
src/main/java/a8k/service/appdevicectrl/action/base/A8kActionStepType.java

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

44
src/main/java/a8k/service/appdevicectrl/action/mainflow/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java

@ -1,5 +1,6 @@
package a8k.service.appdevicectrl.action.mainflow;
import a8k.baseservice.AppExceptionBuilder;
import a8k.baseservice.appeventbus.AppEventBusService;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.service.appdevicectrl.AppConsumablesMgrService;
@ -47,6 +48,9 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction {
@Resource
AppEventBusService ebus;
@Resource
AppExceptionBuilder ebuilder;
@PostConstruct
void init() {
@ -80,10 +84,6 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction {
}
void checkIsReadyToRun(Tube tube) {
}
@Override public void doaction() throws AppException {
/*
* 1. 将下一个试管移动到预处理位
@ -92,27 +92,39 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction {
*/
//当前是否有有急诊试管需要处理
Tube nextProcessTube = null;
Boolean isEmergencyTube = false;
boolean isEmergencyTube = false;
int nextTubeIndex = -1;
if (gstate.getEmergencyTubePos().tube.state.equals(TubeState.TO_BE_PROCESSED)) {
logger.info("当前有急诊试管需要处理");
nextProcessTube = gstate.getEmergencyTubePos().tube;
isEmergencyTube = true;
} else {
int nextPos = moveToNextTube();
assert nextPos != -1;
nextProcessTube = gstate.getTubeHolder().tubes[nextPos];
isEmergencyTube = false;
// logger.info("移动到下一个试管:{}", nextPos);
// sstc.moveTubeToPreProcessPos(nextPos);
// gstate.setCurProcessingTube();
// gstate.getCurProcessingTube().state = TubeState.PRE_PROCESSING;
nextTubeIndex = moveToNextTube();
assert nextTubeIndex != -1;
nextProcessTube = gstate.getTubeHolder().tubes[nextTubeIndex];
}
//检查孵育盘是否有空位
if (!checkReactionPlateResource(nextProcessTube)) {
return;
}
if (!isHasEnoughConsumables(nextProcessTube)) {
throw new AppException(A8kEcode.ConsumeNotEnough);
//检查耗材是否足够
for (Integer projIndex : nextProcessTube.projIndex) {
if (!consumablesMgrService.isHasEnoughConsumables(projIndex)) {
throw ebuilder.buildConsumeNotEnoughError(projIndex);
}
}
//设置状态
if (isEmergencyTube) {
logger.info("处理急诊试管:{}", nextProcessTube);
} else {
logger.info("处理下一个试管:{}", nextProcessTube);
sstc.moveTubeToPreProcessPos(nextTubeIndex);
}
nextProcessTube.state = TubeState.PRE_PROCESSING;
gstate.setCurProcessingTube(nextProcessTube);
}
@Override public Boolean checkCondition() {

89
src/main/java/a8k/service/appdevicectrl/action/mainflow/SEQ3_CHECK_THE_QUANTITY_OF_CONSUMABLES.java

@ -1,89 +0,0 @@
package a8k.service.appdevicectrl.action.mainflow;
import a8k.service.appdata.AppProjInfoMgrService;
import a8k.service.appdevicectrl.action.base.A8kActionStepType;
import a8k.service.appdevicectrl.action.base.A8kStepAction;
import a8k.service.appstate.AppA8kGStateService;
import a8k.service.appstate.resource.A8kPublicResourceType;
import a8k.service.devicedriver.ctrl.SampleScanTransportCtrl;
import a8k.type.exception.AppException;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 检查耗材是否充足
*/
@Component
public class SEQ3_CHECK_THE_QUANTITY_OF_CONSUMABLES extends A8kStepAction {
static Logger logger = LoggerFactory.getLogger(SEQ3_CHECK_THE_QUANTITY_OF_CONSUMABLES.class);
SEQ3_CHECK_THE_QUANTITY_OF_CONSUMABLES() {
super(A8kActionStepType.DO_CHECK_THE_QUANTITY_OF_CONSUMABLES);
}
@Resource
AppA8kGStateService gstate;
@Resource
SampleScanTransportCtrl sstc;
@Resource
AppProjInfoMgrService projInfoMgrService;
void init() {
}
void checkProjResource(Integer projIndex) {
//检查项目ID卡是否存在
// if(projInfoMgrService.)
//检查耗材
//申请耗材
//申请失败抛出异常
//如果出错要归还耗材
}
@Override public void doaction() throws AppException {
//检查当前试管的待做项目所需要的资源是否充足
// List<Integer> projIndex = gstate.getTubeHolder().getProcessingTube().projIndex;
// if (projIndex.isEmpty()) {
// logger.error("试管待处理项目为空");//属于代码异常
// sstc.ejectTubeHolder();
// throw new AppException(A8kEcode.CodeError.index, "试管待处理项目为空");
// }
//
// for (Integer proj : projIndex) {
// checkProjResource(proj);
// }
}
@Override public Boolean checkCondition() {
// // 仪器是否在工作
// Boolean cond1 = gstate.isWorking();
// // 试管架是否在处理中
// Boolean cond2 = gstate.getTubeHolder().state.equals(TubeHolderState.PROCESSING);
// // 试管是否待处理
// Boolean cond3 = gstate.getTubeHolder().getProcessingTube() != null && gstate.getTubeHolder().getProcessingTube().state.equals(TubeState.TO_BE_PROCESSED);
// // 孵育盘是否有空位
// Boolean cond4 = gstate.getIncubationPlate().getEmptyPos() != null;
// return cond1 && cond2 && cond3 && cond4;
return false;
}
@Override public List<A8kPublicResourceType> getDeplyResourceList() {
return List.of();
}
@Override public Boolean isAllowsParallelRunning() {
return false;//串行任务无需担心状态冲突
}
}

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

@ -4,7 +4,6 @@ import a8k.OS;
import a8k.baseservice.appeventbus.AppEventBusService;
import a8k.baseservice.appeventbus.appevent.A8kEcodeContextListPromptEvent;
import a8k.baseservice.appeventbus.appevent.DoA8kStepActionEvent;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.service.appdevicectrl.action.base.A8kActionStepType;
import a8k.service.appdevicectrl.action.base.A8kStepAction;
import a8k.service.appdevicectrl.type.*;
@ -12,6 +11,7 @@ import a8k.service.appstate.AppA8kGStateService;
import a8k.service.appstate.AppCondtionMgrService;
import a8k.service.appstate.AppResourceMgrService;
import a8k.service.appstate.MainFlowCtrlState;
import a8k.service.appstate.type.state.A8kWorkState;
import a8k.type.exception.AppException;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
@ -33,12 +33,12 @@ public class MainFlowCtrlScheduler {
@FunctionalInterface
public interface A8kEcodePostProcesser {
void process(List<A8kEcodeContext> ecodeList);
void process(List<A8kErrorContext> ecodeList);
}
@FunctionalInterface
public interface A8kEcodeClearProcesser {
boolean process(List<A8kEcodeContext> ecodeList) throws AppException;
boolean process(List<A8kErrorContext> ecodeList) throws AppException;
}
@Resource
@ -67,7 +67,6 @@ public class MainFlowCtrlScheduler {
@PostConstruct
void init() {
state = gstate.mainFlowCtrlState;
}
/*
@ -134,14 +133,14 @@ public class MainFlowCtrlScheduler {
}
A8kEcodeContext callFn(A8kStepAction key) {
A8kErrorContext callFn(A8kStepAction key) {
beforeDoWhat(key.step);
try {
logger.info("doaction:{}", key.step);
key.doaction();
return new A8kEcodeContext(key.step, null);
return new A8kErrorContext(key.step, null);
} catch (AppException appe) {
return new A8kEcodeContext(key.step, appe.error);
return new A8kErrorContext(key.step, appe.error);
}
}
@ -158,17 +157,17 @@ public class MainFlowCtrlScheduler {
state.errorFlag = false;
}
} catch (AppException appe) {
A8kEcodeContext context = new A8kEcodeContext(A8kActionStepType.DO_CLEAR_ERROR, appe.error);
A8kErrorContext context = new A8kErrorContext(A8kActionStepType.DO_CLEAR_ERROR, appe.error);
a8kEcodePostProcesser(List.of(context));
}
}
List<A8kEcodeContext> waitAllActionIsDone(List<Future<A8kEcodeContext>> futureList) {
List<A8kEcodeContext> ecodeList = new ArrayList<>();
List<A8kErrorContext> waitAllActionIsDone(List<Future<A8kErrorContext>> futureList) {
List<A8kErrorContext> ecodeList = new ArrayList<>();
while (true) {
boolean someTaskNotDone = false;
for (Future<A8kEcodeContext> future : futureList) {
for (Future<A8kErrorContext> future : futureList) {
if (!future.isDone()) {
someTaskNotDone = true;
break;
@ -180,7 +179,7 @@ public class MainFlowCtrlScheduler {
OS.forceSleep(30);
}
for (Future<A8kEcodeContext> future : futureList) {
for (Future<A8kErrorContext> future : futureList) {
try {
ecodeList.add(future.get());
} catch (Exception e) {
@ -198,7 +197,7 @@ public class MainFlowCtrlScheduler {
//
List<A8kStepAction> serialActionList = new ArrayList<>();
List<A8kStepAction> parallelActionList = new ArrayList<>();
List<A8kEcodeContext> ecodeList = new ArrayList<>();
List<A8kErrorContext> ecodeList = new ArrayList<>();
for (A8kStepAction action : dowhatList) {
if (action.isAllowsParallelRunning()) {
@ -210,19 +209,19 @@ public class MainFlowCtrlScheduler {
//执行串行任务
for (A8kStepAction action : serialActionList) {
A8kEcodeContext aec = callFn(action);
A8kErrorContext aec = callFn(action);
ecodeList.add(aec);
}
//执行并行任务
List<Future<A8kEcodeContext>> futureList = new ArrayList<>();
List<Future<A8kErrorContext>> futureList = new ArrayList<>();
for (A8kStepAction dowhat : parallelActionList) {
var future = executor.submit(() -> callFn(dowhat));
futureList.add(future);
}
//等待并行任务完成
List<A8kEcodeContext> ecodeListParallel = waitAllActionIsDone(futureList);
List<A8kErrorContext> ecodeListParallel = waitAllActionIsDone(futureList);
appResourceMgrService.releaseAllResource(this);
//合并错误
@ -233,7 +232,7 @@ public class MainFlowCtrlScheduler {
}
}
void a8kEcodePostProcesser(List<A8kEcodeContext> ecodeList) {
void a8kEcodePostProcesser(List<A8kErrorContext> ecodeList) {
//如果有错误且错误列表不为空则将错误列表添加到错误列表中
if (!this.state.ecodeList.isEmpty()) {
ecodeList.addAll(this.state.ecodeList);
@ -254,11 +253,12 @@ public class MainFlowCtrlScheduler {
}
ebus.pushEvent(new A8kEcodeContextListPromptEvent(ecodeList));
state.errorFlag = true;
this.state.errorFlag = true;
this.state.ecodeList = ecodeList;
this.state.workState = A8kWorkState.PAUSE;
gstate.setWorkState(A8kWorkState.PAUSE);
}
void threadLoopFn() {
while (workThread.isAlive()) {
if (state.fatalErrorFlag) {

7
src/main/java/a8k/service/appdevicectrl/type/A8kEcodeContext.java → src/main/java/a8k/service/appdevicectrl/type/A8kErrorContext.java

@ -1,19 +1,18 @@
package a8k.service.appdevicectrl.type;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.service.appdevicectrl.action.base.A8kActionStepType;
import a8k.type.ecode.AppError;
public class A8kEcodeContext {
public class A8kErrorContext {
public A8kActionStepType dowhat;
public AppError ecode;
public A8kEcodeContext(A8kActionStepType dowhat, AppError ecode) {
public A8kErrorContext(A8kActionStepType dowhat, AppError ecode) {
this.dowhat = dowhat;
this.ecode = ecode;
}
public Boolean equals(A8kEcodeContext other) {
public Boolean equals(A8kErrorContext other) {
return this.dowhat.equals(other.dowhat) && this.ecode.code.equals(other.ecode.code);
}

4
src/main/java/a8k/service/appstate/MainFlowCtrlState.java

@ -1,6 +1,6 @@
package a8k.service.appstate;
import a8k.service.appdevicectrl.type.A8kEcodeContext;
import a8k.service.appdevicectrl.type.A8kErrorContext;
import a8k.service.appstate.type.state.A8kWorkState;
import java.util.ArrayList;
@ -10,5 +10,5 @@ public class MainFlowCtrlState {
public A8kWorkState workState = A8kWorkState.IDLE; //
public Boolean errorFlag = false; //错误标志
public Boolean fatalErrorFlag = false; //致命错误标志
public List<A8kEcodeContext> ecodeList = new ArrayList<>();
public List<A8kErrorContext> ecodeList = new ArrayList<>();
}

13
src/main/java/a8k/type/ecode/ConsumeNotEnoughError.java

@ -0,0 +1,13 @@
package a8k.type.ecode;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
public class ConsumeNotEnoughError extends AppError {
Integer projIndex;
String projName;
public ConsumeNotEnoughError(String projName, Integer projIndex) {
super(A8kEcode.ConsumeNotEnough);
}
}

4
src/main/java/a8k/type/projecttype/a8kidcard/A8kIdCardInfo.java

@ -1,5 +1,6 @@
package a8k.type.projecttype.a8kidcard;
import a8k.type.projecttype.A8kReactionFlowType;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -47,6 +48,9 @@ public class A8kIdCardInfo {
public Integer resultDecimalPlaces; // 结果小数点位数 0x0041
public Integer scanningRange; // 扫描范围 0x0042
public A8kReactionFlowType reactionFlowType; //反应流程
public Integer reactionTemperature; //反应温度
public A8kIdCardProjectFormula projFormula = new A8kIdCardProjectFormula();

Loading…
Cancel
Save