2016年9月20日

ミニマルなIRKitクローンを作ってiOSから家電を制御する

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
どうも、お久しぶりです。生きてます。

さて、iOS 10が配信開始されて新たに登場した「ホーム」アプリのおかげで、日本ではあんまり注目されてなかったHomeKitが熱くなってるみたいです。(個人的感想)

HomeKitではPhilips Hueを操作できたりするのですが、そもそも対応していない家電を対応させるためのDIY的手法も色々存在しています。
例えば、HomebridgeとIRKitを組み合わせた方法。
Raspberry PiにHomebridgeを入れて、homebridge-irkitでIRKitを叩くみたいなお手軽スマートハウスのやり方は検索すれば山ほど出てきます。
そしてここで使われるIRKit、赤外線リモコンの信号を送受信できるオープンソースハードウェアなのですが、大人気なんですね。
在庫切れ入荷予定無しで手に入らないんだけど(キレ)という声も周囲にチラホラあったり。

というわけで、欲しいけど無いなら作りましょう。
自分で作ると安いし、面白いですし...

回路はこんな感じ。

必要な部品は以下の通り。
ESP-WROOM-02でミニマルなIRKitクローンを作る



もしESP-WROOM-02とかブレッドボードとか抵抗とか...持ってるなら、赤外線LEDと赤外線リモコン受信モジュールだけ買っちゃってください。

私はオリジナルのESP-WROOM-02搭載ボードとプロトタイプ・シールド基板を作っているので、これを使ってサクッと作りました。


中身のソフトウェアはIRremoteESP8266とaJSONを使って100行程度で実現しています。
コードはこちら。
9SQ/minIRum: A minimal implementation of infrared sender/receiver like IRKit by ESP8266

Arduino core for ESP8266をArduinoに入れて、コードをビルドしてESP-WROOM-02に書き込んであげてください。

あとは、IRKitみたいに GET /messages で最後に受信したリモコンのコードが取得できるので、これをメモしておいて...
POST /messages にこれを投げてあげれば、リモコンと同じように発光してくれます。
もし、エアコンなどの長めのコードを飛ばすリモコンの場合は、IRremoteESP8266/IRremoteESP8266.hの#define RAWBUF 100を200とかにしてあげれば取れるかも。

あとはHomebridgeと組み合わせれば、このようなことが出来ます。

Raspberry PiにHomebridge諸々を入れるのは、検索すればいっぱい記事が出てくると思います。
ただ、Raspbianはapt-getで取れるnodeが古かったりするので、楽をしたいならArch Linux(RasPi2/RasPi3)をお勧めします...
pacman -S git python2 nodejs npm nss-mdns avahi
systemctl enable avahi-daemon
systemctl start avahi-daemon
npm install -g homebridge
npm install -g homebridge-irkit
mkdir .homebridge
cd .homebridge
nano config.json
config.jsonは以下のような感じで。
irkit_hostは適宜変更してください。
{
    "bridge":
    {
       "name": "Homebridge",
       "username": "B8:27:EB:4D:31:D7",
       "port": 51826,
       "pin": "031-45-154"
    },

    "accessories": [
        {
            "accessory": "IRKit",
            "name": "ライト",
            "irkit_host": "minirum-a492cd.local",
            "on_form": {"format":"raw","freq":38,"data":[3550,1700,500,400,500,400,450,1300,500,1300,500,400,450,1300,500,400,500,400,450,450,450,1300,500,400,500,400,450,1300,450,450,450,1300,500,400,450,1300,500,450,500,400,500,1300,500,400,500,400,450,450,450,450,450,1300,500,400,500,1300,500,1300,450,450,500,1300,500,400,500,400,500,400,450,450,500,1300,500,400,500,450,450,1300,500,400,500,400,450]},
            "off_form": {"format":"raw","freq":38,"data":[3550,1700,500,400,500,400,450,1300,500,1300,450,450,500,1300,500,400,500,400,500,400,500,1300,500,400,500,400,500,1300,500,400,450,1300,500,400,500,1300,450,450,500,400,450,1300,500,400,500,400,450,450,450,450,500,1300,450,1300,450,1300,450,1300,450,450,500,1300,450,450,450,450,450,450,450,1300,500,1300,500,400,500,400,450,1300,500,400,500,400,500]}
        }
    ]
}
ちなみに、この赤外線コードはPanasonic製のシーリングライトのON/OFFです。

homebridgeを立ち上げて、iPhoneとペアリングします。
homebridge
[Tue Sep 20 2016 03:31:29 GMT+0900 (JST)] Loaded plugin: homebridge-irkit
[Tue Sep 20 2016 03:31:29 GMT+0900 (JST)] Registering accessory 'homebridge-irkit.IRKit'
[Tue Sep 20 2016 03:31:29 GMT+0900 (JST)] ---
[Tue Sep 20 2016 03:31:29 GMT+0900 (JST)] Loaded config.json with 1 accessories and 0 platforms.
[Tue Sep 20 2016 03:31:29 GMT+0900 (JST)] ---
[Tue Sep 20 2016 03:31:29 GMT+0900 (JST)] Loading 1 accessories...
[Tue Sep 20 2016 03:31:29 GMT+0900 (JST)] [ライト] Initializing IRKit accessory...
Scan this code with your HomeKit App on your iOS device to pair with Homebridge:
                       
    ┌────────────┐     
    │ 031-45-154 │     
    └────────────┘     
                       
