IoTシステムをつくってみよう【Web表示編】
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 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を始めるきっかけになれれば嬉しいです。