From 9a32b043eee81366c26bb24da81b27fd130ce7cf Mon Sep 17 00:00:00 2001 From: ChNussbaum Date: Fri, 14 Feb 2020 17:07:12 -0600 Subject: [PATCH] Add pool lights --- README.md | 2 +- TreoLedPoolLight.h | 135 +++++++++++++++++++++++++++++++++++++ patio_and_pool_lights.yaml | 72 ++++++++++++++++++++ 3 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 TreoLedPoolLight.h create mode 100644 patio_and_pool_lights.yaml diff --git a/README.md b/README.md index 6b63812..9a20c3e 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ > > * Basement Bathroom Shower Light and Heater > ### [SANA Triple Switch](https://www.amazon.com/gp/product/B07Q5XPRKD/ref=ox_sc_act_title_1?smid=A3EOKYTNCLEIKH&psc=1) -> COMING SOON! I plan to use this in conjuction with a custom light component I wrote to turn on/off and change the color of my [TREO LED Pool Lights](https://www.amazon.com/gp/product/B06XTRLM5M/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) and control my [Patio Lights](#patio-lights) which currently I don't have a way to control other than through [Home Assistant](https://www.home-assistant.io/). +> This switch will be installed in place of the switch that controls my pool lights. My pool lights are [TREO LED Pool Lights](https://www.amazon.com/gp/product/B06XTRLM5M/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1). These lights have the option to select different colors by briefly turning them off and back on again and they do remember the last color when turned on again. The custom light component handles tracking the current color and exposes custom "effects" for each of the colors to [Home Assistant](https://www.home-assistant.io/). I went with the triple switch so that I could use the third button to control my [Patio Lights](#patio-lights) which otherwise do not have a physical switch. Note I have tested the code on a [WEMOS D1 Mini clone](https://www.amazon.com/gp/product/B076F52NQD/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) but I have not installed this on the switch yet or confirmed the timings actually work with the lights yet. ## Dimmer Switches > I have been trying to find a dimmer switch I realy like to standardize on through out my home but haven't found it yet. These are the dimmers I have tried so far. diff --git a/TreoLedPoolLight.h b/TreoLedPoolLight.h new file mode 100644 index 0000000..c4b50e8 --- /dev/null +++ b/TreoLedPoolLight.h @@ -0,0 +1,135 @@ +#pragma once +#include "esphome.h" +#include "esphome/components/light/light_state.h" +#include "esphome/components/light/light_output.h" +#include "esphome/components/light/light_effect.h" + +class TreoColorLightEffect; + +class TreoLedPoolLight : public Component, public LightOutput { + public: + TreoLedPoolLight(int gpio); + LightTraits get_traits() override; + void setup_state(LightState *state) override; + void write_state(LightState *state) override; + void next_color(); + void reset(); + + protected: + friend TreoColorLightEffect; + + void set_color(int color); + + int relayGpio; + int currentColor; + ESPPreferenceObject rtc; + LightState *parent; + TreoColorLightEffect *effectSlow; + TreoColorLightEffect *effectWhite; + TreoColorLightEffect *effectBlue; + TreoColorLightEffect *effectGreen; + TreoColorLightEffect *effectRed; + TreoColorLightEffect *effectAmber; + TreoColorLightEffect *effectMagenta; + TreoColorLightEffect *effectFast; +}; + +class TreoColorLightEffect : public LightEffect { + public: + TreoColorLightEffect(TreoLedPoolLight *treo, const std::string &name, const uint32_t color); + void apply() override; + + protected: + TreoLedPoolLight *treoLight; + uint32_t effectColor; +}; + +TreoLedPoolLight::TreoLedPoolLight(int gpio) : LightOutput(), relayGpio(gpio) {} + +LightTraits TreoLedPoolLight::get_traits() { + auto traits = LightTraits(); + traits.set_supports_brightness(false); + traits.set_supports_rgb(false); + traits.set_supports_rgb_white_value(false); + traits.set_supports_color_temperature(false); + return traits; +} + +void TreoLedPoolLight::setup_state(LightState *state) { + pinMode(this->relayGpio, OUTPUT); + this->rtc = global_preferences.make_preference(1944399030U ^ 12345); + this->rtc.load(&this->currentColor); + + this->parent = state; + + this->effectSlow = new TreoColorLightEffect(this, "Slow Change", 1); + this->effectWhite = new TreoColorLightEffect(this, "White", 2); + this->effectBlue = new TreoColorLightEffect(this, "Blue", 3); + this->effectGreen = new TreoColorLightEffect(this, "Green", 4); + this->effectRed = new TreoColorLightEffect(this, "Red", 5); + this->effectAmber = new TreoColorLightEffect(this, "Amber", 6); + this->effectMagenta = new TreoColorLightEffect(this, "Magenta", 7); + this->effectFast = new TreoColorLightEffect(this, "Fast Change", 8); + state->add_effects({ this->effectSlow, this->effectWhite , this->effectBlue , this->effectGreen , this->effectRed , this->effectAmber , this->effectMagenta , this->effectFast }); +} + +void TreoLedPoolLight::write_state(LightState *state) { + bool currentState; + state->current_values_as_binary(¤tState); + digitalWrite(relayGpio, currentState); + if (currentState && state->get_effect_name() == "None") { + auto call = state->turn_on(); + call.set_effect(this->currentColor); + call.perform(); + } +} + +void TreoLedPoolLight::next_color() { + auto call = this->parent->turn_on(); + call.set_effect(this->currentColor < 8 ? this->currentColor + 1 : 1); + call.perform(); +} + +void TreoLedPoolLight::reset() { + bool currentState; + this->parent->current_values_as_binary(¤tState); + digitalWrite(relayGpio, LOW); + delay(5500); + for (int i = 0; i < 3; i++) { + digitalWrite(relayGpio, HIGH); + delay(200); + digitalWrite(relayGpio, LOW); + delay(200); + } + delay(5500); + this->currentColor = 1; + this->rtc.save(&this->currentColor); + auto call = this->parent->turn_on(); + call.set_effect(1); + call.perform(); + call = this->parent->make_call(); + call.set_state(currentState); + call.perform(); +} + +void TreoLedPoolLight::set_color(int color) { + if (this->currentColor != color) { + while (this->currentColor != color) { + digitalWrite(this->relayGpio, LOW); + delay(200); + digitalWrite(this->relayGpio, HIGH); + delay(200); + this->currentColor = this->currentColor < 8 ? this->currentColor + 1 : 1; + } + this->rtc.save(&this->currentColor); + } +} + +TreoColorLightEffect::TreoColorLightEffect(TreoLedPoolLight *treo, const std::string &name, const uint32_t color) + : LightEffect(name), treoLight(treo), effectColor(color) {} + +void TreoColorLightEffect::apply() { + this->treoLight->set_color(this->effectColor); +} + +TreoLedPoolLight *Treo; \ No newline at end of file diff --git a/patio_and_pool_lights.yaml b/patio_and_pool_lights.yaml new file mode 100644 index 0000000..e20fbd8 --- /dev/null +++ b/patio_and_pool_lights.yaml @@ -0,0 +1,72 @@ +substitutions: + device_id: pool_and_patio_lights + device_name: Pool and Patio Lights + platform: ESP8266 + board: esp01_1m + ip_address: !secret pool_and_patio_lights_ip + ota_pwd: !secret pool_and_patio_lights_ota_pwd + api_pwd: !secret pool_and_patio_lights_api_pwd + ap_wifi_pwd: !secret pool_and_patio_lights_ap_wifi_pwd + +esphome: + <<: !include common/esphome.yaml + +<<: !include common/common.yaml +<<: !include common/logger/logger_none.yaml + +binary_sensor: + - !include common/binary_sensor/status.yaml + - platform: gpio + id: patio_lights_button + pin: + number: 12 + mode: INPUT_PULLUP + on_press: + then: + - homeassistant.service: + service: homeassistant.toggle + data: + entity_id: switch.patio_lights + - platform: gpio + id: pool_lights_button + pin: + number: 5 + mode: INPUT_PULLUP + on_press: + then: + - light.toggle: pool_lights + - platform: gpio + id: color_button + pin: + number: 3 + mode: INPUT_PULLUP + on_press: + then: + - lambda: |- + Treo->next_color(); + +light: + - platform: custom + lambda: |- + Treo = new TreoLedPoolLight(15); + App.register_component(Treo); + return {Treo}; + lights: + - id: pool_lights + name: "Pool Lights" + +sensor: + - !include common/sensor/uptime.yaml + - !include common/sensor/wifi.yaml + +status_led: + pin: + number: 0 + inverted: true + +switch: + - !include common/switch/restart.yaml + +text_sensor: + - !include common/text_sensor/version.yaml + - !include common/text_sensor/wifi.yaml \ No newline at end of file