[Tue Sep 20 2016 03:31:29 GMT+0900 (JST)] Homebridge is running on port 51826.

iOS 10のデバイスで「ホーム」アプリを起動して「アクセサリを追加」、Homebridgeが表示されるのでコードを入力してペアリングを完了させます。
Homebridgeを追加したら、configに書いたアクセサリ(上記例では「ライト」)が表示されると思うので、これを追加すれば制御できるようになります。

Raspberry PiでのHomebridgeの自動起動は以下を読むと早いです。
Arch Linuxなら、Running Homebridge on Bootup (systemd)のセクションです。
https://github.com/nfarina/homebridge/wiki/Running-HomeBridge-on-a-Raspberry-Pi

homebridge-irkitではON/OFFの単純操作しかできないので、そのうち色々なコードを叩けるhomebridgeのプラグインでも書こうかな...
ちなみに、Raspberry Piにhomebridge-cmdを入れて、GPIOにSSRを繋いであげれば、リモコンの無いAC100Vの機器もON/OFFできます。

8 件のコメント:

  1. homeアプリを使ってのリビングライトのon/offなど、大変便利に利用させていただいています。しかし、東芝のテレビでは、赤外線を学習しても、3桁[8950,2300,550]といった形で、電源のon/offすらまだ実現しておりません。リビングライトも向きによっては反応が悪いので、電源も別で用意してやってみたのですが、状況変わらず。何か、ここみた方がいい的なことありますでしょうか。

    返信削除
    返信
    1. ボタンを軽く一瞬だけ押すと取れたりしませんか?
      あるいは、送信開始リーダ部の点滅時間がリモコンによっては長すぎてタイムアウトになっている可能性もあります。
      IRremoteライブラリのIRrecv.hに記述されている定数を変えてみたりすると良いかもしれません。

      削除
  2. はっきりとは分からないので断言はできないですが、リモコンの赤外線の内容を短くまとめる時には、学習させるときにボタンを長時間ではなく一瞬だけ押します。そうすれば、ON/OFをするための最低限の信号しか処理しないので、わざわざプログラムを楽にするために人工で書き換えるのではなく、ボタン一瞬だけ押して学習させ直してみてください。

    返信削除
  3. 大変興味深く拝見しました。 コードをビルトしてESPに書き込んだ後に、どのようにしてGET/messageやPOST/messageはどのような操作をして行うのでしょうか ボタンを押す?シリアルモニターに打ち込む? 素人のような質問ですみません

    返信削除
    返信
    1. コード中のssidとpasswordをご自宅のWi-Fiアクセスポイントの設定と同じようにしていれば、同じネットワーク内に「minirum-」から始まるHost名を持つ機器が見えるはずです。
      あるいは、ESP8266とパソコンがシリアル接続可能な場合は、シリアルコンソールを開いた状態でESP8266の電源を入れると「Connected to SSID」に続いて「IP address: xxx.xxx.xxx.xxx」の出力を得られるはずです。
      この minirum-xxxxxx.local あるいは xxx.xxx.xxx.xxx のアドレスに対して、HTTPのGETメソッドで/messageにアクセスすると最近受信したリモコンコードが、POSTメソッドで受信したリモコンコード(JSON形式)を送ります。
      Mac/Linuxの場合はGitHubリポジトリ内のREADMEに記載したExample Requests(curlコマンド)を試してみてください。

      削除
    2. 素敵なプロジェクトをありがとうございます。
      やりたかったことが説明されていたので見よう見まねでやってっました。

      コンパイルでエラーがでたのですが
      ライブラリIRremoteESP8266.hのバージョンを2.1.1に戻して
      #include
      #include
      もコードにいれて
      旧 unsigned int rawData[d_size];
      新 uint16_t rawData[d_size];
      として
      66行目で}をひとつ追加したところバイナリまでいけるようになりました。
      間違ったことをしているかもしれませんが、同じことでひっかかっている人がいるかもとおもいポストします。

      削除
  4. 遅ればせながら製作して便利に使わせていただいています。ESP8266を作った学習リモコンの作例はいろいろありますが、個人的にはこれがベストかと思っています。
    IRremoteESP8266 v2.5.0で変数の命名規則が変わったため、そのままではコンパイルが通らなかったのですが、1行変更してそれはクリアできました。(pull requestさせていただきました)
    また、自宅のエアコンが当初データの読み込みはできているものの送信しても反応しなかったのですが、調べた結果データ長が255個を超えていて、aJsonの "max 255 elements" の制限に引っかかっていたのが判明しました。(本家IRkitはどう回避しているのか確認したら、JSONのデコードを自前でやっているのですね) 今回はお手軽にaJsonに簡単なパッチを当てることで制限を回避しました(私の名前のリンク先に置いてあります)。これでうちでは問題なく動いています。もしエアコンで動かないという方がいるかも知れませんのでご参考までに。

    返信削除
    返信
    1. 返信遅れまして申し訳ありません。そしてPull requestありがとうございました。
      aJson起因の問題も解決しようと思いつつ手をつけられていなかったので非常に助かります。

      削除

記事へのコメントはいつも確認している訳ではないので、お返事が遅れる場合があります。
ご質問やご意見は twitter@9SQ へお送り頂けると早くお返事できると思います。