@t0a5tbr0t/node-red-contrib-opcua 0.1.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 (82) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE +20 -0
  3. package/Readme.md +239 -0
  4. package/images/PROSYS-OPC-UA-EXAMPLE2.png +0 -0
  5. package/images/nodeopcua64.png +0 -0
  6. package/images/opcuanode.png +0 -0
  7. package/images/opcuanodeLogo64.png +0 -0
  8. package/opcua/101-opcuaitem.html +106 -0
  9. package/opcua/101-opcuaitem.js +82 -0
  10. package/opcua/102-opcuaclient.html +274 -0
  11. package/opcua/102-opcuaclient.js +2741 -0
  12. package/opcua/103-opcuabrowser.html +71 -0
  13. package/opcua/103-opcuabrowser.js +230 -0
  14. package/opcua/104-opcuaserver.html +261 -0
  15. package/opcua/104-opcuaserver.js +1844 -0
  16. package/opcua/105-opcuaendpoint.html +224 -0
  17. package/opcua/105-opcuaendpoint.js +64 -0
  18. package/opcua/106-opcuaevent.html +110 -0
  19. package/opcua/106-opcuaevent.js +50 -0
  20. package/opcua/107-opcuamethod.html +244 -0
  21. package/opcua/107-opcuamethod.js +521 -0
  22. package/opcua/108-opcuarights.html +223 -0
  23. package/opcua/108-opcuarights.js +156 -0
  24. package/opcua/109-opcuadiscovery.html +51 -0
  25. package/opcua/109-opcuadiscovery.js +180 -0
  26. package/opcua/dump_certificates.js +55 -0
  27. package/opcua/icons/opcuanode.png +0 -0
  28. package/opcua/icons/opcuanodeLogo.png +0 -0
  29. package/opcua/opcua-basics.js +1061 -0
  30. package/opcua/public/vendor/opc-foundation/binary/OPC.ISA95.Types.bsd.xml +141 -0
  31. package/opcua/public/vendor/opc-foundation/binary/Opc.Ua.Adi.Types.bsd.xml +76 -0
  32. package/opcua/public/vendor/opc-foundation/binary/Opc.Ua.Di.Types.bsd.xml +11 -0
  33. package/opcua/public/vendor/opc-foundation/binary/Opc.Ua.Gds.Types.bsd.xml +25 -0
  34. package/opcua/public/vendor/opc-foundation/binary/Opc.Ua.Types.bsd.xml +2391 -0
  35. package/opcua/public/vendor/opc-foundation/csv/AttributeIds.csv +22 -0
  36. package/opcua/public/vendor/opc-foundation/csv/NodeIds.csv +5746 -0
  37. package/opcua/public/vendor/opc-foundation/csv/Opc.Ua.StatusCodes.csv +227 -0
  38. package/opcua/public/vendor/opc-foundation/csv/OpcUaDiModel.csv +1523 -0
  39. package/opcua/public/vendor/opc-foundation/csv/OpcUaGdsModel.csv +400 -0
  40. package/opcua/public/vendor/opc-foundation/csv/ServerCapabilities.csv +13 -0
  41. package/opcua/public/vendor/opc-foundation/csv/ServerCapabilityIdentifiers.csv +13 -0
  42. package/opcua/public/vendor/opc-foundation/csv/StatusCode.csv +227 -0
  43. package/opcua/public/vendor/opc-foundation/csv/StatusCodes.csv +227 -0
  44. package/opcua/public/vendor/opc-foundation/schema/OPC.ISA95.Types.xsd +163 -0
  45. package/opcua/public/vendor/opc-foundation/schema/OPCBinarySchema.xsd +119 -0
  46. package/opcua/public/vendor/opc-foundation/schema/Opc.Ua.Types.xsd +3938 -0
  47. package/opcua/public/vendor/opc-foundation/schema/SecuredApplication.xsd +106 -0
  48. package/opcua/public/vendor/opc-foundation/schema/UANodeSet.xsd +420 -0
  49. package/opcua/public/vendor/opc-foundation/xml/OPC.ISA95.NodeSet2.Nov52013.xml +3293 -0
  50. package/opcua/public/vendor/opc-foundation/xml/Opc.ISA95.NodeSet2.xml +3589 -0
  51. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Adi.NodeSet2.xml +8301 -0
  52. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Adi.Types.bsd.xml +76 -0
  53. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Adi.Types.xsd +157 -0
  54. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.AutoID.NodeSet2.xml +6062 -0
  55. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Di.NodeSet2.xml +5066 -0
  56. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Di.PredefinedNodes.xml +11495 -0
  57. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Di.Types.bsd +86 -0
  58. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Di.Types.bsd.xml +11 -0
  59. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Di.Types.xsd +155 -0
  60. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Gds.NodeSet.xml +15226 -0
  61. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Gds.NodeSet2.xml +6214 -0
  62. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Gds.Types.bsd.xml +25 -0
  63. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.Gds.Types.xsd +30 -0
  64. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet-2.xml +134881 -0
  65. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet-3.xml +134881 -0
  66. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet.xml +134881 -0
  67. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part10.xml +832 -0
  68. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part11.xml +793 -0
  69. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part12.xml +3877 -0
  70. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part13.xml +344 -0
  71. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part3.xml +1103 -0
  72. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part4.xml +3091 -0
  73. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part5.xml +17092 -0
  74. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part8.xml +525 -0
  75. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part9.xml +2049 -0
  76. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.Part999.xml +134 -0
  77. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.NodeSet2.xml +67169 -0
  78. package/opcua/public/vendor/opc-foundation/xml/Opc.Ua.PredefinedNodes.xml +64500 -0
  79. package/opcua/public/vendor/opc-foundation/xml/OpcUaDiModel.xml +1239 -0
  80. package/opcua/utils.js +55 -0
  81. package/package.json +68 -0
  82. package/users.json +22 -0
