From 0ce57e5a39af1c55b469cea99d520ee28fb7e9ce Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sun, 23 May 2021 22:20:11 +0200 Subject: [PATCH] Light & Switch Inverted Restore mode (#1810) --- esphome/components/gpio/switch/__init__.py | 2 ++ esphome/components/gpio/switch/gpio_switch.cpp | 12 ++++++++++++ esphome/components/gpio/switch/gpio_switch.h | 2 ++ esphome/components/light/__init__.py | 2 ++ esphome/components/light/light_state.cpp | 14 ++++++++++++-- esphome/components/light/light_state.h | 2 ++ 6 files changed, 32 insertions(+), 2 deletions(-) diff --git a/esphome/components/gpio/switch/__init__.py b/esphome/components/gpio/switch/__init__.py index ebd12d10ca..44a9699b84 100644 --- a/esphome/components/gpio/switch/__init__.py +++ b/esphome/components/gpio/switch/__init__.py @@ -13,6 +13,8 @@ RESTORE_MODES = { "RESTORE_DEFAULT_ON": GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_DEFAULT_ON, "ALWAYS_OFF": GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_OFF, "ALWAYS_ON": GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_ON, + "RESTORE_INVERTED_DEFAULT_OFF": GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_OFF, + "RESTORE_INVERTED_DEFAULT_ON": GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_ON, } CONF_INTERLOCK_WAIT_TIME = "interlock_wait_time" diff --git a/esphome/components/gpio/switch/gpio_switch.cpp b/esphome/components/gpio/switch/gpio_switch.cpp index d87e5a61e6..2475d43e93 100644 --- a/esphome/components/gpio/switch/gpio_switch.cpp +++ b/esphome/components/gpio/switch/gpio_switch.cpp @@ -18,6 +18,12 @@ void GPIOSwitch::setup() { case GPIO_SWITCH_RESTORE_DEFAULT_ON: initial_state = this->get_initial_state().value_or(true); break; + case GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_OFF: + initial_state = !this->get_initial_state().value_or(true); + break; + case GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_ON: + initial_state = !this->get_initial_state().value_or(false); + break; case GPIO_SWITCH_ALWAYS_OFF: initial_state = false; break; @@ -49,6 +55,12 @@ void GPIOSwitch::dump_config() { case GPIO_SWITCH_RESTORE_DEFAULT_ON: restore_mode = "Restore (Defaults to ON)"; break; + case GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_ON: + restore_mode = "Restore inverted (Defaults to ON)"; + break; + case GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_OFF: + restore_mode = "Restore inverted (Defaults to OFF)"; + break; case GPIO_SWITCH_ALWAYS_OFF: restore_mode = "Always OFF"; break; diff --git a/esphome/components/gpio/switch/gpio_switch.h b/esphome/components/gpio/switch/gpio_switch.h index dc0dd9bc95..c0036b20e9 100644 --- a/esphome/components/gpio/switch/gpio_switch.h +++ b/esphome/components/gpio/switch/gpio_switch.h @@ -11,6 +11,8 @@ enum GPIOSwitchRestoreMode { GPIO_SWITCH_RESTORE_DEFAULT_ON, GPIO_SWITCH_ALWAYS_OFF, GPIO_SWITCH_ALWAYS_ON, + GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_OFF, + GPIO_SWITCH_RESTORE_INVERTED_DEFAULT_ON, }; class GPIOSwitch : public switch_::Switch, public Component { diff --git a/esphome/components/light/__init__.py b/esphome/components/light/__init__.py index a382c5604e..276bf8073d 100644 --- a/esphome/components/light/__init__.py +++ b/esphome/components/light/__init__.py @@ -46,6 +46,8 @@ RESTORE_MODES = { "RESTORE_DEFAULT_ON": LightRestoreMode.LIGHT_RESTORE_DEFAULT_ON, "ALWAYS_OFF": LightRestoreMode.LIGHT_ALWAYS_OFF, "ALWAYS_ON": LightRestoreMode.LIGHT_ALWAYS_ON, + "RESTORE_INVERTED_DEFAULT_OFF": LightRestoreMode.LIGHT_RESTORE_INVERTED_DEFAULT_OFF, + "RESTORE_INVERTED_DEFAULT_ON": LightRestoreMode.LIGHT_RESTORE_INVERTED_DEFAULT_ON, } LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend( diff --git a/esphome/components/light/light_state.cpp b/esphome/components/light/light_state.cpp index dd78ced650..4e450f6ccb 100644 --- a/esphome/components/light/light_state.cpp +++ b/esphome/components/light/light_state.cpp @@ -106,10 +106,20 @@ void LightState::setup() { switch (this->restore_mode_) { case LIGHT_RESTORE_DEFAULT_OFF: case LIGHT_RESTORE_DEFAULT_ON: + case LIGHT_RESTORE_INVERTED_DEFAULT_OFF: + case LIGHT_RESTORE_INVERTED_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 + // Attempt to load from preferences, else fall back to default values if (!this->rtc_.load(&recovered)) { - recovered.state = this->restore_mode_ == LIGHT_RESTORE_DEFAULT_ON; + recovered.state = false; + if (this->restore_mode_ == LIGHT_RESTORE_DEFAULT_ON || + this->restore_mode_ == LIGHT_RESTORE_INVERTED_DEFAULT_ON) { + recovered.state = true; + } + } else if (this->restore_mode_ == LIGHT_RESTORE_INVERTED_DEFAULT_OFF || + this->restore_mode_ == LIGHT_RESTORE_INVERTED_DEFAULT_ON) { + // Inverted restore state + recovered.state = !recovered.state; } break; case LIGHT_ALWAYS_OFF: diff --git a/esphome/components/light/light_state.h b/esphome/components/light/light_state.h index e761e576e3..aff63bf5db 100644 --- a/esphome/components/light/light_state.h +++ b/esphome/components/light/light_state.h @@ -165,6 +165,8 @@ enum LightRestoreMode { LIGHT_RESTORE_DEFAULT_ON, LIGHT_ALWAYS_OFF, LIGHT_ALWAYS_ON, + LIGHT_RESTORE_INVERTED_DEFAULT_OFF, + LIGHT_RESTORE_INVERTED_DEFAULT_ON, }; /** This class represents the communication layer between the front-end MQTT layer and the