diff --git a/src/main/java/club/joylink/xiannccda/ats/message/line3/device/DeviceType.java b/src/main/java/club/joylink/xiannccda/ats/message/line3/device/DeviceType.java
index ab13636..a79a1e3 100644
--- a/src/main/java/club/joylink/xiannccda/ats/message/line3/device/DeviceType.java
+++ b/src/main/java/club/joylink/xiannccda/ats/message/line3/device/DeviceType.java
@@ -5,31 +5,56 @@ import lombok.Getter;
@Getter
public enum DeviceType {
- /** 未知的设备 */
+ /**
+ * 未知的设备
+ */
DEVICE_TYPE_UNKNOW(0),
- /** 集中站 */
+ /**
+ * 集中站
+ */
DEVICE_TYPE_RTU(1),
- /** 车站 */
+ /**
+ * 车站
+ */
DEVICE_TYPE_STATION(2),
- /** 信号机 */
+ /**
+ * 信号机
+ */
DEVICE_TYPE_SIGNAL(3),
- /** 道岔 */
+ /**
+ * 道岔
+ */
DEVICE_TYPE_SWITCH(4),
- /** 轨道 */
+ /**
+ * 轨道
+ */
DEVICE_TYPE_TRACK(5),
- /** 方向 */
+ /**
+ * 方向
+ */
DEVICE_TYPE_ENTRY(6),
- /** 站台 */
+ /**
+ * 站台
+ */
DEVICE_TYPE_PLATFORM(7),
- /** 供电区段 */
+ /**
+ * 供电区段
+ */
DEVICE_TYPE_SCADA(9),
- /** 防淹门 */
+ /**
+ * 防淹门
+ */
DEVICE_TYPE_WATERPROOF_DOOR(11),
- /** 工作区 */
+ /**
+ * 工作区
+ */
DEVICE_TYPE_WORK_AREA(12),
- /** 区域自动驾驶 */
+ /**
+ * 区域自动驾驶
+ */
DEVICE_TYPE_GAMA(13),
;
+ @Getter
int val;
DeviceType(int d) {
diff --git a/src/main/java/club/joylink/xiannccda/dto/protos/DeviceStatusProto.java b/src/main/java/club/joylink/xiannccda/dto/protos/DeviceStatusProto.java
index 36cd05c..1e32a1c 100644
--- a/src/main/java/club/joylink/xiannccda/dto/protos/DeviceStatusProto.java
+++ b/src/main/java/club/joylink/xiannccda/dto/protos/DeviceStatusProto.java
@@ -52,21 +52,21 @@ public final class DeviceStatusProto {
*/
PLATFORM(7),
/**
- * SCADA = 8;
+ * SCADA = 9;
*/
- SCADA(8),
+ SCADA(9),
/**
- * WATERPROOF_DOOR = 9;
+ * WATERPROOF_DOOR = 11;
*/
- WATERPROOF_DOOR(9),
+ WATERPROOF_DOOR(11),
/**
- * WORK_AREA = 10;
+ * WORK_AREA = 12;
*/
- WORK_AREA(10),
+ WORK_AREA(12),
/**
- * GAMA = 11;
+ * GAMA = 13;
*/
- GAMA(11),
+ GAMA(13),
UNRECOGNIZED(-1),
;
@@ -103,21 +103,21 @@ public final class DeviceStatusProto {
*/
public static final int PLATFORM_VALUE = 7;
/**
- * SCADA = 8;
+ * SCADA = 9;
*/
- public static final int SCADA_VALUE = 8;
+ public static final int SCADA_VALUE = 9;
/**
- * WATERPROOF_DOOR = 9;
+ * WATERPROOF_DOOR = 11;
*/
- public static final int WATERPROOF_DOOR_VALUE = 9;
+ public static final int WATERPROOF_DOOR_VALUE = 11;
/**
- * WORK_AREA = 10;
+ * WORK_AREA = 12;
*/
- public static final int WORK_AREA_VALUE = 10;
+ public static final int WORK_AREA_VALUE = 12;
/**
- * GAMA = 11;
+ * GAMA = 13;
*/
- public static final int GAMA_VALUE = 11;
+ public static final int GAMA_VALUE = 13;
public final int getNumber() {
@@ -152,10 +152,10 @@ public final class DeviceStatusProto {
case 5: return TRACK;
case 6: return ENTRY;
case 7: return PLATFORM;
- case 8: return SCADA;
- case 9: return WATERPROOF_DOOR;
- case 10: return WORK_AREA;
- case 11: return GAMA;
+ case 9: return SCADA;
+ case 11: return WATERPROOF_DOOR;
+ case 12: return WORK_AREA;
+ case 13: return GAMA;
default: return null;
}
}
@@ -19381,8 +19381,8 @@ public final class DeviceStatusProto {
"\001(\010*\243\001\n\nDeviceType\022\n\n\006UNKNOW\020\000\022\007\n\003RTU\020\001\022" +
"\013\n\007STATION\020\002\022\n\n\006SIGNAL\020\003\022\n\n\006SWITCH\020\004\022\t\n\005" +
"TRACK\020\005\022\t\n\005ENTRY\020\006\022\014\n\010PLATFORM\020\007\022\t\n\005SCAD" +
- "A\020\010\022\023\n\017WATERPROOF_DOOR\020\t\022\r\n\tWORK_AREA\020\n\022" +
- "\010\n\004GAMA\020\013B6\n!club.joylink.xiannccda.dto." +
+ "A\020\t\022\023\n\017WATERPROOF_DOOR\020\013\022\r\n\tWORK_AREA\020\014\022" +
+ "\010\n\004GAMA\020\rB6\n!club.joylink.xiannccda.dto." +
"protosB\021DeviceStatusProtob\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
diff --git a/src/main/java/club/joylink/xiannccda/mock/message/MockDeviceController.java b/src/main/java/club/joylink/xiannccda/mock/message/MockDeviceController.java
index 9157077..8293109 100644
--- a/src/main/java/club/joylink/xiannccda/mock/message/MockDeviceController.java
+++ b/src/main/java/club/joylink/xiannccda/mock/message/MockDeviceController.java
@@ -4,6 +4,7 @@ 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.device.DeviceType;
import club.joylink.xiannccda.ats.message.line3.req.AlarmAckRequest;
import club.joylink.xiannccda.ats.message.line3.req.AlarmAckRequest.MsgTypeEnum;
import club.joylink.xiannccda.ats.message.line3.req.LoadDeviceStatusRequest;
@@ -14,14 +15,23 @@ 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.dto.protos.DeviceStatusProto.TrainMode;
+import club.joylink.xiannccda.dto.protos.LayoutGraphicsProto;
+import club.joylink.xiannccda.dto.protos.TrainProto;
+import club.joylink.xiannccda.dto.protos.TrainProto.NccWindow;
+import club.joylink.xiannccda.dto.protos.TrainProto.TrainRemove;
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 club.joylink.xiannccda.mock.message.Status.Train;
+import club.joylink.xiannccda.mock.message.Status.TrainBlock;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
+import com.google.common.collect.Maps;
+import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.GeneratedMessageV3;
import io.swagger.v3.oas.annotations.Operation;
@@ -30,6 +40,8 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
+import java.util.Map;
+import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
@@ -51,6 +63,24 @@ public class MockDeviceController {
@Autowired
private OccMessageManage occMessageManage;
+ @Operation(summary = "train阻塞状态设置变更")
+ @PostMapping("train/remove/{lineId}")
+ public void trainRemove(@PathVariable("lineId") String lineId, @RequestBody Status.TrainRemove train) {
+ this.saveBuild(lineId, train, TrainProto.TrainRemove.newBuilder());
+ }
+
+ @Operation(summary = "train阻塞状态设置变更")
+ @PostMapping("train/Block/{lineId}")
+ public void trainBlock(@PathVariable("lineId") String lineId, @RequestBody Status.TrainBlock train) {
+ this.saveBuild(lineId, train, TrainProto.TrainBlock.newBuilder());
+ }
+
+ @Operation(summary = "train位置状态设置变更")
+ @PostMapping("train/offset/{lineId}")
+ public void changeTrainOffset(@PathVariable("lineId") String lineId, @RequestBody Train train) {
+ this.saveBuild(lineId, train, TrainProto.TrainInfo.newBuilder());
+ }
+
@Operation(summary = "rtu状态设置变更")
@PostMapping("rtu/status/{lineId}")
public void changeRtuStatus(@PathVariable("lineId") String lineId, @RequestBody Rtu rtu) {
@@ -87,14 +117,52 @@ public class MockDeviceController {
this.saveBuild(lineId, scdad, Scada.newBuilder());
}
+ static Map CLASS_BUILDER_MAP = Maps.newHashMap();
+
+ static {
+ CLASS_BUILDER_MAP.put(Status.TrainMode.class, TrainMode.newBuilder());
+ CLASS_BUILDER_MAP.put(Status.NccWindow.class, NccWindow.newBuilder());
+ }
+
+
+ private void setVal(GeneratedMessageV3.Builder builder, String key, Object val) {
+ FieldDescriptor fieldDesc = builder.getDescriptorForType().findFieldByName(key);
+ if (val.getClass() == DeviceType.class) {
+ DeviceType dt = (DeviceType) val;
+ EnumDescriptor enumD = builder.getDescriptorForType().findEnumTypeByName(key);
+
+ DeviceStatusProto.DeviceType dt2 = DeviceStatusProto.DeviceType.forNumber(dt.getVal());
+ builder.setField(fieldDesc, dt2.getValueDescriptor());
+
+ } else {
+ builder.setField(fieldDesc, val);
+
+ }
+ }
+
+
private void saveBuild(String lineId, Object obj, GeneratedMessageV3.Builder builder) {
Object jo = JSON.toJSON(obj);
+ DataTypeEnum dataType = DataTypeEnum.DEVICE;
+ if (obj instanceof Status.Train || obj instanceof Status.TrainBlock || obj instanceof Status.TrainRemove) {
+ dataType = DataTypeEnum.TRAIN;
+ }
if (jo instanceof JSONObject jsonObject) {
for (String s : jsonObject.keySet()) {
- FieldDescriptor fieldDesc = builder.getDescriptorForType().findFieldByName(s);
- builder.setField(fieldDesc, jsonObject.get(s));
+ Object val = jsonObject.get(s);
+ GeneratedMessageV3.Builder messsageBuilder = CLASS_BUILDER_MAP.get(val.getClass());
+ if (Objects.isNull(messsageBuilder)) {
+ this.setVal(builder, s, val);
+ } else {
+ GeneratedMessageV3.Builder cloneBuilder = messsageBuilder.clone();
+ JSONObject jo2 = val instanceof JSONObject ? (JSONObject) val : (JSONObject) JSON.toJSON(val);
+ for (String s1 : jo2.keySet()) {
+ Object v = jo2.get(s1);
+ this.setVal(cloneBuilder, s1, v);
+ }
+ }
}
- DeviceDataRepository.add(lineId, List.of(builder), DataTypeEnum.DEVICE);
+ DeviceDataRepository.add(lineId, List.of(builder), dataType);
} else {
throw new RuntimeException("");
diff --git a/src/main/java/club/joylink/xiannccda/mock/message/Status.java b/src/main/java/club/joylink/xiannccda/mock/message/Status.java
index 1096284..24f4054 100644
--- a/src/main/java/club/joylink/xiannccda/mock/message/Status.java
+++ b/src/main/java/club/joylink/xiannccda/mock/message/Status.java
@@ -1,5 +1,7 @@
package club.joylink.xiannccda.mock.message;
+import club.joylink.xiannccda.ats.message.line3.device.DeviceType;
+import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@@ -154,4 +156,143 @@ public class Status {
private String id;
}
+ @Data
+ public static class Train {
+
+ String groupId;
+ NccWindow window;
+ TrainMode trainMode;
+ @Schema(description = "设备类型 DEVICE_TYPE_UNKNOW;\n"
+ + " DEVICE_TYPE_RTU;\n"
+ + " DEVICE_TYPE_STATION;\n"
+ + " DEVICE_TYPE_SIGNAL;\n"
+ + " DEVICE_TYPE_SWITCH;\n"
+ + " DEVICE_TYPE_TRACK;\n"
+ + " DEVICE_TYPE_ENTRY;\n"
+ + " DEVICE_TYPE_PLATFORM;\n"
+ + " DEVICE_TYPE_SCADA;\n"
+ + " DEVICE_TYPE_WATERPROOF_DOOR;\n"
+ + " DEVICE_TYPE_WORK_AREA;\n"
+ + " DEVICE_TYPE_GAMA;")
+ DeviceType devType;
+ String devName;
+ }
+
+ @Data
+ public static class TrainBlock {
+
+ Integer lineId;
+ // 列车编组号
+ String groupId;
+ // 表号
+ String trainId;
+ // 方向
+ // 0:上行
+ // 1:下行
+ // 2:未知
+ Integer direction;
+ // 列车所在区间左边车站的站号
+ Integer stationIDInUpSide;
+ // 列车所在区间右边车站的站号
+ Integer stationIDInDownSide;
+ // 集中站站号
+ Integer rtuId;
+ // 列车所在的设备的类型
+ @Schema(description = "设备类型 DEVICE_TYPE_UNKNOW;\n"
+ + " DEVICE_TYPE_RTU;\n"
+ + " DEVICE_TYPE_STATION;\n"
+ + " DEVICE_TYPE_SIGNAL;\n"
+ + " DEVICE_TYPE_SWITCH;\n"
+ + " DEVICE_TYPE_TRACK;\n"
+ + " DEVICE_TYPE_ENTRY;\n"
+ + " DEVICE_TYPE_PLATFORM;\n"
+ + " DEVICE_TYPE_SCADA;\n"
+ + " DEVICE_TYPE_WATERPROOF_DOOR;\n"
+ + " DEVICE_TYPE_WORK_AREA;\n"
+ + " DEVICE_TYPE_GAMA;")
+ DeviceType deviceType;
+ String devName;
+ // 列车所在的设备的名称
+ // 列车阻塞标记
+ // 1:列车阻塞
+ // 0:列车没有阻塞
+ Integer blockFlag;
+ }
+
+ @Data
+ public static class TrainRemove {
+
+ Integer lineId;
+ // 集中站站号
+ Integer rtuId;
+ // NCC车次窗编号
+ // 列车在车次窗中的位置
+ NccWindow window;
+ // 列车所在的设备的类型
+ @Schema(description = "设备类型 DEVICE_TYPE_UNKNOW;\n"
+ + " DEVICE_TYPE_RTU;\n"
+ + " DEVICE_TYPE_STATION;\n"
+ + " DEVICE_TYPE_SIGNAL;\n"
+ + " DEVICE_TYPE_SWITCH;\n"
+ + " DEVICE_TYPE_TRACK;\n"
+ + " DEVICE_TYPE_ENTRY;\n"
+ + " DEVICE_TYPE_PLATFORM;\n"
+ + " DEVICE_TYPE_SCADA;\n"
+ + " DEVICE_TYPE_WATERPROOF_DOOR;\n"
+ + " DEVICE_TYPE_WORK_AREA;\n"
+ + " DEVICE_TYPE_GAMA;")
+ DeviceType deviceType;
+ String devName;
+ // 列车标示号,全线唯一(若无法提供,缺省值为0)
+ String trainIndex;
+ // 列车编组号
+ String groupId;
+ }
+
+ @Data
+ public static class NccWindow {
+
+ Integer nccWindow;
+ Integer nccWinOffset;
+ }
+
+ @Data
+ public static class TrainMode {
+
+ Boolean ipModeTrainTypeManual;
+ Boolean ipModeTrainTypeHead;
+ Boolean ipModeTrainTypeSpecial;
+ Boolean ipModeTrainTypeSchedule;
+ // Boolean ipModeTrainTypeRoute;
+// Boolean ipModeTrainTypeShuttle;
+// Boolean ipModeTrainTypeLineup;
+ Boolean ipModeTrainSchdEarly;
+ Boolean ipModeTrainSchdLate;
+ Boolean ipModeTrainSkipstop;
+ Boolean ipModeTrainCbtcMode;
+ Boolean ipModeTrainAtpCut;
+ Boolean ipModeTrainBerthed;
+ // Boolean ipModeTrainStoped;
+ Boolean ipModeTrainHolded;
+ // Boolean ipModeTrainItama;
+ Boolean ipModeTrainDirUp;
+ Boolean ipModeTrainDirDown;
+ Boolean ipModeTrainDirHeadUp;
+ Boolean ipModeTrainDirHeadDown;
+ Boolean ipModeTrainDoorOpen;
+ // Boolean ipModeTrainRsAlarm;
+// Boolean ipModeTrainDoorAlarm;
+ Boolean ipModeTrainEbAlarm;
+ Boolean ipModeTrainIntegrityAlarm;
+ Boolean ipModeTrainDriveModeAm;
+ Boolean ipModeTrainDriveModeCm;
+ Boolean ipModeTrainDriveModeRmf;
+ // Boolean ipModeTrainDriveModeDto;
+ Boolean ipModeTrainDriveModeAtb;
+ Boolean ipModeTrainDriveBlockAm;
+ Boolean ipModeTrainDriveBlockCm;
+ Boolean ipModeTrainDriveModeRmr;
+// Boolean ipModeTrainDriveModeWash;
+ }
+
}
diff --git a/src/main/java/club/joylink/xiannccda/ws/LineDeviceMessageServer.java b/src/main/java/club/joylink/xiannccda/ws/LineDeviceMessageServer.java
index 8461490..6e0413c 100644
--- a/src/main/java/club/joylink/xiannccda/ws/LineDeviceMessageServer.java
+++ b/src/main/java/club/joylink/xiannccda/ws/LineDeviceMessageServer.java
@@ -53,11 +53,10 @@ public class LineDeviceMessageServer implements IMessageServer {
builderMap.forEach((k, v) -> messageMap.put(k, v.build()));
return messageMap;
}, builder);
- if (this.isNull(builder)) {
- return null;
+ if (this.isNotNull(builder)) {
+ WsLineMessage buildMsg = builder.build();
+ return buildMsg.toByteArray();
}
- WsLineMessage buildMsg = builder.build();
- return buildMsg.toByteArray();
}
return null;
}
@@ -82,8 +81,11 @@ public class LineDeviceMessageServer implements IMessageServer {
}
WsLineMessage.Builder msg = WsLineMessage.newBuilder();
fillBuilderFunction((field) -> deviceDataSource.getStatusVOMap().get(field), msg);
- DeviceStatusDataOperate.clearStatusVOMap(DeviceStatusDataRepository.getDeviceStatusData(lineId));
- messages.add(new TopicMessage(destination, msg.build().toByteArray()));
+ if (this.isNotNull(msg)) {
+ DeviceStatusDataOperate.clearStatusVOMap(DeviceStatusDataRepository.getDeviceStatusData(lineId));
+ messages.add(new TopicMessage(destination, msg.build().toByteArray()));
+ }
+
}
return messages;
}
diff --git a/src/test/java/club/joylink/xiannccda/service/StompTest.java b/src/test/java/club/joylink/xiannccda/service/StompTest.java
index b3fc2c4..6bc59f5 100644
--- a/src/test/java/club/joylink/xiannccda/service/StompTest.java
+++ b/src/test/java/club/joylink/xiannccda/service/StompTest.java
@@ -21,6 +21,9 @@ public class StompTest {
@Test
public void subscribe() {
+
+ String token = "eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJzZWxmIiwic3ViIjoiOSIsImV4cCI6MTY4ODY5OTQ0OSwiaWF0IjoxNjg4NDQwMjQ5fQ.gYCTq_oPw_31MqnH3VZ71RVm659Lim8z86-VnEV9D4XIvr8GNblkN1cMNC2TH5HkqzKMUDJC_Nn-bH6n1LcJQTwJv1V4kY8cm1rCN8aedxRgq5NGIrDl5K2zLy9qvs-iOHQF8PdK2KC8zWy1RV9t34cuSsUsiCc14-KmvCRXE801YSpzLsOgF0Ulz4fl-CDX5LO2fGyFF6Lv298BOvbocfJ3KghpvocuT2tx5nl2C4tHfLV5XRxD9cQlsoRi_VOQp8Y49mRdhIe-vOv_rkOaRNuINdyAfYTyntKv0IkKj3Rh6y0wERV-ymkfsfgm-0gkeQ9qtwVIBjEK5Btq0LhlSQ";
+
StandardWebSocketClient socketClient = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(socketClient);
@@ -28,7 +31,7 @@ public class StompTest {
WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
StompHeaders headers1 = new StompHeaders();
headers1.set("Authorization",
- "Bearer eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJzZWxmIiwic3ViIjoiOSIsImV4cCI6MTY4NzkzODcwNCwiaWF0IjoxNjg3Njc5NTA0fQ.W__1N-IyXIJ4SIPsFviK-1q_0H9lqQsr0uI6VhdpZsPME63Aes8Fr23XItIlVqb14pgWVeVxTnRMKnG8gKzqFj8FTJs6c2jo5wDYX2UTBED3GPBIdzPTNETQATwh2vQNoItxyGcepVzToN4jmjtIScmtly3ppIXmCgYUNtwniWRz_5FAbDyy18cawd7-rr9ex37uahUewdohgrQFDOHDRzxC0M5AGTpfxKIiXHYs-rGdyfqhvhpoy26bM0TTMr8_EpssODLY8EvSLFfQgqtzhlXbrOQWuOjG7fQ4RQa1cKFHzFtQPosIkE3gsvyCRw2BCLERlqmGoAor-3RZ5Mqv_w");
+ "Bearer " + token);
CompletableFuture future = stompClient.connectAsync("ws://127.0.0.1:9081/ws-default", headers, headers1, handler);
@@ -38,7 +41,7 @@ public class StompTest {
} catch (Exception e) {
e.printStackTrace();
}
- stompSession.subscribe("/queue/line/3", new StompFrameHandler() {
+ stompSession.subscribe("/queue/line/3/device", new StompFrameHandler() {
@Override
public Type getPayloadType(StompHeaders stompHeaders) {
return byte[].class;
diff --git a/xian-ncc-da-message b/xian-ncc-da-message
index 8fd000d..1ab5b1a 160000
--- a/xian-ncc-da-message
+++ b/xian-ncc-da-message
@@ -1 +1 @@
-Subproject commit 8fd000d45907f94410786c3bd6c1ab37edbe91e8
+Subproject commit 1ab5b1ae7fd44e5b31e424407f3b783b40190c95