node-opcua-address-space 2.59.0 → 2.62.1
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/dist/source/address_space_ts.d.ts +0 -2
- package/dist/source/helpers/argument_list.js +12 -1
- package/dist/source/helpers/argument_list.js.map +1 -1
- package/dist/source/helpers/multiform_func.d.ts +11 -0
- package/dist/source/helpers/multiform_func.js +74 -0
- package/dist/source/helpers/multiform_func.js.map +1 -0
- package/dist/source/loader/load_nodeset2.js +47 -64
- package/dist/source/loader/load_nodeset2.js.map +1 -1
- package/dist/source/set_namespace_meta_data.js +1 -1
- package/dist/src/address_space.js +12 -6
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/alarms_and_conditions/condition_snapshot.js +3 -3
- package/dist/src/alarms_and_conditions/condition_snapshot.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js +1 -1
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_condition_impl.js +8 -6
- package/dist/src/alarms_and_conditions/ua_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js +1 -1
- package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js.map +1 -1
- package/dist/src/base_node_impl.js +2 -0
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/base_node_private.d.ts +3 -3
- package/dist/src/base_node_private.js +198 -25
- package/dist/src/base_node_private.js.map +1 -1
- package/dist/src/event_data.js +1 -1
- package/dist/src/event_data.js.map +1 -1
- package/dist/src/namespace_impl.js +5 -5
- package/dist/src/namespace_impl.js.map +1 -1
- package/dist/src/nodeset_tools/nodeset_to_xml.js +15 -9
- package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
- package/dist/src/nodeset_tools/typedictionary_to_xml.js +17 -10
- package/dist/src/nodeset_tools/typedictionary_to_xml.js.map +1 -1
- package/dist/src/state_machine/ua_shelving_state_machine_ex.js +20 -13
- package/dist/src/state_machine/ua_shelving_state_machine_ex.js.map +1 -1
- package/dist/src/ua_data_type_impl.d.ts +15 -5
- package/dist/src/ua_data_type_impl.js +129 -51
- package/dist/src/ua_data_type_impl.js.map +1 -1
- package/dist/src/ua_method_impl.js +2 -1
- package/dist/src/ua_method_impl.js.map +1 -1
- package/dist/src/ua_object_impl.js +2 -1
- package/dist/src/ua_object_impl.js.map +1 -1
- package/dist/src/ua_object_type_impl.js +1 -0
- package/dist/src/ua_object_type_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.d.ts +12 -18
- package/dist/src/ua_variable_impl.js +287 -215
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/src/ua_variable_type_impl.d.ts +3 -4
- package/dist/src/ua_variable_type_impl.js +61 -52
- package/dist/src/ua_variable_type_impl.js.map +1 -1
- package/dist/src/ua_view_impl.js +1 -1
- package/dist/src/ua_view_impl.js.map +1 -1
- package/distHelpers/mock_session.js +1 -1
- package/distHelpers/mock_session.js.map +1 -1
- package/package.json +35 -35
- package/source/address_space_ts.ts +0 -1
- package/source/helpers/argument_list.ts +13 -3
- package/source/helpers/multiform_func.ts +76 -0
- package/source/loader/load_nodeset2.ts +64 -80
- package/source/set_namespace_meta_data.ts +1 -1
- package/src/address_space.ts +16 -7
- package/src/alarms_and_conditions/condition_snapshot.ts +4 -4
- package/src/alarms_and_conditions/ua_alarm_condition_impl.ts +2 -2
- package/src/alarms_and_conditions/ua_condition_impl.ts +18 -8
- package/src/alarms_and_conditions/ua_off_normal_alarm_impl.ts +1 -1
- package/src/base_node_impl.ts +3 -1
- package/src/base_node_private.ts +282 -36
- package/src/event_data.ts +1 -1
- package/src/namespace_impl.ts +6 -6
- package/src/nodeset_tools/nodeset_to_xml.ts +20 -10
- package/src/nodeset_tools/typedictionary_to_xml.ts +17 -7
- package/src/state_machine/ua_shelving_state_machine_ex.ts +28 -16
- package/src/ua_data_type_impl.ts +168 -61
- package/src/ua_method_impl.ts +10 -2
- package/src/ua_object_impl.ts +10 -2
- package/src/ua_object_type_impl.ts +1 -0
- package/src/ua_variable_impl.ts +421 -325
- package/src/ua_variable_type_impl.ts +87 -52
- package/src/ua_view_impl.ts +1 -1
- package/test_helpers/mock_session.ts +1 -1
- package/test_helpers/test_fixtures/fixture_simple_statemachine_nodeset2.xml +18 -0
- package/test_helpers/test_fixtures/fixuture_nodeset_objects_with_some_methods.xml +9 -1
- package/test_helpers/test_fixtures/mini.Node.Set2.xml +22 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UAVariableImplT = exports.UAVariableImpl = exports.
|
|
3
|
+
exports.UAVariableImplT = exports.UAVariableImpl = exports.adjust_userAccessLevel = exports.adjust_accessLevel = void 0;
|
|
4
4
|
/* eslint-disable max-statements */
|
|
5
5
|
/* eslint-disable complexity */
|
|
6
6
|
/**
|
|
@@ -10,6 +10,7 @@ exports.UAVariableImplT = exports.UAVariableImpl = exports.verifyRankAndDimensio
|
|
|
10
10
|
// tslint:disable:no-console
|
|
11
11
|
// tslint:disable:max-line-length
|
|
12
12
|
const chalk = require("chalk");
|
|
13
|
+
const node_opcua_address_space_base_1 = require("node-opcua-address-space-base");
|
|
13
14
|
const node_opcua_assert_1 = require("node-opcua-assert");
|
|
14
15
|
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
15
16
|
const node_opcua_data_value_1 = require("node-opcua-data-value");
|
|
@@ -24,6 +25,7 @@ const utils = require("node-opcua-utils");
|
|
|
24
25
|
const node_opcua_utils_1 = require("node-opcua-utils");
|
|
25
26
|
const node_opcua_variant_1 = require("node-opcua-variant");
|
|
26
27
|
const session_context_1 = require("../source/session_context");
|
|
28
|
+
const multiform_func_1 = require("../source/helpers/multiform_func");
|
|
27
29
|
const base_node_impl_1 = require("./base_node_impl");
|
|
28
30
|
const base_node_private_1 = require("./base_node_private");
|
|
29
31
|
const ua_data_type_impl_1 = require("./ua_data_type_impl");
|
|
@@ -104,13 +106,13 @@ function validateDataType(addressSpace, dataTypeNodeId, variantDataType, nodeId,
|
|
|
104
106
|
}
|
|
105
107
|
let builtInType;
|
|
106
108
|
let builtInUADataType;
|
|
107
|
-
const destUADataType = addressSpace.
|
|
109
|
+
const destUADataType = addressSpace.findDataType(dataTypeNodeId);
|
|
108
110
|
(0, node_opcua_assert_1.assert)(destUADataType instanceof ua_data_type_impl_1.UADataTypeImpl);
|
|
109
111
|
if (destUADataType.isAbstract || destUADataType.nodeId.namespace !== 0) {
|
|
110
112
|
builtInUADataType = destUADataType;
|
|
111
113
|
}
|
|
112
114
|
else {
|
|
113
|
-
builtInType =
|
|
115
|
+
builtInType = addressSpace.findCorrespondingBasicDataType(destUADataType);
|
|
114
116
|
builtInUADataType = addressSpace.findDataType(builtInType);
|
|
115
117
|
}
|
|
116
118
|
(0, node_opcua_assert_1.assert)(builtInUADataType instanceof ua_data_type_impl_1.UADataTypeImpl);
|
|
@@ -121,8 +123,8 @@ function validateDataType(addressSpace, dataTypeNodeId, variantDataType, nodeId,
|
|
|
121
123
|
if (destUADataType.isSupertypeOf(enumerationUADataType)) {
|
|
122
124
|
// istanbul ignore next
|
|
123
125
|
if (doDebug) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
+
debugLog("destUADataType.", destUADataType.browseName.toString(), destUADataType.nodeId.toString());
|
|
127
|
+
debugLog("enumerationUADataType.", enumerationUADataType.browseName.toString(), enumerationUADataType.nodeId.toString());
|
|
126
128
|
}
|
|
127
129
|
return true;
|
|
128
130
|
}
|
|
@@ -134,45 +136,21 @@ function validateDataType(addressSpace, dataTypeNodeId, variantDataType, nodeId,
|
|
|
134
136
|
if (doDebug) {
|
|
135
137
|
if (dest_isSuperTypeOf_variant) {
|
|
136
138
|
/* istanbul ignore next*/
|
|
137
|
-
|
|
139
|
+
debugLog(chalk.green(" ---------- Type match !!! "), " on ", nodeId.toString());
|
|
138
140
|
}
|
|
139
141
|
else {
|
|
140
142
|
/* istanbul ignore next*/
|
|
141
|
-
|
|
143
|
+
debugLog(chalk.red(" ---------- Type mismatch "), " on ", nodeId.toString());
|
|
142
144
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
145
|
+
debugLog(chalk.cyan(" Variable data Type is = "), destUADataType.browseName.toString());
|
|
146
|
+
debugLog(chalk.cyan(" which matches basic Type = "), builtInUADataType.browseName.toString());
|
|
147
|
+
debugLog(chalk.yellow(" Actual dataType = "), variantUADataType.browseName.toString());
|
|
146
148
|
}
|
|
147
149
|
return dest_isSuperTypeOf_variant;
|
|
148
150
|
}
|
|
149
|
-
function
|
|
150
|
-
|
|
151
|
-
if (options.arrayDimensions && options.valueRank === undefined) {
|
|
152
|
-
options.valueRank = options.arrayDimensions.length;
|
|
153
|
-
}
|
|
154
|
-
options.valueRank = options.valueRank === undefined ? -1 : options.valueRank || 0; // UInt32
|
|
155
|
-
(0, node_opcua_assert_1.assert)(typeof options.valueRank === "number");
|
|
156
|
-
options.arrayDimensions = options.arrayDimensions || null;
|
|
157
|
-
(0, node_opcua_assert_1.assert)(options.arrayDimensions === null || Array.isArray(options.arrayDimensions));
|
|
158
|
-
if (options.arrayDimensions && options.valueRank <= 0) {
|
|
159
|
-
throw new Error("[CONFORMANCE] arrayDimensions must be null if valueRank <=0");
|
|
160
|
-
}
|
|
161
|
-
// specify default arrayDimension if not provided
|
|
162
|
-
if (options.valueRank > 0 && !options.arrayDimensions) {
|
|
163
|
-
options.arrayDimensions = new Array(options.valueRank).fill(0);
|
|
164
|
-
}
|
|
165
|
-
if (!options.arrayDimensions && options.valueRank > 0) {
|
|
166
|
-
throw new Error("[CONFORMANCE] arrayDimension must be specified if valueRank >0 " + options.valueRank);
|
|
167
|
-
}
|
|
168
|
-
if (options.valueRank > 0 && options.arrayDimensions.length !== options.valueRank) {
|
|
169
|
-
throw new Error("[CONFORMANCE] when valueRank> 0, arrayDimensions must have valueRank elements, this.valueRank =" +
|
|
170
|
-
options.valueRank +
|
|
171
|
-
" whereas arrayDimensions.length =" +
|
|
172
|
-
options.arrayDimensions.length);
|
|
173
|
-
}
|
|
151
|
+
function default_func(dataValue1, callback1) {
|
|
152
|
+
return _default_writable_timestamped_set_func.call(this, dataValue1, callback1);
|
|
174
153
|
}
|
|
175
|
-
exports.verifyRankAndDimensions = verifyRankAndDimensions;
|
|
176
154
|
/**
|
|
177
155
|
* A OPCUA Variable Node
|
|
178
156
|
*
|
|
@@ -203,16 +181,15 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
203
181
|
constructor(options) {
|
|
204
182
|
super(options);
|
|
205
183
|
this.nodeClass = node_opcua_data_model_1.NodeClass.Variable;
|
|
206
|
-
verifyRankAndDimensions(options);
|
|
184
|
+
(0, node_opcua_variant_1.verifyRankAndDimensions)(options);
|
|
207
185
|
this.valueRank = options.valueRank;
|
|
208
186
|
this.arrayDimensions = options.arrayDimensions;
|
|
209
187
|
this.dataType = this.resolveNodeId(options.dataType); // DataType (NodeId)
|
|
210
188
|
this.accessLevel = adjust_accessLevel(options.accessLevel);
|
|
211
189
|
this.userAccessLevel = adjust_userAccessLevel(options.userAccessLevel, this.accessLevel);
|
|
212
190
|
this.minimumSamplingInterval = adjust_samplingInterval(options.minimumSamplingInterval || 0);
|
|
213
|
-
this.historizing = !!options.historizing; // coerced to boolean
|
|
214
|
-
this
|
|
215
|
-
// xx options.value = options.value || { dataType: DataType.Null };
|
|
191
|
+
this.historizing = !!options.historizing; // coerced to boolean"
|
|
192
|
+
this.$dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.UncertainInitialValue, value: { dataType: node_opcua_variant_1.DataType.Null } });
|
|
216
193
|
if (options.value) {
|
|
217
194
|
this.bindVariable(options.value);
|
|
218
195
|
}
|
|
@@ -301,10 +278,17 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
301
278
|
}
|
|
302
279
|
if (this._timestamped_get_func) {
|
|
303
280
|
if (this._timestamped_get_func.length === 0) {
|
|
304
|
-
|
|
281
|
+
const dataValueOrPromise = this._timestamped_get_func();
|
|
282
|
+
if (!Object.prototype.hasOwnProperty.call(dataValueOrPromise, "then")) {
|
|
283
|
+
this.$dataValue = dataValueOrPromise;
|
|
284
|
+
this.verifyVariantCompatibility(this.$dataValue.value);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
errorLog("Unsupported: _timestamped_get_func returns a Promise !");
|
|
288
|
+
}
|
|
305
289
|
}
|
|
306
290
|
}
|
|
307
|
-
let dataValue = this
|
|
291
|
+
let dataValue = this.$dataValue;
|
|
308
292
|
if (isGoodish(dataValue.statusCode)) {
|
|
309
293
|
// note : extractRange will clone the dataValue
|
|
310
294
|
dataValue = (0, node_opcua_data_value_1.extractRange)(dataValue, indexRange);
|
|
@@ -342,6 +326,9 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
342
326
|
return dataTypeNode._getEnumerationInfo();
|
|
343
327
|
}
|
|
344
328
|
asyncRefresh(...args) {
|
|
329
|
+
if (isGoodish(this.$dataValue.statusCode)) {
|
|
330
|
+
this.verifyVariantCompatibility(this.$dataValue.value);
|
|
331
|
+
}
|
|
345
332
|
const oldestDate = args[0];
|
|
346
333
|
(0, node_opcua_assert_1.assert)(oldestDate instanceof Date);
|
|
347
334
|
const callback = args[1];
|
|
@@ -358,21 +345,31 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
358
345
|
return callback(null, dataValue);
|
|
359
346
|
}
|
|
360
347
|
}
|
|
361
|
-
if (this.
|
|
348
|
+
if (this.$dataValue.serverTimestamp && oldestDate.getTime() <= this.$dataValue.serverTimestamp.getTime()) {
|
|
362
349
|
const dataValue = this.readValue();
|
|
363
350
|
dataValue.serverTimestamp = oldestDate;
|
|
364
351
|
dataValue.serverPicoseconds = 0;
|
|
365
352
|
return callback(null, dataValue);
|
|
366
353
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
354
|
+
try {
|
|
355
|
+
this.refreshFunc.call(this, (err, dataValue) => {
|
|
356
|
+
if (err || !dataValue) {
|
|
357
|
+
errorLog("-------------- refresh call failed", this.browseName.toString(), this.nodeId.toString(), err === null || err === void 0 ? void 0 : err.message);
|
|
358
|
+
dataValue = { statusCode: node_opcua_status_code_1.StatusCodes.BadNoDataAvailable };
|
|
359
|
+
}
|
|
360
|
+
if (dataValue !== this.$dataValue) {
|
|
361
|
+
this._internal_set_dataValue(coerceDataValue(dataValue), null);
|
|
362
|
+
}
|
|
363
|
+
callback(err, this.$dataValue);
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
catch (err) {
|
|
367
|
+
errorLog("-------------- refresh call failed 2", this.browseName.toString(), this.nodeId.toString());
|
|
368
|
+
errorLog(err);
|
|
369
|
+
const dataValue = new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError });
|
|
370
|
+
this._internal_set_dataValue(dataValue, null);
|
|
371
|
+
callback(err, this.$dataValue);
|
|
372
|
+
}
|
|
376
373
|
}
|
|
377
374
|
readEnumValue() {
|
|
378
375
|
const value = this.readValue().value.value;
|
|
@@ -441,10 +438,80 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
441
438
|
return base_node_impl_1.BaseNodeImpl.prototype.readAttribute.call(this, context, attributeId);
|
|
442
439
|
}
|
|
443
440
|
}
|
|
444
|
-
|
|
441
|
+
getBasicDataType() {
|
|
442
|
+
if (this._basicDataType) {
|
|
443
|
+
return this._basicDataType;
|
|
444
|
+
}
|
|
445
|
+
if (this.dataType.namespace === 0 && this.dataType.value === 0) {
|
|
446
|
+
return node_opcua_variant_1.DataType.Null;
|
|
447
|
+
}
|
|
445
448
|
const addressSpace = this.addressSpace;
|
|
446
|
-
const
|
|
447
|
-
|
|
449
|
+
const dataTypeNode = addressSpace.findDataType(this.dataType);
|
|
450
|
+
const basicDataType = dataTypeNode ? dataTypeNode.getBasicDataType() : node_opcua_variant_1.DataType.Null;
|
|
451
|
+
// const basicDataType = addressSpace.findCorrespondingBasicDataType(this.dataType);
|
|
452
|
+
this._basicDataType = basicDataType;
|
|
453
|
+
return basicDataType;
|
|
454
|
+
}
|
|
455
|
+
adjustVariant(variant) {
|
|
456
|
+
return (0, node_opcua_variant_1.adjustVariant)(variant, this.valueRank, this.getBasicDataType());
|
|
457
|
+
}
|
|
458
|
+
verifyVariantCompatibility(variant) {
|
|
459
|
+
var _a;
|
|
460
|
+
try {
|
|
461
|
+
// istanbul ignore next
|
|
462
|
+
if (Object.prototype.hasOwnProperty.call(variant, "value")) {
|
|
463
|
+
if (variant.dataType === null || variant.dataType === undefined) {
|
|
464
|
+
throw new Error("Variant must provide a valid dataType : variant = " +
|
|
465
|
+
variant.toString() +
|
|
466
|
+
" this.dataType= " +
|
|
467
|
+
this.dataType.toString());
|
|
468
|
+
}
|
|
469
|
+
if (variant.dataType === node_opcua_variant_1.DataType.Boolean &&
|
|
470
|
+
(this.dataType.namespace !== 0 || this.dataType.value !== node_opcua_variant_1.DataType.Boolean)) {
|
|
471
|
+
throw new Error("Variant must provide a valid Boolean : variant = " +
|
|
472
|
+
variant.toString() +
|
|
473
|
+
" this.dataType= " +
|
|
474
|
+
this.dataType.toString());
|
|
475
|
+
}
|
|
476
|
+
if (this.dataType.namespace === 0 &&
|
|
477
|
+
this.dataType.value === node_opcua_variant_1.DataType.LocalizedText &&
|
|
478
|
+
variant.dataType !== node_opcua_variant_1.DataType.LocalizedText) {
|
|
479
|
+
throw new Error("Variant must provide a valid LocalizedText : variant = " +
|
|
480
|
+
variant.toString() +
|
|
481
|
+
" this.dataType= " +
|
|
482
|
+
this.dataType.toString());
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
const basicType = this.getBasicDataType();
|
|
486
|
+
if (basicType !== node_opcua_variant_1.DataType.Null &&
|
|
487
|
+
basicType !== node_opcua_variant_1.DataType.Variant &&
|
|
488
|
+
variant.dataType !== node_opcua_variant_1.DataType.Null &&
|
|
489
|
+
variant.dataType !== basicType) {
|
|
490
|
+
const message = "UAVariable.setValueFromSource " +
|
|
491
|
+
this.browseName.toString() +
|
|
492
|
+
" nodeId:" +
|
|
493
|
+
this.nodeId.toString() +
|
|
494
|
+
" dataType:" +
|
|
495
|
+
this.dataType.toString() +
|
|
496
|
+
":\n" +
|
|
497
|
+
"the provided variant must have the expected dataType!\n" +
|
|
498
|
+
" - the expected dataType is " +
|
|
499
|
+
chalk.cyan(node_opcua_variant_1.DataType[basicType]) +
|
|
500
|
+
"\n" +
|
|
501
|
+
" - the actual dataType is " +
|
|
502
|
+
chalk.magenta(node_opcua_variant_1.DataType[variant.dataType]) +
|
|
503
|
+
"\n" +
|
|
504
|
+
" - " +
|
|
505
|
+
variant.toString();
|
|
506
|
+
throw new Error(message);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
catch (err) {
|
|
510
|
+
errorLog("UAVariable ", (_a = err) === null || _a === void 0 ? void 0 : _a.message, this.browseName.toString(), " nodeId=", this.nodeId.toString());
|
|
511
|
+
errorLog(err.message);
|
|
512
|
+
errorLog(err.stack);
|
|
513
|
+
throw err;
|
|
514
|
+
}
|
|
448
515
|
}
|
|
449
516
|
/**
|
|
450
517
|
* setValueFromSource is used to let the device sets the variable values
|
|
@@ -458,32 +525,27 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
458
525
|
* @param [sourceTimestamp= Now]
|
|
459
526
|
*/
|
|
460
527
|
setValueFromSource(variant, statusCode, sourceTimestamp) {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
528
|
+
var _a;
|
|
529
|
+
try {
|
|
530
|
+
statusCode = statusCode || node_opcua_status_code_1.StatusCodes.Good;
|
|
531
|
+
const variant1 = node_opcua_variant_1.Variant.coerce(variant);
|
|
532
|
+
this.verifyVariantCompatibility(variant1);
|
|
533
|
+
const now = (0, node_opcua_date_time_1.coerceClock)(sourceTimestamp, 0);
|
|
534
|
+
const dataValue = new node_opcua_data_value_1.DataValue(null);
|
|
535
|
+
dataValue.serverPicoseconds = now.picoseconds;
|
|
536
|
+
dataValue.serverTimestamp = now.timestamp;
|
|
537
|
+
dataValue.sourcePicoseconds = now.picoseconds;
|
|
538
|
+
dataValue.sourceTimestamp = now.timestamp;
|
|
539
|
+
dataValue.statusCode = statusCode;
|
|
540
|
+
dataValue.value = variant1;
|
|
541
|
+
this._internal_set_dataValue(dataValue);
|
|
542
|
+
}
|
|
543
|
+
catch (err) {
|
|
544
|
+
errorLog("UAVariable#setValueFromString Error : ", this.browseName.toString(), this.nodeId.toString());
|
|
545
|
+
errorLog(err.message);
|
|
546
|
+
errorLog((_a = this.parent) === null || _a === void 0 ? void 0 : _a.toString());
|
|
547
|
+
throw err;
|
|
476
548
|
}
|
|
477
|
-
const variant1 = node_opcua_variant_1.Variant.coerce(variant);
|
|
478
|
-
const now = (0, node_opcua_date_time_1.coerceClock)(sourceTimestamp, 0);
|
|
479
|
-
const dataValue = new node_opcua_data_value_1.DataValue(null);
|
|
480
|
-
dataValue.serverPicoseconds = now.picoseconds;
|
|
481
|
-
dataValue.serverTimestamp = now.timestamp;
|
|
482
|
-
dataValue.sourcePicoseconds = now.picoseconds;
|
|
483
|
-
dataValue.sourceTimestamp = now.timestamp;
|
|
484
|
-
dataValue.statusCode = statusCode;
|
|
485
|
-
dataValue.value = variant1;
|
|
486
|
-
this._internal_set_dataValue(dataValue);
|
|
487
549
|
}
|
|
488
550
|
writeValue(context, dataValue, ...args) {
|
|
489
551
|
context = context || session_context_1.SessionContext.defaultContext;
|
|
@@ -536,49 +598,43 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
536
598
|
if (statusCode.isNot(node_opcua_status_code_1.StatusCodes.Good)) {
|
|
537
599
|
return callback(null, statusCode);
|
|
538
600
|
}
|
|
539
|
-
|
|
540
|
-
// xx assert(!indexRange,"indexRange Not Implemented");
|
|
541
|
-
return _default_writable_timestamped_set_func.call(this, dataValue1, callback1);
|
|
542
|
-
}
|
|
543
|
-
const write_func = (this._timestamped_set_func || default_func);
|
|
601
|
+
const write_func = this._timestamped_set_func || default_func;
|
|
544
602
|
if (!write_func) {
|
|
545
603
|
warningLog(" warning " + this.nodeId.toString() + " " + this.browseName.toString() + " has no setter. \n");
|
|
546
604
|
warningLog("Please make sure to bind the variable or to pass a valid value: new Variant({}) during construction time");
|
|
547
605
|
return callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable);
|
|
548
606
|
}
|
|
549
607
|
(0, node_opcua_assert_1.assert)(write_func);
|
|
550
|
-
write_func.call(this, dataValue,
|
|
608
|
+
write_func.call(this, dataValue, (err, statusCode1) => {
|
|
551
609
|
if (!err) {
|
|
552
|
-
|
|
553
|
-
(0, node_opcua_assert_1.assert)(correctedDataValue instanceof node_opcua_data_value_1.DataValue);
|
|
554
|
-
// xx assert(correctedDataValue.serverTimestamp);
|
|
610
|
+
dataValue && this.verifyVariantCompatibility(dataValue.value);
|
|
555
611
|
if (indexRange && !indexRange.isEmpty()) {
|
|
556
612
|
if (!indexRange.isValid()) {
|
|
557
613
|
return callback(null, node_opcua_status_code_1.StatusCodes.BadIndexRangeInvalid);
|
|
558
614
|
}
|
|
559
|
-
const newArrayOrMatrix =
|
|
560
|
-
if (
|
|
561
|
-
if (this.
|
|
615
|
+
const newArrayOrMatrix = dataValue.value.value;
|
|
616
|
+
if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Array) {
|
|
617
|
+
if (this.$dataValue.value.arrayType !== node_opcua_variant_1.VariantArrayType.Array) {
|
|
562
618
|
return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
|
|
563
619
|
}
|
|
564
620
|
// check that destination data is also an array
|
|
565
|
-
(0, node_opcua_assert_1.assert)(check_valid_array(this.
|
|
566
|
-
const destArr = this.
|
|
621
|
+
(0, node_opcua_assert_1.assert)(check_valid_array(this.$dataValue.value.dataType, this.$dataValue.value.value));
|
|
622
|
+
const destArr = this.$dataValue.value.value;
|
|
567
623
|
const result = indexRange.set_values(destArr, newArrayOrMatrix);
|
|
568
624
|
if (result.statusCode.isNot(node_opcua_status_code_1.StatusCodes.Good)) {
|
|
569
625
|
return callback(null, result.statusCode);
|
|
570
626
|
}
|
|
571
|
-
|
|
627
|
+
dataValue.value.value = result.array;
|
|
572
628
|
// scrap original array so we detect range
|
|
573
|
-
this.
|
|
629
|
+
this.$dataValue.value.value = null;
|
|
574
630
|
}
|
|
575
|
-
else if (
|
|
576
|
-
const dimensions = this.
|
|
577
|
-
if (this.
|
|
631
|
+
else if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Matrix) {
|
|
632
|
+
const dimensions = this.$dataValue.value.dimensions;
|
|
633
|
+
if (this.$dataValue.value.arrayType !== node_opcua_variant_1.VariantArrayType.Matrix || !dimensions) {
|
|
578
634
|
// not a matrix !
|
|
579
635
|
return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
|
|
580
636
|
}
|
|
581
|
-
const matrix = this.
|
|
637
|
+
const matrix = this.$dataValue.value.value;
|
|
582
638
|
const result = indexRange.set_values_matrix({
|
|
583
639
|
matrix,
|
|
584
640
|
dimensions
|
|
@@ -586,17 +642,17 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
586
642
|
if (result.statusCode.isNot(node_opcua_status_code_1.StatusCodes.Good)) {
|
|
587
643
|
return callback(null, result.statusCode);
|
|
588
644
|
}
|
|
589
|
-
|
|
590
|
-
|
|
645
|
+
dataValue.value.dimensions = this.$dataValue.value.dimensions;
|
|
646
|
+
dataValue.value.value = result.matrix;
|
|
591
647
|
// scrap original array so we detect range
|
|
592
|
-
this.
|
|
648
|
+
this.$dataValue.value.value = null;
|
|
593
649
|
}
|
|
594
650
|
else {
|
|
595
651
|
return callback(null, node_opcua_status_code_1.StatusCodes.BadTypeMismatch);
|
|
596
652
|
}
|
|
597
653
|
}
|
|
598
654
|
try {
|
|
599
|
-
this._internal_set_dataValue(
|
|
655
|
+
this._internal_set_dataValue(dataValue, indexRange);
|
|
600
656
|
}
|
|
601
657
|
catch (err) {
|
|
602
658
|
if (err instanceof Error) {
|
|
@@ -605,7 +661,7 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
605
661
|
return callback(null, node_opcua_status_code_1.StatusCodes.BadInternalError);
|
|
606
662
|
}
|
|
607
663
|
}
|
|
608
|
-
callback(err, statusCode1);
|
|
664
|
+
callback(err || null, statusCode1);
|
|
609
665
|
});
|
|
610
666
|
}
|
|
611
667
|
writeAttribute(context, writeValueOptions, callback) {
|
|
@@ -656,6 +712,12 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
656
712
|
if (!this._validate_DataType(value.dataType)) {
|
|
657
713
|
return node_opcua_status_code_1.StatusCodes.BadTypeMismatch;
|
|
658
714
|
}
|
|
715
|
+
try {
|
|
716
|
+
this.verifyVariantCompatibility(value);
|
|
717
|
+
}
|
|
718
|
+
catch (err) {
|
|
719
|
+
return node_opcua_status_code_1.StatusCodes.BadTypeMismatch;
|
|
720
|
+
}
|
|
659
721
|
return node_opcua_status_code_1.StatusCodes.Good;
|
|
660
722
|
}
|
|
661
723
|
/**
|
|
@@ -669,11 +731,11 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
669
731
|
*/
|
|
670
732
|
touchValue(optionalNow) {
|
|
671
733
|
const now = optionalNow || (0, node_opcua_date_time_1.getCurrentClock)();
|
|
672
|
-
this.
|
|
673
|
-
this.
|
|
674
|
-
this.
|
|
675
|
-
this.
|
|
676
|
-
this.
|
|
734
|
+
this.$dataValue.sourceTimestamp = now.timestamp;
|
|
735
|
+
this.$dataValue.sourcePicoseconds = now.picoseconds;
|
|
736
|
+
this.$dataValue.serverTimestamp = now.timestamp;
|
|
737
|
+
this.$dataValue.serverPicoseconds = now.picoseconds;
|
|
738
|
+
this.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
677
739
|
if (this.minimumSamplingInterval === 0) {
|
|
678
740
|
if (this.listenerCount("value_changed") > 0) {
|
|
679
741
|
const clonedDataValue = this.readValue();
|
|
@@ -826,8 +888,9 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
826
888
|
this._historyRead = _historyRead;
|
|
827
889
|
(0, node_opcua_assert_1.assert)(this._historyRead.length === 6);
|
|
828
890
|
}
|
|
891
|
+
// post conditions
|
|
829
892
|
(0, node_opcua_assert_1.assert)(typeof this._timestamped_set_func === "function");
|
|
830
|
-
(0, node_opcua_assert_1.assert)(this._timestamped_set_func.length ===
|
|
893
|
+
(0, node_opcua_assert_1.assert)(this._timestamped_set_func.length === 2, "expecting 2 parameters");
|
|
831
894
|
}
|
|
832
895
|
readValueAsync(context, callback) {
|
|
833
896
|
if (!context) {
|
|
@@ -841,7 +904,7 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
841
904
|
return;
|
|
842
905
|
}
|
|
843
906
|
const readImmediate = (innerCallback) => {
|
|
844
|
-
(0, node_opcua_assert_1.assert)(this
|
|
907
|
+
(0, node_opcua_assert_1.assert)(this.$dataValue instanceof node_opcua_data_value_1.DataValue);
|
|
845
908
|
const dataValue = this.readValue();
|
|
846
909
|
innerCallback(null, dataValue);
|
|
847
910
|
};
|
|
@@ -895,11 +958,11 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
895
958
|
// check this eventNotifier: this.eventNotifier,
|
|
896
959
|
// check this symbolicName: this.symbolicName,
|
|
897
960
|
accessLevel: this.accessLevel, arrayDimensions: this.arrayDimensions, dataType: this.dataType, historizing: this.historizing, minimumSamplingInterval: this.minimumSamplingInterval, userAccessLevel: this.userAccessLevel, valueRank: this.valueRank });
|
|
898
|
-
const newVariable = base_node_private_1._clone.call(this, UAVariableImpl, options, optionalFilter, extraInfo);
|
|
961
|
+
const newVariable = base_node_private_1._clone.call(this, UAVariableImpl, options, optionalFilter || node_opcua_address_space_base_1.defaultCloneFilter, extraInfo || node_opcua_address_space_base_1.defaultCloneExtraInfo);
|
|
899
962
|
newVariable.bindVariable();
|
|
900
963
|
(0, node_opcua_assert_1.assert)(typeof newVariable._timestamped_set_func === "function");
|
|
901
964
|
(0, node_opcua_assert_1.assert)(newVariable.dataType === this.dataType);
|
|
902
|
-
newVariable
|
|
965
|
+
newVariable.$dataValue = this.$dataValue.clone();
|
|
903
966
|
return newVariable;
|
|
904
967
|
}
|
|
905
968
|
getDataTypeNode() {
|
|
@@ -919,8 +982,9 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
919
982
|
return true;
|
|
920
983
|
}
|
|
921
984
|
const addressSpace = this.addressSpace;
|
|
985
|
+
// istanbul ignore next
|
|
922
986
|
if (!(extObj && extObj.constructor)) {
|
|
923
|
-
|
|
987
|
+
errorLog(extObj);
|
|
924
988
|
throw new Error("expecting an valid extension object");
|
|
925
989
|
}
|
|
926
990
|
const dataType = addressSpace.findDataType(this.dataType);
|
|
@@ -948,7 +1012,7 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
948
1012
|
}
|
|
949
1013
|
}
|
|
950
1014
|
catch (err) {
|
|
951
|
-
|
|
1015
|
+
errorLog(err);
|
|
952
1016
|
return false;
|
|
953
1017
|
}
|
|
954
1018
|
}
|
|
@@ -957,7 +1021,7 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
957
1021
|
* @return {ExtensionObject}
|
|
958
1022
|
*/
|
|
959
1023
|
bindExtensionObject(optionalExtensionObject) {
|
|
960
|
-
var _a, _b
|
|
1024
|
+
var _a, _b;
|
|
961
1025
|
const addressSpace = this.addressSpace;
|
|
962
1026
|
const structure = addressSpace.findDataType("Structure");
|
|
963
1027
|
let extensionObject_;
|
|
@@ -968,7 +1032,7 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
968
1032
|
}
|
|
969
1033
|
// istanbul ignore next
|
|
970
1034
|
if (doDebug) {
|
|
971
|
-
|
|
1035
|
+
debugLog(" ------------------------------ binding ", this.browseName.toString(), this.nodeId.toString());
|
|
972
1036
|
}
|
|
973
1037
|
(0, node_opcua_assert_1.assert)(structure && structure.browseName.toString() === "Structure", "expecting DataType Structure to be in IAddressSpace");
|
|
974
1038
|
const dt = this.getDataTypeNode();
|
|
@@ -990,8 +1054,8 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
990
1054
|
// }
|
|
991
1055
|
// istanbul ignore next
|
|
992
1056
|
if (!this.checkExtensionObjectIsCorrect(this.$extensionObject)) {
|
|
993
|
-
|
|
994
|
-
|
|
1057
|
+
warningLog("on node : ", this.browseName.toString(), this.nodeId.toString(), "dataType=", this.dataType.toString({ addressSpace: this.addressSpace }));
|
|
1058
|
+
warningLog((_a = this.$extensionObject) === null || _a === void 0 ? void 0 : _a.toString());
|
|
995
1059
|
throw new Error("bindExtensionObject: $extensionObject is incorrect: we are expecting a " +
|
|
996
1060
|
this.dataType.toString({ addressSpace: this.addressSpace }) +
|
|
997
1061
|
" but we got a " +
|
|
@@ -1003,38 +1067,28 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
1003
1067
|
this.$extensionObject = optionalExtensionObject;
|
|
1004
1068
|
// ------------------------------------------------------------------
|
|
1005
1069
|
function prepareVariantValue(dataType, value) {
|
|
1006
|
-
if (typeof dataType === "string") {
|
|
1007
|
-
dataType = node_opcua_variant_1.DataType[dataType];
|
|
1008
|
-
}
|
|
1009
1070
|
if ((dataType === node_opcua_variant_1.DataType.Int32 || dataType === node_opcua_variant_1.DataType.UInt32) && value && value.key) {
|
|
1010
1071
|
value = value.value;
|
|
1011
1072
|
}
|
|
1012
1073
|
return value;
|
|
1013
1074
|
}
|
|
1014
|
-
const bindProperty = (propertyNode, name, extensionObject,
|
|
1015
|
-
const dataTypeAsString = node_opcua_variant_1.DataType[dataTypeNodeId];
|
|
1016
|
-
/*
|
|
1017
|
-
property.setValueFromSource(new Variant({
|
|
1018
|
-
dataType: dataType,
|
|
1019
|
-
value: prepareVariantValue(dataType, this.$extensionObject[name])
|
|
1020
|
-
}));
|
|
1021
|
-
*/
|
|
1022
|
-
(0, node_opcua_assert_1.assert)(propertyNode.readValue().statusCode.equals(node_opcua_status_code_1.StatusCodes.Good));
|
|
1075
|
+
const bindProperty = (propertyNode, name, extensionObject, dataType) => {
|
|
1023
1076
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1024
1077
|
const self = this;
|
|
1025
1078
|
propertyNode.bindVariable({
|
|
1026
1079
|
timestamped_get: () => {
|
|
1027
|
-
const
|
|
1028
|
-
if (
|
|
1029
|
-
propertyNode.
|
|
1030
|
-
propertyNode.
|
|
1031
|
-
propertyNode.
|
|
1032
|
-
return new node_opcua_data_value_1.DataValue(propertyNode
|
|
1080
|
+
const propertyValue = self.$extensionObject[name];
|
|
1081
|
+
if (propertyValue === undefined) {
|
|
1082
|
+
propertyNode.$dataValue.value.dataType = node_opcua_variant_1.DataType.Null;
|
|
1083
|
+
propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
1084
|
+
propertyNode.$dataValue.value.value = null;
|
|
1085
|
+
return new node_opcua_data_value_1.DataValue(propertyNode.$dataValue);
|
|
1033
1086
|
}
|
|
1034
|
-
const value = prepareVariantValue(
|
|
1035
|
-
propertyNode.
|
|
1036
|
-
propertyNode.
|
|
1037
|
-
|
|
1087
|
+
const value = prepareVariantValue(dataType, propertyValue);
|
|
1088
|
+
propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
1089
|
+
propertyNode.$dataValue.value.dataType = dataType;
|
|
1090
|
+
propertyNode.$dataValue.value.value = value;
|
|
1091
|
+
return new node_opcua_data_value_1.DataValue(propertyNode.$dataValue);
|
|
1038
1092
|
},
|
|
1039
1093
|
timestamped_set: (dataValue, callback) => {
|
|
1040
1094
|
dataValue;
|
|
@@ -1049,8 +1103,8 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
1049
1103
|
const s = this.readValue();
|
|
1050
1104
|
// istanbul ignore next
|
|
1051
1105
|
if (this.dataTypeObj.isAbstract) {
|
|
1052
|
-
|
|
1053
|
-
|
|
1106
|
+
warningLog("Warning the DataType associated with this Variable is abstract ", this.dataTypeObj.browseName.toString());
|
|
1107
|
+
warningLog("You need to provide a extension object yourself ");
|
|
1054
1108
|
throw new Error("bindExtensionObject requires a extensionObject as associated dataType is only abstract");
|
|
1055
1109
|
}
|
|
1056
1110
|
if (s.value && (s.value.dataType === node_opcua_variant_1.DataType.Null || (s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject && !s.value.value))) {
|
|
@@ -1067,8 +1121,8 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
1067
1121
|
const self = this;
|
|
1068
1122
|
this.bindVariable({
|
|
1069
1123
|
timestamped_get() {
|
|
1070
|
-
self.
|
|
1071
|
-
const d = new node_opcua_data_value_1.DataValue(self
|
|
1124
|
+
self.$dataValue.value.value = self.$extensionObject;
|
|
1125
|
+
const d = new node_opcua_data_value_1.DataValue(self.$dataValue);
|
|
1072
1126
|
d.value = new node_opcua_variant_1.Variant(d.value);
|
|
1073
1127
|
return d;
|
|
1074
1128
|
},
|
|
@@ -1090,26 +1144,28 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
1090
1144
|
(0, node_opcua_assert_1.assert)(this.checkExtensionObjectIsCorrect(this.$extensionObject));
|
|
1091
1145
|
(0, node_opcua_assert_1.assert)(s.statusCode.equals(node_opcua_status_code_1.StatusCodes.Good));
|
|
1092
1146
|
}
|
|
1093
|
-
let property;
|
|
1094
|
-
let camelCaseName;
|
|
1095
1147
|
// ------------------------------------------------------
|
|
1096
1148
|
// now bind each member
|
|
1097
1149
|
// ------------------------------------------------------
|
|
1098
|
-
const definition = dt._getDefinition(
|
|
1150
|
+
const definition = dt._getDefinition();
|
|
1099
1151
|
// istanbul ignore next
|
|
1100
1152
|
if (!definition) {
|
|
1101
1153
|
throw new Error("xx definition missing in " + dt.toString());
|
|
1102
1154
|
}
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
const
|
|
1106
|
-
if (
|
|
1107
|
-
|
|
1155
|
+
const getOrCreateProperty = (field) => {
|
|
1156
|
+
let property;
|
|
1157
|
+
const selectedComponents = components.filter((f) => f instanceof UAVariableImpl && f.browseName.name.toString() === field.name);
|
|
1158
|
+
if (field.dataType.value === node_opcua_variant_1.DataType.Variant) {
|
|
1159
|
+
warningLog("Warning : variant is not supported in ExtensionObject");
|
|
1160
|
+
}
|
|
1161
|
+
if (selectedComponents.length === 1) {
|
|
1162
|
+
property = selectedComponents[0];
|
|
1108
1163
|
/* istanbul ignore next */
|
|
1109
1164
|
}
|
|
1110
1165
|
else {
|
|
1166
|
+
debugLog("adding missing array variable", field.name, this.browseName.toString(), this.nodeId.toString());
|
|
1111
1167
|
// todo: Handle array appropriately...
|
|
1112
|
-
(0, node_opcua_assert_1.assert)(
|
|
1168
|
+
(0, node_opcua_assert_1.assert)(selectedComponents.length === 0);
|
|
1113
1169
|
// create a variable (Note we may use ns=1;s=parentName/0:PropertyName)
|
|
1114
1170
|
property = this.namespace.addVariable({
|
|
1115
1171
|
browseName: { namespaceIndex: structureNamespace, name: field.name.toString() },
|
|
@@ -1119,62 +1175,64 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
1119
1175
|
});
|
|
1120
1176
|
(0, node_opcua_assert_1.assert)(property.minimumSamplingInterval === this.minimumSamplingInterval);
|
|
1121
1177
|
}
|
|
1122
|
-
property
|
|
1123
|
-
|
|
1178
|
+
return property;
|
|
1179
|
+
};
|
|
1180
|
+
for (const field of definition.fields || []) {
|
|
1124
1181
|
if (node_opcua_nodeid_1.NodeId.sameNodeId(node_opcua_nodeid_1.NodeId.nullNodeId, field.dataType)) {
|
|
1125
|
-
|
|
1126
|
-
|
|
1182
|
+
warningLog("field.dataType is null ! ", field.toString(), node_opcua_nodeid_1.NodeId.nullNodeId.toString());
|
|
1183
|
+
warningLog(" dataType replaced with BaseDataType ");
|
|
1184
|
+
warningLog(definition.toString());
|
|
1127
1185
|
field.dataType = this.resolveNodeId("BaseDataType");
|
|
1128
1186
|
}
|
|
1129
|
-
const
|
|
1187
|
+
const camelCaseName = (0, node_opcua_utils_1.lowerFirstLetter)(field.name);
|
|
1130
1188
|
(0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(this.$extensionObject, camelCaseName));
|
|
1189
|
+
const propertyNode = getOrCreateProperty(field);
|
|
1190
|
+
propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
1191
|
+
propertyNode.touchValue();
|
|
1192
|
+
const basicDataType = addressSpace.findCorrespondingBasicDataType(field.dataType);
|
|
1131
1193
|
// istanbul ignore next
|
|
1132
1194
|
if (doDebug) {
|
|
1133
1195
|
const x = addressSpace.findNode(field.dataType).browseName.toString();
|
|
1134
|
-
|
|
1135
|
-
debugLog(chalk.cyan("xxx"), " dataType", w(field.dataType.toString(), 8), w(field.name, 35), "valueRank", chalk.cyan(w((0, base_node_private_1.valueRankToString)(field.valueRank), 10)), chalk.green(w(x, 25)), "basicType = ", chalk.yellow(w(basicType.toString(), 20)), property.nodeId.toString(), property.readValue().statusCode.toString());
|
|
1196
|
+
debugLog(chalk.cyan("xxx"), " dataType", w(field.dataType.toString(), 8), w(field.name, 35), "valueRank", chalk.cyan(w((0, base_node_private_1.valueRankToString)(field.valueRank), 10)), chalk.green(w(x, 25)), "basicType = ", chalk.yellow(w(basicDataType.toString(), 20)), propertyNode.nodeId.toString(), propertyNode.readValue().statusCode.toString());
|
|
1136
1197
|
}
|
|
1137
|
-
if (this.$extensionObject[camelCaseName] !== undefined &&
|
|
1198
|
+
if (this.$extensionObject[camelCaseName] !== undefined && basicDataType === node_opcua_variant_1.DataType.ExtensionObject) {
|
|
1138
1199
|
(0, node_opcua_assert_1.assert)(this.$extensionObject[camelCaseName] instanceof Object);
|
|
1139
|
-
this.$extensionObject[camelCaseName] = new Proxy(this.$extensionObject[camelCaseName], makeHandler(
|
|
1140
|
-
|
|
1200
|
+
this.$extensionObject[camelCaseName] = new Proxy(this.$extensionObject[camelCaseName], makeHandler(propertyNode));
|
|
1201
|
+
propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
|
|
1141
1202
|
dataType: node_opcua_variant_1.DataType.ExtensionObject,
|
|
1142
1203
|
value: this.$extensionObject[camelCaseName]
|
|
1143
|
-
});
|
|
1144
|
-
|
|
1145
|
-
|
|
1204
|
+
}));
|
|
1205
|
+
propertyNode.bindExtensionObject();
|
|
1206
|
+
propertyNode.$extensionObject = this.$extensionObject[camelCaseName];
|
|
1146
1207
|
}
|
|
1147
1208
|
else {
|
|
1148
|
-
const dataTypeAsString = node_opcua_variant_1.DataType[dataTypeNodeId];
|
|
1149
|
-
(0, node_opcua_assert_1.assert)(typeof dataTypeAsString === "string");
|
|
1150
1209
|
const prop = this.$extensionObject[camelCaseName];
|
|
1151
1210
|
if (prop === undefined) {
|
|
1152
|
-
|
|
1211
|
+
propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
|
|
1153
1212
|
dataType: node_opcua_variant_1.DataType.Null
|
|
1154
|
-
});
|
|
1213
|
+
}));
|
|
1155
1214
|
}
|
|
1156
1215
|
else {
|
|
1157
|
-
const preparedValue = prepareVariantValue(
|
|
1158
|
-
|
|
1159
|
-
dataType:
|
|
1216
|
+
const preparedValue = prepareVariantValue(basicDataType, prop);
|
|
1217
|
+
propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
|
|
1218
|
+
dataType: basicDataType,
|
|
1160
1219
|
value: preparedValue
|
|
1161
|
-
});
|
|
1220
|
+
}));
|
|
1162
1221
|
}
|
|
1163
1222
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1164
1223
|
const self = this;
|
|
1165
|
-
property.camelCaseName = camelCaseName;
|
|
1166
|
-
|
|
1224
|
+
// property.camelCaseName = camelCaseName;
|
|
1225
|
+
propertyNode.setValueFromSource = function (variant) {
|
|
1167
1226
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1168
1227
|
const inner_this = this;
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
self.$extensionObject[inner_this.camelCaseName] = variant.value;
|
|
1228
|
+
const variant1 = node_opcua_variant_1.Variant.coerce(variant);
|
|
1229
|
+
inner_this.verifyVariantCompatibility(variant1);
|
|
1230
|
+
self.$extensionObject[camelCaseName] = variant1.value;
|
|
1173
1231
|
self.touchValue();
|
|
1174
1232
|
};
|
|
1175
1233
|
}
|
|
1176
|
-
(0, node_opcua_assert_1.assert)(
|
|
1177
|
-
bindProperty(
|
|
1234
|
+
(0, node_opcua_assert_1.assert)(propertyNode.readValue().statusCode.equals(node_opcua_status_code_1.StatusCodes.Good));
|
|
1235
|
+
bindProperty(propertyNode, camelCaseName, this.$extensionObject, basicDataType);
|
|
1178
1236
|
}
|
|
1179
1237
|
(0, node_opcua_assert_1.assert)(this.$extensionObject instanceof Object);
|
|
1180
1238
|
return this.$extensionObject;
|
|
@@ -1211,7 +1269,6 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
1211
1269
|
name = path[path.length - 1];
|
|
1212
1270
|
c1[name] = c2[name];
|
|
1213
1271
|
c1[name] += 1;
|
|
1214
|
-
// xx console.log(partialData);
|
|
1215
1272
|
setExtensionObjectValue(this, partialData);
|
|
1216
1273
|
}
|
|
1217
1274
|
constructExtensionObjectFromComponents() {
|
|
@@ -1261,10 +1318,16 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
1261
1318
|
_validate_DataType(variantDataType) {
|
|
1262
1319
|
return validateDataType(this.addressSpace, this.dataType, variantDataType, this.nodeId, /* allow Nulls */ false);
|
|
1263
1320
|
}
|
|
1321
|
+
_internal_set_value(value) {
|
|
1322
|
+
if (value.dataType !== node_opcua_variant_1.DataType.Null) {
|
|
1323
|
+
this.verifyVariantCompatibility(value);
|
|
1324
|
+
}
|
|
1325
|
+
this.$dataValue.value = value;
|
|
1326
|
+
}
|
|
1264
1327
|
_internal_set_dataValue(dataValue, indexRange) {
|
|
1265
1328
|
(0, node_opcua_assert_1.assert)(dataValue, "expecting a dataValue");
|
|
1266
1329
|
(0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue, "expecting dataValue to be a DataValue");
|
|
1267
|
-
(0, node_opcua_assert_1.assert)(dataValue !== this
|
|
1330
|
+
(0, node_opcua_assert_1.assert)(dataValue !== this.$dataValue, "expecting dataValue to be different from previous DataValue instance");
|
|
1268
1331
|
if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Matrix) {
|
|
1269
1332
|
if (!dataValue.value.dimensions) {
|
|
1270
1333
|
throw new Error("missing dimensions: a Matrix Variant needs a dimension");
|
|
@@ -1283,23 +1346,26 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
1283
1346
|
// istanbul ignore next
|
|
1284
1347
|
if (this.dataType.namespace === 0) {
|
|
1285
1348
|
if (this.dataType.value === node_opcua_variant_1.DataType.LocalizedText && dataValue.value.dataType !== node_opcua_variant_1.DataType.LocalizedText) {
|
|
1286
|
-
|
|
1349
|
+
const message = "Invalid dataValue provided (expecting a LocalizedText) but got " + dataValue.toString();
|
|
1350
|
+
errorLog(message);
|
|
1351
|
+
throw new Error(message);
|
|
1287
1352
|
}
|
|
1288
1353
|
}
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
this
|
|
1354
|
+
this.verifyVariantCompatibility(dataValue.value);
|
|
1355
|
+
const old_dataValue = this.$dataValue;
|
|
1356
|
+
this.$dataValue = dataValue;
|
|
1357
|
+
this.$dataValue.statusCode = this.$dataValue.statusCode || node_opcua_status_code_1.StatusCodes.Good;
|
|
1292
1358
|
// repair missing timestamps
|
|
1293
1359
|
if (!dataValue.serverTimestamp) {
|
|
1294
|
-
this.
|
|
1295
|
-
this.
|
|
1360
|
+
this.$dataValue.serverTimestamp = old_dataValue.serverTimestamp;
|
|
1361
|
+
this.$dataValue.serverPicoseconds = old_dataValue.serverPicoseconds;
|
|
1296
1362
|
}
|
|
1297
1363
|
if (!dataValue.sourceTimestamp) {
|
|
1298
|
-
this.
|
|
1299
|
-
this.
|
|
1364
|
+
this.$dataValue.sourceTimestamp = old_dataValue.sourceTimestamp;
|
|
1365
|
+
this.$dataValue.sourcePicoseconds = old_dataValue.sourcePicoseconds;
|
|
1300
1366
|
}
|
|
1301
1367
|
if (!(0, node_opcua_data_value_1.sameDataValue)(old_dataValue, dataValue)) {
|
|
1302
|
-
this.emit("value_changed", this
|
|
1368
|
+
this.emit("value_changed", this.$dataValue, indexRange);
|
|
1303
1369
|
}
|
|
1304
1370
|
}
|
|
1305
1371
|
_conditionRefresh(_cache) {
|
|
@@ -1467,7 +1533,7 @@ function _calculateEffectiveUserAccessLevelFromPermission(node, context, userAcc
|
|
|
1467
1533
|
function adjustVariant2(variant) {
|
|
1468
1534
|
// convert Variant( Scalar|ByteString) => Variant(Array|ByteArray)
|
|
1469
1535
|
const addressSpace = this.addressSpace;
|
|
1470
|
-
const basicType =
|
|
1536
|
+
const basicType = this.getBasicDataType();
|
|
1471
1537
|
variant = (0, node_opcua_variant_1.adjustVariant)(variant, this.valueRank, basicType);
|
|
1472
1538
|
return variant;
|
|
1473
1539
|
}
|
|
@@ -1476,7 +1542,6 @@ function _not_writable_timestamped_set_func(dataValue, callback) {
|
|
|
1476
1542
|
callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable, null);
|
|
1477
1543
|
}
|
|
1478
1544
|
function _default_writable_timestamped_set_func(dataValue, callback) {
|
|
1479
|
-
/* jshint validthis: true */
|
|
1480
1545
|
(0, node_opcua_assert_1.assert)(dataValue instanceof node_opcua_data_value_1.DataValue);
|
|
1481
1546
|
callback(null, node_opcua_status_code_1.StatusCodes.Good, dataValue);
|
|
1482
1547
|
}
|
|
@@ -1511,7 +1576,7 @@ function _Variable_bind_with_async_refresh(options) {
|
|
|
1511
1576
|
(0, node_opcua_assert_1.assert)(!this.refreshFunc);
|
|
1512
1577
|
this.refreshFunc = options.refreshFunc;
|
|
1513
1578
|
// assert(this.readValue().statusCode === StatusCodes.BadNodeIdUnknown);
|
|
1514
|
-
this.
|
|
1579
|
+
this.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.UncertainInitialValue;
|
|
1515
1580
|
// TO DO : REVISIT THIS ASSUMPTION
|
|
1516
1581
|
if (false && this.minimumSamplingInterval === 0) {
|
|
1517
1582
|
// when a getter /timestamped_getter or async_getter is provided
|
|
@@ -1530,13 +1595,17 @@ function _Variable_bind_with_timestamped_get(options) {
|
|
|
1530
1595
|
const async_refresh_func = (callback) => {
|
|
1531
1596
|
Promise.resolve(this._timestamped_get_func.call(this))
|
|
1532
1597
|
.then((dataValue) => callback(null, dataValue))
|
|
1533
|
-
.catch((err) =>
|
|
1598
|
+
.catch((err) => {
|
|
1599
|
+
errorLog("asyncRefresh error: Variable is ", this.nodeId.toString(), this.browseName.toString());
|
|
1600
|
+
callback(err);
|
|
1601
|
+
});
|
|
1534
1602
|
};
|
|
1603
|
+
const pThis = this;
|
|
1535
1604
|
if (options.timestamped_get.length === 0) {
|
|
1536
1605
|
const timestamped_get = options.timestamped_get;
|
|
1537
1606
|
// sync version | Promise version
|
|
1538
1607
|
this._timestamped_get_func = timestamped_get;
|
|
1539
|
-
const dataValue_verify = timestamped_get.call(
|
|
1608
|
+
const dataValue_verify = timestamped_get.call(pThis);
|
|
1540
1609
|
// dataValue_verify should be a DataValue or a Promise
|
|
1541
1610
|
/* istanbul ignore next */
|
|
1542
1611
|
if (!(dataValue_verify instanceof node_opcua_data_value_1.DataValue) && typeof dataValue_verify.then !== "function") {
|
|
@@ -1575,16 +1644,14 @@ function _Variable_bind_with_simple_get(options) {
|
|
|
1575
1644
|
return new node_opcua_data_value_1.DataValue({ statusCode: value });
|
|
1576
1645
|
}
|
|
1577
1646
|
else {
|
|
1578
|
-
if (!this
|
|
1647
|
+
if (!this.$dataValue || !isGoodish(this.$dataValue.statusCode) || !(0, node_opcua_variant_1.sameVariant)(this.$dataValue.value, value)) {
|
|
1579
1648
|
this.setValueFromSource(value, node_opcua_status_code_1.StatusCodes.Good);
|
|
1580
1649
|
}
|
|
1581
|
-
|
|
1582
|
-
// XX console.log("YYYYYYYYYYYYYYYYYYYYYYYYYY",this.browseName.toString());
|
|
1583
|
-
}
|
|
1584
|
-
return this._dataValue;
|
|
1650
|
+
return this.$dataValue;
|
|
1585
1651
|
}
|
|
1586
1652
|
};
|
|
1587
1653
|
_Variable_bind_with_timestamped_get.call(this, {
|
|
1654
|
+
get: undefined,
|
|
1588
1655
|
timestamped_get: timestamped_get_func_from__Variable_bind_with_simple_get
|
|
1589
1656
|
});
|
|
1590
1657
|
}
|
|
@@ -1596,12 +1663,13 @@ function _Variable_bind_with_simple_set(options) {
|
|
|
1596
1663
|
(0, node_opcua_assert_1.assert)(!this._set_func);
|
|
1597
1664
|
this._set_func = turn_sync_to_async(options.set, 1);
|
|
1598
1665
|
(0, node_opcua_assert_1.assert)(this._set_func.length === 2, " set function must have 2 arguments ( variant, callback)");
|
|
1599
|
-
this._timestamped_set_func = (timestamped_value,
|
|
1666
|
+
this._timestamped_set_func = (timestamped_value, callback) => {
|
|
1600
1667
|
(0, node_opcua_assert_1.assert)(timestamped_value instanceof node_opcua_data_value_1.DataValue);
|
|
1601
1668
|
this._set_func(timestamped_value.value, (err, statusCode) => {
|
|
1669
|
+
// istanbul ignore next
|
|
1602
1670
|
if (!err && !statusCode) {
|
|
1603
|
-
|
|
1604
|
-
|
|
1671
|
+
errorLog(chalk.red("UAVariable Binding Error _set_func must return a StatusCode, check the bindVariable parameters"));
|
|
1672
|
+
errorLog(chalk.yellow("StatusCode.Good is assumed"));
|
|
1605
1673
|
return callback(err, node_opcua_status_code_1.StatusCodes.Good, timestamped_value);
|
|
1606
1674
|
}
|
|
1607
1675
|
callback(err, statusCode, timestamped_value);
|
|
@@ -1609,14 +1677,10 @@ function _Variable_bind_with_simple_set(options) {
|
|
|
1609
1677
|
};
|
|
1610
1678
|
}
|
|
1611
1679
|
function _Variable_bind_with_timestamped_set(options) {
|
|
1612
|
-
(0, node_opcua_assert_1.assert)(this instanceof UAVariableImpl);
|
|
1613
1680
|
(0, node_opcua_assert_1.assert)(typeof options.timestamped_set === "function");
|
|
1614
1681
|
(0, node_opcua_assert_1.assert)(options.timestamped_set.length === 2, "timestamped_set must have 2 parameters timestamped_set: function(dataValue,callback){}");
|
|
1615
1682
|
(0, node_opcua_assert_1.assert)(!options.set, "should not specify set when timestamped_set_func exists ");
|
|
1616
|
-
this._timestamped_set_func = (
|
|
1617
|
-
// xx assert(!indexRange,"indexRange Not Implemented");
|
|
1618
|
-
return options.timestamped_set.call(this, dataValue, callback);
|
|
1619
|
-
};
|
|
1683
|
+
this._timestamped_set_func = (0, multiform_func_1.convertToCallbackFunction1)(options.timestamped_set);
|
|
1620
1684
|
}
|
|
1621
1685
|
function bind_setter(options) {
|
|
1622
1686
|
if (typeof options.set === "function") {
|
|
@@ -1626,17 +1690,22 @@ function bind_setter(options) {
|
|
|
1626
1690
|
else if (typeof options.timestamped_set === "function") {
|
|
1627
1691
|
// variation 2
|
|
1628
1692
|
(0, node_opcua_assert_1.assert)(typeof options.timestamped_get === "function", "timestamped_set must be used with timestamped_get ");
|
|
1629
|
-
_Variable_bind_with_timestamped_set.call(this,
|
|
1693
|
+
_Variable_bind_with_timestamped_set.call(this, {
|
|
1694
|
+
set: undefined,
|
|
1695
|
+
timestamped_set: options.timestamped_set
|
|
1696
|
+
});
|
|
1630
1697
|
}
|
|
1631
1698
|
else if (typeof options.timestamped_get === "function") {
|
|
1632
1699
|
// timestamped_get is specified but timestamped_set is not
|
|
1633
1700
|
// => Value is read-only
|
|
1634
1701
|
_Variable_bind_with_timestamped_set.call(this, {
|
|
1702
|
+
set: undefined,
|
|
1635
1703
|
timestamped_set: _not_writable_timestamped_set_func
|
|
1636
1704
|
});
|
|
1637
1705
|
}
|
|
1638
1706
|
else {
|
|
1639
1707
|
_Variable_bind_with_timestamped_set.call(this, {
|
|
1708
|
+
set: undefined,
|
|
1640
1709
|
timestamped_set: _default_writable_timestamped_set_func
|
|
1641
1710
|
});
|
|
1642
1711
|
}
|
|
@@ -1648,7 +1717,10 @@ function bind_getter(options) {
|
|
|
1648
1717
|
}
|
|
1649
1718
|
else if (typeof options.timestamped_get === "function") {
|
|
1650
1719
|
// variation 2
|
|
1651
|
-
_Variable_bind_with_timestamped_get.call(this,
|
|
1720
|
+
_Variable_bind_with_timestamped_get.call(this, {
|
|
1721
|
+
get: undefined,
|
|
1722
|
+
timestamped_get: options.timestamped_get
|
|
1723
|
+
});
|
|
1652
1724
|
}
|
|
1653
1725
|
else if (typeof options.refreshFunc === "function") {
|
|
1654
1726
|
// variation 3
|