diff --git a/esphome/components/light/__init__.py b/esphome/components/light/__init__.py index e0ea8f246d..63aac69462 100644 --- a/esphome/components/light/__init__.py +++ b/esphome/components/light/__init__.py @@ -3,7 +3,7 @@ import esphome.config_validation as cv from esphome.components import mqtt, power_supply from esphome.const import CONF_COLOR_CORRECT, \ CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_ID, \ - CONF_INTERNAL, CONF_NAME, CONF_MQTT_ID, CONF_POWER_SUPPLY + CONF_INTERNAL, CONF_NAME, CONF_MQTT_ID, CONF_POWER_SUPPLY, CONF_RESTORE_MODE from esphome.core import coroutine, coroutine_with_priority from .automation import light_control_to_code # noqa from .effects import validate_effects, BINARY_EFFECTS, \ @@ -12,9 +12,20 @@ from .types import ( # noqa LightState, AddressableLightState, light_ns, LightOutput, AddressableLight) IS_PLATFORM_COMPONENT = True + +LightRestoreMode = light_ns.enum('LightRestoreMode') +RESTORE_MODES = { + 'RESTORE_DEFAULT_OFF': LightRestoreMode.LIGHT_RESTORE_DEFAULT_OFF, + 'RESTORE_DEFAULT_ON': LightRestoreMode.LIGHT_RESTORE_DEFAULT_ON, + 'ALWAYS_OFF': LightRestoreMode.LIGHT_ALWAYS_OFF, + 'ALWAYS_ON': LightRestoreMode.LIGHT_ALWAYS_ON, +} + LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(LightState), cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_id(mqtt.MQTTJSONLightComponent), + cv.Optional(CONF_RESTORE_MODE, default='restore_default_off'): + cv.enum(RESTORE_MODES, upper=True, space='_'), }) BINARY_LIGHT_SCHEMA = LIGHT_SCHEMA.extend({ @@ -41,6 +52,7 @@ ADDRESSABLE_LIGHT_SCHEMA = RGB_LIGHT_SCHEMA.extend({ @coroutine def setup_light_core_(light_var, output_var, config): + cg.add(light_var.set_restore_mode(config[CONF_RESTORE_MODE])) if CONF_INTERNAL in config: cg.add(light_var.set_internal(config[CONF_INTERNAL])) if CONF_DEFAULT_TRANSITION_LENGTH in config: diff --git a/esphome/components/light/light_state.cpp b/esphome/components/light/light_state.cpp index 7e61ea245a..cafced27fc 100644 --- a/esphome/components/light/light_state.cpp +++ b/esphome/components/light/light_state.cpp @@ -98,12 +98,25 @@ void LightState::setup() { effect->init_internal(this); } - this->rtc_ = global_preferences.make_preference(this->get_object_id_hash()); - LightStateRTCState recovered{}; - // Attempt to load from preferences, else fall back to default values from struct - this->rtc_.load(&recovered); - auto call = this->make_call(); + LightStateRTCState recovered{}; + switch (this->restore_mode_) { + case LIGHT_RESTORE_DEFAULT_OFF: + case LIGHT_RESTORE_DEFAULT_ON: + this->rtc_ = global_preferences.make_preference(this->get_object_id_hash()); + // Attempt to load from preferences, else fall back to default values from struct + if (!this->rtc_.load(&recovered)) { + recovered.state = this->restore_mode_ == LIGHT_RESTORE_DEFAULT_ON; + } + break; + case LIGHT_ALWAYS_OFF: + recovered.state = false; + break; + case LIGHT_ALWAYS_ON: + recovered.state = true; + break; + } + call.set_state(recovered.state); call.set_brightness_if_supported(recovered.brightness); call.set_red_if_supported(recovered.red); diff --git a/esphome/components/light/light_state.h b/esphome/components/light/light_state.h index 24e659ec8a..d67aa2c53d 100644 --- a/esphome/components/light/light_state.h +++ b/esphome/components/light/light_state.h @@ -160,6 +160,13 @@ class LightCall { bool save_{true}; }; +enum LightRestoreMode { + LIGHT_RESTORE_DEFAULT_OFF, + LIGHT_RESTORE_DEFAULT_ON, + LIGHT_ALWAYS_OFF, + LIGHT_ALWAYS_ON, +}; + /** This class represents the communication layer between the front-end MQTT layer and the * hardware output layer. */ @@ -249,6 +256,7 @@ class LightState : public Nameable, public Component { /// Set the gamma correction factor void set_gamma_correct(float gamma_correct); float get_gamma_correct() const { return this->gamma_correct_; } + void set_restore_mode(LightRestoreMode restore_mode) { restore_mode_ = restore_mode; } const std::vector &get_effects() const; @@ -292,6 +300,8 @@ class LightState : public Nameable, public Component { /// Object used to store the persisted values of the light. ESPPreferenceObject rtc_; + /// Restore mode of the light. + LightRestoreMode restore_mode_; /// Default transition length for all transitions in ms. uint32_t default_transition_length_{}; /// Value for storing the index of the currently active effect. 0 if no effect is active