BACnet/IP-Treiber
Überblick
BACnet/IP — Standardprotokoll für die Gebäudeautomation (HLK / Beleuchtung / Brandmeldung / Zutrittskontrolle). Arbeitet über UDP/47808 mit den Schichten BVLC + NPDU + APDU. Native Neuimplementierung 2026-07 — die frühere Delegation an Apache PLC4j bacnet-ip wurde entfernt (BACnet in PLC4j 0.13.1 ist canRead()=false (nur passive/EDE), sodass beim connect eine "doesn't support reading"-Ausnahme auftrat und die Erfassung überhaupt nicht möglich war). Jetzt wird die eigene BACnet/IP-Implementierung mit confirmed ReadProperty-Polling aus plantpulse-plc-protocol verwendet (BacnetIpPLC) — dasselbe native Muster wie bei AB-ETH.
| Punkt | Wert |
|---|---|
opc_type | BACNET |
| Implementierungsklasse | plantpulse.driver.protocol.bacnet.BACnetDriver |
| Bibliothek | eigene native Implementierung (plantpulse-plc-protocol in bacnet — ReadProperty) |
| Vererbung | BaseProtocolDriver (nicht PLC4j) |
| Standardport | 47808 (0xBAC0, UDP) |
| Status | stabil (ReadProperty-Polling) |
| read | OK (ReadProperty, einzelne Property) |
| write | ❌ (nur lesend — WriteProperty nicht implementiert) |
| Sicherheit | keine (BACnet/SC nicht unterstützt) |
Die frühere PLC4j-Implementierung bildete die Objektliste statisch über eine EDE-CSV-Datei (Engineering Data Exchange) ab. Der native Treiber verwendet keine EDE-Datei — er sendet confirmed ReadProperty direkt anhand der Tag-Adresse. Die Optionen ede-file-path / ede-directory-path des alten Formulars werden ignoriert (entfernt).
Klassenstruktur
BaseProtocolDriver
└── BACnetDriver — connect() 에서 BacnetIpPLC(host, port) 생성 (UDP connectionless)
Da UDP verbindungslos ist, gibt es keinen Handshake — die bereitstehende Socket ist bereits die Verbindung, und die Liveness der Kommunikation wird bei Lesefehlern über setConnected(false) verwaltet (AB-ETH-Muster). Bei einem Lesefehler wird die Socket invalidiert, damit der Edge einen Neuaufbau der Verbindung auslöst.
Zusammenfassung des Wire-Formats (eigene Implementierung)
- BVLC (Block Virtual Link Control) → NPDU (Network) → APDU (Application).
- ReadProperty-Request:
objectIdentifier+propertyIdentifier. - ReadProperty-ACK: BACnet-Primitivtypen (Real / Unsigned / Boolean / Enumerated / CharacterString) werden als Zeichenkette dekodiert.
- BBMD (Foreign Device Registration) wird nicht verwendet — Betrieb nur innerhalb der Broadcast-Domäne desselben Subnetzes.
OPC-Registrierungsoptionen
| Feld | Bedeutung | Standard |
|---|---|---|
opc_agent_ip | IP des BACnet-Device | 192.168.1.50 |
opc_agent_port | UDP-Port | 47808 (in der Regel fest) |
options.read-timeout | Antwort-Timeout (ms) | 3000 |
Tag-plc_address-Format
<object-type>:<instance>[:<property>]
Wird property weggelassen, gilt present-value. Für object-type / property sind Name oder numerischer Code zulässig. Die alte PLC4j-Schreibweise (Punkt vor der Property: analog-input:1.present-value) wird aus Kompatibilitätsgründen ebenfalls akzeptiert.
| Schreibweise | Bedeutung |
|---|---|
analog-input:0 | present-value von AI 0 (REAL) — Property weggelassen |
analog-input:0:present-value | identisch (explizit) |
binary-input:1 | present-value von BI 1 (Boolean) |
analog-value:10 | AV 10 (berechneter Wert) |
multi-state-input:2 | MSI 2 (Unsigned) |
device:1:object-name | Name von Device 1 (CharacterString) |
0:5:85 | object-type 0 (AI) / instance 5 / property 85 (present-value) — numerische Codes |
Unterstützt / nicht unterstützt
- read: ReadProperty (einzelne Property) — OK.
- write: nicht unterstützt —
isWriteSupported() = false,write()liefern stetsfalse. (WriteProperty folgt später.) - COV-Subscription (Change Of Value): nicht unterstützt — Polling-basiert.
- BBMD / Foreign Device: nicht unterstützt — nur dasselbe Subnetz.
- BACnet/SC (Secure Connect WebSocket) und BACnet MS/TP seriell: nicht unterstützt.
curl-Registrierungsbeispiel
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"}
]
}'
Hinweise
- BACnet-Standard ASHRAE 135.
- Code: Paket
bacnetinplantpulse-edge-driver/src/plantpulse/driver/protocol/bacnet/BACnetDriver.java+plantpulse-plc-protocol. - Betrieb: Dieselbe L2-Broadcast-Domäne ist erforderlich. Devices hinter einem Router benötigen einen BBMD oder ein separates Gateway (nicht unterstützt).