For the complete documentation index, see llms.txt. This page is also available as Markdown.

PLC Relay

Configure PLC Relay to read and write PLC tags over Allen-Bradley, Modbus TCP, or Siemens S7.

PLC Relay is an edge container service that provides an HTTP API for reading and writing PLC tags. You configure it through the Deployment Manager UI by selecting a protocol, entering connection details, and defining tags.

PLC Relay is available exclusively for Enterprise customers. Contact the Roboflow sales team to learn more.

Supported Protocols

When adding or editing a PLC Relay service, you select one of three protocols. Each protocol has its own connection settings and tag format.

Protocol

PLC_DRIVER

PLCs

Default Port

Allen-Bradley (EtherNet/IP)

allen_bradley

CompactLogix, ControlLogix, Micro800

44818

Modbus TCP

modbus

Any Modbus TCP device

502

Siemens S7

siemens_s7

S7-300, S7-400, S7-1200, S7-1500

102

Connection Settings

PLC Address

The address format depends on the selected protocol:

  • Allen-Bradley: IP or hostname, optionally followed by /slot (e.g. 192.168.1.100/0) or a full CIP routing path.

  • Modbus TCP: IP or hostname, with optional :port (e.g. 192.168.1.100:502). Also requires a Unit ID (0-255) and Word Order (big or little) for 32-bit values.

  • Siemens S7: IP or hostname, with optional :port (e.g. 192.168.1.100:102). Also requires Rack (0-7) and Slot (0-31).

Simulation Mode

When enabled, PLC Relay uses an in-memory simulator instead of connecting to a real PLC. All API operations work normally, but values are stored in memory. This is useful for testing without hardware.

Tag Configuration

Tags define the PLC data points accessible through the API. Each tag has a name, data type, writable flag, and optional description.

Data Types

Type
Description
Range

BOOL

Boolean

true / false

INT

16-bit signed integer

-32,768 to 32,767

DINT

32-bit signed integer

-2,147,483,648 to 2,147,483,647

REAL

32-bit floating point

IEEE 754

Tag Name Formats

Tag names match the PLC program and are case-sensitive.

Style
Example

Simple

TagName

Program-scoped

Program:MainProgram.TagName

Array element

TagName[0]

UDT member

MyUDT.Member

Format: {area}:{address} where address is a non-negative integer.

Area
Type(s)
Access
Example

coil

BOOL

Writable

coil:0

discrete

BOOL

Read-only

discrete:5

holding

INT, DINT, REAL

Writable

holding:100

input

INT, DINT, REAL

Read-only

input:200

Data Block format: DB{n}.DB[XWD]{byte}[.{bit}]

Area format: [MIQEA][WD]?{byte}[.{bit}]

Address
Type
Description

DB1.DBX0.0

BOOL

Bit 0 of byte 0 in Data Block 1

DB1.DBW0

INT

16-bit word in DB1

DB1.DBD0

DINT or REAL

32-bit double-word in DB1

M0.0

BOOL

Merker bit

I0.0 / Q0.0

BOOL

Process input/output bit

MW0 / MD0

INT / DINT or REAL

Merker word / double-word

For S7-1200/1500: enable PUT/GET in TIA Portal and disable optimized block access on accessed DBs.

Web Dashboard

PLC Relay includes a built-in web dashboard for monitoring tag values in real time. Once the service is running, access it at http://<device-ip>:8007.

The dashboard also hosts interactive Swagger documentation at /docs and a visual config builder at /static/config-builder.html.

HTTP API

The API reads and writes the configured tags over HTTP, so a pipeline can exchange PLC data without speaking Allen-Bradley EtherNet/IP, Modbus TCP, or Siemens S7 directly. Base URL is http://<device-ip>:8007, and the API is unauthenticated. See Services for the rules shared by all on-device service APIs.

Tags come from the PLC_TAGS environment variable on the service and cannot be created or changed through the API. Only values can be written, and only for tags configured as writable.

Read Before You Trust the Status Code

A request that reaches the service but fails at the PLC returns 200. Check the body:

  • /read returns value: null with error populated.

  • /write returns success: false with error populated.

  • /healthz returns plc_connected: false.

Genuine 4xx responses mean the request itself was wrong: 404 for a tag that is not configured, 403 for a tag configured as read-only, 400 for an empty batch or a duplicate tag name in a write batch, 422 for a body or query parameter that fails validation.

Health and Validation

/healthz also reports the active driver, whether the relay is in live or simulation mode, and the latest tag validation summary. Validation compares each configured tag against the PLC and reports it as ok, not_found, type_mismatch, or not_validated.

Health check

get

Returns service status, PLC connection state, the active driver and mode, and the latest tag validation summary. Returns 200 with plc_connected: false when the PLC is unreachable, so check the field rather than the status code.

Responses
200

Service status

application/json
statusstringRequired

Service status, healthy or unhealthy

plc_connectedbooleanRequired

Whether the PLC is connected

tag_countintegerRequired

Number of configured tags

plc_driverstring · enumRequired

Active PLC driver

Possible values:
modestring · enumRequired

Whether the relay is talking to a real PLC or the in-memory simulator

Possible values:
plc_ipstring · nullableOptional

Configured PLC address

get/healthz
200

Service status

Re-run validation after a PLC program change or a reconnection:

Re-run tag validation

post

Validates every configured tag against the PLC, checking that it exists and that its data type matches the configuration. Useful after a PLC program change or a reconnection. Returns a summary with validated: false and zeroed counts when no validation results are available.

Responses
200

Validation summary

application/json
validatedbooleanRequired

Whether validation has been performed

totalintegerRequired

Total number of configured tags

okintegerRequired

Tags that passed validation

