

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

# AWS IoT Device Shadow 服務
<a name="iot-device-shadows"></a>

 AWS IoT Device Shadow 服務會將陰影新增至 AWS IoT 物件。影子可讓應用程式和其他服務使用裝置的狀態，無論裝置是否連接到 AWS IoT 。 AWS IoT 物件可以有多個具名影子，讓您的 IoT 解決方案有更多選項可將您的裝置連接到其他應用程式和服務。

AWS IoT 物件在明確建立之前沒有任何陰影。您可以使用 AWS IoT 主控台建立、更新和刪除陰影。裝置、其他 Web 用戶端和服務可使用 MQTT 及[預留的 MQTT 主題](reserved-topics.md#reserved-topics-shadow)、使用 [Device Shadow REST API](device-shadow-rest-api.md) 的 HTTP，以及 [AWS IoT的AWS CLI](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot-data/index.html)。由於陰影由 存放在 AWS 雲端，因此無論裝置是否已連線，它們都可以從應用程式和其他雲端服務收集和報告裝置狀態資料。

## 使用影子
<a name="device-shadow-using"></a>

影子會提供可靠的資料存放區，讓裝置、應用程式和其他雲端服務共用資料。它們可讓裝置、應用程式和其他雲端服務連線和中斷連線，而不會遺失裝置的狀態。

當裝置、應用程式和其他雲端服務連線時 AWS IoT，他們可以透過其影子來存取和控制裝置的目前狀態。例如，應用程式可以透過更新影子來請求裝置狀態的變更。 會 AWS IoT 發佈訊息，指出裝置變更。裝置會接收此訊息、更新其狀態以符合，並發佈具有更新狀態的訊息。Device Shadow 服務會在對應的影子中反映此更新的狀態。應用程式可以訂閱影子的更新，也可以查詢影子的目前狀態。

當裝置離線時，應用程式仍可與 AWS IoT 和裝置的陰影通訊。當裝置重新連線時，它會收到其影子的目前狀態，以便更新其狀態以符合其影子的狀態，然後發佈具有更新狀態的訊息。同樣地，當應用程式離線且裝置狀態在離線時變更時，裝置會保持影子更新，以便在重新連線時，應用程式可以查詢其目前狀態的影子。

如果您的裝置頻繁離線，而您希望將裝置設定為在重新連線後接收增量訊息，則可以使用持續工作階段功能。如需持續工作階段有效期限的詳細資訊，請參閱[持續工作階段有效期限](https://docs.aws.amazon.com//general/latest/gr/iot-core.html#message-broker-limits)。

### 選擇使用已命名或未命名的影子
<a name="iot-device-shadow-named"></a>

Device Shadow 服務支援已命名、未命名或傳統的影子。一個物件可以有多個已命名的影子，並且不超過一個未命名的影子。物件也可以具有預留已命名影子，其運作方式與已命名影子類似，只是您無法更新其名稱。如需詳細資訊，請參閱[預留已命名影子](https://docs.aws.amazon.com/iot/latest/developerguide/preparing-to-use-software-package-catalog.html#reserved-named-shadow)。

一個物件物件可以同時具有已命名和未命名的影子；但是用於存取每個影子的 API 略有不同，所以決定最適合您解決方案的影子類型並僅使用該類型可能會更有效率。如需存取影子 API 的詳細資訊，請參閱 [影子主題](reserved-topics.md#reserved-topics-shadow)。

使用已命名的影子，您可以建立物件物件狀態的不同檢視。例如，您可以將具有許多屬性的物件物件分割成具有邏輯屬性群組的影子，每個屬性都用其影子名稱加以識別。您也可以透過將屬性分組成不同的影子，並使用原則來控制存取來限制屬性的存取權限。如需與裝置影子搭配使用之政策的詳細資訊，請參閱[適用於 AWS IoT的動作、資源及條件索引鍵](https://docs.aws.amazon.com//service-authorization/latest/reference/list_awsiot.html)及 [AWS IoT Core 政策](https://docs.aws.amazon.com//iot/latest/developerguide/iot-policies.html)。

典型、未命名的影子比已命名的影子更簡單，但限制比已命名的影子多。每個 AWS IoT 物件只能有一個未命名的影子。如果您預期 IoT 解決方案對影子資料的需求有限，這可能就是您要開始使用影子的契機。但是，如果您認為未來可能想要增加其他影子，請考慮從一開始就使用已命名的影子。

機群索引以不同方式支援未命名的影子和已命名的影子。如需詳細資訊，請參閱[管理機群索引](managing-fleet-index.md)。

### 存取影子
<a name="device-shadow-using-access"></a>

每個影子都有預留的 [MQTT 主題](reserved-topics.md#reserved-topics-shadow)和 [HTTP URL](device-shadow-rest-api.md)，其支援在影子上的 `get`、`update` 和 `delete` 動作。

影子會使用 [JSON 影子文件](device-shadow-document.md) 來儲存和擷取資料。影子的文件包含狀態屬性，描述裝置狀態的下列層面：
+ `desired`

  應用程式會透過更新 `desired` 物件來指定裝置屬性的所需狀態。
+ `reported`

  裝置會報告 `reported` 物件中的目前狀態。
+ `delta`

  AWS IoT 會報告 `delta` 物件中所需狀態與報告狀態之間的差異。

儲存在影子中的資料會由更新動作訊息內文的狀態屬性決定。後續的更新動作可以修改現有資料物件的值，也可以在影子的狀態物件中新增和刪除金鑰和其他元素。如需存取影子的詳細資訊，請參閱 [在裝置中使用影子](device-shadow-comms-device.md) 和 [在應用程式和服務中使用影子](device-shadow-comms-app.md)。

**重要**  
提出更新要求的權限應限於受信任的應用程式和裝置。這可以防止影子的狀態屬性遭意外地變更；否則，使用影子的裝置和應用程式的設計應預期狀態屬性中的金鑰會變更。

### 在裝置、應用程式和其他雲端服務中使用影子
<a name="device-shadow-implementing"></a>

在裝置、應用程式和其他雲端服務中使用影子需要一致性和協調性。 AWS IoT Device Shadow 服務會儲存陰影狀態、在陰影狀態變更時傳送訊息，以及回應變更其狀態的訊息。IoT 解決方案中的裝置、應用程式和其他雲端服務必須管理其狀態，並使其與 Device Shadow 狀態保持一致。

影子狀態資料是動態的，可由裝置、應用程式和其他具有存取影子權限的雲端服務進行變更。基於這個原因，請務必考慮每個裝置、應用程式和其他雲端服務如何與影子互動。例如：
+ 將狀態資料傳到影子時，*設備*應該只會寫入影子狀態的 `reported` 屬性。
+ 透過影子將狀態變更要求傳給裝置時，*應用程式和其他雲端服務*應該只會寫入 `desired` 屬性。

**重要**  
包含在影子資料物件中的資料是獨立於其他影子和其他物件物件屬性的資料，例如物件的屬性和物件物件的裝置可能發佈的 MQTT 訊息內容。但如有必要，裝置可以在不同的 MQTT 主題和影子中報告相同的資料。  
支援多重影子的裝置必須維持它在不同影子中報告之資料的一致性。

### 訊息順序
<a name="message-ordering"></a>

我們無法保證服務的訊息 AWS IoT 會以任何特定順序送達裝置。下列情境說明在此情況下會發生的情況。

初始狀態文件：

```
{
  "state": {
    "reported": {
      "color": "blue"
    }
  },
  "version": 9,
  "timestamp": 123456776
}
```

更新 1：

```
{
  "state": {
    "desired": {
      "color": "RED"
    }
  },
  "version": 10,
  "timestamp": 123456777
}
```

更新 2：

```
{
  "state": {
    "desired": {
      "color": "GREEN"
    }
  },
  "version": 11,
  "timestamp": 123456778
}
```

最終狀態文件：

```
{
  "state": {
    "reported": {
      "color": "GREEN"
    }
  },
  "version": 12,
  "timestamp": 123456779
}
```

這樣會產生兩個差量訊息：

```
{
  "state": {
    "color": "RED"
  },
  "version": 11,
  "timestamp": 123456778
}
```

```
{
  "state": {
    "color": "GREEN"
  },
  "version": 12,
  "timestamp": 123456779
}
```

裝置可能不會依此順序收到這些訊息。由於這些訊息中的狀態是累積的，因此裝置可以安全捨棄比追蹤中版本編號更舊的所有訊息。如果裝置在接收到版本 11 的差量之前收到了版本 12 的差量，則可安全捨棄版本 11 的訊息。

### 裁剪影子訊息
<a name="device-shadow-trim-messages"></a>

若要減少傳送至您裝置的影子訊息大小，請定義只選擇了裝置所需之欄位的規則，然後將訊息重新發佈至裝置目前監聽的 MQTT 主題。

規則是在 JSON 中指定，並應如下所示：

```
{
  "sql": "SELECT state, version FROM '$aws/things/+/shadow/update/delta'",
  "ruleDisabled": false,
  "actions": [
    {
      "republish": {
        "topic": "${topic(3)}/delta",
        "roleArn": "arn:aws:iam:123456789012:role/my-iot-role"
      }
    }
  ]
}
```

SELECT 陳述會決定將訊息的哪些欄位重新發佈至指定主題。使用 "\$1" 萬用字元表示所有影子名稱。規則會指定所有符合的訊息都應重新發佈至指定主題。在這種情況下，該 `"topic()"` 函數是用於指定要重新發佈的主題。`topic(3)` 會評估原始主題中的物件名稱。如需關於建立規則的詳細資訊，請參閱 [的規則 AWS IoT](iot-rules.md)。