node-opcua-address-space 2.117.0 → 2.119.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 (171) hide show
  1. package/dist/source/continuation_points/continuation_point_manager.js.map +1 -1
  2. package/dist/source/helpers/adjust_browse_direction.js.map +1 -1
  3. package/dist/source/helpers/argument_list.js.map +1 -1
  4. package/dist/source/helpers/call_helpers.js.map +1 -1
  5. package/dist/source/helpers/coerce_enum_value.js +1 -1
  6. package/dist/source/helpers/coerce_enum_value.js.map +1 -1
  7. package/dist/source/helpers/dump_tools.js.map +1 -1
  8. package/dist/source/helpers/ensure_secure_access.js.map +1 -1
  9. package/dist/source/helpers/make_optionals_map.js.map +1 -1
  10. package/dist/source/helpers/multiform_func.js.map +1 -1
  11. package/dist/source/helpers/resolve_opaque_on_address_space.js.map +1 -1
  12. package/dist/source/index.d.ts +1 -0
  13. package/dist/source/index.js +5 -2
  14. package/dist/source/index.js.map +1 -1
  15. package/dist/source/interfaces/alarms_and_conditions/condition_info_i.d.ts +2 -0
  16. package/dist/source/interfaces/alarms_and_conditions/condition_snapshot.d.ts +14 -6
  17. package/dist/source/interfaces/alarms_and_conditions/ua_condition_ex.d.ts +3 -2
  18. package/dist/source/interfaces/data_access/ua_multistate_discrete_ex.d.ts +26 -3
  19. package/dist/source/interfaces/data_access/ua_multistate_value_discrete_ex.d.ts +2 -1
  20. package/dist/source/interfaces/data_access/ua_two_state_discrete_ex.d.ts +2 -1
  21. package/dist/source/interfaces/i_condition_variable_type_setter_options.d.ts +3 -0
  22. package/dist/source/interfaces/i_condition_variable_type_setter_options.js +3 -0
  23. package/dist/source/interfaces/i_condition_variable_type_setter_options.js.map +1 -0
  24. package/dist/source/interfaces/i_set_state_options.d.ts +4 -0
  25. package/dist/source/interfaces/i_set_state_options.js +3 -0
  26. package/dist/source/interfaces/i_set_state_options.js.map +1 -0
  27. package/dist/source/loader/decode_xml_extension_object.js.map +1 -1
  28. package/dist/source/loader/ensure_datatype_extracted.js.map +1 -1
  29. package/dist/source/loader/generateAddressSpaceRaw.js.map +1 -1
  30. package/dist/source/loader/load_nodeset2.js.map +1 -1
  31. package/dist/source/loader/make_semver_compatible.js.map +1 -1
  32. package/dist/source/loader/make_xml_extension_object_parser.js.map +1 -1
  33. package/dist/source/loader/namespace_post_step.js.map +1 -1
  34. package/dist/source/pseudo_session.js +12 -26
  35. package/dist/source/pseudo_session.js.map +1 -1
  36. package/dist/source/session_context.js.map +1 -1
  37. package/dist/source/set_namespace_meta_data.js.map +1 -1
  38. package/dist/source/ua_two_state_variable_ex.d.ts +2 -1
  39. package/dist/src/_instantiate_helpers.js.map +1 -1
  40. package/dist/src/_mandatory_child_or_requested_optional_filter.js.map +1 -1
  41. package/dist/src/address_space.js +4 -27
  42. package/dist/src/address_space.js.map +1 -1
  43. package/dist/src/address_space_change_event_tools.js.map +1 -1
  44. package/dist/src/alarms_and_conditions/condition.d.ts +2 -1
  45. package/dist/src/alarms_and_conditions/condition.js +2 -2
  46. package/dist/src/alarms_and_conditions/condition.js.map +1 -1
  47. package/dist/src/alarms_and_conditions/condition_info_impl.js.map +1 -1
  48. package/dist/src/alarms_and_conditions/condition_snapshot_impl.d.ts +20 -11
  49. package/dist/src/alarms_and_conditions/condition_snapshot_impl.js +72 -33
  50. package/dist/src/alarms_and_conditions/condition_snapshot_impl.js.map +1 -1
  51. package/dist/src/alarms_and_conditions/deviation_alarm_helper.js.map +1 -1
  52. package/dist/src/alarms_and_conditions/ua_acknowledgeable_condition_impl.js.map +1 -1
  53. package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js +1 -1
  54. package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js.map +1 -1
  55. package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.js.map +1 -1
  56. package/dist/src/alarms_and_conditions/ua_condition_impl.d.ts +3 -2
  57. package/dist/src/alarms_and_conditions/ua_condition_impl.js +13 -26
  58. package/dist/src/alarms_and_conditions/ua_condition_impl.js.map +1 -1
  59. package/dist/src/alarms_and_conditions/ua_discrete_alarm_impl.js.map +1 -1
  60. package/dist/src/alarms_and_conditions/ua_exclusive_deviation_alarm_impl.js.map +1 -1
  61. package/dist/src/alarms_and_conditions/ua_exclusive_limit_alarm_impl.js.map +1 -1
  62. package/dist/src/alarms_and_conditions/ua_limit_alarm_impl.js.map +1 -1
  63. package/dist/src/alarms_and_conditions/ua_non_exclusive_deviation_alarm_impl.js.map +1 -1
  64. package/dist/src/alarms_and_conditions/ua_non_exclusive_limit_alarm_impl.js.map +1 -1
  65. package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js +2 -25
  66. package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js.map +1 -1
  67. package/dist/src/apply_condition_refresh.js.map +1 -1
  68. package/dist/src/base_node_impl.js +3 -26
  69. package/dist/src/base_node_impl.js.map +1 -1
  70. package/dist/src/base_node_private.js.map +1 -1
  71. package/dist/src/check_value_rank_compatibility.js.map +1 -1
  72. package/dist/src/data_access/add_dataItem_stuff.js.map +1 -1
  73. package/dist/src/data_access/adjust_datavalue_status_code.js.map +1 -1
  74. package/dist/src/data_access/ua_multistate_discrete_impl.d.ts +3 -2
  75. package/dist/src/data_access/ua_multistate_discrete_impl.js +4 -4
  76. package/dist/src/data_access/ua_multistate_discrete_impl.js.map +1 -1
  77. package/dist/src/data_access/ua_multistate_value_discrete_impl.d.ts +8 -5
  78. package/dist/src/data_access/ua_multistate_value_discrete_impl.js +91 -50
  79. package/dist/src/data_access/ua_multistate_value_discrete_impl.js.map +1 -1
  80. package/dist/src/data_access/ua_two_state_discrete_impl.d.ts +2 -1
  81. package/dist/src/data_access/ua_two_state_discrete_impl.js +3 -3
  82. package/dist/src/data_access/ua_two_state_discrete_impl.js.map +1 -1
  83. package/dist/src/event_data.js.map +1 -1
  84. package/dist/src/extension_object_array_node.js.map +1 -1
  85. package/dist/src/get_basic_datatype.d.ts +4 -1
  86. package/dist/src/get_basic_datatype.js +12 -7
  87. package/dist/src/get_basic_datatype.js.map +1 -1
  88. package/dist/src/historical_access/address_space_historical_data_node.js.map +1 -1
  89. package/dist/src/idx_iterator.js.map +1 -1
  90. package/dist/src/namespace_impl.js +3 -26
  91. package/dist/src/namespace_impl.js.map +1 -1
  92. package/dist/src/namespace_private.js.map +1 -1
  93. package/dist/src/nodeid_manager.js.map +1 -1
  94. package/dist/src/nodeset_tools/adjust_namespace_array.js.map +1 -1
  95. package/dist/src/nodeset_tools/construct_namespace_dependency.js.map +1 -1
  96. package/dist/src/nodeset_tools/dump_to_bsd.js.map +1 -1
  97. package/dist/src/nodeset_tools/nodeset_to_xml.js +3 -26
  98. package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
  99. package/dist/src/reference_impl.js +2 -25
  100. package/dist/src/reference_impl.js.map +1 -1
  101. package/dist/src/state_machine/finite_state_machine.js +2 -2
  102. package/dist/src/state_machine/finite_state_machine.js.map +1 -1
  103. package/dist/src/state_machine/ua_shelving_state_machine_ex.js +1 -1
  104. package/dist/src/state_machine/ua_shelving_state_machine_ex.js.map +1 -1
  105. package/dist/src/state_machine/ua_two_state_variable.d.ts +2 -1
  106. package/dist/src/state_machine/ua_two_state_variable.js +10 -8
  107. package/dist/src/state_machine/ua_two_state_variable.js.map +1 -1
  108. package/dist/src/tool_isSubtypeOf.js.map +1 -1
  109. package/dist/src/ua_data_type_impl.d.ts +2 -3
  110. package/dist/src/ua_data_type_impl.js +6 -29
  111. package/dist/src/ua_data_type_impl.js.map +1 -1
  112. package/dist/src/ua_method_impl.js.map +1 -1
  113. package/dist/src/ua_object_impl.js.map +1 -1
  114. package/dist/src/ua_object_type_impl.d.ts +2 -3
  115. package/dist/src/ua_object_type_impl.js +4 -28
  116. package/dist/src/ua_object_type_impl.js.map +1 -1
  117. package/dist/src/ua_reference_type_impl.d.ts +2 -3
  118. package/dist/src/ua_reference_type_impl.js +6 -29
  119. package/dist/src/ua_reference_type_impl.js.map +1 -1
  120. package/dist/src/ua_variable_impl.js +3 -26
  121. package/dist/src/ua_variable_impl.js.map +1 -1
  122. package/dist/src/ua_variable_impl_ext_obj.js.map +1 -1
  123. package/dist/src/ua_variable_type_impl.d.ts +2 -3
  124. package/dist/src/ua_variable_type_impl.js +5 -28
  125. package/dist/src/ua_variable_type_impl.js.map +1 -1
  126. package/dist/src/ua_view_impl.js.map +1 -1
  127. package/dist/src/validate_data_type_correctness.js.map +1 -1
  128. package/dist/tsconfig_common.tsbuildinfo +1 -1
  129. package/distHelpers/alarms_and_conditions_demo.js +2 -2
  130. package/distHelpers/alarms_and_conditions_demo.js.map +1 -1
  131. package/distHelpers/assertHasMatchingReference.js.map +1 -1
  132. package/distHelpers/boiler_system.js.map +1 -1
  133. package/distHelpers/create_minimalist_address_space_nodeset.js.map +1 -1
  134. package/distHelpers/get_address_space_fixture.js +16 -36
  135. package/distHelpers/get_address_space_fixture.js.map +1 -1
  136. package/distHelpers/get_mini_address_space.js.map +1 -1
  137. package/distNodeJS/generate_address_space.js +5 -25
  138. package/distNodeJS/generate_address_space.js.map +1 -1
  139. package/package.json +33 -33
  140. package/source/helpers/coerce_enum_value.ts +2 -2
  141. package/source/index.ts +2 -0
  142. package/source/interfaces/alarms_and_conditions/condition_info_i.ts +4 -0
  143. package/source/interfaces/alarms_and_conditions/condition_snapshot.ts +13 -8
  144. package/source/interfaces/alarms_and_conditions/ua_condition_ex.ts +4 -2
  145. package/source/interfaces/data_access/ua_multistate_discrete_ex.ts +39 -3
  146. package/source/interfaces/data_access/ua_multistate_value_discrete_ex.ts +2 -1
  147. package/source/interfaces/data_access/ua_two_state_discrete_ex.ts +2 -1
  148. package/source/interfaces/i_condition_variable_type_setter_options.ts +5 -0
  149. package/source/interfaces/i_set_state_options.ts +4 -0
  150. package/source/pseudo_session.ts +8 -2
  151. package/source/ua_two_state_variable_ex.ts +2 -1
  152. package/source_nodejs/generate_address_space.ts +1 -1
  153. package/src/address_space.ts +2 -2
  154. package/src/alarms_and_conditions/condition.ts +4 -2
  155. package/src/alarms_and_conditions/condition_snapshot_impl.ts +75 -38
  156. package/src/alarms_and_conditions/ua_condition_impl.ts +14 -27
  157. package/src/alarms_and_conditions/ua_off_normal_alarm_impl.ts +2 -4
  158. package/src/base_node_impl.ts +2 -2
  159. package/src/data_access/ua_multistate_discrete_impl.ts +5 -3
  160. package/src/data_access/ua_multistate_value_discrete_impl.ts +109 -55
  161. package/src/data_access/ua_two_state_discrete_impl.ts +5 -3
  162. package/src/get_basic_datatype.ts +16 -7
  163. package/src/namespace_impl.ts +5 -7
  164. package/src/nodeset_tools/nodeset_to_xml.ts +3 -4
  165. package/src/reference_impl.ts +2 -2
  166. package/src/state_machine/ua_two_state_variable.ts +14 -8
  167. package/src/ua_data_type_impl.ts +14 -15
  168. package/src/ua_object_type_impl.ts +6 -6
  169. package/src/ua_reference_type_impl.ts +4 -4
  170. package/src/ua_variable_impl.ts +4 -6
  171. package/src/ua_variable_type_impl.ts +3 -3
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { assert } from "node-opcua-assert";
5
5
  import { DataType, Variant, VariantArrayType } from "node-opcua-variant";
