n8n-nodes-modbus-trigger
Version:
n8n node to trigger Modbus Address on change
252 lines • 10.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Modbus = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const GenericFunctions_1 = require("./GenericFunctions");
class Modbus {
constructor() {
this.description = {
displayName: 'MODBUS',
name: 'modbus',
icon: 'file:modbus.svg',
group: ['input'],
version: 1,
description: 'Read and write to MODBUS devices',
eventTriggerDescription: '',
defaults: {
name: 'MODBUS',
},
usableAsTool: true,
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'modbusApi',
required: true,
},
],
properties: [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
options: [
{
name: 'Read',
value: 'read',
},
{
name: 'Write',
value: 'write',
},
],
default: 'read',
noDataExpression: true,
},
{
displayName: 'Memory Address',
name: 'memoryAddress',
type: 'number',
default: 1,
description: 'The memory address (register index) to read from or write to',
},
{
displayName: 'Unit-ID',
name: 'unitId',
type: 'number',
default: 1,
description: 'Unit-ID to address devices behind modbus-bridges',
},
{
displayName: 'Data Type',
name: 'dataTypeRead',
type: 'options',
displayOptions: {
show: {
operation: ['read'],
},
},
options: [
{
name: 'Signed 16-Bit Integer',
value: 'int16',
},
{
name: 'Signed 32-Bit Integer',
value: 'int32',
},
{
name: 'Signed 64-Bit Big-Integer',
value: 'int64',
},
{
name: 'Unsigned 16-Bit Integer',
value: 'uint16',
},
{
name: 'Unsigned 32-Bit Integer',
value: 'uint32',
},
{
name: 'Unsigned 64-Bit Big-Integer',
value: 'uint64',
},
],
default: 'int16',
noDataExpression: true,
},
{
displayName: 'Data Type',
name: 'dataTypeWrite',
type: 'options',
displayOptions: {
show: {
operation: ['write'],
},
},
options: [
{
name: 'Signed 16-Bit Integer',
value: 'int16',
},
{
name: 'Signed 32-Bit Integer',
value: 'int32',
},
{
name: 'Unsigned 16-Bit Integer',
value: 'uint16',
},
{
name: 'Unsigned 32-Bit Integer',
value: 'uint32',
},
],
default: 'int16',
noDataExpression: true,
},
{
displayName: 'Quantity',
displayOptions: {
show: {
operation: ['read'],
},
},
name: 'quantity',
type: 'number',
default: 1,
description: 'The number of data to read from the memory address',
},
{
displayName: 'Value',
displayOptions: {
show: {
operation: ['write'],
},
},
name: 'value',
type: 'number',
typeOptions: {
maxValue: 4294967295,
minValue: -2147483648,
},
default: 1,
description: 'The value to write to the memory address',
},
],
};
}
async execute() {
let responseData = {};
const credentials = await this.getCredentials('modbusApi');
const client = await (0, GenericFunctions_1.createClient)(credentials);
const memoryAddress = this.getNodeParameter('memoryAddress', 0);
const operation = this.getNodeParameter('operation', 0);
const unitId = this.getNodeParameter('unitId', 0, 1);
const dataType = this.getNodeParameter(operation === 'read' ? 'dataTypeRead' : 'dataTypeWrite', 0, 'int16');
if (operation === 'read') {
const quantity = this.getNodeParameter('quantity', 0);
responseData = await new Promise((resolve) => {
client.readHoldingRegisters({
address: memoryAddress,
quantity: quantity * (0, GenericFunctions_1.registerCount)(dataType),
extra: { unitId },
}, (err, data) => {
if (err) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'MODBUS Error: ' + err.message);
}
const registers = data === null || data === void 0 ? void 0 : data.response.data;
if (!registers) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'MODBUS Error: received no data');
}
resolve({
data: (0, GenericFunctions_1.extractModbusData)(this.getNode(), registers, dataType),
});
});
});
}
if (operation === 'write') {
const value = this.getNodeParameter('value', 0);
const buffer = Buffer.alloc((0, GenericFunctions_1.registerCount)(dataType) * 2);
switch (dataType) {
case 'int16':
if (value > 32767 || value < -32768) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'MODBUS Error: value does not fit into selected data type');
}
buffer.writeInt16BE(value);
break;
case 'uint16':
if (value > 65535 || value < 0) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'MODBUS Error: value does not fit into selected data type');
}
buffer.writeUInt16BE(value);
break;
case 'int32':
if (value > 2147483647 || value < -2147483648) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'MODBUS Error: value does not fit into selected data type');
}
buffer.writeInt32BE(value);
break;
case 'uint32':
if (value > 4294967295 || value < 0) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'MODBUS Error: value does not fit into selected data type');
}
buffer.writeUInt32BE(value);
break;
default:
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `MODBUS Error: Not implemented for data type ${dataType}`);
}
responseData = await new Promise((resolve) => {
const values = [];
for (let i = 0; i < (0, GenericFunctions_1.registerCount)(dataType); i++) {
const buf = Buffer.alloc(2);
buffer.copy(buf, 0, i * 2, i * 2 + 2);
values.push(buf);
}
if (values.length === 1) {
client.writeSingleRegister({ address: memoryAddress, value: values[0], extra: { unitId } }, (err, data) => {
if (err) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'MODBUS Error: ' + err.message);
}
resolve({
data: data.response,
});
});
}
else {
client.writeMultipleRegisters({ address: memoryAddress, values, extra: { unitId } }, (err, data) => {
if (err) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'MODBUS Error: ' + err.message);
}
resolve({
data: data.response,
});
});
}
});
}
return [this.helpers.returnJsonArray(responseData)];
}
}
exports.Modbus = Modbus;
//# sourceMappingURL=Modbus.node.js.map