Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅
中国的 Amazon Web Services 服务入门
(PDF)。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
与组件配置交互
组件配置 IPC 服务让您可以执行以下操作:
最低 SDK 版本
下表列出了与组件配置交互时 Amazon IoT Device SDK 必须使用的最低版本。
GetConfiguration
获取核心设备上某个组件的配置值。您可以指定要获取配置值的键路径。
请求
此操作的请求包含以下参数:
componentName(Python:component_name)
-
(可选)组件的名称。
默认为发出请求的组件名称。
keyPath(Python:key_path)
-
配置值的键路径。指定一个列表,其中每个条目都是配置对象中单个级别的键。例如,在以下配置中,指定 ["mqtt", "port"] 以获取 port 的值。
{
"mqtt": {
"port": 443
}
}
要获取组件的完整配置,请指定一个空列表。
响应
此操作的响应包含以下信息:
componentName(Python:component_name)
-
组件名称。
value
-
请求的配置,以对象形式表示。
示例
以下示例演示了如何在自定义组件代码中调用该操作。
- Rust
-
例示例:获取配置
use core::mem::MaybeUninit;
use gg_sdk::{Sdk, UnpackedObject};
fn main() {
let sdk = Sdk::init();
sdk.connect().expect("Failed to establish IPC connection");
// Get a configuration value at key path ["mqtt", "port"]
let mut buf = [MaybeUninit::uninit(); 1024];
let value = sdk
.get_config(&["mqtt", "port"], None, &mut buf)
.expect("Failed to get configuration");
if let UnpackedObject::I64(port) = value.unpack() {
println!("Configuration value: {port}");
}
}
- C
-
例示例:获取配置
#include <gg/error.h>
#include <gg/ipc/client.h>
#include <gg/object.h>
#include <gg/sdk.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
gg_sdk_init();
GgError err = ggipc_connect();
if (err != GG_ERR_OK) {
fprintf(stderr, "Failed to establish IPC connection.\n");
exit(-1);
}
// Get a configuration value at key path ["mqtt", "port"]
uint8_t response_mem[1024];
GgObject value;
err = ggipc_get_config(
GG_BUF_LIST(GG_STR("mqtt"), GG_STR("port")),
NULL, // component_name (NULL = current component)
GG_BUF(response_mem),
&value
);
if (err != GG_ERR_OK) {
fprintf(stderr, "Failed to get configuration.\n");
exit(-1);
}
if (gg_obj_type(value) == GG_TYPE_I64) {
printf("Configuration value: %" PRId64 "\n", gg_obj_into_i64(value));
} else if (gg_obj_type(value) == GG_TYPE_BUF) {
GgBuffer buf = gg_obj_into_buf(value);
printf("Configuration value: %.*s\n", (int) buf.len, buf.data);
} else {
printf("Configuration value is of unexpected type.\n");
}
}
- C++ (Component SDK)
-
例示例:获取配置
#include <gg/ipc/client.hpp>
#include <iostream>
int main() {
auto &client = gg::ipc::Client::get();
auto error = client.connect();
if (error) {
std::cerr << "Failed to establish IPC connection.\n";
exit(-1);
}
// Get a configuration value at key path ["mqtt", "port"]
std::array key_path = { gg::Buffer { "mqtt" }, gg::Buffer { "port" } };
int64_t value = 0;
error = client.get_config(key_path, std::nullopt, value);
if (error) {
std::cerr << "Failed to get configuration.\n";
exit(-1);
}
std::cout << "Configuration value: " << value << "\n";
}
UpdateConfiguration
更新核心设备上此组件的配置值。
请求
此操作的请求包含以下参数:
keyPath(Python:key_path)
-
(可选)要更新的容器节点(对象)的键路径。指定一个列表,其中每个条目都是配置对象中单个级别的键。例如,在以下配置中指定键路径 ["mqtt"] 和合并值 {
"port": 443 } 以设置 port 的值。
{
"mqtt": {
"port": 443
}
}
键路径必须在配置中指定容器节点(对象)。如果组件配置中不存在该节点,则此操作会创建该节点并将其值设置为 valueToMerge 中的对象。
默认为配置对象的根目录。
timestamp
-
当前 Unix 纪元时间(以毫秒为单位)。此操作使用此时间戳来解析键的并发更新。如果组件配置中的键的时间戳大于请求中的时间戳,则请求将失败。
valueToMerge(Python:value_to_merge)
-
要在 keyPath 中指定的位置合并的配置对象。有关更多信息,请参阅 更新组件配置。
响应
此操作在其响应中未提供任何信息。
示例
以下示例演示了如何在自定义组件代码中调用该操作。
- Rust
-
例示例:更新配置
use gg_sdk::Sdk;
fn main() {
let sdk = Sdk::init();
sdk.connect().expect("Failed to establish IPC connection");
// Update configuration value at key path ["mqtt", "port"] to 443
sdk.update_config(&["mqtt", "port"], None, 443)
.expect("Failed to update configuration");
println!("Successfully updated configuration.");
}
- C
-
例示例:更新配置
#include <gg/error.h>
#include <gg/ipc/client.h>
#include <gg/object.h>
#include <gg/sdk.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
gg_sdk_init();
GgError err = ggipc_connect();
if (err != GG_ERR_OK) {
fprintf(stderr, "Failed to establish IPC connection.\n");
exit(-1);
}
// Update configuration value at key path ["mqtt", "port"] to 443
err = ggipc_update_config(
GG_BUF_LIST(GG_STR("mqtt"), GG_STR("port")),
NULL, // timestamp (NULL = current time)
gg_obj_i64(443)
);
if (err != GG_ERR_OK) {
fprintf(stderr, "Failed to update configuration.\n");
exit(-1);
}
printf("Successfully updated configuration.\n");
}
- C++ (Component SDK)
-
例示例:更新配置
#include <gg/ipc/client.hpp>
#include <iostream>
int main() {
auto &client = gg::ipc::Client::get();
auto error = client.connect();
if (error) {
std::cerr << "Failed to establish IPC connection.\n";
exit(-1);
}
// Update configuration value at key path ["mqtt", "port"] to 443
std::array key_path = { gg::Buffer { "mqtt" }, gg::Buffer { "port" } };
error = client.update_config(key_path, 443);
if (error) {
std::cerr << "Failed to update configuration.\n";
exit(-1);
}
std::cout << "Successfully updated configuration.\n";
}
SubscribeToConfigurationUpdate
订阅即可在组件配置更新时接收通知。订阅某个键后,只要该键的任何子项有所更新,您都会收到通知。
此操作是一种订阅操作,您可以在其中订阅事件消息流。要使用此操作,请定义一个流响应处理程序,其中包含处理事件消息、错误和流关闭的函数。有关更多信息,请参阅 订阅 IPC 事件流。
事件消息类型:ConfigurationUpdateEvents
请求
此操作的请求包含以下参数:
componentName(Python:component_name)
-
(可选)组件的名称。
默认为发出请求的组件名称。
keyPath(Python:key_path)
-
要订阅的配置值的键路径。指定一个列表,其中每个条目都是配置对象中单个级别的键。例如,在以下配置中,指定 ["mqtt", "port"] 以获取 port 的值。
{
"mqtt": {
"port": 443
}
}
要订阅组件配置中所有值的更新,请指定一个空列表。
响应
此操作的响应包含以下信息:
messages
-
通知消息流。此对象 ConfigurationUpdateEvents 包含以下信息:
configurationUpdateEvent(Python:configuration_update_event)
-
配置更新事件。此对象 ConfigurationUpdateEvent 包含以下信息:
componentName(Python:component_name)
-
组件名称。
keyPath(Python:key_path)
-
已更新的配置值的键路径。
示例
以下示例演示了如何在自定义组件代码中调用该操作。
- Rust
-
例示例:订阅配置更新
use gg_sdk::Sdk;
use std::{thread, time::Duration};
fn main() {
let sdk = Sdk::init();
sdk.connect().expect("Failed to establish IPC connection");
// Subscribe to configuration updates for key path ["mqtt"]
let callback = |component_name: &str, key_path: &[&str]| {
println!(
"Received configuration update for component: {component_name}"
);
println!("Key path: {key_path:?}");
};
let _sub = sdk
.subscribe_to_configuration_update(None, &["mqtt"], &callback)
.expect("Failed to subscribe to configuration updates");
println!("Successfully subscribed to configuration updates.");
// Keep the main thread alive, or the process will exit.
loop {
thread::sleep(Duration::from_secs(10));
}
}
- C
-
例示例:订阅配置更新
#include <gg/error.h>
#include <gg/ipc/client.h>
#include <gg/object.h>
#include <gg/sdk.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
static void on_subscription_response(
void *ctx,
GgBuffer component_name,
GgList key_path,
GgIpcSubscriptionHandle handle
) {
(void) ctx;
(void) handle;
printf(
"Received configuration update for component: %.*s\n",
(int) component_name.len,
component_name.data
);
printf("Key path: [");
for (size_t i = 0; i < key_path.len; i++) {
if (i > 0) {
printf(", ");
}
GgObject *obj = &key_path.items[i];
if (gg_obj_type(*obj) == GG_TYPE_BUF) {
GgBuffer key = gg_obj_into_buf(*obj);
printf("\"%.*s\"", (int) key.len, key.data);
}
}
printf("]\n");
}
int main(void) {
gg_sdk_init();
GgError err = ggipc_connect();
if (err != GG_ERR_OK) {
fprintf(stderr, "Failed to establish IPC connection.\n");
exit(-1);
}
// Subscribe to configuration updates for key path ["mqtt"]
GgIpcSubscriptionHandle handle;
err = ggipc_subscribe_to_configuration_update(
NULL, // component_name (NULL = current component)
GG_BUF_LIST(GG_STR("mqtt")),
on_subscription_response,
NULL,
&handle
);
if (err != GG_ERR_OK) {
fprintf(stderr, "Failed to subscribe to configuration updates.\n");
exit(-1);
}
printf("Successfully subscribed to configuration updates.\n");
// Keep the main thread alive, or the process will exit.
while (1) {
sleep(10);
}
// To stop subscribing, close the stream.
ggipc_close_subscription(handle);
}
- C++ (Component SDK)
-
例示例:订阅配置更新
#include <gg/ipc/client.hpp>
#include <unistd.h>
#include <iostream>
class ResponseHandler : public gg::ipc::ConfigurationUpdateCallback {
void operator()(
std::string_view component_name,
gg::List key_path,
gg::ipc::Subscription &handle
) override {
(void) handle;
std::cout << "Received configuration update for component: "
<< component_name << "\n";
std::cout << "Key path: [";
for (size_t i = 0; i < key_path.size(); i++) {
if (i > 0) {
std::cout << ", ";
}
std::cout << "\"" << get<gg::Buffer>(key_path[i]) << "\"";
}
std::cout << "]\n";
}
};
int main() {
auto &client = gg::ipc::Client::get();
auto error = client.connect();
if (error) {
std::cerr << "Failed to establish IPC connection.\n";
exit(-1);
}
// Subscribe to configuration updates for key path ["mqtt"]
std::array key_path = { gg::Buffer { "mqtt" } };
static ResponseHandler handler;
error = client.subscribe_to_configuration_update(
key_path, std::nullopt, handler
);
if (error) {
std::cerr << "Failed to subscribe to configuration updates.\n";
exit(-1);
}
std::cout << "Successfully subscribed to configuration updates.\n";
// Keep the main thread alive, or the process will exit.
while (1) {
sleep(10);
}
}
SubscribeToValidateConfigurationUpdates
订阅即可在此组件配置更新之前接收通知。这样,组件就可以验证自己配置的更新。使用 SendConfigurationValidityReport 操作告知 Nucleus 配置是否有效。
此操作是一种订阅操作,您可以在其中订阅事件消息流。要使用此操作,请定义一个流响应处理程序,其中包含处理事件消息、错误和流关闭的函数。有关更多信息,请参阅 订阅 IPC 事件流。
事件消息类型:ValidateConfigurationUpdateEvents
请求
此操作的请求没有任何参数。
响应
此操作的响应包含以下信息:
messages
-
通知消息流。此对象 ValidateConfigurationUpdateEvents 包含以下信息:
validateConfigurationUpdateEvent(Python:validate_configuration_update_event)
-
配置更新事件。此对象 ValidateConfigurationUpdateEvent 包含以下信息:
deploymentId(Python:deployment_id)
-
更新组件的 Amazon IoT Greengrass 部署的 ID。
configuration
-
包含新配置的对象。
SendConfigurationValidityReport
告知 Nucleus 对此组件的配置更新是否有效。如果您告知 Nucleus 新配置无效,则部署将失败。使用 SubscribeToValidateConfigurationUpdates 操作订阅即可验证配置更新。
如果组件未响应验证配置更新通知,则 Nucleus 会按您在部署配置验证策略中指定的时间等待。超时之后,Nucleus 继续部署。默认组件验证超时值为 20 秒。有关更多信息,请参阅创建部署以及您在调用CreateDeployment操作时可以提供的DeploymentConfigurationValidationPolicy对象。
请求
此操作的请求包含以下参数:
configurationValidityReport(Python:configuration_validity_report)
-
告知 Nucleus 配置更新是否有效的报告。此对象 ConfigurationValidityReport 包含以下信息:
status
-
有效状态。此枚举 ConfigurationValidityStatus 包含以下值:
deploymentId(Python:deployment_id)
-
请求配置更新的 Amazon IoT Greengrass 部署的 ID。
message
-
(可选)用于报告配置无效原因的消息。
响应
此操作在其响应中未提供任何信息。