Smart HomeをDIYする

Apple HomeKit は対応製品が少なくて高価なのでHomebridgeでがんばります

Nature RemoをHomebridge / HomeKitから使う

ネットから操作できる赤外線リモコンNature RemoをHomeKitから使えるように設定します。クラウド経由の設定と、ローカルAPIを使った設定の2種類の方法があります。

Nature Remo製品案内

Natureは日本(横浜市)の会社で、ネットからコントロールする赤外線リモコンユニットNature Remoを作ってます。いくつか製品がありますが、Nature Remo mini 2が一番安価で良いかと思います。

類似のネット接続リモコンはこの他にも多数出回ってます。Tuyaのソフトで動く廉価な製品もあります。

diysmarthome.hatenablog.com

これに比べるとNature Remoは高価ですが、日本の製品にきめ細かに対応しているとのことです。今回試したところでは、Tuyaの格安リモコンでも家のエアコンは操作できました。でも、場合によってはNature Remoじゃないと操作できないこともあるらしいです。また、Nature Remo mini 2には温度センサがついていますが、格安リモコンにはついていません。

赤外線制御の照明器具は絶滅危惧

今回、HomeKitから操作できるようにした器具は、シーリングライト(天井照明)とエアコンです。天井照明は、Amazonで売っている格安のLEDシーリングライトです。赤外線リモコンを使用する製品です。

確認したところ、今回使用した照明器具は、もはや販売されてませんでした。他に赤外線を使用しているらしい製品は、たとえばこんな製品です。

     

最近の照明器具では、赤外線リモコンがBLEに置き換わりつつあるようです。 BLEにしておけば、スマホからの操作が可能になり、スマホ用のリモコンアプリも簡単に提供できます。

Nature Remoは赤外線を送出する製品なので、電波を使うBLEリモコンは使用できません。なので、赤外線リモコンを使用する製品を選ぶ必要があります。困ったことにほとんどの販売ページでは、リモコンが赤外線式なのかBLE方式なのか記載がありません。リモコンにLEDらしきものが付いていても、それは動作確認用のLEDで、実際の通信はBLEという場合もあります。注意が必要です。

ちなみに、上位機種のNature Remo 3はBLEにも対応しているらしいです。ただし赤外線学習リモコンのようにどんなBLE製品でも登録できるわけではなく、対応している少数の製品だけが対象です。BLEで接続できても、上位のプロトコルが各社でバラバラなのですね。近い将来には、Matter + Threadで統一されていくのかと思います。

スマホアプリでリモコンを登録

HomeKitの設定をする前に、まずは、Nature Remoを通常通り設定します。スマホアプリ、Nature Remoをダウンロードして、手持ちの赤外線リモコンを登録します。今回は、以下の2個のリモコンを登録しました。

  • 天井照明リモコンのon/offボタン
  • エアコン

天井照明は、照明器具付属のリモコンをNature Remoに向けて、on/offボタンを学習させました。エアコンは、アプリの指示に従って赤外線リモコンを操作すると、メーカを自動検出してくれました。これで問題なく登録できました。

バイス登録の結果、Nature Remoアプリの画面は以下のようになりました。照明ボタンをタップすると、シーリングライトがon/offを繰り返します。エアコンをタップすると、on/off、動作切り替え、温度設定、風量調整、風向調整が可能になります。

クラウドの役割

Nature Remoの機能は、ほぼクラウドが担当してます。Nature Remoは、クラウドから送られたパターンの赤外線信号を送出していると思われます。エアコンを赤外リモコンで操作する場合は、登録したメーカに合わせて、温度、風量、風向などを総合した長い赤外線信号を組み立てる必要があります。おそらくそれはクラウドが全てやってくれて、最終的に発信すべき赤外線信号がNature Remoに伝えられるのだと想像してます。

Amazon AlexaGoogleのスマートスピーカとの連携もクラウドが担当しているようです。HomeKitは、基本的にクラウドに依存しないプロトコル(HAP)なので、連携が難しいのかサポートされてません。NatureのiPhoneアプリはショートカット対応しているので、Siriからショートカット経由でコントロールすることは可能です。HomeKitで使えないのは残念です。

