Browse Source

update

tags/v0
zhaohe 10 months ago
parent
commit
f090873785
  1. BIN
      app.db
  2. 14
      src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java
  3. 8
      src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java
  4. 3
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java
  5. 23
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java
  6. 27
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java
  7. 1
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_RESUME.java
  8. 14
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java
  9. 33
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java
  10. 5
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java
  11. 3
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java
  12. 19
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java
  13. 14
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java
  14. 63
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java
  15. 13
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java
  16. 10
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java
  17. 2
      src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kActionStepType.java
  18. 4
      src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kStepAction.java
  19. 2
      src/main/java/a8k/service/app/appstate/EmergencySamplePosStateMgrService.java
  20. 8
      src/main/java/a8k/service/app/appstate/GStateService.java
  21. 15
      src/main/java/a8k/service/app/appstate/OptScanModuleStateMgrService.java
  22. 261
      src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java
  23. 7
      src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java
  24. 7
      src/main/java/a8k/service/app/appstate/type/OptScanModule.java
  25. 15
      src/main/java/a8k/service/app/appstate/type/Tube.java
  26. 6
      src/main/java/a8k/service/app/appstate/type/TubeHolder.java
  27. 1
      src/main/java/a8k/service/app/appstate/type/state/ProjProcessState.java
  28. 88
      src/main/java/a8k/service/db/DeviceStatisticDBService.java
  29. 10
      src/main/java/a8k/service/db/type/DeviceStatistic.java
  30. 6
      src/main/java/a8k/service/db/type/StatisticType.java
  31. 10
      src/main/java/a8k/utils/ZSqliteJdbcHelper.java
  32. 46
      src/main/java/a8k/utils/ZStringUtils.java

BIN
app.db

14
src/main/java/a8k/service/app/appctrl/mainflowctrl/CondtionMgrService.java

@ -48,9 +48,6 @@ public class CondtionMgrService {
}
}
public Boolean isNoMoreTubeToBeProcessed() {
return !gstate.getTubeHolder().isHasTubeToBeProcessed();
}
public Boolean isCanDoAction() {
return gstate.mainFlowCtrlState.workState.equals(A8kWorkState.WORKING) && !gstate.mainFlowCtrlState.errorFlag && !gstate.mainFlowCtrlState.workStateChangeFlag;
@ -72,7 +69,7 @@ public class CondtionMgrService {
public Boolean isTimeToEnterNewTubeHolder() {
Boolean cond0 = isCanDoAction();
//试管架处于空闲状态
Boolean cond1 = gstate.getTubeHolder().state.equals(TubeHolderState.IDLE);
Boolean cond1 = gstate.getTubeHolder().getState().equals(TubeHolderState.IDLE);
//入料通道是否为空
Boolean cond2 = getTubeholderEnterPosPPS();
return cond0 && cond1 && cond2;
@ -151,7 +148,14 @@ public class CondtionMgrService {
Tube tube = gstate.getCurProcessingTube();
if (tube == null)
return false;
return gstate.getEmergencyTubePos().tube.getState().equals(TubeState.ERROR);
return gstate.getCurProcessingTube().getState().equals(TubeState.ERROR);
}
public Boolean isHasPostProcessedTube() {
Tube tube = gstate.getCurProcessingTube();
if (tube == null)
return false;
return gstate.getCurProcessingTube().getState().equals(TubeState.POST_PROCESSED);
}
}

8
src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java

@ -12,6 +12,7 @@ import a8k.service.app.appstate.ResourceMgrService;
import a8k.service.app.appstate.type.MainFlowCtrlState;
import a8k.service.app.appstate.type.state.A8kWorkState;
import a8k.type.exception.AppException;
import a8k.utils.ZStringUtils;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
@ -118,15 +119,18 @@ public class MainFlowCtrlScheduler {
A8kErrorContext callFn(A8kStepAction key) {
logger.info("----------------------{}---------------------->", ZStringUtils.leftAlignStr(key.step.name(), '-', 35));
logger.info("Relate {} ", key.logCxtState());
beforeDoWhat(key.step);
try {
logger.info("执行动作:{} ++++++++++++++++++++", key.step);
key.doaction();
logger.info("执行动作完成:{} +++++++", key.step);
return new A8kErrorContext(key.step, null);
} catch (AppException appe) {
return new A8kErrorContext(key.step, appe.error);
} finally {
logger.info("{}------<", ZStringUtils.leftAlignStr(key.step.name(), '-', 35));
}
}

3
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java

@ -27,7 +27,7 @@ public class DO_CLEAR_ERROR_BEFORE_WORK extends A8kStepAction {
}
@Resource
GStateService gstate;
GStateService gstate;
@Resource
CondtionMgrService cms;
@Resource
@ -65,4 +65,5 @@ public class DO_CLEAR_ERROR_BEFORE_WORK extends A8kStepAction {
A8kPublicResourceType.PlatesBoxModule
);
}
}

23
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_TUBE.java → src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_FINISH_TUBE_PROCESS.java

@ -26,11 +26,11 @@ import java.util.List;
* 处理错误的试管
*/
@Component
public class DO_PROCESS_ERROR_TUBE extends A8kStepAction {
static Logger logger = LoggerFactory.getLogger(DO_PROCESS_ERROR_TUBE.class);
public class DO_FINISH_TUBE_PROCESS extends A8kStepAction {
static Logger logger = LoggerFactory.getLogger(DO_FINISH_TUBE_PROCESS.class);
DO_PROCESS_ERROR_TUBE() {
super(A8kActionStepType.DO_PROCESS_ERROR_TUBE);
DO_FINISH_TUBE_PROCESS() {
super(A8kActionStepType.DO_FINISH_TUBE_PROCESS);
}
@Resource
@ -60,6 +60,10 @@ public class DO_PROCESS_ERROR_TUBE extends A8kStepAction {
Tube tube = gstate.getCurProcessingTube();
assert tube != null;
if(tube.getState().equals(TubeState.POST_PROCESSED)){
projectProcessContextMgrService.finishedTubeProcess();
return;
}
if (appDebugHelper.isDebug()) {
logger.info("处理错误试管:{}", tube.getSampleId());
@ -70,12 +74,12 @@ public class DO_PROCESS_ERROR_TUBE extends A8kStepAction {
//复位HBOT
OS.forceSleep(4000);
}
projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PROCESS_COMPLETE);
projectProcessContextMgrService.finishedTubeProcess();
}
@Override public Boolean checkCondition() {
Boolean cond1 = cms.isCanDoAction();
Boolean cond2 = cms.isHasSomeErrorTubeToBeProcessed();
Boolean cond2 = cms.isHasSomeErrorTubeToBeProcessed() || cms.isHasPostProcessedTube();
return cond1 && cond2;
}
@ -85,4 +89,11 @@ public class DO_PROCESS_ERROR_TUBE extends A8kStepAction {
A8kPublicResourceType.HBOT
);
}
@Override public String logCxtState() {
var tube = gstate.getCurProcessingTube();
if (tube == null)
return "";
return String.format("[sid: %s, tanpos: %s]", tube.getSampleId(), tube.getPos());
}
}

27
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_PROCESS_ERROR_PLATE.java

@ -7,6 +7,7 @@ import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction;
import a8k.service.app.appstate.GStateService;
import a8k.service.app.appstate.IncubationPlateStateMgrService;
import a8k.service.app.appstate.OptScanModuleStateMgrService;
import a8k.service.app.appstate.ProjectProcessContextMgrService;
import a8k.service.app.appstate.resource.A8kPublicResourceType;
import a8k.service.app.appstate.type.IncubationSubTank;
import a8k.service.app.appstate.type.MainFlowCtrlState;
@ -33,15 +34,17 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction {
}
@Resource
GStateService gstate;
GStateService gstate;
@Resource
CondtionMgrService cms;
CondtionMgrService cms;
@Resource
IncubationPlateStateMgrService incubationPlateStateMgrService;
IncubationPlateStateMgrService incubationPlateStateMgrService;
@Resource
OptScanModuleStateMgrService optScanModuleStateMgrService;
OptScanModuleStateMgrService optScanModuleStateMgrService;
@Resource
AppDebugHelperService appDebugHelperService;
AppDebugHelperService appDebugHelperService;
@Resource
ProjectProcessContextMgrService projectProcessContextMgrService;
MainFlowCtrlState mfcs;
@ -68,8 +71,8 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction {
OS.forceSleep(3000);
}
//
optScanModuleStateMgrService.newPlateToOptScanPos(errorTank);
optScanModuleStateMgrService.dropPlate();
projectProcessContextMgrService.newPlateToOptScanPos(errorTank);
projectProcessContextMgrService.dropPlate();
incubationPlateStateMgrService.resetIncubatorPos(errorTank.getPos());
}
}
@ -82,6 +85,14 @@ public class DO_PROCESS_ERROR_PLATE extends A8kStepAction {
}
@Override public List<A8kPublicResourceType> getResourceList() {
return List.of();
return List.of(A8kPublicResourceType.OPTModule, A8kPublicResourceType.IncubationPlateModule);
}
@Override public String logCxtState() {
var errorTank = incubationPlateStateMgrService.getErrorPlate();
if (errorTank == null) {
return "";
}
return String.format("[sid: %s, proj: %s tanpos: %s]", errorTank.getSampleId(), errorTank.getProjIndex(), errorTank.getPos());
}
}

