亚马逊AWS官方博客

使用 AWS IoT TwinMaker 构建 IoT 设备的数字孪生并监控实时传感器数据(第 2 部分,共 2 部分)

这篇博文是该系列的第二篇博文,介绍如何使用  AWS IoT TwinMaker 创建 Raspberry Pi 设备(该设备连接到收集温度和湿度数据的传感器)的数字孪生,并将它与  Amazon Managed Grafana 控制面板集成。这可让用户可视化数字孪生与收集到的数据所在的 3D 环境,从而实时影响设备状态和 3D 模型表示。

第 1 部分中,我们提出了这个观点并介绍了总体架构(如下所示)。如果您已完成第 1 部分中的操作,则已配置完托管数据的 Amazon Timestream 数据库、IoT 事物的设置以及收集温度和湿度数据并将该数据传输到 Raspberry Pi 设备的传感器的接线。

图 1:解决方案的高级架构
图 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(创建工作区)。使用 TempHumidTwinmaker 作为 Grafana 工作区的名称,也可以选择提供描述。选择 Next(下一步)。

在 Step 2 Configure Settings(步骤 2 配置设置)中,从 Authentication access(身份验证访问)部分中选择 AWS IAM Identity Center (successor to AWS SSO)(AWS IAM Identity Center(AWS SSO 的后继产品))。对于 Permission Type(权限类型),选择 Service managed(服务托管)。请注意,如果这是您首次配置 SSO,则可能需要创建用户。

选择 Next(下一步),并保留下一页上的默认值(当前账户,而不选择任何数据源)。 选择 Next(下一步),然后选择 Create 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]

图 2:Amazon Managed Grafana 工作区已准备就绪。IAM 角色显示在右上角
图 2:Amazon Managed Grafana 工作区已准备就绪。IAM 角色显示在右上角

接下来,创建将访问控制面板的用户。

如果您已在 AWS 账户中执行这些操作,则可以跳过此步骤。否则,请从控制台搜索栏中选择 AWS IAM Identity Center (successor to AWS SSO)(AWS IAM Identity Center(AWS SSO 的后继产品)),然后选择 Users → Add user(用户 → 添加用户)。输入您的用户名,选择所需的密码获取方式,输入您的电子邮件地址以及您的名字和姓氏。

选择 Next(下一步),通过选择 Next(下一步)跳过 Groups(组)部分(因为您不希望将此用户分配给一个或多个组),然后选择 Add user(添加用户)来进行确认。系统将向您指定的电子邮件地址发送一封邀请电子邮件,您需要接受邀请才能访问 AWS SSO 门户。接受邀请后,您将需要更改密码,具体取决于您在创建用户时选择的设置。

