DEV Community

vitagroup HIP for vitagroup HIP

Posted on • Edited on

Part 2: Creating a Patient and Encounter from the HIS via HL7v2

Series by Stefan Spiska, Senior Backend Developer, PEN, vitagroup HIP

Part 2 of the series "Vendor neutral interoperability with openEHR and HL7 FHIR"

The first step in integration is typically patient onboarding. In most hospital settings, when a patient is created in the Hospital Information System (HIS), other systems within the hospital are notified by sending an HL7 v2 ADT message, such as the following:

MSH|^~\&|MIRTH|MIRTH_CONNECT|HIS001|MIRTH_CONNECT|20231010121200||ADT^A01|MSG0000001|P|2.3|||NE|NE|CO|8859/1|ES-CO
PID|||6537077^^^^CC||Smith^John||19860705|M
PV1||I|||||||||||||||||22cce64c-8ea1-4ac9-8974-163087171c85
Enter fullscreen mode Exit fullscreen mode

HL7 v2 defines a set of structured messages, each consisting of different segments separated by line breaks. Each segment is made up of fields separated by a pipe (|), which can be further divided into components (^) and subcomponents (&).

Common HL7 v2 Segments

  • MSH (Message Header): Contains metadata about the message.
  • PID (Patient Identification): Holds patient demographic details.
  • PV1 (Patient Visit): Captures information about the patient's hospital encounter.

Example Breakdown

  • MSH-9 (ADT^A01): Message type ADT (Admission, Discharge, Transfer) Admit/Visit Notification.
  • PID-5 (Smith^John): Patient Name.
  • ** - PID-5.1 (Smith): Family Name.
  • ** - PID-5.2 (John): Given Name.

When a patient is admitted, an HL7 ADT (Admission, Discharge, Transfer) message is generated by the Hospital Information System (HIS), to inform 3rd party systems in the hospital. The HIP HL7v2 Connector receives the HL7v2 mesages and forwards them towards HIP.

Convert HL7v2 to a FHIR Patient and a FHIR Encounter

PSLP - Protocol Specific Path Language

To facilitate data mapping between different formats, vitagroup developed PSPL (Protocol Specific Path Language) - a path based navigation and extraction language.

With PSPL, integration experts can define mappings between various data formats. Elements are identified using expressions similar to XPath or FHIRPath. The language supports operations such as traversal, selection, and filtering of hierarchical data models.

Using PSPL, we can define mappings:

  • The Patient Identification (PID) segment to a FHIR Patient resource
  • The Patient Visit (PV1) segment to a FHIR Encounter resource

Defining a Trigger Condition

Before applying mappings, we must define when they should be triggered. The following condition ensures that the mapping applies to any incoming message of type "ADT^A01" (Admit/Visit notification), as specified in the message header:

"createConditions": [
      {
        "condition" : "MSH.9",
        "anyExpectedValue" : [
          "ADT^A01"
        ]
      }
    ]
Enter fullscreen mode Exit fullscreen mode

Mapping an HL7 v2 PID segment to a FHIR Patient resource

Next, we define a mapping between an HL7 v2.3 PID segment and an HL7 FHIR R4 Patient resource:

"sourceProtocol": "HL7v2",
    "sourceProtocolVersions": [
      "2.3"
    ],
    "sourceType": "PID",
    "storageProtocol": "FHIR",
    "storageProtocolVersion": "R4",
    "storageType": "Patient",
Enter fullscreen mode Exit fullscreen mode

A series of mappings between segments and elements is then applied. The snippet below maps PID.5.1 (Family Name) to FHIR Patient’s name.family:

      {
        "storageClass": "String",
        "storagePath": "name[isList: true].family",
        "attributes": {
          "value": {
            "type": "rw",
            "sourcePath": "PID.5.1",
            "dataType": "String"
          }
        }
      }
Enter fullscreen mode Exit fullscreen mode

The function isList: true ensures that the name element is represented as a JSON array instead of a single JSON object.

Resulting FHIR Patient Resource

Thus for the incoming Hl7 v2 message we create a Patient resource as follows:

{
  "resourceType": "Patient",
  "name": [
    {
      "family": "Smith",
      "given": [
        "John"
      ]
    }
  ]
...  
}
Enter fullscreen mode Exit fullscreen mode

Mapping an HL7 v2 PV1 segment to a FHIR Encounter resource