6
- import { coerceInt32, coerceInt64toInt32, coerceUInt64, Int32, Int64, isValidUInt64 } from "node-opcua-basic-types";
6
+ import { coerceInt32, coerceInt64toInt32, coerceUInt64, coerceUInt64toInt32, Int32, Int64, isValidInt64, isValidUInt64 } from "node-opcua-basic-types";
7
7
  import { coerceLocalizedText, LocalizedText, QualifiedNameLike } from "node-opcua-data-model";
8
8
  import { DataValue, DataValueT } from "node-opcua-data-value";
9
9
  import { StatusCodes } from "node-opcua-status-code";
@@ -12,26 +12,68 @@ import { NumericRange } from "node-opcua-numeric-range";
12
12
  import { DTEnumValue } from "node-opcua-nodeset-ua";
13
13
  import { BindVariableOptions, INamespace, UAVariable, UAProperty, ISessionContext } from "node-opcua-address-space-base";
14
14
  import { VariableTypeIds } from "node-opcua-constants";
15
+ import { _getBasicDataType, _getBasicDataTypeFromDataTypeNodeId } from "../get_basic_datatype";
15
16
 
16
17
  import { registerNodePromoter } from "../../source/loader/register_node_promoter";
17
18
  import { coerceEnumValues } from "../../source/helpers/coerce_enum_value";
