Getting Started Integrate Your Devices Tracking Patient Care Using FHIR®

Tracking Patient Care Using FHIR®

40 minutes

A Bluetooth oximeter measures oxygen saturation, critical in monitoring newborn babies since low oxygen saturation can be a sign of a congenital heart defect. A smart device using an app called Health@Home can configure a FHIR Observation resource and send it into InterSystems IRIS for Health™ for processing. In this exercise, you will modify an existing FHIR® server to monitor incoming FHIR data from a smart device connected to a Bluetooth oximeter. This exercise simulates the output of this application through a rudimentary front-end application that sends the equivalent FHIR resource.

InterSystems IRIS for Health acts as a decision support tool, sending an HL7 v2 scheduling request to an application to schedule a follow-up appointment to screen for heart defects if the oxygen levels fall beneath a certain level.

The application receiving this request is part of a legacy hospital system that still operates using the HL7 v2.3 messaging protocol, so it cannot receive a FHIR resource directly. Using InterSystems IRIS for Health, you will construct an HL7 v2.3 scheduling message (SIU_S12) and send it on to this scheduling system.

If you would like to view the incoming JSON payload representing the FHIR Observation resource, open test_data.json. This exercise will only be dealing with a subsection of this message representing the actual value of the observation, which looks like this:

"subject": {
      "reference": "Patient/example"
"effectiveDateTime": "2014-12-05T09:30:10+01:00",
"valueQuantity": {
      "value": 95,
      "unit": "%",
      "system": "",
      "code": "%"

As you can see, the measure of oxygen saturation can be found in the value attribute of the valueQuantity field. For the purpose of simplicity, this exercise does not include steps to link an incoming observation resource to a patient record, substituting Patient/example instead. A real implementation would need to link incoming resources to an existing patient record before it could send a useful message to the scheduling application.

Throughout this exercise, if you would like to see what the finished application looks like, just navigate to Interoperability > List > Productions and open Solution.FoundationProduction.

For a visual overview of this exercise and more details about the rationale behind the steps, watch this video:



It is recommended that you use the InterSystems IRIS for Health development sandbox for this exercise. However, if you would prefer to do it locally, you can use a preconfigured Docker image by cloning the GitHub repository. Instructions for each path are below.

InterSystems IRIS Sandbox

  1. Change the directory: cd /home/project/shared
  2. Type git clone
  3. Change the directory: cd Samples-FHIR-Oximeter-Devices
  4. Open the web terminal by navigating to InterSystems > Web Terminal and enter the login credentials provided with your sandbox.
  5. At the command prompt, type do $system.OBJ.Load("/home/project/shared/Samples-FHIR-Oximeter-Devices/Setup.cls","ck")
  6. Once that completes, type do ##class(Setup).setUpLearningLab(). Note that this step will take a while, as it is creating and installing a FHIR server.
  7. Open the Management Portal by clicking the Management Portal link in your sandbox.
  8. Change the namespace to R4FHIRNAMESPACE.



  1. Install Docker Desktop.
  2. Type git clone
  3. Change the directory: cd Samples-FHIR-Oximeter-Devices
  4. In the command line, type docker-compose up -d
  5. Throughout the exercise, use the following connection settings:
    • Username: SuperUser
    • Password: SYS
    • Host: localhost
    • Port: 52773
  6. Open the Management Portal by navigating to http://localhost:52773/csp/sys/UtilHome.csp.
  7. Change the namespace to R4FHIRNAMESPACE.

Creating the Outgoing HL7 Message

Before implementing FHIR resource processing, we first need to configure the message type of the outgoing HL7 message that will be sent to the downstream scheduling application. This will involve configuring an outbound operation that will send the data.

  1. Creating the To_Scheduling Operation
    1. Start by viewing the existing production that is handling FHIR REST requests. A production is an instance of the InterSystems IRIS for Health interoperability engine. It has three components:
      • Business services: responsible for receiving incoming messages from external applications
      • Business processes: handle incoming messages and apply rules and transformations, then decide where to send them
      • Business operations: send the messages to external systems downstream
    2. Navigate to Interoperability > List > Production and open Demo.FoundationProduction. If you are doing this exercise using a Docker container, you will have to start the production by clicking the Start button; otherwise, the production should already be running.
      Note that HS.FHIRServer.Interop.Service receives incoming REST requests and passes them onto Demo.FHIRBPL, the business process that you will be completing in this exercise. This process passes requests onto HS.FHIRServer.Interop.Operation, which communicates to the underlying FHIR server and then returns the response message to the upstream components.
    3. Create an additional business process to communicate to the external scheduling application in case a follow-up appointment is needed. Click the plus sign under operations in the R4FHIRNAMESPACE production.
    4. InterSystems IRIS for Health has built-in components that allow you to quickly connect to HL7 v2 systems. In this example, you will create a component that takes a message and writes it to a file. Select HL7 Output and File, and then fill in the following settings:
      • HL7 Operation Name: To_Scheduling
      • Enable Now: checked
      • File Path: /home/project/shared/Samples-FHIR-Oximeter-Devices/Out/

      It should look like this:
      Business Operation Wizard creating To_Scheduling

Updating the Business Process to Check Oxygen Levels

In this section, you will update the existing business process for this production to check oxygen saturation levels. A BPL business process is a graphical tool used in designing decision logic that processes incoming messages in InterSystems IRIS for Health. In this exercise, we have already created a stump BPL that takes in a FHIR request and forwards it onto a FHIR operation for processing. This allows normal REST operations to flow through the production unencumbered.

This BPL has also has implemented some ObjectScript code, the native programming language built into InterSystems IRIS for Health. This code unpacks the FHIR payload from the incoming request and exposes the oxygen saturation value in a locally accessible variable named context.O2Sat.

  1. Check the O2 Values and Call To_Scheduling
    1. Open the Demo.FHIRBPL business process by navigating to Home > Interoperability > List > Business Processes > Demo.FHIRBPL and clicking Open. To start, you will add decision logic to this BPL to interpret the value of the oxygen saturation and decide whether or not to send a scheduling request for a follow-up appointment. While keeping the Code activity selected, add an if activity (Add Activity > If).
    2. Call it Check O2 Levels and set the Condition field to the following: context.O2Sat && (context.O2Sat < 90)
      This will first check that the context.O2Sat variable is defined. Recall that any FHIR resource with any HTTP method can pass through this production. The code block activity above filters out irrelevant messages and only sets the context.O2Sat variable if the FHIR resource type and method are correct.
    3. The if activity will also return false if the oxygen saturation from the incoming FHIR resource is greater than 90%.
    4. The if activity automatically comes with a join activity as well as a true arrow. The true arrow leads to the series of activities to perform should the condition field in the if activity returns true. While selecting the true line, add a Transform activity. Call it Transform to Send and set Data Transformation Class to Demo.FromFhirObsToSIUS12, a data transformation built into this exercise. You can explore this data transformation by clicking DTL Editor.
      1. Since our data transformation does not need to access anything about the incoming FHIR message, we will set the Source field to any property, as it will not be used. In this case, set it to context. In a real application, this source field would likely reference the FHIR resource so that the data transformation could access its properties quickly. However, in this exercise, we are not including this step.
      2. Set the Target field to context.Schedule, a local variable, so that we can store the HL7 message before sending it.
        The settings for your Transform activity should look like this:
        Settings for Transform Activity in BPL
    5. Since these activities happen only when oxygen saturation is lower than 90%, the process should call the To_Scheduling operation to send the HL7 message you just created to the hospital’s scheduling system. With the Transform to Send activity still selected, add a call activity (Add Activity > Call).
      1. Name it To Scheduling Service.
      2. Set Target to To_Scheduling, the name of the business operation we created earlier.
      3. Set Request Message Class to EnsLib.HL7.Message, and click Request Builder to open it. The Request Builder closely resembles the data transformation wizard, as both are graphical tools for instantiating and populating message objects using the properties of the local process context.
      4. In the request builder interface, drag the Schedule field (in the context section of the Source message) over to the callrequest field in the Target message. This will set the request message to the value of the context.Schedule property that you set in the data transformation.
      5. Click OK.
        Your request builder should look like this:
        Request Builder for BPL
    6. Returning to the Business Process Designer, drag an additional line from the if activity to the triangular join activity to set the path, should the condition in the if clause be false. This tells the process to do nothing at all before the true and false paths converge in the join activity.
    7. Click Compile.
      Your business process should look like this:
      Completed Business Process

Test Your Production

In this step, you will use a rudimentary front-end web application to send observation resources into the production you created. Depending on the oxygen levels recorded in the outgoing message, your service will either send the message to a scheduling service or simply log them in your database.

  1. Send a request
    1. In the IDE, navigate to /shared/Samples-FHIR-Oximeter. Right-click app.html and select Open With > Preview.
    2. Fill in Username, Password, and Server Details with the connection details of your instance.
      1. If you are using an InterSystems IRIS sandbox, this information can be found on your launcher page. For Server Details, use the Atelier Server Address provided.
      2. If you are using a Docker container supplied with the GitHub repository, set the Server Details field to localhost:52773 and clear the Send Over SLL check box.
    3. If not already done, set Base FHIR Path to /csp/healthshare/fhirnamespace/fhir/r4/Observation. This is the REST endpoint that receives FHIR Observation resources. A POST request carrying a JSON payload will create a new observation in the FHIR resource repository.
    4. Use the slider on the top to adjust the oxygen saturation, and send a few test messages by clicking the Send button at the bottom of the page.
    5. The To_Scheduling operation you set earlier will write a file to the /Out directory when oxygen levels fall below 90%.
  2. (Optional) View the Message Trace
    1. Navigate to the message view: Home > Interoperability > View > Messages.
    2. Select the most recent message, click the Trace tab, and then click View full trace. As you can see, this trace shows the journey of the FHIR resource through the production. The production message does not carry the FHIR payload directly, instead storing a reference to it in memory. For this reason, the trace message includes only the wrapper class instantiated to pass it through the production, not the actual FHIR data.
      Message Trace Viewer