node-red-contrib-buffer-parser
Advanced tools
Comparing version 2.3.0 to 2.4.0
@@ -18,6 +18,6 @@ | ||
module.exports = function(RED) { | ||
module.exports = function (RED) { | ||
const RESULTYPEOPTS = ["object", "keyvalue", "value", "array", "buffer"]; | ||
const SWAPOPTS = ["swap16", "swap32", "swap64"]; | ||
const TYPEOPTS = [ | ||
const TYPEOPTS = [ | ||
"int", "int8", "byte", | ||
@@ -31,9 +31,9 @@ "uint", "uint8", | ||
"bcd", "bcdle", "bcdbe", | ||
"string", "ascii", "utf8", "utf16le", "ucs2", "latin1", "binary", "buffer" | ||
"string", "ascii", "utf8", "utf16le", "ucs2", "latin1", "binary", "buffer" | ||
]; | ||
function bufferParserNode(config) { | ||
RED.nodes.createNode(this,config); | ||
RED.nodes.createNode(this, config); | ||
var node = this; | ||
node.data = config.data || "";//data | ||
node.dataType = config.dataType || "msg"; | ||
node.data = config.data || "";//data | ||
node.dataType = config.dataType || "msg"; | ||
node.specification = config.specification || "";//specification | ||
@@ -58,3 +58,3 @@ node.specificationType = config.specificationType || "ui"; | ||
function isNumber(n) { | ||
if(n === "" || n === true || n === false) return false; | ||
if (n === "" || n === true || n === false) return false; | ||
return !isNaN(parseFloat(n)) && isFinite(n); | ||
@@ -71,8 +71,8 @@ } | ||
if(!item) | ||
if (!item) | ||
throw new Error("Spec item is invalid"); | ||
let isObject = (item != null && typeof item === 'object' && (Array.isArray(item) === false)); | ||
if(!isObject) | ||
if (!isObject) | ||
throw new Error("Spec item is invalid"); | ||
let formattedSpecItem = Object.assign({},item, { | ||
let formattedSpecItem = Object.assign({}, item, { | ||
"name": item.name || "item" + itemNumber, | ||
@@ -82,8 +82,9 @@ "type": item.type, | ||
"offsetbit": item.offsetbit, | ||
"scale": item.scale, | ||
"length": item.length || 1, | ||
"id" : itemNumber - 1 | ||
"id": itemNumber - 1 | ||
}); | ||
//ensure name is something | ||
if(!formattedSpecItem.name){ | ||
if (!formattedSpecItem.name) { | ||
formattedSpecItem.name = `item[${formattedSpecItem.id}]` | ||
@@ -93,16 +94,16 @@ } | ||
//ensure type is provided | ||
if(!formattedSpecItem.type) | ||
if (!formattedSpecItem.type) | ||
throw new Error("type is not specified for item '" + (formattedSpecItem.name || "unnamed") + "'"); | ||
//validate type | ||
if(!TYPEOPTS.includes(formattedSpecItem.type.toLowerCase())){ | ||
if (!TYPEOPTS.includes(formattedSpecItem.type.toLowerCase())) { | ||
throw new Error("'" + formattedSpecItem.type + "' is not a valid type (item '" + (formattedSpecItem.name || "unnamed") + "')"); | ||
} | ||
//ensure length is valid | ||
if(formattedSpecItem.length == null || formattedSpecItem.length == undefined){ | ||
if (formattedSpecItem.length == null || formattedSpecItem.length == undefined) { | ||
formattedSpecItem.length = 1; | ||
} else if(isNumber(formattedSpecItem.length)){ | ||
} else if (isNumber(formattedSpecItem.length)) { | ||
formattedSpecItem.length = parseInt(formattedSpecItem.length); | ||
if(formattedSpecItem.length == 0 /* || formattedSpecItem.length < -1 */ ){ | ||
if (formattedSpecItem.length == 0 /* || formattedSpecItem.length < -1 */) { | ||
throw new Error("length is not a valid number (item '" + (formattedSpecItem.name || "unnamed") + "')"); | ||
@@ -115,12 +116,12 @@ } | ||
//ensure offest is something (check other permissable property names for "offset" e.g. index & start) | ||
if(formattedSpecItem.offset == null || formattedSpecItem.offset == undefined){ | ||
if (formattedSpecItem.offset == null || formattedSpecItem.offset == undefined) { | ||
formattedSpecItem.offset == item.index; | ||
if(formattedSpecItem.offset == null) | ||
if (formattedSpecItem.offset == null) | ||
formattedSpecItem.offset == item.start || 0; | ||
} | ||
formattedSpecItem.offset = formattedSpecItem.offset || 0; | ||
if(isNumber(formattedSpecItem.offset)){ | ||
if (isNumber(formattedSpecItem.offset)) { | ||
formattedSpecItem.offset = parseInt(formattedSpecItem.offset) | ||
if(formattedSpecItem.offset < 0) { | ||
throw new Error("offsetbit must be zero or greater (item '" + (formattedSpecItem.name || "unnamed") + "')"); | ||
if (formattedSpecItem.offset < 0) { | ||
throw new Error("offsetbit must be zero or greater (item '" + (formattedSpecItem.name || "unnamed") + "')"); | ||
} | ||
@@ -130,11 +131,11 @@ } else { | ||
} | ||
//ensure offsetbit is something | ||
if(formattedSpecItem.offsetbit == null || formattedSpecItem.offsetbit == undefined){ | ||
if (formattedSpecItem.offsetbit == null || formattedSpecItem.offsetbit == undefined) { | ||
formattedSpecItem.offsetbit = 0; | ||
} | ||
if(isNumber(formattedSpecItem.offsetbit)){ | ||
if (isNumber(formattedSpecItem.offsetbit)) { | ||
formattedSpecItem.offsetbit = parseInt(formattedSpecItem.offsetbit); | ||
if(formattedSpecItem.offsetbit < 0) { | ||
throw new Error("offsetbit must be zero or greater (item '" + (formattedSpecItem.name || "unnamed") + "')"); | ||
if (formattedSpecItem.offsetbit < 0) { | ||
throw new Error("offsetbit must be zero or greater (item '" + (formattedSpecItem.name || "unnamed") + "')"); | ||
} | ||
@@ -145,2 +146,12 @@ } else { | ||
//ensure scale is something | ||
if (formattedSpecItem.scale == null || formattedSpecItem.scale == undefined) { | ||
formattedSpecItem.scale = 0; | ||
} | ||
if (isNumber(formattedSpecItem.scale)) { | ||
formattedSpecItem.scale = parseFloat(formattedSpecItem.scale); | ||
} else { | ||
throw new Error("scale is not a number (item '" + (formattedSpecItem.name || "unnamed") + "')"); | ||
} | ||
return formattedSpecItem; | ||
@@ -154,4 +165,4 @@ } | ||
*/ | ||
function parseSpecification(specification){ | ||
if(typeof specification == "string"){ | ||
function parseSpecification(specification) { | ||
if (typeof specification == "string") { | ||
specification = JSON.parse(); | ||
@@ -171,19 +182,19 @@ } | ||
_spec.options.msgProperty = specification.options.msgProperty || "payload"; | ||
if(specification.options.multipleResult === true) _spec.options.singleResult = false; | ||
if(specification.options.multipleResult === false) _spec.options.singleResult = true; | ||
if(specification.options.singleResult === false) _spec.options.singleResult = false; | ||
if(specification.options.singleResult === true) _spec.options.singleResult = true; | ||
if (specification.options.multipleResult === true) _spec.options.singleResult = false; | ||
if (specification.options.multipleResult === false) _spec.options.singleResult = true; | ||
if (specification.options.singleResult === false) _spec.options.singleResult = false; | ||
if (specification.options.singleResult === true) _spec.options.singleResult = true; | ||
_spec.options.setTopic = specification.options.setTopic === false ? false : true; | ||
//validate resultType | ||
if(!RESULTYPEOPTS.includes(_spec.options.resultType)){ | ||
if (!RESULTYPEOPTS.includes(_spec.options.resultType)) { | ||
throw new Error("resultType property is invalid"); | ||
} | ||
} | ||
//validate byteSwap | ||
if(Array.isArray(_spec.options.byteSwap)){ | ||
let allFound = _spec.options.byteSwap.every( ai => SWAPOPTS.includes(ai) ); | ||
if(!allFound){ | ||
throw new Error("byteSwap property contains unsupported option"); | ||
if (Array.isArray(_spec.options.byteSwap)) { | ||
let allFound = _spec.options.byteSwap.every(ai => SWAPOPTS.includes(ai)); | ||
if (!allFound) { | ||
throw new Error("byteSwap property contains unsupported option"); | ||
} | ||
@@ -193,9 +204,9 @@ } | ||
//dont parse .items if user just wants a buffer | ||
if(_spec.options.resultType !== "buffer"){ | ||
if (_spec.options.resultType !== "buffer") { | ||
//validate items | ||
if(specification.items == null || Array.isArray(specification.items) == false || specification.items.length < 1){ | ||
throw new Error("items property is not an array of objects") | ||
if (specification.items == null || Array.isArray(specification.items) == false || specification.items.length < 1) { | ||
throw new Error("items property is not an array of objects") | ||
} | ||
let itemNum = 0; | ||
_spec.items = specification.items.map(function(item) { | ||
_spec.items = specification.items.map(function (item) { | ||
itemNum++; | ||
@@ -215,8 +226,8 @@ return parseSpecificationItem(item, itemNum); | ||
*/ | ||
function setObjectProperty(obj, path, val){ | ||
function setObjectProperty(obj, path, val) { | ||
const keys = path.split('.'); | ||
const lastKey = keys.pop(); | ||
const lastObj = keys.reduce((obj, key) => | ||
obj[key] = obj[key] || {}, | ||
obj); | ||
const lastObj = keys.reduce((obj, key) => | ||
obj[key] = obj[key] || {}, | ||
obj); | ||
lastObj[lastKey] = val; | ||
@@ -234,31 +245,31 @@ }; | ||
function parser(data, validatedSpec, msg) { | ||
let result = { | ||
objectResults : {}, | ||
keyvalues : {}, | ||
arrayResults : [], | ||
values : [], | ||
objectResults: {}, | ||
keyvalues: {}, | ||
arrayResults: [], | ||
values: [], | ||
specification: validatedSpec | ||
} | ||
/** @type Buffer */ var buf; | ||
let isArray = Array.isArray(data); | ||
let isBuffer = Buffer.isBuffer(data); | ||
if(typeof data == "string"){ | ||
data = new Buffer.from(data); | ||
if (typeof data == "string") { | ||
data = new Buffer.from(data, "hex"); | ||
isBuffer = true; | ||
} | ||
if(!isArray && !isBuffer){ | ||
throw new Error(`data is not an array or a buffer`); | ||
if (!isArray && !isBuffer) { | ||
throw new Error(`data is not an array or a buffer`); | ||
} | ||
//get buffer | ||
if(isBuffer){ | ||
if (isBuffer) { | ||
buf = data; | ||
} | ||
//convert int16 array to buffer for easy access to data | ||
if(isArray){ | ||
buf = new Buffer.alloc(data.length*2); | ||
if (isArray) { | ||
buf = new Buffer.alloc(data.length * 2); | ||
let pos = 0; | ||
@@ -269,8 +280,8 @@ var arrayLength = data.length; | ||
let hb = ((data[i] & 0xff00) >> 8); | ||
buf.writeUInt8(hb,pos++); | ||
buf.writeUInt8(lb,pos++); | ||
buf.writeUInt8(hb, pos++); | ||
buf.writeUInt8(lb, pos++); | ||
} | ||
} | ||
//byte swap the data if requested | ||
@@ -280,8 +291,8 @@ //byteSwap can be boolean (i.e. swap16) | ||
//an array of directives e.g. ["swap64", "swap", "swap32"] - they will be executed in order | ||
if(validatedSpec.options.byteSwap){ | ||
if(Array.isArray(validatedSpec.options.byteSwap)){ | ||
if (validatedSpec.options.byteSwap) { | ||
if (Array.isArray(validatedSpec.options.byteSwap)) { | ||
let swaps = validatedSpec.options.byteSwap; | ||
for (let index = 0; index < swaps.length; index++) { | ||
let sw = swaps[index]; | ||
if(sw && typeof sw == "string" && sw.length > 0){ | ||
if (sw && typeof sw == "string" && sw.length > 0) { | ||
sw = sw.toLowerCase(); | ||
@@ -306,3 +317,3 @@ try { | ||
} | ||
} | ||
@@ -322,18 +333,18 @@ | ||
function getBit(number, bitPosition) { | ||
return (number & (1 << bitPosition)) === 0 ? 0 : 1; | ||
return (number & (1 << bitPosition)) === 0 ? 0 : 1; | ||
} | ||
//Set Bit | ||
function setBit(number, bitPosition) { | ||
return number | (1 << bitPosition); | ||
return number | (1 << bitPosition); | ||
} | ||
//Clear Bit | ||
function clearBit(number, bitPosition) { | ||
const mask = ~(1 << bitPosition); | ||
return number & mask; | ||
const mask = ~(1 << bitPosition); | ||
return number & mask; | ||
} | ||
//Update Bit | ||
function updateBit(number, bitPosition, bitValue) { | ||
const bitValueNormalized = bitValue ? 1 : 0; | ||
const clearMask = ~(1 << bitPosition); | ||
return (number & clearMask) | (bitValueNormalized << bitPosition); | ||
const bitValueNormalized = bitValue ? 1 : 0; | ||
const clearMask = ~(1 << bitPosition); | ||
return (number & clearMask) | (bitValueNormalized << bitPosition); | ||
} | ||
@@ -343,16 +354,16 @@ function byteToBits(val) { | ||
for (let index = 0; index < 8; index++) { | ||
const bit = getBit(val,index); | ||
const bit = getBit(val, index); | ||
bits.push(bit); | ||
} | ||
return { | ||
bits : bits, | ||
bit0 : bits[0], | ||
bit1 : bits[1], | ||
bit2 : bits[2], | ||
bit3 : bits[3], | ||
bit4 : bits[4], | ||
bit5 : bits[5], | ||
bit6 : bits[6], | ||
bit7 : bits[7], | ||
bits: bits, | ||
bit0: bits[0], | ||
bit1: bits[1], | ||
bit2: bits[2], | ||
bit3: bits[3], | ||
bit4: bits[4], | ||
bit5: bits[5], | ||
bit6: bits[6], | ||
bit7: bits[7], | ||
} | ||
@@ -363,23 +374,23 @@ } | ||
for (let index = 0; index < 16; index++) { | ||
const bit = getBit(val,index); | ||
const bit = getBit(val, index); | ||
bits.push(bit); | ||
} | ||
return { | ||
bits : bits, | ||
bit0 : bits[0], | ||
bit1 : bits[1], | ||
bit2 : bits[2], | ||
bit3 : bits[3], | ||
bit4 : bits[4], | ||
bit5 : bits[5], | ||
bit6 : bits[6], | ||
bit7 : bits[7], | ||
bit8 : bits[8], | ||
bit9 : bits[9], | ||
bit10 : bits[10], | ||
bit11 : bits[11], | ||
bit12 : bits[12], | ||
bit13 : bits[13], | ||
bit14 : bits[14], | ||
bit15 : bits[15], | ||
bits: bits, | ||
bit0: bits[0], | ||
bit1: bits[1], | ||
bit2: bits[2], | ||
bit3: bits[3], | ||
bit4: bits[4], | ||
bit5: bits[5], | ||
bit6: bits[6], | ||
bit7: bits[7], | ||
bit8: bits[8], | ||
bit9: bits[9], | ||
bit10: bits[10], | ||
bit11: bits[11], | ||
bit12: bits[12], | ||
bit13: bits[13], | ||
bit14: bits[14], | ||
bit15: bits[15], | ||
} | ||
@@ -389,3 +400,3 @@ } | ||
//helper function to convert to bcd equivelant | ||
var bcd2number = function(num, bytesize = 4) { | ||
var bcd2number = function (num, bytesize = 4) { | ||
let loByte = (num & 0x00ff); | ||
@@ -395,8 +406,8 @@ let hiByte = (num >> 8) & 0x00ff; | ||
n += (loByte & 0x0F) * 1; | ||
if(bytesize < 2) return n; | ||
n += ((loByte>>4) & 0x0F) * 10; | ||
if(bytesize < 3) return n; | ||
if (bytesize < 2) return n; | ||
n += ((loByte >> 4) & 0x0F) * 10; | ||
if (bytesize < 3) return n; | ||
n += (hiByte & 0x0F) * 100; | ||
if(bytesize < 4) return n; | ||
n += ((hiByte>>4) & 0x0F) * 1000; | ||
if (bytesize < 4) return n; | ||
n += ((hiByte >> 4) & 0x0F) * 1000; | ||
return n; | ||
@@ -407,3 +418,3 @@ } | ||
function itemReader(item, buffer, bufferFunction, dataSize) { | ||
item.value = dataGetter(buffer,item.offset,item.length,bufferFunction,dataSize,item.mask); | ||
item.value = dataGetter(buffer, item.offset, item.length, bufferFunction, dataSize, item.mask, item.scale); | ||
result.objectResults[item.name] = item; | ||
@@ -414,41 +425,42 @@ result.keyvalues[item.name] = item.value; | ||
} | ||
function sanitizeMask(mask, throwError){ | ||
function sanitizeMask(mask, throwError) { | ||
var _mask = mask | ||
try { | ||
if(_mask){ | ||
if(typeof _mask == "string" && _mask.trim() != ""){ | ||
if (_mask) { | ||
if (typeof _mask == "string" && _mask.trim() != "") { | ||
_mask = parseInt(_mask) | ||
} | ||
if(isNaN(_mask)){ | ||
if(throwError) throw new Error("mask " + mask + " is invalid") | ||
if (isNaN(_mask)) { | ||
if (throwError) throw new Error("mask " + mask + " is invalid") | ||
} | ||
} | ||
} catch (error) { | ||
if(throwError) throw e | ||
} | ||
return _mask; | ||
if (throwError) throw e | ||
} | ||
return _mask; | ||
} | ||
//helper function to return 1 or more correctly formatted values from the buffer | ||
function dataGetter(buffer, startByte, dataCount, bufferFunction, dataSize, mask) { | ||
function dataGetter(buffer, startByte, dataCount, bufferFunction, dataSize, mask, scale) { | ||
var _mask = sanitizeMask(mask) | ||
let index = 0; | ||
let index = 0; | ||
let value; | ||
if(dataCount > 1){ | ||
if (dataCount > 1) { | ||
value = []; | ||
} | ||
var fn = buffer[bufferFunction].bind(buffer); | ||
for(index = 0; index < dataCount; index++){ | ||
let bufPos = startByte + (index*dataSize); | ||
for (index = 0; index < dataCount; index++) { | ||
let bufPos = startByte + (index * dataSize); | ||
let val = fn(bufPos);//call specified function on the buffer | ||
if(_mask) val = (val & _mask) | ||
if(dataCount > 1){ | ||
value.push( val ); | ||
if (_mask) val = (val & _mask) | ||
if (scale && scale != 1) val = val * scale; | ||
if (dataCount > 1) { | ||
value.push(val); | ||
} else { | ||
value = val | ||
} | ||
} | ||
} | ||
return value; | ||
} | ||
@@ -458,6 +470,6 @@ | ||
result.buffer = buf; | ||
if(validatedSpec.resultType === "buffer"){ | ||
if (validatedSpec.resultType === "buffer") { | ||
return result; | ||
} | ||
var itemCount = validatedSpec.items.length; | ||
@@ -494,3 +506,3 @@ | ||
break; | ||
case 'uint16': | ||
@@ -551,3 +563,3 @@ case 'uint16be': | ||
break | ||
case 'string':// supported: 'ascii', 'utf8', 'utf16le', 'ucs2', 'latin1', and 'binary'. | ||
@@ -561,3 +573,3 @@ type = "ascii" | ||
case "binary": | ||
item.value = buf.toString(type, offset, offset+length); | ||
item.value = buf.toString(type, offset, offset + length); | ||
result.objectResults[item.name] = item; | ||
@@ -575,5 +587,5 @@ result.keyvalues[item.name] = item.value; | ||
if(Array.isArray(data) == false){ | ||
if (Array.isArray(data) == false) { | ||
data = [data] | ||
} | ||
} | ||
for (let index = 0; index < data.length; index++) { | ||
@@ -584,3 +596,3 @@ const thisByte = data[index]; | ||
} | ||
if(length == 1){ | ||
if (length == 1) { | ||
item.value = bitData[item.offsetbit]; | ||
@@ -595,3 +607,3 @@ } else { | ||
} | ||
break; | ||
break; | ||
case "8bit": | ||
@@ -601,5 +613,5 @@ { | ||
let bitData = []; | ||
if(Array.isArray(data) === false){ | ||
if (Array.isArray(data) === false) { | ||
data = [data] | ||
} | ||
} | ||
for (let index = 0; index < data.length; index++) { | ||
@@ -621,8 +633,8 @@ const thisByte = data[index]; | ||
{ | ||
let fn = type == "16bitle" ? "readUInt16LE": "readUInt16BE"; | ||
let fn = type == "16bitle" ? "readUInt16LE" : "readUInt16BE"; | ||
let data = dataGetter(buf, item.offset, item.length, fn, 2, item.mask) | ||
let bitData = []; | ||
if(Array.isArray(data) == false){ | ||
if (Array.isArray(data) == false) { | ||
data = [data]; | ||
} | ||
} | ||
for (let index = 0; index < data.length; index++) { | ||
@@ -639,3 +651,3 @@ const thisByte = data[index]; | ||
} | ||
break; | ||
break; | ||
case "bcd": | ||
@@ -645,5 +657,5 @@ case "bcdle": | ||
{ | ||
let fn = type == "bcdle" ? "readUInt16LE": "readUInt16BE"; | ||
let fn = type == "bcdle" ? "readUInt16LE" : "readUInt16BE"; | ||
let data = dataGetter(buf, item.offset, item.length, fn, 2, item.mask) | ||
if(item.length > 1){ | ||
if (item.length > 1) { | ||
dataBCD = data.map(e => bcd2number(e)); | ||
@@ -659,5 +671,5 @@ } else { | ||
} | ||
break; | ||
break; | ||
case "buffer": | ||
item.value = buf.slice(offset,offset+length); | ||
item.value = buf.slice(offset, offset + length); | ||
result.objectResults[item.name] = item; | ||
@@ -671,8 +683,8 @@ result.keyvalues[item.name] = item.value; | ||
console.warn(errmsg); | ||
throw new Error(errmsg); | ||
throw new Error(errmsg); | ||
break; | ||
} | ||
if(validatedSpec.options.singleResult === false){ | ||
let m = { topic: msg.topic, specification : item }; | ||
if(validatedSpec.options.setTopic) m.topic = item.name; | ||
if (validatedSpec.options.singleResult === false) { | ||
let m = { topic: msg.topic, specification: item }; | ||
if (validatedSpec.options.setTopic) m.topic = item.name; | ||
switch (validatedSpec.options.resultType) { | ||
@@ -686,3 +698,3 @@ case "value": | ||
break; | ||
} | ||
} | ||
node.send(m); | ||
@@ -695,9 +707,9 @@ } | ||
node.on('input', function(msg) { | ||
node.on('input', function (msg) { | ||
node.status({});//clear status | ||
var data; | ||
RED.util.evaluateNodeProperty(node.data,node.dataType,node,msg,(err,value) => { | ||
RED.util.evaluateNodeProperty(node.data, node.dataType, node, msg, (err, value) => { | ||
if (err) { | ||
node.error("Unable to evaluate data",msg); | ||
node.status({fill:"red",shape:"ring",text:"Unable to evaluate data"}); | ||
node.error("Unable to evaluate data", msg); | ||
node.status({ fill: "red", shape: "ring", text: "Unable to evaluate data" }); | ||
return;//halt flow! | ||
@@ -707,8 +719,8 @@ } else { | ||
} | ||
}); | ||
}); | ||
var specification; | ||
RED.util.evaluateNodeProperty(node.specification,node.specificationType,node,msg,(err,value) => { | ||
RED.util.evaluateNodeProperty(node.specification, node.specificationType, node, msg, (err, value) => { | ||
if (err) { | ||
node.error("Unable to evaluate specification",msg); | ||
node.status({fill:"red",shape:"ring",text:"Unable to evaluate specification"}); | ||
node.error("Unable to evaluate specification", msg); | ||
node.status({ fill: "red", shape: "ring", text: "Unable to evaluate specification" }); | ||
return;//halt flow! | ||
@@ -718,14 +730,14 @@ } else { | ||
} | ||
}); | ||
}); | ||
if(node.specificationType == "ui") { | ||
if (node.specificationType == "ui") { | ||
specification = {}; | ||
var swap1; | ||
RED.util.evaluateNodeProperty(node.swap1,node.swap1Type,node,msg,(err,value) => { | ||
RED.util.evaluateNodeProperty(node.swap1, node.swap1Type, node, msg, (err, value) => { | ||
if (err) { | ||
node.error("Unable to evaluate swap1",msg); | ||
node.status({fill:"red",shape:"ring",text:"Unable to evaluate swap1"}); | ||
node.error("Unable to evaluate swap1", msg); | ||
node.status({ fill: "red", shape: "ring", text: "Unable to evaluate swap1" }); | ||
return;//halt flow! | ||
} else { | ||
if(node.swap1Type == "env"){ | ||
if (node.swap1Type == "env") { | ||
swap1 = value.split(","); | ||
@@ -737,10 +749,10 @@ swap1 = swap1.map(e => e.trim()); | ||
} | ||
}); | ||
}); | ||
var swap2; | ||
var swap3; | ||
if(node.swap1Type == "swap"){ | ||
RED.util.evaluateNodeProperty(node.swap2,node.swap2Type,node,msg,(err,value) => { | ||
if (node.swap1Type == "swap") { | ||
RED.util.evaluateNodeProperty(node.swap2, node.swap2Type, node, msg, (err, value) => { | ||
if (err) { | ||
node.error("Unable to evaluate swap2",msg); | ||
node.status({fill:"red",shape:"ring",text:"Unable to evaluate swap2"}); | ||
node.error("Unable to evaluate swap2", msg); | ||
node.status({ fill: "red", shape: "ring", text: "Unable to evaluate swap2" }); | ||
return;//halt flow! | ||
@@ -750,7 +762,7 @@ } else { | ||
} | ||
}); | ||
RED.util.evaluateNodeProperty(node.swap3,node.swap3Type,node,msg,(err,value) => { | ||
}); | ||
RED.util.evaluateNodeProperty(node.swap3, node.swap3Type, node, msg, (err, value) => { | ||
if (err) { | ||
node.error("Unable to evaluate swap3",msg); | ||
node.status({fill:"red",shape:"ring",text:"Unable to evaluate swap3"}); | ||
node.error("Unable to evaluate swap3", msg); | ||
node.status({ fill: "red", shape: "ring", text: "Unable to evaluate swap3" }); | ||
return;//halt flow! | ||
@@ -760,10 +772,10 @@ } else { | ||
} | ||
}); | ||
}); | ||
} | ||
var resultType; | ||
RED.util.evaluateNodeProperty(node.resultType,node.resultTypeType,node,msg,(err,value) => { | ||
RED.util.evaluateNodeProperty(node.resultType, node.resultTypeType, node, msg, (err, value) => { | ||
if (err) { | ||
node.error("Unable to evaluate resultType",msg); | ||
node.status({fill:"red",shape:"ring",text:"Unable to evaluate resultType"}); | ||
node.error("Unable to evaluate resultType", msg); | ||
node.status({ fill: "red", shape: "ring", text: "Unable to evaluate resultType" }); | ||
return;//halt flow! | ||
@@ -773,3 +785,3 @@ } else { | ||
} | ||
}); | ||
}); | ||
var msgProperty = node.msgProperty; | ||
@@ -787,10 +799,10 @@ // RED.util.evaluateNodeProperty(node.msgProperty,"str" node.msgPropertyType,node,msg,(err,value) => { | ||
var swap = []; | ||
if(Array.isArray(swap1)){ | ||
if (Array.isArray(swap1)) { | ||
swap = swap1; | ||
} else { | ||
if(swap1){ | ||
if (swap1) { | ||
swap.push(swap1); | ||
if(swap2){ | ||
if (swap2) { | ||
swap.push(swap2); | ||
if(swap3){ | ||
if (swap3) { | ||
swap.push(swap3); | ||
@@ -811,3 +823,3 @@ } | ||
} | ||
} | ||
@@ -819,4 +831,4 @@ | ||
} catch (error) { | ||
node.error(error,msg); | ||
node.status({fill:"red",shape:"dot",text:error.message}); | ||
node.error(error, msg); | ||
node.status({ fill: "red", shape: "dot", text: error.message }); | ||
return;//halt flow | ||
@@ -827,5 +839,5 @@ } | ||
try { | ||
let results = parser(data,validatedSpec,msg); | ||
if(validatedSpec.options.singleResult !== false){ | ||
let results = parser(data, validatedSpec, msg); | ||
if (validatedSpec.options.singleResult !== false) { | ||
msg.specification = results.specification; | ||
@@ -855,3 +867,3 @@ msg.values = results.values; | ||
break; | ||
} | ||
} | ||
node.send(msg); | ||
@@ -861,4 +873,4 @@ } | ||
} catch (error) { | ||
node.error(error,msg); | ||
node.status({fill:"red",shape:"dot",text:"Error parsing data"}); | ||
node.error(error, msg); | ||
node.status({ fill: "red", shape: "dot", text: "Error parsing data" }); | ||
return;//halt flow | ||
@@ -870,3 +882,3 @@ } | ||
} | ||
RED.nodes.registerType("buffer-parser",bufferParserNode); | ||
RED.nodes.registerType("buffer-parser", bufferParserNode); | ||
} |
{ | ||
"name": "node-red-contrib-buffer-parser", | ||
"version": "2.3.0", | ||
"version": "2.4.0", | ||
"description": "A dynamic node to convert values in a buffer or integer array into the many different data type(s). Supports Big/Little Endian, BCD, byte swapping and much more", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -36,2 +36,3 @@ node-red-contrib-buffer-parser | ||
* Input data can be a 16bit array (common plc data format) simplifying working with PLC type data arrays | ||
* Input data can be a hex string e.g. `1FE2D7FFBE` | ||
* Output results can be multiple messages as `topic` and `payload` | ||
@@ -47,2 +48,5 @@ * ideal for taking PLC data and sending it directly to MQTT | ||
* "buffer" : this mode simply returns a buffer (no item processing) | ||
* Final values can be masked (e.g. a MASK of `0x7FFF` could be used to remove the MSB) | ||
* Final values can be have a scale applied (e.g. a scale of `0.01` would turn `9710` into `97.1` or a scale of 10 would turn `50` into `500`) | ||
* NOTE: the scale is applied AFTER the mask | ||
* Built in help | ||
@@ -49,0 +53,0 @@ |
Sorry, the diff of this file is not supported yet
423302
755
118