-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathclient_rcb.go
156 lines (144 loc) · 4.64 KB
/
client_rcb.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
145
146
147
148
149
150
151
152
153
154
155
156
package iec61850
// #include <iec61850_client.h>
// #include <iec61850_common.h>
import "C"
import (
"unsafe"
)
type TrgOps struct {
DataChange bool // 值变化
QualityChange bool // 品质变化
DataUpdate bool // 数据修改
TriggeredPeriodically bool // 周期触发
Gi bool // GI(一般审问)请求触发
Transient bool // 瞬变
}
type OptFlds struct {
SequenceNumber bool // 顺序号
TimeOfEntry bool // 报告时标
ReasonForInclusion bool // 原因码
DataSetName bool // 数据集
DataReference bool // 数据引用
BufferOverflow bool // 缓存溢出标识
EntryID bool // 报告标识符
ConfigRevision bool // 配置版本号
}
type ClientReportControlBlock struct {
Ena bool // 使能
IntgPd int // 周期上送时间
TrgOps TrgOps // 触发条件
OptFlds OptFlds // 报告选项
}
func (c *Client) GetRCBValues(objectReference string) (*ClientReportControlBlock, error) {
var clientError C.IedClientError
cObjectRef := C.CString(objectReference)
defer C.free(unsafe.Pointer(cObjectRef))
rcb := C.IedConnection_getRCBValues(c.conn, &clientError, cObjectRef, nil)
if rcb == nil {
return nil, GetIedClientError(clientError)
}
return &ClientReportControlBlock{
Ena: c.getRCBEnable(rcb),
IntgPd: int(c.getRCBIntgPd(rcb)),
TrgOps: c.getTrgOps(rcb),
OptFlds: c.getOptFlds(rcb),
}, nil
}
func (c *Client) getRCBEnable(rcb C.ClientReportControlBlock) bool {
enable := C.ClientReportControlBlock_getRptEna(rcb)
return bool(enable)
}
func (c *Client) getRCBIntgPd(rcb C.ClientReportControlBlock) uint32 {
intgPd := C.ClientReportControlBlock_getIntgPd(rcb)
return uint32(intgPd)
}
func (c *Client) getOptFlds(rcb C.ClientReportControlBlock) OptFlds {
optFlds := C.ClientReportControlBlock_getOptFlds(rcb)
g := int(optFlds)
return OptFlds{
SequenceNumber: IsBitSet(g, 0),
TimeOfEntry: IsBitSet(g, 1),
ReasonForInclusion: IsBitSet(g, 2),
DataSetName: IsBitSet(g, 3),
DataReference: IsBitSet(g, 4),
BufferOverflow: IsBitSet(g, 5),
EntryID: IsBitSet(g, 6),
ConfigRevision: IsBitSet(g, 7),
}
}
func (c *Client) getTrgOps(rcb C.ClientReportControlBlock) TrgOps {
trgOps := C.ClientReportControlBlock_getTrgOps(rcb)
g := int(trgOps)
return TrgOps{
DataChange: IsBitSet(g, 0),
QualityChange: IsBitSet(g, 1),
DataUpdate: IsBitSet(g, 2),
TriggeredPeriodically: IsBitSet(g, 3),
Gi: IsBitSet(g, 4),
Transient: IsBitSet(g, 5),
}
}
func (c *Client) SetRCBValues(objectReference string, settings ClientReportControlBlock) error {
var clientError C.IedClientError
cObjectRef := C.CString(objectReference)
defer C.free(unsafe.Pointer(cObjectRef))
rcb := C.ClientReportControlBlock_create(cObjectRef)
defer C.ClientReportControlBlock_destroy(rcb)
var trgOps, optFlds C.int
// trgOps
if settings.TrgOps.DataChange {
trgOps = trgOps | C.TRG_OPT_DATA_CHANGED
}
if settings.TrgOps.QualityChange {
trgOps = trgOps | C.TRG_OPT_QUALITY_CHANGED
}
if settings.TrgOps.DataUpdate {
trgOps = trgOps | C.TRG_OPT_DATA_UPDATE
}
if settings.TrgOps.TriggeredPeriodically {
trgOps = trgOps | C.TRG_OPT_INTEGRITY
}
if settings.TrgOps.Gi {
trgOps = trgOps | C.TRG_OPT_GI
}
if settings.TrgOps.Transient {
trgOps = trgOps | C.TRG_OPT_TRANSIENT
}
// optFlds
if settings.OptFlds.SequenceNumber {
optFlds = optFlds | C.RPT_OPT_SEQ_NUM
}
if settings.OptFlds.TimeOfEntry {
optFlds = optFlds | C.RPT_OPT_TIME_STAMP
}
if settings.OptFlds.ReasonForInclusion {
optFlds = optFlds | C.RPT_OPT_REASON_FOR_INCLUSION
}
if settings.OptFlds.DataSetName {
optFlds = optFlds | C.RPT_OPT_DATA_SET
}
if settings.OptFlds.DataReference {
optFlds = optFlds | C.RPT_OPT_DATA_REFERENCE
}
if settings.OptFlds.BufferOverflow {
optFlds = optFlds | C.RPT_OPT_BUFFER_OVERFLOW
}
if settings.OptFlds.EntryID {
optFlds = optFlds | C.RPT_OPT_ENTRY_ID
}
if settings.OptFlds.ConfigRevision {
optFlds = optFlds | C.RPT_OPT_CONF_REV
}
C.ClientReportControlBlock_setTrgOps(rcb, trgOps) // 触发条件
C.ClientReportControlBlock_setRptEna(rcb, C.bool(settings.Ena)) // 报告使能
C.ClientReportControlBlock_setIntgPd(rcb, C.uint32_t(settings.IntgPd)) // 周期上送时间
C.ClientReportControlBlock_setOptFlds(rcb, optFlds)
C.IedConnection_setRCBValues(c.conn, &clientError, rcb, C.RCB_ELEMENT_RPT_ENA|C.RCB_ELEMENT_TRG_OPS|C.RCB_ELEMENT_INTG_PD, true)
if err := GetIedClientError(clientError); err != nil {
return err
}
return nil
}
func IsBitSet(val int, pos int) bool {
return (val & (1 << pos)) != 0
}