[新增]11号线联锁通信所属线路配置;11号线联锁通信原始数据及解析后的json数据日志
All checks were successful
local-test分支打包构建docker并发布运行 / Docker-Build (push) Successful in 1m31s
All checks were successful
local-test分支打包构建docker并发布运行 / Docker-Build (push) Successful in 1m31s
This commit is contained in:
parent
61e60e4e64
commit
cac309f4b1
@ -3,10 +3,9 @@ package config
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"joylink.club/iot/dto"
|
"joylink.club/iot/dto"
|
||||||
|
"log/slog"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -126,6 +125,7 @@ type InterlockConfig struct {
|
|||||||
RemotePort int `json:"remotePort" description:"远端接收采集信息端口"`
|
RemotePort int `json:"remotePort" description:"远端接收采集信息端口"`
|
||||||
Open bool `json:"open" description:"是否开启"`
|
Open bool `json:"open" description:"是否开启"`
|
||||||
Code string `json:"code" description:"所属集中站"`
|
Code string `json:"code" description:"所属集中站"`
|
||||||
|
Line string `json:"line" description:"联锁通信协议所属线路"`
|
||||||
}
|
}
|
||||||
type ElectricMachineryConfig struct {
|
type ElectricMachineryConfig struct {
|
||||||
Ip string `json:"ip" description:"IP配置"`
|
Ip string `json:"ip" description:"IP配置"`
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
package beijing11
|
|
||||||
|
|
||||||
var (
|
|
||||||
FrameHead byte = 0x0E //帧头
|
|
||||||
FrameTail byte = 0x0E //帧尾
|
|
||||||
ControlWord = controlWord{
|
|
||||||
HeartBeat: 0x00,
|
|
||||||
ReadRegister: 0x01,
|
|
||||||
WriteRegister: 0x02,
|
|
||||||
Response: 0x03,
|
|
||||||
Upstream: 0x06,
|
|
||||||
DownStream: 0x07,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type controlWord struct {
|
|
||||||
HeartBeat byte //心跳
|
|
||||||
ReadRegister byte //读寄存器
|
|
||||||
WriteRegister byte //写寄存器
|
|
||||||
Response byte //回复
|
|
||||||
Upstream byte //上行流数据
|
|
||||||
DownStream byte //下行流数据
|
|
||||||
}
|
|
133
third_party/interlock/beijing11/interlock.go
vendored
133
third_party/interlock/beijing11/interlock.go
vendored
@ -2,6 +2,7 @@
|
|||||||
package beijing11
|
package beijing11
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"joylink.club/bj-rtsts-server/config"
|
"joylink.club/bj-rtsts-server/config"
|
||||||
"joylink.club/bj-rtsts-server/third_party/udp"
|
"joylink.club/bj-rtsts-server/third_party/udp"
|
||||||
@ -11,116 +12,52 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
initMutex = sync.Mutex{}
|
initMutex = sync.Mutex{}
|
||||||
interlockMap = make(map[string]*InterlockProxy)
|
|
||||||
logTag = "[北京11号线联锁通信]"
|
logTag = "[北京11号线联锁通信]"
|
||||||
|
running = false
|
||||||
|
server udp.UdpServer
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetInstant(c *config.InterlockConfig, msgManager MsgManager) *InterlockProxy {
|
func Start(interlockConfig *config.InterlockConfig) {
|
||||||
initMutex.Lock()
|
if interlockConfig == nil || interlockConfig.Ip == "" || !interlockConfig.Open {
|
||||||
defer initMutex.Unlock()
|
|
||||||
if interlockMap[c.Code] == nil {
|
|
||||||
interlockMap[c.Code] = &InterlockProxy{runConfig: c, msgManager: msgManager}
|
|
||||||
}
|
|
||||||
return interlockMap[c.Code]
|
|
||||||
}
|
|
||||||
|
|
||||||
type MsgManager interface {
|
|
||||||
HandleReadRegisterMsg(req *ReadRegisterReq) (*ReadRegisterRes, error)
|
|
||||||
HandleWriteRegisterMsg(req *WriteRegisterReq) error
|
|
||||||
HandleDownstreamMsg(data []byte) error
|
|
||||||
CollectUpstreamMsg() []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type msgManager struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
type InterlockProxy struct {
|
|
||||||
runConfig *config.InterlockConfig //联锁通信配置
|
|
||||||
msgManager MsgManager //消息获取与处理接口0
|
|
||||||
client udp.UdpClient //向上位机发送数据的UDP客户端
|
|
||||||
server udp.UdpServer //接收上位机数据的UDP服务端
|
|
||||||
running bool //此服务正在运行的标志
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *InterlockProxy) Start() {
|
|
||||||
if i.runConfig == nil || i.runConfig.Ip == "" || !i.runConfig.Open {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if i.running {
|
if running {
|
||||||
panic("启动联锁消息服务错误: 存在正在运行的任务")
|
return
|
||||||
|
}
|
||||||
|
initMutex.Lock()
|
||||||
|
defer initMutex.Unlock()
|
||||||
|
if running {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
//UDP通信设施
|
//UDP通信设施
|
||||||
i.server = udp.NewServer(fmt.Sprintf(":%d", i.runConfig.LocalPort), i.handleUpperData)
|
server = udp.NewServer(fmt.Sprintf(":%d", interlockConfig.LocalPort), func(b []byte) {
|
||||||
err := i.server.Listen()
|
slog.Info(fmt.Sprintf("%s收到消息:%x", logTag, b))
|
||||||
|
frame := &FromInterlockFrame{}
|
||||||
|
err := frame.Decode(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("启动联锁消息服务错误:无法启动UDP服务")
|
slog.Error(fmt.Sprintf("%s解析数据出错:%s", logTag, err))
|
||||||
|
} else {
|
||||||
|
marshal, err := json.Marshal(frame)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(fmt.Sprintf("%s解析为json出错:%s", logTag, err))
|
||||||
|
} else {
|
||||||
|
slog.Info(fmt.Sprintf("%s解析为json:%s", logTag, string(marshal)))
|
||||||
}
|
}
|
||||||
i.running = true
|
}
|
||||||
i.client = udp.NewClient(fmt.Sprintf("%v:%v", i.runConfig.Ip, i.runConfig.RemotePort))
|
})
|
||||||
|
err := server.Listen()
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("%s启动UDP服务失败:%s", logTag, err))
|
||||||
|
}
|
||||||
|
running = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理来自上位机的数据
|
func Stop() {
|
||||||
func (i *InterlockProxy) handleUpperData(data []byte) {
|
|
||||||
baseData := &BaseStruct{}
|
|
||||||
err := baseData.Decode(data)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error(logTag + "数据解析出错:" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch baseData.ControlWord {
|
|
||||||
case ControlWord.ReadRegister:
|
|
||||||
req := &ReadRegisterReq{}
|
|
||||||
err := req.Decode(baseData.Data)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error(logTag + "读寄存器数据解析出错:" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
res, err := i.msgManager.HandleReadRegisterMsg(req)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error(logTag + "读寄存器数据处理出错:" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resData := &BaseStruct{
|
|
||||||
ID: baseData.ID,
|
|
||||||
ControlWord: ControlWord.Response,
|
|
||||||
Data: res.Encode(),
|
|
||||||
}
|
|
||||||
i.SendToUpper(resData.Encode())
|
|
||||||
case ControlWord.WriteRegister:
|
|
||||||
req := &WriteRegisterReq{}
|
|
||||||
err := req.Decode(baseData.Data)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error(logTag + "写寄存器数据解析出错:" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = i.msgManager.HandleWriteRegisterMsg(req)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error(logTag + "写寄存器数据处理出错:" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case ControlWord.DownStream:
|
|
||||||
err = i.msgManager.HandleDownstreamMsg(baseData.Data)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error(logTag + "下行数据处理出错:" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *InterlockProxy) SendToUpper(data []byte) {
|
|
||||||
err := i.client.Send(data)
|
|
||||||
slog.Error(logTag + "向上位机发送数据失败:" + err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *InterlockProxy) Stop() {
|
|
||||||
initMutex.Lock()
|
initMutex.Lock()
|
||||||
defer initMutex.Unlock()
|
defer initMutex.Unlock()
|
||||||
delete(interlockMap, i.runConfig.Code)
|
running = false
|
||||||
if i.client != nil {
|
if server != nil {
|
||||||
i.client.Close()
|
server.Close()
|
||||||
|
server = nil
|
||||||
}
|
}
|
||||||
if i.server != nil {
|
|
||||||
i.server.Close()
|
|
||||||
}
|
|
||||||
i.running = false
|
|
||||||
}
|
}
|
||||||
|
373
third_party/interlock/beijing11/msg.go
vendored
373
third_party/interlock/beijing11/msg.go
vendored
@ -3,84 +3,337 @@ package beijing11
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/crc32"
|
|
||||||
"joylink.club/bj-rtsts-server/sys_error"
|
"joylink.club/bj-rtsts-server/sys_error"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BaseStruct struct {
|
// FromInterlockFrame 来自联锁的数据帧
|
||||||
ID byte
|
type FromInterlockFrame struct {
|
||||||
ControlWord byte
|
Len uint16
|
||||||
Data []byte
|
InterlockCode uint16 //联锁ID
|
||||||
|
WaysideCode uint16 //轨旁ID
|
||||||
|
TurnoutData *DeviceData //道岔数据
|
||||||
|
PSDData *DeviceData //屏蔽门数据
|
||||||
|
ESBData *ESBData //紧急停车按钮数据
|
||||||
|
HoldTrainData *HoldTrainData //扣车按钮数据
|
||||||
|
SignalData *DeviceData //信号机数据
|
||||||
|
AxleSectionData *DeviceData //计轴区段数据
|
||||||
|
WrzfData *DeviceData //无人折返数据
|
||||||
|
FymData *DeviceData //防淹门数据
|
||||||
|
SPKSData *SPKSData //SPKS数据
|
||||||
|
CkmData *DeviceData //车库门数据
|
||||||
|
XcjData *DeviceData //洗车机数据
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *BaseStruct) Decode(buf []byte) error {
|
func (f *FromInterlockFrame) Decode(data []byte) error {
|
||||||
if buf[0] != FrameHead {
|
f.Len = binary.BigEndian.Uint16(data[1:3])
|
||||||
return sys_error.New(logTag + "帧头不正确:" + fmt.Sprintf("%02X", buf[0]))
|
if int(f.Len) != len(data)-3 {
|
||||||
|
return sys_error.New(fmt.Sprintf("%s数据长度不对[%d:%d]", logTag, f.Len, len(data)-3))
|
||||||
}
|
}
|
||||||
if buf[len(buf)-1] != FrameTail {
|
f.InterlockCode = binary.BigEndian.Uint16(data[3:5])
|
||||||
return sys_error.New(logTag + "帧尾不正确:" + fmt.Sprintf("%02X", buf[len(buf)-1]))
|
f.WaysideCode = binary.BigEndian.Uint16(data[5:7])
|
||||||
}
|
|
||||||
crc := crc32.ChecksumIEEE(buf[1 : len(buf)-5])
|
turnoutData, i := decodeDeviceData(data, 7)
|
||||||
if crc != binary.BigEndian.Uint32(buf[len(buf)-5:len(buf)-1]) {
|
f.TurnoutData = turnoutData
|
||||||
return sys_error.New(logTag + "CRC校验失败")
|
psdData, i := decodeDeviceData(data, i)
|
||||||
}
|
f.PSDData = psdData
|
||||||
m.ID = buf[1]
|
esbData, i := decodeESBData(data, i)
|
||||||
m.ControlWord = buf[2]
|
f.ESBData = esbData
|
||||||
m.Data = buf[5 : len(buf)-5]
|
holdTrainData, i := decodeHoldTrainData(data, i)
|
||||||
|
f.HoldTrainData = holdTrainData
|
||||||
|
signalData, i := decodeDeviceData(data, i)
|
||||||
|
f.SignalData = signalData
|
||||||
|
axleSectionData, i := decodeDeviceData(data, i)
|
||||||
|
f.AxleSectionData = axleSectionData
|
||||||
|
wrzfData, i := decodeDeviceData(data, i)
|
||||||
|
f.WrzfData = wrzfData
|
||||||
|
fymData, i := decodeDeviceData(data, i)
|
||||||
|
f.FymData = fymData
|
||||||
|
spksData, i := decodeSPKSData(data, i)
|
||||||
|
f.SPKSData = spksData
|
||||||
|
ckmData, i := decodeDeviceData(data, i)
|
||||||
|
f.CkmData = ckmData
|
||||||
|
xcjData, i := decodeDeviceData(data, i)
|
||||||
|
f.XcjData = xcjData
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *BaseStruct) Encode() []byte {
|
func decodeDeviceData(data []byte, index uint16) (*DeviceData, uint16) {
|
||||||
var data []byte
|
data = data[index:]
|
||||||
data = append(data, FrameHead)
|
num := binary.BigEndian.Uint16(data[0:2])
|
||||||
data = append(data, m.ID)
|
i := 2 + 3*num
|
||||||
data = append(data, m.ControlWord)
|
data = data[2:i]
|
||||||
data = binary.BigEndian.AppendUint16(data, uint16(len(m.Data)))
|
var cmdList []*DeviceCmd
|
||||||
data = append(data, m.Data...)
|
for i := 0; i < len(data); i += 3 {
|
||||||
crc := crc32.ChecksumIEEE(data[1:])
|
cmdList = append(cmdList, &DeviceCmd{
|
||||||
data = binary.BigEndian.AppendUint32(data, crc)
|
Id: binary.BigEndian.Uint16(data[i : i+2]),
|
||||||
data = append(data, FrameTail)
|
Cmd: data[i+2],
|
||||||
return data
|
})
|
||||||
}
|
|
||||||
|
|
||||||
type ReadRegisterReq struct {
|
|
||||||
RegisterAddr []uint16 //寄存器地址
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ReadRegisterReq) Decode(buf []byte) error {
|
|
||||||
if len(buf)%2 != 0 {
|
|
||||||
return sys_error.New(logTag + "读寄存器数据字节长度不是2的倍数")
|
|
||||||
}
|
}
|
||||||
for i := 0; i < len(buf); i += 2 {
|
deviceData := &DeviceData{
|
||||||
r.RegisterAddr = append(r.RegisterAddr, binary.BigEndian.Uint16(buf[i:i+2]))
|
Num: num,
|
||||||
|
CmdList: cmdList,
|
||||||
}
|
}
|
||||||
return nil
|
return deviceData, index + i
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReadRegisterRes struct {
|
func decodeESBData(data []byte, index uint16) (*ESBData, uint16) {
|
||||||
RegisterData [][]byte //寄存器数据
|
data = data[index:]
|
||||||
|
num := binary.BigEndian.Uint16(data[0:2])
|
||||||
|
nextIndex := 2 + 6*num
|
||||||
|
data = data[2:nextIndex]
|
||||||
|
var cmdList []*ESBCmd
|
||||||
|
for i := 0; i < len(data); i += 6 {
|
||||||
|
cmdList = append(cmdList, &ESBCmd{
|
||||||
|
Id: binary.BigEndian.Uint16(data[i : i+2]),
|
||||||
|
JjtcCmd: data[i+2],
|
||||||
|
JjtcplCmd: data[i+3],
|
||||||
|
JjtcfmqCmd: data[i+4],
|
||||||
|
Ess1Cmd: data[i+5],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
deviceData := &ESBData{
|
||||||
|
Num: num,
|
||||||
|
CmdList: cmdList,
|
||||||
|
}
|
||||||
|
return deviceData, index + nextIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReadRegisterRes) Encode() []byte {
|
func decodeHoldTrainData(data []byte, index uint16) (*HoldTrainData, uint16) {
|
||||||
var data []byte
|
data = data[index:]
|
||||||
for _, datum := range r.RegisterData {
|
num := binary.BigEndian.Uint16(data[0:2])
|
||||||
data = append(data, datum...)
|
nextIndex := 2 + 6*num
|
||||||
|
data = data[2:nextIndex]
|
||||||
|
var cmdList []*HoldTrainCmd
|
||||||
|
for i := 0; i < len(data); i += 6 {
|
||||||
|
cmdList = append(cmdList, &HoldTrainCmd{
|
||||||
|
Id: binary.BigEndian.Uint16(data[i : i+2]),
|
||||||
|
KcCmd: data[i+2],
|
||||||
|
KcplCmd: data[i+3],
|
||||||
|
Kc2Cmd: data[i+4],
|
||||||
|
Kcpl2Cmd: data[i+5],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return data
|
deviceData := &HoldTrainData{
|
||||||
|
Num: num,
|
||||||
|
CmdList: cmdList,
|
||||||
|
}
|
||||||
|
return deviceData, index + nextIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
type WriteRegisterReq struct {
|
func decodeSPKSData(data []byte, index uint16) (*SPKSData, uint16) {
|
||||||
RegisterAddr []uint16 //寄存器地址
|
data = data[index:]
|
||||||
RegisterData [][]byte //寄存器数据
|
num := binary.BigEndian.Uint16(data[0:2])
|
||||||
|
nextIndex := 2 + 4*num
|
||||||
|
data = data[2:nextIndex]
|
||||||
|
var cmdList []*SPKSCmd
|
||||||
|
for i := 0; i < len(data); i += 4 {
|
||||||
|
cmdList = append(cmdList, &SPKSCmd{
|
||||||
|
Id: binary.BigEndian.Uint16(data[i : i+2]),
|
||||||
|
SPKSCmd: data[i+2],
|
||||||
|
SPKSPLCmd: data[i+3],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
deviceData := &SPKSData{
|
||||||
|
Num: num,
|
||||||
|
CmdList: cmdList,
|
||||||
|
}
|
||||||
|
return deviceData, index + nextIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WriteRegisterReq) Decode(buf []byte) error {
|
type DeviceData struct {
|
||||||
if len(buf)%6 != 0 {
|
Num uint16 //设备数量
|
||||||
return sys_error.New(logTag + "写寄存器数据字节长度不是6的倍数")
|
CmdList []*DeviceCmd
|
||||||
}
|
}
|
||||||
for i := 0; i < len(buf); i += 6 {
|
|
||||||
w.RegisterAddr = append(w.RegisterAddr, binary.BigEndian.Uint16(buf[i:i+2]))
|
type ESBData struct {
|
||||||
w.RegisterData = append(w.RegisterData, buf[i+2:i+6])
|
Num uint16 //紧急停车按钮的数量
|
||||||
}
|
CmdList []*ESBCmd
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
type HoldTrainData struct {
|
||||||
|
Num uint16 //扣车的数量
|
||||||
|
CmdList []*HoldTrainCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
type SPKSData struct {
|
||||||
|
Num uint16 //SPKS的数量
|
||||||
|
CmdList []*SPKSCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
type ESBCmd struct {
|
||||||
|
Id uint16 //紧急停车ID
|
||||||
|
JjtcCmd byte //紧急停车按钮命令
|
||||||
|
JjtcplCmd byte //紧急停车旁路按钮命令
|
||||||
|
JjtcfmqCmd byte //紧急停车蜂鸣器命令
|
||||||
|
Ess1Cmd byte //Ess1指示灯状态
|
||||||
|
}
|
||||||
|
|
||||||
|
type HoldTrainCmd struct {
|
||||||
|
Id uint16 //扣车ID
|
||||||
|
KcCmd byte //扣车命令
|
||||||
|
KcplCmd byte //扣车旁路命令
|
||||||
|
Kc2Cmd byte //2号扣车命令
|
||||||
|
Kcpl2Cmd byte //2号扣车旁路命令
|
||||||
|
}
|
||||||
|
|
||||||
|
type SPKSCmd struct {
|
||||||
|
Id uint16 //SPKS ID
|
||||||
|
SPKSCmd byte //SPKS按钮
|
||||||
|
SPKSPLCmd byte //SPKSPL按钮
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeviceCmd struct {
|
||||||
|
Id uint16 //设备ID
|
||||||
|
Cmd byte //设备命令
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToInterlockFrame 发往联锁的数据帧
|
||||||
|
type ToInterlockFrame struct {
|
||||||
|
Len uint16
|
||||||
|
WaysideCode uint16
|
||||||
|
InterlockCode uint16
|
||||||
|
TurnoutData *ToInterlockTurnoutData //道岔数据
|
||||||
|
PSDData *ToInterlockPSDData //屏蔽门数据
|
||||||
|
ESBData *ToInterlockESBData //紧急停车按钮数据
|
||||||
|
HoldTrainData *ToInterlockHoldTrainData //扣车按钮数据
|
||||||
|
SignalData *ToInterlockSignalData //信号机数据
|
||||||
|
AxleSectionData *ToInterlockAxleSectionData //计轴区段数据
|
||||||
|
WrzfData *ToInterlockWrzfData //无人折返数据
|
||||||
|
FymData *ToInterlockFymData //防淹门数据
|
||||||
|
SPKSData *ToInterlockSPKSData //SPKS数据
|
||||||
|
CkmData *ToInterlockCkmData //车库门数据
|
||||||
|
XcjData *ToInterlockXcjData //洗车机数据
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockTurnoutData struct {
|
||||||
|
Num uint16 //该联锁集中区包含的道岔数量
|
||||||
|
StateList []*TurnoutState
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockPSDData struct {
|
||||||
|
Num uint16 //该联锁集中区包含的屏蔽门数量
|
||||||
|
StateList []*PSDState
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockESBData struct {
|
||||||
|
Num uint16 //紧急停车按钮数量
|
||||||
|
StateList []*ESBState
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockHoldTrainData struct {
|
||||||
|
Num uint16 //扣车数量
|
||||||
|
StateList []*HoldTrainState
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockSignalData struct {
|
||||||
|
Num uint16 //该联锁集中区信号机的数量
|
||||||
|
StateList []*SignalState
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockAxleSectionData struct {
|
||||||
|
Num uint16 //该联锁集中区计轴区段的数量
|
||||||
|
StateList []*AxleSectionState
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockWrzfData struct {
|
||||||
|
Num uint16 //该联锁集中区无人折返的数量
|
||||||
|
StateList []*WrzfState
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockFymData struct {
|
||||||
|
Num uint16 //该联锁集中区防<E58CBA><E998B2>门的数量
|
||||||
|
StateList []*FymState
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockSPKSData struct {
|
||||||
|
Num uint16 //SPKS数量
|
||||||
|
StateList []*SPKSState
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockCkmData struct {
|
||||||
|
Num uint16 //车库门数量
|
||||||
|
StateList []*CkmState
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToInterlockXcjData struct {
|
||||||
|
Num uint16 //洗车机数量
|
||||||
|
StateList []*XcjState
|
||||||
|
}
|
||||||
|
|
||||||
|
type TurnoutState struct {
|
||||||
|
Id uint16 //道岔ID
|
||||||
|
State byte //道岔的采集状态
|
||||||
|
Alarm byte //道岔的报警状态
|
||||||
|
Current1 byte //转辙机1电流值,单位A
|
||||||
|
Current2 byte //转辙机2电流值,单位A
|
||||||
|
}
|
||||||
|
|
||||||
|
type PSDState struct {
|
||||||
|
Id uint16 //屏蔽门ID
|
||||||
|
State byte //屏蔽门开关门状态
|
||||||
|
Hsjc byte //互锁解除状态
|
||||||
|
PCB byte //PCB状态
|
||||||
|
POB byte //POB状态
|
||||||
|
DPB byte //DPB状态
|
||||||
|
}
|
||||||
|
|
||||||
|
type ESBState struct {
|
||||||
|
Id uint16 //紧急停车ID
|
||||||
|
State byte //紧急停车按钮状态
|
||||||
|
PlState byte //紧急停车按钮旁路状态
|
||||||
|
ESS byte //ESS状态(按下55,抬起aa)
|
||||||
|
}
|
||||||
|
|
||||||
|
type HoldTrainState struct {
|
||||||
|
Id uint16 //扣车ID
|
||||||
|
State byte //扣车按钮状态(按下55,抬起aa)
|
||||||
|
PlState byte //扣车按钮旁路状态(按下55,抬起aa)
|
||||||
|
State2 byte //2号扣车按钮状态(55开启,aa关闭)
|
||||||
|
PlState2 byte //2号扣车按钮旁路状态(55开启,aa关闭)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SignalState struct {
|
||||||
|
Id uint16 //信号机ID
|
||||||
|
State byte //信号机的采集状态
|
||||||
|
Current byte //信号机当前亮灯的电流值
|
||||||
|
}
|
||||||
|
|
||||||
|
type AxleSectionState struct {
|
||||||
|
Id uint16 //计轴区段Id
|
||||||
|
State byte //计轴区段的采集状态
|
||||||
|
}
|
||||||
|
|
||||||
|
type WrzfState struct {
|
||||||
|
Id uint16 //无人折返ID
|
||||||
|
State byte //无人折返的采集状态
|
||||||
|
}
|
||||||
|
|
||||||
|
type FymState struct {
|
||||||
|
Id uint16 //防淹门ID
|
||||||
|
OpenAndLock byte //防淹门打开锁闭状态
|
||||||
|
CloseReq byte //防淹门关闭请求状态
|
||||||
|
}
|
||||||
|
|
||||||
|
type SPKSState struct {
|
||||||
|
Id uint16 //SPKS ID
|
||||||
|
State byte //SPKS按钮状态
|
||||||
|
PlState byte //SPKSPL按钮状态
|
||||||
|
}
|
||||||
|
|
||||||
|
type CkmState struct {
|
||||||
|
Id uint16 //车库门ID
|
||||||
|
State byte //车库门采集状态
|
||||||
|
ModeState byte //车库门模式状态
|
||||||
|
FaultState byte //车库门故障状态
|
||||||
|
}
|
||||||
|
|
||||||
|
type XcjState struct {
|
||||||
|
Id uint16 //洗车机ID
|
||||||
|
Ready byte //洗车机就绪状态
|
||||||
|
ResponseConfirm byte //回复确认状态
|
||||||
|
GoState1 byte //出发状态1
|
||||||
|
GoState2 byte //出发状态2
|
||||||
|
StopState byte //急停状态
|
||||||
|
BackConfirm byte //返回确认状态
|
||||||
|
BackMode byte //模式
|
||||||
}
|
}
|
||||||
|
60
third_party/interlock/beijing11/msg_test.go
vendored
Normal file
60
third_party/interlock/beijing11/msg_test.go
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package beijing11
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFromInterlockFrame_Decode(t *testing.T) {
|
||||||
|
var interlockCode uint16 = 10010
|
||||||
|
var waysideCode uint16 = 10086
|
||||||
|
var data []byte
|
||||||
|
data = append(data, 0x82)
|
||||||
|
data = append(data, 0, 0) //报文长度(占位)
|
||||||
|
data = binary.BigEndian.AppendUint16(data, interlockCode)
|
||||||
|
data = binary.BigEndian.AppendUint16(data, waysideCode)
|
||||||
|
//填充设备数据
|
||||||
|
deviceCmdCount := []int{1, 1, 4, 4, 1, 1, 1, 1, 2, 1, 1}
|
||||||
|
for i, count := range deviceCmdCount {
|
||||||
|
data = binary.BigEndian.AppendUint16(data, uint16(i)) //设备数量
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
data = binary.BigEndian.AppendUint16(data, uint16(j)) //设备ID
|
||||||
|
for k := 0; k < count; k++ {
|
||||||
|
data = append(data, byte(k)) //设备命令
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//替换长度
|
||||||
|
len := uint16(len(data) - 3)
|
||||||
|
data[1] = byte(len >> 8)
|
||||||
|
data[2] = byte(len)
|
||||||
|
|
||||||
|
f := &FromInterlockFrame{}
|
||||||
|
err := f.Decode(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
marshal, _ := json.Marshal(f)
|
||||||
|
fmt.Println(marshal)
|
||||||
|
//if f.InterlockCode != interlockCode {
|
||||||
|
// t.Error()
|
||||||
|
//}
|
||||||
|
//if f.WaysideCode != waysideCode {
|
||||||
|
// t.Error()
|
||||||
|
//}
|
||||||
|
//elem := reflect.ValueOf(f).Elem()
|
||||||
|
//for i, count := range deviceCmdCount {
|
||||||
|
// field := elem.Field(3 + i)
|
||||||
|
// num := field.FieldByName("Num").Uint()
|
||||||
|
// if int(num) != count {
|
||||||
|
// t.Error()
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestName(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
@ -444,6 +444,7 @@ func (s *VerifySimulation) GetInterlockCodes() []*config.InterlockConfig {
|
|||||||
LocalPort: c.LocalPort,
|
LocalPort: c.LocalPort,
|
||||||
RemotePort: c.RemotePort,
|
RemotePort: c.RemotePort,
|
||||||
Open: c.Open,
|
Open: c.Open,
|
||||||
|
Line: c.Line,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return configs
|
return configs
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"joylink.club/bj-rtsts-server/third_party/acc"
|
"joylink.club/bj-rtsts-server/third_party/acc"
|
||||||
"joylink.club/bj-rtsts-server/third_party/btm_vobc"
|
"joylink.club/bj-rtsts-server/third_party/btm_vobc"
|
||||||
|
"joylink.club/bj-rtsts-server/third_party/interlock/beijing11"
|
||||||
"joylink.club/bj-rtsts-server/third_party/interlock/beijing12"
|
"joylink.club/bj-rtsts-server/third_party/interlock/beijing12"
|
||||||
"joylink.club/bj-rtsts-server/third_party/radar"
|
"joylink.club/bj-rtsts-server/third_party/radar"
|
||||||
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
||||||
@ -121,8 +122,13 @@ func runThirdParty(s *memory.VerifySimulation) error {
|
|||||||
semi_physical_train.Default().Start(s)
|
semi_physical_train.Default().Start(s)
|
||||||
// 联锁启动
|
// 联锁启动
|
||||||
for _, c := range s.GetInterlockCodes() {
|
for _, c := range s.GetInterlockCodes() {
|
||||||
|
switch c.Line {
|
||||||
|
case "11":
|
||||||
|
beijing11.Start(c)
|
||||||
|
default:
|
||||||
beijing12.Default(c).Start(s)
|
beijing12.Default(c).Start(s)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// 计轴RSSP启动
|
// 计轴RSSP启动
|
||||||
axle_device.StartLineAllRsspAxleServices(s)
|
axle_device.StartLineAllRsspAxleServices(s)
|
||||||
// 电机UDP启动
|
// 电机UDP启动
|
||||||
@ -152,8 +158,13 @@ func stopThirdParty(s *memory.VerifySimulation) {
|
|||||||
semi_physical_train.Default().Stop()
|
semi_physical_train.Default().Stop()
|
||||||
// 联锁启动
|
// 联锁启动
|
||||||
for _, c := range s.GetInterlockCodes() {
|
for _, c := range s.GetInterlockCodes() {
|
||||||
|
switch c.Line {
|
||||||
|
case "11":
|
||||||
|
beijing11.Stop()
|
||||||
|
default:
|
||||||
beijing12.Default(c).Stop()
|
beijing12.Default(c).Stop()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//计轴RSSP启动销毁
|
//计轴RSSP启动销毁
|
||||||
axle_device.StopLineAllRsspAxleServices()
|
axle_device.StopLineAllRsspAxleServices()
|
||||||
// 电机UDP停止
|
// 电机UDP停止
|
||||||
|
Loading…
Reference in New Issue
Block a user