@vitormnm/node-red-simple-opcua 1.3.2 → 1.4.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.
@@ -4,6 +4,7 @@ const {
4
4
  AttributeIds,
5
5
  BrowseDirection,
6
6
  coerceNodeId,
7
+ VariantArrayType,
7
8
  DataType,
8
9
  MessageSecurityMode,
9
10
  NodeClass,
@@ -13,6 +14,18 @@ const {
13
14
  Variant
14
15
  } = require("node-opcua");
15
16
 
17
+ // Mapa DataType → TypedArray nativo para escrita eficiente no servidor OPC UA
18
+ const TYPED_ARRAY_MAP = {
19
+ [DataType.SByte]: Int8Array,
20
+ [DataType.Byte]: Uint8Array,
21
+ [DataType.Int16]: Int16Array,
22
+ [DataType.UInt16]: Uint16Array,
23
+ [DataType.Int32]: Int32Array,
24
+ [DataType.UInt32]: Uint32Array,
25
+ [DataType.Float]: Float32Array,
26
+ [DataType.Double]: Float64Array,
27
+ };
28
+
16
29
  function resolveSecurityPolicy(name) {
17
30
  return SecurityPolicy[name] || SecurityPolicy.None;
18
31
  }
@@ -61,19 +74,26 @@ function inferTypeName(value) {
61
74
  if (value instanceof Date) {
62
75
  return "DateTime";
63
76
  }
64
- if (Buffer.isBuffer(value)) {
77
+ if (Buffer.isBuffer(value) || (value && typeof value === 'object' && value.type === 'Buffer' && Array.isArray(value.data))) {
65
78
  return "ByteString";
66
79
  }
67
80
  return "String";
68
81
  }
69
82
 
70
83
  function coerceValue(value, typeName) {
84
+
85
+ if (Array.isArray(value)) {
86
+ return value.map(element => coerceValue(element, typeName));
87
+ }
88
+
89
+
71
90
  switch (typeName) {
72
91
  case "Boolean":
73
92
  if (typeof value === "string") {
74
93
  return value.trim().toLowerCase() === "true";
75
94
  }
76
95
  return Boolean(value);
96
+
77
97
  case "Byte":
78
98
  case "SByte":
79
99
  case "Int16":
@@ -81,16 +101,44 @@ function coerceValue(value, typeName) {
81
101
  case "UInt16":
82
102
  case "UInt32":
83
103
  return Number.parseInt(value, 10);
104
+
84
105
  case "Int64":
85
106
  case "UInt64":
86
107
  return BigInt(value);
108
+
87
109
  case "Float":
88
110
  case "Double":
89
111
  return Number.parseFloat(value);
112
+
113
+ case "ByteString":
114
+ if (value && typeof value === "object" && value.type === "Buffer" && Array.isArray(value.data)) {
115
+ return Buffer.from(value.data);
116
+ }
117
+
118
+ if (Buffer.isBuffer(value)) {
119
+ return value;
120
+ }
121
+
122
+ if (value instanceof Uint8Array) {
123
+ return Buffer.from(value);
124
+ }
125
+
126
+ if (Array.isArray(value)) {
127
+ return Buffer.from(value);
128
+ }
129
+
130
+ if (typeof value === "string") {
131
+ return Buffer.from(value, "base64");
132
+ }
133
+
134
+ return Buffer.alloc(0);
135
+
90
136
  case "DateTime":
91
137
  return value instanceof Date ? value : new Date(value);
138
+
92
139
  case "String":
93
140
  return value === undefined || value === null ? "" : String(value);
141
+
94
142
  default:
95
143
  return value;
96
144
  }
@@ -104,8 +152,26 @@ function buildVariantFromItem(item, fallbackTypeName) {
104
152
  throw new Error("Unsupported OPC UA data type: " + typeName);
105
153
  }
106
154
 
155
+ const isArray = Array.isArray(item.value);
156
+
157
+ if (isArray) {
158
+ // Coerce cada elemento e converte para TypedArray se disponível
159
+ const coercedArray = coerceValue(item.value, typeName); // retorna JS Array
160
+ const TypedArrayCtor = TYPED_ARRAY_MAP[dataType];
161
+
162
+ return new Variant({
163
+ dataType,
164
+ arrayType: VariantArrayType.Array,
165
+ value: TypedArrayCtor
166
+ ? TypedArrayCtor.from(coercedArray) // Int32Array, Float32Array, etc.
167
+ : coercedArray // String[], Boolean[], DateTime[]
168
+ });
169
+ }
170
+
171
+ // Escalar — comportamento original preservado
107
172
  return new Variant({
108
173
  dataType,
174
+ arrayType: VariantArrayType.Scalar,
109
175
  value: coerceValue(item.value, typeName)
110
176
  });
111
177
  }
@@ -317,4 +383,4 @@ module.exports = {
317
383
  resolveSecurityMode,
318
384
  resolveSecurityPolicy,
319
385
  statusCodeToString
320
- };
386
+ };