投稿日 2020-10-06

最小限のデバイス開発でデータをAmazon Timestreamに送るSORACOMとAWSの構成

こんにちは、ソリューションアーキテクトのtakiponeこと大瀧です。

時系列データベースサービス Amazon Timestream が、先日正式リリースされました。 Timestream は従来のリレーショナルデータベースやNoSQLデータベースと比べ、データベース容量の上限が無いスケール性時系列データの分析を柔軟に行えるSQLライクなクエリサポートなど、IoTの膨大なテレメトリデータの格納に最適な、先進的なサービスです。AWSの他のサービスと組み合わせて、例えば Timestream にある IoT データを Amazon QuickSight で可視化したり、 Amazon SageMaker で機械学習処理を行うことができます。

本ブログでは、SORACOMからAmazon Timestreamにデータを送る構成パターンとおすすめの構成、設定時のポイントをご紹介します。

SORACOM から Timestreamにデータを送る構成パターン

Timestream へのデータ投入はいくつかの方法があり、例えば IoT デバイスから MQTT クライアントによる MQTT over TLS で AWS IoT Core に接続し、 IoT Core 経由で Timestream に連携します。一方で SORACOM にはクラウド連携サービスがあり、デバイスからシンプルな送信プログラムで SORACOM に送信し、それを連携サービスが AWS IoT Core に中継することができます。

SORACOMのクラウド連携サービスを間に入れると、以下のメリットがあります。

  • デバイスからは、 MQTT クライアントの代わりに汎用な通信プロトコルでデータが送信できる
  • AWS認証情報をSORACOMに保存し、デバイスには配置不要
  • SIMの識別情報やタイムスタンプなどのメタデータをSORACOMの中継時に付与できる

SORACOM FunnelSORACOM Beam の2つがあり、デバイスの通信プロトコルによって使い分けます。

SORACOMサービス名デバイスの通信プロトコル
SORACOM FunnelHTTP
TCP
UDP
SORACOM BeamMQTT

SORACOM Funnel は Sigfox や LoRaWAN といった LPWAN デバイスからのデータも扱うことができ、今回の構成で Amazon Timestream にデータを送ることもできます。

AWS IoT Core は一部の用途を除きメッセージが JSON テキスト形式であることを要求しますので、デバイスから送信するデータの形式を確認しましょう。 JSON 形式でない場合は、 SORACOM Funnel であれば SORACOMの以下のサービスを組み合わせてメッセージを JSON 形式に変換できます。

今回はシンプルにデータを送る構成例として、デバイスとしてソラコムが販売する GPSマルチユニット SORACOM Edition を例に GPS マルチユニットのデータ送信形式 UDP に対応する SORACOM Funnel 、 AWS IoT Core を経由してデータを送る設定を行います。 GPSマルチユニットは、以下の手順に従いデータが送信されるところまで確認しておきます。

必要なもの

  • SORACOMアカウント
  • GPSマルチユニット SORACOM Edition (代わりにUSBドングルをRaspberry PiやPCにセットしてもOK)
  • GPSマルチユニットに対応する SORACOM IoT SIM plan-D もしくは plan-KM1 (USBドングルの場合は、ドングルが対応する他のプランで構いません)

1. Timestream の設定

Timestream のデータ取り込み先としてデータベースとテーブルをそれぞれ事前に作成しておきます。Timestream のテーブルは動的スキーマなので、テーブル作成時にカラムなど定義する必要はなく、データの保持期限 (Magnetic store retention) を用途に応じて調整すれば、他の項目は任意ないし既定値で良さそうです。今回は以下の名称でそれぞれ作成しました。

  • AWSリージョン : オレゴン( us-west-2 )
  • データベース名 : soracomSampleDB
  • テーブル名 : gpsMultiunit
  • データ保持期限: 1年

AWS管理コンソールでリージョンを選択し、Timestreamの画面から[Create Database]ボタンをクリックします。

Create Database 画面では、空のデータベースを作成する [Standard database] を選択、Name に soracomSampleDB と入力して他の項目は初期値のまま右下の [Create database] ボタンをクリックします。

続いて作成した soracomSampleDB のプロパティにある Tables の右側、 [Create table] ボタンをクリックしテーブル作成画面を開きます。

テーブル作成画面では、 Table name に gpsMultiunit と入力して、 retention 項目をそれぞれ 1 Day / 1 Year にセットし [Create table] ボタンをクリックしてテーブルを作成します。

これで Timestream の準備は完了です。

2. IAM ロールの作成

続いて、 AWS IoT Core から Timestream にデータを書き込むための IAM ロールを作成します。以下の手順をベースに、 AWS CLI で操作します。

以下の内容で iot-role-trust.json というファイル名のファイルを作成します。

{
    "Version":"2012-10-17",
    "Statement":[{
        "Effect": "Allow",
        "Principal": {
            "Service": "iot.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
    }]
}

以下の内容で iot-policy.json というファイル名のファイルを作成します。

{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Action": [
        	"timestream:DescribeEndpoints",
        	"timestream:WriteRecords"
        ],
        "Resource": "*"
    }]
}

以下のコマンドを実行し、各ファイルを読み込んで IAM ロールの作成およびポリシーのアタッチを行います。コマンド中の <AWSアカウントID> は実際の値に置き換えてください。

aws iam create-role --role-name my-iot-role --assume-role-policy-document file://iot-role-trust.json
aws iam create-policy --policy-name my-iot-policy --policy-document file://iot-policy.json
aws iam attach-role-policy --role-name my-iot-role --policy-arn "arn:aws:iam::<AWSアカウントID>:policy/my-iot-policy"

