

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

# 在设备处于离线状态时使用设备影子保持设备状态
<a name="iot-shadows-tutorial"></a>

这些教程向您展示了 AWS IoT 如何使用 Device Shadow 服务来存储和更新设备的状态信息。影子文档是 JSON 文档，根据设备、本地应用程序或服务发布的消息显示设备状态的更改。在本教程中，影子文档将显示灯泡颜色的变化。这些教程还显示影子如何存储此信息，即使设备与互联网断开连接，并在设备重新联机并请求此信息时将最新状态信息传递回设备。

我们建议您按照这里显示的顺序尝试这些教程，从需要创建的 AWS IoT 资源以及必要的硬件设置开始，这也有助于您逐步学习这些概念。这些教程展示了如何配置和连接 Raspberry Pi 设备以供使用 AWS IoT。如果您没有所需的硬件，您可以按照这些教程将它们适配于您选择的设备或[使用 Amazon EC2 创建虚拟设备](creating-a-virtual-thing.md)。

**教程场景概览**  
这些教程的场景是一个本地应用程序或服务，该应用程序或服务可更改灯泡的颜色，并将其数据发布到预留的影子主题。这些教程类似于[交互式入门教程](interactive-demo.md)中描述的 Device Shadow 功能，并在Raspberry Pi设备上实现。本部分中的教程侧重于单个经典影子，同时将展示如何容纳已命名的影子或多个设备。

以下教程将帮助您学习如何使用 Dev AWS IoT ice Shadow 服务。
+ 

**[教程：准备 Raspberry Pi 运行影子应用程序](create-resources-shadow.md)**  
本教程介绍如何设置 Raspberry Pi 设备以进行连接 AWS IoT。您还将创建 AWS IoT 策略文档和事物资源，下载证书，然后将策略附加到该事物资源。完成本教程需要大约 30 分钟。
+ 

**[教程：安装设备软件开发包并运行 Device Shadow 示例应用程序](lightbulb-shadow-application.md)**  
本教程介绍如何安装所需的工具、软件和适用于 Python 的 AWS IoT 设备 SDK，然后运行示例影子应用程序。本教程基于 [连接 Raspberry Pi 或其他设备](connecting-to-existing-device.md) 中介绍的概念所打造，完成需要 20 分钟。
+ 

**[教程：示例应用程序及 MQTT 测试客户端与 Device Shadow 交互](interact-lights-device-shadows.md)**  
本教程展示了如何使用`shadow.py`示例应用程序和**AWS IoT 控制台**来观察 AWS IoT 设备阴影与灯泡状态变化之间的相互作用。本教程还介绍了如何将 MQTT 消息发送到 Device Shadow 的预留主题。完成本教程需要大约 45 分钟。

**AWS IoT Device Shadow 概述**  
Device Shadow 是设备的永久虚拟表示形式，由您在 AWS IoT 注册表中创建[的事物资源](iot-thing-management.md)管理。Shadow 文档是一个 JSON 或 JavaScript 符号文档，用于存储和检索设备的当前状态信息。无论设备是否已连接到互联网，您都可以使用 shadow 通过 MQTT 主题或 HTTP RES APIs T 获取和设置设备的状态。

影子文档包含一个 `state` 属性，以描述设备状态的以下方面。
+ `desired`：应用程序更新 `desired` 对象以指定设备属性的所需状态。
+ `reported`：设备在 `reported` 对象中报告其当前状态。
+ `delta`： AWS IoT 报告`delta`对象中所需状态和报告状态之间的差异。

以下为示例影子状态文档：

```
{
  "state": {
    "desired": {
      "color": "green"
      },
    "reported": {
      "color": "blue"
      },
    "delta": {
      "color": "green"
      }
   }
}
```

