備忘録

開発でつまったところの備忘録.不定期に更新します.

IRKitをiOSで動かす

今日のお題は

f:id:nawafuji:20140604193450j:plain

です。

こいつはリモコンなどの赤外線信号を記録して、スマホから家電等を操作できるよ!っていうアイテムです。

 

AndroidiPhoneともに公式アプリが無料で出ていて、使うことができます。

今回は、公式アプリを使わずに、ゼロからこいつを操作するiOSアプリを作ります。

 

まず、公式サイト

http://getirkit.com

に、丁寧にターミナルからの操作方法が説明されています。

 

以下サイトから抜粋

IRKit Device HTTP API

IRKitデバイスは、Bonjourを使ってIPアドレスを求めることができます。

% dns-sd -B _irkit._tcp
Browsing for _irkit._tcp
DATE: ---Sat 28 Dec 2013---
23:12:55.623  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
23:12:55.768  Add        2   4 local.               _irkit._tcp.         irkitd2a4
^C

% dns-sd -G v4 irkitd2a4.local
DATE: ---Sat 28 Dec 2013---
23:16:29.698  ...STARTING...
Timestamp     A/R Flags if Hostname                               Address                                      TTL
23:16:29.818  Add     2  4 irkitd2a4.local.                       10.0.1.2                                     10
^C

IPアドレスがわかったら、以下のHTTP APIにアクセスしましょう。
* SafariなどBonjourの.localホスト名を解決するクライアントから以下のHTTPリクエストをする場合には上記は不要です。

 

GET /messages

最も新しい受信した赤外線信号を返します。

% curl -i "http://10.0.1.2/messages"
HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Server: IRKit/1.3.0.182.gaf86b44
Content-Type: text/plain

{"format":"raw","freq":38,"data":[18031,8755,1190,1190,1190,3341,1190,3341,1190,3341,1190,1190,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,1190,1190,1190,1190,1190,1190,1190,1190,3341,1190,3341,1190,1190,1190,3341,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,65535,0,9379,18031,4400,1190]}

GET /messages が完了すると、保存していた赤外線信号は消去します。
同じ赤外線信号を2度、続けてGETすることはできません。

 

POST /messages

赤外線信号を送ります。

% curl -i "http://10.0.1.2/messages" -d '{"format":"raw","freq":38,"data":[18031,8755,1190,1190,1190,3341,1190,3341,1190,3341,1190,1190,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,1190,1190,1190,1190,1190,1190,1190,1190,3341,1190,3341,1190,1190,1190,3341,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,65535,0,9379,18031,4400,1190]}'
HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Server: IRKit/1.3.0.182.gaf86b44
Content-Type: text/plain

 

 以上から

  1. 目的のIRKitのIPアドレスを特定
  2. 赤外線信号のjsonデータをgetし保存
  3. 保存したjsonデータをpost

の流れでiOSからも制御できると考えられます。

 

1. IPアドレスの特定

IPアドレスの特定は

NSNetService, NSNetServiceBrowser等を用いて実現できます。

まず、NSNetService, NSNetServiceBrowserのオブジェクトを宣言しておきましょう。

gist78be6fd11a36347d09a2

 

次に、NSNetServiceBrowserを使って送信先を探します。 

gistf79960e56a1d35111870

ここではNSNetServiceBrowserのdelegateを設定しています。

またIRKitを探すためにserviceTypeを"_irkit._tcp"とします。

 

該当するサービスが見つかったときのdelegateメソッドを実装します。

gist827c743f7e4612c9c996

ここでまた、NSNetServiceのdelegateを設定します。

descliptionによってIRKitが見つかっているかが確認できます。

 

ホスト名が解決されたときのdelegateメソッドを実装します。

gistac21edd6ba604c7cb8c1

成功していればIRKitのIPアドレスを含むNSDataを得ることができます。

NSDataの中身は ×××××××× ×××××××× ×××××××× ×××××××× のような形になっており、最初の8文字が16進数でIPアドレスを示しています。

従ってこれを10進数に直して、http://と.を追加すればIPアドレスを得ることができます。

(僕の変換方法は少々無理矢理なのでおそらくもう少しきれいな方法があります)

 

参考

http://d.hatena.ne.jp/soundflower/20090428/p1

 

2. jsonデータのget

 

IPアドレスを指定して、赤外線信号のjsonデータを取得します。

gistd3cddc48f5929d5c543b

ターミナルでの方法に習って、IPアドレスに"/messages"を追加したものをURLとしてNSMutableURLRequestオブジェクトを作ります。

非同期のhandlerを定義して、requestに登録します。

handlerの中で得られるNSDataがjsonデータになっているので、NSJSONSerializationオブジェクトに変換して、保存します。

注意点としては、IRKitに保存されるjsonデータは一度getされると消去されるので、getするときはその直前に赤外線信号を送る必要が有ります。

また、通信はなぜかたまに失敗することが有るので、失敗したときの処理もきちんと書いておく必要が有ります。

 

参考 

http://studio.tgl.jp/blog/?p=2055

http://sushichop.blogspot.jp/2013/06/ioshttp.html 

3. jsonデータのsend

保存したjsonデータをIRKitに送って、赤外線信号を出力させます。 

gist7141e23c42a8e1357ace

同じように"/message"を追加したURLでrequestを作成して、設定を追加します。

NSJSONSerializationをふたたびNSDataに変換して、requestに登録してsendします。

通信がうまく行けば、IRKitが反応して、赤外線信号が送られます!

 

 以上の3ステップで、iOSから簡単にIRKitを制御できました。

しかしIRKitを普通に家で使おうとする人などいるのだろうか。。