Raspberry Pi Zeroで作る、お手軽簡単温湿度・二酸化炭素濃度測定装置

冬は暖房に石油ファンヒーターを使っているのですが、換気しないとどれくらい二酸化炭素が増えているのか気になったので、ささっと作ってみました。ついでに気温と湿度も測定して、それぞれがどういう動きをしているのか見れるようにしたら楽しいかなぁ~、と。商品として提供するわけではないので、かなりいい加減に最低限のことだけやっていますが、同じことを目論んでいる方の参考になればと。

この記事で作るもの

部屋の気温・湿度・二酸化炭素濃度を測定し、ほぼリアルタイムでグラフ表示する。

この装置でできること

  1. 気温、湿度、二酸化炭素濃度の測定
  2. 測定値をCSVで記録
  3. 測定値をグラフ表示Webサービスにアップして、いつでもどこでも測定値を確認

構成

測定端末

  1. Raspberry Pi Zero WH
  2. 二酸化炭素センサー MH-Z19
  3. 気温・湿度センサー DHT22
  4. 電源(ACアダプター)

ちなみに上記の二酸化炭素センサーですが、中華製の安物

サーバー

  1. Raspberry Pi3 Model B+
  2. 電源(ACアダプター)

確認画面

Ambient – IoTデータ可視化サービス

大まかな仕組み

  1. 端末は、各センサーの値をサーバーへHTTPでPOSTする
  2. サーバーは端末から値を受け取ったら、Ambientに送信する
  3. Ambientで、収集した値をグラフで見る

サーバーを使わずに端末から直接Ambientに送信してもいいのですが、一度サーバーに集約したほうがメンテナンスやデータ処理の面で色々と便利なので。

作り方

本装置のRaspberry PiのOSは、すべてRaspberry Pi OS Liteをインストールしています。

ごく基本的な機能しか使用していませんので、バージョン依存は特にはないと思います。

測定端末

Raspberry Pi Zeroと各センサーを下図のとおり配線します。MH-Z19はスルーホールだけでピンがないので、ピンヘッダーをはんだ付けしました。

MH-Z19用にシリアル通信を有効にします。

raspi-configを起動します

sudo raspi-config

「5 Interfacing Option」を選択します。

「P6 Serial」を選択します。

「Would you like a login shell to be accessible over serial? 」は、Noを選択します。

「Would you like the serial port hardware to be enabled? 」は、Yesを選択します。

再起動して設定を有効化します

sodo reboot

スクリプトの実行に必要なライブラリをインストールします。

sudo apt-get install python3-dev
sudo apt-get install python3-pip
sudo pip install mh-z19
sudo git clone --recursive https://github.com/freedom27/MyPyDHT
cd MyPyDHT/
sudo python3 setup.py install

下記のスクリプトをPiのホームディレクトリにpostenv.pyとして保存します。

#!/usr/bin/python
# coding: utf-8

import MyPyDHT
import time
import datetime
import requests
import mh_z19
import json

loopflag = 0
host = 'サーバーのIPアドレス'
port = 80
timeout = 60

while loopflag==0:
  try:
    # 現在時刻
    nowtime = datetime.datetime.now()
    # 温湿度の測定(4は、AM2303を接続したGPIOポート)
    humidity, temperature = MyPyDHT.sensor_read(MyPyDHT.Sensor.DHT22, 4)
    # 二酸化炭素濃度の測定(MH-Z19)
    co2 = mh_z19.read()
  except:
    # 一定時間後に再度測定
    time.sleep(5)
  else:
    # サーバーに値を送信
    payload = {'temp': temperature , 'humi' : humidity , 'co2' : co2["co2"]}
    url = 'http://' + str(host) + ':' + str(port) + "/recenv/recenv.py"
    r = requests.post( str(url) , data=payload, timeout=timeout )
    rcode = r.status_code
    if rcode == 200:
      loopflag = 1

センサーの値を取得して、そのままサーバーへPOSTするだけです。ただ、温湿度センサーの値取得によく失敗するので、成功するまでループさせています。

crontabを設定します。

sudo crontab -e
下記の設定を追加します。
*/10 * * * * sudo python3 /home/pi/postenv.py >/dev/null 2>&1

