node-opcua-address-space 2.60.0 → 2.61.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 (34) hide show
  1. package/dist/source/helpers/multiform_func.d.ts +11 -0
  2. package/dist/source/helpers/multiform_func.js +74 -0
  3. package/dist/source/helpers/multiform_func.js.map +1 -0
  4. package/dist/src/address_space.js +4 -1
  5. package/dist/src/address_space.js.map +1 -1
  6. package/dist/src/base_node_impl.js +2 -0
  7. package/dist/src/base_node_impl.js.map +1 -1
  8. package/dist/src/base_node_private.d.ts +3 -3
  9. package/dist/src/base_node_private.js +196 -23
  10. package/dist/src/base_node_private.js.map +1 -1
  11. package/dist/src/ua_method_impl.js +2 -1
  12. package/dist/src/ua_method_impl.js.map +1 -1
  13. package/dist/src/ua_object_impl.js +2 -1
  14. package/dist/src/ua_object_impl.js.map +1 -1
  15. package/dist/src/ua_variable_impl.d.ts +6 -12
  16. package/dist/src/ua_variable_impl.js +58 -36
  17. package/dist/src/ua_variable_impl.js.map +1 -1
  18. package/dist/src/ua_variable_type_impl.js +47 -34
  19. package/dist/src/ua_variable_type_impl.js.map +1 -1
  20. package/dist/src/ua_view_impl.js +1 -1
  21. package/dist/src/ua_view_impl.js.map +1 -1
  22. package/package.json +30 -30
  23. package/source/helpers/multiform_func.ts +76 -0
  24. package/src/address_space.ts +11 -8
  25. package/src/base_node_impl.ts +3 -1
  26. package/src/base_node_private.ts +276 -34
  27. package/src/ua_method_impl.ts +10 -2
  28. package/src/ua_object_impl.ts +10 -2
  29. package/src/ua_variable_impl.ts +153 -131
  30. package/src/ua_variable_type_impl.ts +79 -39
  31. package/src/ua_view_impl.ts +1 -1
  32. package/test_helpers/test_fixtures/fixture_simple_statemachine_nodeset2.xml +9 -0
  33. package/test_helpers/test_fixtures/fixuture_nodeset_objects_with_some_methods.xml +9 -1
  34. package/test_helpers/test_fixtures/mini.Node.Set2.xml +8 -1
@@ -8,7 +8,19 @@
8
8
  // tslint:disable:max-line-length
9
9
  import * as chalk from "chalk";
10
10
 
11
- import { ContinuationData, GetFunc, SetFunc } from "node-opcua-address-space-base";
11
+ import {
12
+ CloneExtraInfo,
13
+ ContinuationData,
14
+ defaultCloneExtraInfo,
15
+ defaultCloneFilter,
16
+ GetFunc,
17
+ SetFunc,
18
+ VariableDataValueGetterCallback,
19
+ VariableDataValueGetterPromise,
20
+ VariableDataValueGetterSync,
21
+ VariableDataValueSetterWithCallback,
22
+ VariableDataValueSetterWithPromise
23
+ } from "node-opcua-address-space-base";
12
24
  import { assert } from "node-opcua-assert";
