Browse Source

update

master
zhaohe 2 months ago
parent
commit
4ad7e0c1f4
  1. BIN
      out/A8000_VIRTUAL_BAK_END/a8000-1.jar
  2. 16513
      out/linecounter.json
  3. 2619
      out/linecounter.txt
  4. 25
      src/main/java/a8k/app/controler/api/v1/app/ws/AppWebSocketEndpointMgr.java
  5. 8
      src/main/java/a8k/app/optalgo/A8kOptCurveAnalyzer.java
  6. 35
      src/main/java/a8k/app/service/module/InFeedingCtrlModule.java
  7. 33
      src/main/java/a8k/app/service/statemgr/AppWarningFlagStateMgr.java
  8. 12
      src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java
  9. 7
      src/main/java/a8k/app/service/statemgr/DeviceWorkStateMgrService.java
  10. 10
      src/main/java/a8k/app/service/statemgr/GStateMgrService.java
  11. 34
      src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java
  12. 2
      src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java
  13. 198
      src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java
  14. 36
      src/main/java/a8k/app/service/statemgr/TubeStateMgr.java
  15. 42
      src/main/java/a8k/app/type/PreReactionGrid.java
  16. 15
      src/main/java/a8k/app/type/PreReactionGridGroup.java
  17. 8
      src/main/java/a8k/app/type/a8k/state/IncubationSubTank.java
  18. 2
      src/main/java/a8k/app/type/a8k/state/OptScanModuleState.java
  19. 20
      src/main/java/a8k/extui/page/debug/PreReactionPosStateMgrDebugPage.java
  20. 14
      src/main/java/a8k/extui/page/extapp/debug_assistant/VirtualEventGeneratorPage.java

BIN
out/A8000_VIRTUAL_BAK_END/a8000-1.jar

16513
out/linecounter.json
File diff suppressed because it is too large
View File

2619
out/linecounter.txt
File diff suppressed because it is too large
View File

25
src/main/java/a8k/app/controler/api/v1/app/ws/AppWebSocketEndpointMgr.java

@ -10,6 +10,7 @@ import a8k.app.service.mainctrl.AppDeviceInitCtrlService;
import a8k.app.service.mainctrl.TubeHolderSettingMgrService;
import a8k.app.service.statemgr.*;
import a8k.app.service.background.FrontEndMessageBoxAndEventMgr;
import a8k.app.type.a8k.ConsumableGroup;
import a8k.app.utils.ZJsonHelper;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
@ -126,10 +127,14 @@ public class AppWebSocketEndpointMgr {
}
synchronized public void reportState(String type, Integer version, AppGetStateFn getStateFn) {
Integer lastVersion = stateVersionCache.get(type);
reportState(type, type, version, getStateFn);
}
synchronized public void reportState(String typeKey, String reportName, Integer version, AppGetStateFn getStateFn) {
Integer lastVersion = stateVersionCache.get(typeKey);
if (lastVersion == null || !lastVersion.equals(version)) {
stateVersionCache.put(type, version);
reportState(type, getStateFn.getState());
stateVersionCache.put(typeKey, version);
reportState(reportName, getStateFn.getState());
}
}
@ -162,7 +167,6 @@ public class AppWebSocketEndpointMgr {
reportState("ConsumablesState", consumablesMgrService.getState());
reportState("GDeviceState", gstate.getGState());
reportState("EngineerModeState", engineerModeStateMgrService.getState());
reportState("PreReactionPosState", preReactionStateMgr.getPreReactionPosState());
}
@Scheduled(fixedDelay = 30)
@ -175,6 +179,19 @@ public class AppWebSocketEndpointMgr {
consumablesMgrService::getState);
reportState("MessageBoxState", frontEndMessageBoxAndEventMgr.getMessageBoxStateVersion(),
frontEndMessageBoxAndEventMgr::getMessageBoxState);
reportState("PreReactionPosGroupState-CG1", "PreReactionPosGroupState", preReactionStateMgr.getPreReactionGridGroupVersion(ConsumableGroup.CG1),
() -> preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG1));
reportState("PreReactionPosGroupState-CG2", "PreReactionPosGroupState", preReactionStateMgr.getPreReactionGridGroupVersion(ConsumableGroup.CG2),
() -> preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG2));
reportState("PreReactionPosGroupState-CG3", "PreReactionPosGroupState", preReactionStateMgr.getPreReactionGridGroupVersion(ConsumableGroup.CG3),
() -> preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG3));
reportState("PreReactionPosGroupState-CG4", "PreReactionPosGroupState", preReactionStateMgr.getPreReactionGridGroupVersion(ConsumableGroup.CG4),
() -> preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG4));
reportState("PreReactionPosGroupState-CG5", "PreReactionPosGroupState", preReactionStateMgr.getPreReactionGridGroupVersion(ConsumableGroup.CG5),
() -> preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG5));
reportState("PreReactionPosGroupState-CG6", "PreReactionPosGroupState", preReactionStateMgr.getPreReactionGridGroupVersion(ConsumableGroup.CG6),
() -> preReactionStateMgr.getPreReactionGridGroupState(ConsumableGroup.CG6));
}

8
src/main/java/a8k/app/optalgo/A8kOptCurveAnalyzer.java

