mirror of
https://github.com/esphome/esphome.git
synced 2024-11-21 22:48:10 +01:00
parent
cbc03aae80
commit
81f6750211
16 changed files with 148 additions and 76 deletions
|
@ -79,6 +79,50 @@ Color Image::get_pixel(int x, int y, Color color_on, Color color_off) const {
|
||||||
return color_off;
|
return color_off;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef USE_LVGL
|
||||||
|
lv_img_dsc_t *Image::get_lv_img_dsc() {
|
||||||
|
// lazily construct lvgl image_dsc.
|
||||||
|
if (this->dsc_.data != this->data_start_) {
|
||||||
|
this->dsc_.data = this->data_start_;
|
||||||
|
this->dsc_.header.always_zero = 0;
|
||||||
|
this->dsc_.header.reserved = 0;
|
||||||
|
this->dsc_.header.w = this->width_;
|
||||||
|
this->dsc_.header.h = this->height_;
|
||||||
|
this->dsc_.data_size = image_type_to_width_stride(this->dsc_.header.w * this->dsc_.header.h, this->get_type());
|
||||||
|
switch (this->get_type()) {
|
||||||
|
case IMAGE_TYPE_BINARY:
|
||||||
|
this->dsc_.header.cf = LV_IMG_CF_ALPHA_1BIT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IMAGE_TYPE_GRAYSCALE:
|
||||||
|
this->dsc_.header.cf = LV_IMG_CF_ALPHA_8BIT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IMAGE_TYPE_RGB24:
|
||||||
|
this->dsc_.header.cf = LV_IMG_CF_RGB888;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IMAGE_TYPE_RGB565:
|
||||||
|
#if LV_COLOR_DEPTH == 16
|
||||||
|
this->dsc_.header.cf = this->has_transparency() ? LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED : LV_IMG_CF_TRUE_COLOR;
|
||||||
|
#else
|
||||||
|
this->dsc_.header.cf = LV_IMG_CF_RGB565;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case image::IMAGE_TYPE_RGBA:
|
||||||
|
#if LV_COLOR_DEPTH == 32
|
||||||
|
this->dsc_.header.cf = LV_IMG_CF_TRUE_COLOR;
|
||||||
|
#else
|
||||||
|
this->dsc_.header.cf = LV_IMG_CF_RGBA8888;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &this->dsc_;
|
||||||
|
}
|
||||||
|
#endif // USE_LVGL
|
||||||
|
|
||||||
bool Image::get_binary_pixel_(int x, int y) const {
|
bool Image::get_binary_pixel_(int x, int y) const {
|
||||||
const uint32_t width_8 = ((this->width_ + 7u) / 8u) * 8u;
|
const uint32_t width_8 = ((this->width_ + 7u) / 8u) * 8u;
|
||||||
const uint32_t pos = x + y * width_8;
|
const uint32_t pos = x + y * width_8;
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "esphome/core/color.h"
|
#include "esphome/core/color.h"
|
||||||
#include "esphome/components/display/display_buffer.h"
|
#include "esphome/components/display/display.h"
|
||||||
|
|
||||||
|
#ifdef USE_LVGL
|
||||||
|
// required for clang-tidy
|
||||||
|
#ifndef LV_CONF_H
|
||||||
|
#define LV_CONF_SKIP 1 // NOLINT
|
||||||
|
#endif // LV_CONF_H
|
||||||
|
|
||||||
|
#include <lvgl.h>
|
||||||
|
#endif // USE_LVGL
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace image {
|
namespace image {
|
||||||
|
@ -37,7 +46,7 @@ class Image : public display::BaseImage {
|
||||||
Color get_pixel(int x, int y, Color color_on = display::COLOR_ON, Color color_off = display::COLOR_OFF) const;
|
Color get_pixel(int x, int y, Color color_on = display::COLOR_ON, Color color_off = display::COLOR_OFF) const;
|
||||||
int get_width() const override;
|
int get_width() const override;
|
||||||
int get_height() const override;
|
int get_height() const override;
|
||||||
const uint8_t *get_data_start() { return this->data_start_; }
|
const uint8_t *get_data_start() const { return this->data_start_; }
|
||||||
ImageType get_type() const;
|
ImageType get_type() const;
|
||||||
|
|
||||||
void draw(int x, int y, display::Display *display, Color color_on, Color color_off) override;
|
void draw(int x, int y, display::Display *display, Color color_on, Color color_off) override;
|
||||||
|
@ -45,6 +54,9 @@ class Image : public display::BaseImage {
|
||||||
void set_transparency(bool transparent) { transparent_ = transparent; }
|
void set_transparency(bool transparent) { transparent_ = transparent; }
|
||||||
bool has_transparency() const { return transparent_; }
|
bool has_transparency() const { return transparent_; }
|
||||||
|
|
||||||
|
#ifdef USE_LVGL
|
||||||
|
lv_img_dsc_t *get_lv_img_dsc();
|
||||||
|
#endif
|
||||||
protected:
|
protected:
|
||||||
bool get_binary_pixel_(int x, int y) const;
|
bool get_binary_pixel_(int x, int y) const;
|
||||||
Color get_rgb24_pixel_(int x, int y) const;
|
Color get_rgb24_pixel_(int x, int y) const;
|
||||||
|
@ -57,6 +69,9 @@ class Image : public display::BaseImage {
|
||||||
ImageType type_;
|
ImageType type_;
|
||||||
const uint8_t *data_start_;
|
const uint8_t *data_start_;
|
||||||
bool transparent_;
|
bool transparent_;
|
||||||
|
#ifdef USE_LVGL
|
||||||
|
lv_img_dsc_t dsc_{};
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace image
|
} // namespace image
|
||||||
|
|
|
@ -53,7 +53,7 @@ from .types import (
|
||||||
lv_style_t,
|
lv_style_t,
|
||||||
lvgl_ns,
|
lvgl_ns,
|
||||||
)
|
)
|
||||||
from .widgets import Widget, add_widgets, lv_scr_act, set_obj_properties
|
from .widgets import Widget, add_widgets, lv_scr_act, set_obj_properties, styles_used
|
||||||
from .widgets.animimg import animimg_spec
|
from .widgets.animimg import animimg_spec
|
||||||
from .widgets.arc import arc_spec
|
from .widgets.arc import arc_spec
|
||||||
from .widgets.button import button_spec
|
from .widgets.button import button_spec
|
||||||
|
@ -280,6 +280,8 @@ async def to_code(config):
|
||||||
|
|
||||||
for comp in helpers.lvgl_components_required:
|
for comp in helpers.lvgl_components_required:
|
||||||
CORE.add_define(f"USE_LVGL_{comp.upper()}")
|
CORE.add_define(f"USE_LVGL_{comp.upper()}")
|
||||||
|
if "transform_angle" in styles_used:
|
||||||
|
add_define("LV_COLOR_SCREEN_TRANSP", "1")
|
||||||
for use in helpers.lv_uses:
|
for use in helpers.lv_uses:
|
||||||
add_define(f"LV_USE_{use.upper()}")
|
add_define(f"LV_USE_{use.upper()}")
|
||||||
lv_conf_h_file = CORE.relative_src_path(LV_CONF_FILENAME)
|
lv_conf_h_file = CORE.relative_src_path(LV_CONF_FILENAME)
|
||||||
|
|
|
@ -452,6 +452,7 @@ CONF_OFFSET_Y = "offset_y"
|
||||||
CONF_ONE_CHECKED = "one_checked"
|
CONF_ONE_CHECKED = "one_checked"
|
||||||
CONF_ONE_LINE = "one_line"
|
CONF_ONE_LINE = "one_line"
|
||||||
CONF_ON_SELECT = "on_select"
|
CONF_ON_SELECT = "on_select"
|
||||||
|
CONF_OPA = "opa"
|
||||||
CONF_NEXT = "next"
|
CONF_NEXT = "next"
|
||||||
CONF_PAD_ROW = "pad_row"
|
CONF_PAD_ROW = "pad_row"
|
||||||
CONF_PAD_COLUMN = "pad_column"
|
CONF_PAD_COLUMN = "pad_column"
|
||||||
|
|
|
@ -31,7 +31,6 @@ from .defines import (
|
||||||
literal,
|
literal,
|
||||||
)
|
)
|
||||||
from .helpers import esphome_fonts_used, lv_fonts_used, requires_component
|
from .helpers import esphome_fonts_used, lv_fonts_used, requires_component
|
||||||
from .lvcode import lv_expr
|
|
||||||
from .types import lv_font_t, lv_gradient_t, lv_img_t
|
from .types import lv_font_t, lv_gradient_t, lv_img_t
|
||||||
|
|
||||||
opacity_consts = LvConstant("LV_OPA_", "TRANSP", "COVER")
|
opacity_consts = LvConstant("LV_OPA_", "TRANSP", "COVER")
|
||||||
|
@ -330,7 +329,7 @@ def image_validator(value):
|
||||||
lv_image = LValidator(
|
lv_image = LValidator(
|
||||||
image_validator,
|
image_validator,
|
||||||
lv_img_t,
|
lv_img_t,
|
||||||
retmapper=lambda x: lv_expr.img_from(MockObj(x)),
|
retmapper=lambda x: MockObj(x, "->").get_lv_img_dsc(),
|
||||||
requires="image",
|
requires="image",
|
||||||
)
|
)
|
||||||
lv_bool = LValidator(cv.boolean, cg.bool_, retmapper=literal)
|
lv_bool = LValidator(cv.boolean, cg.bool_, retmapper=literal)
|
||||||
|
|
|
@ -356,49 +356,6 @@ bool lv_is_pre_initialise() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_LVGL_IMAGE
|
|
||||||
lv_img_dsc_t *lv_img_from(image::Image *src, lv_img_dsc_t *img_dsc) {
|
|
||||||
if (img_dsc == nullptr)
|
|
||||||
img_dsc = new lv_img_dsc_t(); // NOLINT
|
|
||||||
img_dsc->header.always_zero = 0;
|
|
||||||
img_dsc->header.reserved = 0;
|
|
||||||
img_dsc->header.w = src->get_width();
|
|
||||||
img_dsc->header.h = src->get_height();
|
|
||||||
img_dsc->data = src->get_data_start();
|
|
||||||
img_dsc->data_size = image_type_to_width_stride(img_dsc->header.w * img_dsc->header.h, src->get_type());
|
|
||||||
switch (src->get_type()) {
|
|
||||||
case image::IMAGE_TYPE_BINARY:
|
|
||||||
img_dsc->header.cf = LV_IMG_CF_ALPHA_1BIT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case image::IMAGE_TYPE_GRAYSCALE:
|
|
||||||
img_dsc->header.cf = LV_IMG_CF_ALPHA_8BIT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case image::IMAGE_TYPE_RGB24:
|
|
||||||
img_dsc->header.cf = LV_IMG_CF_RGB888;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case image::IMAGE_TYPE_RGB565:
|
|
||||||
#if LV_COLOR_DEPTH == 16
|
|
||||||
img_dsc->header.cf = src->has_transparency() ? LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED : LV_IMG_CF_TRUE_COLOR;
|
|
||||||
#else
|
|
||||||
img_dsc->header.cf = LV_IMG_CF_RGB565;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case image::IMAGE_TYPE_RGBA:
|
|
||||||
#if LV_COLOR_DEPTH == 32
|
|
||||||
img_dsc->header.cf = LV_IMG_CF_TRUE_COLOR;
|
|
||||||
#else
|
|
||||||
img_dsc->header.cf = LV_IMG_CF_RGBA8888;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return img_dsc;
|
|
||||||
}
|
|
||||||
#endif // USE_LVGL_IMAGE
|
|
||||||
|
|
||||||
#ifdef USE_LVGL_ANIMIMG
|
#ifdef USE_LVGL_ANIMIMG
|
||||||
void lv_animimg_stop(lv_obj_t *obj) {
|
void lv_animimg_stop(lv_obj_t *obj) {
|
||||||
auto *animg = (lv_animimg_t *) obj;
|
auto *animg = (lv_animimg_t *) obj;
|
||||||
|
|
|
@ -102,10 +102,6 @@ class FontEngine {
|
||||||
lv_font_t lv_font_{};
|
lv_font_t lv_font_{};
|
||||||
};
|
};
|
||||||
#endif // USE_LVGL_FONT
|
#endif // USE_LVGL_FONT
|
||||||
#ifdef USE_LVGL_IMAGE
|
|
||||||
lv_img_dsc_t *lv_img_from(image::Image *src, lv_img_dsc_t *img_dsc = nullptr);
|
|
||||||
#endif // USE_LVGL_IMAGE
|
|
||||||
|
|
||||||
#ifdef USE_LVGL_ANIMIMG
|
#ifdef USE_LVGL_ANIMIMG
|
||||||
void lv_animimg_stop(lv_obj_t *obj);
|
void lv_animimg_stop(lv_obj_t *obj);
|
||||||
#endif // USE_LVGL_ANIMIMG
|
#endif // USE_LVGL_ANIMIMG
|
||||||
|
|
|
@ -52,6 +52,7 @@ from ..types import LV_STATE, LvType, WidgetType, lv_coord_t, lv_obj_t, lv_obj_t
|
||||||
EVENT_LAMB = "event_lamb__"
|
EVENT_LAMB = "event_lamb__"
|
||||||
|
|
||||||
theme_widget_map = {}
|
theme_widget_map = {}
|
||||||
|
styles_used = set()
|
||||||
|
|
||||||
|
|
||||||
class LvScrActType(WidgetType):
|
class LvScrActType(WidgetType):
|
||||||
|
@ -158,6 +159,7 @@ class Widget:
|
||||||
def set_style(self, prop, value, state):
|
def set_style(self, prop, value, state):
|
||||||
if value is None:
|
if value is None:
|
||||||
return
|
return
|
||||||
|
styles_used.add(prop)
|
||||||
lv.call(f"obj_set_style_{prop}", self.obj, value, state)
|
lv.call(f"obj_set_style_{prop}", self.obj, value, state)
|
||||||
|
|
||||||
def __type_base(self):
|
def __type_base(self):
|
||||||
|
|
|
@ -2,13 +2,12 @@ from esphome import automation
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_DURATION, CONF_ID
|
from esphome.const import CONF_DURATION, CONF_ID
|
||||||
from esphome.cpp_generator import MockObj
|
|
||||||
|
|
||||||
from ..automation import action_to_code
|
from ..automation import action_to_code
|
||||||
from ..defines import CONF_AUTO_START, CONF_MAIN, CONF_REPEAT_COUNT, CONF_SRC
|
from ..defines import CONF_AUTO_START, CONF_MAIN, CONF_REPEAT_COUNT, CONF_SRC
|
||||||
from ..helpers import lvgl_components_required
|
from ..helpers import lvgl_components_required
|
||||||
from ..lv_validation import lv_image, lv_milliseconds
|
from ..lv_validation import lv_image, lv_milliseconds
|
||||||
from ..lvcode import lv, lv_expr
|
from ..lvcode import lv
|
||||||
from ..types import LvType, ObjUpdateAction, void_ptr
|
from ..types import LvType, ObjUpdateAction, void_ptr
|
||||||
from . import Widget, WidgetType, get_widgets
|
from . import Widget, WidgetType, get_widgets
|
||||||
from .img import CONF_IMAGE
|
from .img import CONF_IMAGE
|
||||||
|
@ -63,7 +62,7 @@ class AnimimgType(WidgetType):
|
||||||
if CONF_SRC in config:
|
if CONF_SRC in config:
|
||||||
for x in config[CONF_SRC]:
|
for x in config[CONF_SRC]:
|
||||||
await cg.get_variable(x)
|
await cg.get_variable(x)
|
||||||
srcs = [lv_expr.img_from(MockObj(x)) for x in config[CONF_SRC]]
|
srcs = [await lv_image.process(x) for x in config[CONF_SRC]]
|
||||||
src_id = cg.static_const_array(config[CONF_SRC_LIST_ID], srcs)
|
src_id = cg.static_const_array(config[CONF_SRC_LIST_ID], srcs)
|
||||||
count = len(config[CONF_SRC])
|
count = len(config[CONF_SRC])
|
||||||
lv.animimg_set_src(w.obj, src_id, count)
|
lv.animimg_set_src(w.obj, src_id, count)
|
||||||
|
@ -73,7 +72,7 @@ class AnimimgType(WidgetType):
|
||||||
lv.animimg_start(w.obj)
|
lv.animimg_start(w.obj)
|
||||||
|
|
||||||
def get_uses(self):
|
def get_uses(self):
|
||||||
return CONF_IMAGE, CONF_LABEL
|
return "img", CONF_IMAGE, CONF_LABEL
|
||||||
|
|
||||||
|
|
||||||
animimg_spec = AnimimgType()
|
animimg_spec = AnimimgType()
|
||||||
|
|
|
@ -20,6 +20,7 @@ from ..defines import (
|
||||||
CONF_END_VALUE,
|
CONF_END_VALUE,
|
||||||
CONF_INDICATOR,
|
CONF_INDICATOR,
|
||||||
CONF_MAIN,
|
CONF_MAIN,
|
||||||
|
CONF_OPA,
|
||||||
CONF_PIVOT_X,
|
CONF_PIVOT_X,
|
||||||
CONF_PIVOT_Y,
|
CONF_PIVOT_Y,
|
||||||
CONF_SRC,
|
CONF_SRC,
|
||||||
|
@ -35,10 +36,11 @@ from ..lv_validation import (
|
||||||
lv_color,
|
lv_color,
|
||||||
lv_float,
|
lv_float,
|
||||||
lv_image,
|
lv_image,
|
||||||
|
opacity,
|
||||||
requires_component,
|
requires_component,
|
||||||
size,
|
size,
|
||||||
)
|
)
|
||||||
from ..lvcode import LocalVariable, lv, lv_assign, lv_expr
|
from ..lvcode import LocalVariable, lv, lv_assign, lv_expr, lv_obj
|
||||||
from ..types import LvType, ObjUpdateAction
|
from ..types import LvType, ObjUpdateAction
|
||||||
from . import Widget, WidgetType, get_widgets
|
from . import Widget, WidgetType, get_widgets
|
||||||
from .arc import CONF_ARC
|
from .arc import CONF_ARC
|
||||||
|
@ -76,6 +78,7 @@ INDICATOR_LINE_SCHEMA = cv.Schema(
|
||||||
cv.Optional(CONF_COLOR, default=0): lv_color,
|
cv.Optional(CONF_COLOR, default=0): lv_color,
|
||||||
cv.Optional(CONF_R_MOD, default=0): size,
|
cv.Optional(CONF_R_MOD, default=0): size,
|
||||||
cv.Optional(CONF_VALUE): lv_float,
|
cv.Optional(CONF_VALUE): lv_float,
|
||||||
|
cv.Optional(CONF_OPA): opacity,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
INDICATOR_IMG_SCHEMA = cv.Schema(
|
INDICATOR_IMG_SCHEMA = cv.Schema(
|
||||||
|
@ -84,6 +87,7 @@ INDICATOR_IMG_SCHEMA = cv.Schema(
|
||||||
cv.Required(CONF_PIVOT_X): pixels,
|
cv.Required(CONF_PIVOT_X): pixels,
|
||||||
cv.Required(CONF_PIVOT_Y): pixels,
|
cv.Required(CONF_PIVOT_Y): pixels,
|
||||||
cv.Optional(CONF_VALUE): lv_float,
|
cv.Optional(CONF_VALUE): lv_float,
|
||||||
|
cv.Optional(CONF_OPA): opacity,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
INDICATOR_ARC_SCHEMA = cv.Schema(
|
INDICATOR_ARC_SCHEMA = cv.Schema(
|
||||||
|
@ -94,6 +98,7 @@ INDICATOR_ARC_SCHEMA = cv.Schema(
|
||||||
cv.Exclusive(CONF_VALUE, CONF_VALUE): lv_float,
|
cv.Exclusive(CONF_VALUE, CONF_VALUE): lv_float,
|
||||||
cv.Exclusive(CONF_START_VALUE, CONF_VALUE): lv_float,
|
cv.Exclusive(CONF_START_VALUE, CONF_VALUE): lv_float,
|
||||||
cv.Optional(CONF_END_VALUE): lv_float,
|
cv.Optional(CONF_END_VALUE): lv_float,
|
||||||
|
cv.Optional(CONF_OPA): opacity,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
INDICATOR_TICKS_SCHEMA = cv.Schema(
|
INDICATOR_TICKS_SCHEMA = cv.Schema(
|
||||||
|
@ -218,9 +223,7 @@ class MeterType(WidgetType):
|
||||||
for indicator in scale_conf.get(CONF_INDICATORS, ()):
|
for indicator in scale_conf.get(CONF_INDICATORS, ()):
|
||||||
(t, v) = next(iter(indicator.items()))
|
(t, v) = next(iter(indicator.items()))
|
||||||
iid = v[CONF_ID]
|
iid = v[CONF_ID]
|
||||||
ivar = cg.new_variable(
|
ivar = cg.Pvariable(iid, cg.nullptr, type_=lv_meter_indicator_t)
|
||||||
iid, cg.nullptr, type_=lv_meter_indicator_t_ptr
|
|
||||||
)
|
|
||||||
# Enable getting the meter to which this belongs.
|
# Enable getting the meter to which this belongs.
|
||||||
wid = Widget.create(iid, var, obj_spec, v)
|
wid = Widget.create(iid, var, obj_spec, v)
|
||||||
wid.obj = ivar
|
wid.obj = ivar
|
||||||
|
@ -268,9 +271,7 @@ class MeterType(WidgetType):
|
||||||
v[CONF_PIVOT_Y],
|
v[CONF_PIVOT_Y],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
start_value = await get_start_value(v)
|
await set_indicator_values(var, ivar, v)
|
||||||
end_value = await get_end_value(v)
|
|
||||||
set_indicator_values(var, ivar, start_value, end_value)
|
|
||||||
|
|
||||||
|
|
||||||
meter_spec = MeterType()
|
meter_spec = MeterType()
|
||||||
|
@ -285,21 +286,22 @@ meter_spec = MeterType()
|
||||||
cv.Exclusive(CONF_VALUE, CONF_VALUE): lv_float,
|
cv.Exclusive(CONF_VALUE, CONF_VALUE): lv_float,
|
||||||
cv.Exclusive(CONF_START_VALUE, CONF_VALUE): lv_float,
|
cv.Exclusive(CONF_START_VALUE, CONF_VALUE): lv_float,
|
||||||
cv.Optional(CONF_END_VALUE): lv_float,
|
cv.Optional(CONF_END_VALUE): lv_float,
|
||||||
|
cv.Optional(CONF_OPA): opacity,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
async def indicator_update_to_code(config, action_id, template_arg, args):
|
async def indicator_update_to_code(config, action_id, template_arg, args):
|
||||||
widget = await get_widgets(config)
|
widget = await get_widgets(config)
|
||||||
start_value = await get_start_value(config)
|
|
||||||
end_value = await get_end_value(config)
|
|
||||||
|
|
||||||
async def set_value(w: Widget):
|
async def set_value(w: Widget):
|
||||||
set_indicator_values(w.var, w.obj, start_value, end_value)
|
await set_indicator_values(w.var, w.obj, config)
|
||||||
|
|
||||||
return await action_to_code(widget, set_value, action_id, template_arg, args)
|
return await action_to_code(widget, set_value, action_id, template_arg, args)
|
||||||
|
|
||||||
|
|
||||||
def set_indicator_values(meter, indicator, start_value, end_value):
|
async def set_indicator_values(meter, indicator, config):
|
||||||
|
start_value = await get_start_value(config)
|
||||||
|
end_value = await get_end_value(config)
|
||||||
if start_value is not None:
|
if start_value is not None:
|
||||||
if end_value is None:
|
if end_value is None:
|
||||||
lv.meter_set_indicator_value(meter, indicator, start_value)
|
lv.meter_set_indicator_value(meter, indicator, start_value)
|
||||||
|
@ -307,3 +309,6 @@ def set_indicator_values(meter, indicator, start_value, end_value):
|
||||||
lv.meter_set_indicator_start_value(meter, indicator, start_value)
|
lv.meter_set_indicator_start_value(meter, indicator, start_value)
|
||||||
if end_value is not None:
|
if end_value is not None:
|
||||||
lv.meter_set_indicator_end_value(meter, indicator, end_value)
|
lv.meter_set_indicator_end_value(meter, indicator, end_value)
|
||||||
|
if opa := config.get(CONF_OPA):
|
||||||
|
lv_assign(indicator.opa, await opacity.process(opa))
|
||||||
|
lv_obj.invalidate(meter)
|
||||||
|
|
|
@ -2,13 +2,13 @@ spi:
|
||||||
- id: spi_main_lcd
|
- id: spi_main_lcd
|
||||||
clk_pin: 16
|
clk_pin: 16
|
||||||
mosi_pin: 17
|
mosi_pin: 17
|
||||||
miso_pin: 15
|
miso_pin: 32
|
||||||
|
|
||||||
display:
|
display:
|
||||||
- platform: ili9xxx
|
- platform: ili9xxx
|
||||||
id: main_lcd
|
id: main_lcd
|
||||||
model: ili9342
|
model: ili9342
|
||||||
cs_pin: 12
|
cs_pin: 14
|
||||||
dc_pin: 13
|
dc_pin: 13
|
||||||
reset_pin: 21
|
reset_pin: 21
|
||||||
invert_colors: true
|
invert_colors: true
|
||||||
|
|
|
@ -8,8 +8,8 @@ display:
|
||||||
- platform: ili9xxx
|
- platform: ili9xxx
|
||||||
id: main_lcd
|
id: main_lcd
|
||||||
model: ili9342
|
model: ili9342
|
||||||
cs_pin: 8
|
cs_pin: 3
|
||||||
dc_pin: 9
|
dc_pin: 11
|
||||||
reset_pin: 10
|
reset_pin: 10
|
||||||
invert_colors: true
|
invert_colors: true
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ display:
|
||||||
- platform: ili9xxx
|
- platform: ili9xxx
|
||||||
id: main_lcd
|
id: main_lcd
|
||||||
model: ili9342
|
model: ili9342
|
||||||
cs_pin: 8
|
cs_pin: 3
|
||||||
dc_pin: 9
|
dc_pin: 11
|
||||||
reset_pin: 10
|
reset_pin: 10
|
||||||
invert_colors: true
|
invert_colors: true
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ spi:
|
||||||
- id: spi_main_lcd
|
- id: spi_main_lcd
|
||||||
clk_pin: 16
|
clk_pin: 16
|
||||||
mosi_pin: 17
|
mosi_pin: 17
|
||||||
miso_pin: 15
|
miso_pin: 18
|
||||||
|
|
||||||
display:
|
display:
|
||||||
- platform: ili9xxx
|
- platform: ili9xxx
|
||||||
id: main_lcd
|
id: main_lcd
|
||||||
model: ili9342
|
model: ili9342
|
||||||
cs_pin: 12
|
cs_pin: 19
|
||||||
dc_pin: 13
|
dc_pin: 13
|
||||||
reset_pin: 21
|
reset_pin: 21
|
||||||
invert_colors: true
|
invert_colors: true
|
||||||
|
|
|
@ -608,6 +608,58 @@ lvgl:
|
||||||
id: tabview_id
|
id: tabview_id
|
||||||
index: 0
|
index: 0
|
||||||
animated: true
|
animated: true
|
||||||
|
- meter:
|
||||||
|
height: 200px
|
||||||
|
width: 200px
|
||||||
|
indicator:
|
||||||
|
bg_color: 0xFF
|
||||||
|
radius: 0
|
||||||
|
bg_opa: TRANSP
|
||||||
|
text_color: 0xFFFFFF
|
||||||
|
scales:
|
||||||
|
- ticks:
|
||||||
|
width: 1
|
||||||
|
count: 61
|
||||||
|
length: 20
|
||||||
|
color: 0xFFFFFF
|
||||||
|
range_from: 0
|
||||||
|
range_to: 60
|
||||||
|
angle_range: 360
|
||||||
|
rotation: 270
|
||||||
|
indicators:
|
||||||
|
- line:
|
||||||
|
opa: 50%
|
||||||
|
id: minute_hand
|
||||||
|
color: 0xFF0000
|
||||||
|
r_mod: -1
|
||||||
|
width: 3
|
||||||
|
-
|
||||||
|
angle_range: 330
|
||||||
|
rotation: 300
|
||||||
|
range_from: 1
|
||||||
|
range_to: 12
|
||||||
|
ticks:
|
||||||
|
width: 1
|
||||||
|
count: 12
|
||||||
|
length: 1
|
||||||
|
major:
|
||||||
|
stride: 1
|
||||||
|
width: 4
|
||||||
|
length: 8
|
||||||
|
color: 0xC0C0C0
|
||||||
|
label_gap: 6
|
||||||
|
- angle_range: 360
|
||||||
|
rotation: 270
|
||||||
|
range_from: 0
|
||||||
|
range_to: 720
|
||||||
|
indicators:
|
||||||
|
- line:
|
||||||
|
id: hour_hand
|
||||||
|
value: 180
|
||||||
|
width: 4
|
||||||
|
color: 0xA0A0A0
|
||||||
|
r_mod: -20
|
||||||
|
|
||||||
font:
|
font:
|
||||||
- file: "gfonts://Roboto"
|
- file: "gfonts://Roboto"
|
||||||
id: space16
|
id: space16
|
||||||
|
|
|
@ -10,7 +10,7 @@ sensor:
|
||||||
- platform: rotary_encoder
|
- platform: rotary_encoder
|
||||||
name: "Rotary Encoder"
|
name: "Rotary Encoder"
|
||||||
id: encoder
|
id: encoder
|
||||||
pin_a: 2
|
pin_a: 3
|
||||||
pin_b: 1
|
pin_b: 1
|
||||||
internal: true
|
internal: true
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue