##概要
Raspberry PiでスイッチサイエンスのBME280モジュールを使用して、温湿度と気圧を測定し、WEBブラウザで確認できるようにする。どうせならグラフ化して表示したい。今回は、PHPのページ作成について記載します。なお、内容については私自身がよく分かっておりません。ヘルプとにらめっこしてとりあえず動いたという程度の内容です。
試行錯誤したけど全部忘れたので、結論だけ書きます。
サンプルコードは、スクリプトを実行して結果を返すだけですが、PHPで表示するために関数化した(のかな?)
そのまま返すのではなく変数に格納して、別スクリプトから読みだしている。
(用語がよくわからない^^;)
##WEBページの構造
/var/www/html/ にphpを配置。ここからスクリプトを実行する。
スクリプトは/home/pi/bme280/に配置、内容は以下。
ファイル名 | 内容 |
---|---|
bme280.py | CSVファイルを作成 |
bme280_custom.py | 温度、湿度、気圧を返す |
bme280_temp.py | 温度を返す |
bme280_humid.py | 湿度を返す |
bme280_pres.py | 気圧を返す |
一覧表とグラフの両方を見るためにこのようにしました。もっとうまいやり方があるとは思いますが。
/home/pi/bme280/data/ に観測値をcsvファイルとして保存する。csvファイルは日付単位で作成する。
##スクリプトの作成
###1.サンプルコードを修正する
bme280_sample.pyをbme280_custom.py にリネームして以下のように修正しました。
先頭部分は
先頭部分
(元)
from smbus2 import SMBus
import time
bus_number = 1
i2c_address = 0x76
bus = SMBus(bus_number)
(修正後)
import smbus
import time
bus_number = 1
i2c_address = 0x76
bus = smbus.SMBus(bus_number)
~~中略~~
def readData():
data = []
for i in range (0xF7, 0xF7+8):
data.append(bus.read_byte_data(i2c_address,i))
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
hum_raw = (data[6] << 8) | data[7]
#compensate_T(temp_raw)
#compensate_P(pres_raw)
#compensate_H(hum_raw)
t = compensate_T(temp_raw)
p = compensate_P(pres_raw)
h = compensate_H(hum_raw)
return p + "," + t + "," + h
def compensate_P(adc_P):
:
#print "pressure : %7.2f hPa" % (pressure/100)
return "%7.2f" % (pressure/100)
def compensate_T(adc_T):
:
#print "temp : %-6.2f ℃" % (temperature)
return "%.2f" % (temperature)
def compensate_H(adc_H):
:
#print "hum : %6.2f %" % (var_h)
return "%.2f" % (var_h)
###2.温度のみ返すスクリプトを作成
基本的にはcustomファイルから温度の部分のみを取り出したものです。
ちゃんと作るべきなんだろうけど、tだけ返せばいいわけで、bme280_custom.pyをコピー&リネームして、下記1行のみ変更。
(元)
def readData():
:
return p + "," + t + "," + h
(修正)
def readData():
:
return t
###3.湿度のみ返すスクリプトを作成
温度と同じです。
bme280_custom.pyをコピー&リネームして、下記1行のみ変更。
(元)
def readData():
:
return p + "," + t + "," + h
(修正)
def readData():
:
return h
###4.気圧のみ返すスクリプトを作成
温度と同じです。
bme280_custom.pyをコピー&リネームして、下記1行のみ変更。
(元)
def readData():
:
return p + "," + t + "," + h
(修正)
def readData():
:
return p
###5.CSVファイルに保存するスクリプトを作成
読みだした値をCSVファイルとして保存します。WEBに表示する際に、日付ごとに分けたいので、手っ取り早く日付単位でファイルを作成します。
#coding: utf-8
import bme280_custom
import bme280_temp
import bme280_pres
import bme280_humid
import datetime
import os
dir_path = '/home/pi/bme280/data'
now = datetime.datetime.now()
filename = now.strftime('%Y%m%d')
label = now.strftime('%H:%M')
date = now.strftime('%Y/%m/%d %H:%M')
csv = bme280_custom.readData()
csv_t = bme280_temp.readData()
csv_p = bme280_pres.readData()
csv_h = bme280_humid.readData()
if not os.path.exists('/home/pi/bme280/data'):
os.makedirs('/home/pi/bme280/data')
f = open('/home/pi/bme280/data/'+filename+'.csv','a')
f.write("'"+date+"',"+csv+"\n")
f.close()
f = open('/home/pi/bme280/data/'+filename+'_t.csv','a')
f.write("'"+date+"',"+csv_t+"\n")
f.close()
f = open('/home/pi/bme280/data/'+filename+'_p.csv','a')
f.write("'"+date+"',"+csv_p+"\n")
f.close()
f = open('/home/pi/bme280/data/'+filename+'_h.csv','a')
f.write("'"+date+"',"+csv_h+"\n")
f.close()
##WEBページの作成
###1.表形式で表示する
記録した温度、湿度、気圧を表形式でまとめて表示する。表の作成はGoogleChartを使用する。
<?php
$today = date("Ymd");
$csv_dir = '/home/pi/bme280/data/';
$csv_file = $today.'.csv';
$grapgh = '';
if (($handle = fopen($csv_dir.$csv_file, "r")) !== false) {
while (($line = fgets($handle)) !== false) {
$grapgh .= '['.rtrim($line).'],'.PHP_EOL;
}
fclose($handle);
}else{
echo 'no data';
}
?>
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["table"]});
google.setOnLoadCallback(drawTable);
function drawTable() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Time');
data.addColumn('number', 'Pressure[hPa]');
data.addColumn('number', 'Temperature[℃]');
data.addColumn('number', 'Humidity[%]');
data.addRows([
<?php echo $grapgh; ?>
]);
var table = new google.visualization.Table(document.getElementById('table_div'));
table.draw(data, {showRowNumber: true});
}
</script>
</head>
<body>
<div id="table_div"></div>
</body>
</html>
###2.グラフで表示する
記録した温度、湿度、気圧をそれぞれをグラフにして表示する。Y軸を複数にして重ねることもできるが、温度と湿度と気圧だと2桁と4桁なので単純に重ねると気圧しか見えなくなり、難しいので3つに分けた。グラフの作成はGoogleChartを使用する。
<?php
$today = date("Ymd");
$csv_dir = '/home/pi/bme280/data/';
$temp_file = $today.'_t.csv';
$grapgh_t = '';
$pres_file = $today.'_p.csv';
$grapgh_p = '';
$hum_file = $today.'_h.csv';
$grapgh_h = '';
if (($handle = fopen($csv_dir.$temp_file, "r")) !== false) {
while (($line = fgets($handle)) !== false) {
$grapgh_t .= '['.rtrim($line).'],'.PHP_EOL;
}
fclose($handle);
}else{
echo 'no data';
}
if (($handle = fopen($csv_dir.$pres_file, "r")) !== false) {
while (($line = fgets($handle)) !== false) {
$grapgh_p .= '['.rtrim($line).'],'.PHP_EOL;
}
fclose($handle);
}else{
echo 'no data';
}
if (($handle = fopen($csv_dir.$hum_file, "r")) !== false) {
while (($line = fgets($handle)) !== false) {
$grapgh_h .= '['.rtrim($line).'],'.PHP_EOL;
}
fclose($handle);
}else{
echo 'no data';
}
?>
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {packages:['corechart', 'line']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Time');
data.addColumn('number', 'Temperature[℃]');
data.addRows([
<?php echo $grapgh_t; ?>
]);
var options = {
title: 'Temprature by BME280(raspberry pi3)'
};
var chart = new google.visualization.LineChart(document.getElementById('chart1'));
chart.draw(data,options);
}
google.charts.load('current', {packages:['corechart', 'line']});
google.charts.setOnLoadCallback(drawChart2);
function drawChart2() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Time');
data.addColumn('number', 'Pressure[hPa]');
data.addRows([
<?php echo $grapgh_p; ?>
]);
var options = {
title: 'Pressure by BME280(raspberry pi3)'
};
var chart = new google.visualization.LineChart(document.getElementById('chart2'));
chart.draw(data,options);
}
google.charts.load('current', {packages:['corechart', 'line']});
google.charts.setOnLoadCallback(drawChart3);
function drawChart3() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Time');
data.addColumn('number', 'Humid[%]');
data.addRows([
<?php echo $grapgh_h; ?>
]);
var options = {
title: 'Humid by BME280(raspberry pi3)'
};
var chart = new google.visualization.LineChart(document.getElementById('chart3'));
chart.draw(data,options);
}
</script>
</head>
<body>
<div id="chart1"></div>
<div id="chart2"></div>
<div id="chart3"></div>
</body>
</html>
##WEBの設定と自動実行
###1.ファイルの配置
作成したPHPファイルを/var/www/html/に置きます。
作成したスクリプトファイルを/home/pi/bme280/に置きます。
bme280.pyのパーミッションを755に変更する。
sudo chmod 755 bme280.py
###2.自動実行の設定
cronを起動する。
sudo /etc/init.d/cron start
[ ok ] Starting periodic command scheduler: cron.
sudo apt install -y chkconfig
sudo chkconfig cron
cron on
スクリプトを登録する。bme280.pyを実行すると、ほかの4つはこの中で呼ばれるのでbme280.pyのみ登録すればよい。10分ごとにスクリプトを実行する。
初めて登録する場合、エディタの選択肢が出るので好きなものを指定する。
crontab -e
最下行に以下を追加。
*/10 * * * * python /home/pi/bme280/bme280.py
###3.動作確認
ブラウザで、ラズパイのIPアドレスを表示。
(例)
http://192.168.0.36/bme280.php
http://192.168.0.36/bme280-2.php
グラフはマウスをあてると吹き出しが出る。Google Chartは高性能だった。
##参考