Raspberry Pi Desktop へ enebular agent をインストールして sonospollytts ノードを使ってみた。

# はじめに
Sonos を enebular (Node-RED) から操作するノードを調べていた時に Amazon Polly を利用する TTS (Text To Speech) ノードを見つけて、それを使用できるようにするメモです。

### Sonos とは
米国サンタバーバラ生まれのワイヤレスホームサウンドシステムです。
https://www.sonos.com/ja-jp/home
Sonos を操作するツールを調べたメモ
https://qiita.com/kitazaki/items/ccde18e10f49fcbb9437

### Amazon Polly とは
深層学習を使用して文章をリアルな音声に変換するサービスです。日本語は女性 (Mizuki) と男性 (Takumi) の声が用意されています。
https://aws.amazon.com/jp/polly/

# 環境
Sonos と同じネットワークに Raspberry Pi を接続して enebular agent をインストールすれば、sonospollytts ノードは問題なく使用できます。
<img width="75%" alt="env.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/a150906a-ef7f-1d84-7557-faefee62fc3e.png">

## 動作概要
1. Amazon Polly サービスに対してテキスト文章を送信します。
2. テキスト文章から音声変換された mp3 ファイルをダウンロードします。
3. Raspberry Pi から Sonos へ mp3 ファイルを再生することを指示します。
4. Sonos から Raspberry Pi へアクセスし、mp3 ファイルを取得して再生します。

## Raspberry Pi Desktop
ブラウザでアクセスするクラウド環境の enebular は Heroku へデプロイされるため使用できません。問題になるのは動作概要 2. で、ダウンロードされた mp3 ファイルは一時的にストレージ (デフィルトでは /tmp ディレクトリ) に保存される実装になっているため、エラーとなります。
Raspberry Pi が手元に無い場合、他の選択肢としては 仮想環境で動作する Raspberry Pi Desktop へ enebular agent をインストールして使用する方法があります。

<img width="75%" alt="env2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/879f0e44-c3c8-11ee-66f1-1281f22614c3.png">

## enebular editor
enebular editor は ポート番号 1888 で起動する (Node-REDは通常、ポート番号 1880 で起動する) ため、sonospollytts ノードのポート設定を変更すれば動作します。(sonospollytts ノード Version 1.0.21 まで)
動作概要 2. で、ダウンロードされた mp3 ファイルは enebular editor を動作させている PC (今回は MacBookPro を使用) のストレージ (デフォルトでは /tmp ディレクトリ) に保存されます。

<img width="75%" alt="ee.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/ac354766-4815-ed50-c4b2-cfd750674096.png">

<font color=#FF0000>※2019/11/11 更新</font>
sonospollytts ノードが 1.1.0 にバージョンアップされ、Node-RED の Webserver 機能の利用ではなく、sonospollytts ノード自体の Webserver 機能の利用に変更された (Sonos の HTTPS SSL certificate 問題の対策) ため、ポート番号が 1980 に変更されました。そのため、sonospollytts ノードのポート設定を変更する必要が無くなりました。

<img width="75%" alt="sonospollytts_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5fd4887c-d4eb-6329-6c71-d30f70d7bf6a.png">

# 準備
- MacBookPro (macOS Mojave 10.14.6)
- VirtualBox (6.0.14)
 - https://www.virtualbox.org
- Debian Stretch with Raspberry Pi Desktop (2019-04-11-rpd-x86-stretch.iso)
 - https://www.raspberrypi.org/downloads/raspberry-pi-desktop/

※ Debian Buster with Raspberry Pi Desktop (2019-09-25-rpd-x86-buster.iso) がリリースされていますが、enebular agent のサポート対象外なので、1つ前のリリースの Stretch で動作確認しました。

- enebular-agent (2.8.0)
- enebular editor (0.12.0)

## Raspberry Pi Desktop のインストールと VirtualBox の環境設定
1. VirtualBox のインストール
VirtualBox をインストールします。合わせて拡張パック (Extension Pack) もインストールします。
<img width="75%" alt="VB.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/3547c3d9-7c5b-2ae4-65c4-c9de019ebc35.png">

