设备测试初始化功能,ws推送occ连接消息

This commit is contained in:
tiger_zhou 2023-12-20 14:25:38 +08:00
parent 68ed9de49f
commit bf58d8f2fd
15 changed files with 238 additions and 4 deletions

View File

@ -58,6 +58,9 @@ public class AlertManager extends EventEmitter {
return getInstance("default"); return getInstance("default");
} }
public void clearAlertDataMsg(Integer lineId) {
DEVICE_ALTER_TABLE.clear();
}
public boolean putAlterDevice(Integer lineId, String customName, String deviceName) { public boolean putAlterDevice(Integer lineId, String customName, String deviceName) {
AlertTableDetail detail = DEVICE_ALTER_TABLE.get(lineId, customName); AlertTableDetail detail = DEVICE_ALTER_TABLE.get(lineId, customName);

View File

@ -1,5 +1,8 @@
package club.joylink.xiannccda.ats.message; 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.bootstrap.Bootstrap;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
@ -48,19 +51,23 @@ public class OccTcpClientConnection {
final ReconnectState reconnectState; final ReconnectState reconnectState;
@Getter
final boolean isRealPort;
public void write(MessageData messageData) { public void write(MessageData messageData) {
if (Objects.nonNull(this.channel)) { if (Objects.nonNull(this.channel)) {
this.channel.writeAndFlush(List.of(messageData)); 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.client = client;
this.host = host; this.host = host;
this.port = port; this.port = port;
this.group = new NioEventLoopGroup(1); this.group = new NioEventLoopGroup(1);
this.bootstrap = new Bootstrap(); this.bootstrap = new Bootstrap();
this.isRealPort = isRealPort;
OccTcpClientConnection self = this; OccTcpClientConnection self = this;
bootstrap.group(group) bootstrap.group(group)
.channel(NioSocketChannel.class) .channel(NioSocketChannel.class)
@ -101,6 +108,7 @@ public class OccTcpClientConnection {
this.channel = channelFuture.channel(); this.channel = channelFuture.channel();
this.connected = true; this.connected = true;
this.client.requestBaseData(); this.client.requestBaseData();
SystemContext.publishEvent(new SystemWarnConnStateEvent(this.client.getLineId(), this));
} }
}); });
channelFuture.channel().closeFuture().addListener(listener -> { channelFuture.channel().closeFuture().addListener(listener -> {
@ -109,7 +117,9 @@ public class OccTcpClientConnection {
this.connected = false; this.connected = false;
this.channel = null; this.channel = null;
this.client.resetRequestBaseDataFlag(); this.client.resetRequestBaseDataFlag();
} }
SystemContext.publishEvent(new SystemWarnConnStateEvent(this.client.getLineId(), this));
this.reconnectState.resetState(); this.reconnectState.resetState();
}); });
} }

View File

@ -63,8 +63,8 @@ public class XianOccMessagingClient {
this.lineId = lineId; this.lineId = lineId;
this.requestBaseTime = TimeUnit.HOURS.toMillis(receiveMsgTimeout); this.requestBaseTime = TimeUnit.HOURS.toMillis(receiveMsgTimeout);
// 创建实时和非实时消息连接 // 创建实时和非实时消息连接
this.rtConnection = new OccTcpClientConnection(this, host, realPort, collectorData); this.rtConnection = new OccTcpClientConnection(this, host, realPort, collectorData, true);
this.nrtConnection = new OccTcpClientConnection(this, host, unRealPort, false); this.nrtConnection = new OccTcpClientConnection(this, host, unRealPort, false, false);
this.timeOutHandler.addConnection(this.rtConnection); this.timeOutHandler.addConnection(this.rtConnection);
this.timeOutHandler.addConnection(this.nrtConnection); this.timeOutHandler.addConnection(this.nrtConnection);

View File

@ -18,4 +18,5 @@ public abstract class AbstractData {
public abstract void clear(); public abstract void clear();
public abstract void reset();
} }

View File

@ -1,19 +1,22 @@
package club.joylink.xiannccda.ats.message.collect.datasource; package club.joylink.xiannccda.ats.message.collect.datasource;
import club.joylink.xiannccda.ats.message.collect.DeviceStatusDataOperate; import club.joylink.xiannccda.ats.message.collect.DeviceStatusDataOperate;
import club.joylink.xiannccda.dto.protos.DeviceStatusProto;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.protobuf.GeneratedMessageV3; import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.GeneratedMessageV3.Builder; import com.google.protobuf.GeneratedMessageV3.Builder;
import com.google.protobuf.Message; import com.google.protobuf.Message;
import com.google.protobuf.MessageOrBuilder; import com.google.protobuf.MessageOrBuilder;
import java.util.Collections; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import lombok.Getter; import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
@Getter @Getter
public class DeviceStatusData extends AbstractData { public class DeviceStatusData extends AbstractData {
@ -106,4 +109,51 @@ public class DeviceStatusData extends AbstractData {
this.allDeviceMap.clear(); this.allDeviceMap.clear();
this.statusVOMap.clear(); this.statusVOMap.clear();
} }
@Override
public void reset() {
for (Entry<String, Map<String, Builder>> mapEntry : this.allDeviceMap.entrySet()) {
String deviceType = mapEntry.getKey();
Collection<Builder> 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<Builder> builders) {
for (Builder builder : builders) {
if (builder instanceof DeviceStatusProto.Rtu.Builder b) {
b.setIpRtuStusDown(false);
}
}
}
private void resetSwitch(Collection<Builder> 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<Builder> 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);
}
}
}
} }

View File

@ -63,5 +63,10 @@ public class InUsedScheduleData extends AbstractData {
trainSchedule.clear(); trainSchedule.clear();
} }
@Override
public void reset() {
}
} }

