node-opcua-client-proxy 2.71.0 → 2.72.2

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.
@@ -1,463 +1,463 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readUAStructure = exports.ObjectExplorer = void 0;
4
- /**
5
- * @module node-opcua-client-proxy
6
- */
7
- const async = require("async");
8
- const node_opcua_assert_1 = require("node-opcua-assert");
9
- const node_opcua_data_model_1 = require("node-opcua-data-model");
10
- const node_opcua_service_call_1 = require("node-opcua-service-call");
11
- const node_opcua_status_code_1 = require("node-opcua-status-code");
12
- const node_opcua_utils_1 = require("node-opcua-utils");
13
- const node_opcua_variant_1 = require("node-opcua-variant");
14
- const node_opcua_debug_1 = require("node-opcua-debug");
15
- const proxy_1 = require("./proxy");
16
- const proxy_variable_1 = require("./proxy_variable");
17
- const node_opcua_constants_1 = require("node-opcua-constants");
18
- const doDebug = false;
19
- const errorLog = (0, node_opcua_debug_1.make_errorLog)("Proxy");
20
- const debugLog = (0, node_opcua_debug_1.make_debugLog)("Proxy");
21
- const resultMask = (0, node_opcua_data_model_1.makeResultMask)("ReferenceType | IsForward | BrowseName | NodeClass | TypeDefinition");
22
- /**
23
- * @method convertNodeIdToDataTypeAsync
24
- *
25
- * @param session
26
- * @param dataTypeId
27
- * @param callback
28
- * @param callback.err
29
- * @param callback.dataType
30
- *
31
- * @example
32
- *
33
- * const dataTypeId ="ns=0;i=11"; // Double
34
- * convertNodeIdToDataTypeAsync(session,dataTypeId,function(err,dataType) {
35
- * assert(!err && dataType === DataType.Double);
36
- * });
37
- *
38
- * const dataTypeId ="ns=0;i=290"; // Duration => SubTypeOf Double
39
- * convertNodeIdToDataTypeAsync(session,dataTypeId,function(err,dataType) {
40
- * assert(!err && dataType === DataType.Double);
41
- * });
42
- *
43
- * see also AddressSpace#findCorrespondingBasicDataType
44
- *
45
- * for an enumeration dataType will be DataType.Int32
46
- */
47
- function convertNodeIdToDataTypeAsync(session, dataTypeId, callback) {
48
- const nodeToRead = {
49
- attributeId: node_opcua_data_model_1.AttributeIds.BrowseName,
50
- nodeId: dataTypeId
51
- };
52
- session.read(nodeToRead, (err, dataValue) => {
53
- // istanbul ignore next
54
- if (err) {
55
- setImmediate(() => {
56
- callback(err);
57
- });
58
- return;
59
- }
60
- dataValue = dataValue;
61
- let dataType;
62
- // istanbul ignore next
63
- if (dataValue.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
64
- dataType = node_opcua_variant_1.DataType.Null;
65
- setImmediate(() => {
66
- callback(null, dataType);
67
- });
68
- return;
69
- }
70
- const dataTypeName = dataValue.value.value;
71
- if (dataTypeId.namespace === 0 && dataTypeId.value === node_opcua_constants_1.DataTypeIds.Enumeration) {
72
- dataType = node_opcua_variant_1.DataType.Int32;
73
- setImmediate(() => {
74
- callback(null, dataType);
75
- });
76
- return;
77
- }
78
- if (dataTypeId.namespace === 0 && node_opcua_variant_1.DataType[dataTypeId.value]) {
79
- dataType = node_opcua_variant_1.DataType[dataTypeId.value];
80
- setImmediate(() => {
81
- callback(null, dataType);
82
- });
83
- return;
84
- }
85
- /// example => Duration (i=290) => Double (i=11)
86
- // read subTypeOf
87
- const nodeToBrowse = {
88
- browseDirection: node_opcua_data_model_1.BrowseDirection.Inverse,
89
- includeSubtypes: false,
90
- nodeId: dataTypeId,
91
- // BrowseDescription
92
- referenceTypeId: (0, proxy_1.makeRefId)("HasSubtype"),
93
- // xx nodeClassMask: makeNodeClassMask("ObjectType"),
94
- resultMask
95
- };
96
- // tslint:disable:no-shadowed-variable
97
- session.browse(nodeToBrowse, (err, browseResult) => {
98
- // istanbul ignore next
99
- if (err) {
100
- return callback(err);
101
- }
102
- const references = browseResult.references;
103
- if (!references || references.length !== 1) {
104
- return callback(new Error("cannot find SuperType of " + dataTypeName.toString()));
105
- }
106
- const nodeId = references[0].nodeId;
107
- return convertNodeIdToDataTypeAsync(session, nodeId, callback);
108
- });
109
- });
110
- }
111
- function convertToVariant(value, arg, propName) {
112
- const dataType = arg._basicDataType || node_opcua_variant_1.DataType.Null;
113
- const arrayType = arg.valueRank === 1 ? node_opcua_variant_1.VariantArrayType.Array : arg.valueRank === -1 ? node_opcua_variant_1.VariantArrayType.Scalar : node_opcua_variant_1.VariantArrayType.Matrix;
114
- if (value === undefined) {
115
- throw new Error("expecting input argument ");
116
- }
117
- if (arrayType === node_opcua_variant_1.VariantArrayType.Array) {
118
- if (!Array.isArray(value)) {
119
- throw new Error("expecting value to be an Array or a TypedArray");
120
- }
121
- }
122
- return new node_opcua_variant_1.Variant({ arrayType, dataType, value });
123
- }
124
- function convertToVariantArray(inputArgsDef, inputArgs) {
125
- const inputArguments = inputArgsDef.map((arg) => {
126
- const propName = (0, node_opcua_utils_1.lowerFirstLetter)(arg.name || "");
127
- const value = inputArgs[propName];
128
- return convertToVariant(value, arg, propName);
129
- });
130
- return inputArguments;
131
- }
132
- const thenify = require("thenify");
133
- function makeFunction(obj, methodName) {
134
- return thenify.withCallback(function functionCaller(inputArgs, callback) {
135
- const session = this.proxyManager.session;
136
- (0, node_opcua_assert_1.assert)(typeof callback === "function");
137
- const methodDef = this.$methods[methodName];
138
- // convert input arguments into Variants
139
- const inputArgsDef = methodDef.inputArguments || [];
140
- const inputArguments = convertToVariantArray(inputArgsDef, inputArgs);
141
- const methodToCall = new node_opcua_service_call_1.CallMethodRequest({
142
- inputArguments,
143
- methodId: methodDef.nodeId,
144
- objectId: obj.nodeId
145
- });
146
- session.call(methodToCall, (err, callResult) => {
147
- // istanbul ignore next
148
- if (err) {
149
- return callback(err);
150
- }
151
- callResult = callResult;
152
- if (callResult.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
153
- return callback(new Error("Error " + callResult.statusCode.toString()));
154
- }
155
- callResult.outputArguments = callResult.outputArguments || [];
156
- if (callResult.outputArguments.length !== methodDef.outputArguments.length) {
157
- return callback(new Error("Internal error callResult.outputArguments.length " +
158
- callResult.outputArguments.length +
159
- " " +
160
- obj[methodName].outputArguments.length));
161
- }
162
- const output = {};
163
- methodDef.outputArguments.map((arg, index) => {
164
- const variant = callResult.outputArguments[index];
165
- const propName = (0, node_opcua_utils_1.lowerFirstLetter)(arg.name);
166
- output[propName] = variant.value;
167
- });
168
- callback(err, output);
169
- });
170
- });
171
- }
172
- function extractDataType(session, arg, callback) {
173
- if (arg.dataType && arg._basicDataType) {
174
- setImmediate(callback); // already converted
175
- return;
176
- }
177
- convertNodeIdToDataTypeAsync(session, arg.dataType, (err, dataType) => {
178
- if (!err) {
179
- arg._basicDataType = dataType;
180
- }
181
- callback(err || undefined);
182
- });
183
- }
184
- /**
185
- * @method add_method
186
- * @private
187
- */
188
- function add_method(proxyManager, obj, reference, outerCallback) {
189
- const session = proxyManager.session;
190
- const methodName = (0, node_opcua_utils_1.lowerFirstLetter)(reference.browseName.name);
191
- let inputArguments = [];
192
- let outputArguments = [];
193
- // tslint:disable:no-shadowed-variable
194
- async.series([
195
- (callback) => {
196
- session.getArgumentDefinition(reference.nodeId, (err, argumentDefinition) => {
197
- // istanbul ignore next
198
- if (err) {
199
- errorLog("getArgumentDefinition failed ", err);
200
- return callback(err);
201
- }
202
- // istanbul ignore next
203
- if (!argumentDefinition) {
204
- return callback(new Error("Internal Error"));
205
- }
206
- inputArguments = argumentDefinition.inputArguments || [];
207
- outputArguments = argumentDefinition.outputArguments || [];
208
- const _extractDataType = extractDataType.bind(null, session);
209
- async.series([
210
- (innerCallback) => async.eachSeries(inputArguments, _extractDataType, innerCallback),
211
- (innerCallback) => async.eachSeries(outputArguments, _extractDataType, innerCallback)
212
- ], (err) => callback(err));
213
- });
214
- },
215
- (callback) => {
216
- const methodObj = {
217
- browseName: methodName,
218
- executableFlag: false,
219
- func: makeFunction(obj, methodName),
220
- nodeId: reference.nodeId,
221
- inputArguments,
222
- outputArguments
223
- };
224
- obj.$methods[methodName] = methodObj;
225
- obj[methodName] = methodObj.func;
226
- obj[methodName].inputArguments = inputArguments;
227
- obj[methodName].outputArguments = outputArguments;
228
- doDebug && debugLog("installing method name", methodName);
229
- proxyManager._monitor_execution_flag(methodObj, () => {
230
- callback();
231
- });
232
- }
233
- ], (err) => {
234
- if (err) {
235
- errorLog("Error =>", err);
236
- }
237
- outerCallback(err);
238
- });
239
- }
240
- function add_component(proxyManager, obj, reference, callback) {
241
- const session = proxyManager.session;
242
- const name = (0, node_opcua_utils_1.lowerFirstLetter)(reference.browseName.name || "");
243
- proxyManager.getObject(reference.nodeId, (err, childObj) => {
244
- // istanbul ignore else
245
- if (!err) {
246
- childObj = new ObjectExplorer({
247
- name,
248
- nodeId: reference.nodeId,
249
- parent: obj,
250
- proxyManager
251
- });
252
- obj[name] = childObj;
253
- obj.$components.push(childObj);
254
- childObj.$resolve(callback);
255
- }
256
- else {
257
- callback(err);
258
- }
259
- });
260
- }
261
- function addFolderElement(proxyManager, obj, reference, callback) {
262
- const session = proxyManager.session;
263
- const name = (0, node_opcua_utils_1.lowerFirstLetter)(reference.browseName.name || "");
264
- const childObj = new ObjectExplorer({
265
- name,
266
- nodeId: reference.nodeId,
267
- parent: obj,
268
- proxyManager
269
- });
270
- obj[name] = childObj;
271
- obj.$organizes.push(childObj);
272
- childObj.$resolve(callback);
273
- }
274
- function add_property(proxyManager, obj, reference, callback) {
275
- const session = proxyManager.session;
276
- const name = (0, node_opcua_utils_1.lowerFirstLetter)(reference.browseName.name || "");
277
- obj[name] = new proxy_variable_1.ProxyVariable(proxyManager, reference.nodeId, reference);
278
- obj.$properties[name] = obj[name];
279
- setImmediate(callback);
280
- }
281
- function add_typeDefinition(proxyManager, obj, references, callback) {
282
- const session = proxyManager.session;
283
- references = references || [];
284
- if (references.length !== 1) {
285
- setImmediate(callback);
286
- return;
287
- }
288
- const reference = references[0];
289
- (0, node_opcua_assert_1.assert)(!obj.typeDefinition, "type definition can only be set once");
290
- obj.typeDefinition = reference.browseName.name || "";
291
- setImmediate(callback);
292
- }
293
- function addFromState(proxyManager, obj, reference, callback) {
294
- proxyManager.getObject(reference.nodeId, (err, childObj) => {
295
- if (err) {
296
- callback(err);
297
- }
298
- obj.$fromState = childObj;
299
- callback();
300
- });
301
- }
302
- function addToState(proxyManager, obj, reference, callback) {
303
- proxyManager.getObject(reference.nodeId, (err, childObj) => {
304
- if (err) {
305
- callback(err);
306
- }
307
- obj.$toState = childObj;
308
- callback();
309
- });
310
- }
311
- class ObjectExplorer {
312
- constructor(options) {
313
- this.proxyManager = options.proxyManager;
314
- this.name = options.name;
315
- this.nodeId = options.nodeId;
316
- this.parent = options.parent;
317
- }
318
- $resolve(callback) {
319
- this.proxyManager.getObject(this.nodeId, (err, childObj) => {
320
- // istanbul ignore next
321
- if (err) {
322
- return callback(err);
323
- }
324
- this.parent[this.name] = childObj;
325
- this.parent.$components.push(childObj);
326
- callback();
327
- });
328
- }
329
- }
330
- exports.ObjectExplorer = ObjectExplorer;
331
- function t(references) {
332
- if (!references)
333
- return "";
334
- return references.map((r) => r.browseName.name + " " + r.nodeId.toString());
335
- }
336
- function readUAStructure(proxyManager, obj, callback) {
337
- const session = proxyManager.session;
338
- // 0 Object
339
- // 1 Variable
340
- // 2 Method
341
- const nodeId = obj.nodeId;
342
- const nodesToBrowse = [
343
- // Components (except Methods)
344
- {
345
- // BrowseDescription
346
- browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
347
- includeSubtypes: true,
348
- nodeClassMask: (0, node_opcua_data_model_1.makeNodeClassMask)("Object | Variable"),
349
- nodeId,
350
- referenceTypeId: (0, proxy_1.makeRefId)("HasComponent"),
351
- resultMask
352
- },
353
- // Properties
354
- {
355
- // BrowseDescription
356
- browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
357
- includeSubtypes: true,
358
- // nodeClassMask: makeNodeClassMask("Variable"),
359
- nodeId,
360
- referenceTypeId: (0, proxy_1.makeRefId)("HasProperty"),
361
- resultMask
362
- },
363
- // Methods
364
- {
365
- // BrowseDescription
366
- browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
367
- includeSubtypes: true,
368
- nodeClassMask: (0, node_opcua_data_model_1.makeNodeClassMask)("Method"),
369
- nodeId,
370
- referenceTypeId: (0, proxy_1.makeRefId)("HasComponent"),
371
- resultMask
372
- },
373
- // TypeDefinition
374
- {
375
- // BrowseDescription
376
- browseDirection: node_opcua_data_model_1.BrowseDirection.Both,
377
- includeSubtypes: true,
378
- nodeId,
379
- referenceTypeId: (0, proxy_1.makeRefId)("HasTypeDefinition"),
380
- resultMask
381
- },
382
- // FromState
383
- {
384
- // BrowseDescription
385
- browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
386
- includeSubtypes: true,
387
- nodeId,
388
- referenceTypeId: (0, proxy_1.makeRefId)("FromState"),
389
- resultMask
390
- },
391
- // ToState
392
- {
393
- // BrowseDescription
394
- browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
395
- includeSubtypes: true,
396
- nodeId,
397
- referenceTypeId: (0, proxy_1.makeRefId)("ToState"),
398
- resultMask
399
- },
400
- // (for folders ) Organizes
401
- {
402
- // BrowseDescription
403
- browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
404
- includeSubtypes: true,
405
- nodeId,
406
- referenceTypeId: (0, proxy_1.makeRefId)("Organizes"),
407
- resultMask
408
- }
409
- ];
410
- session.browse(nodesToBrowse, (err, browseResults) => {
411
- browseResults = browseResults || [];
412
- // istanbul ignore next
413
- if (err) {
414
- return callback(err);
415
- }
416
- if (doDebug) {
417
- debugLog("Components", t(browseResults[0].references));
418
- debugLog("Properties", t(browseResults[1].references));
419
- debugLog("Methods", t(browseResults[2].references));
420
- }
421
- async.series([
422
- (callback) => {
423
- async.mapSeries(browseResults[0].references, (reference, innerCallback) => add_component(proxyManager, obj, reference, innerCallback), (err) => callback(err));
424
- },
425
- (callback) => {
426
- async.mapSeries(browseResults[1].references, (reference, innerCallback) => add_property(proxyManager, obj, reference, innerCallback), (err) => callback(err));
427
- },
428
- // now enrich our object with nice callable async methods
429
- (callback) => {
430
- async.mapSeries(browseResults[2].references, (reference, innerCallback) => add_method(proxyManager, obj, reference, innerCallback), (err) => callback(err));
431
- },
432
- // now set typeDefinition
433
- (callback) => {
434
- add_typeDefinition(proxyManager, obj, browseResults[3].references, callback);
435
- },
436
- // FromState
437
- (callback) => {
438
- // fromState
439
- const reference = browseResults[4].references ? browseResults[4].references[0] : null;
440
- // fromState
441
- if (reference) {
442
- return addFromState(proxyManager, obj, reference, callback);
443
- }
444
- callback();
445
- },
446
- // ToState
447
- (callback) => {
448
- const reference = browseResults[5].references ? browseResults[5].references[0] : null;
449
- // fromState
450
- if (reference) {
451
- return addToState(proxyManager, obj, reference, callback);
452
- }
453
- callback();
454
- },
455
- // Organizes
456
- (callback) => {
457
- async.mapSeries(browseResults[6].references, (reference, callback) => addFolderElement(proxyManager, obj, reference, callback), (err) => callback(err));
458
- }
459
- ], (err) => callback(err));
460
- });
461
- }
462
- exports.readUAStructure = readUAStructure;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readUAStructure = exports.ObjectExplorer = void 0;
4
+ /**
5
+ * @module node-opcua-client-proxy
6
+ */
7
+ const async = require("async");
8
+ const node_opcua_assert_1 = require("node-opcua-assert");
9
+ const node_opcua_data_model_1 = require("node-opcua-data-model");
10
+ const node_opcua_service_call_1 = require("node-opcua-service-call");
11
+ const node_opcua_status_code_1 = require("node-opcua-status-code");
12
+ const node_opcua_utils_1 = require("node-opcua-utils");
13
+ const node_opcua_variant_1 = require("node-opcua-variant");
14
+ const node_opcua_debug_1 = require("node-opcua-debug");
15
+ const proxy_1 = require("./proxy");
16
+ const proxy_variable_1 = require("./proxy_variable");
17
+ const node_opcua_constants_1 = require("node-opcua-constants");
18
+ const doDebug = false;
19
+ const errorLog = (0, node_opcua_debug_1.make_errorLog)("Proxy");
20
+ const debugLog = (0, node_opcua_debug_1.make_debugLog)("Proxy");
21
+ const resultMask = (0, node_opcua_data_model_1.makeResultMask)("ReferenceType | IsForward | BrowseName | NodeClass | TypeDefinition");
22
+ /**
23
+ * @method convertNodeIdToDataTypeAsync
24
+ *
25
+ * @param session
26
+ * @param dataTypeId
27
+ * @param callback
28
+ * @param callback.err
29
+ * @param callback.dataType
30
+ *
31
+ * @example
32
+ *
33
+ * const dataTypeId ="ns=0;i=11"; // Double
34
+ * convertNodeIdToDataTypeAsync(session,dataTypeId,function(err,dataType) {
35
+ * assert(!err && dataType === DataType.Double);
36
+ * });
37
+ *
38
+ * const dataTypeId ="ns=0;i=290"; // Duration => SubTypeOf Double
39
+ * convertNodeIdToDataTypeAsync(session,dataTypeId,function(err,dataType) {
40
+ * assert(!err && dataType === DataType.Double);
41
+ * });
42
+ *
43
+ * see also AddressSpace#findCorrespondingBasicDataType
44
+ *
45
+ * for an enumeration dataType will be DataType.Int32
46
+ */
47
+ function convertNodeIdToDataTypeAsync(session, dataTypeId, callback) {
48
+ const nodeToRead = {
49
+ attributeId: node_opcua_data_model_1.AttributeIds.BrowseName,
50
+ nodeId: dataTypeId
51
+ };
52
+ session.read(nodeToRead, (err, dataValue) => {
53
+ // istanbul ignore next
54
+ if (err) {
55
+ setImmediate(() => {
56
+ callback(err);
57
+ });
58
+ return;
59
+ }
60
+ dataValue = dataValue;
61
+ let dataType;
62
+ // istanbul ignore next
63
+ if (dataValue.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
64
+ dataType = node_opcua_variant_1.DataType.Null;
65
+ setImmediate(() => {
66
+ callback(null, dataType);
67
+ });
68
+ return;
69
+ }
70
+ const dataTypeName = dataValue.value.value;
71
+ if (dataTypeId.namespace === 0 && dataTypeId.value === node_opcua_constants_1.DataTypeIds.Enumeration) {
72
+ dataType = node_opcua_variant_1.DataType.Int32;
73
+ setImmediate(() => {
74
+ callback(null, dataType);
75
+ });
76
+ return;
77
+ }
78
+ if (dataTypeId.namespace === 0 && node_opcua_variant_1.DataType[dataTypeId.value]) {
79
+ dataType = node_opcua_variant_1.DataType[dataTypeId.value];
80
+ setImmediate(() => {
81
+ callback(null, dataType);
82
+ });
83
+ return;
84
+ }
85
+ /// example => Duration (i=290) => Double (i=11)
86
+ // read subTypeOf
87
+ const nodeToBrowse = {
88
+ browseDirection: node_opcua_data_model_1.BrowseDirection.Inverse,
89
+ includeSubtypes: false,
90
+ nodeId: dataTypeId,
91
+ // BrowseDescription
92
+ referenceTypeId: (0, proxy_1.makeRefId)("HasSubtype"),
93
+ // xx nodeClassMask: makeNodeClassMask("ObjectType"),
94
+ resultMask
95
+ };
96
+ // tslint:disable:no-shadowed-variable
97
+ session.browse(nodeToBrowse, (err, browseResult) => {
98
+ // istanbul ignore next
99
+ if (err) {
100
+ return callback(err);
101
+ }
102
+ const references = browseResult.references;
103
+ if (!references || references.length !== 1) {
104
+ return callback(new Error("cannot find SuperType of " + dataTypeName.toString()));
105
+ }
106
+ const nodeId = references[0].nodeId;
107
+ return convertNodeIdToDataTypeAsync(session, nodeId, callback);
108
+ });
109
+ });
110
+ }
111
+ function convertToVariant(value, arg, propName) {
112
+ const dataType = arg._basicDataType || node_opcua_variant_1.DataType.Null;
113
+ const arrayType = arg.valueRank === 1 ? node_opcua_variant_1.VariantArrayType.Array : arg.valueRank === -1 ? node_opcua_variant_1.VariantArrayType.Scalar : node_opcua_variant_1.VariantArrayType.Matrix;
114
+ if (value === undefined) {
115
+ throw new Error("expecting input argument ");
116
+ }
117
+ if (arrayType === node_opcua_variant_1.VariantArrayType.Array) {
118
+ if (!Array.isArray(value)) {
119
+ throw new Error("expecting value to be an Array or a TypedArray");
120
+ }
121
+ }
122
+ return new node_opcua_variant_1.Variant({ arrayType, dataType, value });
123
+ }
124
+ function convertToVariantArray(inputArgsDef, inputArgs) {
125
+ const inputArguments = inputArgsDef.map((arg) => {
126
+ const propName = (0, node_opcua_utils_1.lowerFirstLetter)(arg.name || "");
127
+ const value = inputArgs[propName];
128
+ return convertToVariant(value, arg, propName);
129
+ });
130
+ return inputArguments;
131
+ }
132
+ const thenify = require("thenify");
133
+ function makeFunction(obj, methodName) {
134
+ return thenify.withCallback(function functionCaller(inputArgs, callback) {
135
+ const session = this.proxyManager.session;
136
+ (0, node_opcua_assert_1.assert)(typeof callback === "function");
137
+ const methodDef = this.$methods[methodName];
138
+ // convert input arguments into Variants
139
+ const inputArgsDef = methodDef.inputArguments || [];
140
+ const inputArguments = convertToVariantArray(inputArgsDef, inputArgs);
141
+ const methodToCall = new node_opcua_service_call_1.CallMethodRequest({
142
+ inputArguments,
143
+ methodId: methodDef.nodeId,
144
+ objectId: obj.nodeId
145
+ });
146
+ session.call(methodToCall, (err, callResult) => {
147
+ // istanbul ignore next
148
+ if (err) {
149
+ return callback(err);
150
+ }
151
+ callResult = callResult;
152
+ if (callResult.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
153
+ return callback(new Error("Error " + callResult.statusCode.toString()));
154
+ }
155
+ callResult.outputArguments = callResult.outputArguments || [];
156
+ if (callResult.outputArguments.length !== methodDef.outputArguments.length) {
157
+ return callback(new Error("Internal error callResult.outputArguments.length " +
158
+ callResult.outputArguments.length +
159
+ " " +
160
+ obj[methodName].outputArguments.length));
161
+ }
162
+ const output = {};
163
+ methodDef.outputArguments.map((arg, index) => {
164
+ const variant = callResult.outputArguments[index];
165
+ const propName = (0, node_opcua_utils_1.lowerFirstLetter)(arg.name);
166
+ output[propName] = variant.value;
167
+ });
168
+ callback(err, output);
169
+ });
170
+ });
171
+ }
172
+ function extractDataType(session, arg, callback) {
173
+ if (arg.dataType && arg._basicDataType) {
174
+ setImmediate(callback); // already converted
175
+ return;
176
+ }
177
+ convertNodeIdToDataTypeAsync(session, arg.dataType, (err, dataType) => {
178
+ if (!err) {
179
+ arg._basicDataType = dataType;
180
+ }
181
+ callback(err || undefined);
182
+ });
183
+ }
184
+ /**
185
+ * @method add_method
186
+ * @private
187
+ */
188
+ function add_method(proxyManager, obj, reference, outerCallback) {
189
+ const session = proxyManager.session;
190
+ const methodName = (0, node_opcua_utils_1.lowerFirstLetter)(reference.browseName.name);
191
+ let inputArguments = [];
192
+ let outputArguments = [];
193
+ // tslint:disable:no-shadowed-variable
194
+ async.series([
195
+ (callback) => {
196
+ session.getArgumentDefinition(reference.nodeId, (err, argumentDefinition) => {
197
+ // istanbul ignore next
198
+ if (err) {
199
+ errorLog("getArgumentDefinition failed ", err);
200
+ return callback(err);
201
+ }
202
+ // istanbul ignore next
203
+ if (!argumentDefinition) {
204
+ return callback(new Error("Internal Error"));
205
+ }
206
+ inputArguments = argumentDefinition.inputArguments || [];
207
+ outputArguments = argumentDefinition.outputArguments || [];
208
+ const _extractDataType = extractDataType.bind(null, session);
209
+ async.series([
210
+ (innerCallback) => async.eachSeries(inputArguments, _extractDataType, innerCallback),
211
+ (innerCallback) => async.eachSeries(outputArguments, _extractDataType, innerCallback)
212
+ ], (err) => callback(err));
213
+ });
214
+ },
215
+ (callback) => {
216
+ const methodObj = {
217
+ browseName: methodName,
218
+ executableFlag: false,
219
+ func: makeFunction(obj, methodName),
220
+ nodeId: reference.nodeId,
221
+ inputArguments,
222
+ outputArguments
223
+ };
224
+ obj.$methods[methodName] = methodObj;
225
+ obj[methodName] = methodObj.func;
226
+ obj[methodName].inputArguments = inputArguments;
227
+ obj[methodName].outputArguments = outputArguments;
228
+ doDebug && debugLog("installing method name", methodName);
229
+ proxyManager._monitor_execution_flag(methodObj, () => {
230
+ callback();
231
+ });
232
+ }
233
+ ], (err) => {
234
+ if (err) {
235
+ errorLog("Error =>", err);
236
+ }
237
+ outerCallback(err);
238
+ });
239
+ }
240
+ function add_component(proxyManager, obj, reference, callback) {
241
+ const session = proxyManager.session;
242
+ const name = (0, node_opcua_utils_1.lowerFirstLetter)(reference.browseName.name || "");
243
+ proxyManager.getObject(reference.nodeId, (err, childObj) => {
244
+ // istanbul ignore else
245
+ if (!err) {
246
+ childObj = new ObjectExplorer({
247
+ name,
248
+ nodeId: reference.nodeId,
249
+ parent: obj,
250
+ proxyManager
251
+ });
252
+ obj[name] = childObj;
253
+ obj.$components.push(childObj);
254
+ childObj.$resolve(callback);
255
+ }
256
+ else {
257
+ callback(err);
258
+ }
259
+ });
260
+ }
261
+ function addFolderElement(proxyManager, obj, reference, callback) {
262
+ const session = proxyManager.session;
263
+ const name = (0, node_opcua_utils_1.lowerFirstLetter)(reference.browseName.name || "");
264
+ const childObj = new ObjectExplorer({
265
+ name,
266
+ nodeId: reference.nodeId,
267
+ parent: obj,
268
+ proxyManager
269
+ });
270
+ obj[name] = childObj;
271
+ obj.$organizes.push(childObj);
272
+ childObj.$resolve(callback);
273
+ }
274
+ function add_property(proxyManager, obj, reference, callback) {
275
+ const session = proxyManager.session;
276
+ const name = (0, node_opcua_utils_1.lowerFirstLetter)(reference.browseName.name || "");
277
+ obj[name] = new proxy_variable_1.ProxyVariable(proxyManager, reference.nodeId, reference);
278
+ obj.$properties[name] = obj[name];
279
+ setImmediate(callback);
280
+ }
281
+ function add_typeDefinition(proxyManager, obj, references, callback) {
282
+ const session = proxyManager.session;
283
+ references = references || [];
284
+ if (references.length !== 1) {
285
+ setImmediate(callback);
286
+ return;
287
+ }
288
+ const reference = references[0];
289
+ (0, node_opcua_assert_1.assert)(!obj.typeDefinition, "type definition can only be set once");
290
+ obj.typeDefinition = reference.browseName.name || "";
291
+ setImmediate(callback);
292
+ }
293
+ function addFromState(proxyManager, obj, reference, callback) {
294
+ proxyManager.getObject(reference.nodeId, (err, childObj) => {
295
+ if (err) {
296
+ callback(err);
297
+ }
298
+ obj.$fromState = childObj;
299
+ callback();
300
+ });
301
+ }
302
+ function addToState(proxyManager, obj, reference, callback) {
303
+ proxyManager.getObject(reference.nodeId, (err, childObj) => {
304
+ if (err) {
305
+ callback(err);
306
+ }
307
+ obj.$toState = childObj;
308
+ callback();
309
+ });
310
+ }
311
+ class ObjectExplorer {
312
+ constructor(options) {
313
+ this.proxyManager = options.proxyManager;
314
+ this.name = options.name;
315
+ this.nodeId = options.nodeId;
316
+ this.parent = options.parent;
317
+ }
318
+ $resolve(callback) {
319
+ this.proxyManager.getObject(this.nodeId, (err, childObj) => {
320
+ // istanbul ignore next
321
+ if (err) {
322
+ return callback(err);
323
+ }
324
+ this.parent[this.name] = childObj;
325
+ this.parent.$components.push(childObj);
326
+ callback();
327
+ });
328
+ }
329
+ }
330
+ exports.ObjectExplorer = ObjectExplorer;
331
+ function t(references) {
332
+ if (!references)
333
+ return "";
334
+ return references.map((r) => r.browseName.name + " " + r.nodeId.toString());
335
+ }
336
+ function readUAStructure(proxyManager, obj, callback) {
337
+ const session = proxyManager.session;
338
+ // 0 Object
339
+ // 1 Variable
340
+ // 2 Method
341
+ const nodeId = obj.nodeId;
342
+ const nodesToBrowse = [
343
+ // Components (except Methods)
344
+ {
345
+ // BrowseDescription
346
+ browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
347
+ includeSubtypes: true,
348
+ nodeClassMask: (0, node_opcua_data_model_1.makeNodeClassMask)("Object | Variable"),
349
+ nodeId,
350
+ referenceTypeId: (0, proxy_1.makeRefId)("HasComponent"),
351
+ resultMask
352
+ },
353
+ // Properties
354
+ {
355
+ // BrowseDescription
356
+ browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
357
+ includeSubtypes: true,
358
+ // nodeClassMask: makeNodeClassMask("Variable"),
359
+ nodeId,
360
+ referenceTypeId: (0, proxy_1.makeRefId)("HasProperty"),
361
+ resultMask
362
+ },
363
+ // Methods
364
+ {
365
+ // BrowseDescription
366
+ browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
367
+ includeSubtypes: true,
368
+ nodeClassMask: (0, node_opcua_data_model_1.makeNodeClassMask)("Method"),
369
+ nodeId,
370
+ referenceTypeId: (0, proxy_1.makeRefId)("HasComponent"),
371
+ resultMask
372
+ },
373
+ // TypeDefinition
374
+ {
375
+ // BrowseDescription
376
+ browseDirection: node_opcua_data_model_1.BrowseDirection.Both,
377
+ includeSubtypes: true,
378
+ nodeId,
379
+ referenceTypeId: (0, proxy_1.makeRefId)("HasTypeDefinition"),
380
+ resultMask
381
+ },
382
+ // FromState
383
+ {
384
+ // BrowseDescription
385
+ browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
386
+ includeSubtypes: true,
387
+ nodeId,
388
+ referenceTypeId: (0, proxy_1.makeRefId)("FromState"),
389
+ resultMask
390
+ },
391
+ // ToState
392
+ {
393
+ // BrowseDescription
394
+ browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
395
+ includeSubtypes: true,
396
+ nodeId,
397
+ referenceTypeId: (0, proxy_1.makeRefId)("ToState"),
398
+ resultMask
399
+ },
400
+ // (for folders ) Organizes
401
+ {
402
+ // BrowseDescription
403
+ browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
404
+ includeSubtypes: true,
405
+ nodeId,
406
+ referenceTypeId: (0, proxy_1.makeRefId)("Organizes"),
407
+ resultMask
408
+ }
409
+ ];
410
+ session.browse(nodesToBrowse, (err, browseResults) => {
411
+ browseResults = browseResults || [];
412
+ // istanbul ignore next
413
+ if (err) {
414
+ return callback(err);
415
+ }
416
+ if (doDebug) {
417
+ debugLog("Components", t(browseResults[0].references));
418
+ debugLog("Properties", t(browseResults[1].references));
419
+ debugLog("Methods", t(browseResults[2].references));
420
+ }
421
+ async.series([
422
+ (callback) => {
423
+ async.mapSeries(browseResults[0].references, (reference, innerCallback) => add_component(proxyManager, obj, reference, innerCallback), (err) => callback(err));
424
+ },
425
+ (callback) => {
426
+ async.mapSeries(browseResults[1].references, (reference, innerCallback) => add_property(proxyManager, obj, reference, innerCallback), (err) => callback(err));
427
+ },
428
+ // now enrich our object with nice callable async methods
429
+ (callback) => {
430
+ async.mapSeries(browseResults[2].references, (reference, innerCallback) => add_method(proxyManager, obj, reference, innerCallback), (err) => callback(err));
431
+ },
432
+ // now set typeDefinition
433
+ (callback) => {
434
+ add_typeDefinition(proxyManager, obj, browseResults[3].references, callback);
435
+ },
436
+ // FromState
437
+ (callback) => {
438
+ // fromState
439
+ const reference = browseResults[4].references ? browseResults[4].references[0] : null;
440
+ // fromState
441
+ if (reference) {
442
+ return addFromState(proxyManager, obj, reference, callback);
443
+ }
444
+ callback();
445
+ },
446
+ // ToState
447
+ (callback) => {
448
+ const reference = browseResults[5].references ? browseResults[5].references[0] : null;
449
+ // fromState
450
+ if (reference) {
451
+ return addToState(proxyManager, obj, reference, callback);
452
+ }
453
+ callback();
454
+ },
455
+ // Organizes
456
+ (callback) => {
457
+ async.mapSeries(browseResults[6].references, (reference, callback) => addFolderElement(proxyManager, obj, reference, callback), (err) => callback(err));
458
+ }
459
+ ], (err) => callback(err));
460
+ });
461
+ }
462
+ exports.readUAStructure = readUAStructure;
463
463
  //# sourceMappingURL=object_explorer.js.map