冬になると窓を閉め切ってしまうことが多いので、二酸化炭素濃度が高くなることが気になっていた。そこで、二酸化炭素濃度を計測してmacOSのメニューバーに表示できるようにした。
Raspberry Pi Zero WとMH-Z19Bを使って二酸化炭素濃度を計測している。かなり昔に購入したので、今はMH-Z19BではなくMH-Z19Eぐらいになっているらしい。
接続はググればわかるはずなので省略。pip などを使って mh-z19 をインストールして、python3 -m mh_z19 のようにすると、{'co2': 540.0} のような値が返ってくる。
このあたりはかなり前にやっていたので思い出せないが、PWMで繋いでいたので、python3 -m mh_z19 --pwm としていた。
ちょっとしたWebサーバなので、Flaskを使うことにした。pip などを使って Flask をインストールし、以下のように実装した。よくわからないが、GPIO.cleanup() を呼ばないと数回計測を実行するだけでタイムアウトしてしまうので追加した。このあたりは生成AIに書いてもらったのであまり参考にならないかもしれない。
from flask import Flask, jsonify
import mh_z19
import RPi.GPIO as GPIO
app = Flask(__name__)
@app.route('/co2')
def co2():
try:
GPIO.cleanup()
result = mh_z19.read_from_pwm()
except mh_z19.GPIO_Edge_Timeout as e:
try:
GPIO.cleanup()
except Exception:
pass
return jsonify({'error': 'timeout reading CO2 sensor'}), 500
if result and 'co2' in result:
# 正常
return jsonify({'co2': result['co2']})
else:
try:
GPIO.cleanup()
except Exception:
pass
return jsonify({'error': 'could not read CO2'}), 500
if __name__ == '__main__':
try:
app.run(host='0.0.0.0', port=5000)
finally:
GPIO.cleanup()
上記のPythonファイルを指定して実行し、問題なくデータが取得できそうだったら自動で起動できるようにする。
sudo nano /etc/systemd/system/co2-api.service
[Unit]
Description=CO2 API Service
After=network.target
[Service]
ExecStart=/usr/bin/python3 /home/pi/app.py
WorkingDirectory=/home/pi
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi
[Install]
WantedBy=multi-user.target
登録
sudo systemctl daemon-reload
sudo systemctl enable co2-api
sudo systemctl start co2-api
サービスの状態を確認
sudo systemctl status co2-api
macOSのメニューバーの表示にはSwiftBarというアプリを使うことにした。このアプリはシェルスクリプトを定期的に実行して標準出力の内容をメニューバーに表示してくれるようだ。
シェルスクリプトはプラグインという扱いで、特定のフォルダに保存する。今回はRaspberry PiのFlaskで実装したサーバーにアクセスするシェルスクリプトを書いた。Rubyで書いたのは私がRuby好きなだけで、好きな言語で書くとよい。
#!/usr/bin/env ruby
require "json"
require "net/http"
require "uri"
SERVER_URL = "http://YOUR_SERVER:5000/"
response, body = Net::HTTP.get(URI.parse(SERVER_URL))
if response.nil?
puts "error"
return
end
puts "#{JSON.parse(response)["co2"]}ppm"