node-opcua-address-space 2.98.2 → 2.100.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/loader/load_nodeset2.js +3 -4
- package/dist/source/loader/load_nodeset2.js.map +1 -1
- package/dist/src/base_node_private.d.ts +1 -1
- package/dist/src/base_node_private.js +52 -45
- package/dist/src/base_node_private.js.map +1 -1
- package/dist/src/ua_method_impl.js +1 -1
- package/dist/src/ua_method_impl.js.map +1 -1
- package/dist/src/ua_object_impl.js +2 -2
- package/dist/src/ua_object_impl.js.map +1 -1
- package/dist/src/ua_reference_type_impl.d.ts +1 -1
- package/dist/src/ua_variable_impl.d.ts +2 -2
- package/dist/src/ua_variable_impl.js +37 -21
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/src/ua_variable_type_impl.js +5 -215
- package/dist/src/ua_variable_type_impl.js.map +1 -1
- package/dist/tsconfig_common.tsbuildinfo +1 -1
- package/distHelpers/get_address_space_fixture.js +9 -1
- package/distHelpers/get_address_space_fixture.js.map +1 -1
- package/distHelpers/get_mini_address_space.d.ts +1 -1
- package/distHelpers/get_mini_address_space.js +1 -1
- package/distHelpers/get_mini_address_space.js.map +1 -1
- package/nodesets/mini.Nodeset2.xml +4736 -0
- package/package.json +33 -31
- package/source/loader/load_nodeset2.ts +4 -5
- package/source_nodejs/generate_address_space.ts +60 -0
- package/source_nodejs/index.ts +1 -0
- package/src/base_node_private.ts +111 -59
- package/src/ua_method_impl.ts +3 -3
- package/src/ua_object_impl.ts +5 -5
- package/src/ua_variable_impl.ts +84 -68
- package/src/ua_variable_type_impl.ts +18 -278
|
@@ -19,14 +19,17 @@ import {
|
|
|
19
19
|
UAReference,
|
|
20
20
|
UAVariable,
|
|
21
21
|
UAVariableType,
|
|
22
|
-
CloneFilter
|
|
22
|
+
CloneFilter,
|
|
23
|
+
CloneHelper,
|
|
24
|
+
reconstructFunctionalGroupType,
|
|
25
|
+
reconstructNonHierarchicalReferences
|
|
23
26
|
} from "node-opcua-address-space-base";
|
|
24
|
-
|
|
27
|
+
|
|
25
28
|
import { coerceQualifiedName, NodeClass, QualifiedName, BrowseDirection, AttributeIds } from "node-opcua-data-model";
|
|
26
29
|
import { DataValue, DataValueLike } from "node-opcua-data-value";
|
|
27
30
|
import { checkDebugFlag, make_debugLog, make_warningLog, make_errorLog } from "node-opcua-debug";
|
|
28
|
-
import { coerceNodeId,
|
|
29
|
-
import {
|
|
31
|
+
import { coerceNodeId, NodeId, NodeIdLike, sameNodeId } from "node-opcua-nodeid";
|
|
32
|
+
import { StatusCodes } from "node-opcua-status-code";
|
|
30
33
|
import { UInt32 } from "node-opcua-basic-types";
|
|
31
34
|
import { isNullOrUndefined } from "node-opcua-utils";
|
|
32
35
|
import { DataType, Variant, VariantArrayType, verifyRankAndDimensions } from "node-opcua-variant";
|
|
@@ -402,103 +405,6 @@ class MandatoryChildOrRequestedOptionalFilter implements CloneFilter {
|
|
|
402
405
|
}
|
|
403
406
|
}
|
|
404
407
|
|
|
405
|
-
/*
|
|
406
|
-
* @function _get_parent_as_VariableOrObjectType
|
|
407
|
-
* @param originalObject
|
|
408
|
-
* @return {null|BaseNode}
|
|
409
|
-
* @private
|
|
410
|
-
*/
|
|
411
|
-
function _get_parent_as_VariableOrObjectType(originalObject: BaseNode): UAVariableType | UAObjectType | null {
|
|
412
|
-
if (originalObject.nodeClass === NodeClass.Method) {
|
|
413
|
-
return null;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
const addressSpace = originalObject.addressSpace;
|
|
417
|
-
|
|
418
|
-
const parents = originalObject.findReferencesEx("HasChild", BrowseDirection.Inverse);
|
|
419
|
-
|
|
420
|
-
// istanbul ignore next
|
|
421
|
-
if (parents.length > 1) {
|
|
422
|
-
warningLog(" object ", originalObject.browseName.toString(), " has more than one parent !");
|
|
423
|
-
warningLog(originalObject.toString());
|
|
424
|
-
warningLog(" parents : ");
|
|
425
|
-
for (const parent of parents) {
|
|
426
|
-
warningLog(" ", parent.toString(), addressSpace.findNode(parent.nodeId)!.browseName.toString());
|
|
427
|
-
}
|
|
428
|
-
return null;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
assert(parents.length === 0 || parents.length === 1);
|
|
432
|
-
if (parents.length === 0) {
|
|
433
|
-
return null;
|
|
434
|
-
}
|
|
435
|
-
const theParent = addressSpace.findNode(parents[0]!.nodeId)!;
|
|
436
|
-
if (theParent && (theParent.nodeClass === NodeClass.VariableType || theParent.nodeClass === NodeClass.ObjectType)) {
|
|
437
|
-
return theParent as UAVariableType | UAObjectType;
|
|
438
|
-
}
|
|
439
|
-
return null;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
interface CloneInfo {
|
|
443
|
-
cloned: UAObject | UAVariable | UAMethod;
|
|
444
|
-
original: UAVariableType | UAObjectType;
|
|
445
|
-
}
|
|
446
|
-
class CloneHelper {
|
|
447
|
-
public level = 0;
|
|
448
|
-
private readonly mapOrgToClone: Map<string, CloneInfo> = new Map();
|
|
449
|
-
|
|
450
|
-
public pad(): string {
|
|
451
|
-
return " ".padEnd(this.level * 2, " ");
|
|
452
|
-
}
|
|
453
|
-
public registerClonedObject<TT extends UAVariableType | UAObjectType, T extends UAObject | UAVariable | UAMethod>(
|
|
454
|
-
objInType: TT,
|
|
455
|
-
clonedObj: T
|
|
456
|
-
) {
|
|
457
|
-
this.mapOrgToClone.set(objInType.nodeId.toString(), {
|
|
458
|
-
cloned: clonedObj,
|
|
459
|
-
original: objInType
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
//
|
|
463
|
-
// /-----------------------------\
|
|
464
|
-
// | AcknowledgeableConditionType |
|
|
465
|
-
// \-----------------------------/
|
|
466
|
-
// ^ |
|
|
467
|
-
// | +---------------------|- (EnabledState) (shadow element)
|
|
468
|
-
// |
|
|
469
|
-
// /-----------------------------\
|
|
470
|
-
// | AlarmConditionType |
|
|
471
|
-
// \-----------------------------/
|
|
472
|
-
// |
|
|
473
|
-
// +-------------------------------|- EnabledState <
|
|
474
|
-
//
|
|
475
|
-
// find also child object with the same browse name that are
|
|
476
|
-
// overridden in the SuperType
|
|
477
|
-
//
|
|
478
|
-
const origParent = _get_parent_as_VariableOrObjectType(objInType);
|
|
479
|
-
if (origParent) {
|
|
480
|
-
let base = origParent.subtypeOfObj;
|
|
481
|
-
while (base) {
|
|
482
|
-
const shadowChild = base.getChildByName(objInType.browseName) as UAObjectType | UAVariableType | null;
|
|
483
|
-
if (shadowChild) {
|
|
484
|
-
this.mapOrgToClone.set(shadowChild.nodeId.toString(), {
|
|
485
|
-
cloned: clonedObj,
|
|
486
|
-
original: shadowChild
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
base = base.subtypeOfObj;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
// find subTypeOf
|
|
493
|
-
}
|
|
494
|
-
public getCloned(original: UAVariableType | UAObjectType): UAObject | UAVariable | UAMethod | null {
|
|
495
|
-
const info = this.mapOrgToClone.get(original.nodeId.toString());
|
|
496
|
-
if (info) {
|
|
497
|
-
return info.cloned;
|
|
498
|
-
}
|
|
499
|
-
return null;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
408
|
// install properties and components on a instantiated Object
|
|
503
409
|
//
|
|
504
410
|
// based on their ModelingRule
|
|
@@ -514,7 +420,7 @@ function _initialize_properties_and_components<B extends UAObject | UAVariable |
|
|
|
514
420
|
typeDefinitionNode: T,
|
|
515
421
|
copyAlsoModellingRules: boolean,
|
|
516
422
|
optionalsMap: OptionalMap,
|
|
517
|
-
extraInfo: CloneHelper,
|
|
423
|
+
extraInfo: CloneHelper,
|
|
518
424
|
browseNameMap: Set<string>
|
|
519
425
|
) {
|
|
520
426
|
if (doDebug) {
|
|
@@ -539,7 +445,6 @@ function _initialize_properties_and_components<B extends UAObject | UAVariable |
|
|
|
539
445
|
typeDefinitionNode.browseName.toString()
|
|
540
446
|
);
|
|
541
447
|
|
|
542
|
-
|
|
543
448
|
_clone_hierarchical_references(typeDefinitionNode, instance, copyAlsoModellingRules, filter, extraInfo, browseNameMap);
|
|
544
449
|
|
|
545
450
|
// now apply recursion on baseTypeDefinition to get properties and components from base class
|
|
@@ -633,192 +538,27 @@ export function assertUnusedChildBrowseName(addressSpace: AddressSpacePrivate, o
|
|
|
633
538
|
exports.assertUnusedChildBrowseName = assertUnusedChildBrowseName;
|
|
634
539
|
exports.initialize_properties_and_components = initialize_properties_and_components;
|
|
635
540
|
|
|
636
|
-
const hasTypeDefinitionNodeId = makeNodeId(ReferenceTypeIds.HasTypeDefinition);
|
|
637
|
-
const hasModellingRuleNodeId = makeNodeId(ReferenceTypeIds.HasModellingRule);
|
|
638
|
-
|
|
639
|
-
/**
|
|
640
|
-
* remove unwanted reference such as HasTypeDefinition and HasModellingRule
|
|
641
|
-
* from the list
|
|
642
|
-
*/
|
|
643
|
-
function _remove_unwanted_ref(references: UAReference[]): UAReference[] {
|
|
644
|
-
// filter out HasTypeDefinition (i=40) , HasModellingRule (i=37);
|
|
645
|
-
references = references.filter(
|
|
646
|
-
(reference: UAReference) =>
|
|
647
|
-
!sameNodeId(reference.referenceType, hasTypeDefinitionNodeId) &&
|
|
648
|
-
!sameNodeId(reference.referenceType, hasModellingRuleNodeId)
|
|
649
|
-
);
|
|
650
|
-
return references;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
/**
|
|
654
|
-
*
|
|
655
|
-
*/
|
|
656
|
-
function findNonHierarchicalReferences(originalObject: BaseNode): UAReference[] {
|
|
657
|
-
// todo: MEMOIZE this method
|
|
658
|
-
const addressSpace: IAddressSpace = originalObject.addressSpace;
|
|
659
|
-
const referenceId = addressSpace.findReferenceType("NonHierarchicalReferences");
|
|
660
|
-
if (!referenceId) {
|
|
661
|
-
return [];
|
|
662
|
-
}
|
|
663
|
-
assert(referenceId);
|
|
664
|
-
|
|
665
|
-
// we need to explore the non hierarchical references backwards
|
|
666
|
-
let references = originalObject.findReferencesEx("NonHierarchicalReferences", BrowseDirection.Inverse);
|
|
667
|
-
|
|
668
|
-
references = ([] as UAReference[]).concat(
|
|
669
|
-
references,
|
|
670
|
-
originalObject.findReferencesEx("HasEventSource", BrowseDirection.Inverse)
|
|
671
|
-
);
|
|
672
|
-
|
|
673
|
-
const parent = _get_parent_as_VariableOrObjectType(originalObject);
|
|
674
|
-
|
|
675
|
-
if (parent && parent.subtypeOfObj) {
|
|
676
|
-
// parent is a ObjectType or VariableType and is not a root type
|
|
677
|
-
assert(parent.nodeClass === NodeClass.VariableType || parent.nodeClass === NodeClass.ObjectType);
|
|
678
|
-
|
|
679
|
-
// let investigate the same child base child
|
|
680
|
-
const child = parent.subtypeOfObj!.getChildByName(originalObject.browseName);
|
|
681
|
-
|
|
682
|
-
if (child) {
|
|
683
|
-
const baseRef = findNonHierarchicalReferences(child);
|
|
684
|
-
references = ([] as UAReference[]).concat(references, baseRef);
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
// perform some cleanup
|
|
688
|
-
references = _remove_unwanted_ref(references);
|
|
689
|
-
|
|
690
|
-
return references;
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
function reconstructNonHierarchicalReferences(extraInfo: any): void {
|
|
694
|
-
const findImplementedObject = (ref: UAReference): CloneInfo | null =>
|
|
695
|
-
extraInfo.mapOrgToClone.get(ref.nodeId.toString()) || null;
|
|
696
|
-
|
|
697
|
-
// navigate through original objects to find those that are being references by node that
|
|
698
|
-
// have been cloned .
|
|
699
|
-
// this could be node organized by some FunctionalGroup
|
|
700
|
-
//
|
|
701
|
-
for (const { original, cloned } of extraInfo.mapOrgToClone.values()) {
|
|
702
|
-
// find NonHierarchical References on original object
|
|
703
|
-
const originalNonHierarchical = findNonHierarchicalReferences(original);
|
|
704
|
-
|
|
705
|
-
if (originalNonHierarchical.length === 0) {
|
|
706
|
-
continue;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
// istanbul ignore next
|
|
710
|
-
if (doDebug) {
|
|
711
|
-
debugLog(
|
|
712
|
-
" investigation ",
|
|
713
|
-
original.browseName.toString(),
|
|
714
|
-
cloned.nodeClass.toString(),
|
|
715
|
-
original.nodeClass.toString(),
|
|
716
|
-
original.nodeId.toString(),
|
|
717
|
-
cloned.nodeId.toString()
|
|
718
|
-
);
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
for (const ref of originalNonHierarchical) {
|
|
722
|
-
const info = findImplementedObject(ref);
|
|
723
|
-
|
|
724
|
-
// if the object pointed by this reference is also cloned ...
|
|
725
|
-
if (info) {
|
|
726
|
-
const originalDest = info.original;
|
|
727
|
-
const cloneDest = info.cloned;
|
|
728
|
-
|
|
729
|
-
// istanbul ignore next
|
|
730
|
-
if (doDebug) {
|
|
731
|
-
debugLog(
|
|
732
|
-
chalk.cyan(" adding reference "),
|
|
733
|
-
ref.referenceType,
|
|
734
|
-
" from cloned ",
|
|
735
|
-
cloned.nodeId.toString(),
|
|
736
|
-
cloned.browseName.toString(),
|
|
737
|
-
" to cloned ",
|
|
738
|
-
cloneDest.nodeId.toString(),
|
|
739
|
-
cloneDest.browseName.toString()
|
|
740
|
-
);
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
// restore reference
|
|
744
|
-
cloned.addReference({
|
|
745
|
-
isForward: false,
|
|
746
|
-
nodeId: cloneDest.nodeId,
|
|
747
|
-
referenceType: ref.referenceType
|
|
748
|
-
});
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
/**
|
|
755
|
-
* recreate functional group types according to type definition
|
|
756
|
-
*
|
|
757
|
-
* @method reconstructFunctionalGroupType
|
|
758
|
-
* @param baseType
|
|
759
|
-
*/
|
|
760
|
-
|
|
761
|
-
/* @example:
|
|
762
|
-
*
|
|
763
|
-
* MyDeviceType
|
|
764
|
-
* |
|
|
765
|
-
* +----------|- ParameterSet(BaseObjectType)
|
|
766
|
-
* | |
|
|
767
|
-
* | +-----------------|- Parameter1
|
|
768
|
-
* | ^
|
|
769
|
-
* +----------|- Config(FunctionalGroupType) |
|
|
770
|
-
* | |
|
|
771
|
-
* +-------- Organizes---+
|
|
772
|
-
*/
|
|
773
|
-
function reconstructFunctionalGroupType(extraInfo: any) {
|
|
774
|
-
// navigate through original objects to find those that are being organized by some FunctionalGroup
|
|
775
|
-
for (const { original, cloned } of extraInfo.mapOrgToClone.values()) {
|
|
776
|
-
const organizedByArray = original.findReferencesEx("Organizes", BrowseDirection.Inverse);
|
|
777
|
-
|
|
778
|
-
for (const ref of organizedByArray) {
|
|
779
|
-
const info = extraInfo.mapOrgToClone.get(ref.nodeId.toString());
|
|
780
|
-
if (!info) continue;
|
|
781
|
-
|
|
782
|
-
const folder = info.original;
|
|
783
|
-
if (folder.nodeClass !== NodeClass.Object) continue;
|
|
784
|
-
|
|
785
|
-
if (!folder.typeDefinitionObj) continue;
|
|
786
|
-
|
|
787
|
-
assert(folder.typeDefinitionObj.browseName.name.toString() === "FunctionalGroupType");
|
|
788
|
-
|
|
789
|
-
// now create the same reference with the instantiated function group
|
|
790
|
-
const destFolder = info.cloned as BaseNode;
|
|
791
|
-
|
|
792
|
-
assert(ref.referenceType);
|
|
793
|
-
|
|
794
|
-
// may be we should check that the referenceType is a subtype of Organizes
|
|
795
|
-
const alreadyExist = destFolder.findReferences(ref.referenceType, !ref.isForward).find((r) => r.nodeId === cloned.nodeId);
|
|
796
|
-
if (alreadyExist) {
|
|
797
|
-
continue;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
destFolder.addReference({
|
|
801
|
-
isForward: !ref.isForward,
|
|
802
|
-
nodeId: cloned.nodeId,
|
|
803
|
-
referenceType: ref.referenceType
|
|
804
|
-
});
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
|
|
809
541
|
export function initialize_properties_and_components<
|
|
810
542
|
B extends UAObject | UAVariable | UAMethod,
|
|
811
543
|
T extends UAVariableType | UAObjectType
|
|
812
544
|
>(instance: B, topMostType: T, nodeType: T, copyAlsoModellingRules: boolean, optionals?: string[]): void {
|
|
813
545
|
const extraInfo = new CloneHelper();
|
|
814
546
|
|
|
815
|
-
extraInfo.registerClonedObject(
|
|
547
|
+
extraInfo.registerClonedObject(instance, nodeType);
|
|
816
548
|
|
|
817
549
|
const optionalsMap = makeOptionalsMap(optionals);
|
|
818
550
|
|
|
819
551
|
const browseNameMap = new Set<string>();
|
|
820
552
|
|
|
821
|
-
_initialize_properties_and_components(
|
|
553
|
+
_initialize_properties_and_components(
|
|
554
|
+
instance,
|
|
555
|
+
topMostType,
|
|
556
|
+
nodeType,
|
|
557
|
+
copyAlsoModellingRules,
|
|
558
|
+
optionalsMap,
|
|
559
|
+
extraInfo,
|
|
560
|
+
browseNameMap
|
|
561
|
+
);
|
|
822
562
|
|
|
823
563
|
reconstructFunctionalGroupType(extraInfo);
|
|
824
564
|
|