これで完了です。

3. AWS IoT Core の設定

SORACOM Funnel の Tips の設定を含めた AWS IoT Core のルールを JSON ファイル rule.json で作成します。

{
    "sql": "SELECT payloads.temp, payloads.humi, payloads.x, payloads.y, payloads.z, payloads.lon, payloads.lat, payloads.bat FROM 'data/#'",
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23",
    "actions": [
        {
            "timestream": {
                "roleArn": "arn:aws:iam::<AWSアカウントID>:role/my-iot-role",
                "databaseName": "soracomSampleDB",
                "tableName": "gpsMultiunit",
                "dimensions": [
                    {
                        "name": "deviceId",
                        "value": "${imsi}"
                    },
                    {
                        "name": "operatorId",
                        "value": "${operatorId}"
                    }
                ],
                "timestamp": {
                    "value": "${timestamp}",
                    "unit": "MILLISECONDS"
                }
            }
        }
    ]
}

AWS CLI でファイルを読み込みルール rule1の作成を操作します。

aws iot create-topic-rule --region us-west-2 --rule-name rule1 --topic-rule-payload file://rule.json

これで完了です。

4. SORACOM Funnel の設定

ステップ3で作成した AWS IoT Core のルールに対応するトピックにデータを連携する、 SORACOM Funnel の設定を追加します。以下のドキュメントの「Funnel のセットアップ」手順に従い、認証情報の登録と GPS マルチユニットの所属する SIM グループに設定を行います。

「転送先URL」は以下を設定します。末尾の device1 は任意の項目です。

https://<AWS IoT Coreのエンドポイント>/$aws/rule/rule1/data/device1

これで完了です。

5. 動作確認

GPS マルチユニットのファンクションボタンを1秒ほど押し、データを送信します。 GPS マルチユニットをお持ちでない方は、 Raspberry Pi などに USB ドングルと SORACOM IoT SIM をセットし、以下のコマンドラインで代用できます。

curl --header 'Content-Type: application/json' --data '{"temp":15, "humidity": 35.5}' http://uni.soracom.io

少し待つとデータが送信され、 Timestream のクエリエディタで以下のクエリを実行するとデータが確認できます。

SELECT * FROM "soracomSampleDB"."gpsMultiunit" ORDER BY time DESC LIMIT 10

考慮するべきポイントとTips

手順を振り返りながら、設定のポイントをおさらいしておきます。

ポイント : SELECT文の要素を絞ろう

AWS IoT Core から Timestream へのデータ投入は、ルールの SQL の SELECT 句で指定する JSON の要素ひとつずつを Timestream のメジャーとするレコードとして投入します。

要素の数がレコード数に比例するため、 SELECT 句には時系列データとして必要なもののみを指定し、またディメンジョンに入れるべき要素はそちらに入れるようにするのが良いでしょう。

ポイント : AWS IoT Core の基本的な取り込み(Basic ingest)機能を活用しよう

今回の用途ではメッセージの購読が不要ですので、費用の安い基本的な取り込み機能(Basic ingest)を積極的に検討しましょう。

SORACOM Funnel の Tips

SORACOM Funnel の場合は、デバイスからの送信データが JSON の payloads 要素内に入れ子で入るため、 SELECT 句では payloads.temp というようにキーの接頭辞に payloads. を入れるのがポイントです。 Timestream 内では接頭辞が省かれた要素名が measure_name になるようです。SELECT 文の例を以下に示します。

SELECT payloads.temp, payloads.humi, payloads.x, payloads.y, payloads.z, payloads.lon, payloads.lat, payloads.bat FROM 'data/#'

また、デバイスやマルチテナントのアカウントを識別するためのディメンジョンとして、以下を設定すると良いでしょう。Funnel が JSON の要素に imsi (SIMの識別子)と operatorId (SORACOMアカウントの識別子) を付与することを利用したものです。

ディメンジョン名の例ディメンジョンの値
deviceId${imsi}
operatorId${operatorId}

タイムスタンプは Funnel が付与する timestamp 要素があるので、デバイスから送信されるデータにタイムスタンプが含まれない場合は、こちらを Timestream で利用しても良いでしょう。現時点で AWS 管理コンソールでは Timestream のタイムスタンプ要素をユーザーが指定する設定項目が無いため、 AWS CLIの aws iot create-topic-rule コマンドで設定します。

SORACOM Beam のTips

Funnel と同様、ディメンジョンに IMSI をセットするのがオススメです。 Beam の設定オプションの「 IMSI 付与」をオンにするとトピック名の末尾に /<IMSI> が追加されるので、これをディメンジョンの値から参照します。ただし、参照する関数 topic() は引数にトピックの階層番号を指定するため、デバイスから送信する際のトピックの階層に合わせて 階層数+1 を指定する点に注意します。

デバイスから送信するトピック名の例AWS IoT Core に届くトピック名設定するべきディメンジョンの値
/data/data/440XXXXXXXXXXXX${topic(2)}

SORACOM Funnel の Tips と同様、タイムスタンプは必要に応じてAWS CLIの aws iot create-topic-rule コマンドでデバイスからのデータに含まれるタイムスタンプ要素を指定しましょう。

まとめ

SORACOM でデバイスのデータを Amazon Timestream に送る様子をご紹介しました。 Timestream の登場で AWS での IoT デバイスのデータがより扱いやすくなった印象があります。ぜひ皆さんの IoT システムでも SORACOMを活用して Timestream にデータを溜めていきましょう!