====== 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). → [[lyx_-_programmiersprache:start|Übersicht]] · [[lyx_-_programmiersprache:units|Standard Library]] · [[lyx_-_programmiersprache:guides:welche-unit|Welche Unit?]] ---- ===== Units ===== ^ Unit ^ WP ^ Beschreibung ^ | [[lyx_-_programmiersprache:units:hl7:core|std.hl7.core]] | WP-HL7-00 | MLLP-Framing (VT+FS+CR), MSH-Parser, ACK-Generator, Duplikatserkennung (FNV1a-Ring), Versions- und Testmodus-Prüfung | | [[lyx_-_programmiersprache:units:hl7:adt|std.hl7.adt]] | WP-HL7-01 | Patient Administration: ADT^Axx parsen/schreiben; PID, PV1, MRG, NK1; automatische Merge-Erkennung (A34–A45) | | [[lyx_-_programmiersprache:units:hl7:orders|std.hl7.orders]] | WP-HL7-02 | Order Management: ORM^O01, OML^O21, RAS^O17 parsen/schreiben; ORC, OBR, RXA; STAT-Erkennung; ORR^O02/ORL^O22-Quittung | | [[lyx_-_programmiersprache:units:hl7:results|std.hl7.results]] | WP-HL7-03 | Result Reporting: ORU^R01, OUL^R22 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