Hubotからテレビの電源を入れる。 (IRKit入門)


[IRKIT](http://getirkit.com/)が手元にあるので使ってみた感じのメモです。

**Chatwork/Hubot->(milkcocoa)->ローカルマシン->(curl/HTTP)->IRKit->(赤外線)->テレビ** という連携をしてみました。

![](http://i.gyazo.com/72917b2632e34371d3276d0f92eeac37.png)

## はじめに
IRKitは赤外線の信号を記憶して、自由に発信することが出来るガジェットです。公式サイトの説明はこんな感じです。

`IRKitは、 公式のリモコンアプリ IRKitシンプルリモコン から操作できるほか、 IRKit iOS-SDK を使えば、 任意のタイミングで赤外線信号を送ることのできるiOSアプリを簡単につくることができます。`

```
また、JavaScriptを使ってブラウザから赤外線信号を送ったり
curlを使って黒い画面(Terminal)から赤外線信号を送ることもできます。
IRKitデバイス自体にHTTPサーバがあり、
JSON形式の赤外線情報を HTTP POSTリクエストにのせて送ることで、赤外線信号を送ることができるのです。
また、IRKitと同じWiFiにいなくても、外出先から赤外線信号を送るための、インターネット上にあるサーバのAPIも公開しています。
```

IRKit自体にHTTPサーバ機能があり、外部からAPIを叩けるみたいなので、今回はこれを利用して、Hubotからテレビの電源を入れてみたいと思います。

##とりあえず動かす

基本的に何ができるのかは[アスキーの記事](http://weekly.ascii.jp/elem/000/000/243/243041/)を見ると分かりやすいです。

ちなみにこの時点でかなりハマりました。
どうやら無線LANの設定によって使える場合と使えない場合があるみたいです。会社のWifiではIRKITが使えなかったので焦りました。

ポケットwifiではうまくいったので、 **もし最初にハマった方は違うLAN内で使ってみると良いと思います。**

##ターミナルからAPIを叩いてみる

###手順
手順はこんな感じになります。

1. IRKitの名前(host名)を探す
2. IRKitのIPを探す
3. APIを叩いてみる

シンプルに見えて **初っ端からハマりました。**

> ※macなら1と2は[LanScan](https://itunes.apple.com/jp/app/lanscan/id472226235?mt=12&ign-mpt=uo%3D4)などで調べてもいいかもしれません。

### 手順1. STARTING...から進まない

公式サイトをみると`dns-sd -B _irkit._tcp`とコマンドを打てば良いみたい。
とりあえずIRKitと同一LAN内のMacから実行。

```
$ dns-sd -B _irkit._tcp
Browsing for _irkit._tcp
DATE: ---Wed 11 Feb 2015---
23:52:55.195  ...STARTING...
```

という感じで待ち受け状態になって反応無し。。

[ここの記事](http://iyuto.com/accessory/irkit-mac-terminal-control/)を見ると、 **この待ち受け状態のままIRKitを再起動**すると良いみたい。

#### まだ上手く行かなかった。

他の人の記事を見てるとここで上手くいってるみたいなのですが、私の場合はSTARTINGから全く反応がなかったです。

試しに**Macのインターネット共有を使ってルーター化させて、そのLANにIRKitを接続**させることにしました。ルーターになっているMacから先ほどのコマンドを実行し、待ち受け状態になったら↑のようにIRKitを再起動したところ。。。

![](http://i.gyazo.com/9a10d5d699d0789c4733f014a4ed0706.png)

!!!! 来ましたね。
`IRKitFEBA`ってのがこのIRKitの名前みたいです。

**ここでやっと`手順1`のhost名が分かりました。**

### 手順2. IRKitのIPアドレスを発見します。

`dns-sd -G v4 IRKitの名前.local`という感じでコマンドを打ちましょう。

```
$ dns-sd -G v4 IRKitFEBA.local
```

![](http://i.gyazo.com/a963bba165d5f9957e970228230d48f6.png)
ここでも待ち受け状態のSTATING...から進まなかったのでこの状態のままIRKitを再起動しました。

Addressの列に表示されるIPアドレスがIRKitのアドレスです。

今回の場合は`192.168.2.5`がIRKitのIPアドレスになります。

### 手順3. APIを叩いてみます。

`curl -i "http://上記IPアドレス/messages"`という形式でターミナルから実行してみましょう。

```
$ curl -i "http://192.168.2.5/messages"
HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Server: IRKit/2.1.2.0.g424fa95
Content-Type: text/plain
```

ステータス200が出ればOKです。

#### リモコンの信号を記憶させる [リモコン ->(記憶)-> IRKiT]
messagesのAPIでは直前に記憶した信号をレスポンスとして返してくれます。

**TVのリモコンなどをIRKitに向かってボタンを押しましょう。**

その後、もう一度APIを叩いてみます。

```
$ curl -i "http://192.168.2.5/messages"
HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Server: IRKit/2.1.2.0.g424fa95
Content-Type: text/plain

{"format":"raw","freq":38,"data":[17421,8755,1190,1037,1190,1037,1190,1037,1190,1037,1190,1037,1190,1037,1190,3228,1190,1037,1190,3228,1190,3228,1190,3228,1190,3228,...]}
```

こんな感じでjson文字列を返してくれます。dataに入ってる情報(途中省略しています)がリモコンの赤外線電波の情報になります。

#### IRKitで赤外線信号を発信する [IRKit ->(信号発信)-> TVなどの対象機器]

`-dオプション`で送信する情報を指定してあげて実行すると発信できます。

```
$ curl -i "http://192.168.2.5/messages" -d '{"format":"raw","freq":38,"data":[17421,8755,1190,1037,1190,1037,1190,1037,1190,1037,1190,1037,1190,1037,1190,3228,1190,1037,1190,3228,1190,3228,1190,3228,1190,3228,...]}'

HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Server: IRKit/2.1.2.0.g424fa95
Content-Type: text/plain
```
先ほど記憶したデータをそのまま指定してあげましょう。電波がIRKitから発信されます。


コマンドを叩いてIRKitが反応すれば成功です。

![](http://i.gyazo.com/b5fb2233ca0c98923072bc4c893f6afe.gif)

## Node.jsからコマンドを叩く

Hubotから扱ってみたいと思ったのでNode.jsでコマンド実行してみます。

### 時期的にせっかくなので[iojs](https://iojs.org/en/index.html)でやってみます。

- 現時点最新のiojsの1.2.0をインストール

```
$ nodebrew install io@1.2
$ nodebrew use io@1.2
$ iojs -v
v1.2.0
```

`exec`で先ほどのコマンドを実行します。
先ほどcurlコマンドを実行していたローカルマシン上で実行します。

```app.js(ローカルマシン)
var exec = require('child_process').exec;
var data = '{"format":"raw","freq":38,"data":[17421,8755,1190,1037,1190,1037,1190,1037,1190,1037,1190,1037,1190,1037,1190,3228,1190,1037,1190,3228,1190,3228,1190,3228,1190,3228,...]}';
var cmd = 'curl -i "http://192.168.2.5/messages" -d ' + "'"+data+"'";

/*コマンド実行関数*/
function update() {
    return exec(cmd, {timeout: 90000},
        function(error, stdout, stderr) {
            console.log('stdout: '+(stdout||'none'));
            console.log('stderr: '+(stderr||'none'));
            if(error !== null) {
                console.log('exec error: '+error);
            }
        }
    )
};

update();
```

実行してみます。

```
$ iojs app.js
```

IRKitが無事に反応すれば成功です。

## Hubotとローカルマシンをmilkcocoaで連携させる

[milkcocoa](https://mlkcca.com/)は国産BaaSサービスです。簡単にインタラクティブなものを実現できます。

### アプリを作成しましょう。
![](http://i.gyazo.com/31e9d477bbea18308894cdc5a73170a7.png)

アプリIDを以下で使っていきます。

### milkcocoaのNode.js SDKを使う準備

[こちらの記事](http://qiita.com/n0bisuke/items/c6fa760e4bb480e95d2f)を参考にセッティングしましょう。

### Hubotとmilkcocoa連携(ローカルマシン)

イメージはこんな感じです
`Hubot->(milkcocoa)->ローカルマシン`

先ほどのapp.jsにmilkcocoaコードを追加します。

```app.js(ローカルマシン)
var MilkCocoa = require('./mlkcca'); //milkcocoa SDKパス
var milkcocoa = new MilkCocoa("https://[your-app-id].mlkcca.com");
var ds = milkcocoa.dataStore("nodejs");
var exec = require('child_process').exec;
var data = '{"format":"raw","freq":38,"data":[17421,8755,1190,1037,1190,1037,1190,1037,1190,1037,1190,1037,1190,1037,1190,3228,1190,1037,1190,3228,1190,3228,1190,3228,1190,3228,1190,3228,1190,3228,1190,...]}';
var cmd = 'curl -i "http://192.168.2.5/messages" -d ' + "'"+data+"'";

/*コマンド実行関数*/
function update() {
    return exec(cmd, {timeout: 90000},
        function(error, stdout, stderr) {
            console.log('stdout: '+(stdout||'none'));
            console.log('stderr: '+(stderr||'none'));
            if(error !== null) {
                console.log('exec error: '+error);
            }
        }
    )
};

//sendが発火したらコマンド実行
ds.on('send', function(res){
	update();
});
```

この状態で実行&待機させておきましょう。

```
$ iojs app.js
```

### Hubotとmilkcocoa連携(Hubot側)

Hubotスクリプトを記述します。
私が使っているHubot v2.11.0ではscriptsフォルダ内にjsファイルorCoffeeScriptファイルを設置すれば動いてくれます。

`ボット名 irkit-tv on`とすればIRKit経由でテレビが付くコマンドを作ります。

```irkit.js(HubotScript)

var MilkCocoa = require('./lib/mlkcca.lib'); //milkcocoa SDKパス
var milkcocoa = new MilkCocoa('https://[your-app-id].mlkcca.com');
var ds = milkcocoa.dataStore('nodejs');

module.exports = function(robot) {

  robot.respond(/irkit-tv (.+)$/i, function(msg){
    if(!msg.match[1]){
      msg.send('!?');
      return;
    }

    if(msg.match[1] === 'on'){
      ds.send({text:1234});
      msg.send('TV on');
    }
  });

}
```

Hubotを実行してコマンド実行してみましょう。

```
> hubot irkit-tv on
TV on
```

実行するとこんな感じで Hubotコマンドを打つとIRKitが反応してくれます。
![](http://i.gyazo.com/045a8bb60f318ceed13690d0d8c69cee.gif)


## ChatworkからTVをつける

最後にChatworkに接続してみます。

HubotとChatworkの連携は[こちらの記事](http://liginc.co.jp/web/programming/node-js/142351)を参考にしてください。

ChatworkからLIG子というBotに呼びかけます。

![](http://i.gyazo.com/1c5cca1752a05803a1360994898db74e.gif)
(撮影が難しい...)

やりましたね！！

## まとめ
これで **Chatwork/Hubot->ローカルマシン->IRKit->テレビ** という連携ができました!

色々応用考えたいです。