Amazon Web Services ブログ

IoT デバイスのデジタルツインを構築し、AWS IoT TwinMaker を使用してリアルタイムのセンサーデータを監視する (パート 2/2)

このブログは、*Angelo Postiglione* によって書かれた、Build a digital twin of your IoT device and monitor real-time sensor data using AWS IoT TwinMaker (Part 2 of 2) を翻訳したものです。

イントロダクション

この投稿は、AWS IoT TwinMaker を使用して、温度と湿度のデータを収集するセンサーに接続された Raspberry Pi デバイスのデジタルツインを作成し、それを Amazon Managed Grafana ダッシュボードと統合する方法に関するシリーズのパート 2 です。これにより、デバイスの状態や収集データをもとに、デジタルツインの 3D 環境をリアルタイムに可視化することができます。

パート 1 では、以下に示す一般的なアーキテクチャとともにこの考え方を紹介しました。すでにパート 1 に従っている場合は、データをホストする Amazon Timestream データベースの構成、IoT Thing と、温度と湿度を収集して Raspberry Pi デバイスに送信するセンサーの配線のセットアップは完了しています。


Figure 1: The high-level architecture of the solution
図 1: ソリューションのアーキテクチャの概要

この 2 番目のパートでは、データの視覚化に使用される Amazon Managed Grafana ダッシュボードのセットアップを続けます。AWS Lambda 関数を作成して、Amazon Timestream データベースからデータを読み取ります。最も重要な点としては、AWS IoT TwinMaker をセットアップし、それを Amazon Managed Grafana のダッシュボードと統合して、収集するリアルタイムデータとともに 3D モデルを表示します。

1. Amazon Managed Grafana ダッシュボード ワークスペースのセットアップ

コンソールで、AWS サービスのリストから Amazon Managed Grafana を検索して選択します。Create Workspace を選択します。Grafana ワークスペースの名前として TempHumidTwinmaker を使用し、必要に応じて説明を入力します。Next を選択します。

ステップ 2 設定の構成では、 Authentication access セクションから AWS IAM Identity Center (successor to AWS SSO) を選択します。Permission Type には、Service managed を選択します。初めて SSO を構成する場合は、ユーザーの作成が必要になる場合があることに注意してください。

Next を選択し、次のページでデフォルト (データソースを選択せずに現在のアカウント) のままにします。NextCreate Workspace の順に選択します。

: AWS IoT TwinMaker はデータソースとしてリストされていません。ただし、プラグインはすべての Amazon Managed Grafana ワークスペースに既にインストールされています。後で追加します。

ワークスペースが作成されるまで数分待ちます。Amazon Managed Grafana ワークスペースの準備が整うと、IAM サービスロールが作成されます。ワークスペースを選択すると、Summary タブから表示できるようになります。後で必要になるため、この IAM サービスロールを書き留めておきます。arn:aws:iam::[YOUR-AWS-ACCOUNT-ID]:role/service-role/AmazonGrafanaServiceRole-[1234abcd] のようになります。


Figure 2: The Amazon Managed Grafana workspace is ready. IAM role is displayed in the top right corner
図 2: Amazon Managed Grafana ワークスペースの準備が整いました。 IAM ロールは右上隅に表示されます。

次に、ダッシュボードにアクセスするユーザーを作成します。

AWS アカウントでこれらのアクションをすでに実行している場合は、このステップをスキップできます。それ以外の場合は、コンソールの検索バーから AWS IAM Identity Center (successor to AWS SSO) を選択し、Users → Add user を選択します。ユーザー名を入力し、パスワードの取得方法を選択し、メール アドレスと姓名を入力します。

Next を選択し、Next を選択による Groups セクションをスキップし (このユーザーを 1 つ以上のグループに割り当てたくないため)、Add user を選択して確定します。指定したアドレスに招待メールが届きます。AWS SSO ポータルにアクセスするには、招待を受け入れる必要があります。招待が承認されると、ユーザーの作成時に選択した設定に応じて、パスワードを変更するよう求められます。

Amazon Managed Grafana ワークスペースに戻り、Authentication セクションを選択してから、AWS IAM Identity Center (successor to AWS SSO) セクションで Configure users and user groups を選択します。作成したばかりのユーザーを選択し、Assign users and groups を選択します。


