package ym485 import ( "github.com/valyala/bytebufferpool" ) // QuerySoftVerAck 1E,查询单灯控制器软件版本响应,终端上报 type QuerySoftVerAck struct { Dp DataPack Mark [4]byte Model string //软件型号,ascii码 Version string //2字节BCD码,版本号 Date string //日期,日月年顺序 } func (o *QuerySoftVerAck) EnCode(Addr string, Mark [4]byte, Model string, Version string, Date string) (*bytebufferpool.ByteBuffer, error) { copy(o.Mark[0:], Mark[0:]) o.Model = Model o.Version = Version o.Date = Date tmpModel := make([]byte, 16) if len(Model) <= 16 { copy(tmpModel, o.Model) } else { copy(tmpModel, []byte(o.Model)[0:16]) } dataBuf := make([]byte, 0, 25) dataBuf = append(dataBuf, o.Mark[0:]...) dataBuf = append(dataBuf, tmpModel[0:]...) dataBuf = append(dataBuf, o.Version[0:]...) dataBuf = append(dataBuf, o.Date[0:]...) return o.Dp.EnCode(Addr, 0x1E, dataBuf) } func (o *QuerySoftVerAck) DeCode(data []byte) error { if err := o.Dp.DeCode(data); err == nil { len0 := len(o.Dp.Data) if len0 >= 25 { copy(o.Mark[0:], o.Dp.Data[0:4]) o.Model = string(o.Dp.Data[4:20]) o.Version = string(bcd2Ascii(o.Dp.Data[20:22])) o.Date = string(bcd2Ascii(o.Dp.Data[22:25])) } return nil } else { return err } } type DeviceState struct { State uint8 //当前状态 Voltage float64 //电压,2字节bcd码,1位小数从000.0~999.9 Current float64 //电压,2字节bcd码,2位小数从00.00~99.99 ActivePower uint16 //有功功率,2字节bcd码,无小数 LeakageCurrent float64 //漏电流值,2字节bcd码,2位小数 BrightnessState uint8 //调光状态,1字节BIN码 ColorState uint8 //调色温状态,1字节BIN码 Degree float64 //当前电度值,4字节bcd码,2位小数 } // QueryDeviceStateAck 1E,查询单灯控制器软件版本响应,终端上报 type QueryDeviceStateAck struct { Dp DataPack Mark [4]byte V byte //数据区版本号,03H L uint8 //路数 State []DeviceState //路n的状态 } func (o *QueryDeviceStateAck) EnCode(Addr string, Mark [4]byte, State []DeviceState) (*bytebufferpool.ByteBuffer, error) { copy(o.Mark[0:], Mark[0:]) o.V = 0x03 o.L = uint8(len(State)) dataBuf := make([]byte, 0, 6+15*len(State)) dataBuf = append(dataBuf, o.Mark[0:]...) dataBuf = append(dataBuf, o.V, o.L) for _, v := range State { dataBuf = append(dataBuf, v.State) buf, err := EncodeFloat64(v.Voltage, 3, 1) if err == nil { dataBuf = append(dataBuf, buf...) } buf, err = EncodeFloat64(v.Current, 2, 2) if err == nil { dataBuf = append(dataBuf, buf...) } buf, err = EncodeFloat64(float64(v.ActivePower), 4, 0) if err == nil { dataBuf = append(dataBuf, buf...) } buf, err = EncodeFloat64(v.LeakageCurrent, 2, 2) if err == nil { dataBuf = append(dataBuf, buf...) } dataBuf = append(dataBuf, v.BrightnessState) dataBuf = append(dataBuf, v.ColorState) buf, err = EncodeFloat64(v.Degree, 6, 2) if err == nil { dataBuf = append(dataBuf, buf...) } } return o.Dp.EnCode(Addr, 0x1E, dataBuf) } // DeCode 解码串口返回的数据 func (o *QueryDeviceStateAck) DeCode(data []byte) error { if err := o.Dp.DeCode(data); err == nil { //串口回的数据校验打包 len0 := len(o.Dp.Data) if len0 >= 6 { copy(o.Mark[0:], o.Dp.Data[0:4]) o.V = o.Dp.Data[4] o.L = o.Dp.Data[5] tmpData := o.Dp.Data[6:] for { obj, err := ParseState(tmpData) //解析所有路的电压电度等 if err == nil { o.State = append(o.State, *obj) tmpData = tmpData[15:] } else { break } } } return nil } else { return err } } func ParseState(data []byte) (*DeviceState, error) { if len(data) >= 15 { var obj DeviceState obj.State = data[0] f, err := DecodeFloat64(data[1:3], 1) if err == nil { obj.Voltage = f } f, err = DecodeFloat64(data[3:5], 2) if err == nil { obj.Current = f } f, err = DecodeFloat64(data[5:7], 0) if err == nil { obj.ActivePower = uint16(f) } f, err = DecodeFloat64(data[7:9], 2) if err == nil { obj.LeakageCurrent = f } obj.BrightnessState = data[9] obj.ColorState = data[10] f, err = DecodeFloat64(data[11:15], 2) if err == nil { obj.Degree = f } return &obj, nil } return nil, ErrorInvalidLenght }