2015年12月19日土曜日

ひまかん Advent Calendar 19日目: IRKitとGoogle App Engineで毎朝NHKをつける

技術系集団であるひまかんがこれまでに作ってきた作品の紹介や、技術ネタ、ライフハックなど、ノンジャンルな記事を埋めていくアドベントカレンダーです。
ひまかん Advent Calendar 2015




IRKitとは



会社の人たちからの誕生日プレゼントでIRKitをもらいました。
IRKitとはリモコンの赤外線をハックして、思い通りに家電を操作するデバイスです。標準でWi-Fiモジュールが内蔵されており、かつ操作するためのシンプルなREST APIが公開されているので、エンジニアであればそれこそ自由自在にリモコンを操ることができます。

IRKitの機能は非常にシンプルで、「直近で受信した信号データを返す」と、「信号データを送信する」だけです。各リモコンの信号データをいくつも保存しておく、などの機能はありません。逆に言えばそのへんはいくらでも自由に実装できます。

また、家庭内に置いたIRKitへのAPIコールはローカルネットワーク内でのみしか到達できませんが、適切にトークンを取得することで api.getirkit.com がプロキシとなり、インターネット経由でIRKitのAPIをコールすることができます。これを利用することで、外出先からエアコンを操作したりできるのはもちろんのこと、クラウド上のサーバープログラムから任意のタイミングでIRKitを操作することができます。


毎朝指定した時間にTVをつける



非常に簡単なサンプルですが、我が家では毎朝NHKの朝ドラを見ているので、目覚ましも兼ねて指定した時間にNHKをつけるプログラムを組んで動かしてみました。また、休日はゆっくり寝ていたいので、平日のみ起動するようにもします。

家に常時起動しているサーバーがあれば楽なのですが、我が家ではそんなものを置かせてもらうことはできないため、クラウド上のサーバーからcronでAPIを叩くことにしました。クラウドサービスは、(こんな趣味程度の規模であれば)無料で使えること、golangに興味があったことなどを理由に、Google App Engine for Go を採用しました。

まずは下準備として、IRKitをインターネットにつなぎ、Internet APIをコールするためのclientkeydeviceidを取得する必要があります。詳しくはここを参照してください。

http://getirkit.com/#IRKit-Internet-API

無事Internet APIを叩けるようになったら、TVリモコンの赤外線信号を取得します。我が家のソニー製のTVは数字ボタンを押すことでTVの電源が入っていない状態でも電源か入り、その数字のチャンネルに合わせてくれる機能があります。そこで、今回はリモコンの「1」ボタンの信号データを取得することにしました。

IRKitにリモコンを向け、「1」を押したあとに以下のようにAPIを叩きます。



curl -i "https://api.getirkit.com/1/messages?clientkey=XXXXXXXXXXXXXXXX&clear=1"
HTTP/1.1 200 OK
Server: ngx_openresty
Date: Tue, 07 Jan 2014 09:03:59 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 481
Connection: keep-alive
ETag: "-19571392"
X-Content-Type-Options: nosniff

{"message":{"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]},"hostname":"IRKitD2A4","deviceid":"FBEC7F5148274DADB608799D43175FD1"}



返ってきたJSONのmessageオブジェクトをそのままPOSTすることで、リモコンの「1」が再現されます。


curl -i "https://api.getirkit.com/1/messages" \
     -d 'clientkey=XXXXXXXXXXXXXXXXXXXXXXXXXX' \
     -d 'deviceid=XXXXXXXXXXXXXXXXXXXXXXXXXXX' \
     -d 'message={"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.1 200 OK
Server: ngx_openresty
Date: Tue, 07 Jan 2014 08:52:24 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
X-Content-Type-Options: nosniff


無事TVの電源が入り、1chが映ることを確認したら、これをGoogle App Engineから起動してみます。Google App Engine for Goのセットアップはこちらを参考に進めます。


書いたGoプログラムは、ほとんどサンプルをコピペしたような簡素なものです。



このプログラムは、指定されたパスへのリクエストがあると、IRKitのInternet APIを裏で叩くようになっています。



また、app.yamllogin: admin を付けることで、リクエストの際にGoogleアカウントでのログインが必須となり、かつ管理者以外からのリクエストの場合は自動的にエラーが返されるようになります。第三者に勝手に家のTVを操作されるのは困りますからね。

続いて、このパスへのリクエストをスケジューリングしてみます。 cron.yaml にこのような記述をします。


これは、平日の朝7:30にスクリプトを起動させる指定をしています。デプロイした後に、Google Developer Console のスケジュールタスク画面で、このような表示になっていることが確認できたらOKです。


IRKitを設置する


IRKitをTVの信号が届く範囲に設置します。我が家ではこのように壁に貼り付けました。ここなら同時にエアコンと照明を操作することができるので夢が広がります。



今後の展望としては、せっかくApp Engineを使っているので、信号データやトークンをソースコードにベタ書きせずにDatastore APIを使って登録・参照できるようにしたいです。汎用的なシステムが作れたら公開しようと思います。

0 件のコメント:

コメントを投稿