mirror of
https://github.com/esphome/esphome.git
synced 2024-11-09 16:57:47 +01:00
[lvgl] Fix race condition involving numbers, switches etc. (#7345)
This commit is contained in:
parent
8677763492
commit
c1774c42c2
11 changed files with 33 additions and 12 deletions
|
@ -266,7 +266,10 @@ async def to_code(config):
|
|||
await add_top_layer(config)
|
||||
await msgboxes_to_code(config)
|
||||
await disp_update(f"{lv_component}->get_disp()", config)
|
||||
Widget.set_completed()
|
||||
# At this point only the setup code should be generated
|
||||
assert LvContext.added_lambda_count == 1
|
||||
Widget.set_completed()
|
||||
async with LvContext(lv_component):
|
||||
await generate_triggers(lv_component)
|
||||
for conf in config.get(CONF_ON_IDLE, ()):
|
||||
templ = await cg.templatable(conf[CONF_TIMEOUT], [], cg.uint32)
|
||||
|
|
|
@ -10,7 +10,7 @@ from ..defines import CONF_LVGL_ID, CONF_WIDGET
|
|||
from ..lvcode import EVENT_ARG, LambdaContext, LvContext
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, lv_pseudo_button_t
|
||||
from ..widgets import Widget, get_widgets
|
||||
from ..widgets import Widget, get_widgets, wait_for_widgets
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
binary_sensor_schema(BinarySensor)
|
||||
|
@ -29,6 +29,7 @@ async def to_code(config):
|
|||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
assert isinstance(widget, Widget)
|
||||
await wait_for_widgets()
|
||||
async with LambdaContext(EVENT_ARG) as pressed_ctx:
|
||||
pressed_ctx.add(sensor.publish_state(widget.is_pressed()))
|
||||
async with LvContext(paren) as ctx:
|
||||
|
|
|
@ -8,7 +8,7 @@ from ..defines import CONF_LVGL_ID
|
|||
from ..lvcode import LvContext
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LvType, lvgl_ns
|
||||
from ..widgets import get_widgets
|
||||
from ..widgets import get_widgets, wait_for_widgets
|
||||
|
||||
lv_led_t = LvType("lv_led_t")
|
||||
LVLight = lvgl_ns.class_("LVLight", LightOutput)
|
||||
|
@ -28,5 +28,6 @@ async def to_code(config):
|
|||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_LED)
|
||||
widget = widget[0]
|
||||
await wait_for_widgets()
|
||||
async with LvContext(paren) as ctx:
|
||||
ctx.add(var.set_obj(widget.obj))
|
||||
|
|
|
@ -176,6 +176,8 @@ class LvContext(LambdaContext):
|
|||
Code generation into the LVGL initialisation code (called in `setup()`)
|
||||
"""
|
||||
|
||||
added_lambda_count = 0
|
||||
|
||||
def __init__(self, lv_component, args=None):
|
||||
self.args = args or LVGL_COMP_ARG
|
||||
super().__init__(parameters=self.args)
|
||||
|
@ -183,6 +185,7 @@ class LvContext(LambdaContext):
|
|||
|
||||
async def add_init_lambda(self):
|
||||
cg.add(self.lv_component.add_init_lambda(await self.get_lambda()))
|
||||
LvContext.added_lambda_count += 1
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||
await super().__aexit__(exc_type, exc_val, exc_tb)
|
||||
|
|
|
@ -16,7 +16,7 @@ from ..lvcode import (
|
|||
)
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LvNumber, lvgl_ns
|
||||
from ..widgets import get_widgets
|
||||
from ..widgets import get_widgets, wait_for_widgets
|
||||
|
||||
LVGLNumber = lvgl_ns.class_("LVGLNumber", number.Number)
|
||||
|
||||
|
@ -44,6 +44,7 @@ async def to_code(config):
|
|||
step=widget.get_step(),
|
||||
)
|
||||
|
||||
await wait_for_widgets()
|
||||
async with LambdaContext([(cg.float_, "v")]) as control:
|
||||
await widget.set_property(
|
||||
"value", MockObj("v") * MockObj(widget.get_scale()), config[CONF_ANIMATED]
|
||||
|
|
|
@ -15,7 +15,7 @@ from ..lvcode import (
|
|||
)
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LvSelect, lvgl_ns
|
||||
from ..widgets import get_widgets
|
||||
from ..widgets import get_widgets, wait_for_widgets
|
||||
|
||||
LVGLSelect = lvgl_ns.class_("LVGLSelect", select.Select)
|
||||
|
||||
|
@ -37,6 +37,7 @@ async def to_code(config):
|
|||
options = widget.config.get(CONF_OPTIONS, [])
|
||||
selector = await select.new_select(config, options=options)
|
||||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
await wait_for_widgets()
|
||||
async with LambdaContext(EVENT_ARG) as pub_ctx:
|
||||
pub_ctx.add(selector.publish_index(widget.get_value()))
|
||||
async with LambdaContext([(cg.uint16, "v")]) as control:
|
||||
|
|
|
@ -14,7 +14,7 @@ from ..lvcode import (
|
|||
)
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LvNumber
|
||||
from ..widgets import Widget, get_widgets
|
||||
from ..widgets import Widget, get_widgets, wait_for_widgets
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
sensor_schema(Sensor)
|
||||
|
@ -33,6 +33,7 @@ async def to_code(config):
|
|||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
assert isinstance(widget, Widget)
|
||||
await wait_for_widgets()
|
||||
async with LambdaContext(EVENT_ARG) as lamb:
|
||||
lv_add(sensor.publish_state(widget.get_value()))
|
||||
async with LvContext(paren, LVGL_COMP_ARG):
|
||||
|
|
|
@ -16,7 +16,7 @@ from ..lvcode import (
|
|||
)
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LV_STATE, lv_pseudo_button_t, lvgl_ns
|
||||
from ..widgets import get_widgets
|
||||
from ..widgets import get_widgets, wait_for_widgets
|
||||
|
||||
LVGLSwitch = lvgl_ns.class_("LVGLSwitch", Switch)
|
||||
CONFIG_SCHEMA = (
|
||||
|
@ -35,6 +35,7 @@ async def to_code(config):
|
|||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
await wait_for_widgets()
|
||||
async with LambdaContext(EVENT_ARG) as checked_ctx:
|
||||
checked_ctx.add(switch.publish_state(widget.get_value()))
|
||||
async with LambdaContext([(cg.bool_, "v")]) as control:
|
||||
|
|
|
@ -15,7 +15,7 @@ from ..lvcode import (
|
|||
)
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LvText, lvgl_ns
|
||||
from ..widgets import get_widgets
|
||||
from ..widgets import get_widgets, wait_for_widgets
|
||||
|
||||
LVGLText = lvgl_ns.class_("LVGLText", text.Text)
|
||||
|
||||
|
@ -32,6 +32,7 @@ async def to_code(config):
|
|||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
await wait_for_widgets()
|
||||
async with LambdaContext([(cg.std_string, "text_value")]) as control:
|
||||
await widget.set_property("text", "text_value.c_str())")
|
||||
lv.event_send(widget.obj, API_EVENT, None)
|
||||
|
|
|
@ -10,7 +10,7 @@ from ..defines import CONF_LVGL_ID, CONF_WIDGET
|
|||
from ..lvcode import API_EVENT, EVENT_ARG, UPDATE_EVENT, LambdaContext, LvContext
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LvText
|
||||
from ..widgets import get_widgets
|
||||
from ..widgets import get_widgets, wait_for_widgets
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
text_sensor_schema(TextSensor)
|
||||
|
@ -28,6 +28,7 @@ async def to_code(config):
|
|||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
await wait_for_widgets()
|
||||
async with LambdaContext(EVENT_ARG) as pressed_ctx:
|
||||
pressed_ctx.add(sensor.publish_state(widget.get_value()))
|
||||
async with LvContext(paren) as ctx:
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import asyncio
|
||||
import sys
|
||||
from typing import Any, Union
|
||||
|
||||
|
@ -224,9 +223,17 @@ async def get_widget_(wid: Widget):
|
|||
return await FakeAwaitable(get_widget_generator(wid))
|
||||
|
||||
|
||||
def widgets_wait_generator():
|
||||
while True:
|
||||
if Widget.widgets_completed:
|
||||
return
|
||||
yield
|
||||
|
||||
|
||||
async def wait_for_widgets():
|
||||
while not Widget.widgets_completed:
|
||||
await asyncio.sleep(0)
|
||||
if Widget.widgets_completed:
|
||||
return
|
||||
await FakeAwaitable(widgets_wait_generator())
|
||||
|
||||
|
||||
async def get_widgets(config: Union[dict, list], id: str = CONF_ID) -> list[Widget]:
|
||||
|
|
Loading…
Reference in a new issue