> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# EtherNet/IP Route

> Connect to Allen-Bradley PLCs and CIP-compatible devices using EtherNet/IP explicit messaging

## EtherNet/IP Overview

The `ETHERNETIP` route enables communication with CIP (Common Industrial Protocol) compatible devices using EtherNet/IP explicit messaging. It provides access to device attributes using CIP addressing (Class, Instance, Attribute) and supports Allen-Bradley PLCs and other EtherNet/IP devices.

<Tip>
  EtherNet/IP uses CIP addressing which provides structured access to device data. Use this route when you need explicit messaging to specific CIP objects.
</Tip>

## Basic Syntax

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE EIPDevice WITH TYPE ETHERNETIP
    ADD ETHERNETIP_CONFIG
        WITH IP "192.168.1.100"
        WITH PORT 44818
        WITH POLLING_MS 750
    ADD MAPPING DeviceData
        WITH EVERY 1 SECOND
        ADD TAG Temperature
            WITH ADDRESS "1.1.100.0"
            WITH DATA_TYPE "FLOAT32"
            WITH SOURCE_TOPIC "eip/temperature"
```

***

## Connection Configuration

### ETHERNETIP\_CONFIG Parameters

<ParamField path="IP" type="string" required>
  EtherNet/IP device IP address.
</ParamField>

<ParamField path="PORT" type="integer">
  EtherNet/IP port. Default: 44818.
</ParamField>

<ParamField path="POLLING_MS" type="integer">
  Polling interval in milliseconds. Default: 750.
</ParamField>

<ParamField path="CONNECTION_TIMEOUT" type="integer">
  Connection timeout in milliseconds. Default: 5000.
</ParamField>

<ParamField path="READ_WRITE_TIMEOUT" type="integer">
  Read/Write timeout in milliseconds. Default: 3000.
</ParamField>

<ParamField path="RETRY_ATTEMPTS" type="integer">
  Number of retry attempts. Default: 3.
</ParamField>

<ParamField path="RETRY_TIME_SECONDS" type="integer">
  Retry delay in seconds. Default: 5.
</ParamField>

### Connection Example

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
ADD ETHERNETIP_CONFIG
    WITH IP "192.168.1.100"
    WITH PORT 44818
    WITH POLLING_MS 500
    WITH CONNECTION_TIMEOUT 5000
    WITH READ_WRITE_TIMEOUT 3000
    WITH RETRY_ATTEMPTS 3
    WITH RETRY_TIME_SECONDS 5
```

***

## CIP Addressing

EtherNet/IP uses CIP addressing in the format: `ClassID.InstanceID.AttributeID.AttributeIndex`

| Component | Description | Example |
| - | - | - |
| ClassID | CIP object class | 1 (Identity), 4 (Assembly), etc. |
| InstanceID | Object instance | 1, 2, 3... |
| AttributeID | Attribute number | Varies by class |
| AttributeIndex | Index for arrays | 0 for first element |

### Common CIP Classes

| Class ID | Name | Description |
| - | - | - |
| 1 | Identity | Device identification |
| 2 | Message Router | Message routing |
| 4 | Assembly | I/O assemblies |
| 6 | Connection Manager | Connection handling |
| 102 | Analog Input Point | Analog inputs |
| 103 | Analog Output Point | Analog outputs |
| 104 | Discrete Input Point | Digital inputs |
| 105 | Discrete Output Point | Digital outputs |

***

## Data Types

<ParamField path="DATA_TYPE" type="string" required>
  CIP data type for the attribute:
</ParamField>

| Data Type | Description | Size |
| - | - | - |
| `BOOLEAN` / `BOOL` | Boolean value | 1 bit |
| `BYTE` | Unsigned 8-bit | 8 bits |
| `USINT` | Unsigned 8-bit integer | 8 bits |
| `SINT` | Signed 8-bit integer | 8 bits |
| `INT16` / `INT` | Signed 16-bit integer | 16 bits |
| `UINT16` / `UINT` / `WORD` | Unsigned 16-bit integer | 16 bits |
| `INT32` / `DINT` | Signed 32-bit integer | 32 bits |
| `UINT32` / `UDINT` / `DWORD` | Unsigned 32-bit integer | 32 bits |
| `INT64` / `LINT` | Signed 64-bit integer | 64 bits |
| `UINT64` / `ULINT` / `LWORD` | Unsigned 64-bit integer | 64 bits |
| `FLOAT32` / `REAL` / `FLOAT` | 32-bit floating point | 32 bits |
| `FLOAT64` / `LREAL` / `DOUBLE` | 64-bit floating point | 64 bits |
| `CHAR` | Single character | 8 bits |
| `WCHAR` | Wide character | 16 bits |
| `TIME` | Time duration | 32 bits |
| `DATE` | Date value | 16 bits |
| `TOD` | Time of day | 32 bits |
| `ASCII` | ASCII string | 8 bits |
| `STRING` | String value (configurable `LENGTH`) | Variable |

