# WebSocket

### Server

`ws://localhost:63336/`

### Channel

{% hint style="info" %}
There is only one channel you can subscribe to: **`v3/Observation`**
{% endhint %}

The Channel `v3/Observation` provides [Observation resources](http://hl7.org/fhir/STU3/observation.html) as defined in the **FHIR STU3** release in real time.

Here are two examples of payload you can retrieve from this channel.&#x20;

{% tabs %}
{% tab title="Simple" %}

```javascript

{
  "category": [
    {
      "coding": [
        {
          "code": "vital-signs",
          "display": "Vital Signs",
          "system": "http://hl7.org/fhir/observation-category"
        }
      ],
      "text": "Vital Signs"
    }
  ],
  "code": {
    "coding": [
      {
        "code": "8310-5",
        "display": "body_temperature",
        "system": "http://loinc.org"
      }
    ],
    "text": "Température"
  },
  "context": {
    "reference": "863b08e6-601e-48ce-b71c-728421e16b95"
  },
  "device": {
    "display": "thermometer",
    "reference": "5d1a2fefa37f4d0017966643"
  },
  "effectiveDateTime": "2019-12-10T14:08:48.645Z",
  "resourceType": "observation",
  "status": "final",
  "valueQuantity": {
    "code": "C",
    "system": "http://unitsofmeasure.org",
    "unit": "C",
    "value": 41.6
  }
}
```

{% endtab %}

{% tab title="Composed" %}

```javascript
{
  "category": [
    {
      "coding": [
        {
          "code": "vital-signs",
          "display": "Vital Signs",
          "system": "http://hl7.org/fhir/observation-category"
        }
      ],
      "text": "Vital Signs"
    }
  ],
  "code": {
    "coding": [
      {
        "code": "blood_pressure",
        "display": "blood_pressure",
        "system": "http://loinc.org"
      }
    ],
    "text": "blood_pressure"
  },
  "component": [
    {
      "code": {
        "coding": [
          {
            "code": "8480-6",
            "display": "systolic_blood_pressure",
            "system": "http://loinc.org"
          }
        ]
      },
      "valueQuantity": {
        "system": "http://unitsofmeasure.org",
        "unit": "mmHg",
        "value": 141
      }
    },
    {
      "code": {
        "coding": [
          {
            "code": "8462-4",
            "display": "diastolic_blood_pressure",
            "system": "http://loinc.org"
          }
        ]
      },
      "valueQuantity": {
        "system": "http://unitsofmeasure.org",
        "unit": "mmHg",
        "value": 83
      }
    },
    {
      "code": {
        "coding": [
          {
            "code": "8867-4",
            "display": "heart_rate",
            "system": "http://loinc.org"
          }
        ]
      },
      "valueQuantity": {
        "system": "http://unitsofmeasure.org",
        "unit": "bpm",
        "value": 75
      }
    }
  ],
  "context": {
    "reference": "08281fa8-d8f2-4cac-b46b-d9cd951058e9"
  },
  "device": {
    "display": "blood_pressure_monitor",
    "reference": "5c98c120184d54001718d5ce"
  },
  "effectiveDateTime": "2019-12-10T17:24:04.227Z",
  "resourceType": "Observation",
  "status": "final"
}
```

{% endtab %}

{% tab title="" %}

```
```

{% endtab %}
{% endtabs %}

Depending on the device you are using the observation can look a bit different:

* **simple:** When you use a simple device like a weight scale or a thermometer for instance, you will get only one simple measurement attached to the observation (e.g. weight for the scale or temperature for the thermometer).\
  Therefore you can directly access the measurement in the `valueQuantity` property.
* **composed:** When you use a pulse oximeter or a blood pressure monitor for instance, you will get two or three different kinds of measurements (e.g. heart rate and spO2 for the pulse oximeter or systolic, diastolic blood pressure for the blood pressure monitor). \
  Therefore the measurements are gathered in the `component` property.

For more details on how to retrieve information from the payload please refer to the schema section.

### Schema

Measurements use the [Observation schema](http://hl7.org/fhir/STU3/observation.html#resource) as defined in the FHIR STU3 release:

```javascript
{
  "resourceType" : "Observation",
  // from Resource: id, meta, implicitRules, and language
  // from DomainResource: text, contained, extension, and modifierExtension
  "identifier" : [{ Identifier }], // Business Identifier for observation
  "basedOn" : [{ Reference(CarePlan|DeviceRequest|ImmunizationRecommendation|
   MedicationRequest|NutritionOrder|ProcedureRequest|ReferralRequest) }], // Fulfills plan, proposal or order
  "status" : "<code>", // R!  registered | preliminary | final | amended +
  "category" : [{ CodeableConcept }], // Classification of  type of observation
  "code" : { CodeableConcept }, // R!  Type of observation (code / type)
  "subject" : { Reference(Patient|Group|Device|Location) }, // Who and/or what this is about
  "context" : { Reference(Encounter|EpisodeOfCare) }, // Healthcare event during which this observation is made
  // effective[x]: Clinically relevant time/time-period for observation. One of these 2:
  "effectiveDateTime" : "<dateTime>",
  "effectivePeriod" : { Period },
  "issued" : "<instant>", // Date/Time this was made available
  "performer" : [{ Reference(Practitioner|Organization|Patient|RelatedPerson) }], // Who is responsible for the observation
  // value[x]: Actual result. One of these 11:
  "valueQuantity" : { Quantity },
  "valueCodeableConcept" : { CodeableConcept },
  "valueString" : "<string>",
  "valueBoolean" : <boolean>,
  "valueRange" : { Range },
  "valueRatio" : { Ratio },
  "valueSampledData" : { SampledData },
  "valueAttachment" : { Attachment },
  "valueTime" : "<time>",
  "valueDateTime" : "<dateTime>",
  "valuePeriod" : { Period },
  "dataAbsentReason" : { CodeableConcept }, // C? Why the result is missing
  "interpretation" : { CodeableConcept }, // High, low, normal, etc.
  "comment" : "<string>", // Comments about result
  "bodySite" : { CodeableConcept }, // Observed body part
  "method" : { CodeableConcept }, // How it was done
  "specimen" : { Reference(Specimen) }, // Specimen used for this observation
  "device" : { Reference(Device|DeviceMetric) }, // (Measurement) Device
  "referenceRange" : [{ // Provides guide for interpretation
    "low" : { Quantity(SimpleQuantity) }, // C? Low Range, if relevant
    "high" : { Quantity(SimpleQuantity) }, // C? High Range, if relevant
    "type" : { CodeableConcept }, // Reference range qualifier
    "appliesTo" : [{ CodeableConcept }], // Reference range population
    "age" : { Range }, // Applicable age range, if relevant
    "text" : "<string>" // Text based reference range in an observation
  }],
  "related" : [{ // Resource related to this observation
    "type" : "<code>", // has-member | derived-from | sequel-to | replaces | qualified-by | interfered-by
    "target" : { Reference(Observation|QuestionnaireResponse|Sequence) } // R!  Resource that is related to this one
  }],
  "component" : [{ // Component results
    "code" : { CodeableConcept }, // R!  Type of component observation (code / type)
    // value[x]: Actual component result. One of these 10:
    "valueQuantity" : { Quantity },
    "valueCodeableConcept" : { CodeableConcept },
    "valueString" : "<string>",
    "valueRange" : { Range },
    "valueRatio" : { Ratio },
    "valueSampledData" : { SampledData },
    "valueAttachment" : { Attachment },
    "valueTime" : "<time>",
    "valueDateTime" : "<dateTime>",
    "valuePeriod" : { Period },
    "dataAbsentReason" : { CodeableConcept }, // C? Why the component result is missing
    "interpretation" : { CodeableConcept }, // High, low, normal, etc.
    "referenceRange" : [{ Content as for Observation.referenceRange }] // Provides guide for interpretation of component result
  }]
}
```

Here are some of the noticeable properties:

| property                 | description                                                                                                                                    |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| **valueQuantity**        |                                                                                                                                                |
| **valueQuantity.system** | <p>defines the system defining the previous code</p><p><em>i.e.</em> <a href="https://loinc.org/8310-5/"><em><https://loinc.org/></em></a></p> |
| **valueQuantity.unit**   | <p>defines the unit in which the quantity is expressed </p><p><em>i.e. C for a body temperature</em></p>                                       |
| **valueQuantity.value**  | <p>defines the actual value of the quantity<br><em>i.e. 37 for a body temperature</em></p>                                                     |
| **device**               |                                                                                                                                                |
| **device.reference**     | <p>defines the id of the device used to take the measurement</p><p><em>i.e. 5d1a2fefa37f4d0017966643</em></p>                                  |
| **device.display**       | <p>defines the type of device used to take the measurement</p><p><em>i.e. thermometer</em></p>                                                 |
| **effectiveDateTime**    | <p>represents the time at which the measurement was taken</p><p>i.e.  2019-12-10T14:08:48.645Z</p>                                             |
| **code**                 |                                                                                                                                                |
| **code.coding**          | describes what the measure is and how we can reference it in a specific system.                                                                |
| **code.coding.code**     | <p>describes the code used to define the measurement</p><p><em>i.e. 8310-5</em></p>                                                            |
| **code.coding.system**   | <p>defines the system related to the code</p><p>i.e. <http://loinc.org></p>                                                                    |
| **code.coding.display**  | a human readable version of the code                                                                                                           |

### Receiving events from Kligo

Here is an example for listening to Observation using a simple web socket javascript client:

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const ws = new WebSocket("ws://localhost:63336/v3/Observation");

ws.onopen = function open() {
  console.log("opened");
  setConnected(true);
};
ws.onclose = function close() {
  console.log("closed");
  setConnected(false);
};

ws.onmessage = function data(event) {
  const observation = JSON.parse(event.data);
  console.log(observation);
};
```

{% endtab %}
{% endtabs %}

A working version of this example can be found [here](https://codesandbox.io/s/fhir-socket-b6kec).
