暫定 - 技術メモなど

今のところはRaspberry Piを使ったIoTが話題の中心です

homebridge on Raspberry Pi + Siriで家電コントロール

f:id:yrn7:20170831002927p:plain
いつか赤外線リモコン対応機器をホームアプリでコントロールできたらなあ、と思っていたのが昨年のこと。

ワタナベ書店さんの「赤外線リモコンで操作する家電をHomekit対応にする、homebridge-irkitの使い方」を読んでからいてもたってもいられなくなり、Raspberry Pi 3とIRKitを購入し、エアコンとプロジェクターをSiriでコントロールできるようにしたのが今年はじめ。

今は冒頭の写真のように赤外線受信機をつけたデスクライト、Raspberry Pi 3のGPIOに取り付けた温度・湿度センサー、Hue、KooGeekを導入して、いろいろな家電をiPhoneからコントロールできる環境になりました。Apple TVとの組み合わせで家の外から操作できるのもとても便利です。

この記事はRaspberry Pi 3にHomeKit APIをエミュレートするhomebridgeを導入し、IRKitを操作できるようにした際のメモです。
参考サイトは都度記載しています。
なお、Raspberry Pi 3の基本的な設定は割愛しています。

1.homebridgeのインストール

参考資料は「Raspberry Pi + HomeKit + IRKit = Siriで家電を音声操作できるようにする」です。

まず、Raspberry Pi 3にログインし、avashiをインストールします。

$ sudo apt-get install libavahi-compat-libdnssd-dev

次にnode.jsをインストール。

$ wget https://nodejs.org/dist/v6.11.2/node-v6.11.2-linux-armv7l.tar.xz

※最新版は公式のここを見てリンク先を確認してください。
 Raspberry Pi 3のCPUはARM8だけど、まだRaspbianが32bitなのでARM7が正しいそうです
 CPUの確認は下記コマンドで。

$ lscpu

ダウンロードしたnode.jsをインストールします。

$ tar -xvf node-v6.11.2-linux-armv7l.tar.xz
cd node-v6.11.2-linux-armv7l
$ sudo cp -R * /usr/local/

インストールしたnode.jsのバージョン確認して、正しく表示されれば問題ありません。

$ node -v
6.11.2

いよいよhomebridgeのインストールをします。

$ sudo su
# npm install -g homebridge

今回使うIRKit用のプラグインをインストールします。

# npm install -g homebridge-irkit
# exit

ここまでできたらとりあえず起動してみます。

$ homebridge
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
[9/1/2017, 1:48:34 PM] ---
[9/1/2017, 1:48:34 PM] Loaded plugin: homebridge-dummy
[9/1/2017, 1:48:34 PM] Registering accessory 'homebridge-dummy.DummySwitch'
[9/1/2017, 1:48:34 PM] ---
[9/1/2017, 1:48:34 PM] Loaded plugin: homebridge-irkit
[9/1/2017, 1:48:34 PM] Registering accessory 'homebridge-irkit.IRKit'
[9/1/2017, 1:48:34 PM] ---
[9/1/2017, 1:48:34 PM] config.json (/home/yorino/.homebridge/config.json) not found.
Scan this code with your HomeKit App on your iOS device to pair with Homebridge:

    ┌────────────┐
    │ 031-45-154 │
    └────────────┘