@@ -0,0 +1,1061 @@
1
+ /*
2
+ Copyright 2016 Klaus Landsdorf
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ "use strict";
18
+ const { stringify } = require('flatted');
19
+ // const { coerceUInt64, coerceInt64, constructInt64 } = require('node-opcua');
20
+ var opcua = require('node-opcua');
21
+
22
+ const typedArrays = {
23
+ SByte: Int8Array,
24
+ Byte: Uint8Array,
25
+ Int8: Int8Array,
26
+ UInt8: Uint8Array,
27
+ Int16: Int16Array,
28
+ Int32: Int32Array,
29
+ UInt16: Uint16Array,
30
+ UInt32: Uint32Array,
31
+ Float: Float32Array,
32
+ Double: Float64Array
33
+ };
34
+
35
+ function cloneObject(obj) {
36
+ let cpy;
37
+
38
+ // Handle the 3 simple types, and null or undefined
39
+ if (null === obj || "object" != typeof obj) return obj;
40
+
41
+ // Handle Buffer
42
+ if (Buffer.isBuffer(obj)) return new Buffer.from(obj);
43
+
44
+ // Handle Date
45
+ if (obj instanceof Date) {
46
+ cpy = new Date();
47
+ cpy.setTime(obj.getTime());
48
+ return cpy;
49
+ }
50
+
51
+ // Handle Array
52
+ if (Array.isArray(obj)) {
53
+ cpy = [];
54
+ for (let i = 0, len = obj.length; i < len; i++) {
55
+ cpy[i] = cloneObject(obj[i]);
56
+ }
57
+ return cpy;
58
+ }
59
+
60
+ // Handle NodeId
61
+ if (obj instanceof opcua.NodeId) {
62
+ cpy = obj.toString();
63
+ return cpy;
64
+ }
65
+
66
+ // Handle Object
67
+ if (obj instanceof Object) {
68
+ cpy = {};
69
+ for (let attr in obj) {
70
+ if (obj.hasOwnProperty(attr)) cpy[attr] = cloneObject(obj[attr]);
71
+ }
72
+ return cpy;
73
+ }
74
+
75
+ throw new Error("Unable to copy obj! Its type isn't supported.");
76
+ };
77
+
78
+ module.exports.clone_object = function (obj) {
79
+ return cloneObject(obj);
80
+ };
81
+
82
+ module.exports.get_timeUnit_name = function (unit) {
83
+
84
+ var unitAbbreviation = '';
85
+
86
+ switch (unit) {
87
+ case "ms":
88
+ unitAbbreviation = 'msec.';
89
+ break;
90
+ case "s":
91
+ unitAbbreviation = 'sec.';
92
+ break;
93
+ case "m":
94
+ unitAbbreviation = 'min.';
95
+ break;
96
+ case "h":
97
+ unitAbbreviation = 'h.';
98
+ break;
99
+ default:
100
+ break;
101
+ }
102
+
103
+ return unitAbbreviation;
104
+ };
105
+
106
+ module.exports.calc_milliseconds_by_time_and_unit = function (time, unit) {
107
+
108
+ switch (unit) {
109
+ case "ms":
110
+ break;
111
+ case "s":
112
+ time = time * 1000; // seconds
113
+ break;
114
+ case "m":
115
+ time = time * 60000; // minutes
116
+ break;
117
+ case "h":
118
+ time = time * 3600000; // hours
119
+ break;
120
+ default:
121
+ time = 10000; // 10 sec.
122
+ break;
123
+ }
124
+
125
+ return time;
126
+ };
127
+
128
+ /*
129
+ Options defaults node-opcua
130
+
131
+ options.requestedPublishingInterval = options.requestedPublishingInterval || 100;
132
+ options.requestedLifetimeCount = options.requestedLifetimeCount || 60;
133
+ options.requestedMaxKeepAliveCount = options.requestedMaxKeepAliveCount || 2;
134
+ options.maxNotificationsPerPublish = options.maxNotificationsPerPublish || 2;
135
+ options.publishingEnabled = options.publishingEnabled ? true : false;
136
+ options.priority = options.priority || 1;
137
+ */
138
+
139
+ module.exports.getEventSubscriptionParameters = function (timeMilliseconds) {
140
+ return {
141
+ requestedPublishingInterval: timeMilliseconds || 100,
142
+ requestedLifetimeCount: 120,
143
+ requestedMaxKeepAliveCount: 3,
144
+ maxNotificationsPerPublish: 0,
145
+ publishingEnabled: true,
146
+ priority: 1
147
+ };
148
+ };
149
+
150
+ module.exports.getSubscriptionParameters = function (timeMilliseconds) {
151
+ return {
152
+ requestedPublishingInterval: timeMilliseconds || 100,
153
+ requestedLifetimeCount: 30,
154
+ requestedMaxKeepAliveCount: 3,
155
+ maxNotificationsPerPublish: 0,
156
+ publishingEnabled: true,
157
+ priority: 10
158
+ }
159
+ };
160
+
161
+ /*
162
+ ALIASES for Basic types:
163
+ <Alias Alias="Boolean">i=1</Alias>
164
+ <Alias Alias="SByte">i=2</Alias>
165
+ <Alias Alias="Byte">i=3</Alias>
166
+ <Alias Alias="Int16">i=4</Alias>
167
+ <Alias Alias="UInt16">i=5</Alias>
168
+ <Alias Alias="Int32">i=6</Alias>
169
+ <Alias Alias="UInt32">i=7</Alias>
170
+ <Alias Alias="Int64">i=8</Alias>
171
+ <Alias Alias="UInt64">i=9</Alias>
172
+ <Alias Alias="Float">i=10</Alias>
173
+ <Alias Alias="Double">i=11</Alias>
174
+ <Alias Alias="DateTime">i=13</Alias>
175
+ <Alias Alias="String">i=12</Alias>
176
+ <Alias Alias="ByteString">i=15</Alias>
177
+ <Alias Alias="Guid">i=14</Alias>
178
+ <Alias Alias="XmlElement">i=16</Alias>
179
+ <Alias Alias="NodeId">i=17</Alias>
180
+ <Alias Alias="ExpandedNodeId">i=18</Alias>
181
+ <Alias Alias="QualifiedName">i=20</Alias>
182
+ <Alias Alias="LocalizedText">i=21</Alias>
183
+ <Alias Alias="StatusCode">i=19</Alias>
184
+ <Alias Alias="Structure">i=22</Alias>
185
+ <Alias Alias="Variant">i=24</Alias>
186
+ <Alias Alias="Number">i=26</Alias>
187
+ <Alias Alias="Integer">i=27</Alias>
188
+ <Alias Alias="UInteger">i=28</Alias>
189
+ <Alias Alias="HasComponent">i=47</Alias>
190
+ <Alias Alias="HasProperty">i=46</Alias>
191
+ <Alias Alias="Organizes">i=35</Alias>
192
+ <Alias Alias="HasEventSource">i=36</Alias>
193
+ <Alias Alias="HasNotifier">i=48</Alias>
194
+ <Alias Alias="HasSubtype">i=45</Alias>
195
+ <Alias Alias="HasTypeDefinition">i=40</Alias>
196
+ <Alias Alias="HasModellingRule">i=37</Alias>
197
+ <Alias Alias="HasEncoding">i=38</Alias>
198
+ <Alias Alias="HasDescription">i=39</Alias>
199
+ */
200
+ module.exports.convertToString = function(inType) {
201
+ if (inType === "ns=0;i=1") return "Boolean";
202
+ if (inType === "ns=0;i=2") return "SByte";
203
+ if (inType === "ns=0;i=3") return "Byte";
204
+ if (inType === "ns=0;i=4") return "Int16";
205
+ if (inType === "ns=0;i=5") return "UInt16";
206
+ if (inType === "ns=0;i=6") return "Int32";
207
+ if (inType === "ns=0;i=7") return "UInt32";
208
+ if (inType === "ns=0;i=8") return "Int64";
209
+ if (inType === "ns=0;i=9") return "UInt64";
210
+ if (inType === "ns=0;i=10") return "Float";
211
+ if (inType === "ns=0;i=11") return "Double";
212
+ if (inType === "ns=0;i=12") return "String"; // Fixed from DateTime
213
+ if (inType === "ns=0;i=13") return "DateTime"; // Fixed from String
214
+ if (inType === "ns=0;i=14") return "Guid";
215
+ if (inType === "ns=0;i=15") return "ByteString";
216
+ if (inType === "ns=0;i=16") return "XmlElement";
217
+ if (inType === "ns=0;i=17") return "NodeId";
218
+ if (inType === "ns=0;i=18") return "ExpandedNodeId";
219
+ if (inType === "ns=0;i=19") return "StatusCode";
220
+ if (inType === "ns=0;i=20") return "QualifiedName";
221
+ if (inType === "ns=0;i=21") return "LocalizedText";
222
+ if (inType === "ns=0;i=22") return "Structure";
223
+ if (inType === "ns=0;i=24") return "Variant";
224
+ if (inType === "ns=0;i=26") return "Number";
225
+ if (inType === "ns=0;i=27") return "Integer";
226
+ if (inType === "ns=0;i=28") return "UInteger";
227
+ if (inType === "ns=0;i=884") return "EngineeringRange";
228
+ if (inType === "ns=0;i=887") return "EngineeringUnits";
229
+
230
+ console.log("Cannot convert from nodeId dataType: '" + inType + "' to string!")
231
+ return "";
232
+ }
233
+
234
+ module.exports.buildBrowseMessage = function (topic) {
235
+ return {
236
+ "topic": topic,
237
+ "nodeId": "",
238
+ "browseName": "",
239
+ "description": "",
240
+ // "nodeClassType": "",
241
+ "typeDefinition": "",
242
+ "dataType": "",
243
+ "payload": ""
244
+ };
245
+ };
246
+
247
+ module.exports.toInt32 = function (x) {
248
+ var uint16 = x;
249
+
250
+ if (uint16 >= Math.pow(2, 15)) {
251
+ uint16 = x - Math.pow(2, 16);
252
+ return uint16;
253
+ } else {
254
+ return uint16;
255
+ }
256
+ };
257
+
258
+ module.exports.get_node_status = function (statusValue) {
259
+
260
+ var fillValue = "red";
261
+ var shapeValue = "dot";
262
+
263
+ switch (statusValue) {
264
+
265
+ case "connected":
266
+ case "initialized":
267
+ case "keepalive":
268
+ case "nodeId stored":
269
+ case "clear items":
270
+ case "building method arguments":
271
+ case "call method":
272
+ case "executing method":
273
+ fillValue = "green";
274
+ shapeValue = "ring";
275
+ break;
276
+ // issue #837
277
+ case "create client":
278
+ case "connecting":
279
+ fillValue = "yellow";
280
+ shapeValue = "ring";
281
+ break;
282
+ case "reconnect":
283
+ case "closed":
284
+ fillValue = "yellow";
285
+ shapeValue = "dot";
286
+ break;
287
+ case "active":
288
+ case "active reading":
289
+ case "value written":
290
+ case "values written":
291
+ case "active multiple reading":
292
+ case "active writing":
293
+ case "writing":
294
+ case "active subscribing":
295
+ case "unsubscribing":
296
+ case "active subscribed":
297
+ case "active browsing":
298
+ case "active monitoring":
299
+ case "active alarm":
300
+ case "active event":
301
+ case "session active":
302
+ case "session closed":
303
+ case "subscribed":
304
+ case "browse done":
305
+ case "changed":
306
+ case "method executed":
307
+ fillValue = "green";
308
+ shapeValue = "dot";
309
+ break;
310
+ case "error":
311
+ case "call method error":
312
+ case "execute method error":
313
+ case "extensionObject error":
314
+ case "invalid session":
315
+ case "invalid endpoint":
316
+ case "invalid certificate":
317
+ case "disconnected":
318
+ case "connection error":
319
+ case "subscription error":
320
+ case "node error":
321
+ case "terminated":
322
+ case "no client":
323
+ case "no items to read":
324
+ case "no items to write":
325
+ fillValue = "red";
326
+ shapeValue = "ring";
327
+ break;
328
+
329
+ default:
330
+ if (!statusValue) {
331
+ fillValue = "blue";
332
+ statusValue = "waiting ...";
333
+ }
334
+ break;
335
+ }
336
+
337
+ return {
338
+ fill: fillValue,
339
+ shape: shapeValue,
340
+ status: statusValue
341
+ };
342
+ };
343
+
344
+
345
+ module.exports.build_new_variant = function (datatype, value) {
346
+
347
+ var nValue = new opcua.Variant({
348
+ dataType: opcua.DataType.Float,
349
+ value: 0.0
350
+ });
351
+
352
+ switch (datatype) {
353
+ case "Float":
354
+ nValue = new opcua.Variant({
355
+ dataType: opcua.DataType.Float,
356
+ value: parseFloat(value)
357
+ });
358
+ break;
359
+ case "Double":
360
+ nValue = new opcua.Variant({
361
+ dataType: opcua.DataType.Double,
362
+ value: parseFloat(value)
363
+ });
364
+ break;
365
+ case "Int32":
366
+ nValue = new opcua.Variant({
367
+ dataType: opcua.DataType.Int32,
368
+ value: parseInt(value)
369
+ });
370
+ break;
371
+ case "Int16":
372
+ nValue = new opcua.Variant({
373
+ dataType: opcua.DataType.Int16,
374
+ value: parseInt(value)
375
+ });
376
+ break;
377
+ case "Int8":
378
+ nValue = new opcua.Variant({
379
+ dataType: opcua.DataType.SByte,
380
+ value: parseInt(value)
381
+ });
382
+ break;
383
+ case "UInt32":
384
+ nValue = new opcua.Variant({
385
+ dataType: opcua.DataType.UInt32,
386
+ value: parseInt(value)
387
+ });
388
+ break;
389
+ case "UInt16":
390
+ nValue = new opcua.Variant({
391
+ dataType: opcua.DataType.UInt16,
392
+ value: parseInt(value)
393
+ });
394
+ break;
395
+ case "UInt8":
396
+ nValue = new opcua.Variant({
397
+ dataType: opcua.DataType.Byte,
398
+ value: parseInt(value)
399
+ });
400
+ break;
401
+ case "Boolean":
402
+ // Support for different value conversions
403
+ if (value && value === "false") {
404
+ nValue = new opcua.Variant({
405
+ dataType: opcua.DataType.Boolean,
406
+ value: false
407
+ });
408
+ }
409
+ if (value && value === false) {
410
+ nValue = new opcua.Variant({
411
+ dataType: opcua.DataType.Boolean,
412
+ value: false
413
+ });
414
+ }
415
+ if (value && value === 0) {
416
+ nValue = new opcua.Variant({
417
+ dataType: opcua.DataType.Boolean,
418
+ value: false
419
+ });
420
+ }
421
+ if (value && value === "true"){
422
+ nValue = new opcua.Variant({
423
+ dataType: opcua.DataType.Boolean,
424
+ value: true
425
+ });
426
+ }
427
+ if (value && value === true){
428
+ nValue = new opcua.Variant({
429
+ dataType: opcua.DataType.Boolean,
430
+ value: true
431
+ });
432
+ }
433
+ if (value && value === 1){
434
+ nValue = new opcua.Variant({
435
+ dataType: opcua.DataType.Boolean,
436
+ value: true
437
+ });
438
+ }
439
+ break;
440
+ case "String":
441
+ nValue = new opcua.Variant({
442
+ dataType: opcua.DataType.String,
443
+ value: value
444
+ });
445
+ break;
446
+ case "LocalizedText":
447
+ nValue = new opcua.Variant({
448
+ dataType: opcua.DataType.LocalizedText,
449
+ value: new opcua.LocalizedText({locale: "en", text: value})
450
+ });
451
+ break;
452
+ case "DateTime":
453
+ if (typeof value === "string") {
454
+ // String format like "2022-04-03 12:13:14"
455
+ nValue = new opcua.Variant({
456
+ dataType: opcua.DataType.DateTime,
457
+ value: new Date(Date.parse(value))
458
+ });
459
+ }
460
+ else if (value instanceof Date) {
461
+ // Date object
462
+ nValue = new opcua.Variant({
463
+ dataType: opcua.DataType.DateTime,
464
+ value: value
465
+ });
466
+ }
467
+ else {
468
+ // Number
469
+ nValue = new opcua.Variant({
470
+ dataType: opcua.DataType.DateTime,
471
+ value: new Date(value)
472
+ });
473
+ }
474
+ break;
475
+ case "Byte":
476
+ nValue = new opcua.Variant({
477
+ dataType: opcua.DataType.Byte,
478
+ value: value
479
+ });
480
+ break;
481
+ case "SByte":
482
+ nValue = new opcua.Variant({
483
+ dataType: opcua.DataType.SByte,
484
+ value: value
485
+ });
486
+ break;
487
+ default:
488
+ nValue = new opcua.Variant({
489
+ dataType: opcua.DataType.BaseDataType,
490
+ value: value
491
+ });
492
+ break;
493
+ }
494
+ // Checks if Array and grabs Data Type
495
+ var m = datatype.match(/\b(\w+) Array\b/);
496
+ if (m) {
497
+ nValue = new opcua.Variant({
498
+ dataType: opcua.DataType[m[1]],
499
+ value: value,
500
+ arrayType: opcua.VariantArrayType.Array,
501
+ arrayDimensions: [value.length]
502
+ });
503
+ }
504
+
505
+ return nValue;
506
+ };
507
+
508
+ function getArrayValues(datatype, items) {
509
+ var uaArray = {};
510
+ uaArray.values = [];
511
+ uaArray.uaType = null;
512
+
513
+ // console.debug("### getArrayValues:" + datatype + " items:" + items);
514
+
515
+ // Check datatype string, example Byte Array, Double Array etc.
516
+ if (datatype.indexOf("Boolean") === 0) {
517
+ uaArray.uaType = opcua.DataType.Boolean;
518
+ uaArray.values = new Array(items.length);
519
+ }
520
+ if (datatype.indexOf("UInt8") === 0 || datatype.indexOf("Byte") === 0) {
521
+ uaArray.uaType = opcua.DataType.Byte;
522
+ uaArray.values = new Uint8Array(items);
523
+ }
524
+ if (datatype.indexOf("UInt16") === 0) {
525
+ uaArray.uaType = opcua.DataType.UInt16;
526
+ uaArray.values = new Uint16Array(items);
527
+ }
528
+ if (datatype.indexOf("UInt32") === 0) {
529
+ uaArray.uaType = opcua.DataType.UInt32;
530
+ uaArray.values = new Uint32Array(items);
531
+ }
532
+ if (datatype.indexOf("Int8") === 0 || datatype.indexOf("SByte") === 0) {
533
+ uaArray.uaType = opcua.DataType.SByte;
534
+ uaArray.values = new Int8Array(items);
535
+ }
536
+ if (datatype.indexOf("Int16") === 0) {
537
+ uaArray.uaType = opcua.DataType.Int16;
538
+ uaArray.values = new Int16Array(items);
539
+ }
540
+ if (datatype.indexOf("Int32") === 0) {
541
+ uaArray.uaType = opcua.DataType.Int32;
542
+ uaArray.values = new Int32Array(items);
543
+ }
544
+ if (datatype.indexOf("Float") === 0) {
545
+ uaArray.uaType = opcua.DataType.Float;
546
+ uaArray.values = new Float32Array(items);
547
+ }
548
+ if (datatype.indexOf("Double") >= 0) {
549
+ uaArray.uaType = opcua.DataType.Double;
550
+ uaArray.values = new Float64Array(items);
551
+ }
552
+ if (datatype.indexOf("String") >= 0) {
553
+ uaArray.uaType = opcua.DataType.String;
554
+ uaArray.values = new Array(items);
555
+ // console.log("ITEMS:" + items.toString());
556
+ }
557
+ if (datatype.indexOf("Variant") >= 0) {
558
+ uaArray.uaType = opcua.DataType.Variant;
559
+ //uaArray.values = new Array(items);
560
+ uaArray.values = items;
561
+ // console.log("ITEMS:" + items.toString());
562
+ }
563
+ if (datatype.indexOf("ExtensionObject") >= 0) {
564
+ uaArray.uaType = opcua.DataType.ExtensionObject;
565
+ uaArray.values = items;
566
+ }
567
+
568
+ if (uaArray.uaType === null) {
569
+ console.warn("Array support for String nor ByteString etc. not implemented, only basic types supported!");
570
+ console.error("Unknown type for Array: " + datatype + " cannot convert items:" + items);
571
+ }
572
+
573
+ function setValue(item, index, arr) {
574
+ // Boolean, Float basic conversions TODO DateTime etc. if needed
575
+ if (uaArray.uaType === opcua.DataType.Float || uaArray.uaType === opcua.DataType.Double) {
576
+ uaArray.values[index] = parseFloat(item);
577
+ }
578
+ else if (uaArray.uaType === opcua.DataType.Boolean) {
579
+ // console.log("Item: " + item + " index: " + index);
580
+ uaArray.values[index] = false;
581
+ if (item === 1 || item === "1" || item === "true" || item === true) {
582
+ uaArray.values[index] = true;
583
+ }
584
+ }
585
+ else if (uaArray.uaType === opcua.DataType.String || uaArray.uaType === opcua.DataType.ExtensionObject) {
586
+ uaArray.values[index] = item;
587
+ }
588
+ else if (uaArray.uaType === opcua.DataType.Variant) {
589
+ //console.log("----------------------");
590
+ //console.log("ITEM: " + JSON.stringify(item));
591
+ //console.log("INDEX: " + JSON.stringify(index));
592
+ if (item.dataType == "Variant" && item.arrayType == "Array"){
593
+ var uaVarItems = [];
594
+ function fillVariatArray (varItem, varIdx, varArr){
595
+ uaVarItems[varIdx] = new opcua.Variant(
596
+ exports.build_new_dataValue(varItem.dataType, varItem.value)
597
+ )
598
+
599
+ }
600
+ item.value.forEach(fillVariatArray);
601
+ uaArray.values[index] = new opcua.Variant({
602
+ dataType: opcua.DataType.Variant,
603
+ arrayType: opcua.VariantArrayType.Array,
604
+ value: uaVarItems
605
+ });
606
+ //console.log("uaArray: " + JSON.stringify(uaArray.values[index]));
607
+ }
608
+ else {
609
+ uaArray.values[index] = item;
610
+ }
611
+ }
612
+ else {
613
+ uaArray.values[index] = parseInt(item);
614
+ }
615
+ }
616
+ items.forEach(setValue);
617
+
618
+ return uaArray.values;
619
+ }
620
+
621
+ module.exports.getUaType = function (datatype) {
622
+ // Convert datatype from string to UA DataType
623
+ if (datatype == "Boolean") {
624
+ return opcua.DataType.Boolean;
625
+ }
626
+ if (datatype === "Byte") {
627
+ return opcua.DataType.Byte;
628
+ }
629
+ if (datatype === "UInt16") {
630
+ return opcua.DataType.UInt16;
631
+ }
632
+ if (datatype === "UInt32") {
633
+ return opcua.DataType.UInt32;
634
+ }
635
+ if (datatype === "SByte") {
636
+ return opcua.DataType.SByte;
637
+ }
638
+ if (datatype === "Int16") {
639
+ return opcua.DataType.Int16;
640
+ }
641
+ if (datatype === "Int32") {
642
+ return opcua.DataType.Int32;
643
+ }
644
+ if (datatype === "Float") {
645
+ return opcua.DataType.Float;
646
+ }
647
+ if (datatype === "Double") {
648
+ return opcua.DataType.Double;
649
+ }
650
+ if (datatype === "String") {
651
+ return opcua.DataType.String;
652
+ }
653
+ if (datatype === "Variant") {
654
+ return opcua.DataType.Variant;
655
+ }
656
+ console.error("Unknown datatype for UA: " + datatype);
657
+
658
+ return null;
659
+ }
660
+
661
+ function getArrayType(datatype) {
662
+
663
+ // console.debug("getArrayType:" + datatype);
664
+
665
+ // Check datatype string, example Byte Array, Double Array etc.
666
+ if (datatype.indexOf("Boolean") >= 0) {
667
+ return opcua.DataType.Boolean;
668
+ }
669
+ if (datatype.indexOf("UInt8") >= 0 || datatype.indexOf("Byte") >= 0) {
670
+ return opcua.DataType.Byte;
671
+ }
672
+ if (datatype.indexOf("UInt16") >= 0) {
673
+ return opcua.DataType.UInt16;
674
+ }
675
+ if (datatype.indexOf("UInt32") >= 0) {
676
+ return opcua.DataType.UInt32;
677
+ }
678
+ if (datatype.indexOf("Int8") >= 0 || datatype.indexOf("SByte") >= 0) {
679
+ return opcua.DataType.SByte;
680
+ }
681
+ if (datatype.indexOf("Int16") >= 0) {
682
+ return opcua.DataType.Int16;
683
+ }
684
+ if (datatype.indexOf("Int32") >= 0) {
685
+ return opcua.DataType.Int32;
686
+ }
687
+ if (datatype.indexOf("Float") >= 0 || datatype.indexOf("Float32") >= 0) {
688
+ return opcua.DataType.Float;
689
+ }
690
+ if (datatype.indexOf("Double") >= 0 || datatype.indexOf("Float64") >= 0) {
691
+ return opcua.DataType.Double;
692
+ }
693
+ if (datatype.indexOf("String") >= 0) {
694
+ return opcua.DataType.String;
695
+ }
696
+ if (datatype.indexOf("Variant") >= 0) {
697
+ return opcua.DataType.Variant;
698
+ }
699
+ if (datatype.indexOf("ExtensionObject") >= 0) {
700
+ return opcua.DataType.ExtensionObject;
701
+ }
702
+
703
+ console.warn("Array support for String nor ByteString etc. not implemented, only basic types supported!");
704
+ console.error("Unknown type for Array: " + datatype);
705
+
706
+ return null;
707
+ }
708
+
709
+ module.exports.build_new_value_by_datatype = function (datatype, value) {
710
+
711
+ var nValue = 0;
712
+ var uaType;
713
+
714
+ switch (datatype) {
715
+ case "Float":
716
+ uaType = opcua.DataType.Float;
717
+ // nValue = parseFloat(value);
718
+ var float32 = new Float32Array([value]);
719
+ nValue = float32[0];
720
+ break;
721
+ case "Double":
722
+ uaType = opcua.DataType.Double;
723
+ // nValue = parseFloat(value); // (Double) or Float64 ?
724
+ var float64 = new Float64Array([value]);
725
+ nValue = float64[0];
726
+ break;
727
+ case "SByte":
728
+ uaType = opcua.DataType.SByte;
729
+ var int8 = new Int8Array([value]);
730
+ nValue = int8[0];
731
+ break;
732
+ case "Int8":
733
+ uaType = opcua.DataType.SByte;
734
+ var int8 = new Int8Array([value]);
735
+ nValue = int8[0];
736
+ break;
737
+ case "Int16":
738
+ uaType = opcua.DataType.Int16;
739
+ var int16 = new Int16Array([value]);
740
+ nValue = int16[0];
741
+ break;
742
+ case "Int32":
743
+ uaType = opcua.DataType.Int32;
744
+ var int32 = new Int32Array([value]);
745
+ nValue = int32[0];
746
+ break;
747
+ case "Byte":
748
+ uaType = opcua.DataType.Byte;
749
+ var uint8 = new Uint8Array([value]);
750
+ nValue = uint8[0];
751
+ break;
752
+ case "ByteString":
753
+ uaType = opcua.DataType.ByteString;
754
+ var nValue = Buffer.from(value);
755
+ break;
756
+ case "UInt8":
757
+ uaType = opcua.DataType.Byte;
758
+ var uint8 = new Uint8Array([value]);
759
+ nValue = uint8[0];
760
+ break;
761
+ case "UInt16":
762
+ uaType = opcua.DataType.UInt16;
763
+ var uint16 = new Uint16Array([value]);
764
+ nValue = uint16[0];
765
+ break;
766
+ case "UInt32":
767
+ uaType = opcua.DataType.UInt32;
768
+ var uint32 = new Uint32Array([value]);
769
+ nValue = uint32[0];
770
+ break;
771
+ case "UInt64":
772
+ uaType = opcua.DataType.UInt64;
773
+ // console.log("BYTES uint64: " + value);
774
+ var bytes = value.toString().split(",");
775
+ nValue = { arrayType: opcua.VariantArrayType.Scalar, dataType: opcua.DataType.UInt64, value: [parseInt(bytes[0]), parseInt(bytes[1])] };
776
+ break;
777
+ case "Int64":
778
+ uaType = opcua.DataType.Int64;
779
+ // console.log("BYTES int64: " + value);
780
+ var bytes = value.toString().split(",");
781
+ nValue = { arrayType: opcua.VariantArrayType.Scalar, dataType: opcua.DataType.Int64, value: [parseInt(bytes[0]), parseInt(bytes[1])] };
782
+ break;
783
+ case "Boolean":
784
+ uaType = opcua.DataType.Boolean;
785
+ if (value && value !== "false") {
786
+ nValue = true;
787
+ } else {
788
+ nValue = false;
789
+ }
790
+ break;
791
+ case "String":
792
+ uaType = opcua.DataType.String;
793
+ nValue = value.toString();
794
+ break;
795
+ case "LocalizedText":
796
+ uaType = opcua.DataType.LocalizedText;
797
+ nValue = new opcua.LocalizedText({locale: "en", text: value});
798
+ break;
799
+ case "DateTime":
800
+ uaType = opcua.DataType.DateTime;
801
+ if (typeof value === "string") {
802
+ nValue = value; // Date.parse(value); // new Date(value); // value.toString();
803
+ }
804
+ else if (value instanceof Date) {
805
+ // Date object
806
+ nValue = new opcua.Variant({
807
+ dataType: opcua.DataType.DateTime,
808
+ value: value
809
+ });
810
+ }
811
+ else {
812
+ // injected timestamp as integer
813
+ nValue = {
814
+ dataType: opcua.DataType.DateTime, // was UtcTime
815
+ value: new Date(parseInt(value)) // Date.parse(value)
816
+ };
817
+ }
818
+ break;
819
+ case "ExtensionObject":
820
+ uaType = opcua.DataType.ExtensionObject;
821
+ if (typeof value === "string") {
822
+ nValue = JSON.parse(value); // value should be valid string
823
+ }
824
+ else {
825
+ // Here we expect that value is already extension object, not a JSON object
826
+ nValue = value;
827
+ /* TEST
828
+ let test = {
829
+ dataType: opcua.DataType.ExtensionObject,
830
+ value: value,
831
+ arrayType: opcua.VariantArrayType.Array
832
+ };
833
+ console.log("TEST: " + JSON.stringify(test));
834
+ // Next Variant constructor will fail if value / test is not an extensionObject
835
+ nodeToWrite = {
836
+ nodeId: "ns=1;s=TEST",
837
+ attributeId: opcua.AttributeIds.Value,
838
+ value: new opcua.DataValue({
839
+ value: new opcua.Variant(test),
840
+ })
841
+ };
842
+ */
843
+ }
844
+ break;
845
+ default:
846
+ // uaType = null;
847
+ nValue = value;
848
+ break;
849
+ }
850
+ // Checks if Array and grabs Data Type
851
+ // var m = datatype.match(/\b(\w+) Array\b/);
852
+ //console.log("-------------------");
853
+ //console.log("datatype: " + datatype);
854
+ //console.log("value: " + value);
855
+
856
+ // Issue #806 FIX
857
+ var m = (datatype ?? "").indexOf("Array");
858
+ if (m > 0) {
859
+ var arrayValues = [];
860
+ var items;
861
+
862
+ // Convert value (string) to individual array values
863
+ if (Array.isArray(value) && value.length === 1 && typeof(value[0]) === "string") {
864
+ var payload = value[0];
865
+ items = payload.split(",");
866
+ }
867
+ else {
868
+ if (value.hasOwnProperty("dataType")) {
869
+ // Already processed, return value
870
+ return value;
871
+ }
872
+ if (Array.isArray(value) && value.length > 0) {
873
+ items = value;
874
+ }
875
+ else {
876
+ items = value.split(",");
877
+ }
878
+ }
879
+
880
+ arrayValues = getArrayValues(datatype, items);
881
+ uaType = getArrayType(datatype);
882
+
883
+ nValue = {
884
+ dataType: uaType,
885
+ value: arrayValues,
886
+ arrayType: opcua.VariantArrayType.Array
887
+ };
888
+ }
889
+
890
+ return nValue;
891
+ };
892
+
893
+ module.exports.build_new_dataValue = function (datatype, value) {
894
+
895
+ var nValue = null;
896
+
897
+ switch (datatype) {
898
+ case "Float":
899
+ nValue = {
900
+ dataType: opcua.DataType.Float,
901
+ value: parseFloat(value)
902
+ };
903
+ break;
904
+ case "Double":
905
+ nValue = {
906
+ dataType: opcua.DataType.Double,
907
+ value: parseFloat(value)
908
+ };
909
+ break;
910
+ case "Int64":
911
+ // console.log("BYTES INT64: " + JSON.stringify(value));
912
+ nValue = { arrayType: opcua.VariantArrayType.Scalar, dataType: opcua.DataType.Int64, value: value.value };
913
+ break;
914
+ case "Int32":
915
+ nValue = {
916
+ dataType: opcua.DataType.Int32,
917
+ value: parseInt(value)
918
+ };
919
+ break;
920
+ case "Int16":
921
+ nValue = {
922
+ dataType: opcua.DataType.Int16,
923
+ value: parseInt(value)
924
+ };
925
+ break;
926
+ case "Int8":
927
+ nValue = {
928
+ dataType: opcua.DataType.SByte,
929
+ value: parseInt(value)
930
+ };
931
+ break;
932
+ case "UInt64":
933
+ // console.log("BYTES UINT64: " + value);
934
+ nValue = { arrayType: opcua.VariantArrayType.Scalar, dataType: opcua.DataType.UInt64, value: value.value };
935
+ break;
936
+ case "UInt32":
937
+ nValue = {
938
+ dataType: opcua.DataType.UInt32,
939
+ value: parseInt(value)
940
+ };
941
+ break;
942
+ case "UInt16":
943
+ nValue = {
944
+ dataType: opcua.DataType.UInt16,
945
+ value: parseInt(value)
946
+ };
947
+ break;
948
+ case "UInt8":
949
+ nValue = {
950
+ dataType: opcua.DataType.Byte,
951
+ value: parseInt(value)
952
+ };
953
+ break;
954
+ case "Boolean":
955
+ if (value && value !== "false") {
956
+ nValue = {
957
+ dataType: opcua.DataType.Boolean,
958
+ value: true
959
+ };
960
+ } else {
961
+ nValue = {
962
+ dataType: opcua.DataType.Boolean,
963
+ value: false
964
+ };
965
+ }
966
+ break;
967
+ case "String":
968
+ nValue = {
969
+ dataType: opcua.DataType.String,
970
+ value: value
971
+ };
972
+ break;
973
+ case "LocalizedText":
974
+ nValue = {
975
+ dataType: opcua.DataType.LocalizedText,
976
+ value: new opcua.LocalizedText({locale: "en", text: value })
977
+ };
978
+ break;
979
+ case "DateTime":
980
+ if (typeof value === "string") {
981
+ nValue = {
982
+ dataType: opcua.DataType.DateTime, // was UtcTime
983
+ value: new Date(Date.parse(value))
984
+ };
985
+ }
986
+ else if (value instanceof Date) {
987
+ // Date object
988
+ nValue = new opcua.Variant({
989
+ dataType: opcua.DataType.DateTime,
990
+ value: value
991
+ });
992
+ }
993
+ else {
994
+ // injected timestamp as integer
995
+ nValue = {
996
+ dataType: opcua.DataType.DateTime, // was UtcTime
997
+ value: new Date(parseInt(value)) // Date.parse(value)
998
+ };
999
+ }
1000
+ break;
1001
+ case "Byte":
1002
+ nValue = {
1003
+ dataType: opcua.DataType.Byte,
1004
+ value: parseInt(value)
1005
+ };
1006
+ break;
1007
+ case "SByte":
1008
+ nValue = {
1009
+ dataType: opcua.DataType.SByte,
1010
+ value: parseInt(value)
1011
+ };
1012
+ break;
1013
+ default:
1014
+ nValue = {
1015
+ dataType: opcua.DataType.BaseDataType,
1016
+ value: value
1017
+ };
1018
+ break;
1019
+ }
1020
+
1021
+ // Issue #806 FIX
1022
+ var m = (datatype ?? "").indexOf("Array");
1023
+ if (m > 0) {
1024
+ var uaType = getArrayType(datatype);
1025
+ var arrayValues;
1026
+ //console.log("ARRAY: " + JSON.stringify({"uaType":uaType,"value":value}));
1027
+ if (value && value.value) {
1028
+ var raw = value.value;
1029
+ if (Array.isArray(raw)) {
1030
+ arrayValues = getArrayValues(datatype, raw);
1031
+ }
1032
+ else if (ArrayBuffer.isView(raw)) {
1033
+ arrayValues = getArrayValues(datatype, Array.from(raw));
1034
+ }
1035
+ else {
1036
+ arrayValues = getArrayValues(datatype, raw);
1037
+ }
1038
+ }
1039
+ else if (Array.isArray(value)) {
1040
+ arrayValues = getArrayValues(datatype, value);
1041
+ }
1042
+ else if (ArrayBuffer.isView(value)) {
1043
+ arrayValues = getArrayValues(datatype, Array.from(value));
1044
+ }
1045
+ else if (typeof value === "string") {
1046
+ var items = value.split(",");
1047
+ arrayValues = getArrayValues(datatype, items);
1048
+ }
1049
+ else {
1050
+ arrayValues = getArrayValues(datatype, [value]);
1051
+ }
1052
+
1053
+ nValue = {
1054
+ dataType: uaType, // maps SByte and Byte // opcua.DataType[m[1]],
1055
+ value: arrayValues,
1056
+ arrayType: opcua.VariantArrayType.Array,
1057
+ };
1058
+ }
1059
+
1060
+ return nValue;
1061
+ };