diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index d154b5992..5bc1c565e 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -2749,6 +2749,53 @@ attribute_t *create_operational_error(cluster_t *cluster, uint8_t value) } /* attribute */ } /* operational_state */ +namespace laundry_washer_mode { +namespace attribute { + +attribute_t *create_supported_modes(cluster_t *cluster, const uint8_t * value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, LaundryWasherMode::Attributes::SupportedModes::Id, ATTRIBUTE_FLAG_NONE, esp_matter_array((uint8_t*)value, length, count)); +} + +attribute_t *create_current_mode(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, LaundryWasherMode::Attributes::CurrentMode::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint8(value)); +} + +} /* attribute */ +} /* laundry_washer_mode */ + +namespace laundry_washer_controls { +namespace attribute { + +attribute_t *create_spin_speeds(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, LaundryWasherControls::Attributes::SpinSpeeds::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); +} + +attribute_t *create_spin_speed_current(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, LaundryWasherControls::Attributes::SpinSpeedCurrent::Id, + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_WRITABLE, + esp_matter_nullable_uint8(value)); + +} + +attribute_t *create_number_of_rinses(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, LaundryWasherControls::Attributes::NumberOfRinses::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +attribute_t *create_supported_rinses(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, LaundryWasherControls::Attributes::SupportedRinses::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_array(value, length, count)); +} +} /* attribute */ +} /* laundry_washer_controls */ + namespace dish_washer_mode { namespace attribute { diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 8a0c3dd1b..0029868be 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -634,6 +634,22 @@ attribute_t *create_supported_operating_modes(cluster_t *cluster, uint16_t value } /* attribute */ } /* door_lock */ +namespace laundry_washer_mode { +namespace attribute { +attribute_t *create_supported_modes(cluster_t *cluster, const uint8_t * value, uint16_t length, uint16_t count); +attribute_t *create_current_mode(cluster_t *cluster, uint8_t value); +} /* attribute */ +} /* laundry_washer_mode */ + +namespace laundry_washer_controls { +namespace attribute { +attribute_t *create_spin_speeds(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); +attribute_t *create_spin_speed_current(cluster_t *cluster, nullable value); +attribute_t *create_number_of_rinses(cluster_t *cluster, uint8_t value); +attribute_t *create_supported_rinses(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); +} /* attribute */ +} /* laundry_washer_controls */ + namespace dish_washer_mode { namespace attribute { attribute_t *create_supported_modes(cluster_t *cluster, const uint8_t * value, uint16_t length, uint16_t count); diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index 94ea01aab..0c8149429 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -1965,6 +1965,83 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } } /* operational_state */ +namespace laundry_washer_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, LaundryWasherMode::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + + if (flags & CLUSTER_FLAG_SERVER) { + add_function_list(cluster, function_list, function_flags); + } + if (flags & CLUSTER_FLAG_CLIENT) { + create_default_binding_cluster(endpoint); + } + + if (flags & CLUSTER_FLAG_SERVER) { + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + global::attribute::create_event_list(cluster, NULL, 0, 0); + + + /* Attributes not managed internally */ + if (config) { + global::attribute::create_cluster_revision(cluster, config->cluster_revision); + attribute::create_current_mode(cluster, config->current_mode); + } else { + ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); + } + } + + return cluster; +} +} /* laundry_washer_mode */ + +namespace laundry_washer_controls { + +const function_generic_t function_list[] = { + (function_generic_t)MatterLaundryWasherControlsClusterServerPreAttributeChangedCallback, +}; +const int function_flags = CLUSTER_FLAG_PRE_ATTRIBUTE_CHANGED_FUNCTION; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) +{ + cluster_t *cluster = cluster::create(endpoint, LaundryWasherControls::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + + if (flags & CLUSTER_FLAG_SERVER) { + add_function_list(cluster, function_list, function_flags); + } + if (flags & CLUSTER_FLAG_CLIENT) { + create_default_binding_cluster(endpoint); + } + + if (flags & CLUSTER_FLAG_SERVER) { + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); + global::attribute::create_event_list(cluster, NULL, 0, 0); + + /* Attributes not managed internally */ + if (config) { + global::attribute::create_cluster_revision(cluster, config->cluster_revision); + } else { + ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); + } + } + + return cluster; +} +} /* laundry_washer_controls */ + namespace dish_washer_mode { 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 86522ee22..7698d691d 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -477,6 +477,25 @@ typedef struct config { cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); } /* operational_state */ +namespace laundry_washer_mode { +typedef struct config { + uint16_t cluster_revision; + uint8_t current_mode; + config() : cluster_revision(1), current_mode(0) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); +} /* laundry_washer_mode */ + +namespace laundry_washer_controls { +typedef struct config { + uint16_t cluster_revision; + config() : cluster_revision(1) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); +} /* laundry_washer_controls */ + namespace dish_washer_mode { 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 a2a4d8be3..29f3d1461 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -2112,6 +2112,16 @@ command_t *create_get_weekly_schedule_response(cluster_t *cluster) } /* command */ } /* thermostat */ +namespace laundry_washer_mode { +namespace command { +command_t *create_change_to_mode(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, LaundryWasherMode::Commands::ChangeToMode::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +} /* command */ +} /* laundry_washer_mode */ + namespace dish_washer_mode { namespace command { command_t *create_change_to_mode(cluster_t *cluster) diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 8737b340c..95db6a8d9 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -264,6 +264,12 @@ command_t *create_get_weekly_schedule_response(cluster_t *cluster); } /* command */ } /* thermostat */ +namespace laundry_washer_mode { +namespace command { +command_t *create_change_to_mode(cluster_t *cluster); +} /* command */ +} /* laundry_washer_mode */ + namespace dish_washer_mode { namespace command { command_t *create_change_to_mode(cluster_t *cluster); diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index 8a5b025f4..792a36e8c 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -641,6 +641,24 @@ endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_dat 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 add device type id:%" PRIu32 ", err: %d", get_device_type_id(), err); + return err; + } + + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); + + return ESP_OK; +} +} /* aggregator */ + namespace air_quality_sensor { uint32_t get_device_type_id() { @@ -754,6 +772,24 @@ esp_err_t add(endpoint_t *endpoint, config_t *config) } } /* dish_washer */ +namespace laundry_washer { +uint32_t get_device_type_id() +{ + return ESP_MATTER_LAUNDRY_WASHER_DEVICE_TYPE_ID; +} + +uint8_t get_device_type_version() +{ + return ESP_MATTER_LAUNDRY_WASHER_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) { @@ -767,10 +803,11 @@ esp_err_t add(endpoint_t *endpoint, config_t *config) } descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); + operational_state::create(endpoint, &(config->operational_state), CLUSTER_FLAG_SERVER); return ESP_OK; } -} /* aggregator */ +} /* laundry_washer */ namespace bridged_node { uint32_t get_device_type_id() diff --git a/components/esp_matter/esp_matter_endpoint.h b/components/esp_matter/esp_matter_endpoint.h index 41a1aaca4..2f667c2b5 100644 --- a/components/esp_matter/esp_matter_endpoint.h +++ b/components/esp_matter/esp_matter_endpoint.h @@ -71,6 +71,8 @@ #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_LAUNDRY_WASHER_DEVICE_TYPE_ID 0x0073 +#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 @@ -351,6 +353,17 @@ 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); } /* dish_washer */ +namespace laundry_washer { +typedef struct config { + cluster::descriptor::config_t descriptor; + cluster::operational_state::config_t operational_state; +} 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); +} /* laundry_washer */ + namespace aggregator { typedef struct config { cluster::descriptor::config_t descriptor; diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 245d5a003..9ffc3c1d5 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -2533,6 +2533,58 @@ esp_err_t add(cluster_t *cluster) } /* feature */ } /* activated_carbon_filter_monitoring */ +namespace laundry_washer_controls { +namespace feature { + +namespace spin { + +uint32_t get_id() +{ + return (uint32_t)LaundryWasherControls::Feature::kSpin; +} + +esp_err_t add(cluster_t *cluster, config_t *config) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + + update_feature_map(cluster, get_id()); + + attribute::create_spin_speed_current(cluster, config->spin_speed_current); + + return ESP_OK; +} + +} /* spin */ + +namespace rinse { + +uint32_t get_id() +{ + return (uint32_t)LaundryWasherControls::Feature::kRinse; +} + +esp_err_t add(cluster_t *cluster, config_t *config) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + + update_feature_map(cluster, get_id()); + + attribute::create_number_of_rinses(cluster, config->number_of_rinses); + + return ESP_OK; +} + +} /* rinse */ + +} /* feature */ +} /* laundry_washer_controls */ + namespace thermostat { namespace feature { diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index 332189e84..20d4c0c90 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -1227,6 +1227,36 @@ esp_err_t add(cluster_t *cluster); } /* feature */ } /* activated_carbon_filter_monitoring */ +namespace laundry_washer_controls { +namespace feature { + +namespace spin { + +typedef struct config { + uint8_t spin_speed_current; + config() : spin_speed_current(0) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* spin */ + +namespace rinse { + +typedef struct config { + uint8_t number_of_rinses; + config() : number_of_rinses(1) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* rinse */ + +} /* feature */ +} /* laundry_washer_controls */ + namespace switch_cluster { namespace feature {