mirror of
https://github.com/esphome/esphome.git
synced 2025-07-29 06:36:45 +00:00
[lvgl] Add start_value to bar; make values templatable and updateable (#9056)
This commit is contained in:
parent
2a45467bf6
commit
78ec9856fb
@ -454,9 +454,13 @@ def container_validator(schema, widget_type: WidgetType):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def validator(value):
|
def validator(value):
|
||||||
result = schema
|
|
||||||
if w_sch := widget_type.schema:
|
if w_sch := widget_type.schema:
|
||||||
result = result.extend(w_sch)
|
if isinstance(w_sch, dict):
|
||||||
|
w_sch = cv.Schema(w_sch)
|
||||||
|
# order is important here to preserve extras
|
||||||
|
result = w_sch.extend(schema)
|
||||||
|
else:
|
||||||
|
result = schema
|
||||||
ltype = df.TYPE_NONE
|
ltype = df.TYPE_NONE
|
||||||
if value and (layout := value.get(df.CONF_LAYOUT)):
|
if value and (layout := value.get(df.CONF_LAYOUT)):
|
||||||
if not isinstance(layout, dict):
|
if not isinstance(layout, dict):
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_MAX_VALUE, CONF_MIN_VALUE, CONF_MODE, CONF_VALUE
|
from esphome.const import CONF_MAX_VALUE, CONF_MIN_VALUE, CONF_MODE, CONF_VALUE
|
||||||
|
|
||||||
from ..defines import BAR_MODES, CONF_ANIMATED, CONF_INDICATOR, CONF_MAIN, literal
|
from ..defines import (
|
||||||
from ..lv_validation import animated, get_start_value, lv_float
|
BAR_MODES,
|
||||||
|
CONF_ANIMATED,
|
||||||
|
CONF_INDICATOR,
|
||||||
|
CONF_MAIN,
|
||||||
|
CONF_START_VALUE,
|
||||||
|
literal,
|
||||||
|
)
|
||||||
|
from ..lv_validation import animated, lv_int
|
||||||
from ..lvcode import lv
|
from ..lvcode import lv
|
||||||
from ..types import LvNumber, NumberType
|
from ..types import LvNumber, NumberType
|
||||||
from . import Widget
|
from . import Widget
|
||||||
@ -10,22 +17,30 @@ from . import Widget
|
|||||||
# Note this file cannot be called "bar.py" because that name is disallowed.
|
# Note this file cannot be called "bar.py" because that name is disallowed.
|
||||||
|
|
||||||
CONF_BAR = "bar"
|
CONF_BAR = "bar"
|
||||||
BAR_MODIFY_SCHEMA = cv.Schema(
|
|
||||||
{
|
|
||||||
cv.Optional(CONF_VALUE): lv_float,
|
def validate_bar(config):
|
||||||
cv.Optional(CONF_ANIMATED, default=True): animated,
|
if config.get(CONF_MODE) != "LV_BAR_MODE_RANGE" and CONF_START_VALUE in config:
|
||||||
}
|
raise cv.Invalid(
|
||||||
|
f"{CONF_START_VALUE} is only allowed when {CONF_MODE} is set to 'RANGE'"
|
||||||
)
|
)
|
||||||
|
if (CONF_MIN_VALUE in config) != (CONF_MAX_VALUE in config):
|
||||||
|
raise cv.Invalid(
|
||||||
|
f"If either {CONF_MIN_VALUE} or {CONF_MAX_VALUE} is set, both must be set"
|
||||||
|
)
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
BAR_SCHEMA = cv.Schema(
|
BAR_SCHEMA = cv.Schema(
|
||||||
{
|
{
|
||||||
cv.Optional(CONF_VALUE): lv_float,
|
cv.Optional(CONF_VALUE): lv_int,
|
||||||
cv.Optional(CONF_MIN_VALUE, default=0): cv.int_,
|
cv.Optional(CONF_START_VALUE): lv_int,
|
||||||
cv.Optional(CONF_MAX_VALUE, default=100): cv.int_,
|
cv.Optional(CONF_MIN_VALUE): lv_int,
|
||||||
cv.Optional(CONF_MODE, default="NORMAL"): BAR_MODES.one_of,
|
cv.Optional(CONF_MAX_VALUE): lv_int,
|
||||||
|
cv.Optional(CONF_MODE): BAR_MODES.one_of,
|
||||||
cv.Optional(CONF_ANIMATED, default=True): animated,
|
cv.Optional(CONF_ANIMATED, default=True): animated,
|
||||||
}
|
}
|
||||||
)
|
).add_extra(validate_bar)
|
||||||
|
|
||||||
|
|
||||||
class BarType(NumberType):
|
class BarType(NumberType):
|
||||||
@ -35,17 +50,23 @@ class BarType(NumberType):
|
|||||||
LvNumber("lv_bar_t"),
|
LvNumber("lv_bar_t"),
|
||||||
parts=(CONF_MAIN, CONF_INDICATOR),
|
parts=(CONF_MAIN, CONF_INDICATOR),
|
||||||
schema=BAR_SCHEMA,
|
schema=BAR_SCHEMA,
|
||||||
modify_schema=BAR_MODIFY_SCHEMA,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def to_code(self, w: Widget, config):
|
async def to_code(self, w: Widget, config):
|
||||||
var = w.obj
|
var = w.obj
|
||||||
|
if mode := config.get(CONF_MODE):
|
||||||
|
lv.bar_set_mode(var, literal(mode))
|
||||||
|
is_animated = literal(config[CONF_ANIMATED])
|
||||||
if CONF_MIN_VALUE in config:
|
if CONF_MIN_VALUE in config:
|
||||||
lv.bar_set_range(var, config[CONF_MIN_VALUE], config[CONF_MAX_VALUE])
|
lv.bar_set_range(
|
||||||
lv.bar_set_mode(var, literal(config[CONF_MODE]))
|
var,
|
||||||
value = await get_start_value(config)
|
await lv_int.process(config[CONF_MIN_VALUE]),
|
||||||
if value is not None:
|
await lv_int.process(config[CONF_MAX_VALUE]),
|
||||||
lv.bar_set_value(var, value, literal(config[CONF_ANIMATED]))
|
)
|
||||||
|
if value := await lv_int.process(config.get(CONF_VALUE)):
|
||||||
|
lv.bar_set_value(var, value, is_animated)
|
||||||
|
if start_value := await lv_int.process(config.get(CONF_START_VALUE)):
|
||||||
|
lv.bar_set_start_value(var, start_value, is_animated)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def animated(self):
|
def animated(self):
|
||||||
|
@ -728,12 +728,15 @@ lvgl:
|
|||||||
value: 30
|
value: 30
|
||||||
max_value: 100
|
max_value: 100
|
||||||
min_value: 10
|
min_value: 10
|
||||||
|
start_value: 20
|
||||||
mode: range
|
mode: range
|
||||||
on_click:
|
on_click:
|
||||||
then:
|
then:
|
||||||
- lvgl.bar.update:
|
- lvgl.bar.update:
|
||||||
id: bar_id
|
id: bar_id
|
||||||
value: !lambda return (int)((float)rand() / RAND_MAX * 100);
|
value: !lambda return (int)((float)rand() / RAND_MAX * 100);
|
||||||
|
start_value: !lambda return (int)((float)rand() / RAND_MAX * 100);
|
||||||
|
mode: symmetrical
|
||||||
- logger.log:
|
- logger.log:
|
||||||
format: "bar value %f"
|
format: "bar value %f"
|
||||||
args: [x]
|
args: [x]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user