返回 Amazon Managed Grafana 工作区,选择 Authentication(身份验证)部分,然后在 AWS IAM Identity Center (successor to AWS SSO)(AWS IAM Identity Center(AWS SSO 的后继产品)部分中配置用户和用户组。选择您刚刚创建的用户,然后选择 Assign users and groups(分配用户和组)。

图 3:将用户分配给 Amazon Managed Grafana 工作区
图 3:将用户分配给 Amazon Managed Grafana 工作区

现在,您的一个用户已具有对您在本博文结尾创建的控制面板的访问权限。您需要将其设置为管理员,使其能够在 Amazon Managed Grafana 中更改设置并使用 AWS IoT TwinMaker 插件。为此,请选择该用户,并选择 Make Admin(授予管理员权限)按钮。

图 4:将您的用户设为管理员
图 4:将您的用户设为管理员

2.创建 Lambda 函数以从 Amazon Timestream 中读取数据

接下来,您将需要创建一个 Lambda 函数来从 Amazon Timestream 数据库中检索数据。在创建 AWS IoT TwinMaker 组件时,此 Lambda 函数将在 AWS IoT TwinMaker 中使用。

首先,创建 Lambda 函数访问 Amazon Timestream 和 Amazon CloudWatch Logs 所需的 IAM role(IAM 角色)。 从控制台中打开 IAM 服务,然后移至 Roles(角色)。选择 Create Role(创建角色)。选择 AWS Service(AWS 服务)作为可信实体类型,然后从 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(创建函数)。

图 5:创建 Lambda 函数以从 Amazon Timestream 读取数据
图 5:创建 Lambda 函数以从 Amazon Timestream 读取数据

创建函数后,移至 Configuration(配置)部分,并在 General configuration(常规配置)中,将内存更改为 256 MB,并将超时更改为 15 分钟。请记住进行保存

还是在 Configuration(配置)部分中,选择 Environment variables(环境变量),然后添加以下两个环境变量:

  • 键:TIMESTREAM_DATABASE_NAME,值 TempHumidityDatabase
  • 键:TIMESTREAM_TABLE_NAME,值 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

注意:此代码包含对 ‘[ENTITY_ID]’ 的引用,它是代表您的传感器的 TwinMaker 实体的 ID。您将在下一节中创建此 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(创建新的 S3 存储桶)。从 Execution Role(执行角色)下拉列表中,选择您在上一步中创建的 TwinMakerWorkspaceRole 角色。 选择 Next(下一步)。

图 6:创建 AWS IoT TwinMaker 工作区
图 6:创建 AWS IoT TwinMaker 工作区

现在,您将参考之前创建的 Grafana 控制面板。在 Dashboard management(控制面板管理)页面中,选择 Amazon Managed Grafana。从 Grafana authentication provider(Grafana 身份验证提供商)下拉列表中,选择之前创建的 Grafana 服务角色 – 具有 AmazonGrafanaServiceRole-[1234abc] 这样的名称的 Grafana 服务角色。 单击 Next(下一步)。

在 Dashboard(控制面板)角色页面中,将 No video permissions(无视频权限)保持选中状态。您将创建一个 IAM 策略和角色,供控制面板用来访问 AWS IoT TwinMaker 工作区的 Amazon S3 存储桶和资源。复制页面中提供的策略代码,然后单击 Create Policy in IAM(在 IAM 中创建策略)。

图 7:创建 Amazon Managed Grafana 控制面板角色和策略
图 7:创建 Amazon Managed Grafana 控制面板角色和策略

在新页面中,选择 JSON 选项卡并粘贴您刚刚复制的策略的代码。依次选择 Next (Tags)(下一步(标签))和 Next (Review)(下一步(查看))。 将此策略命名为 TempHumidWorkspaceDashboardPolicy,并选择 Create Policy(创建策略)。

返回 AWS IoT TwinMaker 工作区创建页面,然后选择 Create dashboard role in IAM(在 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 工作区创建页面,然后从列表中选择您刚刚创建的控制面板角色。如果未立即显示它,请选择刷新按钮。

接下来,复制 Update dashboard role policy(更新控制面板角色策略)选项卡中提供的代码。您将在刚刚创建的 TwinMakerDashboardRole 中应用此策略。选择 Update trust policy in IAM(在 IAM 中更新信任策略),粘贴代码以替换已存在的内容,从而在角色中应用信任策略。 这样您就更改了过于宽松的权限,仅将其应用于特定的 AWS 主体,即 Amazon Managed Grafana 使用的服务角色。选择 Update Policy(更新策略)。

图 8:创建 Amazon Managed Grafana 控制面板角色和策略(续)图 8:创建 Amazon Managed Grafana 控制面板角色和策略(续)

完成后,返回 AWS IoT TwinMaker 工作区创建页面,并依次选择 Next(下一步)和 Create Workspace(创建工作区)。

图 9:查看 Amazon Managed Grafana 工作区创建
图 9:查看 Amazon Managed Grafana 工作区创建

现在,您已准备好 AWS IoT TwinMaker 工作区,并拥有在 Grafana 控制面板中使用它所需的所有权限。

创建 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(添加组件)。

图 10:创建 AWS IoT TwinMaker 实体
图 10:创建 AWS IoT TwinMaker 实体

选择类型 com.blog.DHT11sensor 并为该组件命名。您将在表中看到组件的属性(如温度和湿度)。完成后,选择 Add component(添加组件)。

图 11:将 AWS IoT TwinMaker 组件添加到实体
图 11:将 AWS IoT TwinMaker 组件添加到实体

创建 AWS IoT TwinMaker 资源和场景

接下来,导入 3D 模型以表示虚拟环境中的设备或传感器。AWS IoT TwinMaker 支持各种文件,例如 BIN、GLB、GLTF、PNG、PDF、JPG、JPEG 和 MP4。在此情况下中,使用了 Raspberry Pi4 模型。您应能够在 CGTraderSketchfab 或 TurboSquid 等网站上找到免费模型。

选择工作区后,转到 Resource library(资源库),选择 Add resources(添加资源)并上传您的文件。

图 12:上传 3D 模型
图 12:上传 3D 模型

最后,您将设置您的场景。选择工作区后,转至 Scenes(场景)并选择 Create scene(创建场景)。为其指定一个 ID(名称),然后选择 Create scene(创建场景)。创建完后,您将看到一个包含 3 个主要部分的视图(见以下屏幕截图)。左侧是一个包含 3 个选项卡的部分:

  • Hierarchy(层次结构):您在场景中拥有的对象
  • Rules(规则):如何根据收到的数据更改场景中的项目(我们将在本练习中使用它)
  • Settings(设置)

在中心部分,有一个包含 3D world(3D 世界)的部分,可以将视图四处移动、平移、缩放、倾斜等。在右侧,有一个包含 Inspector(检查器)的部分,可在其中查看场景中的选定内容的详细信息。

图 13:AWS IoT TwinMaker 场景的 UI
图 13:AWS IoT TwinMaker 场景的 UI

首先,您将为场景中的项目创建规则。选择左侧面板上的 Rules(规则)部分,然后选中已存在的规则。创建两个新规则,一个用于湿度数据,另一个用于温度数据。将 temperatureIconRule 定义为 RuleID,并选择 Add New Rule(添加新规则)。选择规则,并单击 Add new statement(添加新语句)以定义一些表达式,使目标图标从 Info(信息)变为 Warning(警告),再变为 Error(错误),如下所示。

重要说明:确保您编写的表达式将使用与您用来命名属性(来自传感器并存储在数据库中)的完全相同的词(即“温度”和“湿度”)。

图 14:使您的标签根据收到的数据更改颜色或图标的规则
图 14:使您的标签根据收到的数据更改颜色或图标的规则

创建温度规则后,重复相同的过程来添加新的湿度规则。

接下来,添加 3D 模型。在屏幕的中央部分,单击 + 图标并选择 Add 3d model(添加 3D 模型),并从资源库中选择您之前上传的 3D 对象。

图 15:将 3D 模型添加到场景
图 15:将 3D 模型添加到场景

加载后,您可以使用右侧面板中的 Transform(转换)部分缩放模型。最有可能的情况是,一旦您将对象添加到场景中,对象就会变暗。要解决此问题,您可以单击 Settings(设置)并选择 Environmental Preset(环境预置)来调整灯光效果。添加灯光的另一种方法是单击 + 图标并选择 Add light(添加灯光)。然后,您可以选择它并用鼠标将它四处移动,从而照亮场景和导入的 3D 模型。

图 16:确保您的模型有适当的灯光效果
图 16:确保您的模型有适当的灯光效果

最后,您将添加一个标记来处理湿度和温度数据,并确保收到的内容将影响场景中显示的内容。单击 + 图标并选择 Add tag(添加标记)。使用检查器部分,将其名称定义为温度并选择 Default Icon(默认图标)。选择您的实体作为 EntityId,并选择您的组件作为 ComponentName。选择温度作为 PropertyName,并选择 temperatureIconRule 作为 RuleId。重复同一操作,为湿度创建新标记,其中湿度作为 PropertyNamehumidityIconRule 作为 RuleId

注意:移动两个标记使其靠近 3D 模型,但足够远,以使它们在场景中可见。

图 17:在场景中放置标记
图 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 工作区 URL)页面中提供的链接访问 Amazon Managed Grafana 工作区。 在配置 AWS IAM Identity Center(AWS SSO 的后继产品)时,系统会要求您使用设置的凭证进行访问。由于您的用户已设为管理员,因此,您应能够访问 Amazon Managed Grafana 设置页面。

首先,您需要添加 AWS IoT TwinMaker 数据源。为此,请转至 Configuration(配置),选择 Add data source(添加数据源),然后搜索 TwinMaker 并选择 AWS IoT TwinMaker

图 18:将 AWS IoT TwinMaker 配置为控制面板的数据源
图 18:将 AWS IoT TwinMaker 配置为控制面板的数据源

然后,确保数据源 Settings(设置)中的所有 Connection Details(连接详细信息)正确。这包括身份验证提供商和 AWS IoT TwinMaker 为访问控制面板和 AWS 区域而代入的角色(TwinMakerDashboardRole)的 ARN。这里还配置了 AWS IoT TwinMaker 工作区。

图 19:连接详细信息
图 19:连接详细信息

选择 Save & Test(保存并测试)以验证 Grafana 和 AWS IoT TwinMaker 工作区之间的连接是否设置正确。

然后,转至控制面板创建操作。在左边栏中,单击 Create → Dashboard(创建 → 控制面板)。  首先,我们将添加一个空面板。选择 Add a new panel(添加新面板)。

在右侧,选择要使用的可视化类型。在搜索栏中,键入 TwinMaker,然后选择 AWS IoT TwinMaker Scene Viewer(AWS IoT TwinMaker 场景查看器)。使用屏幕右部分中的控件为该面板命名,然后选择 AWS IoT TwinMaker 工作区和场景。您的 3D 模型将显示在预览中。

图 20:将 AWS IoT TwinMaker 场景查看器添加到控制面板
图 20:将 AWS IoT TwinMaker 场景查看器添加到控制面板

现在,请确保定义控制面板中显示的内容与您的数据之间已建立连接。为此,请创建两个查询,一个用于温度数据,另一个用于湿度数据。这两个查询将使用您创建的 AWS IoT TwinMaker 组件,该组件反过来使用 Lambda 函数从 Timestream 数据库中读取数据。

在查询部分中,确保选择 AWS IoT TwinMaker 作为数据源,并定义一个类型为 Get Property Value History by Entity(按实体获取属性值历史记录)的新查询。选择您的实体(TempHumiditySensor)和组件(DHTComponent),然后选择 temperature 属性。重复同一操作,添加具有相同类型和相同实体与组件的新查询,但这一次选择 humidity 属性。完成后,保存面板,然后依次单击 Apply(应用)和 Save(保存)。

图 21:使用组件读取数据所需的查询
图 21:使用组件读取数据所需的查询

除了 AWS IoT TwinMaker 面板之外,您还可以创建其他面板来以各种可视化格式(例如,仪表时间序列)表示您的数据,以显示您的温度和湿度数据。您将需要配置相同的查询机制,确保您能够检索数据。每个面板左上角的红色小角会在组件读取数据过程出现问题时通知您。在此情况下,它只是提醒我们没有数据传入 – 那是因为您还没有在 Raspberry Pi 中启动 python 脚本来将数据发送到云。

图 22:向控制面板添加面板
图 22:向控制面板添加面板

5.最终结果

如果您现在在 Raspberry Pi 设备中重新启动 Python 脚本,则您应能够看到控制面板的面板中填入的温度和湿度数据。由于您已在 AWS IoT TwinMaker 工作区中定义规则,因此,只要收到的温度或湿度数据高于/低于您的规则中定义的阈值,与控制面板中表示的实体关联的标记(两个蓝色点)将更改标记(信息、警告、错误)或颜色(如果您定义了基于颜色的规则)。

图 23:最终结果。温度标记显示警告图标,因为规则中定义的阈值为 23°
图 23:最终结果。温度标记显示警告图标,因为规则中定义的阈值为 23°

清理

如果您遵循此解决方案,请完成以下步骤,避免您的 AWS 账户产生不必要的费用。

AWS IoT Core

  • 在 Manage → All devices(管理 → 所有设备)中,删除事物和事物类型。
  • 在 Manage→ Security(管理 → 安全)部分中,删除策略和证书。
  • 在 Manage → Message Routing(管理 → 消息路由)部分中,清理规则。

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 示例项目。另外,请访问 AWS 上的物联网 – 官方博客以了解有关 AWS IoT TwinMaker 的更多信息,或参阅我们的客户使用它构建了什么


关于作者

Angelo Postiglione 是 AWS 的解决方案架构师。他与意大利的医疗保健客户和合作伙伴合作,帮助他们采用云技术,使用 AWS 构建可扩展且安全的解决方案。闲暇时,他喜欢探索世界上的新地方,在大自然中远足,弹吉他和打鼓。