@aaqu/node-red-modbus-tcp 0.4.1

Node-RED nodes for Modbus TCP client communication with PLCs and industrial automation devices. Zero production dependencies.

npm install @aaqu/node-red-modbus-tcp

@aaqu/node-red-modbus-tcp

Node-RED nodes for Modbus TCP client communication.

Support

ko-fi

Disclaimer

THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. The author makes no guarantees regarding the reliability, accuracy, or suitability of this software for any particular purpose. Use at your own risk. The author shall not be liable for any damages arising from the use of this software in production environments, industrial automation, or any other application.

Features

  • Modbus TCP Client - Connect to Modbus TCP servers (PLCs, RTUs, simulators)
  • Read Operations - FC01-FC04, FC24 (FIFO Queue)
  • Write Operations - FC05, FC06, FC15, FC16, FC22 (Mask Write)
  • Read/Write Combined - FC23 (atomic Read/Write Multiple Registers)
  • Diagnostics - FC17 (Report Server ID), FC43/14 (Read Device Identification)
  • File Records - FC20 (Read), FC21 (Write)
  • Response validation - byte-count check on read responses (rejects malformed frames)
  • Auto-reconnect - Automatic reconnection on connection loss
  • Heartbeat - Application-layer keep-alive for unstable links
  • Dynamic configuration - Override parameters via msg properties
  • External Data mode - Hide GUI fields and require parameters from msg only
  • Unit ID per node - Different Unit IDs for each operation
  • No external dependencies - Uses only native Node.js modules
  • Multi-language support - English, Polish, Chinese, Japanese

Installation

From npm

npm install @aaqu/node-red-modbus-tcp

From source

cd ~/.node-red
npm install /path/to/aaqu-modbus-tcp

After installation, restart Node-RED and refresh the browser.

Nodes

aaqu-modbus-client (Configuration Node)

Manages the TCP connection to a Modbus server. Shared by all operation nodes.

Property Type Default Description
Host string localhost IP address or hostname of Modbus server
Port number 502 TCP port number
Timeout number 5000 Request timeout in milliseconds
Auto Reconnect boolean true Automatically reconnect on connection loss
Reconnect Interval number 5000 Time between reconnection attempts (ms)
Log Connection Errors boolean true Log connection errors to console
TCP Keep-Alive boolean true Enable TCP keep-alive probes
Keep-Alive Delay number 10000 Initial delay before first keep-alive probe (ms)
Heartbeat boolean false Send periodic Modbus requests to keep connection active
Heartbeat Interval number 5000 Interval between heartbeat requests (ms)
Include Raw Response boolean false Include raw Modbus frame buffer in msg.raw

Connection Keep-Alive Options

The client provides multiple options to maintain stable connections:

  1. TCP Keep-Alive - System-level TCP probes. May not work with all devices.
  2. Heartbeat - Application-level Modbus requests. More reliable for devices that close idle connections.

Recommendation: If your device closes idle connections, enable Heartbeat. It sends periodic read requests (FC03) that are ignored but keep the connection active. Heartbeat is skipped when there are pending requests to avoid interference.

aaqu-modbus-read

Reads data from a Modbus server.

Properties

Property Type Default Description
Server config - Reference to aaqu-modbus-client node
External Data checkbox false When enabled, Unit ID/Address/Quantity are hidden and must come from msg
Unit ID number 1 Modbus unit identifier (1-255)
Function select FC03 Function code (FC01-FC04)
Address number 0 Starting address (0-65535)
Quantity number 1 Number of items to read

Supported Functions

Function Code Description Max Quantity
Read Coils FC01 Read coil status (bits) 2000
Read Discrete Inputs FC02 Read discrete input status (bits) 2000
Read Holding Registers FC03 Read holding registers (16-bit) 125
Read Input Registers FC04 Read input registers (16-bit) 125
Read FIFO Queue FC24 Read FIFO queue at a single address 31 (server-defined)

For FC24 (FIFO), the quantity field is ignored — the server returns whatever the queue depth is at that address. Output:

msg.payload = [val1, val2, ...];   // Array of 16-bit values from the FIFO
msg.fifoCount = 3;                 // Number of values returned

Input Message (optional overrides)

msg.unitId = 2;           // Override Unit ID
msg.functionCode = 3;     // Override function code
msg.address = 100;        // Override starting address
msg.quantity = 10;        // Override quantity

External Data Mode

When External Data checkbox is enabled, the GUI fields for Unit ID, Address, and Quantity are hidden. These values must be provided in the incoming message:

msg.unitId = 1;           // Required
msg.address = 100;        // Required
msg.quantity = 10;        // Required
msg.functionCode = 3;     // Optional (uses node config if not provided)

This mode is useful when parameters come from external sources (database, API, other nodes) and you don't want to configure them statically in the node.

Output Message

