package fwh_mqtt import ( "encoding/json" "fmt" "hash/crc32" "time" ) const ( topicPrefixS2C = "fwh/s2c/" topicPrefixC2S = "fwh/c2s/" defaultSnno = 123 // 设备不按 snno 应答,固定值即可 equipTypeGateway = 0 // 外层设备类型:网关 IBG ) // FwhMqttMsg FWH MQTT 报文外层 type FwhMqttMsg struct { CmdType uint `json:"cmdType"` // 业务类型标识 Crc string `json:"crc"` // dataArea 数据字符串的CRC DataArea interface{} `json:"dataArea"` // 数据域 EquipNo string `json:"equipNo"` // 设备编号 SN Len int `json:"len"` // dataArea 数据长度 Snno uint `json:"snno"` // 序号 TimeStamp int64 `json:"timeStamp"` // 时间戳 Type uint `json:"type"` // 设备类型 0:设备网关IBG } // NewEnvelope 构造外层:len 为 dataArea 序列化字节长度,crc 为其 CRC32 IEEE 大写十六进制 func NewEnvelope(cmdType uint, equipNo string, dataArea any) (FwhMqttMsg, error) { b, err := json.Marshal(dataArea) if err != nil { return FwhMqttMsg{}, err } return FwhMqttMsg{ CmdType: cmdType, Type: equipTypeGateway, Snno: defaultSnno, TimeStamp: time.Now().Unix(), EquipNo: equipNo, DataArea: dataArea, Len: len(b), Crc: fmt.Sprintf("%08X", crc32.ChecksumIEEE(b)), }, nil } // S2CTopic 服务端 → 设备方向的 topic,如 S2CTopic("mng/" + sn) func S2CTopic(name string) string { return topicPrefixS2C + name } // C2STopic 设备 → 服务端方向的 topic func C2STopic(name string) string { return topicPrefixC2S + name }