node-red-contrib-netvar-utils
Version:
Network Variable List utility nodes for node-red
139 lines • 5.09 kB
JavaScript
;
const throttle_debounce_1 = require("throttle-debounce");
const util_1 = require("../shared/util");
const DEFAULT_TIMEOUT = 100;
const nodeInit = (RED) => {
function NvlEmitterNodeConstructor(config) {
var _a;
RED.nodes.createNode(this, config);
const nvl = (_a = RED.nodes.getNode(config.nvl)) === null || _a === void 0 ? void 0 : _a.nvl;
if (!nvl)
throw new TypeError('Network Variable List is not defined or invalid.');
const listener = config.emitOn === 'last-packet'
? createLastPacketListener(this, config, nvl)
: createEveryPacketListener(this, config, nvl, RED);
this.on('input', listener);
}
RED.nodes.registerType('nvl-reader', NvlEmitterNodeConstructor);
};
function createReadContext(config, nvl, send, onSend) {
const payload = nvl.createEmptyJSON();
const packets = Array(nvl.getExpectedPacketCount()).fill(false);
let messageSent = false;
/* @ts-ignore-next-line */
const context = {
payload,
packets,
counter: 0,
invalidPacketCounter: 0,
};
if (config.sendStats) {
const start = new Date().getTime();
context.send = (msg, timeout) => {
const end = new Date().getTime();
const duration = end - start;
msg.stats = {
start,
end,
duration,
timeout,
validPacketsReceived: context.counter,
invalidPacketsReceived: context.invalidPacketCounter,
missingPackets: packets.reduce((acc, received, index) => {
if (!received)
acc.push(index);
return acc;
}, []),
};
if (!messageSent) {
messageSent = true;
if (!timeout || (timeout && config.timeoutBehaviour === 'send')) {
msg.payload = payload;
send(msg);
onSend();
}
else {
msg.payload = null;
send(msg);
onSend();
}
}
};
}
else {
context.send = (msg, timeout) => {
if (!messageSent) {
messageSent = true;
if (!timeout || (timeout && config.timeoutBehaviour === 'send')) {
msg.payload = payload;
send(msg);
onSend();
}
}
};
}
context.debouncedSend = throttle_debounce_1.debounce(config.timeout || DEFAULT_TIMEOUT, context.send);
return context;
}
function createLastPacketListener(node, config, nvl) {
let context = null;
const expectedPacketCount = nvl.getExpectedPacketCount();
const listener = (msg, send, done) => {
if (!(msg.payload instanceof Buffer))
return done(new TypeError('Expected payload to be Buffer.'));
if (!context) {
context = createReadContext(config, nvl, send, () => {
context = null;
});
}
if (!nvl.isExpectedPacket(msg.payload)) {
context.invalidPacketCounter++;
return done();
}
const packet = msg.payload;
const index = util_1.readPacketIndex(msg.payload);
if (!context.packets[index]) {
context.packets[index] = true;
context.counter++;
nvl.readPacket(context.payload, packet);
context.debouncedSend(msg, true);
if (context.counter >= expectedPacketCount && context.packets.every(v => v)) {
context.debouncedSend.cancel();
context.send(msg, false);
}
}
done();
};
return listener;
}
function createEveryPacketListener(node, config, nvl, api) {
const listener = (msg, send, done) => {
if (!(msg.payload instanceof Buffer))
return done(new TypeError('Expected payload to be Buffer.'));
if (!nvl.isExpectedPacket(msg.payload))
return done();
const packet = msg.payload;
api.util.evaluateNodeProperty(config.initial, config.initialType, node, msg, (err, value) => {
if (value) {
if (!nvl.validateJSON(value)) {
node.error(nvl.validateJSON.errors);
return done(new TypeError('Bad JSON payload. See previous log for information.'));
}
nvl.readPacket(value, packet);
msg.payload = value;
}
else {
if (err)
node.warn(`${err.message}. Using JSON with empty values.`);
const payload = nvl.createEmptyJSON();
nvl.readPacket(payload, packet);
msg.payload = payload;
}
send(msg);
done();
});
};
return listener;
}
module.exports = nodeInit;
//# sourceMappingURL=nvl-reader.js.map