BFT名古屋 TECH BLOG

日々の業務で得た知識を所属するエンジニアたちがアウトプットしていきます。

【Python】Raspberry Pi + mh-z19でCO2濃度取得してみた

こんにちは、BFT名古屋支店の猫です。
昨日初めて黄色いスイカを食べました。違いはよく分からなかったですが美味しかったです!

はじめに

6~8月にかけて名古屋支店で作っている混雑状況可視化サービスでは、ラズパイで店内の滞在人数とCO2濃度を計測してweb画面に表示する、ということを行っています。
今回はセンサーを用いてCO2濃度を取得する手順を書いていきたいと思います!

使用環境

Raspberry Pi

$ uname -a
Linux raspberrypi 5.10.17-v7l+ #1421 SMP Thu May 27 14:00:13 BST 2021 armv7l GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
Codename:       buster

CO2センサ

パッケージ等

version
Python 3.7.3
pip 21.1.3
mh-z19 3.0.2

前提

  • Raspberry Pi にOSがインストールされていること
  • Raspberry Pi がインターネットに接続していること
  • 実行ユーザがsudo権限を持っていること

実行手順

1.ラズパイとCO2センサーを接続する

下図のようにラズパイとCO2センサーを接続する
(ファン付きのラズパイを使用したのでファンの接続(破線)も記載しています)

RaspberryPi,MH-Z19接続図
ラズパイ接続図

2.シリアル通信を有効にする

設定画面を開く

$ sudo raspi-config

「3 Interface Options」を選択する

「P6 Serial Port」を選択する

Would you like a login shell to be accessible over serial? で「いいえ」を選択する

Would you like the serial port hardware to be enabled? で「はい」を選択する

確認画面で「了解」を選択する

再起動する

$ sudo reboot

3.パッケージをインストールする

$ sudo pip3 install mh-z19

インストールしたパッケージについては以下を参照ください。
github.com

4.動作確認

$ sudo python3 -m mh_z19
⇒[sudo] <ユーザ名> のパスワード: ※パスワード+[Enter]を入力
⇒{"co2": 518}

Pythonのプログラム内で実行

今回はCO2濃度取得を、コマンドではなくプログラム内で実行する必要があったため、その方法も書いていきます。

Pythonのプログラム内で実行する場合、 以下の2通りの方法があります。

1. mh_z19モジュールを使用する
  ※プログラムはrootユーザで実行する

import mh_z19

CO2_conce = mh_z19.read_all()["co2"]

2.subprocessモジュールを使用してmh_z19コマンドを実行する
  ※プログラムは一般ユーザで実行する

プログラム自体は一般ユーザで実行したかったため、上記の2.の方法を選択しました。

こちらによれば設定変更によってroot権限なしでも1.の方法がとれそうでしたが、やってみたところ上手くいきませんでした……(メソ)。

これでPythonのプログラム内で実行できるようになりました。しかしまだ問題があります。

実行確認の出力からも分かるように、sudoをつけてコマンドを実行するとパスワードの入力が求められます。
プログラム内でsubprocessモジュールを使用しても同様で、手でパスワードを入力しないと処理が進まない状況。かなり不便です。

これをなくすために、コマンドに -S オプションを追加し、subprocessモジュールにinputとしてパスワードを与えます。

これで「一般ユーザで」「プログラムを実行し」「パスワードの手入力なしで」CO2濃度を取得できるようになりました。

完成コード

というわけで、出来上がったコードがこちら!
▼GetCO2.py

import subprocess
import re

#パスワード設定
passwd="MyPassword"

# CO2濃度取得 (パスワード自動入力)
cmd = "sudo -S python3 -m mh_z19"
cmd_out = subprocess.check_output(cmd.split(), input=passwd).decode('utf-8')

# (おまけ)正規表現マッチで値のみ取得
cmd_out = re.match(r'{\"co2\": (?P<conc>\d+)}', cmd_out)
CO2_conce = int(cmd_out.group('conc'))

print(CO2_conce)

実行イメージはこんな感じ

$ python3 GetCO2.py
[sudo] <ユーザ名> のパスワード:
523

おわりに

普段エッジデバイスを触る機会がないので線を接続するだけであたふたしていましたが、なんとかCO2濃度を取得できるようになりました。

余談ですが、猫はぶっつけ本番ではんだ付けに挑戦してCO2センサーを一つダメにしてしまいました(すみません……)。
とっても手先が器用な方以外ははんだ付け済みの商品の購入も検討してみてくださいね!

参考

Raspberry Pi 4とMH-Z19Bで二酸化炭素濃度を計測してみた | DevelopersIO

GitHub - UedaTakeyuki/mh-z19: Read CO2 concentration from mh-z19 sensor on the Raspberry Pi & handle it. Detect Raspberry Pi model automatically and read the value from an appropriate serial device.

subprocess --- サブプロセス管理 — Python 3.9.4 ドキュメント

Python で sudo を呼び出しパスワードを自動入力 - Qiita