node-red-contrib-broadlink-controlとnode-red-contrib-alexa-home-skillを使ったRM Mini3の制御

# docker上のNode-Redでnode-red-contrib-broadlink-controlとnode-red-contrib-alexa-home-skillを使ったRM Mini3の制御

## はじめに

本記事はnode-red-contrib-broadlink-controlとnode-red-contrib-alexa-home-skillを活用して、各家電をAlexaから操作しようという試みです。また、Node-RedはDocker上で動かしていますが、実マシン上でも同じ設定で動作すると思います。

Docker上でNode-Redを動かす設定は以下のようにしました。

- Docker上にnodered/node-red-dockerをインストール
- node-red-contrib-broadlink-controlとnode-red-contrib-alexa-home-skillをNode-Redにインストール

## 大まかな流れ

以下のような流れで、RM Mini3の学習及び、Flowの作成、Alexaへのデバイスの登録を行います。

1. node-red-contrib-broadlink-controlを用いてCodeの学習
2. node-red-contrib-alexa-home-skillを用いたNode-Redへのデバイスの登録
3. Flowの作成・実行

## node-red-contrib-broadlink-controlを用いてCodeの学習

[こちら](https://blogs.yahoo.co.jp/alexabroadlink/69880582.html)を参考に、node-red-contrib-broadlinkをインストールして、サンプルをImportします。

リンク先のサンプルは取得したCodeを`/home/pi/a.txt`に保存しますが、Docker上で動作しているため、Dockerコンテナとホストの共有フォルダ内のテキストファイルに書き出す形に変更しました。

## node-red-contrib-alexa-home-skillを用いたNode-Redへのデバイスの登録

[Node-RED Alexa Home Skill Bridge](https://alexa-node-red.bm.hardill.me.uk/)にAlexaで使いたいデバイスを登録します。こちらで登録したデバイスがnode-red-contrib-alexa-home-skillを用いて制御することが可能となります。

具体的な手順は他の方がまとめて下さっている記事が多数あるので割愛します。参考のリンク先等をご覧ください。

## Flowの作成・実行

### node-red-contrib-alexa-home-skillのフロー作成

参考記事をもとに、Alexa-Homeノードを接続し、Node-RED Alexa Home Skill Bridgeで登録したデバイスを制御できるように設定します。このフローは__寝室の電灯__をON/OFFしたときに、それぞれ別の処理を呼び出すためのものになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198826/e55d69e4-1e0f-715d-8040-771b7b874b06.png)

Switchの設定は以下の通り、`msg.payload`が`True`であれば上のフローに分岐し、`False`であれば下のフローに分岐するというものになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198826/78de01f8-bd5f-fb7f-0c6a-68bd66993a3c.png)

### node-red-contrib-broadlink-controlのフロー作成

次に、node-red-contrib-broadlink-controlのそれぞれの処理を作成します。フローは[こちら](https://blogs.yahoo.co.jp/alexabroadlink/69880582.html)のサンプルの__RMから赤外線発射__を参考に作成しました。黄色の`[get]/send`、`http`と書かれた2つのhttpノードは無しでも動作しますが、別の用途に後々使うので残しておきます。また、青色の`{}`と書かれたinjectノードは手動でfunctionノードを動作させる際に利用するため、最終的には不要ですが、動作確認のために残しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198826/7642dc9b-6033-22c0-f5c7-dc41eedb0542.png)

functionノードの中は設定の以下の通り、`data`に学習したコードを記述することで、RM Mini3から指定したコードを発射することが可能となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198826/4c58614e-27ce-8e2a-3e93-342dfc367b25.png)

injectノードを使ってfunctionを実行した際のデバッグ内容がこちらになります。これで、先ほど学習したコードがRMから発射され、電灯のON/OFFができることが確認できました。

```c:msg.payload
{
"action":"send",
"data":[38,0,4,2,116,56,16,13,16,12,17,41,16,41,16,13  (--- 中略 ---)　13,5,0,0,0,0],
"repeat":0
}
```


### 2つのフローを接続する

2つのノードを以下の通り接続しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198826/8a8ad7d3-f718-e3d2-023c-b9d604208a43.png)

Alexaで__寝室電灯をON__の操作を行った時の_debug1_と_debug2_の内容がこちら。どうも、switchノードから`true`が出力されてしまい、functionで`msg.payload.data`等を代入しようとしてもオブジェクトの型があっていなくて、代入できていないようです。（理解が誤っていれば指摘してくださる方がいらっしゃれば幸いです。)

```c:debug1
true
```

```c:debug2
true
```

そこで、functionノードに`msg.payload = {}`が入力できるように、入力に限らず、空の`msg`を出力するだけのfunctionノードを間に挿入しました。その結果、Alexaからの操作で電灯のON/OFFが正常にできるようになりました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198826/c2d91f69-fa79-560e-aacf-7ab2bada1d6e.png)

余談ですが、各デバッグ情報は以下の通りになっていました。

```c:debug1
true
```

```c:debug2
{
"action":"send",
"data":[38,0,4,2,116,56,16,13,16,12,17,41,16,41,16,13  (--- 中略 ---)　13,5,0,0,0,0],
"repeat":0
}
```

