Google Home + IRKit で既存の家電を操作するアプリを作ってみた #dialogflow

#Google homeに話しかけて家電を操作する
「電気を付けて」や「TVを消して」という要求に対応するアプリを作成しました。動画デモはこちらからご覧いただけます。

[![Google Home + IRKit ](http://img.youtube.com/vi/riDcdqcKcC4/0.jpg)](http://www.youtube.com/watch?v=riDcdqcKcC4)

##家電を操作する仕組み
 - Google Homeでユーザーの声を認識する
 - API.AIを使いユーザーが操作したい家電と操作内容を理解する
 - [IRKit](http://getirkit.com)を使用し家電に付属しているリモコンと同じ赤外線信号を送信する

##なぜ赤外線信号なのか
 - スマート家電が主流になってきているが、赤外線リモコン付属の家電はまだまだ多い
 - スマート家電は高価でちょっと手が出しにくい
 - 現在使用している家電にすぐ対応することができる

**今回はGoogle homeとIRKitを使用しましたがラズパイでも作れると思います。**

##準備編

 - [IRKitをWi-fiに繋ぐ](http://getirkit.com)
    - 公式アプリでIRKitをWi-fiに繋いでください。
 - ターミナルでClienttokenの取得
    - 同じWi-fi下で作業します
 - Clienttakenを使いDevice id と Client keyを取得します
    - **Device id と Client keyは端末をリセットする毎に再取得する必要があります**

```text:terminal
User$ dns-sd -B _irkit._tcp

//iRKitxxxみたいな名前があったら下記のコマンドを実行します
User$ dns-sd -G v4 iRKitxxxx.local

//iRKitxxxxのIPAddressを使いclienttokenを取得します
curl -i "http://192.168.43.242/keys" -d '' -H "X-Requested-With: curl"

//clienttokenを使いdeviceidとclientkeyを取得します
curl -i -d "clienttoken=xxxxxxxx" "https://api.getirkit.com/1/keys"
```

- 取得したClientkeyとIRKitの公式APIを使い赤外線信号を取得する

```text:terminal
curl -i "https://api.getirkit.com/1/messages?clientkey=xxxxxx&clear=1"
```

こちらのAPIをたたくと信号読み取り状態になるので、リモコンをIRKit向けて登録したいボタンを押しましょう。するとこのような信号の配列が取得できると思います。

```text:terminal
[3968,1927,10762,1927,3013,935,3013,935,1073,968,1073,968,1073,968,1073,968,968,1073,1073,968,3013,935,1073,968,1073,968,1073,968,1073,968,1073,968,968,1073,3013,935,1073,935,3013,935,1073,935,1073,935,1073,935,1073,935,935,1073,1073,935,1073,935,1073,935,1073,935,1073,935,1073,935,1073,935,935,1073,1073,935,1073,935,3013,935,1073,968,3013,935,3013,935,1037,1037,3013,935,3013,935,935]
```

この信号をメモしてください。

- API.AIの準備
    - 新しいAgentの作成
        - 言語は英語を選択
    - 新しいIntentの作成
        - 電気をつけるIntentを作成します
        - Name
            - Turn on light
        - Action
            - light.on
        - User says
            - Turn on light
        - Fulfillment
            - Use webhookにチェック
    - FulfillmentのWebhookをEnableにする
        - URLにCloud functionsのURLを貼る
        - [API.AIとfunctionsの連携はこちらを参照ください](http://qiita.com/flatfisher/items/c96959a0d8d2daf619d2)

##実装編
API.AIで受け取ったアクションに応じてIRKitのAPIに赤外線信号を送信します。

```js:index.js
'use strict';

process.env.DEBUG = 'actions-on-google:*';
const App = require('actions-on-google').ApiAiApp;
const request = require('request');

//IRKit API

//先ほど取得したclientkeyとdeviceidをURLに入れる
var IRKIT_URL = 'https://api.getirkit.com/1/messages?clientkey=xxxx&deviceid=xxx&message={"format":"raw","freq":38,"data":[]}'

// 取得した赤外線信号を入れる
const LIGHT_ON_IR = '[0000,0000]';

var options = {
  url: IRKIT_URL,
  method: 'POST'
}

function postIR () {
  return new Promise(function (resolve, reject) {
      request(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            resolve(body);
        } else {
            reject(error);
      }});
  });
}

//API.AI actions
const LIGHT_ON = 'light.on';

exports.HomeIRKit = (request, response) => {
  const app = new App({request, response});
  console.log('Request headers: ' + JSON.stringify(request.headers));
  console.log('Request body: ' + JSON.stringify(request.body));

  function light_on_handler (app) {
    //IRKitに赤外線信号を送信
    options.url = IRKIT_URL.replace('[]', LIGHT_ON_IR);

    postIR().then(function(result){
        console.log(result.msg);
    }).catch(function (error) {
        console.log(error);
    });

    app.ask('Okay, turn on light');
    console.log('Requested ' + LIGHT_ON);
  }

  const actionMap = new Map();
  actionMap.set(LIGHT_ON, light_on_handler);
  app.handleRequest(actionMap);
};
```

今回はrequestモジュールを使用しているのでpackage.jsonのdependenciesにモジュール名を追加します。

```json:package.json
"dependencies": {
    "request" : "^2.76.0"
  }
```

##テスト
API.AIコンソールのIntegrationsのActions on Googleからテストを行ってください。シュミレーターでも動きますが、Google homeをお持ちの方はせっかくなのでそちらでも試してください。同じGoogleアカウントであれば「Talk to my test app」と言えば動くと思います。

##まとめ
いかがだったでしょうか。思ったより簡単に家電を対応させることができたと思います。ぜひ色々な家電を操作してみてください。

##使ってみて感じたこと
- 料理などをしていて両手が自由に使え無い時に便利
- リモコンが遠くにあって取りにいくのがめんどくさい時に便利
- スマート家電が完全に普及するまでのつなぎになりそう