From 2df84cdc7faf29cc8a2512b627a36a3881276b9f Mon Sep 17 00:00:00 2001 From: zhangqian <zhangqian@123.com> Date: 星期四, 26 十月 2023 16:29:15 +0800 Subject: [PATCH] plc4x读写加入长度 --- pkg/plc/apacheplc4x/modbus.go | 20 + pkg/plc/com.go | 467 ++++++++++++++++++++++++++------------------------- 2 files changed, 249 insertions(+), 238 deletions(-) diff --git a/pkg/plc/apacheplc4x/modbus.go b/pkg/plc/apacheplc4x/modbus.go index b289561..3876010 100644 --- a/pkg/plc/apacheplc4x/modbus.go +++ b/pkg/plc/apacheplc4x/modbus.go @@ -10,6 +10,7 @@ "github.com/apache/plc4x/plc4go/pkg/api/drivers" apiModel "github.com/apache/plc4x/plc4go/pkg/api/model" "github.com/apache/plc4x/plc4go/pkg/api/transports" + "github.com/spf13/cast" "sync/atomic" "time" ) @@ -53,7 +54,7 @@ func readHoldingRegisterSingle(connection plc4go.PlcConnection, address int) ([]byte, error) { tag := fmt.Sprintf("tag:%v", address) - tagAddress := getTagAddress(address) + tagAddress := getTagAddress(address, 1) // 璇绘ā寮� readRequest, err := connection.ReadRequestBuilder().AddTagAddress(tag, tagAddress).Build() @@ -83,7 +84,7 @@ func readHoldingRegisterList(connection plc4go.PlcConnection, address, length int) ([]byte, error) { tag := fmt.Sprintf("tag:%v:%v", address, length) - tagAddress := getTagAddress(address) + tagAddress := getTagAddress(address, length) // 璇绘ā寮� readRequest, err := connection.ReadRequestBuilder().AddTagAddress(tag, tagAddress).Build() @@ -130,12 +131,16 @@ return readHoldingRegisterSingle(connection, address) } -func getTagAddress(address int) string { +func getTagAddress(address int, length int) string { intType := conf.Conf.PLC.ModbusIntType if intType == "" { intType = "DINT" } - return fmt.Sprintf("holding-register:%d:%v", address, intType) + if length == 1 { + return fmt.Sprintf("holding-register:%d:%v", address, intType) + } else { + return fmt.Sprintf("holding-register:%d:%v[%d]", address, intType, length) + } } func WriteHoldingRegister(ipAddr string, address int, value any) (string, error) { @@ -146,7 +151,12 @@ } defer connection.Close() tag := fmt.Sprintf("tag:%v:w", address) - tagAddress := getTagAddress(address) + var tagAddress string + if cast.ToInt32(value) > 2<<16 { + tagAddress = getTagAddress(address, 2) + } else { + tagAddress = getTagAddress(address, 1) + } // 鍐欐ā寮� writeRequest, err := connection.WriteRequestBuilder().AddTagAddress(tag, tagAddress, value).Build() diff --git a/pkg/plc/com.go b/pkg/plc/com.go index 8905dd6..d5df41a 100644 --- a/pkg/plc/com.go +++ b/pkg/plc/com.go @@ -1,235 +1,236 @@ package plc -import ( - "encoding/hex" - "errors" - "fmt" - "io" - "strings" - "time" - - "github.com/jacobsa/go-serial/serial" -) - -/* -瀹氫箟涓插彛瀹㈡埛绔� -*/ - -type SerialClient struct { - readWriter io.ReadWriteCloser - OutBuffer chan string - PortName string - baudRate uint -} - -func NewSerialClient(portName string, baudRate uint) (*SerialClient, error) { - c := &SerialClient{ - readWriter: nil, - OutBuffer: make(chan string, 1024), - PortName: portName, - baudRate: baudRate, - } - r, err := c.open(portName, baudRate) - if err != nil { - return nil, err - } - - c.readWriter = r - return c, nil -} - -func (c *SerialClient) Start() { - for { - buf := make([]byte, 1024) - n, err := c.readWriter.Read(buf) - if err != nil { - if err != io.EOF { - //灏濊瘯閲嶆柊鎵撳紑 - r, err := c.open(c.PortName, c.baudRate) - if err != nil { - time.Sleep(2 * time.Second) - continue - } - c.readWriter = r - } - continue - } - - buf = buf[:n] - res := hex.EncodeToString(buf) - if strings.TrimSpace(res) == "" { - continue - } - fmt.Printf("Rx: %s\n", res) - c.OutBuffer <- res - } -} - -func (c *SerialClient) open(portName string, baudRate uint) (io.ReadWriteCloser, error) { - options := serial.OpenOptions{ - PortName: portName, - BaudRate: baudRate, - DataBits: 7, - StopBits: 1, - MinimumReadSize: 4, - ParityMode: serial.PARITY_EVEN, - } - - r, err := serial.Open(options) - if err != nil { - return nil, err - } - - c.readWriter = r - - return r, err -} - -func (c *SerialClient) Close() { - if c.readWriter != nil { - c.readWriter.Close() - } -} - -func (c *SerialClient) SendMsg(data string) (int, error) { - if c.readWriter == nil { - return 0, errors.New("serial port is closed") - } - - bytes, err := hex.DecodeString(data) - if err != nil { - return 0, err - } - - return c.readWriter.Write(bytes) -} - -func (c *SerialClient) ReadHoldRegister(addr string) (int, error) { - if c.readWriter == nil { - return 0, errors.New("serial port is closed") - } - - // 涓夎彵fn绯诲垪涓插彛鍗忚 - // 02 琛ㄧず寮�濮� + 30 琛ㄧず璇绘暟鎹� + 4浣嶅湴鍧�浣� + 02 鏁版嵁闀垮害 + 03 鍋滄 + 鍋舵牎楠� - - // 鍏堢粍瑁呮暟鎹� - // 璇诲彇鐨勫湴鍧� - dataBytes := append([]byte{0x30}, []byte(addr)...) - - // 璇诲彇鐨勯暱搴� - dataBytes = append(dataBytes, []byte("02")...) - - // 鍋滄 - dataBytes = append(dataBytes, []byte{0x03}...) - - // 璁$畻鏍¢獙鐮�, 30 + 鍦板潃缂栫爜 + 鏁版嵁闀垮害 + 03 , 鍗佸叚杩涘埗缁撴灉鍙栧悗涓や綅. - var sum uint8 - for _, d := range dataBytes { - sum += d - } - - sumStr := fmt.Sprintf("%x", sum) - - fmt.Printf("sumStr: %s\n", sumStr) - - var checkCode string - if len(sumStr) < 2 { - checkCode = "0" + sumStr - } else { - checkCode = sumStr[len(sumStr)-2:] - } - - var bytes = []byte{0x02} - // 娣诲姞鏁版嵁 - bytes = append(bytes, dataBytes...) - // 娣诲姞鏍¢獙 - bytes = append(bytes, []byte(checkCode)...) - - fmt.Printf("Tx: %X \n", bytes) - - // 鍐� - if n, err := c.readWriter.Write(bytes); err != nil { - return n, err - } else { - fmt.Printf("Tx:len:%d\n", n) - } - - // 璇� - buf := make([]byte, 1024) - n, err := c.readWriter.Read(buf) - if err != nil { - return n, err - } - - buf = buf[:n] - - fmt.Printf("Rx: %X\nRx len:%d", buf, n) - fmt.Printf("value: %d\n", buf[2:6]) - - return n, nil -} - -func (c *SerialClient) WriteHoldRegister(addr string) (int, error) { - if c.readWriter == nil { - return 0, errors.New("serial port is closed") - } - - // 涓夎彵fn绯诲垪涓插彛鍗忚 - // 02 琛ㄧず寮�濮� + 31 琛ㄧず鍐欐暟鎹� + 4浣嶅湴鍧�浣� + 02 鏁版嵁闀垮害 + 03 鍋滄 + 鍋舵牎楠� - - // 鍏堢粍瑁呮暟鎹� - // 璇诲彇鐨勫湴鍧� - dataBytes := append([]byte{0x31}, []byte(addr)...) - - // 璇诲彇鐨勯暱搴� - dataBytes = append(dataBytes, []byte("02")...) - - // 鍋滄 - dataBytes = append(dataBytes, []byte{0x03}...) - - // 璁$畻鏍¢獙鐮�, 30 + 鍦板潃缂栫爜 + 鏁版嵁闀垮害 + 03 , 鍗佸叚杩涘埗缁撴灉鍙栧悗涓や綅. - var sum uint8 - for _, d := range dataBytes { - sum += d - } - - sumStr := fmt.Sprintf("%x", sum) - - fmt.Printf("sumStr: %s\n", sumStr) - - var checkCode string - if len(sumStr) < 2 { - checkCode = "0" + sumStr - } else { - checkCode = sumStr[len(sumStr)-2:] - } - - var bytes = []byte{0x02} - // 娣诲姞鏁版嵁 - bytes = append(bytes, dataBytes...) - // 娣诲姞鏍¢獙 - bytes = append(bytes, []byte(checkCode)...) - - fmt.Printf("Tx: %X \n", bytes) - - // 鍐� - if n, err := c.readWriter.Write(bytes); err != nil { - return n, err - } else { - fmt.Printf("Tx:len:%d\n", n) - } - - // 璇� - buf := make([]byte, 1024) - n, err := c.readWriter.Read(buf) - if err != nil { - return n, err - } - - buf = buf[:n] - - fmt.Printf("Rx: %X\nRx len:%d", buf, n) - fmt.Printf("value: %d\n", buf[2:6]) - - return n, nil -} +// +//import ( +// "encoding/hex" +// "errors" +// "fmt" +// "io" +// "strings" +// "time" +// +// "github.com/jacobsa/go-serial/serial" +//) +// +///* +//瀹氫箟涓插彛瀹㈡埛绔� +//*/ +// +//type SerialClient struct { +// readWriter io.ReadWriteCloser +// OutBuffer chan string +// PortName string +// baudRate uint +//} +// +//func NewSerialClient(portName string, baudRate uint) (*SerialClient, error) { +// c := &SerialClient{ +// readWriter: nil, +// OutBuffer: make(chan string, 1024), +// PortName: portName, +// baudRate: baudRate, +// } +// r, err := c.open(portName, baudRate) +// if err != nil { +// return nil, err +// } +// +// c.readWriter = r +// return c, nil +//} +// +//func (c *SerialClient) Start() { +// for { +// buf := make([]byte, 1024) +// n, err := c.readWriter.Read(buf) +// if err != nil { +// if err != io.EOF { +// //灏濊瘯閲嶆柊鎵撳紑 +// r, err := c.open(c.PortName, c.baudRate) +// if err != nil { +// time.Sleep(2 * time.Second) +// continue +// } +// c.readWriter = r +// } +// continue +// } +// +// buf = buf[:n] +// res := hex.EncodeToString(buf) +// if strings.TrimSpace(res) == "" { +// continue +// } +// fmt.Printf("Rx: %s\n", res) +// c.OutBuffer <- res +// } +//} +// +//func (c *SerialClient) open(portName string, baudRate uint) (io.ReadWriteCloser, error) { +// options := serial.OpenOptions{ +// PortName: portName, +// BaudRate: baudRate, +// DataBits: 7, +// StopBits: 1, +// MinimumReadSize: 4, +// ParityMode: serial.PARITY_EVEN, +// } +// +// r, err := serial.Open(options) +// if err != nil { +// return nil, err +// } +// +// c.readWriter = r +// +// return r, err +//} +// +//func (c *SerialClient) Close() { +// if c.readWriter != nil { +// c.readWriter.Close() +// } +//} +// +//func (c *SerialClient) SendMsg(data string) (int, error) { +// if c.readWriter == nil { +// return 0, errors.New("serial port is closed") +// } +// +// bytes, err := hex.DecodeString(data) +// if err != nil { +// return 0, err +// } +// +// return c.readWriter.Write(bytes) +//} +// +//func (c *SerialClient) ReadHoldRegister(addr string) (int, error) { +// if c.readWriter == nil { +// return 0, errors.New("serial port is closed") +// } +// +// // 涓夎彵fn绯诲垪涓插彛鍗忚 +// // 02 琛ㄧず寮�濮� + 30 琛ㄧず璇绘暟鎹� + 4浣嶅湴鍧�浣� + 02 鏁版嵁闀垮害 + 03 鍋滄 + 鍋舵牎楠� +// +// // 鍏堢粍瑁呮暟鎹� +// // 璇诲彇鐨勫湴鍧� +// dataBytes := append([]byte{0x30}, []byte(addr)...) +// +// // 璇诲彇鐨勯暱搴� +// dataBytes = append(dataBytes, []byte("02")...) +// +// // 鍋滄 +// dataBytes = append(dataBytes, []byte{0x03}...) +// +// // 璁$畻鏍¢獙鐮�, 30 + 鍦板潃缂栫爜 + 鏁版嵁闀垮害 + 03 , 鍗佸叚杩涘埗缁撴灉鍙栧悗涓や綅. +// var sum uint8 +// for _, d := range dataBytes { +// sum += d +// } +// +// sumStr := fmt.Sprintf("%x", sum) +// +// fmt.Printf("sumStr: %s\n", sumStr) +// +// var checkCode string +// if len(sumStr) < 2 { +// checkCode = "0" + sumStr +// } else { +// checkCode = sumStr[len(sumStr)-2:] +// } +// +// var bytes = []byte{0x02} +// // 娣诲姞鏁版嵁 +// bytes = append(bytes, dataBytes...) +// // 娣诲姞鏍¢獙 +// bytes = append(bytes, []byte(checkCode)...) +// +// fmt.Printf("Tx: %X \n", bytes) +// +// // 鍐� +// if n, err := c.readWriter.Write(bytes); err != nil { +// return n, err +// } else { +// fmt.Printf("Tx:len:%d\n", n) +// } +// +// // 璇� +// buf := make([]byte, 1024) +// n, err := c.readWriter.Read(buf) +// if err != nil { +// return n, err +// } +// +// buf = buf[:n] +// +// fmt.Printf("Rx: %X\nRx len:%d", buf, n) +// fmt.Printf("value: %d\n", buf[2:6]) +// +// return n, nil +//} +// +//func (c *SerialClient) WriteHoldRegister(addr string) (int, error) { +// if c.readWriter == nil { +// return 0, errors.New("serial port is closed") +// } +// +// // 涓夎彵fn绯诲垪涓插彛鍗忚 +// // 02 琛ㄧず寮�濮� + 31 琛ㄧず鍐欐暟鎹� + 4浣嶅湴鍧�浣� + 02 鏁版嵁闀垮害 + 03 鍋滄 + 鍋舵牎楠� +// +// // 鍏堢粍瑁呮暟鎹� +// // 璇诲彇鐨勫湴鍧� +// dataBytes := append([]byte{0x31}, []byte(addr)...) +// +// // 璇诲彇鐨勯暱搴� +// dataBytes = append(dataBytes, []byte("02")...) +// +// // 鍋滄 +// dataBytes = append(dataBytes, []byte{0x03}...) +// +// // 璁$畻鏍¢獙鐮�, 30 + 鍦板潃缂栫爜 + 鏁版嵁闀垮害 + 03 , 鍗佸叚杩涘埗缁撴灉鍙栧悗涓や綅. +// var sum uint8 +// for _, d := range dataBytes { +// sum += d +// } +// +// sumStr := fmt.Sprintf("%x", sum) +// +// fmt.Printf("sumStr: %s\n", sumStr) +// +// var checkCode string +// if len(sumStr) < 2 { +// checkCode = "0" + sumStr +// } else { +// checkCode = sumStr[len(sumStr)-2:] +// } +// +// var bytes = []byte{0x02} +// // 娣诲姞鏁版嵁 +// bytes = append(bytes, dataBytes...) +// // 娣诲姞鏍¢獙 +// bytes = append(bytes, []byte(checkCode)...) +// +// fmt.Printf("Tx: %X \n", bytes) +// +// // 鍐� +// if n, err := c.readWriter.Write(bytes); err != nil { +// return n, err +// } else { +// fmt.Printf("Tx:len:%d\n", n) +// } +// +// // 璇� +// buf := make([]byte, 1024) +// n, err := c.readWriter.Read(buf) +// if err != nil { +// return n, err +// } +// +// buf = buf[:n] +// +// fmt.Printf("Rx: %X\nRx len:%d", buf, n) +// fmt.Printf("value: %d\n", buf[2:6]) +// +// return n, nil +//} -- Gitblit v1.8.0