Figure 3: Assign a user to the Amazon Managed Grafana workspace
図 3: ユーザーを Amazon Managed Grafana ワークスペースに割り当てる

これで、この投稿の最後に作成するダッシュボードにアクセスするユーザーができました。Amazon Managed Grafana の設定を変更し、AWS IoT TwinMaker プラグインを使用できるように、管理者にする必要があります。これを行うには、ユーザーを選択し、Make Admin ボタンを選択します。


Figure 4: Making your user an admin
図 4: ユーザーを管理者にする

2. Amazon Timestream からデータを読み取る Lambda 関数の作成

次に、Amazon Timestream データベースからデータを取得するための Lambda 関数を作成する必要があります。この Lambda 関数は、AWS IoT TwinMaker コンポーネントを作成するときに AWS IoT TwinMaker 内で使用されます。

最初に、Lambda 関数が Amazon Timestream および Amazon CloudWatch ログにアクセスするために必要な IAM ロールを作成します。コンソールから IAM サービスを開き、Roles に移動します。Create Role を選択します。Trusted Entity Type として AWS Service を選択し、 Use Case セクションから Lambda を選択します。Nextを選択し、AWSLambdaBasicExecutionRole および AmazonTimestreamReadOnlyAccess アクセス許可ポリシーを追加します。Next を選択し、ロールに ReadTimestreamFromLambda という名前を付けてから、詳細を確認し、Create Role をクリックします。

: このブログでは、AmazonTimestreamReadOnlyAccess ポリシーが使用されました。これにより、Timestream への読み取り操作が許可されます。しかし、ベストプラクティスとしては、作成した TimeStream データベース (およびテーブル) のみに読み取りアクセスを制限することとなっています。

次に、Lambda 関数を作成します。Lambda ホームページから Create function を選択し、Author from scratchオプションを選択します。関数に timestreamReader という名前を付け、ランタイムとして Python 3.7 を選択します。Permissions タブで、「Use an existing role」 を選択し、以前に作成したロール ReadTimestreamFromLambda を選択します。 Create function を選択します。


Figure 5: Creating the Lambda function to read data from Amazon Timestream
図 5: Amazon Timestream からデータを読み取る Lambda 関数の作成

関数が作成されたら、Configuration セクションに移動し、General configuration でメモリを 256 MB に、タイムアウトを 15 分に変更します。忘れずに保存してください。

引き続き Configuration セクションで、Environment variables を選択し、次の 2 つの環境変数を追加します。:

  • Key: TIMESTREAM_DATABASE_NAME, value TempHumidityDatabase
  • Key: TIMESTREAM_TABLE_NAME, value TempHumidity

code セクションに移動します。次の Python コードをコピーして貼り付けます。

import logging
import json
import os
import boto3

from datetime import datetime

LOGGER = logging.getLogger()
LOGGER.setLevel(logging.INFO)

# Get db and table name from Env variables
DATABASE_NAME = os.environ['TIMESTREAM_DATABASE_NAME']
TABLE_NAME = os.environ['TIMESTREAM_TABLE_NAME']

# Python boto client for AWS Timestream
QUERY_CLIENT = boto3.client('timestream-query')


# Utility function: parses a timestream row into a python dict for more convenient field access
def parse_row(column_schema, timestream_row):
    """
    Example:
    column=[
        {'Name': 'TelemetryAssetId', 'Type': {'ScalarType': 'VARCHAR'}},
        {'Name': 'measure_name', 'Type': {'ScalarType': 'VARCHAR'}},
        {'Name': 'time', 'Type': {'ScalarType': 'TIMESTAMP'}},
        {'Name': 'measure_value::double', 'Type': {'ScalarType': 'DOUBLE'}},
        {'Name': 'measure_value::varchar', 'Type': {'ScalarType': 'VARCHAR'}}
    ]
    row={'Data': [
        {'ScalarValue': 'Mixer_15_7e3c0bdf-3b1c-46b9-886b-14f9d0b9df4d'},
        {'ScalarValue': 'alarm_status'},
        {'ScalarValue': '2021-10-15 20:45:43.287000000'},
        {'NullValue': True},
        {'ScalarValue': 'ACTIVE'}
    ]}

    ->

    {
        'TelemetryAssetId': 'Mixer_15_7e3c0bdf-3b1c-46b9-886b-14f9d0b9df4d',
        'measure_name': 'alarm_status',
        'time': '2021-10-15 20:45:43.287000000',
        'measure_value::double': None,
        'measure_value::varchar': 'ACTIVE'
    }
    """
    data = timestream_row['Data']
    result = {}
    for i in range(len(data)):
        info = column_schema[i]
        datum = data[i]
        key, val = parse_datum(info, datum)
        result[key] = val
    return result

