IoT AnalyticsとQuickSightつかってみた

ラズパイから温度データをIoT Analyticsに送ってそれをQuickSightで可視化してみました。

# 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/c2caab07-2499-80df-6608-8e4e533f175a.png)

# 全体の流れ

ラズパイのGreengrass CoreからデータをIoT Coreにパブリッシュ
↓
IoT CoreからRuleでIoT Analyticsのチャネルにプッシュ
↓
パイプラインでチャネルからデータを引いてきて加工やフィルタリングした後にデータストアにプッシュ
↓
あらかじめ定義したSQL処理が定期実行されて結果がデータセットとして出力
↓
それをQuickSightで可視化


# ラズパイのGreengrass CoreからデータをIoT Coreにパブリッシュ
ラズパイの`GreenGrass Core`から、デプロイした`Lambda`で`GreengrassSDK`を使って`MQTT通信`で`IoT Core`に温度データを定期的に送信します。温度データはPython組み込み関数の`random.gauss()`を使います。

※例えば`random.gauss(x, y)`で平均がx、標準偏差がyの正規分布からランダムで浮動小数点型の数を返します。場合によっては`str()`で文字列に変換します。

```mqtt.py
import logging
import platform
import sys
from threading import Timer

import greengrasssdk

# Minagawa added
import random

# Setup logging to stdout
logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

# Creating a greengrass core sdk client
client = greengrasssdk.client("iot-data")

# Retrieving platform information to send from the Lambda function - Greengrass_HelloWorld_93ntT
my_platform = platform.platform()


def greengrass_hello_world_run():
    try:
        if not my_platform:
            client.publish(
                topic="minagawa/analyticsandquicksighttest", queueFullPolicy="AllOrException", payload='[{"temperature":'+str(random.gauss(35, 3))+'}]'
            )
        else:
            client.publish(
                topic="minagawa/analyticsandquicksighttest",
                queueFullPolicy="AllOrException",
                payload='[{"temperature":'+str(random.gauss(25, 3))+'}]'
            )
    except Exception as e:
        logger.error("Failed to publish message: " + repr(e))

    # Asynchronously schedule this function to be run again in 10 minutes
    Timer(600, greengrass_hello_world_run).start()


# Start executing the function above
greengrass_hello_world_run()


# This is a dummy handler and will not be invoked
# Instead the code above will be executed in an infinite loop for our example
def function_handler(event, context):
    return

```

# IoT CoreからRuleでIoT Analyticsのチャネルにプッシュ

## Cloudformationでの定義

### IoT TopicRule
IoT Ruleですが、Cloudformationの世界だとTopicRuleと呼びます。下記のサンプルルールだと`temperature`が`20より大きい`データをS3バケットとIoT Analyticsに投げるルールを定義しています。`RuleDisabled`を`false`にして作成すると最初からルールが`Enabled`な状態、つまり有効な状態になります。

```sample-rule.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyTopicRule:
    Type: AWS::IoT::TopicRule
    Properties:
      RuleName: 'ルール名'
      TopicRulePayload:
        RuleDisabled: 'true'
        Sql: SELECT temperature FROM 'トピック名' WHERE temperature > 20
        Actions:
        - S3:
            BucketName: Ref: MyBucket
            RoleArn: !GetAtt MyRole.Arn
            Key: Folder/To/Put/The/File/test.txt
        - IoTAnalytics:
            ChannelName: 'チャネル名'
            RoleArn: Something::like::this
```


### Ref
`BucketName`で`Ref`を使っていますが、これはCloudformation特有の関数です。このように`Ref:MyBucket`で定義すると`＜スタック名＞MyBucket12ABC3D456EFG`というようにランダムな文字列を自動でつけてくれるので文字かぶりを気にしなくて良くなります。

### Fn::GetAtt
Fn::GetAttもCloudformationの組み込み関数の一つです。
`Fn::GetAtt: [ logicalNameOfResource, attributeName ]`という形式で書きます。上記の例の場合`MyRole`という論理名を持ったリソースの`Arn`という属性の値を返すという意味です。短縮形の`!GetAtt`も使用できます。

上記の他にも組み込み関数は複数あります。組み込み関数に関しては日本語版の公式レファレンスがあるので参考にしてください。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html

RefやFn::GetAttの使い所などをまとめた記事：

https://dev.classmethod.jp/articles/cloudformation-tips-focused-on-refs/#org36a57a6

