2024-04-09 08:55:33 +08:00
|
|
|
package message
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"fmt"
|
|
|
|
"github.com/snksoft/crc"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
const PC_SIM_HEADER = 0xEB
|
|
|
|
|
|
|
|
type TrainPcSimBaseMessage struct {
|
|
|
|
Type uint16
|
|
|
|
DataLen byte
|
|
|
|
Data []byte
|
|
|
|
Crc uint16 // 校验码
|
|
|
|
}
|
|
|
|
|
|
|
|
// 编码
|
|
|
|
func (tp *TrainPcSimBaseMessage) Encode() []byte {
|
|
|
|
pack := make([]byte, 0)
|
|
|
|
pack = append(pack, PC_SIM_HEADER)
|
|
|
|
pack = binary.BigEndian.AppendUint16(pack, tp.Type)
|
|
|
|
pack = append(pack, byte(len(tp.Data)))
|
|
|
|
dataBufs := bytes.NewBuffer(nil)
|
|
|
|
binary.Write(dataBufs, binary.BigEndian, tp.Data)
|
|
|
|
data := dataBufs.Bytes()
|
|
|
|
pack = append(pack, data...)
|
|
|
|
pack = binary.BigEndian.AppendUint16(pack, uint16(crc.CalculateCRC(crc.CRC16, data)))
|
|
|
|
return pack
|
|
|
|
}
|
|
|
|
|
|
|
|
// 解码
|
|
|
|
func (tp *TrainPcSimBaseMessage) Decode(data []byte) error {
|
|
|
|
if len(data) < 3 {
|
|
|
|
return fmt.Errorf("")
|
|
|
|
}
|
|
|
|
buf := bytes.NewBuffer(data)
|
|
|
|
h, _ := buf.ReadByte()
|
|
|
|
if h != PC_SIM_HEADER {
|
|
|
|
return fmt.Errorf("")
|
|
|
|
}
|
|
|
|
var pcType uint16
|
|
|
|
binary.Read(buf, binary.BigEndian, &pcType)
|
|
|
|
len, _ := buf.ReadByte()
|
|
|
|
if buf.Len() < int(len)+2 {
|
|
|
|
return fmt.Errorf("")
|
|
|
|
}
|
|
|
|
|
|
|
|
var dd = make([]byte, len)
|
|
|
|
|
|
|
|
binary.Read(buf, binary.BigEndian, &dd)
|
|
|
|
var crcCode uint16
|
|
|
|
binary.Read(buf, binary.BigEndian, &crcCode)
|
|
|
|
tp.Type = pcType
|
|
|
|
tp.DataLen = len
|
|
|
|
tp.Data = dd
|
|
|
|
tp.Crc = crcCode
|
|
|
|
return nil
|
|
|
|
//crc.CalculateCRC(crc.CRC16, data)
|
|
|
|
}
|
|
|
|
|
|
|
|
func IsTrue(d bool) byte {
|
|
|
|
if d {
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
func IsTrueForByte(d byte) bool {
|
|
|
|
if d == 1 {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// 列车速度位置报告
|
|
|
|
type TrainSpeedPlaceReportMsg struct {
|
|
|
|
//列车id
|
|
|
|
TrainId string
|
|
|
|
PulseCount1 uint32
|
|
|
|
PulseCount2 uint32
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tp *TrainSpeedPlaceReportMsg) ParsePulseCount1(s1, s2 uint32) {
|
|
|
|
tp.PulseCount1 += s1
|
|
|
|
tp.PulseCount2 += s2
|
|
|
|
}
|
|
|
|
func (tp *TrainSpeedPlaceReportMsg) Encode(runDir bool, s1, s2 uint32) []byte {
|
|
|
|
data := make([]byte, 0)
|
2024-04-16 17:26:37 +08:00
|
|
|
data = binary.BigEndian.AppendUint16(data, uint16(IsTrue(runDir)))
|
|
|
|
data = binary.BigEndian.AppendUint32(data, s1)
|
|
|
|
data = binary.BigEndian.AppendUint32(data, s2)
|
|
|
|
data = binary.BigEndian.AppendUint32(data, tp.PulseCount1)
|
|
|
|
data = binary.BigEndian.AppendUint32(data, tp.PulseCount2)
|
2024-04-09 08:55:33 +08:00
|
|
|
now := time.Now().UTC()
|
|
|
|
// 将时间转换为毫秒
|
|
|
|
millis := now.UnixNano() / int64(time.Millisecond)
|
|
|
|
millisStr := strconv.Itoa(int(millis))
|
|
|
|
strs := []rune(millisStr)
|
|
|
|
|
|
|
|
second, _ := strconv.Atoi(string(strs[:len(strs)-3]))
|
|
|
|
mm, _ := strconv.Atoi(string(strs[len(strs)-3:]))
|
2024-04-16 17:26:37 +08:00
|
|
|
data = binary.BigEndian.AppendUint32(data, uint32(second))
|
|
|
|
data = binary.BigEndian.AppendUint16(data, uint16(mm))
|
2024-04-09 08:55:33 +08:00
|
|
|
|
|
|
|
return data
|
|
|
|
}
|
|
|
|
|
2024-04-18 11:14:05 +08:00
|
|
|
func (tp *TrainSpeedPlaceReportMsg) Decode(d []byte) {
|
|
|
|
buf := bytes.NewBuffer(d)
|
|
|
|
var runDir uint16
|
|
|
|
binary.Read(buf, binary.BigEndian, &runDir)
|
|
|
|
var s1 uint32
|
|
|
|
binary.Read(buf, binary.BigEndian, &s1)
|
|
|
|
var s2 uint32
|
|
|
|
binary.Read(buf, binary.BigEndian, &s2)
|
|
|
|
var c1 uint32
|
|
|
|
binary.Read(buf, binary.BigEndian, &c1)
|
|
|
|
var c2 uint32
|
|
|
|
binary.Read(buf, binary.BigEndian, &c2)
|
|
|
|
var ts uint32
|
|
|
|
binary.Read(buf, binary.BigEndian, &ts)
|
|
|
|
fmt.Println(runDir, s1, s2, c1, c2, ts)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-04-09 08:55:33 +08:00
|
|
|
// 轨旁向列车pc仿真发送的命令码
|
|
|
|
const (
|
|
|
|
//钥匙开关状态
|
|
|
|
KEY_STATE = iota
|
|
|
|
//手柄向前控制
|
|
|
|
HANDLE_FORWORD
|
|
|
|
//手柄向后控制
|
|
|
|
HANDLE_BACKWORD
|
|
|
|
//外部紧急制动反馈
|
|
|
|
OUTER_EMERGENCY_BRAKE
|
|
|
|
//列车制动状态
|
|
|
|
TRAIN_BRAKE_STATE
|
|
|
|
//开左门
|
|
|
|
LEFT_OPEN_DOOR
|
|
|
|
//关右门
|
|
|
|
CLOSE_RIGHT_DOOR
|
|
|
|
//关左门
|
|
|
|
CLOSE_LEFT_DOOR
|
|
|
|
//开右门
|
|
|
|
OPEN_RIGHT_DOOR
|
|
|
|
//折返按钮
|
|
|
|
TURN_BACK
|
|
|
|
//强制门允许
|
|
|
|
FORCE_DOOR_ALLOW
|
|
|
|
//模式降级按钮
|
|
|
|
TRAIN_MODE_DOWN
|
|
|
|
|
|
|
|
//确认按钮
|
|
|
|
CONFIRM
|
|
|
|
//模式升级按钮
|
|
|
|
TRAIN_MODE_UP
|
|
|
|
//牵引制动手柄零位
|
|
|
|
HANDLE_TO_ZERO
|
|
|
|
//ATO发车按钮
|
|
|
|
ATO_SEND_TRAIN
|
|
|
|
|
|
|
|
//列车完整性
|
|
|
|
TRAIN_INTEGRITY
|
|
|
|
//车载ATP/ATO旁路状态
|
|
|
|
ATP_ATO_BYPASS_STATe
|
|
|
|
//车辆牵引已切除状态
|
|
|
|
TRAIN_TRACTION_CUTED
|
|
|
|
//障碍物检测按钮
|
|
|
|
OBSTACLE_CHECK
|
|
|
|
//驾驶室激活反馈按钮
|
|
|
|
DRIVER_ACTIVE_REPORT
|
|
|
|
//制动重故障按钮
|
|
|
|
BRAKE_HEAVY_FAULT
|
|
|
|
//左门状态按钮
|
|
|
|
LEFT_DOOR_STATE
|
|
|
|
//右门状态按钮
|
|
|
|
RIGHT_DOOR_STATE
|
|
|
|
//唤醒按钮
|
|
|
|
WAKE_UP
|
|
|
|
//检修按钮
|
|
|
|
OVERHAUL
|
|
|
|
//欠压按钮
|
|
|
|
UNDERVOLTAGE
|
|
|
|
//休眠按钮
|
|
|
|
SLEEP
|
|
|
|
_
|
|
|
|
//紧急手柄拉下
|
|
|
|
EMERGENT_HANDLE_DOWN
|
|
|
|
//车门锁闭状态
|
|
|
|
DOOR_LOCK_STATE
|
|
|
|
//逃生门状态
|
|
|
|
LIFE_DOOR
|
|
|
|
//车辆低压上电状态
|
|
|
|
TRAIN_LOW_POWER
|
|
|
|
//ATP上电按钮
|
|
|
|
ATP_POWER_ON
|
|
|
|
_
|
|
|
|
//AA自动开关门
|
|
|
|
DOOR_MODE_AA
|
|
|
|
|
|
|
|
//AM自开人关
|
|
|
|
DOOR_MODE_AM
|
|
|
|
//MM人开人关
|
|
|
|
DOOR_MODE_MM
|
|
|
|
)
|