AWS IoT TwinMaker 時系列データコネクタの開発 - AWS IoT TwinMaker

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

AWS IoT TwinMaker 時系列データコネクタの開発

このセクションでは、時系列データコネクタを開発する方法を段階的に説明します。さらに、3D モデル、エンティティ、コンポーネント、アラーム、およびコネクタを含む、クッキーファクトリーサンプル全体に基づく時系列データコネクタの例を紹介します。クッキーファクトリのサンプルソースは、AWS IoT TwinMaker サンプル GitHub リポジトリにあります。

AWS IoT TwinMaker 時系列データコネクタの前提条件

時系列データコネクタを開発する前に、次のタスクを完了することをお勧めします。

注記

完全に実装されたコネクタの例については、クッキーファクトリーの実装例を参照してください。

時系列データコネクタの背景

クッキーミキサーと水タンクを備えた工場で働いているところを想像してみてください。これらの物理エンティティの AWS IoT TwinMaker デジタルツインを構築して、さまざまな時系列メトリクスをチェックして運用状態をモニタリングできるようにしたいと考えています。

現場のセンサをセットアップし、測定データを既に Timestream データベースにストリーミングしています。オーバーヘッドを最小限に抑えながら、 AWS IoT TwinMaker で測定データを表示し、整理できるようにしたいものです。このタスクは時系列データコネクタを使用して実行できます。以下の画像は、時系列コネクタを使用して入力されるテレメトリテーブルの例を示しています。

アセット ID、タイプ、メジャー、時間、値を含むテレメトリテーブルデータの例。

このスクリーンショットで使用されているデータセットと Timestream テーブルは、AWS IoT TwinMaker サンプル GitHub リポジトリにあります。前のスクリーンショットに示されている結果を生成する、実装用のクッキーファクトリのサンプルコネクタも参照してください。

時系列データコネクタのデータフロー

データプレーンクエリの場合、 はコンポーネントとコンポーネントタイプの定義からコンポーネントとコンポーネントタイプの両方の対応するプロパティ AWS IoT TwinMaker を取得します。 は、クエリ内の API クエリパラメータとともにプロパティを AWS Lambda 関数 AWS IoT TwinMaker に転送します。

AWS IoT TwinMaker は Lambda 関数を使用してデータソースからのクエリにアクセスして解決し、それらのクエリの結果を返します。Lambda 関数は、データプレーンのコンポーネントとコンポーネントタイプのプロパティを使用して最初のリクエストを解決します。

Lambda クエリの結果は API レスポンスにマッピングされ、ユーザーに返されます。

AWS IoT TwinMaker はデータコネクタインターフェイスを定義し、それを使用して Lambda 関数とやり取りします。データコネクタを使用すると、データ移行の手間をかけずに AWS IoT TwinMaker API からデータソースをクエリできます。次の図は、前の段落で説明した基本的なデータフローの概要を示しています。

API リクエストとレスポンスは、データソースにアクセスする 3P Connector リクエストとレスポンスを使用します。

時系列データコネクタの開発

