こんにちは。
GMOアドマーケティングのT.Iです。
突然ですが、Netatmoウェザーステーションをご存知でしょうか?
Netatmoウェザーステーションは屋内外の環境を計測するモジュールで、スマートフォンと連携することで様々な環境(気温や湿度、騒音など)をほぼリアルタイムで計測することが出来ます。
気温や湿度であればその他様々な製品でも計測することが出来ますが、この「Netatmoウェザーステーション」の特徴は二酸化炭素(CO2)濃度を可視化出来ることです。
今回は、そのCO2濃度をSlackに通知するシステムを作成したので、その”きっかけ”と開発方法について紹介いたします。
きっかけ
社内にNetatmoウェザーステーションを導入するきっかけは以下の記事でした。
記事では「CO2濃度が個人のパフォーマンスに大きく影響する」と紹介されています。
実際に社内でも夕方辺りから空気が重く感じたり集中が続かないと言った声があり、その原因の一つと考えられるCO2濃度を可視化することで仕事のパフォーマンスを改善できるのではないかとの意見が出たため、今回の仕組みを導入することになりました。
Netatmoウェザーステーションについて
Netatmoウェザーステーションにはいくつか種類があり、主に親機と子機がセットになっているパーソナルウェザーステーション、雨量計、風速計、追加屋内モジュールの4種類が販売されています。
今回は二箇所にモジュールを設置してCO2濃度を可視化したかったのですが、ウェザーステーションの子機ではCO2濃度を可視化できないとのことだったので、追加で屋内用の追加モジュールを購入しました。
Slackへの通知
購入した2つのNetatmoウェザーステーションを社内の二箇所に設置し、説明書通りに初期設定を済ませるとWeb上やスマートフォンアプリで各計測値を確認することができます。
今回は「CO2濃度が設定した閾値を超えるとSlackに通知する」という仕組みを作りたかったので、まずは簡単に導入できる「IFTTT」を使ってSlackと連携することにしました。
IFTTTでの設定方法は割愛しますが、CO2濃度が設定した閾値を超えた(もしくは下回った)ことをトリガーに設定できたので、以下のような通知フォーマットでテスト運用を始めました。
IFTTTの仕様上フォーマットの限界は諦めがつきますが、IFTTTの連携では実際に運用する中でいくつか気になる点がありました。
- 通知がかなり遅れる
先程のスクリーンショットの例でもわかりますが、場合によっては通知が数時間遅れることがありました。
IFTTT側で「ある閾値を下回ったときにも通知」するように設定することで換気の効果も可視化していたのですが、閾値を下回った通知と超えた通知のタイミングが逆転することもあり、リアルタイム性が重要な今回のシステムではあまり使い物にならない結果となりました。 - IFTTT連携の限界
先程も少し触れましたが、IFTTTでは詳細の制御ができないので、例えば「時間の表記をわかりやすくしたい」「SlackのAttachmentを細かく設定したい」「深夜帯は通知したくない」などの要件を満たすことができません。
特に通知が遅れる問題はクリアしたかったので、IFTTT連携からAPIを使った自作の通知システムへ移行することにしました。
Netatmo API × Ruby でデータの取得
1. 前準備
API経由でデータを取得する下準備として、まずはじめにNetatmo Connectからアプリケーションを作成する必要があります。(事前にこちらからNetatmoのアカウント登録を済ませておきましょう)
「CREATE AN APP」からアプリを作成すると「Client id」「Client secret」が発行されるので、この情報を元にデータを取得します。
2. データの取得
Netatomo APIについては公式のリファレンスが充実しています。
公式のリファレンスには様々な言語のSDKやサンプルコードが公開されていますが、今回はRubyを使ってデータを取得してみます。
APIについてもいくつか公開されていますが、今回はウェザーステーション用に公開されているGetstationsdata APIを使いました。
Rubyの場合は以下のコードでウェザーステーションのデータを取得できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
require 'net/https' require 'json' require 'uri' token_uri = URI('https://api.netatmo.com/oauth2/token') res = Net::HTTP.post_form( token_uri, grant_type: 'password', client_id: 'xxx', client_secret: 'xxx', username: 'xxx', password: 'xxx', scope: 'read_station' ) access_token = JSON.parse(res.body)['access_token'] api_uri = URI.parse('https://api.netatmo.com/api/getstationsdata') http = Net::HTTP.new(api_uri.host, api_uri.port) http.use_ssl = true req = Net::HTTP::Post.new(api_uri.path) req.set_form_data(access_token: access_token) res = http.request(req) data = JSON.parse(res.body) puts JSON.pretty_generate(data) |
JSON形式でモジュールの情報や計測データが返ってくるので、あとは欲しいデータを取り出すだけです。
今回はメインのモジュールに追加のモジュールを接続した状態でしたが、上記のコードで双方のモジュールのデータを取得することができました。
Slackには「モジュールが計測した時間」「CO2濃度」「モジュール名」をポストしたかったので、以下のようにデータを取得しました。
モジュールの名前は初期設定時に設定したモジュール名をJSONから取得してもいいのですが、今回はRuby側でわかりやすい名前をつけてます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
main_device = { # module_name: data['body']['devices'][0]['module_name'], module_name: "xxx", time: Time.at(data['body']['devices'][0]['dashboard_data']['time_utc']), co2: data['body']['devices'][0]['dashboard_data']['CO2'] } sub_device = { # module_name: data['body']['devices'][0]['modules'][1]['module_name'], module_name: "xxx", time: Time.at(data['body']['devices'][0]['modules'][1]['dashboard_data']['time_utc']), co2: data['body']['devices'][0]['modules'][1]['dashboard_data']['CO2'] } |
あとはcronで定期的にデータを取得し、取得したCO2濃度がある閾値を上回った(もしくは下回った)ときにSlackへ出力するようにコードを実装するだけです。
※後述しますが、テキストファイルやGoogle Spreadsheetなどで直近のデータを保持しておけば「上回った or 下回った」ときに通知をするように制御できます。過去データも含めて取得するAPIも用意されているのですが、追加モジュールを接続している場合は今回使用したAPIを採用した方が実装しやすかったので、今回はGoogle Spreadsheetを使って実装することにしました。
また、Slackへの投稿方法はいくつかありますが、Rubyを使う際はslack-incoming-webhooksを使えば簡単に導入できます。
Slack APIのAttachmentsも簡単に制御できるので、濃度の「上昇」「減少」「危険値」を色で表現すれば視覚的にも非常にわかりやすくなります。
おまけ: Google Spreadsheetへ出力
通知に関してはSlackで問題ありませんが、過去の履歴や傾向を観測する用途としてcronでデータを取得するついでにGoogle Spreadsheetへも出力しました。(直近のCO2濃度を保持する用途でも使っています)
RubyとGoogle Spreadsheetへの連携はこちらのgemを使えば簡単に導入できます。
導入方法は今回の記事では紹介しませんが、社内では以下のフォーマットで運用しています(数値はサンプルです)。
Netatmoの管理画面でも推移は確認できますが、制御の柔軟性と社内でSpreadsheetでの運用が浸透していることからSpreadsheetでの管理を採用しました。
まとめ
今回はNetatmo APIでCO2濃度をSlackへ通知する方法を紹介しました。
今回の仕組みを社内に導入することで、Slackへの通知を切っ掛けに換気や空調の調整をしたり、CO2濃度が上がるタイミングにフリースペースへ移動したりなど、個人のパフォーマンスを改善するファーストステップになったと思います。
実際に社内でも
・夕方に集中力が続かない原因が可視化されて気が楽になった
・換気を習慣化することで夕方頃に感じていた「空気の重さ」を感じにくくなった
・換気後の効果がリアルタイムで通知されるのでわかりやすい
・Spreadsheetで時間毎の傾向がつかめるので換気の運用が効率的になった
などの意見が出てきました。
Netatmo APIには他にも様々なAPIが公開されているので、今後も検証しながら社内環境の改善に活用していきたいと思います。
2016卒のWebエンジニア。
採用やマネジメントもやってます。