

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

# 在裝置離線時保留裝置狀態
<a name="iot-shadows-tutorial"></a>

這些教學課程說明如何使用 AWS IoT Device Shadow 服務來存放和更新裝置的狀態資訊。Shadow 文件是一個 JSON 文件，其根據裝置、本機應用程式或服務發佈的訊息，顯示裝置狀態的變化。於本教學課程中，Shadow 文件會顯示燈泡顏色的變化。這些教學課程還會顯示影子如何在裝置與網際網路中斷連線時，儲存此資訊，並在裝置回復連線並請求此資訊時，將最新狀態資訊傳回裝置。

建議您依此處顯示的順序試試這些教學課程，從您需要建立的 AWS IoT 資源和必要的硬體設定開始，這亦可協助您逐步學習概念。這些教學課程示範如何設定和連接 Raspberry Pi 裝置以搭配 使用 AWS IoT。若您並無所需的硬體，您可依照這些教學課程進行調整，以適應您選擇的裝置或[使用 Amazon EC2 建立虛擬裝置](creating-a-virtual-thing.md)。

**教學課程案例概觀**  
這些教學課程的案例為本機應用程式或服務，可變更燈泡的顏色，及將其資料發佈置預留的影子主題。這些教學課程類似於[互動式入門教學課程](interactive-demo.md)中說明的 Device Shadow 功能，並在 Raspberry Pi 裝置實作。本節中的教學課程側重於單一經典影子裝置，同時展現如何容納已命名影子或多個裝置的方法。

下列教學課程將協助您了解如何使用 AWS IoT Device Shadow 服務。
+ 

**[教學課程：準備好 Raspberry Pi 來執行影子應用程式](create-resources-shadow.md)**  
本教學課程說明如何設定 Raspberry Pi 裝置以進行連線 AWS IoT。您也將建立 AWS IoT 政策文件和物件資源、下載憑證，然後將政策連接到該物件資源。此教學課程約需 30 分鐘方能完成。
+ 

