mirror of
https://github.com/esphome/esphome.git
synced 2025-09-01 10:52:19 +01:00
[lvgl] Various validation fixes (#10141)
This commit is contained in:
@@ -287,10 +287,14 @@ def angle(value):
|
||||
:param value: The input in the range 0..360
|
||||
:return: An angle in 1/10 degree units.
|
||||
"""
|
||||
return int(cv.float_range(0.0, 360.0)(cv.angle(value)) * 10)
|
||||
return cv.float_range(0.0, 360.0)(cv.angle(value))
|
||||
|
||||
|
||||
lv_angle = LValidator(angle, uint32)
|
||||
# Validator for angles in LVGL expressed in 1/10 degree units.
|
||||
lv_angle = LValidator(angle, uint32, retmapper=lambda x: int(x * 10))
|
||||
|
||||
# Validator for angles in LVGL expressed in whole degrees
|
||||
lv_angle_degrees = LValidator(angle, uint32, retmapper=int)
|
||||
|
||||
|
||||
@schema_extractor("one_of")
|
||||
|
@@ -161,7 +161,7 @@ class WidgetType:
|
||||
"""
|
||||
return []
|
||||
|
||||
def obj_creator(self, parent: MockObjClass, config: dict):
|
||||
async def obj_creator(self, parent: MockObjClass, config: dict):
|
||||
"""
|
||||
Create an instance of the widget type
|
||||
:param parent: The parent to which it should be attached
|
||||
|
@@ -439,7 +439,7 @@ async def widget_to_code(w_cnfig, w_type: WidgetType, parent):
|
||||
:return:
|
||||
"""
|
||||
spec: WidgetType = WIDGET_TYPES[w_type]
|
||||
creator = spec.obj_creator(parent, w_cnfig)
|
||||
creator = await spec.obj_creator(parent, w_cnfig)
|
||||
add_lv_use(spec.name)
|
||||
add_lv_use(*spec.get_uses())
|
||||
wid = w_cnfig[CONF_ID]
|
||||
|
@@ -20,7 +20,7 @@ from ..defines import (
|
||||
CONF_START_ANGLE,
|
||||
literal,
|
||||
)
|
||||
from ..lv_validation import angle, get_start_value, lv_float
|
||||
from ..lv_validation import get_start_value, lv_angle_degrees, lv_float, lv_int
|
||||
from ..lvcode import lv, lv_expr, lv_obj
|
||||
from ..types import LvNumber, NumberType
|
||||
from . import Widget
|
||||
@@ -29,11 +29,11 @@ CONF_ARC = "arc"
|
||||
ARC_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_VALUE): lv_float,
|
||||
cv.Optional(CONF_MIN_VALUE, default=0): cv.int_,
|
||||
cv.Optional(CONF_MAX_VALUE, default=100): cv.int_,
|
||||
cv.Optional(CONF_START_ANGLE, default=135): angle,
|
||||
cv.Optional(CONF_END_ANGLE, default=45): angle,
|
||||
cv.Optional(CONF_ROTATION, default=0.0): angle,
|
||||
cv.Optional(CONF_MIN_VALUE, default=0): lv_int,
|
||||
cv.Optional(CONF_MAX_VALUE, default=100): lv_int,
|
||||
cv.Optional(CONF_START_ANGLE, default=135): lv_angle_degrees,
|
||||
cv.Optional(CONF_END_ANGLE, default=45): lv_angle_degrees,
|
||||
cv.Optional(CONF_ROTATION, default=0.0): lv_angle_degrees,
|
||||
cv.Optional(CONF_ADJUSTABLE, default=False): bool,
|
||||
cv.Optional(CONF_MODE, default="NORMAL"): ARC_MODES.one_of,
|
||||
cv.Optional(CONF_CHANGE_RATE, default=720): cv.uint16_t,
|
||||
@@ -59,11 +59,14 @@ class ArcType(NumberType):
|
||||
|
||||
async def to_code(self, w: Widget, config):
|
||||
if CONF_MIN_VALUE in config:
|
||||
lv.arc_set_range(w.obj, config[CONF_MIN_VALUE], config[CONF_MAX_VALUE])
|
||||
lv.arc_set_bg_angles(
|
||||
w.obj, config[CONF_START_ANGLE] // 10, config[CONF_END_ANGLE] // 10
|
||||
)
|
||||
lv.arc_set_rotation(w.obj, config[CONF_ROTATION] // 10)
|
||||
max_value = await lv_int.process(config[CONF_MAX_VALUE])
|
||||
min_value = await lv_int.process(config[CONF_MIN_VALUE])
|
||||
lv.arc_set_range(w.obj, min_value, max_value)
|
||||
start = await lv_angle_degrees.process(config[CONF_START_ANGLE])
|
||||
end = await lv_angle_degrees.process(config[CONF_END_ANGLE])
|
||||
rotation = await lv_angle_degrees.process(config[CONF_ROTATION])
|
||||
lv.arc_set_bg_angles(w.obj, start, end)
|
||||
lv.arc_set_rotation(w.obj, rotation)
|
||||
lv.arc_set_mode(w.obj, literal(config[CONF_MODE]))
|
||||
lv.arc_set_change_rate(w.obj, config[CONF_CHANGE_RATE])
|
||||
|
||||
|
@@ -4,7 +4,7 @@ from esphome.const import CONF_SIZE, CONF_TEXT
|
||||
from esphome.cpp_generator import MockObjClass
|
||||
|
||||
from ..defines import CONF_MAIN
|
||||
from ..lv_validation import color, color_retmapper, lv_text
|
||||
from ..lv_validation import lv_color, lv_text
|
||||
from ..lvcode import LocalVariable, lv, lv_expr
|
||||
from ..schemas import TEXT_SCHEMA
|
||||
from ..types import WidgetType, lv_obj_t
|
||||
@@ -16,8 +16,8 @@ CONF_LIGHT_COLOR = "light_color"
|
||||
|
||||
QRCODE_SCHEMA = TEXT_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_DARK_COLOR, default="black"): color,
|
||||
cv.Optional(CONF_LIGHT_COLOR, default="white"): color,
|
||||
cv.Optional(CONF_DARK_COLOR, default="black"): lv_color,
|
||||
cv.Optional(CONF_LIGHT_COLOR, default="white"): lv_color,
|
||||
cv.Required(CONF_SIZE): cv.int_,
|
||||
}
|
||||
)
|
||||
@@ -34,11 +34,11 @@ class QrCodeType(WidgetType):
|
||||
)
|
||||
|
||||
def get_uses(self):
|
||||
return ("canvas", "img", "label")
|
||||
return "canvas", "img", "label"
|
||||
|
||||
def obj_creator(self, parent: MockObjClass, config: dict):
|
||||
dark_color = color_retmapper(config[CONF_DARK_COLOR])
|
||||
light_color = color_retmapper(config[CONF_LIGHT_COLOR])
|
||||
async def obj_creator(self, parent: MockObjClass, config: dict):
|
||||
dark_color = await lv_color.process(config[CONF_DARK_COLOR])
|
||||
light_color = await lv_color.process(config[CONF_LIGHT_COLOR])
|
||||
size = config[CONF_SIZE]
|
||||
return lv_expr.call("qrcode_create", parent, size, dark_color, light_color)
|
||||
|
||||
|
@@ -2,7 +2,7 @@ import esphome.config_validation as cv
|
||||
from esphome.cpp_generator import MockObjClass
|
||||
|
||||
from ..defines import CONF_ARC_LENGTH, CONF_INDICATOR, CONF_MAIN, CONF_SPIN_TIME
|
||||
from ..lv_validation import angle
|
||||
from ..lv_validation import lv_angle_degrees, lv_milliseconds
|
||||
from ..lvcode import lv_expr
|
||||
from ..types import LvType
|
||||
from . import Widget, WidgetType
|
||||
@@ -12,8 +12,8 @@ CONF_SPINNER = "spinner"
|
||||
|
||||
SPINNER_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ARC_LENGTH): angle,
|
||||
cv.Required(CONF_SPIN_TIME): cv.positive_time_period_milliseconds,
|
||||
cv.Required(CONF_ARC_LENGTH): lv_angle_degrees,
|
||||
cv.Required(CONF_SPIN_TIME): lv_milliseconds,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -34,9 +34,9 @@ class SpinnerType(WidgetType):
|
||||
def get_uses(self):
|
||||
return (CONF_ARC,)
|
||||
|
||||
def obj_creator(self, parent: MockObjClass, config: dict):
|
||||
spin_time = config[CONF_SPIN_TIME].total_milliseconds
|
||||
arc_length = config[CONF_ARC_LENGTH] // 10
|
||||
async def obj_creator(self, parent: MockObjClass, config: dict):
|
||||
spin_time = await lv_milliseconds.process(config[CONF_SPIN_TIME])
|
||||
arc_length = await lv_angle_degrees.process(config[CONF_ARC_LENGTH])
|
||||
return lv_expr.call("spinner_create", parent, spin_time, arc_length)
|
||||
|
||||
|
||||
|
@@ -87,12 +87,12 @@ class TabviewType(WidgetType):
|
||||
) as content_obj:
|
||||
await set_obj_properties(Widget(content_obj, obj_spec), content_style)
|
||||
|
||||
def obj_creator(self, parent: MockObjClass, config: dict):
|
||||
async def obj_creator(self, parent: MockObjClass, config: dict):
|
||||
return lv_expr.call(
|
||||
"tabview_create",
|
||||
parent,
|
||||
literal(config[CONF_POSITION]),
|
||||
literal(config[CONF_SIZE]),
|
||||
await DIRECTIONS.process(config[CONF_POSITION]),
|
||||
await size.process(config[CONF_SIZE]),
|
||||
)
|
||||
|
||||
|
||||
|
@@ -723,6 +723,20 @@ lvgl:
|
||||
arc_color: 0xFFFF00
|
||||
focused:
|
||||
arc_color: 0x808080
|
||||
- arc:
|
||||
align: center
|
||||
id: lv_arc_1
|
||||
value: !lambda return 75;
|
||||
min_value: !lambda return 50;
|
||||
max_value: !lambda return 60;
|
||||
arc_color: 0xFF0000
|
||||
indicator:
|
||||
arc_width: !lambda return 20;
|
||||
arc_color: 0xF000FF
|
||||
pressed:
|
||||
arc_color: 0xFFFF00
|
||||
focused:
|
||||
arc_color: 0x808080
|
||||
- bar:
|
||||
id: bar_id
|
||||
align: top_mid
|
||||
|
Reference in New Issue
Block a user