From aeb697ebe739b061dd963171cf2b9151bf8c4c9c Mon Sep 17 00:00:00 2001 From: mahesh Date: Tue, 23 Dec 2025 15:22:01 +0530 Subject: [PATCH] components/esp_matter: Add new electrical device types --- components/esp_matter/CMakeLists.txt | 3 - .../esp_matter_attribute_bounds.cpp | 74 ------------------ .../data_model/esp_matter_attribute_bounds.h | 11 --- .../data_model/esp_matter_cluster.cpp | 3 - .../data_model/esp_matter_endpoint.cpp | 75 +++++++++++++++++++ .../data_model/esp_matter_endpoint.h | 43 ++++++++++- ...sp_matter_plugin_server_init_callbacks.cpp | 2 + .../all_device_types_app/main/device_types.h | 6 ++ .../main/esp_matter_console_helpers.cpp | 28 +++++++ 9 files changed, 153 insertions(+), 92 deletions(-) diff --git a/components/esp_matter/CMakeLists.txt b/components/esp_matter/CMakeLists.txt index ecb13287b..1e13bda50 100644 --- a/components/esp_matter/CMakeLists.txt +++ b/components/esp_matter/CMakeLists.txt @@ -10,9 +10,6 @@ set(INCLUDE_DIRS_LIST "." "${MATTER_SDK_PATH}/third_party/nlfaultinjection/include" "${MATTER_SDK_PATH}/src") -# TODO: These files have compilation errors -set(EXCLUDE_SRCS_LIST "${MATTER_SDK_PATH}/src/app/clusters/commodity-tariff-server/commodity-tariff-server.cpp" - "${MATTER_SDK_PATH}/src/app/clusters/commodity-tariff-server/CommodityTariffAttrsDataMgmt.cpp") set(PRIV_INCLUDE_DIRS_LIST ) if (CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER) diff --git a/components/esp_matter/data_model/esp_matter_attribute_bounds.cpp b/components/esp_matter/data_model/esp_matter_attribute_bounds.cpp index ea16a413d..1bc1af070 100644 --- a/components/esp_matter/data_model/esp_matter_attribute_bounds.cpp +++ b/components/esp_matter/data_model/esp_matter_attribute_bounds.cpp @@ -715,79 +715,5 @@ void add_bounds_cb(cluster_t *cluster) } } /* camera_av_settings_user_level_management */ -namespace commodity_tariff { - -void add_bounds_cb(cluster_t *cluster) -{ - VerifyOrReturn(cluster != nullptr, ESP_LOGE(TAG, "Cluster is NULL. Add bounds Failed!!")); - attribute_t *current_attribute = esp_matter::attribute::get_first(cluster); - VerifyOrReturn(current_attribute != nullptr, ESP_LOGE(TAG, "Attribute is NULL.")); - while(current_attribute) { - switch(esp_matter::attribute::get_id(current_attribute)) { - case CommodityTariff::Attributes::TariffUnit::Id: { - uint8_t min = 0, max = 1; - esp_matter::attribute::add_bounds(current_attribute, esp_matter_enum8(min), esp_matter_enum8(max)); - break; - } - case CommodityTariff::Attributes::DefaultRandomizationType::Id: { - uint8_t min = 0, max = 4; - esp_matter::attribute::add_bounds(current_attribute, esp_matter_enum8(min), esp_matter_enum8(max)); - break; - } - default: - break; - } - current_attribute = esp_matter::attribute::get_next(current_attribute); - } -} -} /* commodity_tariff */ - -namespace commodity_price { -void add_bounds_cb(cluster_t *cluster) -{ - VerifyOrReturn(cluster != nullptr, ESP_LOGE(TAG, "Cluster is NULL. Add bounds Failed!!")); - attribute_t *current_attribute = esp_matter::attribute::get_first(cluster); - VerifyOrReturn(current_attribute != nullptr, ESP_LOGE(TAG, "Attribute is NULL.")); - while(current_attribute) { - switch(esp_matter::attribute::get_id(current_attribute)) { - case CommodityPrice::Attributes::TariffUnit::Id: { - uint8_t min = 0, max = 1; - esp_matter::attribute::add_bounds(current_attribute, esp_matter_enum8(min), esp_matter_enum8(max)); - break; - } - default: - break; - } - current_attribute = esp_matter::attribute::get_next(current_attribute); - } -} -} /* commodity_price */ - -namespace commodity_metering { - -void add_bounds_cb(cluster_t *cluster) -{ - VerifyOrReturn(cluster != nullptr, ESP_LOGE(TAG, "Cluster is NULL. Add bounds Failed!!")); - attribute_t *current_attribute = esp_matter::attribute::get_first(cluster); - VerifyOrReturn(current_attribute != nullptr, ESP_LOGE(TAG, "Attribute is NULL.")); - while(current_attribute) { - switch(esp_matter::attribute::get_id(current_attribute)) { - case CommodityMetering::Attributes::MaximumMeteredQuantities::Id: { - uint16_t min = 1, max = UINT16_MAX; - esp_matter::attribute::add_bounds(current_attribute, esp_matter_uint16(min), esp_matter_uint16(max)); - break; - } - case CommodityMetering::Attributes::TariffUnit::Id: { - uint8_t min = 0, max = 1; - esp_matter::attribute::add_bounds(current_attribute, esp_matter_enum8(min), esp_matter_enum8(max)); - break; - } - default: - break; - } - current_attribute = esp_matter::attribute::get_next(current_attribute); - } -} -} /* commodity_metering */ } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/data_model/esp_matter_attribute_bounds.h b/components/esp_matter/data_model/esp_matter_attribute_bounds.h index 0b845e0cc..efd024352 100644 --- a/components/esp_matter/data_model/esp_matter_attribute_bounds.h +++ b/components/esp_matter/data_model/esp_matter_attribute_bounds.h @@ -50,16 +50,5 @@ namespace camera_av_settings_user_level_management { void add_bounds_cb(cluster_t *cluster); } /* camera_av_settings_user_level_management */ -namespace commodity_tariff { -void add_bounds_cb(cluster_t *cluster); -} /* commodity_tariff */ - -namespace commodity_price { -void add_bounds_cb(cluster_t *cluster); -} /* commodity_price */ - -namespace commodity_metering { -void add_bounds_cb(cluster_t *cluster); -} /* commodity_metering */ } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/data_model/esp_matter_cluster.cpp b/components/esp_matter/data_model/esp_matter_cluster.cpp index d61261da1..125d8a841 100644 --- a/components/esp_matter/data_model/esp_matter_cluster.cpp +++ b/components/esp_matter/data_model/esp_matter_cluster.cpp @@ -4355,7 +4355,6 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } static const auto plugin_server_init_cb = CALL_ONCE(MatterCommodityTariffPluginServerInitCallback); set_plugin_server_init_callback(cluster, plugin_server_init_cb); - set_add_bounds_callback(cluster, commodity_tariff::add_bounds_cb); add_function_list(cluster, function_list, function_flags); VerifyOrReturnValue(config != NULL, ABORT_CLUSTER_CREATE(cluster)); @@ -4435,7 +4434,6 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } static const auto plugin_server_init_cb = CALL_ONCE(MatterCommodityPricePluginServerInitCallback); set_plugin_server_init_callback(cluster, plugin_server_init_cb); - set_add_bounds_callback(cluster, commodity_price::add_bounds_cb); add_function_list(cluster, function_list, function_flags); /* Attributes managed internally */ @@ -4468,7 +4466,6 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) if (flags & CLUSTER_FLAG_SERVER) { static const auto plugin_server_init_cb = CALL_ONCE(MatterCommodityMeteringPluginServerInitCallback); set_plugin_server_init_callback(cluster, plugin_server_init_cb); - set_add_bounds_callback(cluster, commodity_metering::add_bounds_cb); add_function_list(cluster, function_list, function_flags); /* Attributes managed internally */ diff --git a/components/esp_matter/data_model/esp_matter_endpoint.cpp b/components/esp_matter/data_model/esp_matter_endpoint.cpp index ed7aaf017..ea02e1f95 100644 --- a/components/esp_matter/data_model/esp_matter_endpoint.cpp +++ b/components/esp_matter/data_model/esp_matter_endpoint.cpp @@ -2193,6 +2193,81 @@ esp_err_t add(endpoint_t *endpoint, config_t *config) return ESP_OK; } } /* closure_panel */ + +namespace electrical_utility_meter { +uint32_t get_device_type_id() +{ + return ESP_MATTER_ELECTRICAL_UTILITY_METER_DEVICE_TYPE_ID; +} + +uint8_t get_device_type_version() +{ + return ESP_MATTER_ELECTRICAL_UTILITY_METER_DEVICE_TYPE_VERSION; +} + +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data) +{ + return common::create(node, config, flags, priv_data, add); +} + +esp_err_t add(endpoint_t *endpoint, config_t *config) +{ + esp_err_t err = add_device_type(endpoint, get_device_type_id(), get_device_type_version()); + VerifyOrReturnError(err == ESP_OK, err); + cluster::meter_identification::create(endpoint, &(config->meter_identification), CLUSTER_FLAG_SERVER); + return ESP_OK; +} +} /* electrical_utility_meter */ + +namespace electrical_energy_tariff { +uint32_t get_device_type_id() +{ + return ESP_MATTER_ELECTRICAL_ENERGY_TARIFF_DEVICE_TYPE_ID; +} + +uint8_t get_device_type_version() +{ + return ESP_MATTER_ELECTRICAL_ENERGY_TARIFF_DEVICE_TYPE_VERSION; +} + +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data) +{ + return common::create(node, config, flags, priv_data, add); +} + +esp_err_t add(endpoint_t *endpoint, config_t *config) +{ + esp_err_t err = add_device_type(endpoint, get_device_type_id(), get_device_type_version()); + VerifyOrReturnError(err == ESP_OK, err); + return ESP_OK; +} +} /* electrical_energy_tariff */ + +namespace electrical_meter { +uint32_t get_device_type_id() +{ + return ESP_MATTER_ELECTRICAL_METER_DEVICE_TYPE_ID; +} + +uint8_t get_device_type_version() +{ + return ESP_MATTER_ELECTRICAL_METER_DEVICE_TYPE_VERSION; +} + +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data) +{ + return common::create(node, config, flags, priv_data, add); +} + +esp_err_t add(endpoint_t *endpoint, config_t *config) +{ + esp_err_t err = add_device_type(endpoint, get_device_type_id(), get_device_type_version()); + VerifyOrReturnError(err == ESP_OK, err); + cluster::electrical_power_measurement::create(endpoint, &(config->electrical_power_measurement), CLUSTER_FLAG_SERVER); + cluster::electrical_energy_measurement::create(endpoint, &(config->electrical_energy_measurement), CLUSTER_FLAG_SERVER); + return ESP_OK; +} +} /* electrical_meter */ } /* endpoint */ namespace node { diff --git a/components/esp_matter/data_model/esp_matter_endpoint.h b/components/esp_matter/data_model/esp_matter_endpoint.h index d781b107f..6af8e1a06 100644 --- a/components/esp_matter/data_model/esp_matter_endpoint.h +++ b/components/esp_matter/data_model/esp_matter_endpoint.h @@ -161,7 +161,12 @@ #define ESP_MATTER_CLOSURE_PANEL_DEVICE_TYPE_VERSION 1 #define ESP_MATTER_CHIME_DEVICE_TYPE_ID 0x0146 #define ESP_MATTER_CHIME_DEVICE_TYPE_VERSION 1 - +#define ESP_MATTER_ELECTRICAL_UTILITY_METER_DEVICE_TYPE_ID 0x0511 +#define ESP_MATTER_ELECTRICAL_UTILITY_METER_DEVICE_TYPE_VERSION 1 +#define ESP_MATTER_ELECTRICAL_ENERGY_TARIFF_DEVICE_TYPE_ID 0x0513 +#define ESP_MATTER_ELECTRICAL_ENERGY_TARIFF_DEVICE_TYPE_VERSION 1 +#define ESP_MATTER_ELECTRICAL_METER_DEVICE_TYPE_ID 0x0514 +#define ESP_MATTER_ELECTRICAL_METER_DEVICE_TYPE_VERSION 1 namespace esp_matter { /** Specific endpoint (device type) create APIs @@ -1108,6 +1113,42 @@ uint8_t get_device_type_version(); endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data); esp_err_t add(endpoint_t *endpoint, config_t *config); } /* closure_panel */ + +namespace electrical_utility_meter { +typedef struct config { + cluster::descriptor::config_t descriptor; + cluster::meter_identification::config_t meter_identification; +} config_t; + +uint32_t get_device_type_id(); +uint8_t get_device_type_version(); +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data); +esp_err_t add(endpoint_t *endpoint, config_t *config); +} /* electrical_utility_meter */ + +namespace electrical_energy_tariff { +typedef struct config { + cluster::descriptor::config_t descriptor; +} config_t; + +uint32_t get_device_type_id(); +uint8_t get_device_type_version(); +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data); +esp_err_t add(endpoint_t *endpoint, config_t *config); +} /* electrical_energy_tariff */ + +namespace electrical_meter { +typedef struct config { + cluster::descriptor::config_t descriptor; + cluster::electrical_power_measurement::config_t electrical_power_measurement; + cluster::electrical_energy_measurement::config_t electrical_energy_measurement; +} config_t; + +uint32_t get_device_type_id(); +uint8_t get_device_type_version(); +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data); +esp_err_t add(endpoint_t *endpoint, config_t *config); +} /* electrical_meter */ } /* endpoint */ namespace node { diff --git a/components/esp_matter/data_model_provider/esp_matter_plugin_server_init_callbacks.cpp b/components/esp_matter/data_model_provider/esp_matter_plugin_server_init_callbacks.cpp index b600985d1..81272dcc7 100644 --- a/components/esp_matter/data_model_provider/esp_matter_plugin_server_init_callbacks.cpp +++ b/components/esp_matter/data_model_provider/esp_matter_plugin_server_init_callbacks.cpp @@ -67,6 +67,8 @@ void MatterElectricalPowerMeasurementPluginServerInitCallback() {} void MatterServiceAreaPluginServerInitCallback() {} void MatterWaterHeaterManagementPluginServerInitCallback() {} void MatterWaterHeaterModePluginServerInitCallback() {} +void MatterCommodityTariffPluginServerInitCallback() {} void MatterCommodityPricePluginServerInitCallback() {} +void MatterCommodityMeteringPluginServerInitCallback() {} void MatterElectricalGridConditionsPluginServerInitCallback() {} void MatterSoilMeasurementPluginServerInitCallback() {} diff --git a/examples/all_device_types_app/main/device_types.h b/examples/all_device_types_app/main/device_types.h index 461fb93db..b955d8722 100644 --- a/examples/all_device_types_app/main/device_types.h +++ b/examples/all_device_types_app/main/device_types.h @@ -64,6 +64,9 @@ enum device_type_enum { ESP_MATTER_CLOSURE_CONTROLLER, ESP_MATTER_CLOSURE, ESP_MATTER_CLOSURE_PANEL, + ESP_MATTER_ELECTRICAL_ENERGY_TARIFF, + ESP_MATTER_ELECTRICAL_METER, + ESP_MATTER_ELECTRICAL_UTILITY_METER, ESP_MATTER_DEVICE_TYPE_MAX }; @@ -134,5 +137,8 @@ const device_type_name device_type_list[ESP_MATTER_DEVICE_TYPE_MAX] = { {"closure_controller", ESP_MATTER_CLOSURE_CONTROLLER}, {"closure", ESP_MATTER_CLOSURE}, {"closure_panel", ESP_MATTER_CLOSURE_PANEL}, + {"electrical_energy_tariff", ESP_MATTER_ELECTRICAL_ENERGY_TARIFF}, + {"electrical_meter", ESP_MATTER_ELECTRICAL_METER}, + {"electrical_utility_meter", ESP_MATTER_ELECTRICAL_UTILITY_METER}, }; } /* namespace esp_matter */ diff --git a/examples/all_device_types_app/main/esp_matter_console_helpers.cpp b/examples/all_device_types_app/main/esp_matter_console_helpers.cpp index 7a5de910a..26fba07fe 100644 --- a/examples/all_device_types_app/main/esp_matter_console_helpers.cpp +++ b/examples/all_device_types_app/main/esp_matter_console_helpers.cpp @@ -613,6 +613,34 @@ int create(uint8_t device_type_index) endpoint = esp_matter::endpoint::closure_panel::create(node, &closure_panel_config, ENDPOINT_FLAG_NONE, NULL); break; } + case ESP_MATTER_ELECTRICAL_ENERGY_TARIFF: { + esp_matter::endpoint::electrical_energy_tariff::config_t electrical_energy_tariff_config; + endpoint = esp_matter::endpoint::electrical_energy_tariff::create(node, &electrical_energy_tariff_config, ENDPOINT_FLAG_NONE, NULL); + + cluster::commodity_price::config_t commodity_price_config; + cluster::commodity_price::create(endpoint, &commodity_price_config, CLUSTER_FLAG_SERVER); + + cluster::commodity_tariff::config_t commodity_tariff_config; + commodity_tariff_config.feature_flags = cluster::commodity_tariff::feature::pricing::get_id(); + cluster::commodity_tariff::create(endpoint, &commodity_tariff_config, CLUSTER_FLAG_SERVER); + + break; + } + case ESP_MATTER_ELECTRICAL_METER: { + esp_matter::endpoint::electrical_meter::config_t electrical_meter_config; + electrical_meter_config.electrical_power_measurement.feature_flags = cluster::electrical_power_measurement::feature::direct_current::get_id(); + electrical_meter_config.electrical_energy_measurement.feature_flags = cluster::electrical_energy_measurement::feature::imported_energy::get_id() | + cluster::electrical_energy_measurement::feature::exported_energy::get_id() | + cluster::electrical_energy_measurement::feature::cumulative_energy::get_id() | + cluster::electrical_energy_measurement::feature::periodic_energy::get_id(); + endpoint = esp_matter::endpoint::electrical_meter::create(node, &electrical_meter_config, ENDPOINT_FLAG_NONE, NULL); + break; + } + case ESP_MATTER_ELECTRICAL_UTILITY_METER: { + esp_matter::endpoint::electrical_utility_meter::config_t electrical_utility_meter_config; + endpoint = esp_matter::endpoint::electrical_utility_meter::create(node, &electrical_utility_meter_config, ENDPOINT_FLAG_NONE, NULL); + break; + } default: { ESP_LOGE(TAG, "Please input a valid device type"); break;