Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅
中国的 Amazon Web Services 服务入门
(PDF)。
与本地影子交互
使用影子 IPC 服务与设备上的本地影子交互。您选择与之交互的设备可以是您的核心设备或连接的客户端设备。
要使用这些 IPC 操作,请将影子管理器组件作为依赖关系包含在自定义组件中。然后,您可以在自定义组件中使用 IPC 操作,通过影子管理器与设备上的本地影子交互。要使自定义组件能够对本地影子状态的变化做出反应,您还可以使用发布/订阅 IPC 服务来订阅影子事件。有关使用发布/订阅服务的更多信息,请参阅 发布/订阅本地消息。
最低 SDK 版本
下表列出了与本地阴影交互时必须使用的最低版本 Amazon IoT Device SDK。
授权
要在自定义组件中使用影子 IPC 服务,必须定义允许您的组件与影子交互的授权策略。有关定义授权策略的信息,请参阅授权组件执行 IPC 操作。
影子交互授权策略具有以下属性。
IPC 服务标识符:aws.greengrass.ShadowManager
操作 |
描述 |
资源 |
aws.greengrass#GetThingShadow
|
允许组件检索事物的影子。
|
以下字符串之一:
|
aws.greengrass#UpdateThingShadow
|
允许组件更新事物的影子。
|
以下字符串之一:
|
aws.greengrass#DeleteThingShadow
|
允许组件删除事物的影子。
|
以下字符串之一:
|
aws.greengrass#ListNamedShadowsForThing
|
允许组件为事物检索已命名影子列表。
|
允许访问事物以列出其影子的事物名称字符串。
用 * 以允许访问所有事物。
|
IPC 服务标识符:aws.greengrass.ipc.pubsub
操作 |
描述 |
资源 |
aws.greengrass#SubscribeToTopic
|
允许组件订阅您指定主题的消息。
|
以下主题字符串之一:
-
shadowTopicPrefix /get/accepted
-
shadowTopicPrefix /get/rejected
-
shadowTopicPrefix /delete/accepted
-
shadowTopicPrefix /delete/rejected
-
shadowTopicPrefix /update/accepted
-
shadowTopicPrefix /update/delta
-
shadowTopicPrefix /update/rejected
主题前缀 shadowTopicPrefix 的值取决于影子类型:
用 * 以允许访问所有主题。
在 Greengrass Nucleus v2.6.0 及更高版本中,您可以订阅包含 MQTT 主题通配符(# 和 + )的主题。此主题字符串支持 MQTT 主题通配符作为文字字符。例如,如果组件的授权策略授予访问 test/topic/# 的权限,则该组件可以订阅 test/topic/# ,但无法订阅 test/topic/filter 。
|
本地影子授权策略中的配方变量
如果您使用 Greengrass Nucleus 的 v2.6.0 或更高版本,并且将 Greengrass Nucleus 的 interpolateComponentConfiguration 配置选项设置为 true
,则可以在授权策略中使用 {iot:thingName}
配方变量。此功能允许您为一组核心设备配置单个授权策略,其中每个核心设备只能访问自己的影子。例如,您可以允许组件访问以下适用于影子 IPC 操作的资源。
$aws/things/{iot:thingName}/shadow/
授权策略示例
您可以参考以下授权策略示例,帮助您为组件配置授权策略。
例 示例:允许一组核心设备与本地影子交互
以下示例授权策略允许组件 com.example.MyShadowInteractionComponent
与经典设备影子以及运行该组件的核心设备的已命名影子 myNamedShadow
进行交互。此策略还允许此组件接收这些影子的本地主题消息。
- JSON
-
{
"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"
]
}
}
}
}
- YAML
-
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
例 示例:允许一组核心设备与客户端设备影子交互
以下示例授权策略允许组件 com.example.MyShadowInteractionComponent
与名称以 MyClientDevice
开头的客户端设备的所有设备影子进行交互。
- JSON
-
{
"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*"
]
}
}
}
}
- YAML
-
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*
例 示例:允许单个核心设备与本地影子交互
以下示例授权策略允许组件 com.example.MyShadowInteractionComponent
与设备 MyThingName
的经典设备影子和已命名影子 myNamedShadow
进行交互。此策略还允许此组件接收这些影子的本地主题消息。
- JSON
-
{
"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"
]
}
}
}
}
- YAML
-
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
例 示例:允许一组核心设备对本地影子状态变化做出反应
以下示例访问控制策略允许自定义 com.example.MyShadowReactiveComponent
在运行该组件的每台核心设备上接收有关经典设备影子和已命名影子 myNamedShadow
的 /update/delta
主题消息。
- JSON
-
{
"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"
]
}
}
}
}
- YAML
-
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
例 示例:允许单个核心设备对本地影子状态变化做出反应
以下示例访问控制策略允许自定义 com.example.MyShadowReactiveComponent
接收有关设备 MyThingName
的经典设备影子和已命名影子 myNamedShadow
的 /update/delta
主题消息。
- JSON
-
{
"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"
]
}
}
}
}
- YAML
-
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
获取指定事物的影子。
请求
此操作的请求包含以下参数:
thingName
(Python: thing_name
)
-
事物的名称。
类型:string
shadowName
(Python: shadow_name
)
-
影子的名称。要指定事物的经典影子,请将此参数设置为空字符串 (""
)。
Amazon IoT Greengrass 服务使用 AWSManagedGreengrassV2Deployment
命名的影子来管理针对单个核心设备的部署。这个已命名影子保留给 Amazon IoT Greengrass 服务使用。请勿更新或删除该已命名影子。
类型:string
响应
此操作的响应包含以下信息:
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
错误
此操作可返回以下错误。
InvalidArgumentsError
-
本地影子服务无法验证请求参数。如果请求包含格式错误的 JSON 或不支持的字符,则可能会发生这种情况。
ResourceNotFoundError
-
无法找到请求的本地影子文档。
ServiceError
-
发生了内部服务错误,或者对 IPC 服务的请求数超过了影子管理器组件中 maxLocalRequestsPerSecondPerThing
和 maxTotalLocalRequestsRate
配置参数中指定的限制。
UnauthorizedError
-
该组件的授权策略不包括此操作所需权限。
示例
以下示例演示了如何在自定义组件代码中调用该操作。
- Java (IPC client V1)
-
例 示例:获取事物影子
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)
-
例 示例:获取事物影子
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
-
例 示例:获取事物影子
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
更新指定事物的影子。如果影子不存在,则会创建一个。
请求
此操作的请求包含以下参数:
thingName
(Python: thing_name
)
-
事物的名称。
类型:string
shadowName
(Python: shadow_name
)
-
影子的名称。要指定事物的经典影子,请将此参数设置为空字符串 (""
)。
Amazon IoT Greengrass 服务使用 AWSManagedGreengrassV2Deployment
命名的影子来管理针对单个核心设备的部署。这个已命名影子保留给 Amazon IoT Greengrass 服务使用。请勿更新或删除该已命名影子。
类型:string
payload
-
请求状态文档为 blob。
类型:包含以下信息的 object
:
state
-
要更新的状态信息。此 IPC 操作仅影响指定字段。
该对象包含以下信息。通常,您将使用 desired
或 reported
属性,但不能在同一请求中同时使用这两个属性。
desired
-
请求在设备中更新的状态属性和值。
类型:键/值对 map
reported
-
设备报告的状态属性和值。
类型:键/值对 map
clientToken
(Python: client_token
)
-
(可选)用于匹配请求和客户端令牌的相应响应的令牌。
类型:string
version
-
(可选)待更新的本地影子文档版本。影子服务只有在指定的版本与其拥有的最新版本一致时才会处理更新。
类型:integer
响应
此操作的响应包含以下信息:
payload
-
响应状态文档为 blob。
类型:包含以下信息的 object
:
state
-
状态信息。
该对象包含以下信息。
desired
-
请求在设备中更新的状态属性和值。
类型:键/值对 map
reported
-
设备报告的状态属性和值。
类型:键/值对 map
delta
-
设备报告的状态属性和值。
类型:键/值对 map
metadata
-
desired
和 reported
部分中每个属性的时间戳,因此,您可以确定状态的更新时间。
类型:string
timestamp
-
生成响应时的 Epoch 日期和时间。
类型:integer
clientToken
(Python: client_token
)
-
用于匹配请求和相应响应的令牌。
类型:string
version
-
更新完成后的本地影子文档的版本。
类型:integer
错误
此操作可返回以下错误。
ConflictError
-
本地影子服务在更新操作期间遇到了版本冲突。当请求有效载荷中的版本与最新的可用本地影子文档中的版本不匹配时,就会发生这种情况。
InvalidArgumentsError
-
本地影子服务无法验证请求参数。如果请求包含格式错误的 JSON 或不支持的字符,则可能会发生这种情况。
有效的 payload
具有以下属性:
-
该 state
节点存在,并且是一个包含 desired
或 reported
状态信息的对象。
-
desired
和 reported
节点要么是对象,要么为空。这些对象中至少有一个必须包含有效的状态信息。
-
desired
和 reported
对象的深度不能超过八个节点。
-
clientToken
值的长度不能超过 64 个字符。
-
version
值必须为 1
或更高。
ServiceError
-
发生了内部服务错误,或者对 IPC 服务的请求数超过了影子管理器组件中 maxLocalRequestsPerSecondPerThing
和 maxTotalLocalRequestsRate
配置参数中指定的限制。
UnauthorizedError
-
该组件的授权策略不包括此操作所需权限。
示例
以下示例演示了如何在自定义组件代码中调用该操作。
- Java (IPC client V1)
-
例 示例:更新事物影子
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)
-
例 示例:更新事物影子
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
-
例 示例:更新事物影子
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
删除指定事物的影子。
从影子管理器 v2.0.4 开始,删除影子会增加版本号。例如,当您在版本 1 中删除影子 MyThingShadow
时,已删除影子的版本为 2。如果您随后使用名称 MyThingShadow
重新创建影子,则该影子的版本为 3。
请求
此操作的请求包含以下参数:
thingName
(Python: thing_name
)
-
事物的名称。
类型:string
shadowName
(Python: shadow_name
)
-
影子的名称。要指定事物的经典影子,请将此参数设置为空字符串 (""
)。
Amazon IoT Greengrass 服务使用 AWSManagedGreengrassV2Deployment
命名的影子来管理针对单个核心设备的部署。这个已命名影子保留给 Amazon IoT Greengrass 服务使用。请勿更新或删除该已命名影子。
类型:string
响应
此操作的响应包含以下信息:
错误
此操作可返回以下错误。
InvalidArgumentsError
-
本地影子服务无法验证请求参数。如果请求包含格式错误的 JSON 或不支持的字符,则可能会发生这种情况。
ResourceNotFoundError
-
无法找到请求的本地影子文档。
ServiceError
-
发生了内部服务错误,或者对 IPC 服务的请求数超过了影子管理器组件中 maxLocalRequestsPerSecondPerThing
和 maxTotalLocalRequestsRate
配置参数中指定的限制。
UnauthorizedError
-
该组件的授权策略不包括此操作所需权限。
示例
以下示例演示了如何在自定义组件代码中调用该操作。
- Java (IPC client V1)
-
例 示例:删除事物影子
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)
-
例 示例:删除事物影子
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
-
例 示例:删除事物影子
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
列出指定事物的命名影子。
请求
此操作的请求包含以下参数:
thingName
(Python: thing_name
)
-
事物的名称。
类型:string
pageSize
(Python: page_size
)
-
(可选)在每个调用中返回的影子名称的数量。
类型:integer
默认值:25
最大值:100
nextToken
(Python: next_token
)
-
(可选)用于检索下一组结果的令牌。该值在分页结果中返回,并在返回下一页的调用中使用。
类型:string
响应
此操作的响应包含以下信息:
results
-
影子名称列表。
类型:array
timestamp
-
(可选)生成响应的日期和时间。
类型:integer
nextToken
(Python: next_token
)
-
(可选)在检索序列中的下一页的分页请求中使用的令牌值。在没有其它要返回的影子名称时,该令牌不存在。
类型:string
如果请求的页面大小与响应中的影子名称数量完全匹配,则出现此令牌;但使用时,它会返回一个空列表。
错误
此操作可返回以下错误。
InvalidArgumentsError
-
本地影子服务无法验证请求参数。如果请求包含格式错误的 JSON 或不支持的字符,则可能会发生这种情况。
ResourceNotFoundError
-
无法找到请求的本地影子文档。
ServiceError
-
发生了内部服务错误,或者对 IPC 服务的请求数超过了影子管理器组件中 maxLocalRequestsPerSecondPerThing
和 maxTotalLocalRequestsRate
配置参数中指定的限制。
UnauthorizedError
-
该组件的授权策略不包括此操作所需权限。
示例
以下示例演示了如何在自定义组件代码中调用该操作。
- Java (IPC client V1)
-
例 示例:列出事物的已命名影子
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)
-
例 示例:列出事物的已命名影子
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
-
例 示例:列出事物的已命名影子
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();