以下の手順は、機能的な時系列データコネクタまで段階的に構築する開発モデルの概要を示しています。基本的なステップは次のとおりです。

  1. 有効な基本コンポーネントタイプの作成

    コンポーネントタイプでは、コンポーネント間で共有される共通のプロパティを定義します。コンポーネントタイプの定義について詳しくは、「コンポーネントタイプの使用と作成」を参照してください。

    AWS IoT TwinMaker はエンティティコンポーネントモデリングパターンを使用するため、各コンポーネントはエンティティにアタッチされます。各物理項目をエンティティとしてモデル化し、独自のコンポーネントタイプを持つ異なるデータソースをモデル化することをお勧めします。

    次の例では、1 つのプロパティを使用した Timestream テンプレートの例を示します。

    {"componentTypeId": "com.example.timestream-telemetry", "workspaceId": "MyWorkspace", "functions": { "dataReader": { "implementedBy": { "lambda": { "arn": "lambdaArn" } } } }, "propertyDefinitions": { "telemetryType": { "dataType": { "type": "STRING" }, "isExternalId": false, "isStoredExternally": false, "isTimeSeries": false, "isRequiredInEntity": true }, "telemetryId": { "dataType": { "type": "STRING" }, "isExternalId": true, "isStoredExternally": false, "isTimeSeries": false, "isRequiredInEntity": true }, "Temperature": { "dataType": { "type": "DOUBLE" }, "isExternalId": false, "isTimeSeries": true, "isStoredExternally": true, "isRequiredInEntity": false } } }

    コンポーネントタイプの主な要素は次のとおりです。

    • telemetryId プロパティは、対応するデータソース内の物理項目の一意のキーを識別します。データコネクタは、このプロパティをフィルター条件として使用して、指定された項目に関連付けられた値のみをクエリします。さらに、データプレーン API レスポンスに telemetryId プロパティ値を含めると、クライアント側が ID を取得し、必要に応じて逆引きを行うことができます。

    • lambdaArn フィールドは、コンポーネントタイプが関与する Lambda 関数を識別します。

    • isRequiredInEntity フラグは ID の作成を強制します。このフラグは、コンポーネントの作成時に項目の ID もインスタンス化するために必要です。

    • TelemetryId は外部 ID としてコンポーネントタイプに追加されるため、項目は Timestream テーブルで識別できます。

  2. そのコンポーネントタイプでコンポーネントを作成

    作成したコンポーネントタイプを使用するには、コンポーネントを作成して、データを取得したいエンティティにアタッチする必要があります。以下のステップでは、そのコンポーネントを作成するプロセスを詳しく説明します。

    1. AWS IoT TwinMaker コンソールに移動します。

    2. コンポーネントタイプを作成したのと同じワークスペースを選択して開きます。

    3. エンティティのページに移動します。

    4. 新しいエンティティを作成するか、テーブルから既存のエンティティを選択します。

    5. 使用するエンティティを選択したら、[コンポーネントの追加] を選択して [コンポーネントの追加] ページを開きます。

    6. コンポーネントに名前を付け、[タイプ] には [1] でテンプレートで作成したコンポーネントタイプを選択します。有効な基本コンポーネントタイプを作成します

  3. コンポーネントタイプを Lambda コネクタに呼び出すようにする

    Lambda コネクタは、データソースにアクセスし、入力に基づいてクエリステートメントを生成し、それをデータソースに転送する必要があります。次の例は、これを行う JSON リクエストテンプレートを示しています。

    { "workspaceId": "MyWorkspace", "entityId": "MyEntity", "componentName": "TelemetryData", "selectedProperties": ["Temperature"], "startTime": "2022-08-25T00:00:00Z", "endTime": "2022-08-25T00:00:05Z", "maxResults": 3, "orderByTime": "ASCENDING", "properties": { "telemetryType": { "definition": { "dataType": { "type": "STRING" }, "isExternalId": false, "isFinal": false, "isImported": false, "isInherited": false, "isRequiredInEntity": false, "isStoredExternally": false, "isTimeSeries": false }, "value": { "stringValue": "Mixer" } }, "telemetryId": { "definition": { "dataType": { "type": "STRING" }, "isExternalId": true, "isFinal": true, "isImported": false, "isInherited": false, "isRequiredInEntity": true, "isStoredExternally": false, "isTimeSeries": false }, "value": { "stringValue": "item_A001" } }, "Temperature": { "definition": { "dataType": { "type": "DOUBLE", }, "isExternalId": false, "isFinal": false, "isImported": true, "isInherited": false, "isRequiredInEntity": false, "isStoredExternally": false, "isTimeSeries": true } } } }

    リクエストの主要な要素:

    • selectedProperties は、Timestream 計測の対象となるプロパティを入力するリストです。

    • startDateTimestartTimeEndDateTimeendTimeの各フィールドでは、リクエストの時間範囲を指定します。これにより、返される測定値のサンプル範囲が決まります。

    • entityId は、データのクエリ元となるエンティティの名前です。

    • componentName は、データのクエリ元となるコンポーネントの名前です。

    • orderByTime フィールドを使用して、結果が表示される順序を整理します。

    前述のリクエスト例では、特定の項目の特定の時間枠内に、選択したプロパティの一連のサンプルが、選択した時系列で取得されることを想定しています。レスポンスステートメントは、以下のように要約できます。

    { "propertyValues": [ { "entityPropertyReference": { "entityId": "MyEntity", "componentName": "TelemetryData", "propertyName": "Temperature" }, "values": [ { "time": "2022-08-25T00:00:00Z", "value": { "doubleValue": 588.168 } }, { "time": "2022-08-25T00:00:01Z", "value": { "doubleValue": 592.4224 } }, { "time": "2022-08-25T00:00:02Z", "value": { "doubleValue": 594.9383 } } ] } ], "nextToken": "..." }
  4. コンポーネントタイプを 2 つのプロパティを持つように更新

    次の JSON テンプレートは、2 つのプロパティを持つ有効なコンポーネントタイプを示しています。

    { "componentTypeId": "com.example.timestream-telemetry", "workspaceId": "MyWorkspace", "functions": { "dataReader": { "implementedBy": { "lambda": { "arn": "lambdaArn" } } } }, "propertyDefinitions": { "telemetryType": { "dataType": { "type": "STRING" }, "isExternalId": false, "isStoredExternally": false, "isTimeSeries": false, "isRequiredInEntity": true }, "telemetryId": { "dataType": { "type": "STRING" }, "isExternalId": true, "isStoredExternally": false, "isTimeSeries": false, "isRequiredInEntity": true }, "Temperature": { "dataType": { "type": "DOUBLE" }, "isExternalId": false, "isTimeSeries": true, "isStoredExternally": true, "isRequiredInEntity": false }, "RPM": { "dataType": { "type": "DOUBLE" }, "isExternalId": false, "isTimeSeries": true, "isStoredExternally": true, "isRequiredInEntity": false } } }
  5. 2 番目のプロパティを処理するように Lambda コネクタを更新

    AWS IoT TwinMaker データプレーン API は、1 つのリクエストで複数のプロパティのクエリをサポートし、 のリストを指定してコネクタへの 1 つのリクエスト AWS IoT TwinMaker に従いますselectedProperties

    次の JSON リクエストは、2 つのプロパティのリクエストをサポートするようになった変更後のテンプレートを示しています。

    { "workspaceId": "MyWorkspace", "entityId": "MyEntity", "componentName": "TelemetryData", "selectedProperties": ["Temperature", "RPM"], "startTime": "2022-08-25T00:00:00Z", "endTime": "2022-08-25T00:00:05Z", "maxResults": 3, "orderByTime": "ASCENDING", "properties": { "telemetryType": { "definition": { "dataType": { "type": "STRING" }, "isExternalId": false, "isFinal": false, "isImported": false, "isInherited": false, "isRequiredInEntity": false, "isStoredExternally": false, "isTimeSeries": false }, "value": { "stringValue": "Mixer" } }, "telemetryId": { "definition": { "dataType": { "type": "STRING" }, "isExternalId": true, "isFinal": true, "isImported": false, "isInherited": false, "isRequiredInEntity": true, "isStoredExternally": false, "isTimeSeries": false }, "value": { "stringValue": "item_A001" } }, "Temperature": { "definition": { "dataType": { "type": "DOUBLE" }, "isExternalId": false, "isFinal": false, "isImported": true, "isInherited": false, "isRequiredInEntity": false, "isStoredExternally": false, "isTimeSeries": true } }, "RPM": { "definition": { "dataType": { "type": "DOUBLE" }, "isExternalId": false, "isFinal": false, "isImported": true, "isInherited": false, "isRequiredInEntity": false, "isStoredExternally": false, "isTimeSeries": true } } } }

    同様に、次の例に示すように、対応するレスポンスも更新されます。

    { "propertyValues": [ { "entityPropertyReference": { "entityId": "MyEntity", "componentName": "TelemetryData", "propertyName": "Temperature" }, "values": [ { "time": "2022-08-25T00:00:00Z", "value": { "doubleValue": 588.168 } }, { "time": "2022-08-25T00:00:01Z", "value": { "doubleValue": 592.4224 } }, { "time": "2022-08-25T00:00:02Z", "value": { "doubleValue": 594.9383 } } ] }, { "entityPropertyReference": { "entityId": "MyEntity", "componentName": "TelemetryData", "propertyName": "RPM" }, "values": [ { "time": "2022-08-25T00:00:00Z", "value": { "doubleValue": 59 } }, { "time": "2022-08-25T00:00:01Z", "value": { "doubleValue": 60 } }, { "time": "2022-08-25T00:00:02Z", "value": { "doubleValue": 60 } } ] } ], "nextToken": "..." }
    注記

    この場合のページ分割に関しては、リクエスト内のページサイズはすべてのプロパティに適用されます。つまり、クエリのプロパティが 5 つで、ページサイズが 100 の場合、ソースに十分なデータポイントがあれば、プロパティごとに 100 データポイント、合計 500 データポイントが表示されるはずです。

    実装例については、GitHub の「Snowflake コネクタサンプル」を参照してください。

