-
Notifications
You must be signed in to change notification settings - Fork 5.5k
/
request.go
68 lines (57 loc) · 1.87 KB
/
request.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
package modbus
import "sort"
type request struct {
address uint16
length uint16
fields []field
tags map[string]string
}
func newRequest(f field, tags map[string]string) request {
r := request{
address: f.address,
length: f.length,
fields: []field{f},
tags: map[string]string{},
}
// Copy the tags
for k, v := range tags {
r.tags[k] = v
}
return r
}
func groupFieldsToRequests(fields []field, tags map[string]string, maxBatchSize uint16) []request {
if len(fields) == 0 {
return nil
}
// Sort the fields by address (ascending) and length
sort.Slice(fields, func(i, j int) bool {
addrI := fields[i].address
addrJ := fields[j].address
return addrI < addrJ || (addrI == addrJ && fields[i].length > fields[j].length)
})
// Construct the consecutive register chunks for the addresses and construct Modbus requests.
// For field addresses like [1, 2, 3, 5, 6, 10, 11, 12, 14] we should construct the following
// requests (1, 3) , (5, 2) , (10, 3), (14 , 1). Furthermore, we should respect field boundaries
// and the given maximum chunk sizes.
var requests []request
current := newRequest(fields[0], tags)
for _, f := range fields[1:] {
// Check if we need to interrupt the current chunk and require a new one
needInterrupt := f.address != current.address+current.length // not consecutive
needInterrupt = needInterrupt || f.length+current.length > maxBatchSize // too large
if !needInterrupt {
// Still safe to add the field to the current request
current.length += f.length
if !f.omit {
// Omit adding the field but use it for constructing the request.
current.fields = append(current.fields, f)
}
continue
}
// Finish the current request, add it to the list and construct a new one
requests = append(requests, current)
current = newRequest(f, tags)
}
requests = append(requests, current)
return requests
}