> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/deployment/ko/self-hosted/enterprise/deployment-manager/services/plc-relay.md).

# PLC 릴레이

Allen-Bradley, Modbus TCP 또는 Siemens S7을 통해 PLC 태그를 읽고 쓰도록 PLC Relay를 구성합니다.

PLC Relay는 PLC 태그를 읽고 쓰기 위한 HTTP API를 제공하는 엣지 컨테이너 서비스입니다. Deployment Manager UI에서 프로토콜을 선택하고, 연결 정보를 입력하고, 태그를 정의하여 구성합니다.

{% hint style="info" %}
PLC Relay는 Enterprise 고객만 이용할 수 있습니다. [Roboflow 영업팀에 문의하세요](https://roboflow.com/sales) 자세한 내용을 알아보려면.
{% endhint %}

## 지원되는 프로토콜

PLC Relay 서비스를 추가하거나 편집할 때 세 가지 프로토콜 중 하나를 선택합니다. 각 프로토콜에는 고유한 연결 설정과 태그 형식이 있습니다.

<table data-header-hidden data-search="false"><thead><tr><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><td>프로토콜</td><td><code>PLC_DRIVER</code></td><td>PLC</td><td>기본 포트</td></tr><tr><td>Allen-Bradley (EtherNet/IP)</td><td><code>allen_bradley</code></td><td>CompactLogix, ControlLogix, Micro800</td><td>44818</td></tr><tr><td>Modbus TCP</td><td><code>modbus</code></td><td>모든 Modbus TCP 장치</td><td>502</td></tr><tr><td>Siemens S7</td><td><code>siemens_s7</code></td><td>S7-300, S7-400, S7-1200, S7-1500</td><td>102</td></tr></tbody></table>

{% hint style="warning" %}
프로토콜을 변경하면 태그 주소 형식은 프로토콜 간에 호환되지 않으므로 구성된 모든 태그가 지워집니다. UI는 변경 사항을 적용하기 전에 확인을 요청합니다.
{% endhint %}

## 연결 설정

### PLC 주소

주소 형식은 선택한 프로토콜에 따라 다릅니다:

* **Allen-Bradley:** IP 또는 호스트 이름, 뒤에 선택적으로 `/slot` (예: `192.168.1.100/0`) 또는 전체 CIP 라우팅 경로.
* **Modbus TCP:** IP 또는 호스트 이름, 뒤에 선택적으로 `:port` (예: `192.168.1.100:502`). 또한 32비트 값에 대해 Unit ID(0-255)와 Word Order(big 또는 little)도 필요합니다.
* **Siemens S7:** IP 또는 호스트 이름, 뒤에 선택적으로 `:port` (예: `192.168.1.100:102`). 또한 Rack(0-7)과 Slot(0-31)도 필요합니다.

### 시뮬레이션 모드

활성화하면 PLC Relay는 실제 PLC에 연결하는 대신 메모리 내 시뮬레이터를 사용합니다. 모든 API 작업은 정상적으로 작동하지만 값은 메모리에 저장됩니다. 이는 하드웨어 없이 테스트할 때 유용합니다.

## 태그 구성

태그는 API를 통해 접근할 수 있는 PLC 데이터 포인트를 정의합니다. 각 태그에는 이름, 데이터 유형, 쓰기 가능 여부 플래그, 선택적 설명이 있습니다.

### 데이터 유형

| 유형     | 설명            | 범위                              |
| ------ | ------------- | ------------------------------- |
| `BOOL` | 불리언           | `true` / `false`                |
| `INT`  | 16비트 부호 있는 정수 | -32,768 \~ 32,767               |
| `DINT` | 32비트 부호 있는 정수 | -2,147,483,648 \~ 2,147,483,647 |
| `REAL` | 32비트 부동 소수점   | IEEE 754                        |

### 태그 이름 형식

{% tabs %}
{% tab title="Allen-Bradley" %}
태그 이름은 PLC 프로그램과 일치하며 대소문자를 구분합니다.

| 형식           | 예시                            |
| ------------ | ----------------------------- |
| 단순           | `TagName`                     |
| 프로그램 범위      | `Program:MainProgram.TagName` |
| 배열 요소        | `TagName[0]`                  |
| UDT 멤버       | `MyUDT.Member`                |
| {% endtab %} |                               |

{% tab title="Modbus TCP" %}
형식: `{area}:{address}` 여기서 address는 0 이상의 정수입니다.

| 영역           | 유형              | 접근    | 예시            |
| ------------ | --------------- | ----- | ------------- |
| `코일`         | BOOL            | 쓰기 가능 | `coil:0`      |
| `디스크리트`      | BOOL            | 읽기 전용 | `discrete:5`  |
| `홀딩`         | INT, DINT, REAL | 쓰기 가능 | `holding:100` |
| `입력`         | INT, DINT, REAL | 읽기 전용 | `input:200`   |
| {% endtab %} |                 |       |               |

{% tab title="Siemens S7" %}
데이터 블록 형식: `DB{n}.DB[XWD]{byte}[.{bit}]`

영역 형식: `[MIQEA][WD]?{byte}[.{bit}]`

| 주소              | 유형                 | 설명                    |
| --------------- | ------------------ | --------------------- |
| `DB1.DBX0.0`    | BOOL               | 데이터 블록 1의 바이트 0의 비트 0 |
| `DB1.DBW0`      | INT                | DB1의 16비트 워드          |
| `DB1.DBD0`      | DINT 또는 REAL       | DB1의 32비트 더블워드        |
| `M0.0`          | BOOL               | Merker 비트             |
| `I0.0` / `Q0.0` | BOOL               | 프로세스 입력/출력 비트         |
| `MW0` / `MD0`   | INT / DINT 또는 REAL | Merker 워드 / 더블워드      |

S7-1200/1500의 경우: TIA Portal에서 PUT/GET을 활성화하고 액세스하는 DB에서 최적화된 블록 액세스를 비활성화하세요.
{% endtab %}
{% endtabs %}

## 웹 대시보드

PLC Relay에는 태그 값을 실시간으로 모니터링할 수 있는 내장 웹 대시보드가 포함되어 있습니다. 서비스가 실행되면 다음 주소에서 접근할 수 있습니다. `http://<device-ip>:8007`.

대시보드에는 다음에서 상호작용 가능한 Swagger 문서도 함께 제공됩니다. `/docs` 및 다음에서 시각적 구성 빌더도 제공합니다. `/static/config-builder.html`.

## HTTP API

API는 구성된 태그를 HTTP를 통해 읽고 쓰므로, 파이프라인이 Allen-Bradley EtherNet/IP, Modbus TCP 또는 Siemens S7과 직접 통신하지 않아도 PLC 데이터를 주고받을 수 있습니다. 기본 URL은 `http://<device-ip>:8007`, 이며 API에는 인증이 없습니다. 다음을 참조하세요. [서비스](/deployment/ko/self-hosted/enterprise/deployment-manager/services.md#using-the-apis) 장치 내 모든 서비스 API에 공통으로 적용되는 규칙.

태그는 서비스의 `PLC_TAGS` 환경 변수에서 가져오며 API를 통해 생성하거나 변경할 수 없습니다. 값만 쓸 수 있으며, 쓰기 가능으로 구성된 태그에 대해서만 가능합니다.

### 상태 코드를 믿기 전에 먼저 읽어보세요

서비스에는 도달했지만 PLC에서 실패한 요청은 `200`를 반환합니다. 본문을 확인하세요:

* `/read` 는 `value: null` 와 함께 `error` 가 채워집니다.
* `/write` 는 `success: false` 와 함께 `error` 가 채워집니다.
* `/healthz` 는 `plc_connected: false`.

실제 `4xx` 응답은 요청 자체가 잘못되었음을 의미합니다: `404` 구성되지 않은 태그에 대해, `403` 읽기 전용으로 구성된 태그에 대해, `400` 비어 있는 배치 또는 쓰기 배치에서 중복된 태그 이름에 대해, `422` 검증에 실패한 본문 또는 쿼리 매개변수에 대해.

### 상태 및 검증

`/healthz` 또한 활성 드라이버와 릴레이가 `실행` 중인지 `시뮬레이션` 모드인지, 그리고 최신 태그 검증 요약도 보고합니다. 검증은 구성된 각 태그를 PLC와 비교하여 `ok`, `not_found`, `type_mismatch`또는 `not_validated`.

{% openapi src="/files/77e1ab3c53d5d0cbb663ea227bdd37cbd6f1f1cd" path="/healthz" method="get" %}
[edge-plc-relay.yaml](https://1826078061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-bc81a2258bd5eefa9b64b301eac0797c0f01e796%2Fedge-plc-relay.yaml?alt=media)
{% endopenapi %}

PLC 프로그램 변경이나 재연결 후에는 검증을 다시 실행하세요:

{% openapi src="/files/77e1ab3c53d5d0cbb663ea227bdd37cbd6f1f1cd" path="/validate" method="post" %}
[edge-plc-relay.yaml](https://1826078061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-bc81a2258bd5eefa9b64b301eac0797c0f01e796%2Fedge-plc-relay.yaml?alt=media)
{% endopenapi %}

### 태그 정의

태그 이름은 활성 드라이버 형식의 PLC 주소이며, 다음에서 설명합니다. [태그 이름 형식](#tag-name-formats).

{% openapi src="/files/77e1ab3c53d5d0cbb663ea227bdd37cbd6f1f1cd" path="/schema" method="get" %}
[edge-plc-relay.yaml](https://1826078061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-bc81a2258bd5eefa9b64b301eac0797c0f01e796%2Fedge-plc-relay.yaml?alt=media)
{% endopenapi %}

### 값 읽기 및 쓰기

{% openapi src="/files/77e1ab3c53d5d0cbb663ea227bdd37cbd6f1f1cd" path="/all\_tags" method="get" %}
[edge-plc-relay.yaml](https://1826078061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-bc81a2258bd5eefa9b64b301eac0797c0f01e796%2Fedge-plc-relay.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/77e1ab3c53d5d0cbb663ea227bdd37cbd6f1f1cd" path="/read" method="get" %}
[edge-plc-relay.yaml](https://1826078061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-bc81a2258bd5eefa9b64b301eac0797c0f01e796%2Fedge-plc-relay.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/77e1ab3c53d5d0cbb663ea227bdd37cbd6f1f1cd" path="/write" method="post" %}
[edge-plc-relay.yaml](https://1826078061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-bc81a2258bd5eefa9b64b301eac0797c0f01e796%2Fedge-plc-relay.yaml?alt=media)
{% endopenapi %}

### 일괄 작업

두 배치 엔드포인트는 어떤 작업도 실행하기 전에 단위로 검증하므로, 알 수 없는 태그가 있으면 부분 결과를 반환하는 대신 전체 요청이 거부됩니다.

`/write_batch` 반복된 이름의 경우 마지막 값만 유지하면 이전 쓰기가 조용히 버려질 수 있으므로, 같은 태그를 두 번 지정한 배치도 추가로 거부합니다. `/read_batch` 중복을 허용하며, 보낸 순서대로 항목당 하나의 결과를 반환합니다.

검증 후에 발생한 PLC 실패는 `write_batch`의 `결과에`, `success_count` 및 `error_count` 로 배치 요약이 제공됩니다.

{% openapi src="/files/77e1ab3c53d5d0cbb663ea227bdd37cbd6f1f1cd" path="/read\_batch" method="post" %}
[edge-plc-relay.yaml](https://1826078061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-bc81a2258bd5eefa9b64b301eac0797c0f01e796%2Fedge-plc-relay.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/77e1ab3c53d5d0cbb663ea227bdd37cbd6f1f1cd" path="/write\_batch" method="post" %}
[edge-plc-relay.yaml](https://1826078061-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoksNmwps1HmYr8TqHDnX%2Fuploads%2Fgit-blob-bc81a2258bd5eefa9b64b301eac0797c0f01e796%2Fedge-plc-relay.yaml?alt=media)
{% endopenapi %}

## CLI

plc-cli `도구는 태그를 읽고 쓰기 위한 대화형 터미널 인터페이스를 제공합니다. 웹 대시보드에 접근할 수 없을 때 디버깅과 빠른 작업에 사용하세요. 이는 대시보드가 사용하는 것과 동일한 HTTP API에 대해 컨테이너 내부에서 실행되는 로컬 클라이언트입니다.` docker exec -it plc-relay plc-cli

```bash
docker exec -it plc-relay plc-cli
```

<table data-search="false"><thead><tr><th>키</th><th>작업</th></tr></thead><tbody><tr><td><code>R</code></td><td>모든 태그 값 읽기</td></tr><tr><td><code>T</code></td><td>목록에서 선택한 단일 태그 읽기</td></tr><tr><td><code>W</code></td><td>쓰기 가능한 태그 중에서 선택한 태그 쓰기</td></tr><tr><td><code>S</code></td><td>태그 스키마 표시</td></tr><tr><td><code>H</code></td><td>상세 상태 표시</td></tr><tr><td><code>V</code></td><td>PLC에 대해 태그 검증 실행</td></tr><tr><td><code>Enter</code></td><td>화면 새로고침</td></tr><tr><td><code>Q</code></td><td>종료</td></tr></tbody></table>

## 환경 변수

구성 모달이 이 값들을 대신 작성해 줍니다. 배포가 수동으로 관리되는 경우에만 직접 편집하세요. 다음을 참조하세요. [장치 구성 업데이트](/deployment/ko/self-hosted/enterprise/deployment-manager/making-changes/update-device-configuration.md).

<table data-search="false"><thead><tr><th>변수</th><th>기본값</th><th>설명</th></tr></thead><tbody><tr><td><code>PLC_DRIVER</code></td><td>없음</td><td><code>allen_bradley</code>, <code>modbus</code>또는 <code>siemens_s7</code></td></tr><tr><td><code>PLC_IP</code></td><td>없음</td><td>선택한 드라이버 형식의 PLC 주소</td></tr><tr><td><code>PLC_TAGS</code></td><td>없음</td><td>JSON 형식의 태그 정의입니다. 다음의 구성 빌더가 이를 <code>/static/config-builder.html</code> 생성합니다</td></tr><tr><td><code>SIMULATION_MODE</code></td><td>끔</td><td>실제 PLC 대신 메모리 내 시뮬레이터를 사용</td></tr><tr><td><code>LOG_LEVEL</code></td><td><code>INFO</code></td><td>로깅 상세도: <code>DEBUG</code>, <code>INFO</code>, <code>WARNING</code>또는 <code>ERROR</code></td></tr></tbody></table>

드라이버별 설정:

<table data-search="false"><thead><tr><th>드라이버</th><th>변수</th><th>범위</th><th>기본값</th></tr></thead><tbody><tr><td>Modbus</td><td><code>MODBUS_UNIT_ID</code></td><td>0~255</td><td><code>1</code></td></tr><tr><td>Modbus</td><td><code>MODBUS_WORD_ORDER</code></td><td><code>big</code> 중인지 <code>little</code></td><td><code>big</code></td></tr><tr><td>Siemens S7</td><td><code>S7_RACK</code></td><td>0~7</td><td><code>0</code></td></tr><tr><td>Siemens S7</td><td><code>S7_SLOT</code></td><td>0~31</td><td><code>1</code></td></tr></tbody></table>

## 연결 모니터링

장치 페이지에는 현재 연결 상태, 활성 프로토콜, 최신 태그 값이 표시된 라이브 PLC Relay 상태 카드가 있습니다. 릴레이가 PLC에 도달할 수 없으면 카드에 연결 불가 배너가 표시됩니다.

릴레이가 연결을 잃었을 때 알림을 받으려면 장치의 "장치 알림" 탭에서 "PLC 연결 해제" 알림을 추가하세요. 다음을 참조하세요. [장치 알림 설정](/deployment/ko/self-hosted/enterprise/deployment-manager/setting-up/set-up-device-alerts.md).

## 문제 해결

| 증상                                  | 해결                                                                                        |
| ----------------------------------- | ----------------------------------------------------------------------------------------- |
| "PLC not connected" (Allen-Bradley) | PLC 주소 형식(IP/Slot)을 확인하고 포트 44818에 접근할 수 있는지 확인하세요                                        |
| "PLC not connected" (Modbus)        | IP/포트(기본값 502)를 확인하고 Unit ID가 장치와 일치하는지 확인하세요                                             |
| "PLC not connected" (Siemens S7)    | IP/포트(기본값 102), rack, slot 값을 확인하세요. S7-1200/1500의 경우 PUT/GET을 활성화하고 최적화된 블록 액세스를 비활성화하세요 |
| "Function refused" (Siemens S7)     | TIA Portal에서 PUT/GET이 비활성화되어 있거나 대상 DB에서 최적화된 블록 액세스가 활성화되어 있음                            |
| REAL 값이 이상하게 읽힘(Modbus)             | 반대 Word Order(big vs. little)를 시도해 보세요                                                    |
| 검증 결과 NOT\_FOUND로 표시됨               | PLC 프로그램에서 정확한 태그 이름을 확인하세요(대소문자 구분)                                                      |
