@vitormnm/node-red-simple-opcua 1.8.0 → 1.8.1

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.
@@ -584,11 +584,11 @@ async function browseRecursiveNode(session, root) {
584
584
  }
585
585
 
586
586
  const methods = allItems.filter(item => item.nodeClass === "Method");
587
- for (const method of methods) {
587
+ await Promise.all(methods.map(async (method) => {
588
588
  const definition = await readMethodArguments(session, method.nodeID);
589
589
  method.inputArguments = definition.inputArguments;
590
590
  method.outputArguments = definition.outputArguments;
591
- }
591
+ }));
592
592
  }
593
593
 
594
594
  return {
@@ -591,12 +591,22 @@ async function getMethodArgumentDefinition(session, methodNodeId, cache) {
591
591
  return definition;
592
592
  }
593
593
 
594
+ const PRIMITIVE_TYPES = new Set([
595
+ "Null", "Boolean", "SByte", "Byte", "Int16", "UInt16", "Int32", "UInt32", "Int64", "UInt64",
596
+ "Float", "Double", "String", "DateTime", "Guid", "ByteString", "XmlElement",
597
+ "NodeId", "ExpandedNodeId", "StatusCode", "QualifiedName", "LocalizedText"
598
+ ]);
599
+
594
600
  async function enrichItemResultWithEnumeration(result, session, cache, nodeId) {
595
601
  const type = result.type || result.dataType;
596
602
  if (!type) {
597
603
  return result;
598
604
  }
599
605
 
606
+ if (result.dataType && PRIMITIVE_TYPES.has(result.dataType)) {
607
+ return result;
608
+ }
609
+
600
610
  const isStandardEnum = type === "Int32" || type === "Enumeration";
601
611
  const isCustomNodeId = typeof type === "string" && (type.includes("i=") || type.includes("ns="));
602
612
 
@@ -610,88 +620,83 @@ async function enrichItemResultWithEnumeration(result, session, cache, nodeId) {
610
620
 
611
621
  try {
612
622
  const cacheKeyType = "dt:" + nodeId;
613
- let dtNodeId = cache ? cache.get(cacheKeyType) : undefined;
614
- if (dtNodeId === undefined) {
615
- const isNodeIdLike = result.dataType && (
616
- typeof result.dataType !== "string" ||
617
- result.dataType.includes("i=") ||
618
- result.dataType.includes("ns=")
619
- );
620
- if (isNodeIdLike) {
621
- try {
622
- dtNodeId = coerceNodeId(result.dataType);
623
- } catch (e) {
624
- dtNodeId = undefined;
623
+ let dtNodeIdPromise = cache ? cache.get(cacheKeyType) : undefined;
624
+
625
+ if (dtNodeIdPromise === undefined) {
626
+ dtNodeIdPromise = (async () => {
627
+ const isNodeIdLike = result.dataType && (
628
+ typeof result.dataType !== "string" ||
629
+ result.dataType.includes("i=") ||
630
+ result.dataType.includes("ns=")
631
+ );
632
+ if (isNodeIdLike) {
633
+ try {
634
+ return coerceNodeId(result.dataType);
635
+ } catch (e) {
636
+ return null;
637
+ }
625
638
  }
626
- }
627
- if (dtNodeId === undefined) {
628
639
  const dv = await session.read({
629
640
  nodeId: nodeId,
630
641
  attributeId: AttributeIds.DataType
631
642
  });
632
- if (dv.statusCode.isGood()) {
633
- dtNodeId = dv.value.value;
634
- if (cache) cache.set(cacheKeyType, dtNodeId);
635
- } else {
636
- if (cache) cache.set(cacheKeyType, null);
637
- }
638
- }
643
+ return dv.statusCode.isGood() ? dv.value.value : null;
644
+ })();
645
+ if (cache) cache.set(cacheKeyType, dtNodeIdPromise);
639
646
  }
640
647
 
648
+ const dtNodeId = await dtNodeIdPromise;
641
649
  if (!dtNodeId) return result;
642
650
 
643
651
  const cacheKeyStrings = "enumStrings:" + dtNodeId.toString();
644
- let enumStrings = cache ? cache.get(cacheKeyStrings) : undefined;
652
+ let enumStringsPromise = cache ? cache.get(cacheKeyStrings) : undefined;
645
653
 
646
- if (enumStrings === undefined) {
647
- const browseResult = await session.browse({
648
- nodeId: dtNodeId,
649
- referenceTypeId: "HasProperty",
650
- browseDirection: BrowseDirection.Forward,
651
- includeSubtypes: true,
652
- resultMask: 63
653
- });
654
-
655
- const enumStringsRef = browseResult.references ? browseResult.references.find(r => r.browseName.name === "EnumStrings") : null;
656
- const enumValuesRef = browseResult.references ? browseResult.references.find(r => r.browseName.name === "EnumValues") : null;
657
-
658
- if (enumStringsRef) {
659
- const dataValue = await session.read({
660
- nodeId: enumStringsRef.nodeId,
661
- attributeId: AttributeIds.Value
654
+ if (enumStringsPromise === undefined) {
655
+ enumStringsPromise = (async () => {
656
+ const browseResult = await session.browse({
657
+ nodeId: dtNodeId,
658
+ referenceTypeId: "HasProperty",
659
+ browseDirection: BrowseDirection.Forward,
660
+ includeSubtypes: true,
661
+ resultMask: 63
662
662
  });
663
- if (dataValue.statusCode.isGood() && dataValue.value.value) {
664
- enumStrings = dataValue.value.value.map(lt => lt.text);
665
- if (cache) cache.set(cacheKeyStrings, enumStrings);
666
- } else {
667
- if (cache) cache.set(cacheKeyStrings, null);
668
- }
669
- } else if (enumValuesRef) {
670
- const dataValue = await session.read({
671
- nodeId: enumValuesRef.nodeId,
672
- attributeId: AttributeIds.Value
673
- });
674
- if (dataValue.statusCode.isGood() && dataValue.value.value) {
675
- const map = {};
676
- dataValue.value.value.forEach(ev => {
677
- let val;
678
- if (Array.isArray(ev.value) && ev.value.length === 2) {
679
- val = ev.value[1]; // low part of Int64
680
- } else {
681
- val = Number(ev.value);
682
- }
683
- map[val] = ev.displayName.text;
663
+
664
+ const enumStringsRef = browseResult.references ? browseResult.references.find(r => r.browseName.name === "EnumStrings") : null;
665
+ const enumValuesRef = browseResult.references ? browseResult.references.find(r => r.browseName.name === "EnumValues") : null;
666
+
667
+ if (enumStringsRef) {
668
+ const dataValue = await session.read({
669
+ nodeId: enumStringsRef.nodeId,
670
+ attributeId: AttributeIds.Value
684
671
  });
685
- enumStrings = map;
686
- if (cache) cache.set(cacheKeyStrings, enumStrings);
687
- } else {
688
- if (cache) cache.set(cacheKeyStrings, null);
672
+ if (dataValue.statusCode.isGood() && dataValue.value.value) {
673
+ return dataValue.value.value.map(lt => lt.text);
674
+ }
675
+ } else if (enumValuesRef) {
676
+ const dataValue = await session.read({
677
+ nodeId: enumValuesRef.nodeId,
678
+ attributeId: AttributeIds.Value
679
+ });
680
+ if (dataValue.statusCode.isGood() && dataValue.value.value) {
681
+ const map = {};
682
+ dataValue.value.value.forEach(ev => {
683
+ let val;
684
+ if (Array.isArray(ev.value) && ev.value.length === 2) {
685
+ val = ev.value[1]; // low part of Int64
686
+ } else {
687
+ val = Number(ev.value);
688
+ }
689
+ map[val] = ev.displayName.text;
690
+ });
691
+ return map;
692
+ }
689
693
  }
690
- } else {
691
- if (cache) cache.set(cacheKeyStrings, null);
692
- }
694
+ return null;
695
+ })();
696
+ if (cache) cache.set(cacheKeyStrings, enumStringsPromise);
693
697
  }
694
698
 
699
+ const enumStrings = await enumStringsPromise;
695
700
  if (enumStrings && enumStrings[result.value] !== undefined) {
696
701
  result.valueEnumeration = enumStrings[result.value];
697
702
  if (result.type) result.type = "Enumeration";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitormnm/node-red-simple-opcua",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },