Skip to main content

Connect to CIP Devices over EtherNet/IP

The ETHERNETIP connector connects Coreflux to CIP-compatible devices using EtherNet/IP explicit messaging (TCP port 44818). Define an ETHERNETIP_CONFIG block, add TAGs with CIP addresses, and publish each data point to its own MQTT topic — with optional scaling, bit extraction, joined attribute reads, and bidirectional writes.
Like reading labeled drawers in a filing cabinet. Each CIP address (Class.Instance.Attribute.Index) points to a specific property on the device. The connector opens the drawer, reads the value, and places it on an MQTT topic — on a schedule or when you send a command.

When to use this

Use the EtherNet/IP connector when you need explicit messaging to CIP objects on Allen-Bradley PLCs, remote I/O modules, VFDs, or other ODVA-compatible devices. Addresses use the numeric CIP path format ClassID.InstanceID.AttributeID.AttributeIndex.
For symbolic tag names (for example Program:MainProgram.Temperature), use the dedicated Allen-Bradley connector instead. The EtherNet/IP connector reads and writes via CIP class/instance/attribute paths.

Key capabilities

  • Explicit messaging — direct read/write to CIP attributes over TCP (port 44818)
  • TAG-based polling — per-point MQTT topics with configurable intervals
  • Bit extraction — BIT_ADDRESS to read a single bit from an integer word
  • Joined attribute reads — combine bytes from two CIP attributes (legacy asset parity)
  • ARRAY and STRUCT decoding — packed assembly buffers published as JSON arrays or objects
  • Bidirectional writes — WRITABLE scalar tags with DESTINATION_TOPIC, and a result on <DESTINATION_TOPIC>/result
  • Engineering units — SCALING / OFFSET / DEADBAND per tag

Quick Start

Read an analog input point every 500 ms and publish to MQTT:

Connection Configuration

ETHERNETIP_CONFIG Parameters

Raise READ_WRITE_TIMEOUT for slow devices or gateways. When a reply doesn’t arrive in time, or the device closes the connection, the route goes to Reconnecting. See Connection status.
The config block may be declared as ADD ETHERNETIP_CONFIG or ADD EIP_CONFIG — both are equivalent.

Connection Example

Implicit I/O Mode (Forward Open)

Not implemented in release 2.2. The connector parser accepts IO_MODE "IMPLICIT" and related assembly/RPI settings for forward compatibility, but the broker does not establish Forward Open / cyclic UDP connections yet. Use explicit CIP assembly attributes (4.x.y.z paths) for I/O adapter devices until implicit mode ships.
Planned parameters (validated when present, not yet wired to the adapter):

CIP Addressing

EtherNet/IP uses CIP (Common Industrial Protocol) addressing. The adapter issues CIP Get_Attribute_Single / Set_Attribute_Single against numeric paths. Required format: ClassID.InstanceID.AttributeID.AttributeIndex — four numeric segments, dot-separated.

Common CIP Classes

EtherNet/IP Communication Types


Data Types

TIME, TOD, and DATE width and unit are device-specific. Omron NJ/NX controllers store these values as 8 bytes in nanoseconds, which this connector does not decode. The published values come back wrong or as 0.
DATETIME, DTL, and DATE_AND_TIME are rejected when the route is defined, with the message DATETIME is not supported on ETHERNETIP. The connector does not publish 0 for these types.

String sizing

For STRING tags, WITH LENGTH sets the maximum string size in bytes. STRING_SIZE is accepted only as a parser alias for STRING sizing.

Allen-Bradley Type Mapping

SINT is signed. BYTE (alias USINT) is unsigned.

TAG Configuration

Every polled data point is an ADD TAG inside an ADD MAPPING block. Tags without their own SOURCE_TOPIC inherit {mapping SOURCE_TOPIC}/{tagName} when the mapping sets a base topic.

Complete TAG Example

TAG Parameters

string
required
CIP path: ClassID.InstanceID.AttributeID.AttributeIndex
string
required
CIP data type (see table above).
integer
Bytes to read from the primary CIP attribute starting at AttributeIndex (the fourth segment of ADDRESS). Default: 1. For STRING tags, this is the maximum string size in bytes; STRING_SIZE is accepted only as a parser alias for that STRING sizing (not for join, STRUCT, or generic attribute-width uses). For numeric tags in join mode, LENGTH + JOIN_LENGTH must equal the byte width of DATA_TYPE (for example 1 + 1 = 2 for INT16).
integer
Extract a single bit (0-based) from the underlying integer word. Alias: BIT. Use with integer types (UINT16, INT32, etc.) or with BOOL when the device returns a packed word. For BOOL + BIT_ADDRESS, read width auto-widens: bits 0–7 read 1 byte, 8–15 read 2 bytes, 16–31 read 4 bytes, 32–63 read 8 bytes.
string
When "true", perform a second CIP Get_Attribute_Single against the join target and concatenate those bytes onto the primary read before parsing, scaling, or bit extraction. Default: false.
integer
CIP Class ID of the joined attribute. Required when ENABLE_JOIN_ATTRIBUTE is true (must be > 0).
integer
CIP Instance ID of the joined attribute. Required when join is enabled (must be >= 0; instance 0 is valid on some devices).
integer
CIP Attribute ID of the joined attribute. Required when join is enabled (must be > 0).
integer
Byte offset within the joined CIP response where the slice starts. Default: 0.
integer
Bytes to take from the joined attribute starting at JOIN_INDEX. Required when join is enabled (must be > 0). Not related to SCALING_FACTOR.
decimal
Multiply the parsed numeric value after byte parsing. Alias: SCALING_FACTOR. Default: 1.0. Unrelated to byte layout — does not replace JOIN_LENGTH.
decimal
Add after scaling. Default: 0.0.
decimal
Suppress MQTT publish when the change is below this threshold. Default: 0.0.
integer
Decimal places for FLOAT32 / FLOAT64 MQTT payloads. Default: 2.
string
MQTT topic where polled values are published.
string
VALUE_ONLY (default — publish just the value) or JSON (value, quality, and timestamp). Aliases: VALUE, SIMPLE for value-only; FULL, METADATA for JSON.
boolean
When true, subscribe to DESTINATION_TOPIC and write incoming MQTT values to the device.
string
MQTT topic to receive write commands. Required when WRITABLE is true. Each write publishes its outcome on <DESTINATION_TOPIC>/result.

Publish Modes

VALUE_ONLY (default) — publishes just the scaled scalar value:
JSON — publishes a metadata wrapper when explicitly set:

Writes

