2023-10-24 09:14:54 +08:00
|
|
|
|
package message
|
|
|
|
|
|
2024-05-23 19:14:10 +08:00
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"math"
|
|
|
|
|
)
|
2023-10-24 09:14:54 +08:00
|
|
|
|
|
|
|
|
|
// 消息包头解析
|
2023-11-06 15:20:45 +08:00
|
|
|
|
type interlockMsgPkgHeader struct {
|
|
|
|
|
header1 byte //包头1 1个字节 0xFF
|
|
|
|
|
header2 byte //包头2 1个字节 0xFF
|
|
|
|
|
typeCode uint8 //类型码 1个字节 0x02
|
|
|
|
|
serialNumber uint8 //序列号 1个字节 序列号0~255
|
|
|
|
|
reserve1 byte //预留 1个字节
|
|
|
|
|
reserve2 byte //预留 1个字节
|
2023-10-24 09:14:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-06 15:20:45 +08:00
|
|
|
|
func newInterlockMsgPkgHeader() *interlockMsgPkgHeader {
|
|
|
|
|
return &interlockMsgPkgHeader{header1: 0xFF, header2: 0xFF, typeCode: 0x02}
|
2023-10-24 09:14:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-06 15:20:45 +08:00
|
|
|
|
func (h *interlockMsgPkgHeader) encode() []byte {
|
|
|
|
|
return []byte{h.header1, h.header2, h.typeCode, h.serialNumber, h.reserve1, h.reserve2}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *interlockMsgPkgHeader) decode(buf []byte) error {
|
2023-10-24 09:14:54 +08:00
|
|
|
|
if len(buf) < 6 {
|
|
|
|
|
return fmt.Errorf("数据少于6个字节")
|
|
|
|
|
}
|
2023-11-06 15:20:45 +08:00
|
|
|
|
h.header1 = buf[0]
|
|
|
|
|
h.header2 = buf[1]
|
|
|
|
|
h.typeCode = buf[2]
|
|
|
|
|
h.serialNumber = buf[3]
|
|
|
|
|
h.reserve1 = buf[4]
|
|
|
|
|
h.reserve2 = buf[5]
|
2023-10-24 09:14:54 +08:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 消息包尾解析
|
2023-11-06 15:20:45 +08:00
|
|
|
|
type interlockMsgPkgTail struct {
|
|
|
|
|
tail []byte // 包尾2个字节
|
2023-10-24 09:14:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-06 15:20:45 +08:00
|
|
|
|
func newInterlockMsgPkgTail() *interlockMsgPkgTail {
|
|
|
|
|
return &interlockMsgPkgTail{tail: make([]byte, 2)}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *interlockMsgPkgTail) encode() []byte {
|
|
|
|
|
if len(t.tail) == 0 {
|
2023-10-24 09:14:54 +08:00
|
|
|
|
return make([]byte, 2)
|
|
|
|
|
}
|
2023-11-06 15:20:45 +08:00
|
|
|
|
return t.tail
|
2023-10-24 09:14:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-06 15:20:45 +08:00
|
|
|
|
func (t *interlockMsgPkgTail) decode(buf []byte) error {
|
2023-10-24 09:14:54 +08:00
|
|
|
|
if len(buf) < 2 {
|
|
|
|
|
return fmt.Errorf("数据少于2个字节")
|
|
|
|
|
}
|
2023-11-06 15:20:45 +08:00
|
|
|
|
t.tail = buf[len(buf)-2:]
|
2023-10-24 09:14:54 +08:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送给联锁的采集数据
|
|
|
|
|
type InterlockSendMsgPkg struct {
|
2023-11-06 15:20:45 +08:00
|
|
|
|
header *interlockMsgPkgHeader // 包头
|
|
|
|
|
info []bool // 发给联锁的状态数据
|
|
|
|
|
tail *interlockMsgPkgTail // 包尾
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewInterlockSendMsgPkg(info []bool) *InterlockSendMsgPkg {
|
|
|
|
|
return &InterlockSendMsgPkg{
|
|
|
|
|
header: newInterlockMsgPkgHeader(),
|
|
|
|
|
info: info,
|
|
|
|
|
tail: newInterlockMsgPkgTail(),
|
|
|
|
|
}
|
2023-10-24 09:14:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-24 10:57:04 +08:00
|
|
|
|
var boolsToByteArrLen int = 8
|
|
|
|
|
|
2023-11-06 15:20:45 +08:00
|
|
|
|
func (m *InterlockSendMsgPkg) SetSerialNumber(serialNumber uint8) {
|
|
|
|
|
m.header.serialNumber = serialNumber
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-24 09:14:54 +08:00
|
|
|
|
func (m *InterlockSendMsgPkg) Encode() []byte {
|
|
|
|
|
var data []byte
|
2023-11-06 15:20:45 +08:00
|
|
|
|
data = append(data, m.header.encode()...)
|
2024-05-23 19:14:10 +08:00
|
|
|
|
bitLen := len(m.info)
|
|
|
|
|
byteLen := int(math.Ceil(float64(bitLen) / 8))
|
|
|
|
|
infoBytes := make([]byte, byteLen)
|
|
|
|
|
for i, b := range m.info {
|
|
|
|
|
if b {
|
|
|
|
|
infoBytes[i/8] = infoBytes[i/8] + (1 << (i % 8))
|
2023-10-24 10:57:04 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-23 19:14:10 +08:00
|
|
|
|
data = append(data, infoBytes...)
|
|
|
|
|
|
|
|
|
|
//for index, length, cycles := 0, len(m.info), len(m.info)/boolsToByteArrLen; index < cycles; index++ {
|
|
|
|
|
// startIndex := index * boolsToByteArrLen
|
|
|
|
|
// toByteArr := [8]bool{}
|
|
|
|
|
// for i := 0; i < boolsToByteArrLen && startIndex < length; i++ {
|
|
|
|
|
// startIndex = startIndex + i
|
|
|
|
|
// toByteArr[i] = m.info[startIndex+i]
|
|
|
|
|
// }
|
|
|
|
|
// data = append(data, boolsToByte(toByteArr))
|
|
|
|
|
//}
|
2023-11-06 15:20:45 +08:00
|
|
|
|
data = append(data, m.tail.encode()...)
|
2023-10-24 09:14:54 +08:00
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-24 10:57:04 +08:00
|
|
|
|
// bool数组转byte
|
|
|
|
|
func boolsToByte(flags [8]bool) byte {
|
|
|
|
|
var result uint8
|
2023-10-25 11:09:29 +08:00
|
|
|
|
for index, b := range flags {
|
2023-10-24 10:57:04 +08:00
|
|
|
|
if b {
|
2023-10-25 11:09:29 +08:00
|
|
|
|
result = result + (1 << index)
|
2023-10-24 10:57:04 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-24 09:14:54 +08:00
|
|
|
|
// 收到联锁发来的驱动数据
|
|
|
|
|
type InterlockReceiveMsgPkg struct {
|
2023-10-31 15:23:29 +08:00
|
|
|
|
toagent_len int
|
|
|
|
|
et_out_num int
|
|
|
|
|
tcc_output_len int
|
2023-11-06 15:20:45 +08:00
|
|
|
|
header *interlockMsgPkgHeader // 包头
|
2023-10-30 15:23:56 +08:00
|
|
|
|
SyncZone []byte // 同步区状态
|
|
|
|
|
DriveInfo []bool // 驱动数据
|
|
|
|
|
TccInfo []*InterlockResponderMsgPkg // 应答器报文
|
2023-11-06 15:20:45 +08:00
|
|
|
|
tail *interlockMsgPkgTail // 包尾
|
2023-10-30 15:23:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应答器数据格式
|
|
|
|
|
type InterlockResponderMsgPkg struct {
|
|
|
|
|
Index byte
|
|
|
|
|
InternalIndex byte
|
|
|
|
|
Reserve byte
|
|
|
|
|
MsgInfo []byte
|
2023-10-24 09:14:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ET_OUT_NUM、TOAGENTLEN、TCC_OUTPUT_LEN(应答器数量*131)的具体数值取决于数据配置。
|
2023-10-31 15:23:29 +08:00
|
|
|
|
func NewInterlockReceiveMsgPkg(tlen, etLen, tccLen int) *InterlockReceiveMsgPkg {
|
2023-10-24 09:14:54 +08:00
|
|
|
|
return &InterlockReceiveMsgPkg{
|
|
|
|
|
toagent_len: tlen,
|
|
|
|
|
et_out_num: etLen,
|
2023-11-01 16:55:16 +08:00
|
|
|
|
tcc_output_len: tccLen * 131,
|
2023-11-06 15:20:45 +08:00
|
|
|
|
header: newInterlockMsgPkgHeader(),
|
|
|
|
|
tail: newInterlockMsgPkgTail(),
|
2023-10-24 09:14:54 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *InterlockReceiveMsgPkg) Decode(buf []byte) error {
|
2023-11-06 14:30:09 +08:00
|
|
|
|
if len(buf) < 8 {
|
|
|
|
|
return fmt.Errorf("buf 没有足够的数据")
|
|
|
|
|
}
|
2023-10-31 15:23:29 +08:00
|
|
|
|
var preIndex, lastIndex int = 0, 6
|
2023-10-24 09:14:54 +08:00
|
|
|
|
// 包头
|
2023-11-06 15:20:45 +08:00
|
|
|
|
t.header.decode(buf[preIndex:lastIndex])
|
2023-10-24 09:14:54 +08:00
|
|
|
|
// 同步区状态
|
|
|
|
|
preIndex = lastIndex
|
|
|
|
|
lastIndex = lastIndex + t.toagent_len
|
2023-10-30 15:23:56 +08:00
|
|
|
|
t.SyncZone = buf[preIndex:lastIndex]
|
2023-10-24 09:14:54 +08:00
|
|
|
|
// 驱动数据
|
|
|
|
|
preIndex = lastIndex
|
|
|
|
|
lastIndex = lastIndex + t.et_out_num
|
2024-06-06 18:40:48 +08:00
|
|
|
|
t.parseByte(buf, preIndex, lastIndex)
|
2023-10-24 09:14:54 +08:00
|
|
|
|
// 应答器报文
|
|
|
|
|
preIndex = lastIndex
|
|
|
|
|
lastIndex = lastIndex + t.tcc_output_len
|
2023-10-30 15:23:56 +08:00
|
|
|
|
t.TccInfo = parseResponder(buf, preIndex, lastIndex)
|
2023-10-24 09:14:54 +08:00
|
|
|
|
// 包尾
|
2023-11-06 15:20:45 +08:00
|
|
|
|
t.tail.decode(buf)
|
2023-10-24 09:14:54 +08:00
|
|
|
|
return nil
|
|
|
|
|
}
|
2023-10-24 10:57:04 +08:00
|
|
|
|
|
2024-06-06 18:40:48 +08:00
|
|
|
|
func (t *InterlockReceiveMsgPkg) parseByte(buf []byte, start, end int) {
|
2023-10-24 10:57:04 +08:00
|
|
|
|
for i := start; i < end; i++ {
|
|
|
|
|
b := buf[i]
|
|
|
|
|
for bit := 7; bit >= 0; bit-- {
|
2024-06-06 18:40:48 +08:00
|
|
|
|
t.DriveInfo = append(t.DriveInfo, (b&(1<<bit)) != 0)
|
2023-10-24 10:57:04 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-30 15:23:56 +08:00
|
|
|
|
|
2023-10-31 15:23:29 +08:00
|
|
|
|
func parseResponder(buf []byte, start, end int) []*InterlockResponderMsgPkg {
|
2023-10-30 15:23:56 +08:00
|
|
|
|
var msgs []*InterlockResponderMsgPkg
|
|
|
|
|
for i := start; i < end; i = i + 128 {
|
|
|
|
|
b := buf[i : i+128]
|
|
|
|
|
msgs = append(msgs, &InterlockResponderMsgPkg{
|
|
|
|
|
Index: b[0],
|
|
|
|
|
InternalIndex: b[1],
|
|
|
|
|
Reserve: b[2],
|
|
|
|
|
MsgInfo: b[3:],
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
return msgs
|
|
|
|
|
}
|