## コンソールでの作業手順
Createを押します。
![Pasted Graphic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/96a18015-36b6-7aa5-0201-e5f57c8b69ca.png)
ルール名と処理内容となるSQL文を記入しアクションの追加を押します。
![Rule query statement.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/9bde8e31-6485-301d-225d-5302a04b6e34.png)
IoT Analyticsにメッセージを送るを選択します
![Send message.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/abb595c3-d2c8-21c9-6571-af623d4de31f.png)
すでにIoT Analyticsのチャネルができている場合それを選びます。できてない場合は画像のように自動で作成することもできます。
![Configure action.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/cb6318cd-7d18-8090-34c4-991db65bcde1.png)
この通り一連のIoT Analyticsの中身（チャネル、パイプライン、データストア、データセット）が作成されました。アクションの追加が終わったらルールの作成を押します。
![Configure action.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/b5741b53-a2de-efb5-c52c-599cbdde38a3.png)
ルールが作成できました。デフォルトだとdisabled状態になっているので右の…からenableを選んで有効にします。
![Pasted Graphic 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/2d9496e4-eb45-9c25-4211-fe22064c706a.png)
Enabledになりました。これでIoT CoreからIoT Analyticsのチャネルへのプッシュが可能になります。
![Pasted Graphic 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/c82cf295-c45e-6718-a077-c248b36ab291.png)



## チャネル、データストア、パイプライン、データセットのCloudformationでの定義
### チャネル
以下がCloudformationでチャネルを定義する際のYAMLファイルです。基本的に他のリソースから矢印が伸びる形になるのでチャネル自体の定義はかなりシンプルです。設定する項目といえば保存期間の`Retention Period`くらいでしょうか。`Tags`はメタデータをつけたいとき用です。

```sample-channel.yaml
---
Description: "サンプルチャネルを作成"
Resources:
  Channel:
    Type: "AWS::IoTAnalytics::Channel"
    Properties:
      ChannelName: "チャネル名"
      RetentionPeriod:
        Unlimited: false
        NumberOfDays: 10
      Tags:
        -
          Key: "keyname1"
          Value: "value1"
        -
          Key: "keyname2"
          Value: "value2"
```
### データストア

同様にデータストアのCloudformationファイルもシンプルです。基本的にデータをためるだけなので当然といえば当然ですね。

```sample-datastore.yaml

---
Description: "サンプルデータストアを作成"
Resources:
  Datastore:
    Type: "AWS::IoTAnalytics::Datastore"
    Properties:
      DatastoreName: "データストア名"
      RetentionPeriod:
        Unlimited: false
        NumberOfDays: 10
      Tags:
        -
          Key: "keyname1"
          Value: "value1"
        -
          Key: "keyname2"
          Value: "value2"
```

### パイプライン

パイプラインは以下のように2つ以上の`Activity`で構成されています。また`Activity`は`Math`, `AddAttributes`, `Filter`, `Lambda`など全10種類あります。どのチャネルからデータを取るかを定義する`Channel`のActivity（一番最初にきます）と、どのデータストアにデータを渡すか定義する`Datastore`のActivity（一番最後にきます）は必須です。また`Activity`を複数組み合わせる際は`Next`を使って処理の順番を定義していきます。また`Activity`は最大25個持てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/f121872d-4d3c-2fa2-538b-08e66792661d.png)

```sample-pipeline.yaml
---
Description: "サンプルパイプラインを作る"
Resources:
  Pipeline:
    Type: "AWS::IoTAnalytics::Pipeline"
    Properties:
      PipelineName: "パイプライン名"
      PipelineActivities:
        -
          Channel:
            Name: "アクティビティ名"
            ChannelName: "チャネル名"
            Next: "LambdaActivity"
          Lambda:
            Name: "LambdaActivity"
            LambdaName: "Lambda名"
            BatchSize: 1
            Next: "AddAttributesActivity"
          AddAttributes:
            Name: "AddAttributesActivity"
            Attributes:
              key1: "attribute1"
              key2: "attribute2"
            Next: "RemoveAttributesActivity"
          RemoveAttributes:
            Name: "RemoveAttributesActivity"
            Attributes:
              -
                "attribute1"
              -
                "attribute2"
            Next: "SelectAttributesActivity"
          SelectAttributes:
            Name: "SelectAttributesActivity"
            Attributes:
              -
                "attribute1"
              -
                "attribute2"
            Next: "FilterActivity"
          Filter:
            Name: "FilterActivity"
            Filter: "attribute1 > 40 AND attribute2 < 20"
            Next: "MathActivity"
          Math:
            Name: "MathActivity"
            Attribute: "attribute"
            Math: "attribute - 10"
            Next: "DeviceRegistryEnrichActivity"
          DeviceRegistryEnrich:
            Name: "DeviceRegistryEnrichActivity"
            Attribute: "attribute"
            ThingName: "thingName"
            RoleArn: "arn:aws:iam::<your_Account_Id>:role/Enrich"
            Next: "DeviceShadowEnrichActivity"
          DeviceShadowEnrich:
            Name: "DeviceShadowEnrichActivity"
            Attribute: "attribute"
            ThingName: "thingName"
            RoleArn: "arn:aws:iam::<your_Account_Id>:role/Enrich"
            Next: "DatastoreActivity"
          Datastore:
            Name: "DatastoreActivity"
            DatastoreName: "データストア名"
```

