Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Current »

In this tutorial, we will cover transforming messages - in this case HL7v2 to JSON - but you can use the same transformation techniques when mapping data between any of the different types of node trees.

This tutorial will follow a simple repeatable pattern for getting started with any interface:

  1. Parsing the inbound HL7v2 messages.

  2. Filtering unwanted messages.

  3. Transforming the messages to JSON.

  4. Queueing messages for the downstream component.

Let’s build an HL7 to JSON component.

 STEP 1: On the Dashboard, create a custom component, call it "HL7 to JSON", and open the Translator

Create a Component using the Custom Component, call it HL7 to JSON.

In the component card, open the Translator by clicking Edit > Make a Copy and Edit.

 STEP 2: Add sample data to the project

Add Sample Data so we can leverage the Translator’s Auto-complete and the Annotations.

  • Iguana automatically passes the sample data to the main() function.

  • The message can be accessed using the Data parameter.

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
 STEP 3: Parse the inbound HL7 messages with hl7.parse

First, use hl7.parse to parse the HL7 message. In order to parse, we need to pass:

  • A vmd defining our expected inbound HL7 messages.

  • The data to be parsed.

Three values will be returned which we can use later on:

  • 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.

-- 1) Parse the inbound HL7 message
local msgIn, msgType, warnings = hl7.parse{vmd="hl7.vmd", data=Data}  

If a VMD isn't added to the project, you’ll see an “Unable to find…“ error in the Translator.

We must create a VMD to use for our sample message: See Creating a VMD and come back to finish the transformation tutorial.

 STEP 4: Filter unwanted messages

Now that we have our HL7 message parsed and identified, let’s create a filters.lua file to apply filtering rules on inbound messages.

We are going to

  1. First create a new file, call it filters and make sure it is a .lua file type. Use the technique from Filtering Messages to create a rule to filter out messages not identified as an ADTA01.

-- This module contains sample filtering rules.  
-- Use your own filter conditions and error messages.

local filter ={}

function filter.filterMessage(msgType) 
   if msgType ~= 'ADTA01' then
      iguana.logError('Unexpected message type.')
      return true
   end
   return false
end

return filter
  1. Call your filter.filterMessage function in main:

    • First assign the required filters.lua module to the variable filter so you can call it.

    • Use an if statement and the not operator to check the name of the message type. If the msgType is not equal to ADTA01, the filter function will return false and not continue executing the block of code.

local filter = require 'filters'

function main(Data)

   -- Parse the HL7 message
   local msg, msgType = hl7.parse{vmd='hl7.vmd', data=Data}
   
   -- Filter out unwanted messages
   if not filter.filterMessage(msgType) then  
      -- Transform the message to JSON     
      -- Write the data to a destination
   end
   
end

If you add additional sample data to the Translator, you can test to see how your interface reacts to different message types by viewing the annotations.

 STEP 5: Apply mappings to Transform the message

For the purpose of this tutorial we will perform some example mappings for a simple JSON object.

  1. Paste the following JSON template at the top outside of main to use as the outbound message schema:

local jsonTemplate = [[
{   
  "sendingFacility": "",
  "receivingFacility": "",
  "patientId": "",
  "firstName": "",
  "lastName": "",
  "birthdate": ""
}
]]

Now inside your filter if statement under the comment -- Transform the message to JSON, add the transformation logic:

  1. First, parse the JSON template so its ready to be populated with the HL7 data:

-- Transform the message to JSON 
local msgOut = json.parse{data=jsonTemplate}
  1. Create a mapADT.lua file to store your mapping functions. Its good practice to modularize mappings into separate functions for readability and future maintenance. Here we are going to split the mapping into functions for each HL7 segment.

local mapper = {}

-- Map the incoming data to the outgoing JSON
-- Organize mapping functions by HL7 segment 

function mapper.mapMSH(MSH, msgOut)
   msgOut.sendingFacility   = MSH[3][1]:nodeValue()
   msgOut.receivingFacility = MSH[6][1]:nodeValue()
   return msgOut
end 

function mapper.mapPID(PID, msgOut) 
   msgOut.patientId = PID[3][1]:nodeValue()
   msgOut.firstName = PID[5][2]:nodeValue()
   msgOut.lastName  = PID[5][1][1]:nodeValue()
   msgOut.birthdate = PID[7][1]:nodeValue()
   msgOut.race      = PID[10][1]:nodeValue()   
   return msgOut
end

return mapper

In this example, we are using simple assignment mapping, assigning values from the inbound HL7 message to the outbound JSON. There are many different strategies to map messages. Please see Mapping Messages for more strategies.

  1. Now call these mapper functions in main:

    • First assign the required mapADT.lua module to the variable mapper so you can call it.

    • Call each mapping function, passing the appropriate HL7 segments.

-- call mapping functions 
mapper.mapMSH(msg.MSH, msgOut)
mapper.mapPID(msg.PID, msgOut)

Use the annotations to see the results of your mappings. You can also use trace(msgOut) to view your JSON in the annotation window at any point during processing.

 STEP 6: Serialize and queue the translated JSON message

Use queue.push to send your JSON to a linked downstream component to send the data to its final destination system.

  • In order to push messages to the queue, the data must be a string. Therefore we can first serialize the JSON message using:

-- Serialize from node tree to JSON string
local msgOut = json.serialize{data=msgOut}

Your complete script should look as follows:

  • No labels