@wz2b/node-red-modbus-dynamic-server 0.1.1
A Modbus TCP server for Node-RED that lets you write your own functions to handle requests.
node-red-modbus-dynamic-server
Advanced Modbus server nodes for Node-RED
This package provides a set of Node-RED nodes for building flexible, general-purpose Modbus servers.
Unlike the server functionality in node-red-contrib-modbus, these nodes allow incoming Modbus requests to be intercepted before a response is sent. This makes it possible to examine, modify, filter, forward, or fulfill requests dynamically in a flow.
That enables use cases such as Modbus proxies, gateways, protocol conversion, request filtering, and other advanced server-side behaviors that are difficult or impossible with a conventional static register map.
Included Nodes
This package contains the following nodes:
Runtime nodes
Core request/response
modbus-dynamic-server
Receives incoming Modbus requests from the server and emits them into a flow for dynamic handling.modbus-dynamic-server-response
Sends a dynamic response back to the waiting Modbus client request.
Routing and control
modbus-source-router
Routes incoming Modbus requests to different flow outputs based on the client's source IP address.
Rules are expressed as IPv4 CIDR blocks and evaluated top-to-bottom; the first matching rule wins.
If no rule matches, a configurable Modbus exception response is sent and the message is not emitted.modbus-fc-filter
Allows or blocks requests by Modbus function code (payload.fc).
Allowed requests continue unchanged; blocked requests are terminated with a configurable Modbus exception.modbus-server-exception
Convenience terminator node for custom reject paths.
Sends a Modbus exception response for the current pending request and emits no output.
Data handling
modbus-registers-read
Reads and decodes values from the shared register map and emits them as a normal flow message.modbus-registers-write
Writes values into a local register store.modbus-registers-respond
Responds to Modbus requests using values from the local register store.
Integration / proxy
- modbus-dynamic-proxy
Forwards requests dynamically to another Modbus target and returns the result.
Configuration nodes
modbus-dynamic-server-config
Configures and owns the Modbus TCP server instance.modbus-registers-config
Defines local register storage used by register-based nodes.modbus-proxy-target
Defines a downstream Modbus target used for proxying or forwarding requests.
How the pieces fit together
A typical dynamic flow looks like this:
- A Modbus client sends a request to the configured server.
modbus-dynamic-serveremits a friendly request object into the flow.- (Optional)
modbus-source-routerfilters or routes the request based on the client's IP address. - The flow decides what to do with the request:
- answer from local registers
- generate a value dynamically
- forward to another Modbus device
- reject or filter the request
modbus-dynamic-server-responsesends the final response back to the client.
This separation makes it possible to implement dynamic server-side logic entirely in Node-RED flows.
Message Contract
Messages emitted by modbus-dynamic-server include internal request context in msg._modbus.
This context is required by downstream nodes such as:
modbus-dynamic-server-responsemodbus-source-routermodbus-fc-filtermodbus-server-exceptionmodbus-dynamic-proxymodbus-registers-respond
These nodes use msg._modbus to send a response back to the original Modbus client request.
Flows must preserve this property. This is especially important when you use other nodes, including
function nodes or custom nodes, to inspect requests, apply custom logic, transform payloads,
or generate custom responses.
Preferred:
msg.payload = newValue;
return msg;
Also valid (safe alternative):
msg = { ...msg, payload: newValue }
return msg
Not allowed:
msg = { payload: newValue };
return msg;
If msg._modbus is missing, downstream response/termination nodes will be unable to complete the original Modbus request and will raise an error.
In general, modify the existing msg object rather than replacing it entirely.
Use Cases
Protocol Conversion
Requests can be intercepted, decoded, and translated into requests for another protocol. This is useful for protocol mediation and conversion involving systems such as OPC UA, BACnet, MQTT, Sparkplug, or custom APIs.
Modbus Gateway
These nodes can be used to build a Modbus server that answers some requests from a local register cache while forwarding other requests to external devices, including Modbus TCP or Modbus serial targets.
This makes it possible to build gateways, aggregators, and hybrid local/remote data services.
Security, Data Diode, and Request Filtering
These nodes can also be used to build a Modbus TCP gateway that inspects requests and applies filtering rules before allowing them to proceed.
For example, requests can be filtered based on client IP address, function code, unit ID, register address, or other request attributes. This makes it possible to implement read-only gateways, request whitelisting, and "data diode"-style patterns that prevent write operations or other side effects.
Getting Started
A minimal dynamic server setup usually includes:
- one modbus-dynamic-server-config node
- one modbus-dynamic-server node
- one or more flow nodes such as
function,switch, orchange - one modbus-dynamic-server-response node
More advanced flows may also use:
- modbus-source-router to split traffic by client IP before any processing logic
- modbus-fc-filter to allow only selected function codes (for example, read-only gateways)
- modbus-server-exception to terminate requests from custom
switch/functionlogic - modbus-registers-read to expose cached register values to other flows or dashboards
- modbus-registers-config with modbus-registers-write and modbus-registers-respond
- modbus-proxy-target with modbus-dynamic-proxy
Examples
This package includes example flows in the examples/ directory. After installation, they should be available from the Node-RED import dialog under the examples list for this module.