Stream: hapi
Topic: Chaining multi-level+Remote patient monitoring
Dexter (Dec 22 2020 at 08:13):
TL;DR
Is there a query that can directly return me the practitioners and the careteam, given device ID?
I've been working on a small learning goal, so that I can better accustom myself with FHIR.
The idea is, there's a bunch of devices that are with a patient, and the device
is associated with a patient. Now, when a certain patient-limit is exceeded for a patient reading, I need to send notifications to practitioners in the patient's careteam
.
What I did is, when I get a message from a device through a webhook callback, I lookup the FHIR device that has the device identifier, grab the patient ID, and then get the careteam
and practitioner
s in there. Once I have that, I am able to run some code that handles notifications (I fetch the practitioners, from the careteam too, since I store the notification IDs in the Practitioner.identifier
).
Now, for some of the questions I have.
- Is there a query that can directly return me the practitioners and the careteam, given device ID? I'm currently making 3 hops (
device
->careteam
(usingdevice.patientid
) ->practitioner
s). I plan to use a bundle so that I can get this all in a single API call, but wanted to know if there was a better way - I am storing the patent's limits in the device assigned to them as extensions, is that okay?
- I also need to update the code to facilitate preferences for
careteam
notifications, in the sense that when a measurement is out of bounds, I must send notif to only those practitioners in thiscareteam
that haveyes
stored somewhere. Where do I store this preference? I was thinking perhaps as abase64
string under thecareteam
as an extension, so that I need only fetch thepractitioner
s that have yes stored here.
Vibin_chander (Dec 22 2020 at 09:57):
Im having some same problem but with different use-case. I used the _include & _revinclude to solve them
Vibin_chander (Dec 22 2020 at 09:58):
Can you also try using _include or _revinclude search param?
Vibin_chander (Dec 22 2020 at 09:59):
But using these param too im unable to fetch more than 2 resources at a time. I dont see any straight forward solution for this use case .." List of all resources for a selected patient"
Dexter (Dec 22 2020 at 10:08):
Yeah _include
! I'll give that a go thanks!
Dexter (Dec 22 2020 at 10:21):
Hmm so given a device ID, I can get both the device and the patient using _include
, but what I really need are the practitioners. So I'm looking for a query that'll list practitioner
s given a device ID, by possibly traversing deviceID -> patient -> careteam -> practitioners
Dexter (Dec 22 2020 at 10:23):
I'm trying _has
, this works to get patients that have a deviceID [base]/Patient?_has:Device:patient:_id=1722695
Dexter (Dec 22 2020 at 11:48):
Okay made some progress, given a patientID, to get practitioners that are in the careteam, can use this
http://hapi.fhir.org/baseR4/Practitioner?_has:CareTeam:participant:subject={patientId}
Now, just need a way to just pass in the device ID and am good
Dexter (Dec 22 2020 at 11:52):
In general, I'm not sure I completely understand what the 3 parts of the _has
are. From the docs, I think it has to be
[base]/Resource?_has:Something:Reference(s):query
such that Something
references Resource
(be it a single or multiple). Is that correct?
Dexter (Dec 22 2020 at 12:06):
Example here seems to traverse 2 references: patient
s have anObservation
where it has an audit event
from a specific user
Query is: GET [base]/Patient?_has:Observation:patient:_has:AuditEvent:entity:user=MyUserId
On the same lines, practitioners that have careteams where it has a patient with a specific ID
I tried GET [base]/Practitioner?_has:CareTeam:participant:_has:Device:patient:_id=deviceId
, but returns 0 resources.
Here's the resources I'm testing with.
Patient id: 1714653
Device id: 1722695
CareTeam: 1714654
Dexter (Dec 22 2020 at 13:34):
I'm starting to think this isn't possible, or is it
René Spronk (Dec 22 2020 at 14:02):
Nested _has statements may not be supported by the server. Please look at the 'self' link in the response bundle to verify which parts of your search URL are supported by the server.
Dexter (Dec 23 2020 at 04:42):
I'm using the public HAPI server (http://hapi.fhir.org/baseR4), I think it does support nesting
Dexter (Dec 23 2020 at 05:05):
Hmm Not sure if hapi.fhir.org/baseR4
supports it, since the example for Reverse Chaining
on the docs gives this error
Unknown parameter name: AuditEvent:user
Dexter (Dec 23 2020 at 05:30):
I can't seem to use Bundle
either, to get resources together. I assumed fullurl
would be used.
{
"resourceType": "Bundle",
"entry": [
{
"fullUrl": "urn:uuid:b8dea8f5-ef2a-45e4-8f4f-48b71a45e932",
"resource": {
"resourceType": "Device"
},
"request": {
"method": "GET",
"url": "Device?_id=1722695"
}
},
{
"resource": {
"resourceType": "Patient"
},
"request": {
"method": "GET",
"url": "Patient?_has:Device:patient:_id=urn:uuid:b8dea8f5-ef2a-45e4-8f4f-48b71a45e932"
}
}
]
}
What I'm trying to do is, get the patient that the device refers to. I could just use _include
, but something like this is to see if I can reference the next resource to GET
in the bundle based on the identity of the previous GET
in the bundle. Is that possible?
Dexter (Dec 23 2020 at 06:09):
If that works, it'll be possible to create a request that returns me a careteam given a device ID associated with a patient
Dexter (Dec 23 2020 at 06:22):
When I try this, I get this error
{
"resourceType": "Bundle",
"type": "batch",
"entry": [
{
"fullUrl": "urn:uuid:8f2675f5-0961-4d11-bb81-398ffeae4d32",
"resource": {
"resourceType": "Device",
"id": "urn:uuid:8f2675f5-0961-4d11-bb81-398ffeae4d32"
},
"request": {
"method": "GET",
"url": "Device?_id=1722695"
}
},
{
"resource": {
"resourceType": "Patient"
},
"request": {
"method": "GET",
"url": "Patient?_has:Device:patient:_id=urn:uuid:8f2675f5-0961-4d11-bb81-398ffeae4d32"
}
}
]
}
First part gives error Invalid placeholder ID found: urn:uuid:8f2675f5-0961-4d11-bb81-398ffeae4d32 - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'
René Spronk (Dec 23 2020 at 07:58):
In a Bundle, the use of a urn:uuid: fullURL mostly indicates that the resource isn't actually available at a URL. The id would be just the UUID, without the urn:uuid: part. See Bundle for an explanation of this usage.
How about: Patient?_has=Device:patient:_id=xxxx&_revinclude=CareTeam:patient&_include:iterate=CareTeam:participant:Practitioner ?
Dexter (Dec 23 2020 at 09:36):
Wow that's amazing! This works! Patient?_has:Device:patient:_id=xxxx&_revinclude=CareTeam:patient&_include:iterate=CareTeam:participant:Practitioner
Removing the urn:uuid
didn't work though... Did you mean something like this? But either way, is there a way I can reference a next GET
based on the previous GET
, so that I can query the latter resource based on the results of the first one?
{
"resourceType": "Bundle",
"type": "batch",
"entry": [
{
"fullUrl": "urn:uuid:8f2675f5-0961-4d11-bb81-398ffeae4d32",
"resource": {
"resourceType": "Device",
"id": "8f2675f5-0961-4d11-bb81-398ffeae4d32"
},
"request": {
"method": "GET",
"url": "Device?_id=1722695"
}
},
{
"resource": {
"resourceType": "Patient"
},
"request": {
"method": "GET",
"url": "Patient?_has:Device:patient:_id=urn:uuid:8f2675f5-0961-4d11-bb81-398ffeae4d32"
}
}
]
}
René Spronk (Dec 23 2020 at 09:44):
Not in one go, as e.g. a Batch. That's two separate GETs one would have to do as a client.
Dexter (Dec 23 2020 at 09:52):
Ahh okay, because that would be an excellent feature!
I'm now trying this. given a device ID, is it possible, in one request, to get the careteam? (devce -> patient -> careteam). I'm trying something like this, but I think that's not how _has
works.
/CareTeam?subject:_has:Device:patient:_id=deviceId
returns nothing, but curiously,
/CareTeam?subject:_has:Device:patient:_id=patientId
returns the careteam with subject as patientId
René Spronk (Dec 23 2020 at 09:55):
That's a chained _has, which you tried and is not supported by your server. _revincludes are a good alternative, but it means your response bundle will have to be filtered by the client to select (only) the CareTeam resources.
René Spronk (Dec 23 2020 at 09:58):
Actually, it's one forward reference and one reverse reference (my bad).
Dexter (Dec 23 2020 at 10:02):
Yeah one forward and one back, so I thought I could select on the subject and slap a _has
there. But yes, if _has
support isn't there, your approach is the way to go, thank you very much!
not supported by your server
HAPI doesn't have support for chained _has
? How do I check this? I got the CapabilityStatement
, can't find anything there on feature support. Is that the right place to look for?
René Spronk (Dec 23 2020 at 10:04):
The CapStatement should list support for _has, but AFAIK there's no way to express the 'max chaining depth'. Search has many complex options that aren't fully expressed in the CapStatement.
Dexter (Dec 23 2020 at 10:11):
I can't seem to find it here http://hapi.fhir.org/baseR4/CapabilityStatement
, nothing about _has
, or chain
. What am I missing?
René Spronk (Dec 23 2020 at 12:30):
rest.resource.searchParam.name can be "_has" for a particular resource type
Dexter (Dec 24 2020 at 04:46):
I see, okay. So I guess http://hapi.fhir.org/baseR4/
does not have it, since I can't find "_has" anywhere.
Your query workaround was brilliant!
Thanks for the help!
Dexter (Dec 24 2020 at 04:53):
So for each patient, I want to setup limits per patient, in the sense that I am interested in knowing when a particular reading for a patient goes beyond the safe ranges for them. So, I'm thinking of storing these limits as extensions in the Device
resource (since it's assigned to them, and no one else). Is that the right way to go about it?
René Spronk (Dec 24 2020 at 07:25):
Well, if the device produces Observations, then we'd be talking about a reference range, which is part of Observation. If we're talking about device setting (e.g. an implantable device, e.g. pacemaker), then these would be device parameters. In the latter case I suggest you put your question on the #devices stream.
Dexter (Dec 24 2020 at 07:29):
It's not an implantable device (for now I guess), but things like BP machines etc. For the reference range, I'll need to what the ranges are to populate them in the Observation
, correct? Where would I store these numbers? I thought I'd just store the ranges as a base64 string in the device info as an extension (doesn't feel right though), so that when I get an JSON payload from the device (just has values and an identifier
), I can query the FHIR Device
(based on jsonPayload.identifier
), get the limits (from Device.Extension
), check for limits, and if out of range, send notifications to practitioners (thanks to the query you've kindly formulated!)
René Spronk (Dec 24 2020 at 07:39):
Assuming there is some clinical process, with a responsible clinician, for determining the reference ranges for a specific patient, you'd need to capture more than just a reference range, because you'd also need to capture who defined the reference range for a patient, and when they did so. So that makes it sound like you'd attach an Observation with as subject the Patient, Observation.device the reference to the device (or perhaps Observation.focus, given that the device is not used to observe its own reference range, which is implied by using Observation.device), and with the value of the observation using the valueRange data type.
Dexter (Dec 24 2020 at 09:13):
My bad I should've mentioned this is remote patient monitoring.
Devices are assigned to a patient either by the 'admins', or Practitioner
s from the patient's CareTeam
. Where do I store this info? Device doesn't seem to have an attribute for this (who assigned this device).
During assignment, they also add in the the ideal ranges for that patient-device pair. What do I do in this case? I'm capturing other parameters as you described (valueRange
or component
, Device
, effectiveInstant
, so I got that right I guess :) )
René Spronk (Dec 24 2020 at 10:28):
Well, this is getting beyond my area of expertise, so like you I'll await comments by those more in the know.
Dexter (Dec 24 2020 at 10:41):
No issues, thank you for helping me out so far!
Dexter (Dec 24 2020 at 12:12):
In C#, should I use the decimal
or double
for medical values? Looking the FhirDecimal, I think I must use decimal
Dexter (Dec 24 2020 at 12:19):
Also, for some cases, a device gives multiple measurements. Such as systolic, diastolic and pulse. In this case, do I create a single Observation
or multiple? From the example in the docs, I see that Systolic
and Diastolic
are grouped together in component
, should pulse be included in that too?
Dexter (Jan 08 2021 at 11:37):
I noticed just now that this returns all devices under that patient, how do I narrow this to just the specific device I want?
Dexter (Jan 14 2021 at 11:30):
I hope it's okay to tag you @René Spronk. When possible, could you kindly help me out narrowing the above query down? Thank you very much!
René Spronk (Jan 14 2021 at 12:01):
_include and _revinclude don't allow one to specify conditions. If you want a subset of Devices, then you would have to use Device as your focal resource. But that would mean rewriting the entire query URL..
Dexter (Jan 14 2021 at 12:02):
Yikes, thought so. Maybe there's a way I can use Bundle type request to get what I want? But I think there's no way to have a GET in a bundle that's dependent on what the previous GET had generated in the bundle
René Spronk (Jan 14 2021 at 12:08):
correct. But you could use 2 GETs that both use the very same device_id as one of their parameters.
Dexter (Jan 14 2021 at 12:12):
Hmm that makes sense, maybe 2/3 GET based on your pattern to get the patient, careteam and the devices. I think I can just remove the _include from the query you kindly took the time to give me, and then a single query to get the device
Dexter (Jan 14 2021 at 12:58):
Yep this works,
{
"resourceType": "Bundle",
"entry": [
{
"request": {
"method": "GET",
"url": "/Device?identifier=DEVICE_IDENTIFIER"
}
},
{
"request": {
"method": "GET",
"url": "/Patient?_has:Device:patient:identifier=DEVICE_IDENTIFIER&_include:iterate=CareTeam:participant:Practitioner&_revinclude=CareTeam:patient"
}
}
]
}
Lin Zhang (Jan 15 2021 at 00:31):
Interesting:fire:
Dexter (Feb 16 2021 at 13:53):
I'm trying this now, given a patient, I want to get the CareTeam
, Practitioner
, and PractitionerRole
, and I have this so far
https://hapi.fhir.org/baseR4/CareTeam
?subject=1852580
&_include=CareTeam:subject
&_include=CareTeam:participant
&_revinclude=PractitionerRole:Practitioner
The last bit, retrieving the PractitionerRole
doesn't work. I think the server supports revinclude since I recall a request where I could revinclude other resources. Specifically, this works https://hapi.fhir.org/baseR4/Patient?_id=1852580&_revinclude=CareTeam:subject
, and similar for getting a PractitionerRole
that refers to a Practitioner
Lin Zhang (Mar 12 2021 at 14:09):
Alright, you could skip my reply in another thread.
Last updated: Apr 12 2022 at 19:14 UTC