diff --git a/SUPPORTED_DEVICE_TYPES.md b/SUPPORTED_DEVICE_TYPES.md index 991716e5e..4489f7072 100644 --- a/SUPPORTED_DEVICE_TYPES.md +++ b/SUPPORTED_DEVICE_TYPES.md @@ -70,3 +70,4 @@ i. Appliance 7. Cook Surface 8. Cooktop 9. Energy Evse +10. Microwave Oven diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index 29f774e91..26411fa92 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -4565,5 +4565,55 @@ attribute_t *create_session_energy_discharged(cluster_t *cluster, nullable delegate != nullptr) { + static const auto delegate_init_cb = OperationalStateDelegateInitCB; + set_delegate_and_init_callback(cluster, delegate_init_cb, config->delegate); + } add_function_list(cluster, function_list, function_flags); } if (flags & CLUSTER_FLAG_CLIENT) { @@ -3440,6 +3444,93 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } } /* rvc_clean_mode */ +namespace microwave_oven_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, MicrowaveOvenMode::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 = MicrowaveOvenModeDelegateInitCB; + 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."); + } + } + + return cluster; +} +} /* microwave_oven_mode */ + +namespace microwave_oven_control { +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, MicrowaveOvenControl::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 = MicrowaveOvenControlDelegateInitCB; + 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); + microwave_oven_control::attribute::create_cook_time(cluster, 0); + microwave_oven_control::attribute::create_max_cook_time(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."); + } + } + + /* Commands */ + command::create_set_cooking_parameters(cluster); + + if (features & feature::power_as_number::get_id()) { + feature::power_as_number::add(cluster); + } + if (features & feature::power_in_watts::get_id()) { + feature::power_in_watts::add(cluster); + } + if (features & feature::power_number_limits::get_id()) { + feature::power_number_limits::add(cluster); + } + + return cluster; +} +} /* microwave_oven_control */ + namespace rvc_operational_state { 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 5598e0cf1..02657fa99 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -535,7 +535,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); namespace operational_state { typedef struct config { uint16_t cluster_revision; - config() : cluster_revision(1) {} + void *delegate; + config() : cluster_revision(1), delegate(nullptr) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); @@ -841,6 +842,27 @@ typedef struct config { cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); } /* rvc_clean_mode */ +namespace microwave_oven_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); +} /* microwave_oven_mode */ + +namespace microwave_oven_control { +typedef struct config { + uint16_t cluster_revision; + void *delegate; + config() : cluster_revision(1), delegate(nullptr) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); +} /* microwave_oven_control */ + namespace rvc_operational_state { 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 9bb6a9848..de3309744 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -2764,6 +2764,21 @@ command_t *create_get_targets_response(cluster_t *cluster) } /* command */ } /* energy_evse */ +namespace microwave_oven_control { +namespace command { +command_t *create_set_cooking_parameters(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, MicrowaveOvenControl::Commands::SetCookingParameters::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_add_more_time(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, MicrowaveOvenControl::Commands::AddMoreTime::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +} /* command */ +} /* microwave_oven_control */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 5b783ed26..5b61ee342 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -390,5 +390,12 @@ command_t *create_get_targets_response(cluster_t *cluster); } /* command */ } /* energy_evse */ +namespace microwave_oven_control { +namespace command { +command_t *create_set_cooking_parameters(cluster_t *cluster); +command_t *create_add_more_time(cluster_t *cluster); +} /* command */ +} /* microwave_oven_control */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_delegate_callbacks.cpp b/components/esp_matter/esp_matter_delegate_callbacks.cpp index 1d564fb5f..0fc8b9d00 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.cpp +++ b/components/esp_matter/esp_matter_delegate_callbacks.cpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include using namespace chip::app::Clusters; namespace esp_matter { @@ -81,6 +83,11 @@ void EnergyEvseModeDelegateInitCB(void *delegate, uint16_t endpoint_id) InitModeDelegate(delegate, endpoint_id, EnergyEvseMode::Id); } +void MicrowaveOvenModeDelegateInitCB(void *delegate, uint16_t endpoint_id) +{ + InitModeDelegate(delegate, endpoint_id, MicrowaveOvenMode::Id); +} + void EnergyEvseDelegateInitCB(void *delegate, uint16_t endpoint_id) { if(delegate == nullptr) @@ -95,6 +102,47 @@ void EnergyEvseDelegateInitCB(void *delegate, uint16_t endpoint_id) energyEvseInstance->Init(); } +void MicrowaveOvenControlDelegateInitCB(void *delegate, uint16_t endpoint_id) +{ + // Get delegates of MicrowaveOvenMode and OperationalState clusters. + node_t *node = node::get(); + endpoint_t *endpoint = endpoint::get(node, endpoint_id); + cluster_t *cluster = cluster::get(endpoint, MicrowaveOvenMode::Id); + ModeBase::Delegate *microwave_oven_mode_delegate = static_cast(get_delegate_impl(cluster)); + cluster = cluster::get(endpoint, OperationalState::Id); + OperationalState::Delegate *operational_state_delegate = static_cast(get_delegate_impl(cluster)); + if(delegate == nullptr || microwave_oven_mode_delegate == nullptr || operational_state_delegate == nullptr) + { + return; + } + // Create instances of clusters. + static ModeBase::Instance * microwaveOvenModeInstance = nullptr; + static OperationalState::Instance * operationalStateInstance = nullptr; + static MicrowaveOvenControl::Instance * microwaveOvenControlInstance = nullptr; + MicrowaveOvenControl::Delegate *microwave_oven_control_delegate = static_cast(delegate); + uint32_t feature_map = get_feature_map_value(endpoint_id, MicrowaveOvenMode::Id); + + microwaveOvenModeInstance = new ModeBase::Instance(microwave_oven_mode_delegate, endpoint_id, MicrowaveOvenMode::Id, feature_map); + operationalStateInstance = new OperationalState::Instance(operational_state_delegate, endpoint_id); + + feature_map = get_feature_map_value(endpoint_id, MicrowaveOvenControl::Id); + microwaveOvenControlInstance = new MicrowaveOvenControl::Instance(microwave_oven_control_delegate, endpoint_id, MicrowaveOvenControl::Id, feature_map, + *operationalStateInstance, *microwaveOvenModeInstance); + microwaveOvenControlInstance->Init(); +} + +void OperationalStateDelegateInitCB(void *delegate, uint16_t endpoint_id) +{ + if(delegate == nullptr) + { + return; + } + static OperationalState::Instance * operationalStateInstance = nullptr; + OperationalState::Delegate *operational_state_delegate = static_cast(delegate); + operationalStateInstance = new OperationalState::Instance(operational_state_delegate, endpoint_id); + operationalStateInstance->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 f95a76877..29d18f297 100644 --- a/components/esp_matter/esp_matter_delegate_callbacks.h +++ b/components/esp_matter/esp_matter_delegate_callbacks.h @@ -24,6 +24,9 @@ void RvcRunModeDelegateInitCB(void *delegate, uint16_t endpoint_id); void RvcCleanModeDelegateInitCB(void *delegate, uint16_t endpoint_id); void EnergyEvseModeDelegateInitCB(void *delegate, uint16_t endpoint_id); void EnergyEvseDelegateInitCB(void *delegate, uint16_t endpoint_id); +void MicrowaveOvenModeDelegateInitCB(void *delegate, uint16_t endpoint_id); +void MicrowaveOvenControlDelegateInitCB(void *delegate, uint16_t endpoint_id); +void OperationalStateDelegateInitCB(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 adce6ae40..178c09396 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -1791,6 +1791,46 @@ esp_err_t add(endpoint_t *endpoint, config_t *config) } } /* energy_evse */ +namespace microwave_oven { +uint32_t get_device_type_id() +{ + return ESP_MATTER_MICROWAVE_OVEN_DEVICE_TYPE_ID; +} + +uint8_t get_device_type_version() +{ + return ESP_MATTER_MICROWAVE_OVEN_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_t *cluster = operational_state::create(endpoint, &(config->operational_state), CLUSTER_FLAG_SERVER); + operational_state::attribute::create_countdown_time(cluster, 0); + microwave_oven_mode::create(endpoint, &(config->microwave_oven_mode), CLUSTER_FLAG_SERVER); + microwave_oven_control::create(endpoint, &(config->microwave_oven_control), CLUSTER_FLAG_SERVER, ESP_MATTER_NONE_FEATURE_ID); + + return ESP_OK; +} +} /* microwave_oven */ + } /* endpoint */ namespace node { diff --git a/components/esp_matter/esp_matter_endpoint.h b/components/esp_matter/esp_matter_endpoint.h index b059b9a3d..878a4575a 100644 --- a/components/esp_matter/esp_matter_endpoint.h +++ b/components/esp_matter/esp_matter_endpoint.h @@ -75,6 +75,8 @@ #define ESP_MATTER_LAUNDRY_WASHER_DEVICE_TYPE_VERSION 1 #define ESP_MATTER_DISH_WASHER_DEVICE_TYPE_ID 0x0075 #define ESP_MATTER_DISH_WASHER_DEVICE_TYPE_VERSION 1 +#define ESP_MATTER_MICROWAVE_OVEN_DEVICE_TYPE_ID 0x0079 +#define ESP_MATTER_MICROWAVE_OVEN_DEVICE_TYPE_VERSION 1 #define ESP_MATTER_SMOKE_CO_ALARM_DEVICE_TYPE_ID 0x0076 #define ESP_MATTER_SMOKE_CO_ALARM_DEVICE_TYPE_VERSION 1 @@ -722,6 +724,20 @@ 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); } /* energy_evse */ +namespace microwave_oven { +typedef struct config { + cluster::descriptor::config_t descriptor; + cluster::operational_state::config_t operational_state; + cluster::microwave_oven_mode::config_t microwave_oven_mode; + cluster::microwave_oven_control::config_t microwave_oven_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); +} /* microwave_oven */ + } /* endpoint */ namespace node { diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 5c58608fc..6f181ed34 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -4427,5 +4427,96 @@ esp_err_t add(cluster_t *cluster) } /* feature */ } /* energy_evse */ +namespace microwave_oven_control { +namespace feature { + +namespace power_as_number { + +uint32_t get_id() +{ + return (uint32_t)MicrowaveOvenControl::Feature::kPowerAsNumber; +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + uint32_t power_in_watts_feature_map = feature::power_in_watts::get_id(); + if((get_feature_map_value(cluster) & power_in_watts_feature_map) != power_in_watts_feature_map) { + update_feature_map(cluster, get_id()); + /* Attributes managed internally */ + attribute::create_power_setting(cluster, 0); + } else { + ESP_LOGE(TAG, "Cluster shall support either PowerAsNumber or PowerInWatts feature"); + return ESP_ERR_NOT_SUPPORTED; + } + + return ESP_OK; +} +} /* power_as_number */ + +namespace power_in_watts { + +uint32_t get_id() +{ + return (uint32_t)MicrowaveOvenControl::Feature::kPowerInWatts; +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + uint32_t power_as_number_feature_map = feature::power_as_number::get_id(); + if((get_feature_map_value(cluster) & power_as_number_feature_map) != power_as_number_feature_map) { + update_feature_map(cluster, get_id()); + /* Attributes managed internally */ + attribute::create_supported_watts(cluster, NULL, 0, 0); + attribute::create_selected_watt_index(cluster, 0); + } else { + ESP_LOGE(TAG, "Cluster shall support either PowerInWatts or PowerAsNumber feature"); + return ESP_ERR_NOT_SUPPORTED; + } + + return ESP_OK; +} +} /* power_in_watts */ + +namespace power_number_limits { + +uint32_t get_id() +{ + return (uint32_t)MicrowaveOvenControl::Feature::kPowerNumberLimits; +} + +esp_err_t add(cluster_t *cluster) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + + uint32_t power_as_number_feature_map = feature::power_as_number::get_id(); + if((get_feature_map_value(cluster) & power_as_number_feature_map) != power_as_number_feature_map) { + update_feature_map(cluster, get_id()); + /* Attributes managed internally */ + attribute::create_min_power(cluster, 0); + attribute::create_max_power(cluster, 0); + attribute::create_power_step(cluster, 0); + } else { + ESP_LOGE(TAG, "Cluster shall support PowerAsNumber feature."); + return ESP_ERR_NOT_SUPPORTED; + } + + return ESP_OK; +} +} /* power_number_limits */ + +} /* feature */ +} /* microwave_oven_control */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index 65854c63f..601b5257c 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -1985,5 +1985,29 @@ esp_err_t add(cluster_t *cluster); } /* feature */ } /* energy_evse */ +namespace microwave_oven_control { +namespace feature { + +namespace power_as_number { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); +} /* power_as_number */ + +namespace power_in_watts { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); +} /* power_in_watts */ + +namespace power_number_limits { + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster); +} /* power_number_limits */ + +} /* feature */ +} /* microwave_oven_control */ + } /* cluster */ } /* esp_matter */ diff --git a/docs/en/app_guide.rst b/docs/en/app_guide.rst index 08d7daacb..96325ef2a 100644 --- a/docs/en/app_guide.rst +++ b/docs/en/app_guide.rst @@ -59,6 +59,7 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. , `Dish Washer Mode`_ , `Rvc Run And Rvc Clean Mode`_ , `Energy Evse Mode`_ + , `Microwave Oven Mode`_ 9.1.2 Energy Evse Cluster ------------------------- @@ -68,6 +69,22 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. `Energy Evse`_, `Energy Evse Delegate`_ +9.1.3 Operational State Cluster +------------------------------- + +.. csv-table:: Delegate and its impl + :header: "Delegate Class", "Reference Implementation" + + `Operational State`_, `Operational State Delegate`_ + +9.1.4 Microwave Oven Control Cluster +------------------------------------ + +.. csv-table:: Delegate and its impl + :header: "Delegate Class", "Reference Implementation" + + `Microwave Oven Control`_, None + .. note:: Make sure that after implementing delegate class, you set the delegate class pointer at the time of creating cluster. @@ -85,3 +102,7 @@ ModeWaterHeater, ModeRefrigerator, ModeLaundryWasher and ModeMicrowaveOven. .. _`Energy Evse Mode`: https://github.com/project-chip/connectedhomeip/blob/master/examples/all-clusters-app/all-clusters-common/include/energy-evse-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 diff --git a/examples/all_device_types_app/main/device_types.h b/examples/all_device_types_app/main/device_types.h index b598c3415..ba718ba11 100644 --- a/examples/all_device_types_app/main/device_types.h +++ b/examples/all_device_types_app/main/device_types.h @@ -45,6 +45,7 @@ enum device_type_enum { ESP_MATTER_OVEN, ESP_MATTER_COOKTOP, ESP_MATTER_ENERGY_EVSE, + ESP_MATTER_MICROWAVE_OVEN, ESP_MATTER_DEVICE_TYPE_MAX }; @@ -95,6 +96,7 @@ const device_type_name device_type_list[ESP_MATTER_DEVICE_TYPE_MAX] = { {"electrical_sensor", ESP_MATTER_ELECTRICAL_SENSOR}, {"oven", ESP_MATTER_OVEN}, {"cooktop", ESP_MATTER_COOKTOP}, - {"energy_evse", ESP_MATTER_ENERGY_EVSE} + {"energy_evse", ESP_MATTER_ENERGY_EVSE}, + {"microwave_oven", ESP_MATTER_MICROWAVE_OVEN} }; } /* 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 16c1582e5..545f1ac94 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 @@ -419,6 +419,11 @@ int create(uint8_t device_type_index) } break; } + case ESP_MATTER_MICROWAVE_OVEN: { + esp_matter::endpoint::microwave_oven::config_t microwave_oven_config; + endpoint = esp_matter::endpoint::microwave_oven::create(node, µwave_oven_config, ENDPOINT_FLAG_NONE, NULL); + break; + } default: { ESP_LOGE(TAG, "Please input a valid device type"); break;