Health Level 7

HL7 stands for Health Level Seven, which is a standard for exchanging health information between medical applications. This standard defines a format for the transmission of health-related information, such as patient records, lab results, billing data, etc. Information sent using the HL7 standard is sent as a collection of one or more messages, each containing segments, fields, and sub-fields that have predefined meanings and formats.

HL7

Health Level Seven, which is a standard for exchanging health information between medical applications.

See also

Hl7 Summary

ADT

ADT stands for Admission, Discharge and Transfer, which are some of the common events that trigger HL7 messages. ADT messages are used to communicate basic patient information, visit information and patient state at a healthcare facility.

ADT-A01

Patient Admit/Visit Notification

ADT-A02

Patient Transfer Notification

ADT-A03

Patient Discharge/End Visit Notification

ADT-A04

Patient Registration

ADT-A05

Patient Pre-Admission

ADT-A06

Change an outpatient to an inpatient

ADT-A07

Change an inpatient to an outpatient

ADT-A08

Patient Information Update

ADT-A09

Tracks a patient’s movement within a facility.

ADT-A10

Tracks the arrival of a patient at a facility.

ADT-A11

Cancel Patient Admit Notification

ADT-A12

Cancel Patient Transfer Notification

ADT-A13

Cancel Patient Discharge/End Visit Notification

ADT-A14

Pending admission of a patient to a facility.

ADT-A15

Pending transfer of a patient.

ADT-A16

Pending discharge of a patient.

ADT-A40

Merge patient record.

ADT-A42

Merge patient visit.

MRN

Medical reference number

HL7 Integration

MEG provides an API for integrating with HL7 data sources. HL7Config defines an hl7 interface for an AuditForm. HL7 messages can be POSTed to /hl7/api/v1/message

curl -X POST localhost:8000/hl7/api/v1/message -H "Content-Type: application/json" -H "Authorization: Token 432079ad-4c89-478e-bccc-50500d8b1919" -d '{"message": "MSH|^~\\\\&|Company EHR|Company ABC|HIE Application|State HIE|20230704102554||ADT^A01^ADT_A01|1234567890|P|2.8.2\\rPID|1||123456789^^^MRN||Smith^John^A||19800101|M||2106-3^White^HL70005|123 Main St^^Anytown^NY^12345||(555)555-5555\\rPV1|1|I|ICU^A1^B1||||1111111111^Jones^Bob^M^^Dr.^MD^^NPI\\rZxx|1||Some custom data"}'

If the authentication token 432079ad-4c89-478e-bccc-50500d8b1919 matches a HL7Config the message data will be parsed and saved as an observation.

Note

The HL7 API acquires a lock on the AuditForm. This is to prevent race conditions. So no other request can modify the form while the request is being processed.

Complex integrations

If an integration involves more than one form, or message type, it is advisable to use HL7EntryPoint. It can route messages to many HL7Config from a single url endpoint. This means the mirth connect channel can be much simpler while all the complex message routing can be configured in MEG. The url contains the slug of the entrypoint model, providing improved traceability.

curl -X POST localhost:8000/hl7/api/v1/entrypoint/test-integration -H "Content-Type: application/json" -H "Authorization: Token 432079ad-4c89-478e-bccc-50500d8b1919" -d '{"message": "MSH|^~\\\\&|Company EHR|Company ABC|HIE Application|State HIE|20230704102554||ADT^A01^ADT_A01|1234567890|P|2.8.2\\rPID|1||123456789^^^MRN||Smith^John^A||19800101|M||2106-3^White^HL70005|123 Main St^^Anytown^NY^12345||(555)555-5555\\rPV1|1|I|ICU^A1^B1||||1111111111^Jones^Bob^M^^Dr.^MD^^NPI\\rZxx|1||Some custom data"}'

Message Parsing

The HL7FieldMapping model maps a CustomField to a HL7 message segment accessor. Using this field mapping logic observation data is extracted from the message. If the message doesn’t contain the accessor path defined in HL7FieldMapping then an exception is raised to sentry, but it doesn’t crash. This allows messages of varying types to be parsed by the same HL7Config.