13
25
  import {
14
26
  isValidDataEncoding,
@@ -56,7 +68,6 @@ import {
56
68
  IAddressSpace,
57
69
  BindVariableOptions,
58
70
  ContinuationPoint,
59
- DataValueCallback,
60
71
  IVariableHistorian,
61
72
  TimestampGetFunc,
62
73
  TimestampSetFunc,
@@ -65,7 +76,6 @@ import {
65
76
  UAVariableType,
66
77
  CloneOptions,
67
78
  CloneFilter,
68
- CloneExtraInfo,
69
79
  ISessionContext,
70
80
  BaseNode,
71
81
  UAVariableT
@@ -73,6 +83,7 @@ import {
73
83
  import { UAHistoricalDataConfiguration } from "node-opcua-nodeset-ua";
74
84
 
75
85
  import { SessionContext } from "../source/session_context";
86
+ import { convertToCallbackFunction1 } from "../source/helpers/multiform_func";
76
87
  import { BaseNodeImpl, InternalBaseNodeOptions } from "./base_node_impl";
77
88
  import { _clone, ToStringBuilder, UAVariable_toString, valueRankToString } from "./base_node_private";
78
89
  import { EnumerationInfo, IEnumItem, UADataTypeImpl } from "./ua_data_type_impl";
@@ -225,6 +236,10 @@ function validateDataType(
225
236
  return dest_isSuperTypeOf_variant;
226
237
  }
227
238
 
239
+ function default_func(this: UAVariable, dataValue1: DataValue, callback1: CallbackT<StatusCode>) {
240
+ return _default_writable_timestamped_set_func.call(this, dataValue1, callback1);
241
+ }
242
+
228
243
  interface UAVariableOptions extends InternalBaseNodeOptions {
229
244
  value?: any;
230
245
  dataType: NodeId | string;
@@ -236,19 +251,6 @@ interface UAVariableOptions extends InternalBaseNodeOptions {
236
251
  historizing?: number;
237
252
  }
238
253
 
239
- type TimestampGetFunction1 = () => DataValue | Promise<DataValue>;
240
- type TimestampGetFunction2 = (callback: (err: Error | null, dataValue?: DataValue) => void) => void;
241
- type TimestampGetFunction = TimestampGetFunction1 | TimestampGetFunction2;
242
-
243
- type TimestampSetFunction1 = (this: UAVariable, dataValue: DataValue, indexRange: NumericRange) => void | Promise<void>;
244
- type TimestampSetFunction2 = (
245
- this: UAVariable,
246
- dataValue: DataValue,
247
- indexRange: NumericRange,
248
- callback: (err: Error | null, StatusCode: StatusCode) => void
249
- ) => void;
250
- type TimestampSetFunction = TimestampSetFunction1 | TimestampSetFunction2;
251
-
252
254
  /**
253
255
  * A OPCUA Variable Node
254
256
  *
@@ -298,11 +300,11 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
298
300
  public semantic_version: number;
299
301
  public arrayDimensions: null | number[];
300
302
 
301
- public _timestamped_get_func?: TimestampGetFunction | null;
302
- public _timestamped_set_func?: TimestampSetFunction | null;
303
+ public _timestamped_get_func?: TimestampGetFunc | null;
304
+ public _timestamped_set_func?: VariableDataValueSetterWithCallback | null;
303
305
  public _get_func: any;
304
306
  public _set_func: any;
305
- public refreshFunc?: (callback: DataValueCallback) => void;
307
+ public refreshFunc?: (callback: CallbackT<DataValue>) => void;
306
308
  public __waiting_callbacks?: any[];
307
309
 
308
310
  get typeDefinitionObj(): UAVariableType {
@@ -431,8 +433,13 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
431
433
 
432
434
  if (this._timestamped_get_func) {
433
435
  if (this._timestamped_get_func.length === 0) {
434
- this.$dataValue = (this._timestamped_get_func as TimestampGetFunction1)() as DataValue;
435
- this.verifyVariantCompatibility(this.$dataValue.value);
436
+ const dataValueOrPromise = (this._timestamped_get_func as VariableDataValueGetterSync)();
437
+ if (!Object.prototype.hasOwnProperty.call(dataValueOrPromise, "then")) {
438
+ this.$dataValue = dataValueOrPromise as DataValue;
439
+ this.verifyVariantCompatibility(this.$dataValue.value);
440
+ } else {
441
+ errorLog("Unsupported: _timestamped_get_func returns a Promise !");
442
+ }
436
443
  }
437
444
  }
438
445
 
@@ -483,14 +490,14 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
483
490
  return dataTypeNode._getEnumerationInfo();
484
491
  }
485
492
 
486
- public asyncRefresh(oldestDate: Date, callback: DataValueCallback): void;
493
+ public asyncRefresh(oldestDate: Date, callback: CallbackT<DataValue>): void;
487
494
  public asyncRefresh(oldestDate: Date): Promise<DataValue>;
488
495
  public asyncRefresh(...args: any[]): any {
489
496
  this.verifyVariantCompatibility(this.$dataValue.value);
490
497
 
491
498
  const oldestDate = args[0] as Date;
492
499
  assert(oldestDate instanceof Date);
493
- const callback = args[1] as DataValueCallback;
500
+ const callback = args[1] as CallbackT<DataValue>;
494
501
 
495
502
  if (!this.refreshFunc) {
496
503
  // no refresh func
@@ -511,7 +518,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
511
518
  dataValue.serverPicoseconds = 0;
512
519
  return callback(null, dataValue);
513
520
  }
514
-
521
+
515
522
  try {
516
523
  this.refreshFunc.call(this, (err: Error | null, dataValue?: DataValueLike) => {
517
524
  if (err || !dataValue) {
@@ -646,20 +653,35 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
646
653
  // istanbul ignore next
647
654
  if (Object.prototype.hasOwnProperty.call(variant, "value")) {
648
655
  if (variant.dataType === null || variant.dataType === undefined) {
649
- throw new Error("Variant must provide a valid dataType" + variant.toString());
656
+ throw new Error(
657
+ "Variant must provide a valid dataType : variant = " +
658
+ variant.toString() +
659
+ " this.dataType= " +
660
+ this.dataType.toString()
661
+ );
650
662
  }
651
663
  if (
652
664
  variant.dataType === DataType.Boolean &&
653
665
  (this.dataType.namespace !== 0 || this.dataType.value !== DataType.Boolean)
654
666
  ) {
655
- throw new Error("Variant must provide a valid Boolean" + variant.toString());
667
+ throw new Error(
668
+ "Variant must provide a valid Boolean : variant = " +
669
+ variant.toString() +
670
+ " this.dataType= " +
671
+ this.dataType.toString()
672
+ );
656
673
  }
657
674
  if (
658
675
  this.dataType.namespace === 0 &&
659
676
  this.dataType.value === DataType.LocalizedText &&
660
677
  variant.dataType !== DataType.LocalizedText
661
678
  ) {
662
- throw new Error("Variant must provide a valid LocalizedText" + variant.toString());
679
+ throw new Error(
680
+ "Variant must provide a valid LocalizedText : variant = " +
681
+ variant.toString() +
682
+ " this.dataType= " +
683
+ this.dataType.toString()
684
+ );
663
685
  }
664
686
  }
665
687
  const basicType = this.getBasicDataType();
@@ -689,7 +711,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
689
711
  throw new Error(message);
690
712
  }
691
713
  } catch (err) {
692
- errorLog("UAVariable ", (err as Error)?.message, this.browseName.toString(), this.nodeId.toString());
714
+ errorLog("UAVariable ", (err as Error)?.message, this.browseName.toString(), " nodeId=", this.nodeId.toString());
693
715
  errorLog((err as Error).message);
694
716
  errorLog((err as Error).stack);
695
717
  throw err;
@@ -723,6 +745,8 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
723
745
  this._internal_set_dataValue(dataValue);
724
746
  } catch (err) {
725
747
  errorLog("UAVariable#setValueFromString Error : ", this.browseName.toString(), this.nodeId.toString());
748
+ errorLog((err as Error).message);
749
+ errorLog(this.parent?.toString());
726
750
  throw err;
727
751
  }
728
752
  }
@@ -795,16 +819,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
795
819
  return callback!(null, statusCode);
796
820
  }
797
821
 
798
- function default_func(
799
- this: UAVariable,
800
- dataValue1: DataValue,
801
- indexRange1: NumericRange,
802
- callback1: (err: Error | null, statusCode: StatusCode, dataValue?: DataValue | null | undefined) => void
803
- ) {
804
- // xx assert(!indexRange,"indexRange Not Implemented");
805
- return _default_writable_timestamped_set_func.call(this, dataValue1, callback1);
806
- }
807
- const write_func = (this._timestamped_set_func || default_func) as any;
822
+ const write_func = this._timestamped_set_func || default_func;
808
823
 
809
824
  if (!write_func) {
810
825
  warningLog(" warning " + this.nodeId.toString() + " " + this.browseName.toString() + " has no setter. \n");
@@ -813,78 +828,70 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
813
828
  }
814
829
  assert(write_func);
815
830
 
816
- write_func.call(
817
- this,
818
- dataValue,
819
- indexRange,
820
- (err: Error | null, statusCode1?: StatusCode, correctedDataValue?: DataValue) => {
821
- if (!err) {
822
- correctedDataValue = correctedDataValue || dataValue;
823
- assert(correctedDataValue instanceof DataValue);
824
- correctedDataValue && this.verifyVariantCompatibility(correctedDataValue.value);
825
- // xx assert(correctedDataValue.serverTimestamp);
826
-
827
- if (indexRange && !indexRange.isEmpty()) {
828
- if (!indexRange.isValid()) {
829
- return callback!(null, StatusCodes.BadIndexRangeInvalid);
831
+ write_func.call(this, dataValue, (err?: Error | null, statusCode1?: StatusCode) => {
832
+ if (!err) {
833
+ dataValue && this.verifyVariantCompatibility(dataValue.value);
834
+
835
+ if (indexRange && !indexRange.isEmpty()) {
836
+ if (!indexRange.isValid()) {
837
+ return callback!(null, StatusCodes.BadIndexRangeInvalid);
838
+ }
839
+
840
+ const newArrayOrMatrix = dataValue.value.value;
841
+
842
+ if (dataValue.value.arrayType === VariantArrayType.Array) {
843
+ if (this.$dataValue.value.arrayType !== VariantArrayType.Array) {
844
+ return callback(null, StatusCodes.BadTypeMismatch);
830
845
  }
846
+ // check that destination data is also an array
847
+ assert(check_valid_array(this.$dataValue.value.dataType, this.$dataValue.value.value));
848
+ const destArr = this.$dataValue.value.value;
849
+ const result = indexRange.set_values(destArr, newArrayOrMatrix);
831
850
 
832
- const newArrayOrMatrix = correctedDataValue.value.value;
833
-
834
- if (correctedDataValue.value.arrayType === VariantArrayType.Array) {
835
- if (this.$dataValue.value.arrayType !== VariantArrayType.Array) {
836
- return callback(null, StatusCodes.BadTypeMismatch);
837
- }
838
- // check that destination data is also an array
839
- assert(check_valid_array(this.$dataValue.value.dataType, this.$dataValue.value.value));
840
- const destArr = this.$dataValue.value.value;
841
- const result = indexRange.set_values(destArr, newArrayOrMatrix);
842
-
843
- if (result.statusCode.isNot(StatusCodes.Good)) {
844
- return callback!(null, result.statusCode);
845
- }
846
- correctedDataValue.value.value = result.array;
847
-
848
- // scrap original array so we detect range
849
- this.$dataValue.value.value = null;
850
- } else if (correctedDataValue.value.arrayType === VariantArrayType.Matrix) {
851
- const dimensions = this.$dataValue.value.dimensions;
852
- if (this.$dataValue.value.arrayType !== VariantArrayType.Matrix || !dimensions) {
853
- // not a matrix !
854
- return callback!(null, StatusCodes.BadTypeMismatch);
855
- }
856
- const matrix = this.$dataValue.value.value;
857
- const result = indexRange.set_values_matrix(
858
- {
859
- matrix,
860
- dimensions
861
- },
862
- newArrayOrMatrix
863
- );
864
- if (result.statusCode.isNot(StatusCodes.Good)) {
865
- return callback!(null, result.statusCode);
866
- }
867
- correctedDataValue.value.dimensions = this.$dataValue.value.dimensions;
868
- correctedDataValue.value.value = result.matrix;
869
-
870
- // scrap original array so we detect range
871
- this.$dataValue.value.value = null;
872
- } else {
851
+ if (result.statusCode.isNot(StatusCodes.Good)) {
852
+ return callback!(null, result.statusCode);
853
+ }
854
+ dataValue.value.value = result.array;
855
+
856
+ // scrap original array so we detect range
857
+ this.$dataValue.value.value = null;
858
+ } else if (dataValue.value.arrayType === VariantArrayType.Matrix) {
859
+ const dimensions = this.$dataValue.value.dimensions;
860
+ if (this.$dataValue.value.arrayType !== VariantArrayType.Matrix || !dimensions) {
861
+ // not a matrix !
873
862
  return callback!(null, StatusCodes.BadTypeMismatch);
874
863
  }
875
- }
876
- try {
877
- this._internal_set_dataValue(correctedDataValue, indexRange);
878
- } catch (err) {
879
- if (err instanceof Error) {
880
- warningLog(err.message);
864
+ const matrix = this.$dataValue.value.value;
865
+ const result = indexRange.set_values_matrix(
866
+ {
867
+ matrix,
868
+ dimensions
869
+ },
870
+ newArrayOrMatrix
871
+ );
872
+ if (result.statusCode.isNot(StatusCodes.Good)) {
873
+ return callback!(null, result.statusCode);
881
874
  }
882
- return callback!(null, StatusCodes.BadInternalError);
875
+ dataValue.value.dimensions = this.$dataValue.value.dimensions;
876
+ dataValue.value.value = result.matrix;
877
+
878
+ // scrap original array so we detect range
879
+ this.$dataValue.value.value = null;
880
+ } else {
881
+ return callback!(null, StatusCodes.BadTypeMismatch);
883
882
  }
884
883
  }
885
- callback!(err, statusCode1);
884
+ try {
885
+ this._internal_set_dataValue(dataValue, indexRange);
886
+ } catch (err) {
887
+ if (err instanceof Error) {
888
+ warningLog(err.message);
889
+ }
890
+ return callback!(null, StatusCodes.BadInternalError);
891
+ }
886
892
  }
887
- );
893
+ callback!(err || null, statusCode1);
894
+ });
888
895
  }
889
896
 
890
897
  public writeAttribute(context: ISessionContext | null, writeValue: WriteValueOptions, callback: StatusCodeCallback): void;
@@ -952,7 +959,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
952
959
  }
953
960
  try {
954
961
  this.verifyVariantCompatibility(value);
955
- } catch(err) {
962
+ } catch (err) {
956
963
  return StatusCodes.BadTypeMismatch;
957
964
  }
958
965
  return StatusCodes.Good;
@@ -1122,6 +1129,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
1122
1129
 
1123
1130
  assert(typeof this._timestamped_set_func !== "function", "UAVariable already bound");
1124
1131
  assert(typeof this._timestamped_get_func !== "function", "UAVariable already bound");
1132
+
1125
1133
  bind_getter.call(this, options);
1126
1134
  bind_setter.call(this, options);
1127
1135
 
@@ -1133,9 +1141,9 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
1133
1141
  this._historyRead = _historyRead;
1134
1142
  assert(this._historyRead.length === 6);
1135
1143
  }
1136
-
1144
+ // post conditions
1137
1145
  assert(typeof this._timestamped_set_func === "function");
1138
- assert(this._timestamped_set_func!.length === 3);
1146
+ assert(this._timestamped_set_func!.length === 2, "expecting 2 parameters");
1139
1147
  }
1140
1148
 
1141
1149
  /**
@@ -1226,7 +1234,13 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
1226
1234
  valueRank: this.valueRank
1227
1235
  };
1228
1236
 
1229
- const newVariable = _clone.call(this, UAVariableImpl, options, optionalFilter, extraInfo) as UAVariableImpl;
1237
+ const newVariable = _clone.call(
1238
+ this,
1239
+ UAVariableImpl,
1240
+ options,
1241
+ optionalFilter || defaultCloneFilter,
1242
+ extraInfo || defaultCloneExtraInfo
1243
+ ) as UAVariableImpl;
1230
1244
 
1231
1245
  newVariable.bindVariable();
1232
1246
 
@@ -1361,7 +1375,6 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
1361
1375
  }
1362
1376
 
1363
1377
  const bindProperty = (propertyNode: UAVariableImpl, name: string, extensionObject: ExtensionObject, dataType: DataType) => {
1364
-
1365
1378
  // eslint-disable-next-line @typescript-eslint/no-this-alias
1366
1379
  const self = this;
1367
1380
  propertyNode.bindVariable(
@@ -1379,7 +1392,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
1379
1392
  propertyNode.$dataValue.statusCode = StatusCodes.Good;
1380
1393
  propertyNode.$dataValue.value.dataType = dataType;
1381
1394
  propertyNode.$dataValue.value.value = value;
1382
- return new DataValue(propertyNode.$dataValue);
1395
+ return new DataValue(propertyNode.$dataValue);
1383
1396
  },
1384
1397
  timestamped_set: (dataValue: DataValue, callback: CallbackT<StatusCode>) => {
1385
1398
  dataValue;
@@ -1482,7 +1495,6 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
1482
1495
  };
1483
1496
 
1484
1497
  for (const field of definition.fields || []) {
1485
-
1486
1498
  if (NodeId.sameNodeId(NodeId.nullNodeId, field.dataType)) {
1487
1499
  warningLog("field.dataType is null ! ", field.toString(), NodeId.nullNodeId.toString());
1488
1500
  warningLog(" dataType replaced with BaseDataType ");
@@ -2019,7 +2031,6 @@ function _default_writable_timestamped_set_func(
2019
2031
  dataValue: DataValue,
2020
2032
  callback: (err: Error | null, statusCode: StatusCode, dataValue?: DataValue | null) => void
2021
2033
  ) {
2022
- /* jshint validthis: true */
2023
2034
  assert(dataValue instanceof DataValue);
2024
2035
  callback(null, StatusCodes.Good, dataValue);
2025
2036
  }
@@ -2073,7 +2084,13 @@ function _Variable_bind_with_async_refresh(this: UAVariableImpl, options: any) {
2073
2084
  }
2074
2085
 
2075
2086
  // variation 2
2076
- function _Variable_bind_with_timestamped_get(this: UAVariableImpl, options: any) {
2087
+ function _Variable_bind_with_timestamped_get(
2088
+ this: UAVariableImpl,
2089
+ options: {
2090
+ get: undefined;
2091
+ timestamped_get: TimestampGetFunc;
2092
+ }
2093
+ ) {
2077
2094
  /* jshint validthis: true */
2078
2095
  assert(this instanceof UAVariableImpl);
2079
2096
  assert(typeof options.timestamped_get === "function");
@@ -2081,20 +2098,20 @@ function _Variable_bind_with_timestamped_get(this: UAVariableImpl, options: any)
2081
2098
  assert(!this._timestamped_get_func);
2082
2099
 
2083
2100
  const async_refresh_func = (callback: (err: Error | null, dataValue?: DataValue) => void) => {
2084
- Promise.resolve((this._timestamped_get_func! as TimestampGetFunction1).call(this))
2101
+ Promise.resolve((this._timestamped_get_func! as VariableDataValueGetterSync).call(this))
2085
2102
  .then((dataValue) => callback(null, dataValue))
2086
2103
  .catch((err) => {
2087
2104
  errorLog("asyncRefresh error: Variable is ", this.nodeId.toString(), this.browseName.toString());
2088
2105
  callback(err as Error);
2089
2106
  });
2090
2107
  };
2091
-
2108
+ const pThis = this as UAVariable;
2092
2109
  if (options.timestamped_get.length === 0) {
2093
- const timestamped_get = options.timestamped_get as TimestampGetFunction1;
2110
+ const timestamped_get = options.timestamped_get as (this: UAVariable) => DataValue | Promise<DataValue>;
2094
2111
  // sync version | Promise version
2095
2112
  this._timestamped_get_func = timestamped_get;
2096
2113
 
2097
- const dataValue_verify = timestamped_get!.call(this);
2114
+ const dataValue_verify = timestamped_get.call(pThis);
2098
2115
  // dataValue_verify should be a DataValue or a Promise
2099
2116
  /* istanbul ignore next */
2100
2117
  if (!(dataValue_verify instanceof DataValue) && typeof dataValue_verify.then !== "function") {
@@ -2147,12 +2164,13 @@ function _Variable_bind_with_simple_get(this: UAVariableImpl, options: GetterOpt
2147
2164
  } else {
2148
2165
  if (!this.$dataValue || !isGoodish(this.$dataValue.statusCode) || !sameVariant(this.$dataValue.value, value)) {
2149
2166
  this.setValueFromSource(value, StatusCodes.Good);
2150
- }
2167
+ }
2151
2168
  return this.$dataValue;
2152
2169
  }
2153
2170
  };
2154
2171
 
2155
2172
  _Variable_bind_with_timestamped_get.call(this, {
2173
+ get: undefined,
2156
2174
  timestamped_get: timestamped_get_func_from__Variable_bind_with_simple_get
2157
2175
  });
2158
2176
  }
@@ -2170,12 +2188,10 @@ function _Variable_bind_with_simple_set(this: UAVariableImpl, options: any) {
2170
2188
 
2171
2189
  this._timestamped_set_func = (
2172
2190
  timestamped_value: DataValue,
2173
- indexRange: NumericRange,
2174
2191
  callback: (err: Error | null, statusCode: StatusCode, dataValue: DataValue) => void
2175
2192
  ) => {
2176
2193
  assert(timestamped_value instanceof DataValue);
2177
2194
  this._set_func(timestamped_value.value, (err: Error | null, statusCode: StatusCode) => {
2178
-
2179
2195
  // istanbul ignore next
2180
2196
  if (!err && !statusCode) {
2181
2197
  errorLog(
@@ -2189,22 +2205,20 @@ function _Variable_bind_with_simple_set(this: UAVariableImpl, options: any) {
2189
2205
  };
2190
2206
  }
2191
2207
 
2192
- function _Variable_bind_with_timestamped_set(this: UAVariableImpl, options: any) {
2193
- assert(this instanceof UAVariableImpl);
2208
+ function _Variable_bind_with_timestamped_set(
2209
+ this: UAVariableImpl,
2210
+ options: {
2211
+ timestamped_set: TimestampSetFunc;
2212
+ set: undefined;
2213
+ }
2214
+ ) {
2194
2215
  assert(typeof options.timestamped_set === "function");
2195
2216
  assert(
2196
2217
  options.timestamped_set.length === 2,
2197
2218
  "timestamped_set must have 2 parameters timestamped_set: function(dataValue,callback){}"
2198
2219
  );
2199
2220
  assert(!options.set, "should not specify set when timestamped_set_func exists ");
2200
- this._timestamped_set_func = (
2201
- dataValue: DataValue,
2202
- indexRange: NumericRange,
2203
- callback: (err: Error | null, statusCode: StatusCode, dataValue: DataValue) => void
2204
- ) => {
2205
- // xx assert(!indexRange,"indexRange Not Implemented");
2206
- return options.timestamped_set.call(this, dataValue, callback);
2207
- };
2221
+ this._timestamped_set_func = convertToCallbackFunction1<StatusCode, DataValue, UAVariable>(options.timestamped_set);
2208
2222
  }
2209
2223
 
2210
2224
  interface SetterOptions {
@@ -2219,15 +2233,20 @@ function bind_setter(this: UAVariableImpl, options: SetterOptions) {
2219
2233
  } else if (typeof options.timestamped_set === "function") {
2220
2234
  // variation 2
2221
2235
  assert(typeof options.timestamped_get === "function", "timestamped_set must be used with timestamped_get ");
2222
- _Variable_bind_with_timestamped_set.call(this, options);
2236
+ _Variable_bind_with_timestamped_set.call(this, {
2237
+ set: undefined,
2238
+ timestamped_set: options.timestamped_set
2239
+ });
2223
2240
  } else if (typeof options.timestamped_get === "function") {
2224
2241
  // timestamped_get is specified but timestamped_set is not
2225
2242
  // => Value is read-only
2226
2243
  _Variable_bind_with_timestamped_set.call(this, {
2244
+ set: undefined,
2227
2245
  timestamped_set: _not_writable_timestamped_set_func
2228
2246
  });
2229
2247
  } else {
2230
2248
  _Variable_bind_with_timestamped_set.call(this, {
2249
+ set: undefined,
2231
2250
  timestamped_set: _default_writable_timestamped_set_func
2232
2251
  });
2233
2252
  }
@@ -2236,7 +2255,7 @@ function bind_setter(this: UAVariableImpl, options: SetterOptions) {
2236
2255
  interface GetterOptions {
2237
2256
  get?: GetFunc;
2238
2257
  timestamped_get?: TimestampGetFunc;
2239
- refreshFunc?: any;
2258
+ refreshFunc?: (callback: CallbackT<DataValue>) => void;
2240
2259
  dataType?: DataType | string;
2241
2260
  value?: any;
2242
2261
  }
@@ -2246,7 +2265,10 @@ function bind_getter(this: UAVariableImpl, options: GetterOptions) {
2246
2265
  _Variable_bind_with_simple_get.call(this, options);
2247
2266
  } else if (typeof options.timestamped_get === "function") {
2248
2267
  // variation 2
2249
- _Variable_bind_with_timestamped_get.call(this, options);
2268
+ _Variable_bind_with_timestamped_get.call(this, {
2269
+ get: undefined,
2270
+ timestamped_get: options.timestamped_get
2271
+ });
2250
2272
  } else if (typeof options.refreshFunc === "function") {
2251
2273
  // variation 3
2252
2274
  _Variable_bind_with_async_refresh.call(this, options);