本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
與局部陰影互動
使用陰影 IPC 服務與設備上的局部陰影互動。您選擇與之互動的裝置可以是您的核心裝置或連線的用戶端裝置。
若要使用這些 IPC 作業,請在自訂元件中加入陰影管理員元件做為相依性。然後,您可以在自訂元件中使用 IPC 作業,透過陰影管理員與裝置上的局部陰影互動。若要啟用自訂元件回應本機陰影狀態中的變更,您也可以使用發佈/訂閱 IPC 服務來訂閱陰影事件。如需有關使用發佈/訂閱服務的詳細資訊,請參閱。發佈/訂閱本地訊息
若要讓核心裝置與用戶端裝置陰影互動,您還必須設定和部署 MQTT 橋接器元件。如需詳細資訊,請參閱啟用陰影管理員與用戶端裝置通訊。
最低 SDK 版本
下表列出與局部陰影互動AWS IoT Device SDK所必須使用的最低版本。
授權
若要在自訂元件中使用 shadow 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 核心 v2.6.0 及更新版本中,您可以訂閱包含 MQTT 主題萬用字元 (和) 的主題。# + 此主題字串支援 MQTT 主題萬用字元做為常值字元。例如,如果元件的授權原則授與存取權test/topic/# ,則該元件可以訂閱test/topic/# ,但無法訂閱test/topic/filter 。
|
本機陰影授權原則中的配方變數
如果您使用 v2.6.0 或更新版本的 Greengrass 核心,並將 true Greengrass 核心的interpolateComponentConfiguration組態選項設定為,您可以在授權原則中使用 recipe 變數。{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
。
若要讓核心裝置與用戶端裝置陰影互動,您還必須設定和部署 MQTT 橋接器元件。如需詳細資訊,請參閱啟用陰影管理員與用戶端裝置通訊。
- 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
讓元件與裝置的傳統裝置陰影和具名陰影myNamedShadow
互動MyThingName
。此原則也允許此元件接收有關這些陰影之本機主題的訊息。
- 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
接收有關傳統裝置陰影和裝置具名陰影/update/delta
主題myNamedShadow
的訊息MyThingName
。
- 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
)
-
影子的名稱。若要指定物件的經典陰影,請將此參數設定為空字串 (""
)。
此AWS IoT Greengrass服務會使用AWSManagedGreengrassV2Deployment
具名的陰影來管理以個別核心裝置為目標的部署。此具名陰影會保留供AWS IoT Greengrass服務使用。請勿更新或刪除此命名陰影。
類型:string
回應
此作業的回應包含下列資訊:
payload
-
回應狀態文件為 blob。
類型:object
包含下列資訊:
state
-
狀態資訊。
此物件包含下列資訊。
desired
-
要求在設備中更新的狀態屬性和值。
類型:map
鍵值對
reported
-
設備報告的狀態屬性和值。
類型:map
鍵值對
delta
-
所需和報告的狀態屬性和值之間的差異。只有在desired
和reported
狀態不同時,才會顯示此屬性。
類型:map
鍵值對
metadata
-
desired
和reported
區段中每個屬性的時間戳記,以便您判斷狀態的更新時間。
類型:string
timestamp
-
產生回應的紀元日期和時間。
類型:integer
clientToken
(Python:clientToken
)
-
用於匹配請求和相應響應的令牌
類型:string
version
-
本機陰影文件的版本。
類型:integer
錯誤
此作業可能會傳回下列錯誤。
InvalidArgumentsError
-
本機陰影服務無法驗證要求參數。如果要求包含格式錯誤或不支援的字元,就會發生這種情況。
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
)
-
影子的名稱。若要指定物件的經典陰影,請將此參數設定為空字串 (""
)。
此AWS IoT Greengrass服務會使用AWSManagedGreengrassV2Deployment
具名的陰影來管理以個別核心裝置為目標的部署。此具名陰影會保留供AWS IoT Greengrass服務使用。請勿更新或刪除此命名陰影。
類型:string
payload
-
請求狀態文檔作為一個 blob。
類型:object
包含下列資訊:
state
-
要更新的狀態資訊。此 IPC 操作僅影響指定的字段。
此物件包含下列資訊。一般而言,您會在同一個要求中使用reported
屬性或屬性,但不能同時使用這兩者。desired
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
-
產生回應的紀元日期和時間。
類型:integer
clientToken
(Python:client_token
)
-
用於匹配請求和相應響應的令牌。
類型:string
version
-
更新完成後的本機陰影文件版本。
類型:integer
錯誤
此作業可能會傳回下列錯誤。
ConflictError
-
本機陰影服務在更新作業期間遇到版本衝突。當請求裝載中的版本與最新可用的本機陰影文件中的版本不符時,就會發生這種情況。
InvalidArgumentsError
-
本機陰影服務無法驗證要求參數。如果要求包含格式錯誤或不支援的字元,就會發生這種情況。
一個有效的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
)
-
影子的名稱。若要指定物件的經典陰影,請將此參數設定為空字串 (""
)。
此AWS IoT Greengrass服務會使用AWSManagedGreengrassV2Deployment
具名的陰影來管理以個別核心裝置為目標的部署。此具名陰影會保留供AWS IoT Greengrass服務使用。請勿更新或刪除此命名陰影。
類型:string
回應
此作業的回應包含下列資訊:
錯誤
此作業可能會傳回下列錯誤。
InvalidArgumentsError
-
本機陰影服務無法驗證要求參數。如果要求包含格式錯誤或不支援的字元,就會發生這種情況。
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
-
本機陰影服務無法驗證要求參數。如果要求包含格式錯誤或不支援的字元,就會發生這種情況。
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();