Ecovacs deebot 901をAlexaに完全連携する

#追記
2021/03/27
Alexaの提携アクションに「カスタム」というものが追加されました。
これにより、「アレクサ、掃除して」を「アレクサ、ディーボットを使って掃除して」に割当できるので以下の記事はほぼ不要になりました。
こっちのほうが反応も早いのでおすすめです

2021/1/15
sucksからコマンドを送ると反応しないばかりかルーター再起動するまでdeebotがオフラインになるようです。
秘密鍵が変わった模様。

#要約
・ロボット掃除機deebot901を買ったけどAlexa連携がイマイチ
・RasPi Zeroを中間に挟んでデバイスとして認識させた
・定形アクションで使えるようになった！


#我が家にロボット掃除機がやってきた。
突然ですが先日ロボット掃除機を買いました。
ecovacs社製deebot 901で、ニックネームはポチです

(下の写真は後継機のdeebot ozmo 901でモップ拭きもできるすごいやつです。セール時は2万円代で買えることもあります。アフィじゃないです)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188873/db3edcee-8704-fd55-0161-6b78e938cfcc.png)
[deebot ozmo 901 - Amazon](
https://www.amazon.co.jp/%E3%80%90%E7%B4%B0%E8%8F%8C%E9%99%A4%E5%8E%BB%E7%8E%8799-%E3%80%91ECOVACS-OZMO-901-%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E6%8E%83%E9%99%A4%E6%A9%9F-%E3%83%90%E3%83%BC%E3%83%81%E3%83%A3%E3%83%AB%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB/dp/B07MW3QLQN/)

正直ロボット掃除機ナメてたんですけどすごく便利ですごいです(語彙力)
毎日掃除機なんてかけてられなかったんですけど、ポチならスマホからワンタッチで掃除してくれます。

##ルンバじゃないの？
ロボット掃除機マニア以外の方なら、ロボット掃除機と聞いてまずルンバが思い浮かぶんじゃないでしょうか？
もしロボット掃除機を買うならLIDAR or レーザーセンサーが付いてるものがおすすめです！
何故なら部屋の間取り、今自分がどこにいるかを認識していい感じに掃除してくれるからです。
逆に言えばセンサーレスのロボット掃除機は適当にランダムに動いているだけです。

そしてルンバでこの機能が付いているのは上位機種のみで、必然的にお値段も非常に高いのです…。
deebotであれば2万円代でレーザーついてて、例えばリビングだけ掃除するように指示もアプリからできます。

#Alexa連携がイマイチ(本題)
そんな安くてレーザー付いてるポチですが不満点があります。
Alexa公式対応を謳っておきながらできることが以下のことだけなのです。

「Alexa、ディーボットを使って掃除して。」
「Alexa、ディーボットを使って掃除を終了して。」
「Alexa、ディーボットを使ってホームベースに戻して。」

前述の特定の部屋だけ掃除もできませんし、わざわざ「ディーボットを使って」と頭につけないといけなくてスマートではありません。
定形アクションに組み込もうにもデバイスとして認識されない仕様なのです。
(このあたり、ルンバだと対応できるようです？)

#やりたいこと
我が家のリビングのダイニングテーブルはルンバブルではないので、
①アプリを起動
②リビング以外を掃除してもらう
③充電ステーションに帰ろうとするポチを本体ボタンで停止させる
④ダイニングテーブルの椅子を掃除終了箇所へ移動させる
⑤アプリを起動
⑥リビングを掃除してもらう

というのを

①「Alexa、掃除して」と話しかける　→　リビング以外掃除後、自動で一時停止
②ダイニングテーブルの椅子を掃除終了箇所へ移動させる
③「Alexa、リビングを掃除して」と話しかける

にします

#必要なもの
__Raspberry Pi Zero W__
なるべくイニシャルコストもランニングコストも安く済ませたかったためZeroにしました。ピンヘッダも不要です。
しかしながら性能の低さからか話しかけてから掃除開始にちょっとラグがあります。
どうせ命令後放置なので問題ないのですが、Pi 4とか3とかだともっと快適かもしれません。
microSD、電源も忘れずに。

__Ecovacsアカウント__
後述しますが普段ECOVACS HOMEアプリで使用しているもの(メインアカウント)とは別のアカウントを用意してください。
予備スマホにでもHOMEアプリインストール→新規登録後、メインアカウントでロボットの共有からアカウントをリンクしておきます。

#手順
###①Raspberry Pi OSをインストール
ここはググればいくらでも出てくるのでおまかせします。
よくわからなかったのでフル版のRaspberry Pi OS with desktop and recommended software入れときました。
公式からはイメージのダウンロードが重たいのでミラーをおすすめします。
[Raspbian Mirrors](https://www.raspbian.org/RaspbianMirrors)

###②Python3に切り替え
Raspberry Pi OSインストール直後ではPython2がデフォになっています。
今回はPython3を使うので以下を参考に切り替えます。
[RaspberryPiでPythonのデフォルトをPython2.7からPython3に変更する　-そう備忘録](https://www.souichi.club/raspberrypi/python3-default/)

###③deebot 901対応版のsucksをインストール
海外の有志が作ってくれたPythonでdeebotを動かすsucksというプログラムがあるので利用します(すごい名前…)
オリジナルのものでは901などのMQTT機種非対応なのでbmartin5692氏のfork版を使用します
[Github - bmartin5692/sucks](https://github.com/bmartin5692/sucks/tree/D901)

###④deebot901の一時停止に対応する改造を施す
sucksにstopというコマンドがありますが、これが901に対応してません。
代わりにpauseというコマンドを追加します
以下のcommitを参考にして該当ファイルを修正します。
[Github - bmartin5692/sucks　Added pause, resume, fixed stop](https://github.com/bmartin5692/sucks/pull/16/commits/2ee455ae5535f6d8a53189852fdf69df972f0923)

###⑤sucks動作テスト
改造が済んだらターミナルから以下のコマンドを実行します

```
% sucks login
```

メールアドレスとパスワードを要求されるので用意しておいたEcovacsでログインします。
いくつか聞かれますが提示されたものを入力してエンターすればOKです。
sucksはスマホアプリのふりをしてEcovacsのサーバーにログインしているようですが、ログイン時にサーバーに渡している情報が古いので、メインアカウントでログインしてしまうと、以降正規のスマホでアプリを立ち上げたときに更新を促されてしまいます。
面倒なので事前に準備した別アカウントを使用しましょう。

```
% sucks login
    Ecovacs app email: [ecovacsアカウントのメールアドレス]
    Ecovacs app password: [パスワード]
    your two-letter country code: jp
    your two-letter continent code: as
    Config saved.
```

config saved.と表示されたら次のコマンドを打ちます。

```
% sucks clean
```

通常の全部屋掃除が開始すればOKです。

###⑥部屋の割当を確認
Ecovacs homeアプリで部屋の間取りが表示されていると思いますがその対応関係を調べます

```
% sucks clean area 0
```

0となっているところが部屋番号です。おそらく0が充電ステーションがある部屋だと思います。
うちの環境だと0を基準に隣接する廊下が1、その先の部屋が2…という感じでした

```
% sucks clean area 1,2,3
```

のように複数の部屋を指定することもできます。
対応関係を適当にメモしておきます。

###⑦node-redのAlexa用ノードnode-red-contrib-amazon-echoをインストール
まず、スマートデバイスとしてAlexaから認識させるためのnode-red-contrib-amazon-echoをインストールします。
BelkinのWemoを装ってAlexaに認識させるようです。
以下を参考にしました。
[NodeRedでAlexa連携 - by K.I](https://vogel.at.webry.info/201910/article_3.html)
なぜかうちの環境だとポート転送先が8111ではうまく動作しなかったので記事中の8111という数字をすべて1880に置き換えてインストールします。

###⑧node-redのAlexa用ノードnode-red-contrib-alexa-remote2をインストール
続いて、node-redからAlexaを喋らせるためのノードnode-red-contrib-alexa-remote2をインストールします。
掃除が終わったあとに教えてほしかったので入れましたが、不要であれば不要です。
以下を参考にしました。
[Node-redを使ってAlexaを自由に喋らせる方法（alexa-cookie2 v3.4.1編）- 育児×家事×IoT](https://dream-soft.mydns.jp/blog/developper/smarthome/2020/09/2049/)
Verによって微妙に違うようなので気をつけてください。

###⑨node-redでノードを作成する
node-red-contrib-amazon-echoでノードを作成します。
このときのNameがAlexaから認識される名前になります。
日本語だと文字化けしたので英語が無難です。
Alexaからは照明として認識され、ON/OFFしかできないので各動作ごとに分けます。
うちだと、リビング以外掃除、リビング掃除、充電ステーションへ戻る、一時停止に分けました。
execノードの引数にsucks (コマンド名)といれてデプロイします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188873/2fe8ec2e-03fa-af1d-1f9a-f48cc0abe56d.png)
喋らせたい場合はログインするのを忘れないでください。

###⑩Alexaアプリから検索する
あとは通常のスマートデバイスを認識させるときの様に、アプリのデバイス→デバイスを追加→その他で検索させます。
うまく行かない場合、時間を置いてみるか⑦のポート、EchoとRaspberry Piが同一ネットワーク内か(2.4Ghzと5Ghzで分断される場合も)を確認してください。

###⑪定形アクションとして登録
スマートデバイスとして認識されたので定形アクションに登録が可能になります！
うちでいうと[Pochi_excpet_Living]を「Alexa、掃除して」に割り当てます。

#不具合
たまにpauseが効かずに充電ステーションに帰ってしまうことがあります。

#やりたかったけどできなかったこと
####ESP32で実装
HttpsでのGetやらMQTTが理解できなかったので断念しました。
ESP32で出来れば消費電力的にもコスト的にも強いんですが…
あとPythonより早そう。

####ecovacs-deebot.jsを使う
最初っからdeebot901対応したNode.js版sucks的なやつがあります。
[Github - mrbungle64/ecovacs-deebot.js](https://github.com/mrbungle64/ecovacs-deebot.js)
node-redなので同じくNode.jsのほうが相性いいのかなと思ったり。
usageに従って環境構築しようとしましたがうまく動かないので諦めました。

####Amazon AWS上で実装
理屈的にはLambda上でできるはずですし、やってるっぽいのはあります
[Github - EtienneMD/Alexa-Ecovacs](https://github.com/EtienneMD/Alexa-Ecovacs)
[Github - bamminger/ecovacs-aws](https://github.com/bamminger/ecovacs-aws)

Raspberry Piのイニシャルコストもランニングコストも不要で、多分Zeroより処理早い気がします。
おそらくLambdaの無料枠で出来るんでしょうけど、自信がなかったので諦めました。