zhangzengfei
2023-08-11 742923a5512707bdfd4c0e2e9adfcb86b453be28
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package collector
 
import (
    "errors"
    "fmt"
 
    plc4go "github.com/apache/plc4x/plc4go/pkg/api"
    "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"
)
 
func NewModbusConnection(ipAddr string) (plc4go.PlcConnection, error) {
    // 创建驱动管理器
    driverManager := plc4go.NewPlcDriverManager()
 
    // 注册TCP传输
    transports.RegisterTcpTransport(driverManager)
 
    // 注册驱动
    //drivers.RegisterKnxDriver(driverManager)
    drivers.RegisterModbusTcpDriver(driverManager)
 
    // 通过TCP连接PLC设备
    connectionString := fmt.Sprintf("modbus-tcp://%s", ipAddr)
    connectionRequestChanel := driverManager.GetConnection(connectionString)
 
    // 等待连接响应
    connectionResult := <-connectionRequestChanel
 
    // 判断是否连接成功
    if err := connectionResult.GetErr(); err != nil {
        return nil, err
    }
 
    return connectionResult.GetConnection(), nil
}
 
func ReadHoldingRegister(connection plc4go.PlcConnection, address, length int) ([]byte, error) {
    if length > 1 {
        return ReadHoldingRegisterList(connection, address, length)
    }
 
    return ReadHoldingRegisterSingle(connection, address)
}
 
func ReadHoldingRegisterSingle(connection plc4go.PlcConnection, address int) ([]byte, error) {
    tagAddress := fmt.Sprintf("holding-register:%d:UINT", address)
 
    // 读模式
    readRequest, err := connection.ReadRequestBuilder().AddTagAddress("tag", tagAddress).Build()
    if err != nil {
        fmt.Printf("preparing read-request:%s\n", err.Error())
        return nil, err
    }
 
    // 执行
    readResult := <-readRequest.Execute()
    if err := readResult.GetErr(); err != nil {
        fmt.Printf("execting read-request:%s\n", err.Error())
        return nil, err
    }
 
    // 判断响应码是否正确
    if readResult.GetResponse().GetResponseCode("tag") != apiModel.PlcResponseCode_OK {
        fmt.Printf("error an non-ok return code: %s", readResult.GetResponse().GetResponseCode("tag").GetName())
        return nil, nil
    }
 
    value := readResult.GetResponse().GetValue("tag")
 
    return value.GetRaw(), err
 
}
 
func ReadHoldingRegisterList(connection plc4go.PlcConnection, address, length int) ([]byte, error) {
    tagAddress := fmt.Sprintf("holding-register:%d:UINT[%d]", address, length)
 
    // 读模式
    readRequest, err := connection.ReadRequestBuilder().AddTagAddress("tag", tagAddress).Build()
    if err != nil {
        fmt.Printf("preparing read-request:%s\n", err.Error())
        return nil, err
    }
 
    // 执行
    readResult := <-readRequest.Execute()
    if err := readResult.GetErr(); err != nil {
        fmt.Printf("execting read-request:%s\n", err.Error())
        return nil, err
    }
 
    // 判断响应码是否正确
    if readResult.GetResponse().GetResponseCode("tag") != apiModel.PlcResponseCode_OK {
        fmt.Printf("error an non-ok return code: %s", readResult.GetResponse().GetResponseCode("tag").GetName())
        return nil, errors.New("error  code: " + readResult.GetResponse().GetResponseCode("tag").GetName())
    }
 
    value := readResult.GetResponse().GetValue("tag")
 
    var result []byte
 
    for _, val := range value.GetList() {
        result = append(result, val.GetRaw()...)
    }
 
    return result, nil
}