You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
}