RADAR-base / RADAR-RestApi

RESTful interface to access near real-time data
Apache License 2.0
2 stars 0 forks source link

Volume API #39

Closed herkulano closed 6 years ago

herkulano commented 7 years ago

It would be great to have an API that sends the aggregated volume of the sensors for the dashboard.

In the dashboard, we have a graph that represents the volume of visible sensors that is used to zoom in or out of the data in time.

This is the detail of the volume graph: screen shot 2017-08-18 at 12 28 37 https://github.com/RADAR-CNS/RADAR-Design/blob/master/Screens/%5BDesktop%5D%20400-Patient-Overlay.png

Ideally, the API request would take an object of sources and an array of sensors to be aggregated.

Request with a JSON body.

POST /data/volume/{subjectId}

{
  "00:07:80:1F:53:1A": ["ACCELEROMETER", "BATTERY"],
  "00:07:80:1F:53:1B": ["THERMOMETER", "ELECTRODERMAL_ACTIVITY"],
  "00:07:80:1F:53:1C": ["THERMOMETER", "HEART_RATE"],
  "00:07:80:1F:53:1D": ["BLOOD_VOLUME_PULSE", "INTER_BEAT_INTERVAL"]
}

Response

{
  "header": {
    "subjectId": "MRC03",
    "sources": {
      "00:07:80:1F:53:1A": ["ACCELEROMETER", "BATTERY"],
      "00:07:80:1F:53:1B": ["THERMOMETER", "ELECTRODERMAL_ACTIVITY"],
      "00:07:80:1F:53:1C": ["THERMOMETER", "HEART_RATE"],
      "00:07:80:1F:53:1D": ["BLOOD_VOLUME_PULSE", "INTER_BEAT_INTERVAL"]
    },
    "descriptiveStatistic": "COUNT",
    "unit": "COUNT",
    "timeFrame": "TEN_SECOND",
    "max": 5,
    "effectiveTimeFrame": {
      "startDateTime": "2017-07-03T12:38:40Z",
      "endDateTime": "2017-07-03T12:39:40Z"
    }
  },
  "dataset": [
    {
      "value": 0,
      "startDateTime": "2017-07-03T12:38:40Z"
    },
    {
      "value": 5,
      "startDateTime": "2017-07-03T12:38:50Z"
    },
    {
      "value": 4,
      "startDateTime": "2017-07-03T12:39:00Z"
    },
    {
      "value": 0,
      "startDateTime": "2017-07-03T12:39:10Z"
    },
    {
      "value": 1,
      "startDateTime": "2017-07-03T12:39:20Z"
    },
    {
      "value": 2,
      "startDateTime": "2017-07-03T12:39:30Z"
    }
  ]
}
blootsvoets commented 7 years ago

So what I mentioned in the call is that some sensors will overwhelm the others. If you have BLOOD_VOLUME_PULSE there, all other measurements are not going to show on the graph, because it has 64 times the volume of the other topics. Could an alternative be to have a DISTINCT measure that says how many sensors were available in a given time window?

herkulano commented 7 years ago

Good point.

I think that was the original idea. To understand, what we're talking about is given a timeWindow (formerly timeFrame) the API would count if there's a data point in that timeWindow, not how many data points are inside each timeWindow, so the data is normalized and each sensor has the same "strength".

So for a timeWindow of 10 seconds, we only get a 1 or 0 COUNT for each sensor, independently if the sensors have more data points per 10 seconds.

blootsvoets commented 7 years ago

Looking at the API in #42, could the POST request be formatted as follows? POST /api/data/{userId}/aggregate/distinct?startTime=1500000000&endTime=1506000000&timeWindow=TEN_SECOND

{
  "sources": [
     {"id": "00:07:80:1F:53:1A", "sourceData": ["ACCELEROMETER", "BATTERY"]},
     {"id": "00:07:80:1F:53:1B", "sourceData": ["THERMOMETER", "ELECTRODERMAL_ACTIVITY"]},
     {"id": "00:07:80:1F:53:1C", "sourceData": ["THERMOMETER", "HEART_RATE"]},
     {"id": "00:07:80:1F:53:1D", "sourceData": ["BLOOD_VOLUME_PULSE", "INTER_BEAT_INTERVAL"]}
   ],
   "monitors": [
     {"id": "abcd-ef012394-abcdefg", "sourceData": ["UPTIME", "EXTERNAL_TIME"]}
   ]
}

