From 2bb86641f8827f9d6e089b9a5731e00e87bc1c03 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Tue, 15 Apr 2025 05:39:56 +1000 Subject: [PATCH] [lvgl] Ensure captured lambdas are in correct order (#8560) --- esphome/components/lvgl/automation.py | 16 ++++++++++++++-- esphome/components/lvgl/widgets/buttonmatrix.py | 4 ++-- esphome/components/lvgl/widgets/canvas.py | 10 +++++++--- esphome/components/lvgl/widgets/meter.py | 4 +++- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/esphome/components/lvgl/automation.py b/esphome/components/lvgl/automation.py index b0979b2848..4a71872022 100644 --- a/esphome/components/lvgl/automation.py +++ b/esphome/components/lvgl/automation.py @@ -4,6 +4,7 @@ from esphome import automation import esphome.codegen as cg import esphome.config_validation as cv from esphome.const import CONF_ACTION, CONF_GROUP, CONF_ID, CONF_TIMEOUT +from esphome.core import Lambda from esphome.cpp_generator import TemplateArguments, get_variable from esphome.cpp_types import nullptr @@ -64,7 +65,14 @@ async def action_to_code( action_id, template_arg, args, + config=None, ): + # Ensure all required ids have been processed, so our LambdaContext doesn't get context-switched. + if config: + for lamb in config.values(): + if isinstance(lamb, Lambda): + for id_ in lamb.requires_ids: + await get_variable(id_) await wait_for_widgets() async with LambdaContext(parameters=args, where=action_id) as context: for widget in widgets: @@ -84,7 +92,9 @@ async def update_to_code(config, action_id, template_arg, args): lv.event_send(widget.obj, UPDATE_EVENT, nullptr) widgets = await get_widgets(config[CONF_ID]) - return await action_to_code(widgets, do_update, action_id, template_arg, args) + return await action_to_code( + widgets, do_update, action_id, template_arg, args, config + ) @automation.register_condition( @@ -348,4 +358,6 @@ async def obj_update_to_code(config, action_id, template_arg, args): await set_obj_properties(widget, config) widgets = await get_widgets(config[CONF_ID]) - return await action_to_code(widgets, do_update, action_id, template_arg, args) + return await action_to_code( + widgets, do_update, action_id, template_arg, args, config + ) diff --git a/esphome/components/lvgl/widgets/buttonmatrix.py b/esphome/components/lvgl/widgets/buttonmatrix.py index c65bb4b354..0ba1fe4ae1 100644 --- a/esphome/components/lvgl/widgets/buttonmatrix.py +++ b/esphome/components/lvgl/widgets/buttonmatrix.py @@ -250,7 +250,7 @@ async def button_update_to_code(config, action_id, template_arg, args): widgets = await get_widgets(config[CONF_ID]) assert all(isinstance(w, MatrixButton) for w in widgets) - async def do_button_update(w: MatrixButton): + async def do_button_update(w): if (width := config.get(CONF_WIDTH)) is not None: lv.btnmatrix_set_btn_width(w.obj, w.index, width) if config.get(CONF_SELECTED): @@ -275,5 +275,5 @@ async def button_update_to_code(config, action_id, template_arg, args): ) return await action_to_code( - widgets, do_button_update, action_id, template_arg, args + widgets, do_button_update, action_id, template_arg, args, config ) diff --git a/esphome/components/lvgl/widgets/canvas.py b/esphome/components/lvgl/widgets/canvas.py index bc26558624..60812093d5 100644 --- a/esphome/components/lvgl/widgets/canvas.py +++ b/esphome/components/lvgl/widgets/canvas.py @@ -97,7 +97,7 @@ async def canvas_fill(config, action_id, template_arg, args): async def do_fill(w: Widget): lv.canvas_fill_bg(w.obj, color, opa) - return await action_to_code(widget, do_fill, action_id, template_arg, args) + return await action_to_code(widget, do_fill, action_id, template_arg, args, config) @automation.register_action( @@ -145,7 +145,9 @@ async def canvas_set_pixel(config, action_id, template_arg, args): x, y = point lv.canvas_set_px_opa(w.obj, x, y, opa_var) - return await action_to_code(widget, do_set_pixels, action_id, template_arg, args) + return await action_to_code( + widget, do_set_pixels, action_id, template_arg, args, config + ) DRAW_SCHEMA = cv.Schema( @@ -181,7 +183,9 @@ async def draw_to_code(config, dsc_type, props, do_draw, action_id, template_arg lv_assign(getattr(dsc, mapped_prop), value) await do_draw(w, x, y, dsc_addr) - return await action_to_code(widget, action_func, action_id, template_arg, args) + return await action_to_code( + widget, action_func, action_id, template_arg, args, config + ) RECT_PROPS = { diff --git a/esphome/components/lvgl/widgets/meter.py b/esphome/components/lvgl/widgets/meter.py index 29a382f7cf..840511da69 100644 --- a/esphome/components/lvgl/widgets/meter.py +++ b/esphome/components/lvgl/widgets/meter.py @@ -297,7 +297,9 @@ async def indicator_update_to_code(config, action_id, template_arg, args): async def set_value(w: Widget): await set_indicator_values(w.var, w.obj, config) - return await action_to_code(widget, set_value, action_id, template_arg, args) + return await action_to_code( + widget, set_value, action_id, template_arg, args, config + ) async def set_indicator_values(meter, indicator, config):