Skip to main content
Version: 3.0 (next)

EtherNet/IP Nodes

EtherNet/IP is the industrial Ethernet protocol used by Allen-Bradley PLCs (ControlLogix, CompactLogix, Micro820). MaestroHub provides two node types for EtherNet/IP integration: the standard EtherNet/IP Node for executing individual functions, and the EtherNet/IP Read Group Node for batch read operations.

EtherNet/IP Node​

The EtherNet/IP node executes a single function from your EtherNet/IP connection. The function you select determines whether the node performs a read, write, browse, or batch operation.

Configuration​

EtherNet/IP node configuration

EtherNet/IP and Read Group Nodes

The node configuration has two tabs: Parameters and Settings.

Parameters Tab

FieldDescription
ConnectionSelect the EtherNet/IP connection profile to use
FunctionChoose a saved function from the connection (read, write, browse, or batch operation)
Function ParametersFill in any parameters defined in the function. Accepts literal values or Maestro expressions (e.g., $input, $.payload.id)
Timeout Override (seconds)Optional. Override the default function timeout for this node

Settings Tab

FieldDescription
DescriptionOptional description displayed on the node
Timeout (seconds)Maximum time the node may run before timing out. Empty uses the pipeline default
Retry on TimeoutPipeline Default, Enabled or Disabled: whether the node is retried when it times out
Retry on FailPipeline Default, Enabled or Disabled: whether the node is retried when it fails. When Enabled, Advanced Retry Configuration sets the maximum attempts and the delay between them
On ErrorPipeline Default (the pipeline's Error Handling setting), Stop Pipeline or Continue Execution

Quality on reads​

Every read result carries the canonical quality band. A single-tag read is good when the controller answered (CIP reports a failed read as an error, never as a value with a status). A multi-tag read carries quality per tag — good when answered, bad with an error when the tag was missing from the response — and a top-level quality, worst-of across the tags, for a UNS Publish node's Quality parameter.

Supported Function Types​

Function TypePurposeCommon Use Cases
Read TagRead a single tag value (scalar or array)Temperature readings, motor status, setpoint verification
Write TagWrite a single value to a tagUpdate setpoint, change mode, trigger action
Read Multiple TagsBatch read multiple tags in one operationDashboard updates, process snapshots, historian logging
Write Multiple TagsBatch write to multiple tagsRecipe download, coordinated updates, batch configuration
Browse TagsList all available tags with optional filteringTag discovery, documentation, setup validation

Output​

Every function of this node delivers its data under result, and execution facts (success, functionId, durationMs, timestamp) under _metadata. The shape depends on the function:

Read Tag (ethernetip.read):

{
"result": { "tagName": "Temperature", "dataType": "real", "value": 75.5, "quality": "good" },
"_metadata": { "success": true, "functionId": "<function-id>", "durationMs": 12, "timestamp": "2026-09-07T10:30:00Z" }
}
ExpressionDescription
$node["Name"].result.valueThe decoded value
$node["Name"].result.tagName, $node["Name"].result.dataTypeThe tag and its CIP type — with data type auto, the type the controller gave (udt for a structure)
$node["Name"].result.qualitygood — a refused read fails the node instead
$node["Name"].result.length, $node["Name"].result.isArrayPresent for an array tag: the element count and true
$node["Name"].result.udtNamePresent when the function reads a whole UDT (data type udt): the structure's name. result.value is then an object keyed by member name — $node["Name"].result.value.Speed — or a list of them for an array

Write Tag (ethernetip.write): result.tagName, result.dataType, result.value (the typed value written), and result.length + result.isArray for an array tag.

Read Multiple Tags (ethernetip.read_tags):

{
"result": {
"tags": [
{ "tagName": "Temperature", "dataType": "real", "success": true, "value": 75.5, "quality": "good" },
{ "tagName": "Missing", "dataType": "dint", "success": false, "error": "tag not found in response", "quality": "bad" }
],
"count": 2,
"quality": "bad"
},
"_metadata": { "success": true, "functionId": "<function-id>", "durationMs": 18, "timestamp": "2026-09-07T10:30:00Z" }
}

result.tags carries one object per tag, with udtName too when the tag was read as a whole UDT (data type udt, or auto that found a structure); result.count how many; result.quality is the worst-of — bad when any tag was missing.

Write Multiple Tags (ethernetip.write_tags): result.tags (one object per tag — tagName, dataType, success, and error when refused), result.count, result.successCount, result.failureCount.

Browse Tags (ethernetip.browse):

{
"result": {
"tags": [
{ "name": "Temperature", "address": "Temperature", "dataType": "REAL", "dimensions": [], "isArray": false, "isStruct": false },
{ "name": "Motor1", "address": "Motor1", "dataType": "UDT", "udtName": "MotorUDT", "dimensions": [], "isArray": false, "isStruct": true },
{ "name": "program:Main.LocalVar", "address": "Program:Main.LocalVar", "dataType": "INT", "dimensions": [], "isArray": false, "isStruct": false, "program": "Main" }
],
"tagCount": 3,
"types": {
"MotorUDT": [
{ "name": "Running", "dataType": "BOOL", "dimensions": [], "isArray": false, "isStruct": false },
{ "name": "Speed", "dataType": "REAL", "dimensions": [], "isArray": false, "isStruct": false },
{ "name": "Label", "dataType": "STRING", "dimensions": [], "isArray": false, "isStruct": true }
]
}
},
"_metadata": { "success": true, "functionId": "<function-id>", "durationMs": 240, "timestamp": "2026-09-07T10:30:00Z" }
}

result.tags carries one object per tag — name, address (the tag name a read takes), dataType (STRING for a string tag, UDT for a structure), dimensions, isArray, isStruct, program for a program-scoped tag, and udtName for a UDT; result.tagCount how many. result.types lists the members of every UDT those tags hold — nested UDTs included — by the structure's name: each member's name, dataType, dimensions, isArray, isStruct, and udtName when the member is a UDT itself. A member is read by its tag's address and its name: Motor1.Speed.

Safety First

Always implement validation and safety checks before writing to industrial equipment. Consider adding condition nodes to verify values are within safe ranges.

EtherNet/IP Read Group Node​

The EtherNet/IP Read Group node runs several read functions from one EtherNet/IP connection in a single node and returns their results together.

When to Use Read Group vs. Standard Node​

ApproachUse Case
EtherNet/IP NodeExecute a single function (read, write, browse, or batch operation)
Read Group NodeExecute several read functions from one connection in a single node

Configuration​

ParameterDescriptionOptions
ConnectionThe EtherNet/IP connection whose functions are read. Every function in the group comes from this connection—
Function SelectionWhich functions the node readsSelect Functions (default): the functions you list. All Functions: every Read Tag and Read Multiple Tags function on the connection. By Labels: every function whose labels match the labels you pick
FunctionsWith Select Functions: the read functions to run, each with an optional Alias that becomes its output keyRead Tag (ethernetip.read), Read Multiple Tags (ethernetip.read_tags)
Execution ModeHow the functions are runparallel (default), sequential
Continue on ErrorWhether the other functions still run when one failsOn (default), Off
Output ModeWhether every read is emitted, or only reads whose value changed since the last runAlways (default), On Change
Allow Zero MatchesWith All Functions or By Labels: succeed with an empty result when no function matches, instead of failing the nodeOff (default), On

Output Structure​

The node output is the canonical {result, _metadata} envelope: result holds one entry per function read, keyed by the function's output key; _metadata holds the group's accounting.

{
"result": {
"Motor Speed": {
"value": 1450.0,
"success": true,
"error": "",
"duration": 12,
"timestamp": "2026-09-07T08:30:00Z"
},
"Line Tags": {
"value": { "tags": [{ "tagName": "Temperature", "dataType": "REAL", "value": 75.5, "quality": "good" }], "count": 1, "success": true, "quality": "good" },
"success": true,
"error": "",
"duration": 31,
"timestamp": "2026-09-07T08:30:00Z"
}
},
"_metadata": {
"connectionId": "conn-123",
"connectionName": "CompactLogix L33",
"total": 2,
"successful": 2,
"failed": 0,
"totalDuration": 83,
"executionMode": "parallel",
"originalRequests": 2
}
}

Each entry under result is one function's read — keyed by the function's alias, else its name, else its id (see Output Key Resolution):

FieldTypeDescription
result.<alias>.valueanyWhat the function read — its own result.value when it has one (the decoded tag value for ethernetip.read, since its result carries value; the whole {tags, count, success, quality} object for ethernetip.read_tags), otherwise its whole result. null when the read failed
result.<alias>.successbooleantrue when this function's read succeeded
result.<alias>.errorstringWhy the read failed; empty when it succeeded — always present
result.<alias>.durationnumberHow long this function's read took, in milliseconds
result.<alias>.timestampstringWhen the read was issued, RFC 3339 UTC

The _metadata object is the group's execution summary:

FieldTypeDescription
_metadata.connectionIdstringThe connection every function was read on
_metadata.connectionNamestringThat connection's display name
_metadata.totalnumberHow many functions the group ran
_metadata.successfulnumberHow many read successfully — including the ones onChange then suppressed
_metadata.failednumberHow many failed; successful + failed = total
_metadata.totalDurationnumberWall-clock time of the whole group, in milliseconds
_metadata.executionModestringparallel or sequential
_metadata.originalRequestsnumberHow many functions were selected to run
_metadata.keyCollisionsstring[]Output keys that two or more functions resolved to — the later read overwrote the earlier under that key. Present only when it happened
_metadata.configWarningsstring[]Non-fatal problems in the node's config, each saying what was ignored. Present only when there were any
_metadata.outputModestringonChange — present only in that mode
_metadata.suppressedCountnumberonChange mode: how many successful reads were unchanged since the last run and left out of result
_metadata.emittedCountnumberonChange mode: how many entries result carries — total − suppressedCount
_metadata.suppressedKeysstring[]onChange mode: the output keys left out as unchanged. Present only when at least one was
_metadata.reasonstringonChange mode, when every successful read was unchanged: why result is empty — the node buffers instead of waking downstream

Execution Modes​

Parallel Execution (Default)

  • All functions execute concurrently
  • Faster total execution time
  • Best for independent read operations
  • Use when accessing different tags

Sequential Execution

  • Functions execute one after another
  • More predictable timing
  • Better for PLCs with limited concurrent request handling
  • Use when PLC performance is a concern

Output Key Resolution​

Each function's result is keyed in the output using the first available value:

  1. Alias: the alias set on the function entry
  2. Function Name: the name of the function on the connection
  3. Function ID: the function's ID

Use aliases to give results predictable keys.

Error Handling​

Continue on Error = On (Default)

  • A failed read is recorded in the output with its error, and the other functions still run
  • Successful function results are still available in the output
  • Best for monitoring scenarios where partial data is valuable

Continue on Error = Off

  • The node fails as soon as any function fails
  • Best for critical operations where partial data is not acceptable

Best Practices​

  • Use All Functions for commissioning, diagnostics and snapshots of every read function on a connection.
  • Use Select Functions in production pipelines with known data requirements.
  • Use By Labels when the set of functions grows over time: new functions that carry the label are read without editing the node.
  • Assign aliases to keep output keys readable.
  • Use sequential mode when the PLC handles concurrent requests poorly.

Supported Data Types​

EtherNet/IP nodes support all standard CIP data types:

Data TypeDescriptionExample Values
boolBooleantrue, false
sintSigned 8-bit integer-128 to 127
intSigned 16-bit integer-32768 to 32767
dintSigned 32-bit integer-2147483648 to 2147483647
lintSigned 64-bit integerFull 64-bit range
usintUnsigned 8-bit integer0 to 255
uintUnsigned 16-bit integer0 to 65535
udintUnsigned 32-bit integer0 to 4294967295
ulintUnsigned 64-bit integerFull 64-bit range
real32-bit float75.5, -3.14159
lreal64-bit floatHigh-precision decimals
stringCharacter string"Hello World"

Tag Naming Reference​

Tag TypeFormatExample
Controller-scopedTagNameTemperature, Motor1_Speed
Program-scopedProgram:ProgramName.TagNameProgram:Main.LocalVar
Array elementTagName[index]DataArray[0], Temps[5]
Structure memberTagName.MemberMotor.Speed, Pump_Data.Pressure