본문으로 건너뛰기

BACnet/IP 드라이버

개요

BACnet/IP — 빌딩 자동화(HVAC / 조명 / 화재 / 출입통제) 표준 프로토콜. UDP/47808 위에서 BVLC + NPDU + APDU 계층으로 동작. 2026-07 네이티브 재작성 — 옛 Apache PLC4j bacnet-ip 위임은 제거되었습니다(PLC4j 0.13.1 BACnet 은 canRead()=false(passive/EDE 전용)라 connect 시 "doesn't support reading" 예외로 수집 자체가 불가했음). 지금은 plantpulse-plc-protocol 의 자체 BACnet/IP confirmed ReadProperty 폴링 구현(BacnetIpPLC)을 사용 — AB-ETH 와 동일한 네이티브 패턴.

항목
opc_typeBACNET
구현 클래스plantpulse.driver.protocol.bacnet.BACnetDriver
라이브러리자체 네이티브 (plantpulse-plc-protocolbacnet — ReadProperty)
상속BaseProtocolDriver (PLC4j 아님)
기본 포트47808 (0xBAC0, UDP)
상태안정 (ReadProperty 폴링)
readOK (ReadProperty, 단일 property)
write❌ (읽기 전용 — WriteProperty 미구현)
보안없음 (BACnet/SC 미지원)
EDE 파일 불필요

옛 PLC4j 구현은 EDE(Engineering Data Exchange) CSV 파일로 객체 목록을 정적 매핑했습니다. 네이티브 드라이버는 EDE 파일을 쓰지 않습니다 — 태그 주소로 직접 confirmed ReadProperty 를 보냅니다. 옛 폼의 ede-file-path / ede-directory-path 옵션은 무시됩니다(제거됨).


클래스 구조

BaseProtocolDriver
└── BACnetDriver — connect() 에서 BacnetIpPLC(host, port) 생성 (UDP connectionless)

UDP 는 connectionless 라 핸드셰이크가 없습니다 — 소켓 준비가 곧 연결이며, 통신 라이브니스는 read 실패 시 setConnected(false) 로 관리(AB-ETH 패턴). read 실패 시 소켓을 무효화해 엣지가 재연결하도록 유도합니다.


wire 포맷 요약 (자체 구현)

  • BVLC(Block Virtual Link Control) → NPDU(Network) → APDU(Application).
  • ReadProperty-Request: objectIdentifier + propertyIdentifier.
  • ReadProperty-ACK: BACnet 프리미티브 타입(Real / Unsigned / Boolean / Enumerated / CharacterString)을 문자열로 디코드.
  • BBMD(Foreign Device Registration)는 미사용 — 동일 서브넷의 broadcast 도메인에서만 동작.

OPC 등록 옵션

필드의미기본
opc_agent_ipBACnet device IP192.168.1.50
opc_agent_portUDP 포트47808 (보통 고정)
options.read-timeout응답 타임아웃 (ms)3000

태그 plc_address 형식

<object-type>:<instance>[:<property>]

property 를 생략하면 present-value 로 간주합니다. object-type / property 는 이름 또는 숫자 코드 둘 다 허용. 옛 PLC4j 표기(property 앞에 점: analog-input:1.present-value)도 호환 수용합니다.

표기의미
analog-input:0AI 0 의 present-value (REAL) — property 생략
analog-input:0:present-value동일 (명시)
binary-input:1BI 1 present-value (Boolean)
analog-value:10AV 10 (계산값)
multi-state-input:2MSI 2 (Unsigned)
device:1:object-nameDevice 1 의 이름 (CharacterString)
0:5:85object-type 0(AI) / instance 5 / property 85(present-value) — 숫자 코드

support / 미지원

  • read: ReadProperty (단일 property) — OK.
  • write: 미지원isWriteSupported() = false, write() 는 항상 false. (WriteProperty 는 후속 구현.)
  • COV (Change Of Value) subscription: 미지원 — 폴링 기반.
  • BBMD / Foreign Device: 미지원 — 동일 서브넷만.
  • BACnet/SC (Secure Connect WebSocket) 및 BACnet MS/TP 시리얼: 미지원.

curl 등록 예시

curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_BACNET_AHU1",
"opc_type": "BACNET",
"opc_name": "AHU-1 Controller",
"opc_agent_ip": "192.168.1.50",
"opc_agent_port": "47808",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 2000,
"options": { "read-timeout": "3000" },
"tag_list": [
{"tag_id":"OPC_BACNET_AHU1_T01","tag_name":"SupplyTemp","plc_address":"analog-input:0","data_type":"Float"},
{"tag_id":"OPC_BACNET_AHU1_T02","tag_name":"FanRun","plc_address":"binary-input:1","data_type":"Boolean"}
]
}'

참고

  • BACnet ASHRAE 135 표준.
  • 코드: plantpulse-edge-driver/src/plantpulse/driver/protocol/bacnet/BACnetDriver.java + plantpulse-plc-protocolbacnet 패키지.
  • 운영: 동일 L2 broadcast 도메인이 필요. 라우터 너머의 device 는 BBMD 또는 별도 게이트웨이가 필요(미지원).