Cloudからトークンを取得する

そこでHomebridgeの出番です。HAPで受け取った指示に従って、Natureのクラウドにアクセスするプラグインを用意すれば、HomeKitからNature Remoをコントロールできます。

そのためにはまずNatureクラウドへアクセスするためのトークンを入手します。Tuyaのリモコンで行ったように、Natureの特別なページにアクセスします。そこでトークンを生成してもらいます。アクセスするページは以下です。

home.nature.global

このページのLoginボタンを押して、

スマホアプリに登録したメールアドレスを入力すると、メールが来ます。

メールに書かれたアドレスにアクセスし、「許可する」ボタンを押します。

そうすると、アクセストークンを新たに作成したり、消去したりできるページが現れます。生成したアクセストークンは二度と表示されないので、必ずコピーしておきます。

使わなくなったトークンはRevokeボタンを押して消すこともできます。以下のサンプルではこの長いトークンを$TOKENとして表記します。あとはNature社のwebサーバにアクセスすることで、必要なすべての処理が可能です。まずは登録情報を確認します。以下の長いcurlコマンドを発行します。

% curl -H "Authorization: Bearer $TOKEN" -H "accept: application/json" "https://api.nature.global/1/appliances"

すると長いjson形式のテキストが返ってきます。このままでは読みにくいので、jqコマンドに渡して、さらにlessして表示を止めておきます。jqコマンドは、ベタ書きされたjsonテキストを、見やすくフォーマットして表示します。macOSには入っていないのでbrewコマンドなどでインストールします。Raspberry Piには入ってました。何かと一緒にいれたのかもしれません。

% curl -H "Authorization: Bearer $TOKEN" -H "accept: application/json" "https://api.nature.global/1/appliances" | jq | less

Cloudに信号IDを送る

上のcurlコマンドで得た情報の中から、照明のボタンに割り当てた信号のIDを探します。器具の名前を「照明」として、照明のアイコンをつけて、ボタンには「オン」という名前がついてました。それらしきところを見ると、「オン」のボタンに割り当てられたIDがわかります。下のxxxxで書いた部分です。

    "model": null,
    "type": "IR",
    "nickname": "照明",
    "image": "ico_light",
    "settings": null,
    "aircon": null,
    "signals": [
      {
        "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "name": "オン",
        "image": "ico_on"
      }
    ]

このIDを利用して、curlコマンドでクラウドに依頼して、Nature Remoから赤外線信号を送出させることができます。

% curl -H "accept: application/json" -H "Authorization: Bearer $TOKEN" -X POST "https://api.nature.global/1/signals/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send"

これでシーリングライトがon/offします。

CloudからデバイスIDを得る

上のスマホ画面スクショで示したように、現在「Myhouse Office」という場所に照明とエアコンの2個のデバイスを登録しています。先のcurlコマンドで得たjson情報の最上位の部分を見ると、登録されたデバイスが要素になった配列になっています。

[ {照明の情報}, {エアコンの情報} ]

