アレクサでインターホンの通知をする

# インターホンの音をラズパイで検知し、Amazon Echoに話させる

## はじめに

在宅勤務で、自宅の仕事部屋で仕事をしているが、インターホン（ドアホン）の音がほとんど聞こえない。そのため、在宅にも関わらず、不在通知＆再配達となり、配達員に申し訳ない。 また、子供に帰宅気づかず、家の外で待ちぼうけになり、恨まれる。
これを解決するために、インターホンがなったら、RasPiで検知し、仕事部屋のEcho dot通知を話させるシステムを構築する。


## システム構成

* Raspberry Pi 3 Model B
    * 家に転がっていたものを利用
    * Raspbian 10 (buster)
    * コードはPython3 
* [USB mic](https://www.amazon.co.jp/dp/B01KZPF1U8)
    * 安かったので
* Echo Dot
   

## 処理概要
全体の処理の流れ。

1. リアルムタイムに音を取得する
2. 一定期間ごとに、取得した音からインターホンの音の検出を試みる。
3. インターホンの音が検出されたら、Echo Dotに話させる。




### リアルタイムに音を取得する

まず、マイクが認識されているかを `arecord -l` で確認する。

```
pi@rpi:~$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
```

card 1, device 0 で認識されていることがわかる。
次に、`arecord`で録音を試してみる。

```
pi@rpi:~$ arecord -D plughw:1,0 mic.wav
Recording WAVE 'mic.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
```

録音したmic.wavが正しくできていることを、正しく再生できることを確認する。
自分の環境ではノイズが混ざっている。  マイクの問題なのか、RasPiの問題なのか不明だが、インターホンの検知には支障がないので、無視する。

Python3で音を取得するにはPyAudioを利用する。
コードはこのあたり参照
https://github.com/kenmasumitsu/intercom/blob/master/detector.py#L268
https://github.com/kenmasumitsu/intercom/blob/master/detector.py#L146



### 取得した音からインターホンの音の検出を試みる

我が家のインターホンは 「ピンポーン」となる。
[サンプル録音プログラム records.py](https://github.com/kenmasumitsu/intercom/blob/main/records.py) で取得した[wavファイル](https://github.com/kenmasumitsu/intercom/blob/main/test-data/sample1.wav)を [Audacity](https://www.audacityteam.org/) で、「ピン」 と 「ポーン」の部分を解析する。

`ピン`の部分を選択

![スクリーンショット 2021-01-24 11.31.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22885/5438f748-c58d-7e09-d706-715e3e4cfcde.png)

解析 ー スペクトル表示 で、 周波数解析をする。 周波数は `849Hz` とわかる。

![スクリーンショット 2021-01-24 11.31.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22885/5ce92b83-502b-42ee-3d54-2529ba50aa07.png)

`ポーン`の部分を選択

![スクリーンショット 2021-01-24 11.32.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22885/f01f701e-c644-1425-5a0a-3b194a0f9a48.png)

解析 ー スペクトル表示 で、 周波数解析をする。 周波数は、 `681Hz` とわかる。

![スクリーンショット 2021-01-24 11.32.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22885/2fcc0448-4b79-133a-912a-a831cf6fbcce.png)


また、「ピンポーン」の長さは約1.5秒である。

以上のことから、任意の1.5秒の区間内に、周波数 849Hz と 681Hz のピークが検出されたときに、インターホンが鳴ったと判断する。

numpy.fftでFFTをし、scipy.argrelmax で ピークを検出する。

コードはこのあたり参照
https://github.com/kenmasumitsu/intercom/blob/master/detector.py#L288-L294 


### Echo Dotに話させる

https://github.com/thorsten-gehrig/alexa-remote-control を使って、ラズパイから、Echo dotを話させる。

**Update 2022/11/25**
alexa-remote-control が更新しており、`EMAIL`, `PASSWORD`, `MFA`を使わずに、`REFRESH_TOKEN`を使う方式に変更しているので、それに対応する。

#### REFRESH_TOKENの取得

[alexa-cookie-cli](https://github.com/adn77/alexa-cookie-cli) を使う。がこのままだと失敗する。おそらく、利用している    `alexa-cookie2`のバージョンが古い(`4.0.1`)ためだと思われるので、最新版(`4.1.3`)に更新するために、 `package.json` を修正する。

```package.json
  "dependencies": {
-    "alexa-cookie2": "^4.0.1",
+    "alexa-cookie2": "^4.1.3",
    "commander": "^8.2.0"
  },
```

修正後、プログラムを実効する。
```sh
npm install
node cli.js -p amazon.co.jp -a ja_JP
```

ブラウザで、`http://localhost:8080`を開き、amazonのユーザID、パスワードを入力してログインする。
ログインに成功すると、`REFRESH_TOKEN`が、コンソールに出力される(`Atnr|...`の文字列)ので、それを[.env](https://github.com/kenmasumitsu/intercom/blob/master/.env#L4)に書き込む。  


コードはこのあたり参照
https://github.com/kenmasumitsu/intercom/blob/master/detector.py#L236



## 作成したプログラム

https://github.com/kenmasumitsu/intercom


* .env に 各種設定を記述。 主に、https://github.com/thorsten-gehrig/alexa-remote-control を使うために設定。適切な設定が必要。
* detector.py が 実際のプログラム
* run.sh は sshを抜けても実行し続けるために、nohup で、detector.py を実行している。 自分の環境ではvenvを使っているので、`source venv/bin/activate`  をしている。

常時実行しているが、CPU負荷は20-30%ぐらい、誤認識もほとんどないです。


## リファレンス

* https://westgate-lab.hatenablog.com/entry/2019/12/25/225422
* https://github.com/thorsten-gehrig/alexa-remote-control
* https://www.ukeyslabo.com/raspberry-pi/audio/
* https://qiita.com/shge/items/169de61c8f246d26c110