| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- package zigbee
- import (
- "encoding/binary"
- "errors"
- "time"
- "github.com/valyala/bytebufferpool"
- )
- var (
- HeadFlag2Down uint8 = 0xF2
- HeadFlag2Up uint8 = 0xF3
- )
- var (
- CmdSendData uint8 = 0x0B
- CmdSendDataAck uint8 = 0x8B
- CmdSetPid uint8 = 0x13
- CmdGetPid uint8 = 0x14
- CmdSetPidAck uint8 = 0x93
- CmdGetPidAck uint8 = 0x94
- )
- var ErrorProtocol = errors.New("协议错误")
- var ErrorInvalidCrc1 = errors.New("外层CRC校验错误")
- var ErrorInvalidCrc2 = errors.New("内层CRC校验错误")
- type Pack interface {
- SetData(Count, No, Cmd uint16, Data []byte)
- EnCode() (*bytebufferpool.ByteBuffer, error)
- DeCode(Data []byte) error
- }
- // MsgHeader2 消息格式
- type MsgHeader2 struct {
- Head byte //集中到单灯F2,单灯到集中F3
- PoleID uint32 //杆号
- Cmd2 uint8 //固定为F2
- Seq uint8 //流水号,循环利用
- Length2 uint8 //包体2长度
- Body2 Pack //包体内容,普通功能协议或升级功能协议
- Crc2 uint16 //内层CRC
- }
- func (o *MsgHeader2) SetDody(body Pack) {
- o.Body2 = body
- }
- func (o *MsgHeader2) SetData(PoleID uint32, Seq uint8) {
- o.PoleID = PoleID
- o.Seq = Seq
- }
- func (o *MsgHeader2) EnCode() (*bytebufferpool.ByteBuffer, error) {
- bytebuf, err := o.Body2.EnCode() //Body2 Pack //包体内容,普通功能协议或升级功能协议
- defer func() {
- if bytebuf != nil {
- bytebufferpool.Put(bytebuf)
- }
- }()
- if err != nil {
- return nil, err
- }
- buff := bytebufferpool.Get()
- buff.WriteByte(HeadFlag2Down) //Head byte //集中到单灯F2,单灯到集中F3
- tmp := make([]byte, 4)
- binary.BigEndian.PutUint32(tmp, o.PoleID)
- buff.Write(tmp) //LampID uint32 //杆号
- buff.WriteByte(0xF2) //Cmd2 uint8 //固定为F2
- buff.WriteByte(o.Seq) //Seq uint8 //流水号,循环利用
- buff.WriteByte(uint8(bytebuf.Len())) //Length2 uint8 //包体2长度
- buff.Write(bytebuf.B) //Body2 Pack //包体内容,普通功能协议或升级功能协议
- crc16 := CRC16(buff.B)
- tmp2 := make([]byte, 2)
- binary.BigEndian.PutUint16(tmp2, crc16)
- buff.Write(tmp2) //计算内层CRC16
- return buff, nil
- }
- func (o *MsgHeader2) DeCode(Data []byte) error {
- if len(Data) >= 10 {
- o.Head = Data[0] //集中到单灯F2,单灯到集中F3
- o.PoleID = binary.BigEndian.Uint32(Data[1:5]) //杆号
- o.Cmd2 = Data[5] //固定为F2
- o.Seq = Data[6] //流水号,循环利用
- o.Length2 = Data[7] //包体2长度
- o.Crc2 = binary.BigEndian.Uint16(Data[o.Length2+8 : o.Length2+10])
- crc := CRC16(Data[0 : o.Length2+8])
- if crc != o.Crc2 {
- return ErrorInvalidCrc2
- }
- return o.Body2.DeCode(Data[8 : o.Length2+8])
- }
- return ErrorProtocol
- }
- // GeneralFunc 普通功能协议
- type GeneralFunc struct {
- Len uint8 //此包长度
- Count uint8 //总包数
- No uint8 //当前升级包号
- Cmd uint8 //单杆命令
- Data []byte //数据内容
- }
- func (o *GeneralFunc) SetData(Count, No, Cmd uint16, Data []byte) {
- o.Cmd = uint8(Cmd)
- o.Data = Data
- o.Count = uint8(Count)
- o.No = uint8(No)
- }
- func (o *GeneralFunc) EnCode() (*bytebufferpool.ByteBuffer, error) {
- buff := bytebufferpool.Get()
- buff.WriteByte(uint8(4 + len(o.Data))) // Len uint8 //此包长度
- buff.WriteByte(0) //Count uint8 //总包数
- buff.WriteByte(0) //No uint8 //当前升级包号
- buff.WriteByte(o.Cmd) //M1Cmd uint8 //单杆命令
- buff.Write(o.Data) //mapData []byte //数据内容
- return buff, nil
- }
- func (o *GeneralFunc) DeCode(Data []byte) error {
- if len(Data) >= 4 {
- o.Len = Data[0]
- o.Count = Data[1]
- o.No = Data[2]
- o.Cmd = Data[3]
- o.Data = Data[4:]
- return nil
- }
- return ErrorProtocol
- }
- // UpgradeFunc 升级功能协议
- type UpgradeFunc struct {
- Len uint8 //此包长度
- Count uint16 //总包数
- No uint16 //当前升级包号
- Cmd uint8 //单杆命令
- Data []byte //数据内容
- }
- func (o *UpgradeFunc) SetData(Count, No, Cmd uint16, Data []byte) {
- o.Cmd = uint8(Cmd)
- o.Data = Data
- o.Count = Count
- o.No = No
- }
- func (o *UpgradeFunc) EnCode() (*bytebufferpool.ByteBuffer, error) {
- buff := bytebufferpool.Get()
- buff.WriteByte(uint8(6 + len(o.Data))) // Len uint8 //此包长度
- tmp := make([]byte, 2)
- binary.BigEndian.PutUint16(tmp, o.Count)
- buff.Write(tmp) //Count uint16 //总包数
- binary.BigEndian.PutUint16(tmp, o.No)
- buff.Write(tmp) //No uint16 //当前升级包号
- buff.WriteByte(o.Cmd) //M1Cmd uint8 //单杆命令
- buff.Write(o.Data) //mapData []byte //数据内容
- return buff, nil
- }
- func (o *UpgradeFunc) DeCode(Data []byte) error {
- if len(Data) >= 4 {
- o.Len = Data[0]
- o.Count = binary.BigEndian.Uint16(Data[1:3])
- o.No = binary.BigEndian.Uint16(Data[3:5])
- o.Cmd = Data[5]
- o.Data = Data[6:]
- return nil
- }
- return ErrorProtocol
- }
- type OnOffTime struct {
- OnHour uint8 `json:"onhour"`
- OnMinite uint8 `json:"onminite"`
- OffHour uint8 `json:"offhour"`
- OffMinite uint8 `json:"offminite"`
- Brightness uint8 `json:"brightness"` //亮度0~100
- }
- func (o *OnOffTime) SetData(onHour, onMinite, offHour, offMinite, brightness uint8) {
- o.OnHour = onHour
- o.OnMinite = onMinite
- o.OffHour = offHour
- o.OffMinite = offMinite
- o.Brightness = brightness
- }
- func (o *OnOffTime) EnCode() []byte {
- buff := make([]byte, 5)
- buff[0] = o.OnHour
- buff[1] = o.OnMinite
- buff[2] = o.OffHour
- buff[3] = o.OffMinite
- buff[4] = o.Brightness
- return buff
- }
- func (o *OnOffTime) DeCode(data []byte) error {
- if len(data) >= 5 {
- o.OnHour = data[0]
- o.OnMinite = data[1]
- o.OffHour = data[2]
- o.OffMinite = data[3]
- o.Brightness = data[4]
- return nil
- }
- return ErrorProtocol
- }
- func (o *OnOffTime) InTimeRange(t time.Time) bool {
- h := uint8(t.Hour())
- m := uint8(t.Minute())
- if o.OnHour > o.OffHour { //跨日情况,例如19:30~5:30,开灯时间大于关灯时间
- if h > o.OnHour || h < o.OffHour || (h == o.OnHour && m >= o.OnMinite) ||
- (h == o.OffHour && m <= o.OffMinite) {
- return true
- }
- } else if o.OnHour < o.OffHour { //开灯时间小于关灯时间
- if (h > o.OnHour && h < o.OffHour) ||
- (h == o.OnHour && m >= o.OnMinite) ||
- (h == o.OffHour && m <= o.OffMinite) {
- return true
- }
- } else { //开灯时间等于关灯时间
- if h == o.OnHour && m >= o.OnMinite && m <= o.OffMinite {
- return true
- }
- }
- return false
- }
- // CalculateChddjkZigbeeResponselength 长和单灯控制器zigbee协议,预估长度,非精确长度
- func CalculateChddjkZigbeeResponselength(adu []byte) int {
- return int(float32(len(adu)) * 1.5)
- }
|