M5Stack Toughと土壌水分量センサーでプランター菜園をモニタリングするVol.4（データ蓄積編）

# データ蓄積先の選定
前回までの記事で、電源、センサーとりつけ、AWS IoT へのデータ送信を行ってきました。

[M5Stack Toughと土壌水分量センサーでプランター菜園をモニタリングするVol.1（電源編）](https://qiita.com/EuzoBass/items/fb4a8f379c2425ad942b)
[M5Stack Toughと土壌水分量センサーでプランター菜園をモニタリングするVol.2（センサー取り付け編）](https://qiita.com/EuzoBass/items/b4bd99995d39b812ea56)
[M5Stack Toughと土壌水分量センサーでプランター菜園をモニタリングするVol.3（AWS IoT 編）](https://qiita.com/EuzoBass/items/4c30f23ffa3d2b9bfa32)

とりあえずAWS IoT にはデータが届いている状態なのでルールエンジンを用いてデータの蓄積を考えていくことになります。データ蓄積する際は、データベースを使ったりAmazon S3などのオブジェクトストレージを使ったりするケースが多いかと思います。最近だと、何でも貯めることができてデータ型とか気にしなくてよいオブジェクトストレージにとりあえず放り込み、その後どうするか考えるという蓄積系と分析系を分離（疎結合）にする**データレイク**の考え方を取るケースも増えてきていると思います。今回は、リアルタイムに近い形で可視化したかったので、データレイクの形は取らず、データベースに直接投入する方法を選びました。

データベースを選定するにあたって、MySQLやPostgreSQLなどの一般的なRDBMSを使う方法もありますし、AWSだとDynamoDBやTimestreamといったNoSQL型のデータベースもあります。IoTの分野では時系列でデータを取り扱うことになるため、TimestreamやInfluxDBなどの時系列データベースが得意としています。

今回はAWSで組んでいることもあり、また、データベースのインフラのお世話や細かいことを考えたくなかったので、AWSの **Amazon Timestream** で構築することにしてみます。

https://aws.amazon.com/jp/timestream/

# Timestream の準備

データベースの構築は、AWS のマネジメントコンソールで Timestream の画面に移動したのち、**標準データベース** を選んで名前をつけ、**データベースを作成** をクリックするだけです。

![timestream01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534832/f6aceca1-7aa6-16af-e56d-e229bd31bc02.png)


テーブルは、作成したデータベースを選択してテーブル名を付け、パーティションキーにこだわりが無ければ**デフォルトパーティショニング**を選択して**テーブルを作成**をクリックします。

![timestream02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534832/899cbf10-8ef9-c49d-9531-d071ad94ad74.png)

DBの細かいこと考えるのが面倒くさいと思ってしまう私にはちょうど良い感じです。

## AWS IoT から Timestream にデータを投入する

AWS IoTに届いたメッセージをTimestreamのテーブルに投入する場合、IoT のマネジメントコンソールで **管理** - **メッセージのルーティング** - **ルール**にて**ルールの作成**をクリックします。

![iot_rule03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534832/e91e47ec-28cc-3a75-3bb2-2cec45ca88e1.jpeg)

適当なルール名を設定し、**次へ**をクリックします。

![iot_rule04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534832/8f671751-7cdd-e8ad-9be1-2a46cde1272b.jpeg)

今回は、*iotfarm-m5t* というトピックに対してメッセージを送っているため、**SQL ステートメント**に下記のクエリを設定します

```SQL
SELECT * FROM 'iotfarm-m5t'
```
設定したら、**次へ**をクリックします

![iot_rule05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534832/4baf3f62-1ba8-cff4-a89d-164d8972394d.jpeg)

ルールアクションには下記のように設定していきます。


| 設定項目 | 設定値 |
| ----- | ----- |
| アクション1 | Timestream table |
| データベース名 | *demo-db* |
| テーブル名 | *demo-table* |
| ディメンション名 | *deviceid* |
| ディメンション値 | ${*deviceid*} |
| タイムスタンプ値-オプション | ${*sampletime*} |
| タイムスタンプの単位 | MILLISECONDS |
| IAMロール | *Timestream*へのアクセス権限を持つIAMロール |

データベース名とテーブル名は上記で作成したものを利用します。
**ディメンション名**は時系列レコードの属性を表します。今回のようなデバイス名や、工場名などを付けてセンサの値を識別できるようにします。ディメンション値に *${deviceid}* と記述することで、IoTのメッセージの *deviceid* に紐づく値を読み取ってくれるようになります。同様にメッセージに含んでおいたタイムスタンプ値は *${sampletime}* で取得することが出来ます。今回タイムスタンプはミリ秒単位で送っているため、*MILLISECONDS* を選択します。

```JSON
{
    "deviceid":"m5t01", <-- ${deviceid} で読み取れる
    "moisture":516,
    "temperature":28.3,
    "sampletime":"1688779815000" <-- ${sampletime} で読み取れる
}
```

下記のように設定出来たら、**次へ**をクリックします。

![iot_rule06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534832/0086af2e-8cbf-2278-b0f7-5848727d3b62.jpeg)

確認画面で設定を確認したのち、**作成**をクリックします。

## Timestream への書き込みを確認

IoTでデータを受信している状態でTimestream のマネジメントコンソールにてクエリエディタを開きます。
**Choose a database to query** で作成したデータベースを選択し、下に表示されたテーブル名の横の3つの点をクリックし**データをプレビュー**をクリックします。

![timestream04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534832/e46b5fd7-d0d7-3ec2-69eb-9198bcdcc92b.png)

クエリエディタに自動的にSQLクエリが記述されるので、**実行** をクリックします。実行した結果、下記のように表示されれば成功です。


![timestream03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534832/1695de9e-efa6-7f88-f80d-9344262bdc94.png)

表示されない場合はIoTのルールアクションで**エラーアクション**を設定し、CloudWatch Logs などにログを出力できるようにしておくことでトラブルシューティングに役立ちます。

## ここまでのまとめ
IoTのデータはS3やRDBMSに蓄積するだけではなく、Timestreamのような時系列データベースに保管する方法もあります。サーバーレス型のデータベースを利用することで手軽に時系列データを保管してクエリで探索がかけられるようになるので、IoT系でのデータ蓄積の選択肢として入れていけそうです。

## 次回
Amazon Managed Grafana を活用してTimestreamに保管されたデータの可視化をしてみたいと思います。