|
// Every network maintainer gets an API key to authenticate POST, PATCH, DELETE requests on sensors and observations in their network |
|
// What a network maintainer would POST to /sensor-observation |
|
{ |
|
"data": { |
|
"type": "sensor-observation", |
|
"api-key": "abc123mykey", // Assigned to maintainer of sensor network |
|
"attributes": { |
|
"time": "2016-02-29T18:39:30.519207", // The one attribute that we mandate. |
|
"observation": { |
|
// The maintainer of the sensor network is responsible |
|
// for making sure that these fields are consistent. |
|
// Not all need to be present in each observation, |
|
// but "temperature" in one reading needs to be comparable to "temperature" in another. |
|
"temperature": 12, |
|
"no2": 334 |
|
} |
|
} |
|
}, |
|
"relationships": { |
|
// Client needs to inform server which sensor this belongs to |
|
"reported-by": { |
|
"type": "sensor" |
|
"id": 3096 |
|
} |
|
} |
|
} |
|
// Let's say that POST created a sensor-observation object with ID 4567345 |
|
// Here's what GET sensor-observations/4567345 would look like. |
|
|
|
{ |
|
{ |
|
"data": { |
|
"type": "sensor-observation", |
|
"id": "4567345", // Globally unique ID generated by server |
|
"attributes": { |
|
"time": "2016-02-29T18:39:30.519207", |
|
"observation": { |
|
"temperature": 12, |
|
"no2": 334, |
|
... |
|
} |
|
} |
|
"relationships": { |
|
"reported-by": { |
|
"type": "sensor" |
|
"id": 3096 |
|
} |
|
} |
|
}, |
|
"included": [{ |
|
"type": "sensor", |
|
"id": "3096", |
|
"attributes": { |
|
"location": [-87.9137261060048, 41.6462579944754], // Required for every sensor |
|
"description": "Anything special about this sensor?" |
|
"observation-attribute-metadata": { |
|
// Details particular to this sensor. |
|
"temperature": { |
|
"unit": "degrees Fahrenheit", |
|
"description": "Uses Acme Corp. chip with +- .5 degree accuracy." |
|
}, |
|
... |
|
} |
|
"sensor-attributes": { |
|
// What else do clients need to know about this particular sensor? |
|
"height": 2.5, |
|
"direction": "NE", |
|
"installed-date": "" |
|
... |
|
} |
|
} |
|
"relationships": { |
|
"network": { |
|
"type": "sensor-network", |
|
"id": 3 |
|
} |
|
} |
|
}, { |
|
"type": "sensor-network", |
|
"id": 3, |
|
"attributes": { |
|
"name": "Array of Things", |
|
"maintainer-email" "[email protected]", |
|
"description": "Brief description of this sensor network." |
|
"info-link": "https://arrayofthings.github.io/developers" |
|
// ... Whatever other mandated metadata we require ... |
|
"sensor-attribute-metadata": { |
|
"height": { |
|
"unit": "meters", |
|
"description": "How far off the ground is this sensor positioned on the CDOT light post on which it is mounted?" |
|
}, |
|
"direction": { |
|
"unit": "compass direction", |
|
"description": "Which direction is this node facing off of the light post? Options are N, NE, E, SE, S, SW, W, NW" |
|
}, |
|
... |
|
} |
|
} |
|
}] |
|
} |
I think my main interest would be from the GET side but probably without knowing an observation ID. It would be more along the lines of wanting all observations, filtered by some combination of sensor, time, and observation type. Do you have any thoughts what that would look like?
Being duly sensitive to bikeshedding, could there be anything to separating data from metadata? It seems as if including both in every reply could involve a lot of repetition and not necessarily make it easy for the consumer (me) to detect changes in metadata. What if there were two APIs -- one to deliver data (used frequently) and one to deliver metadata (used infrequently)? This, of course, requires knowing when to call the metadata API. As a thought, what if the data API had either a flag to indicate this was the first data observation since a metadata change or the identifier (observation ID if sequential or timestamp) of the first data observation after a metadata change? That could be a trigger to the consumer to call the metadata API. Of these two, I prefer the latter approach. The former has the risk of missing the flagged data observation and then being out of sync for an extended period of time.
In either case of the above, one obviously could get more complicated by flagging different types of metadata changes instead of a simple "something changed" signal. I do not have a strong opinion on that at this point. I could cook up use cases for making this really fancy but complexity has all sorts of cost -- not least, increasing risk of error as multiple entities try to stay in sync -- and there may be something to the idea of just being told to hit the metadata API for that sensor and either reload everything or check the elements I care about and deal with any changes found.