Languages: English简体中文繁體中文

SensorThings API - 過濾觀測值(Observations)並顯示圖表

第一部分教程中,我們根據一個DatastreamObservation绘制了圖表。在第二部分教程中,我們根據多個DatastreamObservation繪製了圖表。在這部分教程中,我們會更進一步介紹如何獲取特定日期的Observations並繪製圖表。我們將會學習如何通過SensorThings API過濾Observations,同時也會學習如何取回分頁的Observations

本次教學唯一與第一部分不同的是取回數據部分。我們會關注如何取回數據而不是繪製圖表。您也可以回到第一部分回顧如何繪製圖表。

SensorThings API 過濾功能

通過SensorThings API 提供的查詢選項(query option)取回數據非常容易且靈活。$filter是查詢選項其中之一,可以用來查詢Observations。基本上,它可以根據Observations的屬性(properties)來回傳過濾後的Observations

我們要取回特定一天的Observations,可根據phenomenonTime过滤Observations。 我們將會使用兩個操作符號,"大於等於(greater than or equal)" ge / >= 以及 "小於(less than)" lt / <

GET https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)/Observations?$filter=phenomenonTime ge '2017-02-07T00:00:00.000Z' and phenomenonTime lt '2017-02-08T00:00:00.000Z'
与之前的教程相比,除了發送HTTP GET請求的URI不同,其他方面沒有區別。代碼如下:

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) {});
});

您可能注意到了上面的HTTP GET響應中,我們有@iot.nextLink。SensorThings 服務支持分頁,並且下一頁結果的連接可在@iot.nextLink屬性中找到。在這種情況下,如需取回特定日期的所有Observations,如若存在@iot.nexLink,則需跟隨@iot.nexLink來獲取分頁數據。所以為了確保在繪製圖表前取回了所有數據,這裏我們需要使用JavaScript Promise來控制加載數據的異步jQuery AJAX。

我們定義一個遞歸函數不斷取得下一頁,直到抵達最後一頁(最後一頁沒有@iot.nextLink),然後轉換Observations為圖表可接受的格式。

代碼如下:

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);
  }
}

在一個回調函數中調用這個遞歸函數,以下是修正過後的代碼:

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 **/
  });
});

最終繪製的圖表如下:

在 SensorThings Share 上查看代碼

下一步?

在本系列最後一部分教程中,我們將會向您介紹如何根據Datastream上最新一個Observation繪製一個儀表圖。

第四部分 - 儀表圖