

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# AWS IoT SiteWise 使用 AWS IoT Core 规则提取数据
<a name="iot-rules"></a>

使用中的规则将数据 AWS IoT SiteWise 从 AWS IoT 事物和其他 AWS 服务发送到 AWS IoT Core。规则转换 MQTT 消息并执行与 AWS 服务交互的操作。 AWS IoT SiteWise 规则操作将消息数据从 AWS IoT SiteWise API 转发给[BatchPutAssetPropertyValue](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_BatchPutAssetPropertyValue.html)操作。有关更多信息，请参阅 *AWS IoT 开发人员指南*中的[规则](https://docs.aws.amazon.com/iot/latest/developerguide/iot-rules.html)和 [AWS IoT SiteWise 操作](https://docs.aws.amazon.com/iot/latest/developerguide/iot-rule-actions.html#iotsitewise-rule)。

如要按照教程逐步完成设置规则来通过设备影子摄取数据的步骤，请参阅[从事物中摄 AWS IoT SiteWise 取 AWS IoT 数据](ingest-data-from-iot-things.md)。

您也可以将数据从发送 AWS IoT SiteWise 到其他 AWS 服务。有关更多信息，请参阅 [与其他 AWS 服务互动](interact-with-other-services.md)。

**Topics**
+ [

# 授 AWS IoT 予所需的访问权限
](grant-rule-access.md)
+ [

# 配置 AWS IoT SiteWise 规则操作
](configure-rule-action.md)
+ [

# 使用 Basic Ingest in 降低成本 AWS IoT SiteWise
](basic-ingest-rules.md)

# 授 AWS IoT 予所需的访问权限
<a name="grant-rule-access"></a>

您可以使用 IAM 角色来控制每条规则可以访问的 AWS 资源。在创建规则之前，您必须创建一个 IAM 角色，其策略允许该规则对所需 AWS 资源执行操作。 AWS IoT 在运行规则时担任此角色。

如果您在 AWS IoT 控制台中创建规则操作，则可以选择根资产来创建有权访问所选资产层次结构的角色。有关如何为规则手动定义角色的更多信息，请参阅《*AWS IoT 开发人员指南 AWS IoT *[》中的授予所需访问](https://docs.aws.amazon.com/iot/latest/developerguide/iot-create-role.html)[权限和传递角色权限](https://docs.aws.amazon.com/iot/latest/developerguide/pass-role.html)。

对于 AWS IoT SiteWise 规则操作，您必须定义一个允许`iotsitewise:BatchPutAssetPropertyValue`访问规则向其发送数据的资产属性的角色。为了提高安全性，您可以在`Condition`属性中指定 AWS IoT SiteWise 资产层次结构路径。

以下示例信任策略允许访问特定资产及其子级。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iotsitewise:BatchPutAssetPropertyValue",
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "iotsitewise:assetHierarchyPath": [
            "/root node asset ID",
            "/root node asset ID/*"
          ]
        }
      }
    }
  ]
}
```

------

从该策略中删除 `Condition`，以便于访问您的所有资产。以下示例信任策略允许访问您在当前区域中的所有资产。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iotsitewise:BatchPutAssetPropertyValue",
      "Resource": "*"
    }
  ]
}
```

------

# 配置 AWS IoT SiteWise 规则操作
<a name="configure-rule-action"></a>

 AWS IoT SiteWise 规则操作将启动规则的 MQTT 消息中的数据发送到中的资产属性。 AWS IoT SiteWise您可以同时将多个数据条目上传到不同的资产属性，以便在一条消息中发送设备的所有传感器的更新。您还可以为每个数据条目一次上传多个数据点。

**注意**  
当您 AWS IoT SiteWise 使用规则操作向发送数据时，您的数据必须满足`BatchPutAssetPropertyValue`操作的所有要求。例如，您的数据的时间戳不能早于当前 Unix 纪元时间 7 天。有关更多信息，请参阅[使用 AWS IoT SiteWise API 提取数据]()。

对于规则操作中的每个数据条目，您可以标识资产属性，并为该资产属性指定每个数据点的时间戳、质量和值。规则操作要求所有参数均为字符串。

