Raspberry Piの照度センサーを使って玄関の光がついたらSlack経由でApple Watchに通知する

Posted: / Tags: Raspberry_Pi Node.js Apple_Watch Slack



Raspberry Piで取得したセンサーデータをリアルタイムに可視化する」のシリーズの番外編です。

上記のシリーズでは、照度センサーのデータを取得してリアルタイムにグラフ表示する方法を説明しました。

でも、せっかくセンサーデータを取得しているので、何か変化が起こったら知らせて欲しいですよね。

なので今回は、電気がついたらSlack経由でApple Watchに通知してみます(iPhoneに通知するのと何も変わりはないんですが)。

Node.jsからSlackに投稿する前の準備(Webhook URLの取得)

Node.jsからSlackに投稿するには、Webhook URLが必要です。

Webhookとはざっくり言うと、あるアプリケーションから別のアプリケーションに対してHTTPのPOSTメソッドでリアルタイムに情報通知が行えるものです。以下の記事とスライドが詳しそうなので貼っておきます。

要は、Node.jsでSlackのWebhook URLに、HTTPのPOSTで送りつけてやればいいんです。

Webhook URLの取得方法

チームの設定から、「Configure Integration」をクリックします。

すると、「Integrations」という見出しのページに飛ぶので、一番下の方までスクロールして「Incoming Webhooks」をAddします。

チャネルを選択する画面が出るので、選択して「Add Incoming Webhooks Integration」を押して進みます。

進むとWebhook URLが書いてありますが、タイトルとアイコンを先に編集しておきましょう。下にスクロールすると「Customize Name」と「Customize Icon」があるので好きな名前とアイコンに変更します。

「Save Change」で保存をしたら、Webhook URLをコピーして準備完了です。

センサーデータがある値を超えたら、POSTする

準備ができたので、Raspberry Pi側のコードを編集します。

センサーデータ取得のコードは、先日の記事:Raspberry Piで取得したセンサーデータをリアルタイムに可視化する(センサー編)のものを使います。

lux.js
var SPI = require('pi-spi');
var MilkCocoa = require('milkcocoa');

var spi = SPI.initialize("/dev/spidev0.0"),
    MCP3002 = Buffer([0x68, 0]);

// {your-app-id}の部分は、Milkcocoaに(無料)登録してアプリを作成した際に生成されるアプリ固有の文字列です。
var milkcocoa = new MilkCocoa("{your-app-id}.mlkcca.com");

var old = 0;

setInterval(function() {
  spi.transfer(MCP3002, MCP3002.length, function (e,d) {
      if (e) console.error(e);
      else {
        var v = ((d[0]<<8) + d[1]) & 0x03FF
        console.log(v, "Got \""+v.toString()+"\" back.");
        if(old != v) milkcocoa.dataStore('light').push({v : v});
        old = v;
      }
  });
}, 5000);

「電気がついたら」の条件分岐

まず、「電気がついたら」の条件分岐をつくります。経験上、消灯時の値が2〜5、点灯時の値が12〜15だったので「6より大きかったら点灯」したことにします。

つけっぱなしの状態で何度も通知されたら困るので、一回通知したら電気を消すまで通知しないようにもします。

lux.js
// 割愛

var flag = false;

setInterval(function() {
  spi.transfer(MCP3002, MCP3002.length, function (e,d) {
    if (e) console.error(e);
    else {

      // 割愛

      if(v > 6){
        if(!flag){
          postToSlack(); // Slackに通知する関数。あとで書く。
          flag = !flag;
        }
      } else {
        if(flag) flag = !flag;
      }
    }
  });
}, 5000);

SlackにPOSTする

では、SlackにPOSTする部分をつくっていきます。

その前に、requestモジュールをインストールしておきます。

Raspberry Piのコマンド
$ npm install request

インストールしたら、忘れずにrequire()して、POSTするコードを書きます。

lux.js
var request = require('request');

// 割愛

function postToSlack(){

  var now = new Date().toString();

  var options = {
    url: '準備のときにコピーしたWebhook URL',
    form: 'payload={"text": "'+now+': 電気がつきました"}',
    json: true
  };

  request.post(options, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      console.log(body);
    }else{
      console.log('error: '+ response.statusCode);
    }
  });
}

コードはこちらの記事を参考にしました。

JSON形式(jsontrue)にしているのは、Slackが「JSONを送って」と言っているからです。

You have two options for sending data to the Webhook URL above:
- Send a JSON string as the payload parameter in a POST request
- Send a JSON string as the body of a POST request

いつ電気がついたかわかるように日付も一緒に送っています(Raspberry PiのタイムゾーンがUTCになっている場合は、sudo raspi-configで「Tokyo」に変更して下さい。詳しくはこちら)。

Slackで確認/Apple Watchで通知が来るか確認

Slackにちゃんと投稿されているか確認します。

Apple Watchで通知を確認します(Apple WatchはiPhoneの通知を肩代わりしているだけなので、iPhoneにSlackのアプリを入れていないと通知は来ません)。

まとめ

センサーデータの変化をSlack経由でApple Watchに通知する方法を説明しました。

何故番外編にしたかというと、通知する部分には一切Milkcocoaは使っていないからです(笑)

ただ、Slackに流すだけではデータの加工や可視化で困ることが多いです。

グラフに出来ないので、後で見ていつ電気がついたかがわかりづらかったり、1日の合計値が出せなかったりします。

Raspberry Piのような端末内のプログラムを変更することは、容易でない場合が多いです。一旦Milkcocoaにデータを流して、サーバなどで処理した方が保守性があがります(複数の端末を扱っている場合は、端末のコードをいじることなく、通知する端末を選択できたりもします)。

こんな感じで色々メリットがあるので、是非Milkcocoaで保存をしながら通知を使って頂ければと思っています。


※Raspberry PiやTesselでMilkcocoaを使うハンズオンが7月6日に開催されます。マイコンボードを持っていない方も会場で購入できるので、興味を持たれた方は是非参加してみて下さい!