[lvgl] Allow a binary sensor to report checked or pressed state (#16073)

Co-authored-by: J. Nick Koston <nick+github@koston.org>
This commit is contained in:
Clyde Stubbs
2026-04-28 22:00:29 +10:00
committed by GitHub
parent 876c8c4c2a
commit 52f80618d4
2 changed files with 41 additions and 9 deletions
@@ -4,15 +4,25 @@ from esphome.components.binary_sensor import (
new_binary_sensor,
)
import esphome.config_validation as cv
from esphome.const import CONF_STATE
from ..defines import CONF_WIDGET
from ..lvcode import EVENT_ARG, LambdaContext, LvContext, lvgl_static
from ..types import LV_EVENT, lv_pseudo_button_t
from ..defines import CONF_WIDGET, LV_OBJ_FLAG, LvConstant
from ..lvcode import EVENT_ARG, UPDATE_EVENT, LambdaContext, LvContext, lvgl_static
from ..types import LV_EVENT, LV_STATE, lv_pseudo_button_t
from ..widgets import Widget, get_widgets, wait_for_widgets
STATE_PRESSED = "PRESSED"
STATE_CHECKED = "CHECKED"
BS_STATE = LvConstant(
"LV_STATE_",
STATE_PRESSED,
STATE_CHECKED,
)
CONFIG_SCHEMA = binary_sensor_schema(BinarySensor).extend(
{
cv.Required(CONF_WIDGET): cv.use_id(lv_pseudo_button_t),
cv.Optional(CONF_STATE, default=STATE_PRESSED): BS_STATE.one_of,
}
)
@@ -22,16 +32,23 @@ async def to_code(config):
widget = await get_widgets(config, CONF_WIDGET)
widget = widget[0]
assert isinstance(widget, Widget)
state = await BS_STATE.process(config[CONF_STATE])
await wait_for_widgets()
async with LambdaContext(EVENT_ARG) as pressed_ctx:
pressed_ctx.add(sensor.publish_state(widget.is_pressed()))
is_pressed = str(state) == str(LV_STATE.PRESSED)
test_expr = widget.is_pressed() if is_pressed else widget.is_checked()
async with LambdaContext(EVENT_ARG) as test_ctx:
test_ctx.add(sensor.publish_state(test_expr))
async with LvContext() as ctx:
ctx.add(sensor.publish_initial_state(widget.is_pressed()))
ctx.add(sensor.publish_initial_state(test_expr))
if is_pressed:
events = [LV_EVENT.PRESSED, LV_EVENT.RELEASED]
widget.add_flag(LV_OBJ_FLAG.CLICKABLE)
else:
events = [LV_EVENT.VALUE_CHANGED, UPDATE_EVENT]
ctx.add(
lvgl_static.add_event_cb(
widget.obj,
await pressed_ctx.get_lambda(),
LV_EVENT.PRESSED,
LV_EVENT.RELEASED,
await test_ctx.get_lambda(),
*events,
)
)
+15
View File
@@ -16,10 +16,19 @@ binary_sensor:
platform: template
- id: left_sensor
platform: template
- platform: lvgl
name: Button A pressed
widget: button_a
state: pressed
- platform: lvgl
name: Button A checked
widget: button_a
state: checked
- platform: lvgl
id: button_checker
name: LVGL button
widget: button_button
state: checked
on_state:
then:
- lvgl.checkbox.update:
@@ -29,6 +38,12 @@ binary_sensor:
auto y = x; // block inlining of one line return
return y;
- platform: lvgl
id: button_presser
name: Button pressed
widget: button_button
state: pressed
lvgl:
id: lvgl_id
rotation: 90