Raspberry PiでIoT 温度・湿度・気圧データ編の3回目です。前回までで、Raspberry Piから温度、湿度、気圧データをWebサーバへ送信してそのデータを蓄積出来るようになりました。今回はそのデータを単純な一覧とグラフで表示してみます。
以下が、Raspberry PiでIoT(温度・湿度・気圧データ編)の記事一覧です。
Raspberry PiでIoT(温度・湿度・気圧データ編 その1)BME280でデータ取得
Raspberry PiでIoT(温度・湿度・気圧データ編 その2)Webサーバ側構築とデータ送信
Raspberry PiでIoT(温度・湿度・気圧データ編 その3)データ表示とグラフ表示”
Raspberry PiでIoT(温度・湿度・気圧データ編 その4)アラートメール送信
今回の作業手順は以下です。
1.Webページのテンプレートを用意する
2.単純な一覧表示のページを作成する
3.グラフ表示のページを作成する
1.Webページのテンプレートを用意する
まずは、Webページのテンプレートを用意します。テンプレートといいましても以下のようなBootstrapを利用したシンプルなテンプレートです。必要なBootstrapとJQueryはインターネット上のファイルを利用しています。jsファイルはページ最初に記述しています。
すいません、Bootstrapを細かく理解している訳ではありませんので反転(navber-inverse)のナビゲーションバーがあればいいかぐらいです。メニューもありませんが、ご了承下さい。
このページ内の何も含まれていない方のdiv class=”container”内に追記していきます。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>タイトル</title> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" /> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script> </head> <body> <nav class="navbar navbar-default navbar-static-top navbar-inverse"> <div class="container"> <div class="navbar-header"> <a href="#" class="navbar-brand"> Sensor Data </a> </div> </div><!-- container --> </nav> <div class="container"> </div><!-- /container --> </body> </html>
2.単純な一覧表示のページを作成する
作成したテンプレートページにセンサーデータ一覧を表示する機能を実装します。ここではとりあえずは、ボタンを押したら保存されている全データの一覧を表示します。以下のようなページを作成しました。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>タイトル</title> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" /> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script> </head> <body> <nav class="navbar navbar-default navbar-static-top navbar-inverse"> <div class="container"> <div class="navbar-header"> <a href="#" class="navbar-brand"> Sensor Data </a> </div> </div><!-- container --> </nav> <div class="container"> センサーデータ一覧<br /> <ul id="list"></ul> <input id="btn_1" type="button" value="データ取得" /> <script type="text/javascript"> //画面構築完了後 $(function() { //ボタンのクリックイベントで $("#btn_1").click(function(){ //データを取得し、jsonというオブジェクトに入れる $.getJSON("http://yourdomain/subsub/sensvalues.php",function(json){ var ulObj = $("#list"); $('#list').empty(''); len = json.length; for(var i = 0; i < len; i++) { ulObj.append($("<li>").attr({"id":json[i].id}).text(json[i].datetime + " " + json[i].temp + " " + json[i].hum + " " + json[i].press )); } }); }); }); </script> </div><!-- /container --> </body> </html>
データを取得するsensvalues.phpですが、前回のままですと、データの順番に規則性がないので、以下のように、order by datetime descを追記しました。
<?php $pdo = new PDO('mysql:host=localhost;dbname=indpsys_iot;charset=utf8','indpsys_iot','Anu32578'); switch ($_SERVER['REQUEST_METHOD']) { case 'GET': $st = $pdo->query("SELECT * FROM sensorvalues order by datetime desc"); echo json_encode($st->fetchAll(PDO::FETCH_ASSOC)); break; case 'POST': $in = json_decode(file_get_contents('php://input'), true); if (!isset($in['id'])) { $st = $pdo->prepare("INSERT INTO sensorvalues(datetime,temp,hum,press) VALUES(:datetime,:temp,:hum,:press)"); } $st->execute($in); echo json_encode("normal end"); break; } ?>
これで以下のように表示されました。上の方がデータが新しくて、時間、温度、湿度、気圧の順に並んでいます。これでは見づらくて、こういったデータはやはりテーブル形式の方が見やすいとか絞り込みが出来ないとかあるとは思いますが、まずは表示は出来たということでここまでにします。
3.グラフ表示のページを作成する
次にグラフ表示のページを作成します。以下のCanvasJSを利用しました。このCanvasJSを選択した理由は何といっても簡単にグラフが生成出来ると思ったからです。
CanvasJS(※商用利用は有料です)
使い方としては、グラフを表示するdivタグ名や、表示形式、グラフデータを指定して、CanvasJS.Chartを生成します。そして、render()を呼び出します。そうすると指定したdivタグにグラフが表示されます。
温度データを折れ線グラフで表示させてみます。
まずは以下のようなグラフ表示用のデータを返すPHPプログラムを作成します。
<?php $pdo = new PDO('mysql:host=localhost;dbname=yourdb;charset=utf8','account','password'); switch ($_SERVER['REQUEST_METHOD']) { case 'GET': $sth = $pdo->prepare("SELECT datetime, temp FROM sensorvalues order by datetime"); $sth->execute(); $tempData = array(); while($row = $sth->fetch(PDO::FETCH_ASSOC)){ $tempData[]=array( 'label'=>$row['datetime'], 'y'=>(float)$row['temp'] ); } //jsonとして出力 header('Content-type: application/json'); echo json_encode($tempData); } ?>
データベースのレコードを1件ずつ読み込んで配列に格納して最終的JSON形式で出力します。ここで、’label’がCanvasJSのラベルになり、’y’がグラフの値になります。’y’は数値形式なので、(float)を指定しています。こうしないと””で囲まれる文字列データになってしまいます。以下のような形式で出力されます。
{"label":"2017-04-01 16:33:50","y":21.44}, {"label":"2017-04-01 16:34:02","y":21.49}, {"label":"2017-04-01 16:35:02","y":21.14}, {"label":"2017-04-01 16:36:01","y":21.12}, {"label":"2017-04-01 16:37:02","y":21.19}
このデータを取得して、グラフ表示するページが以下です。CanvasJSはCDNを利用しています。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>センサーデータ</title> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" /> <script src="//cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script> </head> <body> <nav class="navbar navbar-default navbar-static-top navbar-inverse"> <div class="container"> <div class="navbar-header"> <a href="#" class="navbar-brand"> Sensor Data </a> </div> </div><!-- container --> </nav> <div class="container"> 温度データグラフ<br /> <div id="canvasjs"></div> <input id="btn_1" type="button" value="データ取得" /> <script type="text/javascript"> //画面構築完了後 $(function() { //ボタンのクリックイベントで $("#btn_1").click(function(){ //データを取得し、jsonというオブジェクトに入れる $.getJSON("http://domainOrIP//tempvalues.php", function(tmpdata){ var canvasjs = document.getElementById('canvasjs'); var chart = new CanvasJS.Chart(canvasjs, { title: { text: "温度データ" //グラフタイトル }, theme: "theme1", //デフォルトテーマに設定 data: [{ type: 'line', //グラフの種類 dataPoints: tmpdata //表示するデータ }] }); chart.render(); }); }); }); </script> </div><!-- /container --> </body> </html>
以下のようなページが表示されました。それ程長い時間でもなく普通の室温なのでさほど変化はありませんが、確かにグラフで表示されました。
以上で最低限ですがデータが表示されました。次回は一定以上の温度になったらメールを送信するアラート機能を追加します。
技術要素の補足と雑感等
HTMLとCSS
何といってもWebで表現するための需要な要素です。但し私は開発系エンジニアなので基本的な使い方しか出来ません。最近ではもっぱらBootstrapを使っています。
JavaScript
プログラミング言語の一つですが、これもWebで表現するWebを活用するために不可欠となっていると思います。(※一時期、人気がなかったというか評価が低くなっていた時代もあったと思います。)今現在JavaScriptがWebに必要不可欠となっている要素にAjaxがあると思います。Ajaxの非同期通信では、ユーザビリティの向上やブラウザとサーバとの間の通信軽量化を実現しています。IoT関連でも幅広く利用されていると思います。