# Utility function: parses timestream datum entries into (key,value) tuples. Only ScalarTypes currently supported.
def parse_datum(info, datum):
    """
    Example:
    info={'Name': 'time', 'Type': {'ScalarType': 'TIMESTAMP'}}
    datum={'ScalarValue': '2021-10-15 20:45:25.793000000'}

    ->

    ('time', '2021-10-15 20:45:25.793000000')
    """
    if datum.get('NullValue', False):
        return info['Name'], None
    column_type = info['Type']
    if 'ScalarType' in column_type:
        return info['Name'], datum['ScalarValue']
    else:
        raise Exception(f"Unsupported columnType[{column_type}]")

# This function extracts the timestamp from a Timestream row and returns in ISO8601 basic format
def get_iso8601_timestamp(str):
    #  e.g. '2022-04-06 00:17:45.419000000' -> '2022-04-06T00:17:45.419000000Z'
    return str.replace(' ', 'T') + 'Z'

# Main logic
def lambda_handler(event, context):
    selected_property = event['selectedProperties'][0]

    LOGGER.info("Selected property is %s", selected_property)

    # 1. EXECUTE THE QUERY TO RETURN VALUES FROM DATABASE
    query_string = f"SELECT measure_name, time, measure_value::bigint" \
        f" FROM {DATABASE_NAME}.{TABLE_NAME} " \
        f" WHERE time > from_iso8601_timestamp('{event['startTime']}')" \
        f" AND time <= from_iso8601_timestamp('{event['endTime']}')" \
        f" AND measure_name = '{selected_property}'" \
        f" ORDER BY time ASC"
            
    try:
        query_page = QUERY_CLIENT.query(
            QueryString = query_string
        )
    except Exception as err:
        LOGGER.error("Exception while running query: %s", err)
        raise err

    # Query result structure: https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_Query.html

    next_token = None
    if query_page.get('NextToken') is not None:
       next_token = query_page['NextToken']
    schema = query_page['ColumnInfo']

    # 2. PARSE TIMESTREAM ROWS
    result_rows = []
    for row in query_page['Rows']:
        row_parsed = parse_row(schema,row)
        #LOGGER.info('row parsed: %s', row_parsed)
        result_rows.append(row_parsed)

    # 3. CONVERT THE QUERY RESULTS TO THE FORMAT TWINMAKER EXPECTS

    # There must be one entityPropertyReference for Humidity OR one for Temperature
    entity_property_reference_temp = {}
    entity_property_reference_temp['componentName'] = 'timestream-reader'
    entity_property_reference_temp['propertyName'] = 'temperature’
    entity_property_reference_temp['entityId'] = '[ENTITY_ID]'


    entity_property_reference_hum = {}
    entity_property_reference_hum['componentName'] = 'timestream-reader'
    entity_property_reference_hum['propertyName'] = 'humidity’
    entity_property_reference_hum['entityId'] = '[ENTITY_ID]'


    values_temp = []
    values_hum = []

    for result_row in result_rows:
        ts = result_row['time']
        measure_name = result_row['measure_name']
        measure_value = result_row['measure_value::bigint']

        time = get_iso8601_timestamp(ts)
        value = { 'doubleValue' : str(measure_value) }

        if measure_name == 'temperature':
            values_temp.append({
                'time': time,
                'value':  value
            })
        elif measure_name == 'humidity':
             values_hum.append({
                'time': time,
                'value':  value
            })

    # The final structure "propertyValues"
    property_values = []

    if(measure_name == 'temperature'):
        property_values.append({
            'entityPropertyReference': entity_property_reference_temp,
            'values': values_temp
        })
    elif(measure_name == 'humidity'):
        property_values.append({
            'entityPropertyReference': entity_property_reference_hum,
            'values': values_hum
        })
    LOGGER.info("property_values: %s", property_values)

    # marshall propertyValues and nextToken into final response
    return_obj = {
       'propertyValues': property_values,
       'nextToken': next_token
       }

    return return_obj