要更新设备的 Shadow 文档，您可以使用[保留的 MQTT 主题](reserved-topics.md#reserved-topics-shadow)、支持、、HTTP `DELETE` 操作 APIs的 Device Shado [w RES](device-shadow-rest-api.md) T 以及 [AWS IoT CLI](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot-data/index.html)。`GET` `UPDATE`

在前面的示例中，假设您希望将 `desired` 颜色改为 `yellow`。要执行此操作，请将请求发送到 [UpdateThingShadow](device-shadow-rest-api.md#API_UpdateThingShadow) API 或将消息发布到[更新](device-shadow-mqtt.md#update-pub-sub-topic)主题，`$aws/things/THING_NAME/shadow/update`。

```
{
  "state": {
    "desired": {
      "color": yellow
    }
  }
}
```

更新仅影响请求中指定的字段。成功更新 Device Shadow 后，将新`desired`状态 AWS IoT 发布到`delta`主题`$aws/things/THING_NAME/shadow/delta`。在这种情况下，影子文档如下所示：

```
{
  "state": {
    "desired": {
      "color": yellow
    },
    "reported": {
      "color": green
    },
    "delta": {
      "color": yellow
      }
  }
}
```

然后，使用`$aws/things/THING_NAME/shadow/update`带有以下 JSON 消息的`Update`主题向 Dev AWS IoT ice Shadow 报告新状态：

```
{
  "state": {
    "reported": {
      "color": yellow
    }
  }
}
```

如果要获取当前状态信息，请将请求发送至 [GetThingShadow](device-shadow-rest-api.md#API_GetThingShadow) API 或将 MQTT 消息发布到 [Get](device-shadow-mqtt.md#get-pub-sub-topic)（获取）主题，`$aws/things/THING_NAME/shadow/get`。

有关使用 Device Shadow 服务的更多信息，请参阅 [AWS IoT Device Shadow 服务](iot-device-shadows.md)。

有关在设备、应用程序和服务中使用 Device Shadow 的更多信息，请参阅 [在设备中使用影子](device-shadow-comms-device.md) 和 [在应用程序和服务中使用影子](device-shadow-comms-app.md)。

有关与 AWS IoT 阴影交互的信息，请参见[与影子交互](device-shadow-data-flow.md)。

有关 MQTT 保留主题和 HTTP REST 的信息 APIs，请参阅[Device Shadow MQTT 主题](device-shadow-mqtt.md)和。[Device Shadow REST API](device-shadow-rest-api.md)

# 教程：准备 Raspberry Pi 运行影子应用程序
<a name="create-resources-shadow"></a>

本教程演示如何设置和配置 Raspberry Pi 设备，以及如何创建设备连接和交换 MQTT 消息所需的 AWS IoT 资源。

**注意**  
如果您计划 [使用 Amazon EC2 创建虚拟设备](creating-a-virtual-thing.md)，您可以跳过此页面并继续执行 [配置您的设备](configure-device.md)。创建虚拟事物时，您将创建这些资源。如果您想使用不同的设备，而不是 Raspberry Pi，可以尝试按照这些教程进行操作，将它们调整到您选择的设备。

**在本教程中，您将学习如何：**
+ 设置 Raspberry Pi 设备并将其配置为与一起使用 AWS IoT。
+ 创建 AWS IoT 策略文档，授权您的设备与 AWS IoT 服务进行交互。
+ 在 X.509 设备证书 AWS IoT 中创建事物资源，然后附加策略文档。

  事物是您的设备在 AWS IoT 注册表中的虚拟展示。证书用于向 C AWS IoT ore 对您的设备进行身份验证，策略文档授权您的设备与之交互。 AWS IoT

**如何运行本教程？**  
要为 Device Shadow 运行 `shadow.py` 示例应用程序，您将需要一个连接到 AWS IoT的 Raspberry Pi 设备。我们建议您按照此处显示的顺序遵循本教程，首先设置 Raspberry Pi 及其配件，然后创建策略并将策略附加到您创建的事物资源。然后，您可以使用 Raspberry Pi 支持的图形用户界面 (GUI) 在设备的 Web 浏览器上打开 AWS IoT 控制台，从而更轻松地将证书直接下载到 Raspberry Pi 进行连接 AWS IoT。

**在开始本教程之前，请确保您具有：**
+ 一个 AWS 账户。如果您没有账户，请完成 [设置 AWS 账户](setting-up.md)中介绍的步骤然后继续操作。你需要你的 AWS 账户 和 AWS IoT 主机才能完成本教程。
+ Raspberry Pi 及其必要的配件。您将需要：
  + [Raspberry Pi 3 Model B](https://www.raspberrypi.com/products/) 或更新型号。本教程可能适用于早期版本的 Raspberry Pi，但我们还没有测试过。
  + [Raspberry Pi OS (32 位)](https://www.raspberrypi.com/software/operating-systems/)或更高版本。我们始终建议使用最新版本的 Raspberry Pi OS。早期版本的操作系统可能有用，但我们还没有测试过。
  + 以太网或 Wi-Fi 连接。
  + 键盘、鼠标、显示器、电缆和电源。

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

## 步骤 1：设置和配置 Raspberry Pi 设备
<a name="setup-device-shadow"></a>

在本节中，我们将配置一台 Raspberry Pi 设备与一起使用 AWS IoT。

**重要**  
将这些指令用于其它设备和操作系统可能会非常困难。您需要充分了解您的设备，以便能够解释这些说明并将它们应用到您的设备上。如果遇到困难，可以尝试使用其它设备选项之一作为替代方案，例如 [使用 Amazon EC2 创建虚拟设备](creating-a-virtual-thing.md) 或者 [使用你的 Windows、Linux 电脑或 Mac 作为 AWS IoT 设备](using-laptop-as-device.md)。

您需要配置您的 Raspberry Pi，以便它可以启动操作系统（OS），连接到互联网，并允许您在命令行界面与它进行交互。您也可以使用 Raspberry Pi 支持的图形用户界面 (GUI) 打开 AWS IoT 控制台并运行本教程的其余部分。

**要设置 Raspberry Pi**

1. 将 SD 卡插入 Raspberry Pi 上的 MicroSD 卡槽。有些 SD 卡预装了一个安装管理器，将为您显示在启动主板后安装操作系统的菜单。您还可以使用 Raspberry Pi 在您的卡上安装操作系统。

1. 将 HDMI TV 或显示器 Connect 到 HDMI 电缆，然后连接到 Raspberry Pi 的 HDMI 端口。

1. 将键盘和鼠标连接到 Raspberry Pi 的 USB 端口，然后插入电源适配器以启动主板。

Raspberry Pi 启动后，如果 SD 卡预先加载了安装管理器，则会出现一个菜单来帮助您安装操作系统。如果您在安装操作系统时遇到问题，请尝试以下步骤。有关设置 Raspberry Pi 的更多信息，请参阅[设置您的 Raspberry Pi](https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up/)。

**如果您在设置 Raspberry Pi 时遇到问题：**
+ 在启动主板之前，请检查是否插入了 SD 卡。如果在启动主板后插入 SD 卡，则可能不会显示安装菜单。
+ 确保电视或显示器已打开，并且选择了正确的输入信号源。
+ 确保您使用的是兼容 Raspberry Pi 的软件。

安装并配置 Raspberry Pi 操作系统后，打开 Raspberry Pi 的 Web 浏览器并导航到 AWS IoT Core 控制台，继续本教程中的其余步骤。

如果你能打开 AWS IoT Core 主机，那么 Raspberry Pi 就准备好了，你可以继续[教程：在中配置您的设备 AWS IoT](shadow-provision-cloud.md)。

如果您遇到问题或需要其它帮助，请参阅[为您的 Raspberry Pi 获取帮助](https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up/5)。

# 教程：在中配置您的设备 AWS IoT
<a name="shadow-provision-cloud"></a>

本节创建了您的教程将使用的 AWS IoT Core 资源。

**Topics**
+ [步骤 1：为 Device Shadow 创建 AWS IoT 策略](#create-policy-shadow)
+ [步骤 2：创建事物资源并将策略附加到事物](#create-thing-shadow)
+ [步骤 3：查看结果和后续步骤](#resources-shadow-review)

## 步骤 1：为 Device Shadow 创建 AWS IoT 策略
<a name="create-policy-shadow"></a>

X.509 证书用于对您的设备进行身份验证。 AWS IoT Core AWS IoT 策略附加到证书，允许设备执行 AWS IoT 操作，例如订阅或发布到 Device Shadow 服务使用的 MQTT 保留主题。您的设备在连接并向其发送消息时会出示其证书 AWS IoT Core。

在此流程中，您将创建一个策略以允许您的设备执行运行示例程序所必要的 AWS IoT 操作。建议您创建一个策略以仅授予执行任务所需的许可。您首先创建 AWS IoT 策略，然后将其附加到稍后创建的设备证书。

**创建 AWS IoT 策略**

1. 在左侧菜单中，选择 **Secure**（安全），然后选 **Policies**（策略）。如果您的账户已有策略，请选择 **Create**（创建），否则，在 **You don’t have a policy yet**（您还没有策略）页面上，选择 **Create a policy**（创建策略）。

1. 在 **Create a policy**（创建策略）页面上：

   1. 在 **Name**（名称）字段，输入策略的名称（例如 **My\$1Device\$1Shadow\$1policy**）。请勿在策略名称中使用个人身份信息。

   1. 在策略文档中，您描述了授予设备发布和订阅 MQTT 保留主题权限的连接、订阅、接收和发布操作。

      复制以下策略并将其粘贴到策略文档中。`thingname`替换为您要创建的事物的名称（例如`My_light_bulb`）、`region`您正在使用服务的 AWS IoT 地区以及`account`您的 AWS 账户 电话号码。有关 AWS IoT 策略的更多信息，请参阅[AWS IoT Core 政策](iot-policies.md)。  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/get",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Receive"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/get/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/get/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update/delta"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Subscribe"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/get/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/get/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/update/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/update/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/update/delta"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": "iot:Connect",
                  "Resource": "arn:aws:iot:us-east-1:123456789012:client/test-*"
              }
          ]
      }
      ```

## 步骤 2：创建事物资源并将策略附加到事物
<a name="create-thing-shadow"></a>

连接的设备 AWS IoT 可以用 AWS IoT 注册表中的*事物资源*表示。*事物资源*表示特定设备或逻辑实体，如本教程中的灯泡。

要学习如何在中创建事物 AWS IoT，请按照中所述的步骤进行操作[创建一个事物对象](create-iot-resources.md#create-aws-thing)。以下是您在遵循该教程中的步骤时需要注意的几个关键事项：

1. 选择**创建单个事物**，并在**名称**字段中，输入与您在之前创建策略时指定的 `thingname` 相同的事物名称（例如，`My_light_bulb`)。

   事物名称一旦创建，便不可更改。如果您给它一个不同于 `thingname` 的名字，请以 `thingname` 为名称创建新的事物，并删除旧的事物。
**注意**  
请勿在事物名称中使用个人身份信息。事物名称可以出现在未加密的通信和报告中。

1. 我们建议您将 **Certificate created\$1**（已创建证书！）页面的每个证书文件下载到您可以轻松找到的位置。您需要安装这些文件才能运行示例应用程序。

   建议您将文件下载到 Raspberry Pi 中您的 `home` 目录下的 `certs` 子目录中，并使用一个更简单的名称命名各个文件，如下表所示。  
**证书文件名**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/shadow-provision-cloud.html)

1. 激活证书以启用与之连接后 AWS IoT，选择**附加策略**，并确保将之前创建的策略（例如**My\$1Device\$1Shadow\$1policy**）附加到该事物。

   创建事物后，您可以看到您的事物资源显示在 AWS IoT 控制台的事物列表中。

## 步骤 3：查看结果和后续步骤
<a name="resources-shadow-review"></a>

**在本教程中，您学习了如何：**
+ 设置和配置 Raspberry Pi 设备。
+ 创建授权您的设备与 AWS IoT 服务交互的 AWS IoT 策略文档。
+ 创建事物资源和关联的 X.509 设备证书，并将策略文档附加到其中。

**后续步骤**  
现在，你可以安装适用于 Python 的 AWS IoT 设备 SDK，运行`shadow.py`示例应用程序，并使用设备影子来控制状态。有关如何使用该教程的更多信息，请参阅 [教程：安装设备软件开发包并运行 Device Shadow 示例应用程序](lightbulb-shadow-application.md)。

# 教程：安装设备软件开发包并运行 Device Shadow 示例应用程序
<a name="lightbulb-shadow-application"></a>

本节介绍如何安装所需的软件和适用于 Python 的 AWS IoT 设备 SDK，以及如何运行`shadow.py`示例应用程序来编辑 Shadow 文档和控制阴影的状态。

**在本教程中，您将学习如何：**
+ 使用已安装的软件和适用于 Python 的 AWS IoT 设备 SDK 来运行示例应用程序。
+ 了解使用示例应用程序输入值如何在 AWS IoT 控制台发布预期的值。
+ 查看 `shadow.py` 示例应用程序以及它如何使用 MQTT 协议来更新影子的状态。

**在运行本教程之前：**  
您必须已设置好自己的 Raspberry Pi 设备，并创建了授予设备发布和订阅 Device Shadow 服务的 MQTT 保留主题的权限 AWS IoT 的事物和策略。 AWS 账户有关更多信息，请参阅 [教程：准备 Raspberry Pi 运行影子应用程序](create-resources-shadow.md)。

你还必须安装了 Git、Python 和适用于 Python 的 AWS IoT 设备 SDK。本教程基于教程 [连接 Raspberry Pi 或其他设备](connecting-to-existing-device.md) 中介绍的概念执行。如果您尚未尝试该教程，我们建议您按照该教程中描述的步骤安装证书文件和 Device SDK，然后返回本教程运行 `shadow.py` 示例应用程序。

**Topics**
+ [步骤 1：运行 shadow.py 示例应用程序](#run-sample-application-shadows)
+ [步骤 2：查看 shadow.py 设备软件开发包示例应用](#review-shadow-sample-code)
+ [步骤 3：借助 `shadow.py`示例应用程序排除问题](#shadow-sample-app-troubleshoot)
+ [步骤 4：查看结果和后续步骤](#sample-app-shadow-review)

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

## 步骤 1：运行 shadow.py 示例应用程序
<a name="run-sample-application-shadows"></a>

在运行 `shadow.py` 示例应用程序前，除了安装的证书文件的名称和位置之外，还需要以下信息。


**应用程序参数值**  

|  参数  |  在何处查找值  | 
| --- | --- | 
| your-iot-thing-name |  您之前在中创建 AWS IoT 的事物的名称[步骤 2：创建事物资源并将策略附加到事物](shadow-provision-cloud.md#create-thing-shadow)。 要查找此值，请在 [AWS IoT 控制台](https://console.aws.amazon.com/iot/home)中，选择 **Manage**（管理），然后选择 **Things**（事物）。  | 
| your-iot-endpoint |   该*your-iot-endpoint*值的格式为:`endpoint_id-ats.iot.region.amazonaws.com`，例如`a3qj468EXAMPLE-ats.iot.us-west-2.amazonaws.com`。要查找此值： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/lightbulb-shadow-application.html)  | 

**安装并运行示例应用程序**

1. 导航到示例应用程序目录。

   ```
   cd ~/aws-iot-device-sdk-python-v2/samples/service-clients
   ```

1. 在命令行窗口中，*your-iot-thing-name*按照指示替换*your-iot-endpoint*和并运行此命令。

   ```
   python3 shadow.py --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint --thing_name your-iot-thing-name
   ```

1. 观察示例应用程序：

   1. 连接到您账户的 AWS IoT 服务。

   1. 订阅 `Delta` 事件和 `Update` 及 `Get` 响应。

   1. 提示您在终端中输入所需的值。

   1. 输出类似于以下内容：

   ```
   Connecting to a3qEXAMPLEffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-0c8ae2ff-cc87-49d2-a82a-ae7ba1d0ca5a'...
   Connected!
   Subscribing to Delta events...
   Subscribing to Update responses...
   Subscribing to Get responses...
   Requesting current shadow state...
   Launching thread to read user input...
   Finished getting initial shadow state.
   Shadow contains reported value 'off'.
   Enter desired value:
   ```

**注意**  
如果您在运行 `shadow.py` 示例应用程序时遇到问题，请查看 [步骤 3：借助 `shadow.py`示例应用程序排除问题](#shadow-sample-app-troubleshoot)。若要获取可能帮助您更正此问题的其它信息，请将 `--verbosity debug` 参数添加到命令行，以便示例应用程序显示有关其正在执行的操作的详细消息。

**在影子文档中输入值并观察更新**  
您可以在终端中输入值来指定 `desired` 值，该值还会更新 `reported` 值。假设您在终端中输入颜色 `yellow`。`reported` 值也会更新为颜色 `yellow`。下面显示了终端中显示的消息：

```
Enter desired value:
yellow
Changed local shadow value to 'yellow'.
Updating reported shadow value to 'yellow'...
Update request published.
Finished updating reported shadow value to 'yellow'.
```

当您发布此更新请求时， AWS IoT 会为事物资源创建一个默认的经典影子。您可以通过查看您创建的事物资源（例如`My_light_bulb`）的 Shadow 文档来观察您发布到 AWS IoT 控制台中的`reported`和`desired`值的更新请求。要查看影子文档中的更新：

1. 在 AWS IoT 控制台中，选择 “**管理**”，然后选择 “**事物**”。

1. 在显示的事物列表中，选择您创建的事物，选择 **Shadows**（影子），然后选择 **Classic Shadow**（经典影子）。

影子文档应类似于以下内容，显示为颜色 `yellow` 设置的 `reported` 和 `desired` 值。您可以在文档的 **Shadow state**（影子状态）部分看到这些值。

```
{
"desired": {
  "welcome": "aws-iot",
  "color": "yellow"
},
"reported": {
  "welcome": "aws-iot",
  "color": "yellow"
}
}
```

您还可以看到 **Metadata**（元数据）部分，其中包含请求的时间戳信息和版本号。

您可以使用状态文档版本来确保正在更新的设备影子文档为最新版本。如果您发送另一个更新请求，则版本号将增加 1。当您为更新请求提供版本时，如果状态文档的当前版本与提供的版本不符，该服务将显示 HTTP 409 冲突响应代码并拒绝请求。

```
{
"metadata": {
  "desired": {
    "welcome": {
      "timestamp": 1620156892
    },
    "color": {
      "timestamp": 1620156893
    }
  },
  "reported": {
    "welcome": {
      "timestamp": 1620156892
    },
    "color": {
      "timestamp": 1620156893
    }
  }
},
"version": 10
}
```

要了解有关影子文档的详细信息并观察状态信息的更改，请继续阅读下一教程 [教程：示例应用程序及 MQTT 测试客户端与 Device Shadow 交互](interact-lights-device-shadows.md)，如本教程的 [步骤 4：查看结果和后续步骤](#sample-app-shadow-review) 部分所述。或者，您也可以在下一部分中了解 `shadow.py` 示例代码以及它如何使用 MQTT 协议。

## 步骤 2：查看 shadow.py 设备软件开发包示例应用
<a name="review-shadow-sample-code"></a>

本部分将回顾本教程中适用的来自 **AWS IoT Device SDK v2 for Python** 中的 `shadow.py`示例应用程序。在这里，我们将回顾一下它如何使用基于 WSS AWS IoT Core 的 MQTT 和 MQTT 协议进行连接。[AWS 通用运行时 (AWS-CRT)](https://github.com/awslabs/aws-crt-python#aws-crt-python) 库提供低级通信协议支持，并包含在适用于 Python 的 AWS IoT 设备 SDK v2 中。

虽然本教程使用基于 WSS 的 MQTT 和 MQTT，但 AWS IoT 支持发布 HTTPS 请求的设备。有关从设备发送 HTTP 消息的 Python 程序示例，请参阅使用 Python 的 `requests`库的 [HTTPS 代码示例](http.md#codeexample)。

有关如何对设备通信使用何种协议作出明智决定的信息，请查看 [为设备通信选择应用程序协议](protocols.md#protocol-selection)。

**MQTT**  
`shadow.py` 示例在 [https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py](https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py) 中调用 `mtls_from_path`（此处显示）以使用 MQTT 协议建立与 AWS IoT Core 的连接。`mtls_from_path` 使用 X.509 证书和 TLS v1.2 对设备进行身份验证。 AWS-CRT 库处理该连接的较低级别细节。

```
mqtt_connection = mqtt_connection_builder.mtls_from_path(
  endpoint=args.endpoint,
  cert_filepath=args.cert,
  pri_key_filepath=args.key,
  ca_filepath=args.ca_file,
  client_bootstrap=client_bootstrap,
  on_connection_interrupted=on_connection_interrupted,
  on_connection_resumed=on_connection_resumed,
  client_id=args.client_id,
  clean_session=False,
  keep_alive_secs=6
)
```
+ `endpoint`是您从命令行传入的 AWS IoT 终端节点，`client_id`也是在中唯一标识此设备的 ID AWS 区域。
+ `cert_filepath`、`pri_key_filepath` 和 `ca_filepath` 是指向设备证书和私钥文件以及根 CA 文件的路径。
+ `client_bootstrap` 是处理套接字通信活动的通用运行时对象，并在调用 `mqtt_connection_builder.mtls_from_path` 前实例化。
+ `on_connection_interrupted` 和 `on_connection_resumed` 是在设备连接中断和恢复时调用的回调函数。
+ `clean_session` 表示是否启动新的持久会话，或者如果会话已存在，则重新连接到现有会话。`keep_alive_secs` 是保持活动状态的值（以秒为单位），以发送到 `CONNECT` 请求中。在此时间间隔内将自动发送 ping。如果服务器在此值的 1.5 倍之后没有收到 ping，则假定连接丢失。

`shadow.py` 示例还调用 [https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py](https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py) 中的 `websockets_with_default_aws_signing` 以使用采用 WSS 的 MQTT 协议与 AWS IoT Core 建立连接。采用 WSS 的 MQTT 也使用与 MQTT 相同的参数，并采用以下附加参数：
+ `region`是 Signature V4 身份验证使用的签名区域，`credentials_provider`也是提供用于身份验证的 AWS 凭据。 AWS 区域是从命令行传递的，`credentials_provider` 对象在调用 `mqtt_connection_builder.websockets_with_default_aws_signing` 前进行实例化。
+ `websocket_proxy_options` 是 HTTP 代理选项（如果使用代理主机）。在 `shadow.py` 示例应用程序中，此值在调用 `mqtt_connection_builder.websockets_with_default_aws_signing` 前进行实例化。

**订阅影子主题和活动**  
`shadow.py` 示例尝试建立连接并等待完全连接。如果未连接，命令将排队。连接后，示例将订阅增量事件并更新和获取消息，并发布服务质量（QoS）级别为 1 的消息 (`mqtt.QoS.AT_LEAST_ONCE`)。

当设备订阅 QoS 级别 1 的消息时，消息代理会保存该设备订阅的消息，直到这些消息可以发送到设备。消息代理会重新发送消息，直至收到设备发出的 `PUBACK`响应。

有关 MQTT 协议的更多信息，请参阅 [查看 MQTT 协议](sdk-tutorials.md#sdk-tutorials-mqtt-review)和 [MQTT](mqtt.md)。

有关本教程中如何使用 MQTT、采用 WSS 的 MQTT、持久会话和 QoS 级别的详细信息，请参阅 [查看 pubsub.py Device SDK 示例应用程序](sdk-tutorials.md#sdk-tutorials-explore-sample)。

## 步骤 3：借助 `shadow.py`示例应用程序排除问题
<a name="shadow-sample-app-troubleshoot"></a>

当您运行 `shadow.py` 示例应用程序时，您应该看到终端中显示的一些消息以及输入 `desired` 值的提示。如果程序抛出错误，那么请调试以解决错误，您可以从检查系统是否运行了正确的命令开始。

在某些情况下，错误消息可能会指示连接问题，并且看起来类似于：`Host name was invalid for dns resolution` 或者 `Connection was closed unexpectedly`。在这种情况下，以下是您可以检查的几个事项：
+ 

**检查命令中的端点地址**  
查看您在命令中输入用来运行示例应用程序的 `endpoint` 参数（例如 `a3qEXAMPLEffp-ats.iot.us-west-2.amazonaws.com`），然后在 **AWS IoT 控制台**中检查此值。

  要检查是否使用了正确的值：

  1. 在 **AWS IoT 控制台**中，选择**管理**，然后选择**事物**。

  1. 选择您为示应用程序创建的事物（例如 **My\$1light\$1bulb**），然后选择 **Interact**（交互）。

  您的端点会显示在事物详细信息页面的 **HTTPS** 部分中。您还会看到一条消息，写着：`This thing already appears to be connected.`
+ 

**检查证书激活**  
证书用于对您的设备进行身份验证 AWS IoT Core。

  要检查您的证书是否处于活动状态：

  1. 在 **AWS IoT 控制台**中，选择 **Manage**（管理），然后选择 **Things**（事物）。

  1. 选择您为示应用程序创建的事物（例如 **My\$1light\$1bulb**），然后选择 **Security**（安全）。

  1. 选择证书，然后从证书的详细信息页面中选择 **Actions**（操作）。

  如果在下拉列表中 **Activate**（激活）不可用，且您只能选择 **Deactivate**（停用），则表示您的证书处于活动状态。如果并非如此，请选择 **Activate**（激活）并重新运行示例程序。

  如果程序仍未运行，请检查 `certs` 文件夹中的证书文件名。
+ 

**检查附加到事物资源的策略**  
在证书对您的设备进行身份验证的同时， AWS IoT 策略允许设备执行 AWS IoT 操作，例如订阅或发布 MQTT 保留主题。

  要检查是否附加了正确的策略：

  1. 查找如前所述的证书，然后选择 **Policies**（策略）。

  1. 选择显示的策略，并检查它是否描述 `connect`、`subscribe`、`receive` 和 `publish` 操作，授予设备发布和订阅 MQTT 预留主题的权限。

     如需了解示例策略，请参阅 [步骤 1：为 Device Shadow 创建 AWS IoT 策略](shadow-provision-cloud.md#create-policy-shadow)。

  如果您看到错误消息表明无法连接到该策略 AWS IoT，则可能是因为您正在使用策略的权限。如果是这样的话，我们建议您从提供对 AWS IoT 资源的完全访问权限的策略开始，然后重新运行示例程序。您可以编辑当前策略，也可以选择当前策略，选择 **Detach**（分离），然后创建另一个提供完全访问权限的策略并将其附加到您的事物资源。您可以稍后将策略限制为运行程序所需的操作和策略。  
****  

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

**检查您的设备 Device SDK 安装**  
如果程序仍未运行，您可以重新安装 Device SDK 包以确保 SDK 安装完整且正确。

## 步骤 4：查看结果和后续步骤
<a name="sample-app-shadow-review"></a>

**在本教程中，您学习了如何：**
+ 安装所需的软件、工具和适用于 Python 的 AWS IoT 设备 SDK。
+ 了解示例应用程序 `shadow.py` 如何使用 MQTT 协议检索和更新影子的当前状态。
+ 运行 Device Shadows 的示例应用程序，并在 AWS IoT 控制台中观察 Shadow 文档的更新。您还学习了如何在运行程序时解决任何问题和修复错误。

**后续步骤**  
您现在可以运行 `shadow.py` 示例应用程序，并使用 Device Shadow 控制状态。您可以在 AWS IoT 控制台中观察并更新影子文档，并观察示例应用程序相应的增量事件。使用 MQTT 测试客户端，您可以订阅预留影子主题并在运行示例程序时观察主题收到的消息。有关如何使用该教程的更多信息，请参阅 [教程：示例应用程序及 MQTT 测试客户端与 Device Shadow 交互](interact-lights-device-shadows.md)。

# 教程：示例应用程序及 MQTT 测试客户端与 Device Shadow 交互
<a name="interact-lights-device-shadows"></a>

若要与 `shadow.py` 示例应用程序交互，请在终端中为 `desired` 值输入一个值。例如，您可以指定类似于交通信号灯的颜色，并 AWS IoT 响应请求并更新报告的值。

**在本教程中，您将学习如何：**
+ 使用 `shadow.py`示例应用程序来指定所需的状态并更新影子的当前状态。
+ 编辑影子文档以观察增量事件以及 `shadow.py`示例应用程序如何响应。
+ 使用 MQTT 测试客户端订阅影子主题并在运行示例程序时观察更新。

**运行本教程之前，您必须具有：**  
设置你的 AWS 账户，配置你的 Raspberry Pi 设备，并创建了 AWS IoT 事物和策略。您还必须安装了所需的软件、Device SDK、证书文件，并在终端中运行示例程序。有关更多信息，请参阅教程 [教程：准备 Raspberry Pi 运行影子应用程序](create-resources-shadow.md) 和 [步骤 1：运行 shadow.py 示例应用程序](lightbulb-shadow-application.md#run-sample-application-shadows)。如果您尚未完成这些教程，请先予完成。

**Topics**
+ [步骤 1：使用 `shadow.py` 示例应用程序更新所需值和报告值](#update-desired-shadow-sample)
+ [步骤 2：查看来自 `shadow.py` 中 MQTT 测试客户端中示例应用程序的消息](#shadow-sample-view-msg)
+ [步骤 3：排除 Device Shadow 交互中的错误](#shadow-observe-messages-troubleshoot)
+ [步骤 4：查看结果和后续步骤](#sample-shadow-review)

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

## 步骤 1：使用 `shadow.py` 示例应用程序更新所需值和报告值
<a name="update-desired-shadow-sample"></a>

在上一教程中[步骤 1：运行 shadow.py 示例应用程序](lightbulb-shadow-application.md#run-sample-application-shadows)，您学习了如何在输入所需值时在 AWS IoT 控制台中观察发布到 Shadow 文档的消息（如本节所述）[教程：安装设备软件开发包并运行 Device Shadow 示例应用程序](lightbulb-shadow-application.md)。

在前面的示例中，我们将所需的颜色设置为 `yellow`。输入每个值后，终端将提示您输入另一个 `desired` 值。如果您再次输入相同的值 (`yellow`)，应用程序会识别这一点，并提示您输入一个新的 `desired` 值。

```
Enter desired value:
yellow
Local value is already 'yellow'.
Enter desired value:
```

现在，假设你输入了颜色`green`。 AWS IoT 响应请求并将`reported`值更新为`green`。这就是当 `desired` 状态不同于 `reported` 状态时产生更新的方式，从而导致增量。

**`shadow.py` 示例应用程序模拟 Device Shadow 交互：**

1. 在终端输入 `desired` 值（例如 `yellow`）来发布所需的状态。

1. 由于 `desired` 状态不同于 `reported` 状态（比如说颜色 `green`），则会产生增量，并且订阅增量的应用程序会收到此消息。

1. 应用程序响应消息并将其状态更新为 `desired` 值，`yellow`。

1. 然后，应用程序会发布一条更新消息，其中包含设备状态的新报告值，`yellow`。

下面显示了终端中显示的消息，其展示了更新申请是如何发布的。

```
Enter desired value:
green
Changed local shadow value to 'green'.
Updating reported shadow value to 'green'...
Update request published.
Finished updating reported shadow value to 'green'.
```

在 AWS IoT 控制台中，Shadow 文档将`reported`和`desired`字段`green`的更新值反映为，版本号以 1 为增量。例如，如果以前的版本号显示为 10，则当前版本号将显示为 11。

**注意**  
删除影子不会将版本号重置为 0。当您发布更新请求或创建另一个具有相同名称的影子时，您将看到影子版本递增 1。

**编辑影子文档以观察增量事件**  
`shadow.py` 示例应用程序也订阅 `delta` 事件，并在 `desired` 值出现更改时予以响应。例如，您可以将 `desired`值更改为颜色 `red`。为此，请在 AWS IoT 控制台中单击 “编辑” 来编辑 Shadow 文档，然后**在** JSON `red` 中将该`desired`值设置为，同时将该`reported`值保持为`green`。保存更改之前，请保持 Raspberry Pi 上的终端打开状态，因为当出现更改时，您会看到终端中显示的消息。

```
{
"desired": {
  "welcome": "aws-iot",
  "color": "red"
},
"reported": {
  "welcome": "aws-iot",
  "color": "green"
}
}
```

保存新值后，`shadow.py` 示例应用程序响应此更改，并在终端中显示指示增量的消息。然后，您应该看到以下消息出现在输入 `desired` 值的提示下方。

```
Enter desired value:
Received shadow delta event.
Delta reports that desired value is 'red'. Changing local value...
Changed local shadow value to 'red'.
Updating reported shadow value to 'red'...
Finished updating reported shadow value to 'red'.
Enter desired value:
Update request published.
Finished updating reported shadow value to 'red'.
```

## 步骤 2：查看来自 `shadow.py` 中 MQTT 测试客户端中示例应用程序的消息
<a name="shadow-sample-view-msg"></a>

您可以使用 **AWS IoT 控制台**中的 **MQTT 测试客户端**来监控传递在 AWS 账户中的 MQTT 消息。通过订阅 Device Shadow 服务使用的保留 MQTT 主题，您可以观察在运行示例应用程序时主题收到的消息。

如果尚未使用 MQTT 测试客户端，您可以查看 [使用 MQTT 客户端查看 AWS IoT MQTT 消息](view-mqtt-messages.md)。它可以帮助您了解如何使用 **AWS IoT 控制台**中的 **MQTT 测试客户端**来查看通过消息代理时的 MQTT 消息。

1. 

**打开 MQTT 测试客户端**

   打开 [AWS IoT 控制台中的 MQTT 测试客户端](https://console.aws.amazon.com//iot/home#/test)，以便您可以观察 MQTT 主题收到的消息，而不会丢失 MQTT 测试客户端的配置。如果您让 MQTT 测试客户端进入控制台中的其它页面，则 MQTT 测试客户端不会保留任何订阅或消息日志。在本教程的这一部分中，你可以让你的 AWS IoT 事物的 Shadow 文档和 MQTT 测试客户端在单独的窗口中打开，以便更轻松地观察与设备影子的交互情况。

1. 

**订阅 MQTT 预留的影子主题**

   您可以使用 MQTT 测试客户端输入 Device Shadow 的 MQTT 预留主题的名称，并在运行 `shadow.py` 示例应用程序时订阅它们以接收更新。要订阅主题：

   1. 在 **AWS IoT 控制台**的 **MQTT 测试客户端**中，选择**订阅主题**。

   1.  在**主题筛选器**部分，输入：**\$1aws/things/ /shadow/updat *thingname*** e/ \$1。在这里，`thingname` 是您之前创建的事物资源的名称（例如，`My_light_bulb`）。

   1. 保留附加配置设置的默认值，然后选择 **Subscribe**（订阅）。

   通过使用 **\$1** 通配符，您可以同时订阅多个 MQTT 主题，并在单个窗口中观察设备与其影子之间交换的所有消息。有关通配符及其用法的更多信息，请参阅 [MQTT 主题](topics.md)。

1. 

**运行 `shadow.py` 示例程序和观察消息**

   在 Raspberry Pi 的命令行窗口中，如果您已经断开程序的连接，请再次运行示例应用程序，并在 **AWS IoT 控制台**中的 **MQTT 测试客户端**观察消息。

   1. 运行以下命令以重新启动示程序。将*your-iot-thing-name*和*your-iot-endpoint*替换为您之前创建 AWS IoT 的事物的名称（例如`My_light_bulb`），以及要与设备交互的终端节点。

      ```
      cd ~/aws-iot-device-sdk-python-v2/samples/service-clients
      python3 shadow.py --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint --thing_name your-iot-thing-name
      ```

      `shadow.py` 示例应用程序随后会开始运行并检索当前影子状态。如果已删除影子或清除当前状态，程序会将当前值设置为 `off`，然后提示您输入 `desired` 值。

      ```
      Connecting to a3qEXAMPLEffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-0c8ae2ff-cc87-49d2-a82a-ae7ba1d0ca5a'...
      Connected!
      Subscribing to Delta events...
      Subscribing to Update responses...
      Subscribing to Get responses...
      Requesting current shadow state...
      Launching thread to read user input...
      Finished getting initial shadow state.
      Shadow document lacks 'color' property. Setting defaults...
      Changed local shadow value to 'off'.
      Updating reported shadow value to 'off'...
      Update request published.
      Finished updating reported shadow value to 'off'...
      Enter desired value:
      ```

      另一方面，如果程序正在运行，并且您将程序重新启动，您将看到终端中报告的最新颜色值。**在 MQTT 测试客户端中，你会看到 \$1aws/things//shadow/get 和 **\$1aws/things// *thingname*** 主题的更新。*thingname* shadow/get/accepted**

      假设报告的最新颜色为 `green`。以下显示了 **\$1aws/things// *thingname*** JSON 文件的内容。shadow/get/accepted

      ```
      {
      "state": {
        "desired": {
          "welcome": "aws-iot",
          "color": "green"
        },
        "reported": {
          "welcome": "aws-iot",
          "color": "green"
        }
      },
      "metadata": {
        "desired": {
          "welcome": {
            "timestamp": 1620156892
          },
          "color": {
            "timestamp": 1620161643
          }
        },
        "reported": {
          "welcome": {
            "timestamp": 1620156892
          },
          "color": {
            "timestamp": 1620161643
          }
        }
      },
      "version": 10,
      "timestamp": 1620173908
      }
      ```

   1. 在终端中输入 `desired` 值，例如 `yellow`。`shadow.py` 示例应用程序响应并在终端中显示以下消息，这些消息显示了 `reported` 值变更为 `yellow`的情况。

      ```
      Enter desired value:
      yellow
      Changed local shadow value to 'yellow'.
      Updating reported shadow value to 'yellow'...
      Update request published.
      Finished updating reported shadow value to 'yellow'.
      ```

      在 **AWS IoT 控制台**的 **MQTT 测试客户端**中，在**订阅**下，您会看到以下主题收到一条消息：
      + **\$1aws/things/ *thingname* /shadow/update**：显示和值都`desired`变为颜色。`updated` `yellow`
      + **\$1aws/things*thingname*//shadow/update/accepted**：显示`desired`和`reported`状态的当前值及其元数据和版本信息。
      + **\$1aws/things*thingname*//shadow/update/documents**：显示和`reported`状态的先前`desired`和当前值及其元数据和版本信息。

      由于文档 **\$1aws/things/*thingname*/shadow/update/documents**也包含其他两个主题中包含的信息，因此我们可以查看它以查看状态信息。上一个状态显示报告的值设置为 `green`、其元数据和版本信息，而当前的状态显示报告的值更新为 `yellow`。

      ```
      {
      "previous": {
        "state": {
          "desired": {
            "welcome": "aws-iot",
            "color": "green"
          },
          "reported": {
            "welcome": "aws-iot",
            "color": "green"
          }
        },
        "metadata": {
          "desired": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297898
            }
          },
          "reported": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297898
            }
          }
        },
        "version": 10
      },
      "current": {
        "state": {
          "desired": {
            "welcome": "aws-iot",
            "color": "yellow"
          },
          "reported": {
            "welcome": "aws-iot",
            "color": "yellow"
          }
        },
        "metadata": {
          "desired": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297904
            }
          },
          "reported": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297904
            }
          }
        },
        "version": 11
      },
      "timestamp": 1617297904
      }
      ```

   1. 现在，如果您输入另一个 `desired` 值，您可以看到 `reported` 值的进一步更改和这些主题收到的消息更新。版本号也会增加 1。例如，如果您输入值 `green`，之前的状态会报告值 `yellow`，而当前状态报告值 `green`。

1. 

**编辑影子文档以观察增量事件**

   要观察对增量主题的更改，请在 AWS IoT 控制台编辑影子文档。例如，您可以将 `desired`值更改为颜色 `red`。为此，请在 AWS IoT 控制台中选择 **“编辑”，然后在** JSON 中将该`desired`值设置为红色，同时将该`reported`值设置为`green`。在保存更改之前，请保持终端处于开启状态，因为您将看到终端中报告的增量消息。

   ```
   {
   "desired": {
     "welcome": "aws-iot",
     "color": "red"
   },
   "reported": {
     "welcome": "aws-iot",
     "color": "green"
   }
   }
   ```

   `shadow.py` 示例应用程序响应此更改，并在终端中显示指示增量的消息。在 MQTT 测试客户端中，`update` 主题将收到一条消息，显示对 `desired` 和 `reported` 值的更改。

   你还会看到话题 **\$1aws/things/*thingname*/shadow/update/delta**收到了一条消息。要查看消息，请选择该主题，其列于 **Subscriptions**（订阅）下方。

   ```
   {
   "version": 13,
   "timestamp": 1617318480,
   "state": {
     "color": "red"
   },
   "metadata": {
     "color": {
       "timestamp": 1617318480
     }
   }
   }
   ```

## 步骤 3：排除 Device Shadow 交互中的错误
<a name="shadow-observe-messages-troubleshoot"></a>

运行影子示例应用程序时，在观察与 Device Shadow 服务的交互过程中可能会遇到问题。

如果程序运行成功并提示您输入 `desired` 值，您应该能够通过使用前述影子文档和 MQTT 测试客户端来观察 Device Shadow 交互。但是，如果您无法查看交互，可以检查以下事项：
+ 

**在 AWS IoT 控制台中检查事物名称及其阴影**  
如果您在影子文档中没有看到这些消息，请查看该命令，并确保它与 **AWS IoT 控制台** 中的事物名称相符。您还可以通过选择事物资源，然后选择 **Shadows**（影子）来查看您是否拥有经典影子。本教程主要侧重于与经典影子的交互。

   您还可以确认您使用的设备已连接到互联网。在 **AWS IoT 控制台**，选择您之前创建的事物，然后选择**交互**。在事物详细信息页面上，您应该会在此处看到一条消息：`This thing already appears to be connected.`
+ 

**检查您订阅的 MQTT 预留主题**  
如果在 MQTT 测试客户端中看不到消息，请检查您订阅的主题是否格式正确。MQTT Device Shadow 主题的格式为 **\$1aws/things/ *thingname* /shadow/**，可能有`update``get`、或`delete`关注它，具体取决于你要对影子执行的操作。**本教程使用主题 **\$1aws/things/ *thingname* /shadow/ \$1**，因此在测试客户端的 “主题筛选器” 部分订阅该主题时，请务必正确输入该主题。**

  输入主题名称时，请确保与之前创建 AWS IoT 的事物的名称相同。*thingname*您还可以订阅其它 MQTT 主题，以查看是否已成功执行更新。例如，您可以订阅主题 **\$1aws/things/*thingname*/**，shadow/update/rejected以便在更新请求失败时收到一条消息，以便您可以调试连接问题。有关预留主题的更多信息，请参阅 [影子主题](reserved-topics.md#reserved-topics-shadow) 和 [Device Shadow MQTT 主题](device-shadow-mqtt.md)。

## 步骤 4：查看结果和后续步骤
<a name="sample-shadow-review"></a>

**在本教程中，您学习了如何：**
+ 使用 `shadow.py`示例应用程序来指定所需的状态并更新影子的当前状态。
+ 编辑影子文档以观察增量事件以及 `shadow.py`示例应用程序如何响应。
+ 使用 MQTT 测试客户端订阅影子主题并在运行示例程序时观察更新。

**后续步骤**  
您可以订阅其它 MQTT 预留主题，以观察影子应用程序的更新。例如，如果您只订阅主题 **\$1aws/things/*thingname*/shadow/update/accepted**，则成功执行更新后，您将只能看到当前状态信息。

您还可以订阅其它影子主题以调试问题或了解有关 Device Shadow 交互的详细信息，还可以调试与 Device Shadow 交互有关的任何问题。有关更多信息，请参阅[影子主题](reserved-topics.md#reserved-topics-shadow)和[Device Shadow MQTT 主题](device-shadow-mqtt.md)。

您也可以选择使用命名阴影或使用与 Raspberry Pi 连接的其他硬件来扩展应用程序， LEDs 并使用终端发送的消息观察其状态的变化。

有关 Device Shadow 服务以及在设备、应用程序和服务中使用该服务的详细信息，请参阅 [AWS IoT Device Shadow 服务](iot-device-shadows.md)、[在设备中使用影子](device-shadow-comms-device.md) 和 [在应用程序和服务中使用影子](device-shadow-comms-app.md)。