/usr/local/lib/node_modules/homebridge/node_modules/mdns/lib/advertisement.js:56
  dns_sd.DNSServiceRegister(self.serviceRef, flags, ifaceIdx, name,
         ^

Error: dns service error: name conflict
    at Error (native)
    at new Advertisement (/usr/local/lib/node_modules/homebridge/node_modules/mdns/lib/advertisement.js:56:10)
    at Object.create [as createAdvertisement] (/usr/local/lib/node_modules/homebridge/node_modules/mdns/lib/advertisement.js:64:10)
    at Advertiser.startAdvertising (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Advertiser.js:43:30)
    at Bridge.Accessory._onListening (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Accessory.js:539:20)
    at emitOne (events.js:96:13)
    at HAPServer.emit (events.js:188:7)
    at HAPServer._onListening (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/HAPServer.js:190:8)
    at emitOne (events.js:96:13)
    at EventedHTTPServer.emit (events.js:188:7)

エラーが出て終了しますが、configファイルがないのが原因なので今はこれで問題ありません。

2.IRKitのセットアップと赤外線情報の取得

一旦homebridgeのインストールが完了したところで、WiFi付き赤外線リモコンであるIRKitのセットアップを行います。
IRKitは本体のみの販売なので、別途Android充電用ケーブルとUSB充電器が必要になります。
電源を入れたら公式アプリを使用して自宅のWiFiネットワークに接続します。
公式アプリを見るとiRKitの名前がわかるので、この名前+.localをつけてMacLinuxからcurlコマンドでアクセスすることができます。
まずは、IRKitの公式サイトに書いてあるとおり、iRKitに赤外線リモコンを向けてボタンを押します。(IRKitのLEDが点滅します)
その後、MacLinux(もちろんRaspberry PiでもOK)からcurlコマンドで今の赤外線情報を取得します。

curl -i "http://(IRKitの名前).local/messages" -H "X-Requested-With: curl"

こんなのが出力されます。

HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Server: IRKit/3.0.0.0.g85190b1
Content-Type: text/plain

{"format":"raw","freq":38,"data":[8755,8755,1111,3119,1190,968,(中略)1073,3119,1073,3119,1073,3119,1073]}

このうち必要な部分は {"format": 〜]} です。
これをリモコンごとにON/OFFの2つ分を取得しておきます。
※エアコンの場合はドライや暖房など、機能ごとにON/OFFを取得します。

3.homebridgeの設定

さていよいよhomebridgeの設定を行います。
Raspberry Piにログインして、homebridgeのconfigファイルを作成します。

$ vim ~/.homebridge/config.json

{
    "bridge": {
        "name": "Homebridge",
        "username": "xx:xx:xx:xx:xx:xx",  #usernameはRaspberry PiのMACアドレスを入れます。間違っていても問題ないようです。
        "port": 51826,
        "pin": "031-45-154"               #PINコードも変更可能
    },
    "description": "IRKit Control",
    "accessories": [
        {
            "accessory": "IRKit",
            "name": "ドライ",
            "irkit_host": "irkit1ac5.local",
            "on_form": {"format": "raw","freq": 38,"data": [(ONの赤外線情報)]
            },
            "off_form": {"format": "raw","freq": 38,"data": [(OFFの赤外線情報)]
            }
        },
        {
            "accessory": "IRKit",
            "name": "クーラー",
            "irkit_host": "irkit1ac5.local","freq": 38,"data": [(ONの赤外線情報)]
            },
            "off_form": {"format": "raw","freq": 38,"data": [(OFFの赤外線情報)]
            }
        },
        {
            "accessory": "IRKit",
            "name": "暖房",
            "irkit_host": "irkit1ac5.local",
            "on_form": {"format": "raw","freq": 38,"data": [(ONの赤外線情報)]
            },
            "off_form": {"format": "raw","freq": 38,"data": [(OFFの赤外線情報)]
            }
        },
        {
            "accessory": "IRKit",
            "name": "プロジェクター",
            "irkit_host": "irkit1ac5.local",
            "on_form": {"format": "raw","freq": 38,"data": [(ONの赤外線情報)]
            },
            "off_form": {"format": "raw","freq": 38,"data": [(OFFの赤外線情報)]
            }
        }
    ]
}

config.jsonを作成したらhomebridgeを起動します。

$ homebridge

homebridgeが起動し、最後に先ほどのconfig.jsonに書かれたpinが表示されて止まればconfig.jsonは正しく記述されています。

    ┌────────────┐
    │ 031-45-154 │
    └────────────┘

正しく起動しない場合はjsonの構文チェッカー等を通して修正してください。

