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