はじめに
先日待ちに待ったNature Remoの公式APIが公開されました
で、Qiitaでこんなの素晴らしい記事も見つけました
- Amazon Echoで「○○をつけて」と言って家電を操作する - Qiita
- Amazon Echoに「アレクサ、NHK」、「アレクサ、日テレ」と呼び掛けてテレビのチャンネルを変える - Qiita
これらを組み合わせてみます
Node-REDって今回はじめて使ったのですが、めちゃくちゃ便利ですね。これは楽しい
フロー的なもの
1.Echoに自然な感じで話しかける
「アレクサ、テレビつけて」「エアコンつけて」「テレビの音量下げて」「電気消して」
2.Node-RED Alexa Home Skill Bridgeで受け取ってローカル(今回はラズパイ)のNode-REDに渡す
3.Node-REDからNature RemoのAPIを叩いて家電を操作
めっちゃ簡単そうに見える(簡単とは言っていない)
やったこと
Node-REDの登録とインストールと準備
この辺は前述の記事の「Amazon Echo + Macbook Pro + Nature Remoで家電を操作するための設定手順」がすごくわかりやすいのでそちらを参考に進めると良いです
まずはNode-RED Alexa Home Skill Bridgeにユーザ登録し、操作したいDeviceを登録
登録したDevicesはこんな感じ
Nameはアレクサに呼びかけるときの対象の名前で、これはあとでアプリから変更することもできるっぽいんですが、下手に変更すると管理しづらくなったり混乱するので最初から呼びかける名前で付けます
「アレクサ、照明つけて」より「電気つけて」のほうが呼びかけやすいし自然ですよね
Descriptionはまあ適当に。こっちはあとからEditできます
Actionは、デスクライトはオンオフのみ、テレビと電気は後述しますが音量や明るさを設定するために%も指定(+%、-%だとうまくいかず)、エアコンはわかりやすく温度とその+-ですね
次はスマホのalexaアプリかweb画面から操作です
まずはalexaに「Node-RED」のスキルを追加し、先程登録したDeviceを検出
web画面なら「検出」を、スマホアプリなら「+デバイスを追加」をタップで読み込んでくれます
Node-RED環境は、私はラズパイ上に構築したので元記事とちょっと違いました
困ったときの公式ドキュメント
私のラズパイにはNode-REDがプリインストールされていたっぽいので、お勧めに従いアップグレードしてみる
$ bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)
(なんか色々聞かれたけどとりあえずYって答えるとしばらく待たされる)
$ update-nodejs-and-nodered
(同じくYでまたしばらく待たされる)
これでインストールが完了したはず
node-red
コマンドを実行してStart的なメッセージが出たらOK
http://<ラズパイのIP>:1880/
にアクセスするとNode-REDの画面が出てきます
ついでに自動起動設定もするとなお良し
$ sudo systemctl enable nodered.service
Node-REDのフロー作成
ここからはhttp://<ラズパイのIP>:1880/
のGUIから操作
やはり元記事が素晴らしいので、手順3の後半に従ってnode-red-contrib-alexa-home-skill
というNode-RED用プラグイン(パレットと呼ぶらしい)をインストール
このとき検索結果にnode-red-contrib-alexa-home
という似た名前のものも出てくるので注意
こっちも使えるのかもだけど使ったことないのでわからんです
基本的には左側メニューからノードを持ってきていい感じにつなぐだけです。どれを選ぶかは図から判断してください
一応エアコンだけ中を載せます
Accountのペンマークから手順1で登録した登録したユーザを入力し、Deviceの更新マークをクリックで登録したDeviceが出てくるので選択
ここでは手順1で登録したDeviceに対応するActionのコマンドが選べます
コマンドはここの一覧から対応するものを選択
changeノードでは次のノードであるexecノードに渡すパラメータを指定します
msg.payload
はデフォルトのままで良く、on
としているところは短くわかりやすいパラメータ名がおすすめ
最後にここで実行するシェルスクリプトを指定します
まだ作ってなければ空でもOK
すべての編集操作が終わったら必ず右上の「デプロイ」ボタンを押しましょう
これ以降、何かしら変更を加えた際にも同じくです
Nature Remo APIを使おう
ここからは前項の最後で出てきたシェルスクリプトを作成します
今回はシェルスクリプトからNature Remo APIを叩くことで家電を操作するので、APIを色々といじくり回します
Nature Remo APIの公式ドキュメントはこちら
swagger、いいですよね(独り言)
まずはここからトークンを発行
一度表示されたトークンは二度と表示されないので何処かファイルにでもメモっておきましょう
こいつを使ってとりあえず自分のremoに登録されてる家電と操作を取得してみます
curl https://api.nature.global/1/appliances -H "Authorization: Bearer <accesstoken>" | jq .
<accesstoken>
には取得したトークンを指定しましょう
ちなみにこのときトークンをファイルに1行ペロッと書き込んでると
curl https://api.nature.global/1/appliances -H "Authorization: Bearer $(cat /path/to/token.txt)" | jq .
みたいにそのまま読み込めるのでめっちゃ楽です
また、結果はJSONで返ってくるので整形するのにjqを使ってます
jqについてはこちらがわかりやすいです
さて結果です
[
{
"id": "6c10f1a1-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"device": {
"name": "Remo",
"id": "837b1dc8-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"created_at": "2017-11-12T09:05:04Z",
"updated_at": "2018-02-12T07:47:31Z",
"firmware_version": "Remo/1.0.62-gabbf5bd",
"temperature_offset": 0,
"humidity_offset": 0
},
"model": {
"id": "DCF7AEC4-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"manufacturer": "daikin",
"remote_name": "xxxxxxxx",
"series": "Daikin AC",
"name": "Daikin AC 002",
"image": "ico_ac_1"
},
"nickname": "Daikin AC 002",
"image": "ico_ac_1",
"type": "AC",
"settings": {
"temp": "26",
"mode": "warm",
"vol": "auto",
"dir": "",
以下略
なげえよ。。。
まあでも取得できるのがわかったので良し
次に家電を操作するための信号を送信してみます
先程の結果から一部を抜粋
{
"nickname": "デスクライト",
"signals": [
{
"id": "5320d922-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"name": "オン",
"image": "ico_record"
}
]
}
このid
の値を使って、こんな感じ
curl -X POST https://api.nature.global/1/signals/5320d922-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send -H "Authorization: Bearer $(cat /path/to/token.txt)
はいデスクライトついたー(はず)
他も基本的には同じです
が、エアコンだけはAPIが違います
先程の結果の一部を再度抜粋
{
"id": "6c10f1a1-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"device": {
"name": "Remo",
"id": "837b1dc8-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"created_at": "2017-11-12T09:05:04Z",
"updated_at": "2018-02-12T07:47:31Z",
"firmware_version": "Remo/1.0.62-gabbf5bd",
"temperature_offset": 0,
"humidity_offset": 0
},
"model": {
"id": "DCF7AEC4-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"manufacturer": "daikin",
"remote_name": "xxxxxxxx",
"series": "Daikin AC",
"name": "Daikin AC 002",
"image": "ico_ac_1"
},
"nickname": "Daikin AC 002",
"image": "ico_ac_1",
"type": "AC",
"settings": {
"temp": "26",
"mode": "warm",
"vol": "auto",
"dir": "",
以下略
使うのはやはりid
です
このときdevice.id
やmodel.id
と間違えやすいのでご注意を
とりあえず電源オンしてみますが、aircon_settings
APIでは操作はすべてform dataで送信します
で、電源オン・オフはbutton
の項目で指定しますが、その説明がこちら
Specify “power-off” always if you want the air conditioner powered off. Empty means powered on.
意訳:"power-off"指定でオフ、空文字指定でオンだよ
は? クソ設計 あまり見かけない斬新な設計ですね!
やってみた
curl -X POST https://api.nature.global/1/appliances/6c10f1a1-xxxx-xxxx-xxxx-xxxxxxxxxxxx/aircon_settings -H "Authorization: Bearer $(cat /path/to/token.txt)" -d "button="
たぶんこれでエアコンがついたはずです
温度操作も同じくform dataでの指定ですが、現在の設定に対する+-には対応しておらず、値を直接指定するしかないです
curl -X POST https://api.nature.global/1/appliances/6c10f1a1-xxxx-xxxx-xxxx-xxxxxxxxxxxx/aircon_settings -H "Authorization: Bearer $(cat /path/to/token.txt)" -d "temperature=27"
これってエアコン側の縛りなんですかね? クソ素敵すぎる
幸いにして現在の設定は最初に叩いたappliances
APIでGETできるJSONに含まれているので、こんな感じで抽出します
curl https://api.nature.global/1/appliances -H "Authorization: Bearer $(cat /path/to/token.txt)" | jq -r '.[] | select(.id == "6c10f1a1-xxxx-xxxx-xxxx-xxxxxxxxxxxx") | .settings.temp' | cat
# =>27
jqのselect文めっちゃ便利
今回使うのはこの辺ですかね
シェルスクリプト化していきましょう
シェルスクリプトを作成
githubに上げたのでそれを見ていただければほぼOKです!!!(ぶん投げ)
一応いくつか解説します
テレビ用スクリプト
#!/bin/bash
echo `date` "exec command $1" >> /path/to/log/tv.log
TOKEN=$(cat /path/to/token.txt)
case $1 in
on|off)
curl -X POST https://api.nature.global/1/signals/2c9aa4b9-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send -H "Authorization: Bearer $TOKEN";;
11)
# 1ch
curl -X POST https://api.nature.global/1/signals/0ddd912a-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send -H "Authorization: Bearer $TOKEN";;
4)
# 4ch
curl -X POST https://api.nature.global/1/signals/8ab05d9a-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send -H "Authorization: Bearer $TOKEN";;
10)
# volume down
curl -X POST https://api.nature.global/1/signals/da9efa43-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send -H "Authorization: Bearer $TOKEN"
curl -X POST https://api.nature.global/1/signals/da9efa43-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send -H "Authorization: Bearer $TOKEN"
curl -X POST https://api.nature.global/1/signals/da9efa43-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send -H "Authorization: Bearer $TOKEN";;
100)
# volume up
curl -X POST https://api.nature.global/1/signals/85a0f17d-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send -H "Authorization: Bearer $TOKEN"
curl -X POST https://api.nature.global/1/signals/85a0f17d-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send -H "Authorization: Bearer $TOKEN"
curl -X POST https://api.nature.global/1/signals/85a0f17d-xxxx-xxxx-xxxx-xxxxxxxxxxxx/send -H "Authorization: Bearer $TOKEN";;
*)
echo `date` "unknown command $1" >> /path/to/log/tv.log
esac
Node-REDフローの最後のexecノードに渡されるパラメータ(msg.payload
)に応じてcase文で分岐させます
あとはまあログを出したりIDとTOKENを変数化したりしてますがその辺は読んで察してください
で、工夫点として後述する「定型アクション」のためにチャンネル選択と音量の上下を数値で指定しています。これは照明用のlight.sh
も同様
あと音量は一度のコールで3つずつ上下するようにしています
我が家の場合、音量が1だけ上がっても大して変わらないからですね
この辺は実際に運用して調整すると良いです
こいつをNode-REDで指定してデプロイすればもうアレクサに話しかければオンオフくらいの操作はできるはずです
「アレクサ、テレビつけて」「電気つけて」「エアコンの温度上げて」「エアコンの温度を26度にして」など
ちなみにエアコン関連の操作は「すみません、よくわかりませんでした」と答えながらもしっかり操作してくれてることが多いです
アレクサさんマジポンコツお茶目
定型アクションを設定
今のままだとテレビの音量を上げるのに「テレビを100にして」という必要があります
なので、これを自然な呼びかけでいけるようにします
定型アクションは、alexaのスマホアプリの左側メニューにある「定型アクション」から追加します
- 右上の+ボタンをタップ
- 「実行条件」から呼びかけるための「開始フレーズ」を入力。短くわかりやすいフレーズが良い
- 「アクションを追加」から、スマートホーム>操作したいデバイスを選択して【オン・オフ】と【パーセント】を指定
- 下にある「作成」ボタンを押すことで保存(地味に忘れがち)
ポイントは2.で【パーセント】を指定するところです
例えば先程のテレビ用スクリプトの例では、100を指定することで音量を上げるようにしていたので以下のように指定します
これにより、このアクションが呼ばれるとNode-REDに『100%が指定された』というコマンドが送られ、結果シェルスクリプトの100の分岐に入って音量を上げる処理が実行されます
しかしそもそもここで%指定じゃなくて単純な+-が指定できれば、「100を指定する=音量上げる」みたいなわけのわからない設計にしなくて済んだんですけどね。。。
これはNode-REDスキルの問題なのかな
さて、そしてこっちは完全にバグっぽい挙動なのですが、パーセント指定の最小値である1を指定してアクションを作成すると、実際の実行時には何故か『100%が指定された』ことになります
謎い
そのため、私はNHKをつけるためのアクションでは1のかわりに11を指定するようにしています
1chだから1のほうがわかりやすいんですけど、まあそこはどうせ隠蔽されるので気にしない方向で
というわけで1~4を繰り返すことで一通り指定した結果がこちら
まあ無難ですね
ちなみにNHKと日テレしかないのは私が主にそれしか観ないからですw
そしてよく見ると**「NHK」と「つけて」の間に半角スペース**が入ってます
これは、半角スペースなしだとalexaがフレーズをうまく認識してくれなかったからです
アルファベットと日本語の組み合わせは苦手みたいですね
まとめ
- Node-REDめっちゃ便利。しかも直感的にフローが組める。神か
- alexaスキルの方はもうちょい改善されると嬉しいです。+-をなにとぞ!
- Nature Remo APIも素晴らしい。いちいち赤外線情報とか送信しないで済むのが良いですね
- 定型アクションのおかげでalexaさんが自然な日本語を理解してくれる。これはもっと使いみちがありそう
- そもそも本来はワンフレーズで複数アクションを実行させる、みたいな用途みたいですね
一度一通り組んでしまえば、機器や操作の追加はちょろで済むので色々遊びたいですね
出かけるときや寝るときなどに一声で色々消えるとか?
、、、と思ったけどこれは定型アクションでいけるか
何しようかなあ。。。
参考
- APIを公開しました!!! — Nature
- Amazon Echoで「○○をつけて」と言って家電を操作する - Qiita
- Amazon Echoに「アレクサ、NHK」、「アレクサ、日テレ」と呼び掛けてテレビのチャンネルを変える - Qiita
- Node-RED日本ユーザ会 : Running on Raspberry Pi
- jq コマンドを使う日常のご紹介 - Qiita
- シェルの入出力制御あれこれ - Qiita
素晴らしい記事をありがとうございました!