株式会社インデペンデンスシステムズ横浜

システム開発エンジニアの西田五郎が運営しております。Raspberry Pi や Arduino その他新規開発案件のご依頼をお待ちしております。

IoT Raspberry Pi

Raspberry PiでIoT(温度・湿度・気圧データ編 その3)データ表示とグラフ表示

投稿日:2017年4月2日 更新日:

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関連でも幅広く利用されていると思います。

AdSense

AdSense

-IoT, Raspberry Pi

執筆者:

関連記事

感染症対策のためのIoT技術(その4)WebRTCを利用したリモート関連システム

感染症対策のためのIoT技術について書いています。今回はWebRTC(Web Real-Time Communication)を利用したリモート関連システムについてです。リモート関連システムとは具体的 …

Kivyでの画面遷移(Screen Managerの使い方)について

Raspberry Piの環境でKivyを使っています。今回は画面遷移についてです。その画面遷移のためにScreen Managerというwidgetを使ってみます。 今現在のRaspberry Pi …

Raspberry PiでAC100V(ソリッド・ステート・リレー)制御

Raspberry PiでAC100VのON/OFF制御を試してみました。今回そのために以下のソリッド・ステート・リレーキットを利用しました。この製品を選んだ理由としては「扱いが簡単」かなと思ったから …

無線マイコン ToCoStick(トコスティック)をRaspberry Piで使ってみた

無線マイコンの ToCoStick(トコスティック)をRaspberry Piで使ってみました。前回の記事でブレッドボードが親機でToCoStickが子機という設定でとりあえずということで通信が出来る …

温度センサADT7410(その1)i2C通信とは

温度センサのADT7410を使ってみます。ADT7410はアナログ・デバイセズ社の製品ですが、実際には以下の秋月さんのモジュールを使います。 ADT7410使用 高精度・高分解能 I2C・16Bit …