

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

# 使用 AWS IoT 设备客户端构建演示
<a name="iot-tutorials-dc-intro"></a>

本学习路径中的教程将引导您完成使用 AWS IoT 设备客户端开发演示软件的步骤。 AWS IoT 设备客户端提供在您的物联网设备上运行的软件，用于测试和演示基于物联网解决方案的各个方面 AWS IoT。

这些教程的目标是促进探索和实验，以便在开发设备软件之前，您可以放心地 AWS IoT 支持您的解决方案。

**您将在本教程中学到的内容：**
+ 如何准备 Raspberry Pi 以用作物联网设备 AWS IoT
+ 如何在设备上使用 AWS IoT 设备客户端来演示 AWS IoT 功能

在本学习路径中，你将在自己的 Raspberry Pi 上安装 AWS IoT 设备客户端，并在云端创建 AWS IoT 资源来演示物联网解决方案创意。尽管此学习路径中的教程通过使用 Raspberry Pi 演示功能，也讲解了帮助您适应其他设备的目标和程序。

## 使用 AWS IoT 设备客户端制作演示的先决条件
<a name="iot-dc-tutorial-overview"></a>

本节介绍在此学习路径中的教程开始之前需要了解的内容。

**要完成此学习路径中的教程，您需要：**
+ 

**一个 AWS 账户**  
如果有的话 AWS 账户，您可以使用现有角色或权限，但可能需要添加其他角色或权限才能使用这些教程使用的 AWS IoT 功能。

  如果您需要创建新的 AWS 账户，请参阅[设置 AWS 账户](setting-up.md)。
+ 

