iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 24
0
Modern Web

Webduino 不只是物聯網,智慧插座也可以很 Modern~系列 第 24

實戰智慧插座 24 - 用 Opendata 開關燈 ( PM2.5 篇 )

  • 分享至 

  • xImage
  •  

當我們可以利用一些網路服務來操控智慧插座之後,就可以來玩點比較進階的功能,這篇將會介紹在網頁裡常常使用的 Opendata ( 開放資料 ),並且使用這些 Opendata 來操控智慧插座。



取得 Opendata

基本上我們的縣市政府網站,都有提供不少 Opendata 的資訊讓開發者使用,我自己很喜歡到「政府資料開放平臺」上面去挖寶,或是「台北市政府資料開放平臺」,這兩個平台的開放資料都是相當完整且容易介接。

政府資料開放平臺:http://data.gov.tw/

Webduino Opendata

台北市政府資料開放平臺:http://data.taipei/

Webduino Opendata

而這篇文章裡面,我將會使用政府資料開放平臺裡的「空氣品質即時污染指標」作為我的資料來源,因為我們手邊不見得隨時都會有空氣污染偵測器 ( 也不便宜 ),所以透過每個小時由氣象局偵測的資訊,也可作為基本的預警與提醒功能。

Webduino Opendata

點選 JSON 的格式,這就是待會我要使用的。

Webduino Opendata

此外,我在這邊列出一些我覺得還滿實用,至少都是每小時更新的 Opendata,有興趣就可以參考我後面的做法自行做串接。

  • 即時海水水位:http://data.gov.tw/node/35077
  • 即時水位 ( 10min 更新 ):http://data.gov.tw/node/25768
  • 即時雨量 ( 10 min 更新 ):http://data.gov.tw/node/7879
  • 空氣品質指標 ( AQI ):http://data.gov.tw/node/40448
  • 空氣品質即時污染指標:http://data.gov.tw/node/6074
  • 高雄機場國內線即時到站航班:http://data.gov.tw/node/33649
  • 紫外線即時監測資料:http://data.gov.tw/node/6076
  • 曾文水庫即時水情資訊:http://data.gov.tw/node/32733
  • 台北捷運列車到站:http://data.taipei/opendata/datalist/datasetMeta?oid=6556e1e8-c908-42d5-b984-b3f7337b139b


使用 Opendata ( 網頁前端 )

要直接在「網頁前端」使用 Opendata,最快的做法大概就是使用 jQuery 了,這邊我用了 .get 的方法,只要三行,剛剛的 JSON 資料就全部進到網頁裡了。( 使用 console.log 顯示 )

$.get('http://opendata2.epa.gov.tw/AQX.json',function(e){
  console.log(e);
});

