こと始め
- Google HomeのCMみたいに声で照明をつけたい!
- Amazon EchoとeRemote miniを買ったけど、コレジャナイ!
- Raspberry Piというものがあれば、いい感じに自作できるらしい
やりたいこと
素人具合
- 一応IT業界
- 普段はワードとパワポしか使わない非エンジニア
- webは全然わからない
- linux触ったことない
- プログラミングできない
- markdownわからない
使ったもの
ハードウェア
- Google Home/Amazon Echo(どちらか)
- eRemote mini(RM mini3)
- Raspberry Pi Zero W
ソフトウェア・サービス
- node-RED
- python-broadlink
- IFTTT
- ngrok
工数
- 1人日くらい
参考にした主な記事
- Echosim.ioを使うと日本でもAlexaでSmart Homeを実現できるので、安価なBlack Beanで照明やエアコンを制御してみた
- Amazon Echoとラズパイで、音声で照明をon/offする
- Google Homeとスマートでない家電を接続する
- ほか多数
この記事は「素人でも上の記事を見てできたよ!」というものなので、特に新規性はありません。ごめんなさい。
0.事前準備
情報収集
- RM mini3を制御できるpythonライブラリ?があって、これを使えばいいらしい
- APIはnode-REDというもので簡単に作れそう
- AlexaやGoogle HomeからAPIを叩くには、IFTTTとwebhooksを使うといいらしい
- ngrokで自宅のサーバをインターネットに公開できるらしい
ざっくり設計
1.Raspberry Piのセットアップ
Raspberry Pi(以下Rpiと書きます)を買ってセットアップしました。わかりやすい参考情報はwebに沢山ありましたので、詳細は割愛します。
購入
スイッチサイエンスというサイトでRaspberry Pi zero Wのケース付きを注文。2日程度で届きました。MicroSDカードはAmazonでトランセンドの16GBを買いました。
セットアップ
Raspbian(OS)をセットアップします。以下のサイトを参考にLiteをインストールして、とりあえず家のMacからsshで接続できるようになりました。
参考1:Raspberry Piの無線LANをmicroSDで設定する
参考2:[Raspberry Piの無線LANをmicroSDで簡単に設定するためのツールを作った]
(https://qiita.com/mascii/items/a43d71572e1919e56398)
2.Python-broadlink
RpiにRM mini3を制御するためのpythonツールを導入して、簡単なテストをしました。
手順はほとんど以下の参考サイトと同じです。
Echosim.ioを使うと日本でもAlexaでSmart Homeを実現できるので、安価なBlack Beanで照明やエアコンを制御してみた
インストール
まずgitをインストールし、gitでpython-broadlinkをダウンロードします。
素人なので、gitが何かは特に気にしません。
sudo apt-get install git
git clone https://github.com/mjg59/python-broadlink.git
次にpipをインストールし、pipでbroadlinkというライブラリをインストールします。
素人なので、python-devとpipが何かはよくわかりませんが、とりあえずインストールしました(あとで調べました)。
sudo apt-get install python-dev
sudo apt-get install python-pip
sudo pip install broadlink
リモコンの学習
まずbroadlink_discoveryを実行して、同じネットワーク内のRM mini 3を探し、参考サイトのとおりに「ROOM.device」というファイルを作ります。
(ここで人生で初めてviというものを使ったのですが、たった1行のテキストファイルを作るのに30分くらいかかりました。。。)
./broadlink_discovery
vi ROOM.device
(このあとviで操作してテキストを編集する)
次にpython-broadlinkのcliコマンドを使って、照明のリモコンのON/OFFを学習させます。ここも参考サイトのとおりです。
./broadlink_cli --device @ROOM.device --learnfile LIGHT.on
(RM mini3に向けてリモコンのONボタンを押す)
./broadlink_cli --device @ROOM.device --learnfile LIGHT.off
(RM mini3に向けてリモコンのOFFボタンを押す)
動作テスト
以下のコマンドで、Rpiから照明のON/OFFができました。すごい!
./broadlink_cli --device @ROOM.device --send @LIGHT.on
./broadlink_cli --device @ROOM.device --send @LIGHT.off
3.node-RED
Rpiにnode-REDというツールを導入して、HTTPからpython-broadlinkを操作できるようにしました。
参考1:第三回 Raspberry Pi 3に最新のNode.jsをインストールする
参考2:Node-RED日本ユーザ会 - Running on Raspberry Pi
node.jsのインストール
node.jsというものが必要らしいので、これをRpiにインストールします。
例によって、npmが何かは気にしません。
sudo apt-get install nodejs npm
次にnという何かをインストールして、node.jsのLTS版をインストール(?)します。
この辺りは正直、一体自分が何をしてるのか全くわかりませんでした。
(一応、後で勉強しました。)
sudo npm cache clean
sudo npm install n -g
sudo n lts
node-REDのインストール
npmでnode-REDをインストールします。「--unsafe-perm」が何かはわかりません。
sudo npm install -g --unsafe-perm node-red
起動します。自動起動の設定については参考2に書いてありますので省略します。
node-red-pi --max-old-space-size=256
手元のPCのブラウザからRpiのIPアドレスの1880ポートにアクセスしてみて、node-REDの画面が表示されたら成功です。
node-REDのフロー作成
node-REDのGUIエディタで、python-broadlinkを実行するAPIを定義します。
手元のMacのSafariから以下のアドレスにアクセスして、http-in、http-response、execノードをつなげてフローを定義しました。
RESTfulとかよくわからないので、http-inのURIは適当に決めました。
動作テスト
手元のMacのブラウザで、RpiのIP:1880/Lihgt/on/にアクセスすると、部屋の照明がつきました。すごい!
4.セキュリティ設定
node-REDを外部に公開するため、簡単なセキュリティ設定をしました。
ただ、設定内容にあまり自信がないのと、試行錯誤を記録しておらずコマンドを再現できなくなってしまったので、概要だけ書きます。
ファイアウォールの導入
無用なポートを公開してしまわないよう、Rpiにファイアウォールを導入します。特に理由はないのですが、iptablesではなくfirewalldを使いました。
後でわかったことなのですが、ngrokは特定のポートのみを指定して公開するため、ここの対策は実は不要だったかもしれません
node-REDのeditor認証設定
node-REDをwebサーバ代わりに公開するので、editorに他人がアクセスできないよう、settings.jsを編集してパスワード認証を設定しました
node-REDのHTTP-inノードの認証設定
他人に我が家の照明をON/OFFされないよう、node-REDのWeb API(HTTP-inノード)にもBASIC認証を設定します。
※BASIC認証で充分であるのかについては確証がありませんが、設定しないよりはマシだと思います。
node-RED実行ユーザの作成
node-REDのAPIから意図しない操作を実行された場合を想定して、実行専用のユーザを作成し、乗っ取られても大したことができないように権限設定しました。
5.ngrokでAPIを公開
ngrokで、Rpiのnode-REDのポートをインターネットに公開しました。
アカウント登録
ngrokのサイトから、アカウントを登録します。
https://ngrok.com
ngrokのインストール
Rpiにngrokをインストールします。
(コマンドのログがどっか行ってしまいました。。。後で書き足します。)
インストールしたngrokにauthを登録します。
(コマンドのログがどっか行ってしまいました。。。後で書き足します。)
ngrok 起動
いよいよngrokを起動して、node-REDで作ったAPIを公開します。
node-REDのポート設定を変えていなければ、以下のように1880ポートを指定してngrokを起動すると、公開が開始されます。
./ngrok http 1880
動作テスト
ngrokに表示されたURLに、BASIC認証と定義したAPIのURLを付け加えて、他のPCやスマホのブラウザからアクセスしてみます。
照明がついたらテスト成功です。
6.IFTTT設定
alexa又はGoogle Assistantと連携して、WebhooksでAPIを叩けるようにしました。
IFTTTサインイン
IFTTTのアカウントを持っていなければ、まずはサインインします。
Appletのトリガを設定
IFTTTでAppletを作成します。トリガ(this)にalexaかGoogle Assistantを設定し、トリガーとするフレーズを決めます。
私は当初はAmazon Echo(alexa)を使う予定でしたが、IFTTTを呼び出すのに「トリガー」と発声しなければならないのが嫌だったのと、Google Assistantは任意の返事を設定できる点が気に入り、Google Homeに切り替えました。
AppletのActionを設定
アクション(that)でwebhooksを選択し、ngrokで公開しているAPIのURLを設定します。このときBASIC認証の情報も忘れずに入れ込みます。
認証情報を平文で直接打ち込むというセキュリティ的に残念な実装ですが、悪用されても我が家の照明が操作されるだけなので諦めました。
完成
スマートスピーカーに「照明をつけて」と言うと、照明がつきます。
先人の知見と素晴らしいサービスを使って、素人でもスマートな暮らしを手に入れることができました。
レスポンスタイム
「照明をつけて」と言い終わってから、だいたい2秒でRM mini3 が動作します。
若干遅い気もしますが、Google Homeだと返事を設定できるので、「わかりました」→電気がつく、という感じでほとんどストレスはありません。
TVのチャンネルを変える、とかだとちょっと遅いかも。
おわりに
これまでlinuxやCLI、各種webサービスに触る機会がなかったので、いい勉強になりました。
またこの雑文を書くにあたってmarkdownも初めて使いましたが、とても気に入りました。
内容に関してはほぼ付け焼き刃の知識のみで書いていますので、誤りがあったらすみません。ご指摘いただけると幸いです。
今後の改善点
- ngrokの起動のたびに変わってしまうURLをwebhooksに直打ちしてるブサイクな実装をどうにかしたい
- セキュリティ的に不安な実装があまりに多いので、せめて不正検知の仕組みを入れたい
- そもそも同じネットワークにいるGoogle homeとRM mini3がインターネット経由でしか連携できないのをどうにかしたい