-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
144 lines (126 loc) · 4 KB
/
main.go
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package flexitModbus
import (
"encoding/binary"
"fmt"
"sync"
"github.com/goburrow/modbus"
)
type registerExecutorFunc func(client modbus.Client) ([]byte, error)
const (
numberOfRegisters = 49
)
var clientHandlerFactory func() *modbus.RTUClientHandler
var lock sync.Mutex
func Setup(rtuClientHandlerFactory func() *modbus.RTUClientHandler) {
clientHandlerFactory = rtuClientHandlerFactory
}
func ReadAllHoldingRegisters() (registers map[string]WritableRegister, err error) {
fn := func(client modbus.Client) ([]byte, error) {
return client.ReadHoldingRegisters(0, numberOfRegisters)
}
bytesFromAllRegisters, err := registerExecutor(fn)
if err != nil {
return nil, err
}
registers = GetAllHoldingRegisters()
for _, register := range registers {
parseRegistersInto(bytesFromAllRegisters, register)
}
return
}
func ReadAllInputRegisters() (registers map[string]ReableRegister, err error) {
fn := func(client modbus.Client) ([]byte, error) {
return client.ReadInputRegisters(0, numberOfRegisters)
}
bytesFromAllRegisters, err := registerExecutor(fn)
if err != nil {
return nil, err
}
registers = GetAllInputRegisters()
for _, register := range registers {
parseRegistersInto(bytesFromAllRegisters, register)
}
return
}
func ReadHoldingRegister(registerName string) (holdingRegister WritableRegister, err error) {
register, found := GetAllHoldingRegisters()[registerName]
if !found {
return nil, fmt.Errorf("%v is not a holding register", registerName)
}
fn := func(client modbus.Client) ([]byte, error) {
return client.ReadHoldingRegisters(register.GetAddress(), register.GetNumberOfRegisters())
}
registerBytes, err := registerExecutor(fn)
if err != nil {
return nil, err
}
register.SetValueFromByteArray(registerBytes)
return register, nil
}
func GetHoldingRegister(registerName string) (holdingRegister WritableRegister, err error) {
register, found := GetAllHoldingRegisters()[registerName]
if !found {
return nil, fmt.Errorf("%v is not a holding register", registerName)
}
return register, nil
}
func ReadInputRegister(registerName string) (inputRegister ReableRegister, err error) {
register, found := GetAllInputRegisters()[registerName]
if !found {
return nil, fmt.Errorf("%v is not a input register", registerName)
}
fn := func(client modbus.Client) ([]byte, error) {
return client.ReadInputRegisters(register.GetAddress(), register.GetNumberOfRegisters())
}
registerBytes, err := registerExecutor(fn)
if err != nil {
return nil, err
}
register.SetValueFromByteArray(registerBytes)
return register, nil
}
func GetInputRegister(registerName string) (inputRegister ReableRegister, err error) {
register, found := GetAllInputRegisters()[registerName]
if !found {
return nil, fmt.Errorf("%v is not a input register", registerName)
}
return register, nil
}
func WriteHoldingRegister(register WritableRegister) error {
writeValue := register.GetValueAsUInt16()
fn := func(client modbus.Client) ([]byte, error) {
return client.WriteSingleRegister(register.GetAddress(), writeValue)
}
bytes, err := registerExecutor(fn)
if err != nil {
return err
}
readValue := binary.BigEndian.Uint16(bytes)
if readValue != writeValue {
return fmt.Errorf("Response value %v is not equal sendt value %v", readValue, writeValue)
}
return err
}
func registerExecutor(fn registerExecutorFunc) (result []byte, err error) {
if clientHandlerFactory == nil {
panic("rtuClientHandlerFactory was not set, did you forget to run the Setup() function?")
}
clientHandler := clientHandlerFactory()
err = clientHandler.Connect()
if err != nil {
return nil, fmt.Errorf("ERROR Failed to connect: %v", err)
}
defer clientHandler.Close()
client := modbus.NewClient(clientHandler)
lock.Lock()
result, err = fn(client)
lock.Unlock()
return
}
func parseRegistersInto(registers []byte, register ReableRegister) {
startIndex := register.GetAddress() * 2
endIndex := startIndex + register.GetNumberOfBytes()
registerBytes := registers[startIndex:endIndex]
register.SetValueFromByteArray(registerBytes)
return
}