Webduino Opendata
( 程式:http://bin.webduino.io/diqeh/1/edit?html,js,output )

因為資料是陣列的格式,所以藉由 forEach 就可以去判斷陣列每個元素的內容,然後指篩選出高雄市的資料。

$.get('http://opendata2.epa.gov.tw/AQX.json',function(e){
  e.forEach(function(o){
    if(o.County=='高雄市'){
      console.log(o);
    }
  });
});

Webduino Opendata
( 程式:http://bin.webduino.io/desec/1/edit?html,js,output )

不過只有在 console.log 裡面顯示實在沒有很好閱讀,最終還是得呈現在網頁裡,所以我先在網頁裡放個 div 作為顯示區域,接著就可以透過 append 把資料加到網頁裡面。

var $content = $('#content');
$.get('http://opendata2.epa.gov.tw/AQX.json',function(e){
  e.forEach(function(o){
    if(o.County=='高雄市'){
      console.log(o);
      $content.append('< '+o.SiteName+' > PM2.5:'+o['PM2.5']+', PM10:'+o.PM10+'<br/>');
    }
  });
});

Webduino Opendata
(程式:http://bin.webduino.io/sibu/1/edit?html,js,output )

更進階一點,我們也可以做成下拉選單,選擇之後再呈現對應的資訊,當資料載入之後,透過 filter 做篩選,不然你可能會有十幾個「新北市」出現在選單裡,然後再根據我們選擇的縣市,把感測器所在的區域資料顯示在網頁裡。

var $content = $('#content');
var $select = $('#select');
var $btn = $('#btn');
var county = [];
var result;
$.get('http://opendata2.epa.gov.tw/AQX.json',function(data){
  console.log(data);
  data.forEach(function(e,i){
    county[i] = e.County;
  });
  result=county.filter(function(element, index, arr){
    return arr.indexOf(element)=== index;
  });
  //篩選出縣市名稱(不然會很多重複)
  result.forEach(function(e){
    $select.append('<option value="'+e+'">'+e+'</option>');
  }); 

  $btn.on('click',function(){
    var s = $select.val();
    $content.html(''); //清空內容
    data.forEach(function(e,i){
      //挑選對應的縣市顯示
      if(e.County == s){
        $content.append('< '+e.SiteName+' > PM2.5:'+e['PM2.5']+' , PM10: '+e.PM10+'<br/>');
      }
    });
  });
});

Webduino Opendata
( 程式:http://bin.webduino.io/juru/1/edit?html,js,output )



使用 OpenData ( Node.js )

剛剛的範例是透過網頁前端運行,如果想要 24 小時偵測,可能就得依賴後端了,這邊介紹一個 Node.js 的套件「get-json」,就可以做到剛剛像網頁前端一樣的事情。
程式只要這樣寫,就可以每 10 秒抓一次氣象局的資料囉!

var getJSON = require('get-json')

_getJSON();

setInterval(function(){
    _getJSON();
},10000);

function _getJSON(){
    getJSON('http://opendata2.epa.gov.tw/AQX.json',function(error, response){
      response.forEach(function(e,i){
        if(e.SiteName=='前鎮'){
            console.log('前鎮, PM2.5:'+e['PM2.5']+' , PM10:'+e.PM10);
        };
      });
    });
}

Webduino Opendata



Opendata + Webduino ( 網頁前端 )

知道如何獲取資料並且應用之後,就要來寫點判斷式,接著再對應的狀態下,透過 Webduino 點亮燈泡,首先看到 HTML 的部分,一開始先引入對應的 JavaScript,然後放入兩個下拉選單、一個顯示文字的區域用來顯示數值,最後就是一個提示文字,如果空污指數太高就會顯示,同時點亮燈泡。

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
<script src="https://webduino.io/components/webduino-js/dist/webduino-all.min.js"></script>
<script src="https://blockly.webduino.io/webduino-blockly.js"></script>
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>
  <select id="county"></select>
  <select id="sitename"></select>
  <div id="content"></div>
  <h1 id="h"></h1>
</body>
</html>

JavaScript 的部分一開始先宣告一些變數,還有一個設定檔,如果今天數值大於我們設定黨的數字,就會亮燈並顯示空屋提示。

var $content = $('#content'),
    $county = $('#county'),
    $sitename = $('#sitename'),
    $h = $('#h'),
    $btn = $('#btn');

var county = [];
var site = {};
var result, led;

var config = {
  PM25 : 20,
  PM10 : 40
};

再來就是抓取開放資料的 json 檔,接著對資料做一些轉換,篩選出主要縣市 ( 台北市、新北市...等 ) 以及每個縣市對應的區域 ( 永和、中和...等 ),然後再改變選單的時候,把對應的數值顯示出來,如果數值比較高,就會點亮燈泡以及秀出「空氣污染超標!」的文字

boardReady('你的開發板 ID', function(board) {
  board.systemReset();
  board.samplingInterval = 250;
  led = getLed(board, 10);

  $.get('http://opendata2.epa.gov.tw/AQX.json',function(data){
    data.forEach(function(e,i){
      county[i] = e.County;
    });

    //篩選出父選單縣市名稱(不然會重複)
    result=county.filter(function(element, index, arr){
      return arr.indexOf(element)=== index;
    });

    //初始化父選單
    result.forEach(function(e){
      $county.append('<option value="'+e+'">'+e+'</option>');
    }); 

    //初始化子選單
    _select();

    //當父選單改變時,對應子選單內容
    $county.on('change',function(){
      _select();
    });

    $sitename.on('change',function(){
      _change();
    });

    function _select(){
      $sitename.html(''); //一開始先清空子選單
      data.forEach(function(e,i){
        //挑選對應的地區顯示
        if(e.County == $county.val()){
          $sitename.append('<option value="'+e.SiteName+'">'+e.SiteName+'</option>');
        }
        site[e.SiteName] = [e['PM2.5'],e.PM10];
      });
      _change();
    }

    function _change(){
      var name = site[$sitename.val()];
      $content.html('< '+$sitename.val()+' > PM2.5 ('+name[0]+'), PM10 ('+name[1]+')<br/>');
      if(name[0]>config.PM25 || name[1]>config.PM10){
        $h.text('空氣污染超標!');
        led.on();
      }else{
        $h.text('');
        led.off();
      }
    }

  });
});

Webduino Opendata
(程式:http://bin.webduino.io/sipod/1/edit?html,js,output )



Opendata + Webduino ( 後端 )

剛剛我們是使用前端的方法,繼續介紹 Webduino 後端的用法,如果你有印象,我在「實戰智慧插座 18 - 用網頁聊天室開關燈 ( 前、後端實作篇 )」也有介紹過 Webduino 後端的用法,首先你要先安裝對應的套件,這邊需要 get-jsonwebduino-jswebduino-blockly

npm install webduino-js webduino-blockly get-json

如果你想要在啟動的當下,也有類似對話視窗可以一一輸入資訊的話,可以多安裝 inquirer ( https://www.npmjs.com/package/inquirer )。

npm install inquirer

再來就免不了要寫程式了,最主要跟前端一樣,先抓取對應的縣市 PM2.5 數值,當數值大於多少的時候就亮燈,比較不同的是你可以用一個 setInterval 間隔一段時間抓取一次資料,就可以 24 小時放著讓它自動監控了。

require("webduino-js");
require("webduino-blockly");
var getJSON = require('get-json');
var inquirer = require("inquirer");

var pm = function(a,b,c,d){
    boardReady(a, function(board) {
      board.systemReset();
      board.samplingInterval = 250;
      led = getLed(board, b);

      console.log('裝置連線成功...');

        _getJSON();

        setInterval(function(){
            _getJSON();
        },10000);
    });

    function _getJSON(){
        getJSON('http://opendata2.epa.gov.tw/AQX.json',function(error, response){
          response.forEach(function(e,i){
            if(e.SiteName==d){
                console.log(d+', PM2.5:'+e['PM2.5']+' , PM10:'+e.PM10);
                if(e['PM2.5']>c){
                    led.on();
                }
            };
          });
        });
    }
};

var preguntas = [{
  type: 'input',
  name: 'device',
  message: 'Device ID?',
  default: '你的裝置 ID',
}, {
  type: 'input',
  name: 'led',
  message: 'LED pin?',
  default: '10'
}, {
  type: 'input',
  name: 'rate',
  message: 'PM2.5?',
  default: '20'
}, {
  type: 'input',
  name: 'site',
  message: '縣市名稱',
  default: '前鎮'
}];

inquirer.prompt(preguntas, function(answers) {
}).then(function(answers) {
  console.log(answers.device + ',' + answers.led + ',' + answers.rate + ',' + answers.site);
  pm(answers.device, answers.led * 1, answers.rate * 1, answers.site);
});

Webduino Opendata



小結

以上就是拿 Opendata 來做物聯網應用的範例,雖然說只是點亮一個燈泡,但如果我們可以透過 Webduino 把各種裝置給虛擬化、網路化、變數化,就可以輕鬆地用網頁前端或後端來操控了。


上一篇
實戰智慧插座 23 - 用 Youtube 的魔術開關燈 ( 影片互動篇 )
下一篇
實戰智慧插座 25 - 用 Node-RED 開關燈 ( 基礎操作篇 )
系列文
Webduino 不只是物聯網,智慧插座也可以很 Modern~30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
twcctz50
iT邦新手 4 級 ‧ 2021-11-24 17:06:42

Good read

我要留言

立即登入留言