node-opcua-address-space 2.58.0 → 2.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/source/address_space_ts.d.ts +0 -2
- package/dist/source/helpers/argument_list.js +12 -1
- package/dist/source/helpers/argument_list.js.map +1 -1
- package/dist/source/helpers/multiform_func.d.ts +11 -0
- package/dist/source/helpers/multiform_func.js +74 -0
- package/dist/source/helpers/multiform_func.js.map +1 -0
- package/dist/source/loader/load_nodeset2.js +47 -64
- package/dist/source/loader/load_nodeset2.js.map +1 -1
- package/dist/source/set_namespace_meta_data.js +1 -1
- package/dist/src/address_space.js +12 -6
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/alarms_and_conditions/condition_snapshot.js +3 -3
- package/dist/src/alarms_and_conditions/condition_snapshot.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js +1 -1
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_condition_impl.js +8 -6
- package/dist/src/alarms_and_conditions/ua_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js +1 -1
- package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js.map +1 -1
- package/dist/src/base_node_impl.js +2 -0
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/base_node_private.d.ts +3 -3
- package/dist/src/base_node_private.js +198 -25
- package/dist/src/base_node_private.js.map +1 -1
- package/dist/src/event_data.js +1 -1
- package/dist/src/event_data.js.map +1 -1
- package/dist/src/namespace_impl.js +5 -5
- package/dist/src/namespace_impl.js.map +1 -1
- package/dist/src/nodeset_tools/nodeset_to_xml.js +15 -9
- package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
- package/dist/src/nodeset_tools/typedictionary_to_xml.js +17 -10
- package/dist/src/nodeset_tools/typedictionary_to_xml.js.map +1 -1
- package/dist/src/reference_impl.js +1 -1
- package/dist/src/reference_impl.js.map +1 -1
- package/dist/src/state_machine/ua_shelving_state_machine_ex.js +20 -13
- package/dist/src/state_machine/ua_shelving_state_machine_ex.js.map +1 -1
- package/dist/src/ua_data_type_impl.d.ts +15 -5
- package/dist/src/ua_data_type_impl.js +129 -51
- package/dist/src/ua_data_type_impl.js.map +1 -1
- package/dist/src/ua_method_impl.js +2 -1
- package/dist/src/ua_method_impl.js.map +1 -1
- package/dist/src/ua_object_impl.js +2 -1
- package/dist/src/ua_object_impl.js.map +1 -1
- package/dist/src/ua_object_type_impl.js +1 -0
- package/dist/src/ua_object_type_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.d.ts +12 -18
- package/dist/src/ua_variable_impl.js +285 -215
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/src/ua_variable_type_impl.d.ts +3 -4
- package/dist/src/ua_variable_type_impl.js +61 -52
- package/dist/src/ua_variable_type_impl.js.map +1 -1
- package/dist/src/ua_view_impl.js +1 -1
- package/dist/src/ua_view_impl.js.map +1 -1
- package/distHelpers/mock_session.js +1 -1
- package/distHelpers/mock_session.js.map +1 -1
- package/package.json +35 -35
- package/source/address_space_ts.ts +0 -1
- package/source/helpers/argument_list.ts +13 -3
- package/source/helpers/multiform_func.ts +76 -0
- package/source/loader/load_nodeset2.ts +64 -80
- package/source/set_namespace_meta_data.ts +1 -1
- package/src/address_space.ts +16 -7
- package/src/alarms_and_conditions/condition_snapshot.ts +4 -4
- package/src/alarms_and_conditions/ua_alarm_condition_impl.ts +2 -2
- package/src/alarms_and_conditions/ua_condition_impl.ts +18 -8
- package/src/alarms_and_conditions/ua_off_normal_alarm_impl.ts +1 -1
- package/src/base_node_impl.ts +3 -1
- package/src/base_node_private.ts +282 -36
- package/src/event_data.ts +1 -1
- package/src/namespace_impl.ts +6 -6
- package/src/nodeset_tools/nodeset_to_xml.ts +20 -10
- package/src/nodeset_tools/typedictionary_to_xml.ts +17 -7
- package/src/reference_impl.ts +3 -3
- package/src/state_machine/ua_shelving_state_machine_ex.ts +28 -16
- package/src/ua_data_type_impl.ts +168 -61
- package/src/ua_method_impl.ts +10 -2
- package/src/ua_object_impl.ts +10 -2
- package/src/ua_object_type_impl.ts +1 -0
- package/src/ua_variable_impl.ts +419 -325
- package/src/ua_variable_type_impl.ts +87 -52
- package/src/ua_view_impl.ts +1 -1
- package/test_helpers/mock_session.ts +1 -1
- package/test_helpers/test_fixtures/fixture_simple_statemachine_nodeset2.xml +18 -0
- package/test_helpers/test_fixtures/fixuture_nodeset_objects_with_some_methods.xml +9 -1
- package/test_helpers/test_fixtures/mini.Node.Set2.xml +22 -1
package/src/base_node_private.ts
CHANGED
|
@@ -34,12 +34,16 @@ import {
|
|
|
34
34
|
CloneOptions
|
|
35
35
|
} from "node-opcua-address-space-base";
|
|
36
36
|
import { DataValue } from "node-opcua-data-value";
|
|
37
|
+
import { ObjectTypeIds, VariableTypeIds } from "node-opcua-constants";
|
|
37
38
|
|
|
38
39
|
import { UANamespace_process_modelling_rule } from "./namespace_private";
|
|
39
40
|
import { ReferenceImpl } from "./reference_impl";
|
|
40
41
|
import { BaseNodeImpl, getReferenceType } from "./base_node_impl";
|
|
41
42
|
import { AddressSpacePrivate } from "./address_space_private";
|
|
42
|
-
|
|
43
|
+
|
|
44
|
+
// eslint-disable-next-line prefer-const
|
|
45
|
+
let dotrace = false;
|
|
46
|
+
const traceLog = console.log.bind(console);
|
|
43
47
|
|
|
44
48
|
const g_weakMap = new WeakMap();
|
|
45
49
|
|
|
@@ -184,7 +188,10 @@ export function BaseNode_References_toString(this: BaseNode, options: ToStringOp
|
|
|
184
188
|
const addressSpace = this.addressSpace;
|
|
185
189
|
|
|
186
190
|
options.add(
|
|
187
|
-
options.padding +
|
|
191
|
+
options.padding +
|
|
192
|
+
chalk.yellow(" references : ") +
|
|
193
|
+
" length =" +
|
|
194
|
+
Object.keys(_private._referenceIdx).length
|
|
188
195
|
);
|
|
189
196
|
|
|
190
197
|
function dump_reference(follow: boolean, reference: UAReference | null) {
|
|
@@ -193,8 +200,37 @@ export function BaseNode_References_toString(this: BaseNode, options: ToStringOp
|
|
|
193
200
|
}
|
|
194
201
|
const o = ReferenceImpl.resolveReferenceNode(addressSpace, reference);
|
|
195
202
|
const name = o ? o.browseName.toString() : "<???>";
|
|
203
|
+
const extra =
|
|
204
|
+
(o.modellingRule || " ")[0] +
|
|
205
|
+
(() => {
|
|
206
|
+
switch (o.nodeClass) {
|
|
207
|
+
case NodeClass.Object:
|
|
208
|
+
return "[O] ";
|
|
209
|
+
case NodeClass.Variable:
|
|
210
|
+
return "[V] " + (o as UAVariable).dataType.toString(displayOptions).padEnd(10);
|
|
211
|
+
case NodeClass.Method:
|
|
212
|
+
return "[M] ";
|
|
213
|
+
case NodeClass.DataType:
|
|
214
|
+
return "[DT]";
|
|
215
|
+
case NodeClass.ReferenceType:
|
|
216
|
+
return "[RT]";
|
|
217
|
+
case NodeClass.ObjectType:
|
|
218
|
+
return "[OT]";
|
|
219
|
+
case NodeClass.VariableType:
|
|
220
|
+
return "[VT]";
|
|
221
|
+
case NodeClass.View:
|
|
222
|
+
return "[V] ";
|
|
223
|
+
}
|
|
224
|
+
return "";
|
|
225
|
+
})();
|
|
196
226
|
options.add(
|
|
197
|
-
options.padding +
|
|
227
|
+
options.padding +
|
|
228
|
+
chalk.yellow(" +-> ") +
|
|
229
|
+
reference.toString(displayOptions) +
|
|
230
|
+
" " +
|
|
231
|
+
chalk.cyan(name.padEnd(25, " ")) +
|
|
232
|
+
" " +
|
|
233
|
+
chalk.magentaBright(extra)
|
|
198
234
|
);
|
|
199
235
|
|
|
200
236
|
// ignore HasTypeDefinition as it has been already handled
|
|
@@ -223,7 +259,7 @@ export function BaseNode_References_toString(this: BaseNode, options: ToStringOp
|
|
|
223
259
|
|
|
224
260
|
options.add(
|
|
225
261
|
options.padding +
|
|
226
|
-
chalk.yellow("
|
|
262
|
+
chalk.yellow(" back_references : ") +
|
|
227
263
|
chalk.cyan(" length =") +
|
|
228
264
|
br.length +
|
|
229
265
|
chalk.grey(" ( references held by other nodes involving this node)")
|
|
@@ -343,6 +379,10 @@ function AccessLevelFlags_toString(this: UAVariable, options: ToStringOption) {
|
|
|
343
379
|
);
|
|
344
380
|
}
|
|
345
381
|
}
|
|
382
|
+
|
|
383
|
+
interface WithDataValue {
|
|
384
|
+
$dataValue?: DataValue;
|
|
385
|
+
}
|
|
346
386
|
export function VariableOrVariableType_toString(this: UAVariableType | UAVariable, options: ToStringOption): void {
|
|
347
387
|
assert(options);
|
|
348
388
|
if (this.dataType) {
|
|
@@ -352,7 +392,7 @@ export function VariableOrVariableType_toString(this: UAVariableType | UAVariabl
|
|
|
352
392
|
options.add(options.padding + chalk.yellow(" dataType : ") + this.dataType + " " + n);
|
|
353
393
|
}
|
|
354
394
|
if (this.nodeClass === NodeClass.Variable) {
|
|
355
|
-
const _dataValue = (<
|
|
395
|
+
const _dataValue = (<WithDataValue>this).$dataValue as DataValue | undefined;
|
|
356
396
|
if (_dataValue) {
|
|
357
397
|
options.add(
|
|
358
398
|
options.padding +
|
|
@@ -392,6 +432,16 @@ export function VariableOrVariableType_toString(this: UAVariableType | UAVariabl
|
|
|
392
432
|
}
|
|
393
433
|
}
|
|
394
434
|
|
|
435
|
+
const defaultExtraInfo = {
|
|
436
|
+
level: 0,
|
|
437
|
+
pad(): string {
|
|
438
|
+
return "";
|
|
439
|
+
},
|
|
440
|
+
registerClonedObject(node: BaseNode, node1: BaseNode): void {
|
|
441
|
+
/** */
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
|
|
395
445
|
/**
|
|
396
446
|
* clone properties and methods
|
|
397
447
|
* @private
|
|
@@ -400,17 +450,17 @@ function _clone_collection_new(
|
|
|
400
450
|
newParent: BaseNode,
|
|
401
451
|
collectionRef: UAReference[],
|
|
402
452
|
copyAlsoModellingRules: boolean,
|
|
403
|
-
optionalFilter
|
|
404
|
-
extraInfo
|
|
453
|
+
optionalFilter: CloneFilter,
|
|
454
|
+
extraInfo: CloneExtraInfo,
|
|
455
|
+
browseNameMap: Set<string>
|
|
405
456
|
): void {
|
|
406
457
|
const namespace = newParent.namespace;
|
|
407
|
-
|
|
458
|
+
extraInfo = extraInfo || defaultExtraInfo;
|
|
408
459
|
const addressSpace = newParent.addressSpace;
|
|
409
460
|
assert(!optionalFilter || (typeof optionalFilter.shouldKeep === "function" && typeof optionalFilter.filterFor === "function"));
|
|
410
461
|
|
|
411
462
|
for (const reference of collectionRef) {
|
|
412
|
-
const node
|
|
413
|
-
|
|
463
|
+
const node = ReferenceImpl.resolveReferenceNode(addressSpace, reference) as UAVariable | UAObject | UAMethod;
|
|
414
464
|
// ensure node is of the correct type,
|
|
415
465
|
// it may happen that the xml nodeset2 file was malformed
|
|
416
466
|
|
|
@@ -429,18 +479,41 @@ function _clone_collection_new(
|
|
|
429
479
|
}
|
|
430
480
|
|
|
431
481
|
if (optionalFilter && node && !optionalFilter.shouldKeep(node)) {
|
|
482
|
+
dotrace && traceLog(extraInfo.pad(), "skipping ", node.browseName.toString());
|
|
432
483
|
continue; // skip this node
|
|
433
484
|
}
|
|
485
|
+
const key = node.browseName.toString();
|
|
486
|
+
if (browseNameMap?.has(key)) {
|
|
487
|
+
continue; // skipping node with same browseName
|
|
488
|
+
}
|
|
489
|
+
browseNameMap?.add(key);
|
|
434
490
|
|
|
435
|
-
assert(reference.isForward);
|
|
436
|
-
assert(reference.referenceType instanceof NodeId, "" + reference.referenceType.toString());
|
|
491
|
+
// assert(reference.isForward);
|
|
492
|
+
// assert(reference.referenceType instanceof NodeId, "" + reference.referenceType.toString());
|
|
437
493
|
const options = {
|
|
438
494
|
namespace,
|
|
439
495
|
references: [new ReferenceImpl({ referenceType: reference.referenceType, isForward: false, nodeId: newParent.nodeId })],
|
|
440
496
|
copyAlsoModellingRules
|
|
441
497
|
};
|
|
442
498
|
|
|
499
|
+
dotrace &&
|
|
500
|
+
traceLog(
|
|
501
|
+
extraInfo.pad(),
|
|
502
|
+
"cloning => ",
|
|
503
|
+
reference.referenceType.toString({ addressSpace }),
|
|
504
|
+
"=>",
|
|
505
|
+
node.browseName.toString(),
|
|
506
|
+
chalk.magentaBright(node.typeDefinitionObj?.browseName.toString())
|
|
507
|
+
);
|
|
508
|
+
|
|
509
|
+
extraInfo.level += 4;
|
|
443
510
|
const clone = (node as UAVariable | UAMethod | UAObject).clone(options, optionalFilter, extraInfo);
|
|
511
|
+
extraInfo.level -= 4;
|
|
512
|
+
|
|
513
|
+
// also clone or instantiate interface members that may be required in the optionals
|
|
514
|
+
extraInfo.level++;
|
|
515
|
+
_cloneInterface(newParent, node, optionalFilter, extraInfo, browseNameMap);
|
|
516
|
+
extraInfo.level--;
|
|
444
517
|
|
|
445
518
|
if (extraInfo) {
|
|
446
519
|
extraInfo.registerClonedObject(node, clone);
|
|
@@ -448,24 +521,179 @@ function _clone_collection_new(
|
|
|
448
521
|
}
|
|
449
522
|
}
|
|
450
523
|
|
|
451
|
-
|
|
452
|
-
|
|
524
|
+
type UAInterface = UAObjectType;
|
|
525
|
+
function _extractInterfaces2(typeDefinitionNode: UAObjectType | UAVariableType, extraInfo: CloneExtraInfo): UAInterface[] {
|
|
526
|
+
if (
|
|
527
|
+
!typeDefinitionNode ||
|
|
528
|
+
(typeDefinitionNode.nodeId.namespace === 0 &&
|
|
529
|
+
(typeDefinitionNode.nodeId.value === ObjectTypeIds.BaseObjectType ||
|
|
530
|
+
typeDefinitionNode.nodeId.value === VariableTypeIds.BaseVariableType))
|
|
531
|
+
) {
|
|
532
|
+
return [];
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const addressSpace = typeDefinitionNode.addressSpace;
|
|
536
|
+
// example:
|
|
537
|
+
// FolderType
|
|
538
|
+
// FunctionalGroupType
|
|
539
|
+
// MachineryItemIdentificationType : IMachineryItemVendorNameplateType
|
|
540
|
+
// MachineIdentificationType : IMachineTagNameplateType, IMachineVendorNamePlateType
|
|
541
|
+
// MachineToolIdentificationType
|
|
542
|
+
//
|
|
543
|
+
//
|
|
544
|
+
// IMachineTagNameplateType -subTypeOf-> ITagNameplateType
|
|
545
|
+
// IMachineVendorNamePlateType -subTypeOf-> IMachineryItemVendorNamePlateType
|
|
546
|
+
// IMachineryItemVendorNamePlateType -subTypeOf-> IVendorNameplateType
|
|
547
|
+
const interfacesRef = typeDefinitionNode.findReferencesEx("HasInterface", BrowseDirection.Forward);
|
|
548
|
+
const interfaces = interfacesRef.map((r) => addressSpace.findNode(r.nodeId) as UAInterface);
|
|
549
|
+
|
|
550
|
+
const baseInterfaces: UAInterface[] = [];
|
|
551
|
+
for (const iface of interfaces) {
|
|
552
|
+
dotrace &&
|
|
553
|
+
traceLog(
|
|
554
|
+
extraInfo.pad(),
|
|
555
|
+
typeDefinitionNode.browseName.toString(),
|
|
556
|
+
" - has interface -> ",
|
|
557
|
+
iface.browseName.toString()
|
|
558
|
+
);
|
|
559
|
+
baseInterfaces.push(iface);
|
|
560
|
+
if (iface.subtypeOfObj) {
|
|
561
|
+
extraInfo.level++;
|
|
562
|
+
baseInterfaces.push(..._extractInterfaces2(iface.subtypeOfObj, extraInfo));
|
|
563
|
+
extraInfo.level--;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
interfaces.push(...baseInterfaces);
|
|
567
|
+
if (typeDefinitionNode.subtypeOfObj) {
|
|
568
|
+
dotrace &&
|
|
569
|
+
traceLog(
|
|
570
|
+
extraInfo.pad(),
|
|
571
|
+
typeDefinitionNode.browseName.toString(),
|
|
572
|
+
" - subtypef -> ",
|
|
573
|
+
typeDefinitionNode.subtypeOfObj.browseName.toString()
|
|
574
|
+
);
|
|
575
|
+
extraInfo.level++;
|
|
576
|
+
interfaces.push(..._extractInterfaces2(typeDefinitionNode.subtypeOfObj, extraInfo));
|
|
577
|
+
extraInfo.level--;
|
|
578
|
+
}
|
|
579
|
+
const dedupedInterfaces = [...new Set(interfaces)];
|
|
580
|
+
|
|
581
|
+
dotrace &&
|
|
582
|
+
traceLog(
|
|
583
|
+
extraInfo.pad(),
|
|
584
|
+
chalk.yellow("Interface for ", typeDefinitionNode.browseName.toString()),
|
|
585
|
+
"=",
|
|
586
|
+
dedupedInterfaces.map((x) => x.browseName.toString()).join(" ")
|
|
587
|
+
);
|
|
588
|
+
return dedupedInterfaces;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/*
|
|
592
|
+
|
|
593
|
+
// also find all related interfaces
|
|
594
|
+
if (false && typeDefinitionNode) {
|
|
595
|
+
dotrace && tracelog("typeDefinitionNode = ", typeDefinitionNode.browseName.toString());
|
|
596
|
+
const interfaces = _extractInterfaces(typeDefinitionNode);
|
|
597
|
+
for (const interfaceNode of interfaces) {
|
|
598
|
+
dotrace && tracelog(" adding member of interface ", interfaceNode.browseName.toString());
|
|
599
|
+
const fromInterface = interfaceNode.findReferencesEx("Aggregates", BrowseDirection.Forward);
|
|
600
|
+
dotrace && tracelog(
|
|
601
|
+
" B ",
|
|
602
|
+
fromInterface.map((r) => r.toString({ addressSpace }) + " " + r.node!.browseName.toString()).join("\n")
|
|
603
|
+
);
|
|
604
|
+
add(fromInterface);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
*/
|
|
608
|
+
|
|
609
|
+
function _crap_extractInterfaces(typeDefinitionNode: UAObjectType | UAVariableType, extraInfo: CloneExtraInfo): UAInterface[] {
|
|
610
|
+
if (
|
|
611
|
+
typeDefinitionNode.nodeId.namespace === 0 &&
|
|
612
|
+
(typeDefinitionNode.nodeId.value === ObjectTypeIds.BaseObjectType ||
|
|
613
|
+
typeDefinitionNode.nodeId.value === VariableTypeIds.BaseVariableType)
|
|
614
|
+
) {
|
|
615
|
+
return [];
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
const addressSpace = typeDefinitionNode.addressSpace;
|
|
619
|
+
// example:
|
|
620
|
+
// FolderType
|
|
621
|
+
// FunctionalGroupType
|
|
622
|
+
// MachineryItemIdentificationType : IMachineryItemVendorNameplateType
|
|
623
|
+
// MachineIdentificationType : IMachineTagNameplateType, IMachineVendorNamePlateType
|
|
624
|
+
// MachineToolIdentificationType
|
|
625
|
+
//
|
|
626
|
+
//
|
|
627
|
+
// IMachineTagNameplateType -subTypeOf-> ITagNameplateType
|
|
628
|
+
// IMachineVendorNamePlateType -subTypeOf-> IMachineryItemVendorNamePlateType
|
|
629
|
+
// IMachineryItemVendorNamePlateType -subTypeOf-> IVendorNameplateType
|
|
630
|
+
const interfacesRef = typeDefinitionNode.findReferencesEx("HasInterface", BrowseDirection.Forward);
|
|
631
|
+
const interfaces = interfacesRef.map((r) => r.node! as UAInterface);
|
|
632
|
+
for (const iface of interfaces) {
|
|
633
|
+
dotrace && traceLog(extraInfo.pad(), " interface ", iface.browseName.toString());
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
return interfaces;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
function _cloneInterface(
|
|
453
640
|
newParent: BaseNode,
|
|
641
|
+
node: UAObject | UAVariable | UAMethod,
|
|
642
|
+
optionalFilter: CloneFilter,
|
|
643
|
+
extraInfo: CloneExtraInfo,
|
|
644
|
+
browseNameMap: Set<string>
|
|
645
|
+
): void {
|
|
646
|
+
dotrace &&
|
|
647
|
+
traceLog(
|
|
648
|
+
extraInfo?.pad(),
|
|
649
|
+
chalk.green("-------------------- now cloning interfaces of ", node.browseName.toString(), node.nodeId.toString())
|
|
650
|
+
);
|
|
651
|
+
|
|
652
|
+
extraInfo = extraInfo || defaultExtraInfo;
|
|
653
|
+
const addressSpace = node.addressSpace;
|
|
654
|
+
const typeDefinitionNode = node.typeDefinitionObj;
|
|
655
|
+
if (!typeDefinitionNode) {
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
dotrace && traceLog(extraInfo.pad(), " --- {");
|
|
659
|
+
const interfaces = _extractInterfaces2(typeDefinitionNode, extraInfo);
|
|
660
|
+
dotrace && traceLog(extraInfo.pad(), " --- }");
|
|
661
|
+
dotrace && traceLog(extraInfo?.pad(), chalk.green("-------------------- interfaces are ", interfaces.length));
|
|
662
|
+
|
|
663
|
+
const localFilter = optionalFilter.filterFor(node);
|
|
664
|
+
|
|
665
|
+
for (const iface of interfaces) {
|
|
666
|
+
const aggregates = iface.findReferencesEx("Aggregates", BrowseDirection.Forward);
|
|
667
|
+
dotrace &&
|
|
668
|
+
traceLog(
|
|
669
|
+
extraInfo.pad(),
|
|
670
|
+
chalk.magentaBright(" interface ", iface.browseName.toString()),
|
|
671
|
+
"\n" + extraInfo?.pad(),
|
|
672
|
+
aggregates.map((r) => r.toString({ addressSpace })).join("\n" + extraInfo?.pad())
|
|
673
|
+
);
|
|
674
|
+
_clone_collection_new(newParent, aggregates, false, localFilter, extraInfo, browseNameMap);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
export function _clone_children_references(
|
|
678
|
+
node: UAObject | UAVariable | UAMethod | UAObjectType | UAVariableType,
|
|
679
|
+
newParent: UAObject | UAVariable | UAMethod,
|
|
454
680
|
copyAlsoModellingRules: boolean,
|
|
455
|
-
optionalFilter
|
|
456
|
-
extraInfo
|
|
681
|
+
optionalFilter: CloneFilter,
|
|
682
|
+
extraInfo: CloneExtraInfo,
|
|
683
|
+
browseNameMap: Set<string>
|
|
457
684
|
): void {
|
|
458
685
|
// find all reference that derives from the Aggregates
|
|
459
686
|
const aggregatesRef = node.findReferencesEx("Aggregates", BrowseDirection.Forward);
|
|
460
|
-
_clone_collection_new(newParent, aggregatesRef, copyAlsoModellingRules, optionalFilter, extraInfo);
|
|
687
|
+
_clone_collection_new(newParent, aggregatesRef, copyAlsoModellingRules, optionalFilter, extraInfo, browseNameMap);
|
|
461
688
|
}
|
|
462
689
|
|
|
463
690
|
export function _clone_non_hierarchical_references(
|
|
464
691
|
node: BaseNode,
|
|
465
692
|
newParent: BaseNode,
|
|
466
693
|
copyAlsoModellingRules: boolean,
|
|
467
|
-
optionalFilter
|
|
468
|
-
extraInfo
|
|
694
|
+
optionalFilter: CloneFilter,
|
|
695
|
+
extraInfo: CloneExtraInfo,
|
|
696
|
+
browseNameMap: Set<string>
|
|
469
697
|
): void {
|
|
470
698
|
// clone only some non hierarchical_references that we do want to clone
|
|
471
699
|
// such as:
|
|
@@ -474,7 +702,7 @@ export function _clone_non_hierarchical_references(
|
|
|
474
702
|
assert(newParent instanceof BaseNodeImpl);
|
|
475
703
|
// find all reference that derives from the HasSubStateMachine
|
|
476
704
|
const references = node.findReferencesEx("HasSubStateMachine", BrowseDirection.Forward);
|
|
477
|
-
_clone_collection_new(newParent, references, copyAlsoModellingRules, optionalFilter, extraInfo);
|
|
705
|
+
_clone_collection_new(newParent, references, copyAlsoModellingRules, optionalFilter, extraInfo, browseNameMap);
|
|
478
706
|
}
|
|
479
707
|
|
|
480
708
|
/**
|
|
@@ -485,8 +713,8 @@ export function _clone<T extends UAObject | UAVariable | UAMethod>(
|
|
|
485
713
|
this: T,
|
|
486
714
|
Constructor: new (options: any) => T,
|
|
487
715
|
options: CloneOptions,
|
|
488
|
-
optionalFilter
|
|
489
|
-
extraInfo
|
|
716
|
+
optionalFilter: CloneFilter,
|
|
717
|
+
extraInfo: CloneExtraInfo
|
|
490
718
|
): T {
|
|
491
719
|
assert(typeof Constructor === "function");
|
|
492
720
|
assert(options !== null && typeof options === "object");
|
|
@@ -544,9 +772,31 @@ export function _clone<T extends UAObject | UAVariable | UAMethod>(
|
|
|
544
772
|
|
|
545
773
|
options.copyAlsoModellingRules = options.copyAlsoModellingRules || false;
|
|
546
774
|
|
|
547
|
-
const newFilter = optionalFilter
|
|
548
|
-
|
|
549
|
-
|
|
775
|
+
const newFilter = optionalFilter.filterFor(cloneObj);
|
|
776
|
+
|
|
777
|
+
const browseNameMap = new Set<string>();
|
|
778
|
+
_clone_children_references(this, cloneObj, options.copyAlsoModellingRules, newFilter!, extraInfo, browseNameMap);
|
|
779
|
+
|
|
780
|
+
//
|
|
781
|
+
let typeDefinitionNode: UAVariableType | UAObjectType | null = this.typeDefinitionObj;
|
|
782
|
+
while (typeDefinitionNode) {
|
|
783
|
+
dotrace &&
|
|
784
|
+
traceLog(
|
|
785
|
+
extraInfo?.pad(),
|
|
786
|
+
chalk.blueBright("---------------------- Exploring ", typeDefinitionNode.browseName.toString())
|
|
787
|
+
);
|
|
788
|
+
_clone_children_references(
|
|
789
|
+
typeDefinitionNode,
|
|
790
|
+
cloneObj,
|
|
791
|
+
options.copyAlsoModellingRules,
|
|
792
|
+
newFilter,
|
|
793
|
+
extraInfo,
|
|
794
|
+
browseNameMap
|
|
795
|
+
);
|
|
796
|
+
typeDefinitionNode = typeDefinitionNode.subtypeOfObj;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
_clone_non_hierarchical_references(this, cloneObj, options.copyAlsoModellingRules, newFilter, extraInfo, browseNameMap);
|
|
550
800
|
|
|
551
801
|
cloneObj.propagate_back_references();
|
|
552
802
|
|
|
@@ -584,7 +834,7 @@ function _remove_HierarchicalReference(node: BaseNode, reference: UAReference) {
|
|
|
584
834
|
if (referenceType.isSupertypeOf(HierarchicalReferencesType!)) {
|
|
585
835
|
assert(reference.isForward);
|
|
586
836
|
const targetNode = ReferenceImpl.resolveReferenceNode(addressSpace, reference);
|
|
587
|
-
// Xx
|
|
837
|
+
// Xx dotrace && tracelog(" adding object to map");
|
|
588
838
|
delete _cache._childByNameMap[targetNode.browseName!.name!.toString()];
|
|
589
839
|
}
|
|
590
840
|
}
|
|
@@ -622,7 +872,7 @@ function _makeReferenceDescription(addressSpace: IAddressSpace, reference: UARef
|
|
|
622
872
|
};
|
|
623
873
|
}
|
|
624
874
|
if (data.typeDefinition === null) {
|
|
625
|
-
data.typeDefinition = NodeId
|
|
875
|
+
data.typeDefinition = new NodeId();
|
|
626
876
|
}
|
|
627
877
|
const referenceDescription = new ReferenceDescription(data);
|
|
628
878
|
return referenceDescription;
|
|
@@ -665,18 +915,14 @@ export function BaseNode_add_backward_reference(this: BaseNode, reference: UARef
|
|
|
665
915
|
// istanbul ignore next
|
|
666
916
|
if (_private._back_referenceIdx[h]) {
|
|
667
917
|
const opts = { addressSpace: this.addressSpace };
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
// tslint:disable-next-line:no-console
|
|
673
|
-
console.warn(" already found in ===>");
|
|
674
|
-
// tslint:disable-next-line:no-console
|
|
675
|
-
console.warn(
|
|
918
|
+
warningLog(" Warning !", this.browseName.toString());
|
|
919
|
+
warningLog(" ", reference.toString(opts));
|
|
920
|
+
warningLog(" already found in ===>");
|
|
921
|
+
warningLog(
|
|
676
922
|
(Object.values(_private._back_referenceIdx) as UAReference[]).map((c: UAReference) => c.toString(opts)).join("\n")
|
|
677
923
|
);
|
|
678
924
|
// tslint:disable-next-line:no-console
|
|
679
|
-
|
|
925
|
+
warningLog("===>");
|
|
680
926
|
throw new Error("reference exists already in _back_references");
|
|
681
927
|
}
|
|
682
928
|
|
package/src/event_data.ts
CHANGED
package/src/namespace_impl.ts
CHANGED
|
@@ -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
|
|
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 :
|
|
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
|
|
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).$
|
|
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).$
|
|
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(
|
|
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
|
-
|
|
761
|
-
|
|
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,
|
|
799
|
+
function _dumpUADataTypeDefinition(xw: XmlWriter, uaDataType: UADataType) {
|
|
792
800
|
// to do remove DataType from base class
|
|
793
|
-
|
|
794
|
-
const definition =
|
|
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",
|
|
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",
|
|
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
|
}
|
|
@@ -44,6 +44,7 @@ function dumpDataTypeStructure(
|
|
|
44
44
|
addressSpace: IAddressSpace,
|
|
45
45
|
map: { [key: number]: string },
|
|
46
46
|
structureDefinition: StructureDefinition,
|
|
47
|
+
structureDefinitionBase: StructureDefinition | undefined| null,
|
|
47
48
|
name: string,
|
|
48
49
|
doc?: string
|
|
49
50
|
): void {
|
|
@@ -56,8 +57,14 @@ function dumpDataTypeStructure(
|
|
|
56
57
|
xw.text(doc);
|
|
57
58
|
xw.endElement();
|
|
58
59
|
}
|
|
60
|
+
|
|
61
|
+
const fields = structureDefinition.fields || [];
|
|
62
|
+
// get base class
|
|
63
|
+
const nbFieldsInBase = structureDefinitionBase? structureDefinitionBase.fields?.length || 0 : 0;
|
|
64
|
+
|
|
59
65
|
let optionalsCount = 0;
|
|
60
|
-
for (
|
|
66
|
+
for (let index = nbFieldsInBase; index < fields.length; index ++) {
|
|
67
|
+
const f= fields [index];
|
|
61
68
|
if (f.isOptional) {
|
|
62
69
|
xw.startElement("opc:Field");
|
|
63
70
|
xw.writeAttribute("Name", f.name + "Specified");
|
|
@@ -90,7 +97,9 @@ function dumpDataTypeStructure(
|
|
|
90
97
|
xw.endElement();
|
|
91
98
|
}
|
|
92
99
|
}
|
|
93
|
-
for (
|
|
100
|
+
for (let index = nbFieldsInBase; index < fields.length; index ++) {
|
|
101
|
+
const f= fields [index];
|
|
102
|
+
|
|
94
103
|
const isArray = f.valueRank > 0 && f.arrayDimensions?.length;
|
|
95
104
|
|
|
96
105
|
if (isArray) {
|
|
@@ -124,12 +133,13 @@ function dumpDataTypeToBSD(xw: XmlWriter, dataType: UADataType, map: { [key: num
|
|
|
124
133
|
|
|
125
134
|
const name: string = dataType.browseName.name!;
|
|
126
135
|
|
|
127
|
-
const
|
|
128
|
-
if (
|
|
129
|
-
|
|
136
|
+
const definition = dataType.getDefinition();
|
|
137
|
+
if (definition instanceof StructureDefinition) {
|
|
138
|
+
const structureDefinitionBase = dataType.subtypeOfObj?.getStructureDefinition();
|
|
139
|
+
dumpDataTypeStructure(xw, addressSpace, map, definition, structureDefinitionBase, name);
|
|
130
140
|
}
|
|
131
|
-
if (
|
|
132
|
-
dumpEnumeratedType(xw,
|
|
141
|
+
if (definition instanceof EnumDefinition) {
|
|
142
|
+
dumpEnumeratedType(xw, definition, name);
|
|
133
143
|
}
|
|
134
144
|
}
|
|
135
145
|
|
package/src/reference_impl.ts
CHANGED
|
@@ -53,9 +53,9 @@ function _w(str: string, width: number): string {
|
|
|
53
53
|
return (str + " ").substr(0, width);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
function _localCoerceToNodeID(nodeIdLike: string |
|
|
57
|
-
if ((nodeIdLike
|
|
58
|
-
return (nodeIdLike as
|
|
56
|
+
function _localCoerceToNodeID(nodeIdLike: string | NodeIdLike | { nodeId: NodeId }): NodeId {
|
|
57
|
+
if (Object.prototype.hasOwnProperty.call(nodeIdLike, "nodeId")) {
|
|
58
|
+
return (nodeIdLike as { nodeId: NodeId }).nodeId;
|
|
59
59
|
}
|
|
60
60
|
return coerceNodeId(nodeIdLike);
|
|
61
61
|
}
|