实时消息2.7.2-2.7.7

This commit is contained in:
tiger_zhou 2023-06-06 17:31:42 +08:00
parent 50f23d3502
commit 502eb413e5
9 changed files with 532 additions and 1 deletions

10
Dockerfile-local-test Normal file
View File

@ -0,0 +1,10 @@
FROM openjdk:17
ADD target/xian-ncc-da-0.1.jar app.jar
EXPOSE 9000 19000/tcp
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
CMD java -jar -Dfile.encoding=UTF-8 -Dspring.profiles.active=dev /app.jar

View File

@ -28,9 +28,11 @@ public abstract class MessageData {
this.version = 0x01;
this.msgId = msgId;
}
public MessageData() {
}
public void decode(ByteBuf buf) throws Exception {
final int headerBytes = 10;
int readableBytes = buf.readableBytes();
@ -73,4 +75,25 @@ public abstract class MessageData {
public int total() {
return this.length + 2;
}
public static class DateTime {
private short year;
private byte month;
private byte day;
private byte hour;
private byte minute;
private byte second;
public DateTime(ByteBuf buf) {
this.year = buf.readShort();
this.month = buf.readByte();
this.day = buf.readByte();
this.hour = buf.readByte();
this.minute = buf.readByte();
this.second = buf.readByte();
}
}
}

View File

@ -6,7 +6,30 @@ public enum MessageId {
* 心跳
*/
MESSAGE_POLLING(0x0001),
;
/**
* 信息源网络状态 OCC->NCC
*/
NETWORK_ALIVE_STATUS(0x0002),
/**
* 2.7.3 ATS信息请求消息 OCC<-NCC
*/
LOAD_DEVICE_STATUS(0x0003),
/**
* 2.7.4 设备状态全体消息
*/
DEVICE_STATUS_BITMAP(0x0004),
/**
* 2.7.5 设备状态变化消息
*/
DEVICE_STATUS_CHANGE(0x0005),
/**
* 2.7.6 自动/人工信号模式消息
*/
SIGNAL_ROUTE_STATUS(0x0006),
/**
* 2.7.7 出入库派班计划消息
*/
DEPOT_PLAN(0x0007);
int val;

View File

@ -0,0 +1,174 @@
package club.joylink.xiannccda.ats.message.rep;
import club.joylink.xiannccda.ats.message.MessageData;
import club.joylink.xiannccda.ats.message.MessageId;
import io.netty.buffer.ByteBuf;
/**
* 2.7.7 出入库派班计划消息
*/
/*
2.7.7.1 应用场景
发送条件
当OCC FEP收到NCC FEP的ATS信息请求消息时发送此信息给NCC
当OCC FEP判断和OCC服务器断开重连上后发送此信息给NCC
当当天出入库派班计划发生变更时OCC FEP发送此信息给NCC
*/
public class DepotPlanRep extends MessageData {
public DepotPlanRep(MessageId msgId, int contentLength) {
super(msgId, contentLength);
}
/**
* 线路号(2)
*/
private Short lineId;
/**
* 出入库日期(7)
*/
private DateTime date;
/**
* 出入库记录数(2)
*/
private Short depotCount;
/**
* 出入库终端站号车辆段/停车场的站号(2)
*/
private Short depotStation;
/**
* 车组号(9)
*/
private byte[] groupId = new byte[9];
/**
* 司机号(13)
*/
private byte[] driverId = new byte[13];
/**
* 出库状态(2) 0表示未出库 1表示已出库
*/
private Short outFlag;
/**
* 是否计划车上线属性(1):0 ;1
*/
private Byte outSchedule;
/**
* 上线时间(7)
*/
private DateTime outTime;
/**
* 上线车站编号(转换轨所在车站)(2)
*/
private Short outStation;
/**
* 上线车站站台编号上线转换轨对应的站台(2)
*/
private Short outSide;
/**
* 上线转换轨名称(20)左对齐其它空字符填\0
*/
private byte[] outName = new byte[20];
/**
* 上线表号(9);
*/
private byte[] outTrainid = new byte[9];
/**
* 上线目的地号(4)
*/
private byte[] outDestination = new byte[4];
/**
* 上线车次号(12)
*/
private byte[] outGlobalid = new byte[12];
/**
* 上线序列号(4)
*/
private Integer outLocalSubid;
/**
* 回库状态(2) 0表示未回库 1表示已回库
*/
private Short inFlag;
/**
* 是否计划车下线属性(1) 0 1
*/
private Byte inSchedule;
/**
* 下线时间(7)
*/
private DateTime inTime;
/**
* 下线车站编号(转换轨所在车站)(2)
*/
private Short inStation;
/**
* 下线车站站台编号下线转换轨对应的站台(2)
*/
private Short inSide;
/**
* 下线转换轨名称(20)
*/
private byte[] inName = new byte[20];
/**
* 下线表号(9)
*/
private byte[] inTrainid = new byte[9];
/**
* 下线目的地号(4)
*/
private byte[] inDestination = new byte[4];
/**
* 下线车次号(12)
*/
private byte[] inGlobalid = new byte[12];
/**
* 下线序列号(4)
*/
private Integer inLocalSubid;
// 下一条记录 重复8~30
@Override
public void decode2(ByteBuf buf) throws Exception {
this.lineId = buf.readShort();
this.date = new DateTime(buf);
this.depotCount = buf.readShort();
this.depotStation = buf.readShort();
buf.readBytes(this.groupId);
buf.readBytes(this.driverId);
this.outFlag = buf.readShort();
this.outSchedule = buf.readByte();
this.outTime = new DateTime(buf);
this.outStation = buf.readShort();
this.outSide = buf.readShort();
buf.readBytes(this.outName);
buf.readBytes(this.outTrainid);
buf.readBytes(this.outDestination);
buf.readBytes(this.outGlobalid);
this.outLocalSubid = buf.readInt();
this.inFlag = buf.readShort();
this.inSchedule = buf.readByte();
this.inTime = new DateTime(buf);
this.inStation = buf.readShort();
this.inSide = buf.readShort();
buf.readBytes(this.inName);
buf.readBytes(this.inTrainid);
buf.readBytes(this.inDestination);
buf.readBytes(this.inGlobalid);
this.inLocalSubid = buf.readInt();
}
}

View File

@ -0,0 +1,87 @@
package club.joylink.xiannccda.ats.message.rep;
import club.joylink.xiannccda.ats.message.MessageData;
import club.joylink.xiannccda.ats.message.MessageId;
import io.netty.buffer.ByteBuf;
/**
* 2.7.4 设备状态全体消息
*/
/*
2.7.4.1 应用场景
定义
实时表示信息的全体数据某个集中站全部设备状态全体数据必须包含该集中站的所有设备
发送条件
当某个集中站不活时全体数据信息只包含DEVICE_TYPE_RTU的信息
当某个集中站恢复正常时OCC主动发送包含本集中站所有设备类型状态的全体数据信息
当OCC FEP收到NCC FEP的ATS信息请求消息时发送所有集中站的此信息给NCC
当OCC FEP判断和OCC服务器断开后重连上后发送所有集中站的此信息给NCC
当某些线路集中站本身定时向OCC服务器发送全体数据时同时OCC FEP也会向NCC发全体数据这种情况下周期发送设备状态全体消息的间隔建议不小于600秒
*/
public class DeviceStatusBitmapRep extends MessageData {
/**
* 线路号(2)
*/
private Short lineId;
/**
* 集中站号(2)
*/
// rtu_id: 集中站号编号不为0不重复SCADA,FAS,BAS的信息分别根据所属集中站作为该集中站的设备发送
private Short rtuId;
/**
* 类型数量(2)
*/
private Short typeCnt;
/**
* 设备类型(2)见附录2
*/
/*
Type为DEVICE_TYPE_PLATFORM时预留的4个字节处填充区间运行时间或区间运行等级
0xABCD0001ABCD这两个字节表示下一区间运行时间0x0000AB02AB这个字节表示下一区间运行等级
当Type为DEVICE_TYPE_SWITCH时预留的4个字节处填充限速值
0x000000ABAB这个字节表示限速值KM/H
注1 type:设备类型定义包括信号机,道岔,站台,轨道,报警集中站设备,车站设备等但列车的设备状态不在本消息里面发送
*/
private Short type;
/**
* 该类设备的数目(2)
*/
private Short objCount;
/**
* 设备名称(24)左对齐其它空字符填\0
*/
/*device_name: 设备名称字符型由于信号平面图上逻辑区段描述存在重复现象西安3号线将按照本线路ATS系统内部基友的规则命名所有设备来保证输出信息的设备名称唯一性
当type为DEVICE_TYPE_RTU时该值为空当type为DEVICE_TYPE_STATION时该值预留*/
private byte[] devName = new byte[24];
/**
* 设备的状态(4)见附录3
*/
private Integer status;
/**
* 预留(4)
*/
private Integer spare;
public DeviceStatusBitmapRep(MessageId msgId, int contentLength) {
super(msgId, contentLength);
}
/*下一个设备重复10~12
下一个类型重复8~13*/
@Override
public void decode2(ByteBuf buf) throws Exception {
this.lineId = buf.readShort();
this.rtuId = buf.readShort();
this.typeCnt = buf.readShort();
this.type = buf.readShort();
this.objCount = buf.readShort();
buf.readBytes(this.devName);
this.status = buf.readInt();
this.spare = buf.readInt();
}
}

View File

@ -0,0 +1,60 @@
package club.joylink.xiannccda.ats.message.rep;
import club.joylink.xiannccda.ats.message.MessageData;
import club.joylink.xiannccda.ats.message.MessageId;
import io.netty.buffer.ByteBuf;
import io.swagger.v3.oas.models.security.SecurityScheme.In;
/**
* 2.7.5 设备状态变化消息
*/
/*
定义
实时表示信息的变化数据
发送条件
当某个设备状态变化时OCC发送该消息给NCC集中站状态变化也作为设备状态变化发
*/
public class DeviceStatusChangeRep extends MessageData {
public DeviceStatusChangeRep(MessageId msgId, int contentLength) {
super(msgId, contentLength);
}
/**
* 线路号(2)
*/
private Short lineId;
/**
* 集中站号
*/
private Short rtuId;
/**
* 设备类型(2)见附录2
*/
private Short type;
/**
* 设备名称(24)
*/
private byte[] devName = new byte[24];
/**
* 设备的状态(4)见附录3
*/
private Integer deviceStatus;
/**
* 预留(4)
*/
private Integer spare;
@Override
public void decode2(ByteBuf buf) throws Exception {
this.lineId = buf.readShort();
this.rtuId = buf.readShort();
this.type = buf.readShort();
buf.readBytes(this.devName);
this.deviceStatus = buf.readInt();
this.spare = buf.readInt();
}
}

View File

@ -0,0 +1,34 @@
package club.joylink.xiannccda.ats.message.rep;
import club.joylink.xiannccda.ats.message.MessageData;
import club.joylink.xiannccda.ats.message.MessageId;
import io.netty.buffer.ByteBuf;
/**
* 2.7.2 信息源网络状态消息
*/
//本消息用于OCC FEP向NCC FEP报告其当前与OCC服务器的网络状态变化情况
// 当网络状态变化时发送此消息当NCC FEP与OCC FEP初始建立通信时OCC FEP也发送此消息
public class NetworkAliveStatusRep extends MessageData {
/**
* 线路号(2)
*/
private Short linId;
/**
* 状态字节(1) 1代表与当前线路号的信息源(server)连接正常 0代表断开
*/
private Byte status;
public NetworkAliveStatusRep(MessageId msgId, int contentLength) {
super(msgId, contentLength);
}
@Override
public void decode2(ByteBuf buf) throws Exception {
this.linId = buf.readShort();
this.status = buf.readByte();
}
}

View File

@ -0,0 +1,72 @@
package club.joylink.xiannccda.ats.message.rep;
import club.joylink.xiannccda.ats.message.MessageData;
import club.joylink.xiannccda.ats.message.MessageId;
import io.netty.buffer.ByteBuf;
/**
* 2.7.6 自动/人工信号模式消息
*/
/*
2.7.6.1 应用场景
发送条件
当OCC FEP收到NCC FEP的ATS信息请求消息时发送此信息给NCC
当OCC FEP判断和OCC服务器断开重连上后发送此信息给NCC
当某个集中站恢复正常时OCC主动发送包含本集中站的自动/人工信号模式信息
当集中站的信号机人工/自动模式发生变化时发送集中站的所有信号模式给NCC
*/
public class SignalRouteStatusRep extends MessageData {
public SignalRouteStatusRep(MessageId msgId, int contentLength) {
super(msgId, contentLength);
}
/**
* 线路号(2)
*/
private Short lineId;
/**
* 集中站号(2)
*/
private Short rtuId;
/**
* 信号机的数目(2)
*/
private Short singalCount;
/**
* 信号机名称(20)
*/
private byte[] signalName = new byte[20];
/**
* 进路数量(1)
*/
private Byte routeCount;
/**
* 进路名称(64)
*/
private byte[] routeName = new byte[64];
/**
* 进路控制模式(1)
* <p>
* 进路控制模式 0x55ATS自动信号模式
* <p>
* 0xaa:非ATS自动信号模式
*/
private Byte routeStatus;
@Override
public void decode2(ByteBuf buf) throws Exception {
this.lineId = buf.readShort();
this.rtuId = buf.readShort();
this.singalCount = buf.readShort();
buf.readBytes(this.signalName);
this.routeCount = buf.readByte();
buf.readBytes(this.routeName);
this.routeStatus = buf.readByte();
}
}

View File

@ -0,0 +1,48 @@
package club.joylink.xiannccda.ats.message.req;
import club.joylink.xiannccda.ats.message.MessageData;
import club.joylink.xiannccda.ats.message.MessageId;
import io.netty.buffer.ByteBuf;
/**
* 2.7.3 ATS信息请求消息
*/
//每次当NCC FEP需要更新ATS信息的时候它需要向OCC FEP发送本消息当OCC FEP收到本消息后需要向NCC FEP同步全部的ATS信息以正确初始化NCC然后通过不断发送变化状态来同步
// 如果OCC FEP和OCC服务器断开后重连, NCC FEP并不重发本消息需要由OCC FEP来管理重发以维护连接的有效性
// 当OCC FEP收到NCC FEP的LOAD_DEVICE_STATUS后需要向NCC FEP发送的消息如下
// 1实时通道回复如下消息
// DEVICE_STATUS_BITMAP设备状态全体消息
// SIGNAL_ROUTE_STATUS自动/人工信号模式消息
// TRAIN_INDICATION_INIT列车信息全体消息
// DEPOT_PLAN当天出入库派班计划消息
// TRAIN_BLOCK_INFO列车阻塞消息
// INUSED_SCHEDULE_PARAMETER当天计划运行图参数消息
// 2非实时通道回复如下消息
// INUSED_SCHEDULE当天计划运行图消息
// HISTORY_SCHEDULE当天实际运行图消息
public class LoadDeviceStatusReq extends MessageData {
/**
* 线路号(2)
*/
private Short lineId;
public LoadDeviceStatusReq(MessageId msgId, int contentLength) {
super(msgId, contentLength);
}
public LoadDeviceStatusReq(Short lineId) {
super(MessageId.LOAD_DEVICE_STATUS, 2);
this.lineId = lineId;
}
@Override
public void decode2(ByteBuf buf) throws Exception {
}
@Override
protected void encode2(ByteBuf buf) {
buf.writeShort(this.lineId);
}
}