はじめに
最近はHueやIKEAのスマート電球、Tp-LinkやAmazonのスマートプラグなど、Amazon Echoに対応している製品が多く販売されています。これにより、声で「アレクサ、電気をつけて」と操作したり、スマホのAlexaアプリから電気をOnにすることができるようになりました。
Amazon Echoは家電をコントロールするハブになりつつありますが、声やスマホ以外から家電を操作したい場合があります。例えば、Alexaに対応していない温度計の値が35℃になったらエアコンをつける、WebAPIをインタフェースとして家電を操作するなどです。
そこで今回は、Amazon Echoに接続された家電をNode-redから操作できるようにしてみたいと思います。
設定手順
Alexa-remote2のインストール
Node-redを使ってスマートホーム機器を操作するためには、node-red-contrib-alexa-remote2とNode-redを使います。
①パレットの表示
Node-redの右上の「三」メニューから「パレットの管理」を選択します。

②ノードの追加
パレットの管理画面から「パレット」→「ノードを追加」タブを選択します。

③Alexa-remote2の追加
画面の検索欄に「alexa-remote2」と入力し検索し、検索結果に出て来た「node-red-contrib-alexa-remote2」の「ノードを追加」ボタンをクリックします。

④ノードの追加確認
しばらく待つとnode-red-contrib-alexa-remote2がインストールされるので「閉じる」ボタンをクリックします。

画面左側のパレットにも「alexa」が追加され7個のノードが追加されています。

Alexa-Routineノードの設定
①Alexa-Routineノードの追加
パレットからAlexa Routineノードをドラッグしてフローに追加します。次にAlexa Routineノードをダブルクリックして編集画面を表示し、Account欄の鉛筆アイコンをクリックします。

②Alexa Accountノードの設定
Alexa Accountノードの設定画面が表示されるので、This IP欄にNode-redをインストールしたホストのIPアドレスを入力します。

次に、下にスクロールして、Service Host、Page、Language欄を以下のように設定します。

③設定の完了
「追加」ボタンをクリックし、Alexa Accountノードの設定画面を閉じます。

次に、「完了」ボタンをクリックしてAlexa Routineノードの編集画面を閉じます。

④デプロイ
ここまでの設定をNode-redに反映するために「デプロイ」ボタンをクリックします。

⑤Amazon Alexaにログイン
「デプロイ」ボタンをクリックすると、Alexa Routineノードの下に「open <<IPアドレス>>:3456 in your browser」と表示されます。この指示に従って、ブラウザで新しいタブを開き「http://<<IPアドレス>>:3456」のアドレスを入力して開きます。

するとamazon alexaのログイン画面が表示されるので、お使いのアカウントとパスワードでログインします。

ログインが完了すると以下のような画面が表示されます。

⑥Alexa Routineノードの確認
しかし、Node-redの画面に戻り、Alexa Routineノードを確認すると「Unexpected end on JSON input」と表示され、エラーになっています。これはAlexa-remote2が日本語版のAmazon Alexaに対応していないためです。

Alexa-Cookieの変更
Alexa-remote2からAlexaを利用するためにはAmazon Alexaへのログイン時に取得したCookie情報が必要です。しかし、このCookie情報が日本語版のAmazon Alexaでは少々特殊なため日本語版に対応させる必要があります。
①Alexa-Cookieのバージョンを確認
Node-redをインストールしたホストにログインし、Node-redの設定ディレクトリ(通常はユーザディレクトリ内の.node-red)に移動して「npm list」と入力します。すると、以下のようにインストール済みモジュールが表示されるので、alexa-cookie2の欄を確認します。私のAlexa-Cookieのバージョンは3.4.1でした。
1 2 3 4 5 6 7 8 9 |
$ cd .node-red/ $ npm list node-red-project@0.0.1 /home/pi/.node-red ├─┬ node-red-contrib-alexa-remote2@3.10.4 │ └─┬ alexa-remote2@3.3.1 │ ├─┬ alexa-cookie2@3.4.1 │ │ ├── cookie@0.4.1 │ │ ├─┬ express@4.17.1 |
②alexa-cookie.jsを開く
設定ディレクトリ内の「node_modules/alexa-cookie2」にalexa-cookie.jsがあるので、これをバックアップ(コピー)して、テキストエディタで開きます。
1 2 3 |
$ cd node_modules/alexa-cookie2 $ cp alexa-cookie.js alexa-cookie.js.org $ vi alexa-cookie.js |
③alexa-cookie.jsの変更
alexa-cookie.jsの261行目辺りにある「_options = __options;」の記載を探し、この下の行に「_options.baseAmazonPage=’amazon.co.jp’;」の行を追加します。
1 2 |
_options = __options; _options.baseAmazonPage='amazon.co.jp'; //<--この行を追加 |
④proxy.jsを開く
次に、alexa-cookie.jsがあるディレクトリ内の「lib」ディレクトリにproxy.jsがあるのでこれを開きます。
1 2 3 |
$ cd lib/ $ cp proxy.js proxy.js.org $ vi proxy.js |
⑤proxy.jsの変更
www.amazon.comとwww.amazon.co.jpは少し仕様が違うようで、181行目あたりにあるreturnedInitURLを以下のように変更します。
1 2 |
//returnedInitUrl = `https://www.${_options.baseAmazonPage}/ap/signin?openid.return_to=https%3A%2F%2Fwww.${_options.baseAmazonPage}%2Fap%2Fmaplanding&openid.assoc_handle=amzn_dp_project_dee_ios${_options.baseAmazonPageHandle}&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&pageId=amzn_dp_project_dee_ios${_options.baseAmazonPageHandle}&accountStatusPolicy=P1&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns.oa2=http%3A%2F%2Fwww.${_options.baseAmazonPage}%2Fap%2Fext%2Foauth%2F2&openid.oa2.client_id=device%3A${deviceId}&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.oa2.response_type=token&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.pape.max_auth_age=0&openid.oa2.scope=device_auth_access&language=${_options.amazonPageProxyLanguage}`; returnedInitUrl = `https://www.amazon.co.jp/ap/signin?showRmrMe=1&openid.return_to=https%3A%2F%2Falexa.amazon.co.jp%2F&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.assoc_handle=amzn_dp_project_dee_jp&openid.mode=checkid_setup&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&`; |
⑥Node-redの再起動
上記の変更を有効にするために、念のため、Node-redを再起動しておきます。
1 |
$ sudo systemctl restart nodered.service |
機器操作の設定
Alexa-Cookieの変更が完了したら、再度Alexa-Routineノードの設定に戻ります。
①Cookieの再取得
上でNode-redを再起動したため、ブラウザからNode-redの画面を再読み込みします。すると、Alexa Routineノードの下に再度「open <<IPアドレス>>:3456 in your browser」と表示されるので、ブラウザで「http://<<IPアドレス>>:3456」を開きます。

