std.hl7 — HL7 v2 Messaging

Vier Units für HL7 Version 2 — der im Gesundheitswesen meistverbreitete Nachrichtenstandard. std.hl7 deckt den gesamten Stack ab: MLLP-TCP-Framing, MSH/ACK-Engine, Patientenverwaltung (ADT), Auftragswesen (ORM/OML) und Befundübermittlung (ORU/OUL).

Übersicht · Standard Library · Welche Unit?


Units

Unit WP Beschreibung
std.hl7.core WP-HL7-00 MLLP-Framing (VT+FS+CR), MSH-Parser, ACK-Generator, Duplikatserkennung (FNV1a-Ring), Versions- und Testmodus-Prüfung
std.hl7.adt WP-HL7-01 Patient Administration: ADTAxx parsen/schreiben; PID, PV1, MRG, NK1; automatische Merge-Erkennung (A34–A45)
std.hl7.orders WP-HL7-02 Order Management: ORMO01, OMLO21, RASO17 parsen/schreiben; ORC, OBR, RXA; STAT-Erkennung; ORRO02/ORLO22-Quittung
std.hl7.results WP-HL7-03 Result Reporting: ORUR01, OULR22 parsen/schreiben; OBX (Panikwert- und Korrektur-Flags), NTE-Kommentare

Alle Units importieren std.hl7.core.


Was ist HL7 v2?

HL7 (Health Level 7) Version 2 ist der faktische Standard für Datenintegration in Krankenhäusern. Jede Nachricht besteht aus zeilentrennend (CR) geschriebenen Segmenten (3 Großbuchstaben + |), die wiederum |-getrennte Felder und ^-getrennte Komponenten enthalten:

MSH|^~\&|LIS|HOSPITAL|HIS||20260616083000||ORU^R01|MSG001|P|2.5.1
PID|||PAT123^^^MPI||Muster^Max||19850315|M
OBR|1|ORD042|LAB042|1743-4^Glucose^LN|||20260616082000
OBX|1|NM|1743-4^Glucose^LN||195|mg/dL|70-99||||HH||F

Die Standard-Trennzeichen sind: Feld: |, Komponente: ^, Wiederholung: ~, Escape: \\, Subkomponente: &.


MLLP-Framing

HL7 v2-Nachrichten werden über TCP immer im MLLP-Frame übertragen (Minimal Lower Layer Protocol):

[VT=0x0B] + HL7-Nachrichtenbytes + [FS=0x1C] + [CR=0x0D]

MllpFrameWrite legt den Rahmen um eine fertige HL7-Nachricht; MllpFrameRead extrahiert die Nachricht aus dem TCP-Empfangspuffer.


Designprinzipien

  • Zero-Copy-Parsing: Alle Parse-Funktionen speichern Zeiger in den Originalnachrichtenpuffer — keine String-Kopien. Der Puffer muss während der Struct-Verwendung gültig bleiben.
  • Caller alloziert: Alle Structs (MSH, PID, PV1, ADT, Order, Report, OBX) werden vom Caller alloziert. Größenkonstanten (HL7_*_SIZE) geben die benötigte Byte-Anzahl.
  • Kein rekursiver Besitz: Eine geparste ORU-Nachricht enthält einen Befundkopf (Hl7OruParse) — die einzelnen OBX-Segmente müssen getrennt über Hl7ObxParse in Schleife geparst werden.
  • Implizite Typprüfung: HL7_ORD_ISSTAT und HL7_OBX_ISCRIT/HL7_OBX_ISCORR werden automatisch gesetzt — keine manuellen String-Vergleiche nötig.

Nachrichtenflüsse

Patientenaufnahme (ADT)

HIS/ADT-System          HL7-Gateway / Lyx
    |                        |
    |-- ADT^A01 (Aufnahme) -->|  Hl7AdtParse()
    |<-- ACK^AA (Quittung) --|  Hl7AckWrite() + MllpFrameWrite()
    |                        |
    |-- ADT^A08 (Update) --->|  Hl7AdtParse()
    |<-- ACK^AA -------------|
    |                        |
    |-- ADT^A03 (Entlassung)->|  Hl7AdtParse()
    |<-- ACK^AA -------------|

