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

システム開発エンジニアの西田五郎が運営しております。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

執筆者:

関連記事

Raspberry Piをモニターとキーボードなしで導入する(その2)初期設定とリモートデスクトップ

(※2021/05/02追記 現時点で最新版のRaspberry PI OSでモニターとキーボードなしで導入する手順を書きました。ぜひこちらを見て下さい。) Raspberry Piをモニターとキーボ …

SkyWayの利用(その4)Raspberry Piでの利用

前回の続きです。NTTコミュニケーションズ株式会社提供のリアルタイムコミュニケーションのためのプラットフォームであるSkyWayを使ってみます。前回はJavaScriptでカメラとマイクのストリーミン …

Raspberry Piをモニターとキーボードなしで導入する(2021年5月版 その3)リモートデスクトップの導入から初期設定まで

今現在(2021年5月)の方法でRaspberry Piをヘッドレス(モニターとキーボードなしの状態)で導入する方法について書いています。前回まででSSH経由でログインするところまで書きました。今回で …

Raspberry Piをモニターとキーボードなしで導入する(2021年5月版 その2)SSH接続とWifiの設定からログインまで

今現在(2021年5月)の方法でRaspberry Piをヘッドレス(モニターとキーボードなしの状態)で導入する方法について書いています。前回は全体概要からSDカードの作成まで書きました。今回は作成し …

Raspberry PiでのNode.jsの導入(その1)インストールと動作確認

Node.jsとは、Node.js 日本ユーザグループのサイトから引用させて頂きますと、「Node.jsは高速でスケーラブルなネットワークアプリケーションを 簡単に構築するためにChrome の Ja …