package m9z import ( "encoding/binary" "fmt" "tgk-touch/internal/global" "time" ) type DeviceStatus struct { Mode uint // 模式 (0=自动, 1=手动) DeviceTime time.Time // 系统时间 (UTC秒数) Relays [10]bool // 10路继电器状态 (true=动作) Optocoupler [8]bool // 8路光耦输入状态 (true=触发) PWMOutputs [10]uint8 // 10路PWM输出值 (0-100) } func DeviceStatusRead(deviceId string) (*DeviceStatus, error) { cmd, err := ReadCmd(deviceId, deviceStatus, "读取设备的状态") if err != nil { return nil, err } data := cmd.Data // 数据长度校验 (至少需要18字节) if len(data) < 18 { return nil, fmt.Errorf("invalid data length: expect 18 bytes, got %d", len(data)) } ds := &DeviceStatus{} // 1. 解析工作模式 (Byte0) ds.Mode = uint(data[0]) // 2. 解析系统时间 (Byte1~4 小端序uint32) unixSec := int64(binary.LittleEndian.Uint32(data[1:5])) ds.DeviceTime = time.Unix(unixSec, 0).UTC() // 3. 解析10路继电器状态 (Byte5~6 小端序uint16) //relayBits := binary.LittleEndian.Uint16(data[5:7]) relayBits := binary.LittleEndian.Uint16(data[5:7]) g.Log().Debugf("%s 解析10路继电器状态(二进制): %016b ,% X", deviceId, relayBits, data[5:7]) // 补零显示16位 for i := 0; i < 10; i++ { ds.Relays[i] = (relayBits & (1 << i)) != 0 } // 4. 解析8路光耦输入 (Byte7) optoByte := data[7] for i := 0; i < 8; i++ { ds.Optocoupler[i] = (optoByte & (1 << i)) != 0 } // 5. 解析10路PWM输出 (Byte8~17) for i := 0; i < 10; i++ { ds.PWMOutputs[i] = uint8(data[8+i]) } return ds, nil }