본문으로 건너뛰기

외부 프로그램 연동

엣지가 지원하지 않는 장비도 엣지의 데이터 모델로 들어올 수 있습니다.

HTTP 연결 화면 — 외부에서 밀어 넣은 값을 받는 자리

외부에서 만든 프로그램이 값을 읽어 HTTP 로 밀어 넣으면, 그 값은 엣지가 직접 수집한 태그와 똑같이 취급됩니다. 플랫폼 전송·이력·알람·플로우가 전부 그대로 걸립니다. 드라이버를 새로 만들 필요가 없습니다.

언제 쓰나
  • 엣지에 드라이버가 없는 프로토콜의 장비
  • 이미 값을 읽고 있는 기존 시스템(MES · SCADA · 자체 수집기)
  • 계산·가공을 거친 값을 올리고 싶을 때

어떻게 동작하나​

HTTP 연결은 수집하지 않습니다. 값을 받아 두는 캐시입니다.

외부 프로그램 ──HTTP──▶ 엣지의 값 캐시 ──timecycle 주기로 샘플링──▶ 태그 이력 · 플랫폼

밀어 넣는데 왜 값이 사라지나​

바깥은 푸시인데 엣지 안쪽은 여전히 폴링이기 때문입니다.

다른 드라이버는 엣지가 장비를 직접 폴링합니다. HTTP 는 그 «장비» 자리에 캐시가 앉은 것뿐이고, 캐시를 읽는 쪽은 똑같이 폴링입니다. 그래서 밀어 넣는 쪽과 읽는 쪽의 박자가 다르면 값이 어긋납니다.

바깥 → 엣지엣지 → 이력
방식푸시 (외부가 원할 때)폴링 (timecycle 주기)
놓치면—주기 사이의 값은 마지막 하나만 남습니다
MQTT · Kafka · WebSocket 도 똑같습니다

메시지를 받는 드라이버는 전부 같은 구조입니다. 브로커에서 온 메시지를 «마지막 값» 하나로 덮어쓰고, 수집 스케줄러가 그것을 주기로 읽어 갑니다.

드라이버값이 들어오는 곳
HTTP외부 프로그램의 요청
MQTT Client구독한 토픽
Kafka컨슈머가 받은 레코드
WebSocket수신 프레임

그래서 「브로커에 발행한 건수보다 수집된 건수가 훨씬 적다」는 것이 정상입니다. 브로커의 LAG 이 0 이면 엣지는 다 받고 있습니다 — 다만 이력에 남는 것은 주기마다 하나입니다. 이걸 유실로 오해해 오래 파고든 사례가 있습니다 (현장 사례집).

이 구조 때문에 따라오는 성질이 있습니다. 먼저 이해하고 시작하세요.

성질뜻
밀어 넣은 값이 즉시 저장되지 않습니다연결의 timecycle 주기로 샘플링됩니다
주기보다 빨리 밀면 중간값이 사라집니다마지막 값만 남습니다
주기보다 느리게 밀면 같은 값이 반복 저장됩니다캐시에 남은 값을 계속 읽습니다

빨리 반영되게 하려면 timecycle 을 줄이세요. 이 값이 곧 반영 지연입니다. 1000(1초)이면 최대 1초 뒤에 남고, 200 으로 줄이면 최대 0.2초 뒤에 남습니다. 최소값은 100(0.1초)입니다.

원하는 것timecycle
거의 즉시 반영100 ~ 200
일반적인 실시간 감시1000
느리게 변하는 값(온도·수위)5000 이상
주기를 줄여도 «전수» 는 아닙니다

주기를 줄이면 지연은 줄지만 마지막 값 하나만 읽는다는 성질은 그대로입니다. 주기 사이에 값이 세 번 바뀌면 마지막 하나만 남습니다.

모든 이벤트를 하나도 빠뜨리지 않고 남겨야 한다면 이 방식이 맞지 않습니다. 주기를 아무리 촘촘히 잡아도 그렇습니다.

주기를 줄이면 부하가 늡니다

그 연결에 달린 모든 태그를 그 주기로 읽습니다. 태그가 많은 연결의 주기를 100 으로 내리면 부하가 그만큼 커집니다. 빨라야 하는 태그만 따로 HTTP 연결을 만들어 그 연결만 주기를 낮추는 편이 낫습니다.


1단계 — HTTP 연결을 만듭니다​

화면에서 연결 → 추가 → HTTP 로 들어갑니다.

https://<엣지 주소>/ui/connect/http

