mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[lvgl] Add start_value to bar; make values templatable and updateable (#9056)
This commit is contained in:
		| @@ -454,9 +454,13 @@ def container_validator(schema, widget_type: WidgetType): | ||||
|     """ | ||||
|  | ||||
|     def validator(value): | ||||
|         result = 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 | ||||
|         if value and (layout := value.get(df.CONF_LAYOUT)): | ||||
|             if not isinstance(layout, dict): | ||||
|   | ||||
| @@ -1,8 +1,15 @@ | ||||
| import esphome.config_validation as cv | ||||
| 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 ..lv_validation import animated, get_start_value, lv_float | ||||
| from ..defines import ( | ||||
|     BAR_MODES, | ||||
|     CONF_ANIMATED, | ||||
|     CONF_INDICATOR, | ||||
|     CONF_MAIN, | ||||
|     CONF_START_VALUE, | ||||
|     literal, | ||||
| ) | ||||
| from ..lv_validation import animated, lv_int | ||||
| from ..lvcode import lv | ||||
| from ..types import LvNumber, NumberType | ||||
| from . import Widget | ||||
| @@ -10,22 +17,30 @@ from . import Widget | ||||
| # Note this file cannot be called "bar.py" because that name is disallowed. | ||||
|  | ||||
| CONF_BAR = "bar" | ||||
| BAR_MODIFY_SCHEMA = cv.Schema( | ||||
|     { | ||||
|         cv.Optional(CONF_VALUE): lv_float, | ||||
|         cv.Optional(CONF_ANIMATED, default=True): animated, | ||||
|     } | ||||
| ) | ||||
|  | ||||
|  | ||||
| def validate_bar(config): | ||||
|     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( | ||||
|     { | ||||
|         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_MODE, default="NORMAL"): BAR_MODES.one_of, | ||||
|         cv.Optional(CONF_VALUE): lv_int, | ||||
|         cv.Optional(CONF_START_VALUE): lv_int, | ||||
|         cv.Optional(CONF_MIN_VALUE): lv_int, | ||||
|         cv.Optional(CONF_MAX_VALUE): lv_int, | ||||
|         cv.Optional(CONF_MODE): BAR_MODES.one_of, | ||||
|         cv.Optional(CONF_ANIMATED, default=True): animated, | ||||
|     } | ||||
| ) | ||||
| ).add_extra(validate_bar) | ||||
|  | ||||
|  | ||||
| class BarType(NumberType): | ||||
| @@ -35,17 +50,23 @@ class BarType(NumberType): | ||||
|             LvNumber("lv_bar_t"), | ||||
|             parts=(CONF_MAIN, CONF_INDICATOR), | ||||
|             schema=BAR_SCHEMA, | ||||
|             modify_schema=BAR_MODIFY_SCHEMA, | ||||
|         ) | ||||
|  | ||||
|     async def to_code(self, w: Widget, config): | ||||
|         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: | ||||
|             lv.bar_set_range(var, config[CONF_MIN_VALUE], config[CONF_MAX_VALUE]) | ||||
|             lv.bar_set_mode(var, literal(config[CONF_MODE])) | ||||
|         value = await get_start_value(config) | ||||
|         if value is not None: | ||||
|             lv.bar_set_value(var, value, literal(config[CONF_ANIMATED])) | ||||
|             lv.bar_set_range( | ||||
|                 var, | ||||
|                 await lv_int.process(config[CONF_MIN_VALUE]), | ||||
|                 await lv_int.process(config[CONF_MAX_VALUE]), | ||||
|             ) | ||||
|         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 | ||||
|     def animated(self): | ||||
|   | ||||
| @@ -728,12 +728,15 @@ lvgl: | ||||
|             value: 30 | ||||
|             max_value: 100 | ||||
|             min_value: 10 | ||||
|             start_value: 20 | ||||
|             mode: range | ||||
|             on_click: | ||||
|               then: | ||||
|                 - lvgl.bar.update: | ||||
|                     id: bar_id | ||||
|                     value: !lambda return (int)((float)rand() / RAND_MAX * 100); | ||||
|                     start_value: !lambda return (int)((float)rand() / RAND_MAX * 100); | ||||
|                     mode: symmetrical | ||||
|                 - logger.log: | ||||
|                     format: "bar value %f" | ||||
|                     args: [x] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user