diff --git a/components/esp_matter/CMakeLists.txt b/components/esp_matter/CMakeLists.txt index e1a3d2118..6a4defe95 100644 --- a/components/esp_matter/CMakeLists.txt +++ b/components/esp_matter/CMakeLists.txt @@ -62,6 +62,8 @@ set(SRC_DIRS_LIST "." "${MATTER_SDK_PATH}/src/app/clusters/wifi-network-diagnostics-server" "${MATTER_SDK_PATH}/src/app/clusters/window-covering-server" "${MATTER_SDK_PATH}/src/app/clusters/mode-select-server" + "${MATTER_SDK_PATH}/src/app/clusters/refrigerator-alarm-server" + "${MATTER_SDK_PATH}/src/app/clusters/temperature-control-server" ) set(INCLUDE_DIRS_LIST "." diff --git a/components/esp_matter/Kconfig b/components/esp_matter/Kconfig index a6cc757f5..63f994e6f 100644 --- a/components/esp_matter/Kconfig +++ b/components/esp_matter/Kconfig @@ -127,6 +127,20 @@ menu "ESP Matter" help The maximum dynamic endpoints supported. + config ESP_MATTER_MODE_SELECT_CLUSTER_ENDPOINT_COUNT + int "Endpoints on which mode select cluster is used" + range 0 255 + default 0 + help + Endpoint count which supports mode select. + + config ESP_MATTER_TEMPERATURE_CONTROL_CLUSTER_ENDPOINT_COUNT + int "Endpoints on which temperature control cluster is used" + range 0 255 + default 0 + help + Endpoint count which supports temperature control. + config ESP_MATTER_SCENES_TABLE_SIZE int "Scenes table size" range 1 255 diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index 4caf06499..b8468ac93 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -2511,24 +2511,33 @@ attribute_t *create_temperature_setpoint(cluster_t *cluster, int16_t value) return esp_matter::attribute::create(cluster, TemperatureControl::Attributes::TemperatureSetpoint::Id, ATTRIBUTE_FLAG_NONE, esp_matter_int16(value)); } -attribute_t *create_min_temperature(cluster_t *cluster, int16_t value) +attribute_t *create_min_temperature(cluster_t *cluster, const int16_t value) { return esp_matter::attribute::create(cluster, TemperatureControl::Attributes::MinTemperature::Id, ATTRIBUTE_FLAG_NONE, esp_matter_int16(value)); } -attribute_t *create_max_temperature(cluster_t *cluster, int16_t value) +attribute_t *create_max_temperature(cluster_t *cluster, const int16_t value) { return esp_matter::attribute::create(cluster, TemperatureControl::Attributes::MaxTemperature::Id, ATTRIBUTE_FLAG_NONE, esp_matter_int16(value)); } -attribute_t *create_step(cluster_t *cluster, int16_t value) +attribute_t *create_step(cluster_t *cluster, const int16_t value) { return esp_matter::attribute::create(cluster, TemperatureControl::Attributes::Step::Id, ATTRIBUTE_FLAG_NONE, esp_matter_int16(value)); } -attribute_t *create_current_temperature_level_index(cluster_t *cluster, uint8_t value) +attribute_t *create_selected_temperature_level(cluster_t *cluster, uint8_t value) { - return esp_matter::attribute::create(cluster, TemperatureControl::Attributes::CurrentTemperatureLevelIndex::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint8(value)); + return esp_matter::attribute::create(cluster, TemperatureControl::Attributes::SelectedTemperatureLevel::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint8(value)); +} + +attribute_t *create_supported_temperature_levels(cluster_t *cluster, uint8_t * value, uint16_t length, uint16_t count) +{ + if (count > k_max_temp_level_count) { + ESP_LOGE(TAG, "Could not create attribute, list out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, TemperatureControl::Attributes::SupportedTemperatureLevels::Id, ATTRIBUTE_FLAG_NONE, esp_matter_array((uint8_t*)value, length, count)); } } /* attribute */ @@ -2541,16 +2550,16 @@ attribute_t *create_mask(cluster_t *cluster, uint32_t value) return esp_matter::attribute::create(cluster, RefrigeratorAlarm::Attributes::Mask::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint32(value)); } -attribute_t *create_latch(cluster_t *cluster, uint32_t value) -{ - return esp_matter::attribute::create(cluster, RefrigeratorAlarm::Attributes::Latch::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint32(value)); -} - attribute_t *create_state(cluster_t *cluster, uint32_t value) { return esp_matter::attribute::create(cluster, RefrigeratorAlarm::Attributes::State::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint32(value)); } +attribute_t *create_supported(cluster_t *cluster, uint32_t value) +{ + return esp_matter::attribute::create(cluster, RefrigeratorAlarm::Attributes::Supported::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint32(value)); +} + } /* attribute */ } /* refrigerator_alarm */ diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 9b9022922..7bc6054c5 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -582,21 +582,23 @@ attribute_t *create_active_bat_charge_faults(cluster_t *cluster, uint8_t * value } /* power_source */ namespace temperature_control { +constexpr uint8_t k_max_temp_level_count = 16; + namespace attribute { attribute_t *create_temperature_setpoint(cluster_t *cluster, int16_t value); -attribute_t *create_min_temperature(cluster_t *cluster, int16_t value); -attribute_t *create_max_temperature(cluster_t *cluster, int16_t value); -attribute_t *create_step(cluster_t *cluster, int16_t value); -attribute_t *create_current_temperature_level_index(cluster_t *cluster, uint8_t value); -//attribute_t *create_supported_temperature_levels(cluster_t *cluster, int16_t value); +attribute_t *create_min_temperature(cluster_t *cluster, const int16_t value); +attribute_t *create_max_temperature(cluster_t *cluster, const int16_t value); +attribute_t *create_step(cluster_t *cluster, const int16_t value); +attribute_t *create_selected_temperature_level(cluster_t *cluster, uint8_t value); +attribute_t *create_supported_temperature_levels(cluster_t *cluster, uint8_t * value, uint16_t length, uint16_t count); } /* attribute */ } /* temperature_control */ namespace refrigerator_alarm { namespace attribute { attribute_t *create_mask(cluster_t *cluster, uint32_t value); -attribute_t *create_latch(cluster_t *cluster, uint32_t value); attribute_t *create_state(cluster_t *cluster, uint32_t value); +attribute_t *create_supported(cluster_t *cluster, uint32_t value); } /* attribute */ } /* refrigerator_alarm */ diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index 97a958f77..7045a7a2f 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -1960,15 +1960,9 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ } if (flags & CLUSTER_FLAG_SERVER) { - //set_plugin_server_init_callback(cluster, MatterTemperatureControlPluginServerInitCallback); + set_plugin_server_init_callback(cluster, MatterTemperatureControlPluginServerInitCallback); add_function_list(cluster, function_list, function_flags); - } - if (flags & CLUSTER_FLAG_CLIENT) { - //set_plugin_client_init_callback(cluster, MatterTemperatureControlPluginClientInitCallback); - create_default_binding_cluster(endpoint); - } - if (flags & CLUSTER_FLAG_SERVER) { /* Attributes managed internally */ global::attribute::create_feature_map(cluster, 0); @@ -1986,10 +1980,12 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ /* Features */ if (features & feature::temperature_number::get_id()) { feature::temperature_number::add(cluster, &(config->temperature_number)); - } else{ - if (features & feature::temperature_level::get_id()) { - feature::temperature_level::add(cluster, &(config->temperature_level)); - } + } + if (features & feature::temperature_level::get_id()) { + feature::temperature_level::add(cluster, &(config->temperature_level)); + } + if (features & feature::temperature_step::get_id()) { + feature::temperature_step::add(cluster, &(config->temperature_step)); } return cluster; @@ -2009,15 +2005,9 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } if (flags & CLUSTER_FLAG_SERVER) { - //set_plugin_server_init_callback(cluster, MatterRefrigeratorAlarmPluginServerInitCallback); + set_plugin_server_init_callback(cluster, MatterRefrigeratorAlarmPluginServerInitCallback); add_function_list(cluster, function_list, function_flags); - } - if (flags & CLUSTER_FLAG_CLIENT) { - //set_plugin_client_init_callback(cluster, MatterRefrigeratorAlarmPluginClientInitCallback); - create_default_binding_cluster(endpoint); - } - if (flags & CLUSTER_FLAG_SERVER) { /* Attributes managed internally */ global::attribute::create_feature_map(cluster, 0); @@ -2025,15 +2015,12 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) if (config) { global::attribute::create_cluster_revision(cluster, config->cluster_revision); attribute::create_mask(cluster, config->mask); - attribute::create_latch(cluster, config->latch); attribute::create_state(cluster, config->state); + attribute::create_supported(cluster, config->supported); } else { ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); } } - /* Commands */ - command::create_reset(cluster); - return cluster; } diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index decbec0b4..2209d01f3 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -522,6 +522,7 @@ typedef struct config { uint16_t cluster_revision; feature::temperature_number::config_t temperature_number; feature::temperature_level::config_t temperature_level; + feature::temperature_step::config_t temperature_step; config() : cluster_revision(1) {} } config_t; @@ -532,9 +533,9 @@ namespace refrigerator_alarm { typedef struct config { uint16_t cluster_revision; uint32_t mask; - uint32_t latch; uint32_t state; - config() : cluster_revision(1), mask(1), latch(1), state(0) {} + uint32_t supported; + config() : cluster_revision(1), mask(1), state(0), supported(1) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index 664a7d9fa..998d6699b 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -1007,6 +1007,16 @@ static esp_err_t esp_matter_command_callback_change_to_mode(const ConcreteComman return ESP_OK; } +static esp_err_t esp_matter_command_callback_set_temperature(const ConcreteCommandPath &command_path, TLVReader &tlv_data, void *opaque_ptr) +{ + chip::app::Clusters::TemperatureControl::Commands::SetTemperature::DecodableType command_data; + CHIP_ERROR error = Decode(tlv_data, command_data); + if (error == CHIP_NO_ERROR) { + emberAfTemperatureControlClusterSetTemperatureCallback((CommandHandler *)opaque_ptr, command_path, command_data); + } + return ESP_OK; +} + static esp_err_t esp_matter_command_callback_instance_action(const ConcreteCommandPath &command_path, TLVReader &tlv_data, void *opaque_ptr) { @@ -2075,23 +2085,12 @@ namespace command { command_t *create_set_temperature(cluster_t *cluster) { return esp_matter::command::create(cluster, TemperatureControl::Commands::SetTemperature::Id, COMMAND_FLAG_ACCEPTED, - NULL); + esp_matter_command_callback_set_temperature); } } /* command */ } /* temperature_control */ -namespace refrigerator_alarm { -namespace command { -command_t *create_reset(cluster_t *cluster) -{ - return esp_matter::command::create(cluster, RefrigeratorAlarm::Commands::Reset::Id, COMMAND_FLAG_ACCEPTED, - NULL); -} - -} /* command */ -} /* refrigerator_alarm */ - } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 8e6e42244..c7f81a7a4 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -280,11 +280,5 @@ command_t *create_set_temperature(cluster_t *cluster); } /* command */ } /* temperature_control */ -namespace refrigerator_alarm { -namespace command { -command_t *create_reset(cluster_t *cluster); -} /* command */ -} /* refrigerator_alarm */ - } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index b58a3e87a..412102309 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -1067,6 +1067,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); + descriptor::create(endpoint, CLUSTER_FLAG_SERVER); temperature_control::create(endpoint, &(config->temperature_control), CLUSTER_FLAG_SERVER, ESP_MATTER_NONE_FEATURE_ID); return endpoint; @@ -1099,6 +1100,8 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); + descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + return endpoint; } } /** refrigerator **/ diff --git a/components/esp_matter/esp_matter_endpoint.h b/components/esp_matter/esp_matter_endpoint.h index f3510dde7..544014d82 100644 --- a/components/esp_matter/esp_matter_endpoint.h +++ b/components/esp_matter/esp_matter_endpoint.h @@ -67,13 +67,10 @@ #define ESP_MATTER_HUMIDITY_SENSOR_DEVICE_TYPE_VERSION 2 #define ESP_MATTER_ROOM_AIR_CONDITIONER_DEVICE_TYPE_ID 0x0072 #define ESP_MATTER_ROOM_AIR_CONDITIONER_DEVICE_TYPE_VERSION 1 - #define ESP_MATTER_REFRIGERATOR_DEVICE_TYPE_ID 0x0070 #define ESP_MATTER_REFRIGERATOR_DEVICE_TYPE_VERSION 1 #define ESP_MATTER_TEMPERATURE_CONTROLLED_CABINET_DEVICE_TYPE_ID 0x0071 #define ESP_MATTER_TEMPERATURE_CONTROLLED_CABINET_DEVICE_TYPE_VERSION 1 -#define ESP_MATTER_ROOM_AIR_CONDITIONER_DEVICE_TYPE_ID 0x0072 -#define ESP_MATTER_ROOM_AIR_CONDITIONER_DEVICE_TYPE_VERSION 1 #define ESP_MATTER_FAN_DEVICE_TYPE_ID 0x002B #define ESP_MATTER_FAN_DEVICE_TYPE_VERSION 1 diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 736b26943..e7f98c97e 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -1183,7 +1183,7 @@ esp_err_t add(cluster_t *cluster) } /* feature */ } /* software_diagnostics */ -======= + namespace temperature_control { namespace feature { namespace temperature_number { @@ -1199,17 +1199,22 @@ esp_err_t add(cluster_t *cluster, config_t *config) ESP_LOGE(TAG, "Cluster cannot be NULL"); return ESP_ERR_INVALID_ARG; } - update_feature_map(cluster, get_id()); - /* Attributes not managed internally */ - attribute::create_temperature_setpoint(cluster, config->temp_setpoint); - attribute::create_min_temperature(cluster, config->min_temperature); - attribute::create_max_temperature(cluster, config->max_temperature); - attribute::create_step(cluster, config->step); + uint32_t temp_level_feature_map = feature::temperature_level::get_id(); + if((get_feature_map_value(cluster) & temp_level_feature_map) != temp_level_feature_map) { + update_feature_map(cluster, get_id()); + + /* Attributes not managed internally */ + attribute::create_temperature_setpoint(cluster, config->temp_setpoint); + attribute::create_min_temperature(cluster, config->min_temperature); + attribute::create_max_temperature(cluster, config->max_temperature); + } else { + ESP_LOGE(TAG, "Cluster shall support either TemperatureNumber or TemperatureLevel feature"); + return ESP_ERR_NOT_SUPPORTED; + } return ESP_OK; } - } /* temperature_number */ namespace temperature_level { @@ -1225,15 +1230,54 @@ esp_err_t add(cluster_t *cluster, config_t *config) ESP_LOGE(TAG, "Cluster cannot be NULL"); return ESP_ERR_INVALID_ARG; } - update_feature_map(cluster, get_id()); - /* Attributes not managed internally */ - attribute::create_current_temperature_level_index(cluster, config->current_temp_level_ind); + uint32_t temp_number_feature_map = feature::temperature_number::get_id(); + if((get_feature_map_value(cluster) & temp_number_feature_map) != temp_number_feature_map) { + update_feature_map(cluster, get_id()); + + /* Attributes managed internally */ + attribute::create_supported_temperature_levels(cluster, NULL, 0, 0); + + /* Attributes not managed internally */ + attribute::create_selected_temperature_level(cluster, config->selected_temp_level); + } else { + ESP_LOGE(TAG, "Cluster shall support either TemperatureLevel or TemperatureNumber feature"); + return ESP_ERR_NOT_SUPPORTED; + } + + return ESP_OK; +} +} /* temperature_level */ + +namespace temperature_step { + +uint32_t get_id() +{ + return (uint32_t)TemperatureControl::Feature::kTemperatureStep; +} + +esp_err_t add(cluster_t *cluster, config_t *config) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + + uint32_t temp_number_feature_map = feature::temperature_number::get_id(); + if((get_feature_map_value(cluster) & temp_number_feature_map) == temp_number_feature_map) { + update_feature_map(cluster, get_id()); + + /* Attributes not managed internally */ + attribute::create_step(cluster, config->step); + } else { + ESP_LOGE(TAG, "Cluster shall support TemperatureNumber feature"); + return ESP_ERR_NOT_SUPPORTED; + } return ESP_OK; } +} /* temperature_step */ -} /* temperature_level */ } /* feature */ } /* temperature_control */ diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index 3d378496d..59cc80bb5 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -524,14 +524,15 @@ esp_err_t add(cluster_t *cluster); namespace temperature_control { namespace feature { -namespace temperature_number { +// TemperatureNumber and TemperatureLevel features are mutually exclusive, +// only one of them shall present. +namespace temperature_number { typedef struct config { int16_t temp_setpoint; int16_t min_temperature; int16_t max_temperature; - int16_t step; - config() : temp_setpoint(2), min_temperature(0), max_temperature(10), step(1) {} + config() : temp_setpoint(1), min_temperature(0), max_temperature(10) {} } config_t; uint32_t get_id(); @@ -539,17 +540,32 @@ esp_err_t add(cluster_t *cluster, config_t *config); } /* temperature_number */ +// TemperatureNumber and TemperatureLevel features are mutually exclusive, +// only one of them shall present. namespace temperature_level { - typedef struct config { - uint8_t current_temp_level_ind; - config() : current_temp_level_ind(1) {} + uint8_t selected_temp_level; + config() : selected_temp_level(1) {} } config_t; uint32_t get_id(); esp_err_t add(cluster_t *cluster, config_t *config); } /* temperature_level */ + +// TemperatureStep feature have conformance of TemperatureNumber feature, +// inorder to support TemperatureStep cluster shall support TemperatureNumber. +namespace temperature_step { +typedef struct config { + int16_t step; + config() : step(1) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* temperature_step */ + } /* feature */ } /* temperature_control */ diff --git a/components/esp_matter/zap_common/app/PluginApplicationCallbacks.h b/components/esp_matter/zap_common/app/PluginApplicationCallbacks.h index 1a9b6df49..989e76208 100644 --- a/components/esp_matter/zap_common/app/PluginApplicationCallbacks.h +++ b/components/esp_matter/zap_common/app/PluginApplicationCallbacks.h @@ -69,11 +69,13 @@ void MatterPowerSourcePluginServerInitCallback(); void MatterPowerSourceConfigurationPluginServerInitCallback(); void MatterPressureMeasurementPluginServerInitCallback(); void MatterPumpConfigurationAndControlPluginServerInitCallback(); +void MatterRefrigeratorAlarmPluginServerInitCallback(); void MatterRelativeHumidityMeasurementPluginServerInitCallback(); void MatterScenesPluginServerInitCallback(); void MatterSoftwareDiagnosticsPluginServerInitCallback(); void MatterSwitchPluginServerInitCallback(); void MatterTargetNavigatorPluginServerInitCallback(); +void MatterTemperatureControlPluginServerInitCallback(); void MatterTemperatureMeasurementPluginServerInitCallback(); void MatterThermostatPluginServerInitCallback(); void MatterThermostatUserInterfaceConfigurationPluginServerInitCallback(); diff --git a/components/esp_matter/zap_common/zap-generated/gen_config.h b/components/esp_matter/zap_common/zap-generated/gen_config.h index c663ab650..6272a2746 100644 --- a/components/esp_matter/zap_common/zap-generated/gen_config.h +++ b/components/esp_matter/zap_common/zap-generated/gen_config.h @@ -192,5 +192,9 @@ #define EMBER_AF_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT FIXED_ENDPOINT_COUNT // used in door lock #define EMBER_AF_FAN_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT FIXED_ENDPOINT_COUNT // used in fan control + +#define EMBER_AF_MODE_SELECT_CLUSTER_SERVER_ENDPOINT_COUNT CONFIG_ESP_MATTER_MODE_SELECT_CLUSTER_ENDPOINT_COUNT // used in mode select +#define EMBER_AF_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT CONFIG_ESP_MATTER_TEMPERATURE_CONTROL_CLUSTER_ENDPOINT_COUNT // used in temperature control + #define MATTER_SCENES_TABLE_SIZE CONFIG_ESP_MATTER_SCENES_TABLE_SIZE // used in scenes // TODO: check this again diff --git a/examples/.build-rules.yml b/examples/.build-rules.yml index cbbf2b622..986286d37 100644 --- a/examples/.build-rules.yml +++ b/examples/.build-rules.yml @@ -53,3 +53,9 @@ examples/room_air_conditioner: - if: IDF_TARGET in ["esp32", "esp32c3", "esp32c2", "esp32c6", "esp32h2"] temporary: true reason: the other targets are not tested yet + +examples/refrigerator: + enable: + - if: IDF_TARGET in ["esp32", "esp32c3", "esp32c2", "esp32c6", "esp32h2"] + temporary: true + reason: the other targets are not tested yet diff --git a/examples/refrigerator/README.md b/examples/refrigerator/README.md index b695e64c5..6b517129d 100644 --- a/examples/refrigerator/README.md +++ b/examples/refrigerator/README.md @@ -1,9 +1,7 @@ -# Light Switch +# Refrigerator -This example creates an On/Off Light Switch device using the data model. - -It creates the On/Off client and other devices can be bound to the -switch and then controlled from the switch. +This example creates a Refrigerator device using the ESP +Matter data model. See the [docs](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html) for more information about building and flashing the firmware. @@ -13,222 +11,12 @@ No additional setup is required. ## 2. Post Commissioning Setup -### 2.1 Bind light to switch +No additional setup is required. -Using the chip-tool, commission 2 devices, the switch and a light. -If you are having trouble, try commissioning them one at a time (by powering off the other device) as -the default discriminator and passcode are same for both of them. -Then use the below commands to bind the light to the switch. +## 3. TemperatureLevel feature. -For the commands below: +Set the config `ESP_MATTER_TEMPERATURE_CONTROL_CLUSTER_ENDPOINT_COUNT` (default 1) to the number of endpoints on which +you are using temperature control cluster with temperature level feature from menuconfig (Component config -> ESP Matter). -- Node Id of switch used during commissioning is 0x7283 (29315 in decimal) -- Node Id of light used during commissioning is 0x5164 (20836 in decimal) -- Cluster Id for OnOff cluster is 6 -- Binding cluster is currently present on endpoint 1 on the switch - -Update the light's acl attribute to add the entry of remote device -(switch) in the access control list: -``` -accesscontrol write acl '[{"privilege": 5, "authMode": 2, "subjects": [ 112233, 29315 ], "targets": null}]' 0x5164 0x0 -``` - -Update the switch's binding attribute to add the entry of remote device -(light) in the binding table: -``` - binding write binding '[{"node":20836, "endpoint":1, "cluster":6}]' 0x7283 0x1 -``` - -### 2.2 Bind a group to switch - -Using the chip-tool, commission 3 (or more) devices, 1 switch and 2 (or more) lights. -If you are having trouble, try commissioning them one at a time (by powering off the other device) as -the default discriminator and passcode are same for both of them. -Then use the below commands to add the devices to the group and bind the group to the switch. - -For the commands below: -- Node Id of switch used during commissioning is 0x7283 (29315 in decimal) -- Node Id of light1 used during commissioning is 0x5164 (20836 in decimal) -- Node Id of light2 used during commissioning is 0x5163 (20835 in decimal) -- Group Id for the devices is 257 which is assigned by chip-tool when using the testing-group command -- Binding cluster is currently present on endpoint 1 on the switch - -Send the testing-group command to the switch and lights. -This command will write the acl attributes of the nodes and add the endpoint 1 of the nodes to the group 257. -``` - tests TestGroupDemoConfig --nodeId 29315 - tests TestGroupDemoConfig --nodeId 20836 - tests TestGroupDemoConfig --nodeId 20835 -``` - -Update the switch's binding attribute to add the entry of group in the binding table: -``` - binding write binding '[{"group": 257}]' 0x7283 0x1 -``` - -### 2.3 Device console - -Switch specific console commands: - -- Send command to the specified device on the specified cluster: - (The IDs are in hex): - ``` - matter esp client invoke - ``` - - - Example: Off: - ``` - matter esp client invoke 0x1 0x5164 0x1 0x6 0x0 - ``` - - - Example: On: - ``` - matter esp client invoke 0x1 0x5164 0x1 0x6 0x1 - ``` - - - Example: Toggle: - ``` - matter esp client invoke 0x1 0x5164 0x1 0x6 0x2 - ``` - - - Example: Identify 0x78: - ``` - matter esp client invoke 0x1 0x5164 0x1 0x3 0x78 - ``` - -- Send command to the specified group on the specified cluster: - (The IDs are in hex): - ``` - matter esp client invoke-group - ``` - - - Example: Off: - ``` - matter esp client invoke-group 0x1 0x101 0x6 0x0 - ``` - - - Example: On: - ``` - matter esp client invoke-group 0x1 0x101 0x6 0x1 - ``` - - - Example: Toggle: - ``` - matter esp client invoke-group 0x1 0x101 0x6 0x2 - - ``` - - Example: Identify 0x78: - ``` - matter esp client invoke-group 0x1 0x101 0x3 0x78 - - ``` - -- Send command to all the bound devices on the specified cluster: - (The IDs are in hex): - ``` - matter esp bound invoke - ``` - - - Example: Off: - ``` - matter esp bound invoke 0x1 0x6 0x0 - ``` - - - Example: On: - ``` - matter esp bound invoke 0x1 0x6 0x1 - ``` - - - Example: Toggle: - ``` - matter esp bound invoke 0x1 0x6 0x2 - ``` - - - Example: Identify 0x78: - ``` - matter esp bound invoke 0x1 0x3 0x78 - ``` - -- Send command to all the bound groups on the specified cluster: - (The IDs are in hex): - ``` - matter esp bound invoke-group - ``` - - - Example: Off: - ``` - matter esp bound invoke-group 0x1 0x6 0x0 - ``` - - - Example: On: - ``` - matter esp bound invoke-group 0x1 0x6 0x1 - ``` - - - Example: Toggle: - ``` - matter esp bound invoke-group 0x1 0x6 0x2 - ``` - - - Example: Identify 0x78: - ``` - matter esp bound invoke-group 0x1 0x3 0x78 - ``` - -## 3. Device Performance - -### 3.1 Memory usage - -The following is the Memory and Flash Usage. - -- `Bootup` == Device just finished booting up. Device is not - commissionined or connected to wifi yet. -- `After Commissioning` == Device is conneted to wifi and is also - commissioned and is rebooted. -- device used: esp32c3_devkit_m -- tested on: - [6a244a7](https://github.com/espressif/esp-matter/commit/6a244a7b1e5c70b0aa1bf57254f19718b0755d95) - (2022-06-16) - -| | Bootup | After Commissioning | -|:- |:-: |:-: | -|**Free Internal Memory** |114KB |111KB | - -**Flash Usage**: Firmware binary size: 1.25MB - -This should give you a good idea about the amount of free memory that is -available for you to run your application's code. - -Applications that do not require BLE post commissioning, can disable it using app_ble_disable() once commissioning is complete. It is not done explicitly because of a known issue with esp32c3 and will be fixed with the next IDF release (v4.4.2). - -## A2 Appendix FAQs - -### A2.1 Binding Failed - -My light is not getting bound to my switch: - -- Make sure the light's acl is updated. You can read it again to make - sure it is correct: `accesscontrol read acl 0x5164 0x0`. -- If you are still facing issues, reproduce the issue on the default - example for the device and then raise an [issue](https://github.com/espressif/esp-matter/issues). - Make sure to share these: - - The complete device logs for both the devices taken over UART. - - The complete chip-tool logs. - - The esp-matter and esp-idf branch you are using. - -### A2.2 Command Send Failed - -I cannot send commands to the light from my switch: - -- Make sure the binding command was a success. -- Make sure you are passing the local endpoint_id, and not the remote - endpoint_id, to the cluster_update() API. -- If using device console, make sure you are running the - `bound invoke` command and not the `client invoke` command. The - client commands are for devices which have not been bound. -- If you are still facing issues, reproduce the issue on the default - example for the device and then raise an [issue](https://github.com/espressif/esp-matter/issues). - Make sure to share these: - - The complete device logs for both the devices taken over UART. - - The complete chip-tool logs. - - The esp-matter and esp-idf branch you are using. +Note: By default `SupportedTemperatureLevels` attribute is added for endpoint 1 only. If you want to add for more endpoints, +please add it in `connectedhomeip/connectedhomeip/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp` diff --git a/examples/refrigerator/main/CMakeLists.txt b/examples/refrigerator/main/CMakeLists.txt index c95dff36a..890486731 100644 --- a/examples/refrigerator/main/CMakeLists.txt +++ b/examples/refrigerator/main/CMakeLists.txt @@ -1,6 +1,24 @@ +set(SRC_DIRS_LIST "." + "${MATTER_SDK_PATH}/examples/all-clusters-app/all-clusters-common/src" + ) + set(PRIV_REQUIRES_LIST device esp_matter esp_matter_console app_reset) -idf_component_register(SRC_DIRS "." +set(INCLUDE_DIRS_LIST "${MATTER_SDK_PATH}/examples/all-clusters-app/all-clusters-common/include" ) + +set(exclude_srcs_list "${MATTER_SDK_PATH}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp" + "${MATTER_SDK_PATH}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp" + "${MATTER_SDK_PATH}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp" + "${MATTER_SDK_PATH}/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp" + "${MATTER_SDK_PATH}/examples/all-clusters-app/all-clusters-common/src/operational-state-delegates.cpp" + "${MATTER_SDK_PATH}/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-instances.cpp" + "${MATTER_SDK_PATH}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp" + "${MATTER_SDK_PATH}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp" + ) + +idf_component_register(SRC_DIRS ${SRC_DIRS_LIST} + EXCLUDE_SRCS ${exclude_srcs_list} + INCLUDE_DIRS ${INCLUDE_DIRS_LIST} PRIV_INCLUDE_DIRS "." PRIV_REQUIRES ${PRIV_REQUIRES_LIST}) diff --git a/examples/refrigerator/main/app_driver.cpp b/examples/refrigerator/main/app_driver.cpp index f98a1f9b4..47f377ed6 100644 --- a/examples/refrigerator/main/app_driver.cpp +++ b/examples/refrigerator/main/app_driver.cpp @@ -6,29 +6,12 @@ CONDITIONS OF ANY KIND, either express or implied. */ -#include -#include -#include - #include -#include -#include -#include #include #include -using chip::kInvalidClusterId; -static constexpr chip::CommandId kInvalidCommandId = 0xFFFF'FFFF; - -using namespace chip::app::Clusters; -using namespace esp_matter; -using namespace esp_matter::cluster; - -static const char *TAG = "app_driver"; -extern uint16_t switch_endpoint_id; - -app_driver_handle_t app_driver_refrigerator_init() +app_driver_handle_t app_driver_button_init() { /* Initialize button */ button_config_t config = button_driver_get_config(); diff --git a/examples/refrigerator/main/app_main.cpp b/examples/refrigerator/main/app_main.cpp index 73bed3d31..a0be34bda 100644 --- a/examples/refrigerator/main/app_main.cpp +++ b/examples/refrigerator/main/app_main.cpp @@ -12,19 +12,20 @@ #include #include -#include #include #include +#include static const char *TAG = "app_main"; -uint16_t refrigerator_endpoint_id = 0; -uint16_t temp_ctrl_endpoint_id = 0; +static uint16_t refrigerator_endpoint_id = 0; +static uint16_t temp_ctrl_endpoint_id = 0; using namespace esp_matter; using namespace esp_matter::attribute; using namespace esp_matter::endpoint; +static chip::app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate; static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) { switch (event->Type) { @@ -86,18 +87,20 @@ extern "C" void app_main() nvs_flash_init(); /* Initialize driver */ - app_driver_handle_t switch_handle = app_driver_refrigerator_init(); - app_reset_button_register(switch_handle); + app_driver_handle_t reset_handle = app_driver_button_init(); + app_reset_button_register(reset_handle); /* Create a Matter node and add the mandatory Root Node device type on endpoint 0 */ node::config_t node_config; node_t *node = node::create(&node_config, app_attribute_update_cb, app_identification_cb); + // "Identify", "Groups", "Scenes", "Refrigerator Mode Select" and "Refrigerator Alarm" are optional cluster for refrigerator device type so we are not adding them by default. refrigerator::config_t refrigerator_config; - endpoint_t *endpoint = refrigerator::create(node, &refrigerator_config, ENDPOINT_FLAG_NONE, switch_handle); + endpoint_t *endpoint = refrigerator::create(node, &refrigerator_config, ENDPOINT_FLAG_NONE, NULL); + // "Temperature Measurement", "Refrigerator and Temperature Controlled Cabinet Mode Select" are optional cluster for temperature_controlled_cabinet device type so we are not adding them by default. temperature_controlled_cabinet::config_t temperature_controlled_cabinet_config; - endpoint_t *endpoint1 = temperature_controlled_cabinet::create(node, &temperature_controlled_cabinet_config, ENDPOINT_FLAG_NONE, switch_handle); + endpoint_t *endpoint1 = temperature_controlled_cabinet::create(node, &temperature_controlled_cabinet_config, ENDPOINT_FLAG_NONE, NULL); /* These node and endpoint handles can be used to create/add other endpoints and clusters. */ if (!node || !endpoint || !endpoint1) { @@ -105,6 +108,7 @@ extern "C" void app_main() } esp_matter::cluster_t *cluster = esp_matter::cluster::get(endpoint1, chip::app::Clusters::TemperatureControl::Id); + // Atlest one of temperature_number and temperature_level feature is mandatory. cluster::temperature_control::feature::temperature_number::config_t temperature_number_config; cluster::temperature_control::feature::temperature_number::add(cluster, &temperature_number_config); @@ -113,11 +117,18 @@ extern "C" void app_main() temp_ctrl_endpoint_id = endpoint::get_id(endpoint1); ESP_LOGI(TAG, "Temperature controlled cabinet created with endpoint_id %d", temp_ctrl_endpoint_id); + + err = set_parent_endpoint(endpoint1, endpoint); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set parent %d", err); + } + /* Matter start */ err = esp_matter::start(app_event_cb); if (err != ESP_OK) { ESP_LOGE(TAG, "Matter start failed: %d", err); } + chip::app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); #if CONFIG_ENABLE_CHIP_SHELL esp_matter::console::diagnostics_register_commands(); diff --git a/examples/refrigerator/main/app_priv.h b/examples/refrigerator/main/app_priv.h index ff9191eaa..18e70d1c8 100644 --- a/examples/refrigerator/main/app_priv.h +++ b/examples/refrigerator/main/app_priv.h @@ -13,11 +13,11 @@ typedef void *app_driver_handle_t; -/** Initialize the switch driver +/** Initialize the button driver * * This initializes the switch driver associated with the selected board. * * @return Handle on success. * @return NULL in case of failure. */ -app_driver_handle_t app_driver_refrigerator_init(); +app_driver_handle_t app_driver_button_init(); diff --git a/examples/refrigerator/main/zap-generated/empty_file.cpp b/examples/refrigerator/main/zap-generated/empty_file.cpp deleted file mode 100644 index d47ae50bd..000000000 --- a/examples/refrigerator/main/zap-generated/empty_file.cpp +++ /dev/null @@ -1,8 +0,0 @@ -/** Empty File - * - * This file is just present to prevent cmake warnings about: - * No source files found for SRC_DIRS entry '/Users/chirag/work/gitlab/esp-matter/examples//main/zap-generated'. - * - * We need to keep the path in SRC_DIRS to be compatible with the zap data model. - */ - \ No newline at end of file diff --git a/examples/refrigerator/main/zap-generated/endpoint_config.h b/examples/refrigerator/main/zap-generated/endpoint_config.h deleted file mode 100644 index caafa958e..000000000 --- a/examples/refrigerator/main/zap-generated/endpoint_config.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// THIS FILE IS GENERATED BY ZAP - -// Prevent multiple inclusion -#pragma once - -#include -#include - -#define GENERATED_ATTRIBUTES \ - {} - -#define GENERATED_CLUSTERS \ - {} - -#define GENERATED_ENDPOINT_TYPES \ - {} - -#define ZAP_FIXED_ENDPOINT_DATA_VERSION_COUNT 0 - -// Largest attribute size is needed for various buffers -#define ATTRIBUTE_LARGEST (259) - -static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE, "ATTRIBUTE_LARGEST larger than expected"); - -// Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (0) - -// Number of fixed endpoints -#define FIXED_ENDPOINT_COUNT (0) -#ifdef CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT -#undef CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT -#endif -#define CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT CONFIG_ESP_MATTER_MAX_DYNAMIC_ENDPOINT_COUNT - -// Array of endpoints that are supported, the data inside -// the array is the endpoint number. -#define FIXED_ENDPOINT_ARRAY \ - {0} - -// Array of profile ids -#define FIXED_PROFILE_IDS \ - {0} - -// Array of device types -#define FIXED_DEVICE_TYPES \ - {0} - -// Array of device type offsets -#define FIXED_DEVICE_TYPE_OFFSETS \ - {0} - -// Array of device type lengths -#define FIXED_DEVICE_TYPE_LENGTHS \ - {0} - -// Array of endpoint types supported on each endpoint -#define FIXED_ENDPOINT_TYPES \ - {0} - -// Array of networks supported on each endpoint -#define FIXED_NETWORKS \ - {0} diff --git a/examples/refrigerator/ref.patch b/examples/refrigerator/ref.patch deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/refrigerator/sdkconfig.defaults b/examples/refrigerator/sdkconfig.defaults index b7b3c12b2..8a0a5f442 100644 --- a/examples/refrigerator/sdkconfig.defaults +++ b/examples/refrigerator/sdkconfig.defaults @@ -24,6 +24,9 @@ CONFIG_PARTITION_TABLE_OFFSET=0xC000 # Enable chip shell CONFIG_ENABLE_CHIP_SHELL=y +# Endpoint count for temperature control cluster +CONFIG_ESP_MATTER_TEMPERATURE_CONTROL_CLUSTER_ENDPOINT_COUNT=1 + #enable lwIP route hooks CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y diff --git a/examples/refrigerator/sdkconfig.defaults.esp32s2 b/examples/refrigerator/sdkconfig.defaults.esp32s2 deleted file mode 100644 index 1d221cfc7..000000000 --- a/examples/refrigerator/sdkconfig.defaults.esp32s2 +++ /dev/null @@ -1,28 +0,0 @@ -# Default to 921600 baud when flashing and monitoring device -CONFIG_ESPTOOLPY_BAUD_921600B=y -CONFIG_ESPTOOLPY_BAUD=921600 -CONFIG_ESPTOOLPY_COMPRESSED=y -CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y -CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 -CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y - -#enable lwip ipv6 autoconfig -CONFIG_LWIP_IPV6_AUTOCONFIG=y - -# Use a custom partition table -CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" - -# Enable chip shell -CONFIG_ENABLE_CHIP_SHELL=y - -#enable lwIP route hooks -CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y -CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y - -# Button -CONFIG_BUTTON_PERIOD_TIME_MS=20 -CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000 - -# Disable BLE -CONFIG_ENABLE_CHIPOBLE=n