Everything you never wanted to know about HL7, how to send it to MR, what HL7 fields MR expects data to be in, and how MR and MC can help you get it done.
This page assumes some familiarity with Mirth Connect.
Overview
- Mirth Connect receives HL7 messages
- MC runs those messages through a channel written for MR.
- That channel maps the HL7 message into a Mirth Results Clinical Document Model
- The Clinical Document Model is sent to Mirth Results. Under the hood this is a web service call, but MC can take advantage of a pre-built Mirth Results Client JAR.
- Mirth Results is able to process the Clinical Document Model and persist it in the database
- Mirth Results returns the set of identifiers it has for the patient given in the message. These include identifiers for each of the facilities designated to receive the message as well as the MPI.
The Channel
Mirth provides a Mirth Connect channel with Mirth Results to do the heavy lifting. You will want to know how to "read" this channel and understand its log entries.
Set the MC logging level
In any environment except production you will want to set the logging level for MC to WARN.
In Windows you can use the Server Manager. Go to the Server tab. Set the "Main Log Level" dropdown to "WARN". Restart the service.
In Linux edit $MIRTH_HOME/conf/log4jproperties . Set the "log4j.rootCategory" property to "WARN, stdout, fout"
Understanding the log messages from the channel
The channel will provide several informational and warning messages as it processes HL7 data.
This indicates that a field that is required for MR to properly persist data is not present or could not be interpreted. It tells you what the relevant object is, in this case NextOfKin. It also tells you which message segment it was in. NK10 means the first Nk1 segment.
If this error indicates a critical failure, typically when an Encounter (PV1) or Patient (PID) there will be an additional ERROR level message indicating its importance.
If this data is not important or there is an empty segment in the message you can usually ignore this warning.
If this data is important, you will want to review the message and the HL7 mapping and ensure that the data is in the right fields.
Unparsable date: '11111xxxxx200612131130', length: 22
Indicates that the channel was not able to parse the date. Consider reformatting or blanking out the date before the message is sent to this channel
(PD1.4) Attempted to parse XCN to a Provider object, but got an XCN segment with no ID type declaration. Expected 'upin', 'npi', or 'dea'! Proceeding with ID as generic source faciltiy ID.
HL7 sends provider information as an XCN or XPN. This is a set of HL7 fields that represent a provider and they include his name and identifier. If the identifier is untyped this warning is given. If the identifier is a generic ID, such as one given by an EMR or a hospital, this message can be ignored. If the identifier really is an npi, upin, or dea number you should check the message to ensure that the type is set properly and is in the right field.
Understanding how HL7 maps to fields in MR
The easiest way to see how HL7 maps into MR is to dive into the channel and take a look. Edit the channel and view the Source Transformer steps.
| Don't edit the transformer! Viewing the details of the channel is a good idea. Editing the channel can cause errors and makes support and upgrades for MR difficult. |
Each transformer steps generally maps to one type of object or category of data. For example the PRB segment maps to a Problem, the PID segment maps to a Patient, and so on.
Some example mappings:
patient.setId(getComponentValue('PID', 3, 1));
The Patient.Id field is pulled from PID.3.1. Simple.
patientName = generateNameModelFromXPN('PID', 5);
patient.setName(patientName);
So we're getting the Patient.Name from PID.5. To find out how the name should be arranged, we'll need to look at the "generateNameModelFromXPN" function in code templates.
function generateNameModelFromXPN(segment, id) {
...SNIP!...
newName.setLast(getComponentValue(segment, id, 1));
newName.setFirst(getComponentValue(segment, id, 2));
newName.setMiddle(getComponentValue(segment, id, 3));
..SNIP!...
So we get the last name from the first field. So if we pass PID.5 to this function the last name comes from PID.5.1.
Functions like this are used throughout the channel to capture names, coded elements, provider data, addresses, phone numbers, and other fields which are defined HL7 datatypes.
for each (diag in msg..DG1)
This is a clue that we're dealing with a segment that can repeat.
diagnosis.setActivityTime(getDateObject(getSegmentIndexComponentValue('DG1', 5, 1, diagCount)));
Getting a value from a repeating segment.
Gotchas
Note that an OBX segment can be used to represent either a vital sign or a lab result. The channel distinguishes these by the presence of an ORC and OBR segment. If those segments are present, and contain enough data to build out a lab order and an observation group (AKA lab panel) the OBXs following those segments are treated as lab results for that order. If there are loose OBX segments, or insufficient data for a lab order or observation group, the OBXs will be interpreted as vital signs.
Observations are written to be compliant to HL7 2.5 with backwards support for earlier versions. This makes the capture of specimen and timing information rather tricky. Where possible send HL7 v2.5 messages where these are broken out into segments rather than embedded in the OBX/OBR/ORC segments.
Adjusting incoming HL7 messages for the MR channel
The MR channel was written against the HL7 v2.5 specification and should be able to handle standard v2.5 messages. If the messages you are receiving from your sources do not exactly match the mappings in MR you will need to adjust those messages before sending it through the MR channel.
| Don't alter the MR channel! Do not edit the MR channel! Add a second channel to correct incoming messages and route them to the MR channel. Altering it will make support and upgrades difficult! |
The most common change that needs to be made is to alter MSH.4 and MSH.6 to have the correct source/receiver identifiers. These can be changed with a simple mapper or JavaScript step. Retrieve the message, alter it, and route it to the MR channel.


