All OpenMRS ID accounts have been reset.

Read more and change your password before signing in.
Icon

EXTENDED: OMRS14 Proposals due 30 April! Read more and submit a proposal at OpenMRS Talk.

Skip to end of metadata
Go to start of metadata

Definition

Health Level 7 (HL7) is an international standard for the transmission of medical data and the name of the organization responsible for maintaining and growing this standard (among other things).

HL7 in OpenMRS

Available Message Parsers

  • ORUR01Handler: Built into core
    • Does not support the entire r01 specification
    • See below for example messages
    • Used by the FormEntry Module to process Infopath forms (HTML Form Entry is not using HL7)
  • ADTA28: Built into core
    • (Link to page describing what is implemented)
  • (Link to other parsers developed by the community??)

Adding Custom Parsers

See Custom HL7 Handlers

Importing

Read about the HL7 Import Process.

Different options to get into that import process:

  1. Use the REST Module and its HL7 resource to post a message using curl or some other web service client.
  2. Posting an HL7 message to url /remotecommunication/postHl7.form will insert the message into the hl7 in queue.
    • username: username to authenticate and save the message with
    • password: password to authenticate and save the message with
    • source: Name of an HL7Source in the system (A "LOCAL" hl7 source is shipped by default with openmrs)
    • hl7Message: The hl7 message to save
    • (Note: This was broken in 1.5.0, fixed against in 1.5.1 and 1.6+)
  3. Using the API, a message can be parsed with Context.getHL7Service().parseHL7String(String) --> processHL7Message(Message);

There might be a www.mirthcorp.com-community-overview Mirth module that uses the Web Services to create data in openmrs. In this case, hl7 messages would be posted to the mirth server, mirth would parse them and create the objects in openmrs via the web services.

Example Observation (ORU^R01) Message

Sample Message:

Sample Acknowledgement:

MSH|^~\&|HL7LISTENER|AMRS|FORMENTRY|AMRS|20050217153200||ORU^R01^ACK|?|P|2.5
MSA|AR|AMRS20050217152845|
ERR||PID^1^3^^2|204|E

MSH (Message Header) Key:

MSH|^~\&|FORMENTRY|AMRS|HL7LISTENER|AMRS|20050217152845||ORU^R01|?|P|2.5|1||||||||||1^AMRS-ELDORET^http://schemas.openmrs.org/2006/FormEntry/formId^URI

  • MSH|
    Message type (message header) and next character is the field separator
  • ^~\&

    Encoding characters
    ^ ? component separator
    ~ ? repetition separator
    \ ? escape character
    & ? subcomponent separator

  • FORMENTRY|
    Sending Application
  • AMRS|
    Sending Facility
  • HL7LISTENER|
    Receiving Application
  • AMRS|
    Receiving Facility
  • 20050217152845|
    Date/Time of Message (YYYYMMDDHHMMSS)
  • Security (not necessary)
  • ORU^R01|
    Message Type (ORU = Unsolicited Transmisstion of an observation message

^ Event Type (R01 = Unsolicited Transmisstion of an observation message

  • AMRS20050217152845|
    Message Control ID (Unique identifier, RMRS uses sender + DT Stamp.. this is the "link" to the ACK, so we do need this)
  • P|
    Processing ID
  • 2.5|
    Version ID (HL7 version we're compliant with)
  • 1|
    Sequence Number (if we wanted to send a "batch" of these messages, we could append each encounter with a sequential number).. otherwise, always list 1.
  • Continuation Pointer (not necessary)
  • Accept Acknowledgement Type (not necessary)
  • Application Acknowledgement Type (not necessary)
  • Country Code (not necessary)
  • Character Set (not necesary)
  • Principal Language of Message (not necessary)
  • Alternate Character Set Handling Schema (not necessary)
  • 1^AMRS-ELDORET^http
    //schemas.openmrs.org/2006/FormEntry/formId^URI

    : Message Profile Identifier (1 = form.form_id)
    ^ Unique System ID
    ^ Namespace of assigning authority
    ^ Universal ID type

EVN (Event) Key (currently not implemented in OpenMRS):

EVN||20050221130000|||10^^^^^^^^^^9^M10^^AMRS

  • EVN|
    Message type (event)
  • Event Type Code
  • 20050221130000|
    Recorded Date/Time
  • Date/Time Planned Event
  • Event Reason Code
  • 10^^^^^^^^^^9^M10^^AMRS|
    Operator (10 = User ID (Erica))
    ^ Family Name
    ^ Given Name
    ^ Middle Name
    ^ Suffix
    ^ Prefix
    ^ Degree
    ^ Source Table
    ^ Assigning Authority
    ^ Name Type Code
    ^ Identifier Check Digit (9)
    ^ Check Digit Scheme (M10)
    ^ Identifier Type Code
    ^ Assigning Facility (AMRS)

PID (Patient Identification) Key:

PID|||1MT^0^M10||Patient^Jonny^Dee^DR|Patient^Momma^Thee^MS|20040101000000|M||B|555 Johnson Road^Apt. 555^Indianapolis^IN^46202^USA|||||||||||Indianapolis, IN|||||||||||||||||TRIBE CODE

  • PID|
    Message type (patient identification)
  • Set-ID (not necessary in our system.. we could represent multiple PIDs from different systems with multiple PID segments, one from each system with this)
  • Patient ID (older version of identifier representation.. no longer used commonly)
  • 1MT^0^M10|
    ID Number (1MT)
    ^ Check Digit (0)
    ^ Check Digit Scheme (M10)
    ^ Assigning Authority (hopefully won't have to use.. but if we need multiples)
    // a ~ would separate multiple occurrences of PIDs
  • Alternate Patient ID (older version of identifier representation.. no longer used commonly)
  • Patient^Jonny^Dee^^DR|
    Family Name (Patient)
    ^ Given Name (Jonny)
    ^ Second / Middle Name (Dee)
    ^ Suffix ()
    ^ Prefix (DR)
  • Patient^Momma^Thee^^MS|
    Mother's Maiden Family Name (Patient)
    ^ Given Name (Momma)
    ^ Second / Middle Name (Thee)
    ^ Suffix ()
    ^ Prefix (MS)
  • 20040101000000|
    Date/Time of Birth (YYYYMMDDHHMMSS)
    ^ Degree of Precision (for our purposes Y = estimated, and null = actual)
  • M|
    Administrative Sex (M) .. M, F, O, U, A, N possible answers
  • Patient Alias (older version.. no longer used commonly)
  • B|
    Race (B) .. I, A, B, W, N, O possible answers
  • 555 Johnson Road^Apt. 555^Indianapolis^IN^46202^USA|
    Street Address
    ^ Other Designation
    ^ City
    ^ State
    ^ Zip
  • Country Code (older version.. no longer used commonly)
  • Phone Number (Home)
  • Phone Number (Business)
  • Primary Language
  • Marital Status
  • Religion
  • SSN - Patient (older.. use PID-3 for this, store here for BW compat)
  • Driver's License Number - Patient (older.. use PID-3 for this, store here for BW compat)
  • Mother's Identifier
  • Ethnic Group
  • Indianapolis, IN|
    Birth Place
  • Multiple Birth Indicator
  • Birth Order
  • Citizenship
  • Veteran Military Status
  • Nationality
  • Patient Death Date and Time
  • Patient Death Indicator
  • Identity Unknown Indicator
  • Identity Reliability Code
  • Last Update Date/Time
  • Last Update Facility
  • Species Code
  • Breed Code
  • Strain
  • Production Class Code
  • Tribal Citizenship (here is where we can list the tribe.. it's loosely defined in HL7.. we could just send the code from our list with this)

PV1 (Patient Visit) Key:

PV1|1|O|^^^^^MTRH^1^AMRS|2|||1^Mamlin^Joseph^^^^^^^8^M10^^AMRS|||||||||||||||||||||||||||||||||||||20050217140000|||||||V

This message creates an encounter in OpenMRS. 

  • PV1|
    Message type (patient visit)
  • 1|
    Sub ID (1)
  • O|
    Patient Class (O = Outpatient)
  • ^^^^^^^^MTRH^1^AMRS|
    Assigned Patient Location (1=MTRH)
  • 2|
    Admission Type (2 = Return)
  • Preadmit Number
  • Prior Patient Location
  • 1^Mamlin^Joseph^^^^^^^^8^M10^^AMRS|
    Attending Doctor ID (1)
    ^ Family Name (Mamlin)
    ^ Given Name (Joseph)
    ^ Middle Name
    ^ Suffix
    ^ Prefix
    ^ Degree
    ^ Source Table
    ^ Assigning Authority
    ^ Name Type Code
    ^ Identifier Check Digit (8)
    ^ Check Digit Scheme (M10)
    ^ Identifier Type Code
    ^ Assigning Facility (AMRS)
  • Referring Doctor
  • Consulting Doctor
  • Hospital Service
  • Temporary Location
  • PreAdmit Test Indicator
  • ReAdmission Indicator
  • Admit Source
  • Ambulatory Status
  • VIP Indicator
  • Admitting Doctor
  • Patient Type
  • Visit Number
  • Financial Class
  • Charge Price Indicator
  • Courtesy Code
  • Credit Rating
  • Contract Code
  • Contract Effective Date
  • Contract Amount
  • Contract Period
  • Interest Code
  • Transfer to Bad Debt Code
  • Transfer to Bad Debt Date
  • Bad Debt Agency Code
  • Bad Debt Transfer Amount
  • Bad Debt Recovery Amount
  • Delete Account Indicator
  • Delete Account Date
  • Discharge Disposition
  • Discharge to Location
  • Diet Type
  • Servicing Facility
  • Bed Status
  • Account Status
  • Pending Location
  • Prior Temporary Location
  • 20050217140000|
    Admit Date/Time
  • Discharge Date/Time
  • Current patient balance
  • Total charges
  • Total adjustments
  • Total payments
  • Alternate visit ID
  • V
    Visit indicator (V = visit level, A = account level)

ORC (Common Order Segment):

ORC|RE||||||||20050221130000|1^Enterer^Ima^^^^^AMRS

NOTE: The optional ORC segment is used to transmit enterer and date-entered information in the message.

  • ORC|
    Message type (common order request)
  • RE|
    Order Control (RE = observations to follow)
  • Placer Order Number
  • Filler Order Number
  • Placer Group Number
  • Order Status
  • Response Flag
  • Quantity/Timing
  • Parent
  • 20050221130000|
    Date/Time of Transaction
  • 1^Enterer^Ima^^^^^^^^^^^AMRS
    Entered By ID (1)
    ^ Family Name (Enterer)
    ^ Given Name (Ima)
    ^ Middle Name
    ^ Suffix
    ^ Prefix
    ^ Degree
    ^ Source Table
    ^ Assigning Authority
    ^ Name Type Code
    ^ Identifier Check Digit
    ^ Check Digit Scheme
    ^ Identifier Type Code
    ^ Assigning Facility (AMRS)

OBR (Observation Request) Key:

OBR|1|||1238^MEDICAL RECORD OBSERVATIONS^DCT|

  • OBR|
    Message type (observation request)
  • 1|
    Set ID (1) .. sequential number given to each subsequent OBR.
  • Placer Order Number
  • Filler Order Number
  • 1238^MEDICAL RECORD OBSERVATIONS^DCT|
    Identifier (1238)
    ^ Text (MEDICAL RECORD OBSERVATIONS)
    ^ Name of Coding System (DCT)
  • Priority
  • Requested Date/Time
  • Observation Date/Time (We could list this for posterity's sake, but it's unneeded if you think about it.. as each OBX has it's datetime. RG doesn't typically fill this.

OBX / CE (Observation Result, Coded Datatype) Key:

OBX||CE|1082^REVIEW OF SYSTEMS, CENTRAL NERVOUS SYSTEM^DCT||207^DEPRESSION^DCT||||||F|||20050217204000

  • OBX|
    Message type
  • 1|
    Set ID .. sequential number given to each subsequent OBX within the series.
  • CE|
    Coded datatype
  • 1082^REVIEW OF SYSTEMS, CENTRAL NERVOUS SYSTEM^DCT|
    Concept ID (1082)
    ^ Text Description (REVIEW OF SYSTEMS)
    ^ Name of Coding System (DCT)
  • Sub-ID
  • 207^DEPRESSION^DCT|
    Concept ID (207)
    ^ Text Description (DEPRESSION)
    ^ Name of Coding System (DCT)
  • Units
  • References Range
  • Abnormal Flags
  • Probability
  • Nature of Abnormal Test
  • Observation Result Status
  • Effective Date
  • User Defined Access Checks
  • 20050217204000|
    Date/Time of Observation

OBX / SN (Observation Result, Structured Numeric Datatype) Key:

OBX|2|SN|5497^CD4 COUNT^DCT||<^10|cells/mm3|10-1500|L|||F|||20050217204000

  • OBX|
    Message type
  • 2|
    Set ID ... sequential number given to each subsequent OBX within the series.
  • SN|
    Coded datatype
  • 5497^CD4 COUNT^DCT|
    Concept ID (5497)
    ^ Text Description (CD4 COUNT)
    ^ Name of Coding System (DCT)
  • Sub-ID
  • <^10|
    Comparator (<)
    ^ Value 1 (10)
  • cells/mm3|
    Units
  • 10-1500|
    References Range
  • L|
    Abnormal Flags (we can decide if we want to use this one)
  • Probability
  • Nature of Abnormal Test
  • Observation Result Status
  • Effective Date
  • User Defined Access Checks
  • 20050217204000|
    Date/Time of Observation

OBX / NM (Observation Result, Numeric Datatype) Key:

OBX|3|NM|5089^WEIGHT (KG)^DCT||25|kg|20-300|L|||F|||20050217204000

  • OBX|
    Message type
  • 3|
    Set ID ... sequential number given to each subsequent OBX within the series.
  • NM|
    Coded datatype
  • 5089^WEIGHT (KG)^DCT|
    Concept ID (5089)
    ^ Text Description (WEIGHT (KG))
    ^ Name of Coding System (DCT)
  • Sub-ID
  • 25|
    Value (25)
  • kg|
    Units
  • 20-300|
    References Range
  • L|
    Abnormal Flags (we can decide if we want to use this one)
  • Probability
  • Nature of Abnormal Test
  • Observation Result Status
  • Effective Date
  • User Defined Access Checks
  • 20050217204000|
    Date/Time of Observation

OBX / NM (Observation Result, Timestamp Datatype) Key:

OBX|4|TS|1191^HISTORICAL DRUG STOP DATE^DCT||20050101||||||F|||20050217204000

  • OBX|
    Message type
  • 4|
    Set ID ... sequential number given to each subsequent OBX within the series.
  • TS|
    Timestamp datatype
  • 1191^HISTORICAL DRUG STOP DATE^DCT|
    Concept ID (1191)

^ Text Description (HISTORICAL DRUG STOP DATE)

^ Name of Coding System (DCT)

  • Sub-ID
  • 20050101|
    DateTime could be of the form (YYYYMMDD) or (YYYYMMDDHHMMSS)
  • Units
  • References Range
  • L|
    Abnormal Flags (we can decide if we want to use this one)
  • Probability
  • Nature of Abnormal Test
  • Observation Result Status
  • Effective Date
  • User Defined Access Checks
  • 20050217204000|
    Date/Time of Observation

MSA (Message Acknowledgement) Key:

MSA|AR|AMRS20050217152845|

  • MSA|
    Message Header (Acknowledgement Segment)
  • AR|
    Acknowledgement Code (AR)

HL7 Table 0008 has the list of possible values, but in our case, we only care about 3 (I think):

  • AA = Application Accept
  • AE = Application Error
  • AR = Application Reject

In this case, the message notes that this message was rejected, b/c the MRN had an invalid check digit.

  • AMRS20050217152845|
    Message Control ID (this comes from the MSH segment Control-ID and provides the linkage)

ERR (Error Segment) Key:

This segment is used to add specific error comments to acknowledgement messages:

ERR||PID^1^3^^2|204|E

  • ERR|
    Message type (error segment)
  • Error Code and Location (no longer commonly used/deprecated)
  • PID^1^3^^2|
    Error Location Segment ID (PID)
    ^ Segment Sequence (1)
    ^ Field Position (3)
    ^ Field Repetition
    ^ Component Number (2)
    ^ Subcomponent Number

(in this example.. patient has an incorrect check digit.. it should be '0' (smile) )

  • 204|
    HL7 Error Code (204)

HL7 Table 0357 lists the possible codes, 204 is "unknown key identifier"

  • E|
    Severity (E)

W = Warning, I = Information, E = Error

Example of Grouped Observations

Here's an example of what where we're headed for grouped observations (see COMPLETE BLOOD COUNT below). To be valid HL7, the enterer and datetime for data entry either need to move from the ORC to OBR segments or the ORC needs to be repeated for each OBR. --Burke 12:24, 9 August 2006 (EDT)

Other Examples

To successfully process a ADT_A28 message is required specified within the PID-3 segment the (HD)> <assigning Authority>, in this case "Old Identification Number"

ADT_A28
ORU_R01

Resources

1 Comment

  1. Edit: I was asked to change it in the wiki so the ADT28 message reflects now my solution below.

    Some issue I encountered during the patient creation using the ADT28 message above (after adjusting the header to my installation, dropping the PV, GT sections) was that the patient creation silently failed. I solved this problem by adding a third ^ to the corresponding segment in the PID block.

    Perhaps the given ADT28 message indicates the "Old Identification Number" as a validation scheme instead of the assigning authority.

     

    My final ADT28 message that creates a patient looks as follows (red text shows the fields that I changed for my setting):

    MSH|^~\&|FORMENTRY|ChariteSAP|HL7LISTENER|LOCAL|20091123101300^0|HUP|ADT^A28^ADT_A05|9166768|P|2.5|1|||AL||ASCII

    EVN|A28|20091123101300|||1

    PID|||1338^^^Old Identification Number||Patient^Demo^OldId||20011114|M|||20371^02^2400^724||||||724^Y||||||02|||11|20371|724^DEUT^N||N