node-opcua-address-space 2.59.0 → 2.60.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 (61) 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/loader/load_nodeset2.js +47 -64
  5. package/dist/source/loader/load_nodeset2.js.map +1 -1
  6. package/dist/source/set_namespace_meta_data.js +1 -1
  7. package/dist/src/address_space.js +8 -5
  8. package/dist/src/address_space.js.map +1 -1
  9. package/dist/src/alarms_and_conditions/condition_snapshot.js +3 -3
  10. package/dist/src/alarms_and_conditions/condition_snapshot.js.map +1 -1
  11. package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js +1 -1
  12. package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js.map +1 -1
  13. package/dist/src/alarms_and_conditions/ua_condition_impl.js +8 -6
  14. package/dist/src/alarms_and_conditions/ua_condition_impl.js.map +1 -1
  15. package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js +1 -1
  16. package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js.map +1 -1
  17. package/dist/src/base_node_private.js +2 -2
  18. package/dist/src/base_node_private.js.map +1 -1
  19. package/dist/src/event_data.js +1 -1
  20. package/dist/src/event_data.js.map +1 -1
  21. package/dist/src/namespace_impl.js +5 -5
  22. package/dist/src/namespace_impl.js.map +1 -1
  23. package/dist/src/nodeset_tools/nodeset_to_xml.js +15 -9
  24. package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
  25. package/dist/src/nodeset_tools/typedictionary_to_xml.js +17 -10
  26. package/dist/src/nodeset_tools/typedictionary_to_xml.js.map +1 -1
  27. package/dist/src/state_machine/ua_shelving_state_machine_ex.js +20 -13
  28. package/dist/src/state_machine/ua_shelving_state_machine_ex.js.map +1 -1
  29. package/dist/src/ua_data_type_impl.d.ts +15 -5
  30. package/dist/src/ua_data_type_impl.js +129 -51
  31. package/dist/src/ua_data_type_impl.js.map +1 -1
  32. package/dist/src/ua_variable_impl.d.ts +6 -6
  33. package/dist/src/ua_variable_impl.js +236 -188
  34. package/dist/src/ua_variable_impl.js.map +1 -1
  35. package/dist/src/ua_variable_type_impl.d.ts +3 -4
  36. package/dist/src/ua_variable_type_impl.js +13 -18
  37. package/dist/src/ua_variable_type_impl.js.map +1 -1
  38. package/distHelpers/mock_session.js +1 -1
  39. package/distHelpers/mock_session.js.map +1 -1
  40. package/package.json +35 -35
  41. package/source/address_space_ts.ts +0 -1
  42. package/source/helpers/argument_list.ts +13 -3
  43. package/source/loader/load_nodeset2.ts +64 -80
  44. package/source/set_namespace_meta_data.ts +1 -1
  45. package/src/address_space.ts +15 -9
  46. package/src/alarms_and_conditions/condition_snapshot.ts +4 -4
  47. package/src/alarms_and_conditions/ua_alarm_condition_impl.ts +2 -2
  48. package/src/alarms_and_conditions/ua_condition_impl.ts +18 -8
  49. package/src/alarms_and_conditions/ua_off_normal_alarm_impl.ts +1 -1
  50. package/src/base_node_private.ts +6 -2
  51. package/src/event_data.ts +1 -1
  52. package/src/namespace_impl.ts +6 -6
  53. package/src/nodeset_tools/nodeset_to_xml.ts +20 -10
  54. package/src/nodeset_tools/typedictionary_to_xml.ts +17 -7
  55. package/src/state_machine/ua_shelving_state_machine_ex.ts +28 -16
  56. package/src/ua_data_type_impl.ts +168 -61
  57. package/src/ua_variable_impl.ts +290 -218
  58. package/src/ua_variable_type_impl.ts +9 -15
  59. package/test_helpers/mock_session.ts +1 -1
  60. package/test_helpers/test_fixtures/fixture_simple_statemachine_nodeset2.xml +9 -0
  61. package/test_helpers/test_fixtures/mini.Node.Set2.xml +14 -0
@@ -6,13 +6,13 @@ import * as ec from "node-opcua-basic-types";
6
6
  import { BinaryStream, BinaryStreamSizeCalculator, OutputBinaryStream } from "node-opcua-binary-stream";
7
7
  import { checkDebugFlag, make_debugLog, make_warningLog } from "node-opcua-debug";
8
8
  import * as factories from "node-opcua-factory";
9
- import { NodeId, resolveNodeId } from "node-opcua-nodeid";
9
+ import { coerceNodeId, NodeId, resolveNodeId } from "node-opcua-nodeid";
10
10
  import { Argument } from "node-opcua-service-call";
11
11
  import { StatusCode, StatusCodes } from "node-opcua-status-code";
12
12
  import { Variant } from "node-opcua-variant";
13
13
  import { DataType } from "node-opcua-variant";
14
14
  import { VariantArrayType } from "node-opcua-variant";
15
-
15
+ import { DataTypeIds } from "node-opcua-constants";
16
16
  import { NodeClass } from "node-opcua-data-model";
