diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index 651c1526a..401df1ec1 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -1912,6 +1912,92 @@ attribute_t *create_air_quality(cluster_t *cluster, uint8_t value) } /* attribute */ } /* air_quality */ +namespace hepa_filter_monitoring { +namespace attribute { + +attribute_t *create_condition(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, HepaFilterMonitoring::Attributes::Condition::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +attribute_t *create_degradation_direction(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, HepaFilterMonitoring::Attributes::DegradationDirection::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +attribute_t *create_change_indication(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, HepaFilterMonitoring::Attributes::ChangeIndication::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +attribute_t *create_in_place_indicator(cluster_t *cluster, bool value) +{ + return esp_matter::attribute::create(cluster, HepaFilterMonitoring::Attributes::InPlaceIndicator::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_bool(value)); +} + +attribute_t *create_last_change_time(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, HepaFilterMonitoring::Attributes::LastChangedTime::Id, + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, + esp_matter_nullable_uint8(value)); +} + +attribute_t *create_replacement_product_list(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, HepaFilterMonitoring::Attributes::ReplacementProductList::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); +} + +} /* attribute */ +} /* hepa_filter_monitoring */ + +namespace activated_carbon_filter_monitoring { +namespace attribute { + +attribute_t *create_condition(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, ActivatedCarbonFilterMonitoring::Attributes::Condition::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +attribute_t *create_degradation_direction(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, ActivatedCarbonFilterMonitoring::Attributes::DegradationDirection::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +attribute_t *create_change_indication(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, ActivatedCarbonFilterMonitoring::Attributes::ChangeIndication::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +attribute_t *create_in_place_indicator(cluster_t *cluster, bool value) +{ + return esp_matter::attribute::create(cluster, ActivatedCarbonFilterMonitoring::Attributes::InPlaceIndicator::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_bool(value)); +} + +attribute_t *create_last_change_time(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, ActivatedCarbonFilterMonitoring::Attributes::LastChangedTime::Id, + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, + esp_matter_nullable_uint8(value)); +} + +attribute_t *create_replacement_product_list(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, ActivatedCarbonFilterMonitoring::Attributes::ReplacementProductList::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); +} + +} /* attribute */ +} /* activated_carbon_filter_monitoring */ + namespace carbon_monoxide_concentration_measurement { namespace attribute { attribute_t *create_measured_value(cluster_t *cluster, nullable value) diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 31b3b94eb..62edbd3bb 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -430,6 +430,28 @@ attribute_t *create_air_quality(cluster_t *cluster, uint8_t value); } /* attribute */ } /* air_quality */ +namespace hepa_filter_monitoring { +namespace attribute { +attribute_t *create_condition(cluster_t *cluster, uint8_t value); +attribute_t *create_degradation_direction(cluster_t *cluster, uint8_t value); +attribute_t *create_change_indication(cluster_t *cluster, uint8_t value); +attribute_t *create_in_place_indicator(cluster_t *cluster, bool value); +attribute_t *create_last_changed_time(cluster_t *cluster, nullable value); +attribute_t *create_replacement_product_list(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); +} /* attribute */ +} /* hepa_filter_monitoring */ + +namespace activated_carbon_filter_monitoring { +namespace attribute { +attribute_t *create_condition(cluster_t *cluster, uint8_t value); +attribute_t *create_degradation_direction(cluster_t *cluster, uint8_t value); +attribute_t *create_change_indication(cluster_t *cluster, uint8_t value); +attribute_t *create_in_place_indicator(cluster_t *cluster, bool value); +attribute_t *create_last_changed_time(cluster_t *cluster, nullable value); +attribute_t *create_replacement_product_list(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); +} /* attribute */ +} /* activated_carbon_filter_monitoring */ + namespace carbon_monoxide_concentration_measurement { namespace attribute { attribute_t *create_measured_value(cluster_t *cluster, nullable value); diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index c6fb20988..4ef936c7d 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -1484,6 +1484,80 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } } /* air_quality */ +namespace hepa_filter_monitoring { +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 = cluster::create(endpoint, HepaFilterMonitoring::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + + if (flags & CLUSTER_FLAG_SERVER) { + add_function_list(cluster, function_list, function_flags); + } + if (flags & CLUSTER_FLAG_CLIENT) { + create_default_binding_cluster(endpoint); + } + + if (flags & CLUSTER_FLAG_SERVER) { + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + global::attribute::create_event_list(cluster, NULL, 0, 0); + attribute::create_change_indication(cluster, 0); + + /* Attributes not managed internally */ + if (config) { + global::attribute::create_cluster_revision(cluster, config->cluster_revision); + } else { + ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); + } + } + + return cluster; +} +} /* hepa_filter_monitoring */ + +namespace activated_carbon_filter_monitoring { +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 = cluster::create(endpoint, HepaFilterMonitoring::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + + if (flags & CLUSTER_FLAG_SERVER) { + add_function_list(cluster, function_list, function_flags); + } + if (flags & CLUSTER_FLAG_CLIENT) { + create_default_binding_cluster(endpoint); + } + + if (flags & CLUSTER_FLAG_SERVER) { + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + global::attribute::create_event_list(cluster, NULL, 0, 0); + attribute::create_change_indication(cluster, 0); + + /* Attributes not managed internally */ + if (config) { + global::attribute::create_cluster_revision(cluster, config->cluster_revision); + } else { + ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); + } + } + + return cluster; +} +} /* activated_carbon_filter_monitoring */ + namespace carbon_monoxide_concentration_measurement { const function_generic_t *function_list = NULL; const int function_flags = CLUSTER_FLAG_NONE; diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 0a2b232a3..ca9597aa5 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -380,6 +380,24 @@ typedef struct config { cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); } /* air_quality */ +namespace hepa_filter_monitoring { +typedef struct config { + uint16_t cluster_revision; + config() : cluster_revision(1) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); +} /* hepa_filter_monitoring */ + +namespace activated_carbon_filter_monitoring { +typedef struct config { + uint16_t cluster_revision; + config() : cluster_revision(1) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); +} /* activated_carbon_filter_monitoring */ + namespace carbon_monoxide_concentration_measurement { typedef struct config { uint16_t cluster_revision; diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index ed87d2170..977708a34 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -2210,6 +2210,26 @@ command_t *create_step(cluster_t *cluster) } /* command */ } /* fan_control */ +namespace hepa_filter_monitoring { +namespace command { +command_t *create_reset_condition(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, HepaFilterMonitoring::Commands::ResetCondition::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +} /* command */ +} /* hepa_filter_monitoring */ + +namespace activated_carbon_filter_monitoring { +namespace command { +command_t *create_reset_condition(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, ActivatedCarbonFilterMonitoring::Commands::ResetCondition::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +} /* command */ +} /* activated_carbon_filter_monitoring */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index bba44c3c2..0f4288308 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -301,5 +301,17 @@ command_t *create_step(cluster_t *cluster); } /* command */ } /* fan_control */ +namespace hepa_filter_monitoring { +namespace command { +command_t *create_reset_condition(cluster_t *cluster); +} /* command */ +} /* hepa_filter_monitoring */ + +namespace activated_carbon_filter_monitoring { +namespace command { +command_t *create_reset_condition(cluster_t *cluster); +} /* command */ +} /* activated_carbon_filter_monitoring */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index 715771e4d..78f7c28b3 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -679,6 +679,44 @@ esp_err_t add(endpoint_t *endpoint, config_t *config) } } /* air_quality_sensor */ +namespace air_purifier { +uint32_t get_device_type_id() +{ + return ESP_MATTER_AIR_PURIFIER_DEVICE_TYPE_ID; +} + +uint8_t get_device_type_version() +{ + return ESP_MATTER_AIR_PURIFIER_DEVICE_TYPE_VERSION; +} + +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data) +{ + endpoint_t *endpoint = endpoint::create(node, flags, priv_data); + add(endpoint, config); + return endpoint; +} + +esp_err_t add(endpoint_t *endpoint, config_t *config) +{ + if (!endpoint) { + ESP_LOGE(TAG, "Endpoint cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + esp_err_t err = add_device_type(endpoint, get_device_type_id(), get_device_type_version()); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to add device type id:%" PRIu32 ", err: %d", get_device_type_id(), err); + return err; + } + + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); + identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); + fan_control::create(endpoint, &(config->fan_control), CLUSTER_FLAG_SERVER); + + return ESP_OK; +} +} /* air_purifier */ + esp_err_t add(endpoint_t *endpoint, config_t *config) { if (!endpoint) { diff --git a/components/esp_matter/esp_matter_endpoint.h b/components/esp_matter/esp_matter_endpoint.h index 2ab7423cd..8a1e3d5e5 100644 --- a/components/esp_matter/esp_matter_endpoint.h +++ b/components/esp_matter/esp_matter_endpoint.h @@ -78,6 +78,8 @@ #define ESP_MATTER_THERMOSTAT_DEVICE_TYPE_VERSION 2 #define ESP_MATTER_AIR_QUALITY_SENSOR_DEVICE_TYPE_ID 0x002C #define ESP_MATTER_AIR_QUALITY_SENSOR_DEVICE_TYPE_VERSION 1 +#define ESP_MATTER_AIR_PURIFIER_DEVICE_TYPE_ID 0x002D +#define ESP_MATTER_AIR_PURIFIER_DEVICE_TYPE_VERSION 1 #define ESP_MATTER_DOOR_LOCK_DEVICE_TYPE_ID 0x000A #define ESP_MATTER_DOOR_LOCK_DEVICE_TYPE_VERSION 2 #define ESP_MATTER_WINDOW_COVERING_DEVICE_TYPE_ID 0x0202 @@ -322,6 +324,19 @@ endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_dat esp_err_t add(endpoint_t *endpoint, config_t *config); } /* air_quality_sensor */ +namespace air_purifier { +typedef struct config { + cluster::descriptor::config_t descriptor; + cluster::identify::config_t identify; + cluster::fan_control::config_t fan_control; +} 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); +} /* air_purifier */ + namespace aggregator { typedef struct config { cluster::descriptor::config_t descriptor; diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index be4e0d2bc..245d5a003 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -2391,6 +2391,148 @@ esp_err_t add(cluster_t *cluster) } /* feature */ } /* total_volatile_organic_compounds_concentration_measurement */ +namespace hepa_filter_monitoring { +namespace feature { + +namespace condition { + +uint32_t get_id() +{ + return (uint32_t)HepaFilterMonitoring::Feature::kCondition; +} + +esp_err_t add(cluster_t *cluster, config_t *config) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + attribute::create_condition(cluster, config->condition); + attribute::create_degradation_direction(cluster, config->degradation_direction); + + return ESP_OK; +} + +} /* condition */ + +namespace warning { + +uint32_t get_id() +{ + return (uint32_t)HepaFilterMonitoring::Feature::kWarning; +} + +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()); + + return ESP_OK; +} + +} /* warning */ + +namespace replacement_product_list { + +uint32_t get_id() +{ + return (uint32_t)HepaFilterMonitoring::Feature::kReplacementProductList; +} + +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()); + + attribute::create_replacement_product_list(cluster, NULL, 0, 0); + + return ESP_OK; +} + +} /* replacement_product_list */ + +} /* feature */ +} /* hepa_filter_monitoring */ + +namespace activated_carbon_filter_monitoring { +namespace feature { + +namespace condition { + +uint32_t get_id() +{ + return (uint32_t)ActivatedCarbonFilterMonitoring::Feature::kCondition; +} + +esp_err_t add(cluster_t *cluster, config_t *config) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + attribute::create_condition(cluster, config->condition); + attribute::create_degradation_direction(cluster, config->degradation_direction); + + return ESP_OK; +} + +} /* condition */ + +namespace warning { + +uint32_t get_id() +{ + return (uint32_t)ActivatedCarbonFilterMonitoring::Feature::kWarning; +} + +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()); + + return ESP_OK; +} + +} /* warning */ + +namespace replacement_product_list { + +uint32_t get_id() +{ + return (uint32_t)ActivatedCarbonFilterMonitoring::Feature::kReplacementProductList; +} + +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()); + + attribute::create_replacement_product_list(cluster, NULL, 0, 0); + + return ESP_OK; +} + +} /* replacement_product_list */ + +} /* feature */ +} /* activated_carbon_filter_monitoring */ + namespace thermostat { namespace feature { diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index 8a4006bcf..332189e84 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -1163,6 +1163,70 @@ esp_err_t add(cluster_t *cluster); } /* feature */ } /* total_volatile_organic_compounds_concentration_measurement */ +namespace hepa_filter_monitoring { +namespace feature { + +namespace condition { +typedef struct config { + uint8_t condition; + uint8_t degradation_direction; + config() : condition(0), degradation_direction(0) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* condition */ + +namespace warning { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* warning */ + +namespace replacement_product_list { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* replacement_product_list */ + +} /* feature */ +} /* hepa_filter_monitoring */ + +namespace activated_carbon_filter_monitoring { +namespace feature { + +namespace condition { +typedef struct config { + uint8_t condition; + uint8_t degradation_direction; + config() : condition(0), degradation_direction(0) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* condition */ + +namespace warning { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* warning */ + +namespace replacement_product_list { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* replacement_product_list */ + +} /* feature */ +} /* activated_carbon_filter_monitoring */ + namespace switch_cluster { namespace feature {