From 9524f209dba7241496ae42c4dcef1b80056b73a5 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Wed, 16 Jul 2025 15:24:05 +0800 Subject: [PATCH] Adds virtual state debug settings Introduces a new UI page for configuring virtual device states, specifically focusing on the emergency tube state. This addition enables developers and testers to easily simulate various device scenarios and error conditions for more comprehensive testing and debugging. Also, refactors device virtual state services to virtualstate package. --- .../api/v1/app/ws/AppEventWebsocketEndpoint.java | 15 +- .../api/v1/app/ws/AppStateWebsocketEndpoint.java | 9 +- .../api/v1/app/ws/AppWebSocketEndpointMgr.java | 9 +- .../app/service/DeviceVirtualStateMgrService.java | 312 --------------------- .../a8k/app/service/statemgr/AppFlagStateMgr.java | 15 +- .../service/statemgr/ConsumablesMgrService.java | 3 +- .../statemgr/DeviceWorkStateMgrService.java | 5 +- .../a8k/app/service/statemgr/GStateMgrService.java | 2 +- .../service/statemgr/IncubationPlateStateMgr.java | 6 +- .../service/statemgr/OptScanModuleStateMgr.java | 5 +- .../app/service/statemgr/PreReactionStateMgr.java | 6 +- .../a8k/app/service/statemgr/TubeStateMgr.java | 2 +- .../virtualstate/DeviceVirtualStateMgrService.java | 250 +++++++++++++++++ .../virtualstate/TubeVirtualStateGenerator.java | 106 +++++++ .../a8k/app/type/DeviceWarningFlagStateGroup.java | 31 +- .../java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java | 8 +- .../DeviceVirtualStateMgrSettingPage.java | 35 +++ 17 files changed, 459 insertions(+), 360 deletions(-) delete mode 100644 src/main/java/a8k/app/service/DeviceVirtualStateMgrService.java create mode 100644 src/main/java/a8k/app/service/virtualstate/DeviceVirtualStateMgrService.java create mode 100644 src/main/java/a8k/app/service/virtualstate/TubeVirtualStateGenerator.java create mode 100644 src/main/java/a8k/extui/page/extapp/debug_assistant/DeviceVirtualStateMgrSettingPage.java diff --git a/src/main/java/a8k/app/controler/api/v1/app/ws/AppEventWebsocketEndpoint.java b/src/main/java/a8k/app/controler/api/v1/app/ws/AppEventWebsocketEndpoint.java index 8a2a225..33c56c3 100644 --- a/src/main/java/a8k/app/controler/api/v1/app/ws/AppEventWebsocketEndpoint.java +++ b/src/main/java/a8k/app/controler/api/v1/app/ws/AppEventWebsocketEndpoint.java @@ -1,9 +1,14 @@ package a8k.app.controler.api.v1.app.ws; import a8k.SpringBootBeanUtil; +import jakarta.annotation.PostConstruct; import jakarta.websocket.*; import jakarta.websocket.server.ServerEndpoint; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import java.io.IOException; @@ -11,9 +16,13 @@ import java.io.IOException; @ServerEndpoint(value = "/api/v1/app/ws/event") @Slf4j @Component -public class AppEventWebsocketEndpoint { +public class AppEventWebsocketEndpoint { - private Session session; + private Session session; + +// @Override public void onApplicationEvent(ContextRefreshedEvent event) { +// log.info("listening websocket event endpoint at ws://127.0.0.1:{}/api/v1/app/ws/event", env.getProperty("server.port")); +// } // 收到消息 @OnMessage @@ -44,4 +53,6 @@ public class AppEventWebsocketEndpoint { // 关闭连接。状态码为 UNEXPECTED_CONDITION(意料之外的异常) this.session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, throwable.getMessage())); } + + } diff --git a/src/main/java/a8k/app/controler/api/v1/app/ws/AppStateWebsocketEndpoint.java b/src/main/java/a8k/app/controler/api/v1/app/ws/AppStateWebsocketEndpoint.java index 251ffab..dd17065 100644 --- a/src/main/java/a8k/app/controler/api/v1/app/ws/AppStateWebsocketEndpoint.java +++ b/src/main/java/a8k/app/controler/api/v1/app/ws/AppStateWebsocketEndpoint.java @@ -1,9 +1,14 @@ package a8k.app.controler.api.v1.app.ws; import a8k.SpringBootBeanUtil; +import jakarta.annotation.PostConstruct; import jakarta.websocket.*; import jakarta.websocket.server.ServerEndpoint; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import java.io.IOException; @@ -12,11 +17,9 @@ import java.io.IOException; @Slf4j @Component public class AppStateWebsocketEndpoint { - + //参考 https://springdoc.cn/spring-boot-websocket/ private Session session; - - // 收到消息 @OnMessage public void onMessage(String message) throws IOException { diff --git a/src/main/java/a8k/app/controler/api/v1/app/ws/AppWebSocketEndpointMgr.java b/src/main/java/a8k/app/controler/api/v1/app/ws/AppWebSocketEndpointMgr.java index 1ad6f60..afba9ce 100644 --- a/src/main/java/a8k/app/controler/api/v1/app/ws/AppWebSocketEndpointMgr.java +++ b/src/main/java/a8k/app/controler/api/v1/app/ws/AppWebSocketEndpointMgr.java @@ -1,5 +1,6 @@ package a8k.app.controler.api.v1.app.ws; +import a8k.SpringBootBeanUtil; import a8k.app.service.engineer.state.EngineerModeStateMgrService; import a8k.app.type.AppGetStateFn; import a8k.app.type.DeviceRunMode; @@ -17,6 +18,7 @@ import a8k.app.utils.ZJsonHelper; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.core.env.Environment; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -140,6 +142,7 @@ public class AppWebSocketEndpointMgr { broadcastEvent(message); } + private final Environment env; @PostConstruct void init() { @@ -148,6 +151,10 @@ public class AppWebSocketEndpointMgr { forceUpdateCnt.incrementAndGet(); } }); + + + log.info("Listen ws://127.0.0.1:{}/api/v1/app/ws/state", env.getProperty("server.port")); + log.info("Listen ws://127.0.0.1:{}/api/v1/app/ws/event", env.getProperty("server.port")); } // @@ -217,8 +224,6 @@ public class AppWebSocketEndpointMgr { } - - Boolean isForceUpdateNow() { if (forceUpdateCnt.get() != 0) { forceUpdateCnt.getAndDecrement(); diff --git a/src/main/java/a8k/app/service/DeviceVirtualStateMgrService.java b/src/main/java/a8k/app/service/DeviceVirtualStateMgrService.java deleted file mode 100644 index c91ce37..0000000 --- a/src/main/java/a8k/app/service/DeviceVirtualStateMgrService.java +++ /dev/null @@ -1,312 +0,0 @@ -package a8k.app.service; - - -import a8k.app.channel.iflytophald.type.protocol.A8kEcode; -import a8k.app.constant.AppConstant; -import a8k.app.factory.FakeA8kConsumableContainerFactory; -import a8k.app.factory.FakeAppErrorFactory; -import a8k.app.factory.ZAppPromptFactory; -import a8k.app.service.utils.ProjInfoUtils; -import a8k.app.type.AppFlagKey; -import a8k.app.type.DeviceWarningFlagStateGroup; -import a8k.app.type.PreReactionGrid; -import a8k.app.type.PreReactionGridGroup; -import a8k.app.type.a8k.BloodType; -import a8k.app.type.a8k.ConsumableGroup; -import a8k.app.type.a8k.LittleBottleConsumableType; -import a8k.app.type.a8k.container.A8kConsumableContainer; -import a8k.app.type.a8k.proj.ProjBriefInfo; -import a8k.app.type.a8k.state.*; -import a8k.app.type.a8k.state.enumtype.*; -import a8k.app.type.error.AppError; -import a8k.app.type.exception.AppException; -import a8k.app.utils.ZList; -import cn.hutool.core.util.ObjectUtil; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -import java.util.Date; - -@Component -@RequiredArgsConstructor -@Slf4j -public class DeviceVirtualStateMgrService { - - - synchronized public A8kConsumableContainer getVirtualConsumableContainerState() { - //虚拟状态生成模式 - A8kConsumableContainer state = new A8kConsumableContainer(); - state.tips[0].tipNum = 100; - state.tips[1].tipNum = 101; - state.tips[2].tipNum = 102; - for (int i = 0; i < 6; i++) { - try { - FakeA8kConsumableContainerFactory.buildA8kConsumableContainerState(state, i); - } catch (AppException ignored) { - } - } - return state; - } - - synchronized public Integer getVirtualConsumableContainerStateVersion() { - //虚拟状态生成模式 - return Integer.MAX_VALUE; - } - - - /** - * 获取虚拟孵育盘状态 - * @return 虚拟孵育盘状态 - */ - synchronized public IncubationPlate getVirtualIncubationPlateState() { - IncubationPlate incubationPlate = new IncubationPlate(); - int i = 0; - for (IncubationSubTank subtank : incubationPlate.subtanks) { - i++; - switch (i) { - case 1 -> subtank.state = IncubationSubTankState.RESERVED; - case 2 -> subtank.state = IncubationSubTankState.WAITING_FOR_DROP; - case 3 -> subtank.state = IncubationSubTankState.INCUBATING; - case 4 -> subtank.state = IncubationSubTankState.ERROR; - case 5 -> subtank.state = IncubationSubTankState.INCUBATION_COMPLETE; - default -> subtank.state = IncubationSubTankState.EMPTY; - } - - subtank.sampleInfo = new SampleInfo( - "250109_001E01", 0, false, false, BloodType.WHOLE_BLOOD, "B3A7KK8DKF", "250109_001E" - ); - - - subtank.sampleInfo.bloodType = BloodType.WHOLE_BLOOD; - subtank.sampleInfo.sampleBarcode = "112334455667"; - subtank.sampleInfo.userid = "250109_001E"; - subtank.projInfo = new ProjBriefInfo(); - subtank.projInfo.projId = 1; - subtank.projInfo.projName = "hsCRP"; - subtank.projInfo.projShortName = "CA"; - subtank.projInfo.color = "#DC143C"; - subtank.sampleInfo.sampleId = "250109_001E01"; - subtank.projId = 1; - subtank.lotId = "CA123456"; - subtank.isEmergency = i == 2; - if (subtank.state.equals(IncubationSubTankState.ERROR)) { - subtank.error = new AppError(A8kEcode.PROJ_CARD_ERROR_WRONG_UNSUPPORTED, ""); - subtank.errorInfo = ZAppPromptFactory.buildAppPrompt(subtank.error); - } - subtank.startIncubatedTime = new Date().getTime(); - subtank.incubatedTimeSec = 3 * 60; - subtank.remainTimeSec = 3 * 60; - } - return incubationPlate; - } - - - static void addProjInfoToTube(Tube tube, Integer projId) { - ProjBriefInfo projBriefInfo = FakeA8kConsumableContainerFactory.buildFakeProjBriefInfo(projId); - tube.getProjInfo().add(projBriefInfo); - tube.getProjIds().add(projBriefInfo.projId); - } - - static Tube createFakeTube(Integer pos) { - Tube tube = new Tube(pos); - tube.setSampleId("250109_001E0" + pos); - tube.setBloodType(BloodType.WHOLE_BLOOD); - tube.setSampleBarcode("112334455667"); - tube.setUserid(String.format("250109_%dE", pos)); - - switch (pos) { - case 1 -> tube.setState(TubeState.EMPTY); - case 2 -> { - tube.setState(TubeState.ERROR); - tube.setError(FakeAppErrorFactory.buildAEConsumeNotEnoughError()); - tube.setErrorInfo(ZAppPromptFactory.buildAppPrompt(tube.getError())); - - addProjInfoToTube(tube, 1); - addProjInfoToTube(tube, 2); - - } - case 3, 4, 5, 6 -> { - tube.setState(TubeState.PROCESS_COMPLETE); - addProjInfoToTube(tube, 1); - addProjInfoToTube(tube, 2); - addProjInfoToTube(tube, 3); - } - case 7 -> { - tube.setState(TubeState.PROCESSING); - addProjInfoToTube(tube, 1); - addProjInfoToTube(tube, 2); - addProjInfoToTube(tube, 3); - } - case 8, 9, 10 -> { - tube.setState(TubeState.TO_BE_PROCESSED); - addProjInfoToTube(tube, 1); - addProjInfoToTube(tube, 2); - } - } - tube.setIsHighTube(pos % 2 == 0); //假设偶数位置为高位管 - - return tube; - } - - public TubeHolder getVirtualTubeHolderState() { - TubeHolder tubeHolder = new TubeHolder(); - tubeHolder.setTubes(new Tube[]{ - createFakeTube(1), - createFakeTube(2), - createFakeTube(3), - createFakeTube(4), - createFakeTube(5), - createFakeTube(6), - createFakeTube(7), - createFakeTube(8), - createFakeTube(9), - createFakeTube(10) - }); - tubeHolder.setState(TubeHolderState.PROCESSING); - return tubeHolder; - } - - public EmergencyTubePos getVirtualEmergencyTube() { - var tubePosState = new EmergencyTubePos(); - tubePosState.tube = createFakeTube(0); - tubePosState.tube.setPos(0); - tubePosState.tube.setIsEmergency(true); - return tubePosState; - } - - public Integer getVirtualTubeStateVersion() { - //虚拟状态生成模式 - return Integer.MAX_VALUE; - } - - - public PreReactionGridGroup getFakePreReactionGridGroup(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; - var projBuildInInfo = FakeA8kConsumableContainerFactory.buildFakeProjBuildInInfo(group.off); - gridGroup.projBriefInfo = ProjInfoUtils.buildProjBrefInfo(projBuildInInfo); - gridGroup.version = 10; - for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) { - - gridGroup.grids.get(i).projId = projBuildInInfo.projId; - gridGroup.grids.get(i).projBuildinInfo = projBuildInInfo; - gridGroup.grids.get(i).projExtInfoCard = null; - - switch (i / 5) { - case 0 -> { - gridGroup.grids.get(i).state = PreReactionGrid.State.UNINSTALL; - } - case 1 -> { - gridGroup.grids.get(i).state = PreReactionGrid.State.USED; - } - - case 2 -> { - gridGroup.grids.get(i).state = PreReactionGrid.State.REACTION_COMPLETED; - gridGroup.grids.get(i).sampleInfo.userid = "UID123"; - } - case 3 -> { - gridGroup.grids.get(i).state = PreReactionGrid.State.REACTING; - gridGroup.grids.get(i).sampleInfo.userid = "UID123"; - gridGroup.grids.get(i).reactionRemainingTime = 3 * 60L; - } - case 4 -> { - gridGroup.grids.get(i).state = PreReactionGrid.State.TO_BE_USED; - } - } - } - return gridGroup; - } - - public SensorState getVirtualSensorState() { - SensorState sensorState = new SensorState(); - sensorState.setPboxTemperature(24); - sensorState.setIncubateBoxTemperature(25); - sensorState.setWasteBinFullFlag(false); - return sensorState; - } - - // - // VIRTUAL_OPERATION - // - public DeviceWarningFlagStateGroup getDeviceFlagStateVirtualStateInitVal(DeviceWarningFlagStateGroup deviceWarningFlagState) { - - DeviceWarningFlagStateGroup virtualWarningState = ObjectUtil.clone(deviceWarningFlagState); //初始化时复制一份状态版本号 - virtualWarningState.version = 10000; - - //设置VirtualState初始值 - var consumeNotEnoughState = virtualWarningState.find(AppFlagKey.ConsumeNotEnoughState); - consumeNotEnoughState.state = true; // - consumeNotEnoughState.errorDetailInfo = FakeAppErrorFactory.buildAEConsumeNotEnoughError(); - consumeNotEnoughState.errorPromptInfo = ZAppPromptFactory.buildAppPrompt(consumeNotEnoughState.errorDetailInfo); - - var tipNotEnoughState = virtualWarningState.find(AppFlagKey.TipNotEnoughState); - tipNotEnoughState.state = true; // - tipNotEnoughState.errorDetailInfo = FakeAppErrorFactory.buildError(A8kEcode.APPE_TIP_NOT_ENOUGH); - tipNotEnoughState.errorPromptInfo = ZAppPromptFactory.buildAppPrompt(tipNotEnoughState.errorDetailInfo); - - var infeedExceptionState = virtualWarningState.find(AppFlagKey.InfeedExceptionState); - infeedExceptionState.state = true; // - infeedExceptionState.errorDetailInfo = FakeAppErrorFactory.buildAEHardwareError(); - infeedExceptionState.errorPromptInfo = ZAppPromptFactory.buildAppPrompt(infeedExceptionState.errorDetailInfo); - - var outfeedAreaFullState = virtualWarningState.find(AppFlagKey.OutfeedAreaFullState); - outfeedAreaFullState.state = true; // - outfeedAreaFullState.errorDetailInfo = FakeAppErrorFactory.buildError(A8kEcode.APPE_OUTFEED_AREA_IS_FULL); - outfeedAreaFullState.errorPromptInfo = ZAppPromptFactory.buildAppPrompt(outfeedAreaFullState.errorDetailInfo); - - var wasteBinFullState = virtualWarningState.find(AppFlagKey.WasteBinFull); - wasteBinFullState.state = true; // - wasteBinFullState.errorDetailInfo = FakeAppErrorFactory.buildError(A8kEcode.APPE_WAST_BIN_IS_FULL); - wasteBinFullState.errorPromptInfo = ZAppPromptFactory.buildAppPrompt(wasteBinFullState.errorDetailInfo); - - if (AppFlagKey.InfeedPPSFlag.enabled) - virtualWarningState.find(AppFlagKey.InfeedPPSFlag).state = true; //入料区光电 - if (AppFlagKey.OutfeedPPSFlag.enabled) - virtualWarningState.find(AppFlagKey.OutfeedPPSFlag).state = false; //入料区光电 - if (AppFlagKey.TubeholderChannelPPSFlag.enabled) - virtualWarningState.find(AppFlagKey.TubeholderChannelPPSFlag).state = true; //入料区光电 - if (AppFlagKey.PlateBoxLidPPSState.enabled) - virtualWarningState.find(AppFlagKey.PlateBoxLidPPSState).state = false; //入料区光电 - return virtualWarningState; - - } - - synchronized public DeviceWorkState getVirtualDeviceWorkState() { - DeviceWorkState deviceWorkState = new DeviceWorkState(); - deviceWorkState.workState = A8kWorkState.WORKING; - return deviceWorkState; - } - - synchronized public Integer getVirtualDeviceWorkStateVersion() { - //虚拟状态生成模式 - return Integer.MAX_VALUE; - } - - synchronized public OptScanModuleState getVirtualOptScanModuleState() { - OptScanModuleState optScanModuleState = new OptScanModuleState(); - optScanModuleState.state = OptScanModuleStateEnum.SCANNING; - optScanModuleState.sampleInfo = new SampleInfo( - "SAMPLEID-123456", 1, true, false, BloodType.WHOLE_BLOOD, "1234567890", "2250103_003" - ); - optScanModuleState.setProjInfo(new ProjBriefInfo(1, "hsCRP", "CA", "#DC143C")); - optScanModuleState.setProjId(1); - optScanModuleState.setLotId("CA123456"); - return optScanModuleState; - } - - synchronized public Integer getVirtualOptScanModuleStateVersion() { - //虚拟状态生成模式 - return Integer.MAX_VALUE; - } -} diff --git a/src/main/java/a8k/app/service/statemgr/AppFlagStateMgr.java b/src/main/java/a8k/app/service/statemgr/AppFlagStateMgr.java index d1abd87..7e2f1a0 100644 --- a/src/main/java/a8k/app/service/statemgr/AppFlagStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/AppFlagStateMgr.java @@ -3,22 +3,19 @@ package a8k.app.service.statemgr; import a8k.app.factory.ZAppPromptFactory; import a8k.app.i18n.Internationalization; -import a8k.app.service.DeviceVirtualStateMgrService; +import a8k.app.service.virtualstate.DeviceVirtualStateMgrService; import a8k.app.type.AppFlagKey; import a8k.app.type.AppFlagType; import a8k.app.type.DeviceRunMode; import a8k.app.type.DeviceWarningFlagStateGroup; import a8k.app.type.error.AppError; import a8k.app.type.ui.ZAppPromopt; -import a8k.app.utils.ZJsonHelper; import cn.hutool.core.util.ObjectUtil; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import java.util.Objects; - @Component @Slf4j @RequiredArgsConstructor @@ -51,7 +48,6 @@ public class AppFlagStateMgr { DeviceWarningFlagStateGroup deviceWarningFlagState = new DeviceWarningFlagStateGroup(); - DeviceWarningFlagStateGroup lastCpyDeviceWarningFlagState = new DeviceWarningFlagStateGroup(); //上次复制的状态 DeviceWarningFlagStateGroup virtualWarningState = new DeviceWarningFlagStateGroup(); //虚拟状态,用于前端状态测试 @@ -62,22 +58,15 @@ public class AppFlagStateMgr { continue; deviceWarningFlagState.states.add(new AppFlagState(flagKey, flagKey.flagType)); } - lastCpyDeviceWarningFlagState = ObjectUtil.clone(deviceWarningFlagState); //初始化时复制一份状态 virtualWarningState = deviceVirtualStateMgrService.getDeviceFlagStateVirtualStateInitVal(deviceWarningFlagState); } synchronized public DeviceWarningFlagStateGroup getFlagState() { if (gstate.isInMode(DeviceRunMode.VirtualStateGenerateMode)) { -// log.info("virtualWarningState: {}", ZJsonHelper.objectToJson(virtualWarningState)); return virtualWarningState; } - // // 正常状态下返回值 - // - if (!Objects.equals(lastCpyDeviceWarningFlagState.version, deviceWarningFlagState.version)) { - lastCpyDeviceWarningFlagState = ObjectUtil.clone(deviceWarningFlagState); - } - return lastCpyDeviceWarningFlagState; + return ObjectUtil.clone(deviceWarningFlagState); } synchronized public Integer getStateVersion() { diff --git a/src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java b/src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java index 3af940a..e0b35af 100644 --- a/src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java +++ b/src/main/java/a8k/app/service/statemgr/ConsumablesMgrService.java @@ -3,8 +3,7 @@ package a8k.app.service.statemgr; import a8k.app.dao.AppStatePersistenceDao; import a8k.app.dao.type.combination.ProjBuildInInfo; import a8k.app.dao.type.db.ProjExtInfoCard; -import a8k.app.factory.FakeA8kConsumableContainerFactory; -import a8k.app.service.DeviceVirtualStateMgrService; +import a8k.app.service.virtualstate.DeviceVirtualStateMgrService; import a8k.app.service.data.ProjInfoMgrService; import a8k.app.service.statemgr.consumables_mgr.LarBottleContainerStateMgr; import a8k.app.service.statemgr.consumables_mgr.LittBottleContainerStateMgr; diff --git a/src/main/java/a8k/app/service/statemgr/DeviceWorkStateMgrService.java b/src/main/java/a8k/app/service/statemgr/DeviceWorkStateMgrService.java index 967bad1..7c92912 100644 --- a/src/main/java/a8k/app/service/statemgr/DeviceWorkStateMgrService.java +++ b/src/main/java/a8k/app/service/statemgr/DeviceWorkStateMgrService.java @@ -1,18 +1,15 @@ package a8k.app.service.statemgr; -import a8k.app.service.DeviceVirtualStateMgrService; +import a8k.app.service.virtualstate.DeviceVirtualStateMgrService; 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; -import java.util.List; - @Component @Slf4j @RequiredArgsConstructor diff --git a/src/main/java/a8k/app/service/statemgr/GStateMgrService.java b/src/main/java/a8k/app/service/statemgr/GStateMgrService.java index 07aade1..24f6ee3 100644 --- a/src/main/java/a8k/app/service/statemgr/GStateMgrService.java +++ b/src/main/java/a8k/app/service/statemgr/GStateMgrService.java @@ -1,7 +1,7 @@ package a8k.app.service.statemgr; import a8k.app.i18n.Internationalization; -import a8k.app.service.DeviceVirtualStateMgrService; +import a8k.app.service.virtualstate.DeviceVirtualStateMgrService; import a8k.app.type.BoardVersions; import a8k.app.type.DeviceRunMode; import a8k.app.type.GState; diff --git a/src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java b/src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java index e002992..2020168 100644 --- a/src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/IncubationPlateStateMgr.java @@ -1,24 +1,20 @@ package a8k.app.service.statemgr; import a8k.app.factory.ZAppPromptFactory; -import a8k.app.channel.iflytophald.type.protocol.A8kEcode; -import a8k.app.service.DeviceVirtualStateMgrService; +import a8k.app.service.virtualstate.DeviceVirtualStateMgrService; import a8k.app.type.DeviceRunMode; -import a8k.app.type.a8k.BloodType; import a8k.app.type.a8k.pos.ConsumableInfo; import a8k.app.type.a8k.state.IncubationPlate; import a8k.app.type.a8k.state.IncubationSubTank; import a8k.app.type.a8k.state.SampleInfo; import a8k.app.type.a8k.state.enumtype.IncubationSubTankState; import a8k.app.type.a8k.pos.IncubatorPos; -import a8k.app.type.a8k.proj.ProjBriefInfo; import a8k.app.type.error.AppError; import a8k.app.dao.type.db.ProjExtInfoCard; import a8k.app.dao.type.combination.ProjBuildInInfo; import a8k.app.service.utils.ProjInfoUtils; import a8k.app.utils.ZTimeUtils; import cn.hutool.core.util.ObjectUtil; -import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; diff --git a/src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java b/src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java index e40e78b..fefd66d 100644 --- a/src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/OptScanModuleStateMgr.java @@ -1,16 +1,13 @@ package a8k.app.service.statemgr; -import a8k.app.service.DeviceVirtualStateMgrService; +import a8k.app.service.virtualstate.DeviceVirtualStateMgrService; import a8k.app.service.utils.ProjInfoUtils; import a8k.app.type.DeviceRunMode; -import a8k.app.type.a8k.BloodType; import a8k.app.type.a8k.state.IncubationRecordInfo; import a8k.app.type.a8k.state.OptScanModuleState; import a8k.app.type.a8k.state.SampleInfo; import a8k.app.type.a8k.state.enumtype.OptScanModuleStateEnum; -import a8k.app.type.a8k.proj.ProjBriefInfo; import a8k.app.dao.type.db.ProjExtInfoCard; -import a8k.app.service.data.UtilsProjectColorAllocer; import a8k.app.dao.type.combination.ProjBuildInInfo; import cn.hutool.core.util.ObjectUtil; import jakarta.annotation.Resource; diff --git a/src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java b/src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java index aa2670e..91b7fad 100644 --- a/src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/PreReactionStateMgr.java @@ -1,22 +1,18 @@ package a8k.app.service.statemgr; import a8k.app.constant.AppConstant; -import a8k.app.factory.FakeA8kConsumableContainerFactory; -import a8k.app.service.DeviceVirtualStateMgrService; +import a8k.app.service.virtualstate.DeviceVirtualStateMgrService; 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.ProjectPreProcessContext; 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 lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/a8k/app/service/statemgr/TubeStateMgr.java b/src/main/java/a8k/app/service/statemgr/TubeStateMgr.java index 1924f80..3163a6e 100644 --- a/src/main/java/a8k/app/service/statemgr/TubeStateMgr.java +++ b/src/main/java/a8k/app/service/statemgr/TubeStateMgr.java @@ -2,7 +2,7 @@ package a8k.app.service.statemgr; import a8k.app.dao.type.db.DeviceStatistic; import a8k.app.factory.ZAppPromptFactory; -import a8k.app.service.DeviceVirtualStateMgrService; +import a8k.app.service.virtualstate.DeviceVirtualStateMgrService; import a8k.app.service.analyzer.ConsumableStateAnalyzerService; import a8k.app.type.DeviceRunMode; import a8k.app.type.a8k.pos.ConsumableInfo; diff --git a/src/main/java/a8k/app/service/virtualstate/DeviceVirtualStateMgrService.java b/src/main/java/a8k/app/service/virtualstate/DeviceVirtualStateMgrService.java new file mode 100644 index 0000000..b3cc44d --- /dev/null +++ b/src/main/java/a8k/app/service/virtualstate/DeviceVirtualStateMgrService.java @@ -0,0 +1,250 @@ +package a8k.app.service.virtualstate; + + +import a8k.app.channel.iflytophald.type.protocol.A8kEcode; +import a8k.app.constant.AppConstant; +import a8k.app.factory.FakeA8kConsumableContainerFactory; +import a8k.app.factory.FakeAppErrorFactory; +import a8k.app.factory.ZAppPromptFactory; +import a8k.app.service.utils.ProjInfoUtils; +import a8k.app.type.AppFlagKey; +import a8k.app.type.DeviceWarningFlagStateGroup; +import a8k.app.type.PreReactionGrid; +import a8k.app.type.PreReactionGridGroup; +import a8k.app.type.a8k.BloodType; +import a8k.app.type.a8k.ConsumableGroup; +import a8k.app.type.a8k.LittleBottleConsumableType; +import a8k.app.type.a8k.container.A8kConsumableContainer; +import a8k.app.type.a8k.proj.ProjBriefInfo; +import a8k.app.type.a8k.state.*; +import a8k.app.type.a8k.state.enumtype.*; +import a8k.app.type.error.AppError; +import a8k.app.type.exception.AppException; +import cn.hutool.core.util.ObjectUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Date; + +@Component +@RequiredArgsConstructor +@Slf4j +public class DeviceVirtualStateMgrService { + + private final TubeVirtualStateGenerator tubeVirtualStateGenerator; + + public TubeHolder getVirtualTubeHolderState() { + return tubeVirtualStateGenerator.getVirtualTubeHolderState(); + } + + public EmergencyTubePos getVirtualEmergencyTube() { + return tubeVirtualStateGenerator.getVirtualEmergencyTube(); + } + + public Integer getVirtualTubeStateVersion() { + return tubeVirtualStateGenerator.getVirtualTubeStateVersion(); + } + + public void setEmptyTubeState(TubeState emptyTubeState) { + tubeVirtualStateGenerator.setEmptyTubeState(emptyTubeState); + } + + + synchronized public A8kConsumableContainer getVirtualConsumableContainerState() { + //虚拟状态生成模式 + A8kConsumableContainer state = new A8kConsumableContainer(); + state.tips[0].tipNum = 100; + state.tips[1].tipNum = 101; + state.tips[2].tipNum = 102; + for (int i = 0; i < 6; i++) { + try { + FakeA8kConsumableContainerFactory.buildA8kConsumableContainerState(state, i); + } catch (AppException ignored) { + } + } + return state; + } + + synchronized public Integer getVirtualConsumableContainerStateVersion() { + //虚拟状态生成模式 + return Integer.MAX_VALUE; + } + + + /** + * 获取虚拟孵育盘状态 + * @return 虚拟孵育盘状态 + */ + synchronized public IncubationPlate getVirtualIncubationPlateState() { + IncubationPlate incubationPlate = new IncubationPlate(); + int i = 0; + for (IncubationSubTank subtank : incubationPlate.subtanks) { + i++; + switch (i) { + case 1 -> subtank.state = IncubationSubTankState.RESERVED; + case 2 -> subtank.state = IncubationSubTankState.WAITING_FOR_DROP; + case 3 -> subtank.state = IncubationSubTankState.INCUBATING; + case 4 -> subtank.state = IncubationSubTankState.ERROR; + case 5 -> subtank.state = IncubationSubTankState.INCUBATION_COMPLETE; + default -> subtank.state = IncubationSubTankState.EMPTY; + } + + subtank.sampleInfo = new SampleInfo( + "250109_001E01", 0, false, false, BloodType.WHOLE_BLOOD, "B3A7KK8DKF", "250109_001E" + ); + + + subtank.sampleInfo.bloodType = BloodType.WHOLE_BLOOD; + subtank.sampleInfo.sampleBarcode = "112334455667"; + subtank.sampleInfo.userid = "250109_001E"; + subtank.projInfo = new ProjBriefInfo(); + subtank.projInfo.projId = 1; + subtank.projInfo.projName = "hsCRP"; + subtank.projInfo.projShortName = "CA"; + subtank.projInfo.color = "#DC143C"; + subtank.sampleInfo.sampleId = "250109_001E01"; + subtank.projId = 1; + subtank.lotId = "CA123456"; + subtank.isEmergency = i == 2; + if (subtank.state.equals(IncubationSubTankState.ERROR)) { + subtank.error = new AppError(A8kEcode.PROJ_CARD_ERROR_WRONG_UNSUPPORTED, ""); + subtank.errorInfo = ZAppPromptFactory.buildAppPrompt(subtank.error); + } + subtank.startIncubatedTime = new Date().getTime(); + subtank.incubatedTimeSec = 3 * 60; + subtank.remainTimeSec = 3 * 60; + } + return incubationPlate; + } + + + public PreReactionGridGroup getFakePreReactionGridGroup(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; + var projBuildInInfo = FakeA8kConsumableContainerFactory.buildFakeProjBuildInInfo(group.off); + gridGroup.projBriefInfo = ProjInfoUtils.buildProjBrefInfo(projBuildInInfo); + gridGroup.version = 10; + for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) { + + gridGroup.grids.get(i).projId = projBuildInInfo.projId; + gridGroup.grids.get(i).projBuildinInfo = projBuildInInfo; + gridGroup.grids.get(i).projExtInfoCard = null; + + switch (i / 5) { + case 0 -> { + gridGroup.grids.get(i).state = PreReactionGrid.State.UNINSTALL; + } + case 1 -> { + gridGroup.grids.get(i).state = PreReactionGrid.State.USED; + } + + case 2 -> { + gridGroup.grids.get(i).state = PreReactionGrid.State.REACTION_COMPLETED; + gridGroup.grids.get(i).sampleInfo.userid = "UID123"; + } + case 3 -> { + gridGroup.grids.get(i).state = PreReactionGrid.State.REACTING; + gridGroup.grids.get(i).sampleInfo.userid = "UID123"; + gridGroup.grids.get(i).reactionRemainingTime = 3 * 60L; + } + case 4 -> { + gridGroup.grids.get(i).state = PreReactionGrid.State.TO_BE_USED; + } + } + } + return gridGroup; + } + + public SensorState getVirtualSensorState() { + SensorState sensorState = new SensorState(); + sensorState.setPboxTemperature(24); + sensorState.setIncubateBoxTemperature(25); + sensorState.setWasteBinFullFlag(false); + return sensorState; + } + + // + // VIRTUAL_OPERATION + // + public DeviceWarningFlagStateGroup getDeviceFlagStateVirtualStateInitVal(DeviceWarningFlagStateGroup deviceWarningFlagState) { + + DeviceWarningFlagStateGroup virtualWarningState = ObjectUtil.clone(deviceWarningFlagState); //初始化时复制一份状态版本号 + virtualWarningState.version = 10000; + + //设置VirtualState初始值 + var consumeNotEnoughState = virtualWarningState.find(AppFlagKey.ConsumeNotEnoughState); + consumeNotEnoughState.state = true; // + consumeNotEnoughState.errorDetailInfo = FakeAppErrorFactory.buildAEConsumeNotEnoughError(); + consumeNotEnoughState.errorPromptInfo = ZAppPromptFactory.buildAppPrompt(consumeNotEnoughState.errorDetailInfo); + + var tipNotEnoughState = virtualWarningState.find(AppFlagKey.TipNotEnoughState); + tipNotEnoughState.state = true; // + tipNotEnoughState.errorDetailInfo = FakeAppErrorFactory.buildError(A8kEcode.APPE_TIP_NOT_ENOUGH); + tipNotEnoughState.errorPromptInfo = ZAppPromptFactory.buildAppPrompt(tipNotEnoughState.errorDetailInfo); + + var infeedExceptionState = virtualWarningState.find(AppFlagKey.InfeedExceptionState); + infeedExceptionState.state = true; // + infeedExceptionState.errorDetailInfo = FakeAppErrorFactory.buildAEHardwareError(); + infeedExceptionState.errorPromptInfo = ZAppPromptFactory.buildAppPrompt(infeedExceptionState.errorDetailInfo); + + var outfeedAreaFullState = virtualWarningState.find(AppFlagKey.OutfeedAreaFullState); + outfeedAreaFullState.state = true; // + outfeedAreaFullState.errorDetailInfo = FakeAppErrorFactory.buildError(A8kEcode.APPE_OUTFEED_AREA_IS_FULL); + outfeedAreaFullState.errorPromptInfo = ZAppPromptFactory.buildAppPrompt(outfeedAreaFullState.errorDetailInfo); + + var wasteBinFullState = virtualWarningState.find(AppFlagKey.WasteBinFull); + wasteBinFullState.state = true; // + wasteBinFullState.errorDetailInfo = FakeAppErrorFactory.buildError(A8kEcode.APPE_WAST_BIN_IS_FULL); + wasteBinFullState.errorPromptInfo = ZAppPromptFactory.buildAppPrompt(wasteBinFullState.errorDetailInfo); + + if (AppFlagKey.InfeedPPSFlag.enabled) + virtualWarningState.find(AppFlagKey.InfeedPPSFlag).state = true; //入料区光电 + if (AppFlagKey.OutfeedPPSFlag.enabled) + virtualWarningState.find(AppFlagKey.OutfeedPPSFlag).state = false; //入料区光电 + if (AppFlagKey.TubeholderChannelPPSFlag.enabled) + virtualWarningState.find(AppFlagKey.TubeholderChannelPPSFlag).state = true; //入料区光电 + if (AppFlagKey.PlateBoxLidPPSState.enabled) + virtualWarningState.find(AppFlagKey.PlateBoxLidPPSState).state = false; //入料区光电 + return virtualWarningState; + + } + + synchronized public DeviceWorkState getVirtualDeviceWorkState() { + DeviceWorkState deviceWorkState = new DeviceWorkState(); + deviceWorkState.workState = A8kWorkState.WORKING; + return deviceWorkState; + } + + synchronized public Integer getVirtualDeviceWorkStateVersion() { + //虚拟状态生成模式 + return Integer.MAX_VALUE; + } + + synchronized public OptScanModuleState getVirtualOptScanModuleState() { + OptScanModuleState optScanModuleState = new OptScanModuleState(); + optScanModuleState.state = OptScanModuleStateEnum.SCANNING; + optScanModuleState.sampleInfo = new SampleInfo( + "SAMPLEID-123456", 1, true, false, BloodType.WHOLE_BLOOD, "1234567890", "2250103_003" + ); + optScanModuleState.setProjInfo(new ProjBriefInfo(1, "hsCRP", "CA", "#DC143C")); + optScanModuleState.setProjId(1); + optScanModuleState.setLotId("CA123456"); + return optScanModuleState; + } + + synchronized public Integer getVirtualOptScanModuleStateVersion() { + //虚拟状态生成模式 + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/a8k/app/service/virtualstate/TubeVirtualStateGenerator.java b/src/main/java/a8k/app/service/virtualstate/TubeVirtualStateGenerator.java new file mode 100644 index 0000000..d408285 --- /dev/null +++ b/src/main/java/a8k/app/service/virtualstate/TubeVirtualStateGenerator.java @@ -0,0 +1,106 @@ +package a8k.app.service.virtualstate; + +import a8k.app.factory.FakeA8kConsumableContainerFactory; +import a8k.app.factory.FakeAppErrorFactory; +import a8k.app.factory.ZAppPromptFactory; +import a8k.app.type.a8k.BloodType; +import a8k.app.type.a8k.proj.ProjBriefInfo; +import a8k.app.type.a8k.state.EmergencyTubePos; +import a8k.app.type.a8k.state.Tube; +import a8k.app.type.a8k.state.TubeHolder; +import a8k.app.type.a8k.state.enumtype.TubeHolderState; +import a8k.app.type.a8k.state.enumtype.TubeState; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class TubeVirtualStateGenerator { + + TubeState emptyTubeState = TubeState.EMPTY; + Integer stateVersion = Integer.MAX_VALUE / 2; + + void addProjInfoToTube(Tube tube, Integer projId) { + ProjBriefInfo projBriefInfo = FakeA8kConsumableContainerFactory.buildFakeProjBriefInfo(projId); + tube.getProjInfo().add(projBriefInfo); + tube.getProjIds().add(projBriefInfo.projId); + } + + Tube createFakeTube(Integer pos) { + Tube tube = new Tube(pos); + tube.setSampleId("250109_001E0" + pos); + tube.setBloodType(BloodType.WHOLE_BLOOD); + tube.setSampleBarcode("112334455667"); + tube.setUserid(String.format("250109_%dE", pos)); + + switch (pos) { + case 1 -> tube.setState(TubeState.EMPTY); + case 2 -> { + tube.setState(TubeState.ERROR); + tube.setError(FakeAppErrorFactory.buildAEConsumeNotEnoughError()); + tube.setErrorInfo(ZAppPromptFactory.buildAppPrompt(tube.getError())); + + addProjInfoToTube(tube, 1); + addProjInfoToTube(tube, 2); + + } + case 3, 4, 5, 6 -> { + tube.setState(TubeState.PROCESS_COMPLETE); + addProjInfoToTube(tube, 1); + addProjInfoToTube(tube, 2); + addProjInfoToTube(tube, 3); + } + case 7 -> { + tube.setState(TubeState.PROCESSING); + addProjInfoToTube(tube, 1); + addProjInfoToTube(tube, 2); + addProjInfoToTube(tube, 3); + } + case 8, 9, 10 -> { + tube.setState(TubeState.TO_BE_PROCESSED); + addProjInfoToTube(tube, 1); + addProjInfoToTube(tube, 2); + } + } + tube.setIsHighTube(pos % 2 == 0); //假设偶数位置为高位管 + + return tube; + } + + public TubeHolder getVirtualTubeHolderState() { + TubeHolder tubeHolder = new TubeHolder(); + tubeHolder.setTubes(new Tube[]{ + createFakeTube(1), + createFakeTube(2), + createFakeTube(3), + createFakeTube(4), + createFakeTube(5), + createFakeTube(6), + createFakeTube(7), + createFakeTube(8), + createFakeTube(9), + createFakeTube(10) + }); + tubeHolder.setState(TubeHolderState.PROCESSING); + return tubeHolder; + } + + public EmergencyTubePos getVirtualEmergencyTube() { + var tubePosState = new EmergencyTubePos(); + tubePosState.tube = createFakeTube(0); + tubePosState.tube.setPos(0); + tubePosState.tube.setIsEmergency(true); + tubePosState.tube.setState(emptyTubeState); + return tubePosState; + } + + public Integer getVirtualTubeStateVersion() { + //虚拟状态生成模式 + return stateVersion; + } + + public void setEmptyTubeState(TubeState emptyTubeState) { + this.emptyTubeState = emptyTubeState; + stateVersion++; + } +} diff --git a/src/main/java/a8k/app/type/DeviceWarningFlagStateGroup.java b/src/main/java/a8k/app/type/DeviceWarningFlagStateGroup.java index 6a46388..411d004 100644 --- a/src/main/java/a8k/app/type/DeviceWarningFlagStateGroup.java +++ b/src/main/java/a8k/app/type/DeviceWarningFlagStateGroup.java @@ -6,6 +6,13 @@ import java.util.ArrayList; import java.util.List; public class DeviceWarningFlagStateGroup implements java.io.Serializable { + + public enum NotificationState { + Normal, //通知 + Warn, //警告 + Error, //错误 + } + public List states = new ArrayList<>(); public Integer version = 0; //状态版本号 @@ -19,6 +26,7 @@ public class DeviceWarningFlagStateGroup implements java.io.Serializable { return false; //如果没有任意一个状态为true,则返回false } + // 别删,被前端使用 public Boolean isHasErrorTriggerFlag() { for (AppFlagStateMgr.AppFlagState state : states) { if (state.flagType.equals(AppFlagType.ErrorFlag) && state.state) { @@ -28,13 +36,34 @@ public class DeviceWarningFlagStateGroup implements java.io.Serializable { return false; //如果没有任意一个状态为true,则返回false } + // 别删,被前端使用 + public Integer getWarningAndErrorFlagTriggerNum() { + int count = 0; + for (AppFlagStateMgr.AppFlagState state : states) { + if ((state.flagType.equals(AppFlagType.WarningFlag) || state.flagType.equals(AppFlagType.ErrorFlag)) && state.state) { + count++; //如果有任意一个状态为true,则计数 + } + } + return count; //返回计数 + } + + // 别删,被前端使用 + public NotificationState getNotificationState() { + if (isHasErrorTriggerFlag()) { + return NotificationState.Error; //如果有错误标识位,则返回错误状态 + } else if (isHasWarningTriggerFlag()) { + return NotificationState.Warn; //如果有警告标识位,则返回警告状态 + } else { + return NotificationState.Normal; //否则返回正常状态 + } + } + public AppFlagStateMgr.AppFlagState find(AppFlagKey appFlagKey) { for (AppFlagStateMgr.AppFlagState state : states) { if (state.keyName.equals(appFlagKey)) { return state; } } -// AppFlagStateMgr.log.error("find: Unknown DeviceWarningFlagState: {}", appFlagKey.name()); return null; //如果没有找到,返回null } } diff --git a/src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java b/src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java index 4960648..f70af26 100644 --- a/src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java +++ b/src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java @@ -9,8 +9,7 @@ import a8k.extui.page.driver.*; import a8k.extui.page.driver.pipette_module.*; import a8k.extui.page.extapp.*; import a8k.extui.page.extapp.P02A8kTemperaturaVerfication; -import a8k.extui.page.extapp.debug_assistant.IDCardDataGeneratorPage; -import a8k.extui.page.extapp.debug_assistant.VirtualReportModeOperationPage; +import a8k.extui.page.extapp.debug_assistant.*; import a8k.extui.page.extapp.profession_test.ExperimentConsistencyTestingPage; import a8k.extui.page.extapp.profession_test.P01PipetteGunVerification; import a8k.extui.page.extsetting.db.*; @@ -21,9 +20,7 @@ import a8k.extui.page.measurement.*; import a8k.extui.page.optalgotest.OptAlgoTestPage; import a8k.extui.page.test.codetest.OptFormulaTestPage; import a8k.extui.page.test.codetest.OptFormulaTestPageV2; -import a8k.extui.page.extapp.debug_assistant.FakeReactionRecordGeneratorPage; -import a8k.extui.page.extapp.debug_assistant.VirtualEventGeneratorPage; import a8k.extui.page.extsetting.pos_calibration.*; import a8k.extui.page.test.stress_test.PipetteGunStressTest; import a8k.extui.page.test.verification.*; @@ -215,7 +212,8 @@ public class ExtApiPageGroupCfgMgr { new Menu(FakeReactionRecordGeneratorPage.class, "虚拟反应记录生成"), new Menu(VirtualEventGeneratorPage.class, "虚拟事件生成"), new Menu(IDCardDataGeneratorPage.class, "ID卡数据生成器"), - new Menu(VirtualReportModeOperationPage.class, "虚拟报告模式操作") + new Menu(VirtualReportModeOperationPage.class, "虚拟报告模式操作"), + new Menu(DeviceVirtualStateMgrSettingPage.class,"虚拟状态上报配置") )), new Menu(UsrOperationSimulationPage.class, "用户行为模拟器"), new Menu(CodeGeneratorPage.class, "条码字符生成工具") diff --git a/src/main/java/a8k/extui/page/extapp/debug_assistant/DeviceVirtualStateMgrSettingPage.java b/src/main/java/a8k/extui/page/extapp/debug_assistant/DeviceVirtualStateMgrSettingPage.java new file mode 100644 index 0000000..12b943a --- /dev/null +++ b/src/main/java/a8k/extui/page/extapp/debug_assistant/DeviceVirtualStateMgrSettingPage.java @@ -0,0 +1,35 @@ +package a8k.extui.page.extapp.debug_assistant; + +import a8k.app.service.background.AppEventBusService; +import a8k.app.service.data.ProjInfoMgrService; +import a8k.app.service.statemgr.AppFlagStateMgr; +import a8k.app.service.virtualstate.DeviceVirtualStateMgrService; +import a8k.app.type.a8k.state.enumtype.TubeState; +import a8k.extui.mgr.ExtApiPageMgr; +import a8k.extui.type.ExtUIPageCfg; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +@Slf4j +public class DeviceVirtualStateMgrSettingPage { + + private final ExtApiPageMgr extApiPageMgr; + private final DeviceVirtualStateMgrService deviceVirtualStateMgrService; + + public void setEmergencyTubeState(TubeState tubeState) { + deviceVirtualStateMgrService.setEmptyTubeState(tubeState); + } + + + @PostConstruct + void init() { + ExtUIPageCfg page = new ExtUIPageCfg(this); + page.addFunction("设置应急管状态", this::setEmergencyTubeState); + extApiPageMgr.addPage(page); + } +}