Modbus Client
uniflow.plugin.modbusclient
•
Category: Industrial & Communication Protocols
•
Version: v1.7.0
•
Min Uniflow Version: Uniflow ≥ v1.4.0
Modbus Client Plugin Reference Manual
1. Overview
Plugin Name: Modbus Client
Type: Industrial Protocols
Identifier: uniflow.plugin.modbusclient
Description
Integration with Modbus TCP Servers (acts as Modbus Master).
Modbus Client is the modern Modbus TCP/IP term for a Modbus Master (traditional Modbus RTU/ASCII serial term).
As a Modbus Client (Master), this plugin actively initiates communication, polling data from remote Modbus Servers (Slaves) and issuing register/coil write commands.
License Tier Restrictions
The Modbus Client plugin is available on all license tiers with the following capability differences:
| Capability | Free / Trial | Pro / Enterprise |
|---|---|---|
| Maximum Data Points (coils + registers total) | 5 | Unlimited |
| Bool Data Type | ✅ | ✅ |
| Int16 Data Type | ✅ | ✅ |
| UInt16 Data Type | ✅ | ✅ |
| Int32 Data Type | ✅ | ✅ |
| Int64 Data Type | ✅ | ✅ |
| Double Data Type | ✅ | ✅ |
| String Data Type (120 registers / 240 bytes) | ❌ | ✅ |
On the Free and Trial tiers, the plugin restricts the total number of configurable data points to 5 and disables the String register data type. If you attempt to add a data point that exceeds these constraints, Uniflow will display a dialog alert explaining the license restriction. Upgrading to a Pro or Enterprise license removes all limitations.
2. Technical Architecture
The Modbus Client plugin implements the industrial Modbus master protocol over Modbus TCP/IP socket connections or Modbus RTU (serial RS-485). It handles cyclical polling schedules for Coils (0x), Discrete Inputs (1x), Holding Registers (4x), and Input Registers (3x), manages configurable Unit IDs, supports 16-bit/32-bit register packing and byte-swapping order (Big-Endian, Little-Endian, Mid-Big, Mid-Little), and executes single or multiple register write function codes (FC05, FC06, FC15, FC16).
System Interaction
The Modbus Client plugin acts as a Modbus TCP & RTU Master. It polls Discrete Inputs, Coils, Input Registers, and Holding Registers using Function Codes 01-04, supporting 16-bit, 32-bit float, and byte-swapped endianness encodings.
Change-of-Value (COV / Report by Exception) Dispatching
Starting with v1.7.0, the Modbus Client plugin adopts Change-of-Value (COV) catalog dispatching to completely decouple high-rate hardware polling from rule engine evaluations:
FullSnapshot = true): Upon initial connection or automatic reconnection, the adapter reads all configured data points and publishes a full baseline snapshot to initialize the host catalog, UI, and Rule Engine caches.FullSnapshot = false): On subsequent poll cycles, the adapter reads the hardware registers and compares each value and quality state against its last published state. Only data points that have actually changed are packaged into an incremental delta snapshot and broadcast to subscribers. If no values changed during a poll cycle, no snapshot is published.MergeValueIntoCache), ensuring direct read queries, manual catalog browsing, and dashboard views always reflect current hardware values.Enable Heartbeat Refresh). When enabled, if no value changes have occurred for the duration of the configured Heartbeat Interval (ms) (default: 1000 ms), the adapter re-broadcasts a full baseline snapshot.Register Memory Mapping & Data Types
In standard Modbus protocol, memory is structured into 16-bit register words (2 bytes per register) and 1-bit discrete values. Uniflow automatically manages multi-register data packing, allocation boundaries, and UTF-8 string memory resetting:
Memory Allocation Table by Data Type
| Data Type | Memory Area | Registers / Bits Consumed | Address Range Example | Description |
|---|---|---|---|---|
Bool Coils (0x) / Discrete Inputs (1x) | ||||
| ↳ | 1 Bit | Address 0 | Single 1-bit discrete memory location. | |
Bool Holding (4x) / Input Registers (3x) | ||||
| ↳ | 1 Register (16-bit) | Address 0 | 16-bit register word (0 = False, != 0 = True). | |
Int16 Holding (4x) / Input Registers (3x) | ||||
| ↳ | 1 Register (16-bit) | Address 0 | 16-bit signed integer (-32,768 to 32,767) occupying 1 single register. | |
UInt16 Holding (4x) / Input Registers (3x) | ||||
| ↳ | 1 Register (16-bit) | Address 0 | 16-bit unsigned integer (0 to 65,535) occupying 1 single register. | |
Int32 Holding (4x) / Input Registers (3x) | ||||
| ↳ | 2 Registers (32-bit) | Address 0 .. 1 | 32-bit signed integer combining 2 consecutive 16-bit registers (High Word, Low Word). | |
Int64 Holding (4x) / Input Registers (3x) | ||||
| ↳ | 4 Registers (64-bit) | Address 0 .. 3 | 64-bit signed integer combining 4 consecutive 16-bit registers. | |
Double Holding (4x) / Input Registers (3x) | ||||
| ↳ | 4 Registers (64-bit) | Address 0 .. 3 | 64-bit IEEE 754 floating-point value combining 4 consecutive 16-bit registers. | |
String Holding (4x) / Input Registers (3x) | ||||
| ↳ | 120 Registers (240 Bytes) | Address 0 .. 119 | UTF-8 encoded text string allocated across 120 consecutive registers (2 bytes per register). | |
Uniflow enforces a built-in ModbusRegisterSanitizer during point configuration.
- Overlap Prevention: If a point is assigned
HoldingRegister 0withInt32(spanningAddress 0..1), no other data point can be assigned toAddress 0orAddress 1. - Allocation Boundary Limit: The maximum Modbus address is
65535. Defining a multi-register point (e.g.,Int64consuming 4 registers) starting atAddress 65534is automatically blocked because it would exceed the 65535 allocation table boundary.
Special Treatment for String Data Type (UTF-8 Capacity & Zero-Padding Reset)
When a Holding Register is configured as a String, Uniflow allocates a multi-register byte capacity (default 120 registers = 240 bytes, compliant with the standard Modbus TCP PDU receive buffer limit). Because UTF-8 character length can vary (1 to 4 bytes per character):
1. Automatic Zero-Padding Reset on Write: When writing a string shorter than the allocated capacity (e.g. writing "OK" = 2 bytes into a 240-byte / 120-register allocation), Uniflow automatically resets all remaining unused byte positions to null bytes (0x00).
2. Stale Data Prevention: Without zero-padding, writing a shorter string over a previously written longer string (e.g. writing "OK" over "TEMPERATURE_HIGH") would leave trailing garbage characters. Zero-padding ensures the entire memory block is clean and subsequent reads accurately return "OK".
Architecture Diagram
3. Configuration Parameters
The following configuration fields are available in the User Interface for this plugin:
| Configuration Setting | Description |
|---|---|
| IP Address / Host | Specifies the ip address / host. |
| Port | Numeric value specifying the port. |
| Unit ID | Specifies the unit id. |
| Poll Interval (ms) | Numeric value specifying the poll interval (ms). |
| Connect Timeout (ms) | Numeric value specifying the connect timeout (ms). |
| Reconnect Delay (ms) | Specifies the reconnect delay (ms). |
| Health Check (ms) | Specifies the health check (ms). |
| Enable Heartbeat Refresh | Checkbox indicating whether to periodically dispatch a full baseline snapshot during periods of inactivity (default: disabled). |
| Heartbeat Interval (ms) | Inactivity timeout in milliseconds after which a full baseline snapshot is dispatched when Heartbeat Refresh is enabled (default: 1000 ms). |
4. Exposed Routes & Data Types
This plugin exposes catalog fields across the following rule graph nodes:
Input Source
The Input Source node continuously streams polled register and coil telemetry values into the Uniflow Rule Engine.
| Human-Readable Field Name | Data Type | Description |
|---|---|---|
| Configured Modbus Register / Coil Int16` / `UInt16` / `Int32` / `Int64` / `Double` / `Bool` / `String | ||
| ↳ | Polled value from remote Modbus slave (Holding Register, Input Register, Coil, Discrete Input). | |
Auto-Generated Unit Point ({PointName}_Unit) String | ||
| ↳ | Read-only engineering unit metadata string (e.g., "°C", "kW", "bar"). | |
Event Input
The Event Input node subscribes to real-time polling triggers and connection status lifecycle events emitted by the Modbus Client master engine.
| Human-Readable Event Name | Event Type Identifier | Event Category | Data Type | Exposed Schema Ports & Data Types | Description |
|---|---|---|---|---|---|
| Register Polled modbus.register_polled | |||||
| ↳ | Telemetry | Event Object | PointId (String)Value (Variant)Address (Int32)Timestamp (DateTime) | Emitted on every successful Modbus register poll cycle. | |
| Coil State Changed modbus.coil_state_changed | |||||
| ↳ | Discrete I/O | Event Object | PointId (String)State (Bool)Address (Int32)Timestamp (DateTime) | Emitted when a monitored coil state changes. | |
| Poll Error modbus.poll_error | |||||
| ↳ | Connection | Event Object | Error (String)Host (String)Port (Int32)Timestamp (DateTime) | Connection or protocol timeout event during polling. | |
Data Source
The Data Source node provides secondary query access to all configured Modbus data points and their auto-generated engineering unit metadata points ({PointName}_Unit).
| Human-Readable Field Name / Item | Data Type | Description |
|---|---|---|
| Configured Data Points Int16` / `UInt16` / `Int32` / `Int64` / `Double` / `Bool` / `String | ||
| ↳ | Accessible snapshot values of any defined Modbus register or coil. | |
Auto-Generated Unit Point ({PointName}_Unit) String | ||
| ↳ | Supplementary engineering unit metadata string (e.g., "°C", "bar", "kW"). | |
Output Target
The Output Target node acts as an action sink node to write values to remote Modbus registers and coils.
| Target Name | Data Type | Associated Parameters | Parameter Data Type | Required | Description |
|---|---|---|---|---|---|
| Configured Writable Register / Coil Int16` / `UInt16` / `Int32` / `Int64` / `Double` / `Bool` / `String | |||||
| ↳ | Value | Int16 / UInt16 / Int32 / Int64 / Double / Bool / String | True | Value payload to write to target Modbus register or coil. | |
| Direct Access String | |||||
| ↳ | Type (Type) | String | True | Target memory area (Coils, Discrete Input, Holding Register, Input registers). | |
| ↳ | Address (Address) | Int32 | True | Register/coil 0-based offset address. | |
| ↳ | Value (Value) | String | True | Payload string or numeric value to write. | |
4.1 Auto-Generated Engineering Unit Points ({PointName}_Unit)
For every defined Modbus data point (e.g. HoldingRegister_104) that specifies a non-empty engineering unit (e.g., °C, bar, kW), Uniflow automatically generates and exposes a secondary string data point suffixed with _Unit (e.g., HoldingRegister_104_Unit).
Conditional Generation: The secondary {PointName}_Unit data point is generated only when the Unit field is populated in the point configuration editor. If the Unit field is left empty or blank, Uniflow intentionally omits the _Unit entry to keep the catalog clean and avoid clutter in the Rule Engine point picker.
Unit is set.5. Usage Examples
Scenario A: Modbus Boiler Temperature High Polling Triggers Cooling Relay & Email Alert
Workflow Overview:
The Modbus Client polls Holding Register 104 (Boiler Temperature Sensor, HoldingRegister_104 > 85.0°C). When the temperature exceeds 85.0°C, Uniflow evaluates the condition and executes two simultaneous actions:
1. Writes a True value to Modbus Coil 12 (modbus.write_single_coil) to activate an emergency cooling fan relay.
2. Dispatches an alert email to the plant operations team.
Rule Node Configuration:
1. Input Source Node: Modbus Client Poller
Holding Register104 (Double / Float32)2. Logic Filter Node: GreaterThan
HoldingRegister_104 > 85.03. Output Target Node A: Modbus Client Writer
Direct Access / Write Single CoilType: CoilsAddress: 12Value: True4. Output Target Node B: Email Client Action
Send EmailSubject: BOILER OVERTEMPERATURE WARNING - Reg 104 > 85CLogic Flow Diagram:
Scenario B: Remote MQTT Emergency Stop Command Writes Modbus Coil
Workflow Overview:
When a remote control center publishes an emergency stop topic via MQTT (command/estop with payload == "STOP"), Uniflow intercepts the MQTT message and immediately executes a Modbus Write command (Direct Access) writing Coil 0 to False to shut down the main conveyor drive motor.
Rule Node Configuration:
1. Event Input Node: MQTT Subscriber
command/estopPayload (String)2. Logic Condition Node: Equal
Payload == "STOP"3. Output Target Node: Modbus Client Writer
Direct AccessType: CoilsAddress: 0Value: False