Support fan speed levels (#1541)

* Add fan speed percentage support to the API

* Add float fan speed percentage

* Add percentage support to automation and configuration

* Update Tuya fan

* Fix pylint warning

* Update API to use speed levels instead of percentage

* Use speed levels

* Fix type warnings

* MQTT component now converts between speed levels and enums

* Webserver now supports speed_level

* Update prometheus

* Remove low/medium/high settings from speed fan

* Remove unused enum

* Configurable speed levels for speed fan

* Remove unused import

* Rename speed_level->speed and speed_levels->speed_count

* Rename supported_speed_levels -> supported_speed_count in API and FanTraits

Field id stays the same in the protocol, so the change is not breaking for aioesphome.
This commit is contained in:
Jim Ekman
2021-03-17 14:40:02 +01:00
committed by GitHub
parent 08998caabc
commit 7708b81ef5
22 changed files with 182 additions and 99 deletions
+13 -18
View File
@@ -1,4 +1,5 @@
#include "fan_state.h"
#include "fan_helpers.h"
#include "esphome/core/log.h"
namespace esphome {
@@ -20,7 +21,7 @@ FanStateCall FanState::make_call() { return FanStateCall(this); }
struct FanStateRTCState {
bool state;
FanSpeed speed;
int speed;
bool oscillating;
FanDirection direction;
};
@@ -52,16 +53,8 @@ void FanStateCall::perform() const {
this->state_->direction = *this->direction_;
}
if (this->speed_.has_value()) {
switch (*this->speed_) {
case FAN_SPEED_LOW:
case FAN_SPEED_MEDIUM:
case FAN_SPEED_HIGH:
this->state_->speed = *this->speed_;
break;
default:
// protect from invalid input
break;
}
const int speed_count = this->state_->get_traits().supported_speed_count();
this->state_->speed = static_cast<int>(clamp(*this->speed_, 1, speed_count));
}
FanStateRTCState saved{};
@@ -73,13 +66,15 @@ void FanStateCall::perform() const {
this->state_->state_callback_.call();
}
FanStateCall &FanStateCall::set_speed(const char *speed) {
if (strcasecmp(speed, "low") == 0) {
this->set_speed(FAN_SPEED_LOW);
} else if (strcasecmp(speed, "medium") == 0) {
this->set_speed(FAN_SPEED_MEDIUM);
} else if (strcasecmp(speed, "high") == 0) {
this->set_speed(FAN_SPEED_HIGH);
FanStateCall &FanStateCall::set_speed(const char *legacy_speed) {
const auto supported_speed_count = this->state_->get_traits().supported_speed_count();
if (strcasecmp(legacy_speed, "low") == 0) {
this->set_speed(fan::speed_enum_to_level(FAN_SPEED_LOW, supported_speed_count));
} else if (strcasecmp(legacy_speed, "medium") == 0) {
this->set_speed(fan::speed_enum_to_level(FAN_SPEED_MEDIUM, supported_speed_count));
} else if (strcasecmp(legacy_speed, "high") == 0) {
this->set_speed(fan::speed_enum_to_level(FAN_SPEED_HIGH, supported_speed_count));
}
return *this;
}