Merge branch 'feat/add-commodity_metering-cluster' into 'main'

Add commodity metering cluster

See merge request app-frameworks/esp-matter!1357
This commit is contained in:
Hrishikesh Dhayagude
2025-12-22 21:10:50 +08:00
7 changed files with 114 additions and 0 deletions
@@ -5297,5 +5297,35 @@ attribute_t *create_price_forecast(cluster_t *cluster, uint8_t *value, uint16_t
} /* attribute */
} /* commodity_price */
namespace commodity_metering {
namespace attribute {
attribute_t *create_metered_quantity(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count)
{
return esp_matter::attribute::create(cluster, CommodityMetering::Attributes::MeteredQuantity::Id,
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NULLABLE, esp_matter_array(value, length, count));
}
attribute_t *create_metered_quantity_timestamp(cluster_t *cluster, nullable<uint32_t> value)
{
return esp_matter::attribute::create(cluster, CommodityMetering::Attributes::MeteredQuantityTimestamp::Id,
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint32(value));
}
attribute_t *create_tariff_unit(cluster_t *cluster, nullable<uint8_t> value)
{
return esp_matter::attribute::create(cluster, CommodityMetering::Attributes::TariffUnit::Id,
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_enum8(value));
}
attribute_t *create_maximum_metered_quantities(cluster_t *cluster, nullable<uint16_t> value)
{
return esp_matter::attribute::create(cluster, CommodityMetering::Attributes::MaximumMeteredQuantities::Id,
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint16(value));
}
} /* attribute */
} /* commodity_metering */
} /* cluster */
} /* esp_matter */
@@ -1366,5 +1366,15 @@ attribute_t *create_price_forecast(cluster_t *cluster, uint8_t * value, uint16_t
} /* attribute */
} /* commodity_price */
namespace commodity_metering {
namespace attribute {
attribute_t *create_metered_quantity(cluster_t *cluster, uint8_t * value, uint16_t length, uint16_t count);
attribute_t *create_metered_quantity_timestamp(cluster_t *cluster, nullable<uint32_t> value);
attribute_t *create_tariff_unit(cluster_t *cluster, nullable<uint8_t> value);
attribute_t *create_maximum_metered_quantities(cluster_t *cluster, nullable<uint16_t> value);
} /* attribute */
} /* commodity_metering */
} /* cluster */
} /* esp_matter */
@@ -762,5 +762,32 @@ void add_bounds_cb(cluster_t *cluster)
}
}
} /* 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 */
@@ -57,5 +57,9 @@ void add_bounds_cb(cluster_t *cluster);
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 */
@@ -4456,5 +4456,39 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags)
} /* commodity_price */
namespace commodity_metering {
const function_generic_t *function_list = NULL;
const int function_flags = CLUSTER_FLAG_NONE;
cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags)
{
cluster_t *cluster = esp_matter::cluster::create(endpoint, CommodityMetering::Id, flags);
VerifyOrReturnValue(cluster, NULL, ESP_LOGE(TAG, "Could not create cluster. cluster_id: 0x%08" PRIX32, CommodityMetering::Id));
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 */
global::attribute::create_feature_map(cluster, 0);
attribute::create_metered_quantity(cluster, NULL, 0, 0);
attribute::create_metered_quantity_timestamp(cluster, 0);
attribute::create_tariff_unit(cluster, 0);
attribute::create_maximum_metered_quantities(cluster, 1);
/* Attributes not managed internally */
global::attribute::create_cluster_revision(cluster, cluster_revision);
}
if (flags & CLUSTER_FLAG_CLIENT) {
create_default_binding_cluster(endpoint);
}
return cluster;
}
} /* commodity_metering */
} /* cluster */
} /* esp_matter */
@@ -1057,5 +1057,10 @@ typedef struct config {
cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags);
} /* commodity_price */
namespace commodity_metering {
using config_t = common::config_t;
cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags);
} /* commodity_metering */
} /* cluster */
} /* esp_matter */
@@ -406,6 +406,10 @@ constexpr uint16_t cluster_revision = 1;
namespace commodity_price {
constexpr uint16_t cluster_revision = 4;
} // namespace commodity_price
namespace commodity_metering {
constexpr uint16_t cluster_revision = 1;
} // namespace commodity_metering
} // namespace cluster
} // namespace esp_matter