翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
ローカルシャドウとやり取り
シャドウ IPC サービスを使用して、デバイスのローカルシャドウとやり取りします。やり取りするデバイスには、コアデバイスまたは接続されたクライアントデバイスを選択できます。
これらの IPC オペレーションを使用するには、シャドウマネージャーコンポーネントをカスタムコンポーネントの依存関係として含めます。その後、カスタムコンポーネントの IPC オペレーションを使用して、シャドウマネージャーを介してデバイスのローカルシャドウとやり取りできます。カスタムコンポーネントがローカルシャドウの状態の変更に対応できるようにするには、パブリッシュ/サブスクライブ IPC サービスを使用して、シャドウイベントをサブスクライブすることもできます。パブリッシュ/サブスクライブサービスの使用の詳細については、「ローカルメッセージをパブリッシュ/サブスクライブする」を参照してください。
最小 SDK バージョン
以下の表に AWS IoT Device SDK の最小バージョンを示します。ローカルシャドウとやり取りする際は、これを使用する必要があります。
認証
カスタムコンポーネントでシャドウ IPC サービスを使用するには、コンポーネントがシャドウとやり取りできるように承認ポリシーを定義する必要があります。承認ポリシーの定義については、「コンポーネントにIPCオペレーションの実行を許可する」を参照してください。
シャドウ操作の承認ポリシーには以下のプロパティがあります。
IPC サービス識別子: aws.greengrass.ShadowManager
操作 |
説明 |
リソース |
aws.greengrass#GetThingShadow
|
コンポーネントがモノのシャドウを取得できるようにします。
|
次の文字列のいずれか。
-
$aws/things/thingName /shadow/ は、クラシックデバイスシャドウへのアクセスを許可します。
-
$aws/things/thingName /shadow/name/shadowName は、名前付きシャドウへのアクセスを許可します。
-
* は、すべてのシャドウへのアクセスを許可します。
|
aws.greengrass#UpdateThingShadow
|
コンポーネントがモノのシャドウを更新できるようにします。
|
次の文字列のいずれか。
-
$aws/things/thingName /shadow/ は、クラシックデバイスシャドウへのアクセスを許可します。
-
$aws/things/thingName /shadow/name/shadowName は、名前付きシャドウへのアクセスを許可します。
-
* は、すべてのシャドウへのアクセスを許可します。
|
aws.greengrass#DeleteThingShadow
|
コンポーネントがモノのシャドウを削除できるようにします。
|
次の文字列のいずれか。
-
$aws/things/thingName /shadow/ は、クラシックデバイスシャドウへのアクセスを許可します。
-
$aws/things/thingName /shadow/name/shadowName は、名前付きシャドウへのアクセスを許可します。
-
* は、すべてのシャドウへのアクセスを許可します。
|
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}
recipe 変数を使用できます。この機能を使用すると、コアデバイスのグループに対して 1 つの承認ポリシーを設定できます。各コアデバイスは自身のシャドウにのみアクセスできます。例えば、シャドウ 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
例: コアデバイスのグループがローカルシャドウの状態変化に反応することを許可する
次のアクセスコントロールポリシーの例では、クラシックデバイスシャドウおよび名前付きシャドウ myNamedShadow
の /update/delta
トピックに関するメッセージを、コンポーネントを実行している各コアデバイスで、カスタム com.example.MyShadowReactiveComponent
が受信できるようにします。
- 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
例: シングルコアデバイスに、ローカルシャドウの状態の変化に反応することを許可する
次のアクセスコントロールポリシーの例では、デバイス MyThingName
について、クラシックデバイスシャドウおよび名前付きシャドウ myNamedShadow
の /update/delta
トピックに関するメッセージを、カスタム com.example.MyShadowReactiveComponent
が受信できるようにします。
- 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
-
デバイスで更新がリクエストされた state のプロパティと値。
タイプ: キーバリューペアの map
reported
-
デバイスによってレポートされた state のプロパティと値。
タイプ: キーバリューペアの map
delta
-
望ましい state とレポートされた state のプロパティと値の違い。このプロパティは、desired
と reported
の state が異なる場合のみ存在します。
タイプ: キーバリューペアの map
metadata
-
いつ状態が更新されたか判別するための、desired
および reported
セクションの属性ごとのタイムスタンプ。
タイプ: string
timestamp
-
レスポンスが生成された日付と時刻 (エポック時間)。
タイプ: 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
指定したモノのシャドウを更新します。Shadow が存在しない場合は作成されます。
リクエスト
このオペレーションのリクエストには以下のパラメータがあります。
thingName
(Python: thing_name
)
-
モノの名前。
タイプ: string
shadowName
(Python: shadow_name
)
-
シャドウの名前。モノのクラシックシャドウを指定するには、このパラメータを空の文字列 (""
) に設定します。
AWS IoT Greengrass サービスは、AWSManagedGreengrassV2Deployment
名前付きシャドウを使用して、個々のコアデバイスを対象とするデプロイを管理します。この名前付きシャドウは、AWS IoT Greengrass サービスで使用するために予約されています。この名前付きシャドウを更新または削除しないでください。
タイプ: string
payload
-
BLOB としてのリクエスト状態ドキュメント。
タイプ: 次の情報が含まれる object
。
state
-
更新する状態情報。この IPC オペレーションは、指定したフィールドのみに影響します。
このオブジェクトには、次の情報が含まれます。通常、同じリクエストで desired
プロパティまたは reported
プロパティのいずれかを使用しますが、両方を使用することはありません。
desired
-
デバイスで更新がリクエストされた state のプロパティと値。
タイプ: キーバリューペアの map
reported
-
デバイスによってレポートされた state のプロパティと値。
タイプ: キーバリューペアの map
clientToken
(Python: client_token
)
-
(オプション) クライアントトークンによってリクエストとレスポンスを対応付けるために使用されるトークン。
タイプ: string
version
-
(オプション) 更新するローカルシャドウドキュメントのバージョン。シャドウサービスは、指定したバージョンが最新バージョンと一致した場合のみ更新を処理します。
タイプ: integer
レスポンス
このオペレーションのレスポンスには以下の情報が含まれます。
payload
-
BLOB としてのレスポンス状態ドキュメント。
タイプ: 次の情報が含まれる object
。
state
-
状態情報。
このオブジェクトには、次の情報が含まれます。
desired
-
デバイスで更新がリクエストされた state のプロパティと値。
タイプ: キーバリューペアの map
reported
-
デバイスによってレポートされた state のプロパティと値。
タイプ: キーバリューペアの map
delta
-
デバイスによってレポートされた state のプロパティと値。
タイプ: キーバリューペアの map
metadata
-
いつ状態が更新されたか判別するための、desired
および reported
セクションの属性ごとのタイムスタンプ。
タイプ: string
timestamp
-
レスポンスが生成された日付と時刻 (エポック時間)。
タイプ: integer
clientToken
(Python: client_token
)
-
リクエストとレスポンスを対応付けるために使用されるトークン。
タイプ: string
version
-
更新完了後のローカルシャドウドキュメントのバージョン。
タイプ: integer
エラー
このオペレーションは以下のエラーを返す場合があります。
ConflictError
-
ローカルシャドウサービスで、更新オペレーション中にバージョンの競合が発生しました。これは、リクエストペイロードのバージョンが利用可能な最新のローカルシャドードキュメントのバージョンと一致しない場合に発生します。
InvalidArgumentsError
-
ローカルシャドウサービスは、リクエストパラメータを検証できません。これは、リクエストに不正な形式の JSON またはサポートされていない文字が含まれている場合に発生する可能性があります。
有効な payload
は以下のプロパティを有します。
-
state
ノードが存在すること、そして desired
または reported
の状態情報を含むオブジェクトであること。
-
desired
および reported
ノードはオブジェクトまたはヌルのいずれかであること。これらのオブジェクトの少なくとも 1 つに有効な状態情報が含まれている必要があります。
-
desired
および reported
オブジェクトの深さが 8 ノードを超えることはできません。
-
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
指定したモノの Shadow を削除します。
シャドウマネージャー 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
-
ローカルシャドウサービスは、リクエストパラメータを検証できません。これは、リクエストに不正な形式の 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();