GravioとNature Remoで家電をコントロールする

Gravioでいろんな家電を制御できるといいなぁと思うことがある。ずいぶん前にいろいろ調べてみたことがあったんだけど、どれもクラウド経由になり、エッジ志向なGravioとは相性悪いなぁと思っていた。（できなくないけど美しくない）

で、最近ふと[こちらの記事][yuu26-memo]を見つけた。このNature Remoという赤外線リモコンを真似っこして家電を制御するガジェット、以前から知っていたんだけど、ローカルのAPIがあるのは知らなかった。
[公式にAPIをSwaggerで公開][Nature Remo Local API]してるみたいだし、これはいいねと早速買ってGravioとつないでみました。

ちなみに、Nature RemoはRemoとRemo miniというのがあって、今回は対応距離が長ければ長いほどいいだろってのでこの黒いやつを買いました。その他機能の比較は公式ページを見てね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/2abc81dc-ecb1-f95d-ffb6-48cd631a5e40.png)

# 使用環境

* Raspberry Pi 4 Model B w/8GB RAM
* Ubuntu Server 20.04.2 LTS
* Gravio HubKit v4.3.0-6807
* Gravio Studio v4.3.4198.0

# 手順
## Nature Remoのセットアップ
Nature Remoのセットアップはかんたんです。Nature Remoを付属のケーブルで電源につなぎ、アプリをダウンロードしてセットアップするだけです。
詳しくはマニュアルもしくはアプリを参照してくださいね。

## Nature RemoのIPアドレスを見つける
Nature RemoはWiFiでローカルネットワークに接続します。セットアップ時にWiFiのSSIDとパスワードを指定したと思います。
これを見つけるには、[Nature Remo Local API][Nature Remo Local API]のBonjourのセクションに書いてあるとおり、`dns-sd` コマンドを使って調べます。


まずは `_remo._tcp` のサービスを見つけます。

```
% dns-sd -B _remo._tcp
Browsing for _remo._tcp
DATE: ---Wed 15 Nov 2017---
12:27:52.349  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
12:27:52.603  Add        2  12 local.               _remo._tcp.          Remo-XXXXXX
```
インスタンス名がわかりますので、`.local`をつけてIPアドレスを取得します。

```
% dns-sd -G v4 Remo-XXXXXX.local
DATE: ---Wed 15 Nov 2017---
12:30:58.520  ...STARTING...
Timestamp     A/R Flags if Hostname                               Address                                      TTL
12:30:58.735  Add     2 12 Remo-XXXXXX.local.                     10.0.1.3                                     120
```

これでOKですね。

ちなみに、ルーターの画面等で簡単に見つけられることもあります。私の家のTP-Linkのアプリではこんな感じで見えました。自動取得の名前がちょっと分かりづらかったですけど、MACアドレスでわかりました。MACアドレスはNature Remoのアプリで知ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/1aa6d2b7-ba5d-3f9e-221e-857991b1711a.png)

## 赤外線のコマンドを取得する
赤外線のコマンドを取得するのも簡単です。ローカルAPIは基本的に`http://<ipaddress>/messages`のエンドポイントにリクエストを出します。`GET`だと直近にRemoが受信したコマンドを返してくれます。`POST`でRemoからコマンドを送信します。

なので、簡単なのは`curl`コマンドを実行することです。

一度Nature Remoに向けてリモコンのボタンを押します。すると、ケーブルが出てる側にあるLEDが青く光ります。その後、次のようにコマンドを実行すると表示されるのが赤外線のコマンドです。

```
ubuntu@gravio-rpi4-8g:~curl http://192.168.0.40/messages -H "X-Requested-With: local"
{"format":"us","freq":38,"data":[8989,.....]}
ubuntu@gravio-rpi4-8g:~$
```

これをコピペしておきましょう。

で、これだけならGravioでも調べることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/37d3916d-302f-0ad3-5f40-01bb21944b80.png)

HTTP Requestコンポーネント一つ。簡単ですね。ヘッダをPreMappingsで指定するのを忘れないようにしてください。
また、URLは`https`ではなく`http`で始まりますので、ここも注意してくださいね。

実行すると下のようにコンソールに結果が表示されますので、これをコピペしておいてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/e6320dc7-4adb-949e-4559-98bbb568d1d9.png)

## 赤外線コマンドを実行するアクション
最後に赤外線コマンドを実行するアクションを作ります。
先程も言ったように実行するのもほぼ同じです。メソッドをPOSTに変えて、先程コピペしておいたコマンドをデータとして送ります。データとして送るにはいつものように `cv.Payload` にマッピングすればいいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/d7014b4b-475e-38c8-217c-81f481ab187e.png)

これでアクションを実行するとリモコンの代わりにGravioから家電が制御できたと思います。
うまくいかないようであれば、まずNature Remo単体で動かしてみるのがいいと思います。

# ハマリポイント
今回、最初に使ったのが部屋のライトだったのですが、この部屋のライト、Bluetoothのリモコンだったために何度Nature Remoに受信させても反応なしだったんですね。まぁ、よく見ると赤外線の送信部がないので当たり前なんですが。まぁ、ライトのリモコンくらいだと赤外線だろうという固定観念でしばらくハマりました。

あと、`curl`コマンドを使って試しにコマンドを送ってみるかもしれませんが、そのときLinuxではうまく行ったけどWindowsのコマンドプロンプトだとうまく行かないというのがずっとありました。コマンド自体は同じなんですが、データを渡すときにJSONなので `"`が入ってますね。これを安直に全体を`'`でくくってしまっていたために、Windowsのcurlコマンドでは動かなかったのです。全体を`"`でくくって、キーや値の`"`を`\"`というふうにエスケープすればいけました。

# 活用法
さて、Gravioでどう活用するのがいいかなぁといろいろ考えてみたんですが、まぁ、まずはエッジということで考えればいいんですかね。Nature Remo自体いろいろできるので、例えば温度が上がったらエアコン入れるとか、家に近づいたらエアコン入れるとか、朝エアコン入れるとかいろいろ単体でできてしまいます。ただ、このあたりはたぶんクラウド経由なので、エッジでやりたければGravioからタイマー使ったり温度センサー使ったりすることは可能ですね。
あと、赤外線リモコンがついてれば何でもいけますので、扇風機とかサーキュレーターあたりのショボい家電をコントロールするのにはいいかもしれないですね。GravioといえばCO2センサー。CO2が上がってきたら換気するためにサーキュレーター回すとかはいいかもしれません。

# 参考にした記事・サイト
* [Nature Remo Local API でローカルからリモコン信号を送る][yuu26-memo]
* [Nature Remo][]
* [Nature Remo API][]
* [Nature Remo Local API][]
* [Gravio][]
* [HTTP Requestコンポーネント][Gravio-HTTPRequest]
* [Pre Mappings / Post Mappingsでの式の記述の仕方][Gravio-Mappings]

[yuu26-memo]:https://blog.yuu26.com/nature-remo-local-api/
[Nature Remo API]:https://developer.nature.global/
[Nature Remo Local API]:https://local-swagger.nature.global/
[Nature Remo]:https://nature.global/nature-remo/
[Gravio]:https://www.gravio.com/jp
[Gravio-HTTPRequest]:https://doc.gravio.com/manuals/gravio4/1/ja/topic/httprequest
[Gravio-Mappings]:https://doc.gravio.com/manuals/gravio4/1/ja/topic/premappings-postmappings