I spent a couple hours with my new friend, ChatGPT and "We" came up with the following routine as a starting point for HL7 to FHIR conversion. I had to teach it my formatting style of spelled out mixed case commands. At first it got the $Piece command numbering incorrect, starting at "0" instead of "1". I taught it that and it thanked me for catching that. Made me feel a little needed. It also initially wrote the routine to call from the top; we corrected that.
HL7FHIRAI ; HL7 v2.x → FHIR Bundle Converter
Quit ; prevent accidental execution if called with Do ^HL7FHIRAI
; --- Test driver ---
Test
New HL7MSG,OUTJSON
; Example HL7 message segments
Set HL7MSG(1)="MSH|^~\&|LABSYS|LAB|EHR|HOSP|202501011200||ADT^A01|123456|P|2.3"
Set HL7MSG(2)="PID|1||12345^^^HOSP^MR||Doe^Jane||19851105|F|||123 Main St^^Metropolis^NY^10001||555-1234"
Set HL7MSG(3)="PV1|1|I|2000^2012^01||||1234^Smith^John|||||||||||98765"
Set HL7MSG(4)="OBX|1|NM|GLUCOSE^GLU||120|mg/dL|70-110|H|||F"
Do Convert(.HL7MSG,.OUTJSON)
Write !,"--- FHIR Bundle JSON Output ---",!
Write OUTJSON,!
Quit
; --- Main converter ---
Convert(HL7MSG,OUTJSON)
New FS,CS,RS,EC,SS,SEG,I,TYPE,ENTRY,IDX
Set FS="|"
Set CS=$Extract(HL7MSG(1),5)
Set RS=$Extract(HL7MSG(1),6)
Set EC=$Extract(HL7MSG(1),7)
Set SS=$Extract(HL7MSG(1),8)
Set OUTJSON="{""resourceType"":""Bundle"",""type"":""collection"",""entry"":["
Set IDX=0
For I=1:1 Quit:'$Data(HL7MSG(I)) Do
. Set SEG=HL7MSG(I)
. Set TYPE=$Piece(SEG,FS,1)
. Set ENTRY=""
. Do Dispatch(TYPE,SEG,.ENTRY,FS,RS,CS,SS)
. If ENTRY'="" Do
. . If IDX>0 Set OUTJSON=OUTJSON_","
. . Set OUTJSON=OUTJSON_"{""resource"":"_ENTRY_"}"
. . Set IDX=IDX+1
Set OUTJSON=OUTJSON_"]}"
Quit
; --- Dispatcher ---
Dispatch(TYPE,SEG,OUT,FS,RS,CS,SS)
If TYPE="PID" Do PID(.OUT,SEG,FS,RS,CS,SS) Quit
If TYPE="PV1" Do PV1(.OUT,SEG,FS,RS,CS,SS) Quit
If TYPE="OBX" Do OBX(.OUT,SEG,FS,RS,CS,SS) Quit
Quit
; --- Patient (PID → Patient) ---
PID(OUT,SEG,FS,RS,CS,SS)
New NAME,FAMILY,GIVEN,BIRTH,GENDER
Set NAME=$$FldOne(5,SEG,FS,RS,CS,SS)
Set FAMILY=$Piece(NAME,CS,1)
Set GIVEN=$Piece(NAME,CS,2)
Set BIRTH=$$FldOne(7,SEG,FS,RS,CS,SS)
If $Length(BIRTH)=8 Set BIRTH=$Extract(BIRTH,1,4)_"-"_$Extract(BIRTH,5,6)_"-"_$Extract(BIRTH,7,8)
Set GENDER=$$FldOne(8,SEG,FS,RS,CS,SS)
If GENDER="M" Set GENDER="male"
If GENDER="F" Set GENDER="female"
If GENDER="O" Set GENDER="other"
If GENDER="U" Set GENDER="unknown"
Set OUT="{""resourceType"":""Patient"",""identifier"":[{""value"":"""_$$FldOne(3,SEG,FS,RS,CS,SS)_"""}],""name"":[{""family"":"""_FAMILY_""",""given"":["""_GIVEN_"""]}],""birthDate"":"""_BIRTH_""",""gender"":"""_GENDER_"""}"
Quit
; --- Encounter (PV1 → Encounter) ---
PV1(OUT,SEG,FS,RS,CS,SS)
New VISITNO,CLASSTYP
Set CLASSTYP=$$FldOne(2,SEG,FS,RS,CS,SS)
Set VISITNO=$$FldOne(19,SEG,FS,RS,CS,SS)
Set OUT="{""resourceType"":""Encounter"",""identifier"":[{""value"":"""_VISITNO_"""}],""class"":{""code"":"""_CLASSTYP_"""}}"
Quit
; --- Observation (OBX → Observation) ---
OBX(OUT,SEG,FS,RS,CS,SS)
New ID,VAL,UNIT
Set ID=$$FldOne(3,SEG,FS,RS,CS,SS)
Set VAL=$$FldOne(5,SEG,FS,RS,CS,SS)
Set UNIT=$$FldOne(6,SEG,FS,RS,CS,SS)
Set OUT="{""resourceType"":""Observation"",""code"":{""text"":"""_ID_"""},"
Set OUT=OUT_"""valueQuantity"":{""value"":"""_VAL_""",""unit"":"""_UNIT_"""}}"
Quit
; --- Helpers ---
Fld(N,SEG,OUT,FS,RS,CS,SS)
New FIELD,I
Kill OUT
Set FIELD=$Piece(SEG,FS,N+1)
For I=1:1:$Length(FIELD,RS) Set OUT(I)=$Piece(FIELD,RS,I)
Quit
FldOne(N,SEG,FS,RS,CS,SS)
Quit $Piece(SEG,FS,N+1)