IoTシステムをつくってみよう【Web表示編】

IoTシステムをつくってみようシリーズ

IoTシステムをつくってみよう【構想編】

IoTシステムをつくってみよう【データ取得編】

IoTシステムをつくってみよう【データ送信・保存編】

 

はじめに

引き続き簡単なIoTシステムを作成していきます。

前回は取得したデータをサーバーに送り、そのデータを保存することができました。

今回は取得したデータをWeb画面に表示したいと思います。

準備

今回は取得したデータをWeb画面にグラフで表示したいと思います。

そのため、webサーバ側のプログラムを変更していきます。

グラフの描画を簡単に行うため「chart.js」というjavascriptライブラリを使用します。

以下のコマンドでNodeの「testweb」プロジェクトフォルダに移動し、chart.jsをインストールします。

cd testweb
npm install chart.js

インストール後、「testweb/node_modules/chart.js/dist/」の「chart.js」ライブラリを

「testweb/public/javascripts/」フォルダにコピーします。

 

次に、webページからサーバーへ通信を行う必要があるため、「jQuery」というjavascriptライブラリを使用します。

jQueryのHPへアクセスし、「Download jQuery」をクリックし、

Download jQuery
「Download jQuery」ボタン
Download the compressed, production jQuery X.X.X
「Download the compressed, production jQuery X.X.X」を右クリック

「Download the compressed, production jQuery X.X.X」を右クリックして、「名前を付けてリンク先を保存」を選び、

「jquery-3.6.0.min.js」を保存し、「testweb/public/javascripts/」フォルダにコピーします。

webサーバー動作作成

前回までの温湿度データの受信、保存に加えて、webページからの通信に対して、保存した温湿度データを返信する処理を加えます。

「testweb/routes/index.js」ファイルを以下のように書き換えます。

var express = require('express');
var router = express.Router();

// ホームページの表示
router.get('/', function(req, res, next) {
	res.render('index', { title: 'Express' });
});

// 「fs」モジュールの使用
var fs = require('fs');

// 温湿度データの保存フォルダ
var read_path = "data/";

// POSTリクエスト受信処理
router.post('/post_temp', function(req, res) {
	console.log('req_tmp:' + req.body.tmp);		//受信メッセージ表示 温度
	console.log('req_hum:' + req.body.hum);		//受信メッセージ表示 湿度
	res.send('Hello Pyhon POST');			//応答メッセージ送信

	// 日付の取得
	var date = new Date();																			// 現在の日付時刻を取得
	var year = date.getFullYear();					// 年を西暦で取得:YYYY
	var month = ('0' + (Number(date.getMonth())+1)).slice(-2);	// 月を2桁で取得:MM
	var day = ('0' + date.getDate()).slice(-2);			// 日を2桁で取得:DD
	var strDate = year + '-' + month + '-' + day;			// 日付を"YYYY-MM-DD"の形式へ

	// 時刻の取得
	var hour = ('0' + date.getHours()).slice(-2);			// 時間を2桁で取得:HH
	var minute = ('0' + date.getMinutes()).slice(-2);		// 分を2桁で取得:MM
	var seconds = ('0' + date.getSeconds()).slice(-2);		// 秒を2桁で取得:SS
	var strTime = hour + ':' + minute + ":" + seconds ;		// 時刻を"HH:MM:SS"の形式へ

	var filepath = read_path + strDate + ".csv"				// 保存するファイルパスの指定
	var data = req.body.tmp + "," + req.body.hum + "," + strTime+ "\n"	// データをカンマ区切りにする

	fs.appendFileSync(filepath,data,'utf-8');				// ファイルの追記
});

// グラフデータ取得リクエスト受信処理
router.get('/get_data', function(req,res){
	// 日付の取得
	var date = new Date();						// 現在の日付時刻を取得
	var year = date.getFullYear();					// 年を西暦で取得:YYYY
	var month = ('0' + (Number(date.getMonth())+1)).slice(-2);	// 月を2桁で取得:MM
	var day = ('0' + date.getDate()).slice(-2);			// 日を2桁で取得:DD
	var strDate = year + '-' + month + '-' + day;			// 日付を"YYYY-MM-DD"の形式へ

	var filepath = read_path + strDate + ".csv"			// 読み込むファイルパスの指定

	var list_temp = [];			// 温度データ配列
	var list_humi = [];			// 湿度データ配列
	var list_time = [];			// タイムスタンプ配列

	// 温湿度データファイルがあるかどうか
	if(fs.existsSync(filepath)){
		// ファイルが存在する場合
		var data = fs.readFileSync(filepath, 'utf-8');		// ファイルを読み込み、文字列へ
		fs.close;						// ファイルを閉じる
		data = data.split(/\n/);				// 文字列を一行ごとに分けて配列データへ
		for (var i = 0; i < (data.length - 1); i++) {		// 文字列を一行ごとに順に処理
			data[i] = data[i].split(',');			// ','区切りでデータを分ける
			list_temp.push(Number(data[i][0]));		// 1番目のデータを数値に変換し温度データ配列へ
			list_humi.push(Number(data[i][1]));		// 2番目のデータを数値に変換し湿度データ配列へ
			list_time.push((data[i][2]));			// 3番目のデータをタイムスタンプ配列へ
		}
	}else{
		// ファイルが存在しない場合、エラーメッセージ
		console.log( "ファイルが存在しません");
	}

	// json形式で各データを返信
	res.json({
		"temp" : list_temp,
		"humi" : list_humi,
		"time" : list_time
	});
});

module.exports = router;

webページ作成

今回はNodeのプロジェクト作成時に、テンプレートエンジンに「Pug」を指定しており、

「Pug」はHTMLを書くためのJavaScriptテンプレートエンジンで、HTMLの記述を効率化することができます。

「testweb/views/index.pug」ファイルを以下のように書き換えます。

doctype html
html
	head
		title="温湿度データグラフ"
		link(rel='icon', href='data:,')
		link(rel='stylesheet', href='/stylesheets/style.css')

		//- Chart.jsライブラリの読み込み
		script(src='./javascripts/chart.js')
		//- jqueryライブラリの読み込み
		script(src='./javascripts/jquery-3.6.0.min.js')

	body(id='body',onload='onload()')
		div(class='display')
			p() 温湿度データグラフ

			// 日付表示領域
			p(id='date')
			// 温湿度グラフ表示領域
			canvas(id='myChart')

		script.
			// グラフのデフォルトデータ
			const defaultdata = {
				labels: [],
				temp: [],
				humi: []
			};

			// 温湿度グラフ表示領域にグラフを表示
			const chart = new Chart($('#myChart'), {
				// グラフの種類を 折れ線グラフに設定
				type: 'line',

				// データ設定
				data: {
					// ラベル設定
					labels: defaultdata.labels,				// デフォルト値を設定
					// グラフ表示データ設定
					datasets: [{
						// 温度グラフ設定
						label: '温度(℃)',				// 凡例を設定
						data: defaultdata.temp,				// デフォルト値を設定
						borderColor: 'rgba(60, 160, 220, 0.8)'		// グラフ色を設定
					}, {
						// 湿度グラフ設定
						label: '湿度(%)',				// 凡例を設定
						data: defaultdata.humi,				// デフォルト値を設定
						borderColor: 'rgba(60, 190, 20, 0.8)'		// グラフ色を設定
					}]
				}
			})

			// サーバへデータ取得リクエスト
			function get_data(){
				// サーバの'/get_data'へデータ取得リクエスト
				$.ajax({
					url:'/get_data',
					type: 'GET',
					timeout: 3000,
					data:{
					}
				})
				// リクエストの返信が来た場合の処理
				.done( (res)=>{
					chart.data.datasets[0].data = res.temp;			// グラフの温度データを上書き
					chart.data.datasets[1].data = res.humi;			// グラフの湿度データを上書き
					chart.data.labels = res.time;				// グラフのタイムスタンプを上書き
					chart.update();						// グラフ表示を更新
				});
			}

			// 画面読み込み時動作
			function onload(){
				// 日付取得
				var date = new Date();						// 現在の日付時刻を取得
				var year = date.getFullYear();					// 年を西暦で取得:YYYY
				var month = ('0' + (Number(date.getMonth())+1)).slice(-2);	// 月を2桁で取得:MM
				var day = ('0' + date.getDate()).slice(-2);			// 日を2桁で取得:DD
				var strdate = year + '/' + month + '/' + day;			// 日付を"YYYY/MM/DD"の形式へ
				// 日付表示領域に日付を表示
				$('#date').text(strdate)

				// サーバへデータ取得リクエスト
				get_data();
			}

			// 30秒間隔でサーバへデータ取得リクエストを定期実行
			const intervalId = setInterval(get_data, 30000);

動作の確認

前回と同じように送信側、受信側(webサーバー)ともに同じネットワークに接続します。

はじめに、「testweb」プロジェクトフォルダに移動し、以下のコマンドでwebサーバを起動します。

npm start

 

次に、送信側の”tmphum_post.py”を実行します。

python DHT11_Python/tmphum_post.py

 

次にwebブラウザが入っているPCを同じネットワークに接続し、

webブラウザから”http://xxx.xxx.xxx.xxx:3000″(xxxにはwebサーバーのIPアドレス)に接続します。

成功すると以下のような画面が表示されます。

温湿度グラフ

 

おわりに

今回で、4回にわたって作成してきたIoTシステムが完成しました。

このシステムでは、センサーを動かしてデータを取得し、サーバーに情報を集め、他の端末から表示するという一連の流れで、IoTによる情報の見える化までの動きを体験できます。

これを発展させると、工作機械などに温度センサを取り付けて情報を集め、異常発生データと関連付けて予知保全に活用する等の応用が可能です。

今回の記事がIoTを始めるきっかけになれれば嬉しいです。