Working with HL7
- Aryn Wiebe
HL7 v2 is the most widely used data standard in the healthcare industry. But not all systems and devices use the same version and can have customizations. Thats where HL7 filtering and mapping becomes essential.
Creating HL7 interfaces in Iguana follows a simple repeatable pattern:
Parsing the inbound HL7 messages.
Filtering unwanted messages.
Mapping (translating) or transforming the messages.
Queueing messages for the downstream component.
Let’s build an HL7 Mapping component.
Create a Component using the Custom Component, call it Working with HL7.
In the component card, open the Translator by clicking Edit > Make a Copy and Edit.
So we can leverage the Translator’s Auto-complete and the Annotations, let’s add this sample HL7 ADT^A01 message:
MSH|^~\&|MESA_ADT|XYZ_ADMITTING|iFW|ZYX_HOSPITAL|||ADT^A01|103102|P|2.4||||||||
EVN||200007010800||||200007010800
PID|||583295^^^ADT1||DOE^JANE||19610615|M||2106-3|123 MAIN STREET ^^GREENSBORO^NC^27401-1020|GL|(919)379-1212|(919)271-3434~(919)277-3114||S||PATID12345001^2^M10|123456789|9-87654^NC
NK1|1|BATES^RONALD^L|SPO|||||20011105
PV1||E||||||5101^NELL^FREDERICK^P^^DR|||||||||||V1295^^^ADT1|||||||||||||||||||||||||200007010800||||||||
PV2|||^ABDOMINAL PAIN
OBX|1|HD|SR Instance UID||1.123456.2.2000.31.2.1||||||F||||||
AL1|1||^PENICILLIN||PRODUCES HIVES~RASH
AL1|2||^CAT DANDER
DG1|001|I9|1550|MAL NEO LIVER, PRIMARY|19880501103005|F||
PR1|2234|M11|111^CODE151|COMMON PROCEDURES|198809081123
ROL|45^RECORDER^ROLE MASTER LIST|AD|CP|KATE^SMITH^ELLEN|199505011201
GT1|1122|1519|BILL^GATES^A
IN1|001|A357|1234|BCMD|||||132987
IN2|ID1551001|SSN12345678
First, use hl7.parse{}
to parse the HL7 message so we can break it down and get it ready to transform
local msg, name, warning = hl7.parse{vmd="hl7.vmd", data=Data}
In order to parse an HL7 message, you need to pass a vmd and the data to be parsed. Review Creating a VMD to create a VMD for this tutorial.
hl7.parse{}
returns three values:
The parsed message as an HL7 node tree.
The name of the HL7 message type as defined in the VMD - we can use this in our next step to apply filtering rules based on message type.
Data integrity warnings for missing message segments or fields expected.
If you are applying multiple filtering rules on inbound messages, it is best to create modularize your script and call a filter function you define - see Filtering Messages.
For this example, we will simply use conditional logic to skip any messages not of the type “ADTA01“.
-- filter unwanted messages
if name ~= "ADTA01" then
-- Skip processing if the message type is not ADT^A01
return
end
To test this, we can use the sample data and annotations to view our filtering logic. First, create a Catchall Message Definition to catch all other messages that do not match “ADTA01“.
Open your VMD file and create a Message Definition called “Catchall“.
Add it to the Matching Rules - use the asterisks
*
to match all other messages that do not match ADTA01.
Add this ORM^O01 message to your sample data and view the results:
See Mapping Messages for common mapping methodologies.
Make sure you toggle back to your first sample message (ADT^A01) that does not get filtered out to leverage the annotations and autocomplete when building the mappings!
We’ll cover a few of these in this tutorial:
Hardcoded simple assignment: Map the given name to 'James'.
Map the last name to use lowercase and then capitalize the last name 'Doe'.
Trim white space from the street address to remove unwanted white space from the right side.
Import the Codemap Library and create a codeSet of Sending Applications to map.
Your mappings should look like this (note the results in the annotations):