17
17
  import { IAddressSpace, UAMethod, UAObject } from "node-opcua-address-space-base";
18
18
 
@@ -181,7 +181,17 @@ function isArgumentValid(addressSpace: IAddressSpace, argDefinition: Argument, a
181
181
  }
182
182
 
183
183
  // check that dataType is of the same type (derived )
184
- return argDefDataType.isSupertypeOf(argDataType);
184
+ if (argDefDataType.isSupertypeOf(argDataType)) {
185
+ return true;
186
+ }
187
+ // special case for Enumeration
188
+ if (arg.dataType === DataType.Int32) {
189
+ const enumDataType = addressSpace.findDataType(coerceNodeId(DataTypeIds.Enumeration))!;
190
+ if (argDefDataType.isSupertypeOf(enumDataType)) {
191
+ return true;
192
+ }
193
+ }
194
+ return false;
185
195
  }
186
196
 
187
197
  /**
@@ -15,7 +15,7 @@ import {
15
15
  UAVariableType
16
16
  } from "node-opcua-address-space-base";
17
17
  import { assert, renderError } from "node-opcua-assert";
18
- import { isValidGuid, StatusCodes } from "node-opcua-basic-types";
18
+ import { Int64, isValidGuid, StatusCodes } from "node-opcua-basic-types";
19
19
  import { ExtraDataTypeManager, populateDataTypeManager } from "node-opcua-client-dynamic-extension-object";
20
20
  import { EUInformation } from "node-opcua-data-access";
21
21
  import {
@@ -27,13 +27,21 @@ import {
27
27
  QualifiedNameOptions,
28
28
  stringToQualifiedName
29
29
  } from "node-opcua-data-model";
30
- import { checkDebugFlag, make_debugLog } from "node-opcua-debug";
30
+ import { checkDebugFlag, make_debugLog, make_errorLog } from "node-opcua-debug";
31
31
  import { ExtensionObject } from "node-opcua-extension-object";
32
32
  import { DataTypeFactory, findSimpleType, getStandardDataTypeFactory } from "node-opcua-factory";
33
33
  import { NodeId, resolveNodeId } from "node-opcua-nodeid";
34
34
  import { Argument } from "node-opcua-service-call";
35
35
  import { CallbackT, ErrorCallback } from "node-opcua-status-code";
36
- import { EnumDefinition, EnumValueType, Range, StructureDefinition, StructureFieldOptions, StructureType } from "node-opcua-types";
36
+ import {
37
+ EnumDefinition,
38
+ EnumFieldOptions,
39
+ EnumValueType,
40
+ Range,
41
+ StructureDefinition,
42
+ StructureFieldOptions,
43
+ StructureType
44
+ } from "node-opcua-types";
37
45
  import { DataType, Variant, VariantArrayType, VariantOptions } from "node-opcua-variant";
38
46
  import {
39
47
  _definitionParser,
@@ -56,6 +64,7 @@ import { promoteObjectsAndVariables } from "./namespace_post_step";
56
64
 
57
65
  const doDebug = checkDebugFlag(__filename);
58
66
  const debugLog = make_debugLog(__filename);
67
+ const errorLog = make_errorLog(__filename);
59
68
 
60
69
  export async function ensureDatatypeExtracted(addressSpace: IAddressSpace): Promise<ExtraDataTypeManager> {
61
70
  const addressSpacePriv: any = addressSpace as AddressSpacePrivate;
@@ -151,39 +160,6 @@ async function decodeXmlObject(
151
160
  return userDefinedExtensionObject;
152
161
  }
153
162
 
154
- function makeEnumDefinition(definitionFields: any[]) {
155
- return new EnumDefinition({
156
- fields: definitionFields.map((x) => ({
157
- description: {
158
- text: x.description
159
- },
160
- name: x.name,
161
- value: x.value
162
- }))
163
- });
164
- }
165
- function makeStructureDefinition(name: string, definitionFields: StructureFieldOptions[], isUnion: boolean): StructureDefinition {
166
- // Structure = 0,
167
- // StructureWithOptionalFields = 1,
168
- // Union = 2,
169
- const hasOptionalFields = definitionFields.filter((field) => field.isOptional).length > 0;
170
-
171
- const structureType = isUnion
172
- ? StructureType.Union
173
- : hasOptionalFields
174
- ? StructureType.StructureWithOptionalFields
175
- : StructureType.Structure;
176
-
177
- const sd = new StructureDefinition({
178
- baseDataType: undefined,
179
- defaultEncodingId: undefined,
180
- fields: definitionFields,
181
- structureType
182
- });
183
-
184
- return sd;
185
- }
186
-
187
163
  function __make_back_references(namespace: INamespace) {
188
164
  const namespaceP = namespace as NamespacePrivate;
189
165
  for (const node of namespaceP.nodeIterator()) {
@@ -219,14 +195,21 @@ function makeDefaultVariant2(addressSpace: IAddressSpace, dataTypeNode: NodeId,
219
195
  function makeDefaultVariant(addressSpace: IAddressSpace, dataTypeNode: NodeId, valueRank: number): VariantOptions | undefined {
220
196
  let variant: VariantOptions = { dataType: DataType.Null };
221
197
 
222
- const nodeDataType = addressSpace.findNode(dataTypeNode);
198
+ const nodeDataType = addressSpace.findNode(dataTypeNode) as UADataType;
223
199
  if (nodeDataType) {
224
- const dataType = addressSpace.findCorrespondingBasicDataType(dataTypeNode);
225
- if (dataType === DataType.ExtensionObject) {
200
+
201
+ const basicDataType = nodeDataType.basicDataType;
202
+ if (basicDataType === DataType.Variant) {
203
+ /// we don't now what is the variant
204
+ return undefined
205
+ }
206
+
207
+ // addressSpace.findCorrespondingBasicDataType(dataTypeNode);
208
+ if (basicDataType === DataType.ExtensionObject) {
226
209
  // console.log("xxxxxxxxxx ", dataTypeNode.toString(addressSpace as any));
227
210
  return { dataType: DataType.ExtensionObject, value: null };
228
211
  }
229
- const dv = findSimpleType(DataType[dataType]).defaultValue;
212
+ const dv = findSimpleType(DataType[basicDataType]).defaultValue;
230
213
  if (dv === undefined || dv === null) {
231
214
  // return
232
215
  return { dataType: DataType.Null };
@@ -247,16 +230,16 @@ function makeDefaultVariant(addressSpace: IAddressSpace, dataTypeNode: NodeId, v
247
230
  case -2: // any
248
231
  case -1:
249
232
  arrayType = VariantArrayType.Scalar;
250
- variant = { dataType, value, arrayType };
233
+ variant = { dataType: basicDataType, value, arrayType };
251
234
  break;
252
235
  case 0: // one or more dimension
253
236
  case 1: // one dimension
254
237
  arrayType = VariantArrayType.Array;
255
- variant = { dataType, value: [], arrayType };
238
+ variant = { dataType: basicDataType, value: [], arrayType };
256
239
  break;
257
240
  default:
258
241
  arrayType = VariantArrayType.Matrix;
259
- variant = { dataType, value: [], arrayType, dimensions: [] };
242
+ variant = { dataType: basicDataType, value: [], arrayType, dimensions: [] };
260
243
  break;
261
244
  }
262
245
  // console.log(variant, DataType[dataType], valueRank);
@@ -445,7 +428,6 @@ export function makeStuff(addressSpace: IAddressSpace): any {
445
428
 
446
429
  this.isDraft = attrs.ReleaseStatus === "Draft";
447
430
  this.obj.isDeprecated = attrs.ReleaseStatus === "Deprecated";
448
-
449
431
  },
450
432
  finish(this: any) {
451
433
  if (this.isDraft || this.isDeprecated) {
@@ -558,49 +540,52 @@ export function makeStuff(addressSpace: IAddressSpace): any {
558
540
  debugLog("Ignoring Draft/Deprecated dataType =", this.obj.browseName.toString());
559
541
  return;
560
542
  }
561
- let definitionFields = this.definitionFields;
562
- // replace DataType with nodeId
563
- definitionFields = definitionFields.map((x: any) => {
543
+ /*
544
+ export interface StructureFieldOptions {
545
+ name?: UAString ; // **
546
+ description?: (LocalizedTextLike | null); // **
547
+ dataType?: (NodeIdLike | null);
548
+ valueRank?: Int32 ;
549
+ arrayDimensions?: UInt32 [] | null;
550
+ maxStringLength?: UInt32 ;
551
+ isOptional?: UABoolean ;
552
+ }
553
+ export interface EnumValueTypeOptions {
554
+ value?: Int64 ;
555
+ displayName?: (LocalizedTextLike | null);
556
+ description?: (LocalizedTextLike | null); // **
557
+ }
558
+ export interface EnumFieldOptions extends EnumValueTypeOptions {
559
+ name?: UAString ; // **
560
+ }
561
+ */
562
+
563
+ const definitionFields = this.definitionFields as StructureFieldOptions[] | EnumFieldOptions[];
564
+
565
+ // replace DataType with nodeId, and description to LocalizedText
566
+ definitionFields.map((x: any) => {
567
+ if (x.description) {
568
+ x.description = { text: x.description };
569
+ }
570
+ if (x.displayName) {
571
+ x.displayName = { text: x.displayName };
572
+ }
564
573
  if (x.dataType) {
565
574
  x.dataType = convertToNodeId(x.dataType);
566
575
  }
567
576
  return x;
568
577
  });