### データセット
データセットは`SQLデータセット`と`コンテナデータセット`が存在します。SQLで足りない場合にコンテナ化したJupyterNotebookのPythonでデータセットの作成ができます。

SQLデータセットは対象となるデータストア名、CRON形式で書いた定期実行の周期、出力先となるデータセット名を定義します。ちなみに出力形式はCSVに限ります。

```sample-SQLdataset.yaml
---
Description: "SQLデータセットの作成"
Resources:
  Dataset:
    Type: "AWS::IoTAnalytics::Dataset"
    Properties:
      DatasetName: "データセット名"
      Actions:
        -
          ActionName: "SqlAction"
          QueryAction:
            SqlQuery: "select * from Datastore（対象となるデータストア名）"
            Filters:
              -
                DeltaTime:
                  OffsetSeconds: 1
                  TimeExpression: "timestamp"
      Triggers:
        -
          Schedule:
            ScheduleExpression: "cron(0 12 * * ? *)"
      RetentionPeriod:
        Unlimited: false
        NumberOfDays: 10
      Tags:
        -
          Key: "keyname1"
          Value: "value1"
        -
          Key: "keyname2"
          Value: "value2"
```

コンテナデータセットは処理対象にデータストアではなくSQLデータセットをとるところに注意が必要です。こちらも定期実行ができますが、対象となるSQLデータセットの更新をトリガーにすることもできます。


```sample-containerDataset.yaml
---
Description: "コンテナデータセットの作成"
Resources:
  TriggeringDataset:
    Type: "AWS::IoTAnalytics::Dataset"
    Properties:
      DatasetName: "トリガーとなるデータセット名"
      Actions:
        -
          ActionName: "アクション名"
          QueryAction:
            SqlQuery: "select * from Datastore"

  ContainerDataset:
    Type: "AWS::IoTAnalytics::Dataset"
    DependsOn: TriggeringDataset
    Properties:
      DatasetName: "コンテナ処理の対象となるデータセット名"
      Actions:
        -
          ActionName: "アクション名"
          ContainerAction:
            Image: "<アカウントID>.dkr.ecr.us-east-1.amazonaws.com/sampleimage" 
            ExecutionRoleArn: "arn:aws:iam::<アカウントID>:role/ExecutionRole"
            ResourceConfiguration:
              ComputeType: "ACU_1"
              VolumeSizeInGB: 10
            Variables:
              -
                VariableName: "変数１（※変数の追加はしてもしなくてもいい）"
                StringValue: "文字列１"
              -
                VariableName: "変数２"
                DoubleValue: 1
              -
                VariableName: "変数3"
                DatasetContentVersionValue:
                  DatasetName: "データセット名"
              -
                VariableName: "変数４"
                OutputFileUriValue:
                  FileName: "ファイル名"
      Triggers:
        -
          Schedule:
            ScheduleExpression: "cron(0 12 * * ? *)"
        -
          TriggeringDataset:
            DatasetName: "SQL処理に続けてコンテナ処理をしたい場合、ここで対象となるデータセット名を記載する。そのデータセットにSQL処理が走るとそれがトリガーになる"
```

### さらに細かい設定を足したい場合
日本語未対応ですが公式のドキュメントを参照してください（日本語版のドキュメントから行くとレファレンスが表示すらされないので注意）。例えばデータセットをS3に保存する場合の定義なども載っています。

IoT Analyticsのレファレンス：
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_IoTAnalytics.html

AWSサービス全体のレファレンス：
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-reference.html

データセットをS3に保存する場合：
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-s3destinationconfiguration.html


## パイプラインでチャネルからデータを引いてきて加工やフィルタリングした後にデータストアにプッシューコンソールでの手順

## チャネルとデータストアの設定
チャネルとデータストアはCloudformationのYAMLファイルで見た通り入力先と出力先を選ぶだけなので省きます。データの保存先を選ぶ箇所だけ見てみます。