1
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_RESUME.java

@ -47,4 +47,5 @@ public class DO_RESUME extends A8kStepAction {
@Override public List<A8kPublicResourceType> getResourceList() {
return List.of();
}
}

14
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java

@ -66,20 +66,17 @@ public class PLATE_OPT_SCAN extends A8kStepAction {
OptScanModule optScanModule = gstate.getOptScanModule();
ProjProcessContext ctx = projectProcessContextMgrService.getProjProcessContext(optScanModule.getSampleId(), optScanModule.getProjIndex());
optScanModuleStateMgrService.startScanPlate();
projectProcessContextMgrService.startScanPlate();
logger.info("扫描板夹");
//记录扫描结果
if (appDebugHelper.isDebug()) {
logger.info("VIRTUAL_DO.扫描板夹成功");
OS.forceSleep(3000);
} else {
}
//修改板夹状态
projectProcessContextMgrService.changeContextStateTo(optScanModule.getSampleId(), optScanModule.getProjIndex(), ProjProcessState.FINISH);
optScanModuleStateMgrService.dropPlate();
projectProcessContextMgrService.dropPlate();
projectProcessContextMgrService.finishProcessProj(optScanModule.getSampleId(), optScanModule.getProjIndex());
reactionRecordMgrService.addRecord(ctx,
new ReactionResult(ReactionResultStatus.SUCCESS, "12.8 mg/L"),
new ReactionResult(ReactionResultStatus.ERROR_RESULT_OUT_OF_RANGE, ""));
@ -96,4 +93,9 @@ public class PLATE_OPT_SCAN extends A8kStepAction {
A8kPublicResourceType.OPTModule
);
}
@Override public String logCxtState() {
OptScanModule optScanModule = gstate.getOptScanModule();
return String.format("[sid: %s, proj:%s ]", optScanModule.getSampleId(), optScanModule.getProjInfoStr());
}
}

33
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PROCESS_INCUBATE_COMPLETED_PLATE.java