569
-
578
+ this.obj.partialDefinition = definitionFields;
579
+
570
580
  const dataTypeNode = _internal_createNode(this.obj) as UADataType;
571
581
  assert(addressSpace1.findNode(this.obj.nodeId));
572
582
  const definitionName = dataTypeNode.browseName.name!;
573
583
 
574
- let alreadyCalled = false;
575
584
  const processBasicDataType = async (addressSpace2: IAddressSpace) => {
576
- assert(!alreadyCalled);
577
- alreadyCalled = true;
578
-
579
- const enumeration = addressSpace2.findDataType("Enumeration");
580
- const structure = addressSpace2.findDataType("Structure");
581
- const union = addressSpace2.findDataType("Union");
582
-
583
- // we have a data type from a companion specification
584
- // let's see if this data type need to be registered
585
- const isEnumeration = enumeration && dataTypeNode.isSupertypeOf(enumeration);
586
- const isStructure = structure && dataTypeNode.isSupertypeOf(structure);
587
- const isUnion = !!(structure && union && dataTypeNode.isSupertypeOf(union!));
588
-
589
- if (definitionFields.length) {
590
- // remove <namespace>:
591
- const nameWithoutNamespace = definitionName.split(":").slice(-1)[0];
592
-
593
- if (isStructure /*&& dataTypeNode.nodeId.namespace !== 0*/) {
594
- // note: at this stage, structure definition will be incomplete as we do not know
595
- // what is the subType yet, encodings are also unknown...
596
- // structureType may also be inaccurate
597
- debugLog("setting structure $definition for ", definitionName, nameWithoutNamespace);
598
- (dataTypeNode as any).$definition = makeStructureDefinition(definitionName, definitionFields, isUnion);
599
- } else if (isEnumeration /* && dataTypeNode.nodeId.namespace !== 0 */) {
600
- (dataTypeNode as any).$definition = makeEnumDefinition(definitionFields);
601
- }
602
- }
603
- if (!isEnumeration && !isStructure && this.obj.nodeId.namespace !== 0) {
585
+ const isStructure = dataTypeNode.isStructure();
586
+ const isEnumeration = dataTypeNode.isEnumeration();
587
+ if (!isEnumeration && !isStructure && dataTypeNode.nodeId.namespace !== 0) {
588
+ // add a custom basic type that is not a structure nor a enumeration
604
589
  pendingSimpleTypeToRegister.push({ name: definitionName, dataTypeNodeId: dataTypeNode.nodeId });
605
590
  }
606
591
  };
@@ -1289,7 +1274,6 @@ export function makeStuff(addressSpace: IAddressSpace): any {
1289
1274
 
1290
1275
  this.isDraft = attrs.ReleaseStatus === "Draft";
1291
1276
  this.isDeprecated = attrs.ReleaseStatus === "Deprecated";
1292
-
1293
1277
  },
1294
1278
  finish(this: any) {
1295
1279
  if (this.isDraft || this.isDeprecated) {
@@ -1316,6 +1300,8 @@ export function makeStuff(addressSpace: IAddressSpace): any {
1316
1300
  };
1317
1301
  postTaskInitializeVariable.push(task);
1318
1302
  } else {
1303
+ const captureName = this.obj.browseName.toString();
1304
+ const captureNodeId = this.obj.nodeId;
1319
1305
  const task = async (addressSpace2: IAddressSpace) => {
1320
1306
  const dataTypeNode = variable.dataType;
1321
1307
  const valueRank = variable.valueRank;
@@ -1374,7 +1360,6 @@ export function makeStuff(addressSpace: IAddressSpace): any {
1374
1360
 
1375
1361
  this.isDraft = attrs.ReleaseStatus === "Draft";
1376
1362
  this.isDeprecated = attrs.ReleaseStatus === "Deprecated";
1377
-
1378
1363
  },
1379
1364
  finish(this: any) {
1380
1365
  if (this.isDraft || this.isDeprecated) {
@@ -1420,7 +1405,6 @@ export function makeStuff(addressSpace: IAddressSpace): any {
1420
1405
 
1421
1406
  this.isDraft = attrs.ReleaseStatus === "Draft";
1422
1407
  this.isDeprecated = attrs.ReleaseStatus === "Deprecated";
1423
-
1424
1408
  },
1425
1409
  finish(this: any) {
1426
1410
  if (this.isDraft || this.isDeprecated) {
@@ -54,7 +54,7 @@ export function setNamespaceMetaData(namespace: INamespace): void {
54
54
  {
55
55
  get: () =>
56
56
  new Variant({
57
- dataType: DataType.UInt32,
57
+ dataType: DataType.UInt16,
58
58
  value: namespace.getDefaultAccessRestrictions()
59
59
  })
60
60
  },
@@ -10,7 +10,7 @@ import { ExtraDataTypeManager } from "node-opcua-client-dynamic-extension-object
10
10
  import { DataTypeIds, VariableTypeIds } from "node-opcua-constants";
11
11
  import { BrowseDirection, NodeClass, QualifiedName } from "node-opcua-data-model";
12
12
  import { ExtensionObject } from "node-opcua-extension-object";
13
- import { coerceExpandedNodeId, makeNodeId, NodeId, NodeIdLike, resolveNodeId, sameNodeId } from "node-opcua-nodeid";
13
+ import { coerceExpandedNodeId, coerceNodeId, makeNodeId, NodeId, NodeIdLike, resolveNodeId, sameNodeId } from "node-opcua-nodeid";
14
14
  import { ObjectRegistry } from "node-opcua-object-registry";
15
15
  import { BrowseResult } from "node-opcua-service-browse";
16
16
  import { StatusCodes } from "node-opcua-status-code";
@@ -69,7 +69,8 @@ const doDebug = false;
69
69
  const Dequeue = require("dequeue");
70
70
 
71
71
  const regexNumberColumnString = /^([0-9]+):(.*)/;
72
-
72
+ const enumerationTypeNodeId = coerceNodeId(DataTypeIds.Enumeration);
73
+
73
74
  function _extract_namespace_and_browse_name_as_string(
74
75
  addressSpace: AddressSpace,
75
76
  browseName: NodeIdLike | QualifiedName,
@@ -472,10 +473,8 @@ export class AddressSpace implements AddressSpacePrivate {
472
473
  dataTypeNode.constructor.name
473
474
  );
474
475
  }
475
- dataTypeNode = dataTypeNode as UADataType;
476
-
477
- const enumerationType = this.findDataType("Enumeration")!;
478
- if (sameNodeId(enumerationType.nodeId, dataTypeNode!.nodeId)) {
476
+
477
+ if (sameNodeId(enumerationTypeNodeId, dataTypeNode!.nodeId)) {
479
478
  return DataType.Int32;
480
479
  }
481
480
 
@@ -483,11 +482,18 @@ export class AddressSpace implements AddressSpacePrivate {
483
482
  // Number
484
483
  return DataType.Null; //which one ?
485
484
  }
486
-
487
- if (dataTypeNode.nodeId.namespace === 0 && DataType[dataTypeNode.nodeId.value as number]) {
485
+
486
+ if (dataTypeNode.nodeId.namespace === 0 && dataTypeNode.nodeId.value === 0) {
487
+ return DataType.Null;
488
+ }
489
+
490
+ if (dataTypeNode.nodeId.namespace === 0 && dataTypeNode.nodeId.value <= 25) {
488
491
  return dataTypeNode.nodeId.value as DataType;
489
492
  }
490
- return this.findCorrespondingBasicDataType(dataTypeNode.subtypeOfObj as UADataType);
493
+
494
+ const result = this.findCorrespondingBasicDataType(dataTypeNode.subtypeOfObj as UADataType);
495
+
496
+ return result;
491
497
  }
492
498
 
493
499
  /**
@@ -9,7 +9,7 @@ import { UInt16 } from "node-opcua-basic-types";
9
9
  import { coerceLocalizedText, LocalizedText, LocalizedTextLike, NodeClass } from "node-opcua-data-model";
10
10
  import { DataValue } from "node-opcua-data-value";
11
11
  import { checkDebugFlag, make_debugLog } from "node-opcua-debug";
12
- import { NodeId } from "node-opcua-nodeid";
12
+ import { NodeId, sameNodeId } from "node-opcua-nodeid";
13
13
  import { UAAcknowledgeableCondition } from "node-opcua-nodeset-ua";
14
14
  import { StatusCode, StatusCodes } from "node-opcua-status-code";
15
15
  import { SimpleAttributeOperand, TimeZoneDataType } from "node-opcua-types";
@@ -175,14 +175,14 @@ export class ConditionSnapshot extends EventEmitter {
175
175
  // a nodeId/Variant map
176
176
  _record_condition_state(this, condition);
177
177
 
178
- if (branchId === NodeId.nullNodeId) {
178
+ if (sameNodeId(branchId, NodeId.nullNodeId)) {
179
179
  _installOnChangeEventHandlers(this, condition, "");
180
180
  }
181
181
  this._set_var("branchId", DataType.NodeId, branchId);
182
182
  }
183
183
 
184
184
  public _constructEventData(): IEventData {
185
- if (this.branchId === NodeId.nullNodeId) {
185
+ if (this.branchId && sameNodeId(this.branchId, NodeId.nullNodeId)) {
186
186
  _ensure_condition_values_correctness(this, this.condition!, "", []);
187
187
  }
188
188
  const c = this.condition as UAConditionImpl;
@@ -594,7 +594,7 @@ export class ConditionSnapshot extends EventEmitter {
594
594
  }
595
595
 
596
596
  public isCurrentBranch(): boolean {
597
- return this._get_var("branchId") === NodeId.nullNodeId;
597
+ return sameNodeId(this._get_var("branchId"), NodeId.nullNodeId);
598
598
  }
599
599
 
600
600
  // -- ACKNOWLEDGEABLE -------------------------------------------------------------------
@@ -6,7 +6,7 @@ import { isEqual } from "lodash";
6
6
  import { assert } from "node-opcua-assert";
7
7
  import { NodeClass } from "node-opcua-data-model";
8
8
  import { DataValue } from "node-opcua-data-value";
9
- import { NodeId } from "node-opcua-nodeid";
9
+ import { NodeId, sameNodeId } from "node-opcua-nodeid";
10
10
  import { StatusCodes } from "node-opcua-status-code";
11
11
  import { DataType } from "node-opcua-variant";
12
12
  import { UAAlarmCondition_Base } from "node-opcua-nodeset-ua";
@@ -498,7 +498,7 @@ export class UAAlarmConditionImpl extends UAAcknowledgeableConditionImpl impleme
498
498
  if (this.currentBranch().getRetain()) {
499
499
  // we need to create a new branch so the previous state could be acknowledged
500
500
  const newBranch = this.createBranch();
501
- assert(newBranch.getBranchId() !== NodeId.nullNodeId);
501
+ assert(!sameNodeId(newBranch.getBranchId(), NodeId.nullNodeId));
502
502
  // also raised a new Event for the new branch as branchId has changed
503
503
  this.raiseNewBranchState(newBranch);
504
504
  }
@@ -238,7 +238,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
238
238
  */
239
239
  public post_initialize(): void {
240
240
  assert(!this._branch0);
241
- this._branch0 = new ConditionSnapshot(this, NodeId.nullNodeId);
241
+ this._branch0 = new ConditionSnapshot(this, new NodeId());
242
242
 
243
243
  // the condition OPCUA object alway reflects the default branch states
244
244
  // so we set a mechanism that automatically keeps self in sync
@@ -284,7 +284,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
284
284
  */
285
285
  public deleteBranch(branch: ConditionSnapshot): void {
286
286
  const key = branch.getBranchId().toString();
287
- assert(branch.getBranchId() !== NodeId.nullNodeId, "cannot delete branch zero");
287
+ assert(!sameNodeId(branch.getBranchId(), NodeId.nullNodeId), "cannot delete branch zero");
288
288
  assert(Object.prototype.hasOwnProperty.call(this._branches, key));
289
289
  delete this._branches[key];
290
290
  this.emit("branch_deleted", key);
@@ -560,7 +560,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
560
560
  public raiseNewBranchState(branch: ConditionSnapshot): void {
561
561
  this.raiseConditionEvent(branch, true);
562
562
 
563
- if (branch.getBranchId() !== NodeId.nullNodeId && !branch.getRetain()) {
563
+ if (!sameNodeId(branch.getBranchId(), NodeId.nullNodeId) && !branch.getRetain()) {
564
564
  // xx console.log(" Deleting not longer needed branch ", branch.getBranchId().toString());
565
565
  // branch can be deleted
566
566
  this.deleteBranch(branch);
@@ -789,7 +789,7 @@ function UACondition_instantiate(
789
789
  // install initial branch ID (null NodeId);
790
790
  conditionNode.branchId.setValueFromSource({
791
791
  dataType: DataType.NodeId,
792
- value: NodeId.nullNodeId
792
+ value: new NodeId()
793
793
  });
794
794
 
795
795
  // install 'Comment' condition variable
@@ -920,7 +920,9 @@ function UACondition_instantiate(
920
920
  conditionNode.sourceNode.setValueFromSource(conditionSourceNode.readAttribute(null, AttributeIds.NodeId).value);
921
921
 
922
922
  // set source Name (defined in UABaseEventType)
923
- conditionNode.sourceName.setValueFromSource(conditionSourceNode.readAttribute(null, AttributeIds.DisplayName).value);
923
+ const displayName: LocalizedText = conditionSourceNode.readAttribute(null, AttributeIds.DisplayName).value
924
+ .value as LocalizedText;
925
+ conditionNode.sourceName.setValueFromSource({ dataType: DataType.String, value: displayName.text });
924
926
  }
925
927
  }
926
928
 
@@ -953,7 +955,7 @@ function UACondition_instantiate(
953
955
  */
954
956
  const baseConditionClassType = addressSpace.findObjectType("ProcessConditionClassType");
955
957
  // assert(baseConditionClassType,"Expecting BaseConditionClassType to be in addressSpace");
956
- let conditionClassId = baseConditionClassType ? baseConditionClassType.nodeId : NodeId.nullNodeId;
958
+ let conditionClassId = baseConditionClassType ? baseConditionClassType.nodeId : new NodeId();
957
959
  let conditionClassName = baseConditionClassType ? baseConditionClassType.displayName[0] : "";
958
960
  if (options.conditionClass) {
959
961
  if (typeof options.conditionClass === "string") {
@@ -1123,7 +1125,11 @@ function _perform_condition_refresh(addressSpace: AddressSpacePrivate, inputArgu
1123
1125
  return StatusCodes.Good;
1124
1126
  }
1125
1127
 
1126
- function _condition_refresh2_method(inputArguments: VariantLike[], context: ISessionContext, callback: CallbackT<CallMethodResultOptions>) {
1128
+ function _condition_refresh2_method(
1129
+ inputArguments: VariantLike[],
1130
+ context: ISessionContext,
1131
+ callback: CallbackT<CallMethodResultOptions>
1132
+ ) {
1127
1133
  // arguments : IntegerId SubscriptionId
1128
1134
  // arguments : IntegerId MonitoredItemId
1129
1135
  assert(inputArguments.length === 2);
@@ -1146,7 +1152,11 @@ function _condition_refresh2_method(inputArguments: VariantLike[], context: ISes
1146
1152
  });
1147
1153
  }
1148
1154
 
1149
- function _add_comment_method(inputArguments: VariantLike[], context: ISessionContext, callback: CallbackT<CallMethodResultOptions>) {
1155
+ function _add_comment_method(
1156
+ inputArguments: VariantLike[],
1157
+ context: ISessionContext,
1158
+ callback: CallbackT<CallMethodResultOptions>
1159
+ ) {
1150
1160
  //
1151
1161
  // The AddComment Method is used to apply a comment to a specific state of a Condition
1152
1162
  // instance. Normally, the NodeId of the object instance as the ObjectId is passed to the Call
@@ -79,7 +79,7 @@ export class UAOffNormalAlarmImpl extends UADiscreteAlarmImpl implements UAOffNo
79
79
  const normalState = addressSpace._coerceNode(options.normalState)! as UAVariable;
80
80
  // assert(normalState, "Expecting a valid normalState node");
81
81
 
82
- const normalStateNodeId = normalState ? normalState.nodeId : NodeId.nullNodeId;
82
+ const normalStateNodeId = normalState ? normalState.nodeId : new NodeId();
83
83
  alarmNode.normalState.setValueFromSource({ dataType: DataType.NodeId, value: normalStateNodeId });
84
84
 
85
85
  if (inputNode) {
@@ -343,6 +343,10 @@ function AccessLevelFlags_toString(this: UAVariable, options: ToStringOption) {
343
343
  );
344
344
  }
345
345
  }
346
+
347
+ interface WithDataValue {
348
+ $dataValue?: DataValue;
349
+ }
346
350
  export function VariableOrVariableType_toString(this: UAVariableType | UAVariable, options: ToStringOption): void {
347
351
  assert(options);
348
352
  if (this.dataType) {
@@ -352,7 +356,7 @@ export function VariableOrVariableType_toString(this: UAVariableType | UAVariabl
352
356
  options.add(options.padding + chalk.yellow(" dataType : ") + this.dataType + " " + n);
353
357
  }
354
358
  if (this.nodeClass === NodeClass.Variable) {
355
- const _dataValue = (<any>this)._dataValue as DataValue | undefined;
359
+ const _dataValue = (<WithDataValue>this).$dataValue as DataValue | undefined;
356
360
  if (_dataValue) {
357
361
  options.add(
358
362
  options.padding +
@@ -622,7 +626,7 @@ function _makeReferenceDescription(addressSpace: IAddressSpace, reference: UARef
622
626
  };
623
627
  }
624
628
  if (data.typeDefinition === null) {
625
- data.typeDefinition = NodeId.nullNodeId;
629
+ data.typeDefinition = new NodeId();
626
630
  }
627
631
  const referenceDescription = new ReferenceDescription(data);
628
632
  return referenceDescription;
package/src/event_data.ts CHANGED
@@ -25,7 +25,7 @@ export class EventData implements IEventData {
25
25
 
26
26
  constructor(eventTypeNode: BaseNode) {
27
27
  this.__nodes = {};
28
- this.eventId = NodeId.nullNodeId;
28
+ this.eventId = new NodeId();
29
29
  this.$eventDataSource = eventTypeNode;
30
30
  }
31
31
 
@@ -28,7 +28,7 @@ import {
28
28
  RolePermissionTypeOptions
29
29
  } from "node-opcua-types";
30
30
  import * as utils from "node-opcua-utils";
31
- import { DataType, Variant, VariantArrayType } from "node-opcua-variant";
31
+ import { DataType, Variant, VariantArrayType, verifyRankAndDimensions } from "node-opcua-variant";
32
32
  import {
33
33
  AddBaseNodeOptions,
34
34
  AddEnumerationTypeOptions,
@@ -100,7 +100,7 @@ import { _install_TwoStateVariable_machinery, _addTwoStateVariable } from "./sta
100
100
  //
101
101
  import { NamespacePrivate, UANamespace_process_modelling_rule } from "./namespace_private";
102
102
  import { BaseNodeImpl } from "./base_node_impl";
103
- import { UAVariableImpl, verifyRankAndDimensions } from "./ua_variable_impl";
103
+ import { UAVariableImpl } from "./ua_variable_impl";
104
104
 
105
105
  import { ConstructNodeIdOptions, NodeIdManager } from "./nodeid_manager";
106
106
  import { _addTwoStateDiscrete } from "./data_access/ua_two_state_discrete";
@@ -238,7 +238,7 @@ export class NamespaceImpl implements NamespacePrivate {
238
238
  }
239
239
 
240
240
  public getDefaultNamespace(): NamespacePrivate {
241
- return this.index === 0 ? this : (this.addressSpace.getDefaultNamespace());
241
+ return this.index === 0 ? this : this.addressSpace.getDefaultNamespace();
242
242
  }
243
243
 
244
244
  public dispose(): void {
@@ -656,7 +656,7 @@ export class NamespaceImpl implements NamespacePrivate {
656
656
  */
657
657
  public deleteNode(nodeOrNodeId: NodeId | BaseNode): void {
658
658
  let node: BaseNode | null = null;
659
- let nodeId: NodeId = NodeId.nullNodeId;
659
+ let nodeId: NodeId = new NodeId();
660
660
  if (nodeOrNodeId instanceof NodeId) {
661
661
  nodeId = nodeOrNodeId;
662
662
  node = this.findNode(nodeId);
@@ -1337,7 +1337,7 @@ export class NamespaceImpl implements NamespacePrivate {
1337
1337
  // or OptionSet DataType. It is derived from the DataType EnumValueType. If used for an
1338
1338
  // OptionSet, the corresponding Value in the base type contains the number of the bit associated
1339
1339
  // with the field. The EnumField is formally defined in Table 37.
1340
- (enumType as any).$definition = new EnumDefinition({
1340
+ (enumType as any).$fullDefinition = new EnumDefinition({
1341
1341
  fields: enumeration.map(
1342
1342
  (x: string, index: number) =>
1343
1343
  new EnumField({
@@ -1376,7 +1376,7 @@ export class NamespaceImpl implements NamespacePrivate {
1376
1376
  });
1377
1377
  assert(enumValues.browseName.toString() === "EnumValues");
1378
1378
 
1379
- (enumType as any).$definition = new EnumDefinition({
1379
+ (enumType as any).$fullDefinition = new EnumDefinition({
1380
1380
  fields: enumeration.map(
1381
1381
  (x: EnumerationItem, index: number) =>
1382
1382
  new EnumField({
@@ -592,7 +592,7 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
592
592
 
593
593
  function _dumpArrayDimensionsAttribute(xw: XmlWriter, node: UAVariableType | UAVariable) {
594
594
  if (node.arrayDimensions) {
595
- if (node.arrayDimensions.length === 1 && node.arrayDimensions[0] === 0) {
595
+ if (node.valueRank === -1 || (node.arrayDimensions.length === 1 && node.arrayDimensions[0] === 0)) {
596
596
  return;
597
597
  }
598
598
  xw.writeAttribute("ArrayDimensions", node.arrayDimensions.join(","));
@@ -749,7 +749,11 @@ function _dumpEnumDefinition(xw: XmlWriter, enumDefinition: EnumDefinition) {
749
749
  xw.endElement();
750
750
  }
751
751
  }
752
- function _dumpStructureDefinition(xw: XmlWriter, structureDefinition: StructureDefinition) {
752
+ function _dumpStructureDefinition(
753
+ xw: XmlWriter,
754
+ structureDefinition: StructureDefinition,
755
+ baseStructureDefinition: StructureDefinition | null | undefined
756
+ ) {
753
757
  /*
754
758
  * note: baseDataType and defaultEncodingId are implicit and not stored in the XML file ??
755
759
  *
@@ -757,8 +761,12 @@ function _dumpStructureDefinition(xw: XmlWriter, structureDefinition: StructureD
757
761
  const baseDataType = structureDefinition.baseDataType;
758
762
  const defaultEncodingId = structureDefinition.defaultEncodingId;
759
763
 
760
- structureDefinition.fields = structureDefinition.fields || [];
761
- for (const defItem /*: StructureField*/ of structureDefinition.fields) {
764
+ // do not repeat elements that are already defined in base structure in the xml ouput!
765
+ const fields = structureDefinition.fields || [];
766
+ const nbFieldsInBase: number = baseStructureDefinition ? baseStructureDefinition.fields?.length || 0 : 0;
767
+
768
+ for(let index = nbFieldsInBase; index <fields.length; index++ ) {
769
+ const defItem = fields[index];
762
770
  xw.startElement("Field");
763
771
  xw.writeAttribute("Name", defItem.name!);
764
772
 
@@ -788,27 +796,29 @@ function _dumpStructureDefinition(xw: XmlWriter, structureDefinition: StructureD
788
796
  xw.endElement();
789
797
  }
790
798
  }
791
- function _dumpUADataTypeDefinition(xw: XmlWriter, node: UADataType) {
799
+ function _dumpUADataTypeDefinition(xw: XmlWriter, uaDataType: UADataType) {
792
800
  // to do remove DataType from base class
793
-
794
- const definition = node.getDefinition();
801
+ const uaDataTypeBase = uaDataType.subtypeOfObj;
802
+ const definition = uaDataType.getDefinition();
795
803
  if (!definition) {
796
804
  return;
797
805
  }
798
806
  if (definition instanceof EnumDefinition) {
799
807
  xw.startElement("Definition");
800
- xw.writeAttribute("Name", node.browseName.name!);
808
+ xw.writeAttribute("Name", uaDataType.browseName.name!);
801
809
  _dumpEnumDefinition(xw, definition);
802
810
  xw.endElement();
803
811
  return;
804
812
  }
805
813
  if (definition instanceof StructureDefinition) {
814
+ const baseDefinition = uaDataTypeBase ? (uaDataTypeBase.getDefinition() as StructureDefinition | null) : null;
815
+
806
816
  xw.startElement("Definition");
807
- xw.writeAttribute("Name", node.browseName.name!);
817
+ xw.writeAttribute("Name", uaDataType.browseName.name!);
808
818
  if (definition.structureType === StructureType.Union) {
809
819
  xw.writeAttribute("IsUnion", "true");
810
820
  }
811
- _dumpStructureDefinition(xw, definition);
821
+ _dumpStructureDefinition(xw, definition, baseDefinition);
812
822
  xw.endElement();
813
823
  return;
814
824
  }