チュートリアル

Raspberry PiとECHOPFを組み合わせて家電を操作してみよう(その3:Raspberry Piで家電を操作する)

前回はiPhoneからECHOPFのデータベースにメッセージを書き込む部分を作成しました。三回目となる今回は、Raspberry PiからECHOPFのデータを受け取って、家電を操作したいと思います。

開発時には同じネットワークにありますが、例えばこの仕組みをインターネット上に配置すれば、外出先からでも自宅の家電を操作できるようになります。

HomeBridgeをネットワーク対応させる

標準の起動法のままではHomeBridgeはAPIがありません。そこで -I オプションを付けて起動します。

$ homebridge -I

こうすると http://(Raspbery PiのIPアドレス):51826/characteristics でアクセスできるようになります。

認証がありますが、これはHomeBridgeを起動した時に表示される 031-45-154 といったコードを使います。これを Authorization ヘッダーに追加して利用します。

デバイスを確認する

まず操作するデバイスを確認します。

$ curl -X PUT http://127.0.0.1:51826/accessories \
       --header "Content-Type:Application/json" \
       --header "authorization: 031-45-154"

とアクセスするとJSONが返ってきます。例えば以下のような部分に注目します。ここで必要なのは aid と iid になります。iidは入れ子の構造になっていますが、必要なのは iid = 11 になります。

{
  "accessories": [
    {
      "aid": 5,
      "services": [
        {
          "iid": 8,
          "type": "000000B7-0000-1000-8000-0026BB765291",
          "characteristics": [
            {
              "iid": 11,
              "type": "00000025-0000-1000-8000-0026BB765291",
              "perms": [
                "pr",
                "pw",
                "ev"
              ],
              "format": "bool",
              "value": true,
              "description": "On"
            },
          ],
          "primary": false,
          "hidden": false
        }
      ]
    }
  ]
}

そして例えば以下のようにアクセスするとクーラーをオン/オフすることができます。

# オンの場合
$ curl -X PUT http://127.0.0.1:51826/characteristics \
       --header "Content-Type:Application/json" \
       --header "authorization: 031-45-154" \
       --data "{ \"characteristics\": [{ \"aid\": 8, \"iid\": 11, \"value\": true}] }"
# オフの場合
$ curl -X PUT http://127.0.0.1:51826/characteristics \
      --header "Content-Type:Application/json" \
      --header "authorization: 031-45-154" \
      --data "{ \"characteristics\": [{ \"aid\": 8, \"iid\": 11, \"value\": false}] }"

後はこのアクセスを Node.js で行えば良いだけです。

ECHOPFのJavaScript SDKを使う

基本的な使い方は2回目と変わりません。前回はExpressサーバを立てましたが、今回はバックグラウンドで実行し続けます。今回はネットワークアクセスに superagent というライブラリを使います。

$ npm install superagent --save

まずライブラリの読み込みと、ECHOPFの初期化を行います。

const request = require('superagent');

const config = require('./config');
const ECHOPF = require('./ECHO.min');

ECHOPF.initialize(
  config.domain,
  config.applicationId,
  config.applicationKey
);

config.jsonの内容は例えば次のようになります。

{
  "domain": "iot.echopf.com",
  "applicationId": "b7b...499",
  "applicationKey": "dff...09a",
  "memberInstanceId": "admin",
  "databaseInstanceId": "homebridge",
  "login_id": "LOGIN_ID",
  "password": "PASSWORD"
}

データベースは定期的(今回は5秒ごと)にチェックすることにします。

(async () => {
  setInterval(async () => {
    try {
      // 処理内容を記述
    } catch (err) {
      console.log(err);
    }
  }, 5000)
})();

ログイン処理を行う

まずデータにはACLが設定されていますので、管理者としてログインします。会員管理を行っているインスタンスの指定、およびログインIDとパスワードを指定します。

const result = await ECHOPF.Members.login(
  config.memberInstanceId,
  config.login_id,
  config.password
);

データベースを検索する

データベースの検索は ECHOPF.Databasesfind メソッドを使います。

const results = await ECHOPF.Databases.find(config.databaseInstanceId);
for (const entry of results) {
  // 各レコードに対して処理
}

データの種別を判断してHomeBridgeへアクセス

各レコードがどのデバイスに対する処理かを判断して、HomeBridgeのAPIを呼び出します。例えばクーラーだった場合、先ほどcurlコマンドで行った内容を実行します。

switch (entry.get('contents.device')) {
case 'cooler':
  const value = entry.get('contents.switch') === 1;
  const response = await request
    .put('http://192.168.0.30:51826/characteristics')
    .set('Content-Type', 'Application/json')
    .set('authorization', '031-45-154')
    .send({
      "characteristics": [
        {
          "aid": 5,
          "iid": 11,
          "value": value
        }
      ]
    });
}

レコードを削除する

処理を行ったレコードは不要なので削除します。

await entry.delete();

全体のコード

Raspberry Piのコード全体は次のようになります。

// ライブラリの読み込み
const request = require('superagent');

const config = require('./config');
const ECHOPF = require('./ECHO.min');

// ECHOPFの初期化
ECHOPF.initialize(
  config.domain,
  config.applicationId,
  config.applicationKey
);

(async () => {
  // ログイン処理
  const result = await ECHOPF.Members.login(
    config.memberInstanceId,
    config.login_id,
    config.password
  );
  // 5秒ごとに繰り返し
  setInterval(async () => {
    try {
      // データの確認
      const results = await ECHOPF.Databases.find(config.databaseInstanceId);
      for (const entry of results) {
        // 以下はクーラーの例
        switch (entry.get('contents.device')) {
        case 'cooler':
          // 設定する値
          const value = entry.get('contents.switch') === 1;
          // HomeBridgeへのHTTPアクセス
          const response = await request
            .put('http://192.168.0.30:51826/characteristics')
            .set('Content-Type', 'Application/json')
            .set('authorization', '031-45-154')
            .send({
              "characteristics": [
                {
                  "aid": 5,
                  "iid": 11,
                  "value": value
                }
              ]
            });
          // 利用したレコードは削除
          await entry.delete();
        }
      }
    } catch (err) {
      console.log(err);
    }
  }, 5000)
})();

まとめ

ここまでの処理によって、Raspberry PiでECHOPF上のデータを読み取り、レコードに応じた家電への命令が行えます。 HomeBridgeを使うことで、赤外線デバイス RM mini3 との連携も簡単に行えます。クラウドのECHOPFを介することで、自宅外からでも家電の操作ができます。後はパターンを増やしていくだけでスマートホームが発展していくことでしょう。

今回までのコードはechopfcom/Echopf_IoTにアップロードしてあります。実装時の参考にしてください。