データコネクタの改善

例外処理

Lambda コネクタが例外をスローしても安全です。データプレーン API コールでは、 AWS IoT TwinMaker サービスは Lambda 関数がレスポンスを返すのを待ちます。コネクタ実装が例外をスローする場合、 は例外タイプ AWS IoT TwinMaker を に変換しConnectorFailure、API クライアントがコネクタ内で問題が発生したことを認識できるようにします。

ページネーションの処理

この例では、Timestream はページネーションをネイティブにサポートするユーティリティ関数を提供しています。ただし、SQL などの他のクエリインターフェイスでは、効率的なページネーションアルゴリズムを実装するために余分な労力が必要になる場合があります。SQL インターフェイスでページ分割を処理する Snowflake コネクタの例があります。

コネクタレスポンスインターフェイス AWS IoT TwinMaker を介して新しいトークンが に返されると、トークンは API クライアントに返される前に暗号化されます。トークンが別のリクエストに含まれている場合、 は Lambda コネクタに転送する前にトークンを AWS IoT TwinMaker 復号します。トークンに機密情報を追加しないことをお勧めします。

コネクタのテスト

コネクタをコンポーネントタイプにリンクした後でも実装を更新することはできますが、 AWS IoT TwinMakerとインテグレートする前に Lambda コネクタを検証することを強くお勧めします。

