diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index 1d16c2047..438514383 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -1235,6 +1235,48 @@ attribute_t *create_local_temperature(cluster_t *cluster, nullable valu esp_matter_nullable_int16(value)); } +attribute_t *create_occupancy(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::Occupancy::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_enum8(value)); +} + +attribute_t *create_abs_min_heat_setpoint_limit(cluster_t *cluster, int16_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::AbsMinHeatSetpointLimit::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_int16(value)); +} + +attribute_t *create_abs_max_heat_setpoint_limit(cluster_t *cluster, int16_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::AbsMaxHeatSetpointLimit::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_int16(value)); +} + +attribute_t *create_abs_min_cool_setpoint_limit(cluster_t *cluster, int16_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::AbsMinCoolSetpointLimit::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_int16(value)); +} + +attribute_t *create_abs_max_cool_setpoint_limit(cluster_t *cluster, int16_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::AbsMaxCoolSetpointLimit::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_int16(value)); +} + +attribute_t *create_pi_cooling_demand(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::PICoolingDemand::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + +attribute_t *create_pi_heating_demand(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::PIHeatingDemand::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_uint8(value)); +} + attribute_t *create_occupied_cooling_setpoint(cluster_t *cluster, int16_t value) { return esp_matter::attribute::create(cluster, Thermostat::Attributes::OccupiedCoolingSetpoint::Id, @@ -1247,6 +1289,48 @@ attribute_t *create_occupied_heating_setpoint(cluster_t *cluster, int16_t value) ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_int16(value)); } +attribute_t *create_unoccupied_cooling_setpoint(cluster_t *cluster, int16_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::UnoccupiedCoolingSetpoint::Id, + ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_int16(value)); +} + +attribute_t *create_unoccupied_heating_setpoint(cluster_t *cluster, int16_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::UnoccupiedHeatingSetpoint::Id, + ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_int16(value)); +} + +attribute_t *create_min_heat_setpoint_limit(cluster_t *cluster, int16_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::MinHeatSetpointLimit::Id, + ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_int16(value)); +} + +attribute_t *create_max_heat_setpoint_limit(cluster_t *cluster, int16_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::MaxHeatSetpointLimit::Id, + ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_int16(value)); +} + +attribute_t *create_min_cool_setpoint_limit(cluster_t *cluster, int16_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::MinCoolSetpointLimit::Id, + ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_int16(value)); +} + +attribute_t *create_max_cool_setpoint_limit(cluster_t *cluster, int16_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::MaxCoolSetpointLimit::Id, + ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_int16(value)); +} + +attribute_t *create_min_setpoint_dead_band(cluster_t *cluster, int8_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::MinSetpointDeadBand::Id, + ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, esp_matter_int8(value)); +} + attribute_t *create_control_sequence_of_operation(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max) { attribute_t *attribute = esp_matter::attribute::create(cluster, @@ -1274,6 +1358,66 @@ attribute_t *create_system_mode(cluster_t *cluster, uint8_t value, uint8_t min, return attribute; } +attribute_t *create_thermostat_running_mode(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::ThermostatRunningMode::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +attribute_t *create_start_of_week(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::StartOfWeek::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +attribute_t *create_number_of_weekly_transitions(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::NumberOfWeeklyTransitions::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint8(value)); +} + +attribute_t *create_number_of_daily_transitions(cluster_t *cluster, uint8_t value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::NumberOfDailyTransitions::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); +} + +attribute_t *create_occupied_setback(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::OccupiedSetback::Id, + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_nullable_uint8(value)); +} + +attribute_t *create_occupied_setback_min(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::OccupiedSetbackMin::Id, + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); +} + +attribute_t *create_occupied_setback_max(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::OccupiedSetbackMax::Id, + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); +} + +attribute_t *create_unoccupied_setback(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::UnoccupiedSetback::Id, + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_nullable_uint8(value)); +} + +attribute_t *create_unoccupied_setback_min(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::UnoccupiedSetbackMin::Id, + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); +} + +attribute_t *create_unoccupied_setback_max(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, Thermostat::Attributes::UnoccupiedSetbackMax::Id, + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); +} + } /* attribute */ } /* thermostat */ diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 734c3c63a..61acf9021 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -319,10 +319,34 @@ attribute_t *create_percent_current(cluster_t *cluster, uint8_t value); namespace thermostat { namespace attribute { attribute_t *create_local_temperature(cluster_t *cluster, nullable value); -attribute_t *create_occupied_cooling_setpoint(cluster_t *cluster, uint16_t value); -attribute_t *create_occupied_heating_setpoint(cluster_t *cluster, uint16_t value); +attribute_t *create_occupancy(cluster_t *cluster, uint8_t value); +attribute_t *create_abs_min_heat_setpoint_limit(cluster_t *cluster, int16_t value); +attribute_t *create_abs_max_heat_setpoint_limit(cluster_t *cluster, int16_t value); +attribute_t *create_abs_min_cool_setpoint_limit(cluster_t *cluster, int16_t value); +attribute_t *create_abs_max_cool_setpoint_limit(cluster_t *cluster, int16_t value); +attribute_t *create_pi_cooling_demand(cluster_t *cluster, uint8_t value); +attribute_t *create_pi_heating_demand(cluster_t *cluster, uint8_t value); +attribute_t *create_occupied_cooling_setpoint(cluster_t *cluster, int16_t value); +attribute_t *create_occupied_heating_setpoint(cluster_t *cluster, int16_t value); +attribute_t *create_unoccupied_cooling_setpoint(cluster_t *cluster, int16_t value); +attribute_t *create_unoccupied_heating_setpoint(cluster_t *cluster, int16_t value); +attribute_t *create_min_heat_setpoint_limit(cluster_t *cluster, int16_t value); +attribute_t *create_max_heat_setpoint_limit(cluster_t *cluster, int16_t value); +attribute_t *create_min_cool_setpoint_limit(cluster_t *cluster, int16_t value); +attribute_t *create_max_cool_setpoint_limit(cluster_t *cluster, int16_t value); +attribute_t *create_min_setpoint_dead_band(cluster_t *cluster, int8_t value); attribute_t *create_control_sequence_of_operation(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max); attribute_t *create_system_mode(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max); +attribute_t *create_thermostat_running_mode(cluster_t *cluster, uint8_t value); +attribute_t *create_start_of_week(cluster_t *cluster, uint8_t value); +attribute_t *create_number_of_weekly_transitions(cluster_t *cluster, uint8_t value); +attribute_t *create_number_of_daily_transitions(cluster_t *cluster, uint8_t value); +attribute_t *create_occupied_setback(cluster_t *cluster, nullable value); +attribute_t *create_occupied_setback_min(cluster_t *cluster, nullable value); +attribute_t *create_occupied_setback_max(cluster_t *cluster, nullable value); +attribute_t *create_unoccupied_setback(cluster_t *cluster, nullable value); +attribute_t *create_unoccupied_setback_min(cluster_t *cluster, nullable value); +attribute_t *create_unoccupied_setback_max(cluster_t *cluster, nullable value); } /* attribute */ } /* thermostat */ diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index 667fd2d7d..0b98d6660 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -992,6 +992,39 @@ static esp_err_t esp_matter_command_callback_setpoint_raise_lower(const Concrete return ESP_OK; } +static esp_err_t esp_matter_command_callback_set_weekly_schedule(const ConcreteCommandPath &command_path, + TLVReader &tlv_data, void *opaque_ptr) +{ + chip::app::Clusters::Thermostat::Commands::SetWeeklySchedule::DecodableType command_data; + CHIP_ERROR error = Decode(tlv_data, command_data); + if (error == CHIP_NO_ERROR) { + emberAfThermostatClusterSetWeeklyScheduleCallback((CommandHandler *)opaque_ptr, command_path, command_data); + } + return ESP_OK; +} + +static esp_err_t esp_matter_command_callback_get_weekly_schedule(const ConcreteCommandPath &command_path, + TLVReader &tlv_data, void *opaque_ptr) +{ + chip::app::Clusters::Thermostat::Commands::GetWeeklySchedule::DecodableType command_data; + CHIP_ERROR error = Decode(tlv_data, command_data); + if (error == CHIP_NO_ERROR) { + emberAfThermostatClusterGetWeeklyScheduleCallback((CommandHandler *)opaque_ptr, command_path, command_data); + } + return ESP_OK; +} + +static esp_err_t esp_matter_command_callback_clear_weekly_schedule(const ConcreteCommandPath &command_path, + TLVReader &tlv_data, void *opaque_ptr) +{ + chip::app::Clusters::Thermostat::Commands::ClearWeeklySchedule::DecodableType command_data; + CHIP_ERROR error = Decode(tlv_data, command_data); + if (error == CHIP_NO_ERROR) { + emberAfThermostatClusterClearWeeklyScheduleCallback((CommandHandler *)opaque_ptr, command_path, command_data); + } + return ESP_OK; +} + static esp_err_t esp_matter_command_callback_thread_reset_counts(const ConcreteCommandPath &command_path, TLVReader &tlv_data, void *opaque_ptr) { @@ -2040,6 +2073,30 @@ command_t *create_setpoint_raise_lower(cluster_t *cluster) esp_matter_command_callback_setpoint_raise_lower); } +command_t *create_set_weekly_schedule(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, Thermostat::Commands::SetWeeklySchedule::Id, COMMAND_FLAG_ACCEPTED, + esp_matter_command_callback_set_weekly_schedule); +} + +command_t *create_get_weekly_schedule(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, Thermostat::Commands::GetWeeklySchedule::Id, COMMAND_FLAG_ACCEPTED, + esp_matter_command_callback_get_weekly_schedule); +} + +command_t *create_clear_weekly_schedule(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, Thermostat::Commands::ClearWeeklySchedule::Id, COMMAND_FLAG_ACCEPTED, + esp_matter_command_callback_clear_weekly_schedule); +} + +command_t *create_get_weekly_schedule_response(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, Thermostat::Commands::GetWeeklyScheduleResponse::Id, COMMAND_FLAG_ACCEPTED, + NULL); +} + } /* command */ } /* thermostat */ diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 42671bd10..df962a1c4 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -229,6 +229,10 @@ command_t *create_color_loop_set(cluster_t *cluster); namespace thermostat { namespace command { command_t *create_setpoint_raise_lower(cluster_t *cluster); +command_t *create_set_weekly_schedule(cluster_t *cluster); +command_t *create_get_weekly_schedule(cluster_t *cluster); +command_t *create_clear_weekly_schedule(cluster_t *cluster); +command_t *create_get_weekly_schedule_response(cluster_t *cluster); } /* command */ } /* thermostat */ diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 8c767b580..0b5918de4 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -562,5 +562,195 @@ esp_err_t add(cluster_t *cluster) } /* feature */ } /* diagnostics_network_wifi */ +namespace thermostat { +namespace feature { + +namespace heating { + +uint32_t get_id() +{ + // The ThermostatFeature enum class is not added in the upstream code. + // Return the code according to the SPEC + return 0x01; +} + +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_abs_min_heat_setpoint_limit(cluster, config->abs_min_heat_setpoint_limit); + attribute::create_abs_max_heat_setpoint_limit(cluster, config->abs_max_heat_setpoint_limit); + attribute::create_pi_heating_demand(cluster, config->pi_heating_demand); + attribute::create_occupied_heating_setpoint(cluster, config->occupied_heating_setpoint); + attribute::create_min_heat_setpoint_limit(cluster, config->min_heat_setpoint_limit); + attribute::create_max_heat_setpoint_limit(cluster, config->max_heat_setpoint_limit); + + return ESP_OK; +} + +} /* heating */ + +namespace cooling { + +uint32_t get_id() +{ + // The ThermostatFeature enum class is not added in the upstream code. + // Return the code according to the SPEC + return 0x02; +} + +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_abs_min_cool_setpoint_limit(cluster, config->abs_min_cool_setpoint_limit); + attribute::create_abs_max_cool_setpoint_limit(cluster, config->abs_max_cool_setpoint_limit); + attribute::create_pi_cooling_demand(cluster, config->pi_cooling_demand); + attribute::create_occupied_cooling_setpoint(cluster, config->occupied_cooling_setpoint); + attribute::create_min_cool_setpoint_limit(cluster, config->min_cool_setpoint_limit); + attribute::create_max_cool_setpoint_limit(cluster, config->max_cool_setpoint_limit); + + return ESP_OK; +} +} /* cooling */ + +namespace occupancy { + +uint32_t get_id() +{ + // The ThermostatFeature enum class is not added in the upstream code. + // Return the code according to the SPEC + return 0x04; +} + +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_occupancy(cluster, config->occupancy); + + uint32_t occ_and_cool_feature_map = get_id() | feature::cooling::get_id(); + uint32_t occ_and_heat_feature_map = get_id() | feature::heating::get_id(); + uint32_t occ_and_sb_feature_map = get_id() | feature::setback::get_id(); + + if((get_feature_map_value(cluster) & occ_and_cool_feature_map) == occ_and_cool_feature_map){ + attribute::create_unoccupied_cooling_setpoint(cluster, config->unoccupied_cooling_setpoint); + }else{ + ESP_LOGE(TAG, "Cluster shall support Cool feature"); + return ESP_ERR_NOT_SUPPORTED; + } + if((get_feature_map_value(cluster) & occ_and_heat_feature_map) == occ_and_heat_feature_map){ + attribute::create_unoccupied_heating_setpoint(cluster, config->unoccupied_heating_setpoint); + }else{ + ESP_LOGE(TAG, "Cluster shall support Heat feature"); + return ESP_ERR_NOT_SUPPORTED; + } + if((get_feature_map_value(cluster) & occ_and_sb_feature_map) == occ_and_sb_feature_map){ + attribute::create_unoccupied_setback(cluster, config->unoccupied_setback); + attribute::create_unoccupied_setback_min(cluster, config->unoccupied_setback_min); + attribute::create_unoccupied_setback_max(cluster, config->unoccupied_setback_max); + }else{ + ESP_LOGE(TAG, "Cluster shall support Setback feature"); + return ESP_ERR_NOT_SUPPORTED; + } + + return ESP_OK; +} +} /* occupancy */ + +namespace schedule_configuration { + +uint32_t get_id() +{ + // The ThermostatFeature enum class is not added in the upstream code. + // Return the code according to the SPEC + return 0x08; +} + +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_start_of_week(cluster, config->start_of_week); + attribute::create_number_of_weekly_transitions(cluster, config->number_of_weekly_transitions); + attribute::create_number_of_daily_transitions(cluster, config->number_of_daily_transitions); + + command::create_set_weekly_schedule(cluster); + command::create_get_weekly_schedule(cluster); + command::create_clear_weekly_schedule(cluster); + command::create_get_weekly_schedule_response(cluster); + + return ESP_OK; +} +} /* schedule_configuration */ + +namespace setback { + +uint32_t get_id() +{ + // The ThermostatFeature enum class is not added in the upstream code. + // Return the code according to the SPEC + return 0x10; +} + +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_occupied_setback(cluster, config->occupied_setback); + attribute::create_occupied_setback_min(cluster, config->occupied_setback_min); + attribute::create_occupied_setback_max(cluster, config->occupied_setback_max); + + return ESP_OK; +} +} /* setback */ + +namespace auto_mode { + +uint32_t get_id() +{ + // The ThermostatFeature enum class is not added in the upstream code. + // Return the code according to the SPEC + return 0x20; +} + +esp_err_t add(cluster_t *cluster, config_t *config) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + attribute::create_min_setpoint_dead_band(cluster, config->min_setpoint_dead_band); + attribute::create_thermostat_running_mode(cluster, config->thermostat_running_mode); + + return ESP_OK; +} +} /* auto_mode */ + +} /* feature */ +} /* thermostat */ + } /* cluster */ } /* esp_matter */ diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index 7bf42744d..aec651a62 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -261,5 +261,103 @@ esp_err_t add(cluster_t *cluster); } /* feature */ } /* diagnostics_network_wifi */ +namespace thermostat { +namespace feature { + +namespace heating { + +typedef struct config { + int16_t abs_min_heat_setpoint_limit; + int16_t abs_max_heat_setpoint_limit; + uint8_t pi_heating_demand; + int16_t occupied_heating_setpoint; + int16_t min_heat_setpoint_limit; + int16_t max_heat_setpoint_limit; + + config (): abs_min_heat_setpoint_limit(700), abs_max_heat_setpoint_limit(3000), pi_heating_demand(), occupied_heating_setpoint(2000), min_heat_setpoint_limit(700), max_heat_setpoint_limit(3000) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); +} /* heating */ + +namespace cooling { + +typedef struct config { + int16_t abs_min_cool_setpoint_limit; + int16_t abs_max_cool_setpoint_limit; + uint8_t pi_cooling_demand; + int16_t occupied_cooling_setpoint; + int16_t min_cool_setpoint_limit; + int16_t max_cool_setpoint_limit; + + config (): abs_min_cool_setpoint_limit(1600), abs_max_cool_setpoint_limit(3200), pi_cooling_demand(), occupied_cooling_setpoint(2600), min_cool_setpoint_limit(1600), max_cool_setpoint_limit(3200) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); +} /* cooling */ + +namespace occupancy { + +typedef struct config { + uint8_t occupancy; + int16_t unoccupied_cooling_setpoint; + int16_t unoccupied_heating_setpoint; + nullable unoccupied_setback; + nullable unoccupied_setback_min; + nullable unoccupied_setback_max; + + config (): occupancy(1), unoccupied_cooling_setpoint(2600), unoccupied_heating_setpoint(2000), unoccupied_setback(), unoccupied_setback_min(), unoccupied_setback_max() {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); +} /* occupancy */ + +namespace schedule_configuration { + +typedef struct config { + uint8_t start_of_week; + uint8_t number_of_weekly_transitions; + uint8_t number_of_daily_transitions; + + config (): start_of_week(0), number_of_weekly_transitions(0), number_of_daily_transitions(0) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); +} /* schedule_configuration */ + +namespace setback { + +typedef struct config { + nullable occupied_setback; + nullable occupied_setback_min; + nullable occupied_setback_max; + + config (): occupied_setback(), occupied_setback_min(), occupied_setback_max() {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); +} /* setback */ + +namespace auto_mode { + +typedef struct config { + int8_t min_setpoint_dead_band; + uint8_t thermostat_running_mode; + + config (): min_setpoint_dead_band(25), thermostat_running_mode(0) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); +} /* auto_mode */ + +} /* feature */ +} /* thermostat */ + } /* cluster */ } /* esp_matter */