18
19
  import { UAMultiStateValueDiscreteEx } from "../../source/interfaces/data_access/ua_multistate_value_discrete_ex";
19
20
  import { AddMultiStateValueDiscreteOptions } from "../../source/address_space_ts";
21
+ import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";
20
22
  import { UAVariableImpl } from "../ua_variable_impl";
21
23
 
22
24
  import { add_dataItem_stuff } from "./add_dataItem_stuff";
23
25
 
24
- function install_synchronization<T, DT extends DataType>(variable: UAMultiStateValueDiscreteEx<T, DT>) {
26
+ function convertToArray<T>(array: any): T[] {
27
+ if (Array.isArray(array)) return array;
28
+ const result: T[] = [];
29
+ for (let i = 0; i < array.length; i++) {
30
+ result[i] = array[i];
31
+ }
32
+ return result;
33
+ }
34
+ const getCoerceToInt32 = (dataType: DataType) => {
35
+ switch (dataType) {
36
+ case DataType.UInt64:
37
+ return coerceUInt64toInt32;
38
+ case DataType.Int64:
39
+ return coerceInt64toInt32;
40
+ default:
41
+ return coerceInt32;
42
+ }
43
+ };
44
+
45
+ function install_synchronization<T extends number | Int64 | Int64, DT extends DataType>(
46
+ variable: UAMultiStateValueDiscreteEx<T, DT>
47
+ ) {
25
48
  const _variable = variable as UAMultiStateValueDiscreteEx<T, DT>;
26
- _variable.on("value_changed", (value: DataValue) => {
49
+ _variable.on("value_changed", (dataValue: DataValue) => {
27
50
  const valueAsTextNode = variable.valueAsText || (_variable.getComponentByName("ValueAsText") as UAVariable);
28
51
  if (!valueAsTextNode) {
29
52
  return;
30
53
  }
31
- const valueAsText1 = _variable.findValueAsText(value.value.value);
32
- valueAsTextNode.setValueFromSource(valueAsText1);
54
+ if (dataValue.value.arrayType === VariantArrayType.Array || dataValue.value.arrayType === VariantArrayType.Matrix) {
55
+ //
56
+ const coerce = getCoerceToInt32(_variable.getBasicDataType());
57
+
58
+ const values: number[] = convertToArray<Int32>(dataValue.value.value).map((a) => coerceInt32(a));
59
+ const variantArray: Variant[] = values.map((a) => _variable.findValueAsText(a));
60
+ const localizedText = variantArray.map((a) => a.value);
61
+
62
+ const valueAsText1 = new Variant({
63
+ arrayType: dataValue.value.arrayType,
64
+ dataType: DataType.LocalizedText,
65
+ value: localizedText,
66
+ dimensions: dataValue.value.dimensions
67
+ });
68
+ valueAsTextNode.setValueFromSource(valueAsText1);
69
+ } else {
70
+ const valueAsText1 = _variable.findValueAsText(dataValue.value.value);
71
+ valueAsTextNode.setValueFromSource(valueAsText1);
72
+ }
33
73
  });
34
- _variable.emit("value_changed", _variable.readValue());
74
+ const dataValue = _variable.readValue();
75
+ // detect value changes to update valueAsText (initial state)
76
+ _variable.emit("value_changed", dataValue);
35
77
  }
36
78
 
37
79
  export interface UAMultiStateValueDiscreteImpl<T, DT extends DataType> {
@@ -46,8 +88,11 @@ export interface UAMultiStateValueDiscreteImpl<T, DT extends DataType> {
46
88
 
47
89
  readValueAsync(context: ISessionContext | null, callback?: any): any;
48
90
  }
49
- export class UAMultiStateValueDiscreteImpl<T, DT extends DataType> extends UAVariableImpl implements UAMultiStateValueDiscreteEx<T, DT> {
50
- public setValue(value: string | number | Int64): void {
91
+ export class UAMultiStateValueDiscreteImpl<T, DT extends DataType>
92
+ extends UAVariableImpl
93
+ implements UAMultiStateValueDiscreteEx<T, DT>
94
+ {
95
+ public setValue(value: string | number | Int64, options?: ISetStateOptions): void {
51
96
  if (typeof value === "string") {
52
97
  const enumValues = this.enumValues.readValue().value.value;
53
98
  const selected = enumValues.filter((a: any) => a.displayName.text === value)[0];
@@ -57,16 +102,20 @@ export class UAMultiStateValueDiscreteImpl<T, DT extends DataType> extends UAVar
57
102
  throw new Error("cannot find enum string " + value + " in " + enumValues.toString());
58
103
  }
59
104
  } else {
60
- this._setValue(coerceUInt64(value));
105
+ this._setValue(coerceUInt64(value), options);
61
106
  }
62
107
  }
63
108
 
64
- public getValueAsString(): string {
65
- return this.valueAsText.readValue().value.value.text || "";
109
+ public getValueAsString(): any {
110
+ const v = this.valueAsText.readValue().value.value;
111
+ if (Array.isArray(v)) {
112
+ return v.map((a) => a.text);
113
+ }
114
+ return v.text || "";
66
115
  }
67
116
 
68
- public getValueAsNumber(): number {
69
- return this.readValue().value.value as unknown as number;
117
+ public getValueAsNumber(): any {
118
+ return this.readValue().value.value;
70
119
  }
71
120
 
72
121
  public checkVariantCompatibility(value: Variant): StatusCode {
@@ -89,7 +138,7 @@ export class UAMultiStateValueDiscreteImpl<T, DT extends DataType> extends UAVar
89
138
  public _isValueInRange(value: number): boolean {
90
139
  // MultiStateValueDiscreteType
91
140
  const enumValues = this.enumValues.readValue().value.value as DTEnumValue[];
92
- const e = enumValues.findIndex((x: DTEnumValue) => coerceInt32(x.value) === value);
141
+ const e = enumValues.findIndex((x: DTEnumValue) => coerceInt64toInt32(x.value) === value);
93
142
  return !(e === -1);
94
143
  }
95
144
  /**
@@ -114,18 +163,18 @@ export class UAMultiStateValueDiscreteImpl<T, DT extends DataType> extends UAVar
114
163
  *
115
164
  * @private
116
165
  */
117
- public _setValue(value: Int64): void {
166
+ public _setValue(value: Int64, options?: ISetStateOptions): void {
167
+ const int32Value = coerceInt64toInt32(value);
118
168
  // check that value is in bound
119
- if (!this._isValueInRange(coerceInt32(value))) {
169
+ if (!this._isValueInRange(int32Value)) {
120
170
  throw new Error("UAMultiStateValueDiscrete#_setValue out of range " + value);
121
171
  }
122
172
 
123
173
  const dataType = this._getDataType();
124
174
  if (dataType === DataType.Int64 || dataType === DataType.UInt64) {
125
- this.setValueFromSource({ dataType, value });
175
+ this.setValueFromSource({ dataType, arrayType: VariantArrayType.Scalar, value });
126
176
  } else {
127
- const valueN = value[1];
128
- this.setValueFromSource({ dataType, value: valueN });
177
+ this.setValueFromSource({ dataType, arrayType: VariantArrayType.Scalar, value: int32Value });
129
178
  }
130
179
  }
131
180
 
@@ -135,17 +184,14 @@ export class UAMultiStateValueDiscreteImpl<T, DT extends DataType> extends UAVar
135
184
  */
136
185
  public findValueAsText(value?: number | Int64): Variant {
137
186
  const enumValueIndex = this._enumValueIndex();
138
-
139
187
  if (value === undefined) {
140
188
  throw new Error("Unexpected undefined value");
141
189
  }
142
- if (value instanceof Array) {
143
- value = value[1];
144
- }
145
- assert(!((value as any) instanceof Variant));
190
+ const valueAsInt32 = coerceInt64toInt32(value);
191
+
146
192
  let valueAsText1 = "Invalid";
147
- if (enumValueIndex[value]) {
148
- valueAsText1 = enumValueIndex[value].displayName.text || `Invalid:${value}`;
193
+ if (enumValueIndex[valueAsInt32] !== undefined) {
194
+ valueAsText1 = enumValueIndex[valueAsInt32].displayName.text || `Invalid:${value}`;
149
195
  }
150
196
  const result = new Variant({
151
197
  dataType: DataType.LocalizedText,
@@ -153,6 +199,7 @@ export class UAMultiStateValueDiscreteImpl<T, DT extends DataType> extends UAVar
153
199
  });
154
200
  return result;
155
201
  }
202
+
156
203
  public _getDataType(): DataType {
157
204
  if (this.dataType.value === 26 /* Number */) {
158
205
  return DataType.UInt32;
@@ -170,7 +217,7 @@ export class UAMultiStateValueDiscreteImpl<T, DT extends DataType> extends UAVar
170
217
  // this includes signed and unsigned integers from 8 to 64 Bit length.
171
218
 
172
219
  // istanbul ignore next
173
- validateDataType(this.dataType.value);
220
+ validateIsNumericDataType(this.dataType.value);
174
221
 
175
222
  // find the enum value type
176
223
  install_synchronization(this);
@@ -212,30 +259,33 @@ export function _addMultiStateValueDiscrete<T, DT extends DataType>(
212
259
  if (options.value === undefined && enumValues[0]) {
213
260
  options.value = enumValues[0].value; // Int64
214
261
  }
262
+ // Only DataTypes that can be represented with EnumValues are allowed for Variables of MultiStateValueDiscreteType.
263
+ // These are Integers up to 64 Bits (signed and unsigned).:
264
+
265
+ const dataType: DataType = _getBasicDataTypeFromDataTypeNodeId(addressSpace, options.dataType || DataType.UInt32);
266
+
215
267
  let value: undefined | BindVariableOptions;
216
- if (typeof options.value === "number" || isValidUInt64(options.value as number | number[])) {
217
- if (isValidUInt64(options.value as number | number[])) {
218
- value = new Variant({
219
- dataType: DataType.UInt32,
220
- value: (options.value as Int64)[1] // Low word
221
- });
222
- } else {
223
- value = new Variant({
224
- dataType: DataType.UInt32,
225
- value: options.value
226
- });
227
- }
268
+ if (
269
+ typeof options.value === "number" ||
270
+ isValidUInt64(options.value as number | number[]) ||
271
+ isValidInt64(options.value as number | number[])
272
+ ) {
273
+ value = new Variant({
274
+ dataType,
275
+ value: options.value
276
+ });
228
277
  } else {
229
278
  value = options.value as any;
230
279
  }
231
280
 
232
281
  const cloned_options = {
233
282
  ...options,
234
- dataType: DataType.UInt32,
283
+ dataType,
235
284
  typeDefinition: multiStateValueDiscreteType.nodeId,
236
285
  // valueRank:
237
286
  // note : OPCUA Spec 1.03 specifies -1:Scalar (part 8 page 8) but nodeset file specifies -2:Any
238
287
  value,
288
+ // limitation: although the Specs specify -2:any, we only support -1(Scalar)
239
289
  valueRank: -1 // -1 : Scalar
240
290
  };
241
291
 
@@ -267,6 +317,8 @@ export function _addMultiStateValueDiscrete<T, DT extends DataType>(
267
317
  minimumSamplingInterval: 0,
268
318
  modellingRule: options.modellingRule ? "Mandatory" : undefined,
269
319
  propertyOf: variable,
320
+ arrayDimensions: options.arrayDimensions,
321
+ valueRank: options.valueRank,
270
322
  typeDefinition: "PropertyType",
271
323
  userAccessLevel: "CurrentRead"
272
324
  // value: valueAsText
@@ -282,21 +334,23 @@ export function _addMultiStateValueDiscrete<T, DT extends DataType>(
282
334
  return variable;
283
335
  }
284
336
 
285
- export function validateDataType(dataTypeValue: any): void {
286
- const validTypes = [
287
- DataType.UInt64,
288
- DataType.Int64,
289
- DataType.UInt32,
290
- DataType.Int32,
291
- DataType.UInt16,
292
- DataType.Int16,
293
- DataType.Byte,
294
- DataType.Byte,
295
- DataType.SByte,
296
- 26 /*Number*/
297
- ];
298
-
299
- if (typeof dataTypeValue !== "number" || validTypes.indexOf(dataTypeValue) < 0) {
337
+ const validBasicNumericDataTypes = [
338
+ DataType.UInt64,
339
+ DataType.Int64,
340
+ DataType.UInt32,
341
+ DataType.Int32,
342
+ DataType.UInt16,
343
+ DataType.Int16,
344
+ DataType.Byte,
345
+ DataType.Byte,
346
+ DataType.SByte,
347
+ 26 /*Number*/
348
+ ];
349
+ export function validateIsNumericDataType(dataTypeValue: any): void {
350
+ if (typeof dataTypeValue !== "number" || validBasicNumericDataTypes.indexOf(dataTypeValue) < 0) {
300
351
  throw new Error(`Invalid DataType in UAMultiStateValueDiscrete => ${dataTypeValue.toString()}`);
301
352
  }
302
353
  }
354
+
355
+ /** @deprecated: use validateIsNumericDataType instead */
356
+ export const validateDataType = validateIsNumericDataType;
@@ -10,9 +10,11 @@ import { UAVariableImpl } from "../ua_variable_impl";
10
10
  import { registerNodePromoter } from "../../source/loader/register_node_promoter";
11
11
  import { AddTwoStateDiscreteOptions } from "../../source/address_space_ts";
12
12
  import { UATwoStateDiscreteEx } from "../../source/interfaces/data_access/ua_two_state_discrete_ex";
13
+ import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";
13
14
 
14
15
  import { add_dataItem_stuff } from "./add_dataItem_stuff";
15
16
 
17
+
16
18
  export interface UATwoStateDiscreteImpl {
17
19
  falseState: UAProperty<LocalizedText, /*c*/ DataType.LocalizedText>;
18
20
  trueState: UAProperty<LocalizedText, /*c*/ DataType.LocalizedText>;
@@ -58,15 +60,15 @@ export class UATwoStateDiscreteImpl extends UAVariableImpl implements UATwoState
58
60
  );
59
61
  }
60
62
  }
61
- setValue(value: boolean | LocalizedTextLike): void {
63
+ setValue(value: boolean | LocalizedTextLike, options?: ISetStateOptions): void {
62
64
  if (typeof value === "boolean") {
63
65
  this.setValueFromSource({ dataType: DataType.Boolean, value });
64
66
  } else {
65
67
  const text: string = (typeof value === "string" ? value : value.text) || "";
66
68
  if (text === this.getTrueStateAsString()) {
67
- this.setValue(true);
69
+ this.setValue(true, options);
68
70
  } else if (text === this.getFalseStateAsString()) {
69
- this.setValue(false);
71
+ this.setValue(false, options);
70
72
  } else {
71
73
  throw new Error("setValue invalid value " + value);
72
74
  }
@@ -1,7 +1,7 @@
1
1
  import { IAddressSpace } from "node-opcua-address-space-base";
2
2
  import { DataType } from "node-opcua-basic-types";
3
3
  import { NodeClass } from "node-opcua-data-model";
4
- import { NodeId } from "node-opcua-nodeid";
4
+ import { NodeId, NodeIdLike } from "node-opcua-nodeid";
5
5
 
6
6
  export interface IBaseNodeVariableOrVariableType {
7
7
  addressSpace: IAddressSpace;
@@ -10,6 +10,19 @@ export interface IBaseNodeVariableOrVariableType {
10
10
  interface IBaseNodeVariableOrVariableTypeEx extends IBaseNodeVariableOrVariableType {
11
11
  _basicDataType: DataType;
12
12
  }
13
+
14
+ export function _getBasicDataTypeFromDataTypeNodeId(
15
+ addressSpace: IAddressSpace,
16
+ dataTypeNodeId: { nodeId: NodeIdLike } | NodeIdLike
17
+ ): DataType {
18
+ const dataTypeNodeId_ = (dataTypeNodeId as any).nodeId ? (dataTypeNodeId as any).nodeId : dataTypeNodeId;
19
+ const dataTypeNode = addressSpace.findDataType(dataTypeNodeId_);
20
+ if (!dataTypeNode) {
21
+ return DataType.Null;
22
+ }
23
+ return dataTypeNode.getBasicDataType();
24
+ }
25
+
13
26
  export function _getBasicDataType(uaNode: IBaseNodeVariableOrVariableType): DataType {
14
27
  const _uaNode = uaNode as IBaseNodeVariableOrVariableTypeEx;
15
28
  if (_uaNode._basicDataType) {
@@ -23,10 +36,6 @@ export function _getBasicDataType(uaNode: IBaseNodeVariableOrVariableType): Data
23
36
  // may be node has been deleted already
24
37
  return DataType.Null;
25
38
  }
26
- const dataTypeNode = addressSpace.findDataType(_uaNode.dataType)!;
27
- const basicDataType =
28
- dataTypeNode && dataTypeNode.nodeClass === NodeClass.DataType ? dataTypeNode.getBasicDataType() : DataType.Null;
29
- // const basicDataType = addressSpace.findCorrespondingBasicDataType(uaNode.dataType);
30
- _uaNode._basicDataType = basicDataType;
31
- return basicDataType;
39
+ _uaNode._basicDataType = _getBasicDataTypeFromDataTypeNodeId(addressSpace, _uaNode.dataType);
40
+ return _uaNode._basicDataType;
32
41
  }
@@ -27,7 +27,7 @@ import {
27
27
  RolePermissionType,
28
28
  RolePermissionTypeOptions
29
29
  } from "node-opcua-types";
30
- import * as utils from "node-opcua-utils";
30
+ import { isNullOrUndefined } from "node-opcua-utils";
31
31
  import { DataType, Variant, VariantArrayType, VariantOptions, verifyRankAndDimensions } from "node-opcua-variant";
32
32
  import {
33
33
  AddBaseNodeOptions,
@@ -45,7 +45,6 @@ import {
45
45
  CreateDataTypeOptions,
46
46
  CreateNodeOptions,
47
47
  EnumerationItem,
48
- INamespace,
49
48
  RequiredModel,
50
49
  UADataType,
51
50
  UAEventType,
@@ -58,7 +57,7 @@ import {
58
57
  UAVariableType,
59
58
  UAView
60
59
  } from "node-opcua-address-space-base";
61
- import { UAAnalogItem, UADataItem, UAInitialState, UAState, UAYArrayItem } from "node-opcua-nodeset-ua";
60
+ import { UAAnalogItem, UADataItem, UAInitialState, UAState } from "node-opcua-nodeset-ua";
62
61
 
63
62
  import {
64
63
  AddMultiStateDiscreteOptions,
@@ -70,13 +69,12 @@ import { UAStateMachineEx } from "../source/interfaces/state_machine/ua_state_ma
70
69
  import { UATransitionEx } from "../source/interfaces/state_machine/ua_transition_ex";
71
70
  import {
72
71
  InstantiateAlarmConditionOptions,
73
- InstantiateExclusiveLimitAlarmOptions,
74
72
  InstantiateLimitAlarmOptions,
75
73
  InstantiateOffNormalAlarmOptions,
76
74
  UATwoStateDiscreteEx,
77
75
  UAYArrayItemEx
78
76
  } from "../source";
79
- import { AddAnalogDataItemOptions, AddDataItemOptions, UAAnalogItemEx } from "../source/namespace_data_access";
77
+ import { AddAnalogDataItemOptions, AddDataItemOptions } from "../source/namespace_data_access";
80
78
  import { UATwoStateVariableEx } from "../source/ua_two_state_variable_ex";
81
79
  import { UAMultiStateValueDiscreteEx } from "../source/interfaces/data_access/ua_multistate_value_discrete_ex";
82
80
  import { UAAlarmConditionEx } from "../source/interfaces/alarms_and_conditions/ua_alarm_condition_ex";
@@ -1076,7 +1074,7 @@ export class NamespaceImpl implements NamespacePrivate {
1076
1074
 
1077
1075
  function coerceAxisScale(value: any) {
1078
1076
  const ret = AxisScaleEnumeration[value];
1079
- assert(!utils.isNullOrUndefined(ret));
1077
+ assert(!isNullOrUndefined(ret));
1080
1078
  return ret;
1081
1079
  }
1082
1080
 
@@ -1982,7 +1980,7 @@ export class NamespaceImpl implements NamespacePrivate {
1982
1980
  // ------------------------------------------ DataType
1983
1981
  options.dataType = addressSpace._coerce_DataType(options.dataType!);
1984
1982
 
1985
- options.valueRank = utils.isNullOrUndefined(options.valueRank)
1983
+ options.valueRank = isNullOrUndefined(options.valueRank)
1986
1984
  ? options.arrayDimensions
1987
1985
  ? options.arrayDimensions.length
1988
1986
  : -1
@@ -18,7 +18,7 @@ import {
18
18
  QualifiedName
19
19
  } from "node-opcua-data-model";
20
20
  import { ExpandedNodeId, NodeId, NodeIdType, resolveNodeId } from "node-opcua-nodeid";
21
- import * as utils from "node-opcua-utils";
21
+ import { lowerFirstLetter, isNullOrUndefined } from "node-opcua-utils";
22
22
  import { Variant, VariantArrayType, DataType } from "node-opcua-variant";
23
23
  import {
24
24
  IAddressSpace,
@@ -105,7 +105,6 @@ function b(xw: XmlWriter, browseName: QualifiedName): string {
105
105
  return translateBrowseName(xw, browseName).toString().replace("ns=0;", "");
106
106
  }
107
107
 
108
-
109
108
  function hasHigherPriorityThan(namespaceIndex1: number, namespaceIndex2: number, priorityTable: number[]) {
110
109
  const order1 = priorityTable[namespaceIndex1];
111
110
  const order2 = priorityTable[namespaceIndex2];
@@ -335,7 +334,7 @@ function _dumpVariantInnerExtensionObject(
335
334
  const dataTypeNodeId = field.dataType;
336
335
 
337
336
  const fieldName = field.name!;
338
- const lowerFieldName = utils.lowerFirstLetter(fieldName);
337
+ const lowerFieldName = lowerFirstLetter(fieldName);
339
338
  const v = (value as unknown as Record<string, unknown>)[lowerFieldName];
340
339
  if (v !== null && v !== undefined) {
341
340
  if (
@@ -855,7 +854,7 @@ function _dumpEnumDefinition(xw: XmlWriter, enumDefinition: EnumDefinition) {
855
854
  for (const defItem of enumDefinition.fields!) {
856
855
  xw.startElement("Field");
857
856
  xw.writeAttribute("Name", defItem.name as string);
858
- if (!utils.isNullOrUndefined(defItem.value)) {
857
+ if (!isNullOrUndefined(defItem.value)) {
859
858
  xw.writeAttribute("Value", coerceInt64ToInt32(defItem.value));
860
859
  }
861
860
  _dumpDescription(xw, defItem);
@@ -6,7 +6,7 @@ import chalk from "chalk";
6
6
  import { AddReferenceOpts, UAReference, BaseNode, UAReferenceType } from "node-opcua-address-space-base";
7
7
  import { assert } from "node-opcua-assert";
8
8
  import { coerceNodeId, NodeId, NodeIdLike, sameNodeId } from "node-opcua-nodeid";
9
- import * as utils from "node-opcua-utils";
9
+ import { isNullOrUndefined } from "node-opcua-utils";
10
10
 
11
11
  export function isNodeIdString(str: string): boolean {
12
12
  assert(typeof str === "string");
@@ -17,7 +17,7 @@ function is_valid_reference(ref: UAReference): boolean {
17
17
  const hasRequestedProperties =
18
18
  Object.prototype.hasOwnProperty.call(ref, "referenceType") &&
19
19
  Object.prototype.hasOwnProperty.call(ref, "nodeId") &&
20
- !utils.isNullOrUndefined(ref.isForward);
20
+ !isNullOrUndefined(ref.isForward);
21
21
 
22
22
  if (!hasRequestedProperties) {
23
23
  return false;
@@ -21,6 +21,8 @@ import { AddTwoStateVariableOptions } from "../../source/address_space_ts";
21
21
  import { UATwoStateVariableEx } from "../../source/ua_two_state_variable_ex";
22
22
  // private types
23
23
  import { UAVariableImpl, UAVariableImplT } from "../ua_variable_impl";
24
+ import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";
25
+
24
26
 
25
27
  const hasTrueSubState_ReferenceTypeNodeId = resolveNodeId("HasTrueSubState");
26
28
  const hasFalseSubState_ReferenceTypeNodeId = resolveNodeId("HasFalseSubState");
@@ -54,19 +56,23 @@ const hasFalseSubState_ReferenceTypeNodeId = resolveNodeId("HasFalseSubState");
54
56
  // TwoStateVariableType
55
57
  // <StateIdentifier> Defined in Clause 5.4.3 Optional
56
58
 
57
- function _updateTransitionTime(node: UATwoStateVariableEx, _subState?: UAVariable) {
59
+ function _updateTransitionTime(node: UATwoStateVariableEx, _subState?: UAVariable, options?: ISetStateOptions) {
58
60
  // TransitionTime specifies the time when the current state was entered.
59
61
  if (node.transitionTime) {
60
- node.transitionTime.setValueFromSource({ dataType: DataType.DateTime, value: new Date() });
62
+ const transitionTime = options?.transitionTime || new Date();
63
+ node.transitionTime.setValueFromSource({ dataType: DataType.DateTime, value: transitionTime });
61
64
  }
62
65
  }
63
66
 
64
- function _updateEffectiveTransitionTime(node: UATwoStateVariableImpl) {
67
+ function _updateEffectiveTransitionTime(node: UATwoStateVariableImpl,options?: ISetStateOptions) {
65
68
  if (node.effectiveTransitionTime) {
69
+
70
+ const effectiveTransitionTime = options?.effectiveTransitionTime || new Date();
71
+
66
72
  // because subStateNode ",subStateNode.browseName.toString());
67
73
  node.effectiveTransitionTime.setValueFromSource({
68
74
  dataType: DataType.DateTime,
69
- value: new Date()
75
+ value: effectiveTransitionTime
70
76
  });
71
77
  }
72
78
  }
@@ -308,7 +314,7 @@ export class UATwoStateVariableImpl extends UAVariableImplT<LocalizedText, DataT
308
314
  * @method setValue
309
315
  * @param boolValue {Boolean}
310
316
  */
311
- public setValue(boolValue: boolean): void {
317
+ public setValue(boolValue: boolean, options?: ISetStateOptions): void {
312
318
  assert(typeof boolValue === "boolean");
313
319
  const dataValue = this.id!.readValue();
314
320
  const oldValue = dataValue.value.value;
@@ -317,8 +323,8 @@ export class UATwoStateVariableImpl extends UAVariableImplT<LocalizedText, DataT
317
323
  }
318
324
  //
319
325
  this.id.setValueFromSource(new Variant({ dataType: DataType.Boolean, value: boolValue }));
320
- _updateTransitionTime(this);
321
- _updateEffectiveTransitionTime(this);
326
+ _updateTransitionTime(this, undefined, options);
327
+ _updateEffectiveTransitionTime(this, options);
322
328
  }
323
329
 
324
330
  /**
@@ -369,7 +375,7 @@ export class UATwoStateVariableImpl extends UAVariableImplT<LocalizedText, DataT
369
375
  const addressSpace = this.addressSpace;
370
376
  // add event handle
371
377
  const subState = addressSpace.findNode(reference.nodeId) as UAVariable;
372
- subState.on("value_changed", _updateEffectiveTransitionTime.bind(null, this));
378
+ subState.on("value_changed", _updateEffectiveTransitionTime.bind(null, this, undefined));
373
379
  }
374
380
  }
375
381
  }
@@ -21,16 +21,16 @@ import {
21
21
  import { DataType } from "node-opcua-variant";
22
22
  import { UAObject, ISessionContext, UADataType, UAVariable, BaseNode } from "node-opcua-address-space-base";
23
23
  import { DataTypeIds } from "node-opcua-constants";
24
+ import { Int64, coerceInt32, coerceInt64, coerceInt64toInt32 } from "node-opcua-basic-types";
24
25
 
25
26
  import { SessionContext } from "../source/session_context";
26
27
  import { ExtensionObjectConstructorFuncWithSchema } from "../source/interfaces/extension_object_constructor";
27
28
  import { BaseNodeImpl, InternalBaseNodeOptions } from "./base_node_impl";
28
29
  import { BaseNode_References_toString, BaseNode_toString, ToStringBuilder, ToStringOption } from "./base_node_private";
29
- import * as tools from "./tool_isSubtypeOf";
30
+ import { construct_isSubtypeOf } from "./tool_isSubtypeOf";
30
31
  import { get_subtypeOf } from "./tool_isSubtypeOf";
31
32
  import { get_subtypeOfObj } from "./tool_isSubtypeOf";
32
33
  import { BaseNode_getCache } from "./base_node_private";
33
- import { Int64, coerceInt32, coerceInt64, coerceInt64toInt32 } from "node-opcua-basic-types";
34
34
 
35
35
  export interface UADataTypeImpl {
36
36
  _extensionObjectConstructor: ExtensionObjectConstructorFuncWithSchema;
@@ -76,8 +76,8 @@ export class UADataTypeImpl extends BaseNodeImpl implements UADataType {
76
76
  }
77
77
 
78
78
  /** @deprecated */
79
- public isSupertypeOf = tools.construct_isSubtypeOf<UADataType>(UADataTypeImpl);
80
- public isSubtypeOf = tools.construct_isSubtypeOf<UADataType>(UADataTypeImpl);
79
+ public isSupertypeOf = construct_isSubtypeOf<UADataType>(UADataTypeImpl);
80
+ public isSubtypeOf = construct_isSubtypeOf<UADataType>(UADataTypeImpl);
81
81
 
82
82
  public readonly isAbstract: boolean;
83
83
 
@@ -370,24 +370,24 @@ export function DataType_toString(this: UADataTypeImpl, options: ToStringOption)
370
370
 
371
371
  options.add(
372
372
  options.padding +
373
- chalk.yellow(" binaryEncodingNodeId: ") +
374
- (this.binaryEncodingNodeId ? this.binaryEncodingNodeId.toString() : "<none>")
373
+ chalk.yellow(" binaryEncodingNodeId: ") +
374
+ (this.binaryEncodingNodeId ? this.binaryEncodingNodeId.toString() : "<none>")
375
375
  );
376
376
  options.add(
377
377
  options.padding +
378
- chalk.yellow(" xmlEncodingNodeId : ") +
379
- (this.xmlEncodingNodeId ? this.xmlEncodingNodeId.toString() : "<none>")
378
+ chalk.yellow(" xmlEncodingNodeId : ") +
379
+ (this.xmlEncodingNodeId ? this.xmlEncodingNodeId.toString() : "<none>")
380
380
  );
381
381
  options.add(
382
382
  options.padding +
383
- chalk.yellow(" jsonEncodingNodeId : ") +
384
- (this.jsonEncodingNodeId ? this.jsonEncodingNodeId.toString() : "<none>")
383
+ chalk.yellow(" jsonEncodingNodeId : ") +
384
+ (this.jsonEncodingNodeId ? this.jsonEncodingNodeId.toString() : "<none>")
385
385
  );
386
386
  if (this.subtypeOfObj) {
387
387
  options.add(
388
388
  options.padding +
389
- chalk.yellow(" subtypeOfObj : ") +
390
- (this.subtypeOfObj ? this.subtypeOfObj.browseName.toString() : "")
389
+ chalk.yellow(" subtypeOfObj : ") +
390
+ (this.subtypeOfObj ? this.subtypeOfObj.browseName.toString() : "")
391
391
  );
392
392
  }
393
393
  // references
@@ -396,7 +396,6 @@ export function DataType_toString(this: UADataTypeImpl, options: ToStringOption)
396
396
  dataTypeDefinition_toString.call(this, options);
397
397
  }
398
398
 
399
-
400
399
  const defaultEnumValue: Int64 = coerceInt64(-1);
401
400
 
402
401
  function makeEnumDefinition(definitionFields: EnumFieldOptions[]) {
@@ -424,8 +423,8 @@ function makeStructureDefinition(
424
423
  const structureType = isUnion
425
424
  ? StructureType.Union
426
425
  : hasOptionalFields
427
- ? StructureType.StructureWithOptionalFields
428
- : StructureType.Structure;
426
+ ? StructureType.StructureWithOptionalFields
427
+ : StructureType.Structure;
429
428
 
430
429
  const sd = new StructureDefinition({
431
430
  baseDataType,
@@ -7,7 +7,7 @@ import { AttributeIds } from "node-opcua-data-model";
7
7
  import { DataValue, DataValueLike } from "node-opcua-data-value";
8
8
  import { NodeId } from "node-opcua-nodeid";
9
9
  import { StatusCodes } from "node-opcua-status-code";
10
- import * as utils from "node-opcua-utils";
10
+ import { isNullOrUndefined } from "node-opcua-utils";
11
11
  import { DataType } from "node-opcua-variant";
12
12
  import {
13
13
  AddObjectOptions,
@@ -21,8 +21,8 @@ import {
21
21
  import { SessionContext } from "../source/session_context";
22
22
  import { BaseNodeImpl } from "./base_node_impl";
23
23
  import { ToStringBuilder, UAObjectType_toString } from "./base_node_private";
24
- import { get_subtypeOf, get_subtypeOfObj } from "./tool_isSubtypeOf";
25
- import * as tools from "./tool_isSubtypeOf";
24
+ import { construct_isSubtypeOf, get_subtypeOf, get_subtypeOfObj } from "./tool_isSubtypeOf";
25
+ import { } from "./tool_isSubtypeOf";
26
26
  import {
27
27
  assertUnusedChildBrowseName,
28
28
  topMostParentIsObjectTypeOrVariableType
@@ -49,13 +49,13 @@ export class UAObjectTypeImpl extends BaseNodeImpl implements UAObjectType {
49
49
  }
50
50
 
51
51
 
52
- public isSubtypeOf = tools.construct_isSubtypeOf<UAObjectType>(UAObjectTypeImpl);
52
+ public isSubtypeOf = construct_isSubtypeOf<UAObjectType>(UAObjectTypeImpl);
53
53
  /** @deprecated - use isSubtypeOf instead */
54
- public isSupertypeOf = tools.construct_isSubtypeOf<UAObjectType>(UAObjectTypeImpl);
54
+ public isSupertypeOf = construct_isSubtypeOf<UAObjectType>(UAObjectTypeImpl);
55
55
 
56
56
  constructor(options: any) {
57
57
  super(options);
58
- this.isAbstract = utils.isNullOrUndefined(options.isAbstract) ? false : options.isAbstract;
58
+ this.isAbstract = isNullOrUndefined(options.isAbstract) ? false : options.isAbstract;
59
59
  }
60
60
 
61
61
  public readAttribute(context: ISessionContext, attributeId: AttributeIds): DataValue {