package apacheplc4x import ( "apsClient/model/common" "apsClient/pkg/logx" "context" "errors" "fmt" plc4go "github.com/apache/plc4x/plc4go/pkg/api" apiModel "github.com/apache/plc4x/plc4go/pkg/api/model" "github.com/spf13/cast" "time" ) func newModbusRTUConnection(c *common.RTUConfig) (plc4go.PlcConnection, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) // 创建一个新的 PLC 连接 connectionString := fmt.Sprintf("modbus-rtu:serial://%s?baudrate=%d&databits=%d&stopbits=%d&parity=%s", c.SerialName, c.BaudRate, c.DataBit, c.StopBit, c.Parity.ToString()) connectionRequestChanel := driverManager.GetConnection(connectionString) // 等待连接响应,同时考虑上下文的超时 select { case connectionResult := <-connectionRequestChanel: cancel() if err := connectionResult.GetErr(); err != nil { return nil, err } return connectionResult.GetConnection(), nil case <-ctx.Done(): cancel() return nil, errors.New("connect plc by modbusRTU timeout") } } func ReadHoldingRegisterByRTU(c *common.RTUConfig, address, length int) ([]byte, error) { connection, err := newModbusRTUConnection(c) if err != nil { return nil, err } defer connection.Close() if length > 1 { return readHoldingRegisterList(connection, address, length) } return readHoldingRegisterSingle(connection, address) } func WriteHoldingRegisterByRTU(c *common.RTUConfig, address int, value any) (string, error) { connection, err := newModbusRTUConnection(c) if err != nil { return "", err } defer connection.Close() tag := fmt.Sprintf("tag:%v:w", 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() if err != nil { logx.Errorf("plc4x preparing read-request:%s\n", err.Error()) return "", err } // 执行 writeResult := <-writeRequest.Execute() if err := writeResult.GetErr(); err != nil { logx.Errorf("plc4x execute write-request:%s\n", err.Error()) return "", err } // 判断响应码是否正确 if writeResult.GetResponse().GetResponseCode(tag) != apiModel.PlcResponseCode_OK { logx.Errorf("plc4x response error code: %s", writeResult.GetResponse().GetResponseCode(tag).GetName()) return "", errors.New("error code: " + writeResult.GetResponse().GetResponseCode(tag).GetName()) } result := writeResult.GetResponse().String() return result, nil }