: コードには、センサーを表す TwinMaker エンティティの ID である「ENTITY_ID」への参照が含まれています。これは次のセクションで作成しますが、ここではプレースホルダーをコードに残します。

このコードは、Timestream に対する AWS IoT TwinMaker コネクタの実装です。 Lambda 関数をデプロイすることを忘れないでください。

3. AWS IoT TwinMaker の設定

前の段落では、Amazon Managed Grafana ワークスペースと Lambda 関数を作成して設定し、Amazon Timestream データベースからデータを読み取りました。これで、デジタルツインの構成に移ることができます。

AWS IoT TwinMaker で使用される IAM ポリシーとロールを設定する

コンソールから IAM サービスを選択し、Roles に移動します。 Create Role を選択します。Custom trust policyを選択し、以下のポリシーを貼り付けます。AWS IoT TwinMaker では、サービスロールを使用して、ユーザーに代わって他のサービスのリソースにアクセスできるようにする必要があります。 Next を選択します。

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

次のステップで、Create Policy を選択すると、新しいタブが開きます。 JSON タブを選択し、次のコードを貼り付けます:

{
"Version": "2012-10-17",
"Statement": [
{
    
    "Action": [
        "iottwinmaker:*", 
        "s3:*", 
        "iotsitewise:*", 
        "kinesisvideo:*"
    ],
    "Resource": [ "*" ],
    "Effect": "Allow"
},
{
    "Action": [   
        "lambda:invokeFunction"
    ],
    "Resource": ["*"],
    "Effect": "Allow"
},
{
    "Condition": {
    "StringEquals": {
        "iam:PassedToService": "lambda.amazonaws.com"
        }
    },
    "Action": ["iam:PassRole"],
    "Resource": ["*"],
    "Effect": "Allow"
}]}

AWS IoT TwinMaker に、Amazon Simple Storage Service (Amazon S3)、AWS IoT SiteWise、および Amazon Kinesis サービスと連携する機能と、Lambda 関数を呼び出してデータベースからデータを読み取る機能を提供します。プロダクション環境では、このポリシーを変更してより制限をかけることができます。

Next(Tags)Next (Review) の順に選択します。このポリシーに TwinMakerWorkspacePolicy という名前を付け、Create Policyを選択します。完了したら、作成していたロールのページに戻り、リストで新しいポリシーを探します。すぐに表示されない場合は、Refresh を選択します。Next を選択し、ロールに TwinMakerWorkspaceRole という名前を付けてから、詳細を確認し、Create Role をクリックします。

AWS IoT TwinMaker ワークスペースを作成する

コンソールから、AWS サービスのリストから AWS IoT TwinMaker を検索して選択します。Create workspaceを選択します。ワークスペースを作成するときは、まずいくつかの基本情報を入力する必要があります。ワークスペース名として「TempHumidWorkspace」と入力し、オプションの説明を挿入します。Amazon S3 バケット ドロップダウンから、Create a new S3 bucket を選択します。Execution Role ドロップダウンから、前の手順で作成した TwinMakerWorkspaceRole ロールを選択します。Next を選択します。


Figure 6: Creating the AWS IoT TwinMaker workspace
図 6: AWS IoT TwinMaker ワークスペースの作成

ここで、前に作成した Grafana ダッシュボードを参照します。Dashboard management ページから、Amazon Managed Grafana を選択します。Grafana authentication provider のドロップダウンから、以前に作成した Grafana サービスロールを選択します。これは、AmazonGrafanaServiceRole-[1234abc] のような名前のものです。Next をクリックします。

Dashboard role ページで、No video permissions を選択したままにします。ダッシュボードが AWS IoT TwinMaker ワークスペースの Amazon S3 バケットとリソースにアクセスするために使用する IAM ポリシーとロールを作成します。ページに表示されたポリシーコードをコピーし、Create Policy in IAM をクリックします。


