Zum Hauptinhalt springen

DNP3-Treiber

Übersicht

IEEE 1815 Standard DNP3 (Distributed Network Protocol). De-facto-Standard für Utility-SCADA in den Bereichen Strom, Wasser und Gas. Der Master (Client) baut eine TCP-Verbindung zur Outstation (Server) auf und erfasst über Application-Layer-READ die Messwerte (Analog Input / Binary Input / Counter).

PositionWert
opc_typeDNP3
Implementierungsklasseplantpulse.driver.protocol.dnp3.DNP3Driver
Bibliothekeigene Java-Implementierung (keine externen Abhängigkeiten)
read✅ (Einzelpunkt + Class Poll)
write✅ (G12V1 CROB, G41V1~V4 Analog Output)
Sicherheitkeine (DNP3-SA nicht implementiert)
Standardport20000 (TCP)

Klassenstruktur

KlasseFunktion
DNP3DriverTCP-Socket / Zusammenbau von AL+TL+DLL / Einzelpunkt-read / Class Poll / write
DnpDataLink10-Byte-DLL-Header (Start 0x05 0x64) + LE-CRC je 16-Byte-Block
DnpTransport1-Byte-TL-Header (FIN/FIR/SEQ 6 Bit)
DnpApplicationFunction Code, IIN, Object Header, Qualifier, Response-Parser
DnpObjectObjekt-Encoder/-Decoder für Group 1/2/10/12/20/30/32/40/41
DnpCrcDNP3-spezifisches CRC-16 (Poly 0x3D65, reflected 0xA6BC, ~Komplement, LE-Serialisierung)
DnpAddressAdressparser für gNvM.idx / classN

Wire-Format

TCP payload =
DLL header(10 byte: start 0x0564 + len + ctl + dst LE + src LE + CRC LE)
+ 16-byte 블록마다 user data + LE CRC
↳ TL byte (1: FIN/FIR + SEQ 0..63)
↳ AL bytes:
byte 0 App Control (FIR/FIN/CON/UNS + SEQ 0..15)
byte 1 Function Code (1=READ, 5=DIRECT_OPERATE, 129=RESPONSE)
byte 2.. Object header (group + variation + qualifier) + range/data

CRC: DnpCrc.compute(data) — tabellenbasiert, Init 0, reflected 0xA6BC, abschließend ~crc, LE-Serialisierung in 2 Byte. Verifizierter Vektor: [05 64 05 C9 01 00 00 04] → CRC 0xE521 (LE 21 E5).


OPC-Registrierungsoptionen

FeldBedeutungStandard
opc_agent_ip / opc_agent_portOutstation-IP / Portbei Port 0 gilt 20000
options.master-addressDNP3-Master-DLL-Adresse1
options.outstation-addressOutstation-DLL-Adresse10
options.connect-timeoutTimeout für TCP-Connect (ms)3000
options.read-timeoutSO-Timeout für read (ms)5000

Tag-plc_address-Format

NotationBedeutung
g30v1.5Group 30 Var 1, Point 5 — Analog Input 32 Bit signed (with flag)
g30v5.0Analog Input 32-Bit-Float
g30v6.0Analog Input 64-Bit-Double
g1v2.0Binary Input 0 (with flag)
g20v1.032-Bit-Counter
g40v1.0Analog Output 32 Bit
class0Integrity Poll (G60V1) — Static + alle Klassen
class1 ~ class3Event Class Poll (G60V2/V3/V4)

Der Class Poll wird einmal ausgelöst und die Antwort anschließend zwischengespeichert (lastValueByKey). Ein nachfolgender Einzelpunkt-read liefert bei Cache-Treffer sofort das Ergebnis.

Write-Adresse (g12v1.N + Wert):

EingabewertCROB-Operation
Latch_On oder 1opType=3 (Latch_On), TCC=0
Latch_Off oder 0opType=4 (Latch_Off), TCC=0
Pulse_On:<onMs>:<offMs>:<count>opType=1
Close / TripTCC=1 (Close) / TCC=2 (Trip)

g41v1..g41v4 entsprechen jeweils Analog Output 32 Bit signed / 16 Bit signed / 32-Bit-Float / 64-Bit-Double.


Nicht unterstützte Bereiche

  • DNP3-SA (Secure Authentication, IEEE 1815-2012 §7).
  • Multi-Segment-TL-Antworten (derzeit nur Senden von Single-Segment FIR=FIN=1).
  • Asynchroner Empfang von Unsolicited Responses (FC 130) — Senden ist möglich, ein clientseitiger Unsolicited-Handler ist nicht implementiert.
  • File Transfer (FC 25-30), Time Sync (FC 23 DELAY_MEASURE ist nur als Konstante definiert).

Testabdeckung

test/java/plantpulse/driver/protocol/dnp3/

TestPrüfung
DnpCrcTestSpec-Vektor + CRC beliebiger Länge
DnpDataLinkTest10-Byte-Header + Block-CRC-Round-Trip
DnpTransportTestFIN/FIR/SEQ-Kodierung
DnpApplicationTest / DnpApplicationWriteTestREAD/DIRECT_OPERATE-Aufbau, IIN-Dekodierung
DnpObjectTest / DnpObjectWriteTestG1/G30/G40/G12V1/G41 Encoder/Decoder
DnpAddressTest / DnpAddressWriteTestAdressparser
DNP3DriverTestread/write Ende-zu-Ende mit Mock-Outstation
DnpSpecExtraTestzusätzliche Spec-Konformität

Hinweise

  • IEEE 1815-2012, "DNP3 Specification".
  • Code: plantpulse-edge-driver/src/plantpulse/driver/protocol/dnp3/.
  • Betrieb: Die Master-/Outstation-Adressen müssen mit der Outstation-Seite übereinstimmen. Bei Abweichung wird das Telegramm bereits im DLL-Header verworfen.