node-red-contrib-opcua
Version:
A Node-RED node to communicate via OPC UA based on node-opcua library.
1,045 lines (973 loc) • 34.3 kB
JavaScript
/*
Copyright 2016 Klaus Landsdorf
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
"use strict";
const { stringify } = require('flatted');
// const { coerceUInt64, coerceInt64, constructInt64 } = require('node-opcua');
var opcua = require('node-opcua');
const typedArrays = {
SByte: Int8Array,
Byte: Uint8Array,
Int8: Int8Array,
UInt8: Uint8Array,
Int16: Int16Array,
Int32: Int32Array,
UInt16: Uint16Array,
UInt32: Uint32Array,
Float: Float32Array,
Double: Float64Array
};
function cloneObject(obj) {
let cpy;
// Handle the 3 simple types, and null or undefined
if (null === obj || "object" != typeof obj) return obj;
// Handle Buffer
if (Buffer.isBuffer(obj)) return new Buffer.from(obj);
// Handle Date
if (obj instanceof Date) {
cpy = new Date();
cpy.setTime(obj.getTime());
return cpy;
}
// Handle Array
if (Array.isArray(obj)) {
cpy = [];
for (let i = 0, len = obj.length; i < len; i++) {
cpy[i] = cloneObject(obj[i]);
}
return cpy;
}
// Handle NodeId
if (obj instanceof opcua.NodeId) {
cpy = obj.toString();
return cpy;
}
// Handle Object
if (obj instanceof Object) {
cpy = {};
for (let attr in obj) {
if (obj.hasOwnProperty(attr)) cpy[attr] = cloneObject(obj[attr]);
}
return cpy;
}
throw new Error("Unable to copy obj! Its type isn't supported.");
};
module.exports.clone_object = function (obj) {
return cloneObject(obj);
};
module.exports.get_timeUnit_name = function (unit) {
var unitAbbreviation = '';
switch (unit) {
case "ms":
unitAbbreviation = 'msec.';
break;
case "s":
unitAbbreviation = 'sec.';
break;
case "m":
unitAbbreviation = 'min.';
break;
case "h":
unitAbbreviation = 'h.';
break;
default:
break;
}
return unitAbbreviation;
};
module.exports.calc_milliseconds_by_time_and_unit = function (time, unit) {
switch (unit) {
case "ms":
break;
case "s":
time = time * 1000; // seconds
break;
case "m":
time = time * 60000; // minutes
break;
case "h":
time = time * 3600000; // hours
break;
default:
time = 10000; // 10 sec.
break;
}
return time;
};
/*
Options defaults node-opcua
options.requestedPublishingInterval = options.requestedPublishingInterval || 100;
options.requestedLifetimeCount = options.requestedLifetimeCount || 60;
options.requestedMaxKeepAliveCount = options.requestedMaxKeepAliveCount || 2;
options.maxNotificationsPerPublish = options.maxNotificationsPerPublish || 2;
options.publishingEnabled = options.publishingEnabled ? true : false;
options.priority = options.priority || 1;
*/
module.exports.getEventSubscriptionParameters = function (timeMilliseconds) {
return {
requestedPublishingInterval: timeMilliseconds || 100,
requestedLifetimeCount: 120,
requestedMaxKeepAliveCount: 3,
maxNotificationsPerPublish: 4,
publishingEnabled: true,
priority: 1
};
};
module.exports.getSubscriptionParameters = function (timeMilliseconds) {
return {
requestedPublishingInterval: timeMilliseconds || 100,
requestedLifetimeCount: 30,
requestedMaxKeepAliveCount: 3,
maxNotificationsPerPublish: 10,
publishingEnabled: true,
priority: 10
}
};
/*
ALIASES for Basic types:
<Alias Alias="Boolean">i=1</Alias>
<Alias Alias="SByte">i=2</Alias>
<Alias Alias="Byte">i=3</Alias>
<Alias Alias="Int16">i=4</Alias>
<Alias Alias="UInt16">i=5</Alias>
<Alias Alias="Int32">i=6</Alias>
<Alias Alias="UInt32">i=7</Alias>
<Alias Alias="Int64">i=8</Alias>
<Alias Alias="UInt64">i=9</Alias>
<Alias Alias="Float">i=10</Alias>
<Alias Alias="Double">i=11</Alias>
<Alias Alias="DateTime">i=13</Alias>
<Alias Alias="String">i=12</Alias>
<Alias Alias="ByteString">i=15</Alias>
<Alias Alias="Guid">i=14</Alias>
<Alias Alias="XmlElement">i=16</Alias>
<Alias Alias="NodeId">i=17</Alias>
<Alias Alias="ExpandedNodeId">i=18</Alias>
<Alias Alias="QualifiedName">i=20</Alias>
<Alias Alias="LocalizedText">i=21</Alias>
<Alias Alias="StatusCode">i=19</Alias>
<Alias Alias="Structure">i=22</Alias>
<Alias Alias="Variant">i=24</Alias>
<Alias Alias="Number">i=26</Alias>
<Alias Alias="Integer">i=27</Alias>
<Alias Alias="UInteger">i=28</Alias>
<Alias Alias="HasComponent">i=47</Alias>
<Alias Alias="HasProperty">i=46</Alias>
<Alias Alias="Organizes">i=35</Alias>
<Alias Alias="HasEventSource">i=36</Alias>
<Alias Alias="HasNotifier">i=48</Alias>
<Alias Alias="HasSubtype">i=45</Alias>
<Alias Alias="HasTypeDefinition">i=40</Alias>
<Alias Alias="HasModellingRule">i=37</Alias>
<Alias Alias="HasEncoding">i=38</Alias>
<Alias Alias="HasDescription">i=39</Alias>
*/
module.exports.convertToString = function(inType) {
if (inType === "ns=0;i=1") return "Boolean";
if (inType === "ns=0;i=2") return "SByte";
if (inType === "ns=0;i=3") return "Byte";
if (inType === "ns=0;i=4") return "Int16";
if (inType === "ns=0;i=5") return "UInt16";
if (inType === "ns=0;i=6") return "Int32";
if (inType === "ns=0;i=7") return "UInt32";
if (inType === "ns=0;i=8") return "Int64";
if (inType === "ns=0;i=9") return "UInt64";
if (inType === "ns=0;i=10") return "Float";
if (inType === "ns=0;i=11") return "Double";
if (inType === "ns=0;i=12") return "String"; // Fixed from DateTime
if (inType === "ns=0;i=13") return "DateTime"; // Fixed from String
if (inType === "ns=0;i=14") return "Guid";
if (inType === "ns=0;i=15") return "ByteString";
if (inType === "ns=0;i=16") return "XmlElement";
if (inType === "ns=0;i=17") return "NodeId";
if (inType === "ns=0;i=18") return "ExpandedNodeId";
if (inType === "ns=0;i=19") return "StatusCode";
if (inType === "ns=0;i=20") return "QualifiedName";
if (inType === "ns=0;i=21") return "LocalizedText";
if (inType === "ns=0;i=22") return "Structure";
if (inType === "ns=0;i=24") return "Variant";
if (inType === "ns=0;i=26") return "Number";
if (inType === "ns=0;i=27") return "Integer";
if (inType === "ns=0;i=28") return "UInteger";
if (inType === "ns=0;i=884") return "EngineeringRange";
if (inType === "ns=0;i=887") return "EngineeringUnits";
console.log("Cannot convert from nodeId dataType: '" + inType + "' to string!")
return "";
}
module.exports.buildBrowseMessage = function (topic) {
return {
"topic": topic,
"nodeId": "",
"browseName": "",
"description": "",
// "nodeClassType": "",
"typeDefinition": "",
"dataType": "",
"payload": ""
};
};
module.exports.toInt32 = function (x) {
var uint16 = x;
if (uint16 >= Math.pow(2, 15)) {
uint16 = x - Math.pow(2, 16);
return uint16;
} else {
return uint16;
}
};
module.exports.get_node_status = function (statusValue) {
var fillValue = "red";
var shapeValue = "dot";
switch (statusValue) {
case "create client":
case "connecting":
case "connected":
case "initialized":
case "keepalive":
case "nodeId stored":
case "clear items":
case "building method arguments":
case "call method":
case "executing method":
fillValue = "green";
shapeValue = "ring";
break;
case "reconnect":
case "closed":
fillValue = "yellow";
shapeValue = "dot";
break;
case "active":
case "active reading":
case "value written":
case "values written":
case "active multiple reading":
case "active writing":
case "writing":
case "active subscribing":
case "unsubscribing":
case "active subscribed":
case "active browsing":
case "active monitoring":
case "active alarm":
case "active event":
case "session active":
case "session closed":
case "subscribed":
case "browse done":
case "changed":
case "method executed":
fillValue = "green";
shapeValue = "dot";
break;
case "error":
case "call method error":
case "execute method error":
case "extensionObject error":
case "invalid session":
case "invalid endpoint":
case "invalid certificate":
case "disconnected":
case "connection error":
case "subscription error":
case "node error":
case "terminated":
case "no client":
case "no items to read":
case "no items to write":
fillValue = "red";
shapeValue = "ring";
break;
default:
if (!statusValue) {
fillValue = "blue";
statusValue = "waiting ...";
}
break;
}
return {
fill: fillValue,
shape: shapeValue,
status: statusValue
};
};
module.exports.build_new_variant = function (datatype, value) {
var nValue = new opcua.Variant({
dataType: opcua.DataType.Float,
value: 0.0
});
switch (datatype) {
case "Float":
nValue = new opcua.Variant({
dataType: opcua.DataType.Float,
value: parseFloat(value)
});
break;
case "Double":
nValue = new opcua.Variant({
dataType: opcua.DataType.Double,
value: parseFloat(value)
});
break;
case "Int32":
nValue = new opcua.Variant({
dataType: opcua.DataType.Int32,
value: parseInt(value)
});
break;
case "Int16":
nValue = new opcua.Variant({
dataType: opcua.DataType.Int16,
value: parseInt(value)
});
break;
case "Int8":
nValue = new opcua.Variant({
dataType: opcua.DataType.SByte,
value: parseInt(value)
});
break;
case "UInt32":
nValue = new opcua.Variant({
dataType: opcua.DataType.UInt32,
value: parseInt(value)
});
break;
case "UInt16":
nValue = new opcua.Variant({
dataType: opcua.DataType.UInt16,
value: parseInt(value)
});
break;
case "UInt8":
nValue = new opcua.Variant({
dataType: opcua.DataType.Byte,
value: parseInt(value)
});
break;
case "Boolean":
// Support for different value conversions
if (value && value === "false") {
nValue = new opcua.Variant({
dataType: opcua.DataType.Boolean,
value: false
});
}
if (value && value === false) {
nValue = new opcua.Variant({
dataType: opcua.DataType.Boolean,
value: false
});
}
if (value && value === 0) {
nValue = new opcua.Variant({
dataType: opcua.DataType.Boolean,
value: false
});
}
if (value && value === "true"){
nValue = new opcua.Variant({
dataType: opcua.DataType.Boolean,
value: true
});
}
if (value && value === true){
nValue = new opcua.Variant({
dataType: opcua.DataType.Boolean,
value: true
});
}
if (value && value === 1){
nValue = new opcua.Variant({
dataType: opcua.DataType.Boolean,
value: true
});
}
break;
case "String":
nValue = new opcua.Variant({
dataType: opcua.DataType.String,
value: value
});
break;
case "LocalizedText":
nValue = new opcua.Variant({
dataType: opcua.DataType.LocalizedText,
value: new opcua.LocalizedText({locale: "en", text: value})
});
break;
case "DateTime":
if (typeof value === "string") {
// String format like "2022-04-03 12:13:14"
nValue = new opcua.Variant({
dataType: opcua.DataType.DateTime,
value: new Date(Date.parse(value))
});
}
else if (value instanceof Date) {
// Date object
nValue = new opcua.Variant({
dataType: opcua.DataType.DateTime,
value: value
});
}
else {
// Number
nValue = new opcua.Variant({
dataType: opcua.DataType.DateTime,
value: new Date(value)
});
}
break;
case "Byte":
nValue = new opcua.Variant({
dataType: opcua.DataType.Byte,
value: value
});
break;
case "SByte":
nValue = new opcua.Variant({
dataType: opcua.DataType.SByte,
value: value
});
break;
default:
nValue = new opcua.Variant({
dataType: opcua.DataType.BaseDataType,
value: value
});
break;
}
// Checks if Array and grabs Data Type
var m = datatype.match(/\b(\w+) Array\b/);
if (m) {
nValue = new opcua.Variant({
dataType: opcua.DataType[m[1]],
value: value,
arrayType: opcua.VariantArrayType.Array,
arrayDimensions: [value.length]
});
}
return nValue;
};
function getArrayValues(datatype, items) {
var uaArray = {};
uaArray.values = [];
uaArray.uaType = null;
// console.debug("### getArrayValues:" + datatype + " items:" + items);
// Check datatype string, example Byte Array, Double Array etc.
if (datatype.indexOf("Boolean") === 0) {
uaArray.uaType = opcua.DataType.Boolean;
uaArray.values = new Array(items.length);
}
if (datatype.indexOf("UInt8") === 0 || datatype.indexOf("Byte") === 0) {
uaArray.uaType = opcua.DataType.Byte;
uaArray.values = new Uint8Array(items);
}
if (datatype.indexOf("UInt16") === 0) {
uaArray.uaType = opcua.DataType.UInt16;
uaArray.values = new Uint16Array(items);
}
if (datatype.indexOf("UInt32") === 0) {
uaArray.uaType = opcua.DataType.UInt32;
uaArray.values = new Uint32Array(items);
}
if (datatype.indexOf("Int8") === 0 || datatype.indexOf("SByte") === 0) {
uaArray.uaType = opcua.DataType.SByte;
uaArray.values = new Int8Array(items);
}
if (datatype.indexOf("Int16") === 0) {
uaArray.uaType = opcua.DataType.Int16;
uaArray.values = new Int16Array(items);
}
if (datatype.indexOf("Int32") === 0) {
uaArray.uaType = opcua.DataType.Int32;
uaArray.values = new Int32Array(items);
}
if (datatype.indexOf("Float") === 0) {
uaArray.uaType = opcua.DataType.Float;
uaArray.values = new Float32Array(items);
}
if (datatype.indexOf("Double") >= 0) {
uaArray.uaType = opcua.DataType.Double;
uaArray.values = new Float64Array(items);
}
if (datatype.indexOf("String") >= 0) {
uaArray.uaType = opcua.DataType.String;
uaArray.values = new Array(items);
// console.log("ITEMS:" + items.toString());
}
if (datatype.indexOf("Variant") >= 0) {
uaArray.uaType = opcua.DataType.Variant;
//uaArray.values = new Array(items);
uaArray.values = items;
// console.log("ITEMS:" + items.toString());
}
if (datatype.indexOf("ExtensionObject") >= 0) {
uaArray.uaType = opcua.DataType.ExtensionObject;
uaArray.values = items;
}
if (uaArray.uaType === null) {
console.warn("Array support for String nor ByteString etc. not implemented, only basic types supported!");
console.error("Unknown type for Array: " + datatype + " cannot convert items:" + items);
}
function setValue(item, index, arr) {
// Boolean, Float basic conversions TODO DateTime etc. if needed
if (uaArray.uaType === opcua.DataType.Float || uaArray.uaType === opcua.DataType.Double) {
uaArray.values[index] = parseFloat(item);
}
else if (uaArray.uaType === opcua.DataType.Boolean) {
// console.log("Item: " + item + " index: " + index);
uaArray.values[index] = false;
if (item === 1 || item === "1" || item === "true" || item === true) {
uaArray.values[index] = true;
}
}
else if (uaArray.uaType === opcua.DataType.String || uaArray.uaType === opcua.DataType.ExtensionObject) {
uaArray.values[index] = item;
}
else if (uaArray.uaType === opcua.DataType.Variant) {
//console.log("----------------------");
//console.log("ITEM: " + JSON.stringify(item));
//console.log("INDEX: " + JSON.stringify(index));
if (item.dataType == "Variant" && item.arrayType == "Array"){
var uaVarItems = [];
function fillVariatArray (varItem, varIdx, varArr){
uaVarItems[varIdx] = new opcua.Variant(
exports.build_new_dataValue(varItem.dataType, varItem.value)
)
}
item.value.forEach(fillVariatArray);
uaArray.values[index] = new opcua.Variant({
dataType: opcua.DataType.Variant,
arrayType: opcua.VariantArrayType.Array,
value: uaVarItems
});
//console.log("uaArray: " + JSON.stringify(uaArray.values[index]));
}
else {
uaArray.values[index] = item;
}
}
else {
uaArray.values[index] = parseInt(item);
}
}
items.forEach(setValue);
return uaArray.values;
}
module.exports.getUaType = function (datatype) {
// Convert datatype from string to UA DataType
if (datatype == "Boolean") {
return opcua.DataType.Boolean;
}
if (datatype === "Byte") {
return opcua.DataType.Byte;
}
if (datatype === "UInt16") {
return opcua.DataType.UInt16;
}
if (datatype === "UInt32") {
return opcua.DataType.UInt32;
}
if (datatype === "SByte") {
return opcua.DataType.SByte;
}
if (datatype === "Int16") {
return opcua.DataType.Int16;
}
if (datatype === "Int32") {
return opcua.DataType.Int32;
}
if (datatype === "Float") {
return opcua.DataType.Float;
}
if (datatype === "Double") {
return opcua.DataType.Double;
}
if (datatype === "String") {
return opcua.DataType.String;
}
if (datatype === "Variant") {
return opcua.DataType.Variant;
}
console.error("Unknown datatype for UA: " + datatype);
return null;
}
function getArrayType(datatype) {
// console.debug("getArrayType:" + datatype);
// Check datatype string, example Byte Array, Double Array etc.
if (datatype.indexOf("Boolean") >= 0) {
return opcua.DataType.Boolean;
}
if (datatype.indexOf("UInt8") >= 0 || datatype.indexOf("Byte") >= 0) {
return opcua.DataType.Byte;
}
if (datatype.indexOf("UInt16") >= 0) {
return opcua.DataType.UInt16;
}
if (datatype.indexOf("UInt32") >= 0) {
return opcua.DataType.UInt32;
}
if (datatype.indexOf("Int8") >= 0 || datatype.indexOf("SByte") >= 0) {
return opcua.DataType.SByte;
}
if (datatype.indexOf("Int16") >= 0) {
return opcua.DataType.Int16;
}
if (datatype.indexOf("Int32") >= 0) {
return opcua.DataType.Int32;
}
if (datatype.indexOf("Float") >= 0 || datatype.indexOf("Float32") >= 0) {
return opcua.DataType.Float;
}
if (datatype.indexOf("Double") >= 0 || datatype.indexOf("Float64") >= 0) {
return opcua.DataType.Double;
}
if (datatype.indexOf("String") >= 0) {
return opcua.DataType.String;
}
if (datatype.indexOf("Variant") >= 0) {
return opcua.DataType.Variant;
}
if (datatype.indexOf("ExtensionObject") >= 0) {
return opcua.DataType.ExtensionObject;
}
console.warn("Array support for String nor ByteString etc. not implemented, only basic types supported!");
console.error("Unknown type for Array: " + datatype);
return null;
}
module.exports.build_new_value_by_datatype = function (datatype, value) {
var nValue = 0;
var uaType;
switch (datatype) {
case "Float":
uaType = opcua.DataType.Float;
// nValue = parseFloat(value);
var float32 = new Float32Array([value]);
nValue = float32[0];
break;
case "Double":
uaType = opcua.DataType.Double;
// nValue = parseFloat(value); // (Double) or Float64 ?
var float64 = new Float64Array([value]);
nValue = float64[0];
break;
case "SByte":
uaType = opcua.DataType.SByte;
var int8 = new Int8Array([value]);
nValue = int8[0];
break;
case "Int8":
uaType = opcua.DataType.SByte;
var int8 = new Int8Array([value]);
nValue = int8[0];
break;
case "Int16":
uaType = opcua.DataType.Int16;
var int16 = new Int16Array([value]);
nValue = int16[0];
break;
case "Int32":
uaType = opcua.DataType.Int32;
var int32 = new Int32Array([value]);
nValue = int32[0];
break;
case "Byte":
uaType = opcua.DataType.Byte;
var uint8 = new Uint8Array([value]);
nValue = uint8[0];
break;
case "ByteString":
uaType = opcua.DataType.ByteString;
var nValue = Buffer.from(value);
break;
case "UInt8":
uaType = opcua.DataType.Byte;
var uint8 = new Uint8Array([value]);
nValue = uint8[0];
break;
case "UInt16":
uaType = opcua.DataType.UInt16;
var uint16 = new Uint16Array([value]);
nValue = uint16[0];
break;
case "UInt32":
uaType = opcua.DataType.UInt32;
var uint32 = new Uint32Array([value]);
nValue = uint32[0];
break;
case "UInt64":
uaType = opcua.DataType.UInt64;
// console.log("BYTES uint64: " + value);
var bytes = value.toString().split(",");
nValue = { arrayType: opcua.VariantArrayType.Scalar, dataType: opcua.DataType.UInt64, value: [parseInt(bytes[0]), parseInt(bytes[1])] };
break;
case "Int64":
uaType = opcua.DataType.Int64;
// console.log("BYTES int64: " + value);
var bytes = value.toString().split(",");
nValue = { arrayType: opcua.VariantArrayType.Scalar, dataType: opcua.DataType.Int64, value: [parseInt(bytes[0]), parseInt(bytes[1])] };
break;
case "Boolean":
uaType = opcua.DataType.Boolean;
if (value && value !== "false") {
nValue = true;
} else {
nValue = false;
}
break;
case "String":
uaType = opcua.DataType.String;
nValue = value.toString();
break;
case "LocalizedText":
uaType = opcua.DataType.LocalizedText;
nValue = new opcua.LocalizedText({locale: "en", text: value});
break;
case "DateTime":
uaType = opcua.DataType.DateTime;
if (typeof value === "string") {
nValue = value; // Date.parse(value); // new Date(value); // value.toString();
}
else if (value instanceof Date) {
// Date object
nValue = new opcua.Variant({
dataType: opcua.DataType.DateTime,
value: value
});
}
else {
// injected timestamp as integer
nValue = {
dataType: opcua.DataType.DateTime, // was UtcTime
value: new Date(parseInt(value)) // Date.parse(value)
};
}
break;
case "ExtensionObject":
uaType = opcua.DataType.ExtensionObject;
if (typeof value === "string") {
nValue = JSON.parse(value); // value should be valid string
}
else {
// Here we expect that value is already extension object, not a JSON object
nValue = value;
/* TEST
let test = {
dataType: opcua.DataType.ExtensionObject,
value: value,
arrayType: opcua.VariantArrayType.Array
};
console.log("TEST: " + JSON.stringify(test));
// Next Variant constructor will fail if value / test is not an extensionObject
nodeToWrite = {
nodeId: "ns=1;s=TEST",
attributeId: opcua.AttributeIds.Value,
value: new opcua.DataValue({
value: new opcua.Variant(test),
})
};
*/
}
break;
default:
// uaType = null;
nValue = value;
break;
}
// Checks if Array and grabs Data Type
// var m = datatype.match(/\b(\w+) Array\b/);
//console.log("-------------------");
//console.log("datatype: " + datatype);
//console.log("value: " + value);
var m = datatype.indexOf("Array");
if (m > 0) {
var arrayValues = [];
var items;
// Convert value (string) to individual array values
if (Array.isArray(value) && value.length === 1 && typeof(value[0]) === "string") {
var payload = value[0];
items = payload.split(",");
}
else {
if (value.hasOwnProperty("dataType")) {
// Already processed, return value
return value;
}
if (Array.isArray(value) && value.length > 0) {
items = value;
}
else {
items = value.split(",");
}
}
arrayValues = getArrayValues(datatype, items);
uaType = getArrayType(datatype);
nValue = {
dataType: uaType,
value: arrayValues,
arrayType: opcua.VariantArrayType.Array
};
}
return nValue;
};
module.exports.build_new_dataValue = function (datatype, value) {
var nValue = null;
switch (datatype) {
case "Float":
nValue = {
dataType: opcua.DataType.Float,
value: parseFloat(value)
};
break;
case "Double":
nValue = {
dataType: opcua.DataType.Double,
value: parseFloat(value)
};
break;
case "Int64":
// console.log("BYTES INT64: " + JSON.stringify(value));
nValue = { arrayType: opcua.VariantArrayType.Scalar, dataType: opcua.DataType.Int64, value: value.value };
break;
case "Int32":
nValue = {
dataType: opcua.DataType.Int32,
value: parseInt(value)
};
break;
case "Int16":
nValue = {
dataType: opcua.DataType.Int16,
value: parseInt(value)
};
break;
case "Int8":
nValue = {
dataType: opcua.DataType.SByte,
value: parseInt(value)
};
break;
case "UInt64":
// console.log("BYTES UINT64: " + value);
nValue = { arrayType: opcua.VariantArrayType.Scalar, dataType: opcua.DataType.UInt64, value: value.value };
break;
case "UInt32":
nValue = {
dataType: opcua.DataType.UInt32,
value: parseInt(value)
};
break;
case "UInt16":
nValue = {
dataType: opcua.DataType.UInt16,
value: parseInt(value)
};
break;
case "UInt8":
nValue = {
dataType: opcua.DataType.Byte,
value: parseInt(value)
};
break;
case "Boolean":
if (value && value !== "false") {
nValue = {
dataType: opcua.DataType.Boolean,
value: true
};
} else {
nValue = {
dataType: opcua.DataType.Boolean,
value: false
};
}
break;
case "String":
nValue = {
dataType: opcua.DataType.String,
value: value
};
break;
case "LocalizedText":
nValue = {
dataType: opcua.DataType.LocalizedText,
value: new opcua.LocalizedText({locale: "en", text: value })
};
break;
case "DateTime":
if (typeof value === "string") {
nValue = {
dataType: opcua.DataType.DateTime, // was UtcTime
value: new Date(Date.parse(value))
};
}
else if (value instanceof Date) {
// Date object
nValue = new opcua.Variant({
dataType: opcua.DataType.DateTime,
value: value
});
}
else {
// injected timestamp as integer
nValue = {
dataType: opcua.DataType.DateTime, // was UtcTime
value: new Date(parseInt(value)) // Date.parse(value)
};
}
break;
case "Byte":
nValue = {
dataType: opcua.DataType.Byte,
value: parseInt(value)
};
break;
case "SByte":
nValue = {
dataType: opcua.DataType.SByte,
value: parseInt(value)
};
break;
default:
nValue = {
dataType: opcua.DataType.BaseDataType,
value: value
};
break;
}
// Checks if Array and grabs Data Type
// var m = datatype.match(/\b(\w+) Array\b/);
//console.log("-------------------");
//console.log("datatype: " + JSON.stringify(datatype));
//console.log("value: " + JSON.stringify(value));
var m = datatype.indexOf("Array");
if (m > 0) {
var uaType = getArrayType(datatype);
var arrayValues;
//console.log("ARRAY: " + JSON.stringify({"uaType":uaType,"value":value}));
if (value && value.value) {
arrayValues = getArrayValues(datatype, Object.values(value.value));
}
else {
var items = value.split(",");
arrayValues = getArrayValues(datatype, Object.values(items));
}
nValue = {
dataType: uaType, // maps SByte and Byte // opcua.DataType[m[1]],
value: arrayValues,
arrayType: opcua.VariantArrayType.Array,
};
}
return nValue;
};