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