Figure 7: Creating the Amazon Managed Grafana dashboard role and policy
図 7: Amazon Managed Grafana ダッシュボードのロールとポリシーの作成

新しいページで JSON タブを選択し、コピーしたポリシーのコードを貼り付けます。Next (Tags)Next (Review) の順に選択します。このポリシーに TempHumidWorkspaceDashboardPolicy という名前を付け、Create Policy を選択します。

AWS IoT TwinMaker ワークスペースの作成ページに戻り、Create dashboard role in IAM を選択します。新しいページで、Custom trust policy を選択し、次の信頼ポリシー JSON を貼り付けます:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": { 
                "AWS": "*"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

Next を選択し、作成したばかりの IAM ポリシー (TempHumidWorkspaceDashboardPolicy という名前) を選択します。すぐに表示されない場合は、更新ボタンを選択してください。Next を選択し、このロールに TwinMakerDashboardRole という名前を付けて、Create Role を選択します。信頼ポリシーが過度に寛容であるというアラートを受け取りますが、後で変更します。ここでは、Continue を選択します。

完了したら、AWS IoT TwinMaker ワークスペース作成ページに戻り、作成したばかりのダッシュボードロールをリストから選択します。すぐに表示されない場合は、refresh ボタンを選択してください。

次に、Update dashboard role policy タブにあるコードをコピーします。作成した TwinMakerDashboardRole にこのポリシーを適用します。Update trust policy in IAM を選択し、既存のものを置き換えるコードを貼り付けて、役割に信頼ポリシーを適用します。これにより、Amazon Managed Grafana で使用されるサービスロールである特定の AWS プリンシパルにのみ適用することで、過度に広い権限を変更します。Update Policy を選択します。


Figure 8: Creating the Amazon Managed Grafana dashboard role and policy (continued)図 8: Amazon Managed Grafana ダッシュボードのロールとポリシーの作成 (続き)

完了したら、AWS IoT TwinMaker ワークスペースの作成ページに戻り、NextCreate Workspace の順に選択します。


Figure 9: Review of the Amazon Managed Grafana workspace creation
図 9: Amazon Managed Grafana ワークスペース作成のレビュー

これで、Grafana ダッシュボードから使用するために必要なすべてのアクセス許可を備えた AWS IoT TwinMaker ワークスペースの準備が整いました。

AWS IoT TwinMaker コンポーネントとエンティティを作成する

AWS IoT TwinMaker ワークスペースを選択した状態で、Component types セクションに移動してコンポーネントを作成します。AWS IoT TwinMaker のコンポーネントは、関連付けられたエンティティのプロパティとデータのコンテキストを提供します。デバイスの温度と湿度のデータにアクセスするコンポーネントを作成します。コンポーネントは、AWS IoT TwinMaker ワークスペースと、Timestream データベースから値を読み取るために使用される Lambda 関数との間のリンクになります。

Create component type を選択し、Request セクションに次のコードを貼り付けます。

{
  "workspaceId": "[YOUR_TWINMAKER_WORKSPACE]",
  "isSingleton": false,
  "componentTypeId": "com.blog.DHT11sensor",
  "propertyDefinitions": {
    "humidity": {
      "dataType": {
        "type": "DOUBLE"
      },
      "isTimeSeries": true,
      "isRequiredInEntity": false,
      "isExternalId": false,
      "isStoredExternally": true,
      "isImported": false,
      "isFinal": false,
      "isInherited": false
    },
    "temperature": {
      "dataType": {
        "type": "DOUBLE"
      },
      "isTimeSeries": true,
      "isRequiredInEntity": false,
      "isExternalId": false,
      "isStoredExternally": true,
      "isImported": false,
      "isFinal": false,
      "isInherited": false
    }
  },
  "functions": {
    "dataReader": {
      "implementedBy": {
        "lambda": {
          "arn": "[YOUR_LAMBDA_ARN]"
        },
        "isNative": false
      },
      "isInherited": false
    }
  },
  "creationDateTime": "2022-05-19T14:58:42.140Z",
  "updateDateTime": "2022-05-19T14:58:42.140Z",
  "arn": "arn:aws:iottwinmaker:[YOUR_REGION]:[YOUR_AWS_ACCOUNT]:workspace/[YOUR_TWINMAKER_WORKSPACE]/component-type/com.blog.DHT11sensor",
  "isAbstract": false,
  "isSchemaInitialized": false,
  "status": {
    "state": "ACTIVE",
    "error": {}
    }
  }