```c:debug3
{}
```

## 作成したフロー

今回作成したフローは以下のようになります。

```flow:今回作成したフロー
[{"id":"b15e8cb2.d4c58","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"dd94419e.d3773","type":"alexa-home","z":"b15e8cb2.d4c58","conf":"","device":"49323","acknoledge":true,"name":"","topic":"","x":390,"y":200,"wires":[["1ccdb8c6.7a41a7"]]},{"id":"1ccdb8c6.7a41a7","type":"switch","z":"b15e8cb2.d4c58","name":"","property":"payload","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":650,"y":200,"wires":[["d5f0b37b.6d4b9"],["eddc5f1c.bd75f"]]},{"id":"4af407bb.a44d58","type":"function","z":"b15e8cb2.d4c58","name":"","func":"var data = []\nmsg.payload.action = 'send';\nmsg.payload.data = data;\nmsg.payload.repeat = 0;\nreturn msg;","outputs":1,"noerr":0,"x":1070,"y":200,"wires":[["488f0a3e.212ec4","351d401b.2e437"]]},{"id":"488f0a3e.212ec4","type":"RM","z":"b15e8cb2.d4c58","name":"RM","device":"","action":"_msg_","remote":"3","button":"4","fix":1,"RFSweep":"false","x":1310,"y":160,"wires":[[]]},{"id":"dca079bd.da49a8","type":"inject","z":"b15e8cb2.d4c58","name":"","topic":"","payload":"{}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":870,"y":120,"wires":[["4af407bb.a44d58"]]},{"id":"2f4a7577.9b4f2a","type":"function","z":"b15e8cb2.d4c58","name":"","func":"var data = [];\n \nmsg.payload.action = 'send';\nmsg.payload.data = data;\nmsg.payload.repeat = 0; \n\nreturn msg;","outputs":1,"noerr":0,"x":1070,"y":360,"wires":[["48be7a16.0f8414","e6048187.dfc81"]]},{"id":"6d580f3d.f79c","type":"http in","z":"b15e8cb2.d4c58","name":"","url":"/send","method":"get","upload":false,"swaggerDoc":"","x":670,"y":400,"wires":[["2f4a7577.9b4f2a"]]},{"id":"48be7a16.0f8414","type":"RM","z":"b15e8cb2.d4c58","name":"RM","device":"","action":"_msg_","remote":"3","button":"4","fix":1,"RFSweep":"false","x":1310,"y":320,"wires":[[]]},{"id":"e6048187.dfc81","type":"http response","z":"b15e8cb2.d4c58","name":"","statusCode":"","headers":{"content-type":"application/json"},"x":1310,"y":380,"wires":[]},{"id":"858d4656.ea47f8","type":"inject","z":"b15e8cb2.d4c58","name":"","topic":"","payload":"{}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":690,"y":340,"wires":[["2f4a7577.9b4f2a"]]},{"id":"eddc5f1c.bd75f","type":"function","z":"b15e8cb2.d4c58","name":"","func":"msg.payload = {};\n \nreturn msg;","outputs":1,"noerr":0,"x":870,"y":280,"wires":[["2f4a7577.9b4f2a"]]},{"id":"d5f0b37b.6d4b9","type":"function","z":"b15e8cb2.d4c58","name":"","func":"msg.payload = {};\n \nreturn msg;","outputs":1,"noerr":0,"x":870,"y":220,"wires":[["4af407bb.a44d58"]]},{"id":"351d401b.2e437","type":"http response","z":"b15e8cb2.d4c58","name":"","statusCode":"","headers":{"content-type":"application/json"},"x":1310,"y":220,"wires":[]},{"id":"6bc43cd.9cc55c4","type":"http in","z":"b15e8cb2.d4c58","name":"","url":"/send","method":"get","upload":false,"swaggerDoc":"","x":690,"y":140,"wires":[["4af407bb.a44d58"]]}]
```


## 余談

多くの記事では、RM BridgeにHTTP Requestを送信するようになっており、アンドロイド上でRM Bridgeを常時動作させる必要があります。こちらの機序の内容を使うと、RM Bridge不要ですので、アンドロイド端末をお持ちでない方や、普段使いのスマホ上でRM Bridgeをどうさせる方にはこちらのほうがいいと思います。

また、[こちら](https://qiita.com/yb3/items/2a534da33f0d739fd560)の記事ではRm Bridge使って学習したコードを再利用しようとしましたが、RM BridgeはCodeを10進数、node-red-contrib-broadlink-controlはCodeをカンマ区切りの16進数で表記する必要があり、変換が面倒なので、学習もnode-red-contrib-broadlink-controlを利用することとしました。

## 参考

[node-redのみでRM miniを操作　（node-red-contrib-broadlinkの使い方）](https://blogs.yahoo.co.jp/alexabroadlink/69880582.html)
[Node-REDを用いてRaspberry PiとAmazon Alexaを連携させる方法](http://kodawarism.hatenablog.jp/entry/install_node-red_alexa_home_skill_bridge)
[AlexaとNode-RED【初めてのスキル編】](http://themaster.asia/2019/04/09/raspi/alexa_node-red_skill.html)