はじめに
リモートワーク中、頭がぼーっとするときはありませんか?
そんなときはもしかすると、部屋の二酸化炭素濃度が高いかもしれません。
この記事では、Raspberry Pi(以降、RPi)、CO2センサ、Nature Remo 3、および Amazon Echo(以降、Echo)を用いて、リモートワークを快適にする換気システムを作る方法について、解説します。
この換気システムを使用すれば、換気が必要なタイミング・換気が完了したタイミングを Echo に教えてもらうことができます。
換気システムの全体像
換気システムの機能
- CO2センサから取得した二酸化炭素濃度の値、Nature Remo 3 から取得した温度・湿度・照度の値(以降、各センサの値)をスプレッドシートに記録
- スプレッドシートに記録した各センサの値をグラフ化し、Web に公開
- 現在の各センサの値を Echo に教えてもらう
- 換気が必要なタイミングを Echo に教えてもらう
- 換気が完了したタイミングを Echo に教えてもらう
使用機材
- RPi:Raspberry Pi 3 Model B
- CO2センサ:MH-Z19B
- 温度・湿度・照度センサ:Nature Remo 3
温度・湿度・照度が必要なければ、Nature Remo 3 は用意しなくても大丈夫です。
各機能の実装
RPi に接続した CO2センサから二酸化炭素濃度を取得
RPi と CO2センサをジャンパワイヤで接続
- 参考:mh-z19
シリアル通信を有効化
-
$ sudo raspi-config
を実行して下記の順番で画面を操作し、設定を変更- Interfacing Options
- Serial Port
- Would you like a login shell to be accessible over serial ? →
<No>
- Would you like the serial port hardware to be enabled ? →
<Yes>
- The serial login shell is disabled The serial interface is enabled →
<Ok>
$ sudo reboot
を実行し、設定を反映
必要なライブラリをインストール
$ pip install mh-z19
を実行- 参考:mh-z19
動作確認
-
下記の
get_co2.py
を実行-
/home/pi/.virtualenvs/py3/bin/python
は適宜変更(例:$ which python
の実行結果など)
get_co2.pyimport subprocess import json def get_co2(): cmd = ['sudo', '/home/pi/.virtualenvs/py3/bin/python', '-m', 'mh_z19'] res = subprocess.check_output(cmd).decode() co2 = json.loads(res)['co2'] return co2 if __name__ == '__main__': co2 = get_co2() print(co2)
-
CO2センサから取得される二酸化炭素濃度のキャリブレーション
-
下記を実行し、CO2センサを屋外(400ppm)に20分間放置
$ python >>> import mh_z19 >>> mh_z19.zero_point_calibration()
NatureRemoAPI を叩いて Nature Remo 3 から温度・湿度・照度を取得
必要なライブラリをインストール
- 参考:Nature Remo を Python から操作する
$ pip install nature-remo
を実行
NatureRemoAPI を利用するためのアクセストークンを発行
- Nature にアクセスし、アクセストークンを発行
動作確認
-
下記の
get_natureremo_data.py
を実行get_natureremo_data.pyfrom remo import NatureRemoAPI import json def get_natureremo_data(): api = NatureRemoAPI(json.load(open('./config/setting.json'))['natureremo_token']) device = api.get_devices()[0] te = device.newest_events['te'].val # 温度 hu = device.newest_events['hu'].val # 湿度 il = device.newest_events['il'].val # 照度 return device, te, hu, il if __name__ == '__main__': device, te, hu, il = get_natureremo_data() print(device) print(te, hu, il)
setting.json{ "natureremo_token": "**********" }
各センサの値を Google Apps Script を用いてスプレッドシートに記録
各センサの値を記録・グラフ化するためのスプレッドシートを作成
- 参考:Raspberry PiからGoogleスプレッドシートにCO2濃度データを保存する
-
シートの追加
-
log
-
センサデータの記録用
-
A列:時刻、B列:二酸化炭素濃度、C列:温度、D列:湿度、E列:照度
-
完成後の表示例:
A B C D E 1 2022/04/12 8:51:59 559 26.6 51 137
-
-
filter
-
log
から最新900件(5時間分)の各センサの値を取得 -
A1 に下記を記入
=query( log!A:E, "SELECT A, B, C, D, E ORDER BY A DESC LIMIT 900 FORMAT A 'hh:mm'" )
-
完成後の表示例:
A B C D E 1 08:51 559 26.6 51 137
-
-
graph
-
各センサの値をスプレッドシートへ記録する方法
-
GAS(Google Apps Script)を利用
- GAS は、作成したプログラムを Webアプリとして公開可能
-
記録方法の流れ
- RPi が GAS にセンサデータを POST
- GAS が各センサの値をスプレッドシートに記録
RPi から POSTされた各センサの値を受け取り、スプレッドシートへ記録する GAS のプログラムを作成
- 参考:Raspberry PiからGoogleスプレッドシートにCO2濃度データを保存する
-
GAS のプログラムを書くためのエディタの開き方
- スプレッドシートを開く
- 拡張機能、Apps Script の順にクリック
-
GAS のプログラム(
sensor_data.gs
)を作成sensor_data.gsfunction doPost(e) { // パラメータの値を取得 var co2 = e.parameter.co2; // co2 var te = e.parameter.te; // 温度 var hu = e.parameter.hu; // 湿度 var il = e.parameter.il; // 照度 // 保存先のシートを取得 var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('log'); // シートに各センサの値を追記 sheet.appendRow([new Date(), co2, te, hu, il]); }
GAS のプログラムを Webアプリとして公開
-
デプロイ、新しいデプロイの順にクリック
- 設定する項目
- 新しい説明文:任意
- 次のユーザとして実行:自分
- アクセスできるユーザ:全員
- 許可を確認を選択し、自分のアカウントをクリック
- 設定する項目
-
「このアプリは確認されていません」の画面における操作
- 左下の詳細をクリック
- (安全ではないページ)に移動をクリック
- 許可をクリック
- Webアプリの URL をコピー
RPi が GAS にセンサデータを POSTするプログラムの作成
import schedule
import time
from get_co2 import get_co2
from get_natureremo_data import get_natureremo_data
import requests
import json
def logging_sensor_data():
co2 = get_co2()
device, te, hu, il = get_natureremo_data()
response = requests.post(
url=json.load(open('./config/setting.json'))['apps_script_url'],
data={
'co2': f'{co2}',
'te': f'{te}',
'hu': f'{hu}',
'il': f'{il}'
}
)
def main():
schedule.every(1).minutes.do(logging_sensor_data)
while True:
schedule.run_pending()
time.sleep(1)
if __name__ == '__main__':
main()
{
"apps_script_url": "**********"
}
動作確認
- 上記の
logging_sensor_data.py
を実行 - スプレッドシートが更新されるか確認
スプレッドシートの graph
を Web に公開
- ファイル、Web に公開の順にクリック
Voiceflow で Alexaスキルを作成し、現在の各センサの値を Echo に教えてもらう
プロジェクトを作成
- 参考:Raspberry Piで測定したCO2濃度をAlexaが話せるよう連携する
- Voiceflow のアカウントを作成
- Create Project をクリックしてプロジェクト名を入力し、Japanese を選択
Alexaスキルを作成
-
以下の画像を参考に、Steps から必要なカードを選択して配置
- Speak カード
Speak sensor data
Speak err msg
- Google Sheets カード
Get sensor data
- Speak カード
-
現在の各センサの値を取得するためのカード(
Get sensor data
)を編集 -
Start カードをクリックしてテストを実行し、動作を確認
Alexaスキルをデプロイ
- 右上の Upload to Alexa をクリックし、その後、Connect Amazon をクリック
-
Alexa開発者コンソールにログインし、Alexaシミュレータで Alexaスキルの動作を確認
- Alexaシミュレータにセンサーと入力
動作確認
-
Echo に「エコー、センサー」と話しかけてみる
- 応答例:現在の時刻は14時25分、二酸化炭素濃度は583ppm、温度は26℃、湿度は39%、光量は28lxです。
おまけ
alexa-remote-control を用い、換気が必要なタイミングを Echo に教えてもらう
換気が必要なタイミング
- CO2センサから取得される二酸化炭素濃度の値が1000を超えた場合
- 参考:CO2モニター(二酸化炭素計測機)
alexa-remote-control の設定
-
必要なライブラリをインストール
-
$ sudo apt install jq
を実行
-
-
alexa-remote-control をダウンロード
-
$ wget https://raw.githubusercontent.com/thorsten-gehrig/alexa-remote-control/master/alexa_remote_control.sh
を実行
-
-
alexa_remote_control.sh
を編集- 編集項目
SET_EMAIL='**********' SET_PASSWORD='**********' SET_LANGUAGE='ja-JP' SET_TTS_LOCALE='ja-JP' SET_AMAZON='amazon.co.jp' SET_ALEXA='alexa.amazon.co.jp'
- 編集項目
-
alexa_remote_control.sh
の権限を変更-
$ sudo chmod 777 alexa_remote_control.sh
を実行
-
おまけ(LINEへ通知するための設定)
- LINE Notify にアクセス
- トークンを発行する、1:1でLINE Notifyから通知を受け取るの順にクリック
動作確認
-
下記の
notify.py
を実行notify.pyimport subprocess import json import requests def let_echo_speak(msg): cmd = ['./sh/alexa_remote_control.sh', '-e', f'speak:{msg}'] res = subprocess.check_output(cmd).decode() send_line_notify(msg=msg) def send_line_notify(msg): line_notify_token = json.load(open('./config/setting.json'))['line_notify_token'] line_notify_api = 'https://notify-api.line.me/api/notify' headers = {'Authorization': f'Bearer {line_notify_token}'} data = {'message': msg} requests.post(line_notify_api, headers=headers, data=data) if __name__ == '__main__': let_echo_speak(msg='テスト')
setting.json{ "line_notify_token": "**********" }
Node-RED を用いて RPi と Echo を連携し、換気が完了したタイミングを Echo に教えてもらう
換気が完了したタイミング
- Echo に「換気 ON」と伝えてから、初めてCO2センサから取得される二酸化炭素濃度の値が500を下回った場合
Node-RED の起動
- 参考:Raspberry Piで実行する
-
Node-RED のスクリプトをダウンロード
-
$ bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
を実行
-
-
Node-RED のサービスの起動時実行を有効化
-
$ sudo systemctl enable nodered.service
を実行
-
-
Node-RED のサービスを起動
-
$ node-red-start
を実行
-
- ログに表示される URL(例:http://192.168.10.108:1880/)に PC からアクセス
Node-RED を用いて RPi と Echo を連携
-
Node-RED Alexa Home Skill Bridge の設定
- Node-RED Alexa Home Skill Bridge にアクセスし、Node-RED Alexa Home Skill Bridge のアカウントを作成
- Devices、Add Device の順にクリックし、下記の項目を設定
Name:換気 Description:換気システム Actions:On, Off Application Type:SWITCH
-
Node-RED に Node-RED Alexa Home Skill Bridge を追加
- 参考:Node-RedでAlexa Home Skill Bridgeを設定する
- 右上のタブ、パレットの管理、ノードを追加の順にクリック
- 検索欄に
node-red-contrib-alexa-home-skill
と入力し、ノードを追加をクリック
-
alexa-home ノードの設定
- alexa-home ノードの設定を配置し、ダブルクリック
- Acount の右の編集ボタンをクリックし、Node-RED Alexa Home Skill Bredge のサイトのユーザー名とパスワードを入力して add をクリック
-
Node-RED の Alexaスキルを有効化
- Node-RED にアクセス
- 端末を検出をクリック
Node-RED のフローを作成
-
以下の画像を参考に、ノードを配置
- switch ノード
- is-true
- http request ノード
- メソッド:GET
- URL:http://localhost:50080/ventilate
- http request ノード
- if-false
- http request ノード
- メソッド:GET
- URL:http://localhost:50080/ventilate/stop
- http request ノード
- is-true
- debug ノード
- switch ノード
-
Node-RED のフローのデプロイ
- 右上のデプロイをクリック
動作確認
- 下記の
server.py
を実行
from flask import Flask, Response
import json
from notify import let_echo_speak
from get_co2 import get_co2
import time
app = Flask(__name__)
ventilation = False
@app.route('/ventilate')
def ventilate():
global ventilation
ventilation = True
check_ventilation_is_complete()
return Response(response=json.dumps({'message': 'Start Ventilation!'}), status=200)
@app.route('/stop')
def stop():
global ventilation
ventilation = False
return Response(response=json.dumps({'message': 'Stop Ventilation!'}), status=200)
def check_ventilation_is_complete():
let_echo_speak(msg='換気を開始します。')
while True:
co2 = get_co2()
if int(co2) <= 500:
let_echo_speak(msg='換気が完了しました。')
break
elif not ventilation:
let_echo_speak(msg='換気を終了します。')
break
else:
time.sleep(60)
def main():
app.run(host='0.0.0.0', port=50080)
if __name__ == '__main__':
main()
- Echo に「換気ON」と話しかけてみて、Echo から「換気を開始します」と応答があるか確認
RPi の低消費電力化(Wi-Fi 以外の不要な機能を停止)
オンボードLED の無効化(RPi Model 3B の場合)
-
/boot/config.txt
に下記を追記後、再起動- Act LED:データアクセス時に緑色に点滅
- Pwr LED:起動後常に赤色に点灯
config.txt
# Disable the Activity LED dtparam=act_led_trigger=none,act_led_activelow=on # Disable the PWR LED dtparam=pwr_led_trigger=none,pwr_led_activelow=on
HDMI の無効化
-
/etc/rc.local
に下記を追記後、再起動rc.loal# Disable HDMI tvservice --off
Bluetooth の無効化(RPi Model 3B の場合)
-
/boot/config.txt
に下記を追記後、再起動config.txt# Disable Bluetooth toverlay=disable-bt
USBコントローラの無効化
-
/etc/rc.local
に下記を追記後、再起動rc.loal# Disable USB echo '1-1' |sudo tee /sys/bus/usb/drivers/usb/unbind
おわりに
この記事では、RPi、CO2センサ、Nature Remo 3、および Echo を用いて、リモートワークを快適にする換気システムを作る方法について解説しました。
皆さんのリモートワークが、少しでも快適になればと思います。