diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index c0f92d467..01751030f 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -2023,6 +2023,25 @@ const function_generic_t function_list[] = { }; const int function_flags = CLUSTER_FLAG_INIT_FUNCTION; +static bool check_feature_map(uint32_t features) { + if((features & feature::other::get_id()) == feature::other::get_id()) + return true; + if((features & feature::passive_infrared::get_id()) == feature::passive_infrared::get_id()) + return true; + if((features & feature::ultrasonic::get_id()) == feature::ultrasonic::get_id()) + return true; + if((features & feature::physical_contact::get_id()) == feature::physical_contact::get_id()) + return true; + if((features & feature::active_infrared::get_id()) == feature::active_infrared::get_id()) + return true; + if((features & feature::radar::get_id()) == feature::radar::get_id()) + return true; + if((features & feature::rf_sensing::get_id()) == feature::rf_sensing::get_id()) + return true; + if((features & feature::vision::get_id()) == feature::vision::get_id()) + return true; + return false; +} cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) { cluster_t *cluster = cluster::create(endpoint, OccupancySensing::Id, flags); @@ -2051,6 +2070,34 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) create_default_binding_cluster(endpoint); } + if(config != nullptr && check_feature_map(config->features)) { + if (config->features & feature::other::get_id()) { + feature::other::add(cluster); + } + if (config->features & feature::passive_infrared::get_id()) { + feature::passive_infrared::add(cluster); + } + if (config->features & feature::ultrasonic::get_id()) { + feature::ultrasonic::add(cluster); + } + if (config->features & feature::physical_contact::get_id()) { + feature::physical_contact::add(cluster); + } + if (config->features & feature::active_infrared::get_id()) { + feature::active_infrared::add(cluster); + } + if (config->features & feature::radar::get_id()) { + feature::radar::add(cluster); + } + if (config->features & feature::rf_sensing::get_id()) { + feature::rf_sensing::add(cluster); + } + if (config->features & feature::vision::get_id()) { + feature::vision::add(cluster); + } + } else { + ESP_LOGE(TAG, "Config is NULL or mandatory features are missing."); + } return cluster; } } /* occupancy_sensing */ @@ -2326,6 +2373,20 @@ const function_generic_t function_list[] = { const int function_flags = CLUSTER_FLAG_INIT_FUNCTION | CLUSTER_FLAG_ATTRIBUTE_CHANGED_FUNCTION | CLUSTER_FLAG_PRE_ATTRIBUTE_CHANGED_FUNCTION; +static bool check_feature_map(uint32_t features) { + if ((features & feature::constant_pressure::get_id()) == feature::constant_pressure::get_id()) + return true; + if ((features & feature::compensated_pressure::get_id()) == feature::compensated_pressure::get_id()) + return true; + if ((features & feature::constant_flow::get_id()) == feature::constant_flow::get_id()) + return true; + if ((features & feature::constant_speed::get_id()) == feature::constant_speed::get_id()) + return true; + if ((features & feature::constant_temperature::get_id()) == feature::constant_temperature::get_id()) + return true; + return false; +} + cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) { cluster_t *cluster = cluster::create(endpoint, PumpConfigurationAndControl::Id, flags); @@ -2357,6 +2418,31 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) create_default_binding_cluster(endpoint); } + if(config != nullptr && check_feature_map(config->features)) { + if (config->features & feature::constant_pressure::get_id()) { + feature::constant_pressure::add(cluster, &config->constant_pressure); + } + if (config->features & feature::compensated_pressure::get_id()) { + feature::compensated_pressure::add(cluster, &config->compensated_pressure); + } + if (config->features & feature::constant_flow::get_id()) { + feature::constant_flow::add(cluster, &config->constant_flow); + } + if (config->features & feature::constant_speed::get_id()) { + feature::constant_speed::add(cluster, &config->constant_speed); + } + if (config->features & feature::constant_temperature::get_id()) { + feature::constant_temperature::add(cluster, &config->constant_temperature); + } + if (config->features & feature::automatic::get_id()) { + feature::automatic::add(cluster); + } + if (config->features & feature::local_operation::get_id()) { + feature::local_operation::add(cluster); + } + } else { + ESP_LOGE(TAG, "Config is NULL or mandatory features are missing."); + } return cluster; } } /* pump_configuration_and_control */ @@ -2563,6 +2649,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Commands */ mode_base::command::create_change_to_mode(cluster); + mode_base::command::create_change_to_mode_response(cluster); return cluster; } @@ -2600,6 +2687,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Commands */ mode_base::command::create_change_to_mode(cluster); + mode_base::command::create_change_to_mode_response(cluster); return cluster; } @@ -2636,6 +2724,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Commands */ mode_base::command::create_change_to_mode(cluster); + mode_base::command::create_change_to_mode_response(cluster); return cluster; } @@ -2728,6 +2817,12 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Attributes managed internally */ global::attribute::create_feature_map(cluster, 0); + operational_state::attribute::create_phase_list(cluster, NULL, 0, 0); + operational_state::attribute::create_current_phase(cluster, 0); + operational_state::attribute::create_operational_state_list(cluster, NULL, 0, 0); + operational_state::attribute::create_operational_state(cluster, 0); + operational_state::attribute::create_operational_error(cluster, 0); + /* Attributes not managed internally */ global::attribute::create_cluster_revision(cluster, cluster_revision); } @@ -2949,6 +3044,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Commands */ mode_base::command::create_change_to_mode(cluster); + mode_base::command::create_change_to_mode_response(cluster); return cluster; } @@ -3152,6 +3248,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } /* Commands */ + mode_base::command::create_change_to_mode_response(cluster); mode_base::command::create_change_to_mode(cluster); return cluster; @@ -3365,7 +3462,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ global::attribute::create_cluster_revision(cluster, cluster_revision); attribute::create_heater_types(cluster, config->heater_types); attribute::create_heat_demand(cluster, config->heat_demand); - attribute::create_tank_volume(cluster, config->tank_volume); + attribute::create_boost_state(cluster, config->boost_state); } if (features & feature::energy_management::get_id()) { @@ -3416,6 +3513,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) /* Commands */ mode_base::command::create_change_to_mode(cluster); + mode_base::command::create_change_to_mode_response(cluster); return cluster; } diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index b424a7121..51bb7d5b3 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -592,8 +592,9 @@ typedef struct config { uint8_t occupancy; uint8_t occupancy_sensor_type; uint8_t occupancy_sensor_type_bitmap; + uint32_t features; config() : occupancy(0), occupancy_sensor_type(0), - occupancy_sensor_type_bitmap(0) {} + occupancy_sensor_type_bitmap(0), features(0) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); @@ -685,12 +686,18 @@ typedef struct config { nullable capacity; // Pump Settings Attributes uint8_t operation_mode; + feature::constant_pressure::config_t constant_pressure; + feature::compensated_pressure::config_t compensated_pressure; + feature::constant_flow::config_t constant_flow; + feature::constant_speed::config_t constant_speed; + feature::constant_temperature::config_t constant_temperature; + uint32_t features; config( nullable max_pressure = nullable(), nullable max_speed = nullable(), nullable max_flow = nullable() ) : max_pressure(max_pressure), max_speed(max_speed), max_flow(max_flow), - effective_operation_mode(0), effective_control_mode(0), capacity(), operation_mode(0) {} + effective_operation_mode(0), effective_control_mode(0), capacity(), operation_mode(0), features(0) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); @@ -714,7 +721,8 @@ typedef struct config { feature::temperature_number::config_t temperature_number; feature::temperature_level::config_t temperature_level; feature::temperature_step::config_t temperature_step; - // Empty config for API consistency + uint32_t features; + config() : features(0) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); @@ -915,11 +923,11 @@ namespace water_heater_management { typedef struct config { uint8_t heater_types; uint8_t heat_demand; - uint8_t tank_volume; + uint8_t boost_state; void *delegate; feature::energy_management::config_t energy_management; feature::tank_percent::config_t tank_percent; - config() : heater_types(0), heat_demand(0), tank_volume(0), delegate(nullptr) {} + config() : heater_types(0), heat_demand(0), boost_state(0), delegate(nullptr) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 91c0d3e8d..464dacbe6 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -395,7 +395,7 @@ command_t *create_reset_condition(cluster_t *cluster); namespace mode_base { namespace command { command_t *create_change_to_mode(cluster_t *cluster); -command_t *create_change_to_mode_response(cluster_t *cluster, uint16_t command_id); +command_t *create_change_to_mode_response(cluster_t *cluster); } /* command */ } /* mode_base */ diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index 8a196bbe3..612d1b870 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -1414,7 +1414,7 @@ esp_err_t add(endpoint_t *endpoint, config_t *config) return err; } - temperature_control::create(endpoint, &(config->temperature_control), CLUSTER_FLAG_SERVER, ESP_MATTER_NONE_FEATURE_ID); + temperature_control::create(endpoint, &(config->temperature_control), CLUSTER_FLAG_SERVER, temperature_control::feature::temperature_number::get_id()); return ESP_OK; } diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 885123fd1..99f378a2d 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -4757,5 +4757,156 @@ esp_err_t add(cluster_t *cluster) } /* feature */ } /* occupancy_sensing */ + +namespace pump_configuration_and_control { +namespace feature { +namespace constant_pressure { + +uint32_t get_id() +{ + return (uint32_t)PumpConfigurationAndControl::Feature::kConstantPressure; +} + +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_min_const_pressure(cluster, config->min_const_pressure); + attribute::create_max_const_pressure(cluster, config->max_const_pressure); + + return ESP_OK; +} +} /* constant_pressure */ + +namespace compensated_pressure { + +uint32_t get_id() +{ + return (uint32_t)PumpConfigurationAndControl::Feature::kCompensatedPressure; +} + +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_min_comp_pressure(cluster, config->min_comp_pressure); + attribute::create_max_comp_pressure(cluster, config->max_comp_pressure); + + return ESP_OK; +} +} /* compensated_pressure */ + +namespace constant_flow { + +uint32_t get_id() +{ + return (uint32_t)PumpConfigurationAndControl::Feature::kConstantFlow; +} + +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_min_const_flow(cluster, config->min_const_flow); + attribute::create_max_const_flow(cluster, config->max_const_flow); + + return ESP_OK; +} +} /* constant_flow */ + +namespace constant_speed { + +uint32_t get_id() +{ + return (uint32_t)PumpConfigurationAndControl::Feature::kConstantSpeed; +} + +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_min_const_speed(cluster, config->min_const_speed); + attribute::create_max_const_speed(cluster, config->max_const_speed); + + return ESP_OK; +} +} /* constant_speed */ + +namespace constant_temperature { + +uint32_t get_id() +{ + return (uint32_t)PumpConfigurationAndControl::Feature::kConstantTemperature; +} + +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_min_const_temp(cluster, config->min_const_temp); + attribute::create_max_const_temp(cluster, config->max_const_temp); + + return ESP_OK; +} +} /* constant_temperature */ + +namespace automatic { + +uint32_t get_id() +{ + return static_cast(PumpConfigurationAndControl::Feature::kAutomatic); +} + +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; +} +} /* automatic */ + +namespace local_operation { + +uint32_t get_id() +{ + return static_cast(PumpConfigurationAndControl::Feature::kLocalOperation); +} + +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; +} +} /* local_operation */ + +} /* feature */ +} /* pump_configuration_and_control */ } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index 3680e2e92..75b841521 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -2301,5 +2301,89 @@ esp_err_t add(cluster_t *cluster); } /* feature */ } /* occupancy_sensing */ +namespace pump_configuration_and_control { +namespace feature { + +namespace constant_pressure { + +typedef struct config { + nullable min_const_pressure; + nullable max_const_pressure; + config() : min_const_pressure(), max_const_pressure() {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* constant_pressure */ + +namespace compensated_pressure { + +typedef struct config { + nullable min_comp_pressure; + nullable max_comp_pressure; + config() : min_comp_pressure(), max_comp_pressure() {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* compensated_pressure */ + +namespace constant_flow { + +typedef struct config { + nullable min_const_flow; + nullable max_const_flow; + config() : min_const_flow(), max_const_flow() {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* constant_flow */ + +namespace constant_speed { + +typedef struct config { + nullable min_const_speed; + nullable max_const_speed; + config() : min_const_speed(), max_const_speed() {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* constant_speed */ + +namespace constant_temperature { + +typedef struct config { + nullable min_const_temp; + nullable max_const_temp; + config() : min_const_temp(), max_const_temp() {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* constant_temperature */ + +namespace automatic { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* automatic */ + +namespace local_operation { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); + +} /* automatic */ +} /* feature */ +} /* pump_configuration_and_control */ + } /* cluster */ } /* 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 529c0854e..175ddd296 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 @@ -311,6 +311,7 @@ int create(uint8_t device_type_index) } case ESP_MATTER_OCCUPANCY_SENSOR: { esp_matter::endpoint::occupancy_sensor::config_t occupancy_sensor_config; + occupancy_sensor_config.occupancy_sensing.features = cluster::occupancy_sensing::feature::other::get_id(); endpoint = esp_matter::endpoint::occupancy_sensor::create(node, &occupancy_sensor_config, ENDPOINT_FLAG_NONE, NULL); break; } @@ -336,6 +337,7 @@ int create(uint8_t device_type_index) } case ESP_MATTER_PUMP: { esp_matter::endpoint::pump::config_t pump_config; + pump_config.pump_configuration_and_control.features = cluster::pump_configuration_and_control::feature::constant_pressure::get_id(); endpoint = esp_matter::endpoint::pump::create(node, &pump_config, ENDPOINT_FLAG_NONE, NULL); break; }