From dd0270207f1b356e7f275cfd8b2d8bff53451f8c Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:39:47 +1300 Subject: [PATCH] Allow pulse light effect to have separate on and off transition lengths (#5659) --- esphome/components/light/base_light_effects.h | 10 ++++--- esphome/components/light/effects.py | 30 ++++++++++++++++--- tests/test1.yaml | 14 +++++++++ 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/esphome/components/light/base_light_effects.h b/esphome/components/light/base_light_effects.h index 9211bba7c9..d126e4960c 100644 --- a/esphome/components/light/base_light_effects.h +++ b/esphome/components/light/base_light_effects.h @@ -3,8 +3,8 @@ #include #include -#include "light_effect.h" #include "esphome/core/automation.h" +#include "light_effect.h" namespace esphome { namespace light { @@ -27,8 +27,8 @@ class PulseLightEffect : public LightEffect { auto call = this->state_->turn_on(); float out = this->on_ ? this->max_brightness : this->min_brightness; call.set_brightness_if_supported(out); + call.set_transition_length_if_supported(this->on_ ? this->transition_on_length_ : this->transition_off_length_); this->on_ = !this->on_; - call.set_transition_length_if_supported(this->transition_length_); // don't tell HA every change call.set_publish(false); call.set_save(false); @@ -37,7 +37,8 @@ class PulseLightEffect : public LightEffect { this->last_color_change_ = now; } - void set_transition_length(uint32_t transition_length) { this->transition_length_ = transition_length; } + void set_transition_on_length(uint32_t transition_length) { this->transition_on_length_ = transition_length; } + void set_transition_off_length(uint32_t transition_length) { this->transition_off_length_ = transition_length; } void set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; } @@ -49,7 +50,8 @@ class PulseLightEffect : public LightEffect { protected: bool on_ = false; uint32_t last_color_change_{0}; - uint32_t transition_length_{}; + uint32_t transition_on_length_{}; + uint32_t transition_off_length_{}; uint32_t update_interval_{}; float min_brightness{0.0}; float max_brightness{1.0}; diff --git a/esphome/components/light/effects.py b/esphome/components/light/effects.py index c694d6f50c..5212e90938 100644 --- a/esphome/components/light/effects.py +++ b/esphome/components/light/effects.py @@ -76,6 +76,8 @@ CONF_ADDRESSABLE_RANDOM_TWINKLE = "addressable_random_twinkle" CONF_ADDRESSABLE_FIREWORKS = "addressable_fireworks" CONF_ADDRESSABLE_FLICKER = "addressable_flicker" CONF_AUTOMATION = "automation" +CONF_ON_LENGTH = "on_length" +CONF_OFF_LENGTH = "off_length" BINARY_EFFECTS = [] MONOCHROMATIC_EFFECTS = [] @@ -170,9 +172,15 @@ async def automation_effect_to_code(config, effect_id): PulseLightEffect, "Pulse", { - cv.Optional( - CONF_TRANSITION_LENGTH, default="1s" - ): cv.positive_time_period_milliseconds, + cv.Optional(CONF_TRANSITION_LENGTH, default="1s"): cv.Any( + cv.positive_time_period_milliseconds, + cv.Schema( + { + cv.Required(CONF_ON_LENGTH): cv.positive_time_period_milliseconds, + cv.Required(CONF_OFF_LENGTH): cv.positive_time_period_milliseconds, + } + ), + ), cv.Optional( CONF_UPDATE_INTERVAL, default="1s" ): cv.positive_time_period_milliseconds, @@ -182,7 +190,21 @@ async def automation_effect_to_code(config, effect_id): ) async def pulse_effect_to_code(config, effect_id): effect = cg.new_Pvariable(effect_id, config[CONF_NAME]) - cg.add(effect.set_transition_length(config[CONF_TRANSITION_LENGTH])) + if isinstance(config[CONF_TRANSITION_LENGTH], dict): + cg.add( + effect.set_transition_on_length( + config[CONF_TRANSITION_LENGTH][CONF_ON_LENGTH] + ) + ) + cg.add( + effect.set_transition_off_length( + config[CONF_TRANSITION_LENGTH][CONF_OFF_LENGTH] + ) + ) + else: + transition_length = config[CONF_TRANSITION_LENGTH] + cg.add(effect.set_transition_on_length(transition_length)) + cg.add(effect.set_transition_off_length(transition_length)) cg.add(effect.set_update_interval(config[CONF_UPDATE_INTERVAL])) cg.add( effect.set_min_max_brightness( diff --git a/tests/test1.yaml b/tests/test1.yaml index 7bd6dcb41d..64d1d36f52 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -2179,6 +2179,20 @@ light: state += 1; if (state == 4) state = 0; + - pulse: + transition_length: 10s + update_interval: 20s + min_brightness: 10% + max_brightness: 90% + - pulse: + name: pulse2 + transition_length: + on_length: 10s + off_length: 5s + update_interval: 15s + min_brightness: 10% + max_brightness: 90% + - platform: rgb name: Living Room Lights id: ${roomname}_lights