From a8032054ea38ef30409bf54177865a872e64d869 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 5 Jun 2026 10:28:50 +1200 Subject: [PATCH] [light] Pass light reference into lambda light effect (#16815) --- esphome/components/light/base_light_effects.h | 6 +++--- esphome/components/light/effects.py | 5 ++++- esphome/components/light/types.py | 1 + tests/components/light/common.yaml | 3 +++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/esphome/components/light/base_light_effects.h b/esphome/components/light/base_light_effects.h index cdb9f1f666..ba3fba6c12 100644 --- a/esphome/components/light/base_light_effects.h +++ b/esphome/components/light/base_light_effects.h @@ -111,7 +111,7 @@ class RandomLightEffect : public LightEffect { class LambdaLightEffect : public LightEffect { public: - LambdaLightEffect(const char *name, void (*f)(bool initial_run), uint32_t update_interval) + LambdaLightEffect(const char *name, void (*f)(LightState &, bool initial_run), uint32_t update_interval) : LightEffect(name), f_(f), update_interval_(update_interval) {} void start() override { this->initial_run_ = true; } @@ -119,7 +119,7 @@ class LambdaLightEffect : public LightEffect { const uint32_t now = millis(); if (now - this->last_run_ >= this->update_interval_ || this->initial_run_) { this->last_run_ = now; - this->f_(this->initial_run_); + this->f_(*this->state_, this->initial_run_); this->initial_run_ = false; } } @@ -129,7 +129,7 @@ class LambdaLightEffect : public LightEffect { uint32_t get_current_index() const { return this->get_index(); } protected: - void (*f_)(bool initial_run); + void (*f_)(LightState &, bool initial_run); uint32_t update_interval_; uint32_t last_run_{0}; bool initial_run_; diff --git a/esphome/components/light/effects.py b/esphome/components/light/effects.py index 4088a78e0d..3ae15f9ee5 100644 --- a/esphome/components/light/effects.py +++ b/esphome/components/light/effects.py @@ -51,6 +51,7 @@ from .types import ( FlickerLightEffect, LambdaLightEffect, LightColorValues, + LightStateRef, PulseLightEffect, RandomLightEffect, StrobeLightEffect, @@ -175,7 +176,9 @@ def register_addressable_effect( ) async def lambda_effect_to_code(config, effect_id): lambda_ = await cg.process_lambda( - config[CONF_LAMBDA], [(bool, "initial_run")], return_type=cg.void + config[CONF_LAMBDA], + [(LightStateRef, "it"), (bool, "initial_run")], + return_type=cg.void, ) return cg.new_Pvariable( effect_id, config[CONF_NAME], lambda_, config[CONF_UPDATE_INTERVAL] diff --git a/esphome/components/light/types.py b/esphome/components/light/types.py index c7385cbee3..9c1c7331d1 100644 --- a/esphome/components/light/types.py +++ b/esphome/components/light/types.py @@ -4,6 +4,7 @@ import esphome.codegen as cg # Base light_ns = cg.esphome_ns.namespace("light") LightState = light_ns.class_("LightState", cg.EntityBase, cg.Component) +LightStateRef = LightState.operator("ref") AddressableLightState = light_ns.class_("AddressableLightState", LightState) LightOutput = light_ns.class_("LightOutput") AddressableLight = light_ns.class_("AddressableLight", LightOutput, cg.Component) diff --git a/tests/components/light/common.yaml b/tests/components/light/common.yaml index cd9b27768e..2acc080c6d 100644 --- a/tests/components/light/common.yaml +++ b/tests/components/light/common.yaml @@ -182,6 +182,9 @@ light: state += 1; if (state == 4) state = 0; + if (initial_run) { + ESP_LOGD("custom_effect", "Effect %s started", it.get_name().c_str()); + } - pulse: transition_length: 10s update_interval: 20s