サーバー

Ambientのアカウントの準備

Ambientにアカウントを作成します。手順はAmbientのサイトを参照してください。

アカウントができたらチャネルを追加して、その「チャネルID」と「ライトキー」を控えておきます。

Raspberry Pi 3 Model B+のセットアップ

Raspberry Pi OS Liteを入れたRaspberry Pi 3 Model B+を起動して、Apacheをインストールします。

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install apache2

Ambientにデータを送信するのに必要なライブラリをインストールします。

sudo apt-get install python3-dev
sudo apt-get install python3-pip
sudo pip install git+https://github.com/TakehikoShimojima/ambient-python-lib.git

まず、端末からデータを受け取るスクリプトを配置するディレクトリを作ります。併せて、測定データやログを保存するディレクトリも作ります。

sudo mkdir /home/recenv
cd /home/recenv
sudo mkdir www
sudo mkdir data
sudo mkdir log
cd ../
sudo chown -R www-data:www-data recenv
sudo chmod -R 774 recenv
※dataやlogは実行権限はいらないので、664でもOKです。

wwwに下記のスクリプトrecenv.pyを配置します。

#!/usr/bin/python
# coding:utf-8

import cgi
import logging
from logging import getLogger, FileHandler, Formatter
import os
import datetime
import ambient

# 端末のIPアドレスの取得
remoteip = 'noip'
if 'REMOTE_ADDR' in os.environ:
  remoteip = os.environ['REMOTE_ADDR']

#
# ログの設定
#
log_filepath = '/home/recenv/log/' + remoteip + '.log'
if not os.path.exists(log_filepath):
    with open( log_filepath , "w" ):pass

logger = getLogger("Log")
logger.setLevel(logging.DEBUG)
file_handler = FileHandler(log_filepath , 'a' )
file_handler.setLevel(logging.DEBUG)
handler_format = Formatter('[%(asctime)s][%(levelname)s](%(filename)s:%(lineno)s) %(message)s')
file_handler.setFormatter(handler_format)
logger.addHandler(file_handler)

logger.info('Program START')

#
# POSTデータの取得
#
nowtime = datetime.datetime.now()

form = cgi.FieldStorage()
temperature = form["temp"].value
humidity = form["humi"].value
co2 = form["co2"].value
logger.info('Temp : %s', temperature)
logger.info('Humi : %s', humidity)
logger.info('CO2 : %s', co2)

recfilepath='/home/recenv/data/' + str(remoteip) + '.csv'

recfile = open(recfilepath , 'a')
recfile.write( \
    str(nowtime) + "," + \
    str(remoteip) + "," + \
    str(temperature) + "," + \
    str(humidity) + "," + \
    str(co2) + \
    "\n")
recfile.close()

ambi = ambient.Ambient(チャネルID, "ライトキー")
r = ambi.send({"d1": temperature, "d2": humidity, "d3": co2})

#
# 端末への返信
#
print("Content-Type: text/html\n")
print("<html><body>OK</body></html>")

logger.info('Program END')

スクリプトのパーミッションなどを変更します。

sudo chown -R www-data:www-data recenv.py
sudo chmod -R 554 recenv.py

今回はとりあえず動けばいいので、Apacheは最低限の設定だけします。

/etc/apache2/mods-available/mime.confを下記の通り書き換えます。

# AddHandler cgi-script .cgi
  ↓ コメントを外し、「.py」を追記
  AddHandler cgi-script .cgi .py

cgi.loadを有効化します。

sudo ln -s /etc/apache2/mods-available/cgi.load /etc/apache2/mods-enabled/cgi.load

/etc/apache2/conf-enabledに下記のrecenv.confを追加します。

# Define /zabbix alias, this is the default
<IfModule mod_alias.c>
    ScriptAlias /recenv /home/recenv/www
</IfModule>

<Directory "/home/recenv/www">
    Options FollowSymLinks ExecCGI
    AllowOverride None
    Require all granted
</Directory>

Aapcheを再起動します

sudo service restart apache2

結果

こんな感じで、測定した値が確認できます。

参考サイト