msg.payload = [100, 101, 102, ...];  // Array of read values
msg.modbus = {
    unitId: 1,
    functionCode: 3,
    address: 0,
    quantity: 10,
    byteCount: 20
};

aaqu-modbus-write

Writes a single value to a Modbus server.

Properties

Property Type Default Description
Server config - Reference to aaqu-modbus-client node
External Data checkbox false When enabled, Unit ID/Address are hidden and must come from msg
Unit ID number 1 Modbus unit identifier (1-255)
Function select FC06 Function code (FC05 or FC06)
Address number 0 Address to write (0-65535)

Supported Functions

Function Code Description Value Range
Write Single Coil FC05 Write single coil true/false
Write Single Register FC06 Write single register 0-65535
Mask Write Register FC22 Apply (current AND andMask) OR (orMask AND NOT andMask) to a register masks 0-65535

For FC22 (Mask Write), msg.payload is ignored. Required:

msg.andMask = 0xF2;
msg.orMask  = 0x25;
msg.address = 0x0010;     // (or from node config)
msg.unitId  = 1;

Input Message

msg.payload = 1234;       // Value to write (number for registers, boolean for coils)
msg.unitId = 2;           // Optional: Override Unit ID
msg.functionCode = 6;     // Optional: Override function code
msg.address = 100;        // Optional: Override address

External Data Mode

When External Data checkbox is enabled, the GUI fields for Unit ID and Address are hidden. These values must be provided in the incoming message:

msg.payload = 1234;       // Value to write
msg.unitId = 1;           // Required
msg.address = 100;        // Required
msg.functionCode = 6;     // Optional (uses node config if not provided)

Output Message

msg.payload = 1234;       // Original payload (unchanged)
msg.modbus = {
    unitId: 1,
    functionCode: 6,
    address: 100,
    value: 1234
};

aaqu-modbus-write-multiple

Writes multiple values to a Modbus server. This node operates in forced external data mode - Unit ID and Address must always be provided via the incoming message.

Properties

Property Type Default Description
Server config - Reference to aaqu-modbus-client node
Function select FC16 Function code (FC15 or FC16)

Note: Unit ID and Address are not configurable in the node. They must be provided in msg.unitId and msg.address.

Supported Functions

Function Code Description Max Quantity
Write Multiple Coils FC15 Write multiple coils 1968
Write Multiple Registers FC16 Write multiple registers 123

Input Message

msg.payload = [100, 200, 300];  // Array of values to write
msg.unitId = 1;                  // Required: Modbus Unit ID (1-255)
msg.address = 100;               // Required: Starting address (0-65535)
msg.functionCode = 16;           // Optional: Override function code

Output Message

msg.payload = [100, 200, 300];  // Original payload (unchanged)
msg.requestModbus = {
    unitId: 1,
    functionCode: 16,
    address: 100,
    quantity: 3
};

Why External Data Mode?

This node is designed for dynamic, data-driven scenarios where parameters come from external sources (database, API, other nodes). This makes it ideal for:

  • Multi-device communication with varying addresses
  • Dynamic write operations based on external configuration
  • Integration with SCADA systems and databases

aaqu-modbus-read-write

Atomic Read/Write Multiple Registers (FC23 / 0x17). The write is performed first, then the read — both in a single transaction.

Properties

Property Type Default Description
Server config - Reference to aaqu-modbus-client node
External Data checkbox false When enabled, read/write addresses come from msg
Unit ID number 1 Modbus unit identifier (1-255)
Read Address number 0 Starting read address (0-65535)
Read Quantity number 1 Number of registers to read (1-125)
Write Address number 0 Starting write address (0-65535)

Input Message

msg.payload = [100, 200, 300];  // Values to write (1-121 registers)
// External Data ON additionally requires:
msg.unitId = 1;
msg.readAddress = 0;
msg.readQuantity = 5;
msg.writeAddress = 100;

Output Message

msg.payload = [/* read register bytes */];
msg.requestModbus = {
    functionCode: 23,
    readAddress: 0, readQuantity: 5,
    writeAddress: 100, writeQuantity: 3,
    unitId: 1, byteCount: 10
};

aaqu-modbus-diagnostic

Diagnostic operations: Report Server ID (FC17) and Read Device Identification (FC43 / MEI 0x0E).

Properties

Property Type Default Description
Server config - Reference to aaqu-modbus-client node
Unit ID number 1 Modbus unit identifier (1-255)
Operation select reportServerId reportServerId or readDeviceIdentification
ID Code select 1 - Basic Only for Read Device ID: 1=Basic, 2=Regular, 3=Extended, 4=Specific
Object ID number 0 Only for Read Device ID. 0=VendorName, 1=ProductCode, 2=Revision, 3=VendorUrl, 4=ProductName, 5=ModelName, 6=UserApplicationName

Output Message

For reportServerId:

msg.payload = {
    serverId: 0x42,
    runIndicator: true,
    additionalData: <Buffer ...>
};

For readDeviceIdentification:

