AI 에이전트가 MCP 브리지를 통해 Siemens S7-1500을 프로그래밍하다 - SCL과 포착된 경쟁 조건
요약
LLM 에이전트가 Openness API와 MCP 서버를 통해 Siemens TIA Portal V19 환경에서 실제 산업 제어 프로그램(S7-1500용 컨베이어 분류 제어)을 프로그래밍하는 과정을 다룹니다. 단순 코드 생성을 넘어, CPU 추가, 컴파일, 시뮬레이터 실행 등 전체 엔지니어링 루프를 수행하며 에이전트의 의사결정 과정과 한계를 분석했습니다.
핵심 포인트
- 에이전트는 TIA Portal 환경에서 PLC 개발 전 과정을 자동화할 수 있음.
- 단순 코드 작성을 넘어, 설정 및 검증(Config tasks) 단계가 중요함.
- LLM 에이전트의 엔지니어링 결정 과정과 실패 모드 분석이 핵심임.
- Openness API와 MCP 브리지를 통해 산업용 툴체인 접근 가능.
우리는 Openness API를 통해 Siemens TIA Portal V19을 구동하는 MCP 서버를 구축하고, LLM 에이전트를 이 서버에 연결한 다음, 실제 엔지니어링 과제(S7-1500 (CPU 1511-1 PN)용 컨베이어 분류 제어 프로그램 구현)를 부여했습니다. 이 코드는 S7-PLCSIM에서 검증되었습니다.
단순히 '코드 스니펫 생성' 수준이 아니었습니다. 전체 루프, 즉:
CPU 추가 → 컴파일 → 시뮬레이터 시작 → FB/UDT 생성 → SCL 작성 → 컴파일 → 다운로드 → 검증.
저는 코드가 가장 흥미로운 부분이 될 것이라 예상했습니다. 하지만 그렇지 않았습니다. 흥미로웠던 부분은 에이전트가 어떤 엔지니어링 결정을 내렸는지, 그리고 어디에서 선을 긋고 넘는 것을 거부했는지였습니다.
실제 코드와 에이전트가 플래그를 지정한 실패 모드를 포함하여 상황을 설명합니다.
툴체인 (The toolchain)
- 에이전트: 사양(spec)을 읽고, 단계를 계획하며, 코드를 작성하고 테스트하는 LLM 에이전트 (WorkBuddy).
- 브리지: MCP 서버 (TiaLink). TIA Portal 작업을 MCP를 통해 노출합니다. 즉, 장치 추가, 블록 생성, SCL 작성, 컴파일, 다운로드, 읽기 등이 가능합니다.
- 타겟: Openness가 적용된 TIA Portal V19와 검증을 위한 S7-PLCSIM.
브리지는 TIA Portal과 같은 기계(산업용 PC)에서 실행되며, 에이전트는 브리지에 접근할 수만 있다면 다른 곳에서 실행될 수 있습니다.
프롬프트 (The prompt)
하드웨어 및 네트워크 구성은 이미 완료되었습니다. 과제는 다음과 같았습니다:
- 사양과 동일한 상태 번호를 가진 SCL **상태 머신(state machine)**을 구현합니다 (이렇게 해야 HMI, 알람, 테스트 및 현장 디버깅 모두 같은 번호 매김을 참조할 수 있습니다).
- 자체 인스턴스 DB를 가진 재사용 가능한 FB로 로직을 구성합니다 (라인 #2는 복사-붙여넣기가 아닌 두 번째 인스턴스 DB가 되어야 합니다).
i_입력 /q_출력 /stat_내부 변수의 명확한 분리.- IEC 타이머 (
TON_TIME) 사용 — 수동으로 스캔 사이클 누적 계산 금지. - 다음 기능 구현: 진입 중복 제거(entry de-dup), 품질 결과 래치(quality-result latch), 이중 실린더 인터록(dual-cylinder interlock), 고장 래치(fault latch), 수동 리셋, 정상 정지.
- 모든 출력은 매 스캔마다 결정론적 값(deterministic value)을 가져야 합니다 — 이전 사이클의 잔여값에 의존해서는 안 됩니다.
- 비상 정지는 **안전 회로 상태 입력(safety-circuit status input)**으로만 읽어야 하며, 일반 PLC 코드는 안전 기능이 아닙니다.
제공물(Deliverables): FB SCL 소스, UDTs, 상태 전이 문서(state-transition doc), ≥10개의 자동화 테스트 케이스, 경계/경쟁 조건 분석.
그리고 마지막에 한 줄:
"먼저 CPU를 추가하고 시뮬레이터가 작동하는지 확인하세요."
제가 실제로 테스트에 신경 쓴 부분은 바로 그 부분이었습니다. 설정 작업(Config tasks)은 스크린샷으로 평가됩니다. 프로그램은 동작(behavior)으로 평가됩니다. 따라서: 에이전트가 먼저 검증 환경을 구축하는지, 아니면 코드를 작성하기 시작하는지에 따라 다릅니다.
선택한 순서 (The sequence it chose)
- CPU가 이미 존재하는지 확인 — 그 후에만
PLC_1(CPU 1511-1 PN) 추가 - 컴파일하고 S7-PLCSIM을 시작하여 다운로드/실행이 작동하는지 확인
FB_ConveyorSort를 생성하고 SCL로 상태 기계(state machine) 작성- 필요한 UDTs 생성
OB1에서 인스턴스 DBDB_ConveyorSort_1을 사용하여 FB 호출- 컴파일 + 다운로드 — 오류 없음
- 상태 전이 테이블, 14개 테스트 케이스, 그리고 경쟁/경계 분석 제공
검증 환경을 먼저 구축했습니다. 좋은 신호입니다.
상태 기계 (The state machine)
| State | Name | Enter when | Main action | Exit → target |
|---|---|---|---|---|
| 0 | INIT | 첫 스캔(first scan) | 래치, 오류 코드, 명령 초기화 | 무조건적(unconditional) → 10 |
| ... |
SCL
여기에 에이전트가 제공한 전체 함수 블록(function block)이 있습니다. 읽으면서 두 가지에 주목하세요:
- **섹션 0 (Section 0)**은 사이클 시작 시 모든 출력을 결정론적 값으로 설정합니다(요구사항 #6).
- **섹션 7 (Section 7)**은 인터록과 동일한 결정론적 보장(determinism guarantee)을 갖는 최종 출력 매핑입니다.
FUNCTION_BLOCK
## 배포된 14가지 테스트 케이스
| # | 이름 | 전제 조건 | 동작 | 예상 결과 |
| --- | --- | --- | --- | :--- |
| TC-01 | Power-on init | sim에 다운로드됨 | 첫 번째 스캔 | 상태 10, 모든 출력 0, 오류 없음 |
| ... |
## 플래그된 경쟁 조건 (실제로 유용한 부분)
1. **진입 중복 제거(Entry de-dup) 대 센서 고착(Sensor sticking)** — 부품이 진입 포토아이를 떠날 때까지 래칭되지만, _부품이 실제로 떠나지 않으면_; 나중에 들어오는 부품들이 누락될 수 있습니다. 이 공정은 단일 개체 간의 간격을 보장해야 합니다.
2. **품질 결과 래칭 시점** — 품질 시스템의 결과가 부품이 도착할 때까지 안정적이지 않을 수 있고, 위치 신호와 경쟁(race)하게 될 수 있으므로, 정렬 위치가 아닌 **진입 지점(entry)**에서 래칭합니다. 만약 품질 감지 속도가 느리다면, 단순히 읽기 지연 대신 핸드셰이크/큐를 사용해야 합니다.
3. **동일 스캔에서의 도착 대 시간 초과** — IEC `TON`은 `PT`에 도달하는 스캔에서 `Q = TRUE`로 설정됩니다. 이는 도착 전에 시간 초과를 확인하고, 도착 시 타이머를 명시적으로 재설정합니다. 만약 '도착이 우선'해야 한다면, 순서를 변경해야 합니다.
4. **푸시 후 재트리거(Re-trigger after push)** — 부품이 여전히 정렬 포토아이를 잠시 가릴 수 있습니다. 70에서 20으로 바로 이동하면 이중 정렬을 유발할 것입니다. 상태 80 (DISCHARGE)은 아이가 깨끗해질 때까지 기다린 후에 재활성화됩니다.
5. **인터록 계층화(Interlock layering)** — 소프트웨어는
**첫 스캔 초기화(First-scan init)** — 상태 0에서 초기화가 수행됩니다. 적절한 프로젝트라면 `OB100`도 사용해야 합니다. 상태 0을 유지하여 초기화가 상태 머신 내에서 보이도록 하고 테스트할 수 있게 했습니다.**여러 인스턴스(Multiple instances)** — 타이머와 엣지 메모리는 FB(Function Block)의 statics에 존재하므로, **절대 하나의 인스턴스 DB를 라인 전체에 공유하지 마십시오**.**시뮬레이터 ≠ 현장(Sim ≠ field)** — 시뮬레이터는 포토아이 떨림(photo-eye chatter), 공압 지연(pneumatic delay) 또는 안전 회로 응답 시간은 모델링하지 못합니다. 모든 시간은 실제 기계에서 조정되어야 합니다.
## 명시적으로 거부한 세 가지 사항
이 부분이 제가 가장 중요하다고 생각하며, 이 글을 작성하게 된 이유입니다:
- **비상 정지(Emergency stop)**는 하드웨어 안전 회로(안전 릴레이/안전 PLC)를 통해 구현되어야 합니다. 프로그램은 단지 `i_xSafetyOK`만 읽습니다.
- **이중 실린더 하드 인터록(Dual-cylinder hard interlock)**은 공압식 또는 전기식이어야 합니다. 소프트웨어 인터록은 _보조적입니다_.
- **시간 매개변수 및 센서 튜닝(Time parameters and sensor tuning)**은 실제 기계에서 수행되어야 합니다. 시뮬레이터는 실제 떨림이나 공압 지연을 제공할 수 없습니다.
AI 에이전트는 소프트웨어 부분만 처리하고, 자신이 감당할 수 없는 책임은 다시 인간에게 넘겼습니다. 마치 '완료'한 것처럼 가장하지 않았습니다.
이것이 제가 산업 제어에 관여하는 모든 코드 생성기에게 바라는 속성입니다: 검증 가능한 부분은 생성하고, 무엇을 검증할 수 없는지 명확하게 밝히는 것입니다.
## 솔직한 주의사항(Honest caveats)
- 시뮬레이터 통과가 **현장 준비 완료**를 의미하지는 않습니다.
- 저는 코드가 컴파일되고 다운로드되며 논리적 수준에서 테스트 케이스와 일치하는지만 확인했을 뿐입니다. 실제 하드웨어에 대한 벤치 테스트는 수행하지 않았습니다.
- 에이전트가 자체 보고한 단계 로그(step log)는 전체 글에 나와 있습니다. 모델의 자체 보고는 평소처럼 회의적인 시각으로 다루십시오.
_스크린샷, 전체 소스, 에이전트의 단계 로그가 포함된 전체 글: [AI 기반 PLC 프로그래밍 (WorkBuddy + TiaLink)](https://www.hubwiz.com/blog/ai-powered-plc-programming-with-workbuddy-and-tialink/?utm_source=devto&utm_medium=syndication)._
_공개: 저는 이 작업에 참여하고 있습니다 — 에이전트와 TIA Portal MCP 브리지는 저희 팀의 도구입니다 (汇智网)._
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기