@fabianvolkers/n8n-nodes-modbus-trigger
Version:
n8n node to trigger Modbus Address on change
151 lines • 7.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModbusTrigger = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const GenericFunctions_1 = require("./GenericFunctions");
class ModbusTrigger {
constructor() {
this.description = {
displayName: 'MODBUS Trigger',
name: 'modbusTrigger',
icon: 'file:modbus.svg',
group: ['trigger'],
version: 1,
description: 'Listens to MODBUS TCP events',
eventTriggerDescription: '',
defaults: {
name: 'MODBUS Trigger',
},
triggerPanel: {
header: '',
executionsHelp: {
inactive: "<b>While building your workflow</b>, click the 'listen' button, then trigger an MODBUS event. This will trigger an execution, which will show up in this editor.<br /> <br /><b>Once you're happy with your workflow</b>, <a data-key='activate'>activate</a> it. Then every time a change is detected, the workflow will execute. These executions will show up in the <a data-key='executions'>executions list</a>, but not in the editor.",
active: "<b>While building your workflow</b>, click the 'listen' button, then trigger an MODBUS event. This will trigger an execution, which will show up in this editor.<br /> <br /><b>Your workflow will also execute automatically</b>, since it's activated. Every time a change is detected, this node will trigger an execution. These executions will show up in the <a data-key='executions'>executions list</a>, but not in the editor.",
},
activationHint: "Once you’ve finished building your workflow, <a data-key='activate'>activate</a> it to have it also listen continuously (you just won’t see those executions here).",
},
inputs: [],
outputs: ['main'],
credentials: [
{
name: 'modbusApi',
required: true,
},
],
properties: [
{
displayName: 'Memory Address',
name: 'memoryAddress',
type: 'number',
default: 1,
description: 'The memory address (register index) to read from',
},
{
displayName: 'Quantity',
name: 'quantity',
type: 'number',
default: 1,
description: 'The number of registers to read from the memory address',
},
{
displayName: 'Polling',
name: 'polling',
type: 'number',
default: 1000,
description: 'The polling interval in milliseconds',
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add option',
default: {},
options: [],
},
],
};
}
async trigger() {
let poller;
let client;
try {
const credentials = await this.getCredentials('modbusApi');
const memoryAddress = this.getNodeParameter('memoryAddress');
const quantity = this.getNodeParameter('quantity');
const polling = this.getNodeParameter('polling');
const options = this.getNodeParameter('options');
if (isNaN(memoryAddress)) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Memory address must be a valid number.');
}
client = await (0, GenericFunctions_1.createClient)(credentials);
const compareBuffers = (buf1, buf2) => {
if (!buf1 || !buf2 || buf1.length !== buf2.length)
return false;
return buf1.every((b, i) => b.equals(buf2[i]));
};
if (this.getMode() === 'trigger') {
const donePromise = !options.parallelProcessing
? this.helpers.createDeferredPromise()
: undefined;
let previousData;
poller = setInterval(() => {
client.readHoldingRegisters({ address: memoryAddress, quantity }, (err, data) => {
if (err) {
clearInterval(poller);
throw new n8n_workflow_1.NodeOperationError(this.getNode(), err.message);
}
if (!compareBuffers(previousData, data === null || data === void 0 ? void 0 : data.response.data)) {
previousData = data === null || data === void 0 ? void 0 : data.response.data;
const returnData = {
data: previousData === null || previousData === void 0 ? void 0 : previousData.map((value) => value.readInt16BE(0)),
};
this.emit([this.helpers.returnJsonArray([returnData])]);
if (donePromise) {
donePromise.promise;
}
}
});
}, polling);
}
const manualTriggerFunction = async () => {
return new Promise((resolve, reject) => {
let cycle = 0;
let previousData;
poller = setInterval(() => {
client.readHoldingRegisters({ address: memoryAddress, quantity }, (err, data) => {
if (err) {
clearInterval(poller);
reject(new n8n_workflow_1.NodeOperationError(this.getNode(), err.message));
return;
}
if (!compareBuffers(previousData, data === null || data === void 0 ? void 0 : data.response.data) || cycle === 0) {
previousData = data === null || data === void 0 ? void 0 : data.response.data;
if (cycle > 0) {
const returnData = {
data: previousData === null || previousData === void 0 ? void 0 : previousData.map((value) => value.readInt16BE(0)),
};
this.emit([this.helpers.returnJsonArray([returnData])]);
clearInterval(poller);
resolve();
}
cycle++;
}
});
}, polling);
});
};
const closeFunction = async () => {
clearInterval(poller);
};
return {
closeFunction,
manualTriggerFunction,
};
}
catch (error) {
throw error;
}
}
}
exports.ModbusTrigger = ModbusTrigger;
//# sourceMappingURL=ModbusTrigger.node.js.map