Medical device workflow are rich and complex. This design attempts to factor the domain into a minimal set of components that can be combined to produce useful systems. It's self-consciously naïve, but it should serve as a seed for discussion.
-
Any device can be online all the time, and can act as a FHIR server -- possible all on its own, or possibly with the help of a proxy/manager/facade component that "fronts for" the device. (Communication between the device and its manager occurs using any mechanism necessary; but the components below be useful for such internal communication, too.)
-
A device generates snapshot (i.e. point-in-time) reports -- which can consist of observations or alerts.
-
A device exposes a collection of individual "settings" that can be directly manipulated by authorized clients.
Device
: as-is in FHIR, describes a specific instance of a device. For example:
{
resourceType: 'Device',
type: {
code: [{
system: 'http://carefusion.com/',
code: 'alaris-pulse-ox'
}]
},
identifier: {
system: 'http://carefusion.com/serial-number/',
value: '75023658923523'
},
location: 'Location/medical_ward_5'
}
DeviceSystem
resource: provides a detailed layout of the components of a device system. Specifically in IHE PCD terms, this describes a tree structure of device, virtualdevices, channels, and metrics. Within this tree, every node has a unique identifier (which can, if desired, be expressed as a PCD-like path). For example:
{
resourceType: 'DeviceSystem',
device: 'Device/pulse_ox_unit_8273513',
virtualDevice: [{
identifier: 'vd1',
channel: [{
identifier: 'vd1/ch1',
metric: [{
identifier: 'vd1/ch1/metric183'
}]
}]
}, {
identifier: 'vd2',
channel: [{
identifier: 'vd2/ch1',
metric: [{
identifier: 'vd2/ch1/metric387'
}]
}]
}]
}
Any given device has a collection of associated DeviceSetting
resources that describe the current state of configurable settings. Each DeviceSetting
represent a single state for a device configuration setting. For example, "the SpO2 alarm threshold" for a specific pulse oximeter. These settings are fully qualified by device and (as needed) path within the virtual device system:
{
resourceType: 'DeviceSetting',
device: 'Device/pulse_ox_unit_8273513',
component: 'vd1/ch1/metric138', # <-- virtualdevice, channel or message id in Device/123
name: {
system: 'http://carefusion.com/alaris-pulse-ox',
code: 'spo2_alarm_threshold'
},
allowedValueRange: {
low: {value: 20, unit '%'},
high:{value: 99, unit'%'}
},
valueQuantity: { # <-- This is the only part a client can change
value: 64,
unit: '%'
}
}
In general, an authorized user can update a DeviceSetting
via HTTP PUT
-- but only the value
portion is allowed to change.
A DeviceObservationReport
captures the complete details of a point-in-time observation report. It contains a set of observations, each associated with a specific component metric. Would consider flattening the structure so the entire hierarchy isn't recapitulated from DeviceSystem
:
{
resource: 'DeviceObservationReport',
device: 'Device/pulse_ox_unit_8273513',
observation: [{
component: 'vd1/ch1/metric138', # <-- virtualdevice, channel or message id in Device/123
observation: 'Observation/123' # <-- e.g. about Patient: "has SpO2 = 82%"
}]
}
A DeviceAlertReport
captures the complete details of a point-in-time device alert. This includes details about what alerts are active and why. A report is explicitly generated, and multiple reports can be generated by the same device in sequence. So a report is not a "singleton"; a whole stream, or feed, of alerts would emerge from a device. It's possible that the leaf-level alert details should be Observation
(Which is how IHE does it in v2) -- I'm not sure.
Importantly: when possible, if an alert is
- triggered by a
DeviceSetting
(e.g. SpO2 threshold underrun), or - can be disabled by a `DeviceSetting (e.g. "Alarm is buzzing --> false")
then these links should be conveyed here. So right next to the fact that "the alarm is beeping" there's a reference to the settings that allow a client to change that state -- e.g. to change the threshold or simply silence the alarm.
{
resource: 'DeviceAlertReport',
device: 'Device/pulse_ox_unit_8273513',
alert: [{
component: 'vd1/ch1/metric138',# <-- virtualdevice, channel or message id in Device/123
observation: 'Observation/456', # <-- e.g. about device: "is currently beeping"
wasTriggeredBy: 'DeviceSetting/3897535', # <-- the "SpO2 threshold = 82%" setting
canDisableWith: 'DeviceSetting/9385372' # <-- the "alarm status" setting
}]
}
So a client could GET /DeviceSetting/3897535
, discover the valid settings, and turn the alarm off via HTTP PUT
.