diff --git a/src/main/java/club/joylink/xiannccda/alert/core/AlertManager.java b/src/main/java/club/joylink/xiannccda/alert/core/AlertManager.java index 05b1c7d..b84247f 100644 --- a/src/main/java/club/joylink/xiannccda/alert/core/AlertManager.java +++ b/src/main/java/club/joylink/xiannccda/alert/core/AlertManager.java @@ -58,6 +58,9 @@ public class AlertManager extends EventEmitter { return getInstance("default"); } + public void clearAlertDataMsg(Integer lineId) { + DEVICE_ALTER_TABLE.clear(); + } public boolean putAlterDevice(Integer lineId, String customName, String deviceName) { AlertTableDetail detail = DEVICE_ALTER_TABLE.get(lineId, customName); diff --git a/src/main/java/club/joylink/xiannccda/ats/message/OccTcpClientConnection.java b/src/main/java/club/joylink/xiannccda/ats/message/OccTcpClientConnection.java index b0be186..81ab63d 100644 --- a/src/main/java/club/joylink/xiannccda/ats/message/OccTcpClientConnection.java +++ b/src/main/java/club/joylink/xiannccda/ats/message/OccTcpClientConnection.java @@ -1,5 +1,8 @@ package club.joylink.xiannccda.ats.message; +import club.joylink.xiannccda.constants.SystemContext; +import club.joylink.xiannccda.ws.msg.SystemWarnEvent; +import club.joylink.xiannccda.ws.msg.SystemWarnEvent.SystemWarnConnStateEvent; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -48,19 +51,23 @@ public class OccTcpClientConnection { final ReconnectState reconnectState; + @Getter + final boolean isRealPort; + public void write(MessageData messageData) { if (Objects.nonNull(this.channel)) { this.channel.writeAndFlush(List.of(messageData)); } } - public OccTcpClientConnection(XianOccMessagingClient client, String host, int port, boolean collectorData) { + public OccTcpClientConnection(XianOccMessagingClient client, String host, int port, boolean collectorData, boolean isRealPort) { this.client = client; this.host = host; this.port = port; this.group = new NioEventLoopGroup(1); this.bootstrap = new Bootstrap(); + this.isRealPort = isRealPort; OccTcpClientConnection self = this; bootstrap.group(group) .channel(NioSocketChannel.class) @@ -101,6 +108,7 @@ public class OccTcpClientConnection { this.channel = channelFuture.channel(); this.connected = true; this.client.requestBaseData(); + SystemContext.publishEvent(new SystemWarnConnStateEvent(this.client.getLineId(), this)); } }); channelFuture.channel().closeFuture().addListener(listener -> { @@ -109,7 +117,9 @@ public class OccTcpClientConnection { this.connected = false; this.channel = null; this.client.resetRequestBaseDataFlag(); + } + SystemContext.publishEvent(new SystemWarnConnStateEvent(this.client.getLineId(), this)); this.reconnectState.resetState(); }); } diff --git a/src/main/java/club/joylink/xiannccda/ats/message/XianOccMessagingClient.java b/src/main/java/club/joylink/xiannccda/ats/message/XianOccMessagingClient.java index 6ffc855..c1d38a5 100644 --- a/src/main/java/club/joylink/xiannccda/ats/message/XianOccMessagingClient.java +++ b/src/main/java/club/joylink/xiannccda/ats/message/XianOccMessagingClient.java @@ -63,8 +63,8 @@ public class XianOccMessagingClient { this.lineId = lineId; this.requestBaseTime = TimeUnit.HOURS.toMillis(receiveMsgTimeout); // 创建实时和非实时消息连接 - this.rtConnection = new OccTcpClientConnection(this, host, realPort, collectorData); - this.nrtConnection = new OccTcpClientConnection(this, host, unRealPort, false); + this.rtConnection = new OccTcpClientConnection(this, host, realPort, collectorData, true); + this.nrtConnection = new OccTcpClientConnection(this, host, unRealPort, false, false); this.timeOutHandler.addConnection(this.rtConnection); this.timeOutHandler.addConnection(this.nrtConnection); diff --git a/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/AbstractData.java b/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/AbstractData.java index 2a190b6..e44411c 100644 --- a/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/AbstractData.java +++ b/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/AbstractData.java @@ -18,4 +18,5 @@ public abstract class AbstractData { public abstract void clear(); + public abstract void reset(); } diff --git a/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/DeviceStatusData.java b/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/DeviceStatusData.java index 6564ab4..e0f05f4 100644 --- a/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/DeviceStatusData.java +++ b/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/DeviceStatusData.java @@ -1,19 +1,22 @@ package club.joylink.xiannccda.ats.message.collect.datasource; import club.joylink.xiannccda.ats.message.collect.DeviceStatusDataOperate; +import club.joylink.xiannccda.dto.protos.DeviceStatusProto; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.google.protobuf.GeneratedMessageV3; import com.google.protobuf.GeneratedMessageV3.Builder; import com.google.protobuf.Message; import com.google.protobuf.MessageOrBuilder; -import java.util.Collections; +import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import lombok.Getter; +import org.apache.commons.lang3.StringUtils; @Getter public class DeviceStatusData extends AbstractData { @@ -106,4 +109,51 @@ public class DeviceStatusData extends AbstractData { this.allDeviceMap.clear(); this.statusVOMap.clear(); } + + @Override + public void reset() { + for (Entry> mapEntry : this.allDeviceMap.entrySet()) { + String deviceType = mapEntry.getKey(); + Collection allDevice = mapEntry.getValue().values(); + if (StringUtils.equals(DeviceStatusProto.Rtu.getDescriptor().getName(), deviceType)) { + this.resetRtu(allDevice); + } else if (StringUtils.equals(DeviceStatusProto.Switch.getDescriptor().getName(), deviceType)) { + this.resetSwitch(allDevice); + } else if (StringUtils.equals(DeviceStatusProto.Track.getDescriptor().getName(), deviceType)) { + this.resetTrack(allDevice); + } + } + } + + + private void resetRtu(Collection builders) { + for (Builder builder : builders) { + if (builder instanceof DeviceStatusProto.Rtu.Builder b) { + b.setIpRtuStusDown(false); + } + } + } + + private void resetSwitch(Collection builders) { + for (Builder builder : builders) { + if (builder instanceof DeviceStatusProto.Switch.Builder b) { + b.setIpSingleSwitchStusLostIndication(false); + b.setIpSingleSwitchStusLocked(false); + b.setIpSingleSwitchStusCbtcOccupied(false); + b.setIpSingleSwitchStusCiOccupied(false); + } + } + } + + private void resetTrack(Collection builders) { + for (Builder builder : builders) { + if (builder instanceof DeviceStatusProto.Track.Builder b) { + b.setLocked(false); + b.setBlocked(false); + b.setCiOccupied(false); + b.setCbtcOccupied(false); + b.setAtcInvalid(false); + } + } + } } diff --git a/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/InUsedScheduleData.java b/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/InUsedScheduleData.java index 61ccc40..2b32ebe 100644 --- a/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/InUsedScheduleData.java +++ b/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/InUsedScheduleData.java @@ -63,5 +63,10 @@ public class InUsedScheduleData extends AbstractData { trainSchedule.clear(); } + @Override + public void reset() { + + } + } diff --git a/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/InterLockData.java b/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/InterLockData.java index 3e7e685..65b81ea 100644 --- a/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/InterLockData.java +++ b/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/InterLockData.java @@ -167,6 +167,11 @@ public class InterLockData extends AbstractData { } + @Override + public void reset() { + + } + public static class InterLockDetail { public InterLockDetail(AreaConfigVO areaConfigVO) { diff --git a/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/TrainDataSource.java b/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/TrainDataSource.java index 7db65e1..09e9ef9 100644 --- a/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/TrainDataSource.java +++ b/src/main/java/club/joylink/xiannccda/ats/message/collect/datasource/TrainDataSource.java @@ -164,6 +164,11 @@ public class TrainDataSource extends AbstractData { this.trainOnDeviceTrackMap.clear(); } + @Override + public void reset() { + + } + public enum TrainTypeStatus { TRAIN_BLOCK("TrainBlock", "block"), TRAIN_RECORD("TrainRemove", "remove"), TRAIN_REMOVE("TrainRecord", "record"); /** diff --git a/src/main/java/club/joylink/xiannccda/constants/SystemContext.java b/src/main/java/club/joylink/xiannccda/constants/SystemContext.java index 4cbae42..a97410b 100644 --- a/src/main/java/club/joylink/xiannccda/constants/SystemContext.java +++ b/src/main/java/club/joylink/xiannccda/constants/SystemContext.java @@ -1,6 +1,7 @@ package club.joylink.xiannccda.constants; import club.joylink.xiannccda.configuration.pros.OccNotHandlePros; +import club.joylink.xiannccda.ws.msg.SystemWarnEvent; import lombok.Getter; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; @@ -29,6 +30,10 @@ public class SystemContext implements ApplicationContextAware { return cu.notMatchHandle(lineId, rtuId); } + public static void publishEvent(SystemWarnEvent event) { + appContext.publishEvent(event); + } + @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { diff --git a/src/main/java/club/joylink/xiannccda/controller/AlertMockController.java b/src/main/java/club/joylink/xiannccda/controller/AlertMockController.java index a654041..6d2603b 100644 --- a/src/main/java/club/joylink/xiannccda/controller/AlertMockController.java +++ b/src/main/java/club/joylink/xiannccda/controller/AlertMockController.java @@ -9,7 +9,9 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; +import lombok.Getter; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -35,6 +37,14 @@ public class AlertMockController { alertMockService.setAlert2(alertMockDTO); } + @SecurityRequirement(name = "jwt") + @Operation(summary = "初始化") + @ApiResponse(description = "初始化") + @GetMapping("/reset/{lineId}") + public void reset(@PathVariable(name = "lineId") Integer lineId) { + this.alertMockService.reset(lineId); + } + @SecurityRequirement(name = "jwt") @Operation(summary = "设置模拟故障") @ApiResponse(description = "设置模拟故障") diff --git a/src/main/java/club/joylink/xiannccda/service/AlertMockService.java b/src/main/java/club/joylink/xiannccda/service/AlertMockService.java index 22815f3..ef741f5 100644 --- a/src/main/java/club/joylink/xiannccda/service/AlertMockService.java +++ b/src/main/java/club/joylink/xiannccda/service/AlertMockService.java @@ -5,7 +5,11 @@ import club.joylink.xiannccda.alert.NccAlertInfo; import club.joylink.xiannccda.alert.core.AlertDeviceType; import club.joylink.xiannccda.alert.core.AlertManager; import club.joylink.xiannccda.ats.cache.LineGraphicDataRepository; +import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository; +import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum; import club.joylink.xiannccda.ats.message.collect.DeviceStatusDataOperate; +import club.joylink.xiannccda.ats.message.collect.datasource.AbstractData; +import club.joylink.xiannccda.ats.message.collect.datasource.DeviceStatusData; import club.joylink.xiannccda.ats.message.convertor.DeviceStatusConvertor; import club.joylink.xiannccda.constants.SystemContext; import club.joylink.xiannccda.dto.mock.show.BlueAlertMockDTO; @@ -32,10 +36,13 @@ import club.joylink.xiannccda.mock.message.occ.MockOccServer; import club.joylink.xiannccda.vo.AreaConfigVO; import com.alibaba.fastjson2.JSONObject; import com.google.protobuf.GeneratedMessageV3; +import com.google.protobuf.GeneratedMessageV3.Builder; import com.google.protobuf.MessageOrBuilder; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; @@ -76,6 +83,18 @@ public class AlertMockService { alertManager.emit(alertInfo); } + public void reset(Integer lineId) { + DeviceStatusData deviceStatusData = DeviceDataRepository.findDataSouce(lineId.toString(), DataTypeEnum.DEVICE); + deviceStatusData.reset(); + AbstractData trainData = DeviceDataRepository.findDataSouce(lineId.toString(), DataTypeEnum.TRAIN); + trainData.clear(); + AbstractData planData = DeviceDataRepository.findDataSouce(lineId.toString(), DataTypeEnum.TRAIN_PLAN); + planData.clear(); + AlertManager alertManager = AlertManager.getDefault(); + alertManager.clearAlertDataMsg(lineId); + } + + @Value("${mock-alert-test}") private boolean mockTest; diff --git a/src/main/java/club/joylink/xiannccda/service/LineDeviceStatusService.java b/src/main/java/club/joylink/xiannccda/service/LineDeviceStatusService.java index 5d79c10..81acc43 100644 --- a/src/main/java/club/joylink/xiannccda/service/LineDeviceStatusService.java +++ b/src/main/java/club/joylink/xiannccda/service/LineDeviceStatusService.java @@ -3,6 +3,7 @@ package club.joylink.xiannccda.service; import club.joylink.xiannccda.ws.LineDeviceMessageServer; import club.joylink.xiannccda.ws.LineNetMessageServer; import club.joylink.xiannccda.ws.LineTrainMessageServer; +import club.joylink.xiannccda.ws.SystemInfoStateMessageServer; import club.joylink.xiannccda.ws.WsMessageServerManager; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; @@ -26,5 +27,7 @@ public class LineDeviceStatusService { wsMessageServerManager.registerMessageServer(new LineNetMessageServer()); wsMessageServerManager.registerMessageServer(new LineTrainMessageServer()); wsMessageServerManager.registerMessageServer(new LineDeviceMessageServer()); + wsMessageServerManager.registerMessageServer(new SystemInfoStateMessageServer()); + } } diff --git a/src/main/java/club/joylink/xiannccda/ws/SystemInfoStateMessageServer.java b/src/main/java/club/joylink/xiannccda/ws/SystemInfoStateMessageServer.java new file mode 100644 index 0000000..1d833b0 --- /dev/null +++ b/src/main/java/club/joylink/xiannccda/ws/SystemInfoStateMessageServer.java @@ -0,0 +1,46 @@ +package club.joylink.xiannccda.ws; + +import club.joylink.xiannccda.dto.protos.SystemWarnMsgProto; +import club.joylink.xiannccda.dto.protos.SystemWarnMsgProto.WarnMessage; +import club.joylink.xiannccda.ws.msg.SystemWarnListener; +import java.util.List; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; + +/** + * 系统相关信息 + */ +@Slf4j +public class SystemInfoStateMessageServer implements IMessageServer { + + private final static String SUBSCRIPTION_PATH = "/queue/line/sysi"; + + @Override + public String getDestinationPattern() { + return SUBSCRIPTION_PATH; + } + + @Override + public Object onSubscription(String destination, Map paramMap) { + return this.lineMessage().toByteArray(); + } + + + @Override + public int getInterval() { + return 4000; + } + + @Override + public List onTick() { + + return List.of(new TopicMessage(SUBSCRIPTION_PATH, this.lineMessage().toByteArray())); + } + + private SystemWarnMsgProto.WarnLineMessage lineMessage() { + SystemWarnMsgProto.WarnLineMessage.Builder lineMsg = SystemWarnMsgProto.WarnLineMessage.newBuilder(); + List msgs = SystemWarnListener.getAllSystemWarnBuild(); + lineMsg.addAllMsgs(msgs); + return lineMsg.build(); + } +} diff --git a/src/main/java/club/joylink/xiannccda/ws/msg/SystemWarnEvent.java b/src/main/java/club/joylink/xiannccda/ws/msg/SystemWarnEvent.java new file mode 100644 index 0000000..4a8318f --- /dev/null +++ b/src/main/java/club/joylink/xiannccda/ws/msg/SystemWarnEvent.java @@ -0,0 +1,23 @@ +package club.joylink.xiannccda.ws.msg; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +public abstract class SystemWarnEvent extends ApplicationEvent { + + @Getter + private Integer lineId; + + public SystemWarnEvent(Integer lineId, Object source) { + super(source); + this.lineId = lineId; + } + + public static class SystemWarnConnStateEvent extends SystemWarnEvent { + + public SystemWarnConnStateEvent(Integer lineId, Object source) { + super(lineId, source); + } + } + +} diff --git a/src/main/java/club/joylink/xiannccda/ws/msg/SystemWarnListener.java b/src/main/java/club/joylink/xiannccda/ws/msg/SystemWarnListener.java new file mode 100644 index 0000000..6612351 --- /dev/null +++ b/src/main/java/club/joylink/xiannccda/ws/msg/SystemWarnListener.java @@ -0,0 +1,49 @@ +package club.joylink.xiannccda.ws.msg; + +import club.joylink.xiannccda.ats.message.OccTcpClientConnection; +import club.joylink.xiannccda.dto.protos.SystemWarnMsgProto; +import club.joylink.xiannccda.dto.protos.SystemWarnMsgProto.WarnMessage; +import club.joylink.xiannccda.dto.protos.SystemWarnMsgProto.WarnMessage.Builder; +import club.joylink.xiannccda.ws.msg.SystemWarnEvent.SystemWarnConnStateEvent; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +@Component +public class SystemWarnListener implements ApplicationListener { + + private final static Map SYSTEM_MSG_MAP = new ConcurrentHashMap<>(); + + @Override + public void onApplicationEvent(SystemWarnEvent event) { + Integer lineId = event.getLineId(); + SystemWarnMsgProto.WarnMessage.Builder build = SYSTEM_MSG_MAP.computeIfAbsent(lineId, k -> { + SystemWarnMsgProto.WarnMessage.Builder builder = SystemWarnMsgProto.WarnMessage.newBuilder(); + builder.setLineId(k); + return builder; + }); + this.connedHandle(event, build); + } + + private void connedHandle(SystemWarnEvent event, SystemWarnMsgProto.WarnMessage.Builder build) { + if (event instanceof SystemWarnConnStateEvent) { + OccTcpClientConnection clientConnection = (OccTcpClientConnection) event.getSource(); + if (clientConnection.isRealPort()) { + build.setOccRealConned(clientConnection.isConnected()); + } else { + build.setOccUnrealConned(clientConnection.isConnected()); + } + } + } + + public static Collection getAllSystemWarn() { + return SYSTEM_MSG_MAP.values(); + } + + public static List getAllSystemWarnBuild() { + return SYSTEM_MSG_MAP.values().stream().map(Builder::build).toList(); + } +}