4.iPhoneでの動作テスト

homebridgeを起動した状態でiPhoneの設定を行います。
iPhoneのホーム画面にある「ホーム」をタップして起動します。
f:id:yrn7:20170902165417p:plain
「アクセサリを追加」をタップし、「homebridge」を選択し、「このまま追加」をタップします。

「コードを手動で入力」をタップし、homebridgeのconfig.jsonのpinに入力した数字(今回の例では「031-45-154」)を入力します。
正しく入力するとhomebridgeが登録されます。
場所を変更することができるので、変更する場合は適宜変更し、「次へ」をタップします。

するとhomebridgeに登録されているアクセサリが表示されるので、それぞれ「場所」と「タイプ」を選択して「次へ」をタップします。

これでiPhoneのホームの設定は終了です。
登録したアクセサリをタップしてON/OFFできることを確認します。
確認が取れれば、一旦homebridgeはCtrl + Cで終了させておきます。

5.homebridgeの自動起動設定

参考資料は「Raspberry PiとSiriで家電の音声制御 後編 Siriでの家電制御」の『さて、期待通りのものができたので満足しているのですが・・・』以降です。

まずはhomebridgeの起動専用のユーザーを作成します。

$ sudo useradd --system homebridge

次に、ホームディレクトにあるhomebridgeのconfig.jsonを新しく作成する /var/homebridge ディレクトリに移し、ディレクトリの所有者をhomebridge起動専用ユーザーに変更します。

$ sudo mkdir /var/homebridge
$ sudo cp ~/.homebridge/config.json /var/homebridge/.
$ sudo chown -R homebridge:homebridge /var/homebridge

上記参考リンクに従い、 /etc/default/homebridge と /etc/systemd/system/homebridge.service の二つのファイルを作成します。

$ sudo vim /etc/default/homebridge

# Defaults / Configuration options for homebridge
# The following settings tells homebridge where to find the config.json file and
 where to persist the data (i.e. pairing and others)
HOMEBRIDGE_OPTS=-U /var/homebridge

# If you uncomment the following line, homebridge will log more
# You can display this via systemd's journalctl: journalctl -f -u homebridge
# DEBUG=*
$ sudo vim /etc/systemd/system/homebridge.service

[Unit]
Description=Node.js HomeKit Server
After=syslog.target

[Service]
Type=simple
User=homebridge
EnvironmentFile=/etc/default/homebridge
ExecStart=/usr/local/bin/homebridge $HOMEBRIDGE_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

ファイルを作成したら下記コマンドを実行してsystemdに登録し、Raspberry Pi起動時にhomebridgeが自動起動するようにします。

$ sudo systemctl daemon-reload
$ sudo systemctl enable homebridge
$ sudo systemctl start homebridge

Raspberry Piを再起動します。

$ sudo shutdown -r now

再起動後、下記コマンドでhomebridgeが起動しているか確認します。

$ sudo systemctl status homebridge

● homebridge.service - Node.js HomeKit Server
   Loaded: loaded (/etc/systemd/system/homebridge.service; enabled)
   Active: active (running) since Tue 2017-08-29 02:03:38 JST; 4 days ago
 Main PID: 465 (homebridge)
   CGroup: /system.slice/homebridge.service
           └─465 homebridge

二行目の最後が enable となっていて、三行目が active (running) となっていればOKです。

「4.iPhoneでの動作テスト」で設定したホームの設定は自動起動設定後は使用できませんので、一度設定を削除し、再度設定してください。
これでhomebridgeの設定は完了です。
お疲れ様でした。

赤外線リモコン対応機器を増やす場合は、基本的には /var/homebridge/config.json の設定変更(手順としては「3.homebridgeの設定」と同様ですが、自動起動設定後は使用するconfig.jsonの場所が異なりますので注意)した後、下記コマンドで homebridge を再起動すればOKです。

$ sudo systemctl restart homebridge

このあと、iPhoneのホームに追加したアクセサリを登録します。