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): |     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] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user