Languages: English • 简体中文 • 繁體中文
SensorThings API - Filter Observations and Display on Chart
In Part 1 of this series, we saw how to display Observations
of one Datastream on a chart.
In Part 2, we learned how to display multiple Datastreams' Observations
on a chart.
In this part, we want to go a bit further and representing Observations
for a particular day on a chart. We will
learn how to filter Observations
in SensorThings API. Also, we will learn how to move through Observations
pages
in case our SensorThings service supports pagination.
The only difference between this tutorial and Part 1 is in retriveing the data. So, we focus on data retrieval rather than how to show the data on the chart. You can go to Part 1 for more details on showing a dataset on the chart.
SensorThings API Filtering Capabilities
Retrieving data from SensorThings API is easy and flexible using the query options it provides.
One of the useful query option for representing Observations
is $filter
. Basically it helps
us filter our returned Observations
by Observations
' properties.
Lets focus on our tutorial. We want to retrieve Observations
of a Datastream for a particular day.
We can do it with filtering the Observations
with their phenomenonTime
. We will use two operators, "greater than or equal"
ge / >=
and "less than" lt / <
as follows.
Observations
is no different from previous tutorial except in the URI to which we send
HTTP GET
request.
Here is the code for that:
var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI , function(datastream) {
$.getJSON(datastream["Observations@iot.navigationLink"]+"?$filter=phenomenonTime ge '2017-02-07T00:00:00.000Z' and phenomenonTime lt '2017-02-08T00:00:00.000Z'" , function(observations) {});
});
As you may noticed in HTTP GET
response above, we have @iot.nextLink
. SensorThings
services can optionally support pagination and in that case the link to the next page of results will
be in property @iot.nextLink
. In this case, if we want to get all the Observations
for a particular day, we need to follow through @iot.nexLink
, if any. In this case, we need to make sure
we retrieve all the data we need before plotting them on the chart. To this end we use JavaScript
Promise
to control asynchronous nature of jQuery AJAX call that we use for retrieving data.
We define a recursive function to follow through next pages until it reaches the last page (there is not @iot.nextLink
available anymore).
Then we convert Observations
to the chart format.
Here is the code for the function:
function followNextLink(response){
var data = [];
// chart library expects an array of [timestamp, value]. Prepare the data returned from SensorThings for chart.
$.map(response.value, function(observation) {
var timestamp = moment(observation.phenomenonTime).valueOf();
data = data.concat([[timestamp, parseFloat(observation.result)]]);
});
// If there is a nextLink. follow it to get all the data.
if(response["@iot.nextLink"]!== undefined){
return new Promise(function(resolve, reject) {
$.getJSON(response["@iot.nextLink"], function(response){
// Call followLink again on the response to recursively get all the data
var resultPromise = followNextLink(response);
resultPromise.then(function(d){
resolve(data.concat(d));
});
});
});
} else {
//When there is no more next link return the data
return Promise.resolve(data);
}
}
Then in the call back function we call this recursive function. Here is the modified code:
var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI, function(datastream) {
var primaryPromise = new Promise(function(resolve, reject) {
$.getJSON(datastream["Observations@iot.navigationLink"] + "?$filter=phenomenonTime ge '2017-02-07T00:00:00.000Z' and phenomenonTime lt '2017-02-08T00:00:00.000Z'", function(response) {
//Follow the nextLink to retrieve all the Observations for that day
resolve(followNextLink(response));
});
});
//When the whole data is ready:
primaryPromise.then(function(data) {
data.sort(function(a, b) {
return a[0] - b[0];
});
/** Now data is ready for plotting on chart **/
});
});
Here is the final result of plotting our data on the chart:
What's Next?
In the last tutorial of this series, we will show you how to display the latest Observation of a Datastream on a Gauge. We will learn how to retrieve that latest Observation and also about working with Gauges.