SORACOM GPSマルチユニットで取得した情報をAWS Timestreamへ送信させる

# はじめに
[AWSサービス上で地図画像を作成できるようにした](https://qiita.com/ckw-1227/items/a6470dc3cca1c5fc2d53)ので、次は地図画像に乗せるデータをAWSサービスに取り込みたい。
…ということで、SORACOMのGPSマルチユニットで取得した気温データをAWSサービス上に取り込むことにする。

# 構成
SORACOM Funnelサービスを利用し、GPSマルチユニットの情報をIoTCore経由でTimestreamに送信する。
使用するデータベースはDynamoDBとTimestreamで迷ったのだが、まだ使ったことのないサービスを使いたいという単純な理由でTimestreamを選択。
![007_Timestream_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/1470cf69-2967-f39a-60ba-317ad0d571b0.png)

# 手順
１.GPSマルチユニットがデータを取得・送信していることの確認
２.Timestreamデータベースの作成
３.Funnelを利用するための準備
４.Funnelのセットアップ
５.IoTCoreの設定

# 手順1.GPSマルチユニットがデータを取得・送信していることの確認
まずGPSマルチユニットのデータがSORACOMのサービスまで到達していなければ元も子もないので、SORACOMのユーザコンソールでデータが届いていることを確認する。
ついでにデータの内容も確認して、Timestreamにどのデータを登録するかを検討しておく。

・SORACOMユーザコンソールで、左上のメニューマークをクリック
![007_Timestream_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/fef87e90-3a0a-6f31-bf55-ba613ad54199.png)

・「ガジェット管理」＞「GPSマルチユニット」をクリック
![007_Timestream_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/625c605e-fbf7-4251-3ac8-43e39fcd22ed.png)

・GPSマルチユニット一覧画面で、データの確認をしたいマルチユニットを選択して「SORACOM Harvest Data」をクリック。
![007_Timestream_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/de323f8d-c2b5-8f3c-83ba-a8a272f17be1.png)

・Harvest Dataの画面にデータが表示されることを確認する。
![007_Timestream_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/9e731f08-4ffa-19c7-faa8-86e1cd86a1c0.png)

・GPSマルチユニットから送信されるデータの種類の確認
Harvest Dataで、GPSマルチユニットから送信されているデータの種類を確認しておく。
[公式ガイドの「送信されるデータフォーマット」](https://users.soracom.io/ja-jp/guides/iot-devices/gps-multiunit/payload/)を参照しつつ確認すると、下記データが安定して取れている様子。
| プロパティ | 内容 |
|:-:|:-:|
| lat | 緯度 |
| lon | 経度 |
| bat | 電池残量 |
| rs | 電波強度 |
| temp | 温度 |
| humi | 湿度 |
| type | 送信種別 |

加速度が取得できていないのは、移動していないので仕方ない（今回は必要ないし）。
取れているデータのうち、今回は地図上に温度データを表現したいので、緯度・経度・温度（ついでに湿度も取っておこう）が必要になる。

# 手順2.Timestreamデータベースの作成
次はAWSのマネジメントコンソールでTimestreamデータベースを作成する。

・Timestreamの画面で、「データベースを作成」をクリック。

・「標準データベース」を選択してデータベースの名前を入力して「データベースの作成」をクリック。
　※暗号化キーは自動的に作られる。作成後、KMSコンソールでAWSマネージド型キー一覧を確認すると、aws/timestreamが作成されている。
![007_Timestream_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/bcc1ad0b-6168-de96-d15f-bac59e00ea7c.png)

・データベース一覧画面で、作成されたデータベース名をクリック。
![007_Timestream_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/ef39b012-b05d-e68e-fe8a-e4bf91a59cf1.png)

・データベースの概要画面で、「テーブル」＞「テーブルを作成」をクリック。
![007_Timestream_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/5af9984e-cd18-824b-5ff9-6d0aa5dddd4e.png)

・それぞれ設定を入力して「テーブルを作成」をクリック。
![007_Timestream_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/efa1bf9d-62d9-bf2d-906c-43a60861f6f4.png)
今回設定した値は以下。（テーブル名は任意なので省略）
マグネティックストレージの書き込みをONにすると、[保持期間より過去のデータも書き込める](https://aws.amazon.com/jp/about-aws/whats-new/2021/11/amazon-timestream-scheduled-queries-multi-measure-records-magnetic-storage-writes/)とのことだが、今回は必要ないのでOFFで作成する。
| 項目 | 設定値 |
|:-:|:-:|
| メモリストアの保持期間 | 12時間 |
| マグネティックストアの保持期間 | 1月 |
| マグネティックストレージの書き込み | チェックなし |

# 手順3.Funnelを利用するための準備

・事前にSORACOMユーザコンソールで、Funnelを利用するIoT SIMのカバレッジタイプを確認する。
SORACOMユーザコンソールの上部に「日本」とあれば日本カバレッジ、「グローバル」とあればグローバルカバレッジとなる。
![007_Timestream_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/7a839f86-b59e-017c-ff92-3516c325d0f5.png)


・IoTCoreへのメッセージをPublishするためのIAMロールを作成する。
AWSマネジメントコンソールでIAMのロール一覧画面へ移動し、「ロールを作成」をクリック。
![007_Timestream_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/d0eb7b42-9b8d-6dff-be08-baf23dc4e76f.png)

・信頼されたエンティティタイプに「AWSアカウント」を選択、AWSアカウントは「別のAWSアカウント」を選択し、先に確認したカバレッジタイプが日本であればアカウントID欄に「762707677580」、グローバルであれば「950858143650」を入力する。
![007_Timestream_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/f20cc368-47f7-12f0-7c89-8f8099fd9d9e.png)

・画面下部の「外部IDを要求する」にチェックを入れ、外部ID欄に任意の文字列を入力して「次へ」をクリック。
※ここで入力した外部IDは、これ以降、[External-ID] で表記する。
![007_Timestream_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/8e27d09e-c0af-711e-d414-5993c2d34abd.png)

・許可を追加画面が表示されるので、「ポリシーを作成」をクリック。
![007_Timestream_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/2edea7b5-3c85-c112-16a3-b553cd738d7f.png)

・ポリシーの作成画面のビジュアルエディタで、サービスにIoTを選択し、フィルタアクションに「Publish」と入力して"Publish"にチェックを入れる。
![007_Timestream_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/b2e3d113-1948-93ca-90aa-ecfd03d173bd.png)

・「リソース」＞「指定」を選択し、「ARNの追加」をクリック。
![007_Timestream_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/43403265-dd86-70c0-571b-0891df984e97.png)

・ARNの追加画面が開くので、Region、Account、Topic nameを入力する。
ここではRegion：「すべて」にチェック、Account:自分のアカウントID、Topic name："topic-pyGMT/*"を入力した。
    ※ここで入力したトピック名(この例では"topic-pyGMT")を、以降、[topic_name] として表現する。
![007_Timestream_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/6ad7ed97-24c0-d54f-d450-c4e1abea0141.png)

・「追加」をクリックしてポリシーの作成画面に戻り、「次のステップ：タグ」＞「次のステップ：確認」の順にクリック。

・ポリシーの確認画面でポリシーの名前を入力し、「ポリシーの作成」をクリック。
![007_Timestream_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/ff87f2f5-72d9-a7ff-2182-48de0a5e0f4f.png)

・ポリシー画面を閉じて、許可を追加画面に戻る。

・更新ボタンをクリックしてポリシー一覧を更新し、先ほど作成したポリシーの名前で検索する。
![007_Timestream_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/5d1ce379-92b3-0478-cde7-d328e135a87f.png)

・検索で表示されたポリシーにチェックを入れ、「次へ」をクリック。
![007_Timestream_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/0be9f62f-cfdb-b07c-ceaa-44c18e2282ed.png)

・任意のロール名を入力し、「ロールを作成」をクリック。
ロール一覧画面に戻るので、作成したロール名で検索し、作成されたロールのARNを確認・メモしておく。
※以降、このロールARNを [role_arn] で表記する。
![007_Timestream_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/5ef9caa7-0ba6-b1cd-1432-954f995f3ac1.png)

・AWS IoTのコンソールに移動して、左メニューの「設定」をクリック。
![007_Timestream_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/e915d587-8eb0-325d-3bc3-9db69dba68c4.png)

・デバイスデータのエンドポイントの「エンドポイント」をメモする。
※ここでメモしたエンドポイントは、これ以降、[device_endpoint] で表記する。
![007_Timestream_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/a81cd56d-1509-a684-fca0-cf20ad1ed8ef.png)

# 手順4.Funnelのセットアップ

・SORACOMユーザコンソールで、画面右上のメールアドレス欄をクリック。
![007_Timestream_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/53742278-b539-c5c6-3ad1-9b5808d8c090.png)

・表示されるメニューの「セキュリティ」をクリック。
![007_Timestream_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/f64c3b72-3c5f-728c-1018-dd0874507200.png)

・SAMユーザー一覧画面が表示されるので、左メニューの「認証情報ストア」を選択し、認証情報一覧画面の「認証情報を登録」をクリック。

・認証情報を登録画面で、以下の情報を入力する。
| 項目 | 設定値 |
|:-:|:-:|
| 認証情報ID | 任意の文字列を入力 |
| 種別 | 「AWS IAM ロール認証情報」を選択 |
| ロールARN | [role_arn]を入力 |
| 外部ID | [External-ID]を入力 |

![007_Timestream_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/92cd9a5e-fc17-25f6-c71d-32d6c769cc06.png)

・Funnelを有効化する。
SORACOMユーザコンソールの画面左上のメニューボタンをクリックし、表示されたメニューの「SIMグループ」を選択する。
![007_Timestream_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/1e0abe78-0b07-7c9b-ece9-35fde048d326.png)

・SIMグループ一覧画面で該当のSIMグループを選択し、「SORACOM Funnel 設定」をクリックする。
※該当のSIMグループがない場合は公式の[グループ設定](https://users.soracom.io/ja-jp/docs/group-configuration/)を参照。
![007_Timestream_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/a9350bc0-b88a-ff92-b961-7116c6c5f6c5.png)

・表示されたスイッチをクリックしてONにする。

・各項目を設定し、「保存」をクリック。
TimestreamにSIM IDを登録させるため、「SIM IDを追加」はONにする。
| 項目 | 設定値 |
|:-:|:-:|
| 転送先サービス | 「AWS IoT」を選択 |
| 転送先 URL | 「[device_endpoint]/[topic_name]/#{imsi}」を入力 |
| 認証情報 | 先の手順で登録した認証情報を選択 |
| 送信データ形式 | 「JSON」を選択 |
| SIM ID を追加 | ON |

![007_Timestream_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/cf252040-1366-8a80-ff2c-807fbb52a447.png)


・AWS側へデータが連携されることを確認する。
AWSマネジメントコンソールのAWS IoT画面へ移動し、左メニューから「MQTTテストクライアント」を選択する。
![007_Timestream_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/bc1df5a6-0a87-fff5-c0a3-36e70f38c222.png)

・「トピックのフィルター」欄に「[topic_name]/#」と入力し（今回の例では"topic-pyGMT/#"となる）、「サブスクライブ」をクリック。
![007_Timestream_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/f36a7569-7ffb-5299-b94f-03f909676ddd.png)

・SORACOM側からデータが送信されるまでしばらく待つ。サブスクリプション欄に送られてきたデータが表示されればFunnelの設定はOK。

# 手順5.IoTCoreの設定

・マネジメントコンソールのAWS IoT画面の左メニューで「ルール」を選択し、表示されたルール一覧画面で「ルールの作成」をクリック。
![007_Timestream_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/31533653-32b7-aa89-5ad5-c4c36d8bbbd2.png)

・ルール作成画面が開く。ルール名は任意のものを入力し、「次へ」をクリック。
![007_Timestream_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/b64ef9ba-e650-ba23-707e-573b550e8053.png)

・SQLステートメントに、緯度・経度・温度・湿度を取得するクエリを入力して「次へ」をクリック。
```
SELECT payloads.lat, payloads.lon, payloads.temp, payloads.humi FROM '[topic_name]/#'
```
![007_Timestream_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/e8c8f2c1-f364-a520-9b49-c5006ee803e3.png)



・ルールアクションをアタッチ画面で、ルールアクションに「Timestream table」を選択し、作成しておいたTimestreamデータベース名、テーブル名を選択する。
![007_Timestream_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/a095b019-b30d-32b1-20cf-65b22f3e88d4.png)

・ディメンション欄には以下のように入力する。
また、「新しいロールを作成」をクリックして、作成するロール名を入力する。
| ディメンション名 | ディメンション値 |
|:-:|:-:|
| timestamp | ${timestamp} |
| simId | ${simId} |

![007_Timestream_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/586b5cb1-5a87-7adb-9110-db4335b9bd01.png)


・ここまで設定したら「次へ」をクリックし、確認画面で「作成」をクリック。

・AWSマネジメントコンソールでTimestreamの画面へ移動し、左メニューで「クエリエディタ」を選択。
![007_Timestream_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/b7a13215-601f-3225-144c-c8dc89a29915.png)

・テーブルに対して全件検索をかける。
```
SELECT * FROM "[データベース名]"."[テーブル名]"
```
![007_Timestream_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/56ba7e6b-94ad-10e4-bb8c-8d542da9797b.png)

・クエリ結果に緯度・経度・温度・湿度が返ってこればOK。
![007_Timestream_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1402694/ae539926-d253-09e0-0691-19d1327e812a.png)


# 参考リンク
[（SORACOM公式ドキュメント）AWS IoT アダプターを使用する](https://users.soracom.io/ja-jp/docs/funnel/aws-iot/)
[AWS IoTをつかってSORACOM GPSマルチユニットからAmazon Timestreamへ温湿度データを送信してみた](https://blog.serverworks.co.jp/2020/11/24/192818)