要在条目中标识资产属性，可以指定以下项之一：
+ **资产 ID** (`assetId`) 和 **属性 ID** (`propertyId`)，这是您要将数据发送到的资产属性的值。您可以使用 AWS IoT SiteWise 控制台查找资产 ID 和属性 ID。如果您知道资产 ID，则可以使用 to call AWS CLI [DescribeAsset](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAsset.html)来查找资产 ID。
+ **属性别名** (`propertyAlias`)，这是一个数据流别名（例如，`/company/windfarm/3/turbine/7/temperature`）。要使用此选项，您必须首先设置资产属性的别名。要了解如何设置属性别名，请参阅[管理数据流 AWS IoT SiteWise](manage-data-streams.md)。

对于每个条目中的时间戳，使用设备报告的时间戳或 AWS IoT Core提供的时间戳。时间戳有两个参数：
+ **时间（以秒为单位）**(`timeInSeconds`) – 传感器或设备报告数据的 Unix 纪元时间（以秒为单位）。
+ **偏移量（以纳秒为单位）**(`offsetInNanos`) –（可选）以秒为单位的时间的纳秒偏移量。

**重要**  
如果您的时间戳是一个字符串、包含小数部分或不是以秒为单位，则 AWS IoT SiteWise 会拒绝该请求。您必须将时间戳转换为秒和纳秒偏移量。使用 AWS IoT 规则引擎的功能来转换时间戳。有关更多信息，请参阅下列内容：  
[获取未报告准确时间的设备的时间戳](#rule-timestamp-function)
[转换字符串格式的时间戳](#rule-time-to-epoch-function)

在执行计算、调用函数以及从消息负载中提取值的操作中，您可以为多个参数使用替换模板。有关更多信息，请参阅 *AWS IoT 开发人员指南*中的[替换模板](https://docs.aws.amazon.com/iot/latest/developerguide/iot-substitution-templates.html)。

**注意**  <a name="substitution-template-limitations"></a>
由于替换模板中的表达式与 `SELECT` 语句分开评估，因此您不能使用替换模板来引用使用 `AS` 子句创建的别名。除了支持的函数和运算符之外，您只能引用原始负载中存在的信息。

**Topics**
+ [

## 获取未报告准确时间的设备的时间戳
](#rule-timestamp-function)
+ [

## 转换字符串格式的时间戳
](#rule-time-to-epoch-function)
+ [

## 转换纳秒精度的时间戳字符串
](#rule-convert-precise-timestamp-string)
+ [

## 示例规则配置
](#rule-action-examples)
+ [

## 规则操作问题排查
](#troubleshoot-rule-action)

## 获取未报告准确时间的设备的时间戳
<a name="rule-timestamp-function"></a>

如果您的传感器或设备未报告准确的时间数据，请使用 time [stamp () 从 AWS IoT 规则引擎获取当前 Unix 纪元时间](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-functions.html#iot-function-timestamp)。此函数以毫秒为单位输出时间，因此您必须将值转换为以秒为单位的时间，并将偏移量转换为以纳秒为单位。为此，请使用以下转换：
+ 对于 **时间 (以秒为单位)** (`timeInSeconds`)，使用 **\$1\$1floor(timestamp() / 1E3)\$1** 将时间从毫秒转换为秒。
+ 对于 **偏移量 (以纳秒为单位)** (`offsetInNanos`)，使用 **\$1\$1(timestamp() % 1E3) \$1 1E6\$1** 计算时间戳的纳秒偏移量。

## 转换字符串格式的时间戳
<a name="rule-time-to-epoch-function"></a>

如果您的传感器或设备以字符串格式报告时间数据（例如，`2020-03-03T14:57:14.699Z`），请使用 [time\$1to\$1epoch(String, String)](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-time-to-epoch)。此函数将时间戳和格式模式作为参数输入，并以毫秒为单位输出时间。然后，您必须将时间转换为以秒为单位的时间和以纳秒为单位的偏移量。为此，请使用以下转换：
+ 对于**时间（以秒为单位）**(`timeInSeconds`)，使用 **\$1\$1floor(time\$1to\$1epoch("2020-03-03T14:57:14.699Z", "yyyy-MM-dd'T'HH:mm:ss'Z'") / 1E3)\$1** 将时间戳字符串转换为毫秒，然后转换为秒。
+ 对于**偏移量（以纳秒为单位）**(`offsetInNanos`)，使用 **\$1\$1(time\$1to\$1epoch("2020-03-03T14:57:14.699Z", "yyyy-MM-dd'T'HH:mm:ss'Z'") % 1E3) \$1 1E6\$1** 计算时间戳字符串的纳秒偏移量。

**注意**  
`time_to_epoch` 函数支持高达毫秒精度的时间戳字符串。要转换精度为微秒或纳秒的字符串，请配置一个 AWS Lambda 函数，您的规则会调用该函数将时间戳转换为数值。有关更多信息，请参阅 [转换纳秒精度的时间戳字符串](#rule-convert-precise-timestamp-string)。

## 转换纳秒精度的时间戳字符串
<a name="rule-convert-precise-timestamp-string"></a>

如果您的设备以精度为纳秒的字符串格式发送时间戳信息（例如 `2020-03-03T14:57:14.699728491Z`），请使用以下过程配置规则操作。你可以创建一个 AWS Lambda 函数，将时间戳从字符串转换为以**秒为单位的时间** (`timeInSeconds`) 和以 **nanos 为单位的偏移量** (`offsetInNanos`)。然后，在规则操作参数中使用 [aws\$1lambda(functionArn, inputJson)](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-functions.html#iot-func-aws-lambda)，在规则中调用该 Lambda 函数并使用输出。

**注意**  
本节包含高级说明（假设您已熟悉如何创建以下资源）：  
Lambda 函数。有关更多信息，请参阅《AWS Lambda 开发人员指南》**中的[创建第一个 Lambda 函数](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html)。
AWS IoT 带有规则操作的 AWS IoT SiteWise 规则。有关更多信息，请参阅 [AWS IoT SiteWise 使用 AWS IoT Core 规则提取数据](iot-rules.md)。

**创建解析时间戳字符串的 AWS IoT SiteWise 规则操作**

1. 创建具有以下属性的 Lambda 函数：
   + **函数名称** – 使用描述性函数名称（例如 **ConvertNanosecondTimestampFromString**）。
   + **运行时** – 使用 Python 3 运行时，如 **Python 3.11**（`python3.11`）。
   + **权限**-创建具有基本 Lambda 权限的角色 () **AWS LambdaBasicExecutionRole**。
   + **图层** — 添加 **AWS SDKPandas-Python311 层**以供 Lambda 函数使用。`numpy`
   + **函数代码** – 使用以下函数代码，该函数使用名为 `timestamp` 的字符串参数，并为该时间戳输出 `timeInSeconds` 和 `offsetInNanos` 值。

     ```
     import json
     import math
     import numpy
     
     # Converts a timestamp string into timeInSeconds and offsetInNanos in Unix epoch time.
     # The input timestamp string can have up to nanosecond precision.
     def lambda_handler(event, context):
         timestamp_str = event['timestamp']
         # Parse the timestamp string as nanoseconds since Unix epoch.
         nanoseconds = numpy.datetime64(timestamp_str, 'ns').item()
         time_in_seconds = math.floor(nanoseconds / 1E9)
         # Slice to avoid precision issues.
         offset_in_nanos = int(str(nanoseconds)[-9:])
         return {
             'timeInSeconds': time_in_seconds,
             'offsetInNanos': offset_in_nanos
         }
     ```

     [此 Lambda 函数使用来自 datetime64 输入 [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) 格式的时间戳字符串。](https://numpy.org/doc/stable/reference/arrays.datetime.html) NumPy
**注意**  
如果您的时间戳字符串不是 ISO 8601 格式，则可以使用定义时间戳格式的 pandas 实施解决方案。有关更多信息，请参阅 [pandas.to\$1datetime](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_datetime.html)。

1. 为规则配置 AWS IoT SiteWise 操作时，请使用以下替换模板来替换**时间（以秒**为单位`timeInSeconds`）和以**纳为单位的偏移量**（`offsetInNanos`）。这些替换模板假定您的消息负载包含 `timestamp` 格式的时间戳字符串。`aws_lambda` 函数为其第二个参数使用 JSON 结构，因此您可以根据需要修改以下替换模板。
   + 对于 **时间 (以秒为单位)** (`timeInSeconds`)，请使用以下替换模板。

     ```
     ${aws_lambda('arn:aws:lambda:region:account-id:function:ConvertNanosecondTimestampFromString', {'timestamp': timestamp}).timeInSeconds}
     ```
   + 对于以 **偏移量 (以纳秒为单位)** (`offsetInNanos`)，请使用以下替换模板。

     ```
     ${aws_lambda('arn:aws:lambda:region:account-id:function:ConvertNanosecondTimestampFromString', {'timestamp': timestamp}).offsetInNanos}
     ```

   对于每个参数，将*region*和*account-id*替换为您的地区和 AWS 账户 ID。如果您为 Lambda 函数使用了不同的名称，请相应更改。

1. 授予使用该 AWS IoT 权限调用您的函数的`lambda:InvokeFunction`权限。有关更多信息，请参阅 [aws\$1lambda(functionArn, inputJson)](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-functions.html#iot-func-aws-lambda)。

1. 测试您的规则（例如，使用 AWS IoT MQTT 测试客户端），并验证它 AWS IoT SiteWise 接收了您发送的数据。

   如果您的规则未按预期工作，请参阅 [对 AWS IoT SiteWise 规则操作进行故障排除](troubleshoot-rule.md)。

**注意**  
此解决方案为每个时间戳字符串调用 Lambda 函数两次。如果您的规则处理各个负载中具有相同时间戳的多个数据点，则可以创建另一个规则来减少 Lambda 函数的调用次数。  
为此，请使用重新发布操作创建规则，该操作会调用 Lambda 并发布原始负载，其中时间戳字符串转换为 `timeInSeconds` 和 `offsetInNanos`。然后，创建一个带有规则操作的 AWS IoT SiteWise 规则，以消耗转换后的有效负载。使用这种方法，您可以减少规则调用 Lambda 的次数，但可以增加规则操作的 AWS IoT 运行次数。如果将此解决方案应用于您的使用案例，请考虑每项服务的定价。

## 示例规则配置
<a name="rule-action-examples"></a>

本节包含用于创建带有 AWS IoT SiteWise 操作的规则的示例规则配置。

**Example 使用属性别名作为消息主题的示例规则操作**  
以下示例创建了一个规则，其 AWS IoT SiteWise 操作使用主题（通过 topi [c ()](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-functions.html#iot-function-topic)）作为属性别名来标识资产属性。使用此示例定义一条规则，用于将双类型数据摄取到所有风电场中的所有风力涡轮机。此示例要求您为所有涡轮机资产的属性定义属性别名。您需要定义另一个类似的规则来摄取整数型数据。  

```
aws iot create-topic-rule \
  --rule-name SiteWiseWindFarmRule \
  --topic-rule-payload file://sitewise-rule-payload.json
```
`sitewise-rule-payload.json` 中的示例负载包含以下内容。  

```
{
  "sql": "SELECT * FROM '/company/windfarm/+/turbine/+/+' WHERE type = 'double'",
  "description": "Sends data to the wind turbine asset property with the same alias as the topic",
  "ruleDisabled": false,
  "awsIotSqlVersion": "2016-03-23",
  "actions": [
    {
      "iotSiteWise": {
        "putAssetPropertyValueEntries": [
          {
            "propertyAlias": "${topic()}",
            "propertyValues": [
              {
                "timestamp": {
                  "timeInSeconds": "${timeInSeconds}"
                },
                "value": {
                  "doubleValue": "${value}"
                }
              }
            ]
          }
        ],
        "roleArn": "arn:aws:iam::account-id:role/MySiteWiseActionRole"
      }
    }
  ]
}
```
通过此规则操作，将以下消息作为主题发送到风力涡轮机属性别名（例如 `/company/windfarm/3/turbine/7/temperature`），用于摄取数据。  

```
{
  "type": "double",
  "value": "38.3",
  "timeInSeconds": "1581368533"
}
```

**Example 使用 timestamp() 确定时间的示例规则操作**  
以下示例创建了一个规则，其 AWS IoT SiteWise 操作通过标识资产属性 IDs 并使用 [timestamp ()](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-functions.html#iot-function-timestamp) 来确定当前时间。  

```
aws iot create-topic-rule \
  --rule-name SiteWiseAssetPropertyRule \
  --topic-rule-payload file://sitewise-rule-payload.json
```
`sitewise-rule-payload.json` 中的示例负载包含以下内容。  

```
{
  "sql": "SELECT * FROM 'my/asset/property/topic'",
  "description": "Sends device data to an asset property",
  "ruleDisabled": false,
  "awsIotSqlVersion": "2016-03-23",
  "actions": [
    {
      "iotSiteWise": {
        "putAssetPropertyValueEntries": [
          {
            "assetId": "a1b2c3d4-5678-90ab-cdef-22222EXAMPLE",
            "propertyId": "a1b2c3d4-5678-90ab-cdef-33333EXAMPLE",
            "propertyValues": [
              {
                "timestamp": {
                  "timeInSeconds": "${floor(timestamp() / 1E3)}",
                  "offsetInNanos": "${(timestamp() % 1E3) * 1E6}"
                },
                "value": {
                  "doubleValue": "${value}"
                }
              }
            ]
          }
        ],
        "roleArn": "arn:aws:iam::account-id:role/MySiteWiseActionRole"
      }
    }
  ]
}
```
使用此规则操作，您可以向 `my/asset/property/topic` 发送以下消息以摄取数据。  

```
{
  "type": "double",
  "value": "38.3"
}
```

## 规则操作问题排查
<a name="troubleshoot-rule-action"></a>

要对中的 AWS IoT SiteWise 规则操作进行故障排除 AWS IoT Core，请为您的规则配置 CloudWatch 日志或配置重新发布错误操作。有关更多信息，请参阅 [对 AWS IoT SiteWise 规则操作进行故障排除](troubleshoot-rule.md)。

# 使用 Basic Ingest in 降低成本 AWS IoT SiteWise
<a name="basic-ingest-rules"></a>

AWS IoT Core 提供了一项名为 Basic Ingest 的功能，您可以使用该功能发送数据， AWS IoT Core 而不会产生[AWS IoT 消息传](https://aws.amazon.com/iot-core/pricing/)送费用。Basic Ingest 通过从摄取路径中移除 publish/subscribe 消息代理来优化大容量数据摄取工作负载的数据流。如果您知道消息应该路由到哪些规则，则可以使用“基本提取”。

要使用基本提取，您可以使用特殊主题 `$aws/rules/rule-name`，直接将消息发送到特定规则。例如，要向名为 `SiteWiseWindFarmRule` 的规则发送消息，您可以向主题 `$aws/rules/SiteWiseWindFarmRule` 发送消息。

如果您的规则操作使用包含 [topic(Decimal)](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-functions.html#iot-function-topic) 的替换模板，则可以在“基本提取”特殊主题的末尾传递原始主题，例如 `$aws/rules/rule-name/original-topic`。例如，要将基本提取与之前部分中的风电场属性别名示例结合使用，您可以向以下主题发送消息。

```
$aws/rules/SiteWiseWindFarmRule//company/windfarm/3/turbine/7/temperature
```

**注意**  
上面的示例包含第二个斜杠 (`//`)，因为从规则操作可见的主题中 AWS IoT 删除了 Basic Ingest 前缀 (`$aws/rules/rule-name/`)。在此示例中，规则接收主题 `/company/windfarm/3/turbine/7/temperature`。

有关更多信息，请参阅 *AWS IoT 开发人员指南*中的[借助基本摄取功能降低消息收发成本](https://docs.aws.amazon.com/iot/latest/developerguide/iot-basic-ingest.html)。