重要: [YOUR_TWINMAKER_WORKSPACE]、[YOUR_LAMBDA_ARN]、[YOUR_REGION]、および [YOUR_AWS_ACCOUNT] の間の値を必ず置き換えてください。

準備ができたら、Create component type を選択します。

次に、センサーの Entity を作成します。環境を表すエンティティの構造または階層を作成することもできますが、この場合は簡単にするために、デバイス/センサーを表す単一のエンティティのみが作成されますを作成します。。これを行うには、Entities セクションに移動し、Create entity を選択します。エンティティに名前(TempHumiditySensor など)を付けて、 Create entity を選択します。

重要: このエンティティは、Lambda 関数で使用する必要があるエンティティです。エンティティ ID をコピーし、以前に作成した Lambda 関数にある [ENTITY_ID] を置き換えます。

エンティティのリストからエンティティを選択し、右側の Add component を選択します。


Figure 10: Creating the AWS IoT TwinMaker entity
図 10: AWS IoT TwinMaker エンティティの作成

Type にて、 com.blog.DHT11sensor を選択し、コンポーネントに名前を付けます。コンポーネントのプロパティ (温度や湿度など) がテーブルに表示されます。完了したら、Add component を選択します。


Figure 11: Adding the AWS IoT TwinMaker component to the Entity
図 11: エンティティへの AWS IoT TwinMaker コンポーネントの追加

AWS IoT TwinMaker リソースとシーンを作成する

次に、仮想環境でデバイスまたはセンサーを表す 3D モデルをインポートします。 AWS IoT TwinMaker は、BIN、GLB、GLTF、PNG、PDF、JPG、JPEG、MP4 などのさまざまなファイルをサポートしています。今回はこの場合、Raspberry Pi4 モデルを使用しました。 CGTraderSketchfabTurboSquid などのウェブサイトで無料のモデルを見つけることができるはずです。

ワークスペースを選択した状態で、Resource library に移動し、Add resources を選択してファイルをアップロードします。


Figure 12: Uploading the 3D model
図 12: 3D モデルのアップロード

最後に、シーンをセットアップします。ワークスペースを選択した状態で、Scenes に移動し、Create scene を選択します。ID (名前) を付けて、Create scene を選択します。作成すると、3 つのメイン セクションを含むビューが表示されます (下のスクリーンショットを参照)。左側には、3 つのタブを含むセクションがあります:

  • Hierarchy:シーン内のオブジェクト
  • Rules: 受信したデータに応じてシーン内のアイテムを変更する方法 (この演習で使用します)
  • Settings

中央部分には、3D 空間の表示領域を含むセクションがあり、移動、パン、ズーム、ビューの傾斜などを行うことができます。右側には、Inspector のセクションがあり、シーンで選択されているものの詳細を確認できます。


Figure 13: The UI of the AWS IoT TwinMaker scene
図 13: AWS IoT TwinMaker シーンの UI

シーン内のアイテムのルールを作成することから始めます。左側のパネルで Rules セクションを選択し、既に存在するルールを確認します。湿度データ用と温度データ用の 2 つの新しいルールを作成します。temperatureIconRule を RuleID として定義し、Add New Rule を選択します。ルールを選択し、Add new statement をクリックして、以下に示すように、Target の Icon を Info から Warning や Error に変更する式を定義します。

重要: 記述した式が、センサーから取得され、データベースに格納されたプロパティの名前に使用した正確な単語を使用していることを確認してください (例:「temperature」と「humidity」)。


Figure 14: Rules that will make your tag change color or icon depending on the data received
図 14: 受信したデータに応じてタグの色またはアイコンを変更するルール

温度ルールが完了したら、湿度の新しいルールを追加して同じプロセスを繰り返します。

