package switchRelay import ( "encoding/hex" "github.com/valyala/bytebufferpool" ) func (x DataPack) GetSwitchRelayCommand() *bytebufferpool.ByteBuffer { buf := bytebufferpool.Get() x.Function = 0x05 decodeAddress, _ := hex.DecodeString(x.Address) buf.Write(decodeAddress) buf.WriteByte(x.Function) buf.Write([]byte{0x00, byte(x.Way - 1)}) if x.Command == 1 { buf.Write([]byte{0xFF, 0x00}) } else { buf.Write([]byte{0x00, 0x00}) } x.Crc = calculateCRC16Modbus(buf.Bytes()) buf.Write([]byte{byte(x.Crc & 0xFF), byte(x.Crc >> 8)}) return buf } func (x MultiLoopDataPack) GetControlMuchSwitchRelayCommand() *bytebufferpool.ByteBuffer { buf := bytebufferpool.Get() x.Function = 0x10 decodeAddress, _ := hex.DecodeString(x.Address) buf.Write(decodeAddress) buf.WriteByte(x.Function) if x.TurnOff == 1 { //控制多路打开 buf.Write([]byte{0x04, 0x1A, 0x00, 0x02, 0x04, 0x00}) } else if x.TurnOff == 0 { //控制多路关闭 buf.Write([]byte{0x04, 0x1C, 0x00, 0x02, 0x04, 0x00}) } else { //控制多路取反 buf.Write([]byte{0x04, 0x1E, 0x00, 0x02, 0x04, 0x00}) } buf.Write(generateHexSwitchState(x.State)) x.Command = []byte{0x00, 0x00} buf.Write(x.Command) x.Crc = calculateCRC16Modbus(buf.Bytes()) buf.Write([]byte{byte(x.Crc & 0xFF), byte(x.Crc >> 8)}) return buf } func calculateCRC16Modbus(data []byte) uint16 { var crc uint16 = 0xFFFF // CRC-16 初始化值 for _, byteVal := range data { crc ^= uint16(byteVal) // 对字节进行异或操作 for i := 0; i < 8; i++ { if crc&0x0001 != 0 { crc >>= 1 crc ^= 0xA001 // 多项式 0xA001 } else { crc >>= 1 } } } return crc } func generateHexSwitchState(switches []int) []byte { var state int // 遍历切片,设置对应位置的开关为 1 for _, s := range switches { state |= 1 << (s - 1) // 设置第s位为1,s从1开始 } // 返回字节切片,使用 []byte{} 来包裹十六进制值 return []byte{byte(state)} }