From 7abee629df8567832259a9a3a2ede3b03afc4102 Mon Sep 17 00:00:00 2001 From: Rohit Jadhav Date: Wed, 29 May 2024 18:17:24 +0530 Subject: [PATCH] [component/esp_matter] Add device energy management device type --- SUPPORTED_DEVICE_TYPES.md | 21 +- .../esp_matter/esp_matter_attribute.cpp | 45 ++++ components/esp_matter/esp_matter_attribute.h | 13 ++ components/esp_matter/esp_matter_cluster.cpp | 116 +++++++++++ components/esp_matter/esp_matter_cluster.h | 21 ++ components/esp_matter/esp_matter_command.cpp | 45 ++++ components/esp_matter/esp_matter_command.h | 13 ++ .../esp_matter_delegate_callbacks.cpp | 19 ++ .../esp_matter_delegate_callbacks.h | 2 + components/esp_matter/esp_matter_endpoint.cpp | 39 ++++ components/esp_matter/esp_matter_endpoint.h | 15 ++ components/esp_matter/esp_matter_event.cpp | 25 +++ components/esp_matter/esp_matter_event.h | 9 + components/esp_matter/esp_matter_feature.cpp | 195 ++++++++++++++++++ components/esp_matter/esp_matter_feature.h | 48 +++++ docs/en/app_guide.rst | 14 +- .../all_device_types_app/main/device_types.h | 4 +- .../main/esp_matter_console_helpers.cpp | 5 + 18 files changed, 638 insertions(+), 11 deletions(-) diff --git a/SUPPORTED_DEVICE_TYPES.md b/SUPPORTED_DEVICE_TYPES.md index 89967e761..a56bdcf9a 100644 --- a/SUPPORTED_DEVICE_TYPES.md +++ b/SUPPORTED_DEVICE_TYPES.md @@ -7,9 +7,9 @@ Utility Device Types 2. Power Source 3. OTA Requestor 4. OTA Provider -5. Aggregator -6. Bridged Node -7. Electrical Sensor +5. Bridged Node +6. Electrical Sensor +7. Device Energy Management Application Device Types @@ -34,6 +34,7 @@ c. Smart Plugs/Outlets d. Generic 1. Mode Select +2. Aggregator e. HVAC 1. Fan @@ -58,10 +59,10 @@ g. Sensors 10. Rain Sensor 11. Water Freeze Detector -h. Robotic +h. Robotic Devices 1. Robotic Vacuum Cleaner -i. Appliance +i. Appliances 1. Dishwasher 2. Laundry Washer 3. Room Air Conditioner @@ -70,7 +71,9 @@ i. Appliance 6. Oven 7. Cook Surface 8. Cooktop -9. Energy Evse -10. Microwave Oven -11. Extractor Hood -12. Laundry Dryer +9. Microwave Oven +10. Extractor Hood +11. Laundry Dryer + +j. Energy +1. EVSE (Electric Vehicle Supply Equipment) diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index d7a1783e0..62563ab5a 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -4693,5 +4693,50 @@ attribute_t *create_level_step(cluster_t *cluster, const uint8_t value) } /* attribute */ } /* valve_configuration_and_control */ +namespace device_energy_management { +namespace attribute { +attribute_t *create_esa_type(cluster_t *cluster, const uint8_t value) +{ + return esp_matter::attribute::create(cluster, DeviceEnergyManagement::Attributes::ESAType::Id, ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +attribute_t *create_esa_can_generate(cluster_t *cluster, const bool value) +{ + return esp_matter::attribute::create(cluster, DeviceEnergyManagement::Attributes::ESACanGenerate::Id, ATTRIBUTE_FLAG_NONE, esp_matter_bool(value)); +} + +attribute_t *create_esa_state(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, DeviceEnergyManagement::Attributes::ESAState::Id, ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +attribute_t *create_abs_min_power(cluster_t *cluster, int64_t value) +{ + return esp_matter::attribute::create(cluster, DeviceEnergyManagement::Attributes::AbsMinPower::Id, ATTRIBUTE_FLAG_NONE, esp_matter_int64(value)); +} + +attribute_t *create_abs_max_power(cluster_t *cluster, int64_t value) +{ + return esp_matter::attribute::create(cluster, DeviceEnergyManagement::Attributes::AbsMaxPower::Id, ATTRIBUTE_FLAG_NONE, esp_matter_int64(value)); +} + +attribute_t *create_power_adjustment_capability(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, DeviceEnergyManagement::Attributes::PowerAdjustmentCapability::Id, ATTRIBUTE_FLAG_NULLABLE, esp_matter_array(value, length, count)); +} + +attribute_t *create_forecast(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, DeviceEnergyManagement::Attributes::Forecast::Id, ATTRIBUTE_FLAG_NULLABLE, esp_matter_array((uint8_t*)value, length, count)); +} + +attribute_t *create_opt_out_state(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, DeviceEnergyManagement::Attributes::OptOutState::Id, ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +} /* attribute */ +} /* device_energy_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 8c567aa3d..74d090400 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -1077,5 +1077,18 @@ attribute_t *create_level_step(cluster_t *cluster, const uint8_t value); } /* attribute */ } /* valve_configuration_and_control */ +namespace device_energy_management { +namespace attribute { +attribute_t *create_esa_type(cluster_t *cluster, const uint8_t value); +attribute_t *create_esa_can_generate(cluster_t *cluster, const bool value); +attribute_t *create_esa_state(cluster_t *cluster, uint8_t value); +attribute_t *create_abs_min_power(cluster_t *cluster, int64_t value); +attribute_t *create_abs_max_power(cluster_t *cluster, int64_t value); +attribute_t *create_power_adjustment_capability(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); +attribute_t *create_forecast(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); +attribute_t *create_opt_out_state(cluster_t *cluster, uint8_t value); +} /* attribute */ +} /* device_energy_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index 5254886d1..bcfa021fa 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -4006,6 +4006,122 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ } } /* valve_configuration_and_control */ +namespace device_energy_management { +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, uint32_t features) +{ + cluster_t *cluster = cluster::create(endpoint, DeviceEnergyManagement::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_FLAG_SERVER) { + if (config -> delegate != nullptr) { + static const auto delegate_init_cb = DeviceEnergyManagementDelegateInitCB; + set_delegate_and_init_callback(cluster, delegate_init_cb, config->delegate); + } + static const auto plugin_server_init_cb = CALL_ONCE(MatterDeviceEnergyManagementPluginServerInitCallback); + set_plugin_server_init_callback(cluster, plugin_server_init_cb); + 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); +#if CHIP_CONFIG_ENABLE_EVENTLIST_ATTRIBUTE + global::attribute::create_event_list(cluster, NULL, 0, 0); +#endif + + /* Attributes should managed by application */ + attribute::create_esa_type(cluster, 0); + attribute::create_esa_can_generate(cluster, 0); + attribute::create_esa_state(cluster, 0); + attribute::create_abs_min_power(cluster, 0); + attribute::create_abs_max_power(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."); + } + } + + /* Features */ + if (features & feature::power_adjustment::get_id()) { + feature::power_adjustment::add(cluster); + } + if (features & feature::power_forecast_reporting::get_id()) { + feature::power_forecast_reporting::add(cluster); + } + if (features & feature::state_forecast_reporting::get_id()) { + if ((!(features & feature::power_adjustment::get_id()) || + (features & feature::start_time_adjustment::get_id()) || + (features & feature::pausable::get_id()) || + (features & feature::forecast_adjustment::get_id()) || + (features & feature::constraint_based_adjustment::get_id())) && + !(features & feature::power_forecast_reporting::get_id())) { + + feature::state_forecast_reporting::add(cluster); + } + } + if (features & feature::pausable::get_id()) { + feature::pausable::add(cluster); + } + if (features & feature::forecast_adjustment::get_id()) { + feature::forecast_adjustment::add(cluster); + } + if (features & feature::constraint_based_adjustment::get_id()) { + feature::constraint_based_adjustment::add(cluster); + } + return cluster; +} +} /* device_energy_management */ + +namespace device_energy_management_mode { +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, DeviceEnergyManagementMode::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + + if (flags & CLUSTER_FLAG_SERVER) { + if (config -> delegate != nullptr) { + static const auto delegate_init_cb = DeviceEnergyManagementModeDelegateInitCB; + set_delegate_and_init_callback(cluster, delegate_init_cb, config->delegate); + } + add_function_list(cluster, function_list, function_flags); + + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + global::attribute::create_event_list(cluster, NULL, 0, 0); + mode_base::attribute::create_supported_modes(cluster, NULL, 0, 0); + + /* Attributes not managed internally */ + if (config) { + global::attribute::create_cluster_revision(cluster, config->cluster_revision); + mode_base::attribute::create_current_mode(cluster, config->current_mode); + } else { + ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); + } + } + + /* Commands */ + mode_base::command::create_change_to_mode(cluster); + + return cluster; +} +} /* device_energy_management_mode */ + // namespace binary_input_basic { // // ToDo // } /* binary_input_basic */ diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 96f62572f..e88b5354c 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -959,5 +959,26 @@ typedef struct config { cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); } /* valve_configuration_and_control */ +namespace device_energy_management { +typedef struct config { + uint16_t cluster_revision; + void *delegate; + config() : cluster_revision(4), delegate(nullptr) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); +} /* device_energy_management */ + +namespace device_energy_management_mode { +typedef struct config { + uint16_t cluster_revision; + uint8_t current_mode; + void *delegate; + config() : cluster_revision(1), current_mode(0), delegate(nullptr) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); +} /* device_energy_management_mode */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index f5d1acaa4..fdd62d616 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -2814,6 +2814,51 @@ command_t *create_close(cluster_t *cluster) } /* command */ } /* valve_configuration_and_control */ +namespace device_energy_management { +namespace command { +command_t *create_power_adjust_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, DeviceEnergyManagement::Commands::PowerAdjustRequest::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_cancel_power_adjust_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, DeviceEnergyManagement::Commands::CancelPowerAdjustRequest::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_start_time_adjust_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, DeviceEnergyManagement::Commands::StartTimeAdjustRequest::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_pause_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, DeviceEnergyManagement::Commands::PauseRequest::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_resume_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, DeviceEnergyManagement::Commands::ResumeRequest::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_modify_forecast_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, DeviceEnergyManagement::Commands::ModifyForecastRequest::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_request_constraint_based_forecast(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, DeviceEnergyManagement::Commands::RequestConstraintBasedForecast::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_cancel_request(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, DeviceEnergyManagement::Commands::CancelRequest::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +} /* command */ +} /* device_energy_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 047f11fab..1933dfb5b 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -404,5 +404,18 @@ command_t *create_close(cluster_t *cluster); } /* command */ } /* valve_configuration_and_control */ +namespace device_energy_management { +namespace command { +command_t *create_power_adjust_request(cluster_t *cluster); +command_t *create_cancel_power_adjust_request(cluster_t *cluster); +command_t *create_start_time_adjust_request(cluster_t *cluster); +command_t *create_pause_request(cluster_t *cluster); +command_t *create_resume_request(cluster_t *cluster); +command_t *create_modify_forecast_request(cluster_t *cluster); +command_t *create_request_constraint_based_forecast(cluster_t *cluster); +command_t *create_cancel_request(cluster_t *cluster); +} /* command */ +} /* device_energy_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_delegate_callbacks.cpp b/components/esp_matter/esp_matter_delegate_callbacks.cpp index 8c919f392..e24903ab8 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.cpp +++ b/components/esp_matter/esp_matter_delegate_callbacks.cpp @@ -24,6 +24,7 @@ #include #include #include +#include using namespace chip::app::Clusters; namespace esp_matter { @@ -92,6 +93,11 @@ void MicrowaveOvenModeDelegateInitCB(void *delegate, uint16_t endpoint_id) InitModeDelegate(delegate, endpoint_id, MicrowaveOvenMode::Id); } +void DeviceEnergyManagementModeDelegateInitCB(void *delegate, uint16_t endpoint_id) +{ + InitModeDelegate(delegate, endpoint_id, DeviceEnergyManagementMode::Id); +} + void EnergyEvseDelegateInitCB(void *delegate, uint16_t endpoint_id) { if(delegate == nullptr) @@ -205,6 +211,19 @@ void ValveConfigurationAndControlDelegateInitCB(void *delegate, uint16_t endpoin ValveConfigurationAndControl::SetDefaultDelegate(endpoint_id, valve_configuration_and_control_delegate); } +void DeviceEnergyManagementDelegateInitCB(void *delegate, uint16_t endpoint_id) +{ + if(delegate == nullptr) + { + return; + } + static DeviceEnergyManagement::Instance * deviceEnergyManagementInstance = nullptr; + DeviceEnergyManagement::Delegate *device_energy_management_delegate = static_cast(delegate); + uint32_t feature_map = get_feature_map_value(endpoint_id, DeviceEnergyManagement::Id); + deviceEnergyManagementInstance = new DeviceEnergyManagement::Instance(endpoint_id, *device_energy_management_delegate, chip::BitMask(feature_map)); + deviceEnergyManagementInstance->Init(); +} + } // namespace delegate_cb } // namespace cluster diff --git a/components/esp_matter/esp_matter_delegate_callbacks.h b/components/esp_matter/esp_matter_delegate_callbacks.h index 1e778251d..0eb702cfd 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.h +++ b/components/esp_matter/esp_matter_delegate_callbacks.h @@ -32,6 +32,8 @@ void HepaFilterMonitoringDelegateInitCB(void *delegate, uint16_t endpoint_id); void ActivatedCarbonFilterMonitoringDelegateInitCB(void *delegate, uint16_t endpoint_id); void LaundryDryerControlsDelegateInitCB(void *delegate, uint16_t endpoint_id); void ValveConfigurationAndControlDelegateInitCB(void *delegate, uint16_t endpoint_id); +void DeviceEnergyManagementDelegateInitCB(void *delegate, uint16_t endpoint_id); +void DeviceEnergyManagementModeDelegateInitCB(void *delegate, uint16_t endpoint_id); } // namespace delegate_cb } // namespace cluster diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index da74f569d..1214d9cfd 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -1944,6 +1944,45 @@ esp_err_t add(endpoint_t *endpoint, config_t *config) } } /** water_valve **/ +namespace device_energy_management { + +uint32_t get_device_type_id() +{ + return ESP_MATTER_DEVICE_ENERGY_MANAGEMENT_DEVICE_TYPE_ID; +} + +uint8_t get_device_type_version() +{ + return ESP_MATTER_DEVICE_ENERGY_MANAGEMENT_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); + cluster::device_energy_management::create(endpoint, &(config->device_energy_management), CLUSTER_FLAG_SERVER, ESP_MATTER_NONE_FEATURE_ID); + device_energy_management_mode::create(endpoint, &(config->device_energy_management_mode), CLUSTER_FLAG_SERVER); + + return ESP_OK; +} +} /** device_energy_management **/ + } /* endpoint */ namespace node { diff --git a/components/esp_matter/esp_matter_endpoint.h b/components/esp_matter/esp_matter_endpoint.h index ad8305606..8b3a527ba 100644 --- a/components/esp_matter/esp_matter_endpoint.h +++ b/components/esp_matter/esp_matter_endpoint.h @@ -120,6 +120,8 @@ #define ESP_MATTER_EXTRACTOR_HOOD_DEVICE_TYPE_VERSION 1 #define ESP_MATTER_WATER_VALVE_DEVICE_TYPE_ID 0x0042 #define ESP_MATTER_WATER_VALVE_DEVICE_TYPE_VERSION 1 +#define ESP_MATTER_DEVICE_ENERGY_MANAGEMENT_DEVICE_TYPE_ID 0x050D +#define ESP_MATTER_DEVICE_ENERGY_MANAGEMENT_DEVICE_TYPE_VERSION 1 namespace esp_matter { @@ -780,6 +782,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); } /** water_valve **/ +namespace device_energy_management { +typedef struct config { + cluster::descriptor::config_t descriptor; + cluster::device_energy_management::config_t device_energy_management; + cluster::device_energy_management_mode::config_t device_energy_management_mode; +} 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); +} /* device_energy_management */ + } /* endpoint */ namespace node { diff --git a/components/esp_matter/esp_matter_event.cpp b/components/esp_matter/esp_matter_event.cpp index f2f463b7f..2ad7aab74 100644 --- a/components/esp_matter/esp_matter_event.cpp +++ b/components/esp_matter/esp_matter_event.cpp @@ -719,5 +719,30 @@ event_t *create_valve_fault(cluster_t *cluster) } // namespace event } // namespace valve_configuration_and_control +namespace device_energy_management { +namespace event { +event_t *create_power_adjust_start(cluster_t *cluster) +{ + return esp_matter::event::create(cluster, DeviceEnergyManagement::Events::PowerAdjustStart::Id); +} + +event_t *create_power_adjust_end(cluster_t *cluster) +{ + return esp_matter::event::create(cluster, DeviceEnergyManagement::Events::PowerAdjustEnd::Id); +} + +event_t *create_paused(cluster_t *cluster) +{ + return esp_matter::event::create(cluster, DeviceEnergyManagement::Events::Paused::Id); +} + +event_t *create_resumed(cluster_t *cluster) +{ + return esp_matter::event::create(cluster, DeviceEnergyManagement::Events::Resumed::Id); +} + +} // namespace event +} // namespace device_energy_management + } // namespace cluster } // namespace esp_matter diff --git a/components/esp_matter/esp_matter_event.h b/components/esp_matter/esp_matter_event.h index c7b528be1..ce96838de 100644 --- a/components/esp_matter/esp_matter_event.h +++ b/components/esp_matter/esp_matter_event.h @@ -214,5 +214,14 @@ event_t *create_valve_fault(cluster_t *cluster); } // namespace event } // namespace valve_configuration_and_control +namespace device_energy_management { +namespace event { +event_t *create_power_adjust_start(cluster_t *cluster); +event_t *create_power_adjust_end(cluster_t *cluster); +event_t *create_paused(cluster_t *cluster); +event_t *create_resumed(cluster_t *cluster); +} // namespace event +} // namespace device_energy_management + } // namespace cluster } // namespace esp_matter diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 1b5598370..0bb282f25 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -4567,5 +4567,200 @@ esp_err_t add(cluster_t *cluster, config_t *config) } /* feature */ } /* valve_configuration_and_control */ +namespace device_energy_management { +namespace feature { + +namespace power_adjustment { + +uint32_t get_id() +{ + return (uint32_t)DeviceEnergyManagement::Feature::kPowerAdjustment; +} + +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_power_adjustment_capability(cluster, NULL, 0, 0); + attribute::create_opt_out_state(cluster, 0); + + /* Commands */ + command::create_power_adjust_request(cluster); + command::create_cancel_power_adjust_request(cluster); + + /* Events */ + event::create_power_adjust_start(cluster); + event::create_power_adjust_end(cluster); + + + return ESP_OK; +} +} /* power_adjustment */ + +namespace power_forecast_reporting { + +uint32_t get_id() +{ + return (uint32_t)DeviceEnergyManagement::Feature::kPowerForecastReporting; +} + +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_forecast(cluster, NULL, 0, 0); + + return ESP_OK; +} +} /* power_forecast_reporting */ + +namespace state_forecast_reporting { + +uint32_t get_id() +{ + return (uint32_t)DeviceEnergyManagement::Feature::kStateForecastReporting; +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + + uint32_t power_adjustment_id = feature::power_adjustment::get_id(); + uint32_t power_forecast_reporting = feature::power_forecast_reporting::get_id(); + uint32_t start_time_adjustment_id = feature::start_time_adjustment::get_id(); + uint32_t pausable_id = feature::pausable::get_id(); + uint32_t forecast_adjustment_id = feature::forecast_adjustment::get_id(); + uint32_t constraint_based_adjustment_id = feature::constraint_based_adjustment::get_id(); + uint32_t feature_map_value = get_feature_map_value(cluster); + if((((feature_map_value & power_adjustment_id) != power_adjustment_id) || + ((feature_map_value & start_time_adjustment_id) == start_time_adjustment_id) || + ((feature_map_value & pausable_id) == pausable_id) || + ((feature_map_value & forecast_adjustment_id) == forecast_adjustment_id) || + ((feature_map_value & constraint_based_adjustment_id) == constraint_based_adjustment_id)) && + ((feature_map_value & power_forecast_reporting) != power_forecast_reporting)) { + update_feature_map(cluster, get_id()); + attribute::create_forecast(cluster, NULL, 0, 0); + } else { + ESP_LOGE(TAG, "Cluster shall satisfy condition (STA|PAU|FA|CON|!PA)&!PFR of feature"); + return ESP_ERR_NOT_SUPPORTED; + } + + + return ESP_OK; +} +} /* state_forecast_reporting */ + +namespace start_time_adjustment { + +uint32_t get_id() +{ + return (uint32_t)DeviceEnergyManagement::Feature::kStartTimeAdjustment; +} + +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_opt_out_state(cluster, 0); + + /* Commands */ + command::create_start_time_adjust_request(cluster); + command::create_cancel_request(cluster); + + return ESP_OK; +} +} /* start_time_adjustment */ + +namespace pausable { + +uint32_t get_id() +{ + return (uint32_t)DeviceEnergyManagement::Feature::kPausable; +} + +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_opt_out_state(cluster, 0); + + /* Commands */ + command::create_pause_request(cluster); + command::create_resume_request(cluster); + + /* Events */ + event::create_paused(cluster); + event::create_resumed(cluster); + + return ESP_OK; +} +} /* pausable */ + +namespace forecast_adjustment { + +uint32_t get_id() +{ + return (uint32_t)DeviceEnergyManagement::Feature::kForecastAdjustment; +} + +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_opt_out_state(cluster, 0); + + /* Commands */ + command::create_modify_forecast_request(cluster); + command::create_cancel_request(cluster); + + return ESP_OK; +} +} /* forecast_adjustment */ + +namespace constraint_based_adjustment { + +uint32_t get_id() +{ + return (uint32_t)DeviceEnergyManagement::Feature::kConstraintBasedAdjustment; +} + +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_opt_out_state(cluster, 0); + + /* Commands */ + command::create_request_constraint_based_forecast(cluster); + command::create_cancel_request(cluster); + + return ESP_OK; +} +} /* constraint_based_adjustment */ + +} /* feature */ +} /* device_energy_management */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index 69f758115..825573509 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -2036,5 +2036,53 @@ esp_err_t add(cluster_t *cluster, config_t *config); } /* feature */ } /* valve_configuration_and_control */ +namespace device_energy_management { +namespace feature { + +namespace power_adjustment { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); +} /* power_adjustment */ + +namespace power_forecast_reporting { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); +} /* power_forecast_reporting */ + +namespace state_forecast_reporting { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); +} /* state_forecast_reporting */ + +namespace start_time_adjustment { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); +} /* start_time_adjustment */ + +namespace pausable { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); +} /* pausable */ + +namespace forecast_adjustment { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); +} /* forecast_adjustment */ + +namespace constraint_based_adjustment { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); +} /* constraint_based_adjustment */ + +} /* feature */ +} /* device_energy_management */ + } /* cluster */ } /* esp_matter */ diff --git a/docs/en/app_guide.rst b/docs/en/app_guide.rst index 194b53102..c61cdd189 100644 --- a/docs/en/app_guide.rst +++ b/docs/en/app_guide.rst @@ -60,6 +60,7 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. , `Rvc Run And Rvc Clean Mode`_ , `Energy Evse Mode`_ , `Microwave Oven Mode`_ + , `Device Energy Management Mode`_ 9.1.2 Energy Evse Cluster ------------------------- @@ -118,6 +119,14 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. `Valve Configuration And Control`_, None +9.1.9 Device Energy Management Cluster +-------------------------------------- + +.. csv-table:: Delegate and its impl + :header: "Delegate Class", "Reference Implementation" + + `Device Energy Management`_, `Device Energy Management Delegate`_ + .. note:: Make sure that after implementing delegate class, you set the delegate class pointer at the time of creating cluster. @@ -134,9 +143,10 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. .. _`Dish Washer Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/dishwasher-mode.h .. _`Rvc Run And Rvc Clean Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/rvc-modes.h .. _`Energy Evse Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/energy-evse-modes.h +.. _`Microwave Oven Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/microwave-oven-mode.h +.. _`Device Energy Management Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/energy-management-app/energy-management-common/include/device-energy-management-modes.h .. _`Energy Evse`: https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/energy-evse-server/energy-evse-server.h .. _`Energy Evse Delegate`: https://github.com/project-chip/connectedhomeip/blob/master/examples/energy-management-app/energy-management-common/include/EnergyEvseDelegateImpl.h -.. _`Microwave Oven Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/microwave-oven-mode.h .. _`Operational State`: https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/operational-state-server/operational-state-server.h .. _`Operational State Delegate`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h .. _`Microwave Oven Control`: https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/microwave-oven-control-server/microwave-oven-control-server.h @@ -147,3 +157,5 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. .. _`Laundry Dryer Controls`: https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h .. _`Laundry Dryer Controls Delegate`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h .. _`Valve Configuration And Control`: https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/valve-configuration-and-control-server/valve-configuration-and-control-delegate.h +.. _`Device Energy Management`: https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/device-energy-management-server/device-energy-management-server.h +.. _`Device Energy Management Delegate`: https://github.com/project-chip/connectedhomeip/blob/master/examples/energy-management-app/energy-management-common/include/DeviceEnergyManagementDelegateImpl.h diff --git a/examples/all_device_types_app/main/device_types.h b/examples/all_device_types_app/main/device_types.h index cc9c3ccbc..503c87b55 100644 --- a/examples/all_device_types_app/main/device_types.h +++ b/examples/all_device_types_app/main/device_types.h @@ -49,6 +49,7 @@ enum device_type_enum { ESP_MATTER_EXTRACTOR_HOOD, ESP_MATTER_LAUNDRY_DRYER, ESP_MATTER_WATER_VALVE, + ESP_MATTER_DEVICE_ENERGY_MANAGEMENT, ESP_MATTER_DEVICE_TYPE_MAX }; @@ -103,6 +104,7 @@ const device_type_name device_type_list[ESP_MATTER_DEVICE_TYPE_MAX] = { {"microwave_oven", ESP_MATTER_MICROWAVE_OVEN}, {"extractor_hood", ESP_MATTER_EXTRACTOR_HOOD}, {"laundry_dryer", ESP_MATTER_LAUNDRY_DRYER}, - {"water_valve", ESP_MATTER_WATER_VALVE} + {"water_valve", ESP_MATTER_WATER_VALVE}, + {"device_energy_management", ESP_MATTER_DEVICE_ENERGY_MANAGEMENT} }; } /* 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 01b882dcf..c96517853 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 @@ -439,6 +439,11 @@ int create(uint8_t device_type_index) endpoint = esp_matter::endpoint::water_valve::create(node, &water_valve_config, ENDPOINT_FLAG_NONE, NULL); break; } + case ESP_MATTER_DEVICE_ENERGY_MANAGEMENT: { + esp_matter::endpoint::device_energy_management::config_t device_energy_management_config; + endpoint = esp_matter::endpoint::device_energy_management::create(node, &device_energy_management_config, ENDPOINT_FLAG_NONE, NULL); + break; + } default: { ESP_LOGE(TAG, "Please input a valid device type"); break;