2. Raspberry Pi Desktop のインストール
VirtualBox のメニューから「仮想マシン」→「新規」を選択して、新しい仮想マシンを追加します。
名前「(任意)」
タイプ「Linux」
バージョン「Linux 2.6 / 3.x / 4.x (64-bit)」
メモリーサイズ「2048MB」
仮想ハードディスク「VDI」「可変サイズ」「16.00GB」
<img width="75%" alt="OracleVM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/68200b6b-a699-443a-ad79-d84126676377.png">
VirtualBox のメニューから「仮想マシン」→「設定」を選択して、「ストレージ」の光学ドライブに Debian Stretch with Raspberry Pi Desktop の ISO イメージ (2019-04-11-rpd-x86-stretch.iso) を割り当てます。
<img width="75%" alt="storage.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/66a16914-94ad-edaa-085c-1400d7cd17ca.png">

3. Raspberry Pi Desktop の起動
VirtualBox のメニューから「仮想マシン」→「起動」を選択して、Raspberry Pi Desktop を起動します。起動後、Raspberry Pi Desktop のインストールを行います。
<img width="75%" alt="RPi2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/1a6f4bb2-2f12-59f6-8c57-7682023bd1fc.png">

4. VirtualBox の環境設定
VirtualBox のメニューから「仮想マシン」→「設定」を選択して、「ネットワーク」→「アダプター 1」→「高度」で「ポートフォワーディング」の設定を行います。仮想マシンのネットワークアダプターは NAT で割り当てられているため、ホスト OS (今回は macOS) からゲスト OS (Raspberry Pi Desktop) への通信を転送する必要があります。
<img width="75%" alt="network.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/95b58baa-6361-b31d-1d1e-6b5f30c3de8d.png">
<img width="75%" alt="network_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5f5fa16e-c5fb-960b-7e1c-d72971d5507b.png">
SSH (ホスト OS ポート番号:10022 → ゲスト OS ポート番号:22) と Node-RED (ホスト OS ポート番号:11880 → ゲスト OS ポート番号:1880) と sonospollytts (ホスト OS ポート番号:1980 → ゲスト OS ポート番号:1980) の転送設定を追加します。
<img width="75%" alt="portforward.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/023d06c2-80fb-ec00-155e-875d117c917c.png">

5. enebular-agent のインストール
フローのデプロイが楽になるため、AWS IoT を利用して enebular-agent をインストールします。
(参考) Raspberry Pi を AWS IoT に繋いで enebular と連携
https://qiita.com/kitazaki/items/ffd50396cb09d6ab7050
(参考) enebular agentをバージョンアップ(2.5.0)してみた。 
https://note.mu/kitazaki/n/n09fb4c73785f

6. フローのデプロイ
enebular web dashboard または enebular editor からフローをRaspberry Pi Desktop へデプロイします。
<img width="75%" alt="web_dashboard.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/ee047a0a-d63b-b6a5-9a9a-86f5f846bef0.png">
<img width="75%" alt="ee_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/f80b280e-0a53-a6fa-ea5c-6c33367c2217.png">

## enebular editor の起動
enebular editor の場合は、インストールや設定の必要は無く、デスクトップモードでフローを起動すればOKです。
<img width="75%" alt="ee_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/3891b226-301c-b0e6-5da7-96b6113feedf.png">
 
## サンプルフロー
inject ノードと sonospollytts ノードを接続します。debug ノードは無くても動作には問題ありません。
<img width="75%" alt="flow.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/29c3f2ce-496a-bc81-4985-e05b264171cf.png">
inject ノードの編集を行います。ペイロードは「文字列」を選択し、値に発話させたい文章 (ここでは「こんにちは」 )を設定します。
<img width="75%" alt="inject.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/b6f6a151-2ea7-47a3-c380-924bdf687860.png">
sonospollytts ノードの編集を行います。
Polly Config は AWS IAM で作成した Polly Access key と Polly Secret key を設定します。
Polly Voice は 日本語では Mizuki （女性） と Takumi （男性） から選択できます。
Sonos IP は Sonos に割り当てられた IP アドレスを設定します。
Sonos Hailing は Disable を設定します。
Node-Red IP は ホスト OS に割り当てられた IP アドレスを設定します。 ゲスト OS に割り当てられた IP アドレスは設定しません。
<img width="75%" alt="sonospollytts.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/f024054a-1e02-38e1-be07-2d8443da1797.png">
<img width="75%" alt="polly_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/7a6769b7-8be0-023b-570f-a06f51156a31.png">

# まとめ
Sonos の指定した mp3 を再生する機能と Amazon Polly を利用して Sonos から発話させてみました。
音楽を再生している途中で Sonos が突然しゃべり始めると、ちょっとビックリすると思います。(笑

良き Sonos ライフを！