not_foundintegerRequired

Tags not found on the PLC

type_mismatchintegerRequired

Tags whose PLC type does not match the configuration

not_validatedintegerRequired

Tags not yet validated

post/validate

Tag Definitions

Tag names are PLC addresses in the format for the active driver, described in Tag Name Formats.

Get tag definitions

get

Returns the tag schema as defined by the PLC_TAGS environment variable.

Responses
200

Tag definitions

application/json
countintegerRequired

Number of tags

get/schema
200

Tag definitions

Read and Write Values

Read all tag values

get

Returns the current value of every configured tag, along with connection state.

Responses
200

Current values for all tags

application/json
countintegerRequired
plc_connectedbooleanRequired
get/all_tags

Read a single tag

get

Reads one tag by name. A read that reaches the service but fails at the PLC returns 200 with error populated and value null, so check error as well as the status code.

Query parameters
tagstringRequired

Name of the tag to read, as configured in PLC_TAGS.

Example: Station1.CycleCount
Responses
200

Tag value

application/json
namestringRequired
typestring · enumRequired

Tag data type. INT is a 16-bit signed integer (-32,768 to 32,767), DINT a 32-bit signed integer (-2,147,483,648 to 2,147,483,647), and REAL a 32-bit float.

Possible values:
descriptionstringRequired
writablebooleanRequired
valueone of · nullableOptional

Current value, null when the read failed

booleanOptional
or
numberOptional
last_updatedstring · date-time · nullableOptional
errorstring · nullableOptional

Read error, null on success

validation_statusstring · enum · nullableOptionalPossible values:
validation_detailstring · nullableOptional
get/read

Write a single tag

post

Writes one value to a configured writable tag. A write that reaches the PLC and fails there returns 200 with success: false and error populated.

Body
namestringRequired

Tag name to write

valueone ofRequired

Value to write

booleanOptional
or
numberOptional
Responses
200

Write result

application/json
namestringRequired
valueone of · nullableOptional

Value written, null when the write failed

booleanOptional
or
numberOptional
successbooleanRequired
errorstring · nullableOptional
post/write

Batch Operations

Both batch endpoints validate as a unit before anything runs, so an unknown tag rejects the whole request rather than returning partial results.

/write_batch additionally rejects a batch that names the same tag twice, since keeping only the last value for a repeated name would silently drop the earlier writes. /read_batch accepts duplicates and returns one result per entry, in the order you sent them.

PLC failures that happen after validation are reported per entry in write_batch's results, with success_count and error_count summarizing the batch.

Read several tags

post

Reads several tags in one request. Every name is checked before any read runs, so an unknown tag fails the whole request with 404 rather than returning partial results.

Body
tagsstring[]Required

Tag names to read

Responses
200

Tag values

application/json
countintegerRequired

Number of tags read

post/read_batch

Write several tags

post

Writes several tags in one request. The whole batch is validated first: an empty list, a duplicate tag name, an unknown tag, or a tag that is not writable rejects the request before any write happens. Duplicates are rejected rather than collapsed, since silently keeping the last value for a name would drop the earlier writes.

Individual PLC failures after validation are reported per entry in results, with success_count and error_count summarizing the batch.

Body
Responses
200

Per-write results

application/json
success_countintegerRequired
error_countintegerRequired
post/write_batch

CLI

The plc-cli tool gives an interactive terminal interface for reading and writing tags. Use it for debugging and quick operations when the web dashboard is not reachable. It is a local client running inside the container against the same HTTP API the dashboard uses.

Key
Action

R

Read all tag values

T

Read a single tag, selected from a list

W

Write a tag, selected from the writable tags

S

Show the tag schema

H

Show detailed health status

V

Run tag validation against the PLC

Enter

Refresh the display

Q

Quit

Environment Variables

The Configure modal writes these for you. Edit them directly only when a deployment is managed by hand. See Update Device Configuration.

Variable
Default
Description

PLC_DRIVER

none

allen_bradley, modbus, or siemens_s7

PLC_IP

none

PLC address in the format for the selected driver

PLC_TAGS

none

Tag definitions as JSON. The config builder at /static/config-builder.html generates this

SIMULATION_MODE

off

Use the in-memory simulator instead of a real PLC

LOG_LEVEL

INFO

Logging verbosity: DEBUG, INFO, WARNING, or ERROR

Driver-specific settings:

Driver
Variable
Range
Default

Modbus

MODBUS_UNIT_ID

0 to 255

1

Modbus

MODBUS_WORD_ORDER

big or little

big

Siemens S7

S7_RACK

0 to 7

0

Siemens S7

S7_SLOT

0 to 31

1

Connection Monitoring

The device page shows a live PLC Relay status card with the current connection state, the active protocol, and the latest tag values. When the relay cannot reach the PLC, the card displays an unreachable banner.

To be notified when a relay loses connectivity, add a "PLC Disconnected" alert from the device's "Device Alerts" tab. See Set up Device Alerts.

Troubleshooting

Symptom
Fix

"PLC not connected" (Allen-Bradley)

Verify PLC address format (IP/Slot), check port 44818 is reachable

"PLC not connected" (Modbus)

Check IP/port (default 502) and verify Unit ID matches the device

"PLC not connected" (Siemens S7)

Check IP/port (default 102), rack, and slot values; for S7-1200/1500 enable PUT/GET and disable optimized block access

"Function refused" (Siemens S7)

PUT/GET disabled in TIA Portal, or optimized block access enabled on the target DB

REAL value reads as garbage (Modbus)

Try the opposite Word Order (big vs. little)

Validation shows NOT_FOUND

Check the PLC program for the exact tag name (case-sensitive)

Last updated

Was this helpful?