Laborauftrag und Befund (ORM → ORU)

KIS / Station           LIS (Labor)
    |                        |
    |-- ORM^O01 (Auftrag) -->|  Hl7OrmParse()
    |<-- ORR^O02 (OK/ER) ----|  Hl7OrrWrite()
    |                        |  [Analyse läuft ...]
    |<-- ORU^R01 (Befund) ---|  Hl7OruWrite() + Hl7ObxParse()
    |-- ACK^AA -------------->|

Medikamentengabe (RAS)

Medikamentensystem      Stationssystem
    |                        |
    |-- RAS^O17 ------------>|  Hl7RasParse()
    |<-- ACK^AA -------------|


Struct-Größentabelle

Struct Konstante Bytes Zweck
Hl7Msh HL7_MSH_SIZE 192 MSH-Header einer beliebigen Nachricht
Hl7State HL7_STATE_SIZE 8448 Dedup-State (16 Partner × 528 Bytes)
Hl7Pid HL7_PID_SIZE 176 Patient Identification
Hl7Pv1 HL7_PV1_SIZE 160 Patient Visit / Stationsbelegung
Hl7Mrg HL7_MRG_SIZE 48 Patient Merge
Hl7Nk1 HL7_NK1_SIZE 48 Next of Kin / Angehörige
Hl7Adt HL7_ADT_SIZE 544 Vollständige ADT-Nachricht (PID+PV1+MRG+NK1)
Hl7Order HL7_ORD_SIZE 192 Auftragsstruktur (ORC+OBR+PID+PV1)
Hl7RxAdmin HL7_RXA_SIZE 112 Medikamentengabe (RXA)
Hl7ObxResult HL7_OBX_SIZE 144 Einzelbeobachtung mit Panikwert-Flag
Hl7NteNote HL7_NTE_SIZE 16 Kommentar (NTE)
Hl7Report HL7_RPT_SIZE 104 Befundkopf (OBR+PID ohne OBX)

Quickstart

import std.hl7.core;
import std.hl7.adt;
import std.alloc;

fn main(): int64 {
    // Dedup-State initialisieren (einmalig pro Server-Instanz)
    var state: int64 := alloc(HL7_STATE_SIZE);
    Hl7StateInit(state);

    // Aus TCP-Empfangspuffer: MLLP-Frame lesen
    var tcpBuf: int64 := alloc(65536);
    var msgBuf: int64 := alloc(65536);
    // ... tcpBuf aus Socket befüllen ...
    var msgLen: int64 := MllpFrameRead(tcpBuf, tcpBufLen, msgBuf, 65536);
    if (msgLen < 0) { return 1; }

    // MSH parsen
    var msh: int64 := alloc(HL7_MSH_SIZE);
    if (Hl7MshParse(msgBuf, msgLen, msh) != HL7_OK) {
        free(msh, HL7_MSH_SIZE);
        return 1;
    }

    // ADT-Nachricht vollständig parsen
    var adt: int64 := alloc(HL7_ADT_SIZE);
    Hl7AdtParse(msgBuf, msgLen, adt);

    var pid1: int64 := peek64(adt + HL7_ADT_PID + HL7_PID_ID1);
    var bed:  int64 := peek64(adt + HL7_ADT_PV1 + HL7_PV1_LBED);

    // ACK zurücksenden
    var ackBuf: int64 := alloc(512);
    var ackLen: int64 := Hl7AckWrite(msh, "AA"c as int64, "OK"c as int64, ackBuf, 512);
    var outBuf: int64 := alloc(600);
    MllpFrameWrite(outBuf, 600, ackBuf, ackLen);

    free(outBuf, 600);
    free(ackBuf, 512);
    free(adt, HL7_ADT_SIZE);
    free(msh, HL7_MSH_SIZE);
    free(msgBuf, 65536);
    free(tcpBuf, 65536);
    free(state, HL7_STATE_SIZE);
    return 0;
}


Letzte Aktualisierung: 2026-06-16