下の丸を選ぶとIoT Analytics内に保存されます。保存期間も指定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/f4aef2ee-8ed5-879c-f19a-37291912bb12.png)
保存先にS3を選ぶこともできますが、ファイル形式を指定できません。Base64でエンコードされ、gz圧縮が共生になります。IoT Analyticsは基本的にSageMakerやQuickSightにデータセットを提供するためのサービスということなのでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/2f7f2213-dbfb-b9d3-979b-cbe985996222.png)

## パイプラインの設定
パイプラインを作成を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/fd219b81-7b7f-e4d0-dd39-9c4c75dfd7ce.png)
入力先と出力先（チャネルとデータストア）を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/7159e91e-c59d-58ef-3faa-388919ec864c.png)
次にテストとなるデータをここで追加します。今回は`temperature:24.7`といった感じのデータがラズパイから送られてくるのでそれに即して追加します。記入したら属性の追加を押します（すでにチャネルにデータがたまっている場合は自動で追加されています）。そしたら次へを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/38a78199-fd66-7a4e-f529-9258d7e625eb.png)
8種類の処理の中から処理内容を追加します。個々の処理内容に関しては以下の公式資料を参考にしてください。アクティビティは最大25個登録できます。Cloudformationの箇所で見た通り入力先を指定するチャネルアクティビティと出力先を指定するデータセットアクティビティは必須なので実質23個アクティビティを登録できることになります。アクティビティの登録が終わったらパイプラインを作成を押します。

https://docs.aws.amazon.com/ja_jp/iotanalytics/latest/userguide/pipeline-activities.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/972e40d0-c747-d4eb-8495-57570cb9ab6d.png)
![Image Pasted at 2021-6-30 14-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/d4703fe6-6357-ad84-40b2-c3d8aed34358.png)
無事作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/bbb196c2-f344-5fa3-57cb-1715bd8f8b53.png)

## データセットの設定
ここではコンテナデータセットの設定は行わずSQLデータセットの設定のみ行います。
データセットの作成を押すとタイプが選べますが、上のSQLデータセットを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/ff2493c6-5e24-ad81-147a-9d131de096bd.png)
データセット名と入力ソースを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/6333d127-58a9-c720-02fc-a1b647d07ec2.png)
SQL文を書きます。（詳しくは https://docs.aws.amazon.com/ja_jp/iotanalytics/latest/userguide/sql-support.html を参考にしてください）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/a50b1c7c-d137-4f72-6b2e-f4e7c220ea32.png)
デルタウィンドウの設定をします。データの漏れ・重複を防いだり一定の期間の平均をとりたい時などに使います。詳しくは下に貼ったリンクかAWSJ Blackbeltの動画 https://youtu.be/IePnxlX1MbA?t=1908 を参考にしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/473b9ef7-6228-e3ff-2bca-cb0ecf6ad08a.png)

>Q:DeltaTime ウィンドウとは何ですか?

>Delta ウィンドウは、重複することなく連続する時間間隔であり、ユーザーが定義します。Delta ウィンドウを使用すると、前回の分析以降にデータストアに到着した新しいデータを使用してデータセットコンテンツを作成し、これらのデータに対して分析を実行できます。Delta ウィンドウを作成するには、データセットの queryAction のフィルター部分に DeltaTime を設定します。基本的には、この操作で特定の時間ウィンドウに到着したメッセージをフィルタリングし、以前の時間ウィンドウのメッセージに含まれたデータが重複してカウントされないようにします。

https://aws.amazon.com/jp/iot-analytics/faq/

最後にSQL処理の定期実行をいつやるか設定します。最頻で1分毎ができるほか、毎時毎分毎月なども選べます。自分でCRONを書くこともできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/fce861b5-5362-55c1-c041-7e32bc82e0fb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/db404a0d-e66b-bd14-5788-90514ac2d29d.png)
最後にデータの保存期間（90日間が推奨されています）とバージョニングの有無を選んで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/eec1adfb-5e1a-90e9-4214-ffab9b9edcad.png)
SQLクエリー結果として出力されるcsvファイルの配信先を選べます。現在はS3とIoT Eventsのみサポートされています。下の画像ではクエリーが実行されたUNIXタイムスタンプとデータセットのUUIDをファイル名とするように組み込み関数を使っています。またメタデータをGlueにエクスポートすることもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/d8f329db-938c-dd41-1009-c3b5911508b6.png)
最後にデータセットの作成を押すと画像のようにメッセージが表示されます。無事作成ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/c171f735-baeb-2589-5c4c-7d3c4f366c63.png)