@ -10,6 +10,7 @@ import a8k.app.type.a8k.container.A8kOptPeakContainer;
import a8k.app.type.a8k.opt.A8kOptPeak;
import a8k.app.type.a8k.opt.PeakName;
import a8k.app.type.a8k.opt.PeakQuotient;
import a8k.app.utils.ZJsonHelper;
import lombok.extern.slf4j.Slf4j;
@ -78,6 +79,13 @@ public class A8kOptCurveAnalyzer {
}
}
public static void main(String[] args) {
A8kOptPeakContainer peaks = new A8kOptPeakContainer();
assignPeakName(1, 2, peaks);
log.info("{}",
ZJsonHelper.objToPrettyJson(peaks));
}
private A8kOptPeakInfo analysCurve(double[] data) {

35
src/main/java/a8k/app/service/module/InFeedingCtrlModule.java

@ -216,12 +216,15 @@ public class InFeedingCtrlModule {
APPE_NO_TUBE_IN_HOLDER,//试管架中没有试管
PROJ_CARD_ERROR_WRONG_UNSUPPORTED,//项目不支持
PROJ_CARD_ERROR_BUILD_IN_PROJ_INFO_ERROR//内置项目信息异常
:
appWarningFlagStateMgr.setFlagState(AppWarningFlagType.InfeedError, e.getError());
case APPE_CONSUME_NOT_ENOUGH: //耗材不足
appWarningFlagStateMgr.setFlagState(AppWarningFlagType.ConsumeNotEnoughError, e.getError());
case APPE_TIP_NOT_ENOUGH: //Tip不足
appWarningFlagStateMgr.setFlagState(AppWarningFlagType.TipNotEnoughError, e.getError());
-> appWarningFlagStateMgr.setFlagState(AppWarningFlagType.InfeedError, e.getError());
case APPE_CONSUME_NOT_ENOUGH ->//耗材不足
appWarningFlagStateMgr.setFlagState(AppWarningFlagType.ConsumeNotEnoughError, e.getError());
case APPE_TIP_NOT_ENOUGH -> //Tip不足
appWarningFlagStateMgr.setFlagState(AppWarningFlagType.TipNotEnoughError, e.getError());
default -> {
}
}
rollbackEnterTubeholder();
@ -267,15 +270,15 @@ public class InFeedingCtrlModule {
//添加试管架到系统中
tubeStateMgr.newTubeHolder(tubeholderInfo);
/*
* 当使用试管架扩展配置说明当前处于一致性测试模式该模式下试管架配置会被重复使用不会被删除
*其他模式下试管架配置会被删除
*/
// /*
// * 当使用试管架扩展配置说明当前处于一致性测试模式该模式下试管架配置会被重复使用不会被删除
// *其他模式下试管架配置会被删除
// */
if (tubeHolderSetting != null) {
if (!tubeholderExSettingMgr.isEnabled()) {
log.info("删除试管架配置 {}", tubeHolderSetting.uuid);
tubeHolderSettingMgrService.removeLockTubeHolderSetting(tubeHolderSetting);
}
// if (!tubeholderExSettingMgr.isEnabled()) {
log.info("删除试管架配置 {}", tubeHolderSetting.uuid);
tubeHolderSettingMgrService.removeLockTubeHolderSetting(tubeHolderSetting);
// }
}
}
@ -333,9 +336,7 @@ public class InFeedingCtrlModule {
}
private void docmd(String mark, A8kCmdRunnable runnable) throws AppException {
docmd(mark, runnable, () -> {
OS.forceSleep(1000);
});
docmd(mark, runnable, () -> OS.forceSleep(1000));
}
private Boolean getTubeholderEnterPosPPS() { // 入料通道是否为空

33
src/main/java/a8k/app/service/statemgr/AppWarningFlagStateMgr.java

@ -2,7 +2,9 @@ package a8k.app.service.statemgr;
import a8k.app.factory.ZAppPromoptFactory;
import a8k.app.hardware.type.A8kEcode;
import a8k.app.type.AppWarningFlagType;
import a8k.app.type.DeviceRunMode;
import a8k.app.type.error.AppError;
import a8k.app.type.ui.ZAppPromopt;
import cn.hutool.core.util.ObjectUtil;
@ -37,7 +39,7 @@ public class AppWarningFlagStateMgr {
public List<DeviceWarningFlagState> states = new ArrayList<>();
}
private final GStateMgrService gstate;
DeviceWarningFlagStateGroup deviceWarningFlagState = new DeviceWarningFlagStateGroup();
DeviceWarningFlagStateGroup lastCpyDeviceWarningFlagState = new DeviceWarningFlagStateGroup(); //上次复制的状态
int stateVersion = 0; //状态版本号
@ -54,6 +56,25 @@ public class AppWarningFlagStateMgr {
}
synchronized public DeviceWarningFlagStateGroup getDeviceWarningFlagState() {
if (gstate.isInMode(DeviceRunMode.VirtualStateGenerateMode)) {
//虚拟状态,用于前端状态测试
var cpy = ObjectUtil.clone(deviceWarningFlagState);
int i = 0;
for (DeviceWarningFlagState flagState : cpy.states) {
flagState.state = i % 2 == 0; //模拟状态
if (flagState.state) {
flagState.errorDetailInfo = new AppError(A8kEcode.DEVICE_IS_BUSY);
flagState.errorPromptInfo = ZAppPromoptFactory.buildAppPromopt(flagState.errorDetailInfo);
} else {
flagState.errorDetailInfo = null;
flagState.errorPromptInfo = null;
}
i++;
}
return cpy;
}
if (lastCpyStateVersion != stateVersion) {
lastCpyDeviceWarningFlagState = ObjectUtil.clone(deviceWarningFlagState);
lastCpyStateVersion = stateVersion;
@ -61,6 +82,13 @@ public class AppWarningFlagStateMgr {
return lastCpyDeviceWarningFlagState;
}
synchronized public Integer getStateVersion() {
if (gstate.isInMode(DeviceRunMode.VirtualStateGenerateMode)) {
return 9999; //
}
return stateVersion;
}
synchronized public DeviceWarningFlagState getDeviceWarningFlagState(AppWarningFlagType flagType) {
for (DeviceWarningFlagState flagState : deviceWarningFlagState.states) {
if (flagState.keyName.equals(flagType.name())) {
@ -71,9 +99,6 @@ public class AppWarningFlagStateMgr {
return null;
}
synchronized public Integer getStateVersion() {
return stateVersion;
}
synchronized public void setFlagState(AppWarningFlagType flagType, AppError errorDetailInfo) {
for (DeviceWarningFlagState flagState : deviceWarningFlagState.states) {

12
src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java

@ -171,10 +171,16 @@ public class ConsumablesMgrService {
if (deviceWorkStateMgrService.isDeviceWorking()) {
throw AppException.of(A8kEcode.APPE_DO_ACTION_FAIL_DEVICE_IS_WORKING);
}
if (deviceWorkStateMgrService.isNotInIDLE() && preReactionStateMgr.isHasInUSEReactionGrid(ch)) {
throw AppException.of(A8kEcode.APPE_CONSUMABLES_IS_IN_USE_NOT_ALLOW_UNSTALL);
}
if (larBottleContainerStateMgr.isInstall(ch))
larBottleContainerStateMgr.setNum(ch, num);
if (littBottleContainerStateMgr.isInstall(ch))
if (littBottleContainerStateMgr.isInstall(ch)) {
littBottleContainerStateMgr.setNum(ch, num);
preReactionStateMgr.setConsumableNum(ch, num);
}
if (reactionPlateContainerStateMgr.isInstall(ch))
reactionPlateContainerStateMgr.setReactionPlateNum(ch, num);
}
@ -247,7 +253,7 @@ public class ConsumablesMgrService {
ConsumableInfo littBottle = null;
switch (flowType) {
case SampleAndBS: {
case SampleAndBS-> {
reactionPlate = reactionPlateContainerStateMgr.reverseOneByProjId(projId);
littBottle = littBottleContainerStateMgr.reverse(reactionPlate);
if (reactionPlate == null || littBottle == null) {
@ -259,7 +265,7 @@ public class ConsumablesMgrService {
stateVersion++;
return littBottle;
}
case SampleAndBSAndProbeSubstance: {
case SampleAndBSAndProbeSubstance-> {
reactionPlate = reactionPlateContainerStateMgr.reverseOneByProjId(projId);
littBottle = littBottleContainerStateMgr.reverse(reactionPlate);
larBottle = larBottleContainerStateMgr.reverse(reactionPlate);

7
src/main/java/a8k/app/service/statemgr/DeviceWorkStateMgrService.java

@ -1,9 +1,11 @@
package a8k.app.service.statemgr;
import a8k.app.type.DeviceRunMode;
import a8k.app.type.a8k.state.DeviceWorkState;
import a8k.app.type.a8k.state.enumtype.A8kWorkState;
import a8k.app.type.a8k.state.enumtype.A8kWorkTaskType;
import a8k.app.type.error.AppError;
import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@ -19,6 +21,11 @@ public class DeviceWorkStateMgrService {
synchronized public DeviceWorkState getDeviceWorkState() {
if (gstate.isInMode(DeviceRunMode.VirtualStateGenerateMode)) {
var cpy = ObjectUtil.clone(deviceWorkState);
cpy.workState = A8kWorkState.WORKING;
return cpy;
}
return deviceWorkState;
}

10
src/main/java/a8k/app/service/statemgr/GStateMgrService.java

@ -33,7 +33,17 @@ public class GStateMgrService {
}
Integer i = 0;
public synchronized SensorState getSensorState() {
if (isInMode(DeviceRunMode.VirtualStateGenerateMode)) {
SensorState sensorState = new SensorState();
sensorState.setPboxTemperature(-i % 40);
sensorState.setIncubateBoxTemperature(i % 40);
sensorState.setWasteBinFullFlag((i / 100) % 2 == 0);
i++;
return sensorState;
}
return this.gState.sensorState;
}

34
src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java

@ -1,5 +1,7 @@
package a8k.app.service.statemgr;
import a8k.app.factory.ZAppPromoptFactory;
import a8k.app.hardware.type.A8kEcode;
import a8k.app.type.DeviceRunMode;
import a8k.app.type.a8k.BloodType;
import a8k.app.type.a8k.pos.ConsumableInfo;
@ -48,8 +50,19 @@ public class IncubationPlateStateMgr {
synchronized public IncubationPlate getVirtualState() {
IncubationPlate incubationPlate = new IncubationPlate();
int i = 0;
for (IncubationSubTank subtank : incubationPlate.subtanks) {
subtank.state = IncubationSubTankState.ERROR;
i++;
switch (i % 6) {
case 0 -> subtank.state = IncubationSubTankState.EMPTY;
case 1 -> subtank.state = IncubationSubTankState.RESERVED;
case 2 -> subtank.state = IncubationSubTankState.INCUBATING;
case 3 -> subtank.state = IncubationSubTankState.INCUBATION_COMPLETE;
case 4 -> subtank.state = IncubationSubTankState.ERROR;
case 5 -> subtank.state = IncubationSubTankState.WAITING_FOR_DROP;
}
subtank.bloodType = BloodType.WHOLE_BLOOD;
subtank.sampleBarcode = "112334455667";
subtank.userid = "250109_001E";
@ -61,10 +74,14 @@ public class IncubationPlateStateMgr {
subtank.sampleId = "250109_001E01";
subtank.projId = 1;
subtank.lotId = "CA123456";
subtank.isEmergency = true;
subtank.startIncubatedTime = new Date().getTime();
subtank.incubatedTimeSec = 3 * 60;
subtank.remainTimeSec = 3 * 60;
subtank.isEmergency = i % 2 == 0;
if (subtank.state.equals(IncubationSubTankState.ERROR)) {
subtank.error = new AppError(A8kEcode.APPE_DEVICE_IS_IN_FATAL_ERROR, "");
subtank.errorInfo = ZAppPromoptFactory.buildAppPromopt(subtank.error);
}
subtank.startIncubatedTime = new Date().getTime();
subtank.incubatedTimeSec = 3 * 60;
subtank.remainTimeSec = 3 * 60;
}
return incubationPlate;
}
@ -183,15 +200,16 @@ public class IncubationPlateStateMgr {
}
synchronized public void setIncubationToErrorState(IncubatorPos pos, List<AppError> errors) {
synchronized public void setIncubationToErrorState(IncubatorPos pos, AppError error) {
if (pos == null) {
return;
}
var subtanks = incubationPlate.subtanks;
for (IncubationSubTank subtank : subtanks) {
if (subtank.getPos().equals(pos)) {
subtank.state = IncubationSubTankState.ERROR;
subtank.errors = errors;
subtank.state = IncubationSubTankState.ERROR;
subtank.error = error;
subtank.errorInfo = ZAppPromoptFactory.buildAppPromopt(subtank.error);
log.info("孵育盘[{}] 状态->错误", subtank.getPos());
break;
}

2
src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java

@ -42,7 +42,7 @@ public class OptScanModuleStateMgr {
synchronized public OptScanModuleState getOptScanModule() {
if (gStateMgrService.isInMode(DeviceRunMode.VirtualStateGenerateMode)) {
OptScanModuleState virstate = new OptScanModuleState();
virstate.state = OptScanModuleStateEnum.PLATE_IS_READY;
virstate.state = OptScanModuleStateEnum.EMPTY;
virstate.setBloodType(BloodType.WHOLE_BLOOD);
virstate.setSampleBarcode("1234567890");
virstate.setUserid("2250103_003");

198
src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java

@ -1,13 +1,20 @@
package a8k.app.service.statemgr;
import a8k.app.constant.AppConstant;
import a8k.app.service.data.ProjInfoMgrService;
import a8k.app.service.utils.ProjInfoUtils;
import a8k.app.type.DeviceRunMode;
import a8k.app.type.PreReactionGrid;
import a8k.app.type.PreReactionGridGroup;
import a8k.app.type.PreReactionPosState;
import a8k.app.type.a8k.ConsumableGroup;
import a8k.app.type.a8k.LittleBottleConsumableType;
import a8k.app.type.a8k.container.LittBottleConsumablesInfo;
import a8k.app.type.a8k.pos.PreReactionPos;
import a8k.app.type.a8k.state.SampleInfo;
import a8k.app.type.a8k.state.Tube;
import a8k.app.type.exception.AppException;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.log.Log;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
@ -21,20 +28,84 @@ import org.springframework.util.Assert;
@EnableScheduling
public class PreReactionStateMgr {
private final ProjInfoMgrService projInfoMgrService;
private final GStateMgrService gStateMgrService;
PreReactionPosState preReactionPosState = new PreReactionPosState();
public synchronized PreReactionPosState getPreReactionPosState() {
public synchronized PreReactionPosState getPreReactionGridState() {
return ObjectUtil.cloneByStream(preReactionPosState);
}
private PreReactionGridGroup buildFakePreReactionGridGroup(ConsumableGroup group) {
PreReactionGridGroup gridGroup = new PreReactionGridGroup(group);
gridGroup.group = group;
if (group.off % 2 == 0) {
gridGroup.installed = true;
gridGroup.hasSomeGridInReacting = true;
gridGroup.hasSomeGridReactedCompleted = true;
} else {
gridGroup.installed = false;
gridGroup.hasSomeGridInReacting = false;
gridGroup.hasSomeGridReactedCompleted = false;
}
gridGroup.consumableType = LittleBottleConsumableType.BufferSolution;
try {
gridGroup.projBriefInfo = ProjInfoUtils.buildProjBrefInfo(projInfoMgrService.getProjBuildInInfo(1));
} catch (AppException e) {
throw new RuntimeException(e);
}
gridGroup.version = 10;
for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) {
switch (i % 5) {
case 0 -> {
gridGroup.grids.get(i).state = PreReactionGrid.State.UNINSTALL;
}
case 1 -> {
gridGroup.grids.get(i).state = PreReactionGrid.State.TO_BE_USED;
}
case 2 -> {
gridGroup.grids.get(i).state = PreReactionGrid.State.REACTING;
gridGroup.grids.get(i).sampleInfo.userid = "FAKE-UID-121";
gridGroup.grids.get(i).reactionRemainingTime = i * 60L;
}
case 3 -> {
gridGroup.grids.get(i).state = PreReactionGrid.State.REACTION_COMPLETED;
gridGroup.grids.get(i).sampleInfo.userid = "FAKE-UID-123";
}
case 4 -> {
gridGroup.grids.get(i).state = PreReactionGrid.State.USED;
}
}
}
return gridGroup;
}
public synchronized PreReactionGridGroup getPreReactionGridGroupState(ConsumableGroup group) {
if (gStateMgrService.isInMode(DeviceRunMode.VirtualStateGenerateMode)) {
return buildFakePreReactionGridGroup(group);
}
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group);
return ObjectUtil.cloneByStream(gridGroup);
}
public synchronized Integer getPreReactionGridGroupVersion(ConsumableGroup group) {
if (gStateMgrService.isInMode(DeviceRunMode.VirtualStateGenerateMode)) {
return buildFakePreReactionGridGroup(group).version;
}
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group);
if (gridGroup != null) {
return gridGroup.version;
}
return 0;
}
public synchronized boolean isHasReactionCompleted() {
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) {
if (gridGroup.isHasReactionCompleted) {
if (gridGroup.hasSomeGridReactedCompleted) {
return true;
}
}
@ -43,7 +114,7 @@ public class PreReactionStateMgr {
public synchronized boolean isHasInReactionGrid() {
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) {
if (gridGroup.isHasInReactionGrid) {
if (gridGroup.hasSomeGridInReacting) {
return true;
}
}
@ -52,7 +123,7 @@ public class PreReactionStateMgr {
public synchronized PreReactionPos getReactionCompletedPos() {
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) {
if (gridGroup.isHasReactionCompleted) {
if (gridGroup.hasSomeGridReactedCompleted) {
for (PreReactionGrid grid : gridGroup.grids) {
if (grid.state.equals(PreReactionGrid.State.REACTION_COMPLETED)) {
PreReactionPos pos = new PreReactionPos();
@ -67,22 +138,36 @@ public class PreReactionStateMgr {
return null;
}
public synchronized void changeReactionGridStateToReacting(PreReactionPos preReactionPos, Long totalReactionTimeMs) {
public synchronized void changeReactionGridStateToReacting(PreReactionPos preReactionPos, Tube fromTube, Integer off, Long totalReactionTimeS) {
PreReactionGridGroup gridGroup = getPreReactionGridGroup(preReactionPos.group);
Assert.notNull(gridGroup, "gridGroup != null");
var grid = gridGroup.grids.get(preReactionPos.index);
grid.state = PreReactionGrid.State.REACTING;
grid.totalReactionTime = totalReactionTimeS;
grid.startReactionTime = System.currentTimeMillis() / 1000;
grid.reactionRemainingTime = totalReactionTimeS;
grid.projBuildinInfo = fromTube.getPreProcessContexts().get(off).getProjBuildinInfo();
grid.projExtInfoCard = fromTube.getPreProcessContexts().get(off).getProjExtInfoCard();
grid.sampleInfo = fromTube.getSampleInfo();
grid.bindIncubatorPos = fromTube.getPreProcessContexts().get(off).getIncubatorPos();
gridGroup.hasSomeGridInReacting = true;
gridGroup.version++;
}
public synchronized void changeReactionGridStateToUsed(PreReactionPos preReactionPos) {
PreReactionGridGroup gridGroup = getPreReactionGridGroup(preReactionPos.group);
Assert.notNull(gridGroup, "gridGroup != null");
var grid = gridGroup.grids.get(preReactionPos.index);
grid.state = PreReactionGrid.State.REACTING;
grid.totalReactionTime = totalReactionTimeMs;
grid.startReactionTime = System.currentTimeMillis();
grid.hasReactionTime = 0L;
gridGroup.isHasInReactionGrid = true;
grid.state = PreReactionGrid.State.USED;
gridGroup.version++;
}
public synchronized boolean isHasInUSEReactionGrid(ConsumableGroup group) {
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group);
if (gridGroup != null) {
return gridGroup.isHasInReactionGrid || gridGroup.isHasReactionCompleted;
return gridGroup.hasSomeGridInReacting || gridGroup.hasSomeGridReactedCompleted;
}
return false;
}
@ -92,19 +177,40 @@ public class PreReactionStateMgr {
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group);
Assert.notNull(gridGroup, "gridGroup != null");
gridGroup.consumableType = littBottleConsumablesInfo.type;
gridGroup.isInstalled = true;
gridGroup.installed = true;
changeAllGridStateToIdle(gridGroup.group);
gridGroup.syncInfo();
gridGroup.version++;
}
public synchronized void setConsumableNum(ConsumableGroup group, Integer num) {
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group);
Assert.notNull(gridGroup, "gridGroup != null");
gridGroup.syncInfo();
for (int i = 0; i < gridGroup.grids.size(); i++) {
if (i < AppConstant.CONSUMABLE_NUM - num) {
gridGroup.grids.get(i).state = PreReactionGrid.State.UNINSTALL;
} else {
gridGroup.grids.get(i).state = PreReactionGrid.State.TO_BE_USED;
}
}
gridGroup.version++;
}
public synchronized void unInstallConsumable(ConsumableGroup group) {
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group);
Assert.notNull(gridGroup, "gridGroup != null");
gridGroup.isInstalled = false;
gridGroup.installed = false;
changeAllGridStateToIdle(gridGroup.group);
gridGroup.version++;
}
public synchronized void resetAll() {
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) {
changeAllGridStateToIdle(gridGroup.group);
}
@ -115,19 +221,27 @@ public class PreReactionStateMgr {
// *********************************************************************************
private void changeAllGridStateToIdle(ConsumableGroup group) {
PreReactionGridGroup gridGroup = getPreReactionGridGroup(group);
Assert.notNull(gridGroup, "gridGroup != null");
gridGroup.isHasInReactionGrid = false;
gridGroup.isHasReactionCompleted = false;
gridGroup.hasSomeGridInReacting = false;
gridGroup.hasSomeGridReactedCompleted = false;
for (PreReactionGrid grid : gridGroup.grids) {
grid.state = PreReactionGrid.State.IDLE;
grid.startReactionTime = 0L;
grid.hasReactionTime = 0L;
grid.totalReactionTime = 0L;
grid.state = PreReactionGrid.State.UNINSTALL;
grid.startReactionTime = 0L;
grid.reactionRemainingTime = 0L;
grid.totalReactionTime = 0L;
grid.bindIncubatorPos = null;
grid.sampleInfo = new SampleInfo();
grid.projBuildinInfo = null;
grid.projExtInfoCard = null;
}
gridGroup.version++;
}
private PreReactionGridGroup getPreReactionGridGroup(ConsumableGroup group) {
for (PreReactionGridGroup gridGroup : preReactionPosState.preReactionGridGroups) {
if (gridGroup.group.equals(group)) {
return gridGroup;
@ -138,32 +252,42 @@ public class PreReactionStateMgr {
private void autoRefreshPreReactionPosState(PreReactionGridGroup group) {
// update hasReactionTime
if (!group.isInstalled) {
if (!group.installed)
return;
}
boolean isHasInReactionGrid = false;
boolean isHasReactionCompleted = false;
for (PreReactionGrid grid : group.grids) {
if (grid.state.equals(PreReactionGrid.State.IDLE)) {
continue;
}
if (grid.state.equals(PreReactionGrid.State.REACTING)) {
grid.hasReactionTime = System.currentTimeMillis() - grid.startReactionTime;
if (grid.hasReactionTime < grid.totalReactionTime) {
isHasInReactionGrid = true;
} else {
grid.state = PreReactionGrid.State.REACTION_COMPLETED;
isHasReactionCompleted = true;
switch (grid.state) {
case UNINSTALL, TO_BE_USED, USED -> {
}
} else if (grid.state.equals(PreReactionGrid.State.REACTION_COMPLETED)) {
isHasReactionCompleted = true;
case REACTING -> {
grid.reactionRemainingTime = grid.totalReactionTime - (System.currentTimeMillis() / 1000 - grid.startReactionTime);
group.version++;
//grid.reactionRemainingTime 发生改变时不更新VERSION,否则上报频繁了
if (grid.reactionRemainingTime <= 0) {
grid.state = PreReactionGrid.State.REACTION_COMPLETED;
grid.reactionRemainingTime = 0L;
isHasReactionCompleted = true;
} else {
isHasInReactionGrid = true;
}
}
case REACTION_COMPLETED -> isHasReactionCompleted = true;
}
}
group.isHasInReactionGrid = isHasInReactionGrid;
group.isHasReactionCompleted = isHasReactionCompleted;
if (group.hasSomeGridReactedCompleted != isHasReactionCompleted) {
group.hasSomeGridReactedCompleted = isHasReactionCompleted;
group.version++;
}
if (group.hasSomeGridInReacting != isHasInReactionGrid) {
group.hasSomeGridInReacting = isHasInReactionGrid;
group.version++;
}
}
@Scheduled(fixedDelay = 600)

36
src/main/java/a8k/app/service/statemgr/TubeStateMgr.java

@ -25,6 +25,7 @@ import a8k.app.dao.type.combination.ProjBuildInInfo;
import a8k.app.service.utils.ProjInfoUtils;
import a8k.app.service.utils.ZAppChecker;
import a8k.app.utils.ZJsonHelper;
import a8k.app.utils.ZList;
import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -345,16 +346,39 @@ public class TubeStateMgr {
tube.setBloodType(BloodType.WHOLE_BLOOD);
tube.setSampleBarcode("112334455667");
tube.setUserid(String.format("250109_%dE", pos));
tube.setProjInfo(List.of(
var toBeUsedPBI = ZList.of(
new ProjBriefInfo(1, "hsCRP", "CA", UtilsProjectColorAllocer.getProjColor(1)),
new ProjBriefInfo(2, "PCT", "PC", UtilsProjectColorAllocer.getProjColor(2)),
new ProjBriefInfo(3, "TSH", "TS", UtilsProjectColorAllocer.getProjColor(3)),
new ProjBriefInfo(4, "TRL", "PL", UtilsProjectColorAllocer.getProjColor(4)),
new ProjBriefInfo(10, "Progesterone", "T3", UtilsProjectColorAllocer.getProjColor(10)),
new ProjBriefInfo(20, "Tn-I/CK-MB/Myoglobin", "T4", UtilsProjectColorAllocer.getProjColor(20))
));
tube.setProjIds(List.of(1, 2, 3, 4, 10, 20));
tube.setState(TubeState.TO_BE_PROCESSED);
);
var toBeUsedProjIds = ZList.of(1, 2, 3, 4, 10, 20);
for (int i = 0; i < pos; i++) {
if (i >= 6)
break;
if (i < toBeUsedPBI.size()) {
tube.getProjInfo().add(toBeUsedPBI.get(i));
tube.getProjIds().add(toBeUsedProjIds.get(i));
}
}
switch (pos) {
case 0 -> tube.setState(TubeState.TO_BE_PROCESSED);
case 1 -> tube.setState(TubeState.PENDING);
case 2 -> tube.setState(TubeState.RESOURCE_IS_READY);
case 3 -> tube.setState(TubeState.PROCESSING);
case 4 -> tube.setState(TubeState.PROCESS_COMPLETE);
case 6 -> tube.setState(TubeState.ERROR);
case 5, 7, 8 -> tube.setState(TubeState.PROCESS_COMPLETE);
case 9 -> tube.setState(TubeState.EMPTY);
}
tube.setIsHighTube(pos % 2 == 0); //假设偶数位置为高位管
return tube;
}
@ -362,7 +386,9 @@ public class TubeStateMgr {
synchronized public EmergencyTubePos getEmergencyPosRunState() {
if (gStateMgrService.isInMode(DeviceRunMode.VirtualStateGenerateMode)) {
var tubePosState = new EmergencyTubePos();
tubePosState.tube = createFakeTube(0);
tubePosState.tube = createFakeTube(3);
tubePosState.tube.setPos(0);
tubePosState.tube.setIsEmergency(true);
return tubePosState;
}
return ObjectUtil.cloneByStream(emergencyTubePos);

42
src/main/java/a8k/app/type/PreReactionGrid.java

@ -1,15 +1,22 @@
package a8k.app.type;
import a8k.app.dao.type.combination.ProjBuildInInfo;
import a8k.app.dao.type.db.ProjExtInfoCard;
import a8k.app.type.a8k.ConsumableGroup;
import a8k.app.type.a8k.LittleBottleConsumableType;
import a8k.app.type.a8k.pos.IncubatorPos;
import a8k.app.type.a8k.state.SampleInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
public class PreReactionGrid implements Serializable {
public enum State {
IDLE,
UNINSTALL,
TO_BE_USED,
REACTING,
REACTION_COMPLETED,
USED
}
public State state;
@ -17,25 +24,32 @@ public class PreReactionGrid implements Serializable {
public ConsumableGroup group;
public Integer posIndex;
public Long startReactionTime;
public Long hasReactionTime;
public Long reactionRemainingTime;
public Long totalReactionTime;
public SampleInfo sampleInfo = new SampleInfo();
@JsonIgnore
public ProjBuildInInfo projBuildinInfo;
@JsonIgnore
public ProjExtInfoCard projExtInfoCard;
public Integer projId = 0;
public IncubatorPos bindIncubatorPos;
PreReactionGrid(ConsumableGroup group, Integer posIndex) {
this.group = group;
this.posIndex = posIndex;
this.state = State.IDLE;
this.startReactionTime = 0L;
this.hasReactionTime = 0L;
this.totalReactionTime = 0L;
this.group = group;
this.posIndex = posIndex;
this.state = State.UNINSTALL;
this.startReactionTime = 0L;
this.reactionRemainingTime = 0L;
this.totalReactionTime = 0L;
}
public PreReactionGrid() {
this.group = ConsumableGroup.CG1;
this.posIndex = 0;
this.state = State.IDLE;
this.startReactionTime = 0L;
this.hasReactionTime = 0L;
this.totalReactionTime = 0L;
this.group = ConsumableGroup.CG1;
this.posIndex = 0;
this.state = State.UNINSTALL;
this.startReactionTime = 0L;
this.reactionRemainingTime = 0L;
this.totalReactionTime = 0L;
}
}

15
src/main/java/a8k/app/type/PreReactionGridGroup.java

@ -2,6 +2,7 @@ package a8k.app.type;
import a8k.app.type.a8k.ConsumableGroup;
import a8k.app.type.a8k.LittleBottleConsumableType;
import a8k.app.type.a8k.proj.ProjBriefInfo;
import java.io.Serializable;
import java.util.ArrayList;
@ -11,10 +12,16 @@ public class PreReactionGridGroup implements Serializable {
public List<PreReactionGrid> grids;
public ConsumableGroup group;
public LittleBottleConsumableType consumableType = LittleBottleConsumableType.BufferSolution;
public Boolean isHasInReactionGrid = false;
public Boolean isHasReactionCompleted = false;
public Boolean isInstalled = false;
public LittleBottleConsumableType consumableType = LittleBottleConsumableType.BufferSolution;
public Boolean hasSomeGridInReacting = false;
public Boolean hasSomeGridReactedCompleted = false;
public Boolean installed = false;
public Integer version = 0;
public ProjBriefInfo projBriefInfo;
public Boolean isInReacting() {
return hasSomeGridInReacting || hasSomeGridReactedCompleted;
}
public PreReactionGridGroup(ConsumableGroup group) {
grids = new ArrayList<>();

8
src/main/java/a8k/app/type/a8k/state/IncubationSubTank.java

@ -3,11 +3,13 @@ package a8k.app.type.a8k.state;
import a8k.app.type.a8k.pos.ConsumableInfo;
import a8k.app.type.a8k.state.enumtype.IncubationSubTankState;
import a8k.app.type.a8k.pos.IncubatorPos;
import a8k.app.type.appevent.AppPromptEvent;
import a8k.app.type.error.AppError;
import a8k.app.type.a8k.BloodType;
import a8k.app.type.a8k.proj.ProjBriefInfo;
import a8k.app.dao.type.db.ProjExtInfoCard;
import a8k.app.dao.type.combination.ProjBuildInInfo;
import a8k.app.type.ui.ZAppPromopt;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
@ -65,7 +67,9 @@ public class IncubationSubTank implements Serializable {
@Setter
@Schema(description = "错误信息,用来标识当前孵育盘的错误信息,例如推出的反应板夹有问题")
public List<AppError> errors = new ArrayList<>(); //错误信息
public AppError error = null;
public ZAppPromopt errorInfo = null; //错误提示
@Schema(description = "是否已经清空过")
public Boolean hasCleared = true;
@ -86,7 +90,7 @@ public class IncubationSubTank implements Serializable {
projInfo = null;
sampleId = "";
projId = null;
errors.clear();
error = null;
}
public SampleInfo toSampleInfo() {

2
src/main/java/a8k/app/type/a8k/state/OptScanModuleState.java

@ -29,7 +29,7 @@ public class OptScanModuleState implements Serializable {
@Schema(description = "样本ID(后端使用)")
String sampleId = "";
@Schema(description = "项目ID")
Integer projId = 0;
Integer projId = 1;
@Schema(description = "是否是急诊样本")
Boolean isEmergency = false;

20
src/main/java/a8k/extui/page/debug/PreReactionPosStateMgrDebugPage.java

@ -61,15 +61,15 @@ public class PreReactionPosStateMgrDebugPage {
public void uninstall(ConsumableGroup group) {
preReactionStateMgr.unInstallConsumable(group);
}
public void changeStateToReacting(ConsumableGroup group, Integer off, Integer reactionTimeS) {
PreReactionPos pos = new PreReactionPos();
pos.group = group;
pos.type = LittleBottleConsumableType.BufferSolution;
pos.index = off;
preReactionStateMgr.changeReactionGridStateToReacting(pos, reactionTimeS.longValue() * 1000);
}
//
// public void changeStateToReacting(ConsumableGroup group, Integer off, Integer reactionTimeS) {
//
// PreReactionPos pos = new PreReactionPos();
// pos.group = group;
// pos.type = LittleBottleConsumableType.BufferSolution;
// pos.index = off;
// preReactionStateMgr.changeReactionGridStateToReacting(pos, reactionTimeS.longValue() * 1000);
// }
@PostConstruct
@ -78,7 +78,7 @@ public class PreReactionPosStateMgrDebugPage {
page.newGroup("预反应位点状态管理(只在单元测试中使用)");
page.addFunction("加载耗材", this::installOne);
page.addFunction("卸载耗材", this::uninstall);
page.addFunction("切换状态到反应中", this::changeStateToReacting);
// page.addFunction("切换状态到反应中", this::changeStateToReacting);
extApiPageMgr.addPage(page);
}
}

14
src/main/java/a8k/extui/page/extapp/debug_assistant/VirtualEventGeneratorPage.java

@ -42,15 +42,9 @@ public class VirtualEventGeneratorPage {
public void buildInfoPromoptEvent(MessageLevel level, ZAppPromoptDetailInfoType infoType) {
switch (infoType) {
case Text:
eventBus.pushEvent(new AppPromptEvent(new ZAppPromopt(level, "硬件异常", null, "子设备断开连接了......")));
break;
case Forms:
eventBus.pushEvent(new AppPromptEvent(new ZAppPromopt(level, "板夹仓硬件异常", null, buildZAppPromoptFormsItem())));
break;
case Table:
eventBus.pushEvent(new AppPromptEvent(new ZAppPromopt(level, "耗材不足", null, buildZAppPromoptTable())));
break;
case Text -> eventBus.pushEvent(new AppPromptEvent(new ZAppPromopt(level, "硬件异常", null, "子设备断开连接了......")));
case Forms -> eventBus.pushEvent(new AppPromptEvent(new ZAppPromopt(level, "板夹仓硬件异常", null, buildZAppPromoptFormsItem())));
case Table -> eventBus.pushEvent(new AppPromptEvent(new ZAppPromopt(level, "耗材不足", null, buildZAppPromoptTable())));
}
}
@ -68,7 +62,7 @@ public class VirtualEventGeneratorPage {
ExtUIPageCfg page = new ExtUIPageCfg(this);
page.addFunction("构建弹窗事件", this::buildInfoPromoptEvent);
page.addFunction("构造消息", this::pushMessageBoxEvent)
.setParamVal("info", ()->"测试消息");
.setParamVal("info", () -> "测试消息");
extApiPageMgr.addPage(page);
}
}
Loading…
Cancel
Save