Updating Observations

The default behavior is to create an observation for every message that’s POSTed to the endpoint. If you would like to update observations, HL7FieldMapping allows you to specify a field as unique in Django HL7 config Admin as a checkbox, which can be used to look up observations for updating.

Note

Observations are updated in a celery task. While updating, a lock is acquired on the observation to prevent race conditions in updating the observation.

If there are multiple observations with a value for the unique field, the first one created will be updated. The config field of HL7Config provides a way to filter for unique matches if there are multiple observations that may match the value of your unique field.

Example of filtering records for update when admission_date is null
{
    "observation_filters": {
        "field": "admission_date",
        "answer_operator": "is_null",
        "answer": true
    }
}

Nested filtering is also supported

{
    "observation_filters": {
        "operator": "and",
        "field": [
            {
                "answer_operator": "equal",
                "field": "field_1",
                "answer": "1"
            },
            {
                "operator": "or",
                "field": [
                    {
                        "answer_operator": "equal",
                        "field": "field_2",
                        "answer": "2"
                    },
                    {
                        "answer_operator": "equal",
                        "field": "field_3",
                        "answer": "3"
                    }
                ]
            }
        ]
    }
}

You can configure the HL7 integration to only update existing records and never create new ones.

Set update_only to true in the config field of HL7Config to prevent creating new observations
{
    "update_only": true
}

When update_only is enabled, the system will only update existing observations that match the unique field. If no matching observation is found, no new observation will be created and the system will return a 200 response.

You can configure the HL7 integration to set hardcoded values for specific message types.

An example of set_value where a patient discharge event is cancelled (ADT-A13).
{
    "set_value": {
        "discharge_date": null,
        "status": "Inpatient",
    }
}

Merging a patient record

The ADT-A40 message type represents a merged patient record. It identifies the old record id and the new one. Assuming a prior ADT-A01 or other demographic message was dispatched to record the new patient record, we can use ADT-A40 to unpublish the old one. We do this by creating a HL7Config to listen for the ADT-A40 and unpublish the record that matches the old record id.

Add the below condition to the Configuration JSON field in Django HL7 Admin config to unpublish existing records.
{
    "unpublish": true
}

Merging a patient visit via A40

Some systems don’t dispatch an ADT-A42 message to signify that a patient visit record should be merged. Instead they merge the patient record, the patient visits and then dispatch an ADT-A40. To handle this in MEG we need to merge all the patient visit records of the merged patient record. This requires some specific configuration on the HL7Config.

Add the below condition to the Configuration JSON field in Django HL7 Admin config to signify that many records must be updated by this configuration.
{
    "update_many": true,
    "unpublish": true
}

This HL7Config will listen for the ADT-A40 and unpublish all records that have been found that match the old record id.

If you need to move the patient visits to the merged MRN, this requires a different setup. In this case you need to query the patient visit records by one MRN and then update the MRN from another accessor:

A HL7FieldMapping queries by the mrn in MRG.1.1 and all patient records found will be moved to the MRN in PID.3.1.
{
    "update_many": true,
    "overwrite": {
        "mrn": "PID.3.1"
    }
}

Dynamically updating the ward

By default every form entry created or updated by HL7 is assigned the ward of the HL7Config. If you need this to be dynamically set based on content in the message, you need to configure the HL7Config to specify the field where the ward code is stored.

The HL7 API will look for a ward based on the value stored in PV1.3.4.
{
    "ward_accessor": "PV1.3.4",
}

If you have a Ward where the ward_number (code) field matches the value in the HL7 message located at the ward_accessor, then that Ward will be assigned to the form entry. This will also update the Ward of the AuditSession (provided there is only one form entry in the session, otherwise only the Ward of the form entry will be updated).

Testing HL7 Integration

mirth_connect_channels/meg-message-forwarder.xml is an example channel which is configured to POST HL7 messages to the aforementioned endpoint. This channel is configured to point at the HL7Config configuration generated by setupdatabase.sh.