Publish a value to DESTINATION_TOPIC on a tag with WRITABLE true. The connector sends a CIP Set_Attribute_Single and publishes the outcome on <DESTINATION_TOPIC>/result. The connection stays up whether the device accepts the write or rejects it. When the device accepts the write, the result has "success": true. When the device rejects the write, the result has "success": false, an error string, and a numeric cip_status:
WORD, DWORD, and LWORD write payloads are parsed as hexadecimal (16#XXXX, 0xXXXX, or plain hex). A payload of 99 is written as 0x99 (153).

Using an Omron NJ/NX

Through this connector, variables are reached as Tag Data Link Assemblies, not by name. A write to an input or output Assembly can be answered OK and ignored by the controller (measured on an NX1P2). Writing a variable by name needs CIP services this connector does not implement.

ARRAY and STRUCT Tags

CIP assembly buffers often contain packed arrays or structured records. Use DATA_TYPE "ARRAY" or DATA_TYPE "STRUCT" to decode them into JSON on MQTT.

ARRAY

MQTT payload: JSON array, e.g. [10, 20, 30, 40, 50].

STRUCT

Field spec format: name:byte_offset:type:size (comma-separated). Field types accept the same aliases as scalar DATA_TYPE, including FLOAT32 and FLOAT64. An unknown field type publishes null for that field and the broker logs a warning. MQTT payload: JSON object, e.g. {"temp":25.5,"pressure":101.325,"status":1}.
ARRAY and STRUCT tags are read-focused in release 2.2. Writable scalar tags use normal CIP encoding; complex-type writes from JSON arrays/objects are not yet supported.

Joined Attribute Reads

Some legacy CIP devices split a logical value across two attributes (for example a status word plus an extension attribute). When ENABLE_JOIN_ATTRIBUTE is "true", the broker performs two Get_Attribute_Single reads per cycle, concatenates the byte buffers (primary first, joined second), then parses, scales, and applies BIT_ADDRESS. If the join read fails, a warning is logged and the primary buffer is parsed alone — the polling loop continues.
For numeric DATA_TYPE values in join mode, LENGTH + JOIN_LENGTH must equal the type byte width (2 for 16-bit, 4 for 32-bit, 8 for 64-bit). BOOL tags with BIT_ADDRESS are exempt (Kaeser-style alarm bit pattern).
SCALING / SCALING_FACTOR multiplies the parsed value — it does not replace JOIN_LENGTH. Using scaling to compensate for a missing join length produces silently wrong values.

Migrating from a Legacy EtherNet/IP Asset

If you are converting an EtherNet/IP Asset (Coreflux HUB Configure / Tags panel) into a Connector, map each asset field to the LoT parameter below.

Examples

Read identity object attributes on a slow interval:

CIP Object Reference


Best Practices

Match the interval to how fast the value changes: 100 ms for safety-critical data, 1 s for process variables, 10 s or more for slow-changing status.
Use DEADBAND on noisy analog values to reduce MQTT traffic. Set 0.0 on digital status tags so every change publishes.
Increase CONNECTION_TIMEOUT and READ_WRITE_TIMEOUT on congested or remote networks. Raise RETRY_ATTEMPTS when connections are intermittent.
Always set JOIN_LENGTH explicitly when ENABLE_JOIN_ATTRIBUTE is "true". Verify LENGTH + JOIN_LENGTH matches the numeric type width before deploying to production.
Use numeric CIP paths on this connector. For Rockwell tag-name access (Program:MainProgram.Counter), use the Allen-Bradley connector.

Troubleshooting

  • Verify IP with ping
  • Confirm port 44818 (TCP) is open through firewalls
  • Ensure the device is powered and allows external connections
  • Increase CONNECTION_TIMEOUT and RETRY_ATTEMPTS
  • Confirm four-segment format: ClassID.InstanceID.AttributeID.AttributeIndex
  • Check the device manual for valid class/instance/attribute numbers
  • Instance numbering varies by device (often starts at 1, not 0)
  • Verify DATA_TYPE matches the device attribute
  • Check DEADBAND is not suppressing small changes
  • For join tags, confirm JOIN_LENGTH and LENGTH byte layout
  • For bit tags, confirm BIT_ADDRESS is within the read width
  • WORD, DWORD, and LWORD publish IEC hex text (for example 16#ABCD)
  • INT64 and UINT64 above 2^53 publish every digit when no scaling, offset, minimum, or maximum is set
  • On an Omron NJ/NX, TIME, TOD, and DATE are 8-byte nanosecond values this connector does not decode, so they come back wrong or as 0
  • DATETIME, DTL, and DATE_AND_TIME are rejected with the message DATETIME is not supported on ETHERNETIP
  • Read <DESTINATION_TOPIC>/result. "success": false means the device rejected the CIP write. The connection stays up. cip_status 19 (0x13) is not enough data, 0x15 is too much data, and 0x0E means the attribute is not settable
  • WORD, DWORD, and LWORD payloads are hexadecimal. 99 is written as 0x99 (153)
  • On an Omron NJ/NX, a write to an input or output Assembly can be answered OK and ignored by the controller
  • JOIN_CLASS_ID and JOIN_ATTRIBUTE_ID must be > 0
  • JOIN_INSTANCE_ID must be present and >= 0
  • JOIN_LENGTH must be > 0
  • For numeric types, LENGTH + JOIN_LENGTH must equal the type byte width (unless BOOL + BIT_ADDRESS)

Next Steps

Allen-Bradley Connector

Symbolic tag-name access for ControlLogix, CompactLogix, and MicroLogix PLCs.

Industrial Connectors Overview

Compare OT connectors and choose the right protocol for your devices.
Last modified on October 22, 2026