**[教學課程：安裝裝置 SDK 並執行 Device Shadows 的範例應用程式](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 Device Shadows 與燈泡狀態變更之間的互動。本教學課程也會展示如何將 MQTT 訊息傳送至 Device Shadow 的預留主題。此教學課程約需 45 分鐘方能完成。

**AWS IoT Device Shadow 概觀**  
Device Shadow 是由您在 AWS IoT 登錄檔中建立的[物件資源](iot-thing-management.md)管理之裝置的持久性虛擬表示法。Shadow 文件是個 JSON 或 JavaScript 標記法文件，用來存儲和檢索裝置的目前狀態資訊。您可透過 MQTT 或 HTTP REST API，使用影子來取得及設定裝置的狀態 (無論該裝置是否連線至網際網路)。

Shadow 的文件包含 `state` 屬性，說明裝置狀態的下列層面：
+ `desired`：應用程式會透過更新 `desired` 物件來指定裝置屬性的所需狀態。
+ `reported`：裝置會報告其在 `reported` 物件中的目前狀態。
+ `delta`： AWS IoT 報告 `delta` 物件中所需狀態與報告狀態之間的差異。

以下為 Shadow 狀態文件的範例：

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

如要更新裝置的 Shadow 文件，您可使用[預留的 MQTT 主題](reserved-topics.md#reserved-topics-shadow)、以 HTTP 支援 `GET`、`UPDATE` 和 `DELETE` 操作的 [Device Shadow REST API](device-shadow-rest-api.md)，以及 [AWS IoT CLI](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot-data/index.html)。

在上一個範例中，假設您想將 `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`。於此狀況下，Shadow 文件看起來像這樣：

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

接著會使用`$aws/things/THING_NAME/shadow/update`具有下列 JSON 訊息`Update`的主題，向 AWS IoT Device Shadow 報告新狀態：

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

若您想要取得目前的狀態資訊，請將請求傳送至 [GetThingShadow](device-shadow-rest-api.md#API_GetThingShadow) API 或將 MQTT 訊息發佈至[取得](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 Shadows 的詳細資訊，請參閱 [在裝置中使用影子](device-shadow-comms-device.md) 和 [在應用程式和服務中使用影子](device-shadow-comms-app.md)。

如需與 AWS IoT 陰影互動的資訊，請參閱 [與影子互動](device-shadow-data-flow.md)。

如需 MQTT 預留主題和 HTTP REST API 的相關資訊，請參閱 [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 互動。
+  AWS IoT 在 X.509 裝置憑證中建立物件資源，然後連接政策文件。

  問題是您的裝置在 AWS IoT 登錄檔中的虛擬表示。憑證會將您的裝置驗證為 AWS IoT Core，而政策文件會授權您的裝置與之互動 AWS IoT。

**如何執行本教學課程**  
如要執行 Device Shadows 的 `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 代 B 型](https://www.raspberrypi.com/products/)或更新的型號。本教學課程可能適用於較早版本的 Raspberry Pi，但我們尚未對其進行測試。
  + [Raspberry Pi OS (32 位元)](https://www.raspberrypi.com/software/operating-systems/) 或更新版本。我們建議您使用最新版本的 Raspberry Pi 作業系統。較早版本的作業系統可能適用，但我們尚未對其進行測試。
  + 乙太網路或 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 PC 或 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 電視或顯示器連接至連接到 Raspberry Pi 之 HDMI 連接埠的 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 policies 驗證您的裝置，會連接到允許裝置執行 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 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. 選擇 **Create a single thing** (建立單一物件)，在 **Name** (名稱) 欄位中，輸入與您先前建立政策時指定之 `thingname` 相同的物件名稱 (例如，`My_light_bulb`)。

   物件類型建立之後，您就無法變更其名稱。若您給它一個不同於 `thingname` 的名字，請建立名為 `thingname` 的新物件並刪除舊物件。
**注意**  
請勿在物件名稱中使用個人識別資訊。物件名稱可以出現在未加密的通訊和報告中。

1. 我們建議您將**憑證已建立！**頁面上的每個憑證檔案下載至您可輕鬆找到的位置。您必須安裝這些檔案，才能執行範例應用程式。

   建議您將檔案下載至 Raspberry Pi `home` 目錄中的 `certs` 子目錄上，並使用如下表中所建議更簡單名稱對其進行命名。  
**憑證檔案名稱**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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 Shadows 控制狀態。如需如何執行本教學課程的詳細資訊，請參閱 [教學課程：安裝裝置 SDK 並執行 Device Shadows 的範例應用程式](lightbulb-shadow-application.md)。

# 教學課程：安裝裝置 SDK 並執行 Device Shadows 的範例應用程式
<a name="lightbulb-shadow-application"></a>

本節說明如何安裝必要的軟體和適用於 Python 的 AWS IoT Device SDK，並執行`shadow.py`範例應用程式來編輯 Shadow 文件並控制影子的狀態。

**於本教學課程中，您會了解如何：**
+ 使用已安裝的軟體和適用於 Python 的 AWS IoT Device SDK 來執行範例應用程式。
+ 了解如何使用範例應用程式輸入值，以於 AWS IoT 主控台中發佈所需的值。
+ 檢閱 `shadow.py` 範例應用程式，及其如何使用 MQTT 通訊協定來更新影子的狀態。

**在您執行此教學課程之前：**  
您必須設定好 AWS 帳戶、設定 Raspberry Pi 裝置，並建立 AWS IoT 物件和政策，授予裝置發佈和訂閱 Device Shadow 服務 MQTT 預留主題的許可。如需詳細資訊，請參閱[教學課程：準備好 Raspberry Pi 來執行影子應用程式](create-resources-shadow.md)。

您還必須安裝 Git、Python 和適用於 Python 的 AWS IoT 裝置 SDK。本教學課程是以教學課程 [連接 Raspberry Pi 或其他裝置](connecting-to-existing-device.md) 中提出的概念為基礎。若您尚未嘗試該教學課程，建議您依照該教學課程中說明的步驟，安裝憑證檔案和裝置 SDK，然後回到本教學課程，執行 `shadow.py` 範例應用程式。

**Topics**
+ [步驟 1：執行 shadow.py 範例應用程式](#run-sample-application-shadows)
+ [步驟 2：檢閱 shadow.py 裝置 SDK 範例應用程式](#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_tw/iot/latest/developerguide/lightbulb-shadow-application.html)  | 

**安裝並執行範例應用程式**

1. 導覽至範例應用程式目錄。

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

1. 在命令列視窗中，按照指示替換 *your-iot-endpoint* 和 *your-iot-thing-name* 並執行此命令。

   ```
   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` 參數新增至命令列，以便範例應用程式會顯示有關其正在執行之動作的詳細訊息。

**輸入值並觀察 Shadow 文件中的更新**  
您可於終端機中輸入值，以指定 `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 建立預設、傳統陰影。您可以查看您建立之物件資源的 Shadow 文件 （例如，)，以觀察您發佈至 AWS IoT 主控台中 `reported`和 `desired`值的更新請求`My_light_bulb`。如要在 Shadow 文件中查看更新：

1. 在 AWS IoT 主控台中，選擇**管理**，然後選擇**實物**。

1. 在顯示的物件清單中，選取您所建立的物件，然後依序選擇 **Shadows** (影子) 和 **Classic Shadow** (經典影子)。

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
}
```

如要了解 Shadow 文件的更多資訊並觀察狀態資訊的變更，請繼續參閱說明於本教學課程 [步驟 4：檢閱結果及後續步驟](#sample-app-shadow-review) 部分中的下一個教學課程 [教學課程：使用範例應用程式和 MQTT 測試用戶端，與 Device Shadow 互動](interact-lights-device-shadows.md)。或者，您還可於下一節中了解 `shadow.py` 範本程式碼及其如何使用 MQTT 通訊協定。

## 步驟 2：檢閱 shadow.py 裝置 SDK 範例應用程式
<a name="review-shadow-sample-code"></a>

本節會從用於本教學課程中之**適用於 Python 的AWS IoT 裝置 SDK v2** 檢閱 `shadow.py` 範例應用程式。在這裡，我們將 AWS IoT Core 使用 MQTT 和透過 WSS 通訊協定的 MQTT 來檢閱它如何連接到 。[AWS 通用執行時間 (AWS-CRT)](https://github.com/awslabs/aws-crt-python#aws-crt-python) 程式庫提供低階通訊協定支援，並包含在適用於 Python 的 AWS IoT Device 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 身分驗證所使用的 AWS 簽署區域，`credentials_provider`也是提供用於身分驗證的 AWS 登入資料。從命令列傳入 Region (區域)，並在呼叫 `mqtt_connection_builder.websockets_with_default_aws_signing` 之前將 `credentials_provider` 物件實例化。
+ 若使用代理主機，`websocket_proxy_options` 是 HTTP 代理選項。在 `shadow.py` 範例應用程式中，此值在呼叫 `mqtt_connection_builder.websockets_with_default_aws_signing` 之前進行實例化。

**訂閱 Shadow 主題和事件**  
`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 裝置 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`。於此狀況下，您可檢查下列事項：
+ 

**檢查命令中的端點的地址**  
請檢閱您為執行範例應用程式 (例如 `a3qEXAMPLEffp-ats.iot.us-west-2.amazonaws.com`) 輸入命令中的 `endpoint` 引數，並在 **AWS IoT 主控台** 中檢查此值。

  如要檢查您是否使用了正確的值：

  1. 於 **AWS IoT 主控台**中，依序選擇 **Manage** (管理) 和 **Things** (物件)。

  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. 選取憑證，然後從憑證的詳細資料頁面選擇 Select the certificate (選取憑證)，然後從憑證的詳細資料頁面選擇 **Actions** (動作)。

  若於下拉式清單中 **Activate** (啟用) 無法使用，則您只能選擇 **Deactivate**(停用)，表示您的憑證處於作用中。若無，請選擇 **Activate** (啟用)，然後重新執行範例程式。

  若程式仍然無法執行，請檢查 `certs` 資料夾中的憑證檔案名稱。
+ 

**檢查連接至該物件資源的政策**  
當憑證驗證您的裝置時， AWS IoT 政策會允許裝置執行 AWS IoT 操作，例如訂閱或發佈至 MQTT 預留主題。

  如要檢查是否已連接正確的政策：

  1. 如先前所述尋找憑證，然後選擇 **Policies** (政策)。

  1. 選擇顯示的政策，並檢查其是否說明了授予裝置發佈和訂閱 MQTT 預留主題之許可權限的 `connect`、`subscribe`、`receive` 和 `publish` 動作。

     若是範例政策，請參閱 [步驟 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": "*"
        }
    ]
  }
  ```
+ 

**檢查您的裝置 SDK 安裝**  
若程式仍然無法執行，您可重新安裝裝置 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 Shadows 來控制狀態。您可以觀察 AWS IoT 主控台中 Shadow 文件的更新，並觀察範例應用程式回應的差異事件。使用 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 文件，以觀察差異事件，及 `shadow.py` 範例應用程序如何加以回應。
+ 使用 MQTT 測試用戶端訂閱影子主題，並在執行範例程式時觀察更新。

**執行本教學課程之前，您必須具備：**  
設定您的 AWS 帳戶、設定您的 Raspberry Pi 裝置，並建立 AWS IoT 物件和政策。您也必須安裝了必要的軟體、裝置 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：檢視 MQTT 測試用戶端中 `shadow.py` 範例應用程式的訊息](#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 文件的訊息，如 一節所述[教學課程：安裝裝置 SDK 並執行 Device Shadows 的範例應用程式](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 文件以觀察差異事件**  
`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：檢視 MQTT 測試用戶端中 `shadow.py` 範例應用程式的訊息
<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 用戶端前往主控台中的另一個頁面，其不會保留任何訂閱或訊息記錄。在教學課程的本節中，您可以讓 AWS IoT 物件的 Shadow 文件和 MQTT 測試用戶端在不同的視窗中開啟，以更輕鬆地觀察與 Device Shadows 的互動。

1. 

**訂閱 MQTT 預留的 Shadow 主題**

   您可使用 MQTT 測試用戶端輸入 Device Shadow 之 MQTT 預留主題的名稱，並加以訂閱，以於執行 `shadow.py` 範例應用程式時收到更新。如要訂閱主題：

   1. 於 **AWS IoT 主控台**的 **MQTT 測試用戶端**中，選擇 **Subscribe to a topic** (訂閱主題)。

   1.  於 **主題篩選條件**區段中，輸入：**\$1aws/things/*thingname*/shadow/update/\$1**。在此，`thingname` 是您先前所建立物件資源的名稱 (例如，`My_light_bulb`)。

   1. 保留其他組態設定的預設值，然後選擇 **Subscribe** (訂閱)。

   在主題訂閱中使用 **\$1** 萬用字元，您可同時訂閱多個 MQTT 主題，並在單一視窗中觀察裝置及其 Shadow 間交換的所有訊息。如需萬用字元及其用法的詳細資訊，請參閱 [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/*thingname*/shadow/get** 和 **\$1aws/things/*thingname*/shadow/get/accepted**。

      假設回報的最新顏色是 `green`。下列會顯示 **\$1aws/things/*thingname*/shadow/get/accepted** JSON 檔案的內容。

      ```
      {
      "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 console (主控台)** **MQTT test client (MQTT 測試用戶端)** 的 **Subscriptions (訂閱)** 之下，您會看到下列主題收到訊息：
      + **\$1aws/things/*thingname*/shadow/update**：顯示 `desired` 和 `updated` 值會變更為顏色 `yellow`。
      + **\$1aws/things/*thingname*/shadow/update/accepted**：顯示 `desired` 和 `reported` 狀態的目前值及其中繼資料和版本資訊。
      + **\$1aws/things/*thingname*/shadow/update/documents**：顯示 `desired` 和 `reported` 狀態的先前的值和目前值及其中繼資料和版本資訊。

      作為文件 **\$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. 

**編輯 Shadow 文件以觀察差異事件**

   如要觀察差異主題的變更，請編輯 AWS IoT 主控台中的 Shadow 文件。例如，您可將 `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>

當您執行 Shadow 範例應用程式時，您可能會遇到觀察與 Device Shadow 服務互動的問題。

若程式執行成功，並提示您輸入 `desired` 值，您應可使用如前所述的 Shadow 文件和 MQTT 測試用戶端，觀察 Device Shadow 互動。不過，若您無法看到互動，您可檢查下列事項：
+ 

**在 AWS IoT 主控台中檢查物件名稱及其影子**  
若您看不到 Shadow 文件中的訊息，請檢閱命令，並確定其符合 **AWS IoT 主控台**中的物件名稱。您還可依序選擇您的物件名稱和 **Shadows** (影子)，來檢查您是否有經典影子。本教學課程主要著重於與經典影子的互動。

   您也可以確認您使用的裝置已連線至網際網路。於 **AWS IoT 主控台**中，選擇您先前建立的物件，然後選擇 **Interact** (互動)。在物件詳細資訊頁面上，您應會在此處看到訊息：`This thing already appears to be connected.`
+ 

**查看您訂閱的 MQTT 預留主題**  
若您在 MQTT 測試用戶端中看不到訊息，請檢查您訂閱的主題是否已正確格式化。MQTT Device Shadow 主題具有格式 **\$1aws/things/*thingname*/shadow/**，且可能具有 `update`、`get` 或 `delete`，根據您希望對影子執行的動作而定。本教學課程使用主題 **\$1aws/things/*thingname*/shadow/\$1**，因此，在訂閱測試用戶端之**主題篩選條件**部分中的主題時，請確定您已正確輸入。

  當您輸入主題名稱時，請確定 *thingname* 與您先前建立的 AWS IoT 物件名稱相同。您還可訂閱其他 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 文件，以觀察差異事件，及 `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)。

您也可選擇使用命名影子或使用為 LED 與 Raspberry Pi 連接其他的硬體擴展您的應用程式，並使用從終端傳送訊息來觀察其狀態的變化。

如需有關 Device Shadows 服務及在裝置、應用程式和服務中使用服務的詳細資訊，請參閱 [AWS IoT Device Shadow 服務](iot-device-shadows.md)、[在裝置中使用影子](device-shadow-comms-device.md) and [在應用程式和服務中使用影子](device-shadow-comms-app.md)。