AWS IoT Coreと連動してSumerianエンティティを変化させてみる

#はじめに
AWS Sumerianでは、簡単にAR/VRのコンテンツが作成できます。
また、さまざまなAWSのサービスと組み合わせることができることも魅力のひとつ。
そこで、今回はAWS IoT Coreと連携し、値に応じてSumerian上の球の色を変化させるコンテンツを作ってみたいと思います。

##必要なもの
- WEBブラウザ(Chrome)

##全体のしくみ
全体は、こんなイメージになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/f757cf4a-f29c-78b0-5385-7391a4c678a8.png)


#手順
手順は、大きく4つです。

1. Cognito の設定
2. IoT Core の設定
3. Sumerianコンテンツを作成する
4. 値を更新してブラウザで表示してみる

それぞれの手順について解説していきます。

##① Amazon Cognito の設定
Sumerianから他のAWSサービスにアクセスするためには、Cognito Identity Poolを作成し、シーンに割り当てる必要があります。
まずは、SumerianからIoT Coreに接続するために、Amazon Cognito の設定を行い、Pool IDを取得します。

1.Cognito Identity Poolは、下記のテンプレートを使って作成します。
※注意：Cognito Identity Poolは、Sumerianシーンと同じリージョンで作成します。

■テンプレート
[IoT Thing Shadow and Script Actions スタックの作成テンプレート](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?templateURL=https://s3.amazonaws.com/sumerian-cfn-templates/IotThingShadowTutorialTemplate.yml&stackName=AmazonSumerianIotDataTutorialStack)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/946bea98-89fc-804d-8461-cc23a96b8e60.png)


2.スタックの名前を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/e28a4e65-133b-2289-bfce-ae135b564075.png)


3.承認欄にチェックを入れて「スタックの作成」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/5869e7c4-a443-a0b2-7818-39a1a5bd3ffd.png)


スタックの作成が完了すると、ステータスが「CREATE_COMPLETE」になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/e4c9a676-4f20-5651-07b7-b24bf1fc85e6.png)


4.「出力」タブでCognitoIdentityPoolIDの値をメモ帳などにコピーしておきます。
※Pool IDは、あとでSumerianの設定に使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/2010db40-00e5-4ded-e659-5c3d98b68497.png)


##② AWS IoT Core の設定
次に、AWS IoT Coreの設定を行います。
AWS IoT Coreは、インターネットに接続されたデバイスから、アプリケーションや他のデバイスに通信するためのサービスです。
今回は、手順を簡略化するために、デバイスとの接続は行いませんが、利用する際はIoTデバイスから送信されるデータを保持し、Sumerianから取得可能にしてくれる仲介役として機能します。

1.AWSサービス画面で「IoT Core」を検索し、AWS IoTコンソールを開きます。画面左側のメニューから「管理」>「モノ」を選択し、「作成」ボタンをクリックします。


2.「単一のモノを作成する」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/4b6c7f60-debe-cc05-ef39-ef525b55e186.png)


3.モノの登録画面で「名前」を指定し、「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/c44f1594-c5bf-b2d0-f795-ad9ee0c83a37.png)


4.「証明書をスキップしてモノを作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/258ec060-d5aa-c879-8800-af622dbadbd3.png)
※今回は、手順を簡略化するために、証明書は発行しませんが、IoTデバイスを利用する際は、ここで発行する証明書をIoTデバイスに持たせて認証させます。

##③AWS Sumerianコンテンツを作成する
次に、Sumerianのコンテンツを作成していきます。
少し長くなるので、先に大まかな流れを説明すると、大きく以下の5ステップとなります。
1. シーンを作成
2. AWSの設定（CognitoなどAWSサービスと連携させる）
3. エンティティの作成（何を表示するか、どんな状態を定義するか）
4. スクリプトの設定（どんな状態のとき、何をするか）
5. コンテンツを公開する


### 1.シーンの作成
Sumerianのホーム画面のテンプレートから「Create new scene」を選択し、名前を付けて「作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/38f97e61-3bbf-d1cf-10a5-402f1d42e83c.png)


###  2.AWSの設定
シーンが作成されたら、右側のメニューから「AWSの設定」をクリックし、下記の値を設定します。

| 項目 | 設定値 |
|:-----------|------------|
| Cognito ID プール | 「①Amazon Cognitoの設定」で取得したPool ID |
| IoTデータクライアント | 有効 |
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/cf5a2570-a8a9-9b48-ad8f-286697308325.png)

### 3.エンティティの作成
画面上部の「＋エンティティの作成」をクリックし、「Sphereの追加」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/d666af95-3fd3-aeb3-d612-586c431945ce.png)


エンティティツリーで作成した「Sphere」を選択した状態で、画面右側に表示されるメニューから「コンポーネントの追加」をクリックし、「ステートマシン」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/092a2853-704a-d4e4-783e-8c167fa66797.png)


ステートマシンで、「＋」マークをクリックし、状態を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/024553d9-13f1-2ebf-906c-b1b1c44ca3f7.png)

名前を「init」に変更します。名前を変更したら、「＋状態の追加」をクリックし、全部で、以下4つの状態を作成します。

