mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
Merge branch 'time-sync' into 'main'
esp_matter: add missing attributes and commands for time sync cluster See merge request app-frameworks/esp-matter!990
This commit is contained in:
@@ -5028,5 +5028,94 @@ attribute_t *create_location_directory(cluster_t *cluster, uint8_t *value, uint1
|
||||
} /* attribute */
|
||||
} /* ecosystem_information */
|
||||
|
||||
namespace time_synchronization {
|
||||
namespace attribute {
|
||||
attribute_t *create_utc_time(cluster_t *cluster, nullable<uint64_t> value)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::UTCTime::Id,
|
||||
ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_MANAGED_INTERNALLY,
|
||||
esp_matter_nullable_uint64(value));
|
||||
}
|
||||
|
||||
attribute_t *create_granularity(cluster_t *cluster, uint8_t value)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::Granularity::Id,
|
||||
ATTRIBUTE_FLAG_MANAGED_INTERNALLY, esp_matter_enum8(value));
|
||||
}
|
||||
|
||||
attribute_t *create_time_source(cluster_t *cluster, uint8_t value)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::TimeSource::Id,
|
||||
ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value));
|
||||
}
|
||||
|
||||
attribute_t *create_trusted_time_source(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::TrustedTimeSource::Id,
|
||||
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE,
|
||||
esp_matter_array(value, length, count));
|
||||
}
|
||||
|
||||
attribute_t *create_default_ntp(cluster_t *cluster, char *value, uint16_t length)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::DefaultNTP::Id,
|
||||
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE,
|
||||
esp_matter_char_str(value, length));
|
||||
}
|
||||
|
||||
attribute_t *create_time_zone(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::TimeZone::Id,
|
||||
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NONVOLATILE,
|
||||
esp_matter_array(value, length, count));
|
||||
}
|
||||
|
||||
attribute_t *create_dst_offset(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::DSTOffset::Id,
|
||||
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NONVOLATILE,
|
||||
esp_matter_array(value, length, count));
|
||||
}
|
||||
|
||||
attribute_t *create_local_time(cluster_t *cluster, nullable<uint64_t> value)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::LocalTime::Id,
|
||||
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NULLABLE,
|
||||
esp_matter_nullable_uint64(value));
|
||||
}
|
||||
|
||||
attribute_t *create_time_zone_database(cluster_t *cluster, uint8_t value)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::TimeZoneDatabase::Id,
|
||||
ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value));
|
||||
}
|
||||
|
||||
attribute_t *create_ntp_server_available(cluster_t *cluster, bool value)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::NTPServerAvailable::Id,
|
||||
ATTRIBUTE_FLAG_NONE, esp_matter_bool(value));
|
||||
}
|
||||
|
||||
attribute_t *create_time_zone_list_max_size(cluster_t *cluster, uint8_t value)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::TimeZoneListMaxSize::Id,
|
||||
ATTRIBUTE_FLAG_MANAGED_INTERNALLY, esp_matter_uint8(value));
|
||||
}
|
||||
|
||||
attribute_t *create_dst_offset_list_max_size(cluster_t *cluster, uint8_t value)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::DSTOffsetListMaxSize::Id,
|
||||
ATTRIBUTE_FLAG_MANAGED_INTERNALLY, esp_matter_uint8(value));
|
||||
}
|
||||
|
||||
attribute_t *create_supports_dns_resolve(cluster_t *cluster, bool value)
|
||||
{
|
||||
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::SupportsDNSResolve::Id,
|
||||
ATTRIBUTE_FLAG_NONE, esp_matter_uint64(value));
|
||||
}
|
||||
|
||||
} /* attribute */
|
||||
} /* time_synchronization */
|
||||
|
||||
} /* cluster */
|
||||
} /* esp_matter */
|
||||
|
||||
@@ -1245,5 +1245,23 @@ attribute_t *create_location_directory(cluster_t *cluster, uint8_t *value, uint1
|
||||
} /* attribute */
|
||||
} /* ecosystem_information */
|
||||
|
||||
namespace time_synchronization {
|
||||
namespace attribute {
|
||||
attribute_t *create_utc_time(cluster_t *cluster, nullable<uint64_t> value);
|
||||
attribute_t *create_granularity(cluster_t *cluster, uint8_t value);
|
||||
attribute_t *create_time_source(cluster_t *cluster, uint8_t value);
|
||||
attribute_t *create_trusted_time_source(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count);
|
||||
attribute_t *create_default_ntp(cluster_t *cluster, char *value, uint16_t length);
|
||||
attribute_t *create_time_zone(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count);
|
||||
attribute_t *create_dst_offset(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count);
|
||||
attribute_t *create_local_time(cluster_t *cluster, nullable<uint64_t> value);
|
||||
attribute_t *create_time_zone_database(cluster_t *cluster, uint8_t value);
|
||||
attribute_t *create_ntp_server_available(cluster_t *cluster, bool value);
|
||||
attribute_t *create_time_zone_list_max_size(cluster_t *cluster, uint8_t value);
|
||||
attribute_t *create_dst_offset_list_max_size(cluster_t *cluster, uint8_t value);
|
||||
attribute_t *create_supports_dns_resolve(cluster_t *cluster, bool value);
|
||||
} /* attribute */
|
||||
} /* time_synchronization */
|
||||
|
||||
} /* cluster */
|
||||
} /* esp_matter */
|
||||
|
||||
@@ -679,9 +679,14 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags)
|
||||
|
||||
/* Attributes managed internally */
|
||||
global::attribute::create_feature_map(cluster, 0);
|
||||
attribute::create_utc_time(cluster, nullable<uint64_t>());
|
||||
attribute::create_granularity(cluster, 0);
|
||||
|
||||
/* Attributes not managed internally */
|
||||
global::attribute::create_cluster_revision(cluster, cluster_revision);
|
||||
|
||||
/* Commands */
|
||||
command::create_set_utc_time(cluster);
|
||||
}
|
||||
|
||||
event::create_time_failure(cluster);
|
||||
|
||||
@@ -1555,6 +1555,62 @@ static esp_err_t esp_matter_command_callback_close(const ConcreteCommandPath &co
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_matter_command_callback_set_utc_time(const ConcreteCommandPath &command_path, TLVReader &tlv_data,
|
||||
void *opaque_ptr)
|
||||
{
|
||||
chip::app::Clusters::TimeSynchronization::Commands::SetUTCTime::DecodableType command_data;
|
||||
CHIP_ERROR error = Decode(tlv_data, command_data);
|
||||
if (error == CHIP_NO_ERROR) {
|
||||
emberAfTimeSynchronizationClusterSetUTCTimeCallback((CommandHandler *)opaque_ptr, command_path, command_data);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_matter_command_callback_set_trusted_time_source(const ConcreteCommandPath &command_path,
|
||||
TLVReader &tlv_data, void *opaque_ptr)
|
||||
{
|
||||
chip::app::Clusters::TimeSynchronization::Commands::SetTrustedTimeSource::DecodableType command_data;
|
||||
CHIP_ERROR error = Decode(tlv_data, command_data);
|
||||
if (error == CHIP_NO_ERROR) {
|
||||
emberAfTimeSynchronizationClusterSetTrustedTimeSourceCallback((CommandHandler *)opaque_ptr, command_path,
|
||||
command_data);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_matter_command_callback_set_time_zone(const ConcreteCommandPath &command_path, TLVReader &tlv_data,
|
||||
void *opaque_ptr)
|
||||
{
|
||||
chip::app::Clusters::TimeSynchronization::Commands::SetTimeZone::DecodableType command_data;
|
||||
CHIP_ERROR error = Decode(tlv_data, command_data);
|
||||
if (error == CHIP_NO_ERROR) {
|
||||
emberAfTimeSynchronizationClusterSetTimeZoneCallback((CommandHandler *)opaque_ptr, command_path, command_data);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_matter_command_callback_set_dst_offset(const ConcreteCommandPath &command_path, TLVReader &tlv_data,
|
||||
void *opaque_ptr)
|
||||
{
|
||||
chip::app::Clusters::TimeSynchronization::Commands::SetDSTOffset::DecodableType command_data;
|
||||
CHIP_ERROR error = Decode(tlv_data, command_data);
|
||||
if (error == CHIP_NO_ERROR) {
|
||||
emberAfTimeSynchronizationClusterSetDSTOffsetCallback((CommandHandler *)opaque_ptr, command_path, command_data);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_matter_command_callback_set_default_ntp(const ConcreteCommandPath &command_path, TLVReader &tlv_data,
|
||||
void *opaque_ptr)
|
||||
{
|
||||
chip::app::Clusters::TimeSynchronization::Commands::SetDefaultNTP::DecodableType command_data;
|
||||
CHIP_ERROR error = Decode(tlv_data, command_data);
|
||||
if (error == CHIP_NO_ERROR) {
|
||||
emberAfTimeSynchronizationClusterSetDefaultNTPCallback((CommandHandler *)opaque_ptr, command_path, command_data);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
namespace esp_matter {
|
||||
namespace cluster {
|
||||
|
||||
@@ -3451,6 +3507,53 @@ command_t *create_reverse_open_commissioning_window(cluster_t *cluster)
|
||||
} /* command */
|
||||
} /* commissioner_control */
|
||||
|
||||
namespace time_synchronization {
|
||||
namespace command {
|
||||
constexpr const command_entry_t accepted_command_list[] = {
|
||||
{TimeSynchronization::Commands::SetUTCTime::Id, COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_set_utc_time},
|
||||
};
|
||||
|
||||
constexpr const command_entry_t generated_command_list[] = {};
|
||||
|
||||
command_t *create_set_utc_time(cluster_t *cluster)
|
||||
{
|
||||
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetUTCTime::Id, COMMAND_FLAG_ACCEPTED,
|
||||
esp_matter_command_callback_set_utc_time);
|
||||
}
|
||||
|
||||
command_t *create_set_trusted_time_source(cluster_t *cluster)
|
||||
{
|
||||
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetTrustedTimeSource::Id,
|
||||
COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_set_trusted_time_source);
|
||||
}
|
||||
|
||||
command_t *create_set_time_zone(cluster_t *cluster)
|
||||
{
|
||||
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetTimeZone::Id, COMMAND_FLAG_ACCEPTED,
|
||||
esp_matter_command_callback_set_time_zone);
|
||||
}
|
||||
|
||||
command_t *create_set_time_zone_response(cluster_t *cluster)
|
||||
{
|
||||
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetTimeZoneResponse::Id,
|
||||
COMMAND_FLAG_GENERATED, nullptr);
|
||||
}
|
||||
|
||||
command_t *create_set_dst_offset(cluster_t *cluster)
|
||||
{
|
||||
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetDSTOffset::Id,
|
||||
COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_set_dst_offset);
|
||||
}
|
||||
|
||||
command_t *create_set_default_ntp(cluster_t *cluster)
|
||||
{
|
||||
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetDefaultNTP::Id,
|
||||
COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_set_default_ntp);
|
||||
}
|
||||
|
||||
} /* command */
|
||||
} /* time_synchronization */
|
||||
|
||||
} /* cluster */
|
||||
} /* esp_matter */
|
||||
|
||||
@@ -3499,6 +3602,7 @@ constexpr const cluster_command_t cluster_command_table[] = {
|
||||
{ThreadNetworkDirectory::Id, GET_COMMAND_COUNT_LIST(cluster::thread_network_directory)},
|
||||
{WaterHeaterManagement::Id, GET_COMMAND_COUNT_LIST(cluster::water_heater_management)},
|
||||
{CommissionerControl::Id, GET_COMMAND_COUNT_LIST(cluster::commissioner_control)},
|
||||
{TimeSynchronization::Id, GET_COMMAND_COUNT_LIST(cluster::time_synchronization)},
|
||||
};
|
||||
|
||||
#if defined(CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER) && defined(CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)
|
||||
|
||||
@@ -503,5 +503,16 @@ command_t *create_reverse_open_commissioning_window(cluster_t *cluster);
|
||||
} /* command */
|
||||
} /* commissioner_control */
|
||||
|
||||
namespace time_synchronization {
|
||||
namespace command {
|
||||
command_t *create_set_utc_time(cluster_t *cluster);
|
||||
command_t *create_set_trusted_time_source(cluster_t *cluster);
|
||||
command_t *create_set_time_zone(cluster_t *cluster);
|
||||
command_t *create_set_time_zone_response(cluster_t *cluster);
|
||||
command_t *create_set_dst_offset(cluster_t *cluster);
|
||||
command_t *create_set_default_ntp(cluster_t *cluster);
|
||||
} /* command */
|
||||
} /* time_synchronization */
|
||||
|
||||
} /* cluster */
|
||||
} /* esp_matter */
|
||||
|
||||
@@ -4941,5 +4941,123 @@ esp_err_t add(cluster_t *cluster)
|
||||
|
||||
} /* feature */
|
||||
} /* pump_configuration_and_control */
|
||||
|
||||
namespace time_synchronization {
|
||||
namespace feature {
|
||||
|
||||
namespace time_zone {
|
||||
uint32_t get_id()
|
||||
{
|
||||
return static_cast<uint32_t>(TimeSynchronization::Feature::kTimeZone);
|
||||
}
|
||||
|
||||
esp_err_t add(cluster_t *cluster, config_t *config)
|
||||
{
|
||||
if (!cluster || !config) {
|
||||
ESP_LOGE(TAG, "Cluster or config cannot be NULL");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
update_feature_map(cluster, get_id());
|
||||
|
||||
// Attributes managed internally
|
||||
attribute::create_time_zone(cluster, nullptr, 0, 0);
|
||||
attribute::create_dst_offset(cluster, nullptr, 0, 0);
|
||||
attribute::create_local_time(cluster, nullable<uint64_t>());
|
||||
attribute::create_time_zone_list_max_size(cluster, 0);
|
||||
attribute::create_dst_offset_list_max_size(cluster, 0);
|
||||
|
||||
// Attributes not managed internally
|
||||
attribute::create_time_zone_database(cluster, config->time_zone_database);
|
||||
|
||||
// Commands
|
||||
command::create_set_time_zone(cluster);
|
||||
command::create_set_dst_offset(cluster);
|
||||
command::create_set_time_zone_response(cluster);
|
||||
|
||||
// Events
|
||||
event::create_dst_table_empty(cluster);
|
||||
event::create_dst_status(cluster);
|
||||
event::create_time_zone_status(cluster);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
} /* time_zone */
|
||||
|
||||
namespace ntp_client {
|
||||
uint32_t get_id()
|
||||
{
|
||||
return static_cast<uint32_t>(TimeSynchronization::Feature::kNTPClient);
|
||||
}
|
||||
|
||||
esp_err_t add(cluster_t *cluster, config_t *config)
|
||||
{
|
||||
if (!cluster || !config) {
|
||||
ESP_LOGE(TAG, "Cluster or config cannot be NULL");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
update_feature_map(cluster, get_id());
|
||||
|
||||
// Attributes managed internally
|
||||
attribute::create_default_ntp(cluster, nullptr, 0);
|
||||
|
||||
// Attributes not managed internally
|
||||
attribute::create_supports_dns_resolve(cluster, config->supports_dns_resolve);
|
||||
|
||||
// Commands
|
||||
command::create_set_default_ntp(cluster);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
} /* ntp_client */
|
||||
|
||||
namespace ntp_server {
|
||||
|
||||
uint32_t get_id()
|
||||
{
|
||||
return static_cast<uint32_t>(TimeSynchronization::Feature::kNTPServer);
|
||||
}
|
||||
|
||||
esp_err_t add(cluster_t *cluster, config_t *config)
|
||||
{
|
||||
if (!cluster || !config) {
|
||||
ESP_LOGE(TAG, "Cluster or config cannot be NULL");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
update_feature_map(cluster, get_id());
|
||||
|
||||
// Attributes not managed internally
|
||||
attribute::create_ntp_server_available(cluster, config->ntp_server_available);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
} /* ntp_server */
|
||||
|
||||
namespace time_sync_client {
|
||||
uint32_t get_id()
|
||||
{
|
||||
return static_cast<uint32_t>(TimeSynchronization::Feature::kTimeSyncClient);
|
||||
}
|
||||
|
||||
esp_err_t add(cluster_t *cluster)
|
||||
{
|
||||
if (!cluster) {
|
||||
ESP_LOGE(TAG, "Cluster cannot be NULL");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
update_feature_map(cluster, get_id());
|
||||
|
||||
// Attributes managed internally
|
||||
attribute::create_trusted_time_source(cluster, nullptr, 0, 0);
|
||||
|
||||
// Commands
|
||||
command::create_set_trusted_time_source(cluster);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
} /* time_sync_client */
|
||||
|
||||
} /* feature */
|
||||
} /* time_synchronization */
|
||||
|
||||
} /* cluster */
|
||||
} /* esp_matter */
|
||||
|
||||
@@ -2395,5 +2395,46 @@ esp_err_t add(cluster_t *cluster);
|
||||
} /* feature */
|
||||
} /* pump_configuration_and_control */
|
||||
|
||||
namespace time_synchronization {
|
||||
namespace feature {
|
||||
|
||||
namespace time_zone {
|
||||
typedef struct config {
|
||||
uint8_t time_zone_database;
|
||||
config() : time_zone_database(2/* None */) {}
|
||||
} config_t;
|
||||
|
||||
uint32_t get_id();
|
||||
esp_err_t add(cluster_t *cluster, config_t *config);
|
||||
} /* time_zone */
|
||||
|
||||
namespace ntp_client {
|
||||
typedef struct config {
|
||||
bool supports_dns_resolve;
|
||||
config() : supports_dns_resolve(false) {}
|
||||
} config_t;
|
||||
|
||||
uint32_t get_id();
|
||||
esp_err_t add(cluster_t *cluster, config_t *config);
|
||||
} /* ntp_client */
|
||||
|
||||
namespace ntp_server {
|
||||
typedef struct config {
|
||||
bool ntp_server_available;
|
||||
config() : ntp_server_available(false) {}
|
||||
} config_t;
|
||||
|
||||
uint32_t get_id();
|
||||
esp_err_t add(cluster_t *cluster, config_t *config);
|
||||
} /* ntp_server */
|
||||
|
||||
namespace time_sync_client {
|
||||
uint32_t get_id();
|
||||
esp_err_t add(cluster_t *cluster);
|
||||
} /* time_sync_client */
|
||||
|
||||
} /* feature */
|
||||
} /* time_synchronization */
|
||||
|
||||
} /* cluster */
|
||||
} /* esp_matter */
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#if CONFIG_DYNAMIC_PASSCODE_COMMISSIONABLE_DATA_PROVIDER
|
||||
#include <custom_provider/dynamic_commissionable_data_provider.h>
|
||||
#endif
|
||||
#if CONFIG_ENABLE_SNTP_TIME_SYNC
|
||||
#include <app/clusters/time-synchronization-server/DefaultTimeSyncDelegate.h>
|
||||
#endif
|
||||
|
||||
static const char *TAG = "app_main";
|
||||
uint16_t switch_endpoint_id = 0;
|
||||
@@ -109,6 +112,19 @@ extern "C" void app_main()
|
||||
node::config_t node_config;
|
||||
node_t *node = node::create(&node_config, app_attribute_update_cb, app_identification_cb);
|
||||
ABORT_APP_ON_FAILURE(node != nullptr, ESP_LOGE(TAG, "Failed to create Matter node"));
|
||||
#ifdef CONFIG_ENABLE_SNTP_TIME_SYNC
|
||||
endpoint_t *root_node_ep = endpoint::get_first(node);
|
||||
ABORT_APP_ON_FAILURE(root_node_ep != nullptr, ESP_LOGE(TAG, "Failed to find root node endpoint"));
|
||||
|
||||
cluster::time_synchronization::config_t time_sync_cfg;
|
||||
static chip::app::Clusters::TimeSynchronization::DefaultTimeSyncDelegate time_sync_delegate;
|
||||
time_sync_cfg.delegate = &time_sync_delegate;
|
||||
cluster_t *time_sync_cluster = cluster::time_synchronization::create(root_node_ep, &time_sync_cfg, CLUSTER_FLAG_SERVER);
|
||||
ABORT_APP_ON_FAILURE(time_sync_cluster != nullptr, ESP_LOGE(TAG, "Failed to create time_sync_cluster"));
|
||||
|
||||
cluster::time_synchronization::feature::time_zone::config_t tz_cfg;
|
||||
cluster::time_synchronization::feature::time_zone::add(time_sync_cluster, &tz_cfg);
|
||||
#endif
|
||||
|
||||
on_off_switch::config_t switch_config;
|
||||
endpoint_t *endpoint = on_off_switch::create(node, &switch_config, ENDPOINT_FLAG_NONE, switch_handle);
|
||||
|
||||
Reference in New Issue
Block a user