Edit: renamed sensors and measures to sourceData and use enum syntax for the timeWindow.

blootsvoets commented 7 years ago

One more note: in the ManagementPortal, sensors and measures of a source will collectively be called "sourceData". We could name it like that in the POST request as well? @dennyverbeeck @nivemaham @herkulano what do you think?

herkulano commented 7 years ago

Looking at the API in #42, could the POST request be formatted as follows? POST /api/data/{userId}/aggregate/distinct?startTime=1500000000&endTime=1506000000&timeWindow=ten-second

The only comment here is that to keep consistency with the enums we'll send timeWindow enums in CAPS enum syntax (&timeWindow=TEN_SECOND). Is that OK with you?

One more note: in the ManagementPortal, sensors and measures of a source will collectively be called "sourceData". We could name it like that in the POST request as well?

Sounds good to me.

Edit: renamed to enum syntax.

//cc @mpgxvii

nivemaham commented 7 years ago

@blootsvoets I agree. Sounds good to me

nivemaham commented 6 years ago

@herkulano @blootsvoets According to current structure, monitors are also treated as sources and the unique identifier of a SourceData is called SourceDataName, So I would say the request would look like below. POST /api/data-aggregate/{projectId}/{subjectId}?startTime=1500000000&endTime=1506000000&timeWindow=TEN_SECOND

{
  "sources": [
     {"sourceId": "00:07:80:1F:53:1A", "sourceDataName": ["Empatica_E4_v1_ACCELEROMETER", "Empatica_E4_v1_BATTERY"]},
     {"sourceId": "00:07:80:1F:53:1B", "sourceDataName": ["Empatica_E4_v1_THERMOMETER", "Empatica_E4_v1_ELECTRODERMAL_ACTIVITY"]},
     {"sourceId": "00:07:80:1F:53:1C", "sourceDataName": ["BIOVOTION_m1_v1_THERMOMETER", "BIOVOTION_m1_v1_HEART_RATE"]},
     {"sourceId": "00:07:80:1F:53:1D", "sourceDataName": ["Empatica_E4_v1_BLOOD_VOLUME_PULSE", "Empatica_E4_v1_INTER_BEAT_INTERVAL"]}
     {"sourceId": "abcd-ef012394-abcdefg", "sourceDataName": ["Android_pRMT_v1_UPTIME", "Android_pRMT_v1_EXTERNAL_TIME"]}
   ]
}

I was also wondering why should you send set of sourceDataName in the POST request. Is there a possibility that the requester needs to know the availability of a subset of source-data of a particular source, or would they want to know the availability of all the source-data of a particular source. In the case of later, may be just the set of sourceIds would be sufficient to process the request. What are your thoughts?

blootsvoets commented 6 years ago

In the interface, you could select only certain sourceData (e.g., I want acceleration from Biovotion, Empatica and Phone to compare them). Then you only get the volume of those sourceData. Preferably, the sourceDataName does not have the {Producer}_{model}_{version} prefix.

nivemaham commented 6 years ago

OK. So I understand that set of sourceDataName is required to be part of the request body. However, the sourceDataName which is the unique identifier of the SourceData has the {Producer}_{model}_{version} prefix. But indeed the user interface can show just the ACCELEROMETER which is the sourceDataType.

herkulano commented 6 years ago

@nivemaham the sourceDataName is necessary to select only the data that is being shown in the dashboard's UI because users can hide certain sources and their subset of data.

One thing to mention is that I thought it would be the sourceDataType, e.g, ACCELEROMETER that would be requested and not the specific sourceDataName, e.g, Empatica_E4_v1_ACCELEROMETER. From my perspective, it's simpler to use the "normalised" sourceDataType.

nivemaham commented 6 years ago

@herkulano The earlier APIs were designed that way. I propose sourceDataName since it is the unique identifier of SourceData. Currently, the SourceData has OneToMany relationship between SourceType, which was designed to allow more than one SourceData of a sourceDataType in a SourceType. We don't have a use case for this. But I think it is better to have consistent designs among components.