***

## TAG Configuration

### Complete TAG Example

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
ADD TAG ProcessTemperature
    WITH ADDRESS "102.1.3.0"
    WITH DATA_TYPE "FLOAT32"
    WITH SOURCE_TOPIC "eip/process/temperature"
    WITH SCALING_FACTOR 0.1
    WITH OFFSET 0
    WITH DEADBAND 0.5
    WITH PUBLISH_MODE "JSON"
    WITH LENGTH 1
```

### TAG Parameters

<AccordionGroup>
  <Accordion title="Address Configuration">
    <ParamField path="ADDRESS" type="string" required>
      CIP address in format: ClassID.InstanceID.AttributeID.AttributeIndex
    </ParamField>

    <ParamField path="DATA_TYPE" type="string" required>
      CIP data type: BOOLEAN, BYTE, INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT32, FLOAT64, ASCII, STRING.
    </ParamField>

    <ParamField path="LENGTH" type="integer">
      String length (for STRING type only).
    </ParamField>
  </Accordion>

  <Accordion title="Value Transformation">
    <ParamField path="SCALING_FACTOR" type="decimal">
      Scaling multiplier for the value.
    </ParamField>

    <ParamField path="OFFSET" type="decimal">
      Value offset applied after scaling.
    </ParamField>

    <ParamField path="DEADBAND" type="decimal">
      Suppress updates if change is less than threshold.
    </ParamField>
  </Accordion>

  <Accordion title="Publishing">
    <ParamField path="SOURCE_TOPIC" type="string">
      Topic where PLC values are published. Subscribe here to receive sensor data.
    </ParamField>

    <ParamField path="PUBLISH_MODE" type="string">
      Output format: `JSON`, `RAW`, or `BINARY`. Default: JSON.
    </ParamField>
  </Accordion>
</AccordionGroup>

***

## Event-Based Operations

For on-demand EtherNet/IP operations (not polling), use the EVENT syntax. Publish a message to SOURCE\_TOPIC to trigger the operation; the route executes it and publishes the result to DESTINATION\_TOPIC.

### Supported Operations

| Operation | Description | Query Parameters |
| - | - | - |
| `READ` | Read a CIP attribute on demand | `address`, `data_type` |
| `WRITE` | Write a value to a CIP attribute | `address`, `data_type`, `value` |

### Query Parameters

| Parameter | Description | Example |
| - | - | - |
| `operation` | Operation type: `READ` or `WRITE` | `READ` |
| `address` | CIP address: ClassID.InstanceID.AttributeID.Index | `102.1.3.0`, `1.1.7.0` |
| `data_type` | CIP data type | `FLOAT32`, `UINT16`, `BOOLEAN`, `STRING` |
| `value` | Value to write (WRITE only) | `50.0`, `1`, `true` |

### Read Example

Read an analog input point value on demand:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
ADD EVENT ReadAttribute
    WITH SOURCE_TOPIC "eip/commands/read"
    WITH DESTINATION_TOPIC "eip/responses/read"
    WITH QUERY "{operation: READ, address: 102.1.3.0, data_type: FLOAT32}"
```

### Write Example

Write to an analog output point on demand:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
ADD EVENT WriteOutput
    WITH SOURCE_TOPIC "eip/commands/write"
    WITH DESTINATION_TOPIC "eip/responses/write"
    WITH QUERY "{operation: WRITE, address: 103.1.3.0, data_type: FLOAT32, value: 50.0}"
