Skip to content

Commit 18ee91f

Browse files
committed
增加control和sg相关操作
1 parent 3c9ee64 commit 18ee91f

File tree

379 files changed

+919
-3288
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

379 files changed

+919
-3288
lines changed

client.go

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
package iec61850
2+
3+
// #include <iec61850_client.h>
4+
import "C"
5+
import (
6+
"sync/atomic"
7+
"unsafe"
8+
)
9+
10+
type Client struct {
11+
conn C.IedConnection
12+
connected *atomic.Bool
13+
}
14+
15+
type Settings struct {
16+
Host string
17+
Port int
18+
ConnectTimeout uint
19+
RequestTimeout uint
20+
}
21+
22+
func NewSettings() *Settings {
23+
return &Settings{
24+
Host: "localhost",
25+
Port: 102,
26+
ConnectTimeout: 10000,
27+
RequestTimeout: 10000,
28+
}
29+
}
30+
31+
func NewClient(settings *Settings) (*Client, error) {
32+
conn, clientErr := connect(settings)
33+
if err := GetIedClientError(clientErr); err != nil {
34+
return nil, err
35+
}
36+
37+
connected := &atomic.Bool{}
38+
connected.Store(true)
39+
connection := &Client{
40+
conn: conn,
41+
connected: connected,
42+
}
43+
return connection, nil
44+
}
45+
46+
func (c *Client) Write(objectRef string, fc FC, value interface{}) error {
47+
mmsType, err := c.GetVariableSpecType(objectRef, fc)
48+
if err != nil {
49+
return err
50+
}
51+
var (
52+
mmsValue *C.MmsValue
53+
clientError C.IedClientError
54+
)
55+
56+
mmsValue, err = toMmsValue(mmsType, value)
57+
if err != nil {
58+
return err
59+
}
60+
61+
cObjectRef := C.CString(objectRef)
62+
defer C.free(unsafe.Pointer(cObjectRef))
63+
defer C.MmsValue_delete(mmsValue)
64+
C.IedConnection_writeObject(c.conn, &clientError, cObjectRef, C.FunctionalConstraint(fc), mmsValue)
65+
return GetIedClientError(clientError)
66+
}
67+
68+
// ReadBool 读取bool类型值
69+
func (c *Client) ReadBool(objectRef string, fc FC) (bool, error) {
70+
cObjectRef := C.CString(objectRef)
71+
defer C.free(unsafe.Pointer(cObjectRef))
72+
73+
var clientError C.IedClientError
74+
value := C.IedConnection_readBooleanValue(c.conn, &clientError, cObjectRef, C.FunctionalConstraint(fc))
75+
if err := GetIedClientError(clientError); err != nil {
76+
return false, err
77+
}
78+
return bool(value), nil
79+
}
80+
81+
// ReadInt32 读取int32类型值
82+
func (c *Client) ReadInt32(objectRef string, fc FC) (int32, error) {
83+
cObjectRef := C.CString(objectRef)
84+
defer C.free(unsafe.Pointer(cObjectRef))
85+
86+
var clientError C.IedClientError
87+
value := C.IedConnection_readInt32Value(c.conn, &clientError, cObjectRef, C.FunctionalConstraint(fc))
88+
if err := GetIedClientError(clientError); err != nil {
89+
return 0, err
90+
}
91+
return int32(value), nil
92+
}
93+
94+
// ReadInt64 读取int64类型值
95+
func (c *Client) ReadInt64(objectRef string, fc FC) (int64, error) {
96+
cObjectRef := C.CString(objectRef)
97+
defer C.free(unsafe.Pointer(cObjectRef))
98+
99+
var clientError C.IedClientError
100+
value := C.IedConnection_readInt64Value(c.conn, &clientError, cObjectRef, C.FunctionalConstraint(fc))
101+
if err := GetIedClientError(clientError); err != nil {
102+
return 0, err
103+
}
104+
return int64(value), nil
105+
}
106+
107+
// ReadUint32 读取uint32类型值
108+
func (c *Client) ReadUint32(objectRef string, fc FC) (uint32, error) {
109+
cObjectRef := C.CString(objectRef)
110+
defer C.free(unsafe.Pointer(cObjectRef))
111+
112+
var clientError C.IedClientError
113+
value := C.IedConnection_readUnsigned32Value(c.conn, &clientError, cObjectRef, C.FunctionalConstraint(fc))
114+
if err := GetIedClientError(clientError); err != nil {
115+
return 0, err
116+
}
117+
return uint32(value), nil
118+
}
119+
120+
// ReadFloat 读取float类型值
121+
func (c *Client) ReadFloat(objectRef string, fc FC) (float64, error) {
122+
cObjectRef := C.CString(objectRef)
123+
defer C.free(unsafe.Pointer(cObjectRef))
124+
125+
var clientError C.IedClientError
126+
value := C.IedConnection_readFloatValue(c.conn, &clientError, cObjectRef, C.FunctionalConstraint(fc))
127+
if err := GetIedClientError(clientError); err != nil {
128+
return 0, err
129+
}
130+
return float64(value), nil
131+
}
132+
133+
// ReadString 读取string类型值
134+
func (c *Client) ReadString(objectRef string, fc FC) (string, error) {
135+
cObjectRef := C.CString(objectRef)
136+
defer C.free(unsafe.Pointer(cObjectRef))
137+
138+
var clientError C.IedClientError
139+
value := C.IedConnection_readStringValue(c.conn, &clientError, cObjectRef, C.FunctionalConstraint(fc))
140+
if err := GetIedClientError(clientError); err != nil {
141+
return "", err
142+
}
143+
return C.GoString(value), nil
144+
}
145+
146+
// Read 读取数据
147+
func (c *Client) Read(objectRef string, fc FC) (interface{}, error) {
148+
var clientError C.IedClientError
149+
cObjectRef := C.CString(objectRef)
150+
defer C.free(unsafe.Pointer(cObjectRef))
151+
152+
mmsValue := C.IedConnection_readObject(c.conn, &clientError, cObjectRef, C.FunctionalConstraint(fc))
153+
if err := GetIedClientError(clientError); err != nil {
154+
return nil, err
155+
}
156+
157+
defer C.MmsValue_delete(mmsValue)
158+
mmsType := MmsType(C.MmsValue_getType(mmsValue))
159+
return c.toGoValue(mmsValue, mmsType), nil
160+
}
161+
162+
func (c *Client) ReadDataSet(objectRef string) ([]*MmsValue, error) {
163+
cObjectRef := C.CString(objectRef)
164+
defer C.free(unsafe.Pointer(cObjectRef))
165+
166+
var clientError C.IedClientError
167+
dataSet := C.IedConnection_readDataSetValues(c.conn, &clientError, cObjectRef, nil)
168+
if err := GetIedClientError(clientError); err != nil {
169+
return nil, err
170+
}
171+
defer C.ClientDataSet_destroy(dataSet)
172+
173+
dataSetValues := C.ClientDataSet_getValues(dataSet)
174+
// 长度
175+
dataSetSize := int(C.ClientDataSet_getDataSetSize(dataSet))
176+
mmsValues := make([]*MmsValue, dataSetSize)
177+
for i := 0; i < dataSetSize; i++ {
178+
value := C.MmsValue_getElement(dataSetValues, C.int(i))
179+
mmsType := MmsType(C.MmsValue_getType(value))
180+
mmsValue := &MmsValue{
181+
Type: mmsType,
182+
Value: c.toGoValue(value, mmsType),
183+
}
184+
mmsValues[i] = mmsValue
185+
}
186+
return mmsValues, nil
187+
}
188+
189+
// Close 关闭连接
190+
func (c *Client) Close() {
191+
if c.conn != nil && c.connected.CompareAndSwap(true, false) {
192+
C.IedConnection_destroy(c.conn)
193+
}
194+
}
195+
196+
// GetVariableSpecType 获取类型规格
197+
func (c *Client) GetVariableSpecType(objectReference string, fc FC) (MmsType, error) {
198+
var clientError C.IedClientError
199+
cObjectRef := C.CString(objectReference)
200+
defer C.free(unsafe.Pointer(cObjectRef))
201+
202+
// 获取类型
203+
spec := C.IedConnection_getVariableSpecification(c.conn, &clientError, cObjectRef, C.FunctionalConstraint(fc))
204+
if err := GetIedClientError(clientError); err != nil {
205+
return 0, err
206+
}
207+
defer C.MmsVariableSpecification_destroy(spec)
208+
mmsType := MmsType(C.MmsVariableSpecification_getType(spec))
209+
switch mmsType {
210+
case Integer:
211+
i := int(spec.typeSpec[0])
212+
switch i {
213+
case 8:
214+
return Int8, nil
215+
case 16:
216+
return Int16, nil
217+
case 32:
218+
return Int32, nil
219+
default:
220+
return Int64, nil
221+
}
222+
case Unsigned:
223+
switch int(spec.typeSpec[0]) {
224+
case 8:
225+
return Uint8, nil
226+
case 16:
227+
return Uint16, nil
228+
default:
229+
return Uint32, nil
230+
}
231+
}
232+
return mmsType, nil
233+
}
234+
235+
func (c *Client) toGoValue(mmsValue *C.MmsValue, mmsType MmsType) interface{} {
236+
var value interface{}
237+
238+
switch mmsType {
239+
case Integer:
240+
value = int64(C.MmsValue_toInt64(mmsValue))
241+
case Unsigned:
242+
value = uint32(C.MmsValue_toUint32(mmsValue))
243+
case Boolean:
244+
value = bool(C.MmsValue_getBoolean(mmsValue))
245+
case Float:
246+
value = float64(C.MmsValue_toDouble(mmsValue))
247+
case String, VisibleString:
248+
value = C.GoString(C.MmsValue_toString(mmsValue))
249+
case Structure, Array:
250+
value = c.toGoStructure(mmsValue, mmsType)
251+
case BitString:
252+
value = uint32(C.MmsValue_getBitStringAsInteger(mmsValue))
253+
case OctetString:
254+
size := uint16(C.MmsValue_getOctetStringSize(mmsValue))
255+
bytes := make([]byte, size)
256+
for i := 0; i < int(size); i++ {
257+
bytes[i] = uint8(C.getOctetStringOctet(mmsValue, C.int(i)))
258+
}
259+
value = bytes
260+
case BinaryTime:
261+
value = uint64(C.MmsValue_getBinaryTimeAsUtcMs(mmsValue))
262+
case UTCTime:
263+
value = uint32(C.MmsValue_toUnixTimestamp(mmsValue))
264+
}
265+
return value
266+
}
267+
268+
func (c *Client) toGoStructure(mmsValue *C.MmsValue, mmsType MmsType) []*MmsValue {
269+
if mmsType != Structure {
270+
return nil
271+
}
272+
mmsValues := make([]*MmsValue, 0)
273+
for i := 0; ; i++ {
274+
value := C.MmsValue_getElement(mmsValue, C.int(i))
275+
// 读不到表示节点下没有属性了
276+
if value == nil {
277+
return mmsValues
278+
}
279+
valueType := MmsType(C.MmsValue_getType(value))
280+
mmsValues = append(mmsValues, &MmsValue{
281+
Type: valueType,
282+
Value: c.toGoValue(value, valueType),
283+
})
284+
}
285+
}
286+
287+
func connect(settings *Settings) (C.IedConnection, C.IedClientError) {
288+
conn := C.IedConnection_create()
289+
C.IedConnection_setConnectTimeout(conn, C.uint(settings.ConnectTimeout))
290+
C.IedConnection_setRequestTimeout(conn, C.uint(settings.RequestTimeout))
291+
host := C.CString(settings.Host)
292+
// 释放内存
293+
defer C.free(unsafe.Pointer(host))
294+
var err C.IedClientError
295+
// 建立连接
296+
C.IedConnection_connect(conn, &err, host, C.int(settings.Port))
297+
return conn, err
298+
}

client/core.go

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)