部屋の空気が悪くなるとtwitterで通知を送ってくれるbotを作った話
この記事はhttps://adventar.org/calendars/3952の12日目の記事です。
スライド版
LT会で話す機会があったので、スライドでのかんたんな解説があります。参考にどうぞ。
はじめに
センサーを置いて
監視させていると、空気が悪くなったら
リプライが飛んでくる仕組みを作りました。換気の目安になって捗ります。
なぜやるのか
空気が悪い状態では作業効率が落ちます。作業効率が落ちているのに自分で気づくのは難しいので、外部から通知が飛んでくるようになると安心です。
センサーから値を取得する
API連携できたりする高機能なCO2センサーはそこそこ高価で、25000円程度します。 10000円ほどで手に入る安価な製品にCO2-miniというものがあります。USBで給電して部屋の二酸化炭素濃度をモニターしてくれます。
http://r-kurain.hatenablog.com/entry/2016/01/26/164648
このセンサーから値を拾ってくるgem を書いてくださった人がいるので、これを使います。 記事によるとこのセンサーは、商品紹介ページに一切書いていないけどUSB経由でセンサーの値を取得できるようです。実際に値を取ってみました。
値の取り方
Could not open library 'hidapi' · Issue #1 · kurain/co2mini
ruby_hid_api のgem が特定のhidapi ライブラリにしか対応していないことにより、利用しているOSとライブラリの組み合わせによっては動作しないようです。 筆者環境(tinkerboard OS)では動作しなかったので、forkしてこちらのissueにある通りの更新をしたところ動作しました。そのリポジトリがこちらです。
https://github.com/jyllsarta/airryr
install
まず必要なライブラリをまとめてインストールしてしまいます。
sudo apt-get install libhidapi-hidraw0
sudo apt-get install usbutils
あとは clone して gem をインストールすればOKです。
git clone https://github.com/jyllsarta/airryr.git
cd airryr/
bundle install
動作確認
show.rb を実行するとデバイスから一度だけ値を読み取り、結果を出力します。
bundle exec ruby show.rb
気温と二酸化炭素濃度が標準出力に出てくれば成功です。
監視
監視を行う場合、以下の要件を満たしたいところです。
- 時系列で値を可視化できること
- 任意の場所にアラートを発報させられること
- ログ記録の停止を感知できること
Mackerelがちょうどよいサービスでした。二酸化炭素濃度の値を定期的にここにPOSTすることで、うまくモニターできそうです。 間にこのサービスを挟むことで、アラートを管理する部分とセンサーから値を取得する部分でうまくサービスの境界を作れるのも良さそうです。
モニターの開始
airryr にはMackerelへのメトリクス投稿機能をつけてあります。APIのトークンを .env に書き込むと使えます。
cp dotenv.example .env
vim .env
Mackerelに登録した際に設定したサービス名と、プロフィールページから参照できるAPIキーを入力します。
- MACKEREL_SERVICE_NAME=xxxxxxxx
- MACKEREL_API_KEY=XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx
+ MACKEREL_SERVICE_NAME=your_mackerel_service_name
+ MACKEREL_API_KEY=YoUrMaCkErElApIkEy00000000000000000000000000
監視はairryr.rb を実行させておくとできます。
bundle exec ruby airryr.rb &>> airryr.log &
動作状況
監視をさせながら、窓と扉を閉め切ってみました。部屋に人が入ってから、みるみるうちに二酸化炭素濃度が上昇していくのがわかります。換気は大事ですね。
Mackerel の Webhook 連携
Mackerel上で値は取れたので、次は一定値を超えたらアラートを発報してみましょう。
アラートしきい値の設定は https://mackerel.io/orgs/オーガニゼーション名/monitors からできます。
対象メトリクス・Warning/Criticalのしきい値・途切れアラート発報までの時間を設定できます。 ここで設定した条件を満たすと、通知チャンネル ( https://mackerel.io/orgs/オーガニゼーション名/channels ) に指定した通知先にpostされます。
airryr_web
MackerelはSlackやLINE, Yammerなどプライベートなチャットツールへの通知のみ標準で用意されています。本来はサーバ監視サービスなので、オープンな場であるtwitterに投稿させるのは想定していないのでしょう。 しかし通知先には任意のWebhook URLを指定できます。これを利用すれば、通知を受け取って発言させることができそうです。
そこで、Webhookの通知のPOSTリクエストを受け取ってtwitterに発言させるだけのsinatra アプリケーションを作りました。
https://github.com/jyllsarta/airryr_web
READMEの指示に従って設定を書き込むとwebサーバとして動作します。 (twitter のデベロッパーアカウントが必要になります。取得に少し手間がかかりますのでご注意ください。)
bundle exec ruby airryr_web.rb &
こちらを動作させた状態でメトリクスがしきい値を超えると、対象のユーザアカウントで発言を行います。
できた
しきい値を超えた / 下がり始めたタイミングでリプライを飛ばさせることができました。 twitterに発言を流させることによって、在宅時に監視すべきものを増やさずに済んだのがよいですね。
まとめ
- 二酸化炭素センサーから値を読み取って
- Mackerelに流して
- MackerelからのWebhook通知をtwitterに流すしくみ
それぞれを作りました。実際にはシステムを作る過程で部屋の空気に対して意識が向くようになってしまったので、現状は換気をそもそも怠らなくなってしまい通知が飛んでくることがほとんどなくなってしまいました。 ただ、うっかり空気が悪い中のろのろと効率悪く作業している、ということがなくなったのは確かな安心感があります。 導入までにかかるコストはセンサーとラズパイなどの費用だけですので、空気がこもってると感じることがある方は試してみるとよいでしょう。それで数%でも作業効率が改善すればすぐに元は取れます。
余談
ちなみに二酸化炭素濃度の値は人間の活動によってわかりやすく変わってしまうので、インターネットに公開するのはおすすめしません。 調理や運動でスパイクしたり、在宅時と不在時で収束する位置が違ったりするため部屋の様子が間接的にバレます。