amazon alexaのログイン画面になったら、ログインします。

ログインすると、以下のようにエラー画面となります。

しかし、Node-redの画面に戻ってみるとAlexa Routineノードの下にReadyと表示されており、Alexa-RoutineからAlexaへのアクセスが可能となったことが確認できます。

②操作情報の入力
Readyになったら、Alexa Routineノードをダブルクリックして設定画面を表示します。そして、操作欄から「SmartHome」を選択します。するとAlexaと連携している機器が選択できるようになります。
そして、一覧から操作したい機器を選択し、Actionには操作方法を選択します。以下の例では、照明をオフにします。
一点注意点としてゃ、デバイス名が日本語の場合、文字化けしてしまうので、Alexa側で機器名を英語で設定しておくのが良いと思います。

③Injectノードの追加
最後にInjectノードを下のように追加し、ノード間を接続し、「デプロイ」ボタンをクリックします。

④テスト
それでは、Injectノードの左のボタンをクリックしてみましょう!!Amazon Echoに接続されている機器が動作しましたか?

おわりに
今回はNode-redにnode-red-contrib-alexa-remote2をインストールし、Node-redからAmazon Echoに接続されているスマートホーム機器を操作することをやってみました。
Node-redからスマートホーム機器を自由に操作できることが可能になったことで、Alexa非対応の機器との連携、WebAPIを通じた家電の操作、MQTTをベースとした家電操作など、自由度が格段にあがります!
コメント
v3.2.1の頃から「Alexa-Cookieの変更」を参考にさせていただいてます。
さて,naka-kazz様にお聞きするのが筋違いな気もしますが、お時間がありましたら教えて下さい。
上記のとおり「node-red-contrib-alexa-remote2」で色々と遊んでいるのですが、何かの拍子にcookie再取得(amazon alexaの認証作業)を求められる状態に戻っているときがあります。特に操作しなくてもそうなるときもあります。
これはどんな事が考えられるでしょうか?また、この認証作業を自動化することは出来るものでしょうか?
ブログをお読みいただきありがとうございます。そうですよね、Cookie取得待ちに戻ってしまう事があります。
当ブログのユーザ様でCRONを使った自動化をしている方がいますので、参考になると思います。以下の記事の一番下のコメント欄を参照ください。
https://www.smarthome-diy.info/blog/developper/smarthome/2020/09/2049/
いつもありがとうございます!
おかげさまでNodeREDからAlexaを喋らせたり出来るので、スマートホームのクオリティが格段に上がっております。
ただ、一点だけ残念なことがあり、定期的にcookieが切れて(?)modeledのAlexa RoutineがReady」から「open your browser …」に戻ります。
これって私だけですか?
それとも何か対策していますか?
常用だとなかなか大きな問題と感じています。
何か知っていることがあれば教えていただきたいです!
ブログをお読みいただきありがとうございます。私もときどきCookieが切れてしまいます。当ブログのユーザ様でCRONを使った自動化をしている方がいますので、参考になると思います。以下の記事の一番下のコメント欄を参照ください。
https://www.smarthome-diy.info/blog/developper/smarthome/2020/09/2049/
いつも楽しみに、そして有難く拝見させて頂いております。
今はRaspberry Pi Zero WHにNode-RED環境を構築して楽しんでいます。
Alexa-Cookieの記事はとても参考になりました。
また、今回の記事も参考にさせて頂いて、郵便受けにセンサー(リードスイッチ)を取り付け、検知したらEcho Showに喋らせて、かつ、郵便受けを確認するように「やることリスト」に登録しています。
本記事そのものではありませんが、一点だけ問題が解決できていません。
夜中になったらGet List Itemsで取得した「やることリスト」の項目を判別してRemove Itemで削除しようとしましたが、削除に必要なidをmsgで渡すとエラーで動作しませんでした。文字列定数で設定すると動作するのですが・・・。
しかたなく今は、Edit Itemで完了(Completed)にして、気付いた時に手動で削除しています。
今後、何か気付いたことがあれば教えてください。
あと、他の方もコメントしていましたが、cookieの問題はAccount設定でRefreshをデフォルトの3dayにしているので、そのくらいで有効期限切れになっているのだと勝手に思っています。
有効期限を長くするのもアリですが根本的な解決にはならないので、私は毎晩Alexa InitノードのオプションでRefresh Cookieを指定して強制的にリフレッシュした後、Pythonからseleniumをヘッドレスモードで動かして自動ログインしてCookieを再取得するフローを動かしています。まだ動作させて数日ですが問題なく動作しています。
これからも楽しみに読ませていただきます。