msg.payload = {
    conformityLevel: 0x01,
    moreFollows: false,
    nextObjectId: 0,
    objects: { 0: 'VendorName', 1: 'ProductCode', 2: 'v1.0' }
};

aaqu-modbus-file

Extended file record access: Read File Record (FC20) and Write File Record (FC21).

Properties

Property Type Default Description
Server config - Reference to aaqu-modbus-client node
Unit ID number 1 Modbus unit identifier (1-255)
Operation select read read or write

Input Message

For read:

msg.payload = [
    { fileNumber: 4, recordNumber: 1, recordLength: 2 },
    { fileNumber: 4, recordNumber: 5, recordLength: 1 }
];

For write:

msg.payload = [
    { fileNumber: 4, recordNumber: 7, recordData: [0x06AF, 0x04BE] }
];

Limits: file number 1-65535, record number 0-9999, up to 122 16-bit words per record. Whole PDU must fit in 253 bytes.

Output Message

For read, msg.payload is an array of { recordData: [uint16, ...] }. For write, msg.payload is an echo of the request descriptors.

Examples

Read 10 Holding Registers

[inject] -> [aaqu-modbus-read] -> [debug]

Configure aaqu-modbus-read:

  • Function: FC03 - Read Holding Registers
  • Address: 0
  • Quantity: 10
  • Unit ID: 1

Write Single Register

[inject (payload: 1234)] -> [aaqu-modbus-write] -> [debug]

Configure aaqu-modbus-write:

  • Function: FC06 - Write Single Register
  • Address: 0
  • Unit ID: 1

Write Multiple Registers

[inject] -> [function] -> [aaqu-modbus-write-multiple] -> [debug]

Inject node sends payload, Function node adds required properties:

msg.payload = [100, 200, 300];
msg.unitId = 1;
msg.address = 100;
return msg;

Configure aaqu-modbus-write-multiple:

  • Function: FC16 - Write Multiple Registers

Dynamic Configuration

Use a function node to set parameters dynamically:

msg.unitId = 2;
msg.address = flow.get('startAddress') || 0;
msg.quantity = 5;
return msg;

External Data Mode

When you need all parameters to come from external sources (database, API, etc.), enable External Data checkbox. This hides the GUI fields and requires values in the message:

[inject] -> [function] -> [aaqu-modbus-read (External Data: ON)] -> [debug]

Function node:

msg.unitId = msg.payload.deviceId;
msg.address = msg.payload.registerAddress;
msg.quantity = msg.payload.count;
return msg;

This is useful for:

  • Reading device configuration from database
  • Dynamic polling based on external schedules
  • Multi-device scanning with varying parameters

Error Handling

Errors are reported through Node-RED's standard error handling:

  1. Node status - Visual indicator (red ring with error message)
  2. Catch node - Use a catch node to handle errors programmatically
  3. Debug sidebar - Errors appear in the debug sidebar

Common Errors

Error Description Solution
Not connected No connection to server Check host/port, network connectivity
Request timeout Server didn't respond in time Increase timeout, check server
Illegal Data Address Invalid address Check address range
Illegal Data Value Invalid value Check value range
Illegal Function Function not supported Check server capabilities

Modbus Protocol Reference

Address Space

Type Address Range Description
Coils 0-65535 Read/Write single bits
Discrete Inputs 0-65535 Read-only single bits
Holding Registers 0-65535 Read/Write 16-bit values
Input Registers 0-65535 Read-only 16-bit values

Data Types

  • Coils/Discrete Inputs: Boolean (true/false)
  • Registers: 16-bit unsigned integer (0-65535)

For larger data types (32-bit, float, etc.), read multiple consecutive registers and combine them in a function node.

Unit ID

The Unit ID (also called Slave ID) identifies the target device when multiple devices share a connection (e.g., through a gateway). Valid range: 1-255.

Testing

Run the test suite:

npm test

Supported Languages

Language Locale
English en-US
Polish pl-PL
Chinese (Simplified) zh-CN
Japanese ja-JP

Requirements

  • Node.js >= 14.0.0
  • Node-RED >= 2.0.0
  • No external dependencies (uses native Node.js net module)

License

MIT

Author

Aaqu

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests: npm test
  5. Submit a pull request

Changelog

See CHANGELOG.md for the full version history.

Node Info

Version: 0.4.1
Updated 1 week, 2 days ago
License: MIT
Rating: not yet rated

Categories

Actions

Rate:

Downloads

54 in the last week

Nodes

  • aaqu-modbus-client
  • aaqu-modbus-read
  • aaqu-modbus-write
  • aaqu-modbus-write-multiple
  • aaqu-modbus-read-write
  • aaqu-modbus-diagnostic
  • aaqu-modbus-file

Keywords

  • aaqu
  • portal
  • aaqu-portal
  • node-red
  • modbus
  • modbus-tcp
  • industrial
  • automation
  • plc

Maintainers