Alexa Voice ServiceをRaspberry Pi 2で動かす（未遂）

Amazonの音声エージェント、Alexa Voice ServiceをRaspberry Pi 2で動かすための手順記録です。
**※まだちゃんと動くところまでいっていないのであくまでメモです。ちゃんと動くようになったら改めて更新します。**

# サンプルコードのダウンロード

* Amazon開発者アカウントを持っていない場合は[ここ](https://developer.amazon.com/login.html)より作成
* Amazonのページから[リファレンスコード一式](https://developer.amazon.com/edw/res/download/AlexaVoiceServiceExamples.zip)をダウンロード
* 適当なディレクトリ（ここではホーム）に展開

# 関連ツールのインストール

## Maven

```
$ sudo apt-get install maven
```

## node.js

apt-getだと古いバージョンがインストールされてしまうので、node-armからインストールする。

```
$ wget http://node-arm.herokuapp.com/node_latest_armhf.deb
$ sudo dpkg -i node_latest_armhf.deb
```

# サーバ用自己署名証明書の作成
RasPi上で動かすnode.jsサーバがSSL通信できるように証明書を作成する。

## 秘密鍵の作成

```
$ cd ~/AlexaVoiceServiceExamples/samples/service/ssl
$ openssl genrsa -des3 -out server.key 2048
```
パスフレーズを設定するように求められるので適当に入力する。

## 証明書の作成

```
$ openssl req -new -key server.key -out server.csr
```
証明書の情報を入力するように求められるが、"Common Name (e.g. server FQDN or YOUR name)"のところだけ`localhost`と入力し、あとはブランクもしくは適当でOK。

## 秘密鍵からパスフレーズを削除

```
$ cp server.key server.key.passphrase
$ openssl rsa -in server.key.passphrase -out server.key
```

## 証明書に署名

```
$ openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
```
`-days`の引数は証明書の有効日数なので適当に。

## Javaのキーストアに証明書を追加

```
$ keytool -import -v -trustcacerts -alias avs-companion-service -file server.crt -keystore /usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/jre/lib/security/cacerts -keypass changeit -storepass changeit
```

"Trust this certificate?"と聞かれるので`yes`と入力。

# Amazonセキュリティプロファイルの作成

* [Alexa Developer Portal](https://developer.amazon.com/edw/home.html)へ移動
* "Alexa Voice Service"をクリック
* "Register a Product Type"メニューから"Device"を選択
* 各フィールドに以下の値を入力（適当でよい）

| 項目名 | 値 |
|:-----|:----|
|Device Type ID|`my_device`|
|Display Name |`My Device`|
|Security Profile| "Create a new profile"を選択 |
|Security Profile Name| `Alexa Voice Service Sample App Security Profile`|
|Security Profile Description | `Alexa Voice Service Sample App Security Profile Description`|

* "Web Settings"タブを選択
* "Allowed Origins"の欄の"Add Another"をクリックし、`https://localhost:3000`と入力
* "Allowed Return URLs"の欄の"Add Another"をクリックし、`https://localhost:3000/authresponse`と入力

* 残りのフィールドに値を入力

| 項目名 | 値 |
|:-----|:----|
| Category | "Other"を選択 |
| Description | `Alexa Voice Service sample app test`|
| Enable Amazon Music? |  "No"を選択 |

* "Security Profile"の項目をクリックし、そこに表示される"Client ID"と"Client Secret"の値をメモしておく

# サーバの起動

* 関連モジュールのインストール

```
$ cd ~/AlexaVoiceServiceExamples/samples/service
$ npm install
```

* config.jsの編集

```js:config.js
var config = {
    clientId: 'ここにClient IDの値をペースト',
    clientSecret: 'ここにClient Secretの値をペースト',
    products: {
      "my_device": ["123456"] // デバイス固有のIDを表す適当な英数字
    },
};
```

* サーバ起動

```
$ npm start
```

"Listening on port 3000"と出ればOK。

# クライアントアプリの起動

```
$ cd ../javaclient
```

* config.jsの編集

```js:config.js
{
    "pid": "my_device",
    "serial": "123456", // サーバ側のconfig.jsで設定したデバイス固有のIDを指定
    "url":"https://localhost:3000"
}
```

* pom.xmlに以下のエントリを追加

```xml:pom.xml
<dependency>
  <groupId>net.java.dev.jna</groupId>
  <artifactId>jna</artifactId>
  <version>4.1.0</version>
  <scope>compile</scope>
</dependency>
```

* Mavenでビルド＆実行

```
$ mvn install
$ mvn exec:java
```

# 成功！となるはずが...。

SIGILLで落ちる。

* VLCのアップデート
 
```
$ sudo apt-get upgrade vlc
```

→エラーがSIGSEGVになったが相変わらず落ちる。

JDKのバージョンを落とすなどいろいろやってみたが状況が変わらないので、とりあえずここで断念。Amazonのフォーラムでも同じ症状の人が結構いる様子。

[Thread: java client blows up JRE - please help](http://forums.developer.amazon.com/forums/thread.jspa?threadID=6142&tstart=0)

# 補足：プロキシの設定が必要な環境の場合

## apt
/etc/apt.confに設定を追加。

```text:apt.conf
Acquire::http::proxy "http://プロキシサーバー名:ポート番号/";
Acquire::https::proxy "https://プロキシサーバー名:ポート番号/";
```

##wget
~/.bashrcに環境変数を追加。

```text:.bashrc
export http_proxy=http://プロキシサーバー名:ポート番号
export https_proxy=http://プロキシサーバー名:ポート番号
```

## Maven
~/.m2/以下にsettings.xmlを作成。

```xml:settings.xml
<settings>
  <proxies>
    <proxy>
      <active>true</active>
      <protocol>http</protocol>
      <host>プロキシサーバー名</host>
      <port>ポート番号</port>
    </proxy>
  </proxies>
</settings>
```