次に、3D モデルを追加します。画面の中央部分で、+ アイコンをクリックして Add 3d model を選択し、resource library から以前にアップロードした 3d オブジェクトを選択します。


Figure 15: Adding your 3D model to the scene
図 15: 3D モデルをシーンに追加する

読み込まれたら、右側のパネルの Transform セクションでモデルをスケーリングできます。ほとんどの場合、シーンに追加すると、オブジェクトは暗くなります。これを修正するには、Settings をクリックして Environmental Preset を選択することで、照明を調整できます。ライトを追加するもう 1 つの方法は、+ アイコンをクリックして Add light を選択することです。次に、それを選択してマウスで動かし、シーンとインポートされた 3D モデルを照らすことができます。


Figure 16: Make sure your model has proper lighting
図 16: モデルに適切な照明があることを確認する

最後に、湿度と温度のデータを処理する tag を追加し、受信したものがシーンに表示されるものに影響することを確認します。+ アイコンをクリックし、Add tag を選択します。Inspector セクションを使用して、その名前を温度と定義し、Default Icon を選択します。エンティティを EntityId として選択し、コンポーネントを ComponentName として選択します。PropertyName として温度を選択し、RuleId として temperatureIconRuleを選択します。同じアクションを繰り返して、PropertyName に湿気、RuleIdhumidityIconRule を使用して、Humidity の新しいタグを作成します。

: 2 つのタグを 3D モデルの近くに移動しますが、シーン内で見えるように十分に離します。


Figure 17: Positioning tags in the scene
図 17: シーン内のタグの配置

4. AWS IoT TwinMaker プラグインを使用して Amazon Managed Grafana ダッシュボードを作成する

Amazon Managed Grafana でダッシュボードを作成して、デジタルツインとデータを視覚化する準備がようやく整いました。コンソールから、Amazon Managed Grafana を選択してから、Amazon Managed Grafana ワークスペースを選択します。Amazon Managed Grafana workspace URL のページにあるリンクから、Amazon Managed Grafana ワークスペースにアクセスします。AWS IAM Identity Center (AWS SSO の後継) を構成するときに設定した認証情報を使用してアクセスするよう求められます。ユーザーは管理者に設定されているため、Amazon Managed Grafana 設定ページにアクセスできるはずです。

まず、AWS IoT TwinMaker データソースを追加する必要があります。これを行うには、Configuration に移動して Add data source を選択し、TwinMaker を検索して AWS IoT TwinMaker を選択します。


Figure 18: Configure AWS IoT TwinMaker as datasource for your dashboard
図 18: AWS IoT TwinMaker をダッシュボードのデータソースとして設定する

次に、データソースの設定ですべての Connection Details が正しいことを確認します。これには、AWS IoT TwinMaker がダッシュボードと AWS リージョン (TwinMakerDashboardRole) にアクセスするために引き受けるロールの Authentication Provider と ARN が含まれます。ここでは、AWS IoT TwinMaker ワークスペースも構成されています。


Figure 19: Connection details
図 19:Connection Details

Save & Test を選択して、Grafana と AWS IoT TwinMaker ワークスペース間の接続が正しく設定されていることを確認します。

次に、ダッシュボードの作成に移ります。左側のサイドバーから、Create → Dashboard をクリックします。最初に empty panel を追加することから始めます。 Add a new panel を選択します。

右側で、使用するビジュアライゼーションのタイプを選択します。検索バーに TwinMaker と入力し、AWS IoT TwinMaker Scene Viewer を選択します。画面の右側にあるコントロールを使用して、このパネルに名前を付け、AWS IoT TwinMaker ワークスペースとシーンを選択します。 3D モデルがプレビューに表示されます。


Figure 20: Adding AWS IoT TwinMaker Scene Viewer to the dashboard
図 20: AWS IoT TwinMaker Scene Viewer をダッシュボードに追加する

ここで、ダッシュボードに表示されるものとデータの間の接続が定義されていることを確認します。そのためには、温度データ用と湿度用の 2 つのクエリを作成します。これらのクエリは、作成した AWS IoT TwinMaker コンポーネントを使用し、次に Lambda 関数を使用して Timestream データベースから読み取ります。