@ -7,9 +7,12 @@ import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction;
import a8k.service.app.appstate.GStateService;
import a8k.service.app.appstate.IncubationPlateStateMgrService;
import a8k.service.app.appstate.OptScanModuleStateMgrService;
import a8k.service.app.appstate.ProjectProcessContextMgrService;
import a8k.service.app.appstate.resource.A8kPublicResourceType;
import a8k.service.app.appstate.type.IncubationPlate;
import a8k.service.app.appstate.type.IncubationSubTank;
import a8k.service.app.appstate.type.MainFlowCtrlState;
import a8k.service.app.appstate.type.ProjProcessContext;
import a8k.service.app.appstate.type.state.IncubationSubTankState;
import a8k.service.debug.AppDebugHelperService;
import a8k.type.exception.AppException;
@ -33,15 +36,17 @@ public class PROCESS_INCUBATE_COMPLETED_PLATE extends A8kStepAction {
}
@Resource
GStateService gstate;
GStateService gstate;
@Resource
CondtionMgrService cms;
CondtionMgrService cms;
@Resource
IncubationPlateStateMgrService incubationPlateStateMgrService;
IncubationPlateStateMgrService incubationPlateStateMgrService;
@Resource
OptScanModuleStateMgrService optScanModuleStateMgrService;
OptScanModuleStateMgrService optScanModuleStateMgrService;
@Resource
AppDebugHelperService appDebugHelper;
AppDebugHelperService appDebugHelper;
@Resource
ProjectProcessContextMgrService projectProcessContextMgrService;
MainFlowCtrlState mfcs;
@ -51,24 +56,27 @@ public class PROCESS_INCUBATE_COMPLETED_PLATE extends A8kStepAction {
mfcs = gstate.mainFlowCtrlState;
}
IncubationSubTank getToBeProcessedTank() {
return incubationPlateStateMgrService.getOneExpiredPlate();
}
@Override public void doaction() throws AppException {
IncubationSubTank tank = incubationPlateStateMgrService.getOneExpiredPlate();
IncubationSubTank tank = getToBeProcessedTank();
if (tank == null) {
return;
}
if (appDebugHelper.isDebug()) {
logger.info("VIRTUAL_DO.推出板夹到光学模组,{}", tank.getPos());
OS.forceSleep(3000);
}
optScanModuleStateMgrService.newPlateToOptScanPos(tank);
projectProcessContextMgrService.newPlateToOptScanPos(tank);
incubationPlateStateMgrService.resetIncubatorPos(tank.getPos());
}
@Override public Boolean checkCondition() {
Boolean cond1 = cms.isCanDoAction();
Boolean cond2 = incubationPlateStateMgrService.isHasExpiredPlate();
Boolean cond2 = getToBeProcessedTank() != null;
Boolean cond3 = optScanModuleStateMgrService.isEmpty();
return cond1 && cond2 && cond3;
}
@ -79,4 +87,11 @@ public class PROCESS_INCUBATE_COMPLETED_PLATE extends A8kStepAction {
A8kPublicResourceType.IncubationPlateModule
);
}
@Override public String logCxtState() {
IncubationSubTank tank = getToBeProcessedTank();
if (tank == null)
return "";
return String.format("[sid:%s, proj:%s tanpos:%s]", tank.getSampleId(), tank.getProjInfoStr(), tank.getPos());
}
}

5
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java

@ -5,7 +5,6 @@ import a8k.service.app.appstate.ProjectProcessContextMgrService;
import a8k.service.app.appstate.type.Tube;
import a8k.service.bases.AppEventBusService;
import a8k.service.bases.appevent.AppWarningNotifyEvent;
import a8k.hardware.A8kCanBusService;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService;
import a8k.service.app.appctrl.TubeSettingMgrService;
@ -187,7 +186,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction {
}
}
//设置试管架状态
tubeholder.state = TubeHolderState.PROCESSING;
tubeholder.setState(TubeHolderState.PROCESSING);
//删除之前的试管架配置
tubeSettingMgrService.removeTubeHolderSetting(setting);
return tubeholder;
@ -226,7 +225,7 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction {
}
logger.info("更新试管架状态");
projectProcessContextMgrService.addNewTubeHolder(tubeholder);
projectProcessContextMgrService.newTubeHolder(tubeholder);
}
@Override public Boolean checkCondition() {

3
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java

@ -72,7 +72,6 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction {
public void moveToNextTube(Integer tubeIndex) throws AppException {
if (appDebugHelperService.isDebug()) {
logger.info("VIRTUAL.DO,移动到下一个试管:{}", tubeIndex);
OS.forceSleep(1000);
} else {
sstc.moveTubeToPreProcessPos(tubeIndex);
@ -106,7 +105,7 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction {
logger.info("处理下一个试管:{}", nextProcessTube.getSampleId());
moveToNextTube(nextTubeIndex);
}
projectProcessContextMgrService.changeTubeStateToPending(nextProcessTube);
projectProcessContextMgrService.pendingTube(nextProcessTube);
}
@Override public Boolean checkCondition() {

19
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java

@ -57,10 +57,11 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction {
@Override public void doaction() throws AppException {
Tube tube = gstate.getCurProcessingTube();
projectProcessContextMgrService.startPrepareRecourseOK();
assert tube != null;
boolean applyConsumable = projectProcessContextMgrService.takeConsumable(tube);
boolean applyTips = applyConsumable && projectProcessContextMgrService.takeTip(tube);
boolean applyIncubatorPos = applyTips && projectProcessContextMgrService.takeIncubatorPos(tube);
boolean applyConsumable = projectProcessContextMgrService.takeResourceConsumable(tube);
boolean applyTips = applyConsumable && projectProcessContextMgrService.takeResourceTip(tube);
boolean applyIncubatorPos = applyTips && projectProcessContextMgrService.takeResourceIncubatorPos(tube);
if (!applyConsumable) {
for (Integer projIndex : tube.getProjIndex()) {
@ -82,12 +83,12 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction {
assert applyIncubatorPos;
logger.info("Tube:{} 申请资源成功", tube.getSampleId());
boolean assProjInfoSuc = projectProcessContextMgrService.checkAndAssignProjInfo(tube);
boolean assProjInfoSuc = projectProcessContextMgrService.prepareProjInfoData(tube);
assert assProjInfoSuc;
//创建项目处理上下文
projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.RESOURCE_IS_READY);
projectProcessContextMgrService.prepareRecourseOK();
logger.info("apply resource ok");
}
@ -98,4 +99,12 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction {
@Override public List<A8kPublicResourceType> getResourceList() {
return List.of(A8kPublicResourceType.CurTubeProcessToken);
}
@Override public String logCxtState() {
var tube = gstate.getCurProcessingTube();
if (tube == null) {
return "";
}
return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList());
}
}

14
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java

@ -161,6 +161,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction {
// 2.取tip头
// 3.摇匀脱帽
//
projectProcessContextMgrService.startTubePreProcessing();
Tube tube = gstate.getCurProcessingTube();
//准备反应板夹
@ -187,10 +188,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction {
throw ebuilder.buildMutiErrorAppException(errors);
}
projectProcessContextMgrService.changeContextStateTo(gstate.getCurProcessingTube(), ProjProcessState.PROCESS);
projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PRE_PROCESSED);
projectProcessContextMgrService.changeTubeAssociatedReactionPlateStateTo(gstate.getCurProcessingTube(), IncubationSubTankState.WAITING_FOR_DROP);
logger.info("pre process success");
projectProcessContextMgrService.tubePreProcessingOK();
}
@ -215,4 +213,12 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction {
OS.forceSleep(100);
}
}
@Override public String logCxtState() {
var tube = gstate.getCurProcessingTube();
if (tube == null) {
return "";
}
return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList());
}
}

63
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java

@ -9,6 +9,7 @@ import a8k.service.app.appctrl.mainflowctrl.base.A8kStepAction;
import a8k.service.app.appstate.*;
import a8k.service.app.appstate.resource.A8kPublicResourceType;
import a8k.service.app.appstate.type.MainFlowCtrlState;
import a8k.service.app.appstate.type.ProjProcessContext;
import a8k.service.app.appstate.type.Tube;
import a8k.service.app.appstate.type.state.TubeState;
import a8k.type.exception.AppException;
@ -23,9 +24,9 @@ import java.util.concurrent.*;
/**
*
* 核对物料资源是否足够
* TUBE
* TO_BE_PROCESSED --> PRE_PROCESSING
* 核对物料资源是否足够
* TUBE
* TO_BE_PROCESSED --> PRE_PROCESSING
*/
@Component
public class SEQ5_PROCESS extends A8kStepAction {
@ -36,17 +37,16 @@ public class SEQ5_PROCESS extends A8kStepAction {
}
@Resource
GStateService gstate;
GStateService gstate;
@Resource
AppExceptionBuilder ebuilder;
AppExceptionBuilder ebuilder;
@Resource
IncubationPlateStateMgrService incubationPlateStateMgrService;
IncubationPlateStateMgrService incubationPlateStateMgrService;
@Resource
CondtionMgrService cms;
CondtionMgrService cms;
@Resource
ProjectProcessContextMgrService projectProcessContextMgrService;
MainFlowCtrlState state;
@PostConstruct
@ -54,41 +54,54 @@ public class SEQ5_PROCESS extends A8kStepAction {
state = gstate.mainFlowCtrlState;
}
@Override public void doaction() throws AppException {
@Override
public void doaction() throws AppException {
//
// 1.准备3份反应板夹
// 2.取tip头
// 3.摇匀脱帽
// 1.准备3份反应板夹
// 2.取tip头
// 3.摇匀脱帽
//
projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PROCESSING);
Tube tube = gstate.getCurProcessingTube();
logger.info("处理试管 {}", tube.getSampleId());
var tube = gstate.getCurProcessingTube();
projectProcessContextMgrService.startProcessTube();
OS.forceSleep(3000);
projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.PROCESSED);
projectProcessContextMgrService.changeTubeAssociatedReactionPlateStateToINCUBATING(gstate.getCurProcessingTube());
projectProcessContextMgrService.changeContextStateTo(gstate.getCurProcessingTube(), ProjProcessState.INCUBATING);
}
List<Integer> projList = tube.getProjIndex();
for (Integer projIndex : projList) {
ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(),
projIndex);
projectProcessContextMgrService.startIncubating(cxt);
}
projectProcessContextMgrService.processIngTubeOK();
}
@Override public Boolean checkCondition() {
@Override
public Boolean checkCondition() {
return cms.isTimeToProcessTube();
}
@Override public List<A8kPublicResourceType> getResourceList() {
@Override
public List<A8kPublicResourceType> getResourceList() {
return List.of(
A8kPublicResourceType.IncubationPlateModule,
A8kPublicResourceType.HBOT,
A8kPublicResourceType.CurTubeProcessToken
);
A8kPublicResourceType.CurTubeProcessToken);
}
//
// UTILS
// UTILS
//
void wait(Future<?> future) {
while (!future.isDone()) {
OS.forceSleep(100);
}
}
@Override
public String logCxtState() {
var tube = gstate.getCurProcessingTube();
if (tube == null) {
return "";
}
return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList());
}
}

