Languages: English • 简体中文 • 繁體中文
SensorThings API - Getting Started with Representing Observations
The SensorThings API handles a wide variety of data necessary for creating a geospatial-enabled Internet of Things (IoT) solution. One of the entities in SensorThings is the Observation
, which is used to store Sensor
Observations
/readings.
The very first step in analysing the IoT data is to visualize the different Observations
from different Things.
In this tutorial, we're going to focus on how we can retrieve Observations
from SensorThings, and display them in a chart.
Toronto Bike Sharing Dataset
SensorThings allows you to share data using open standards, which is a good thing. The city of Toronto has a bike sharing program, which is also a good thing. This program shares bike availability and docking availability information via an open data feed, which is, you guessed it, a good thing. We've put these good things to good use by taking the Bike Share Toronto data and putting it in a SensorUp Cloud instance. We'll be using that instance as the data source for this tutorial.
Prerequisite
In this tutorial we'll be using Highcharts library, which is
a JavaScript library for creating interactive charts. Let's start by showing a basic chart. We are also using jQuery library for retrieving data from SensorThings server. Also, Moment.js library is used for parsing Dates in Observations
.
Here is the code for adding jQuery, Moment.js, and Highcharts libraries.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highstock/4.2.6/highstock.js"></script>
First Learning Step:
How to retrieve Observations from a SensorThings Service
In this step we will retrieve Observations
from Bike Share data.
In SensorThings API each Things has multiple Datastreams
and each Datastreams
has Observation
. We can look at Datastream
as the grouping for Observations
of a Sensor
. What we need to do is representing the Observations
of one Datastream
as they are coming from the same Sensor
. So, what we do is first we retrieve the Datastream
and then we retrieve the Observations
of that Datastream
to show on a chart.
We can retrieve the Datastream
by sending an HTTP GET
request.
Here is the code for retrieving a Datastream
using jQuery library:
var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI, function(datastream) {});
Then, in the callback function we can follow Observations
@iot.navigationLink
to retrieve the Observations
of that Datastream
. Again it can be done with HTTP GET
Request.
Here is the code for retrieving a Observations
:
var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI, function(datastream) {
$.getJSON(datastream["Observations@iot.navigationLink"], function(observations) {});
});
Now we have the Observations
data needed for plotting on a chart. However,
the data format that Highcharts is accepting is different.
- First, data needs to be sorted by time in ascending order.
- Second, the data format is array of [timestamp, value], like
[[phenomneonTime1, result1],...]
So lets correct the data format before start preparing chart.
Here is the code for re-formatting and sorting Observations
data:
var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI, function(datastream) {
$.getJSON(datastream["Observations@iot.navigationLink"], function(observations) {
var data = $.map(observations.value, function(observation) {
var timestamp = moment(observation.phenomenonTime).valueOf();
return [[timestamp, parseFloat(observation.result)]];
});
data.sort(function(a, b) {
return a[0] - b[0];
});
});
});
Now that we have the data ready and in the correct format, lets start preparing the chart.
Second Step:
How to represent on Chart
We start with creating the container for the chart. Here is the code for a 500 pixel tall div
tag. Later, we will tell Highcharts to show the chart in this div.
<div id="chart" style="height: 500px"></div>
Now we create a Highcharts chart in the chart
div we created earlier, and set the title as "Loading chart data". We will update this title as we load the data into the chart.
var chart = new Highcharts.StockChart("chart", {
title: { text: "Loading Chart Data..." },
series: []
});
We can enable the chart to display that it is loading until we load it with data. Highcharts library handles it and the code for that is as simple as following code.
chart.showLoading();
First we want to update chart title with the information we retrieved from Datastream
. Here is the code for that.
vchart.setTitle({ text: datastream.description });
Now we want to load our prepared data to the chart. We just need to use "addSeries" function from the Highcharts library and load our data. We also set the tooltip text for the chart points so that it will show unitOfMeasurement on mouse over.
Here is the code for that.
var series = chart.addSeries({
data: data,
tooltip: {
valueSuffix: " " + datastream.unitOfMeasurement.symbol
}
});
The last thing we want to do is to update the Y axis and add unitOfMeasurement to that. Then we can remove loading from the chart.
series.yAxis.update({
title: {
text: datastream.unitOfMeasurement.name + " (" + datastream.unitOfMeasurement.symbol + ")"
}
});
chart.hideLoading();
Lets check the result
It is time to check the result of our work. Here is how it looks.
How to make it better?
Instead of sending two HTTP GET
request to the Datastream
and its Observations
, we can use SensorThings API query capabilities to retrieve all we need in one request. To this end, we can use $expand
query to embed the Observations
in our Datastream
query.
We need to make a slight change in the retrieving data part and the rest of code is exactly the same.
Here is how we need to change the code for using $expand
:
var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)?$expand=Observations";
$.getJSON(datastreamURI, function(datastream) {
var data = $.map(datastream.Oservations, function(observation) {
var timestamp = moment(observation.phenomenonTime).valueOf();
return [[timestamp, parseFloat(observation.result)]];
});
data.sort(function(a, b) {
return a[0] - b[0];
});
});
Here is the code uses $expand
that you can also try:
What's Next?
Our next tutorial will show you how to show multiple Datastreams
on the same chart.
This type of visualization can be more useful for comparing the trend of changing between multiple Datastreams
.