mirror of
https://github.com/esphome/esphome.git
synced 2026-05-22 18:56:40 +08:00
[thermostat] Enhance timer behavior for immediate response to duration changes (#12610)
CI / Create common environment (push) Has been cancelled
CI / Check pylint (push) Has been cancelled
CI / Run script/ci-custom (push) Has been cancelled
CI / Run pytest (macOS-latest, 3.11) (push) Has been cancelled
CI / Run pytest (ubuntu-latest, 3.11) (push) Has been cancelled
CI / Run pytest (ubuntu-latest, 3.13) (push) Has been cancelled
CI / Run pytest (windows-latest, 3.11) (push) Has been cancelled
CI / Determine which jobs to run (push) Has been cancelled
CI / Run integration tests (push) Has been cancelled
CI / Run C++ unit tests (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 IDF (push) Has been cancelled
CI / Run script/clang-tidy for ESP8266 (push) Has been cancelled
CI / Run script/clang-tidy for ZEPHYR (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 1/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 2/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 3/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 4/4 (push) Has been cancelled
CI / Test components batch (${{ matrix.components }}) (push) Has been cancelled
CI / pre-commit.ci lite (push) Has been cancelled
CI / Build target branch for memory impact (push) Has been cancelled
CI / Build PR branch for memory impact (push) Has been cancelled
CI / Comment memory impact (push) Has been cancelled
CI / CI Status (push) Has been cancelled
Stale / stale (push) Has been cancelled
Lock closed issues and PRs / lock (push) Has been cancelled
Publish Release / Initialize build (push) Has been cancelled
Publish Release / Build and publish to PyPi (push) Has been cancelled
Publish Release / Build ESPHome amd64 (push) Has been cancelled
Publish Release / Build ESPHome arm64 (push) Has been cancelled
Publish Release / Publish ESPHome docker to dockerhub (push) Has been cancelled
Publish Release / Publish ESPHome docker to ghcr (push) Has been cancelled
Publish Release / Publish ESPHome ha-addon to dockerhub (push) Has been cancelled
Publish Release / Publish ESPHome ha-addon to ghcr (push) Has been cancelled
Publish Release / deploy-ha-addon-repo (push) Has been cancelled
Publish Release / deploy-esphome-schema (push) Has been cancelled
Publish Release / version-notifier (push) Has been cancelled
CI / Create common environment (push) Has been cancelled
CI / Check pylint (push) Has been cancelled
CI / Run script/ci-custom (push) Has been cancelled
CI / Run pytest (macOS-latest, 3.11) (push) Has been cancelled
CI / Run pytest (ubuntu-latest, 3.11) (push) Has been cancelled
CI / Run pytest (ubuntu-latest, 3.13) (push) Has been cancelled
CI / Run pytest (windows-latest, 3.11) (push) Has been cancelled
CI / Determine which jobs to run (push) Has been cancelled
CI / Run integration tests (push) Has been cancelled
CI / Run C++ unit tests (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 IDF (push) Has been cancelled
CI / Run script/clang-tidy for ESP8266 (push) Has been cancelled
CI / Run script/clang-tidy for ZEPHYR (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 1/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 2/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 3/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 4/4 (push) Has been cancelled
CI / Test components batch (${{ matrix.components }}) (push) Has been cancelled
CI / pre-commit.ci lite (push) Has been cancelled
CI / Build target branch for memory impact (push) Has been cancelled
CI / Build PR branch for memory impact (push) Has been cancelled
CI / Comment memory impact (push) Has been cancelled
CI / CI Status (push) Has been cancelled
Stale / stale (push) Has been cancelled
Lock closed issues and PRs / lock (push) Has been cancelled
Publish Release / Initialize build (push) Has been cancelled
Publish Release / Build and publish to PyPi (push) Has been cancelled
Publish Release / Build ESPHome amd64 (push) Has been cancelled
Publish Release / Build ESPHome arm64 (push) Has been cancelled
Publish Release / Publish ESPHome docker to dockerhub (push) Has been cancelled
Publish Release / Publish ESPHome docker to ghcr (push) Has been cancelled
Publish Release / Publish ESPHome ha-addon to dockerhub (push) Has been cancelled
Publish Release / Publish ESPHome ha-addon to ghcr (push) Has been cancelled
Publish Release / deploy-ha-addon-repo (push) Has been cancelled
Publish Release / deploy-esphome-schema (push) Has been cancelled
Publish Release / version-notifier (push) Has been cancelled
This commit is contained in:
@@ -1330,45 +1330,64 @@ void ThermostatClimate::set_heat_deadband(float deadband) { this->heating_deadba
|
||||
void ThermostatClimate::set_heat_overrun(float overrun) { this->heating_overrun_ = overrun; }
|
||||
void ThermostatClimate::set_supplemental_cool_delta(float delta) { this->supplemental_cool_delta_ = delta; }
|
||||
void ThermostatClimate::set_supplemental_heat_delta(float delta) { this->supplemental_heat_delta_ = delta; }
|
||||
|
||||
void ThermostatClimate::set_timer_duration_in_sec_(ThermostatClimateTimerIndex timer_index, uint32_t time) {
|
||||
uint32_t new_duration_ms = 1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
|
||||
if (this->timer_[timer_index].active) {
|
||||
// Timer is running, calculate elapsed time and adjust if needed
|
||||
uint32_t current_time = App.get_loop_component_start_time();
|
||||
uint32_t elapsed = current_time - this->timer_[timer_index].started;
|
||||
|
||||
if (elapsed >= new_duration_ms) {
|
||||
// Timer should complete immediately (including when new_duration_ms is 0)
|
||||
ESP_LOGVV(TAG, "timer %d completing immediately (elapsed %d >= new %d)", timer_index, elapsed, new_duration_ms);
|
||||
this->timer_[timer_index].active = false;
|
||||
// Trigger the timer callback immediately
|
||||
this->timer_[timer_index].func();
|
||||
return;
|
||||
} else {
|
||||
// Adjust timer to run for remaining time - keep original start time
|
||||
ESP_LOGVV(TAG, "timer %d adjusted: elapsed %d, new total %d, remaining %d", timer_index, elapsed, new_duration_ms,
|
||||
new_duration_ms - elapsed);
|
||||
this->timer_[timer_index].time = new_duration_ms;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Original logic for non-running timers
|
||||
this->timer_[timer_index].time = new_duration_ms;
|
||||
}
|
||||
|
||||
void ThermostatClimate::set_cooling_maximum_run_time_in_sec(uint32_t time) {
|
||||
this->timer_[thermostat::THERMOSTAT_TIMER_COOLING_MAX_RUN_TIME].time =
|
||||
1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
this->set_timer_duration_in_sec_(thermostat::THERMOSTAT_TIMER_COOLING_MAX_RUN_TIME, time);
|
||||
}
|
||||
void ThermostatClimate::set_cooling_minimum_off_time_in_sec(uint32_t time) {
|
||||
this->timer_[thermostat::THERMOSTAT_TIMER_COOLING_OFF].time =
|
||||
1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
this->set_timer_duration_in_sec_(thermostat::THERMOSTAT_TIMER_COOLING_OFF, time);
|
||||
}
|
||||
void ThermostatClimate::set_cooling_minimum_run_time_in_sec(uint32_t time) {
|
||||
this->timer_[thermostat::THERMOSTAT_TIMER_COOLING_ON].time =
|
||||
1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
this->set_timer_duration_in_sec_(thermostat::THERMOSTAT_TIMER_COOLING_ON, time);
|
||||
}
|
||||
void ThermostatClimate::set_fan_mode_minimum_switching_time_in_sec(uint32_t time) {
|
||||
this->timer_[thermostat::THERMOSTAT_TIMER_FAN_MODE].time =
|
||||
1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
this->set_timer_duration_in_sec_(thermostat::THERMOSTAT_TIMER_FAN_MODE, time);
|
||||
}
|
||||
void ThermostatClimate::set_fanning_minimum_off_time_in_sec(uint32_t time) {
|
||||
this->timer_[thermostat::THERMOSTAT_TIMER_FANNING_OFF].time =
|
||||
1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
this->set_timer_duration_in_sec_(thermostat::THERMOSTAT_TIMER_FANNING_OFF, time);
|
||||
}
|
||||
void ThermostatClimate::set_fanning_minimum_run_time_in_sec(uint32_t time) {
|
||||
this->timer_[thermostat::THERMOSTAT_TIMER_FANNING_ON].time =
|
||||
1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
this->set_timer_duration_in_sec_(thermostat::THERMOSTAT_TIMER_FANNING_ON, time);
|
||||
}
|
||||
void ThermostatClimate::set_heating_maximum_run_time_in_sec(uint32_t time) {
|
||||
this->timer_[thermostat::THERMOSTAT_TIMER_HEATING_MAX_RUN_TIME].time =
|
||||
1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
this->set_timer_duration_in_sec_(thermostat::THERMOSTAT_TIMER_HEATING_MAX_RUN_TIME, time);
|
||||
}
|
||||
void ThermostatClimate::set_heating_minimum_off_time_in_sec(uint32_t time) {
|
||||
this->timer_[thermostat::THERMOSTAT_TIMER_HEATING_OFF].time =
|
||||
1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
this->set_timer_duration_in_sec_(thermostat::THERMOSTAT_TIMER_HEATING_OFF, time);
|
||||
}
|
||||
void ThermostatClimate::set_heating_minimum_run_time_in_sec(uint32_t time) {
|
||||
this->timer_[thermostat::THERMOSTAT_TIMER_HEATING_ON].time =
|
||||
1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
this->set_timer_duration_in_sec_(thermostat::THERMOSTAT_TIMER_HEATING_ON, time);
|
||||
}
|
||||
void ThermostatClimate::set_idle_minimum_time_in_sec(uint32_t time) {
|
||||
this->timer_[thermostat::THERMOSTAT_TIMER_IDLE_ON].time =
|
||||
1000 * (time < this->min_timer_duration_ ? this->min_timer_duration_ : time);
|
||||
this->set_timer_duration_in_sec_(thermostat::THERMOSTAT_TIMER_IDLE_ON, time);
|
||||
}
|
||||
void ThermostatClimate::set_sensor(sensor::Sensor *sensor) { this->sensor_ = sensor; }
|
||||
void ThermostatClimate::set_humidity_sensor(sensor::Sensor *humidity_sensor) {
|
||||
|
||||
@@ -267,6 +267,8 @@ class ThermostatClimate : public climate::Climate, public Component {
|
||||
bool timer_active_(ThermostatClimateTimerIndex timer_index);
|
||||
uint32_t timer_duration_(ThermostatClimateTimerIndex timer_index);
|
||||
std::function<void()> timer_cbf_(ThermostatClimateTimerIndex timer_index);
|
||||
/// Enhanced timer duration setter with running timer adjustment
|
||||
void set_timer_duration_in_sec_(ThermostatClimateTimerIndex timer_index, uint32_t time);
|
||||
|
||||
/// set_timeout() callbacks for various actions (see above)
|
||||
void cooling_max_run_time_timer_callback_();
|
||||
|
||||
Reference in New Issue
Block a user