**Raspberry Pi 或兼容的物联网设备**  
由于因数不同，这些教程使用 [Raspberry Pi](https://www.raspberrypi.org/)，这是一种常用的演示色斑，成本相对较低。已在 [Raspberry Pi 3 Model B\$1](https://www.raspberrypi.com/products/raspberry-pi-3-model-b-plus/)、[Raspberry Pi 4 Model B](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/) 以及运行 Ubuntu Server 20.04 LTS（HVM）的 Amazon EC2 实例上测试了教程。要使用 AWS CLI 和运行命令，我们建议您使用最新版本的 Raspberry Pi 操作系统[（64 位）或 O](https://www.raspberrypi.com/software/operating-systems/) S Lite）。早期版本的操作系统可能有用，但我们还没有测试过。
**注意**  
这些教程解释了每个步骤的目标，帮助您适应我们没有尝试过的物联网硬件；但是，没有具体描述如何适用于其他设备。
+ 

**熟悉物联网设备的操作系统**  
这些教程中的步骤假设您熟悉使用 Raspberry Pi 支持的命令行界面中的基本 Linux 命令和操作。如果您不熟悉这些操作，可能需要给自己更多的时间来完成教程。

  要完成这些教程，您应已经了解下列操作：
  + 安全地执行基本的设备操作，例如组装和连接组件、将设备连接到所需的电源以及安装和卸载存储卡。
  + 将系统软件和文件上传并下载到设备。如果您的设备不使用可移动存储设备，例如 microSD 卡，您需要知道如何连接到设备以及如何将系统软件和文件上传并下载到设备。
  + 将您的设备连接到计划使用的网络。
  + 用 SSH 终端或类似程序从另一台计算机连接到您的设备。
  + 用命令行界面在设备上创建、复制、移动、重命名和设置文件和目录的权限。
  + 在设备上安装新程序。
  + 使用 FTP 或 SCP 等工具在设备之间传输文件。
+ 

**IoT 解决方案的开发和测试环境**  
教程描述了所需的软件和硬件；然而，教程假设您能够执行可能没有明确描述的操作。此类硬件和操作的示例包括：
  + 

**下载并存储文件的本地主机**  
对于 Raspberry Pi 而言，通常是可以读写 microSD 存储卡的个人计算机或笔记本电脑。本地主机必须：
    + 连接到互联网。
    + 已经安装并配置 [AWS CLI](https://aws.amazon.com//cli/)。
    + 使用支持 AWS 控制台的 Web 浏览器。
  + 

**能够将本地主机连接到设备进行通信、输入命令以及传输文件**  
在 Raspberry Pi 上，通常是使用本地主机上的 SSH 和 SCP 完成的。
  + 

**连接到物联网设备上的显示器和键盘**  
这些可能会有所帮助，但并不是完成教程的必需内容。
  + 

**您本地主机和物联网设备能够连接到互联网**  
这可能是连接到互联网的路由器或网关的有线网络连接或无线网络连接。本地主机还必须能够连接到 Raspberry Pi。这可能需要它们在同一个局域网上。这些教程无法向您展示如何针对特定设备或设备配置进行设置，但说明了如何测试连通性。
  + 

**访问局域网的路由器查看连接的设备**  
要完成此学习路径中的教程，您需要能够找到物联网设备的 IP 地址。

    在局域网上，可以通过访问设备连接到的网络路由器的管理界面来完成此操作。如果您可以在路由器中为设备分配固定 IP 地址，可以在设备每次重新启动后简化重新连接。

    如果键盘和显示器连接到设备上，**ifconfig** 可以显示设备的 IP 地址。

    如果没有使用上述设备，需要在每次重启设备后找到一种方法来识别设备的 IP 地址。

获得所有资料之后，继续 [教程：为设备客户端准备 AWS IoT 设备](iot-dc-prepare-device.md)。

**Topics**
+ [使用 AWS IoT 设备客户端制作演示的先决条件](#iot-dc-tutorial-overview)
+ [教程：为设备客户端准备 AWS IoT 设备](iot-dc-prepare-device.md)
+ [教程：安装和配置 AWS IoT 设备客户端](iot-dc-install-dc.md)
+ [教程：演示与 AWS IoT 设备客户端的 MQTT 消息通信](iot-dc-testconn.md)
+ [教程：使用 AWS IoT 设备客户端演示远程操作（作业）](iot-dc-runjobs.md)
+ [教程：运行 AWS IoT 设备客户端教程后进行清理](iot-dc-cleanup.md)

# 教程：为设备客户端准备 AWS IoT 设备
<a name="iot-dc-prepare-device"></a>

本教程将引导您完成 Raspberry Pi 的初始化，为此学习路径中的后续教程做好准备。

本教程的目标是安装当前版本的设备操作系统，确保您可以在开发环境中与设备进行通信。

**先决条件**  
开始学习本教程之前，请确保您具有 [使用 AWS IoT 设备客户端制作演示的先决条件](iot-tutorials-dc-intro.md#iot-dc-tutorial-overview) 中所列的条目，并准备开始使用。

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

**在本教程中，您将：**
+ 安装并更新设备的操作系统。
+ 安装并验证运行教程所需的任何其他软件。
+ 测试设备的连接并安装所需的证书。

完成本教程后，下一个教程将为使用设备客户端的演示做好 AWS IoT 设备准备。

**Topics**
+ [安装并更新设备的操作系统](iot-dc-prepare-device-sys.md)
+ [在设备上安装并验证所需的软件](iot-dc-prepare-device-sw.md)
+ [测试您的设备并保存 Amazon CA 证书](iot-dc-prepare-device-test.md)

# 安装并更新设备的操作系统
<a name="iot-dc-prepare-device-sys"></a>

本节中的步骤介绍了如何初始化 Raspberry Pi 用于系统驱动器的 microSD 卡。Raspberry Pi 的 microSD 卡包含其操作系统（OS）软件和应用程序文件存储空间。如果您没有使用 Raspberry Pi，请按照设备的说明安装和更新设备的操作系统软件。

完成本部分后，您应能够启动物联网设备并从本地主机上的终端程序进行连接。

**所需的设备：**
+ 您的本地开发和测试环境 
+ 可以连接到互联网的 Raspberry Pi 或您的物联网设备
+ 至少 8 GB 或足够空间的 microSD 存储卡，用于存储操作系统和所需的软件。
**注意**  
在选择 microSD 卡进行练习时，请选择一张存储量较小的卡。  
小容量 SD 卡的备份和更新速度会更快。在 Raspberry Pi 上，这些教程中使用的 microSD 卡容量不需要超过 8 GB。如果您需要更大的存储量用于特定的应用程序，在这些教程中保存的较小的图片文件可以调整存储量较大卡上的文件系统大小，使用所选卡的所有支持空间。

**可选设备：**
+ 连接到 Raspberry Pi 的 USB 键盘
+ 用于将显示器连接到 Raspberry Pi 的 HDMI 显示器和电缆

**Topics**
+ [将设备的操作系统加载到 microSD 卡内](#iot-dc-prepare-device-sys-step1)
+ [用新的操作系统启动物联网设备](#iot-dc-prepare-device-sys-step2)
+ [将您的本地主机连接到设备上](#iot-dc-prepare-device-sys-step3)

## 将设备的操作系统加载到 microSD 卡内
<a name="iot-dc-prepare-device-sys-step1"></a>

此一步骤使用本地主机将设备的操作系统加载到 microSD 卡内。

**注意**  
如果您的设备没有用于操作系统的可移动存储设备，请使用该设备的过程安装操作系统，然后继续 [用新的操作系统启动物联网设备](#iot-dc-prepare-device-sys-step2)。

**要在 Raspberry Pi 上安装操作系统**

1. 在本地主机上，下载并解压缩要使用的 Raspberry Pi 操作系统映像。最新版本可从[ https://www.raspberrypi.com/software/操作系统/](https://www.raspberrypi.com/software/operating-systems/) 

**选择 Raspberry Pi OS 版本**  
本教程使用 **Raspberry Pi OS Lite** 版本，因为它是在此学习路径中支持这些教程的最小版本。这个版本的 Raspberry Pi 操作系统只有命令行界面，没有图形用户界面。带图形用户界面的最新版本 Raspberry Pi 操作系统也可以使用这些教程；但是，本学习路径中描述的步骤仅使用命令行界面对 Raspberry Pi 执行操作。

1. 将 microSD 卡插到您的计算机上。

1. 使用 SD 卡成像工具，将解压缩的操作系统映像文件写入 microSD 卡。

1. 将 Raspberry Pi OS 映像写入 microSD 卡之后：

   1. 在命令行窗口或文件资源管理器窗口中打开 microSD 卡上的 BOOT 分区。

   1. 在 microSD 卡的 BOOT 分区中的根目录下，创建一个名为 `ssh`的空文件，没有文件扩展名也没有内容。在首次开机时会告知 Raspberry Pi 启用 SSH 通信。

1. 弹出 microSD 卡并从本地主机上安全取出卡片。

您的 microSD 卡已经准备好 [用新的操作系统启动物联网设备](#iot-dc-prepare-device-sys-step2)。

## 用新的操作系统启动物联网设备
<a name="iot-dc-prepare-device-sys-step2"></a>

此过程安装 microSD 卡并使用下载的操作系统首次启动 Raspberry Pi。

**用新的操作系统启动物联网设备**

1. 从设备断开电源的情况下，插入上一步中的 microSD 卡，[将设备的操作系统加载到 microSD 卡内](#iot-dc-prepare-device-sys-step1)，进入 Raspberry Pi。

1. 将设备连接到有线网络。

1. 这些教程将使用 SSH 终端从本地主机与 Raspberry Pi 进行交互。

   如果还想直接与设备交互，您可以：

   1. 将本地主机上的终端窗口 Connect 到 Raspberry Pi 之前，将 HDMI 显示器连接到Raspberry Pi 观看 Raspberry Pi 的控制台消息。

   1. 如果想直接与 Raspberry Pi 交互，请将 USB 键盘连接。

1. 将电源连接到 Raspberry Pi 上，等待大约一分钟后才能初始化。

   如果您的显示器连接到 Raspberry Pi 上，那您可以在显示器上查看启动过程。

1. 

   找出设备的 IP 地址：
   + 如果您将 HDMI 显示器连接到 Raspberry Pi 上，IP 地址将出现在显示器上的消息中 
   + 如果您可以访问 Raspberry Pi 连接的路由器，可以在路由器的管理界面中看到它的地址。

获得 Raspberry Pi IP 地址后，您可以进行 [将您的本地主机连接到设备上](#iot-dc-prepare-device-sys-step3)。

## 将您的本地主机连接到设备上
<a name="iot-dc-prepare-device-sys-step3"></a>

此过程使用本地主机上的终端程序连接到 Raspberry Pi 上并更改原定设置密码。

**要将您的本地主机连接到设备上**

1. 

   在本地主机上打开 SSH 终端程序：
   + Windows：`PuTTY`
   + Linux/macOS：`Terminal`
**注意**  
在 Windows 上没有自动安装 PuTTY。如果计算机上没有，可能需要下载并安装它。

1. 将终端程序连接到 Raspberry Pi 的 IP 地址，然后使用原定设置凭据登录。

   ```
   username: pi
   password: raspberry
   ```

1. 登录 Raspberry Pi 后，请更改 `pi` 用户的密码。

   ```
   passwd
   ```

   按照提示更改密码。

   ```
   Changing password for pi.
   Current password: raspberry
   New password: YourNewPassword
   Retype new password: YourNewPassword
   passwd: password updated successfully
   ```

在终端窗口中有 Raspberry Pi 的命令行提示符并更改密码后，可以继续 [在设备上安装并验证所需的软件](iot-dc-prepare-device-sw.md)。

# 在设备上安装并验证所需的软件
<a name="iot-dc-prepare-device-sw"></a>

本节中的步骤从[上一节](iot-dc-prepare-device-sys.md)继续，以更新您的 Raspberry Pi 的操作系统，并将软件安装在 Raspberry Pi 上，下一节将使用该软件来构建和安装 AWS IoT 设备客户端。

完成本节后，您的 Raspberry Pi 将拥有 up-to-date操作系统、本学习路径中教程所需的软件，并将根据您的位置进行配置。

**所需的设备：**
+ [上一节](iot-dc-prepare-device-sys.md)中您的本地开发和测试环境
+ [上一节](iot-dc-prepare-device-sys.md)中您使用 的Raspberry Pi
+ [上一节](iot-dc-prepare-device-sys.md)中的 microSD 存储卡

**注意**  
Raspberry Pi Model 3\$1 和 Raspberry Pi Model 4 可以执行此学习路径中描述的所有命令。如果您的物联网设备无法编译软件或无法运行 AWS Command Line Interface，则可能需要在本地主机上安装所需的编译器来构建软件，然后将其传输到您的物联网设备。有关如何为设备安装和构建软件的更多信息，请参阅设备软件的文档。

**Topics**
+ [更新操作系统软件](#iot-dc-prepare-device-sw-step1)
+ [安装所需的应用程序和库](#iot-dc-prepare-device-sw-step2)
+ [（可选）保存 microSD 卡映像](#iot-dc-prepare-device-sw-step3)

## 更新操作系统软件
<a name="iot-dc-prepare-device-sw-step1"></a>

这一步骤会更新操作系统软件。

**要更新 Raspberry Pi 上的操作系统软件**

在本地主机的终端窗口中执行这些步骤。

1. 输入以下命令在您的 Raspberry Pi 上更新系统软件。

   ```
   sudo apt-get -y update
   sudo apt-get -y upgrade
   sudo apt-get -y autoremove
   ```

1. 更新 Raspberry Pi 的区域设置和时区设置（可选）。

   输入此命令可以更新设备的区域设置和时区设置。

   ```
   sudo raspi-config
   ```

   1. 要设置设备的区域：

      1. 在 **Raspberry Pi Software Configuration Tool（raspi-config）**（Raspberry Pi 软件配置工具（raspi-config））屏幕上，选择选项 **5**。

         **`5 Localisation Options Configure language and regional settings`**

         使用 Tab键移动到 **<Select>**，然后按 space bar。

      1. 在本地化选项菜单中，选择选项**L1**。

         **`L1 Locale Configure language and regional settings`**

         使用 Tab键移动到 **<Select>**，然后按 space bar。

      1. 在区域设置选项列表中，使用箭头键滚动并选择要在 Raspberry Pi 上安装的语言环境 space bar来标记您想要的选项。

         在美国，**`en_US.UTF-8`** 是一个很好的选择。

      1. 为设备选择语言环境后，请使用 Tab 键来选择**<OK>**，然后按 space bar 显示**配置区域设置**的确认页面。

   1. 要设置设备的时区：

      1. 在 **aspi-config** 屏幕，选择选项 **5**。

         **`5 Localisation Options Configure language and regional settings`**

         使用 Tab键移动到 **<Select>**，然后按 space bar。

      1. 在本地化选项菜单中，使用箭头键选择选项 **L2**：

         **`L2 time zone Configure time zone`**

         使用 Tab键移动到 **<Select>**，然后按 space bar。

      1. 在**配置 tzdata**菜单中，从列表中选择您的地理区域。

         使用 Tab 键移动到 **<OK>**，然后按 space bar。

      1. 在城市列表中，使用箭头键选择时区内的城市。

         使要设置时区，用 Tab 键移动到 **<OK>**，然后按 space bar。

   1. 更新完设置后，用 Tab 键移动到**<Finish>**，然后按 space bar 关闭 **aspi-config**应用程序。

1. 输入此命令可重启您的 Raspberry Pi。

   ```
   sudo shutdown -r 0
   ```

1. 等您的 Raspberry Pi 重启。

1. 重新启动 Raspberry Pi 后，将本地主机上的终端窗口重新连接到 Raspberry Pi。

您的 Raspberry Pi 系统软件现已配置完毕，您已准备好继续 [安装所需的应用程序和库](#iot-dc-prepare-device-sw-step2)。

## 安装所需的应用程序和库
<a name="iot-dc-prepare-device-sw-step2"></a>

此过程将安装后续教程使用的应用程序软件和库。

如果您使用的是 Raspberry Pi，或可以在物联网设备上编译所需的软件，请在本地主机上的终端窗口中执行以下步骤。如果必须在本地主机上为物联网设备编译软件，请查看物联网设备的软件文档，了解有关如何在设备上执行这些步骤的信息。

**在 Raspberry Pi 上安装应用程序软件和库**

1. 输入此命令安装应用程序软件和库。

   ```
   sudo apt-get -y install build-essential libssl-dev cmake unzip git python3-pip
   ```

1. 输入这些命令来确认安装了正确版本的软件。

   ```
   gcc --version
   cmake --version
   openssl version
   git --version
   ```

1. 

   确认已安装以下版本的应用程序软件：
   + `gcc`：9.3.0 或更高版本
   + `cmake`：3.10.x 或更高版本
   + `OpenSSL`：1.1.1 或更高版本
   + `git`：2.20.1 或更高版本

如果您的Raspberry Pi拥有所需应用程序软件的可接受版本，您准备好继续 [（可选）保存 microSD 卡映像](#iot-dc-prepare-device-sw-step3)。

## （可选）保存 microSD 卡映像
<a name="iot-dc-prepare-device-sw-step3"></a>

在本学习路径中的整个教程中，您会遇到这些过程，将 Raspberry Pi 的 microSD 卡映像的副本保存到本地主机上的文件中。尽管鼓励这样做，但不是必需的任务。通过在建议的位置保存 microSD 卡映像，您可以跳过此学习路径中保存点之前的过程，如果发现需要重试某些内容，这可以节省时间。不定期保存 microSD 卡映像的后果是，如果 microSD 卡损坏或者不小心配置了应用程序或其设置错误，可能必须从头开始重新启动学习路径中的教程。

此时，Raspberry Pi 的 microSD 卡具有更新的操作系统和基本的应用程序软件加载。现在，您可以通过将 microSD 卡的内容保存到文件中来节省完成上述步骤所花的时间。采用拥有设备 microSD 卡映像的当前映像，您可以从这一点开始继续或重试教程或程序，无需从头开始安装和更新软件。

**要将 microSD 卡映像保存到文件中**

1. 输入此命令关闭 Raspberry Pi。

   ```
   sudo shutdown -h 0
   ```

1. Raspberry Pi 完全关闭后，请移除电源。

1. 从 Raspberry Pi 中取出 microSD 卡。

1. 在本地主机上：

   1. 插入 microSD 卡。

   1. 使用 SD 卡成像工具，将 microSD 卡映像保存到文件中。

   1. 保存 microSD 卡映像后，从本地主机上弹出该卡。

1. 从 Raspberry Pi 断开电源后，将 microSD 卡插入 Raspberry Pi。

1. 给 Raspberry Pi 供电。

1. 等待大约一分钟后，在本地主机上重新连接已连接到 Raspberry Pi 的本地主机上的终端窗口，然后登录 Raspberry Pi。

# 测试您的设备并保存 Amazon CA 证书
<a name="iot-dc-prepare-device-test"></a>

本节中的步骤从[上一节](iot-dc-prepare-device-sw.md)继续，安装 AWS Command Line Interface 和用于对连接进行身份验证的证书颁发机构证书 AWS IoT Core。

完成本节后，您将知道您的 Raspberry Pi 拥有安装 AWS IoT 设备客户端所需的系统软件，并且可以正常连接到互联网。

**所需的设备：**
+ [上一节](iot-dc-prepare-device-sw.md)中您的本地开发和测试环境
+ [上一节](iot-dc-prepare-device-sw.md)中您使用 的Raspberry Pi
+ [上一节](iot-dc-prepare-device-sw.md)中的 microSD 存储卡

**Topics**
+ [安装 AWS Command Line Interface](#iot-dc-prepare-device-test-step1)
+ [配置您的 AWS 账户 凭证](#iot-dc-prepare-device-test-step2)
+ [下载 Amazon Root CA 证书](#iot-dc-prepare-device-test-step3)
+ [（可选）保存 microSD 卡映像](#iot-dc-prepare-device-test-step4)

## 安装 AWS Command Line Interface
<a name="iot-dc-prepare-device-test-step1"></a>

此过程将安装 AWS CLI 到您的 Raspberry Pi 上。

如果您使用的是 Raspberry Pi 或者可以在物联网设备上编译软件，请在本地主机上的终端窗口中执行以下步骤。如果必须在本地主机上为物联网设备编译软件，请查看物联网设备的软件文档，了解所需库的信息。

**要在你的 Raspberry Pi AWS CLI 上安装**

1. 运行以下命令下载和并按照安装 AWS CLI。

   ```
   export PATH=$PATH:~/.local/bin # configures the path to include the directory with the AWS CLI
   git clone https://github.com/aws/aws-cli.git # download the AWS CLI code from GitHub
   cd aws-cli && git checkout v2 # go to the directory with the repo and checkout version 2
   pip3 install -r requirements.txt # install the prerequisite software
   ```

1. 运行此命令来安装 AWS CLI。完成此命令可能最多需要 15 分钟。

   ```
   pip3 install . # install the AWS CLI 
   ```

1. 运行此命令以确认安装的版本是否正确。 AWS CLI 

   ```
   aws --version
   ```

   的版本 AWS CLI 应为 2.2 或更高版本。

如果 AWS CLI 显示的是当前版本，则表示您已准备好继续[配置您的 AWS 账户 凭证](#iot-dc-prepare-device-test-step2)。

## 配置您的 AWS 账户 凭证
<a name="iot-dc-prepare-device-test-step2"></a>

在此过程中，您将获取 AWS 账户 凭证并将其添加到 Raspberry Pi 上使用。

**将您的 AWS 账户 凭证添加到您的设备**

1. 从您那里获取**访问密钥 ID** 和**私有访问密钥** AWS 账户 ，以便 AWS CLI 在您的设备上对其进行身份验证。

   如果您不熟悉 AWS IAM，Kn [ https://aws.amazon.com/premiumsupport/owledge-centercreate-access-key/](https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/)将介绍在 AWS 控制台中运行的创建要在设备上使用 AWS 的 IAM 证书的过程。

1. 在连接到 Raspberry Pi 的本地主机上的终端窗口中。并使用设备的**访问密钥 ID** 和**密钥访问密钥**凭据：

   1. 使用以下命令运行 AWS 配置应用程序：

      ```
      aws configure
      ```

   1. 出现提示时，输入您的 凭据和配置信息：

      ```
      AWS Access Key ID: your Access Key ID
      AWS Secret Access Key: your Secret Access Key
      Default region name: your AWS 区域 code
      Default output format: json
      ```

1. 运行此命令以测试您的设备对您的 AWS 账户 和 AWS IoT Core 端点的访问权限。

   ```
   aws iot describe-endpoint --endpoint-type iot:Data-ATS
   ```

   它应该返回您的 AWS 账户特定 AWS IoT 数据端点，例如以下示例：

   ```
   {
       "endpointAddress": "a3EXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

如果您看到自己的 AWS 账户特定 AWS IoT 数据端点，则表示您的 Raspberry Pi 具有继续[下载 Amazon Root CA 证书](#iot-dc-prepare-device-test-step3)访问的连接和权限。

**重要**  
你的 AWS 账户 凭证现在存储在 Raspberry Pi 的 microSD 卡上。虽然这使你将来可以 AWS 轻松地与你在这些教程中创建的软件进行交互，但默认情况下，它们也将被保存并复制到你在此步骤之后制作的任何 microSD 卡图像中。  
为了保护 AWS 账户 凭证的安全，在保存更多 microSD 卡映像之前，请考虑`aws configure`重新运行并输入访问密**钥 ID 和**私有访问密**钥**的随机字符来擦除凭证，以防止您的 AWS 账户 凭据被泄露。  
如果您发现自己无意中保存了 AWS 账户 证书，则可以在 IAM 控制台中将其停用。 AWS 

## 下载 Amazon Root CA 证书
<a name="iot-dc-prepare-device-test-step3"></a>

此过程下载并保存 Amazon Root 证书颁发机构（CA）的证书副本。下载此证书可保存以供后续教程中使用，还可测试设备与 AWS 服务的连接。

**要下载并保存 Amazon Root CA 证书**

1. 运行以下命令为证书创建一个目录。

   ```
   mkdir ~/certs
   ```

1. 运行此命令下载 Amazon Root CA 证书。

   ```
   curl -o ~/certs/AmazonRootCA1.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem
   ```

1. 运行这些命令设置对证书目录及其文件的访问权限。

   ```
   chmod 745 ~
   chmod 700 ~/certs
   chmod 644 ~/certs/AmazonRootCA1.pem
   ```

1. 运行此命令查看新目录中的 CA 证书文件。

   ```
   ls -l ~/certs
   ```

   您会看到如下条目。日期和时间会有所不同；但是，文件大小和所有其他信息应与此处显示的相同。

   ```
   -rw-r--r-- 1 pi pi 1188 Oct 28 13:02 AmazonRootCA1.pem
   ```

   如果文件大小不是 `1188`，检查 **curl** 命令参数。您可能下载了错误的文件。

## （可选）保存 microSD 卡映像
<a name="iot-dc-prepare-device-test-step4"></a>

此时，Raspberry Pi 的 microSD 卡具有更新的操作系统和基本的应用程序软件加载。

**要将 microSD 卡映像保存到文件中**

1. 在本地主机上的终端窗口中，清除 AWS 凭证。

   1. 使用以下命令运行 AWS 配置应用程序：

      ```
      aws configure
      ```

   1. 出现提示时，替换凭证。您可以离开**原定设置区域名称**和**原定设置输出格式**，因为它们是通过按**Enter**（输入）。

      ```
      AWS Access Key ID [****************YT2H]: XYXYXYXYX
      AWS Secret Access Key [****************9plH]: XYXYXYXYX
      Default region name [us-west-2]: 
      Default output format [json]:
      ```

1. 输入此命令关闭 Raspberry Pi。

   ```
   sudo shutdown -h 0
   ```

1. Raspberry Pi 完全关闭后，卸下其电源接头。

1. 从设备中取出 microSD 卡。

1. 在本地主机上：

   1. 插入 microSD 卡。

   1. 使用 SD 卡成像工具，将 microSD 卡映像保存到文件中。

   1. 保存 microSD 卡映像后，从本地主机上弹出该卡。

1. 从 Raspberry Pi 断开电源后，将 microSD 卡插入 Raspberry Pi。

1. 对设备供电。

1. 大约一分钟后，在本地主机上重新启动终端窗口会话并登录到设备。

   **暂时不要重新输入您的 AWS 账户 凭证。**

重新启动并登录 Raspberry Pi 之后，您准备好继续 [教程：安装和配置 AWS IoT 设备客户端](iot-dc-install-dc.md)。

# 教程：安装和配置 AWS IoT 设备客户端
<a name="iot-dc-install-dc"></a>

本教程将引导您完成 AWS IoT 设备客户端的安装和配置，以及创建将在本演示和其他演示中使用的 AWS IoT 资源。

**要开始本教程：**
+ 准备好您的本地主机和[上一教程](iot-dc-prepare-device.md)中的 Raspberry Pi。

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

**完成本主题后：**
+ 您的物联网设备将准备好在其他 AWS IoT 设备客户端演示中使用。
+ 您将在中配置您的物联网设备。 AWS IoT Core
+ 您将在设备上下载并安装 AWS IoT 设备客户端。
+ 您将保存设备 microSD 卡的映像，可在后续教程中使用。

**所需的设备：**
+ [上一节](iot-dc-prepare-device-test.md)中您的本地开发和测试环境
+ [上一节](iot-dc-prepare-device-test.md)中您使用 的Raspberry Pi
+ [上一节](iot-dc-prepare-device-test.md)中您使用的 Raspberry Pi microSD 记忆卡

**Topics**
+ [下载并保存 AWS IoT 设备客户端](iot-dc-install-download.md)
+ [在中配置你的树莓派 AWS IoT](iot-dc-install-provision.md)
+ [配置 AWS IoT 设备客户端以测试连通性](iot-dc-install-configure.md)

# 下载并保存 AWS IoT 设备客户端
<a name="iot-dc-install-download"></a>

本节中的步骤下载 AWS IoT 设备客户端，对其进行编译，然后将其安装到您的 Raspberry Pi 上。测试安装后，您可以保存 Raspberry Pi的 microSD卡映像，以便以后需要再次尝试教程时使用。

**Topics**
+ [下载并构建 AWS IoT 设备客户端](#iot-dc-install-dc-download)
+ [创建教程使用的目录](#iot-dc-install-dc-files)
+ [（可选）保存 microSD 卡映像](#iot-dc-install-dc-save)

## 下载并构建 AWS IoT 设备客户端
<a name="iot-dc-install-dc-download"></a>

此过程将 AWS IoT 设备客户端安装到您的 Raspberry Pi 上。

在连接到 Raspberry Pi 的本地主机上的终端窗口中执行这些命令。

**在 Raspberry Pi 上安装 AWS IoT 设备客户端**

1. 输入这些命令在 Raspberry Pi 上下载和构建 AWS IoT 设备客户端。

   ```
   cd ~
   git clone https://github.com/awslabs/aws-iot-device-client aws-iot-device-client
   mkdir ~/aws-iot-device-client/build && cd ~/aws-iot-device-client/build
   cmake ../
   ```

1. 运行此命令来构建 AWS IoT 设备客户端。完成此命令可能最多需要 15 分钟。

   ```
   cmake --build . --target aws-iot-device-client
   ```

   可以忽略 AWS IoT 设备客户端编译时显示的警告消息。

   这些教程已在 2021 年 10 月 30 日的 Raspberry Pi 操作系统（buster）版本上**gcc**使用内置的 AWS IoT 设备客户端（Raspbian 10.2.1-6\$1rpi1）10.2.1 20210110 进行了测试，版本为（Raspbian 8.3.0-6\$1rpi1）8.3.0。**gcc**

1.  AWS IoT 设备客户端构建完成后，通过运行此命令对其进行测试。

   ```
   ./aws-iot-device-client --help
   ```

如果您看到 AWS IoT 设备客户端的命令行帮助，则 AWS IoT 表示设备客户端已成功构建并可供您使用。

## 创建教程使用的目录
<a name="iot-dc-install-dc-files"></a>

此过程将在 Raspberry Pi 上创建目录，用于存储教程在此学习路径中使用的文件。

**要在此学习路径中创建教程使用的目录，请执行以下操作：**

1. 运行这些命令创建所需的目录。

   ```
   mkdir ~/dc-configs
   mkdir ~/policies
   mkdir ~/messages
   mkdir ~/certs/testconn
   mkdir ~/certs/pubsub
   mkdir ~/certs/jobs
   ```

1. 运行这些命令设置新目录的权限。

   ```
   chmod 745 ~
   chmod 700 ~/certs/testconn
   chmod 700 ~/certs/pubsub
   chmod 700 ~/certs/jobs
   ```

创建这些目录并设置权限后，请继续 [（可选）保存 microSD 卡映像](#iot-dc-install-dc-save)。

## （可选）保存 microSD 卡映像
<a name="iot-dc-install-dc-save"></a>

此时，你的 Raspberry Pi 的 microSD 卡已经更新了操作系统、基本应用软件和 AWS IoT 设备客户端。

如果您想再次尝试这些练习和教程，可以跳过前面的步骤，使用此步骤保存的 microSD 卡映像写入新的 microSD 卡，然后在 [在中配置你的树莓派 AWS IoT](iot-dc-install-provision.md) 中继续教程。

**要将 microSD 卡映像保存到文件中，请执行以下操作：**

在连接到 Raspberry Pi 的本地主机的终端窗口中：

1. 确认您的 AWS 账户 凭证尚未存储。

   1. 使用以下命令运行 AWS 配置应用程序：

      ```
      aws configure
      ```

   1. 如果您的凭据已存储（如果出现在提示中），输入 **XYXYXYXYX** 字符串在提示时，如下所示。保持**原定设置区域名称**和**原定设置输出格式**空白。

      ```
      AWS Access Key ID [****************YXYX]: XYXYXYXYX
      AWS Secret Access Key [****************YXYX]: XYXYXYXYX
      Default region name: 
      Default output format:
      ```

1. 输入此命令关闭 Raspberry Pi。

   ```
   sudo shutdown -h 0
   ```

1. Raspberry Pi 完全关闭后，卸下其电源接头。

1. 从设备中取出 microSD 卡。

1. 在本地主机上：

   1. 插入 microSD 卡。

   1. 使用 SD 卡成像工具，将 microSD 卡映像保存到文件中。

   1. 保存 microSD 卡的映像后，从本地主机上弹出该卡。

您可以继续使用这张 microSD 卡在 [在中配置你的树莓派 AWS IoT](iot-dc-install-provision.md) 中操作。

# 在中配置你的树莓派 AWS IoT
<a name="iot-dc-install-provision"></a>

本节中的步骤从安装了 AWS CLI 和 AWS IoT 设备客户端的保存的 microSD 映像开始，然后创建用于配置 Raspberry Pi 的 AWS IoT 资源和设备证书。 AWS IoT

## 在您的 Raspberry Pi 中安装 microSD 卡
<a name="iot-dc-install-dc-restore"></a>

此过程将 microSD 卡安装在 Raspberry Pi 中已加载和配置的必要软件，并对其进行配置， AWS 账户 以便您可以继续学习本学习路径中的教程。

使用来自 [（可选）保存 microSD 卡映像](iot-dc-install-download.md#iot-dc-install-dc-save) 的 microSD 卡，其中有这个学习路径中进行练习和教程的必要软件。

**要在您的 Raspberry Pi 中安装 microSD 卡**

1. 从 Raspberry Pi 断电后，将 microSD 卡插入 Raspberry Pi。

1. 给 Raspberry Pi 供电。

1. 大约一分钟后，在本地主机上重新启动终端窗口会话并登录 Raspberry Pi。

1. 在本地主机上、终端窗口中以及**访问密钥 ID**和您的 Raspberry Pi 上的**密钥访问密钥**凭证：

   1. 使用以下命令运行 AWS 配置应用程序：

      ```
      aws configure
      ```

   1. 出现提示时，输入您的 AWS 账户 凭据和配置信息：

      ```
      AWS Access Key ID [****************YXYX]: your Access Key ID
      AWS Secret Access Key [****************YXYX]: your Secret Access Key
      Default region name [us-west-2]: your AWS 区域 code
      Default output format [json]: json
      ```

恢复 AWS 账户 凭证后，就可以继续操作了[在中配置您的设备 AWS IoT Core](#iot-dc-install-dc-provision)。

## 在中配置您的设备 AWS IoT Core
<a name="iot-dc-install-dc-provision"></a>

本节中的步骤创建了在中配置 Raspberry Pi 的 AWS IoT 资源 AWS IoT。创建这些资源时，系统将要求您记录各种信息。 AWS IoT 设备客户端配置将在下一个步骤中使用此信息。

要使用你的 Raspberry Pi AWS IoT，必须对其进行配置。配置是创建和配置支持你的 Raspberry Pi 作为物联网设备所需的 AWS IoT 资源的过程。

启动并重新启动 Raspberry Pi 后，将本地主机上的终端窗口连接到 Raspberry Pi 上并完成这些步骤。

**Topics**
+ [创建并下载设备证书文件](#iot-dc-install-dc-provision-certs)
+ [创建 AWS IoT 资源](#iot-dc-install-dc-provision-resources)

### 创建并下载设备证书文件
<a name="iot-dc-install-dc-provision-certs"></a>

此过程为此演示创建设备证书文件。

**要为 Raspberry Pi 创建和下载设备证书文件**

1. 在本地主机的终端窗口中，输入这些命令为您的设备创建设备证书文件。

   ```
   mkdir ~/certs/testconn
   aws iot create-keys-and-certificate \
   --set-as-active \
   --certificate-pem-outfile "~/certs/testconn/device.pem.crt" \
   --public-key-outfile "~/certs/testconn/public.pem.key" \
   --private-key-outfile "~/certs/testconn/private.pem.key"
   ```

   此命令会返回类似以下内容的响应。记录 `certificateArn`值以供将来使用。

   ```
   {
       "certificateArn": "arn:aws:iot:us-west-2:57EXAMPLE833:cert/76e7e4edb3e52f52334be2f387a06145b2aa4c7fcd810f3aea2d92abc227d269",
       "certificateId": "76e7e4edb3e52f5233EXAMPLE7a06145b2aa4c7fcd810f3aea2d92abc227d269",
       "certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDWTCCAkGgAwIBAgI_SHORTENED_FOR_EXAMPLE_Lgn4jfgtS\n-----END CERTIFICATE-----\n",
       "keyPair": {
           "PublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BA_SHORTENED_FOR_EXAMPLE_ImwIDAQAB\n-----END PUBLIC KEY-----\n",
           "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQE_SHORTENED_FOR_EXAMPLE_T9RoDiukY\n-----END RSA PRIVATE KEY-----\n"
       }
   }
   ```

1. 输入以下命令设置证书目录及其文件的权限。

   ```
   chmod 745 ~
   chmod 700 ~/certs/testconn
   chmod 644 ~/certs/testconn/*
   chmod 600 ~/certs/testconn/private.pem.key
   ```

1. 运行此命令可查看证书目录和文件的权限。

   ```
   ls -l ~/certs/testconn
   ```

   命令的输出应与您在此处看到的内容相同，但文件日期和时间会有所不同。

   ```
   -rw-r--r-- 1 pi pi 1220 Oct 28 13:02 device.pem.crt
   -rw------- 1 pi pi 1675 Oct 28 13:02 private.pem.key
   -rw-r--r-- 1 pi pi  451 Oct 28 13:02 public.pem.key
   ```

此时，您已经在 Raspberry Pi 上安装了设备证书文件，可以继续 [创建 AWS IoT 资源](#iot-dc-install-dc-provision-resources)。

### 创建 AWS IoT 资源
<a name="iot-dc-install-dc-provision-resources"></a>

此过程 AWS IoT 通过创建设备访问 AWS IoT 功能和服务所需的资源来配置您的设备。

**要在中配置您的设备 AWS IoT**

1. 在本地主机的终端窗口中，输入以下命令获取您的 AWS 账户设备数据端点的地址。

   ```
   aws iot describe-endpoint --endpoint-type IoT:Data-ATS
   ```

   上面步骤的命令会返回类似以下内容的响应。记录 `endpointAddress`值以供将来使用。

   ```
   {
       "endpointAddress": "a3qjEXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

1. 输入此命令为您的 Raspberry Pi 创建 AWS IoT 事物资源。

   ```
   aws iot create-thing --thing-name "DevCliTestThing"
   ```

   如果您的 AWS IoT 事物资源已创建，则该命令会返回这样的响应。

   ```
   {
       "thingName": "DevCliTestThing",
       "thingArn": "arn:aws:iot:us-west-2:57EXAMPLE833:thing/DevCliTestThing",
       "thingId": "8ea78707-32c3-4f8a-9232-14bEXAMPLEfd"
   }
   ```

1. 在终端窗口中：

   1. 打开文本编辑器，例如 `nano`。

   1. 复制此 JSON 策略文档并将其粘贴到打开的文本编辑器中。  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish",
                      "iot:Subscribe",
                      "iot:Receive",
                      "iot:Connect"
                  ],
                  "Resource": [
                      "*"
                  ]
              }
          ]
      }
      ```
**注意**  
本策略文档慷慨授予每个资源连接、接收、发布和订阅的权限。通常，策略仅向特定资源授予权限执行特定操作。但是，对于初始设备连通性测试，这种过于笼统和宽容的策略用于尽量减少测试期间出现访问问题的可能性。在随后的教程中，将使用范围更窄的策略文档来展示策略设计中的更好做法。

   1. 将文本编辑器中的文件保存为 **\$1/policies/dev\$1cli\$1test\$1thing\$1policy.json**。

1. 运行此命令使用前面步骤中的策略文档来创建 AWS IoT 策略。

   ```
   aws iot create-policy \
   --policy-name "DevCliTestThingPolicy" \
   --policy-document "file://~/policies/dev_cli_test_thing_policy.json"
   ```

   如果创建策略，该命令将返回类似此类的响应。

   ```
   {
       "policyName": "DevCliTestThingPolicy",
       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/DevCliTestThingPolicy",
       "policyDocument": "{\n    \"Version\": \"2012-10-17\",		 	 	 \n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"iot:Publish\",\n                \"iot:Subscribe\",\n                \"iot:Receive\",\n                \"iot:Connect\"\n            ],\n            \"Resource\": [\n                \"*\"\n            ]\n        }\n    ]\n}\n",
       "policyVersionId": "1"
   }
   ```

1. 运行此命令将策略附加到设备证书。将 `certificateArn`替换为 您之前保存的 `certificateArn`值。

   ```
   aws iot attach-policy \
   --policy-name "DevCliTestThingPolicy" \
   --target "certificateArn"
   ```

   如果成功，该命令不返回任何内容。

1. 运行此命令将设备证书附加到 AWS IoT 事物资源。将 `certificateArn`替换为 您之前保存的 `certificateArn`值。

   ```
   aws iot attach-thing-principal \
   --thing-name "DevCliTestThing" \
   --principal "certificateArn"
   ```

   如果成功，该命令不返回任何内容。

在中成功配置设备后 AWS IoT，就可以继续[配置 AWS IoT 设备客户端以测试连通性](iot-dc-install-configure.md)操作了。

# 配置 AWS IoT 设备客户端以测试连通性
<a name="iot-dc-install-configure"></a>

本节中的步骤将 AWS IoT 设备客户端配置为从您的 Raspberry Pi 发布 MQTT 消息。

**Topics**
+ [创建配置文件](#iot-dc-install-dc-configure-step1)
+ [打开 MQTT 测试客户端](#iot-dc-install-dc-configure-step2)
+ [运行 AWS IoT 设备客户端](#iot-dc-install-dc-configure-step3)

## 创建配置文件
<a name="iot-dc-install-dc-configure-step1"></a>

此过程创建配置文件来测试 AWS IoT 设备客户端。

**创建用于测试 AWS IoT 设备客户端的配置文件**
+ 在连接到 Raspberry Pi 的本地主机的终端窗口中：

  1. 输入这些命令为配置文件创建目录并设置对该目录的权限：

     ```
     mkdir ~/dc-configs
     chmod 745 ~/dc-configs
     ```

  1. 打开文本编辑器，例如 `nano`。

  1. 复制此 JSON 文档并将其粘贴到打开的文本编辑器中。

     ```
     {
       "endpoint": "a3qEXAMPLEaffp-ats.iot.us-west-2.amazonaws.com",
       "cert": "~/certs/testconn/device.pem.crt",
       "key": "~/certs/testconn/private.pem.key",
       "root-ca": "~/certs/AmazonRootCA1.pem",
       "thing-name": "DevCliTestThing",
       "logging": {
         "enable-sdk-logging": true,
         "level": "DEBUG",
         "type": "STDOUT",
         "file": ""
       },
       "jobs": {
         "enabled": false,
         "handler-directory": ""
       },
       "tunneling": {
         "enabled": false
       },
       "device-defender": {
         "enabled": false,
         "interval": 300
       },
       "fleet-provisioning": {
         "enabled": false,
         "template-name": "",
         "template-parameters": "",
         "csr-file": "",
         "device-key": ""
       },
       "samples": {
         "pub-sub": {
           "enabled": true,
           "publish-topic": "test/dc/pubtopic",
           "publish-file": "",
           "subscribe-topic": "test/dc/subtopic",
           "subscribe-file": ""
         }
       },
       "config-shadow": {
         "enabled": false
       },
       "sample-shadow": {
         "enabled": false,
         "shadow-name": "",
         "shadow-input-file": "",
         "shadow-output-file": ""
       }
     }
     ```

  1. 将该*endpoint*值替换为您在中找到的设备数据端点[在中配置您的设备 AWS IoT Core](iot-dc-install-provision.md#iot-dc-install-dc-provision)。 AWS 账户 

  1. 将文本编辑器中的文件保存为 **\$1/dc-configs/dc-testconn-config.json**。

  1. 运行这个命令在新文件上设置权限

     ```
     chmod 644 ~/dc-configs/dc-testconn-config.json
     ```

保存文件后，您已准备就绪继续 [打开 MQTT 测试客户端](#iot-dc-install-dc-configure-step2)。

## 打开 MQTT 测试客户端
<a name="iot-dc-install-dc-configure-step2"></a>

此过程使 AWS IoT 控制台中的 **MQTT 测试客户端**做好订阅 AWS IoT 设备客户端运行时发布的 MQTT 消息的准备。

**准备 **MQTT 测试客户端**订阅所有 MQTT 消息**

1. 在本地主机上，在[AWS IoT 控制台](https://console.aws.amazon.com//iot/home#/test)，选择**MQTT 测试客户端**。

1. 在**订阅主题**选项卡的**主题筛选条件**中输入 **\$1**（单个井号），然后选择**订阅**来订阅每个 MQTT 主题。

1. 在**订阅**标签下，确认您看见 **\$1**（单个井号）。

让窗口的 **MQTT 测试客户端** 保持打开，继续 [运行 AWS IoT 设备客户端](#iot-dc-install-dc-configure-step3)。

## 运行 AWS IoT 设备客户端
<a name="iot-dc-install-dc-configure-step3"></a>

此过程运行 AWS IoT 设备客户端，以便它发布一条 MQTT **测试客户端接收并显示的 MQTT** 消息。

**从 AWS IoT 设备客户端发送 MQTT 消息**

1. 在执行此步骤时，确保连接到 Raspberry Pi 的终端窗口和带 **MQTT 测试客户端**可见。

1. 在终端窗口中，输入这些命令以使用中创建的配置文件运行 AWS IoT 设备客户端[创建配置文件](#iot-dc-install-dc-configure-step1)。

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-testconn-config.json
   ```

   在终端窗口中， AWS IoT 设备客户端显示信息消息以及运行时出现的任何错误。

   如果终端窗口中没有显示错误，请查看 **MQTT 测试客户端**。

1. 在 **MQTT 测试客户端**的“订阅”窗口中，查看发送到 `test/dc/pubtopic` 消息主题的 *Hello World\$1* 消息。

1. 如果 AWS IoT 设备客户端没有显示任何错误并且你看到 *Hello World！* 发送到 **MQTT 测试客户端**中的`test/dc/pubtopic`消息时，您已演示连接成功。

1. 在终端窗口中，输入 **^C** (Ctrl-C) 以停止 AWS IoT 设备客户端。

在您证明 AWS IoT 设备客户端在 Raspberry Pi 上运行正常，并且可以与之通信之后 AWS IoT，您可以继续[教程：演示与 AWS IoT 设备客户端的 MQTT 消息通信](iot-dc-testconn.md)。

# 教程：演示与 AWS IoT 设备客户端的 MQTT 消息通信
<a name="iot-dc-testconn"></a>

本教程演示 AWS IoT 设备客户端如何订阅和发布物联网解决方案中常用的 MQTT 消息。

**要开始本教程：**
+ 将本地主机和 Raspberry Pi 配置为在[上一节](iot-dc-install-dc.md)使用。

  如果您在安装 AWS IoT 设备客户端后保存了 microSD 卡映像，则可以将带有该图像的 microSD 卡与 Raspberry Pi 一起使用。
+ 如果您之前运行过此演示，[第 2 步：使用 AWS IoT 设备客户端 AWS 账户 在构建演示之后清理你的](iot-dc-cleanup.md#iot-dc-cleanup-cloud)请查看删除您在之前运行中创建的所有 AWS IoT 资源，以避免出现重复的资源错误。

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

**完成本主题后：**
+ 您将演示物联网设备订阅 MQTT 消息 AWS IoT 并向其发布 MQTT 消息的不同方式。 AWS IoT

**所需的设备：**
+ [上一节](iot-dc-install-dc.md)中您的本地开发和测试环境
+ [上一节](iot-dc-install-dc.md)中您使用 的Raspberry Pi
+ [上一节](iot-dc-install-dc.md)中您使用的 Raspberry Pi microSD 记忆卡

**Topics**
+ [准备 Raspberry Pi 来演示 MQTT 消息通信](iot-dc-testconn-provision.md)
+ [演示使用 AWS IoT 设备客户端发布消息](iot-dc-testconn-publish.md)
+ [演示使用 AWS IoT 设备客户端订阅消息](iot-dc-testconn-subscribe.md)

# 准备 Raspberry Pi 来演示 MQTT 消息通信
<a name="iot-dc-testconn-provision"></a>

此过程在 Raspberry Pi 中 AWS IoT 和中创建资源，以演示使用 AWS IoT 设备客户端进行 MQTT 消息通信。

**Topics**
+ [创建证书文件演示 MQTT 通信](#iot-dc-testconn-provision-certs)
+ [预调配您的设备演示 MQTT 通信](#iot-dc-testconn-provision-aws)
+ [配置 AWS IoT 设备客户端配置文件和 MQTT 测试客户端，演示 MQTT 通信](#iot-dc-testconn-provision-dc-config)

## 创建证书文件演示 MQTT 通信
<a name="iot-dc-testconn-provision-certs"></a>

此过程为此演示创建设备证书文件。

**要为 Raspberry Pi 创建和下载设备证书文件**



1. 在本地主机的终端窗口中，输入以下命令为您的设备创建设备证书文件。

   ```
   mkdir ~/certs/pubsub
   aws iot create-keys-and-certificate \
   --set-as-active \
   --certificate-pem-outfile "~/certs/pubsub/device.pem.crt" \
   --public-key-outfile "~/certs/pubsub/public.pem.key" \
   --private-key-outfile "~/certs/pubsub/private.pem.key"
   ```

   此命令会返回类似以下内容的响应。保存 `certificateArn`值供稍后使用。

   ```
   {
   "certificateArn": "arn:aws:iot:us-west-2:57EXAMPLE833:cert/76e7e4edb3e52f52334be2f387a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificateId": "76e7e4edb3e52f5233EXAMPLE7a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDWTCCAkGgAwIBAgI_SHORTENED_FOR_EXAMPLE_Lgn4jfgtS\n-----END CERTIFICATE-----\n",
   "keyPair": {
       "PublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BA_SHORTENED_FOR_EXAMPLE_ImwIDAQAB\n-----END PUBLIC KEY-----\n",
       "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQE_SHORTENED_FOR_EXAMPLE_T9RoDiukY\n-----END RSA PRIVATE KEY-----\n"
   }
   }
   ```

1. 输入以下命令设置证书目录及其文件的权限。

   ```
   chmod 700 ~/certs/pubsub
   chmod 644 ~/certs/pubsub/*
   chmod 600 ~/certs/pubsub/private.pem.key
   ```

1. 运行此命令可查看证书目录和文件的权限。

   ```
   ls -l ~/certs/pubsub
   ```

   命令的输出应与您在此处看到的内容相同，但文件日期和时间会有所不同。

   ```
   -rw-r--r-- 1 pi pi 1220 Oct 28 13:02 device.pem.crt
   -rw------- 1 pi pi 1675 Oct 28 13:02 private.pem.key
   -rw-r--r-- 1 pi pi  451 Oct 28 13:02 public.pem.key
   ```

1. 输入这些命令创建日志文件的目录。

   ```
   mkdir ~/.aws-iot-device-client
   mkdir ~/.aws-iot-device-client/log
   chmod 745 ~/.aws-iot-device-client/log
   echo " " > ~/.aws-iot-device-client/log/aws-iot-device-client.log
   echo " " > ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   chmod 600 ~/.aws-iot-device-client/log/*
   ```

## 预调配您的设备演示 MQTT 通信
<a name="iot-dc-testconn-provision-aws"></a>

本节创建了在中配置 Raspberry Pi 的 AWS IoT 资源 AWS IoT。

**在 AWS IoT中预置您的设备：**

1. 在本地主机的终端窗口中，输入以下命令获取您的 AWS 账户设备数据端点的地址。

   ```
   aws iot describe-endpoint --endpoint-type IoT:Data-ATS
   ```

   自从您为上一教程运行此命令以来，端点值一直没有更改。再次在此处运行命令是为了方便地查找数据端点值并将其粘贴到本教程中使用的配置文件中。

   上面步骤的命令会返回类似以下内容的响应。记录 `endpointAddress`值以供将来使用。

   ```
   {
   "endpointAddress": "a3qjEXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

1. 输入此命令为您的 Raspberry Pi 创建新 AWS IoT 事物资源。

   ```
   aws iot create-thing --thing-name "PubSubTestThing"
   ```

   由于 AWS IoT 事物资源是您的设备在云中的*虚拟*表示，因此我们可以创建多个事物资源 AWS IoT 以用于不同的目的。它们都可以由同一物理 IoT 设备使用来表示设备的不同方面。

   这些教程一次只能使用一个事物资源来表示 Raspberry Pi。这样，在这些教程中，它们代表了不同的演示，因此在为演示创建 AWS IoT 资源之后，您可以返回并使用专门为每个演示创建的资源重复演示。

   如果您的 AWS IoT 事物资源已创建，则该命令会返回类似这样的响应。

   ```
   {
   "thingName": "PubSubTestThing",
   "thingArn": "arn:aws:iot:us-west-2:57EXAMPLE833:thing/PubSubTestThing",
   "thingId": "8ea78707-32c3-4f8a-9232-14bEXAMPLEfd"
   }
   ```

1. 在终端窗口中：

   1. 打开文本编辑器，例如 `nano`。

   1. 复制此 JSON 文档并将其粘贴到打开的文本编辑器中。  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Connect"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:client/PubSubTestThing"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/pubtopic"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Subscribe"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topicfilter/test/dc/subtopic"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Receive"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/subtopic"
                  ]
              }
          ]
      }
      ```

   1. 在编辑器中，在政策文档的每个`Resource`部分中，*us-west-2:57EXAMPLE833*用您 AWS 区域的、冒号字符 (:) 和您的 12 位 AWS 账户 数字替换。

   1. 将文本编辑器中的文件保存为 **\$1/policies/pubsub\$1test\$1thing\$1policy.json**。

1. 运行此命令使用前面步骤中的策略文档来创建 AWS IoT 策略。

   ```
   aws iot create-policy \
   --policy-name "PubSubTestThingPolicy" \
   --policy-document "file://~/policies/pubsub_test_thing_policy.json"
   ```

   如果创建策略，该命令将返回类似此类的响应。

   ```
   {
                                       "policyName": "PubSubTestThingPolicy",
                                       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/PubSubTestThingPolicy",
                                       "policyDocument": "{\n\"Version\": \"2012-10-17\",		 	 	 \n\"Statement\": [\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Connect\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Publish\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Subscribe\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/subtopic\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Receive\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*\"\n]\n}\n]\n}\n",
                                       "policyVersionId": "1"
                                       }
   ```

1. 运行此命令将策略附加到设备证书。将 `certificateArn`替换为您之前在本部分保存的 `certificateArn`值。

   ```
   aws iot attach-policy \
   --policy-name "PubSubTestThingPolicy" \
   --target "certificateArn"
   ```

   如果成功，该命令不返回任何内容。

1. 运行此命令将设备证书附加到 AWS IoT 事物资源。将 `certificateArn`替换为您之前在本部分保存的 `certificateArn`值。

   ```
   aws iot attach-thing-principal \
   --thing-name "PubSubTestThing" \
   --principal "certificateArn"
   ```

   如果成功，该命令不返回任何内容。

在中成功配置设备后 AWS IoT，就可以继续操作了[配置 AWS IoT 设备客户端配置文件和 MQTT 测试客户端，演示 MQTT 通信](#iot-dc-testconn-provision-dc-config)。

## 配置 AWS IoT 设备客户端配置文件和 MQTT 测试客户端，演示 MQTT 通信
<a name="iot-dc-testconn-provision-dc-config"></a>

此过程创建一个配置文件来测试 AWS IoT 设备客户端。

**创建用于测试 AWS IoT 设备客户端的配置文件**

1. 在连接到 Raspberry Pi 的本地主机的终端窗口中：

   1. 打开文本编辑器，例如 `nano`。

   1. 复制此 JSON 文档并将其粘贴到打开的文本编辑器中。

      ```
      {
        "endpoint": "a3qEXAMPLEaffp-ats.iot.us-west-2.amazonaws.com",
        "cert": "~/certs/pubsub/device.pem.crt",
        "key": "~/certs/pubsub/private.pem.key",
        "root-ca": "~/certs/AmazonRootCA1.pem",
        "thing-name": "PubSubTestThing",
        "logging": {
          "enable-sdk-logging": true,
          "level": "DEBUG",
          "type": "STDOUT",
          "file": ""
        },
        "jobs": {
          "enabled": false,
          "handler-directory": ""
        },
        "tunneling": {
          "enabled": false
        },
        "device-defender": {
          "enabled": false,
          "interval": 300
        },
        "fleet-provisioning": {
          "enabled": false,
          "template-name": "",
          "template-parameters": "",
          "csr-file": "",
          "device-key": ""
        },
        "samples": {
          "pub-sub": {
            "enabled": true,
            "publish-topic": "test/dc/pubtopic",
            "publish-file": "",
            "subscribe-topic": "test/dc/subtopic",
            "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
          }
        },
        "config-shadow": {
          "enabled": false
        },
        "sample-shadow": {
          "enabled": false,
          "shadow-name": "",
          "shadow-input-file": "",
          "shadow-output-file": ""
        }
      }
      ```

   1. 将该*endpoint*值替换为您在中找到的设备数据端点[在中配置您的设备 AWS IoT Core](iot-dc-install-provision.md#iot-dc-install-dc-provision)。 AWS 账户 

   1. 将文本编辑器中的文件保存为 **\$1/dc-configs/dc-pubsub-config.json**。

   1. 运行这个命令在新文件上设置权限

      ```
      chmod 644 ~/dc-configs/dc-pubsub-config.json
      ```

1. 准备 **MQTT 测试客户端**订阅所有 MQTT 消息：

   1. 在本地主机上，在[AWS IoT 控制台](https://console.aws.amazon.com//iot/home#/test)，选择**MQTT 测试客户端**。

   1. 在**订阅主题**选项卡上，在**主题筛选条件**中，输入 **\$1**（单个井号），然后选择**订阅**。

   1. 在**订阅**标签下，确认您看见 **\$1**（单独英镑符号）。

   继续此教程时，让窗口的 **MQTT 测试客户端** 保持打开。

保存文件并配置 **MQTT 测试客户端**后，您便可以继续 [演示使用 AWS IoT 设备客户端发布消息](iot-dc-testconn-publish.md)。

# 演示使用 AWS IoT 设备客户端发布消息
<a name="iot-dc-testconn-publish"></a>

本节中的过程演示 AWS IoT 设备客户端如何发送默认和自定义 MQTT 消息。

在上一步中为这些练习创建的策略中的以下策略声明授予 Raspberry Pi 执行以下操作的权限：
+ 

**`iot:Connect`**  
让名`PubSubTestThing`为的客户端（运行 AWS IoT 设备客户端的 Raspberry Pi）进行连接。

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Connect"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing"
        ]
      }
  ```
+ 

**`iot:Publish`**  
授予 Raspberry Pi 用 `test/dc/pubtopic` MQTT 主题发布消息的全效。

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Publish"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic"
        ]
      }
  ```

  `iot:Publish` 操作提供发布到资源数组中列出的 MQTT 主题权限。那些消息的*内容*不受策略声明的控制。

## 使用 AWS IoT 设备客户端发布默认消息
<a name="iot-dc-testconn-publish-default"></a>

此过程运行 AWS IoT 设备客户端，以便它发布一条默认 MQTT 消息，MQT **T 测试客户端**会收到并显示该消息。

**从 AWS IoT 设备客户端发送默认 MQTT 消息**

1. 执行此过程时，请确保连接到 Raspberry Pi 的本地主机上的终端窗口和使用 **MQTT测试客户端**的窗口都可见。

1. 在终端窗口中，输入这些命令以使用中创建的配置文件运行 AWS IoT 设备客户端[创建配置文件](iot-dc-install-configure.md#iot-dc-install-dc-configure-step1)。

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-config.json
   ```

   在终端窗口中， AWS IoT 设备客户端显示信息消息以及运行时出现的任何错误。

   如果终端窗口中没有显示错误，请查看 **MQTT 测试客户端**。

1. 在 **MQTT 测试客户端**的**订阅**窗口中，查看发送到 `test/dc/pubtopic` 消息主题的 *Hello World\$1* 消息。

1. 如果 AWS IoT 设备客户端没有显示任何错误并且你看到 *Hello World！* 发送到 **MQTT 测试客户端**中的`test/dc/pubtopic`消息时，您已演示连接成功。

1. 在终端窗口中，输入 **^C** (Ctrl-C) 以停止 AWS IoT 设备客户端。

在您演示 AWS IoT 设备客户端发布了默认 MQTT 消息之后，您可以继续。[使用 AWS IoT 设备客户端发布自定义消息](#iot-dc-testconn-publish-custom)

## 使用 AWS IoT 设备客户端发布自定义消息
<a name="iot-dc-testconn-publish-custom"></a>

本节中的步骤创建一条自定义 MQTT 消息，然后运行 AWS IoT Device Client，以便将自定义 MQTT 消息发布一次，以便 **MQTT 测试客户端**接收和显示。

### 为 AWS IoT 设备客户端创建自定义 MQTT 消息
<a name="iot-dc-testconn-publish-custom-create"></a>

在连接到 Raspberry Pi 的本地主机上的终端窗口中执行以下步骤。

**创建自定义消息供 AWS IoT 设备客户端发布**

1. 在终端窗口中，打开文本编辑器，例如 `nano`。

1. 在文本编辑器中，复制并粘贴以下 JSON 文档。这将是 AWS IoT 设备客户端发布的 MQTT 消息有效负载。

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

1. 将文本编辑器的内容另存为 **\$1/messages/sample-ws-message.json**。

1. 输入以下命令设置刚才创建的消息文件的权限。

   ```
   chmod 600 ~/messages/*
   ```

**为 AWS IoT 设备客户端创建用于发送自定义消息的配置文件**

1. 在终端窗口中，在文本编辑器（例如）中`nano`，打开现有的 AWS IoT 设备客户端配置文件：**\$1/dc-configs/dc-pubsub-config.json**。

1. 编辑 `samples` 对象如下所示。此文件的其他部分不需要更改。

   ```
     "samples": {
       "pub-sub": {
         "enabled": true,
         "publish-topic": "test/dc/pubtopic",
         "publish-file": "~/messages/sample-ws-message.json",
         "subscribe-topic": "test/dc/subtopic",
         "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
   ```

1. 将文本编辑器的内容另存为 **\$1/dc-configs/dc-pubsub-custom-config.json**。

1. 运行这个命令在新文件上设置权限

   ```
   chmod 644 ~/dc-configs/dc-pubsub-custom-config.json
   ```

### 使用 AWS IoT 设备客户端发布自定义 MQTT 消息
<a name="iot-dc-testconn-publish-custom-publish"></a>

此更改仅影响 MQTT 消息有效载荷的*内容*，因此当前策略将继续工作。但是，如果*MQTT 主题*（由 `~/dc-configs/dc-pubsub-custom-config.json` 红的 `publish-topic` 值定义) 已更改，还需要修改策略语句 `iot::Publish`，允许 Raspberry Pi 发布到新的 MQTT 主题。

**从 AWS IoT 设备客户端发送 MQTT 消息**

1. 在执行此过程时，确保终端窗口和窗口都有 **MQTT 测试客户端**可见。此外，请确保 **MQTT 测试客户端**仍订阅为**\$1**主题筛选条件。如果没有订阅，请再次订阅**\$1**筛选条件主题。

1. 在终端窗口中，输入这些命令以使用在 AWS IoT 中创建的配置文件运行 [创建配置文件](iot-dc-install-configure.md#iot-dc-install-dc-configure-step1)Device Client。

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-custom-config.json
   ```

   在终端窗口中， AWS IoT 设备客户端显示信息消息以及运行时出现的任何错误。

   如果终端窗口中没有显示错误，请查看 MQTT 测试客户端。

1. 在 **MQTT 测试客户端**中，在**订阅窗口**中，请参阅发送到 `test/dc/pubtopic` 消息主题的自定义消息有效载荷。

1. 如果 AWS IoT 设备客户端未显示任何错误，并且您看到在 **MQTT 测试客户端**中发布到`test/dc/pubtopic`消息的自定义消息负载，则表示您已成功发布自定义消息。

1. 在终端窗口中，输入 **^C** (Ctrl-C) 以停止 AWS IoT 设备客户端。

在您证明 AWS IoT 设备客户端发布了自定义消息负载之后，您可以继续[演示使用 AWS IoT 设备客户端订阅消息](iot-dc-testconn-subscribe.md)。

# 演示使用 AWS IoT 设备客户端订阅消息
<a name="iot-dc-testconn-subscribe"></a>

在本节中，您将演示两种类型的消息订阅：
+ 单独订阅主题
+ 通配符主题订阅

为这些练习创建的策略中的策略语句授予 Raspberry Pi 执行这些操作的权限：
+ 

**`iot:Receive`**  
授予 AWS IoT 设备客户端接收与`Resource`对象中命名主题相匹配的 MQTT 主题的权限。

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Receive"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/subtopic"
        ]
      }
  ```
+ 

**`iot:Subscribe`**  
向 AWS IoT 设备客户端授予订阅与`Resource`对象中命名的过滤器相匹配的 MQTT 主题过滤器的权限。

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Subscribe"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/subtopic"
        ]
      }
  ```

## 订阅单个 MQTT 消息主题
<a name="iot-dc-testconn-subscribe-simple-topic"></a>

此过程演示 AWS IoT 设备客户端如何订阅和记录 MQTT 消息。

在连接到 Raspberry Pi 的本地主机上的终端窗口中，列出 **\$1/dc-configs/dc-pubsub-custom-config.json** 的内容或者在文本编辑器中打开该文件查看内容。定位 `samples` 对象，应如下所示。

```
  "samples": {
    "pub-sub": {
      "enabled": true,
      "publish-topic": "test/dc/pubtopic",
      "publish-file": "~/messages/sample-ws-message.json",
      "subscribe-topic": "test/dc/subtopic",
      "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
```

注意 `subscribe-topic` 值是 AWS IoT Device Client 将在运行时订阅的 MQTT 主题。 AWS IoT 设备客户端将其从此订阅中收到的消息负载写入`subscribe-file`值中命名的文件。

**从 AWS IoT 设备客户端订阅 MQTT 消息主题**

1. 在执行此过程时，确保终端窗口和窗口都有 MQTT 测试客户端可见。此外，请确保 **MQTT 测试客户端**仍订阅为**\$1**主题筛选条件。如果没有订阅，请再次订阅**\$1**筛选条件主题。

1. 在终端窗口中，输入这些命令以使用中创建的配置文件运行 AWS IoT 设备客户端[创建配置文件](iot-dc-install-configure.md#iot-dc-install-dc-configure-step1)。

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-custom-config.json
   ```

   在终端窗口中， AWS IoT 设备客户端显示信息消息以及运行时出现的任何错误。

   如果终端窗口中未显示错误，请在 AWS IoT 控制台继续。

1. 在 AWS IoT 控制台的 **MQTT 测试客户端**中，选择**发布到主题**选项卡。

1. 在 **主题名称**中，输入 **test/dc/subtopic**。

1. 在**消息有效载荷**中，查看消息内容。

1. 选择 **Publish**（发布）发布 MQTT 消息。

1. 在终端窗口中，注意从 AWS IoT 设备客户端*收到的如下所示的消息*条目。

   ```
   2021-11-10T16:02:20.890Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 45 bytes
   ```

1. 看到显示*已收到消息的消息*条目后，输入 **^C** (Ctrl-C) 停止 AWS IoT 设备客户端。

1. 输入此命令可查看消息日志文件的末尾并查看您从 **MQTT 测试客户端**发布的信息

   ```
   tail ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   ```

通过查看日志文件中的消息，您已经演示了 AWS IoT Device Client 收到了您从 MQTT 测试客户端发布的消息。

## 使用通配符订阅多个 MQTT 消息主题
<a name="iot-dc-testconn-subscribe-wild-topic"></a>

这些过程演示了 AWS IoT 设备客户端如何使用通配符订阅和记录 MQTT 消息。要做到这一点，您将：

1. 更新 AWS IoT 设备客户端用于订阅 MQTT 主题的主题筛选器。

1. 更新设备使用的策略允许新订阅。

1. 运行 AWS IoT 设备客户端并从 MQTT 测试控制台发布消息。

**使用通配符 MQTT 主题筛选条件创建配置文件订阅多个 MQTT 消息主题**

1. 在连接到 Raspberry Pi 的本地主机上的终端窗口中，打开 **\$1/dc-configs/dc-pubsub-custom-config.json** 进行编辑并定位 `samples` 对象。

1. 在文本编辑器中，定位 `samples` 对象并更新 `subscribe-topic` 值如下所示。

   ```
     "samples": {
       "pub-sub": {
         "enabled": true,
         "publish-topic": "test/dc/pubtopic",
         "publish-file": "~/messages/sample-ws-message.json",
         "subscribe-topic": "test/dc/#",
         "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
   ```

   新 `subscribe-topic`值是 [MQTT 主题筛选条件](topics.md#topicfilters)，其末尾带有 MQTT 通配符。这描述了以 `test/dc/`开始的所有 MQTT 主题的订阅。 AWS IoT 设备客户端将其从此订阅中收到的消息负载写入中`subscribe-file`名为的文件。

1. 将修改后的配置文件另存为 **\$1/dc-configs/dc-pubsub-wild-config.json**，然后退出编辑器。

**修改 Raspberry Pi 使用的策略允许订阅和接收多个 MQTT 消息主题**

1. 在连接到 Raspberry Pi 的本地主机上的终端窗口中，在您最喜欢的文本编辑器中打开 **\$1/policies/pubsub\$1test\$1thing\$1policy.json** 进行编辑，然后定位 `iot::Subscribe` 和 `iot::Receive` 文件中的策略语句。

1. 在`iot::Subscribe`策略语句中更新 Resource 对象中的字符串用 `*`替换 `subtopic`，如下所示。

   ```
       {
         "Effect": "Allow",
         "Action": [
           "iot:Subscribe"
         ],
         "Resource": [
           "arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/*"
         ]
       }
   ```
**注意**  
[MQTT 主题筛选条件通配符](topics.md#topicfilters) 是 `+`（加号）和 `#`（磅符号）。结尾带有 `#` 的订阅请求订阅以字符前面的字符串开头的 `#` 所有主题（例如，在本使用案例中为 `test/dc/`）。  
但是，授权此订阅的策略语句中的资源值必须在主题筛选条件ARN中使用 `*`（星号）代替 `#`（磅号）。这是因为策略处理器使用的通配符不同于 MQTT 使用的通配符。  
有关在策略中为主题和主题筛选条件使用通配符的详细信息，请参阅 [在 MQTT 和策略中使用通配符 AWS IoT Core](pub-sub-policy.md#pub-sub-policy-cert)。

1. 在 `iot::Receive`策略语句中更新 Resource 对象中的字符串用 `subtopic`替换 `*`，如下所示。

   ```
       {
         "Effect": "Allow",
         "Action": [
           "iot:Receive"
         ],
         "Resource": [
           "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*"
         ]
       }
   ```

1. 将更新后的策略文档另存为 **\$1/policies/pubsub\$1wild\$1test\$1thing\$1policy.json**，然后退出编辑器。

1. 输入此命令可更新本教程的策略使用新的资源定义。

   ```
   aws iot create-policy-version \
   --set-as-default \
   --policy-name "PubSubTestThingPolicy" \
   --policy-document "file://~/policies/pubsub_wild_test_thing_policy.json"
   ```

   如果命令成功，将返回类似于此类的响应。请注意，`policyVersionId` 现在是 `2`，表示这是此策略的第二个版本。

   如果成功更新策略，可以继续下一个过程。

   ```
   {
       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/PubSubTestThingPolicy",
       "policyDocument": "{\n  \"Version\": \"2012-10-17\",		 	 	 \n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Connect\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Publish\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Subscribe\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/*\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Receive\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*\"\n      ]\n    }\n  ]\n}\n",
       "policyVersionId": "2",
       "isDefaultVersion": true
   }
   ```

   如果您收到有太多策略版本无法保存新版本的错误，请输入此命令列出策略的当前版本。查看此命令返回的列表查找可以删除的策略版本。

   ```
   aws iot list-policy-versions --policy-name "PubSubTestThingPolicy"
   ```

   输入此命令删除不再需要的版本。请注意，您无法删除原定设置策略版本。原定设置策略版本为具有 `true` 的 `isDefaultVersion` 值。

   ```
   aws iot delete-policy-version \
   --policy-name "PubSubTestThingPolicy" \
   --policy-version-id policyId
   ```

   删除策略版本后，请重试此步骤。

有了更新的配置文件和策略，您就可以通过 AWS IoT 设备客户端演示通配符订阅了。

**演示 AWS IoT 设备客户端如何订阅和接收多个 MQTT 消息主题**

1. 在 **MQTT 测试客户端**，检查订阅。如果已在 **\$1** 主题筛选条件中订阅了 **MQTT 测试客户端**，请继续执行下一步。如果没有订阅，在 **MQTT 测试客户端**，在**订阅主题**选项卡的**主题筛选条件**中，输入 **\$1**（井号），然后选择**订阅**以进行订阅。

1. 在连接到 Raspberry Pi 的本地主机上的终端窗口中，输入这些命令启动 AWS IoT Device Client。

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-wild-config.json
   ```

1. 在本地主机的终端窗口中观看 AWS IoT 设备客户端输出时，返回 **MQTT 测试客户端**。在**发布主题**选项卡中，**主题名称**，输入 **test/dc/subtopic**，然后选择**发布**。

1. 在终端窗口中，通过查找以下消息确认已收到消息，例如：

   ```
   2021-11-10T16:34:20.101Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 76 bytes
   ```

1. 在本地主机的终端窗口中观看 AWS IoT 设备客户端输出时，返回 **MQTT 测试客户端**。在**发布主题**选项卡中，**主题名称**，输入 **test/dc/subtopic2**，然后选择**发布**。

1. 在终端窗口中，通过查找以下消息确认已收到消息，例如：

   ```
   2021-11-10T16:34:32.078Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 77 bytes
   ```

1. 看到确认收到两条消息的消息后，输入 **^C** (Ctrl-C) 停止 AWS IoT 设备客户端。

1. 输入此命令可查看消息日志文件的末尾并查看您从 **MQTT 测试客户端**发布的信息

   ```
   tail -n 20 ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   ```
**注意**  
该日志文件仅包含消息有效载荷。消息主题不会记录在收到的消息日志文件中。  
您还可能在收到的日志中看到 AWS IoT 设备客户端发布的消息。这是因为通配符主题筛选条件包含该消息主题，有时候，在发布的消息发送给订阅者之前，消息代理可以处理订阅请求。

日志文件中的条目表明已收到消息。您可以使用其他主题名称重复此过程。主题名称以 `test/dc/` 开头的所有消息应该接收并记录。主题名称以任何其他文本开头的消息将被忽略。

演示 AWS IoT 设备客户端如何发布和订阅 MQTT 消息后，请继续。[教程：使用 AWS IoT 设备客户端演示远程操作（作业）](iot-dc-runjobs.md)

# 教程：使用 AWS IoT 设备客户端演示远程操作（作业）
<a name="iot-dc-runjobs"></a>

在这些教程中，您将配置任务并将其部署到 Raspberry Pi，演示如何向物联网设备发送远程操作。

**要开始本教程：**
+ 将本地主机和 Raspberry Pi 配置为在[上一节](iot-dc-testconn.md)使用。
+ 如果您尚未完成上一节中的教程，则可以使用 Raspberry Pi 和 microSD 卡来尝试本教程，该卡上有您在安装 AWS IoT 设备客户端后保存的图像。[（可选）保存 microSD 卡映像](iot-dc-install-download.md#iot-dc-install-dc-save)
+ 如果您之前运行过此演示，[第 2 步：使用 AWS IoT 设备客户端 AWS 账户 在构建演示之后清理你的](iot-dc-cleanup.md#iot-dc-cleanup-cloud)请查看删除您在之前运行中创建的所有 AWS IoT 资源，以避免出现重复的资源错误。

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

**完成本主题后：**
+ 您将演示物联网设备使用不同的方式 AWS IoT Core 来运行由管理的远程操作 AWS IoT 。

**所需的设备：**
+ 您在[上一节](iot-dc-install-dc.md)中测试的本地开发和测试环境
+ 您在[上一节](iot-dc-install-dc.md)中测试的 Raspberry Pi
+ 您在[上一节](iot-dc-install-dc.md)中测试的来自Raspberry Pi 的 microSD 存储卡

**Topics**
+ [准备 Raspberry Pi 运行任务](iot-dc-runjobs-prepare.md)
+ [使用 AWS IoT 设备客户端创建和运行作业 AWS IoT](iot-dc-runjobs-prepare-define.md)

# 准备 Raspberry Pi 运行任务
<a name="iot-dc-runjobs-prepare"></a>

本节中的过程介绍如何使用 AWS IoT 设备客户端让 Raspberry Pi 做好运行作业的准备。

**注意**  
这些过程是特定于设备的。如果要同时对多个设备执行本节中的步骤，每个设备将需要自己的策略和唯一的、特定于设备的证书和设备名称。要为每台设备提供独特的资源，请对每台设备执行一次此过程，同时按照过程中所述更改特定于设备的元素。

**Topics**
+ [提供您的 Raspberry Pi 来演示任务](#iot-dc-runjobs-prepare-provision)
+ [将 AWS IoT 设备客户端配置为运行作业代理](#iot-dc-runjobs-prepare-config)

## 提供您的 Raspberry Pi 来演示任务
<a name="iot-dc-runjobs-prepare-provision"></a>

本节中的过程通过为树莓派创建 AWS IoT 资源和设备证书 AWS IoT 来配置 Raspberry Pi。

**Topics**
+ [创建和下载设备证书文件以演示 AWS IoT 作业](#iot-dc-runjobs-prepare-cert)
+ [创建 AWS IoT 资源来演示 AWS IoT 工作](#iot-dc-runjobs-prepare-iot)

### 创建和下载设备证书文件以演示 AWS IoT 作业
<a name="iot-dc-runjobs-prepare-cert"></a>

此过程为此演示创建设备证书文件。

如果准备了多台设备，必须在每台设备上执行此过程。

**要为 Raspberry Pi 创建和下载设备证书文件，请执行以下操作：**

在连接到 Raspberry Pi 的本地主机上的终端窗口中，输入以下命令。

1. 输入以下命令为您的设备创建设备证书文件。

   ```
   aws iot create-keys-and-certificate \
   --set-as-active \
   --certificate-pem-outfile "~/certs/jobs/device.pem.crt" \
   --public-key-outfile "~/certs/jobs/public.pem.key" \
   --private-key-outfile "~/certs/jobs/private.pem.key"
   ```

   此命令会返回类似以下内容的响应。保存 `certificateArn`值供稍后使用。

   ```
   {
   "certificateArn": "arn:aws:iot:us-west-2:57EXAMPLE833:cert/76e7e4edb3e52f52334be2f387a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificateId": "76e7e4edb3e52f5233EXAMPLE7a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDWTCCAkGgAwIBAgI_SHORTENED_FOR_EXAMPLE_Lgn4jfgtS\n-----END CERTIFICATE-----\n",
   "keyPair": {
       "PublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BA_SHORTENED_FOR_EXAMPLE_ImwIDAQAB\n-----END PUBLIC KEY-----\n",
       "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQE_SHORTENED_FOR_EXAMPLE_T9RoDiukY\n-----END RSA PRIVATE KEY-----\n"
   }
   }
   ```

1. 输入以下命令设置证书目录及其文件的权限。

   ```
   chmod 700 ~/certs/jobs
   chmod 644 ~/certs/jobs/*
   chmod 600 ~/certs/jobs/private.pem.key
   ```

1. 运行此命令可查看证书目录和文件的权限。

   ```
   ls -l ~/certs/jobs
   ```

   命令的输出应与您在此处看到的内容相同，但文件日期和时间会有所不同。

   ```
   -rw-r--r-- 1 pi pi 1220 Oct 28 13:02 device.pem.crt
   -rw------- 1 pi pi 1675 Oct 28 13:02 private.pem.key
   -rw-r--r-- 1 pi pi  451 Oct 28 13:02 public.pem.key
   ```

将设备证书文件下载到 Raspberry Pi 之后，您准备好继续 [提供您的 Raspberry Pi 来演示任务](#iot-dc-runjobs-prepare-provision)。

### 创建 AWS IoT 资源来演示 AWS IoT 工作
<a name="iot-dc-runjobs-prepare-iot"></a>

为此设备创建 AWS IoT 资源。

如果准备了多台设备，必须在每台设备上执行此过程。



**在 AWS IoT中预调配您的设备：**

在连接到 Raspberry Pi 的本地主机的终端窗口中：

1. 输入以下命令获取您的设备数据端点的地址： AWS 账户。

   ```
   aws iot describe-endpoint --endpoint-type IoT:Data-ATS
   ```

   自上次运行此命令以来，端点值未发生更改。再次在此处运行该命令可以轻松查找数据端点值并将其粘贴到本教程中使用的配置文件中。

   此 **describe-endpoint** 命令会返回类似以下内容的响应：记录 `endpointAddress`值以供将来使用。

   ```
   {
   "endpointAddress": "a3qjEXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

1. *uniqueThingName*替换为设备的唯一名称。如果要使用多台设备执行本教程，请为每台设备指定自己的名称。例如，**TestDevice01**、**TestDevice02** 等等。

   输入此命令为您的 Raspberry Pi 创建新 AWS IoT 事物资源。

   ```
   aws iot create-thing --thing-name "uniqueThingName"
   ```

   由于 AWS IoT 事物资源是您的设备在云中的*虚拟*表示，因此我们可以创建多个事物资源 AWS IoT 以用于不同的目的。它们都可以由同一物理 IoT 设备使用来表示设备的不同方面。
**注意**  
当您想要保护多台设备的策略时，可以使用 `${iot:Thing.ThingName}` 而不是静态事物名称 `uniqueThingName`。

   这些教程每台设备一次只能使用一件事资源。这样，在这些教程中，它们代表了不同的演示，因此在为演示创建 AWS IoT 资源之后，您可以使用专门为每个演示创建的资源返回并重复演示。

   如果您的 AWS IoT 事物资源已创建，则该命令会返回这样的响应。记录 `thingArn` 值以供稍后创建要在此设备上运行的任务时使用。

   ```
   {
   "thingName": "uniqueThingName",
   "thingArn": "arn:aws:iot:us-west-2:57EXAMPLE833:thing/uniqueThingName",
   "thingId": "8ea78707-32c3-4f8a-9232-14bEXAMPLEfd"
   }
   ```

1. 在终端窗口中：

   1. 打开文本编辑器，例如 `nano`。

   1. 复制此 JSON 文档并将其粘贴到打开的文本编辑器中。  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Connect"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:client/uniqueThingName"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/pubtopic",
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/events/job/*",
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/events/jobExecution/*",
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/things/uniqueThingName/jobs/*"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Subscribe"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topicfilter/test/dc/subtopic",
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/events/jobExecution/*",
                      "arn:aws:iot:us-west-2:123456789012:topicfilter/$aws/things/uniqueThingName/jobs/*"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Receive"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/subtopic",
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/things/uniqueThingName/jobs/*"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:DescribeJobExecution",
                      "iot:GetPendingJobExecutions",
                      "iot:StartNextPendingJobExecution",
                      "iot:UpdateJobExecution"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/things/uniqueThingName"
                  ]
              }
          ]
      }
      ```

   1. 在编辑器中，在每份政策声明的`Resource`部分中，*us-west-2:57EXAMPLE833*用您的 AWS 区域、冒号字符 (:) 和您的 12 位 AWS 账户 数字替换。

   1. 在编辑器中，在每份策略声明中，*uniqueThingName*用你为该事物资源提供的事物名称替换。

   1. 将文本编辑器中的文件保存为 **\$1/policies/jobs\$1test\$1thing\$1policy.json**。

      如果要为多台设备运行此过程，请将文件保存为每台设备上的此文件名。

1. *uniqueThingName*替换为设备的事物名称，然后运行此命令来创建针对该设备量身定制的 AWS IoT 策略。

   ```
   aws iot create-policy \
   --policy-name "JobTestPolicyForuniqueThingName" \
   --policy-document "file://~/policies/jobs_test_thing_policy.json"
   ```

   如果创建策略，该命令将返回类似此类的响应。  
****  

   ```
   {
       "policyName": "JobTestPolicyForuniqueThingName",
       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/JobTestPolicyForuniqueThingName",
       "policyDocument": "{\n\"Version\": \"2012-10-17\",\n\"Statement\": [\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Connect\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Publish\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Subscribe\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/subtopic\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Receive\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*\"\n]\n}\n]\n}\n",
       "policyVersionId": "1"
   }
   ```

1. *uniqueThingName*替换为设备的事物`certificateArn`名称以及您在本节前面为该设备保存的`certificateArn`值，然后运行此命令将策略附加到设备证书。

   ```
   aws iot attach-policy \
   --policy-name "JobTestPolicyForuniqueThingName" \
   --target "certificateArn"
   ```

   如果成功，该命令不返回任何内容。

1.  *uniqueThingName*替换为设备的事物名称，`certificateArn`替换为本节前面部分中保存的`certificateArn`值，然后运行此命令将设备证书附加到 AWS IoT 事物资源。

   ```
   aws iot attach-thing-principal \
   --thing-name "uniqueThingName" \
   --principal "certificateArn"
   ```

   如果成功，该命令不返回任何内容。

成功预调配 Raspberry Pi 之后，您可以在测试中为另一个 Raspberry Pi 重复此部分，或者，如果所有设备均已预调配，请继续 [将 AWS IoT 设备客户端配置为运行作业代理](#iot-dc-runjobs-prepare-config)。

## 将 AWS IoT 设备客户端配置为运行作业代理
<a name="iot-dc-runjobs-prepare-config"></a>

此过程为 AWS IoT 设备客户端创建一个配置文件以运行作业代理:.

注意：如果准备多台设备，必须在每台设备上执行此过程。

**要创建用于测试 AWS IoT 设备客户端的配置文件，请执行以下操作：**

1. 在连接到 Raspberry Pi 的本地主机的终端窗口中：

   1. 打开文本编辑器，例如 `nano`。

   1. 复制此 JSON 文档并将其粘贴到打开的文本编辑器中。

      ```
      {
        "endpoint": "a3qEXAMPLEaffp-ats.iot.us-west-2.amazonaws.com",
        "cert": "~/certs/jobs/device.pem.crt",
        "key": "~/certs/jobs/private.pem.key",
        "root-ca": "~/certs/AmazonRootCA1.pem",
        "thing-name": "uniqueThingName",
        "logging": {
          "enable-sdk-logging": true,
          "level": "DEBUG",
          "type": "STDOUT",
          "file": ""
        },
        "jobs": {
          "enabled": true,
          "handler-directory": ""
        },
        "tunneling": {
          "enabled": false
        },
        "device-defender": {
          "enabled": false,
          "interval": 300
        },
        "fleet-provisioning": {
          "enabled": false,
          "template-name": "",
          "template-parameters": "",
          "csr-file": "",
          "device-key": ""
        },
        "samples": {
          "pub-sub": {
            "enabled": false,
            "publish-topic": "",
            "publish-file": "",
            "subscribe-topic": "",
            "subscribe-file": ""
          }
        },
        "config-shadow": {
          "enabled": false
        },
        "sample-shadow": {
          "enabled": false,
          "shadow-name": "",
          "shadow-input-file": "",
          "shadow-output-file": ""
        }
      }
      ```

   1. 将该*endpoint*值替换为您在中找到的设备数据端点值[在中配置您的设备 AWS IoT Core](iot-dc-install-provision.md#iot-dc-install-dc-provision)。 AWS 账户 

   1. *uniqueThingName*替换为您用于此设备的事物名称。

   1. 将文本编辑器中的文件保存为 **\$1/dc-configs/dc-jobs-config.json**。

1. 运行此命令设置新配置文件的文件权限。

   ```
   chmod 644 ~/dc-configs/dc-jobs-config.json
   ```

此测试没有使用 **MQTT 测试客户端**。虽然设备将与交换与作业相关的 MQTT 消息 AWS IoT，但任务进度消息仅与运行任务的设备交换。由于任务进度消息仅与运行任务的设备交换，因此您无法从其他设备（例如 AWS IoT 控制台）订阅它们。

保存配置文件后，您已准备继续 [使用 AWS IoT 设备客户端创建和运行作业 AWS IoT](iot-dc-runjobs-prepare-define.md)。

# 使用 AWS IoT 设备客户端创建和运行作业 AWS IoT
<a name="iot-dc-runjobs-prepare-define"></a>

本节中的过程将创建作业文档和 AWS IoT 作业资源。创建作业资源后， AWS IoT 将作业文档发送到指定的作业目标，作业代理会将作业文档应用到设备或客户端。

**Topics**
+ [创建并存储物联网任务的任务文档](#iot-dc-runjobs-prepare-define-jobdoc)
+ [AWS IoT 为一台 IoT 设备运行作业](#iot-dc-runjobs-prepare-define-job)

## 创建并存储物联网任务的任务文档
<a name="iot-dc-runjobs-prepare-define-jobdoc"></a>

此过程创建一个要包含在作业资源中的简单 AWS IoT 作业文档。这份任务文档显示“Hello world\$1” 在任务目标上。

**要创建和存储任务文档：**

1. 选择要将任务文档保存到的 Amazon S3 存储桶。如果您没有现有 Amazon S3 存储桶可用，需要创建一个。有关如何创建 Amazon S3 存储桶的信息，请参阅 [Amazon S3 入门](https://docs.aws.amazon.com//AmazonS3/latest/userguide/GetStartedWithS3.html)中的主题。

1. 为此任务创建并保存任务文档

   1. 在本地主机上，打开文本编辑器。

   1. 复制此文本并粘贴到编辑器中。

      ```
      {
          "operation": "echo",
          "args": ["Hello world!"]
      }
      ```

   1. 在本地主机上，将编辑器内容保存到名为 **hello-world-job.json**的文件中。

   1. 确认文件已正确保存。一些文本编辑器会自动追加 `.txt` 用户保存文本文件时的文件名。如果您的编辑器附加 `.txt` 在文件名中，在继续之前更正文件名。

1. 将替换为路径**hello-world-job.json**，如果它不在您的当前目录中，则将其*s3\$1bucket\$1name*替换为您所选存储桶的 Amazon S3 存储桶路径，然后运行此命令将您的任务文档放入 Amazon S3 存储桶。*path\$1to\$1file*

   ```
   aws s3api put-object \
   --key hello-world-job.json \
   --body path_to_file/hello-world-job.json --bucket s3_bucket_name
   ```

   用于标识您存储在 Amazon S3 中的任务文档的任务文档 URL 是通过替换以下 URL *AWS\$1region* 中的*s3\$1bucket\$1name*和来确定的。记录生成的 URL 以备日后用作 *job\$1document\$1path*

   ```
   https://s3_bucket_name.s3.AWS_Region.amazonaws.com/hello-world-job.json
   ```
**注意**  
AWS 安全性可防止您在外部打开此 URL AWS 账户，例如使用浏览器。默认情况下， AWS IoT 作业引擎使用此 URL，该引擎有权访问该文件。在生产环境中，您需要确保 AWS IoT 服务有权访问存储在 Amazon S3 中的任务文档。

保存任务文档的 URL 后，继续 [AWS IoT 为一台 IoT 设备运行作业](#iot-dc-runjobs-prepare-define-job)。

## AWS IoT 为一台 IoT 设备运行作业
<a name="iot-dc-runjobs-prepare-define-job"></a>

本节中的步骤在 Raspberry Pi 上启动 AWS IoT 设备客户端，在设备上运行作业代理，等待作业运行。它还会在中创建任务资源 AWS IoT，该资源会将任务发送到您的物联网设备并在您的物联网设备上运行。

**注意**  
此过程仅在一台设备上运行任务。

**要在 Raspberry Pi 上启动任务代理：**

1. 在连接到 Raspberry Pi 的本地主机的终端窗口中，运行此命令启动 AWS IoT 设备客户端。

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-jobs-config.json
   ```

1. 在终端窗口中，确认 AWS IoT 设备客户端和显示这些消息

   ```
   2021-11-15T18:45:56.708Z [INFO]  {Main.cpp}: Jobs is enabled
                         .
                         .
                         .
   2021-11-15T18:45:56.708Z [INFO]  {Main.cpp}: Client base has been notified that Jobs has started
   2021-11-15T18:45:56.708Z [INFO]  {JobsFeature.cpp}: Running Jobs!
   2021-11-15T18:45:56.708Z [DEBUG] {JobsFeature.cpp}: Attempting to subscribe to startNextPendingJobExecution accepted and rejected
   2021-11-15T18:45:56.708Z [DEBUG] {JobsFeature.cpp}: Attempting to subscribe to nextJobChanged events
   2021-11-15T18:45:56.708Z [DEBUG] {JobsFeature.cpp}: Attempting to subscribe to updateJobExecutionStatusAccepted for jobId +
   2021-11-15T18:45:56.738Z [DEBUG] {JobsFeature.cpp}: Ack received for SubscribeToUpdateJobExecutionAccepted with code {0}
   2021-11-15T18:45:56.739Z [DEBUG] {JobsFeature.cpp}: Attempting to subscribe to updateJobExecutionStatusRejected for jobId +
   2021-11-15T18:45:56.753Z [DEBUG] {JobsFeature.cpp}: Ack received for SubscribeToNextJobChanged with code {0}
   2021-11-15T18:45:56.760Z [DEBUG] {JobsFeature.cpp}: Ack received for SubscribeToStartNextJobRejected with code {0}
   2021-11-15T18:45:56.776Z [DEBUG] {JobsFeature.cpp}: Ack received for SubscribeToStartNextJobAccepted with code {0}
   2021-11-15T18:45:56.776Z [DEBUG] {JobsFeature.cpp}: Ack received for SubscribeToUpdateJobExecutionRejected with code {0}
   2021-11-15T18:45:56.777Z [DEBUG] {JobsFeature.cpp}: Publishing startNextPendingJobExecutionRequest
   2021-11-15T18:45:56.785Z [DEBUG] {JobsFeature.cpp}: Ack received for StartNextPendingJobPub with code {0}
   2021-11-15T18:45:56.785Z [INFO]  {JobsFeature.cpp}: No pending jobs are scheduled, waiting for the next incoming job
   ```

1. 在终端窗口中，看到此消息后，继续下一步并创建任务资源。请注意，它可能不是列表中的最后一个条目。

   ```
   2021-11-15T18:45:56.785Z [INFO]  {JobsFeature.cpp}: No pending jobs are scheduled, waiting for the next incoming job
   ```

**创建 AWS IoT 任务资源**

1. 在本地主机上：

   1. *job\$1document\$1url*替换为来自的作业文档 URL [创建并存储物联网任务的任务文档](#iot-dc-runjobs-prepare-define-jobdoc)。

   1. *thing\$1arn*替换为您为设备创建的事物资源的 ARN，然后运行此命令。

      ```
      aws iot create-job \
      --job-id hello-world-job-1 \
      --document-source "job_document_url" \
      --targets "thing_arn" \
      --target-selection SNAPSHOT
      ```

      如果成功，该命令将返回类似此结果。

      ```
      {
        "jobArn": "arn:aws:iot:us-west-2:57EXAMPLE833:job/hello-world-job-1",
        "jobId": "hello-world-job-1"
      }
      ```

1. 在终端窗口中，您应该看到 AWS IoT 设备客户端的输出如下所示。

   ```
   2021-11-15T18:02:26.688Z [INFO]  {JobsFeature.cpp}: No pending jobs are scheduled, waiting for the next incoming job
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Job ids differ
   2021-11-15T18:10:24.890Z [INFO]  {JobsFeature.cpp}: Executing job: hello-world-job-1
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Attempting to update job execution status!
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Not including stdout with the status details
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Not including stderr with the status details
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Assuming executable is in PATH
   2021-11-15T18:10:24.890Z [INFO]  {JobsFeature.cpp}: About to execute: echo Hello world!
   2021-11-15T18:10:24.890Z [DEBUG] {Retry.cpp}: Retryable function starting, it will retry until success
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Created EphermalPromise for ClientToken 3TEWba9Xj6 in the updateJobExecution promises map
   2021-11-15T18:10:24.890Z [DEBUG] {JobEngine.cpp}: Child process now running
   2021-11-15T18:10:24.890Z [DEBUG] {JobEngine.cpp}: Child process about to call execvp
   2021-11-15T18:10:24.890Z [DEBUG] {JobEngine.cpp}: Parent process now running, child PID is 16737
   2021-11-15T18:10:24.891Z [DEBUG] {16737}: Hello world!
   2021-11-15T18:10:24.891Z [DEBUG] {JobEngine.cpp}: JobEngine finished waiting for child process, returning 0
   2021-11-15T18:10:24.891Z [INFO]  {JobsFeature.cpp}: Job exited with status: 0
   2021-11-15T18:10:24.891Z [INFO]  {JobsFeature.cpp}: Job executed successfully!
   2021-11-15T18:10:24.891Z [DEBUG] {JobsFeature.cpp}: Attempting to update job execution status!
   2021-11-15T18:10:24.891Z [DEBUG] {JobsFeature.cpp}: Not including stdout with the status details
   2021-11-15T18:10:24.891Z [DEBUG] {JobsFeature.cpp}: Not including stderr with the status details
   2021-11-15T18:10:24.892Z [DEBUG] {Retry.cpp}: Retryable function starting, it will retry until success
   2021-11-15T18:10:24.892Z [DEBUG] {JobsFeature.cpp}: Created EphermalPromise for ClientToken GmQ0HTzWGg in the updateJobExecution promises map
   2021-11-15T18:10:24.905Z [DEBUG] {JobsFeature.cpp}: Ack received for PublishUpdateJobExecutionStatus with code {0}
   2021-11-15T18:10:24.905Z [DEBUG] {JobsFeature.cpp}: Removing ClientToken 3TEWba9Xj6 from the updateJobExecution promises map
   2021-11-15T18:10:24.905Z [DEBUG] {JobsFeature.cpp}: Success response after UpdateJobExecution for job hello-world-job-1
   2021-11-15T18:10:24.917Z [DEBUG] {JobsFeature.cpp}: Ack received for PublishUpdateJobExecutionStatus with code {0}
   2021-11-15T18:10:24.918Z [DEBUG] {JobsFeature.cpp}: Removing ClientToken GmQ0HTzWGg from the updateJobExecution promises map
   2021-11-15T18:10:24.918Z [DEBUG] {JobsFeature.cpp}: Success response after UpdateJobExecution for job hello-world-job-1
   2021-11-15T18:10:25.861Z [INFO]  {JobsFeature.cpp}: No pending jobs are scheduled, waiting for the next incoming job
   ```

1. 当 AWS IoT 设备客户端运行并等待任务时，您可以通过更改`job-id`值并重新运行步骤 1 中的值来提交另一个作业。**create-job**

运行完任务后，在终端窗口中输入 ^C (Control-C) 以停止 AWS IoT 设备客户端。

# 教程：运行 AWS IoT 设备客户端教程后进行清理
<a name="iot-dc-cleanup"></a>

本教程中的过程将指导您在完成本学习路径中的教程时删除创建的文件和资源。

**Topics**
+ [步骤 1：使用设备客户端制作演示后清理 AWS IoT 设备](#iot-dc-cleanup-devices)
+ [第 2 步：使用 AWS IoT 设备客户端 AWS 账户 在构建演示之后清理你的](#iot-dc-cleanup-cloud)

## 步骤 1：使用设备客户端制作演示后清理 AWS IoT 设备
<a name="iot-dc-cleanup-devices"></a>

本教程介绍了在此学习路径中构建演示后如何清理 microSD 卡的两个选项。选择提供所需安全级别的选项。

请注意，清理设备的 microSD 卡并不会移除您 AWS IoT 创建的任何资源。要在清理设备的 microSD 卡后清理 AWS IoT 资源，您应该查看上面的教程。[第 2 步：使用 AWS IoT 设备客户端 AWS 账户 在构建演示之后清理你的](#iot-dc-cleanup-cloud)

### 选项 1：通过重写 microSD 卡进行清理
<a name="iot-dc-cleanup-devices-flash"></a>

在完成本学习路径中的教程之后，清理 microSD 卡最简单、最彻底的方法是用您在首次准备设备时创建的保存图像文件覆盖 microSD 卡。

此过程使用本地主机将保存的 microSD 卡映像写入 microSD 卡。

**注意**  
如果您的设备没有将可移动存储介质用于操作系统，请参阅该设备的步骤。

**要向 microSD 卡写入一个新映像**

1. 在本地主机上，找到要写入 microSD 卡的已保存 microSD 卡映像。

1. 将 microSD 卡插到您的计算机上。

1. 使用 SD 卡成像工具，将选定的图像文件写入 microSD 卡。

1. 将 Raspberry Pi 操作系统映像写入 microSD 卡后，弹出 microSD 卡并将其从本地主机安全地移除。

您的 microSD 卡已准备就绪，可供使用。

### 选项 2：通过删除用户目录进行清理
<a name="iot-dc-cleanup-devices-dirs"></a>

要在完成教程后清理 microSD 卡而不重写 microSD 卡映像，可以单独删除用户目录。这并不像从保存的图像中重写 microSD 卡那么彻底，因为它不会删除可能已安装的任何系统文件。

如果删除用户目录足以满足您的需要，可以按照此步骤操作。

**从设备中删除此学习路径的用户目录**

1. 运行这些命令可以在连接到设备的终端窗口中删除在此学习路径中创建的用户目录、子目录及其所有文件。
**注意**  
删除这些目录和文件后，如果不再完成教程，您将无法运行演示。

   ```
   rm -Rf ~/dc-configs
   rm -Rf ~/policies
   rm -Rf ~/messages
   rm -Rf ~/certs
   rm -Rf ~/.aws-iot-device-client
   ```

1. 在连接到设备的终端窗口中，运行这些命令删除应用程序源目录和文件。
**注意**  
这些命令不会卸载任何程序。他们只删除用于构建和安装它们的源文件。删除这些文件后， AWS CLI 和 AWS IoT 设备客户端可能无法运行。

   ```
   rm -Rf ~/aws-cli
   rm -Rf ~/aws
   rm -Rf ~/aws-iot-device-client
   ```

## 第 2 步：使用 AWS IoT 设备客户端 AWS 账户 在构建演示之后清理你的
<a name="iot-dc-cleanup-cloud"></a>

这些过程可帮助您识别和删除您在完成本学习路径中的教程时创建的 AWS 资源。

### 清理 AWS IoT 资源
<a name="iot-dc-cleanup-cloud-iot"></a>

此过程可帮助您识别和删除您在完成本学习路径中的教程时创建的 AWS IoT 资源。


**AWS IoT 在此学习路径中创建的资源**  

| 教程 | 事物资源 | 策略资源 | 
| --- | --- | --- | 
|  [教程：安装和配置 AWS IoT 设备客户端](iot-dc-install-dc.md)  |  **DevCliTestThing**  | DevCliTestThingPolicy | 
|  [教程：演示与 AWS IoT 设备客户端的 MQTT 消息通信](iot-dc-testconn.md)  |  **PubSubTestThing**  | PubSubTestThingPolicy | 
|  [教程：使用 AWS IoT 设备客户端演示远程操作（作业）](iot-dc-runjobs.md)  | 定义的用户（可能有不止一个） |  *定义的用户*（可能有不止一个）  | 

**要删除 AWS IoT 资源，请针对您创建的每个事物资源执行以下步骤**

1. 将 `thing_name` 替换为要删除的对象资源的名称，然后运行此命令列出从本地主机附加到对象资源的证书。

   ```
   aws iot list-thing-principals --thing-name thing_name
   ```

   此命令返回类似这样的响应，其中列出了附加到 `thing_name`的证书。在大多数情况下，列表中只有一个证书。

   ```
   {
       "principals": [
           "arn:aws:iot:us-west-2:57EXAMPLE833:cert/23853eea3cf0edc7f8a69c74abeafa27b2b52823cab5b3e156295e94b26ae8ac"
       ]
   }
   ```

1. 对于上一个命令列出的每个证书：

   1. 将 `certificate_ID`替换为上一个命令中的证书 ID。证书ID是上一个命令返回的 ARN 中遵循 `cert/`的字母数字字符。然后运行此命令以停用证书。

      ```
      aws iot update-certificate --new-status INACTIVE --certificate-id certificate_ID
      ```

      如果成功，该命令不返回任何内容。

   1. 将 `certificate_ARN` 替换为之前返回的证书列表中的证书 ARN，然后运行此命令列出附加到此证书的策略。

      ```
      aws iot list-attached-policies --target certificate_ARN
      ```

      此命令返回类似这样的响应，其中列出了附加到证书的策略。在大多数情况下，列表中只有一个策略。

      ```
      {
          "policies": [
              {
                  "policyName": "DevCliTestThingPolicy",
                  "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/DevCliTestThingPolicy"
              }
          ]
      }
      ```

   1. 对于附加到该证书的每个策略。

      1. 将 `policy_name` 替换为上一个命令中的 `policyName` 值，将 `certificate_ARN` 替换为证书的 ARN，然后运行此命令将策略与证书分离。

         ```
         aws iot detach-policy --policy-name policy_name --target certificate_ARN
         ```

         如果成功，该命令不返回任何内容。

      1. 将 `policy_name` 替换为 `policyName` 值，然后运行此命令查看策略是否附加到其他证书。

         ```
         aws iot list-targets-for-policy --policy-name policy_name
         ```

         如果该命令返回这样的空列表，该策略不会附加到任何证书，您将继续列出策略版本。如果还有附加到策略的证书，请继续 **detach-thing-principal** 步骤。

         ```
         {
             "targets": []
         }
         ```

      1. 将 `policy_name` 替换为 `policyName` 值，然后运行此命令检查策略版本。要删除策略，它必须只有一个版本。

         ```
         aws iot list-policy-versions --policy-name policy_name
         ```

         如果策略只有一个版本（如此示例），则可以跳至步骤 **delete-policy** 立即删除策略。

         ```
         {
             "policyVersions": [
                 {
                     "versionId": "1",
                     "isDefaultVersion": true,
                     "createDate": "2021-11-18T01:02:46.778000+00:00"
                 }
             ]
         }
         ```

         如果策略有多个版本，如本例所示，则必须先删除 `false` 值为 `isDefaultVersion` 的策略版本，然后才能删除策略。

         ```
         {
             "policyVersions": [
                 {
                     "versionId": "2",
                     "isDefaultVersion": true,
                     "createDate": "2021-11-18T01:52:04.423000+00:00"
                 },
                 {
                     "versionId": "1",
                     "isDefaultVersion": false,
                     "createDate": "2021-11-18T01:30:18.083000+00:00"
                 }
             ]
         }
         ```

         如果您需要删除策略版本，将 `policy_name` 替换为 `policyName` 值，将 `version_ID` 替换为来自上一个命令的 `versionId`值，然后运行此命令删除策略版本。

         ```
         aws iot delete-policy-version --policy-name policy_name --policy-version-id version_ID
         ```

         如果成功，该命令不返回任何内容。

         删除策略版本后，请重复此步骤，直到该策略只有一个策略版本。

      1. 将 `policy_name`替换为 `policyName` 值，然后运行此命令删除策略。

         ```
         aws iot delete-policy --policy-name policy_name
         ```

   1. 将 `thing_name` 替换为事物名称，将 `certificate_ARN` 替换为证书的 ARN，然后运行此命令将证书与事物资源分离。

      ```
      aws iot detach-thing-principal --thing-name thing_name --principal certificate_ARN
      ```

      如果成功，该命令不返回任何内容。

   1. 将 `certificate_ID`替换为上一个命令中的证书 ID。证书 ID 是上一个命令返回的 ARN 中遵循 `cert/`的字母数字字符。运行这个命令删除证书资源。

      ```
      aws iot delete-certificate --certificate-id certificate_ID
      ```

      如果成功，该命令不返回任何内容。

1. 将 `thing_name`替换为事物名称，然后运行此命令删除该事物。

   ```
   aws iot delete-thing --thing-name thing_name
   ```

   如果成功，该命令不返回任何内容。

### 清理 AWS 资源
<a name="iot-dc-cleanup-cloud-aws"></a>

此过程可帮助您识别和删除您在完成本学习路径中的教程时创建的其他 AWS 资源。


**在此学习路径中创建的其他 AWS 资源**  

| 教程 | 资源类型 | 资源名称或 ID | 
| --- | --- | --- | 
|  [教程：使用 AWS IoT 设备客户端演示远程操作（作业）](iot-dc-runjobs.md)  | Amazon S3 对象 | hello-world-job.json | 
|  [教程：使用 AWS IoT 设备客户端演示远程操作（作业）](iot-dc-runjobs.md)  |  AWS IoT 工作资源  | 定义的用户 | 

**删除在此学习路径中创建的 AWS 资源**

1. 要删除在此学习路径中创建的职位

   1. 运行此命令列出您的中的作业 AWS 账户。

      ```
      aws iot list-jobs
      ```

      该命令会返回你的 AWS IoT 任务列表 AWS 账户 AWS 区域 ，如下所示。

      ```
      {
          "jobs": [
              {
                  "jobArn": "arn:aws:iot:us-west-2:57EXAMPLE833:job/hello-world-job-2",
                  "jobId": "hello-world-job-2",
                  "targetSelection": "SNAPSHOT",
                  "status": "COMPLETED",
                  "createdAt": "2021-11-16T23:40:36.825000+00:00",
                  "lastUpdatedAt": "2021-11-16T23:40:41.375000+00:00",
                  "completedAt": "2021-11-16T23:40:41.375000+00:00"
              },
              {
                  "jobArn": "arn:aws:iot:us-west-2:57EXAMPLE833:job/hello-world-job-1",
                  "jobId": "hello-world-job-1",
                  "targetSelection": "SNAPSHOT",
                  "status": "COMPLETED",
                  "createdAt": "2021-11-16T23:35:26.381000+00:00",
                  "lastUpdatedAt": "2021-11-16T23:35:29.239000+00:00",
                  "completedAt": "2021-11-16T23:35:29.239000+00:00"
              }
          ]
      }
      ```

   1. 对于您从列表中识别为在此学习路径中创建的作业的每项作业，请`jobId`替换为要删除的作业的`jobId`值，然后运行此命令删除 AWS IoT 作业。

      ```
      aws iot delete-job --job-id jobId
      ```

      如果命令成功，该命令不返回任何内容。

1. 要删除您在此学习路径中存储在 Amazon S3 存储桶中的任务文档。

   1. 将 `bucket`替换为您使用的存储桶名称，然后运行此命令列出您使用的 Amazon S3 存储桶中的对象。

      ```
      aws s3api list-objects --bucket bucket
      ```

      该命令返回存储桶中 Amazon S3 对象的列表，该列表如下所示。

      ```
      {
          "Contents": [
              {
                  "Key": "hello-world-job.json",
                  "LastModified": "2021-11-18T03:02:12+00:00",
                  "ETag": "\"868c8bc3f56b5787964764d4b18ed5ef\"",
                  "Size": 54,
                  "StorageClass": "STANDARD",
                  "Owner": {
                      "DisplayName": "EXAMPLE",
                      "ID": "e9e3d6ec1EXAMPLEf5bfb5e6bd0a2b6ed03884d1ed392a82ad011c144736a4ee"
                  }
              },
              {
                  "Key": "iot_job_firmware_update.json",
                  "LastModified": "2021-04-13T21:57:07+00:00",
                  "ETag": "\"7c68c591949391791ecf625253658c61\"",
                  "Size": 66,
                  "StorageClass": "STANDARD",
                  "Owner": {
                      "DisplayName": "EXAMPLE",
                      "ID": "e9e3d6ec1EXAMPLEf5bfb5e6bd0a2b6ed03884d1ed392a82ad011c144736a4ee"
                  }
              },
              {
                  "Key": "order66.json",
                  "LastModified": "2021-04-13T21:57:07+00:00",
                  "ETag": "\"bca60d5380b88e1a70cc27d321caba72\"",
                  "Size": 29,
                  "StorageClass": "STANDARD",
                  "Owner": {
                      "DisplayName": "EXAMPLE",
                      "ID": "e9e3d6ec1EXAMPLEf5bfb5e6bd0a2b6ed03884d1ed392a82ad011c144736a4ee"
                  }
              }
          ]
      }
      ```

   1. 对于从列表中识别为在此学习路径中创建的对象的每个对象，将 `bucket` 替换为要删除的对象的存储桶名称，将 `key` 替换为密钥值，然后运行此命令删除 Amazon S3 对象。

      ```
       aws s3api delete-object --bucket bucket --key key
      ```

      如果命令成功，该命令不返回任何内容。

删除完成此学习路径时创建的所有 AWS 资源和对象后，您可以重新开始并重复这些教程。