13
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java

@ -60,10 +60,9 @@ public class SEQ6_POST_PROCESS extends A8kStepAction {
}
@Override public void doaction() throws AppException {
projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.POST_PROCESSING);
Tube tube = gstate.getCurProcessingTube();
projectProcessContextMgrService.postProcessTube();
OS.forceSleep(3000);
projectProcessContextMgrService.changeCurrentTubeStateTo(TubeState.POST_PROCESSED);
projectProcessContextMgrService.postProcessTubeOK();
}
@Override public Boolean checkCondition() {
@ -88,4 +87,12 @@ public class SEQ6_POST_PROCESS extends A8kStepAction {
OS.forceSleep(100);
}
}
@Override public String logCxtState() {
var tube = gstate.getCurProcessingTube();
if (tube == null) {
return "";
}
return String.format("[sid: %s, proj: %s]", tube.getSampleId(), tube.getProjIndexStrList());
}
}

10
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java

@ -49,18 +49,18 @@ public class SEQ7_EJECT_TUBEHOLDER extends A8kStepAction {
SST_HControler.ejectTubeHolder();
SST_HControler.moveTubeRackMoveToEnterPos();
} else {
logger.info("VIRTUAL.DO:弹出试管架");
}
gstate.getTubeHolder().state = TubeHolderState.IDLE;
gstate.getTubeHolder().setState(TubeHolderState.IDLE);
}
@Override public Boolean checkCondition() {
//处于工作状态试管架已经处于空闲状态入料光电被触发
Boolean cond1 = cms.isCanDoAction();
Boolean cond2 = gstate.getTubeHolder().state.equals(TubeHolderState.PROCESSING);
Boolean cond3 = cms.isNoMoreTubeToBeProcessed();
return cond1 && cond2 && cond3;
Boolean cond2 = gstate.getTubeHolder().getState().equals(TubeHolderState.PROCESSING);
Boolean cond3 = cms.isCurTubeProcessCompleted();
Boolean cond4 = !cms.isHasSometubesToBeProcessed();
return cond1 && cond2 && cond3 && cond4;
}
@Override public List<A8kPublicResourceType> getResourceList() {

2
src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kActionStepType.java

@ -23,6 +23,6 @@ public enum A8kActionStepType {
//Error
DO_CLEAR_ERROR_BEFORE_WORK,//在启动前清除错误
DO_PROCESS_ERROR_TUBE,//处理异常的样本
DO_FINISH_TUBE_PROCESS,//处理异常的样本
DO_PROCESS_ERROR_PLATE,//处理异常的孵育盘
}

4
src/main/java/a8k/service/app/appctrl/mainflowctrl/base/A8kStepAction.java

@ -37,4 +37,8 @@ public class A8kStepAction {
return true;
}
public String logCxtState() {
return "";
}
}