| 名前 | 選択済みの状態 |
|:-----------|------------|
| init | アクションの追加で「AWS SDK Ready」を追加。 |
| wait | アクションの追加で「Wait」を追加。Time(second)を2に変更 |
| Get Thing State | アクションの追加で「Execute Script」を追加。 |
| Sphere State | アクションの追加で「Execute Script」を追加。 |

状態を作成したら、各状態の間をドラッグ＆ドロップで下図のように連携します。
Get Thing Stateの「Success」と「Failure」のつなぎ先を間違えないように気を付けてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/3c1af122-7aea-20b0-0300-d4ecd5ce7c98.png)

### 4.スクリプトの設定
次にどんな状態の時に、何をするかスクリプトで定義していきます。
まずは、IoT Coreからデバイスシャドウの値を取得します。

状態の「Get Thing State」をクリック。
「選択済みの状態」のExecute Scriptの「＋」マークをクリックし、「カスタム（レガシー形式）」を選択してします。スクリプトが追加されたら「スクリプトの編集」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/0229ee72-9d07-aeaa-7ffe-ad2a55097ca1.png)

Documentから作成されたスクリプトをダブルクリックしてスクリプト名を「Get Thing State Script」に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/47078d96-b563-f127-510c-52e86613d1dd.png)


スクリプトの内容を、以下のように書き換え、画面左下の「Save」をクリックして保存します。

```javascript:GetThingStateScript
'use strict';

function enter(args, ctx) {
    window.AWSIotData.getThingShadow({ thingName: 'TestDevice' }, (error, data) => {
        if (error) {
            console.error('Error getting state', error);
            return ctx.transitions.failure();
        }
        const payload = JSON.parse(data.payload);       
        //デバイスシャドウの値を取得
        ctx.behaviorData.value = payload.state.reported.value;
        ctx.transitions.success();
    });
}
```

次に「Sphere State」の状態をスクリプトで定義していきます。
Sumerianの画面にもどって「Sphere State」をクリック。
スクリプトを追加して、スクリプト名を「Sphere State Script」に変更し、以下のように書き換えます。

```javascript:SphereStateScript
'use strict';

function setup(args, ctx) {
	//球のエンティティ
	ctx.sphere_entity = ctx.world.by.name('Sphere').first();
	//デバイスシャドウの値
	ctx.spanElement_value = document.getElementById('value');
}

function enter(args, ctx) {
	try {					
		//デバイスシャドウの値から色を定義
		let t_Color = [0,0,0,1]
		if (ctx.behaviorData.value < 100){
			t_Color = [0,0,1,1]
		} else{
			t_Color = [1,0,0,1]									
		}
		//球の色を更新
		ctx.sphere_entity.setDiffuse(t_Color);
		ctx.sphere_entity.transformComponent.setUpdated();		
	} catch (error) {
		console.error('Error change color', error);
		return ctx.transitions.failure();
	}
	ctx.transitions.success();
}
```
### 5.コンテンツを公開する
最後に、コンテンツを公開し、URLを取得します。
画面右上の「公開」>「パブリックリンクを作成する」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/3a9f8d48-c7e0-eceb-3234-8d058664f320.png)

同意確認が表示されますので、内容を確認して「公開」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/fec1b70b-87cf-2354-bfaf-84a8577a4370.png)

URLが発行されますので、「コピー」ボタンでメモ帳などにコピーしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/a8f70b2c-04cd-ec83-a678-ac3abc85d3e0.png)

##④ 値を更新してブラウザで表示してみる
### 1.IoT Coreで値を更新
まずは、IoT Coreからトピックにメッセージを発行します。
IoT Coreのコンソール画面を開き、「テスト」をクリックします。
「トピックのサブスクリプション」に「$aws/things/TestDevice/shadow/update」と入力し、「トピックへのサブスクライブ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/5eaee873-76a2-31fd-0933-f6448c33dcf3.png)

メッセージフィールドに下記のメッセージを入力し、「トピックに発行」をクリックします。

```json:message.json
{
  "state": {
    "reported": {
      "value": 10
    }
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/54ed3286-8a65-2984-c520-d386d1275d32.png)

### 2.Webブラウザで表示する
IoT Coreで値を更新したら、早速ブラウザで表示してみましょう。
ブラウザを開き、Sumerianで発行したURLにアクセスします。
球が表示され、少し時間がたつと「青色」に変化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/2afe6915-2b9d-b06b-803a-7bd97d12e70c.png)

IoT Core画面に戻り、メッセージの値を「"value": 200」に変更して「トピックに発行」すると、球の色が「赤色」に変化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/9f8059a7-e9a6-5b35-e1f3-a1f8b22eb224.png)


#さいごに
今回の内容では、球の色を変化させただけでしたが、テキストで数値を表示することもできます。また、Raspberry piから、AWS IoT Coreに値を送信すれば、センサー情報を表示することもできます。さらに、SumerianならARアプリも作れちゃう！

折角なので、温湿度センサーを取り付けたRaspberry piから、センサー情報を送信して、ARで表示するアプリを作ってみました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536768/e1658b2b-d84c-603d-5955-236bea3169f7.png)

表示させたいところにマーカーを張っておけば、機械内の温度なんかも表示できそうですね！

Sumerianは、簡単にコンテンツを作成できる点が大きな魅力です。
思いついたら、サクサクっと作れるので、夢が広がります！