Add restore_mode to fan component (#3051)

This commit is contained in:
Joshua Spence 2022-01-23 06:41:58 +11:00 committed by GitHub
parent f0b183a552
commit f9a7f00843
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 76 additions and 9 deletions

View file

@ -19,6 +19,7 @@ from esphome.const import (
CONF_ON_TURN_ON, CONF_ON_TURN_ON,
CONF_TRIGGER_ID, CONF_TRIGGER_ID,
CONF_DIRECTION, CONF_DIRECTION,
CONF_RESTORE_MODE,
) )
from esphome.core import CORE, coroutine_with_priority from esphome.core import CORE, coroutine_with_priority
from esphome.cpp_helpers import setup_entity from esphome.cpp_helpers import setup_entity
@ -35,6 +36,16 @@ FAN_DIRECTION_ENUM = {
"REVERSE": FanDirection.FAN_DIRECTION_REVERSE, "REVERSE": FanDirection.FAN_DIRECTION_REVERSE,
} }
FanRestoreMode = fan_ns.enum("FanRestoreMode")
RESTORE_MODES = {
"RESTORE_DEFAULT_OFF": FanRestoreMode.FAN_RESTORE_DEFAULT_OFF,
"RESTORE_DEFAULT_ON": FanRestoreMode.FAN_RESTORE_DEFAULT_ON,
"ALWAYS_OFF": FanRestoreMode.FAN_ALWAYS_OFF,
"ALWAYS_ON": FanRestoreMode.FAN_ALWAYS_ON,
"RESTORE_INVERTED_DEFAULT_OFF": FanRestoreMode.FAN_RESTORE_INVERTED_DEFAULT_OFF,
"RESTORE_INVERTED_DEFAULT_ON": FanRestoreMode.FAN_RESTORE_INVERTED_DEFAULT_ON,
}
# Actions # Actions
TurnOnAction = fan_ns.class_("TurnOnAction", automation.Action) TurnOnAction = fan_ns.class_("TurnOnAction", automation.Action)
TurnOffAction = fan_ns.class_("TurnOffAction", automation.Action) TurnOffAction = fan_ns.class_("TurnOffAction", automation.Action)
@ -51,6 +62,9 @@ FanIsOffCondition = fan_ns.class_("FanIsOffCondition", automation.Condition.temp
FAN_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend( FAN_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
{ {
cv.GenerateID(): cv.declare_id(FanState), cv.GenerateID(): cv.declare_id(FanState),
cv.Optional(CONF_RESTORE_MODE, default="restore_default_off"): cv.enum(
RESTORE_MODES, upper=True, space="_"
),
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTFanComponent), cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTFanComponent),
cv.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.All( cv.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.All(
cv.requires_component("mqtt"), cv.publish_topic cv.requires_component("mqtt"), cv.publish_topic
@ -92,6 +106,8 @@ FAN_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).exte
async def setup_fan_core_(var, config): async def setup_fan_core_(var, config):
await setup_entity(var, config) await setup_entity(var, config)
cg.add(var.set_restore_mode(config[CONF_RESTORE_MODE]))
if CONF_MQTT_ID in config: if CONF_MQTT_ID in config:
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var) mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
await mqtt.register_mqtt_component(mqtt_, config) await mqtt.register_mqtt_component(mqtt_, config)

View file

@ -27,16 +27,52 @@ struct FanStateRTCState {
}; };
void FanState::setup() { void FanState::setup() {
this->rtc_ = global_preferences->make_preference<FanStateRTCState>(this->get_object_id_hash());
FanStateRTCState recovered{};
if (!this->rtc_.load(&recovered))
return;
auto call = this->make_call(); auto call = this->make_call();
call.set_state(recovered.state); FanStateRTCState recovered{};
call.set_speed(recovered.speed);
call.set_oscillating(recovered.oscillating); switch (this->restore_mode_) {
call.set_direction(recovered.direction); case FAN_RESTORE_DEFAULT_OFF:
case FAN_RESTORE_DEFAULT_ON:
case FAN_RESTORE_INVERTED_DEFAULT_OFF:
case FAN_RESTORE_INVERTED_DEFAULT_ON:
this->rtc_ = global_preferences->make_preference<FanStateRTCState>(this->get_object_id_hash());
if (!this->rtc_.load(&recovered)) {
if (this->restore_mode_ == FAN_RESTORE_DEFAULT_ON || this->restore_mode_ == FAN_RESTORE_INVERTED_DEFAULT_ON) {
call.set_state(true);
} else {
call.set_state(false);
}
} else {
if (this->restore_mode_ == FAN_RESTORE_INVERTED_DEFAULT_OFF ||
this->restore_mode_ == FAN_RESTORE_INVERTED_DEFAULT_ON) {
call.set_state(!recovered.state);
} else {
call.set_state(recovered.state);
}
call.set_speed(recovered.speed);
call.set_oscillating(recovered.oscillating);
call.set_direction(recovered.direction);
}
break;
case FAN_ALWAYS_OFF:
case FAN_ALWAYS_ON:
if (this->restore_mode_ == FAN_ALWAYS_OFF) {
call.set_state(false);
} else if (this->restore_mode_ == FAN_ALWAYS_ON) {
call.set_state(true);
}
this->rtc_ = global_preferences->make_preference<FanStateRTCState>(this->get_object_id_hash());
if (this->rtc_.load(&recovered)) {
call.set_speed(recovered.speed);
call.set_oscillating(recovered.oscillating);
call.set_direction(recovered.direction);
}
break;
}
call.perform(); call.perform();
} }
float FanState::get_setup_priority() const { return setup_priority::DATA - 1.0f; } float FanState::get_setup_priority() const { return setup_priority::DATA - 1.0f; }

View file

@ -20,6 +20,15 @@ enum ESPDEPRECATED("FanSpeed is deprecated.", "2021.9") FanSpeed {
/// Simple enum to represent the direction of a fan /// Simple enum to represent the direction of a fan
enum FanDirection { FAN_DIRECTION_FORWARD = 0, FAN_DIRECTION_REVERSE = 1 }; enum FanDirection { FAN_DIRECTION_FORWARD = 0, FAN_DIRECTION_REVERSE = 1 };
enum FanRestoreMode {
FAN_RESTORE_DEFAULT_OFF,
FAN_RESTORE_DEFAULT_ON,
FAN_ALWAYS_OFF,
FAN_ALWAYS_ON,
FAN_RESTORE_INVERTED_DEFAULT_OFF,
FAN_RESTORE_INVERTED_DEFAULT_ON,
};
class FanState; class FanState;
class FanStateCall { class FanStateCall {
@ -81,6 +90,9 @@ class FanState : public EntityBase, public Component {
/// Set the traits of this fan (i.e. what features it supports). /// Set the traits of this fan (i.e. what features it supports).
void set_traits(const FanTraits &traits); void set_traits(const FanTraits &traits);
/// Set the restore mode of this fan
void set_restore_mode(FanRestoreMode restore_mode) { this->restore_mode_ = restore_mode; }
/// The current ON/OFF state of the fan. /// The current ON/OFF state of the fan.
bool state{false}; bool state{false};
/// The current oscillation state of the fan. /// The current oscillation state of the fan.
@ -106,6 +118,9 @@ class FanState : public EntityBase, public Component {
FanTraits traits_{}; FanTraits traits_{};
CallbackManager<void()> state_callback_{}; CallbackManager<void()> state_callback_{};
ESPPreferenceObject rtc_; ESPPreferenceObject rtc_;
/// Restore mode of the fan.
FanRestoreMode restore_mode_;
}; };
} // namespace fan } // namespace fan