```

***

## Complete Examples

<Tabs>
  <Tab title="Device Identity">
    Read device identity information:

    ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    DEFINE ROUTE DeviceIdentity WITH TYPE ETHERNETIP
        ADD ETHERNETIP_CONFIG
            WITH IP "192.168.1.100"
            WITH PORT 44818
            WITH POLLING_MS 5000
        ADD MAPPING IdentityData
            WITH EVERY 30 SECONDS
            ADD TAG VendorID
                WITH ADDRESS "1.1.1.0"
                WITH DATA_TYPE "UINT16"
                WITH SOURCE_TOPIC "device/identity/vendor"
            ADD TAG DeviceType
                WITH ADDRESS "1.1.2.0"
                WITH DATA_TYPE "UINT16"
                WITH SOURCE_TOPIC "device/identity/type"
            ADD TAG ProductCode
                WITH ADDRESS "1.1.3.0"
                WITH DATA_TYPE "UINT16"
                WITH SOURCE_TOPIC "device/identity/product"
            ADD TAG SerialNumber
                WITH ADDRESS "1.1.6.0"
                WITH DATA_TYPE "UINT32"
                WITH SOURCE_TOPIC "device/identity/serial"
            ADD TAG ProductName
                WITH ADDRESS "1.1.7.0"
                WITH DATA_TYPE "STRING"
                WITH LENGTH 32
                WITH SOURCE_TOPIC "device/identity/name"
    ```
  </Tab>

  <Tab title="Analog I/O">
    Read analog input points:

    ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    DEFINE ROUTE AnalogIO WITH TYPE ETHERNETIP
        ADD ETHERNETIP_CONFIG
            WITH IP "192.168.1.100"
            WITH PORT 44818
            WITH POLLING_MS 500
        ADD MAPPING AnalogInputs
            WITH EVERY 500 MILLISECONDS
            ADD TAG AnalogIn1
                WITH ADDRESS "102.1.3.0"
                WITH DATA_TYPE "FLOAT32"
                WITH SOURCE_TOPIC "io/analog/in/1"
                WITH SCALING_FACTOR 0.01
                WITH OFFSET 0
                WITH DEADBAND 0.1
            ADD TAG AnalogIn2
                WITH ADDRESS "102.2.3.0"
                WITH DATA_TYPE "FLOAT32"
                WITH SOURCE_TOPIC "io/analog/in/2"
                WITH SCALING_FACTOR 0.01
                WITH DEADBAND 0.1
            ADD TAG AnalogIn3
                WITH ADDRESS "102.3.3.0"
                WITH DATA_TYPE "FLOAT32"
                WITH SOURCE_TOPIC "io/analog/in/3"
                WITH SCALING_FACTOR 0.01
                WITH DEADBAND 0.1
    ```
  </Tab>

  <Tab title="Digital I/O">
    Read discrete input/output points:

    ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    DEFINE ROUTE DiscreteIO WITH TYPE ETHERNETIP
        ADD ETHERNETIP_CONFIG
            WITH IP "192.168.1.100"
            WITH PORT 44818
            WITH POLLING_MS 100
        ADD MAPPING DiscreteInputs
            WITH EVERY 100 MILLISECONDS
            ADD TAG DI_Status1
                WITH ADDRESS "104.1.3.0"
                WITH DATA_TYPE "BOOLEAN"
                WITH SOURCE_TOPIC "io/discrete/in/1"
            ADD TAG DI_Status2
                WITH ADDRESS "104.2.3.0"
                WITH DATA_TYPE "BOOLEAN"
                WITH SOURCE_TOPIC "io/discrete/in/2"
            ADD TAG DO_Command1
                WITH ADDRESS "105.1.3.0"
                WITH DATA_TYPE "BOOLEAN"
                WITH SOURCE_TOPIC "io/discrete/out/1"
            ADD TAG DO_Command2
                WITH ADDRESS "105.2.3.0"
                WITH DATA_TYPE "BOOLEAN"
                WITH SOURCE_TOPIC "io/discrete/out/2"
    ```
  </Tab>

  <Tab title="Assembly Data">
    Read assembly object data:

    ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    DEFINE ROUTE AssemblyData WITH TYPE ETHERNETIP
        ADD ETHERNETIP_CONFIG
            WITH IP "192.168.1.100"
            WITH PORT 44818
            WITH POLLING_MS 250
        ADD MAPPING InputAssembly
            WITH EVERY 250 MILLISECONDS
            ADD TAG InputAssembly100
                WITH ADDRESS "4.100.3.0"
                WITH DATA_TYPE "UINT32"
                WITH SOURCE_TOPIC "assembly/input/100"
                WITH PUBLISH_MODE "JSON"
            ADD TAG InputAssembly101
                WITH ADDRESS "4.101.3.0"
                WITH DATA_TYPE "UINT32"
                WITH SOURCE_TOPIC "assembly/input/101"
            ADD TAG OutputAssembly150
                WITH ADDRESS "4.150.3.0"
                WITH DATA_TYPE "UINT32"
                WITH SOURCE_TOPIC "assembly/output/150"
    ```
  </Tab>

  <Tab title="Multi-Rate Polling">
    Different polling rates for different data:

    ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    DEFINE ROUTE MultiRateEIP WITH TYPE ETHERNETIP
        ADD ETHERNETIP_CONFIG
            WITH IP "192.168.1.100"
            WITH PORT 44818
        
        ADD MAPPING FastData
            WITH EVERY 100 MILLISECONDS
            ADD TAG CriticalStatus
                WITH ADDRESS "104.1.3.0"
                WITH DATA_TYPE "BOOLEAN"
                WITH SOURCE_TOPIC "fast/status"
            ADD TAG ProcessValue
                WITH ADDRESS "102.1.3.0"
                WITH DATA_TYPE "FLOAT32"
                WITH SOURCE_TOPIC "fast/pv"
        
        ADD MAPPING SlowData
            WITH EVERY 5 SECONDS
            ADD TAG DeviceStatus
                WITH ADDRESS "1.1.5.0"
                WITH DATA_TYPE "UINT16"
                WITH SOURCE_TOPIC "slow/device_status"
            ADD TAG DiagnosticCount
                WITH ADDRESS "1.1.8.0"
                WITH DATA_TYPE "UINT32"
                WITH SOURCE_TOPIC "slow/diagnostic"
    ```
  </Tab>

  <Tab title="Combined (Cyclic + On-Demand)">
    Continuous monitoring with on-demand read and write events in the same route:

    ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    DEFINE ROUTE FullEIPSetup WITH TYPE ETHERNETIP
        ADD ETHERNETIP_CONFIG
            WITH IP "192.168.1.100"
            WITH PORT 44818
            WITH POLLING_MS 500
        
        ADD MAPPING AnalogInputs
            WITH EVERY 500 MILLISECONDS
            ADD TAG ProcessValue
                WITH ADDRESS "102.1.3.0"
                WITH DATA_TYPE "FLOAT32"
                WITH SOURCE_TOPIC "eip/analog/pv"
                WITH SCALING_FACTOR 0.01
            ADD TAG Status
                WITH ADDRESS "104.1.3.0"
                WITH DATA_TYPE "BOOLEAN"
                WITH SOURCE_TOPIC "eip/discrete/status"
        
        ADD EVENT ReadAttribute
            WITH SOURCE_TOPIC "eip/commands/read"
            WITH DESTINATION_TOPIC "eip/responses/read"
            WITH QUERY "{operation: READ, address: 1.1.6.0, data_type: UINT32}"
        
        ADD EVENT WriteOutput
            WITH SOURCE_TOPIC "eip/commands/write"
            WITH DESTINATION_TOPIC "eip/responses/write"
            WITH QUERY "{operation: WRITE, address: 103.1.3.0, data_type: FLOAT32, value: 0}"
    ```

    The MAPPING continuously reads an analog input and a discrete status. To trigger an on-demand read (e.g., device serial number), publish any message to `eip/commands/read`. To write an analog output, publish to `eip/commands/write`.
  </Tab>
</Tabs>

***

## CIP Object Reference

<AccordionGroup>
  <Accordion title="Identity Object (Class 1)">
    | Attribute | Description | Data Type |
    | - | - | - |
    | 1 | Vendor ID | UINT16 |
    | 2 | Device Type | UINT16 |
    | 3 | Product Code | UINT16 |
    | 4 | Revision | UINT16\[2] |
    | 5 | Status | UINT16 |
    | 6 | Serial Number | UINT32 |
    | 7 | Product Name | STRING |
  </Accordion>

  <Accordion title="Analog Input Point (Class 102)">
    | Attribute | Description | Data Type |
    | - | - | - |
    | 3 | Value | FLOAT32/INT16 |
    | 4 | Status | UINT16 |
    | 5 | Scaling Minimum | FLOAT32 |
    | 6 | Scaling Maximum | FLOAT32 |
  </Accordion>

  <Accordion title="Discrete Input Point (Class 104)">
    | Attribute | Description | Data Type |
    | - | - | - |
    | 3 | Value | BOOLEAN |
    | 4 | Status | UINT16 |
  </Accordion>

  <Accordion title="Assembly Object (Class 4)">
    | Attribute | Description | Data Type |
    | - | - | - |
    | 3 | Data | Variable |
    | 4 | Size | UINT16 |
  </Accordion>
</AccordionGroup>

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Connection Failed">
    * Verify IP address is correct
    * Check firewall allows port 44818 (TCP and UDP)
    * Ensure device supports EtherNet/IP explicit messaging
    * Try increasing CONNECTION\_TIMEOUT
  </Accordion>

  <Accordion title="CIP Path Error">
    * Verify ClassID.InstanceID.AttributeID format
    * Check CIP object exists on device
    * Consult device documentation for valid paths
    * Instance usually starts at 1, not 0
  </Accordion>

  <Accordion title="Data Type Mismatch">
    * Verify DATA\_TYPE matches attribute definition
    * Check device documentation for correct types
    * Some devices use INT16 instead of FLOAT32 for analog
  </Accordion>

  <Accordion title="Timeout Errors">
    * Increase READ\_WRITE\_TIMEOUT
    * Check network connectivity
    * Reduce polling rate if device is slow
    * Verify device is not overloaded with connections
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Allen-Bradley" icon="industry" href="./allen-bradley">
    Tag-based access to Allen-Bradley PLCs.
  </Card>

  <Card title="FINS (Omron)" icon="robot" href="./fins">
    Connect to Omron PLCs.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.