node-opcua-client-proxy 2.64.1 → 2.66.0

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