This commit is contained in:
weizhihong 2023-06-30 16:50:05 +08:00
commit f7879fe0d7
15 changed files with 172 additions and 80 deletions

View File

@ -82,7 +82,7 @@ public abstract class MessageData {
*/
public abstract void decode2(ByteBuf buf) throws Exception;
public abstract List<GeneratedMessageV3.Builder> generateProto() throws Exception;
public abstract List<GeneratedMessageV3.Builder> generateProto();
public void encode(ByteBuf buf) {

View File

@ -18,7 +18,7 @@ public abstract class MessageRequest extends MessageData {
}
@Override
public List<Builder> generateProto() throws Exception {
public List<Builder> generateProto() {
return null;
}
}

View File

@ -2,6 +2,7 @@ package club.joylink.xiannccda.ats.message;
import com.google.protobuf.GeneratedMessageV3.Builder;
import io.netty.buffer.ByteBuf;
import java.util.Collections;
import java.util.List;
public abstract class MessageResponse extends MessageData {
@ -13,7 +14,7 @@ public abstract class MessageResponse extends MessageData {
public abstract Short getLineId();
@Override
public List<Builder> generateProto() throws Exception {
return null;
public List<Builder> generateProto() {
return Collections.emptyList();
}
}

View File

@ -40,6 +40,14 @@ public class DeviceStatusData extends AbstractData {
DeviceStatusDataOperate.addDevices(dataList, this);
}
public boolean isAllDeviceEmpty() {
return this.allDeviceMap.isEmpty();
}
public boolean isStatusVOEmpty() {
return this.statusVOMap.isEmpty();
}
@Override
public void clear() {
this.allDeviceMap.clear();

View File

@ -104,13 +104,13 @@ public class DeviceStatusConvertor {
* @param deviceStatusEnum 如DeviceStatus.SIGNAL.class
* @param statusBitMap 该设备的符合状态位图
*/
public static <T extends GeneratedMessageV3.Builder> T convert(final Class<? extends DeviceStatus.Status> deviceStatusEnum, final int statusBitMap) throws Exception {
public static <T extends GeneratedMessageV3.Builder> T convert(final Class<? extends DeviceStatus.Status> deviceStatusEnum, final int statusBitMap) {
final GeneratedMessageV3.Builder to = findBy(deviceStatusEnum);
convert(deviceStatusEnum, statusBitMap, to);
return (T) to;
}
public static <T extends GeneratedMessageV3.Builder> T convert(DeviceType deviceType, final int statusBitMap) throws Exception {
public static <T extends GeneratedMessageV3.Builder> T convert(DeviceType deviceType, final int statusBitMap) {
Class<? extends DeviceStatus.Status> deviceStatusEnum = findByEnum(deviceType);
return convert(deviceStatusEnum, statusBitMap);
}
@ -138,21 +138,25 @@ public class DeviceStatusConvertor {
* @param statusBitMap 该设备的符合状态位图
* @param to proto设备状态
*/
public static void convert(final Class<? extends DeviceStatus.Status> deviceStatusEnum, final int statusBitMap, final GeneratedMessageV3.Builder to) throws Exception {
public static void convert(final Class<? extends DeviceStatus.Status> deviceStatusEnum, final int statusBitMap, final GeneratedMessageV3.Builder to) {
// final Class<?> toClass = to.getClass();
final Method enumValues = deviceStatusEnum.getMethod("values");
final Object values = enumValues.invoke(deviceStatusEnum);
final int len = Array.getLength(values);
for (int i = 0; i < len; i++) {
final DeviceStatus.Status devStateEnum = (DeviceStatus.Status) Array.get(values, i);
final String enumUnitName = devStateEnum.toString();
final int devStateMask = devStateEnum.mask();
String fieldName = toFieldName(enumUnitName);
FieldDescriptor toFieldDescName = to.getDescriptorForType().findFieldByName(fieldName);
to.setField(toFieldDescName, devStateMask == (statusBitMap & devStateMask));
try {
final Method enumValues = deviceStatusEnum.getMethod("values");
final Object values = enumValues.invoke(deviceStatusEnum);
final int len = Array.getLength(values);
for (int i = 0; i < len; i++) {
final DeviceStatus.Status devStateEnum = (DeviceStatus.Status) Array.get(values, i);
final String enumUnitName = devStateEnum.toString();
final int devStateMask = devStateEnum.mask();
String fieldName = toFieldName(enumUnitName);
FieldDescriptor toFieldDescName = to.getDescriptorForType().findFieldByName(fieldName);
to.setField(toFieldDescName, devStateMask == (statusBitMap & devStateMask));
// final String setName = toSetName(enumUnitName);
// final Method setMethod = toClass.getMethod(setName, boolean.class);
// setMethod.invoke(to, devStateMask == (statusBitMap & devStateMask));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

View File

@ -18,7 +18,7 @@ public class HeartBeatMsg extends MessageData {
}
@Override
public List<Builder> generateProto() throws Exception {
public List<Builder> generateProto() {
return null;
}

View File

@ -65,7 +65,7 @@ public class DeviceStatusBitmapResponse extends MessageResponse {
}
@Override
public List<Builder> generateProto() throws Exception {
public List<Builder> generateProto() {
List<GeneratedMessageV3.Builder> msgBuildList = Lists.newArrayList();
for (DeviceTypeEntity deviceTypeEntity : this.entityList) {
DeviceType dt = deviceTypeEntity.getType();

View File

@ -84,7 +84,7 @@ public class DeviceStatusChangeResponse extends MessageResponse {
}
@Override
public List<Builder> generateProto() throws Exception {
public List<Builder> generateProto() {
GeneratedMessageV3.Builder builder = DeviceStatusConvertor.convert(this.type, this.deviceStatus);
DeviceStatusConvertor.fillField(builder, "id", this.devName);

View File

@ -19,16 +19,24 @@ import java.util.ArrayList;
import java.util.List;
import lombok.Setter;
/** 2.7.9列车信息全体消息 */
/**
* 2.7.9列车信息全体消息
*/
@Getter
@Setter
public class TrainIndicationInitResponse extends MessageResponse {
/** 线路号(2) */
/**
* 线路号(2)
*/
private Short lineId;
/** 列车数量(2) */
/**
* 列车数量(2)
*/
private Short trainCnt;
/** 列车列表 */
/**
* 列车列表
*/
private List<TrainCell> trains;
@Override
@ -42,7 +50,7 @@ public class TrainIndicationInitResponse extends MessageResponse {
}
@Override
public List<Builder> generateProto() throws Exception {
public List<Builder> generateProto() {
List<Builder> msgBuildList = Lists.newArrayList();
for (TrainCell trainCell : this.trains) {
TrainInfo.Builder builder = TrainInfo.newBuilder();
@ -100,43 +108,81 @@ public class TrainIndicationInitResponse extends MessageResponse {
@Setter
public static class TrainCell {
/** 集中站站号(2) */
/**
* 集中站站号(2)
*/
private Short rtuId;
/** NCC车次窗编号(2) */
/**
* NCC车次窗编号(2)
*/
private Short nccWindow;
/** 列车在车次窗中的位置(1) */
/**
* 列车在车次窗中的位置(1)
*/
private Byte nccWindowOffset;
/** 列车所在的设备的类型(2) */
/**
* 列车所在的设备的类型(2)
*/
private DeviceType devType;
/** 列车所在的设备的名称(24) */
/**
* 列车所在的设备的名称(24)
*/
private String devName;
/** 列车标示号全线唯一若无法提供缺省值为0(10) */
/**
* 列车标示号全线唯一若无法提供缺省值为0(10)
*/
private String trainIndex;
/** 列车编组号(9) */
/**
* 列车编组号(9)
*/
private String groupId;
/** 表号(9) */
/**
* 表号(9)
*/
private String trainId;
/** 车次号(12) */
/**
* 车次号(12)
*/
private String globalId;
/** 目的地号(4) */
/**
* 目的地号(4)
*/
private Integer destinationId;
/** 编组数量(1) */
/**
* 编组数量(1)
*/
private byte rollingStock;
/** 司机号(13) */
/**
* 司机号(13)
*/
private String driverId;
/** 根据实际报点和计划的偏离时间(单位:秒,-215- +215 ,正数表示列车晚点秒数,负数表示列车早点秒数)(4) */
/**
* 根据实际报点和计划的偏离时间单位-215- +215 正数表示列车晚点秒数负数表示列车早点秒数(4)
*/
private Integer otpTime;
/** 列车状态见附录6.3.14列车状态定义(4) */
/**
* 列车状态见附录6.3.14列车状态定义(4)
*/
private Integer mode;
/** 列车到点(7) */
/**
* 列车到点(7)
*/
private LocalDateTime arriveTime;
/** 列车发点(7) */
/**
* 列车发点(7)
*/
private LocalDateTime departTime;
/** 满载率百分比例如50表示满载率为50%(4) */
/**
* 满载率百分比例如50表示满载率为50%(4)
*/
private Integer rate;
/** 速度KM/H(1) */
/**
* 速度KM/H(1)
*/
private byte speed;
/** 预留(2) */
/**
* 预留(2)
*/
private byte[] reserve = new byte[2];
private TrainCell decode(final ByteBuf buf) {

View File

@ -75,7 +75,7 @@ public class TrainIndicationRemoveResponse extends MessageResponse {
}
@Override
public List<Builder> generateProto() throws Exception {
public List<Builder> generateProto() {
TrainRemove.Builder trainRemove = TrainRemove.newBuilder();
trainRemove.setLineId(this.lineId);
trainRemove.setRtuId(this.rtuId);

View File

@ -123,7 +123,7 @@ public class TrainIndicationUpdateResponse extends MessageResponse {
}
@Override
public List<Builder> generateProto() throws Exception {
public List<Builder> generateProto() {
TrainProto.TrainInfo.Builder train = TrainInfo.newBuilder();
train.setLineId(this.lineId);

View File

@ -128,7 +128,7 @@ public class TrainRecordResponse extends MessageResponse {
}
@Override
public List<Builder> generateProto() throws Exception {
public List<Builder> generateProto() {
TrainRecord.Builder builder = TrainRecord.newBuilder();
builder.setLineId(this.getLineId());
builder.setTrainId(this.getTrainId());

View File

@ -1,5 +1,6 @@
package club.joylink.xiannccda.ws;
import com.google.protobuf.GeneratedMessageV3;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@ -13,6 +14,14 @@ public interface IMessageServer {
final static PropertyPlaceholderHelper PLACEHOLDER_HELPER = new PropertyPlaceholderHelper(
"{", "}", ":", false);
default boolean isNull(GeneratedMessageV3.Builder builder) {
return builder.getAllFields().isEmpty();
}
default boolean isNotNull(GeneratedMessageV3.Builder builder) {
return !this.isNull(builder);
}
default String createPlace(String name, String val) {
Properties properties = new Properties();
properties.put(name, val);

View File

@ -41,21 +41,25 @@ public class LineDeviceMessageServer implements IMessageServer {
String lineId = paramMap.get("lineId");
this.lineIdSet.add(lineId);
DeviceStatusData deviceDataSource = DeviceDataRepository.findDataSouce(lineId, DataTypeEnum.DEVICE);
log.info("线路lineId={}订阅,发布全量数据", lineId);
WsLineMessage.Builder builder = WsLineMessage.newBuilder();
fillBuilderFunction(fun -> {
Map<String, Builder> builderMap = deviceDataSource.getAllDeviceMap().get(fun);
if (Objects.isNull(builderMap)) {
return Map.of();
if (!deviceDataSource.isAllDeviceEmpty()) {
WsLineMessage.Builder builder = WsLineMessage.newBuilder();
fillBuilderFunction(fun -> {
Map<String, Builder> builderMap = deviceDataSource.getAllDeviceMap().get(fun);
if (Objects.isNull(builderMap)) {
return Map.of();
}
Map<String, Message> messageMap = Maps.newHashMap();
builderMap.forEach((k, v) -> messageMap.put(k, v.build()));
return messageMap;
}, builder);
if (this.isNull(builder)) {
return null;
}
Map<String, Message> messageMap = Maps.newHashMap();
builderMap.forEach((k, v) -> messageMap.put(k, v.build()));
return messageMap;
}, builder);
WsLineMessage buildMsg = builder.build();
return buildMsg.toByteArray();
WsLineMessage buildMsg = builder.build();
return buildMsg.toByteArray();
}
return null;
}
@Override
@ -66,18 +70,21 @@ public class LineDeviceMessageServer implements IMessageServer {
@Override
public List<TopicMessage> onTick() {
if (this.lineIdSet.isEmpty()) {
return Collections.emptyList();
return null;
}
List<TopicMessage> messages = Lists.newArrayList();
for (String lineId : this.lineIdSet) {
WsLineMessage.Builder msg = WsLineMessage.newBuilder();
DeviceStatusData deviceDataSource = DeviceDataRepository.findDataSouce(lineId, DataTypeEnum.DEVICE);
// DeviceStatusData statusData = DeviceStatusDataRepository.getDeviceStatusData(lineId);
fillBuilderFunction((field) -> deviceDataSource.getStatusVOMap().get(field), msg);
DeviceStatusDataOperate.clearStatusVOMap(DeviceStatusDataRepository.getDeviceStatusData(lineId));
String destination = this.createPlace("lineId", lineId);
messages.add(new TopicMessage(destination, msg.build().toByteArray()));
if (!deviceDataSource.isStatusVOEmpty()) {
WsLineMessage.Builder msg = WsLineMessage.newBuilder();
fillBuilderFunction((field) -> deviceDataSource.getStatusVOMap().get(field), msg);
DeviceStatusDataOperate.clearStatusVOMap(DeviceStatusDataRepository.getDeviceStatusData(lineId));
String destination = this.createPlace("lineId", lineId);
messages.add(new TopicMessage(destination, msg.build().toByteArray()));
}
}
if (CollectionUtils.isEmpty(messages)) {
return null;
}
return messages;
}

View File

@ -8,12 +8,14 @@ import club.joylink.xiannccda.dto.protos.TrainProto.TrainInfo.Builder;
import club.joylink.xiannccda.dto.protos.WsMessageProto.WsLineTrainMessage;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.protobuf.Descriptors.FieldDescriptor;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
@Slf4j
public class LineTrainMessageServer implements IMessageServer {
@ -33,8 +35,10 @@ public class LineTrainMessageServer implements IMessageServer {
lineIdSet.add(lineId);
log.info("线路lineId={}订阅车辆信息,发布全量数据", lineId);
TrainDataSource trainDataSource = DeviceDataRepository.findDataSouce(lineId, DataTypeEnum.TRAIN);
Collection<Builder> trains = trainDataSource.getAllTrain();
if (CollectionUtils.isEmpty(trains)) {
return null;
}
List<TrainInfo> trainMsg = trains.stream().map(TrainInfo.Builder::build).toList();
WsLineTrainMessage.Builder trainMessage = WsLineTrainMessage.newBuilder();
trainMessage.addAllTrainInfo(trainMsg);
@ -49,24 +53,37 @@ public class LineTrainMessageServer implements IMessageServer {
@Override
public List<TopicMessage> onTick() {
if (this.lineIdSet.isEmpty()) {
return Collections.emptyList();
return null;
}
List<TopicMessage> messages = Lists.newArrayList();
for (String lineId : this.lineIdSet) {
TrainDataSource trainInfoData = DeviceDataRepository.findDataSouce(lineId, DataTypeEnum.TRAIN);
WsLineTrainMessage.Builder trainMessage = WsLineTrainMessage.newBuilder();
for (TrainInfo.Builder trainInfo : trainInfoData.getAllTrain()) {
trainInfoData.fillBlockOrRecordOrRemove(trainInfo, "TrainBlock", "block");
trainInfoData.fillBlockOrRecordOrRemove(trainInfo, "TrainRemove", "remove");
trainInfoData.fillBlockOrRecordOrRemove(trainInfo, "TrainRecord", "record");
trainInfoData.reput(trainInfo);
trainMessage.addTrainInfo(trainInfo);
if (!CollectionUtils.isEmpty(trainInfoData.getAllTrain())) {
for (TrainInfo.Builder trainInfo : trainInfoData.getAllTrain()) {
trainInfoData.fillBlockOrRecordOrRemove(trainInfo, "TrainBlock", "block");
trainInfoData.fillBlockOrRecordOrRemove(trainInfo, "TrainRemove", "remove");
trainInfoData.fillBlockOrRecordOrRemove(trainInfo, "TrainRecord", "record");
trainInfoData.reput(trainInfo);
trainMessage.addTrainInfo(trainInfo);
}
String destination = this.createPlace("lineId", lineId);
messages.add(new TopicMessage(destination, trainMessage.build().toByteArray()));
}
String destination = this.createPlace("lineId", lineId);
messages.add(new TopicMessage(destination, trainMessage.build().toByteArray()));
}
if (CollectionUtils.isEmpty(messages)) {
return null;
}
return messages;
}
public static void main(String[] args) {
WsLineTrainMessage.Builder trainMessage = WsLineTrainMessage.newBuilder();
trainMessage.addTrainInfo(TrainInfo.newBuilder());
Map<FieldDescriptor, Object> maper = trainMessage.getAllFields();
System.out.println(maper);
maper.forEach((k, v) -> {
System.out.println(k.getName());
});
}
}