

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

# 教程：发送 Amazon SNS 通知
<a name="iot-sns-rule"></a>

本教程演示如何创建一条 AWS IoT 规则，将 MQTT 消息数据发送到 Amazon SNS 主题，以便可以将其作为 SMS 短信发送。

在本教程中，您将创建一条规则，以在温度超过规则中设置的值时将消息数据从天气传感器发送到 Amazon SNS 主题的所有订阅者。当报告的温度超过规则设置的值时，规则会检测到，并创建一个新的消息有效载荷，其中仅包含设备 ID、报告的温度和超出的温度限制。规则将新消息有效载荷作为 JSON 文档发送到 SNS 主题，该主题会通知 SNS 主题的所有订阅者。

**您将在本教程中学到的内容：**
+ 如何创建和测试 Amazon SNS 通知
+ 如何根据规则调用 Amazon SNS 通知 AWS IoT 
+ 如何在规则查询语句中使用简单的 SQL 查询和函数
+ 如何使用 MQTT 客户端测试规则 AWS IoT 

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

**Topics**
+ [步骤 1：创建 Amazon SNS 主题，发送 SMS 文本消息](#iot-sns-rule-create-sns-topic)
+ [步骤 2：创建发送短信的 AWS IoT 规则](#iot-sns-rule-create-rule)
+ [第 3 步：测试 AWS IoT 规则和 Amazon SNS 通知](#iot-sns-rule-test-rule)
+ [步骤 4：查看结果和后续步骤](#iot-sns-rule-review-results)

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

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

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

**审核 [Amazon Simple Notification Service](https://docs.aws.amazon.com//sns/latest/dg/welcome.html)**  
如果您以前未使用过 Amazon SNS，请查看 [设置 Amazon SNS 的访问权限](https://docs.aws.amazon.com//sns/latest/dg/sns-setting-up.html)。如果您已经完成了其他 AWS IoT 教程，则 AWS 账户 应该已经正确配置了您的教程。

## 步骤 1：创建 Amazon SNS 主题，发送 SMS 文本消息
<a name="iot-sns-rule-create-sns-topic"></a>

此步骤说明如何创建您的天气传感器可以向其发送消息数据的 Amazon SNS 主题。然后，Amazon SNS 主题将通过 SMS 文本消息通知所有订阅者已超过温度限制。

**创建发送 SMS 文本消息的 Amazon SNS 主题**

1. **创建 Amazon SNS 主题。**

   1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com//sns/home)。

   1. 在左侧导航窗格中，选择**主题**。

   1. 在 **Topics**（主题）页面上，选择 **Create topic**（创建主题）。

   1. 在 **Details**（详细信息）中，选择 **Standard**（标准）类型。默认情况下，控制台会创建 FIFO 主题。

   1. 在 **Name**（名称）中，输入 SNS 主题名称。在本教程中，请输入 **high\_temp\_notice**。

   1. 滚动到页面底部，然后选择 **Create topic**（创建主题）。

      控制台会打开新主题的**详细信息**页面。

1. **创建 Amazon SNS 订阅。**
**注意**  
您将在本教程中发送的消息可能会使您在此订阅中使用的电话号码产生短信费用。

   1. 在 **high\_temp\_notice** 主题详细信息页面上，选择 **Create subscription**（创建订阅）。

   1. 在 **Create subscripition**（创建订阅），在 **Details**（详细信息）部分中，在 **Protocol**（协议）列表中，选择 **SMS**。

   1. 在 **Endpoint**（端点）中，输入可接收文本消息的电话号码。请务必输入号码，以 `+` 开头，包含国家和地区代码，并且不包括任何其它标点符号字符。

   1. 选择 **Create subscription**（创建订阅）。

1. **测试 Amazon SNS 通知。**

   1. 在 [Amazon SNS 控制台](https://console.aws.amazon.com//sns/home)中，左侧导航窗格内，选择 **Topics**（主题）。

   1. 要打开主题的详细信息页面，请在 **Topics**（主题），在主题列表中，选择 **high\_temp\_notice**。

   1. 打开 **Publish message to topic**（将消息发布到主题）页面中的 **high\_temp\_notice**详细信息页面，选择 **Publish message**（发布消息）。

   1. 在 **Publish message to topic**（将消息发布到主题），在 **Message body**（消息正文）部分，**Message body to send to the endpoint**（要发送到端点的消息正文）中，输入一条简短的消息。

   1. 滚动到页面底部并选择 **Publish message**（发布消息）。

   1. 在使用您之前创建订阅时使用的号码的电话上，确认已收到消息。

   如果您没有收到测试消息，请仔细检查电话号码和手机的设置。

   确保您可以从 [Amazon SNS 控制台](https://console.aws.amazon.com//sns/home)发布测试消息，然后继续本教程。

## 步骤 2：创建发送短信的 AWS IoT 规则
<a name="iot-sns-rule-create-rule"></a>

您将在本教程中创建的 AWS IoT 规则订阅了 `device/{{device_id}}/data` MQTT 主题，其中`{{device_id}}`是发送消息的设备的 ID。这些主题在主题筛选条件中描述为 `device/+/data`，其中，`+` 是匹配两个正斜杠字符之间的任何字符串的通配符。此规则还测试消息有效载荷中的 `temperature` 字段值。

当规则收到来自匹配主题的消息时，它会从主题名称中取 `{{device_id}}`，从消息有效载荷中取 `temperature` 值，并为正在测试的限制添加一个常量值，并将这些值作为 JSON 文档发送到 Amazon SNS 通知主题。

 例如，来自气象传感器设备编号 32 的 MQTT 消息使用 `device/32/data` 主题，并具有如下所示的消息有效载荷：

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

规则的规则查询语句从消息有效载荷中取 `temperature` 值，从主题名称中取 `{{device_id}}`，并添加常量 `max_temperature` 值以向 Amazon SNS 主题发送类似于以下内容的消息有效载荷：

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

**创建用于检测超限温度值的 AWS IoT 规则并创建要发送至 Amazon SNS 主题的数据**

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

1. 如果这是您的第一条规则，请选择 **Create**（创建），或者 **Create a rule**（创建规则）。

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

   1. 在 **Name**（名称）中，输入 **temp\_limit\_notify**。

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

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

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

1. 在 **Create a rule**（创建规则）的 **Rule query statement**（规则查询语句）中：

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

   1. 在 **Rule query statement**（规则查询语句）编辑框中，输入语句：

      ```
      SELECT topic(2) as device_id, 
          temperature as reported_temperature, 
          30 as max_temperature 
        FROM 'device/+/data' 
        WHERE temperature > 30
      ```

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

1. 要打开此规则的规则操作列表，请在 **Set one or more actions**（设置一个或多个操作）中，选择 **Add action**（添加操作）。

1. 在 **Select an action**（选择操作）页面上，选择 **Send a message as an SNS push notification**（将消息发送为 SNS 推送通知）。

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

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

   1. 在 **SNS target**（SNS target）中，选择 **Select**（选择），找到您名为 **high\_temp\_notice** 的 SNS 主题，然后选择 **Select**（选择）。

   1. 对于 **Message format**（消息格式），请选择 **RAW**。

   1. 在**选择或创建角色以授予执行此操作的 AWS IoT 访问权限**中，选择**创建角色**。

   1. 在 **Create a new role**（创建新角色）中，**Name**（名称）项下，输入新角色的唯一名称。在本教程中，请使用 **sns\_rule\_role**。

   1. 选择**创建角色**。

   如果要重复本教程或重复使用现有角色，请选择 **Update role**（更新角色）然后再继续。这将更新角色的策略文档，以便与 SNS 目标配合使用。

1. 选择 **Add action**（添加操作），然后返回到 **Create a rule**（创建规则）页。

   在新操作的磁贴中，在 **Send a message as an SNS push notification**（将消息作为 SNS 推送通知发送）项下，您可以看到规则将调用的 SNS 主题。

   这是您将添加到此规则的唯一规则操作。

1. 要创建规则并完成此步骤，请在 **Create a rule**（创建规则）中，向下滚动到底部，然后选择 **Create rule**（创建规则）。

## 第 3 步：测试 AWS IoT 规则和 Amazon SNS 通知
<a name="iot-sns-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/\+/data**。

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

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

      在 **Subscriptions**（订阅）栏，在 **Publish to a topic**（发布到主题）项下，将会显示 **device/\+/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. 选择 **Publish to topic**（发布到主题）以发布您的 MQTT 消息。

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

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

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

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

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

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

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

      请注意，`device_id` 值是一个带引号的字符串，`temperature` 值为数字。这是因为 [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic)函数从输入消息的主题名称中提取字符串，而 `temperature`值使用输入消息负载中的数值。

      如果您想使 `device_id`值为数值，请在规则查询语句中将 `topic(2)`替换为：

      ```
      cast(topic(2) AS DECIMAL)
      ```

      请注意，将 `topic(2)` 值设置为数字，`DECIMAL` 值仅在主题的该部分仅包含数字字符时才起作用。

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 消息，请选择**发布到主题**。

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

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

### 对 SNS 消息规则进行故障排除
<a name="iot-sns-rule-trouble"></a>

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

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

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

**要检查的事项**
  + 

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

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

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

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

**要检查的事项**
  + 

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

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

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

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

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

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

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

**在规则操作中检查重新发布的消息主题**  
重新发布规则操作向其发布新消息的主题必须与您在 MQTT 客户端中订阅的主题匹配。

    在控制台中打开您创建的规则，然后检查规则操作将重新发布消息的主题。
  + 

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

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

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

## 步骤 4：查看结果和后续步骤
<a name="iot-sns-rule-review-results"></a>

**在本教程中：**
+ 您创建并测试了 Amazon SNS 通知主题和订阅。
+ 您在规则查询语句中使用了简单 SQL 查询和函数来为您的通知创建新消息。
+ 您创建了使用您的自定义消息负载发送 Amazon SNS 通知的 AWS IoT 规则。
+ 您使用 MQTT 客户端来测试您的 AWS IoT 规则。

**后续步骤**  
使用此规则发送了几条文本消息后，请尝试使用它来了解更改教程的某些方面如何影响消息以及发送消息的时间。以下想法可以帮助您开始操作。
+ 更改输入消息主题{{device\_id}}中的内容，并观察短信内容中的效果。
+ 更改规则查询语句中选定的字段，并观察文本消息内容中的效果。
+ 将规则查询语句中的测试更改为测试最低温度而不是最高温度。记得更改 `max_temperature` 名称！
+ 添加重新发布规则操作，以便在发送 SNS 通知时发送 MQTT 消息。
+ 尝试本系列中的下一个教程，了解如何 [教程：将设备数据存储在 DynamoDB 表中](iot-ddb-rule.md)。