# 注意点
## データが届いているかの確認が作成から48時間以上たっていないとできない
チャネルやデータストアの作成から48時間以上たっていないと中身の確認ができません。なのでパイプライン処理やデータセットの作成がうまくいっているかすぐに確認できないという弱点があります。ほかにも使いにくい点はいくつかありますが、ここら辺は今後改善されていくでしょう。

# QuickSightでの可視化
データセットができてきたらQuickSightで可視化してみます。アカウントの作成は省略します。

## IoT Analyticsに対するRead権限の追加
コンソールから検索してQuickSightのページに行ったらまずはリージョンをヴァージニア北部（us-east-1）にします（このリージョンじゃないと設定ができません）。画面右上のメールアドレスの箇所をクリックして`manage QuickSight`を押します。左から`Security & permissions`を押します。そして`QuickSight access to AWS services`の`Add or remove`を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/35673c55-99ed-bb13-32e1-ddcc0d6170b7.png)
このような画面に飛びます。AWS IoT Analyticsを追加して`Update`を押します。これで権限が追加できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/d5894592-de90-9b0b-190e-4426e46eeb05.png)


もしSPICE領域が足りない場合は別途購入する必要があります。

SPICEについての日本語記事：

https://dev.classmethod.jp/articles/amazon-athena-quicksight-import-spice/

https://dev.classmethod.jp/articles/quicksight-spice-sizing/

## データセットの追加
まずは先ほどIoT Analyticsで作成したデータセットを追加します。右上の`New dataset`を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/c6568cf3-d175-79f8-ea64-238b1b20651e.png)
AWS IoT Analyticsを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/be244652-62bd-3eb1-3f00-88565f415a0c.png)
このようにIoT Analyticsで作成したデータセットが表示されるので対象となるデータセットを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/c7e4141f-28ca-a2f1-791d-744e9a7d28a6.png)
この表示が出たらデータセットが空です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/4f65b482-2062-5477-8f69-55a75d2485ce.png)
この表示が出たら成功です。`Visualize`を押すとグラフ化できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/74ee17e4-920c-2b9a-c7ce-6c19f8abc5c7.png)

### 注意点：AdBlockをOFFにする
AdBlockを入れているといろいろと変な挙動をするのでQuickSightに対してはAdBlockをOFFにしましょう。

## グラフの作成とAnalysisの作成
先ほどの手順で`Visualize`を押すと以下のような画面に飛びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/24a70e09-ad7b-ab84-f051-f3202f1349d4.png)
左下から折れ線グラフを選んで、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/21c8f81a-4018-61e2-49af-2eef5a615fe2.png)

温度をｙ軸に、デルタウィンドウ（`__dt`）をx軸にそれぞれドラッグアンドドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/0719aed3-3197-5d8c-9e8a-39ec31626f0e.png)
ｙ軸が`sum`合計になっているので`average`に変換して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/939f4044-2dc2-d211-1b71-09aa161fd726.png)
歯車マークを押すと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/aea48d58-1af6-c00a-2f90-8aaae06cff3e.png)
詳細な設定ができるので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/e73521e8-7c10-6071-100e-187f6a5346d0.png)
ｙ軸の表示範囲を変えたりできます。この辺の使いやすさはエクセルと比べると圧倒的ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/a479dce3-4abb-ecba-de62-33411a3309dc.png)
グラフができたら右上の`Share`でダッシュボード化します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/f225b5ca-e3f7-dced-c878-6d274584951b.png)
ダッシュボード名を入力して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/b553a5bc-56fd-7edb-0137-d80f044d0533.png)
シェアする人の範囲を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/f5f5bb65-137a-2d9e-649e-03c8ad8d4e8a.png)
最終的にconfirmを押すとダッシュボードに登録されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/bcfdb4f8-4eba-43d1-2fc6-e4d53fbf20c0.png)
ちなみにスマホのQuickSightアプリからも確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/b485c15d-d1b0-6b0a-30d5-80779de4b233.png)
ちなみにこちらは長期的に測定していた部屋の温度のグラフです。ちゃんと可視化できていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001699/ce764a2f-2ba8-f5a5-6b30-2e9ffe4d2a2c.png)

# さいごに
ラズパイから送った温度データをIoT AnalyticsとQuickSightをつかって可視化してみました。IoT Analytics、QuickSightのどちらもいろんなIoTシステムでその強みを発揮するサービスなので慣れておいて損はないと思います。