Raspberry Pi で温度・湿度・CO2を監視する
コロナ禍によって巷にCO2センサーがあふれていますが、適切な空調設定や換気のために、室内の温度・湿度・CO2を測定してみたいと思います。
まず、Rapsberry Piに温度・湿度・CO2センサを接続し、空気の状態をモニタリングできるようにします。測定したデータは時系列データベースであるInfluxDBに保存し、システム監視等でよく使われるデータ可視化ツールGrafanaでデータの可視化を行います。これすべてをRaspberry Piの中で完結させます。
CO2センサーについて
CO2センサーには、測定方式によっていくつかの種類がありますが、一般的に入手しやすいセンサーはNDIR方式(非分散型赤外)が多いと思います。原理は正確で詳しい説明をされているサイトがたくさんあるのでそちらを参照してもらうとして、センサーの一部が不織布で覆われていて、測定中は赤く点滅するのが特徴です。他にも、水素濃度から等価的にCO2濃度を測定する eCO2 (qquivalent CO2) 方式などもあります。こちらは、CO2そのものをターゲットしているわけではないので、高い精度は出しにくいようです。
今回はCO2センサーとして SENSIRION の SCD-4x を使用します。温度・湿度・CO2センサーが搭載されており、NDIR方式とは別の、光音響センシング原理により小型化を実現させています。
Rasberry Piと簡単に接続でききるように、評価ボードの形になった SEK-SCD-41 を使用します。
CO2の測定
I2C の有効化
SCD-41とRaspberry PiとはI2Cで通信するため、 raspi-config
でI2Cを有効化します。
sudo raspi-config
メニューから 3 Interface Options
- P5 I2C
を選択し、I2Cを有効化します。設定後の再起動は必要ないようです。
ソフトウェアのインストール
SCD-41と通信するためのソフトウェアをインストールします。SENSIRION の Github でSINSIRIONの様々なセンサーのソフトウェアが公開されており、ドキュメントも非常に充実しています。SCD-4xのRaspberry Pi用のソフトウェアも公開されています。
ただし、SINSIRIONが公開しているトライバはC言語で実装されているため、センサーから測定値を読みだした後の扱いやすさを考慮し、Pythonで実装されているAdafruitのドライバを使用します。
Pythonの仮想環境を作成し、ドライバをインストールします。
python3 -m venv .venv
. .venv/bin/activate
pip install adafruit-circuitpython-scd4x
接続
一度、Raspberry Piの電源を落とし、SENSIRIONのGithubを参考に、SEK-SCD-41のジャンパー線と、Raspberry Piのピンヘッダを接続します。
SCD-41のデータシートを見ると、電圧は 2.4 - 5.5V となっているので、Raspberry PiのGPIOは3.3Vのもと5Vのもの、どちらでもよさそうです。
Raspberry Piの電源を投入し、I2Cのデバイスとして認識されているかを確認します。 0x62
として認識されているのが確認できます。
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- 62 -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
動作確認
Adafuruitのサンプルコードをそのまま実行してみます。
$ python scd4x-example.py
Serial number: ['0x81', '0xba', '0x1f', '0x7', '0x3b', '0xe3']
Waiting for first measurement....
CO2: 991 ppm
Temperature: 31.5 *C
Humidity: 54.4 %
CO2: 969 ppm
Temperature: 31.2 *C
Humidity: 55.1 %
CO2: 974 ppm
Temperature: 30.9 *C
Humidity: 55.7 %
無事、測定値の取得を行うことができました。それっぽい値が取れています。明らかにCO2濃度がおかしい場合は、自動補正が効くのを待つか、強制的に補正を行う必要があります。詳細はデータシートに記載されていますが、今回は省略します。
次は、データの保存と蓄積を行います。
データの保存
InfluxDB のインストール
InfluxDB をインストールし、自動起動の設定を行います。InfluxDBは2.0がリリースされていますが、ARM系は64bit OSしかバイナリが用意されていないようなので、apt
コマンドでインストールできる1.x系をインストールします。
sudo apt install influxdb
sudo systemctl start influxdb
sudo systemctl enable influxdb
1.6.4
がインストールされました。(随分と古いような…。)
$ dpkg -l | grep influxdb
ii influxdb 1.6.4-1+deb10u1 armhf Scalable datastore for metrics, events, and real-time analytics
Python クライアントのインストール
InfluxDB にデータを書き込むために Python クライアントをインストールします。2.0系統はクライアントが異なるので注意してください。
pip install influxdb
最初にデータベースとユーザー、リテンションポリシーを作成します。InfluxDBではリテンションポリシーを設定できるため、バッチ処理で古いデータを削除する必要はありません。また、今回は使用しませんが、continuous queriesといって、クエリをを定期実行する機能もあるので、生データは3か月保存するけど、1時間毎に最大・最小・平均を求め、ダウンサンプリングしたデータは1年間保存する、なんて使い方もできます。
データの書き込み
先ほどのSCD-4x用のサンプルを改修し、測定データをInfluxDBに書き込むようにします。変化が分かり易いように1秒間隔でデータを書き込んでいますが、実際に運用する場合は、microSDの耐久性を考慮し、もう少し長い間隔にした方がよいでしょう。(ドライブレコーダーなどと比較すれば、1秒間隔でもかわいいものですが。)
InfluxDBでは、RDBMSにおけるテーブルに相当するものをmeasurement
と呼び、カラムに相当するものをfield
呼びます。このfield
に測定値である温度・湿度・CO2を保存していきます。またレコードには tag
をつけることができ、この tag
を使ってフィルタリングやグルーピングを行うことができます。
スクリプトを実行します。
$ python scd4x-influxdb-write.py
Serial number: ['0x81', '0xba', '0x1f', '0x7', '0x3b', '0xe3']
Waiting for first measurement....
[{'measurement': 'air_condition', 'tags': {'host': 'raspberry-pi-01'}, 'time': '2021-07-30T13:02:56.959541+00:00', 'fields': {'tempareture': 29.8, 'humidity': 46.3, 'co2': 1661}}]
[{'measurement': 'air_condition', 'tags': {'host': 'raspberry-pi-01'}, 'time': '2021-07-30T13:03:01.744396+00:00', 'fields': {'tempareture': 29.5, 'humidity': 47.0, 'co2': 1635}}]
[{'measurement': 'air_condition', 'tags': {'host': 'raspberry-pi-01'}, 'time': '2021-07-30T13:03:06.531361+00:00', 'fields': {'tempareture': 29.1, 'humidity': 47.7, 'co2': 1636}}]
[{'measurement': 'air_condition', 'tags': {'host': 'raspberry-pi-01'}, 'time': '2021-07-30T13:03:11.317588+00:00', 'fields': {'tempareture': 28.8, 'humidity': 48.4, 'co2': 1629}}]
データが書き込めているかを確認してみます。直近、1分間の温度・湿度・CO2を取得します。
$ python scd4x-influxdb-select.py
ResultSet({'('air_condition', None)': [
{'time': '2021-07-30T13:02:56.959541Z', 'tempareture': 29.8, 'humidity': 46.3, 'co2': 1661},
{'time': '2021-07-30T13:03:01.744396Z', 'tempareture': 29.5, 'humidity': 47.0, 'co2': 1635},
{'time': '2021-07-30T13:03:06.531361Z', 'tempareture': 29.1, 'humidity': 47.7, 'co2': 1636},
{'time': '2021-07-30T13:03:11.317588Z', 'tempareture': 28.8, 'humidity': 48.4, 'co2': 1629}]})
データの可視化
InfluxDBに保存したデータを可視化するためにGrafanaをインストールします。
curl -sL https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list
sudo apt update
sudo apt install grafana
インストールが完了したら、Grafanaを起動し、自動起動を有効にします。
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
Webブラウザで http://raspberrypi:3000/login にアクセスします。 admin
/ admin
でログインします。初回ログインでは、パスワードの変更を要求されます。
サイドメニューから Configuration
- Data sources
を選択します。
Add data source
を選択します。
データソースとして最低限必要な設定項目は、Name
, URL
, Database
, User
, Password
になります。
サイドメニューから Create
を選択し、ダッシュボードを追加します。
Add an empty panel
を選択します。
パネルの編集画面で Data source
に先ほど作成したデータソースを設定し、Query を設定していきます。パネルの種類は右上で選択できます。
FROM
に、InfluxDB をセットアップした時の Retension policy
と Measurement
を設定します。Tag など、条件を追加する場合は WHERE
に追加していきます。
SELECT
で表示したい Field
(温度・湿度・CO2)を選択します。mean()
を設定すると、次に設定する GROUP BY
と合わせて、単位時間当たりの平均値が取得できます。
GROUP BY
に time($__interval)
を設定することにより、表示する時間(直近の何時間か?)に合わせて適切にグループ化してくれま。 fill
で欠損値のの補完方法指定します。 fill(null)
で、グラフが線にならずに点の集合になってしまう場合には、none
や linear
などを選びましょう。
色々設定するとこんな感じになります。
エアコンをつけていると、室温は設定温度のあたりでジグザクするようなグラフになるようです。
CO2は、外気が 400 ~ 500 ppm くらい、屋内でも 1,000 ppm 以下が推奨され、15,000 ppm を超えるようであれば換気が必要になります。
6畳程度の部屋では、一人でも閉め切っていると 15,000 ppm を超えることがあるようです。眠気や集中力の低下にもつながるので、こまめな換気を心がけましょう。
まとめ
Raspberry Pi と環境センサーを使って、室内の空気の状態を可視化することができました。大抵の温湿度センサーやCO2センサーは、I2CやUARTのインタフェースを持っているため、Raspberry Piからでも簡単に測定値を読みだすことができます。ネット上にはLEDを点灯させる(Lチカ)のたくさんありますので、それと組み合わせて、換気を促すような仕組みを実現できると思います。
Discussion
大変参考になりました.ありがとうございます.
Grafanaのインストール部分でリポジトリ情報を
/etc/apt/sources.list
に上書きするとその後のインストールに不具合がでるので,追記するか,またはsources.list.d以下に追加が良いのではと思いました.また,Rapsberry Pi の環境によっては通常のgrafanaが動作せず,grafana-rpiなら動作することがあるようでした
sudo apt install grafana-rpi