

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

# 与本地影子交互
<a name="ipc-local-shadows"></a>

使用影子 IPC 服务与设备上的本地影子交互。您选择与之交互的设备可以是您的核心设备或连接的客户端设备。

要使用这些 IPC 操作，请将[影子管理器组件](shadow-manager-component.md)作为依赖关系包含在自定义组件中。然后，您可以在自定义组件中使用 IPC 操作，通过影子管理器与设备上的本地影子交互。要使自定义组件能够对本地阴影状态的变化做出反应，您还可以使用 publish/subscribe IPC 服务订阅影子事件。有关使用该 publish/subscribe 服务的更多信息，请参阅[发布/订阅本地消息](ipc-publish-subscribe.md)。

**注意**  <a name="note-requirement-enable-shadow-manager-client-devices"></a>
要使核心设备能够与客户端设备影子交互，您还必须配置和部署 MQTT 网桥组件。有关更多信息，请参阅[启用影子管理器以与客户端设备通信](work-with-client-device-shadows.md)。

**Topics**
+ [最低 SDK 版本](#ipc-local-shadows-sdk-versions)
+ [Authorization](#ipc-local-shadow-authorization)
+ [GetThingShadow](#ipc-operation-getthingshadow)
+ [UpdateThingShadow](#ipc-operation-updatethingshadow)
+ [DeleteThingShadow](#ipc-operation-deletethingshadow)
+ [ListNamedShadowsForThing](#ipc-operation-listnamedshadowsforthing)

## 最低 SDK 版本
<a name="ipc-local-shadows-sdk-versions"></a>

下表列出了与本地阴影交互时必须使用的最低版本。 AWS IoT Device SDK 


| SDK | 最低版本 | 
| --- | --- | 
|  [AWS IoT Device SDK 适用于 Java v2](https://github.com/aws/aws-iot-device-sdk-java-v2)  |  v1.4.0  | 
|  [AWS IoT Device SDK 适用于 Python v2](https://github.com/aws/aws-iot-device-sdk-python-v2)  |  v1.6.0  | 
|  [AWS IoT Device SDK 适用于 C\$1\$1 v2](https://github.com/aws/aws-iot-device-sdk-cpp-v2)  |  v1.17.0  | 
|  [AWS IoT Device SDK 适用于 JavaScript v2](https://github.com/aws/aws-iot-device-sdk-js-v2)  |  v1.12.0  | 

## Authorization
<a name="ipc-local-shadow-authorization"></a>

要在自定义组件中使用影子 IPC 服务，必须定义允许您的组件与影子交互的授权策略。有关定义授权策略的信息，请参阅[授权组件执行 IPC 操作](interprocess-communication.md#ipc-authorization-policies)。

影子交互授权策略具有以下属性。

**IPC 服务标识符：**`aws.greengrass.ShadowManager`


| 操作 | 说明 | 资源 | 
| --- | --- | --- | 
|  `aws.greengrass#GetThingShadow`  |  允许组件检索事物的影子。  |  以下字符串之一： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v2/developerguide/ipc-local-shadows.html)  | 
|  `aws.greengrass#UpdateThingShadow`  |  允许组件更新事物的影子。  |  以下字符串之一： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v2/developerguide/ipc-local-shadows.html)  | 
|  `aws.greengrass#DeleteThingShadow`  |  允许组件删除事物的影子。  |  以下字符串之一： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v2/developerguide/ipc-local-shadows.html)  | 
|  `aws.greengrass#ListNamedShadowsForThing`  |  允许组件为事物检索已命名影子列表。  |  允许访问事物以列出其影子的事物名称字符串。 用 `*` 以允许访问所有事物。  | 

**IPC 服务标识符：**`aws.greengrass.ipc.pubsub`


| 操作 | 说明 | 资源 | 
| --- | --- | --- | 
|  `aws.greengrass#SubscribeToTopic`  |  允许组件订阅您指定主题的消息。  |  以下主题字符串之一： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v2/developerguide/ipc-local-shadows.html) 主题前缀 `shadowTopicPrefix` 的值取决于影子类型： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/greengrass/v2/developerguide/ipc-local-shadows.html) 用 `*` 以允许访问所有主题。 <a name="ipc-local-publish-subscribe-authorization-mqtt-wildcards"></a>在 [Greengrass Nucleus](greengrass-nucleus-component.md) v2.6.0 及更高版本中，您可以订阅包含 MQTT 主题通配符（`#` 和 `+`）的主题。此主题字符串支持 MQTT 主题通配符作为文字字符。例如，如果组件的授权策略授予访问 `test/topic/#` 的权限，则该组件可以订阅 `test/topic/#`，但无法订阅 `test/topic/filter`。  | 

### 本地影子授权策略中的配方变量
<a name="ipc-local-shadow-authorization-recipe-variables"></a>

[如果您使用 Greengrass 核心的 v2.6.0 或更高版本，并且将 [Greengrass nucleus](greengrass-nucleus-component.md) 的配置选项设置为，则可以在授权策略中使用配方变量[interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration)。`true``{iot:thingName}`](component-recipe-reference.md#recipe-variables)此功能允许您为一组核心设备配置单个授权策略，其中每个核心设备只能访问自己的影子。例如，您可以允许组件访问以下适用于影子 IPC 操作的资源。

```
$aws/things/{iot:thingName}/shadow/
```

### 授权策略示例
<a name="ipc-local-shadow-authorization-policy-examples"></a>

您可以参考以下授权策略示例，帮助您为组件配置授权策略。

**Example 示例：允许一组核心设备与本地影子交互**  
 <a name="phrase-example-uses-recipe-variables-in-configuration"></a>此示例使用了 [Greengrass Nucleus 组件](greengrass-nucleus-component.md)的 v2.6.0 及更高版本中可用的功能。Greengrass Nucleus v2.6.0 在组件配置中添加了对大多数[配方变量](component-recipe-reference.md#recipe-variables)（例如 `{iot:thingName}`）的支持。要启用此功能，请将 Green [interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration)grass 核的配置选项设置为。`true`有关适用于所有版本 Greengrass Nucleus 的示例，请参阅[单个核心设备的授权策略示例](#ipc-local-shadows-authorization-example-single-device)。
以下示例授权策略允许组件 `com.example.MyShadowInteractionComponent` 与经典设备影子以及运行该组件的核心设备的已命名影子 `myNamedShadow` 进行交互。此策略还允许此组件接收这些影子的本地主题消息。  

```
{
  "accessControl": {
    "aws.greengrass.ShadowManager": {
      "com.example.MyShadowInteractionComponent:shadow:1": {
        "policyDescription": "Allows access to shadows",
        "operations": [
          "aws.greengrass#GetThingShadow",
          "aws.greengrass#UpdateThingShadow",
          "aws.greengrass#DeleteThingShadow"
        ],
        "resources": [
          "$aws/things/{iot:thingName}/shadow",
          "$aws/things/{iot:thingName}/shadow/name/myNamedShadow"
        ]
      },
      "com.example.MyShadowInteractionComponent:shadow:2": {
        "policyDescription": "Allows access to things with shadows",
        "operations": [
          "aws.greengrass#ListNamedShadowsForThing"
        ],
        "resources": [
          "{iot:thingName}"
        ]
      }    
    },
    "aws.greengrass.ipc.pubsub": {
      "com.example.MyShadowInteractionComponent:pubsub:1": {
        "policyDescription": "Allows access to shadow pubsub topics",
        "operations": [
          "aws.greengrass#SubscribeToTopic"
        ],
        "resources": [
          "$aws/things/{iot:thingName}/shadow/get/accepted",
          "$aws/things/{iot:thingName}/shadow/name/myNamedShadow/get/accepted"
        ]
      }
    }
  }
}
```

```
accessControl:
  aws.greengrass.ShadowManager:
    'com.example.MyShadowInteractionComponent:shadow:1':
      policyDescription: 'Allows access to shadows'
      operations:
        - 'aws.greengrass#GetThingShadow'
        - 'aws.greengrass#UpdateThingShadow'
        - 'aws.greengrass#DeleteThingShadow'
      resources:
        - $aws/things/{iot:thingName}/shadow
        - $aws/things/{iot:thingName}/shadow/name/myNamedShadow
    'com.example.MyShadowInteractionComponent:shadow:2':
      policyDescription: 'Allows access to things with shadows'
      operations:
        - 'aws.greengrass#ListNamedShadowsForThing'
      resources:
        - '{iot:thingName}'
  aws.greengrass.ipc.pubsub:
    'com.example.MyShadowInteractionComponent:pubsub:1':
      policyDescription: 'Allows access to shadow pubsub topics'
      operations:
        - 'aws.greengrass#SubscribeToTopic'
      resources:
        - $aws/things/{iot:thingName}/shadow/get/accepted
        - $aws/things/{iot:thingName}/shadow/name/myNamedShadow/get/accepted
```

**Example 示例：允许一组核心设备与客户端设备影子交互**  
此功能需要 [Greengrass Nucleus](greengrass-nucleus-component.md) v2.6.0 或更高版本、[影子管理器](shadow-manager-component.md) v2.2.0 或更高版本以及 [MQTT 网桥器](mqtt-bridge-component.md) v2.2.0 或更高版本。您必须配置 MQTT 网桥器才能[使影子管理器能够与客户端设备通信](work-with-client-device-shadows.md#enable-shadow-manager-client-devices)。
以下示例授权策略允许组件 `com.example.MyShadowInteractionComponent` 与名称以 `MyClientDevice` 开头的客户端设备的所有设备影子进行交互。  
要使核心设备能够与客户端设备影子交互，您还必须配置和部署 MQTT 网桥组件。有关更多信息，请参阅[启用影子管理器以与客户端设备通信](work-with-client-device-shadows.md)。

```
{
  "accessControl": {
    "aws.greengrass.ShadowManager": {
      "com.example.MyShadowInteractionComponent:shadow:1": {
        "policyDescription": "Allows access to shadows",
        "operations": [
          "aws.greengrass#GetThingShadow",
          "aws.greengrass#UpdateThingShadow",
          "aws.greengrass#DeleteThingShadow"
        ],
        "resources": [
          "$aws/things/MyClientDevice*/shadow",
          "$aws/things/MyClientDevice*/shadow/name/*"
        ]
      },
      "com.example.MyShadowInteractionComponent:shadow:2": {
        "policyDescription": "Allows access to things with shadows",
        "operations": [
          "aws.greengrass#ListNamedShadowsForThing"
        ],
        "resources": [
          "MyClientDevice*"
        ]
      }    
    }
  }
}
```

```
accessControl:
  aws.greengrass.ShadowManager:
    'com.example.MyShadowInteractionComponent:shadow:1':
      policyDescription: 'Allows access to shadows'
      operations:
        - 'aws.greengrass#GetThingShadow'
        - 'aws.greengrass#UpdateThingShadow'
        - 'aws.greengrass#DeleteThingShadow'
      resources:
        - $aws/things/MyClientDevice*/shadow
        - $aws/things/MyClientDevice*/shadow/name/*
    'com.example.MyShadowInteractionComponent:shadow:2':
      policyDescription: 'Allows access to things with shadows'
      operations:
        - 'aws.greengrass#ListNamedShadowsForThing'
      resources:
        - MyClientDevice*
```<a name="ipc-local-shadows-authorization-example-single-device"></a>

**Example 示例：允许单个核心设备与本地影子交互**  
以下示例授权策略允许组件 `com.example.MyShadowInteractionComponent` 与设备 `MyThingName` 的经典设备影子和已命名影子 `myNamedShadow` 进行交互。此策略还允许此组件接收这些影子的本地主题消息。  

```
{
  "accessControl": {
    "aws.greengrass.ShadowManager": {
      "com.example.MyShadowInteractionComponent:shadow:1": {
        "policyDescription": "Allows access to shadows",
        "operations": [
          "aws.greengrass#GetThingShadow",
          "aws.greengrass#UpdateThingShadow",
          "aws.greengrass#DeleteThingShadow"
        ],
        "resources": [
          "$aws/things/MyThingName/shadow",
          "$aws/things/MyThingName/shadow/name/myNamedShadow"
        ]
      },
      "com.example.MyShadowInteractionComponent:shadow:2": {
        "policyDescription": "Allows access to things with shadows",
        "operations": [
          "aws.greengrass#ListNamedShadowsForThing"
        ],
        "resources": [
          "MyThingName"
        ]
      }    
    },
    "aws.greengrass.ipc.pubsub": {
      "com.example.MyShadowInteractionComponent:pubsub:1": {
        "policyDescription": "Allows access to shadow pubsub topics",
        "operations": [
          "aws.greengrass#SubscribeToTopic"
        ],
        "resources": [
          "$aws/things/MyThingName/shadow/get/accepted",
          "$aws/things/MyThingName/shadow/name/myNamedShadow/get/accepted"
        ]
      }
    }
  }
}
```

```
accessControl:
  aws.greengrass.ShadowManager:
    'com.example.MyShadowInteractionComponent:shadow:1':
      policyDescription: 'Allows access to shadows'
      operations:
        - 'aws.greengrass#GetThingShadow'
        - 'aws.greengrass#UpdateThingShadow'
        - 'aws.greengrass#DeleteThingShadow'
      resources:
        - $aws/things/MyThingName/shadow
        - $aws/things/MyThingName/shadow/name/myNamedShadow
    'com.example.MyShadowInteractionComponent:shadow:2':
      policyDescription: 'Allows access to things with shadows'
      operations:
        - 'aws.greengrass#ListNamedShadowsForThing'
      resources:
        - MyThingName
  aws.greengrass.ipc.pubsub:
    'com.example.MyShadowInteractionComponent:pubsub:1':
      policyDescription: 'Allows access to shadow pubsub topics'
      operations:
        - 'aws.greengrass#SubscribeToTopic'
      resources:
        - $aws/things/MyThingName/shadow/get/accepted
        - $aws/things/MyThingName/shadow/name/myNamedShadow/get/accepted
```<a name="interact-with-shadows-react-example-authorization-policies"></a>

**Example 示例：允许一组核心设备对本地影子状态变化做出反应**  
 <a name="phrase-example-uses-recipe-variables-in-configuration"></a>此示例使用了 [Greengrass Nucleus 组件](greengrass-nucleus-component.md)的 v2.6.0 及更高版本中可用的功能。Greengrass Nucleus v2.6.0 在组件配置中添加了对大多数[配方变量](component-recipe-reference.md#recipe-variables)（例如 `{iot:thingName}`）的支持。要启用此功能，请将 Green [interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration)grass 核的配置选项设置为。`true`有关适用于所有版本 Greengrass Nucleus 的示例，请参阅[单个核心设备的授权策略示例](#interact-with-shadows-react-example-authorization-policy-single-device)。
以下示例访问控制策略允许自定义 `com.example.MyShadowReactiveComponent` 在运行该组件的每台核心设备上接收有关经典设备影子和已命名影子 `myNamedShadow` 的 `/update/delta` 主题消息。  

```
{
  "accessControl": {
    "aws.greengrass.ipc.pubsub": {
      "com.example.MyShadowReactiveComponent:pubsub:1": {
        "policyDescription": "Allows access to shadow pubsub topics",
        "operations": [
          "aws.greengrass#SubscribeToTopic"
        ],
        "resources": [
          "$aws/things/{iot:thingName}/shadow/update/delta",
          "$aws/things/{iot:thingName}/shadow/name/myNamedShadow/update/delta"
        ]
      }
    }
  }
}
```

```
accessControl:
  aws.greengrass.ipc.pubsub:
    "com.example.MyShadowReactiveComponent:pubsub:1":
      policyDescription: Allows access to shadow pubsub topics
      operations:
        - 'aws.greengrass#SubscribeToTopic'
      resources:
        - $aws/things/{iot:thingName}/shadow/update/delta
        - $aws/things/{iot:thingName}/shadow/name/myNamedShadow/update/delta
```<a name="interact-with-shadows-react-example-authorization-policy-single-device"></a>

**Example 示例：允许单个核心设备对本地影子状态变化做出反应**  
以下示例访问控制策略允许自定义 `com.example.MyShadowReactiveComponent` 接收有关设备 `MyThingName` 的经典设备影子和已命名影子 `myNamedShadow` 的 `/update/delta` 主题消息。  

```
{
  "accessControl": {
    "aws.greengrass.ipc.pubsub": {
      "com.example.MyShadowReactiveComponent:pubsub:1": {
        "policyDescription": "Allows access to shadow pubsub topics",
        "operations": [
          "aws.greengrass#SubscribeToTopic"
        ],
        "resources": [
          "$aws/things/MyThingName/shadow/update/delta",
          "$aws/things/MyThingName/shadow/name/myNamedShadow/update/delta"
        ]
      }
    }
  }
}
```

```
accessControl:
  aws.greengrass.ipc.pubsub:
    "com.example.MyShadowReactiveComponent:pubsub:1":
      policyDescription: Allows access to shadow pubsub topics
      operations:
        - 'aws.greengrass#SubscribeToTopic'
      resources:
        - $aws/things/MyThingName/shadow/update/delta
        - $aws/things/MyThingName/shadow/name/myNamedShadow/update/delta
```

## GetThingShadow
<a name="ipc-operation-getthingshadow"></a>

获取指定事物的影子。

### 请求
<a name="ipc-operation-getthingshadow-request"></a>

此操作的请求包含以下参数：

`thingName` (Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
事物的名称。  
类型：`string`

`shadowName` (Python: `shadow_name`)  <a name="ipc-local-shadows-shadow-name"></a>
影子的名称。要指定事物的经典影子，请将此参数设置为空字符串 (`""`)。  
该 AWS IoT Greengrass 服务使用`AWSManagedGreengrassV2Deployment`命名的影子来管理针对单个核心设备的部署。这个名为 shadow 的保留供 AWS IoT Greengrass 服务使用。请勿更新或删除该已命名影子。
类型：`string`

### 响应
<a name="ipc-operation-getthingshadow-response"></a>

此操作的响应包含以下信息：

`payload`  
响应状态文档为 blob。  
类型：包含以下信息的 `object`：    
`state`  
状态信息。  
该对象包含以下信息。    
`desired`  
请求在设备中更新的状态属性和值。  
类型：键/值对 `map`  
`reported`  
设备报告的状态属性和值。  
类型：键/值对 `map`  
`delta`  
所需状态和报告的状态属性和值之间的差异。仅当 `desired` 和 `reported` 状态不同时，才会出现此属性。  
类型：键/值对 `map`  
`metadata`  
`desired` 和 `reported` 部分中每个属性的时间戳，因此，您可以确定状态的更新时间。  
类型：`string`  
`timestamp`  
生成响应时的 Epoch 日期和时间。  
类型：`integer`  
`clientToken` (Python: `clientToken`)  
用于匹配请求和相应响应的令牌。  
类型：`string`  
`version`  
本地影子文档版本。  
类型：`integer`

### 错误
<a name="ipc-operation-getthingshadow-errors"></a>

此操作可返回以下错误。

`InvalidArgumentsError`  <a name="ipc-invalidargumentserror"></a>
<a name="ipc-invalidargumentserror-para"></a>本地影子服务无法验证请求参数。如果请求包含格式错误的 JSON 或不支持的字符，则可能会发生这种情况。

`ResourceNotFoundError`  <a name="ipc-resourcenotfounderror"></a>
无法找到请求的本地影子文档。

`ServiceError`  <a name="ipc-serviceerror"></a>
发生了内部服务错误，或者对 IPC 服务的请求数超过了影子管理器组件中 `maxLocalRequestsPerSecondPerThing` 和 `maxTotalLocalRequestsRate` 配置参数中指定的限制。

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
该组件的授权策略不包括此操作所需权限。

### 示例
<a name="ipc-operation-getthingshadow-examples"></a>

以下示例演示了如何在自定义组件代码中调用该操作。

------
#### [ Java (IPC client V1) ]

**Example 示例：获取事物影子**  
此示例使用一个`IPCUtils`类来创建与 C AWS IoT Greengrass ore IPC 服务的连接。有关更多信息，请参阅 [Connect 到 C AWS IoT Greengrass ore IPC 服务](interprocess-communication.md#ipc-service-connect)。

```
package com.aws.greengrass.docs.samples.ipc;

import com.aws.greengrass.docs.samples.ipc.util.IPCUtils;
import software.amazon.awssdk.aws.greengrass.GetThingShadowResponseHandler;
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.model.GetThingShadowRequest;
import software.amazon.awssdk.aws.greengrass.model.GetThingShadowResponse;
import software.amazon.awssdk.aws.greengrass.model.ResourceNotFoundError;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;

import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class GetThingShadow {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        // Use the current core device's name if thing name isn't set.
        String thingName = args[0].isEmpty() ? System.getenv("AWS_IOT_THING_NAME") : args[0];
        String shadowName = args[1];
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            GetThingShadowResponseHandler responseHandler =
                    GetThingShadow.getThingShadow(ipcClient, thingName, shadowName);
            CompletableFuture<GetThingShadowResponse> futureResponse =
                    responseHandler.getResponse();
            try {
                GetThingShadowResponse response = futureResponse.get(TIMEOUT_SECONDS,
                        TimeUnit.SECONDS);
                String shadowPayload = new String(response.getPayload(), StandardCharsets.UTF_8);
                System.out.printf("Successfully got shadow %s/%s: %s%n", thingName, shadowName,
                        shadowPayload);
            } catch (TimeoutException e) {
                System.err.printf("Timeout occurred while getting shadow: %s/%s%n", thingName,
                        shadowName);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.printf("Unauthorized error while getting shadow: %s/%s%n",
                            thingName, shadowName);
                } else if (e.getCause() instanceof ResourceNotFoundError) {
                    System.err.printf("Unable to find shadow to get: %s/%s%n", thingName,
                            shadowName);
                } else {
                    throw e;
                }
            }
        } catch (InterruptedException e) {
            System.out.println("IPC interrupted.");
        } catch (ExecutionException e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static GetThingShadowResponseHandler getThingShadow(GreengrassCoreIPCClient greengrassCoreIPCClient, String thingName, String shadowName) {
        GetThingShadowRequest getThingShadowRequest = new GetThingShadowRequest();
        getThingShadowRequest.setThingName(thingName);
        getThingShadowRequest.setShadowName(shadowName);
        return greengrassCoreIPCClient.getThingShadow(getThingShadowRequest, Optional.empty());
    }
}
```

------
#### [ Python (IPC client V1) ]

**Example 示例：获取事物影子**  

```
import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import GetThingShadowRequest

TIMEOUT = 10

def sample_get_thing_shadow_request(thingName, shadowName):
    try:
        # set up IPC client to connect to the IPC server
        ipc_client = awsiot.greengrasscoreipc.connect()
                
        # create the GetThingShadow request
        get_thing_shadow_request = GetThingShadowRequest()
        get_thing_shadow_request.thing_name = thingName
        get_thing_shadow_request.shadow_name = shadowName
        
        # retrieve the GetThingShadow response after sending the request to the IPC server
        op = ipc_client.new_get_thing_shadow()
        op.activate(get_thing_shadow_request)
        fut = op.get_response()
        
        result = fut.result(TIMEOUT)
        return result.payload
        
    except InvalidArgumentsError as e:
        # add error handling
        ...
    # except ResourceNotFoundError | UnauthorizedError | ServiceError
```

------
#### [ JavaScript ]

**Example 示例：获取事物影子**  

```
import {
    GetThingShadowRequest
} from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc/model';
import * as greengrasscoreipc from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc';

class GetThingShadow {
    private ipcClient: greengrasscoreipc.Client;
    private thingName: string;
    private shadowName: string;

    constructor() {
        // Define args parameters here           
        this.thingName = "<define_your_own_thingName>";
        this.shadowName = "<define_your_own_shadowName>";
        this.bootstrap();
    }

    async bootstrap() {
        try {
            this.ipcClient = await getIpcClient();
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
        
        try {
            await this.handleGetThingShadowOperation(this.thingName,
                this.shadowName);
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
    }

    async handleGetThingShadowOperation(
        thingName: string,
        shadowName: string
    ) {
        const request: GetThingShadowRequest = {
            thingName: thingName,
            shadowName: shadowName
        };
        const response = await this.ipcClient.getThingShadow(request);
    }
}

export async function getIpcClient() {
    try {
        const ipcClient = greengrasscoreipc.createClient();
        await ipcClient.connect()
            .catch(error => {
                // parse the error depending on your use cases
                throw error;
            });
        return ipcClient
    } catch (err) {
        // parse the error depending on your use caseså
        throw err
    }
}

const startScript = new GetThingShadow();
```

------

## UpdateThingShadow
<a name="ipc-operation-updatethingshadow"></a>

更新指定事物的影子。如果影子不存在，则会创建一个。

### 请求
<a name="ipc-operation-updatethingshadow-request"></a>

此操作的请求包含以下参数：

`thingName` (Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
事物的名称。  
类型：`string`

`shadowName` (Python: `shadow_name`)  <a name="ipc-local-shadows-shadow-name"></a>
影子的名称。要指定事物的经典影子，请将此参数设置为空字符串 (`""`)。  
该 AWS IoT Greengrass 服务使用`AWSManagedGreengrassV2Deployment`命名的影子来管理针对单个核心设备的部署。这个名为 shadow 的保留供 AWS IoT Greengrass 服务使用。请勿更新或删除该已命名影子。
类型：`string`

`payload`  
请求状态文档为 blob。  
类型：包含以下信息的 `object`：    
`state`  
要更新的状态信息。此 IPC 操作仅影响指定字段。  
该对象包含以下信息。通常，您将使用 `desired` 或 `reported` 属性，但不能在同一请求中同时使用这两个属性。    
`desired`  
请求在设备中更新的状态属性和值。  
类型：键/值对 `map`  
`reported`  
设备报告的状态属性和值。  
类型：键/值对 `map`  
`clientToken`（Python：`client_token`）  
（可选）用于匹配请求和客户端令牌的相应响应的令牌。  
类型：`string`  
`version`  
（可选）待更新的本地影子文档版本。影子服务只有在指定的版本与其拥有的最新版本一致时才会处理更新。  
类型：`integer`

### 响应
<a name="ipc-operation-updatethingshadow-response"></a>

此操作的响应包含以下信息：

`payload`  
响应状态文档为 blob。  
类型：包含以下信息的 `object`：    
`state`  
状态信息。  
该对象包含以下信息。    
`desired`  
请求在设备中更新的状态属性和值。  
类型：键/值对 `map`  
`reported`  
设备报告的状态属性和值。  
类型：键/值对 `map`  
`delta`  
设备报告的状态属性和值。  
类型：键/值对 `map`  
`metadata`  
`desired` 和 `reported` 部分中每个属性的时间戳，因此，您可以确定状态的更新时间。  
类型：`string`  
`timestamp`  
生成响应时的 Epoch 日期和时间。  
类型：`integer`  
`clientToken` (Python: `client_token`)  
用于匹配请求和相应响应的令牌。  
类型：`string`  
`version`  
更新完成后的本地影子文档的版本。  
类型：`integer`

### 错误
<a name="ipc-operation-updatethingshadow-errors"></a>

此操作可返回以下错误。

`ConflictError`  
本地影子服务在更新操作期间遇到了版本冲突。当请求有效载荷中的版本与最新的可用本地影子文档中的版本不匹配时，就会发生这种情况。

`InvalidArgumentsError`  
<a name="ipc-invalidargumentserror-para"></a>本地影子服务无法验证请求参数。如果请求包含格式错误的 JSON 或不支持的字符，则可能会发生这种情况。  
有效的 `payload` 具有以下属性：  
+ 该 `state` 节点存在，并且是一个包含 `desired` 或 `reported` 状态信息的对象。
+ `desired` 和 `reported` 节点要么是对象，要么为空。这些对象中至少有一个必须包含有效的状态信息。
+ `desired` 和 `reported` 对象的深度不能超过八个节点。
+ `clientToken` 值的长度不能超过 64 个字符。
+  `version` 值必须为 `1` 或更高。

`ServiceError`  <a name="ipc-serviceerror"></a>
发生了内部服务错误，或者对 IPC 服务的请求数超过了影子管理器组件中 `maxLocalRequestsPerSecondPerThing` 和 `maxTotalLocalRequestsRate` 配置参数中指定的限制。

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
该组件的授权策略不包括此操作所需权限。

### 示例
<a name="ipc-operation-updatethingshadow-examples"></a>

以下示例演示了如何在自定义组件代码中调用该操作。

------
#### [ Java (IPC client V1) ]

**Example 示例：更新事物影子**  
此示例使用一个`IPCUtils`类来创建与 C AWS IoT Greengrass ore IPC 服务的连接。有关更多信息，请参阅 [Connect 到 C AWS IoT Greengrass ore IPC 服务](interprocess-communication.md#ipc-service-connect)。

```
package com.aws.greengrass.docs.samples.ipc;

import com.aws.greengrass.docs.samples.ipc.util.IPCUtils;
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.UpdateThingShadowResponseHandler;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;
import software.amazon.awssdk.aws.greengrass.model.UpdateThingShadowRequest;
import software.amazon.awssdk.aws.greengrass.model.UpdateThingShadowResponse;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;

import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class UpdateThingShadow {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        // Use the current core device's name if thing name isn't set.
        String thingName = args[0].isEmpty() ? System.getenv("AWS_IOT_THING_NAME") : args[0];
        String shadowName = args[1];
        byte[] shadowPayload = args[2].getBytes(StandardCharsets.UTF_8);
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            UpdateThingShadowResponseHandler responseHandler =
                    UpdateThingShadow.updateThingShadow(ipcClient, thingName, shadowName,
                            shadowPayload);
            CompletableFuture<UpdateThingShadowResponse> futureResponse =
                    responseHandler.getResponse();
            try {
                futureResponse.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
                System.out.printf("Successfully updated shadow: %s/%s%n", thingName, shadowName);
            } catch (TimeoutException e) {
                System.err.printf("Timeout occurred while updating shadow: %s/%s%n", thingName,
                        shadowName);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.printf("Unauthorized error while updating shadow: %s/%s%n",
                            thingName, shadowName);
                } else {
                    throw e;
                }
            }
        } catch (InterruptedException e) {
            System.out.println("IPC interrupted.");
        } catch (ExecutionException e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static UpdateThingShadowResponseHandler updateThingShadow(GreengrassCoreIPCClient greengrassCoreIPCClient, String thingName, String shadowName, byte[] shadowPayload) {
        UpdateThingShadowRequest updateThingShadowRequest = new UpdateThingShadowRequest();
        updateThingShadowRequest.setThingName(thingName);
        updateThingShadowRequest.setShadowName(shadowName);
        updateThingShadowRequest.setPayload(shadowPayload);
        return greengrassCoreIPCClient.updateThingShadow(updateThingShadowRequest,
                Optional.empty());
    }
}
```

------
#### [ Python (IPC client V1) ]

**Example 示例：更新事物影子**  

```
import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import UpdateThingShadowRequest

TIMEOUT = 10

def sample_update_thing_shadow_request(thingName, shadowName, payload):
    try:
        # set up IPC client to connect to the IPC server
        ipc_client = awsiot.greengrasscoreipc.connect()
                
        # create the UpdateThingShadow request
        update_thing_shadow_request = UpdateThingShadowRequest()
        update_thing_shadow_request.thing_name = thingName
        update_thing_shadow_request.shadow_name = shadowName
        update_thing_shadow_request.payload = payload
                        
        # retrieve the UpdateThingShadow response after sending the request to the IPC server
        op = ipc_client.new_update_thing_shadow()
        op.activate(update_thing_shadow_request)
        fut = op.get_response()
        
        result = fut.result(TIMEOUT)
        return result.payload
        
    except InvalidArgumentsError as e:
        # add error handling
    ...
    # except ConflictError | UnauthorizedError | ServiceError
```

------
#### [ JavaScript ]

**Example 示例：更新事物影子**  

```
import {
    UpdateThingShadowRequest
} from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc/model';
import * as greengrasscoreipc from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc';

class UpdateThingShadow {
    private ipcClient: greengrasscoreipc.Client;
    private thingName: string;
    private shadowName: string;
    private shadowDocumentStr: string;

    constructor() {
        // Define args parameters here

        this.thingName = "<define_your_own_thingName>";
        this.shadowName = "<define_your_own_shadowName>";
        this.shadowDocumentStr = "<define_your_own_payload>";

        this.bootstrap();
    }

    async bootstrap() {
        try {
            this.ipcClient = await getIpcClient();
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }

        try {
            await this.handleUpdateThingShadowOperation(
                this.thingName,
                this.shadowName,
                this.shadowDocumentStr);
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
    }

    async handleUpdateThingShadowOperation(
        thingName: string,
        shadowName: string,
        payloadStr: string
    ) {
        const request: UpdateThingShadowRequest = {
            thingName: thingName,
            shadowName: shadowName,
            payload: payloadStr
        }
        // make the UpdateThingShadow request
        const response = await this.ipcClient.updateThingShadow(request);
    }
}

export async function getIpcClient() {
    try {
        const ipcClient = greengrasscoreipc.createClient();
        await ipcClient.connect()
            .catch(error => {
                // parse the error depending on your use cases
                throw error;
            });
        return ipcClient
    } catch (err) {
        // parse the error depending on your use cases
        throw err
    }
}

const startScript = new UpdateThingShadow();
```

------

## DeleteThingShadow
<a name="ipc-operation-deletethingshadow"></a>

删除指定事物的影子。

从影子管理器 v2.0.4 开始，删除影子会增加版本号。例如，当您在版本 1 中删除影子 `MyThingShadow` 时，已删除影子的版本为 2。如果您随后使用名称 `MyThingShadow` 重新创建影子，则该影子的版本为 3。

### 请求
<a name="ipc-operation-deletethingshadow-request"></a>

此操作的请求包含以下参数：

`thingName` (Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
事物的名称。  
类型：`string`

`shadowName` (Python: `shadow_name`)  <a name="ipc-local-shadows-shadow-name"></a>
影子的名称。要指定事物的经典影子，请将此参数设置为空字符串 (`""`)。  
该 AWS IoT Greengrass 服务使用`AWSManagedGreengrassV2Deployment`命名的影子来管理针对单个核心设备的部署。这个名为 shadow 的保留供 AWS IoT Greengrass 服务使用。请勿更新或删除该已命名影子。
类型：`string`

### 响应
<a name="ipc-operation-deletethingshadow-response"></a>

此操作的响应包含以下信息：

`payload`  
一个空的响应状态文档。

### 错误
<a name="ipc-operation-deletethingshadow-errors"></a>

此操作可返回以下错误。

`InvalidArgumentsError`  <a name="ipc-invalidargumentserror"></a>
<a name="ipc-invalidargumentserror-para"></a>本地影子服务无法验证请求参数。如果请求包含格式错误的 JSON 或不支持的字符，则可能会发生这种情况。

`ResourceNotFoundError`  <a name="ipc-resourcenotfounderror"></a>
无法找到请求的本地影子文档。

`ServiceError`  <a name="ipc-serviceerror"></a>
发生了内部服务错误，或者对 IPC 服务的请求数超过了影子管理器组件中 `maxLocalRequestsPerSecondPerThing` 和 `maxTotalLocalRequestsRate` 配置参数中指定的限制。

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
该组件的授权策略不包括此操作所需权限。

### 示例
<a name="ipc-operation-deletethingshadow-examples"></a>

以下示例演示了如何在自定义组件代码中调用该操作。

------
#### [ Java (IPC client V1) ]

**Example 示例：删除事物影子**  
此示例使用一个`IPCUtils`类来创建与 C AWS IoT Greengrass ore IPC 服务的连接。有关更多信息，请参阅 [Connect 到 C AWS IoT Greengrass ore IPC 服务](interprocess-communication.md#ipc-service-connect)。

```
package com.aws.greengrass.docs.samples.ipc;

import com.aws.greengrass.docs.samples.ipc.util.IPCUtils;
import software.amazon.awssdk.aws.greengrass.DeleteThingShadowResponseHandler;
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.model.DeleteThingShadowRequest;
import software.amazon.awssdk.aws.greengrass.model.DeleteThingShadowResponse;
import software.amazon.awssdk.aws.greengrass.model.ResourceNotFoundError;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class DeleteThingShadow {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        // Use the current core device's name if thing name isn't set.
        String thingName = args[0].isEmpty() ? System.getenv("AWS_IOT_THING_NAME") : args[0];
        String shadowName = args[1];
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            DeleteThingShadowResponseHandler responseHandler =
                    DeleteThingShadow.deleteThingShadow(ipcClient, thingName, shadowName);
            CompletableFuture<DeleteThingShadowResponse> futureResponse =
                    responseHandler.getResponse();
            try {
                futureResponse.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
                System.out.printf("Successfully deleted shadow: %s/%s%n", thingName, shadowName);
            } catch (TimeoutException e) {
                System.err.printf("Timeout occurred while deleting shadow: %s/%s%n", thingName,
                        shadowName);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.printf("Unauthorized error while deleting shadow: %s/%s%n",
                            thingName, shadowName);
                } else if (e.getCause() instanceof ResourceNotFoundError) {
                    System.err.printf("Unable to find shadow to delete: %s/%s%n", thingName,
                            shadowName);
                } else {
                    throw e;
                }
            }
        } catch (InterruptedException e) {
            System.out.println("IPC interrupted.");
        } catch (ExecutionException e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static DeleteThingShadowResponseHandler deleteThingShadow(GreengrassCoreIPCClient greengrassCoreIPCClient, String thingName, String shadowName) {
        DeleteThingShadowRequest deleteThingShadowRequest = new DeleteThingShadowRequest();
        deleteThingShadowRequest.setThingName(thingName);
        deleteThingShadowRequest.setShadowName(shadowName);
        return greengrassCoreIPCClient.deleteThingShadow(deleteThingShadowRequest,
                Optional.empty());
    }
}
```

------
#### [ Python (IPC client V1) ]

**Example 示例：删除事物影子**  

```
import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import DeleteThingShadowRequest

TIMEOUT = 10

def sample_delete_thing_shadow_request(thingName, shadowName):
    try:
        # set up IPC client to connect to the IPC server
        ipc_client = awsiot.greengrasscoreipc.connect()
                
        # create the DeleteThingShadow request
        delete_thing_shadow_request = DeleteThingShadowRequest()
        delete_thing_shadow_request.thing_name = thingName
        delete_thing_shadow_request.shadow_name = shadowName
                        
        # retrieve the DeleteThingShadow response after sending the request to the IPC server
        op = ipc_client.new_delete_thing_shadow()
        op.activate(delete_thing_shadow_request)
        fut = op.get_response()
        
        result = fut.result(TIMEOUT)
        return result.payload
        
    except InvalidArgumentsError as e:
        # add error handling
    ...
    # except ResourceNotFoundError | UnauthorizedError | ServiceError
```

------
#### [ JavaScript ]

**Example 示例：删除事物影子**  

```
import {
    DeleteThingShadowRequest
} from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc/model';
import * as greengrasscoreipc from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc';

class DeleteThingShadow {
    private ipcClient: greengrasscoreipc.Client;
    private thingName: string;
    private shadowName: string;

    constructor() {
        // Define args parameters here
        this.thingName = "<define_your_own_thingName>";
        this.shadowName = "<define_your_own_shadowName>";
        this.bootstrap();
    }

    async bootstrap() {
        try {
            this.ipcClient = await getIpcClient();
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }

        try {
            await this.handleDeleteThingShadowOperation(this.thingName, this.shadowName)
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
    }

    async handleDeleteThingShadowOperation(thingName: string, shadowName: string) {
        const request: DeleteThingShadowRequest = {
            thingName: thingName,
            shadowName: shadowName
        }
        // make the DeleteThingShadow request
        const response = await this.ipcClient.deleteThingShadow(request);
    }
}

export async function getIpcClient() {
    try {
        const ipcClient = greengrasscoreipc.createClient();
        await ipcClient.connect()
            .catch(error => {
                // parse the error depending on your use cases
                throw error;
            });
        return ipcClient
    } catch (err) {
        // parse the error depending on your use cases
        throw err
    }
}

const startScript = new DeleteThingShadow();
```

------

## ListNamedShadowsForThing
<a name="ipc-operation-listnamedshadowsforthing"></a>

列出指定事物的命名影子。

### 请求
<a name="ipc-operation-listnamedshadowsforthing-request"></a>

此操作的请求包含以下参数：

`thingName` (Python: `thing_name`)  <a name="ipc-local-shadows-thing-name"></a>
事物的名称。  
类型：`string`

`pageSize` (Python: `page_size`)  
（可选）在每个调用中返回的影子名称的数量。  
类型：`integer`  
默认值：25  
最大值：100

`nextToken`（Python：`next_token`）  
（可选）用于检索下一组结果的令牌。该值在分页结果中返回，并在返回下一页的调用中使用。  
类型：`string`

### 响应
<a name="ipc-operation-listnamedshadowsforthing-response"></a>

此操作的响应包含以下信息：

`results`  
影子名称列表。  
类型：`array`

`timestamp`  
（可选）生成响应的日期和时间。  
类型：`integer`

`nextToken` (Python: `next_token`)  
（可选）在检索序列中的下一页的分页请求中使用的令牌值。在没有其它要返回的影子名称时，该令牌不存在。  
类型：`string`  
如果请求的页面大小与响应中的影子名称数量完全匹配，则出现此令牌；但使用时，它会返回一个空列表。

### 错误
<a name="ipc-operation-listnamedshadowsforthing-errors"></a>

此操作可返回以下错误。

`InvalidArgumentsError`  <a name="ipc-invalidargumentserror"></a>
<a name="ipc-invalidargumentserror-para"></a>本地影子服务无法验证请求参数。如果请求包含格式错误的 JSON 或不支持的字符，则可能会发生这种情况。

`ResourceNotFoundError`  <a name="ipc-resourcenotfounderror"></a>
无法找到请求的本地影子文档。

`ServiceError`  <a name="ipc-serviceerror"></a>
发生了内部服务错误，或者对 IPC 服务的请求数超过了影子管理器组件中 `maxLocalRequestsPerSecondPerThing` 和 `maxTotalLocalRequestsRate` 配置参数中指定的限制。

`UnauthorizedError`  <a name="ipc-unauthorizederror"></a>
该组件的授权策略不包括此操作所需权限。

### 示例
<a name="ipc-operation-listnamedshadowsforthing-examples"></a>

以下示例演示了如何在自定义组件代码中调用该操作。

------
#### [ Java (IPC client V1) ]

**Example 示例：列出事物的已命名影子**  
此示例使用一个`IPCUtils`类来创建与 C AWS IoT Greengrass ore IPC 服务的连接。有关更多信息，请参阅 [Connect 到 C AWS IoT Greengrass ore IPC 服务](interprocess-communication.md#ipc-service-connect)。

```
package com.aws.greengrass.docs.samples.ipc;

import com.aws.greengrass.docs.samples.ipc.util.IPCUtils;
import software.amazon.awssdk.aws.greengrass.GreengrassCoreIPCClient;
import software.amazon.awssdk.aws.greengrass.ListNamedShadowsForThingResponseHandler;
import software.amazon.awssdk.aws.greengrass.model.ListNamedShadowsForThingRequest;
import software.amazon.awssdk.aws.greengrass.model.ListNamedShadowsForThingResponse;
import software.amazon.awssdk.aws.greengrass.model.ResourceNotFoundError;
import software.amazon.awssdk.aws.greengrass.model.UnauthorizedError;
import software.amazon.awssdk.eventstreamrpc.EventStreamRPCConnection;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ListNamedShadowsForThing {

    public static final int TIMEOUT_SECONDS = 10;

    public static void main(String[] args) {
        // Use the current core device's name if thing name isn't set.
        String thingName = args[0].isEmpty() ? System.getenv("AWS_IOT_THING_NAME") : args[0];
        try (EventStreamRPCConnection eventStreamRPCConnection =
                     IPCUtils.getEventStreamRpcConnection()) {
            GreengrassCoreIPCClient ipcClient =
                    new GreengrassCoreIPCClient(eventStreamRPCConnection);
            List<String> namedShadows = new ArrayList<>();
            String nextToken = null;
            try {
                // Send additional requests until there's no pagination token in the response.
                do {
                    ListNamedShadowsForThingResponseHandler responseHandler =
                            ListNamedShadowsForThing.listNamedShadowsForThing(ipcClient, thingName,
                                    nextToken, 25);
                    CompletableFuture<ListNamedShadowsForThingResponse> futureResponse =
                            responseHandler.getResponse();
                    ListNamedShadowsForThingResponse response =
                            futureResponse.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
                    List<String> responseNamedShadows = response.getResults();
                    namedShadows.addAll(responseNamedShadows);
                    nextToken = response.getNextToken();
                } while (nextToken != null);
                System.out.printf("Successfully got named shadows for thing %s: %s%n", thingName,
                        String.join(",", namedShadows));
            } catch (TimeoutException e) {
                System.err.println("Timeout occurred while listing named shadows for thing: " + thingName);
            } catch (ExecutionException e) {
                if (e.getCause() instanceof UnauthorizedError) {
                    System.err.println("Unauthorized error while listing named shadows for " +
                            "thing: " + thingName);
                } else if (e.getCause() instanceof ResourceNotFoundError) {
                    System.err.println("Unable to find thing to list named shadows: " + thingName);
                } else {
                    throw e;
                }
            }
        } catch (InterruptedException e) {
            System.out.println("IPC interrupted.");
        } catch (ExecutionException e) {
            System.err.println("Exception occurred when using IPC.");
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static ListNamedShadowsForThingResponseHandler listNamedShadowsForThing(GreengrassCoreIPCClient greengrassCoreIPCClient, String thingName, String nextToken, int pageSize) {
        ListNamedShadowsForThingRequest listNamedShadowsForThingRequest =
                new ListNamedShadowsForThingRequest();
        listNamedShadowsForThingRequest.setThingName(thingName);
        listNamedShadowsForThingRequest.setNextToken(nextToken);
        listNamedShadowsForThingRequest.setPageSize(pageSize);
        return greengrassCoreIPCClient.listNamedShadowsForThing(listNamedShadowsForThingRequest,
                Optional.empty());
    }
}
```

------
#### [ Python (IPC client V1) ]

**Example 示例：列出事物的已命名影子**  

```
import awsiot.greengrasscoreipc
import awsiot.greengrasscoreipc.client as client
from awsiot.greengrasscoreipc.model import ListNamedShadowsForThingRequest

TIMEOUT = 10

def sample_list_named_shadows_for_thing_request(thingName, nextToken, pageSize):
    try:
        # set up IPC client to connect to the IPC server
        ipc_client = awsiot.greengrasscoreipc.connect()
                
        # create the ListNamedShadowsForThingRequest request
        list_named_shadows_for_thing_request = ListNamedShadowsForThingRequest()
        list_named_shadows_for_thing_request.thing_name = thingName
        list_named_shadows_for_thing_request.next_token = nextToken
        list_named_shadows_for_thing_request.page_size = pageSize
        
        # retrieve the ListNamedShadowsForThingRequest response after sending the request to the IPC server
        op = ipc_client.new_list_named_shadows_for_thing()
        op.activate(list_named_shadows_for_thing_request)
        fut = op.get_response()
        
        list_result = fut.result(TIMEOUT)
        
        # additional returned fields
        timestamp = list_result.timestamp
        next_token = result.next_token
        named_shadow_list = list_result.results
        
        return named_shadow_list, next_token, timestamp
                
    except InvalidArgumentsError as e:
        # add error handling
    ...
    # except ResourceNotFoundError | UnauthorizedError | ServiceError
```

------
#### [ JavaScript ]

**Example 示例：列出事物的已命名影子**  

```
import {
    ListNamedShadowsForThingRequest
} from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc/model';
import * as greengrasscoreipc from 'aws-iot-device-sdk-v2/dist/greengrasscoreipc';

class listNamedShadowsForThing {
    private ipcClient: greengrasscoreipc.Client;
    private thingName: string;
    private pageSizeStr: string;
    private nextToken: string;

    constructor() {
        // Define args parameters here
        this.thingName = "<define_your_own_thingName>";
        this.pageSizeStr = "<define_your_own_pageSize>";
        this.nextToken = "<define_your_own_token>";
        this.bootstrap();
    }

    async bootstrap() {
        try {
            this.ipcClient = await getIpcClient();
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
        
        try {
            await this.handleListNamedShadowsForThingOperation(this.thingName,
                this.nextToken, this.pageSizeStr);
        } catch (err) {
            // parse the error depending on your use cases
            throw err
        }
    }

    async handleListNamedShadowsForThingOperation(
        thingName: string,
        nextToken: string,
        pageSizeStr: string
    ) {
        let request: ListNamedShadowsForThingRequest = {
            thingName: thingName,
            nextToken: nextToken,
        };
        if (pageSizeStr) {
            request.pageSize = parseInt(pageSizeStr);
        }
        // make the ListNamedShadowsForThing request
        const response = await this.ipcClient.listNamedShadowsForThing(request);
        const shadowNames = response.results;
    }
}

export async function getIpcClient(){
    try {
        const ipcClient = greengrasscoreipc.createClient();
        await ipcClient.connect()
            .catch(error => {
                // parse the error depending on your use cases
                throw error;
            });
        return ipcClient
    } catch (err) {
        // parse the error depending on your use cases
        throw err
    }
}

const startScript = new listNamedShadowsForThing();
```

------