2
src/main/java/a8k/service/app/appstate/EmergencySamplePosStateMgrService.java

@ -79,7 +79,7 @@ public class EmergencySamplePosStateMgrService {
tube.setProjInfo(projInfo);
tube.setState(TubeState.TO_BE_PROCESSED);
projectProcessContextMgrService.addNewEmergencyTubeHolder(tube);
projectProcessContextMgrService.newEmergencyTube(tube);
logger.info("添加紧急样本设置成功 {}", ZJsonHelper.objectToJson(tube));
} else if (tube.getState().equals(TubeState.TO_BE_PROCESSED)) {
projectProcessContextMgrService.updateEmergencyTubeCfg(userid, sampleBarcode, bloodType, projInfo);

8
src/main/java/a8k/service/app/appstate/GStateService.java

@ -60,8 +60,8 @@ public class GStateService {
return consumableState;
}
public synchronized void setTubeHolder(TubeHolder state) {
this.tubeHolder = state;
public synchronized void setTubeHolder(TubeHolder tubeHolder) {
this.tubeHolder = tubeHolder;
}
public synchronized TubeHolder getTubeHolder() {
@ -72,8 +72,4 @@ public class GStateService {
return mainFlowCtrlState.workState.equals(A8kWorkState.WORKING);
}
public TubeHolderState getTubeHolderState() {
return tubeHolder.state;
}
}

15
src/main/java/a8k/service/app/appstate/OptScanModuleStateMgrService.java

@ -13,21 +13,6 @@ public class OptScanModuleStateMgrService {
@Resource
GStateService gstate;
synchronized public void newPlateToOptScanPos(IncubationSubTank tank) {
OptScanModule optScanModule = gstate.getOptScanModule();
optScanModule.state = OptScanModuleState.PLATE_IS_READY;
optScanModule.syncCfg(tank);
}
synchronized public void dropPlate() {
OptScanModule optScanModule = gstate.getOptScanModule();
optScanModule.state = OptScanModuleState.EMPTY;
}
synchronized public void startScanPlate() {
OptScanModule optScanModule = gstate.getOptScanModule();
optScanModule.state = OptScanModuleState.SCANNING;
}
synchronized public Boolean isEmpty() {
OptScanModule optScanModule = gstate.getOptScanModule();

261
src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java

@ -1,14 +1,15 @@
package a8k.service.app.appstate;
import a8k.service.app.appdata.AppProjInfoMgrService;
import a8k.service.app.appstate.type.ProjProcessContext;
import a8k.service.app.appstate.type.Tube;
import a8k.service.app.appstate.type.TubeHolder;
import a8k.service.app.appstate.type.*;
import a8k.service.app.appstate.type.state.IncubationSubTankState;
import a8k.service.app.appstate.type.state.OptScanModuleState;
import a8k.service.app.appstate.type.state.ProjProcessState;
import a8k.service.app.appstate.type.state.TubeState;
import a8k.service.db.DeviceStatisticDBService;
import a8k.service.db.SampleRecordDBService;
import a8k.service.db.type.SampleRecord;
import a8k.service.db.type.StatisticType;
import a8k.service.db.type.a8kidcard.zenum.A8kReactionFlowType;
import a8k.type.ecode.AppError;
import a8k.type.type.BloodType;
@ -36,44 +37,56 @@ public class ProjectProcessContextMgrService {
IncubationPlateStateMgrService incubationPlateStateMgrService;
@Resource
AppProjInfoMgrService appProjInfoMgrService;
@Resource
DeviceStatisticDBService deviceStatisticDBService;
List<ProjProcessContext> contexts = new ArrayList<>();
private String generateSampleId(Integer tubePos, Boolean isEmergency) {
private String priGenerateSampleId(Integer tubePos, Boolean isEmergency) {
String sampleid = "";
Integer cnt = sampleRecordDBService.getRecordCntToday();
Integer cnt = 0;
Date date = new Date();
if (isEmergency) {
cnt = deviceStatisticDBService.get(StatisticType.EmergencyTubeCnt);
} else {
cnt = deviceStatisticDBService.get(StatisticType.TubeHolderCnt);
}
SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
if (isEmergency) {
sampleid = String.format("%s_%sE", sdf.format(date), cnt);
} else {
sampleid = String.format("%s_%s", sdf.format(date), cnt);
sampleid = String.format("%s_%d%02d", sdf.format(date), cnt, tubePos + 1);
}
return sampleid;
}
public void newSample(Tube tube) {
SampleRecord sampleRecord = new SampleRecord();
sampleRecord.sampleid = generateSampleId(tube.getPos(), tube.getIsEmergency());
sampleRecord.createDate = new Date();
sampleRecord.bloodType = tube.getBloodType();
sampleRecord.isEmergency = tube.getIsEmergency();
sampleRecord.sampleBarcode = tube.getSampleBarcode();
sampleRecord.userid = tube.getUserid();
sampleRecord.projIndex = tube.getProjIndex();
tube.setSampleId(sampleRecord.sampleid);
sampleRecordDBService.add(sampleRecord);
void priChangeReactionPlateStateTo(Tube tube, IncubationSubTankState state) {
var incubationState = gstate.getIncubationPlate();
var subtanks = incubationState.subtanks;
List<ProjProcessContext> cxts = getTubeAssociatedProjContext(tube.getSampleId());
for (ProjProcessContext cxt : cxts) {
subtanks[cxt.incubatorPos.off].state = state;
}
}
void finishProcessProj(Tube tube, ProjProcessState state) {
List<ProjProcessContext> cxts = getTubeAssociatedProjContext(tube.getSampleId());
for (ProjProcessContext cxt : cxts) {
cxt.state = state;
}
}
private void newProjProcessContext(Tube tube) {
private void priNewProjProcessContext(Tube tube) {
List<ProjBriefInfo> projInfos = tube.getProjInfo();
for (ProjBriefInfo projInfo : projInfos) {
ProjProcessContext projProcessContext = new ProjProcessContext();
projProcessContext.sampleId = tube.getSampleId();
projProcessContext.state = ProjProcessState.INIT;
projProcessContext.projIndex = projInfo.projIndex;
projProcessContext.isHighTube = tube.getIsHighTube();
projProcessContext.isEmergency = tube.getIsEmergency();
@ -89,7 +102,22 @@ public class ProjectProcessContextMgrService {
}
}
private void removeProjProcessContext(String sampleId) {
public void priNewSample(Tube tube) {
SampleRecord sampleRecord = new SampleRecord();
sampleRecord.sampleid = priGenerateSampleId(tube.getPos(), tube.getIsEmergency());
sampleRecord.createDate = new Date();
sampleRecord.bloodType = tube.getBloodType();
sampleRecord.isEmergency = tube.getIsEmergency();
sampleRecord.sampleBarcode = tube.getSampleBarcode();
sampleRecord.userid = tube.getUserid();
sampleRecord.projIndex = tube.getProjIndex();
tube.setSampleId(sampleRecord.sampleid);
sampleRecordDBService.add(sampleRecord);
}
private void priRemoveProjProcessContext(String sampleId) {
for (ProjProcessContext context : contexts) {
if (context.sampleId.equals(sampleId)) {
contexts.remove(context);
@ -144,17 +172,25 @@ public class ProjectProcessContextMgrService {
* 添加新的试管架
* @param tubeholder 试管架
*/
synchronized public void addNewTubeHolder(TubeHolder tubeholder) {
synchronized public void newTubeHolder(TubeHolder tubeholder) {
deviceStatisticDBService.add(StatisticType.TubeHolderCnt, 1);
logger.info("添加新的试管架");
for (Tube tube : tubeholder.tubes) {
newSample(tube);
newProjProcessContext(tube);
if (tube.getState().equals(TubeState.EMPTY)) {
continue;
}
priNewSample(tube);
priNewProjProcessContext(tube);
logger.info(" 试管ID:{}", tube.getSampleId());
}
gstate.setTubeHolder(tubeholder);
}
synchronized public void addNewEmergencyTubeHolder(Tube tube) {
newSample(tube);
newProjProcessContext(tube);
synchronized public void newEmergencyTube(Tube tube) {
deviceStatisticDBService.add(StatisticType.EmergencyTubeCnt, 1);
priNewSample(tube);
priNewProjProcessContext(tube);
logger.info("添加新的急诊试管,试管ID:{}", tube.getSampleId());
}
synchronized public void updateEmergencyTubeCfg(String userid, String sampleBarcode, BloodType bloodType, List<ProjBriefInfo> projInfo) {
@ -165,8 +201,9 @@ public class ProjectProcessContextMgrService {
tube.setSampleBarcode(sampleBarcode);
tube.setProjInfo(projInfo);
removeProjProcessContext(tube.getSampleId());
newProjProcessContext(tube);
priRemoveProjProcessContext(tube.getSampleId());
priNewProjProcessContext(tube);
logger.info("更新急诊试管配置,试管ID:{}", tube.getSampleId());
}
@ -174,7 +211,23 @@ public class ProjectProcessContextMgrService {
// List<IncubatorPos> incubatorPoss = incubationPlateStateMgrService.takeIncubationIDLEPos(projs.size());
// List<TipPos> tips = consumablesMgrService.takeTip(projInfos.get(i).reactionFlowType);
synchronized public Boolean takeConsumable(Tube tube) {
synchronized public void pendingTube(Tube tube) {
/**
* 挂起试管
* @param nextProcessTube 下一个处理的试管
*/
gstate.curProcessingTube = tube;
gstate.getCurProcessingTube().setState(TubeState.PENDING);
finishProcessProj(tube, ProjProcessState.PENDING);
}
synchronized public void startPrepareRecourseOK() {
}
synchronized public Boolean takeResourceConsumable(Tube tube) {
for (Integer projIndex : tube.getProjIndex()) {
ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex);
assert cxt != null;
@ -186,7 +239,7 @@ public class ProjectProcessContextMgrService {
return true;
}
synchronized public Boolean takeIncubatorPos(Tube tube) {
synchronized public Boolean takeResourceIncubatorPos(Tube tube) {
var incubationState = gstate.getIncubationPlate();
var subtanks = incubationState.subtanks;
for (Integer projIndex : tube.getProjIndex()) {
@ -202,7 +255,7 @@ public class ProjectProcessContextMgrService {
return true;
}
synchronized public Boolean takeTip(Tube tube) {
synchronized public Boolean takeResourceTip(Tube tube) {
for (Integer projIndex : tube.getProjIndex()) {
ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex);
assert cxt != null;
@ -215,19 +268,6 @@ public class ProjectProcessContextMgrService {
return true;
}
synchronized public Boolean checkAndAssignProjInfo(Tube tube) {
for (Integer projIndex : tube.getProjIndex()) {
ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex);
assert cxt != null;
cxt.projCfg = appProjInfoMgrService.getProjCfgByProjIndex(cxt.consumable.lotId);
if (cxt.projCfg == null) {
return false;
}
}
return true;
}
synchronized public void bakAllTubeAResource(Tube tube) {
for (Integer projIndex : tube.getProjIndex()) {
ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex);
@ -247,28 +287,89 @@ public class ProjectProcessContextMgrService {
}
}
synchronized public void changeCurrentTubeStateTo(TubeState state) {
gstate.getCurProcessingTube().setState(state);
synchronized public Boolean prepareProjInfoData(Tube tube) {
for (Integer projIndex : tube.getProjIndex()) {
ProjProcessContext cxt = getProjProcessContext(tube.getSampleId(), projIndex);
assert cxt != null;
cxt.projCfg = appProjInfoMgrService.getProjCfgByProjIndex(cxt.consumable.lotId);
if (cxt.projCfg == null) {
return false;
}
}
return true;
}
synchronized public void changeTubeStateToPending(Tube tube) {
/**
* 挂起试管
* @param nextProcessTube 下一个处理的试管
*/
gstate.curProcessingTube = tube;
changeCurrentTubeStateTo(TubeState.PENDING);
changeContextStateTo(tube, ProjProcessState.PENDING);
synchronized public void prepareRecourseOK() {
Tube tube = gstate.getCurProcessingTube();
tube.setState(TubeState.RESOURCE_IS_READY);
finishProcessProj(tube, ProjProcessState.PROCESS);
}
synchronized public void startTubePreProcessing() {
Tube tube = gstate.getCurProcessingTube();
tube.setState(TubeState.PRE_PROCESSING);
}
synchronized public void changeTubeAssociatedReactionPlateStateTo(Tube tube, IncubationSubTankState state) {
var incubationState = gstate.getIncubationPlate();
var subtanks = incubationState.subtanks;
List<ProjProcessContext> cxts = getTubeAssociatedProjContext(tube.getSampleId());
for (ProjProcessContext cxt : cxts) {
subtanks[cxt.incubatorPos.off].state = state;
}
synchronized public void tubePreProcessingOK() {
Tube tube = gstate.getCurProcessingTube();
tube.setState(TubeState.PRE_PROCESSED);
priChangeReactionPlateStateTo(tube, IncubationSubTankState.WAITING_FOR_DROP);
}
synchronized public void startProcessTube() {
Tube tube = gstate.getCurProcessingTube();
tube.setState(TubeState.PROCESSING);
}
synchronized public void startIncubating(ProjProcessContext cxt) {
var subtanks = gstate.getIncubationPlate().subtanks;
cxt.state = ProjProcessState.INCUBATING;
subtanks[cxt.incubatorPos.off].state = IncubationSubTankState.INCUBATING;
subtanks[cxt.incubatorPos.off].startIncubatedTime = System.currentTimeMillis();
subtanks[cxt.incubatorPos.off].incubatedTimeSec = cxt.projCfg.getReactionPlateIncubationTimeMin() * 60;
logger.info("{} 开始孵育,开始时间:{},孵育时间:{}s", subtanks[cxt.incubatorPos.off].getPos(), subtanks[cxt.incubatorPos.off].startIncubatedTime,
subtanks[cxt.incubatorPos.off].incubatedTimeSec);
}
synchronized public void processIngTubeOK() {
Tube tube = gstate.getCurProcessingTube();
tube.setState(TubeState.PROCESSED);
}
synchronized public void postProcessTube() {
Tube tube = gstate.getCurProcessingTube();
tube.setState(TubeState.POST_PROCESSING);
}
synchronized public void postProcessTubeOK() {
Tube tube = gstate.getCurProcessingTube();
tube.setState(TubeState.POST_PROCESSED);
}
synchronized public void newPlateToOptScanPos(IncubationSubTank tank) {
OptScanModule optScanModule = gstate.getOptScanModule();
optScanModule.state = OptScanModuleState.PLATE_IS_READY;
optScanModule.syncCfg(tank);
}
synchronized public void dropPlate() {
OptScanModule optScanModule = gstate.getOptScanModule();
optScanModule.state = OptScanModuleState.EMPTY;
}
synchronized public void startScanPlate() {
OptScanModule optScanModule = gstate.getOptScanModule();
optScanModule.state = OptScanModuleState.SCANNING;
}
synchronized public void finishProcessProj(String sampleId, Integer projIndex) {
ProjProcessContext cxt = getProjProcessContext(sampleId, projIndex);
assert cxt != null;
cxt.state = ProjProcessState.FINISH;
}
@ -277,42 +378,24 @@ public class ProjectProcessContextMgrService {
var subtanks = incubationState.subtanks;
List<ProjProcessContext> cxts = getTubeAssociatedProjContext(tube.getSampleId());
//设置
changeCurrentTubeStateTo(TubeState.ERROR);
//设置试管状态为Error
gstate.getCurProcessingTube().setState(TubeState.ERROR);
tube.setErrors(errors);
for (ProjProcessContext cxt : cxts) {
cxt.state = ProjProcessState.ERROR;
cxt.errors = errors;
//设置cxt状态为ERROR
cxt.state = ProjProcessState.ERROR;
cxt.errors = errors;
//设置孵育子槽状态为ERROR
subtanks[cxt.incubatorPos.off].state = IncubationSubTankState.ERROR;
subtanks[cxt.incubatorPos.off].errors = errors;
}
}
synchronized public void changeTubeAssociatedReactionPlateStateToINCUBATING(Tube tube) {
var incubationState = gstate.getIncubationPlate();
var subtanks = incubationState.subtanks;
List<ProjProcessContext> cxts = getTubeAssociatedProjContext(tube.getSampleId());
for (ProjProcessContext cxt : cxts) {
cxt.state = ProjProcessState.INCUBATING;
subtanks[cxt.incubatorPos.off].state = IncubationSubTankState.INCUBATING;
subtanks[cxt.incubatorPos.off].startIncubatedTime = System.currentTimeMillis();
subtanks[cxt.incubatorPos.off].incubatedTimeSec = cxt.projCfg.getReactionPlateIncubationTimeMin() * 60;
logger.info("{} 开始孵育,开始时间:{},孵育时间:{}s", subtanks[cxt.incubatorPos.off].getPos(), subtanks[cxt.incubatorPos.off].startIncubatedTime,
subtanks[cxt.incubatorPos.off].incubatedTimeSec);
}
synchronized public void finishedTubeProcess() {
Tube tube = gstate.getCurProcessingTube();
tube.setState(TubeState.PROCESS_COMPLETE);
}
synchronized public void changeContextStateTo(Tube tube, ProjProcessState state) {
List<ProjProcessContext> cxts = getTubeAssociatedProjContext(tube.getSampleId());
for (ProjProcessContext cxt : cxts) {
cxt.state = state;
}
}
synchronized public void changeContextStateTo(String sampleId, Integer projIndex, ProjProcessState state) {
ProjProcessContext cxt = getProjProcessContext(sampleId, projIndex);
assert cxt != null;
cxt.state = state;
}
}

7
src/main/java/a8k/service/app/appstate/type/IncubationSubTank.java

@ -63,5 +63,12 @@ public class IncubationSubTank {
errors.clear();
}
public String getProjInfoStr() {
if (projInfo == null) {
return "null";
}
return String.format("%s(%d)", projInfo.projShotName, projInfo.projIndex);
}
}

7
src/main/java/a8k/service/app/appstate/type/OptScanModule.java

@ -29,6 +29,11 @@ public class OptScanModule {
this.isErrorPlate = tank.state.equals(IncubationSubTankState.ERROR);
}
public String getProjInfoStr() {
if (projInfo == null) {
return "null";
}
return String.format("%s(%d)", projInfo.projShotName, projInfo.projIndex);
}
}

15
src/main/java/a8k/service/app/appstate/type/Tube.java

@ -32,10 +32,17 @@ public class Tube {
return ProjBriefInfo.toPorjIndex(projInfo);
}
public List<String> getProjIndexStrList(){
List<String> projIndexStrList = new ArrayList<>();
for (ProjBriefInfo info : projInfo) {
projIndexStrList.add(info.projShotName);
}
return projIndexStrList;
}
Tube(Integer pos) {
// ProjBriefInfo info = new ProjBriefInfo(1,"hscrp","CA","#FF0000");
// projInfo.add(info);
// projInfo.add(info);
// projInfo.add(info);
this.pos = pos;
}
}

6
src/main/java/a8k/service/app/appstate/type/TubeHolder.java

@ -3,11 +3,15 @@ package a8k.service.app.appstate.type;
import a8k.service.app.appstate.type.state.TubeHolderState;
import a8k.service.app.appstate.type.state.TubeState;
import a8k.type.type.A8kTubeHolderType;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@Data
public class TubeHolder {
public A8kTubeHolderType tubeHolderType = A8kTubeHolderType.BloodTube; //试管架类型
public Tube[] tubes = new Tube[10];
public TubeHolderState state = TubeHolderState.IDLE; //处理状态
TubeHolderState state = TubeHolderState.IDLE; //处理状态
public TubeHolder() {
for (int i = 0; i < tubes.length; i++) {

1
src/main/java/a8k/service/app/appstate/type/state/ProjProcessState.java

@ -3,7 +3,6 @@ package a8k.service.app.appstate.type.state;
public enum ProjProcessState {
INIT,
PENDING,
PREPARE_RESOUCE,
PROCESS,
INCUBATING,
OPTSCAN,

88
src/main/java/a8k/service/db/DeviceStatisticDBService.java

@ -0,0 +1,88 @@
package a8k.service.db;
import a8k.service.app.appdata.UtilsProjectColorAllocer;
import a8k.service.db.type.DeviceStatistic;
import a8k.service.db.type.StatisticType;
import a8k.service.debug.AppDebugHelperService;
import a8k.utils.DateUtil;
import a8k.utils.ZDateUtils;
import a8k.utils.ZSqliteJdbcHelper;
import jakarta.annotation.Nullable;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Component
public class DeviceStatisticDBService {
private static final Logger logger = LoggerFactory.getLogger(DeviceStatisticDBService.class);
private static final String tableName = "zapp_a8k_statistic";
private static Class<?> tClass = DeviceStatistic.class;
@Resource
JdbcTemplate jdbcTemplate;
@PostConstruct
void init() {
if (!ZSqliteJdbcHelper.isTableExist(jdbcTemplate, tableName)) {
ZSqliteJdbcHelper.createTable(jdbcTemplate, tableName, tClass);
}
}
@SneakyThrows private DeviceStatistic rowMapper(ResultSet rs, int rowNum) {
return (DeviceStatistic) ZSqliteJdbcHelper.rowMapper(rs, tClass);
}
public <T> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args) {
try {
return jdbcTemplate.queryForObject(sql, rowMapper, args);
} catch (Exception e) {
logger.error("queryForObject error: {}", e.getMessage());
return null;
}
}
public void add(StatisticType statisticType, Integer cnt) {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String today = sdf.format(now);
List<DeviceStatistic> statisticList = jdbcTemplate.query("select * from " + tableName + " where statisticDate = ? and statisticType = ?", this::rowMapper, today, statisticType);
if (statisticList.isEmpty()) {
DeviceStatistic statistic = new DeviceStatistic();
statistic.statisticDate = today;
statistic.statisticType = statisticType;
statistic.cnt = cnt;
ZSqliteJdbcHelper.addObj(jdbcTemplate, tableName, tClass, statistic);
} else {
DeviceStatistic statistic = statisticList.get(0);
statistic.cnt += cnt;
ZSqliteJdbcHelper.updateObj(jdbcTemplate, tableName, tClass, statistic);
}
}
public Integer get(StatisticType type) {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String today = sdf.format(now);
List<DeviceStatistic> statisticList = jdbcTemplate.query("select * from " + tableName + " where statisticDate = ? and statisticType = ?", this::rowMapper, today, type);
if (statisticList.isEmpty()) {
return 0;
} else {
return statisticList.get(0).cnt;
}
}
}

10
src/main/java/a8k/service/db/type/DeviceStatistic.java

@ -0,0 +1,10 @@
package a8k.service.db.type;
import java.util.Date;
public class DeviceStatistic {
public int id;
public String statisticDate;
public StatisticType statisticType;
public Integer cnt;
}

6
src/main/java/a8k/service/db/type/StatisticType.java

@ -0,0 +1,6 @@
package a8k.service.db.type;
public enum StatisticType {
TubeHolderCnt,
EmergencyTubeCnt,
}

10
src/main/java/a8k/utils/ZSqliteJdbcHelper.java

@ -38,7 +38,13 @@ public class ZSqliteJdbcHelper {
static public void createTable(JdbcTemplate jdbcTemplate, String tableName, Class<?> tClass) {
StringBuilder sql = new StringBuilder("create table " + tableName + " (");
Boolean hasId = false;
for (java.lang.reflect.Field field : tClass.getDeclaredFields()) {
if (field.getName().equals("id")) {
hasId = true;
}
sql.append(" '").append(field.getName()).append("' ");
if (field.getType().equals(Integer.class) || field.getType().equals(int.class)) {
sql.append("integer,");
@ -56,6 +62,10 @@ public class ZSqliteJdbcHelper {
sql.append("text,");
}
}
if(!hasId) {
throw new RuntimeException("id field not found in class " + tClass.getName());
}
sql.append(" PRIMARY KEY ('id' DESC));");
jdbcTemplate.execute(sql.toString());
}

46
src/main/java/a8k/utils/ZStringUtils.java

@ -0,0 +1,46 @@
package a8k.utils;
public class ZStringUtils {
static public String centerStr(String str, Character c, int len) {
if (str == null || str.length() >= len) {
return str;
}
int left = (len - str.length()) / 2;
int right = len - str.length() - left;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < left; i++) {
sb.append(c);
}
sb.append(str);
for (int i = 0; i < right; i++) {
sb.append(c);
}
return sb.toString();
}
static public String rightAlignStr(String str, Character c, int len) {
if (str == null || str.length() >= len) {
return str;
}
int right = len - str.length();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < right; i++) {
sb.append(c);
}
sb.append(str);
return sb.toString();
}
static public String leftAlignStr(String str, Character c, int len) {
if (str == null || str.length() >= len) {
return str;
}
int left = len - str.length();
StringBuilder sb = new StringBuilder();
sb.append(str);
for (int i = 0; i < left; i++) {
sb.append(c);
}
return sb.toString();
}
}
Loading…
Cancel
Save