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

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

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

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

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

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

注記

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    次の例では、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は Timestream テーブルで項目を識別できるように、外部 ID としてコンポーネントタイプに追加されます。

  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データポイントが表示されるはずです。

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

データコネクタの改善

例外処理

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 サンプル内のコンポーネントタイプ定義を確認できます。コンポーネントタイプがコンポーネントによって一度使用されると、そのコンポーネントタイプのプロパティ定義と関数は更新できません。

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

AWS IoT TwinMaker との統合テストを実施して、データプレーンクエリが機能することを確認することをお勧めします end-to-end。GetPropertyValueHistoryAPI を使用して実行することも、AWS IoT TwinMaker コンソールで簡単に実行することもできます

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

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

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

次のステップ

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