

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 設定 AWS IoT SiteWise 規則動作
<a name="configure-rule-action"></a>

 AWS IoT SiteWise 規則動作會從啟動規則的 MQTT 訊息，將資料傳送至其中的資產屬性 AWS IoT SiteWise。您可以同時將多個資料項目上傳至不同的資產屬性，以一則訊息傳送裝置所有感應器的更新。您也可以針對每個資料項目一次上傳多個資料點。

**注意**  
當您 AWS IoT SiteWise 使用規則動作將資料傳送至 時，您的資料必須符合`BatchPutAssetPropertyValue`操作的所有要求。例如，您的資料的時間戳記不能早於目前 Unix epoch 時間的 7 天。如需詳細資訊，請參閱[使用 AWS IoT SiteWise API 導入資料]()。

針對規則動作中的每個資料項目，您需要識別資產屬性並指定時間戳記、品質，以及該資產屬性的每個資料點的值。規則動作預期會接受所有參數的字串。

若要識別項目中的資產屬性，請指定下列其中一個項目：
+ 您要傳送資料到其中的資產屬性的 **Asset ID (資產 ID)** (`assetId`) 和 **Property ID (屬性 ID)** (`propertyId`)。您可以使用 尋找資產 ID 和屬性 ID AWS IoT SiteWise 主控台。如果您知道資產 ID，您可以使用 AWS CLI 呼叫 [DescribeAsset](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAsset.html) 來尋找屬性 ID。
+ **Property alias (屬性別名)** (`propertyAlias`)，這是資料串流別名 (例如 `/company/windfarm/3/turbine/7/temperature`)。若要使用這個選項，您必須先設定您的資產屬性別名。若要了解如何設定屬性別名，請參閱[管理 的資料串流 AWS IoT SiteWise](manage-data-streams.md)。

對於每個項目中的時間戳記，請使用設備報告的時間戳記或 提供的時間戳記 AWS IoT Core。時間戳記有兩個參數：
+ 以**秒為單位的時間** (`timeInSeconds`) – 感應器或設備報告資料的 Unix epoch 時間，以秒為單位。
+ **以奈米為單位的位移** (`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>

如果您的感應器或設備未報告準確的時間資料，請從具有 [timestamp()](https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-functions.html#iot-function-timestamp) 的 AWS IoT 規則引擎取得目前的 Unix epoch 時間。此函數會以毫秒為單位輸出時間，因此您必須將值轉換為以秒為單位的時間，並以奈秒為單位偏移。若要這樣做，請使用下列轉換：
+ 針對 **Time in seconds (以秒為單位的時間)** (`timeInSeconds`)，使用 **\$1\$1floor(timestamp() / 1E3)\$1** 將時間從毫秒轉換為秒。
+ 針對 **Offset in nanos (以奈米為單位的位移)** (`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`) 和以**奈米為單位的位移 **()`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**) 的角色。
   + **Layers** – 新增 **AWS SDKPandas-Python311** layer，讓 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 函數會使用 NumPy 中的 [datetime64](https://numpy.org/doc/stable/reference/arrays.datetime.html)，以 [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) 格式輸入時間戳記字串。
**注意**  
如果您的時間戳記字串不是 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 結構，因此您可視需要修改以下替代範本。
   + 針對 **Time in seconds (以秒為單位的時間)** (`timeInSeconds`)，使用以下替代範本。

     ```
     ${aws_lambda('arn:aws:lambda:region:account-id:function:ConvertNanosecondTimestampFromString', {'timestamp': timestamp}).timeInSeconds}
     ```
   + 針對 **Offset in nanos (以奈米為單位的位移)** (`offsetInNanos`)，使用以下替代範本。

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

   對於每個參數，請將 *region* 和 *account-id* 取代為您的 region 和 AWS account 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 動作的規則，該動作使用 主題 （透過 [topic()](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 Logs 或為您的規則設定重新發佈錯誤動作。如需詳細資訊，請參閱[對 AWS IoT SiteWise 規則動作進行故障診斷](troubleshoot-rule.md)。