模拟设备状态变更接口

This commit is contained in:
tiger_zhou 2023-07-04 10:33:35 +08:00
parent c059ac912f
commit 13f4bb4acb
13 changed files with 420 additions and 7 deletions

View File

@ -16,6 +16,11 @@ import lombok.Getter;
@Getter
public class DeviceDataRepository {
/**
* key = lineId
* <p>
* val = 对应的数据源
*/
static Map<String, AbstractData> device_data = Maps.newConcurrentMap();

View File

@ -0,0 +1,33 @@
package club.joylink.xiannccda.ats.message.collect.convertor;
import club.joylink.xiannccda.ats.message.MessageData;
import club.joylink.xiannccda.ats.message.MessageResponse;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
import club.joylink.xiannccda.ats.message.collect.DeviceStatusConvertor;
import com.google.protobuf.GeneratedMessageV3;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Collection;
public abstract class DefaultConvertor extends DeviceStatusConvertor {
public List<MessageResponse> convertToResponse(List<MessageData> messageDataList) {
return messageDataList.stream().filter(d -> d instanceof MessageResponse).map(d -> (MessageResponse) d).toList();
}
public abstract DataTypeEnum dataType();
@Override
public void run(List<MessageData> messageDataList) {
List<MessageResponse> responseList = this.convertToResponse(messageDataList);
Map<Short, List<MessageResponse>> lineMapper = responseList.stream().collect(Collectors.groupingBy(MessageResponse::getLineId));
lineMapper.forEach((k, v) -> {
List<GeneratedMessageV3.Builder> builders = v.stream().map(MessageResponse::generateProto).flatMap(Collection::stream).collect(Collectors.toList());
DeviceDataRepository.add(k.toString(), builders, this.dataType());
});
}
}

View File

@ -0,0 +1,23 @@
package club.joylink.xiannccda.ats.message.collect.convertor;
import club.joylink.xiannccda.ats.message.MessageData;
import club.joylink.xiannccda.ats.message.MessageId;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DeviceChangeStatusConvertor extends DefaultConvertor {
@Override
public MessageId getMessageId() {
return MessageId.DEVICE_STATUS_CHANGE;
}
@Override
public DataTypeEnum dataType() {
return DataTypeEnum.DEVICE;
}
}

View File

@ -0,0 +1,23 @@
package club.joylink.xiannccda.ats.message.collect.convertor;
import club.joylink.xiannccda.ats.message.MessageData;
import club.joylink.xiannccda.ats.message.MessageId;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DeviceInitConvertor extends DefaultConvertor {
@Override
public MessageId getMessageId() {
return MessageId.DEVICE_STATUS_BITMAP;
}
@Override
public DataTypeEnum dataType() {
return DataTypeEnum.DEVICE;
}
}

View File

@ -0,0 +1,21 @@
package club.joylink.xiannccda.ats.message.collect.convertor;
import club.joylink.xiannccda.ats.message.MessageId;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TrainInitConvertor extends DefaultConvertor {
@Override
public MessageId getMessageId() {
return MessageId.TRAIN_INDICATION_INIT;
}
@Override
public DataTypeEnum dataType() {
return DataTypeEnum.TRAIN;
}
}

View File

@ -0,0 +1,21 @@
package club.joylink.xiannccda.ats.message.collect.convertor;
import club.joylink.xiannccda.ats.message.MessageId;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TrainRecordConvertor extends DefaultConvertor {
@Override
public MessageId getMessageId() {
return MessageId.TRAIN_RECORD;
}
@Override
public DataTypeEnum dataType() {
return DataTypeEnum.TRAIN;
}
}

View File

@ -0,0 +1,21 @@
package club.joylink.xiannccda.ats.message.collect.convertor;
import club.joylink.xiannccda.ats.message.MessageId;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TrainRemoveConvertor extends DefaultConvertor {
@Override
public MessageId getMessageId() {
return MessageId.TRAIN_INDICATION_REMOVE;
}
@Override
public DataTypeEnum dataType() {
return DataTypeEnum.TRAIN;
}
}

View File

@ -0,0 +1,21 @@
package club.joylink.xiannccda.ats.message.collect.convertor;
import club.joylink.xiannccda.ats.message.MessageId;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TrainUpdateConvertor extends DefaultConvertor {
@Override
public MessageId getMessageId() {
return MessageId.TRAIN_INDICATION_UPDATE;
}
@Override
public DataTypeEnum dataType() {
return DataTypeEnum.TRAIN;
}
}

View File

@ -220,7 +220,7 @@ public class DeviceStatusConvertor {
throw new RuntimeException(String.format("枚举类型%s对应的proto不存在", deviceType.name()));
}
private static GeneratedMessageV3.Builder findBy(final Class<?> deviceStatusEnum) {
public static GeneratedMessageV3.Builder findBy(final Class<?> deviceStatusEnum) {
if (deviceStatusEnum.isAssignableFrom(DeviceStatus.RTU.class)) {
return DeviceStatusProto.Rtu.newBuilder();

View File

@ -1,6 +1,8 @@
package club.joylink.xiannccda.mock.message;
import club.joylink.xiannccda.ats.message.OccMessageManage;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
import club.joylink.xiannccda.ats.message.line3.DateTimeUtil;
import club.joylink.xiannccda.ats.message.line3.req.AlarmAckRequest;
import club.joylink.xiannccda.ats.message.line3.req.AlarmAckRequest.MsgTypeEnum;
@ -9,14 +11,31 @@ import club.joylink.xiannccda.ats.message.line3.req.LoadHistoryTGDataRequest;
import club.joylink.xiannccda.ats.message.line3.req.LoadHistoryTGDataRequest.ApplyTypeEnum;
import club.joylink.xiannccda.ats.message.line3.req.ReportAskRequest;
import club.joylink.xiannccda.ats.message.line3.req.ReportAskRequest.MsgFlagEnum;
import club.joylink.xiannccda.dto.protos.DeviceStatusProto;
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Scada;
import club.joylink.xiannccda.mock.message.Status.Platform;
import club.joylink.xiannccda.mock.message.Status.Rtu;
import club.joylink.xiannccda.mock.message.Status.SCDAD;
import club.joylink.xiannccda.mock.message.Status.Signal;
import club.joylink.xiannccda.mock.message.Status.Switch;
import club.joylink.xiannccda.mock.message.Status.Track;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.GeneratedMessageV3;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
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;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@ -32,6 +51,55 @@ public class MockDeviceController {
@Autowired
private OccMessageManage occMessageManage;
@Operation(summary = "rtu状态设置变更")
@PostMapping("rtu/status/{lineId}")
public void changeRtuStatus(@PathVariable("lineId") String lineId, @RequestBody Rtu rtu) {
this.saveBuild(lineId, rtu, DeviceStatusProto.Rtu.newBuilder());
}
@Operation(summary = "signal状态设置变更")
@PostMapping("signal/status/{lineId}")
public void changeSignalStatus(@PathVariable("lineId") String lineId, @RequestBody Signal signal) {
this.saveBuild(lineId, signal, DeviceStatusProto.Signal.newBuilder());
}
@Operation(summary = "Switch状态设置变更")
@PostMapping("switch/status/{lineId}")
public void changeSwitchStatus(@PathVariable("lineId") String lineId, @RequestBody Switch switchs) {
this.saveBuild(lineId, switchs, DeviceStatusProto.Switch.newBuilder());
}
@Operation(summary = "Track状态设置变更")
@PostMapping("track/status/{lineId}")
public void changeTrackStatus(@PathVariable("lineId") String lineId, @RequestBody Track track) {
this.saveBuild(lineId, track, DeviceStatusProto.Track.newBuilder());
}
@Operation(summary = "Platform状态设置变更")
@PostMapping("platform/status/{lineId}")
public void changePlatformStatus(@PathVariable("lineId") String lineId, @RequestBody Platform platform) {
this.saveBuild(lineId, platform, DeviceStatusProto.Platform.newBuilder());
}
@Operation(summary = "SCDAD状态设置变更")
@PostMapping("scdad/status/{lineId}")
public void changeSCDADStatus(@PathVariable("lineId") String lineId, @RequestBody SCDAD scdad) {
this.saveBuild(lineId, scdad, Scada.newBuilder());
}
private void saveBuild(String lineId, Object obj, GeneratedMessageV3.Builder builder) {
Object jo = JSON.toJSON(obj);
if (jo instanceof JSONObject jsonObject) {
for (String s : jsonObject.keySet()) {
FieldDescriptor fieldDesc = builder.getDescriptorForType().findFieldByName(s);
builder.setField(fieldDesc, jsonObject.get(s));
}
DeviceDataRepository.add(lineId, List.of(builder), DataTypeEnum.DEVICE);
} else {
throw new RuntimeException("");
}
}
@GetMapping("reset")
@Operation(summary = "重置设备状态")
@ -50,7 +118,8 @@ public class MockDeviceController {
@Operation(summary = "统计信息查询")
public void reportAskRequest(@RequestParam("lineId") Integer lineId,
@RequestParam("reportId") Short reportId,
@RequestParam("msgFlag") MsgFlagEnum msgFlag, @RequestParam(value = "content", required = false) String content) {
@RequestParam("msgFlag") MsgFlagEnum msgFlag,
@RequestParam(value = "content", required = false) String content) {
LocalDateTime dateTime = DateTimeUtil.parse(content, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
ReportAskRequest askRequest = new ReportAskRequest(lineId.shortValue(), reportId, msgFlag, dateTime);
this.occMessageManage.sendMsg(lineId, askRequest, false);
@ -61,9 +130,11 @@ public class MockDeviceController {
@Operation(summary = "事件及告警信息请求")
public void alarmAckRequest(@RequestParam("lineId") Integer lineId,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss", iso = DateTimeFormat.ISO.DATE_TIME)
@RequestParam(value = "startDateTime", defaultValue = "2023-07-07 11:11:11") LocalDateTime startDateTime,
@Parameter(description = "开始时间", example = "2023-07-07 11:11:11")
@RequestParam(value = "startDateTime") LocalDateTime startDateTime,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss", iso = DateTimeFormat.ISO.DATE_TIME)
@RequestParam(value = "endDateTime", defaultValue = "2023-07-07 11:11:11") LocalDateTime endDateTime,
@Parameter(description = "结束时间", example = "2023-07-07 11:11:11")
@RequestParam(value = "endDateTime") LocalDateTime endDateTime,
@RequestParam("msgType") MsgTypeEnum typeEnum,
@RequestParam("reportId") Short reportId) {
AlarmAckRequest aar = new AlarmAckRequest(lineId.shortValue(), reportId, typeEnum, startDateTime, endDateTime);
@ -75,7 +146,8 @@ public class MockDeviceController {
@Operation(summary = "历史运行图申请消息")
public void loadHistoryTgRequest(@RequestParam("lineId") Integer lineId,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss", iso = DateTimeFormat.ISO.DATE_TIME)
@RequestParam(value = "localDateTime", defaultValue = "2023-07-07 11:11:11") LocalDateTime localDateTime,
@Parameter(description = "时间", example = "2023-07-07 11:11:11")
@RequestParam(value = "localDateTime") LocalDateTime localDateTime,
@RequestParam("applyType") ApplyTypeEnum typeEnum) {
LoadHistoryTGDataRequest tgDataRequest = new LoadHistoryTGDataRequest(lineId.shortValue(), localDateTime, typeEnum);
this.occMessageManage.sendMsg(lineId, tgDataRequest, false);

View File

@ -78,7 +78,7 @@ public class MockLoadData implements ApplicationRunner {
private void loadTrain() {
List<MessageResponse> messageDataList = this.nccMockDataService.getMessageData(DataType.TRAIN);
if (CollectionUtils.isEmpty(messageDataList)) {
System.out.println("没有新的数据");
this.nccMockDataService.reset(1);
}
for (MessageResponse messageData : messageDataList) {
try {
@ -92,7 +92,7 @@ public class MockLoadData implements ApplicationRunner {
private void loadDevice() {
List<MessageResponse> messageDataList = this.nccMockDataService.getMessageData(DataType.DEVICE);
if (CollectionUtils.isEmpty(messageDataList)) {
System.out.println("没有新的数据");
this.nccMockDataService.reset(1);
}
for (MessageResponse messageData : messageDataList) {
try {

View File

@ -0,0 +1,157 @@
package club.joylink.xiannccda.mock.message;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
public class Status {
@Data
public static class Rtu {
Boolean ipRtuStusDown;
Boolean ipRtuStusInLocalCtrl;
Boolean ipRtuStusInCentralCtrl;
Boolean ipRtuStusInEmergencyCtrl;
private String id;
}
/* @Data
public static class Station {
Boolean ipStaStusTermMode1;
Boolean ipStaStusTermMode2;
Boolean ipStaStusTermMode3;
Boolean ipStaStusTermMode4;
Boolean ipStaStusTermMode5;
Boolean ipStaStusTermMode6;
Boolean ipStaStusExpectTermMode1;
Boolean ipStaStusExpectTermMode2;
Boolean ipStaStusExpectTermMode3;
Boolean ipStaStusExpectTermMode4;
Boolean ipStaStusExpectTermMode5;
Boolean ipStaStusExpectTermMode6;
Boolean ipStaStusInCycle1;
Boolean ipStaStusInCycle2;
Boolean ipStaStusInCycle3;
Boolean ipStaStusInCycle4;
Boolean ipStaStusInCycle5;
Boolean ipStaStusInCycle6;
Boolean ipStaStusExpectCycle1;
Boolean ipStaStusExpectCycle2;
Boolean ipStaStusExpectCycle3;
Boolean ipStaStusExpectCycle4;
Boolean ipStaStusExpectCycle5;
Boolean ipStaStusExpectCycle6;
}*/
@Data
public static class Signal {
Boolean redOpen;
// Boolean redFlash;
Boolean greenOpen;
// Boolean greenFlash;
Boolean yellowOpen;
// Boolean yellowFlash;
Boolean whiteOpen;
// Boolean whiteFlash;
Boolean blueOpen;
// Boolean blueFlash;
Boolean fleetMode;
// Boolean ctrlFleetMode;
// Boolean autoMode;
// Boolean ctrlAutoMode;
Boolean extinguish;
Boolean approachLock;
Boolean protectRoute;
// Boolean autoRouteDisable;
Boolean callon;
Boolean yellowYellow;
Boolean yellowGreen;
Boolean blocked;
// Boolean lampFailure;
private String id;
}
@Data
public static class Switch {
Boolean ipSingleSwitchStusCiOccupied;
Boolean ipSingleSwitchStusCbtcOccupied;
Boolean ipSingleSwitchStusLocked;
Boolean ipSingleSwitchStusFailLocked;
Boolean ipSingleSwitchStusNormal;
Boolean ipSingleSwitchStusReverse;
Boolean ipSingleSwitchStusBlocked1;
Boolean ipSingleSwitchStusJammed;
// Boolean ipSingleSwitchStusExpectLock;
// Boolean ipSingleSwitchStusExpectUnlock;
// Boolean ipSingleSwitchStusExpectNormal;
// Boolean ipSingleSwitchStusExpectReverse;
// Boolean ipSingleSwitchStusExpectBlock;
// Boolean ipSingleSwitchStusExpectUnblock;
// Boolean ipSingleSwitchStusInRoute;
// Boolean ipSingleSwitchStusManualMode;
Boolean ipSingleSwitchStusCut;
Boolean ipSingleSwitchStusAtcInvalid;
Boolean ipSingleSwitchStusOverlap;
Boolean ipSingleSwitchStusTsrCbtcMain;
Boolean ipSingleSwitchStusTsrCbtcNormal;
Boolean ipSingleSwitchStusTsrCbtcReverse;
Boolean ipSingleSwitchStusTsrBmMain;
Boolean ipSingleSwitchStusTsrBmNormal;
Boolean ipSingleSwitchStusTsrBmReverse;
Boolean ipSingleSwitchStusBlocked2;
Boolean ipSingleSwitchStusLostIndication;
private String id;
}
@Data
public static class Track {
Boolean ciOccupied;
Boolean cbtcOccupied;
Boolean locked;
Boolean failLocked;
// Boolean expectLock;
// Boolean expectUnlock;
// Boolean inRoute;
Boolean cut;
Boolean atcInvalid;
Boolean overlap;
Boolean blocked;
private String id;
}
@Data
public static class Platform {
Boolean emergstop;
Boolean trainberth;
Boolean close;
Boolean upHold;
Boolean downHold;
Boolean upOccHold;
Boolean downOccHold;
Boolean psdOpen;
Boolean psdCut;
Boolean upSkipstop;
Boolean downSkipstop;
Boolean upTrainSkipstop;
Boolean downTrainSkipstop;
private String id;
}
@Data
public static class SCDAD {
Boolean scadaOn;
Boolean scadaSinglePower;
Boolean scadaUnkown;
private String id;
}
}

View File

@ -6,10 +6,15 @@ import club.joylink.xiannccda.ats.message.collect.DeviceStatusConvertorManager;
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository;
import club.joylink.xiannccda.ats.message.collect.DeviceStatusDataRepository;
import club.joylink.xiannccda.ats.message.collect.convertor.DeviceInitConvertor;
import club.joylink.xiannccda.ats.message.collect.convertor.LineNetTrainInitConvertor;
import club.joylink.xiannccda.ats.message.collect.convertor.LineNetTrainRecordConvertor;
import club.joylink.xiannccda.ats.message.collect.convertor.LineNetTrainRemoveConvertor;
import club.joylink.xiannccda.ats.message.collect.convertor.LineNetTrainUpdateConvertor;
import club.joylink.xiannccda.ats.message.collect.convertor.TrainInitConvertor;
import club.joylink.xiannccda.ats.message.collect.convertor.TrainRecordConvertor;
import club.joylink.xiannccda.ats.message.collect.convertor.TrainRemoveConvertor;
import club.joylink.xiannccda.ats.message.collect.convertor.TrainUpdateConvertor;
import club.joylink.xiannccda.ats.message.collect.datasource.DeviceStatusData;
import club.joylink.xiannccda.mock.message.NccMockDataService;
import club.joylink.xiannccda.ws.IMessageServer;
@ -58,6 +63,7 @@ public class LineDeviceStatusService {
// 列车删除转换方法
LineNetTrainRemoveConvertor removeConvertor = new LineNetTrainRemoveConvertor(deviceStatusData);
DeviceStatusConvertorManager.addStatusConvertor(removeConvertor);
// websocket发送服务
IMessageServer iMessageServer = new LineNetMessageServer(deviceStatusData);
wsMessageServerManager.registerMessageServer(iMessageServer);
@ -68,6 +74,16 @@ public class LineDeviceStatusService {
refreshTestData();
}
private void createDataConvertor() {
// DeviceChangeStatusConvertor
// DeviceInitConvertor
// TrainInitConvertor
// TrainRecordConvertor
// TrainRemoveConvertor
// TrainRecordConvertor
// TrainUpdateConvertor
}
public void refreshTestData() {
List<MessageData> allMockData = nccMockDataService.loadAllTrainInitData();
DeviceStatusConvertorManager.doConvertor(allMockData);