Rivian on FHIR®

Rivian on FHIR®
Section titled “Rivian on FHIR®”Good to know: Rivian is not an ISO-13485 compliant Medical Device
This is an example of the flexibility of Healthcare Standard, FHIR@ (Fast Healthcare Interoperability Resources) and how it could be used to onboard a Medical Device for something like a Patient Home Monitoring solution where the device emits metrics back to the hospital as observations for external care.
Now, for fun and little profit, lets augment the scenario above and use FHIR to Deliver a Rivian to a Driver, and have it send back metrics to the Plant after the vehicle has been entitled to its new owner.
FHIR® Resource Modeling
Section titled “FHIR® Resource Modeling”Though it may not be perfect, I think we can get this done with 5 FHIR Resource types.
| Medical Device Onboarding | Rivian Onboarding |
|---|---|
| Organization | Organization |
| Device | Device |
| DeviceMetric | DeviceMetric |
| Patient | Account |
| Observation | Observation |
Using clinFHIR, lets visualize our FHIR Resources and the relationships between them to model our payloads for the workload. The model the left is a somewhat accurate way to onboard a device for Remote Monitoring in a hospital, on the right, is how we would onboard the Rivian. represented in FSH (FHIR Shorthand) and visualized by gb2.
.png)
FHIR Resource Models
Now that we got things modeled, we are going to execute the workflow in two different parts. On boarding and Post Delivery Observation as a stateful API. The on boarding is done exactly once, the Post Delivery Observation posts continuously utilizing values from the on boarding process.
On boarding
Section titled “On boarding”On boarding is quite simple, the Organization (Rivian) builds the Device (R1S), formulates the Metrics (telemetry) and associates it to its Account to take home.
Lets look at the payloads of the FHIR resources adapted to this Scenario.
Organization Rivian Headquarters, where the whip rolled out of the plant.
{ "resourceType": "Organization", "id": "rivian_automotive", "name": "Rivian Automotive", "address": [ { "line": [ "100 N Rivian Motorway" ], "city": "Normal", "state": "IL", "postalCode": "61761", "country": "USA" } ],}Device The whip itself. R1S to be exact.
{ "resourceType": "Device", "id": "01-24926594", "manufacturer" : "Rivian Automotive", "identifier": [ { "system": "http://deezwatts.com/devices/vin/id", "value": "7PDSGABA90000000" } ], "name" : [{ "value" : "Deez Watts", "type" : "user-friendly-name" }], "modelNumber" : "r1s",}DeviceMeasurements These are the metric “thingers” the device is capturing and capable of publishing, think of these as an envelop to the metric, declaring the data type, labels, and all that stuff around the unit of measure.
{ "resourceType": "DeviceMetric", "id": "miles", "identifier": [ { "system": "http://deezwatts.com/devicemetric/id", "value": "milesmetric" } ], "type": { "coding": [ { "system": "urn:iso:std:iso:11073:10101", "code": "2000", "display": "MILES" } ] }, "unit": { "coding": [ { "system": "urn:iso:std:iso:11073:10101", "code": "262688", "display": "MILES_LEFT" } ] }, "source": { "reference": "Device/01-24926594" }, "parent": { "reference": "Device/01-24926594" }, "operationalStatus": "on", "color": "blue", "category": "measurement", "measurementPeriod": { "repeat": { "frequency": 1, "period": 1, "periodUnit": "s" } }}Account This is the owner of the vehicle, in this example myself.
{ "resourceType": "Account", "id": "02-f3939935-a667-4c22-9ddf-e84a5c2550ba-e48c09ce", "active": true, "name": [ { "use": "official", "family": "Sweeney", "given": [ "Ronald" ] } ], "gender": "male", "managingOrganization": { "reference": "Organization/rivian_automotive", "display": "Rivian Automotive" }}Now, lets post these to the server and have a look at the result.
You can do this in a bundle, or individually as resources, but here we are going to do it as individual resources to drive home the order of events, and we’ll use bundles for the next part of the workload.
Pay attention to the relationships built in the above payloads… cause its awesome.
{% hint style=“warning” %} UNDER CONSTRUCTION HERE
Post Delivery Observation
Section titled “Post Delivery Observation”So the above all happened and the Device (R1S) is now rolling all over the State of Michigan collecting and spewing forth Observations for remote monitoring. We’re going to poll the Rivian API for the data, and ship it to a FHIR Server.
We have a trusty technique for scheduling the workload found in the Data Access section of the data adventure, Ill go over it again, but make it dismissable with one of those collapsble thingies, but show the script in its entirety that gets the job done.
import timeimport uuidimport json
# Bundlefhir = {}fhir["type"] = "transaction"fhir["resourceType"] = "Bundle"fhir["entry"] = []
# For simplicity, these are the values of the associated resources we created in the previous step that associate the metrics in FHIR
whip_device_id =rivian_org_id = "rivian_automotive"person_customer_id =metricone =
# lets grab our metrics from the api
# Lets add the observation resources to the bundlewith open('affected_patients_missing_id_obs.csv') as f:
# Observation obsentry = {} obsentry["request"] = {} obsentry["resource"] = {} obsentry["request"]["method"] = "POST" obsentry["request"]["url"] = "Observation" obsentry["resource"]["resourceType"] = "Observation"
# Top Level obsentry["resource"]["status"] = "final" obsentry["resource"]["valueString"] = obsvaluestring
# basedOn obsentry["resource"]["basedOn"] = [ { 'reference': 'ServiceRequest/' + referralId, 'type': 'ServiceRequest' } ]
# subject obsentry["resource"]["subject"] = {} obsentry["resource"]["subject"]["reference"] = "Patient/" + data["personId"] obsentry["resource"]["subject"]["display"] = getnamefrompersonid(data["personId"])
# Add the Observation Resource Entries to the Bundle fhir["entry"].append(obsentry)
payload = fhir.dumps(fhir)Lets run it, if you are curious on we run python as kubernetes jobs, have a look at our foundational section, Data Access or the github repo associated with this post for clues.
Transaction Bundles Posting!
Lets have a look through the
Section titled “Lets have a look through the”I wrote this up initially for participants of the MIT Hack in 2022 as a simple of example of how to do exactly the above using FHIR, and provided a postman collection of sorts to back it. It fits nicely for those wanting to understand how slick and powerful relationships between FHIR resources are, and t