Lambda コネクタをテストするには複数の方法があります。Lambda コンソールで Lambda コネクタをテストすることも、 AWS CDKでローカルにテストすることもできます。

Lambda 関数のテストの詳細については、「Lambda 関数のテスト」および「アプリケーションのローカルテスト」を参照してください AWS CDK

セキュリティ

Timestream のセキュリティベストプラクティスに関するドキュメントについては、「Timestream のセキュリティ」を参照してください。

SQL インジェクション防止の例については、 AWS IoT TwinMaker サンプル GitHub リポジトリの次の Python スクリプトを参照してください。

AWS IoT TwinMaker リソースの作成

Lambda 関数を実装したら、AWS IoT TwinMaker コンソールまたは API を使用して、コンポーネントタイプ、エンティティ、コンポーネントなどの AWS IoT TwinMaker リソースを作成できます。

注記

GitHub サンプルのセットアップ手順に従うと、すべての AWS IoT TwinMaker リソースが自動的に使用可能になります。コンポーネントのタイプ定義はAWS IoT TwinMaker GitHub サンプルで確認できます。コンポーネントタイプがコンポーネントによって一度使用されると、そのコンポーネントタイプのプロパティ定義と関数は更新できません。

インテグレーションテスト

データプレーンクエリがend-to-endで機能することを検証する AWS IoT TwinMaker には、 と統合されたテストを行うことをお勧めします。これは GetPropertyValueHistory を使用して実行することも、AWS IoT TwinMaker コンソールで簡単に実行することもできます。

TwinMaker コンポーネント情報コンソールページには、コンポーネントの名前、タイプ、ステータスなどが表示されます。

AWS IoT TwinMaker コンソールでコンポーネントの詳細に移動し、テストの下にコンポーネント内のすべてのプロパティが一覧表示されます。コンソールの [テスト] エリアでは、時系列プロパティだけでなく、時系列プロパティ以外のプロパティもテストできます。時系列プロパティには GetPropertyValueHistory API を使用でき、non-time-seriesプロパティには GetPropertyValue API を使用することもできます。Lambda コネクタが複数のプロパティクエリをサポートしている場合、複数のプロパティを選択できます。

コンポーネントのテストを示す TwinMaker コンポーネント情報コンソールページの一部。

次のステップ

AWS IoT TwinMaker Grafana ダッシュボードを設定してメトリクスを視覚化できるようになりました。また、AWS IoT TwinMaker サンプル GitHub リポジトリにある他のデータコネクタサンプルを調べて、ユースケースに合っているかどうかを確認することもできます。