Some transformations require additional logic. For instance, when creating an Encounter from the PV1 (Patient Visit) segment, PV1-2 contains Patient Class (Inpatient, Emergency, etc.). Since PV1-2 uses a HL7 v2 value set, it must be translated into the corresponding FHIR value set (FHIR Encounter Class ValueSet).

See the following Transformation definition:

{
...
  "definition": {
    "sourceProtocol": "HL7v2",
    "sourceProtocolVersions": [
      "2.3"
    ],
    "sourceType": "PV1",
    "storageProtocol": "FHIR",
    "storageProtocolVersion": "R4",
    "storageType": "Encounter",
    "transformations": [
      {
        "storageClass": "String",
        "storagePath": "class.code",
        "attributes": {
          "value": {
            "type": "rw",
            "sourcePath": "PV1.2[convert: '\"E\" -> \"EMER\"; \"I\" -> \"IMP\"; \"O\" -> \"AMB\"; \"P\" -> \"PRENC\";']",
            "dataType": "String"
          }
        }
      },
      {
        "storageClass": "String",
        "storagePath": "class.system",
        "attributes": {
          "value": {
            "type": "static",
            "sourcePath": "",
            "staticValue": "http://terminology.hl7.org/CodeSystem/v3-ActCode"
          }
        },
        "conditions": [
          {
            "sourcePath": "PV1.2",
            "anyExpectedValue": [
             "E","I","O","P"
           ]  
          }
        ]
      }
   ...   
    ],
...
    "createConditions": [
      {
        "condition" : "MSH.9",
        "anyExpectedValue" : [
          "ADT^A01"
        ]
      }
    ]
  }
}


Enter fullscreen mode Exit fullscreen mode

Explanation of transformations

  1. convert function:
  • Maps HL7 v2 PV1-2 codes (E, I, O, P) to the FHIR equivalent values (EMER, IMP, AMB, PRENC).
  1. Static mapping for terminology system:

As a Result we get a correct Fhir Fhir coding:

"class" : [{
    "coding" : [{
      "system" : "http://terminology.hl7.org/CodeSystem/v3-ActCode",
      "code" : "IMP"
    }]
  }]
Enter fullscreen mode Exit fullscreen mode

For more complex scenarios a FHIR terminology service and concept maps can be used.

Linking the FHIR Encounter to the FHIR Patient

All that left is to connect the Patient and Encounter resource. With the following mapping we ensure that the created Encounter references the create Patient as subject.

{
...
  "definition": {
    "sourceProtocol": "HL7v2",
    "sourceProtocolVersions": [
      "2.3"
    ],
    "sourceType": "PV1",
    "storageProtocol": "FHIR",
    "storageProtocolVersion": "R4",
    "storageType": "Encounter",
    "transformations": [
      {
        "storageClass": "String",
        "storagePath": "subject.reference",
        "attributes": {
          "value": {
            "type": "rw",
            "sourcePath": "PID.3.1[isIdValue: 'Patient']",
            "dataType": "String"
          }
        }
      }      
   ...   
    ],
...
    "createConditions": [
      {
        "condition" : "MSH.9",
        "anyExpectedValue" : [
          "ADT^A01"
        ]
      }
    ]
  }
}

Enter fullscreen mode Exit fullscreen mode

Final Workflow

Now, whenever an HL7 ADT message arrives at HIP, the defined mappings are triggered, and the HIP-Bridge executes the following actions:

  • Create a FHIR Patient Resource and a FHIR Encounter from the HL7 ADT message
  • Links the Encounter to the Patient
  • Stores Encounter and Patient in the FHIR-Store.
  • Should storing fail because the validation does not pass or any other error, a transaction rollback is conducted across all services to ensure data integrity.

Hot sauce if you're wrong - web dev trivia for staff engineers

Hot sauce if you're wrong · web dev trivia for staff engineers (Chris vs Jeremy, Leet Heat S1.E4)

  • Shipping Fast: Test your knowledge of deployment strategies and techniques
  • Authentication: Prove you know your OAuth from your JWT
  • CSS: Demonstrate your styling expertise under pressure
  • Acronyms: Decode the alphabet soup of web development
  • Accessibility: Show your commitment to building for everyone

Contestants must answer rapid-fire questions across the full stack of modern web development. Get it right, earn points. Get it wrong? The spice level goes up!

Watch Video 🌶️🔥

Top comments (0)

👋 Kindness is contagious

If you found this post useful, please drop a ❤️ or leave a kind comment!

Okay