node-red-contrib-netvar-utils
Version:
Network Variable List utility nodes for node-red
163 lines • 5.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.countVariables = exports.isNvlPacket = exports.writePacketHeader = exports.readPacketIndex = exports.readPacketHeader = exports.getReaderOf = exports.getSizeOf = exports.buildNetworkVariableListJSON = exports.times = void 0;
const constants_1 = require("./constants");
function times(repeat, callback) {
const arr = [];
for (let i = 0; i < repeat; i++)
arr.push(callback(i));
return arr;
}
exports.times = times;
function buildNetworkVariableListJSON(netvars) {
const nvl = {};
for (const netvar of netvars) {
nvl[netvar.name]
= netvar.isArray
? buildNetworkVariableListJSONArray(netvar.dimensions, getInitialValue(netvar.type))
: getInitialValue(netvar.type);
}
return nvl;
}
exports.buildNetworkVariableListJSON = buildNetworkVariableListJSON;
function buildNetworkVariableListJSONArray(dimensions, fill) {
const recurse = (rest) => rest.length === 1
? times(rest[0], () => fill)
: times(rest[0], () => recurse(rest.slice(1)));
return recurse(dimensions);
}
/** Get zero-based value for given Netvar Type */
function getInitialValue(type) {
switch (type) {
case 'LWORD':
case 'ULINT':
case 'LINT':
// TODO: BigInt
return 0;
case 'BOOL':
return false;
case 'STRING':
return '';
default:
return 0;
}
}
const byteSizes = {
// boolean
BOOL: 1,
// integer
BYTE: 1,
WORD: 2,
DWORD: 4,
LWORD: 8,
SINT: 1,
USINT: 1,
INT: 2,
UINT: 2,
DINT: 4,
UDINT: 4,
LINT: 8,
ULINT: 8,
// float
REAL: 4,
LREAL: 8,
// string (default)
STRING: 81,
// time
TIME: 4,
TIME_OF_DAY: 4,
DATE: 4,
DATE_AND_TIME: 4,
};
function getSizeOf(type) {
return byteSizes[type] || 0;
}
exports.getSizeOf = getSizeOf;
function getReaderOf(type) {
switch (type) {
case 'BOOL':
return (buffer, offset) => buffer.readUInt8(offset) === 1;
case 'BYTE':
case 'USINT':
return (buffer, offset) => buffer.readUInt8(offset);
case 'SINT':
return (buffer, offset) => buffer.readInt8(offset);
case 'WORD':
case 'UINT':
return (buffer, offset) => buffer.readUInt16LE(offset);
case 'INT':
return (buffer, offset) => buffer.readInt16LE(offset);
case 'DWORD':
case 'UDINT':
case 'TIME':
case 'TIME_OF_DAY':
case 'DATE':
case 'DATE_AND_TIME':
return (buffer, offset) => buffer.readUInt32LE(offset);
case 'DINT':
return (buffer, offset) => buffer.readInt32LE(offset);
case 'LWORD':
case 'ULINT':
return (buffer, offset) => buffer.readBigUInt64LE(offset);
case 'LINT':
return (buffer, offset) => buffer.readBigInt64LE(offset);
case 'REAL':
return (buffer, offset) => buffer.readFloatLE(offset);
case 'LREAL':
return (buffer, offset) => buffer.readDoubleLE(offset);
case 'STRING':
return (buffer, offset = 0) => buffer.toString('ascii', offset, buffer.indexOf(0, offset, 'ascii'));
default:
throw new TypeError('Unrecognized data type');
}
}
exports.getReaderOf = getReaderOf;
function readPacketHeader(buffer) {
if (buffer.length < 20)
throw new TypeError('Network Variable UDP packets should be at least 20 byte long');
return {
protocol: buffer.toString('ascii', constants_1.OFFSET_PROTOCOL, constants_1.NETVAR_PROTOCOL_ID.length),
listId: buffer.readUInt16LE(constants_1.OFFSET_LIST_ID),
packetIndex: buffer.readUInt16LE(constants_1.OFFSET_PACKET_INDEX),
variableCount: buffer.readUInt16LE(constants_1.OFFSET_VAR_COUNT),
packetSize: buffer.readUInt16LE(constants_1.OFFSET_PACKET_SIZE),
counter: buffer.readUInt16LE(constants_1.OFFSET_COUNTER),
};
}
exports.readPacketHeader = readPacketHeader;
function readPacketIndex(buffer) {
if (buffer.length < constants_1.PACKET_HEADER_SIZE)
throw new TypeError(`Network Variable UDP packets should be at least ${constants_1.PACKET_HEADER_SIZE} byte long`);
return buffer.readUInt16LE(10);
}
exports.readPacketIndex = readPacketIndex;
function writePacketHeader(buffer, header) {
if (buffer.length < constants_1.PACKET_HEADER_SIZE)
throw new TypeError(`Network Variable UDP packets should be at least ${constants_1.PACKET_HEADER_SIZE} byte long`);
buffer.write(constants_1.NETVAR_PROTOCOL_ID, constants_1.OFFSET_PROTOCOL, 'ascii');
buffer.writeUInt16LE(header.listId, constants_1.OFFSET_LIST_ID);
buffer.writeUInt16LE(header.packetIndex, constants_1.OFFSET_PACKET_INDEX);
buffer.writeUInt16LE(header.variableCount, constants_1.OFFSET_VAR_COUNT);
buffer.writeUInt16LE(header.packetSize, constants_1.OFFSET_PACKET_SIZE);
buffer.writeUInt32LE(header.counter, constants_1.OFFSET_COUNTER);
}
exports.writePacketHeader = writePacketHeader;
function isNvlPacket(buffer) {
return buffer.length >= constants_1.PACKET_HEADER_SIZE
&& buffer.toString('ascii', 0, 4) === constants_1.NETVAR_PROTOCOL_ID
&& buffer.readUInt16LE(constants_1.OFFSET_PACKET_SIZE) === buffer.length;
}
exports.isNvlPacket = isNvlPacket;
/** Calculates the total number of variables in all definitions */
function countVariables(definitions) {
let variableCount = 0;
for (const definition of definitions) {
if (definition.isArray)
variableCount += definition.end - definition.begin;
else
variableCount += 1;
}
return variableCount;
}
exports.countVariables = countVariables;
//# sourceMappingURL=util.js.map