fix
zhangqian
2023-12-01 8324f872ef3a4d0c978a9b1d062800c6a1701c12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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
}