added idle action for climate (#859)

* added idle

* more clear state description

* Also add drying/fan

Putting it in this PR because it will be put in the same aioesphomeapi release anyway.

* Update bang_bang for idle action


Co-authored-by: root <root@mail.danman.eu>
Co-authored-by: Otto Winter <otto@otto-winter.com>
This commit is contained in:
Daniel Kucera
2019-11-26 16:56:04 +00:00
committed by Otto Winter
parent be36eef939
commit fe89dcdc08
6 changed files with 49 additions and 13 deletions
@@ -51,12 +51,15 @@ climate::ClimateTraits BangBangClimate::traits() {
}
void BangBangClimate::compute_state_() {
if (this->mode != climate::CLIMATE_MODE_AUTO) {
// in non-auto mode
// in non-auto mode, switch directly to appropriate action
// - HEAT mode -> HEATING action
// - COOL mode -> COOLING action
// - OFF mode -> OFF action (not IDLE!)
this->switch_to_action_(static_cast<climate::ClimateAction>(this->mode));
return;
}
if (isnan(this->current_temperature) || isnan(this->target_temperature_low) || isnan(this->target_temperature_high)) {
// if any control values are nan, go to OFF (idle) mode
// if any control parameters are nan, go to OFF action (not IDLE!)
this->switch_to_action_(climate::CLIMATE_ACTION_OFF);
return;
}
@@ -69,18 +72,18 @@ void BangBangClimate::compute_state_() {
if (this->supports_heat_)
target_action = climate::CLIMATE_ACTION_HEATING;
else
target_action = climate::CLIMATE_ACTION_OFF;
target_action = climate::CLIMATE_ACTION_IDLE;
} else if (too_hot) {
// too hot -> enable cooling if possible, else idle
if (this->supports_cool_)
target_action = climate::CLIMATE_ACTION_COOLING;
else
target_action = climate::CLIMATE_ACTION_OFF;
target_action = climate::CLIMATE_ACTION_IDLE;
} else {
// neither too hot nor too cold -> in range
if (this->supports_cool_ && this->supports_heat_) {
// if supports both ends, go to idle mode
target_action = climate::CLIMATE_ACTION_OFF;
// if supports both ends, go to idle action
target_action = climate::CLIMATE_ACTION_IDLE;
} else {
// else use current mode and don't change (hysteresis)
target_action = this->action;
@@ -94,6 +97,16 @@ void BangBangClimate::switch_to_action_(climate::ClimateAction action) {
// already in target mode
return;
if ((action == climate::CLIMATE_ACTION_OFF && this->action == climate::CLIMATE_ACTION_IDLE) ||
(action == climate::CLIMATE_ACTION_IDLE && this->action == climate::CLIMATE_ACTION_OFF)) {
// switching from OFF to IDLE or vice-versa
// these only have visual difference. OFF means user manually disabled,
// IDLE means it's in auto mode but value is in target range.
this->action = action;
this->publish_state();
return;
}
if (this->prev_trigger_ != nullptr) {
this->prev_trigger_->stop();
this->prev_trigger_ = nullptr;
@@ -101,6 +114,7 @@ void BangBangClimate::switch_to_action_(climate::ClimateAction action) {
Trigger<> *trig;
switch (action) {
case climate::CLIMATE_ACTION_OFF:
case climate::CLIMATE_ACTION_IDLE:
trig = this->idle_trigger_;
break;
case climate::CLIMATE_ACTION_COOLING:
@@ -112,13 +126,11 @@ void BangBangClimate::switch_to_action_(climate::ClimateAction action) {
default:
trig = nullptr;
}
if (trig != nullptr) {
// trig should never be null, but still check so that we don't crash
trig->trigger();
this->action = action;
this->prev_trigger_ = trig;
this->publish_state();
}
assert(trig != nullptr);
trig->trigger();
this->action = action;
this->prev_trigger_ = trig;
this->publish_state();
}
void BangBangClimate::change_away_(bool away) {
if (!away) {