| | |
| | | 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 |
| | | } |
| | | // |
| | | //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 |
| | | //} |