package m9z import ( "encoding/binary" "fmt" "github.com/towgo/towgo/errors/terror" "tgk-touch/internal/global" ) type DeviceConfig struct { Latitude float64 // 纬度(实际值) Longitude float64 // 经度(实际值) TimezoneOffset float64 // 时区偏移(实际值,单位小时,如 UTC+8 为 8.0) SunriseAdjust int // 日出偏差调整(分钟) SunsetAdjust int // 日落偏差调整(分钟) ProgrammingMode uint8 // 编程模式 0-2 RS485Address uint8 // 485地址 (默认0x01) } // todo 和实际有出入 func DeviceConfigRead(deviceId string) (*DeviceConfig, error) { cmd, err := ReadCmd(deviceId, deviceConfig, "设备配置读取") if err != nil { return nil, err } data := cmd.Data // 数据长度校验(至少18字节) if len(data) < 18 { return nil, fmt.Errorf("invalid config data length: %d", len(data)) } dc := &DeviceConfig{} // 1. 解析纬度(Byte0-3,小端序int32) latInt := float64(binary.LittleEndian.Uint32(data[0:4])) dc.Latitude = float64(latInt) / 1_000_000 // 2. 解析经度(Byte4-7,小端序int32) lngInt := float64(binary.LittleEndian.Uint32(data[4:8])) dc.Longitude = float64(lngInt) / 1_000_000 // 3. 解析时区偏移(Byte8-11,小端序int32) tzInt := float64(binary.LittleEndian.Uint32(data[8:12])) dc.TimezoneOffset = float64(tzInt) / 1_000_000 // 4. 日出/日落调整(Byte12-13) g.Log().Infof("日出日落偏差2% X", data[12:14]) dc.SunriseAdjust = int(data[12]) dc.SunsetAdjust = int(data[13]) // 5. 编程模式(Byte16) dc.ProgrammingMode = data[16] // 6. 485地址(Byte17) dc.RS485Address = data[17] return dc, nil } func DeviceConfigWrite(deviceId string, dc *DeviceConfig) error { // 构造18字节数据缓冲区 buf := make([]byte, 18) // 1. 编码纬度(扩大1,000,000倍) latInt := int32(dc.Latitude * 1_000_000) binary.LittleEndian.PutUint32(buf[0:4], uint32(latInt)) // 2. 编码经度 lngInt := int32(dc.Longitude * 1_000_000) binary.LittleEndian.PutUint32(buf[4:8], uint32(lngInt)) // 3. 编码时区偏移 tzInt := int32(dc.TimezoneOffset * 1_000_000) binary.LittleEndian.PutUint32(buf[8:12], uint32(tzInt)) // 4. 日出/日落调整 buf[12] = byte(dc.SunriseAdjust) buf[13] = byte(dc.SunsetAdjust) // 5. 备用字段(Byte14-15)填充0 binary.LittleEndian.PutUint16(buf[14:16], 0) // 6. 编程模式 buf[16] = dc.ProgrammingMode // 7. 485地址 buf[17] = dc.RS485Address // 发送写入命令 writeResp, err := WriteCmd(deviceId, deviceConfig, buf, "设备配置写入") if err != nil { return err } if !writeResp.Success { return terror.New("写入失败") } return nil }