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へのデバイスの登録を行います。
- node-red-contrib-broadlink-controlを用いてCodeの学習
- node-red-contrib-alexa-home-skillを用いたNode-Redへのデバイスの登録
- Flowの作成・実行
node-red-contrib-broadlink-controlを用いてCodeの学習
こちらを参考に、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にAlexaで使いたいデバイスを登録します。こちらで登録したデバイスがnode-red-contrib-alexa-home-skillを用いて制御することが可能となります。
具体的な手順は他の方がまとめて下さっている記事が多数あるので割愛します。参考のリンク先等をご覧ください。
Flowの作成・実行
node-red-contrib-alexa-home-skillのフロー作成
参考記事をもとに、Alexa-Homeノードを接続し、Node-RED Alexa Home Skill Bridgeで登録したデバイスを制御できるように設定します。このフローは寝室の電灯をON/OFFしたときに、それぞれ別の処理を呼び出すためのものになります。
Switchの設定は以下の通り、msg.payload
がTrue
であれば上のフローに分岐し、False
であれば下のフローに分岐するというものになります。
node-red-contrib-broadlink-controlのフロー作成
次に、node-red-contrib-broadlink-controlのそれぞれの処理を作成します。フローはこちらのサンプルのRMから赤外線発射を参考に作成しました。黄色の[get]/send
、http
と書かれた2つのhttpノードは無しでも動作しますが、別の用途に後々使うので残しておきます。また、青色の{}
と書かれたinjectノードは手動でfunctionノードを動作させる際に利用するため、最終的には不要ですが、動作確認のために残しておきます。
functionノードの中は設定の以下の通り、data
に学習したコードを記述することで、RM Mini3から指定したコードを発射することが可能となります。
injectノードを使ってfunctionを実行した際のデバッグ内容がこちらになります。これで、先ほど学習したコードがRMから発射され、電灯のON/OFFができることが確認できました。
{
"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つのノードを以下の通り接続しました。
Alexaで寝室電灯をONの操作を行った時のdebug1とdebug2の内容がこちら。どうも、switchノードからtrue
が出力されてしまい、functionでmsg.payload.data
等を代入しようとしてもオブジェクトの型があっていなくて、代入できていないようです。(理解が誤っていれば指摘してくださる方がいらっしゃれば幸いです。)
true
true
そこで、functionノードにmsg.payload = {}
が入力できるように、入力に限らず、空のmsg
を出力するだけのfunctionノードを間に挿入しました。その結果、Alexaからの操作で電灯のON/OFFが正常にできるようになりました。
余談ですが、各デバッグ情報は以下の通りになっていました。
true
{
"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
}
{}
作成したフロー
今回作成したフローは以下のようになります。
[{"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をどうさせる方にはこちらのほうがいいと思います。
また、こちらの記事では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の使い方)
Node-REDを用いてRaspberry PiとAmazon Alexaを連携させる方法
AlexaとNode-RED【初めてのスキル編】