query セクションで、AWS IoT TwinMaker がデータソースとして選択されていることを確認し、タイプ Get Property Value History by Entity の新しいクエリを定義します。Entity (TempHumiditySensor) と Component (DHTComponent) を選択し、temperature プロパティを選択します。同じ種類の新しいクエリを追加し、同じエンティティとコンポーネントを使用して同じことを繰り返しますが、今回は humidity プロパティを選択します。完了したら、パネルを保存し、ApplySave の順にクリックします。


Figure 21: The query needed to read data with the component
図 21: コンポーネントでデータを読み取るために必要なクエリ

AWS IoT TwinMaker パネルとは別に、GaugeTime series などのさまざまな視覚化形式でデータを表す他のパネルを作成して、温度と湿度のデータを表示することもできます。データを取得できることを確認するには、同じクエリメカニズムを構成する必要があります。各パネルの左上にある小さな赤いコーナーは、コンポーネントの読み取りデータに問題がある場合に通知します。この場合、データが来ていないことを警告するだけです。これは、データをクラウドに送信するために Raspberry Pi で Python スクリプトを開始していないためです。


Figure 22: Adding panels to the dashboard
図 22: ダッシュボードへのパネルの追加

5. 最終結果

Raspberry Pi デバイスで Python スクリプトを再度開始すると、ダッシュボードのパネルに温度と湿度のデータが表示されるはずです。AWS IoT TwinMaker ワークスペースでルールを定義したので、ダッシュボード (2 つの青い点) に表示されるエンティティに関連付けられたタグは、受け取った温度または湿度のデータが、ルールで定義されたしきい値を上回る/下回るときに、アイコン (情報、警告、エラー)、または色ベースのルールを定義する場合は色を変更します。


Figure 23: The final result. Temperature tag is showing a warning icon as the threshold defined in the rule was 23°
図 23: 最終結果。ルールで定義されたしきい値が 23° であるため、温度タグに警告アイコンが表示されます。

クリーンアップ

このソリューションに従った場合は、次の手順を実行して、AWS アカウントに不要な料金が発生しないようにしてください。

AWS IoT Core

  • Manage → All devices にて、Thing と Thing type を削除します。
  • Manage→ Security セクションにて、Policy と Certificate を削除します。
  • Manage → Message Routing セクションにて、Rule をクリーンアップします。

Amazon Timestream

  • テーブルとデータベースを削除します。

Amazon Managed Grafana

  • Amazon Managed Grafana のワークスペースを削除します。

AWS IAM

  • ここまでで作成したロールを削除します。

AWS IoT TwinMaker

  • AWS IoT TwinMaker のワークスペースを削除します。

まとめ

このブログ投稿シリーズでは、Raspberry Pi デバイスと DHT センサーを使用してデジタルツインを作成し、温度と湿度のデータを監視するためのシンプルなエンドツーエンドのソリューションをセットアップする方法を学びました。このソリューションは、最初に MQTT を使用して Raspberry Pi を AWS IoT Core に接続し、続いて AWS IoT ルールを使用してトピックストリームからメッセージを転送し、Amazon Timestream データベースにレコードを配置することによって実現されます。また、AWS IoT TwinMaker を使用してデバイス/センサーのデジタルツインを作成し、Amazon Managed Grafana を使用してリアルタイムのインタラクティブなダッシュボードを構築しました。

多数のデバイスとセンサーを使用し、実際の環境を再現する、より複雑なシナリオを作成できます。より複雑なユースケースについては、AWS IoT TwinMaker Cookie Factory サンプルプロジェクトを確認してください。また、The Internet of Things on AWS – Official Blog にアクセスして、AWS IoT TwinMaker の詳細を確認したり、お客様がそれを使用して構築したものを確認したりしてください。


About the author

Angelo Postiglioneは、AWS のソリューションアーキテクトです。彼はイタリアのヘルスケアの顧客やパートナーと協力して、AWS を使用してスケーラブルで安全なソリューションを構築するためにクラウド技術を採用するのを支援しています。余暇には、世界の新しい場所を発見したり、自然の中で長い散歩をしたり、ギターやドラムを演奏したりするのが好きです。

このブログは、ソリューションアーキテクトの戸塚智哉が翻訳しました。