

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

# 教程：使用 AWS Lambda 函数格式化通知
<a name="iot-lambda-rule"></a>

本教程演示如何将 MQTT 消息数据发送到 AWS Lambda 操作以进行格式化并发送到其他 AWS 服务。在本教程中， AWS Lambda 操作使用 AWS 软件开发工具包将格式化的消息发送到您在教程中创建的有关如何操作的 Amazon SNS 主题。[教程：发送 Amazon SNS 通知](iot-sns-rule.md)

在有关如何 [教程：发送 Amazon SNS 通知](iot-sns-rule.md) 的教程中，则由规则的查询语句生成的 JSON 文档将作为文本消息的正文发送。结果是一条文本消息，示例如下：

```
{"device_id":"32","reported_temperature":38,"max_temperature":30}
```

在本教程中，您将使用 AWS Lambda 规则操作来调用一个 AWS Lambda 函数，该函数将规则查询语句中的数据格式化为更友好的格式，例如以下示例：

```
Device 32 reports a temperature of 38, which exceeds the limit of 30.
```

您将在本教程中创建的 AWS Lambda 函数使用规则查询语句中的数据格式化消息字符串，并调用 [S AWS DK 的 SNS 发布](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sns.html#SNS.Client.publish)函数来创建通知。

**在本教程中您将学到**
+ 如何创建和测试 AWS Lambda 函数
+ 如何在 AWS Lambda 函数中使用 AWS 软件开发工具包发布 Amazon SNS 通知
+ 如何在规则查询语句中使用简单的 SQL 查询和函数
+ 如何使用 MQTT 客户端测试规则 AWS IoT 

完成本教程需要大约 45 分钟。

**Topics**
+ [

## 步骤 1：创建发送短信的 AWS Lambda 函数
](#iot-lambda-rule-create-lambda)
+ [

## 步骤 2：使用 AWS IoT 规则操作创建 AWS Lambda 规则
](#iot-lambda-rule-create-rule)
+ [

## 步骤 3：测试 AWS IoT 规则和 AWS Lambda 规则操作
](#iot-lambda-rule-test-rule)
+ [

## 步骤 4：查看结果和后续步骤
](#iot-lambda-rule-next-steps)

**在开始本教程之前，请确保您具有：**
+ 

**[设置 AWS 账户](setting-up.md)**  
你需要你的 AWS 账户 和 AWS IoT 主机才能完成本教程。
+ 

**审核 [使用 MQTT 客户端查看 AWS IoT MQTT 消息](view-mqtt-messages.md)**  
请确保您可以使用 MQTT 客户端订阅和发布主题。您将使用 MQTT 客户端在此流程中测试新规则。
+ 

**完成本部分中的其它规则教程**  
本教程需要您在如何 [教程：发送 Amazon SNS 通知](iot-sns-rule.md) 的教程中创建的 SNS 通知主题。本教程还假定您已完成本部分中其它与规则相关的教程。
+ 

**审核 [AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html)概览**  
如果您 AWS Lambda 以前从未使用过，请查看[AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html)并[开始使用 Lambda](https://docs.aws.amazon.com//lambda/latest/dg/getting-started.html)，以了解其术语和概念。

## 步骤 1：创建发送短信的 AWS Lambda 函数
<a name="iot-lambda-rule-create-lambda"></a>

本教程中的 AWS Lambda 函数接收规则查询语句的结果，将元素插入文本字符串，然后将生成的字符串作为通知中的消息发送到 Amazon SNS。

与使用 AWS IoT 规则操作发送通知的操作方法教程不同，本教程使用软件开发工具包的函数从 Lambda 函数发送通知。[教程：发送 Amazon SNS 通知](iot-sns-rule.md) AWS 但是，本教程中使用的实际 Amazon SNS 通知主题与您在有关如何 [教程：发送 Amazon SNS 通知](iot-sns-rule.md) 的教程中使用的主题相同。

**创建发送短信的 AWS Lambda 函数**

1. 创建新 AWS Lambda 函数。

   1. 在 [AWS Lambda 控制台](https://console.aws.amazon.com//lambda/home)中，选择 **Create function**（创建函数）。

   1. 在 **Create function**（创建函数）中，选择 **Use a blueprint**（使用蓝图）。

      搜索并选择 **hello-world-python** 蓝图，然后选择**配置**。

   1. 在 **Basic information**（基本信息）中：

      1. 在 **Function name**（函数名称）中，输入函数的名称，**format-high-temp-notification**。

      1. 在**执行角色**中，选择**从 AWS 策略模板创建新角色**。

      1. 在 Role name（角色名称）中，为新角色输入名称，**format-high-temp-notification-role**。

      1. 在**策略模板 - *可选***中，搜索并选择 **Amazon SNS 发布策略**。

      1. 选择 **Create function**（创建函数）。

1. 修改蓝图代码以格式化并发送 Amazon SNS 通知。

   1. 创建函数后，您应该会看到**format-high-temp-notification**详细信息页面。如果您不这样做，请从 [Lambda **Functions**](https://console.aws.amazon.com//lambda/home#/functions)（Lambda 函数）页打开它。

   1. 在**format-high-temp-notification**详细信息页面中，选择**配置**选项卡，然后滚动到**函数代码**面板。

   1. 在 **Function code**（函数代码）窗口中的 **Environment**（环境）窗格中，选择 Python 文件，`lambda_function.py`。

   1. 在 **Function code**（函数代码）窗口中，从蓝图中删除所有原始程序代码，并将其替换为此代码。

      ```
      import boto3
      #
      #   expects event parameter to contain:
      #   {
      #       "device_id": "32",
      #       "reported_temperature": 38,
      #       "max_temperature": 30,
      #       "notify_topic_arn": "arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice"
      #   }
      # 
      #   sends a plain text string to be used in a text message
      #
      #      "Device {0} reports a temperature of {1}, which exceeds the limit of {2}."
      #   
      #   where:
      #       {0} is the device_id value
      #       {1} is the reported_temperature value
      #       {2} is the max_temperature value
      #
      def lambda_handler(event, context):
      
          # Create an SNS client to send notification
          sns = boto3.client('sns')
      
          # Format text message from data
          message_text = "Device {0} reports a temperature of {1}, which exceeds the limit of {2}.".format(
                  str(event['device_id']),
                  str(event['reported_temperature']),
                  str(event['max_temperature'])
              )
      
          # Publish the formatted message
          response = sns.publish(
                  TopicArn = event['notify_topic_arn'],
                  Message = message_text
              )
      
          return response
      ```

   1. 选择 **Deploy**（部署）。

1. 在新窗口中，从关于如何 [教程：发送 Amazon SNS 通知](iot-sns-rule.md) 的教程中查找 Amazon SNS 主题的 Amazon 资源名称（ARN）。

   1. 在新窗口中，打开 [Topics page of the Amazon SNS console](https://console.aws.amazon.com//sns/v3/home#/topics)（Amazon SNS 控制台主题页面）。

   1. 在**主题**页面上，在 Amazon SNS 主题列表中找到 **high\$1temp\$1notice** 通知主题。

   1. 查找 **high\$1temp\$1notice** 通知主题的 **ARN**，以在下一步中使用。

1. 为您的 Lambda 函数创建一个测试使用案例。

   1. 在控制台的 [Lambda F **un**](https://console.aws.amazon.com//lambda/home#/functions) ctions 页面的**format-high-temp-notification**详细信息页面上，**选择页面右上角的选择测试事件**（尽管它看起来已禁用），然后选择**配置测试**事件。

   1. 在 **Configure test event**（配置测试事件）中，选择 **Create new test event**（创建新测试事件）。

   1. 在 **Event name**（事件名称）中，输入 **SampleRuleOutput**。

   1. 在 **Event name**（事件名称）下方的 JSON 编辑器中，请粘贴此示例 JSON 文档。这是您的 AWS IoT 规则将向 Lambda 函数发送的内容的示例。

      ```
      {
        "device_id": "32",
        "reported_temperature": 38,
        "max_temperature": 30,
        "notify_topic_arn": "arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice"
      }
      ```

   1. 请参阅具有 **high\$1temp\$1notice**通知主题的 **ARN** 的窗口并复制 ARN 值。

   1. 在 JSON 编辑器中将 `notify_topic_arn` 值替换成您通知主题中的 ARN。

      保持此窗口打开状态，以便在创建 AWS IoT 规则时再次使用该 ARN 值。

   1. 选择 **Choose**（创建）。

1. 使用示例数据测试函数。

   1. 在页面右上角的**format-high-temp-notification**详细信息页面中，确认**SampleRuleOutput**显示在 “**测试**” 按钮旁边。如果没有，请从可用测试事件列表中选择它。

   1. 要将示例规则输出消息发送到您的函数，请选择 **Test**（测试）。

如果函数和通知都有效，您将在订阅通知的手机上收到一条文本消息。

如果您在手机上没有收到文本消息，请检查操作结果。在 **Function code**（函数代码）面板中的 **Execution result**（执行结果）选项卡上，查看响应以查找发生的任何错误。请勿继续执行下一步，直到您的函数可以将通知发送到您的手机。

## 步骤 2：使用 AWS IoT 规则操作创建 AWS Lambda 规则
<a name="iot-lambda-rule-create-rule"></a>

在此步骤中，您将使用规则查询语句格式化来自虚拟气象传感器设备的数据，以发送到 Lambda 函数，该函数将格式化并发送文本消息。

从天气设备接收的示例消息有效载荷如下所示：

```
{
  "temperature": 28,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

在此规则中，您将使用规则查询语句为 Lambda 函数创建消息有效载荷，如下所示：

```
{
  "device_id": "32",
  "reported_temperature": 38,
  "max_temperature": 30,
  "notify_topic_arn": "arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice"
}
```

这包含 Lambda 函数格式化和发送正确文本消息所需的所有信息。

**创建调用 Lambda 函数的 AWS IoT 规则**

1. 打开[AWS IoT 控制台的 “**规则**” 中心](https://console.aws.amazon.com//iot/home#/rulehub)。

1. 要在 **Rule**（规则）中创建新规则，请选择 **Create**（创建）。

1. 在 **Create a rule**（创建规则）顶部：

   1. 在 **Name**（名称）中，输入规则的名称，**wx\$1friendly\$1text**。

      请记住，规则名称在您的 AWS 账户 和区域内必须是唯一的，并且不能有任何空格。我们在此名称中使用了下划线字符来分隔规则名称中的两个单词。

   1.  在 **Description**（说明）中，描述规则。

      有意义的描述可以更容易地记住此规则的作用以及您创建它的原因。描述可以根据需要延长，因此请尽可能详细。

1. 在**创建规则**的**规则查询语句**中：

   1.  在**使用 SQL 版本**中，选择 **2016-03-23**。

   1. 在**规则查询语句**编辑框中，输入语句：

      ```
      SELECT 
        cast(topic(2) AS DECIMAL) as device_id, 
        temperature as reported_temperature,
        30 as max_temperature,
        'arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice' as notify_topic_arn
      FROM 'device/+/data' WHERE temperature > 30
      ```

      本语句：
      + 侦听主题与 `device/+/data`主题筛选条件相符，并且 `temperature`值大于 30 的 MQTT 消息。
      + 从主题字符串中选择第二个元素，将其转换为十进制数，然后将其分配给 `device_id` 字段。
      + 从消息有效载荷中选择 `temperature` 字段的值，并将其分配给 `reported_temperature` 字段。
      + 创建常数值 `30` 来表示限制值，并将其赋值给 `max_temperature` 字段。
      + 为 `notify_topic_arn` 字段创建常数值。

   1. 请参阅具有 **high\$1temp\$1notice** 通知主题的 **ARN** 的窗口并复制 ARN 值。

   1. 将规则查询语句编辑器中的 ARN 值 (*arn:aws:sns:us-east-1:57EXAMPLE833:high\$1temp\$1notice*) 替换为通知主题的 ARN。

1. 在**设置一个或多个操作**中：

   1. 要打开此规则的规则操作列表，请选择 **Add action**（添加操作）。

   1. 在 **Select an action**（选择操作）中，选择 **Send a message to a Lambda function**（向 Lambda 函数发送消息）。

   1. 要打开选定操作的配置页面，请在操作列表底部选择 **Configure action**（配置操作）。

1. 在 **Configure action**（配置操作）中：

   1. 在 **Function name**（函数名称）中，选择 **Select**（选择）。

   1. 选择 **format-high-temp-notification**。

   1. 在 **Configure action**（配置操作）底部，选择 **Add action**（添加操作）。

   1. 要创建规则，请在 **Create a rule**（创建一条规则）底部，选择 **Create rule**（创建规则）。

## 步骤 3：测试 AWS IoT 规则和 AWS Lambda 规则操作
<a name="iot-lambda-rule-test-rule"></a>

要测试新规则，您将使用 MQTT 客户端发布和订阅此规则所使用的 MQTT 消息。

在新窗口中打开 [AWS IoT 控制台中的 MQTT 客户端](https://console.aws.amazon.com//iot/home#/test)。现在，您可以在不丢失 MQTT 客户端配置的情况下编辑规则。如果您离开 MQTT 客户端并转到控制台中的其它页面，则将丢失您的订阅或消息日志。

**如需使用 MQTT 客户端来测试您的规则**

1. 在 [AWS IoT 控制台中的 MQTT 客户端](https://console.aws.amazon.com//iot/home#/test)中，订阅输入主题，在本例中为 `device/+/data`。

   1. 在 MQTT 客户端中，在**订阅**下，选择**订阅主题**。

   1. 在**订阅主题**中，输入输入主题筛选条件的主题，**device/\$1/data**。

   1. 将其它字段保留为默认设置。

   1. 选择**订阅主题**。

      在 **Subscriptions**（订阅）栏，在 **Publish to a topic**（发布到主题）项下，将会显示 **device/\$1/data**。

1. 使用特定设备 ID **device/32/data**向输入主题发布消息。您无法发布到包含通配符的 MQTT 主题。

   1. 在 MQTT 客户端中，在**订阅**下，选择**订阅主题**。

   1. 在**发布**字段中，输入输入主题名称，**device/32/data**。

   1. 复制此处显示的示例数据，然后在主题名称下方的编辑框中粘贴示例数据。

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. 如需发布 MQTT 消息，请选择 **Publish to topic**（发布到主题）。

1. 确认文本消息已发送。

   1. 在 MQTT 客户端的**订阅**下，您之前订阅的主题旁边会有一个绿色圆点。

      绿色圆点表示自上次查看消息以来已收到一条或多条新消息。

   1. 在 **Subscriptions**（订阅）中，选择 **device/\$1/data** 来检查消息负载是否与刚刚发布的内容匹配，如下所示：

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. 检查您用于订阅 SNS 主题的电话，并确认消息负载的内容，如下所示：

      ```
      Device 32 reports a temperature of 38, which exceeds the limit of 30.
      ```

      如果您更改消息主题中的主题 ID 元素，请记住，将 `topic(2)` 值投射为数字值仅在消息主题中的元素仅包含数字字符时才起作用。

1. 尝试发送温度未超过限制的 MQTT 消息。

   1. 在 MQTT 客户端中，在 **Subscriptions**（订阅）项下，选择 **Subscribe to a topic**（订阅主题）。

   1. 在**发布**字段中，输入输入主题名称，**device/33/data**。

   1. 复制此处显示的示例数据，然后在主题名称下方的编辑框中粘贴示例数据。

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. 要发送您的 MQTT 消息，请选择 **Publish to topic**（发布到主题）。

   您应在 **device/\$1/data** 订阅中看到您发送的消息；但是，由于温度值低于规则查询语句中的最大温度，因此您不应收到文本消息。

   如果您未看到正确的行为，请检查故障排除提示。

### 对您的 AWS Lambda 规则和通知进行故障排除
<a name="iot-lambda-rule-troubleshoot"></a>

如果您没有看到期望的结果，可以检查以下事项。
+ 

**您收到了一个错误的广告条**  
如果在您发布输入消息时出现错误，请先更正该错误。以下步骤可帮助您更正此错误。
+ 

**您未在 MQTT 客户端中看到输入消息**  
每次将输入消息发布到 `device/32/data`主题时，如果您如流程中所述订阅了 `device/+/data`主题筛选条件，则消息应当会在 MQTT 客户端中显示。

**要检查的事项**
  + 

**检查您订阅的主题筛选条件**  
如果您如流程中所述订阅了输入消息主题，则每次发布输入消息时都应看到该输入消息的副本。

    如果没有看到该消息，请检查您订阅的主题名称，并将其与您发布的主题进行比较。主题名称区分大小写，您订阅的主题必须与发布消息负载的主题相同。
  + 

**检查消息发布函数**  
在 MQTT 客户端中，在**订阅**下，选择 **device/\$1/data**，检查发布消息的主题，然后选择**发布到主题**。您应该会看到来自主题下方编辑框中的消息负载出现在消息列表中。
+ 

**您没有收到 SMS 消息**  
要使规则起作用，规则必须具有授权其接收消息和发送 SNS 通知的正确策略，并且必须接收消息。

**要检查的事项**
  + 

**检查您 AWS 区域 的 MQTT 客户端和您创建的规则**  
您在其中运行 MQTT 客户端的控制台必须位于您所创建规则的同一 AWS 区域。
  + 

**检查消息负载中的温度值是否超过测试阈值**  
如果温度值小于或等于 30（如规则查询语句中定义），则规则将不会执行其任何操作。
  + 

**检查规则查询语句中的输入消息主题**  
要使规则起作用，它必须收到一条消息，消息主题名称应与规则查询语句 FROM 子句中的主题筛选条件相匹配。

    检查规则查询语句中主题筛选条件的拼写与 MQTT 客户端中主题的拼写。主题名称区分大小写，消息的主题必须与规则查询语句中的主题筛选条件匹配。
  + 

**检查输入消息负载的内容**  
要使规则起作用，则必须在 SELECT 语句中声明的消息负载中找到数据字段。

    检查规则查询语句 `temperature`字段中的拼写与 MQTT 客户端中消息负载的拼写。字段名称区分大小写，规则查询语句中 `temperature`字段必须与消息负载中的 `temperature`字段相同。

    确保消息负载中的 JSON 文档格式正确。如果 JSON 有任何错误（例如缺少逗号），则规则将无法读取它。
  + 

**查看 Amazon SNS 通知**  
在 [步骤 1：创建 Amazon SNS 主题，发送 SMS 文本消息](iot-sns-rule.md#iot-sns-rule-create-sns-topic)中，请参阅步骤 3，该步骤介绍如何测试 Amazon SNS 通知并测试通知以确保通知有效。
  + 

**检查 Lambda 函数**  
在 [步骤 1：创建发送短信的 AWS Lambda 函数](#iot-lambda-rule-create-lambda) 中，请参阅步骤 5，该步骤介绍如何使用测试数据测试 Lambda 函数并测试 Lambda 函数。
  + 

**检查规则所使用的角色**  
规则操作必须具有接收原始主题和发布新主题的权限。

    授权规则接收消息数据并重新发布的策略特定于所使用的主题。如果更改用于重新发布消息数据的主题，则必须更新规则操作的角色，以更新其策略来匹配当前主题。

    如果怀疑这里出现了问题，请编辑“重新发布”规则操作并创建新角色。规则操作创建的新角色将接收执行这些操作所需的授权。

## 步骤 4：查看结果和后续步骤
<a name="iot-lambda-rule-next-steps"></a>

**在本教程中：**
+ 您创建了一 AWS IoT 条规则来调用 Lambda 函数，该函数使用您的自定义消息负载发送了 Amazon SNS 通知。
+ 您在规则查询语句中使用了简单的 SQL 查询和函数来为 Lambda 函数创建新的消息有效载荷。
+ 您使用 MQTT 客户端来测试您的 AWS IoT 规则。

**后续步骤**  
使用此规则发送了几条文本消息后，请尝试使用它来了解更改教程的某些方面如何影响消息以及发送消息的时间。以下想法可以帮助您开始操作。
+ 更改输入消息主题*device\$1id*中的内容，并观察短信内容中的效果。
+ 更改规则查询语句中选定的字段，更新 Lambda 函数以在新消息中使用这些字段，并观察文本消息内容中的效果。
+ 将规则查询语句中的测试更改为测试最低温度而不是最高温度。更新 Lambda 函数以格式化新消息，并记得更改 `max_temperature` 名称。
+ 要详细了解如何查找在开发和使用 AWS IoT 规则时可能出现的错误，请参阅[监控 AWS IoT](monitoring_overview.md)。