HTTP 연결에는 드라이버 옵션이 하나도 없습니다. IP 와 포트 칸이 있지만 드라이버가 읽지 않습니다 — 형식상 입력이므로 아무 값이나 넣어도 동작에 영향이 없습니다.

REST 로 만들 수도 있습니다. 여덟 필드가 전부 필수입니다.

curl -X POST https://<엣지 주소>/api/v1/opc \
-H 'X-API-Key: <API 키>' \
-H 'Content-Type: application/json' \
-d '{
"opc_id": "OPC_EXTERNAL_01",
"opc_name": "외부 수집기",
"opc_type": "HTTP",
"site_id": "SITE_00001",
"opc_agent_ip": "127.0.0.1",
"opc_agent_port": 80,
"timecycle": 1000,
"async": false
}'
필드규칙
opc_idOPC_ 로 시작, 대문자·숫자·밑줄 1~60자
site_idSITE_ 로 시작
opc_type정확히 HTTP 여야 합니다. 다르면 값 밀어넣기가 거부됩니다
opc_agent_port1~65535
timecycle100 이상(밀리초). 이 값이 곧 샘플링 주기입니다
하나라도 빠지면 화면과 다르게 동작합니다

화면으로 만들면 빠진 값을 화면이 채워 줍니다. 그래서 REST 로 만들 때만 필드 누락으로 연결이 만들어지고도 동작하지 않는 일이 생깁니다.


2단계 — 태그를 등록하고 tag_id 를 받습니다​

그 연결 아래에 태그를 만듭니다. 값 하나가 태그 하나입니다.

데이터 타입을 값 성격에 맞게 고르세요. 값이 문자열로 와도 선언한 타입만 맞으면 정확히 파싱됩니다. 반대로 타입이 틀리면 적재 단계에서 예외가 납니다.

값타입
전류 · 온도 · 전압 · 중량 · 속도 · 좌표Double
배터리 · 에러코드 · 카운터Integer
알람 · 상태 · 구역 · 방향 · 색String

밀어넣을 때 쓸 tag_id 는 태그 목록 화면이나 태그 조회 API 로 확인합니다.


3단계 — 값을 밀어 넣습니다​

curl -X POST https://<엣지 주소>/api/v1/tag/<tag_id>/value \
-H 'X-API-Key: <API 키>' \
-H 'Content-Type: application/json' \
-d '{"value":"1500"}'

값은 문자열로 보내도 됩니다. 태그에 선언한 타입으로 파싱됩니다.

인증​

/api/ 아래는 전부 인증이 걸립니다. 키가 없으면 막힙니다 — 설정이 빠져 있어도 열리지 않습니다.

방법형태
헤더 (권장)X-API-Key: <키>
헤더Authorization: Bearer <키>
브라우저 세션로그인 상태면 키 없이 통과
쿼리 파라미터는 안 됩니다

?api_key=… 는 v1 에서 제거됐습니다. 쓰면 401 입니다. 옛 예제를 그대로 옮기지 마세요.

HTTPS 로 부르세요​

기본값이 HTTPS 전용입니다. http:// 로 부르면 403 이 돌아옵니다.


값이 안 들어올 때​

순서대로 좁힙니다.

  1. 연결이 기동 중인가 — 정지 상태면 값을 받지 않고 거부합니다. 화면에서 그 연결을 시작하세요.
  2. opc_type 이 HTTP 인가 — 다른 타입의 연결에는 밀어넣을 수 없습니다.
  3. HTTPS 로 불렀는가 — http:// 는 403 입니다.
  4. 키를 헤더로 보냈는가 — 쿼리 파라미터는 401 입니다.
  5. tag_id 가 맞는가 — 태그 목록에서 다시 확인합니다.
  6. 주기를 기다렸는가 — 밀어 넣은 즉시 저장되지 않습니다. timecycle 만큼 기다린 뒤 이력을 봅니다.

알아 둘 것​

한 번에 하나씩입니다. 여러 태그를 한 요청으로 밀어 넣는 엔드포인트는 없습니다. 태그마다 따로 호출합니다.

이중화 구성에서도 받습니다. 쓰기 권한이 없는 엣지라도 HTTP 로 밀어 넣는 값은 계속 받습니다. 외부 연동이 이중화 전환에 끊기지 않도록 일부러 그렇게 되어 있습니다.

옛 엔드포인트가 있습니다. POST /api/http 는 opc_id 와 plc_address 로 대상을 지정하는 예전 방식입니다. 2026년 12월 31일에 없어집니다. 요율 제한과 중복 방지도 걸리지 않으므로 새로 만드는 연동은 위의 /api/v1/tag/{tag_id}/value 를 쓰세요.


관련 문서​