それぞれの情報の部分にidという変数名があります。エアコンのidは、エアコン情報が書かれた部分の最初の方に見つかります。

  {
    "id": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
    "device": {
      "name": "Myhouse Office",

このidは、次のセクションで、Homebridgeを使用するために必要になります。

照明をHomebridgeに追加する

まずは「照明」をHomeKitに追加します。Homebridgeのプラグインのタブで、natureという名前で検索すると、Nature Remo用のプラグインが多数表示されます。現時点で24個ありました。日本の製品なので日本の方が作ってくれているプラグインがほとんどです。皆さんに感謝です。

「照明」を使用するために、この中からhomebridge-nature-airconを使わせていただくことにしました。

github.com

他にも、シーリングライトのためのプラグインが多数あります。シーリングライトによっては、リモコンボタンを押すと明るい点灯-->暗い点灯-->消灯と変化するものもあります。その場合、消灯-->明るい点灯には1回押し、明るい点灯-->消灯には2回押しする必要があります。その回数を設定できるプラグインもありました。また点灯・消灯をNature Remo 3の照度センサで判定するプラグインもあります。今回のプラグインは、一番シンプルなものです。

インストールするとaccessoryとnameの設定項目だけ追加されますので、これに、access_tokenとsignal_IDの項目を追加して設定します。access_tokenは、上記で調べた$TOKENの値です。signal_IDも、上で調べたxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxの値です。

設定を保存して、Homebridgeを再起動するとiPhone, Macのホームに照明が現れます。

   

クリックするとシーリングライトがon/offします。ただ、on/off状態を把握できていないので、逆の動作になっている場合もあります。そのような場合は、リモコンから一回on/offすれば同期します。もちろん、またズレるかもしれません。

エアコンをHomeKitに追加する

今度はエアコンを追加します。Homebridgeのプラグインの中から、homebridge-nature-airconを使わせていただくことにしました。

www.npmjs.com

ここまで準備が終わっていれば、プラグインの設定は簡単です。accessTokenの場所に、上で説明した$TOKENの文字列を書き、airconIDの場所に、これも先ほど入手したid(yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyyの部分)を書きます。

これを保存し、Homebridgeを再起動すれば、iPhoneMacのホームにエアコンが現れます。

これをクリックするとon/offします。詳細を開ければ、運転切り替え、温度設定が可能です。Nature Remoには温度センサが搭載されているので、現在の室温も表示されます。

ローカルAPIを使う

ここまではNatureのクラウドを利用していました。NatureはNature RemoのローカルAPIを公開しています。ローカルAPIを利用すれば、LAN内からNature Remoにhttpで接続して操作可能です。インターネット上のクラウドを使用しないので、Natureのサイトが止まってもリモコンを動かすことができます。応答速度も速いはずです。公式の案内ページは以下です。

local-swagger.nature.global

これによると、Bonjourの仕組みを使ってIPアドレスを取得できるようです。まずはdns-sd -BコマンドでInstance Nameを取得します。次にその名前を使ってdns-sd -Gコマンドで数値のIPアドレスを取得します。以下の太字の部分が入力するコマンドです。

% dns-sd -B _remo._tcp
Browsing for _remo._tcp
DATE: ---Fri 28 Oct 2022---
20:15:44.225  ...STARTING...
Timestamp     A/R    Flags  if Domain           Service Type         Instance Name
20:15:45.450  Add        3   4 local.           _remo._tcp.          Remo-XXXXXX
^C
% dns-sd -G v4 Remo-XXXXXX.local
DATE: ---Fri 28 Oct 2022---
20:16:13.033  ...STARTING...
Timestamp     A/R  Flags         IF  Hostname               Address                 TTL
20:16:13.034  Add  40000003       4  Remo-XXXXXX.local.     192.168.xxx.xxx         120
^C

これで、アドレス名がRemo-XXXXXX.localで、数字のIPアドレスは192.168.xxx.xxxであることがわかりました。このアドレスに、赤外線の信号パターンを送れば、それを発信してくれます。問題は、信号パターンをどうやって知るかです。

方法の一つが、Nature Remoの学習リモコン機能を使う方法です。まずは、赤外線リモコンをNature Remoに向けて学習させます。ここでは、シーリングライトのリモコンをNature Remoに向けて、そのon/offボタンを押しました。学習完了するとNature Remoの青いリングが点滅します。その直後に、ターミナルから以下のコマンドを発行します(太字部分です)。その結果、赤外線パターンを示す情報が得られます。

% curl http://Remo-XXXXXX.local/messages -H "X-Requested-With: local" 
{"format":"us","freq":40,"data":[6830,4629,283,573,283,1409,286,569,286,1426,259,573,291,1399,259,597,283,1409,258,597,285,1408,282,573,281,579,285,1401,280,1407,283,1405,281,1409,310]}

アドレス部分には文字の名前を使いましたが、数字のアドレスでもokです。文字の名前は応答が悪いことがありました。数字のアドレスの方が確実です。

リモコンのデータが判明したので、次にこれを送信してみます。以下のコマンドです。

% curl -XPOST http://Remo-XXXXXX.local/messages -H "X-Requested-With: local" -d '{"format":"us","freq":40,"data":[6830,4629,283,573,283,1409,286,569,286,1426,259,573,291,1399,259,597,283,1409,258,597,285,1408,282,573,281,579,285,1401,280,1407,283,1405,281,1409,310]}'

この結果、点灯しているシーリングライトが消灯します。もう一度発行すれば点灯します。

リモコンコードを解析する

リモコンコードを解析してみました。ただ、これは手元のシーリングライトのリモコンのコードなので、他の方には何の参考にもならないです。

数字の配列部分は、おそらくは信号パターンの1, 0の持続時間を列挙していると思われます。データの部分を、試しに280の倍数にして、以下のようにしてみたのですが、同様に動作しました。

% curl -XPOST http://Remo-XXXXXX.local/messages -H "X-Requested-With: local" -d '{"format":"us","freq":40,"data":[7000,4760,280,560,280,1400,280,560,280,1400,280,560,280,1400,280,560,280,1400,280,560,280,1400,280,560,280,560,280,1400,280,1400,280,1400,280,1400,280]}' 

280,560が0で、280,1400が1の位相変調だと考えると、0101010101001111というビット列にも見えます。ちょうど16ビットなので正しそうです。ちなみに、リモコンにはCH1とCH2というボタンがあって長押しするとチャンネルが切り替わるのですが、現在はCH2でした。CH1に切り替えると、on/offボタンのビット列が1010101010011111となりました。チャンネルを切り替えると、時系列で最初の8ビットが全部反転するようです。

リモコンには他に、常夜灯、明るく、暗くというボタンがあるのですが、それぞれの後半8ビットのビット列は、11011111, 01100111, 11001101でした。

まとめると、ビット列がMSBから流されるとして、16進数で表した場合

  • 0xAA4F: CH1のon/off
  • 0xAADF: CH1の常夜灯
  • 0xAA67: CH1の「明るく」
  • 0xAACD: CH1の「暗く」
  • 0x554F: CH2のon/off
  • 0x55DF: CH2の常夜灯
  • 0x5567: CH2の「明るく」
  • 0x55CD: CH2の「暗く」

でした。

ローカルAPIをHomeKitで使う

次にローカルAPIをHomeKitから使えるように設定します。ローカルAPIを使うプラグインがあったのでそちらを使ってみました。このプラグインです。

www.npmjs.com

でも、[NatureRemo] No Nature Remo device foundというエラーメッセージが出てしまいました。Bonjourに失敗しているのかもしれません。

HomeKitのプラグインにはシェルコマンドを実行するプラグインもあります。次善の策としてそれを利用して、上記のcurlコマンドを実行すれば良いと考えました。homebridge-shell-switchという名前のプラグインです。

github.com

インストールして、configの部分に以下のように設定しました。

{
    "accessory": "ShellSwitch",
    "name": "ShellSwitch",
    "onCmd": "myswitch.sh",
    "offCmd": "myswitch.sh",
    "stateful": true
}

onCmdとoffCmdには、onとoffを行うときに実行すべきシェルコマンドを書きます。トグルスイッチなので同じmyswitch.shというシェルスクリプを名を書きました。ここにcurlコマンドを直接書いても良いかと思いましたが、うまく実行できませんでした。シェルの実行環境などの関係かと思います。引用記号を逆スラッシュで無効にすることに失敗しているのかもしれません。そこで、以下のようなシェルスクリプトを書いて、これを/usr/local/bin/myswitch.shにおきました。それをconfigに書いたonCmdとoffCmdで実行します。

#!/bin/sh
curl -XPOST http://192.168.xxx.xxx/messages -H "X-Requested-With: local" -d '{"format":"us","freq":40,"data":[7000,4760,280,560,280,1400,280,560,280,1400,280,560,280,1400,280,560,280,1400,280,560,280,1400,280,560,280,560,280,1400,280,1400,280,1400,280,1400,280]}'

 Homebridgeを再起動すると、PhoneとMacのホームに以下のように現れます。

   

(追記) ローカルAPIを使う他のプラグイン

追記です。上で紹介したhomebridge-nature-remo-localがうまく動かなかったと書きました。デバイスが発見できなかったようです。探したところ、IPアドレスを直接各方式の、ローカルAPI対応プラグインがありました。こちらです。

github.com

これも日本の方が作ってくれているようで、gitの説明も日本語です。複数の機器のコントロールマルチタスクで行うような機能もあるようです。一番シンプルに使うなら、

{
  "accessory": "remo",
"name": "Light", "host": "192.168.xxx.xxx", "command": { "power": { "format": "us", "freq": 40, "data": [7000,4760,280,560,280,1400,280,560,280,1400,280,560, 280,1400,280,560,280,1400,280,560,280,1400,280,560,280,560,280,1400,280,1400,280,1400,280,1400,280] } }, "on": [ "power" ], "off": [ "power" ] }

のような設定で良いようでした。

クラウドとローカル

これでローカルAPIを使ってシーリングライトをon/offできます。クラウドを使用しないので、クラウドやネットワークが不調でも動作しますし、応答速度も高速なはずです。また、クラウド仕様には、5分間に30回までの制限があります。デバッグなどで何度も使っていると、しばらく応答しなくなってしまいます。ローカルで使用する場合は、この制約は無関係です。

ただ、ローカルAPIを使用するためには、上記のように赤外線信号タイミングを用意する必要があります。エアコンのように、設定温度や風量・風向なども含めてコマンドが複雑になる場合は簡単ではありません。複雑な赤外線タイミングが必要な操作はクラウドの任せるのが良いと思います。ローカルAPIは、シンプルなリモコン操作に適していると思います。

リモコンの限界

赤外線リモコンはコマンドを送出しているだけで、機器の状態を把握できていません。なので、HomeKit側では、赤外線信号が正しく受信されたと仮定して、現在の状態を推定することしかできません。なので、他のリモコンで操作されたり、シーリングライトのように壁スイッチで操作されると、実際の状態と乖離してしまいます。エアコンリモコンのコマンドに、設定温度・風量・風向などの情報が全て含まれているのも、リモコン上の表示を実際エアコンの状態にできる限り合わせたいためです。

さらには、今回使用したシーリングライトのリモコンのように、on/offがトグルで動作するタイプもあります。この場合は、ライトが点灯しているか、消灯しているかを推定することもできません。

HomeKitが正しく状態把握するためには、機器と双方向に通信して、現在の状態を問い合わせできる仕組みが理想です。その点で赤外線リモコンは不完全です。エアコンならば、WiFiで通信するような仕組みを利用したいところです。シーリングライトは、壁スイッチをスマートスイッチにして、人手による壁スイッチ操作もシステムで把握できるようにするのが良いです。壁スイッチを自動化する記事はこちらをご覧ください。

diysmarthome.hatenablog.com

まとめ

Nature RemoをHomeKitで使う方法を説明しました。Natureのクラウドを使う方法と、ローカルAPIを使う方法があります。クラウドを使う場合は、NatureのサーバからトークンやID情報を入手して設定します。ローカルAPIを使う場合は、赤外線パターンを学習昨日により取得し、Nature Remoにhttp送信します。赤外線リモコンを使えば機器の操作が容易ですが、実際の状態を把握できない欠点もあります。

追記

この後、スマート赤外線リモコンをDIYしました。赤外線LEDを取り付けたESP32で動作して、HomebridgeとはMQTT経由で通信します。以下の記事をご覧ください。

diysmarthome.hatenablog.com

diysmarthome.hatenablog.com

diysmarthome.hatenablog.com

diysmarthome.hatenablog.com