View File

@ -167,6 +167,11 @@ public class InterLockData extends AbstractData {
} }
@Override
public void reset() {
}
public static class InterLockDetail { public static class InterLockDetail {
public InterLockDetail(AreaConfigVO areaConfigVO) { public InterLockDetail(AreaConfigVO areaConfigVO) {

View File

@ -164,6 +164,11 @@ public class TrainDataSource extends AbstractData {
this.trainOnDeviceTrackMap.clear(); this.trainOnDeviceTrackMap.clear();
} }
@Override
public void reset() {
}
public enum TrainTypeStatus { public enum TrainTypeStatus {
TRAIN_BLOCK("TrainBlock", "block"), TRAIN_RECORD("TrainRemove", "remove"), TRAIN_REMOVE("TrainRecord", "record"); TRAIN_BLOCK("TrainBlock", "block"), TRAIN_RECORD("TrainRemove", "remove"), TRAIN_REMOVE("TrainRecord", "record");
/** /**

View File

@ -1,6 +1,7 @@
package club.joylink.xiannccda.constants; package club.joylink.xiannccda.constants;
import club.joylink.xiannccda.configuration.pros.OccNotHandlePros; import club.joylink.xiannccda.configuration.pros.OccNotHandlePros;
import club.joylink.xiannccda.ws.msg.SystemWarnEvent;
import lombok.Getter; import lombok.Getter;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -29,6 +30,10 @@ public class SystemContext implements ApplicationContextAware {
return cu.notMatchHandle(lineId, rtuId); return cu.notMatchHandle(lineId, rtuId);
} }
public static void publishEvent(SystemWarnEvent event) {
appContext.publishEvent(event);
}
@Override @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

View File

@ -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.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List; import java.util.List;
import lombok.Getter;
import org.springframework.validation.annotation.Validated; 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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -35,6 +37,14 @@ public class AlertMockController {
alertMockService.setAlert2(alertMockDTO); 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") @SecurityRequirement(name = "jwt")
@Operation(summary = "设置模拟故障") @Operation(summary = "设置模拟故障")
@ApiResponse(description = "设置模拟故障") @ApiResponse(description = "设置模拟故障")

View File

@ -5,7 +5,11 @@ import club.joylink.xiannccda.alert.NccAlertInfo;
import club.joylink.xiannccda.alert.core.AlertDeviceType; import club.joylink.xiannccda.alert.core.AlertDeviceType;
import club.joylink.xiannccda.alert.core.AlertManager; import club.joylink.xiannccda.alert.core.AlertManager;
import club.joylink.xiannccda.ats.cache.LineGraphicDataRepository; 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.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.ats.message.convertor.DeviceStatusConvertor;
import club.joylink.xiannccda.constants.SystemContext; import club.joylink.xiannccda.constants.SystemContext;
import club.joylink.xiannccda.dto.mock.show.BlueAlertMockDTO; 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 club.joylink.xiannccda.vo.AreaConfigVO;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.google.protobuf.GeneratedMessageV3; import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.GeneratedMessageV3.Builder;
import com.google.protobuf.MessageOrBuilder; import com.google.protobuf.MessageOrBuilder;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -76,6 +83,18 @@ public class AlertMockService {
alertManager.emit(alertInfo); 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}") @Value("${mock-alert-test}")
private boolean mockTest; private boolean mockTest;

View File

@ -3,6 +3,7 @@ package club.joylink.xiannccda.service;
import club.joylink.xiannccda.ws.LineDeviceMessageServer; import club.joylink.xiannccda.ws.LineDeviceMessageServer;
import club.joylink.xiannccda.ws.LineNetMessageServer; import club.joylink.xiannccda.ws.LineNetMessageServer;
import club.joylink.xiannccda.ws.LineTrainMessageServer; import club.joylink.xiannccda.ws.LineTrainMessageServer;
import club.joylink.xiannccda.ws.SystemInfoStateMessageServer;
import club.joylink.xiannccda.ws.WsMessageServerManager; import club.joylink.xiannccda.ws.WsMessageServerManager;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -26,5 +27,7 @@ public class LineDeviceStatusService {
wsMessageServerManager.registerMessageServer(new LineNetMessageServer()); wsMessageServerManager.registerMessageServer(new LineNetMessageServer());
wsMessageServerManager.registerMessageServer(new LineTrainMessageServer()); wsMessageServerManager.registerMessageServer(new LineTrainMessageServer());
wsMessageServerManager.registerMessageServer(new LineDeviceMessageServer()); wsMessageServerManager.registerMessageServer(new LineDeviceMessageServer());
wsMessageServerManager.registerMessageServer(new SystemInfoStateMessageServer());
} }
} }

View File

@ -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<String, String> paramMap) {
return this.lineMessage().toByteArray();
}
@Override
public int getInterval() {
return 4000;
}
@Override
public List<TopicMessage> onTick() {
return List.of(new TopicMessage(SUBSCRIPTION_PATH, this.lineMessage().toByteArray()));
}
private SystemWarnMsgProto.WarnLineMessage lineMessage() {
SystemWarnMsgProto.WarnLineMessage.Builder lineMsg = SystemWarnMsgProto.WarnLineMessage.newBuilder();
List<WarnMessage> msgs = SystemWarnListener.getAllSystemWarnBuild();
lineMsg.addAllMsgs(msgs);
return lineMsg.build();
}
}

View File

@ -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);
}
}
}

View File

@ -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<SystemWarnEvent> {
private final static Map<Integer, Builder> 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<Builder> getAllSystemWarn() {
return SYSTEM_MSG_MAP.values();
}
public static List<WarnMessage> getAllSystemWarnBuild() {
return SYSTEM_MSG_MAP.values().stream().map(Builder::build).toList();
}
}