Add light restore mode

I don't want users to rely on setup priority.

Ref https://github.com/esphome/esphome-docs/pull/248
This commit is contained in:
Otto Winter 2019-05-27 19:22:16 +02:00
parent 72218171b3
commit 4bc3067725
No known key found for this signature in database
GPG key ID: DB66C0BE6013F97E
3 changed files with 41 additions and 6 deletions

View file

@ -3,7 +3,7 @@ import esphome.config_validation as cv
from esphome.components import mqtt, power_supply from esphome.components import mqtt, power_supply
from esphome.const import CONF_COLOR_CORRECT, \ from esphome.const import CONF_COLOR_CORRECT, \
CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_ID, \ 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 esphome.core import coroutine, coroutine_with_priority
from .automation import light_control_to_code # noqa from .automation import light_control_to_code # noqa
from .effects import validate_effects, BINARY_EFFECTS, \ from .effects import validate_effects, BINARY_EFFECTS, \
@ -12,9 +12,20 @@ from .types import ( # noqa
LightState, AddressableLightState, light_ns, LightOutput, AddressableLight) LightState, AddressableLightState, light_ns, LightOutput, AddressableLight)
IS_PLATFORM_COMPONENT = True 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({ LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(LightState), cv.GenerateID(): cv.declare_id(LightState),
cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_id(mqtt.MQTTJSONLightComponent), 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({ BINARY_LIGHT_SCHEMA = LIGHT_SCHEMA.extend({
@ -41,6 +52,7 @@ ADDRESSABLE_LIGHT_SCHEMA = RGB_LIGHT_SCHEMA.extend({
@coroutine @coroutine
def setup_light_core_(light_var, output_var, config): 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: if CONF_INTERNAL in config:
cg.add(light_var.set_internal(config[CONF_INTERNAL])) cg.add(light_var.set_internal(config[CONF_INTERNAL]))
if CONF_DEFAULT_TRANSITION_LENGTH in config: if CONF_DEFAULT_TRANSITION_LENGTH in config:

View file

@ -98,12 +98,25 @@ void LightState::setup() {
effect->init_internal(this); effect->init_internal(this);
} }
this->rtc_ = global_preferences.make_preference<LightStateRTCState>(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(); 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<LightStateRTCState>(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_state(recovered.state);
call.set_brightness_if_supported(recovered.brightness); call.set_brightness_if_supported(recovered.brightness);
call.set_red_if_supported(recovered.red); call.set_red_if_supported(recovered.red);

View file

@ -160,6 +160,13 @@ class LightCall {
bool save_{true}; 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 /** This class represents the communication layer between the front-end MQTT layer and the
* hardware output layer. * hardware output layer.
*/ */
@ -249,6 +256,7 @@ class LightState : public Nameable, public Component {
/// Set the gamma correction factor /// Set the gamma correction factor
void set_gamma_correct(float gamma_correct); void set_gamma_correct(float gamma_correct);
float get_gamma_correct() const { return this->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<LightEffect *> &get_effects() const; const std::vector<LightEffect *> &get_effects() const;
@ -292,6 +300,8 @@ class LightState : public Nameable, public Component {
/// Object used to store the persisted values of the light. /// Object used to store the persisted values of the light.
ESPPreferenceObject rtc_; ESPPreferenceObject rtc_;
/// Restore mode of the light.
LightRestoreMode restore_mode_;
/// Default transition length for all transitions in ms. /// Default transition length for all transitions in ms.
uint32_t default_transition_length_{}; uint32_t default_transition_length_{};
/// Value for storing the index of the currently active effect. 0 if no effect is active /// Value for storing the index of the currently active effect. 0 if no effect is active