- 記事一覧 >
- ブログ記事
BME280で取得した温湿度気圧をWeb画面に表示する(python,wiringpi,apache)
はじめに
ラズベリーパイとセンサーを組み合わせて温度、湿度、気圧のデータを取得し Web 画面にグラフを表示するシステムを構築しました。いわゆる IoT です。python,wiringpi,apache を使用して、python プログラム(GitHub/wiringpi-python-bme280)でデータを取り出して記録 →Web 画面にグラフを表示までやっていきます。
「BME280 で取得した温湿度気圧を Web 画面に表示する(wiringpi-php8 使用)」の Python 版になります。
「Raspberry Pi 4 に温湿度気圧センサ BME280 を取り付けてデータを LCD 1602A に表示する」は、センサーと LCD の取り付け、単体動作確認を行っています。今回、こちらの作業の続きになります。
【 wiringpi 】
wiringpi(ワイヤリングパイ)とは、GPIOを操作するライブラリです。C言語、Python用に有ります。
※php7,8に対応したものが無かったため、作成し、githubに公開しています。
php8対応版:wiringpi-php8
php7対応版:wiringpi-php7
・環境構築 - apache2、mod_wsgi インストール
・環境構築 - pip インストール
・bme280.py でデータロギング
・Web 画面にグラフを表示
・複数の観測ノードに対応
今回の検証環境は、
LABISTS Raspberry Pi 4 STARTER KIT
Raspbian GNU/Linux 10 (buster)
Python 3.7.3
温湿度気圧センサBME280
LCD 1602A
Apache 2.4.38
wiringpi 2.60.1
Flask 1.0.2
になります。
画面の画像は、「BME280で取得した温湿度気圧をWeb画面に表示する(wiringpi-php8使用)」と同じものは使いまわしています。
環境構築 - apache2、mod_wsgi インストール
ラズパイ本体に Web サーバー apache2 をインストールします。まずは、以下の状況を目指します。
$ sudo passwd root
$ su
# apt update
# apt install apache2
以降、sudoを省略し、root権限でコマンドを入力しているものとします。
apt install
には-yを付けて、? [Y/n]
のような確認は省略します。
/var/www/html/index.html
が自動的に作成されますので、http://[ラズパイのIPアドレス]/
にアクセスします。
⇒Apache2 Debian Default Page が表示されればOKです。
mod_wsgi をインストールします。
# apt install -y libapache2-mod-wsgi-py3
【 mod_wsgi 】
mod_wsgiとは、WSGI (Web Server Gateway Interface) インターフェースに準拠した PythonのプログラムをApache HTTP Serverで動作させるためのモジュールです。
【 WSGI 】
Web Server Gateway Interface (WSGI; ウィスキー) は、WebサーバとWebアプリケーションを接続するための、標準化されたインタフェース定義です。
WSGIで動くプログラムは、WebサーバーがWSGIに対応していれば、無改修で動くという理屈になります。
環境構築 - pip インストール
wiringpi インストール
wiringpi を pip でインストールします。今回 Python3 で動かしたいため、pip3 でインストールします。
# pip3 install wiringpi
Flask
Flask を pip でインストールします。※検証環境では、最初からインストールされていました。
# pip3 install Flask
【 Flask 】
Flask(フラスコ/フラスク)はPythonのWebアプリケーションフレームワークです。標準で提供する機能を最小限に保っているため、小規模なアプリに向いています。
bme280.py でデータロギング
wiringpi-python-bme280のopt/bme280.py
を使って、データロギングを行います。opt/bme280.py
は、温湿度気圧センサ BME280 からデータを取得し、LCD 1602A に表示すると同時に、/var/log/bme280log/YYYYMMDD.log にデータを記録し続けるプログラムです。
wiringpi-python-bme280からwiringpi-python-bme280-main.zip
をダウンロードして、/home/pi に置かれているものとします。
# cd /home/pi
# unzip wiringpi-python-bme280-main.zip
# cd /home/pi/wiringpi-python-bme280-main/opt
# chmod 755 bme280.py
# ./bme280.py
⇒/var/log/bme280log/YYYYMMDD.log に
# tail /var/log/bme280log/20210627.log
date time temp humid press
2021/06/27 17:05:00 26.15 47.05 999.00
2021/06/27 17:10:00 25.79 42.96 998.98
2021/06/27 17:15:00 25.91 46.81 999.21
2021/06/27 17:20:00 26.13 50.05 999.40
のように記録されていれば、bme280.py
と温湿度気圧センサ BME280 の動作は、OKです。※5分間隔で記録します。起動して5分後に初めて YYYYMMDD.log に出力されます。
のように LCD に表示されていれば、bme280.py
と LCD 1602A の動作は、OKです。
止めるときは、以下のコマンドになります。
# cd /home/pi/wiringpi-python-bme280-main/opt
# ./bme280.py stop
再起動時の自動起動は、以下の設定になります。
# cd /home/pi/wiringpi-python-bme280-main/opt
# cp -p bme280.py bme280_inc.py lcd1602_inc.py /opt/
# vi /etc/rc.local
exit 0
の前に/opt/bme280.py
を追加します。
/opt/bme280.py
exit 0
Web 画面にグラフを表示
グラフ表示用にプログラムを配置します。
# cd /home/pi/wiringpi-python-bme280-main
# cp html/bme280.html /var/www/html/
# cp -r js /var/www/html/
# mkdir /var/www/flask
# cp py/app.wsgi /var/www/flask/
# cp py/app.py /var/www/flask/
# cp py/getlogdata.py /var/www/flask/
# chown -R www-data:www-data /var/www/html /var/www/flask /var/log/bme280log
ここまでで以下の配置になるはずです。
# find /var/www/html /var/www/flask -type f
/var/www/html/js/jquery.flot.crosshair.min.js
/var/www/html/js/jquery-1.8.3.min.js
/var/www/html/js/jquery.flot.min.js
/var/www/html/js/excanvas.min.js
/var/www/html/js/jquery.flot.tooltip.min.js
/var/www/html/bme280.html
/var/www/html/index.html
/var/www/flask/getlogdata.py
/var/www/flask/app.py
/var/www/flask/app.wsgi
apache の設定を作成します。
mod_wsgi を使うため、以下の設定にします。
# vi /etc/apache2/sites-available/flask_wsgi.conf
<VirtualHost *:80>
ServerName xxx.example.com
ServerAdmin xxx@example.com
DocumentRoot /var/www/html
WSGIDaemonProcess app user=www-data group=www-data threads=5
WSGIScriptAlias /flask /var/www/flask/app.wsgi
WSGIChunkedRequest On
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/flask/>
WSGIProcessGroup app
WSGIScriptReloading On
Require all granted
Options FollowSymLinks
AllowOverride All
</Directory>
</VirtualHost>
設定を反映して、apache を再起動します。
# a2ensite flask_wsgi
# a2dissite 000-default
# systemctl restart apache2
a2ensite flask_wsgi
:/etc/apache2/sites-enabled/flask_wsgi.conf が作成されて、flask_wsgi.confが有効になります。これは、/etc/apache2/sites-enabled/flask_wsgi.conf -> ../sites-available/flask_wsgi.conf
とシンボリックリンクになっています。※手動でシンボリックリンクを作成しても有効にできます。
a2dissite 000-default
:000-defaultはapacheのデフォルトの設定で、flask_wsgi.confだけ有効にしたいため、これを無効にしています。こちらは、逆にシンボリックリンクを削除しています。
以下のような流れで、グラフを表示します。
http://[ラズパイのIPアドレス]/bme280.html
をブラウザで表示
↓
jQuery の ajax でhttp://[ラズパイのIPアドレス]/flask/getlogdata
にアクセス
↓WSGIScriptAlias /flask /var/www/flask/app.wsgi
の設定により、/var/www/flask/app.wsgi
起動
↓app.wsgi
→ app.py
の以下のルーティング設定により、getlogdata.py
の getlogdata()呼び出し
#!/usr/bin/ python3
# -*- coding: utf-8 -*-
from flask import Flask
import getlogdata
import secrets
app = Flask(__name__)
app.config["JSON_AS_ASCII"] = False
secret = secrets.token_urlsafe(32)
app.secret_key = secret
@app.route("/getlogdata", methods=["GET", "POST"])
def get():
return getlogdata.getlogdata()
if __name__ == "__main__":
app.run()
↓
/var/www/flask/getlogdata.py が /var/log/bme280log/YYYYMMDD.log を読み取って、json を返す。
↓
ブラウザに json データが返ってきて、/js/jquery.flot.min.js でグラフ描画
グラフ上にマウスホバーすると、/js/jquery.flot.tooltip.min.js で値を表示
構成を図示すると、以下です。
http://[ラズパイのIPアドレス]/bme280.html
にアクセスしてみます。
表示されました!
複数の観測ノードに対応
以下の構成にして複数のノード(ラズパイ+センサ)の結果を一画面に表示します。
観測ノード(ラズパイ+センサ)インストール
観測ノード(ラズパイ+センサ)を作成します。(今回は2台)
以下の構成にしてデータ収集と応答だけに特化します。
上述の手順の通り、
wiringpi、apache、mod_wsgi、Flask をインストールして、wiringpi-python-bme280 からwiringpi-python-bme280-main.zip
をダウンロードして、/home/pi に置かれているものとします。
データのロギングを開始します。
# cd /home/pi
# unzip wiringpi-python-bme280-main.zip
# cd /home/pi/wiringpi-python-bme280-main/opt
# chmod 755 bme280.py
# ./bme280.py
ログデータ取得 API の設定をします。(bme280.html、js は必須ではありません。)
# cd /home/pi/wiringpi-python-bme280-main
# cp html/bme280.html /var/www/html/
# cp -r js /var/www/html/
# mkdir /var/www/flask
# cp py/app.wsgi /var/www/flask/
# cp py/app.py /var/www/flask/
# cp py/getlogdata.py /var/www/flask/
# chown -R www-data:www-data /var/www/html /var/www/flask /var/log/bme280log
# vi /etc/apache2/sites-available/flask_wsgi.conf
<VirtualHost *:80>
ServerName xxx.example.com
ServerAdmin xxx@example.com
DocumentRoot /var/www/html
WSGIDaemonProcess app user=www-data group=www-data threads=5
WSGIScriptAlias /flask /var/www/flask/app.wsgi
WSGIChunkedRequest On
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/flask/>
WSGIProcessGroup app
WSGIScriptReloading On
Require all granted
Options FollowSymLinks
AllowOverride All
</Directory>
</VirtualHost>
# a2ensite flask_wsgi
# a2dissite 000-default
# systemctl restart apache2
curl コマンドで getlogdata.py の確認を確認します。
# curl -X POST --data "TYPE=CURRENT" http://localhost/flask/getlogdata
{"datetime":"2021/06/27 18:37:13","humid":"49.15","press":"999.71","temp":"26.14"}
のように現在値が返ればOKです。
インストール - 画面兼中継サーバー
上述の手順の通り、apache、mod_wsgi、Flask がインストール済みとします。(wiringpi は不要です。)
中継サーバーは、curl の機能を使うため、pycurl が必要です。
pycurl を pip でインストールします。
# apt install libcurl4-openssl-dev libssl-dev
# pip3 install pycurl
【 pycurlについて 】
libcurlをpython3のプログラムで利用できるものです。今回、先に開発したphp版(itc-lab/wiringpi-php-bme280)がcurlライブラリを使っていたため、pycurl使用縛りとしました。
wiringpi-python-bme280 から
wiringpi-python-bme280-main.zip
をダウンロードして、/home/piに置かれているものとします。# cd /home/pi
# unzip wiringpi-python-bme280-main.zip
# cd wiringpi-python-bme280-main
# cp html_relay/bme280s.html html_relay/rooms.json /var/www/html/
# cp -r js /var/www/html/
# mkdir /var/www/flask
# cp py_relay/app_relay.wsgi /var/www/flask/
# cp py_relay/app_relay.py /var/www/flask/
# cp py_relay/proxyproc.py /var/www/flask/
# chown -R www-data:www-data /var/www/html /var/www/flask
# vi /var/www/html/rooms.json
この例のように、ノード(ラズパイ+センサ)の台数分の IP アドレスを設定します。
今回は、
192.168.2.32
192.168.2.38
2台とします。※192.168.2.33、192.168.2.34 はコメントアウトされています。
↓
[
{ "url": "http://192.168.2.38/", "name": "居間" },
{ "url": "http://192.168.2.32/", "name": "洋室1" },
{ "//url": "http://192.168.2.33/", "name": "洋室2" },
{ "//url": "http://192.168.2.34/", "name": "洋室3" },
{}
]
apache の設定を作成します。
mod_wsgi を使うため、以下の設定にします。
# vi /etc/apache2/sites-available/flask_wsgi.conf
<VirtualHost *:80>
ServerName xxx.example.com
ServerAdmin xxx@example.com
DocumentRoot /var/www/html
WSGIDaemonProcess app_relay user=www-data group=www-data threads=5
WSGIScriptAlias /flask /var/www/flask/app_relay.wsgi
WSGIChunkedRequest On
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/flask/>
WSGIProcessGroup app_relay
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
Require all granted
Options FollowSymLinks
AllowOverride All
</Directory>
</VirtualHost>
WSGIApplicationGroup %{GLOBAL}:
proxyproc.pyで stdoutをBytesストリームに切り替え(io.BytesIO())→元に戻す という処理があるのですが、アクセスが交錯すると、戻っていない状態で処理が走ることがありました。この設定をすると、正しく動作しました。https://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIApplicationGroup.html
記載の"sub interpreter"ではなく、"first interpreter"で動作させないといけないパターンだったと思われます。※interpreterとはインタープリタの事で、Python言語を解する実行体、同時通訳者のような意味です。
# a2ensite flask_wsgi
# a2dissite 000-default
# systemctl restart apache2
Web 画面にグラフを表示
http://[画面兼中継サーバー]/bme280s.html
にアクセスします。
できました!
その他、宣伝、誹謗中傷等、当方が不適切と判断した書き込みは、理由の如何を問わず、投稿者に断りなく削除します。
書き込み内容について、一切の責任を負いません。
このコメント機能は、予告無く廃止する可能性があります。ご了承ください。
コメントの削除をご依頼の場合はTwitterのDM等でご連絡ください。