@amigo9090/ih-libiec61850-node 1.0.26 → 1.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examples/index_iec61850_client2.js +222 -17
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { MmsClient } = require('../build/Release/addon_iec61850');
|
|
1
|
+
/*const { MmsClient } = require('../build/Release/addon_iec61850');
|
|
2
2
|
const util = require('util');
|
|
3
3
|
|
|
4
4
|
const client = new MmsClient((event, data) => {
|
|
@@ -21,27 +21,28 @@ const client = new MmsClient((event, data) => {
|
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
// Чтение датасетов
|
|
25
|
-
console.log('Reading datasets...');
|
|
26
|
-
dataSets.
|
|
27
|
-
|
|
28
|
-
client.readDataSetValues(ds.reference);
|
|
29
|
-
});
|
|
24
|
+
// Чтение датасетов
|
|
25
|
+
console.log('Reading datasets in batch...');
|
|
26
|
+
const dataSetRefs = dataSets.map(ds => ds.reference);
|
|
27
|
+
client.readDataSetValues(dataSetRefs);
|
|
30
28
|
|
|
31
|
-
// Чтение
|
|
29
|
+
// Чтение одиночного DataSet:
|
|
30
|
+
// client.readDataSetValues('WAGO61850ServerDevice/LLN0.DataSet01');
|
|
31
|
+
|
|
32
|
+
// Пакетное чтение данных
|
|
32
33
|
console.log('Reading data...');
|
|
33
34
|
const dataRefs = [
|
|
34
35
|
'WAGO61850ServerDevice/XCBR1.Pos.stVal',
|
|
35
36
|
'WAGO61850ServerDevice/GGIO1.Ind.stVal',
|
|
36
|
-
'WAGO61850ServerDevice/CALH1.GrAlm.stVal'
|
|
37
|
+
'WAGO61850ServerDevice/CALH1.GrAlm.stVal'
|
|
37
38
|
];
|
|
38
|
-
|
|
39
|
+
client.readData(dataRefs);
|
|
39
40
|
|
|
40
41
|
// Включение отчётов
|
|
41
42
|
const rcbRef = 'WAGO61850ServerDevice/LLN0.RP.ReportBlock0101';
|
|
42
43
|
const dataSetRef = 'WAGO61850ServerDevice/LLN0.DataSet01';
|
|
43
44
|
console.log(`Enabling reporting for ${rcbRef} with dataset ${dataSetRef}`);
|
|
44
|
-
client.enableReporting(rcbRef, dataSetRef);
|
|
45
|
+
client.enableReporting(rcbRef, dataSetRef);
|
|
45
46
|
})
|
|
46
47
|
.catch(err => console.error('Error browsing data model:', err.message));
|
|
47
48
|
}
|
|
@@ -54,7 +55,18 @@ const client = new MmsClient((event, data) => {
|
|
|
54
55
|
} else if (data.event === 'dataModel') {
|
|
55
56
|
console.log(`Data Model received: ${util.inspect(data.dataModel, { depth: null })}`);
|
|
56
57
|
} else if (data.event === 'dataSet') {
|
|
57
|
-
|
|
58
|
+
// Одиночный DataSet (обратная совместимость)
|
|
59
|
+
console.log(`DataSet received for ${data.datasetRef}: ${util.inspect(data.value, { depth: null })}`);
|
|
60
|
+
} else if (data.event === 'multipleDataSets') {
|
|
61
|
+
// Множественные DataSet
|
|
62
|
+
console.log(`Multiple DataSets received for ${util.inspect(data.datasetRefs, { depth: null })}:`);
|
|
63
|
+
data.values.forEach((value, index) => {
|
|
64
|
+
if (value.isValid !== false) {
|
|
65
|
+
console.log(` DataSet[${index}]: ${data.datasetRefs[index]}, Value: ${util.inspect(value, { depth: null })}`);
|
|
66
|
+
} else {
|
|
67
|
+
console.log(` DataSet[${index}]: ${data.datasetRefs[index]}, Error: ${value.errorReason}`);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
58
70
|
} else if (data.event === 'report') {
|
|
59
71
|
console.log(`Report received for ${data.rcbRef} (rptId: ${data.rptId}):`);
|
|
60
72
|
if (data.timestamp) {
|
|
@@ -65,6 +77,15 @@ const client = new MmsClient((event, data) => {
|
|
|
65
77
|
console.log(` Value[${index}]: ${util.inspect(value, { depth: null })}, Reason: ${data.reasonsForInclusion[index]}`);
|
|
66
78
|
}
|
|
67
79
|
});
|
|
80
|
+
} else if (data.event === 'batchData') {
|
|
81
|
+
console.log(`Batch Data received for ${util.inspect(data.dataRefs, { depth: null })}:`);
|
|
82
|
+
data.values.forEach((result, index) => {
|
|
83
|
+
if (result.isValid) {
|
|
84
|
+
console.log(` dataRef[${index}]: ${data.dataRefs[index]}, Value: ${util.inspect(result.value, { depth: null })}`);
|
|
85
|
+
} else {
|
|
86
|
+
console.log(` dataRef[${index}]: ${data.dataRefs[index]}, Error: ${result.errorReason}`);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
68
89
|
} else {
|
|
69
90
|
console.log(`Data received for ${data.dataRef || 'undefined'}: ${util.inspect(data.value, { depth: null })}`);
|
|
70
91
|
}
|
|
@@ -86,8 +107,18 @@ const client = new MmsClient((event, data) => {
|
|
|
86
107
|
console.log(`Reporting enabled for ${data.rcbRef}`);
|
|
87
108
|
} else if (data.event === 'reportingDisabled') {
|
|
88
109
|
console.log(`Reporting disabled for ${data.rcbRef}`);
|
|
110
|
+
} else if (data.event === 'dataSetCreated') {
|
|
111
|
+
console.log(`DataSet created: ${data.datasetRef}`);
|
|
112
|
+
} else if (data.event === 'dataSetDeleted') {
|
|
113
|
+
console.log(`DataSet deleted: ${data.datasetRef}`);
|
|
114
|
+
} else if (data.event === 'stateChanged') {
|
|
115
|
+
console.log(`Connection state changed: ${data.state}, isConnected: ${data.isConnected}`);
|
|
89
116
|
}
|
|
90
117
|
}
|
|
118
|
+
|
|
119
|
+
if (event === 'conn' && data.event === 'stateChanged') {
|
|
120
|
+
console.log(`Connection state changed: ${data.state}, isConnected: ${data.isConnected}`);
|
|
121
|
+
}
|
|
91
122
|
});
|
|
92
123
|
|
|
93
124
|
async function main() {
|
|
@@ -102,12 +133,12 @@ async function main() {
|
|
|
102
133
|
reconnectDelay: 2
|
|
103
134
|
});
|
|
104
135
|
await sleep(5000);
|
|
105
|
-
|
|
106
|
-
//console.log('And now we try do control operation!!!!!!!!!!!!!!!...');
|
|
107
|
-
//client.controlObject("WAGO61850ServerDevice/XCBR1.Pos", true);
|
|
136
|
+
|
|
137
|
+
// console.log('And now we try do control operation!!!!!!!!!!!!!!!...');
|
|
138
|
+
// client.controlObject("WAGO61850ServerDevice/XCBR1.Pos", true);
|
|
108
139
|
|
|
109
140
|
// Дополнительное ожидание для обработки операции управления
|
|
110
|
-
//await sleep(5000);
|
|
141
|
+
// await sleep(5000);
|
|
111
142
|
|
|
112
143
|
// Ожидание обработки данных и отчетов
|
|
113
144
|
console.log('Waiting for data and reports...');
|
|
@@ -116,7 +147,7 @@ async function main() {
|
|
|
116
147
|
// Отключение отчетов
|
|
117
148
|
const rcbRef = 'WAGO61850ServerDevice/LLN0.RP.ReportBlock0101';
|
|
118
149
|
console.log(`Disabling reporting for ${rcbRef}`);
|
|
119
|
-
client.disableReporting(rcbRef);
|
|
150
|
+
client.disableReporting(rcbRef);
|
|
120
151
|
|
|
121
152
|
console.log('Client status:', client.getStatus());
|
|
122
153
|
|
|
@@ -129,4 +160,178 @@ async function main() {
|
|
|
129
160
|
}
|
|
130
161
|
}
|
|
131
162
|
|
|
163
|
+
main().catch(err => console.error('Fatal error:', err.message));*/
|
|
164
|
+
|
|
165
|
+
const { MmsClient } = require('../build/Release/addon_iec61850');
|
|
166
|
+
const util = require('util');
|
|
167
|
+
|
|
168
|
+
const client = new MmsClient((event, data) => {
|
|
169
|
+
console.log(`Event: ${event}, Data: ${util.inspect(data, { depth: null })}`);
|
|
170
|
+
|
|
171
|
+
if (event === 'conn' && data.event === 'opened') {
|
|
172
|
+
console.log('Connection opened, browsing data model...');
|
|
173
|
+
// Запускаем асинхронную логику после открытия соединения
|
|
174
|
+
handleConnectionOpened();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (event === 'data' && data.type === 'data') {
|
|
178
|
+
if (data.event === 'logicalDevices') {
|
|
179
|
+
console.log(`Logical Devices received: ${util.inspect(data.logicalDevices, { depth: null })}`);
|
|
180
|
+
} else if (data.event === 'dataSetDirectory') {
|
|
181
|
+
console.log(`DataSet Directory for ${data.logicalNodeRef}: ${util.inspect(data.dataSets, { depth: null })}`);
|
|
182
|
+
} else if (data.event === 'dataModel') {
|
|
183
|
+
console.log(`Data Model received: ${util.inspect(data.dataModel, { depth: null })}`);
|
|
184
|
+
} else if (data.event === 'dataSet') {
|
|
185
|
+
console.log(`DataSet received for ${data.datasetRef}: ${util.inspect(data.value, { depth: null })}`);
|
|
186
|
+
} else if (data.event === 'multipleDataSets') {
|
|
187
|
+
console.log(`Multiple DataSets received for ${util.inspect(data.datasetRefs, { depth: null })}:`);
|
|
188
|
+
data.values.forEach((value, index) => {
|
|
189
|
+
if (value.isValid !== false) {
|
|
190
|
+
console.log(` DataSet[${index}]: ${data.datasetRefs[index]}, Value: ${util.inspect(value, { depth: null })}`);
|
|
191
|
+
} else {
|
|
192
|
+
console.log(` DataSet[${index}]: ${data.datasetRefs[index]}, Error: ${value.errorReason}`);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
} else if (data.event === 'report') {
|
|
196
|
+
console.log(`Report received for ${data.rcbRef} (rptId: ${data.rptId}):`);
|
|
197
|
+
if (data.timestamp) {
|
|
198
|
+
console.log(` Timestamp: ${data.timestamp}`);
|
|
199
|
+
}
|
|
200
|
+
data.values.forEach((value, index) => {
|
|
201
|
+
if (data.reasonsForInclusion[index] !== 0) {
|
|
202
|
+
console.log(` Value[${index}]: ${util.inspect(value, { depth: null })}, Reason: ${data.reasonsForInclusion[index]}`);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
} else if (data.event === 'batchData') {
|
|
206
|
+
console.log(`Batch Data received for ${util.inspect(data.dataRefs, { depth: null })}:`);
|
|
207
|
+
data.values.forEach((result, index) => {
|
|
208
|
+
if (result.isValid) {
|
|
209
|
+
console.log(` dataRef[${index}]: ${data.dataRefs[index]}, Value: ${util.inspect(result.value, { depth: null })}`);
|
|
210
|
+
} else {
|
|
211
|
+
console.log(` dataRef[${index}]: ${data.dataRefs[index]}, Error: ${result.errorReason}`);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
} else {
|
|
215
|
+
console.log(`Data received for ${data.dataRef || 'undefined'}: ${util.inspect(data.value, { depth: null })}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (event === 'data' && data.type === 'error') {
|
|
220
|
+
console.error(`Error received: ${data.reason}`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (event === 'conn' && data.event === 'reconnecting') {
|
|
224
|
+
console.error(`Reconnection failed: ${data.reason}`);
|
|
225
|
+
if (data.reason.includes('attempt 3')) {
|
|
226
|
+
throw new Error('Max reconnection attempts reached');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (event === 'data' && data.type === 'control') {
|
|
231
|
+
if (data.event === 'reportingEnabled') {
|
|
232
|
+
console.log(`Reporting enabled for ${data.rcbRef}`);
|
|
233
|
+
} else if (data.event === 'reportingDisabled') {
|
|
234
|
+
console.log(`Reporting disabled for ${data.rcbRef}`);
|
|
235
|
+
} else if (data.event === 'dataSetCreated') {
|
|
236
|
+
console.log(`DataSet created: ${data.datasetRef}`);
|
|
237
|
+
} else if (data.event === 'dataSetDeleted') {
|
|
238
|
+
console.log(`DataSet deleted: ${data.datasetRef}`);
|
|
239
|
+
} else if (data.event === 'stateChanged') {
|
|
240
|
+
console.log(`Connection state changed: ${data.state}, isConnected: ${data.isConnected}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (event === 'conn' && data.event === 'stateChanged') {
|
|
245
|
+
console.log(`Connection state changed: ${data.state}, isConnected: ${data.isConnected}`);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Вспомогательная функция сна
|
|
250
|
+
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
251
|
+
|
|
252
|
+
// Основная асинхронная функция обработки после открытия соединения
|
|
253
|
+
async function handleConnectionOpened() {
|
|
254
|
+
try {
|
|
255
|
+
// Просмотр модели данных
|
|
256
|
+
const dataModel = await client.browseDataModel();
|
|
257
|
+
console.log('Data Model:', util.inspect(dataModel, { depth: null }));
|
|
258
|
+
|
|
259
|
+
// Извлечение всех датасетов
|
|
260
|
+
const dataSets = [];
|
|
261
|
+
dataModel.forEach(ld => {
|
|
262
|
+
ld.logicalNodes.forEach(ln => {
|
|
263
|
+
ln.dataSets.forEach(ds => {
|
|
264
|
+
console.log(`Found dataset: ${ds.reference}`);
|
|
265
|
+
dataSets.push(ds);
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// Пакетное чтение датасетов
|
|
271
|
+
if (dataSets.length > 0) {
|
|
272
|
+
console.log('Reading datasets in batch...');
|
|
273
|
+
const dataSetRefs = dataSets.map(ds => ds.reference);
|
|
274
|
+
await client.readDataSetValues(dataSetRefs);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Пакетное чтение отдельных значений
|
|
278
|
+
console.log('Reading data...');
|
|
279
|
+
const dataRefs = [
|
|
280
|
+
'WAGO61850ServerDevice/XCBR1.Pos.stVal',
|
|
281
|
+
'WAGO61850ServerDevice/GGIO1.Ind.stVal',
|
|
282
|
+
'WAGO61850ServerDevice/CALH1.GrAlm.stVal'
|
|
283
|
+
];
|
|
284
|
+
await client.readData(dataRefs);
|
|
285
|
+
|
|
286
|
+
// Включение отчётности
|
|
287
|
+
const rcbRef = 'WAGO61850ServerDevice/LLN0.RP.ReportBlock0101';
|
|
288
|
+
const dataSetRef = 'WAGO61850ServerDevice/LLN0.DataSet01';
|
|
289
|
+
console.log(`Enabling reporting for ${rcbRef} with dataset ${dataSetRef}`);
|
|
290
|
+
await client.enableReporting(rcbRef, dataSetRef);
|
|
291
|
+
|
|
292
|
+
} catch (err) {
|
|
293
|
+
console.error('Error in handleConnectionOpened:', err.message);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Главная функция
|
|
298
|
+
async function main() {
|
|
299
|
+
try {
|
|
300
|
+
console.log('Starting client...');
|
|
301
|
+
await client.connect({
|
|
302
|
+
ip: '192.168.0.102',
|
|
303
|
+
port: 102,
|
|
304
|
+
clientID: 'mms_client1',
|
|
305
|
+
reconnectDelay: 2
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// Ждём открытия соединения (событие будет обработано в колбэке)
|
|
309
|
+
await sleep(5000);
|
|
310
|
+
|
|
311
|
+
// Опционально: управление (раскомментируй при необходимости)
|
|
312
|
+
// console.log('Performing control operation...');
|
|
313
|
+
// await client.controlObject("WAGO61850ServerDevice/XCBR1.Pos", true);
|
|
314
|
+
// await sleep(5000);
|
|
315
|
+
|
|
316
|
+
// Ожидание данных и отчётов
|
|
317
|
+
console.log('Waiting for data and reports...');
|
|
318
|
+
await sleep(30000);
|
|
319
|
+
|
|
320
|
+
// Отключение отчётов
|
|
321
|
+
const rcbRef = 'WAGO61850ServerDevice/LLN0.RP.ReportBlock0101';
|
|
322
|
+
console.log(`Disabling reporting for ${rcbRef}`);
|
|
323
|
+
await client.disableReporting(rcbRef);
|
|
324
|
+
|
|
325
|
+
console.log('Client status:', client.getStatus());
|
|
326
|
+
console.log('Closing client...');
|
|
327
|
+
await client.close();
|
|
328
|
+
console.log('Client closed.');
|
|
329
|
+
|
|
330
|
+
} catch (err) {
|
|
331
|
+
console.error('Main error:', err.message);
|
|
332
|
+
await client.close().catch(e => console.error('Close error:', e.message));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Запуск
|
|
132
337
|
main().catch(err => console.error('Fatal error:', err.message));
|