mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 11:47:30 +01:00
[lvgl] Final stage (#7184)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
7074fa06ae
commit
71ea2cec1f
@ -21,28 +21,10 @@ from esphome.final_validate import full_config
|
||||
from esphome.helpers import write_file_if_changed
|
||||
|
||||
from . import defines as df, helpers, lv_validation as lvalid
|
||||
from .animimg import animimg_spec
|
||||
from .arc import arc_spec
|
||||
from .automation import disp_update, update_to_code
|
||||
from .button import button_spec
|
||||
from .buttonmatrix import buttonmatrix_spec
|
||||
from .checkbox import checkbox_spec
|
||||
from .defines import CONF_SKIP
|
||||
from .dropdown import dropdown_spec
|
||||
from .img import img_spec
|
||||
from .keyboard import keyboard_spec
|
||||
from .label import label_spec
|
||||
from .led import led_spec
|
||||
from .line import line_spec
|
||||
from .lv_bar import bar_spec
|
||||
from .lv_switch import switch_spec
|
||||
from .lv_validation import lv_bool, lv_images_used
|
||||
from .lvcode import LvContext, LvglComponent
|
||||
from .meter import meter_spec
|
||||
from .msgbox import MSGBOX_SCHEMA, msgboxes_to_code
|
||||
from .obj import obj_spec
|
||||
from .page import add_pages, page_spec
|
||||
from .roller import roller_spec
|
||||
from .rotary_encoders import ROTARY_ENCODER_CONFIG, rotary_encoders_to_code
|
||||
from .schemas import (
|
||||
DISP_BG_SCHEMA,
|
||||
@ -57,13 +39,7 @@ from .schemas import (
|
||||
grid_alignments,
|
||||
obj_schema,
|
||||
)
|
||||
from .slider import slider_spec
|
||||
from .spinbox import spinbox_spec
|
||||
from .spinner import spinner_spec
|
||||
from .styles import add_top_layer, styles_to_code, theme_to_code
|
||||
from .tabview import tabview_spec
|
||||
from .textarea import textarea_spec
|
||||
from .tileview import tileview_spec
|
||||
from .touchscreens import touchscreen_schema, touchscreens_to_code
|
||||
from .trigger import generate_triggers
|
||||
from .types import (
|
||||
@ -74,7 +50,31 @@ from .types import (
|
||||
lv_style_t,
|
||||
lvgl_ns,
|
||||
)
|
||||
from .widget import Widget, add_widgets, lv_scr_act, set_obj_properties
|
||||
from .widgets import Widget, add_widgets, lv_scr_act, set_obj_properties
|
||||
from .widgets.animimg import animimg_spec
|
||||
from .widgets.arc import arc_spec
|
||||
from .widgets.button import button_spec
|
||||
from .widgets.buttonmatrix import buttonmatrix_spec
|
||||
from .widgets.checkbox import checkbox_spec
|
||||
from .widgets.dropdown import dropdown_spec
|
||||
from .widgets.img import img_spec
|
||||
from .widgets.keyboard import keyboard_spec
|
||||
from .widgets.label import label_spec
|
||||
from .widgets.led import led_spec
|
||||
from .widgets.line import line_spec
|
||||
from .widgets.lv_bar import bar_spec
|
||||
from .widgets.meter import meter_spec
|
||||
from .widgets.msgbox import MSGBOX_SCHEMA, msgboxes_to_code
|
||||
from .widgets.obj import obj_spec
|
||||
from .widgets.page import add_pages, page_spec
|
||||
from .widgets.roller import roller_spec
|
||||
from .widgets.slider import slider_spec
|
||||
from .widgets.spinbox import spinbox_spec
|
||||
from .widgets.spinner import spinner_spec
|
||||
from .widgets.switch import switch_spec
|
||||
from .widgets.tabview import tabview_spec
|
||||
from .widgets.textarea import textarea_spec
|
||||
from .widgets.tileview import tileview_spec
|
||||
|
||||
DOMAIN = "lvgl"
|
||||
DEPENDENCIES = ["display"]
|
||||
|
@ -38,7 +38,7 @@ from .types import (
|
||||
lv_disp_t,
|
||||
lv_obj_t,
|
||||
)
|
||||
from .widget import Widget, get_widgets, lv_scr_act, set_obj_properties
|
||||
from .widgets import Widget, get_widgets, lv_scr_act, set_obj_properties
|
||||
|
||||
|
||||
async def action_to_code(
|
||||
|
43
esphome/components/lvgl/binary_sensor/__init__.py
Normal file
43
esphome/components/lvgl/binary_sensor/__init__.py
Normal file
@ -0,0 +1,43 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.binary_sensor import (
|
||||
BinarySensor,
|
||||
binary_sensor_schema,
|
||||
new_binary_sensor,
|
||||
)
|
||||
import esphome.config_validation as cv
|
||||
|
||||
from ..defines import CONF_LVGL_ID, CONF_WIDGET
|
||||
from ..lvcode import EVENT_ARG, LambdaContext, LvContext
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, lv_pseudo_button_t
|
||||
from ..widgets import Widget, get_widgets
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
binary_sensor_schema(BinarySensor)
|
||||
.extend(LVGL_SCHEMA)
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_WIDGET): cv.use_id(lv_pseudo_button_t),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
sensor = await new_binary_sensor(config)
|
||||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
assert isinstance(widget, Widget)
|
||||
async with LambdaContext(EVENT_ARG) as pressed_ctx:
|
||||
pressed_ctx.add(sensor.publish_state(widget.is_pressed()))
|
||||
async with LvContext(paren) as ctx:
|
||||
ctx.add(sensor.publish_initial_state(widget.is_pressed()))
|
||||
ctx.add(
|
||||
paren.add_event_cb(
|
||||
widget.obj,
|
||||
await pressed_ctx.get_lambda(),
|
||||
LV_EVENT.PRESSING,
|
||||
LV_EVENT.RELEASED,
|
||||
)
|
||||
)
|
32
esphome/components/lvgl/light/__init__.py
Normal file
32
esphome/components/lvgl/light/__init__.py
Normal file
@ -0,0 +1,32 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import light
|
||||
from esphome.components.light import LightOutput
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_GAMMA_CORRECT, CONF_LED, CONF_OUTPUT_ID
|
||||
|
||||
from ..defines import CONF_LVGL_ID
|
||||
from ..lvcode import LvContext
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LvType, lvgl_ns
|
||||
from ..widgets import get_widgets
|
||||
|
||||
lv_led_t = LvType("lv_led_t")
|
||||
LVLight = lvgl_ns.class_("LVLight", LightOutput)
|
||||
CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_GAMMA_CORRECT, default=0.0): cv.positive_float,
|
||||
cv.Required(CONF_LED): cv.use_id(lv_led_t),
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(LVLight),
|
||||
}
|
||||
).extend(LVGL_SCHEMA)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
|
||||
await light.register_light(var, config)
|
||||
|
||||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_LED)
|
||||
widget = widget[0]
|
||||
async with LvContext(paren) as ctx:
|
||||
ctx.add(var.set_obj(widget.obj))
|
48
esphome/components/lvgl/light/lvgl_light.h
Normal file
48
esphome/components/lvgl/light/lvgl_light.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/light/light_output.h"
|
||||
#include "../lvgl_esphome.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace lvgl {
|
||||
|
||||
class LVLight : public light::LightOutput {
|
||||
public:
|
||||
light::LightTraits get_traits() override {
|
||||
auto traits = light::LightTraits();
|
||||
traits.set_supported_color_modes({light::ColorMode::RGB});
|
||||
return traits;
|
||||
}
|
||||
void write_state(light::LightState *state) override {
|
||||
float red, green, blue;
|
||||
state->current_values_as_rgb(&red, &green, &blue, false);
|
||||
auto color = lv_color_make(red * 255, green * 255, blue * 255);
|
||||
if (this->obj_ != nullptr) {
|
||||
this->set_value_(color);
|
||||
} else {
|
||||
this->initial_value_ = color;
|
||||
}
|
||||
}
|
||||
|
||||
void set_obj(lv_obj_t *obj) {
|
||||
this->obj_ = obj;
|
||||
if (this->initial_value_) {
|
||||
lv_led_set_color(obj, this->initial_value_.value());
|
||||
lv_led_on(obj);
|
||||
this->initial_value_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void set_value_(lv_color_t value) {
|
||||
lv_led_set_color(this->obj_, value);
|
||||
lv_led_on(this->obj_);
|
||||
lv_event_send(this->obj_, lv_custom_event, nullptr);
|
||||
}
|
||||
lv_obj_t *obj_{};
|
||||
optional<lv_color_t> initial_value_{};
|
||||
};
|
||||
|
||||
} // namespace lvgl
|
||||
} // namespace esphome
|
@ -1,13 +1,6 @@
|
||||
#pragma once
|
||||
#include "esphome/core/defines.h"
|
||||
|
||||
#ifdef USE_LVGL_BINARY_SENSOR
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#endif // USE_LVGL_BINARY_SENSOR
|
||||
#ifdef USE_LVGL_ROTARY_ENCODER
|
||||
#include "esphome/components/rotary_encoder/rotary_encoder.h"
|
||||
#endif // USE_LVGL_ROTARY_ENCODER
|
||||
|
||||
// required for clang-tidy
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_SKIP 1 // NOLINT
|
||||
@ -19,6 +12,12 @@
|
||||
#include "esphome/core/log.h"
|
||||
#include <lvgl.h>
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_LVGL_ROTARY_ENCODER
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#include "esphome/components/rotary_encoder/rotary_encoder.h"
|
||||
#endif // USE_LVGL_ROTARY_ENCODER
|
||||
|
||||
#ifdef USE_LVGL_IMAGE
|
||||
#include "esphome/components/image/image.h"
|
||||
#endif // USE_LVGL_IMAGE
|
||||
|
52
esphome/components/lvgl/number/__init__.py
Normal file
52
esphome/components/lvgl/number/__init__.py
Normal file
@ -0,0 +1,52 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import number
|
||||
import esphome.config_validation as cv
|
||||
from esphome.cpp_generator import MockObj
|
||||
|
||||
from ..defines import CONF_ANIMATED, CONF_LVGL_ID, CONF_WIDGET
|
||||
from ..lv_validation import animated
|
||||
from ..lvcode import CUSTOM_EVENT, EVENT_ARG, LambdaContext, LvContext, lv, lv_add
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LvNumber, lvgl_ns
|
||||
from ..widgets import get_widgets
|
||||
|
||||
LVGLNumber = lvgl_ns.class_("LVGLNumber", number.Number)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
number.number_schema(LVGLNumber)
|
||||
.extend(LVGL_SCHEMA)
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_WIDGET): cv.use_id(LvNumber),
|
||||
cv.Optional(CONF_ANIMATED, default=True): animated,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
var = await number.new_number(
|
||||
config,
|
||||
max_value=widget.get_max(),
|
||||
min_value=widget.get_min(),
|
||||
step=widget.get_step(),
|
||||
)
|
||||
|
||||
async with LambdaContext([(cg.float_, "v")]) as control:
|
||||
await widget.set_property(
|
||||
"value", MockObj("v") * MockObj(widget.get_scale()), config[CONF_ANIMATED]
|
||||
)
|
||||
lv.event_send(widget.obj, CUSTOM_EVENT, cg.nullptr)
|
||||
async with LambdaContext(EVENT_ARG) as event:
|
||||
event.add(var.publish_state(widget.get_value()))
|
||||
async with LvContext(paren):
|
||||
lv_add(var.set_control_lambda(await control.get_lambda()))
|
||||
lv_add(
|
||||
paren.add_event_cb(
|
||||
widget.obj, await event.get_lambda(), LV_EVENT.VALUE_CHANGED
|
||||
)
|
||||
)
|
||||
lv_add(var.publish_state(widget.get_value()))
|
33
esphome/components/lvgl/number/lvgl_number.h
Normal file
33
esphome/components/lvgl/number/lvgl_number.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace lvgl {
|
||||
|
||||
class LVGLNumber : public number::Number {
|
||||
public:
|
||||
void set_control_lambda(std::function<void(float)> control_lambda) {
|
||||
this->control_lambda_ = control_lambda;
|
||||
if (this->initial_state_.has_value()) {
|
||||
this->control_lambda_(this->initial_state_.value());
|
||||
this->initial_state_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void control(float value) {
|
||||
if (this->control_lambda_ != nullptr)
|
||||
this->control_lambda_(value);
|
||||
else
|
||||
this->initial_state_ = value;
|
||||
}
|
||||
std::function<void(float)> control_lambda_{};
|
||||
optional<float> initial_state_{};
|
||||
};
|
||||
|
||||
} // namespace lvgl
|
||||
} // namespace esphome
|
@ -16,7 +16,7 @@ from .helpers import lvgl_components_required
|
||||
from .lvcode import lv, lv_add, lv_expr
|
||||
from .schemas import ENCODER_SCHEMA
|
||||
from .types import lv_indev_type_t
|
||||
from .widget import add_group
|
||||
from .widgets import add_group
|
||||
|
||||
ROTARY_ENCODER_CONFIG = cv.ensure_list(
|
||||
ENCODER_SCHEMA.extend(
|
||||
|
46
esphome/components/lvgl/select/__init__.py
Normal file
46
esphome/components/lvgl/select/__init__.py
Normal file
@ -0,0 +1,46 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import select
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_OPTIONS
|
||||
|
||||
from ..defines import CONF_ANIMATED, CONF_LVGL_ID, CONF_WIDGET
|
||||
from ..lvcode import CUSTOM_EVENT, EVENT_ARG, LambdaContext, LvContext, lv, lv_add
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LvSelect, lvgl_ns
|
||||
from ..widgets import get_widgets
|
||||
|
||||
LVGLSelect = lvgl_ns.class_("LVGLSelect", select.Select)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
select.select_schema(LVGLSelect)
|
||||
.extend(LVGL_SCHEMA)
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_WIDGET): cv.use_id(LvSelect),
|
||||
cv.Optional(CONF_ANIMATED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
options = widget.config.get(CONF_OPTIONS, [])
|
||||
selector = await select.new_select(config, options=options)
|
||||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
async with LambdaContext(EVENT_ARG) as pub_ctx:
|
||||
pub_ctx.add(selector.publish_index(widget.get_value()))
|
||||
async with LambdaContext([(cg.uint16, "v")]) as control:
|
||||
await widget.set_property("selected", "v", animated=config[CONF_ANIMATED])
|
||||
lv.event_send(widget.obj, CUSTOM_EVENT, cg.nullptr)
|
||||
async with LvContext(paren) as ctx:
|
||||
lv_add(selector.set_control_lambda(await control.get_lambda()))
|
||||
ctx.add(
|
||||
paren.add_event_cb(
|
||||
widget.obj,
|
||||
await pub_ctx.get_lambda(),
|
||||
LV_EVENT.VALUE_CHANGED,
|
||||
)
|
||||
)
|
||||
lv_add(selector.publish_index(widget.get_value()))
|
62
esphome/components/lvgl/select/lvgl_select.h
Normal file
62
esphome/components/lvgl/select/lvgl_select.h
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace lvgl {
|
||||
|
||||
static std::vector<std::string> split_string(const std::string &str) {
|
||||
std::vector<std::string> strings;
|
||||
auto delimiter = std::string("\n");
|
||||
|
||||
std::string::size_type pos;
|
||||
std::string::size_type prev = 0;
|
||||
while ((pos = str.find(delimiter, prev)) != std::string::npos) {
|
||||
strings.push_back(str.substr(prev, pos - prev));
|
||||
prev = pos + delimiter.size();
|
||||
}
|
||||
|
||||
// To get the last substring (or only, if delimiter is not found)
|
||||
strings.push_back(str.substr(prev));
|
||||
|
||||
return strings;
|
||||
}
|
||||
|
||||
class LVGLSelect : public select::Select {
|
||||
public:
|
||||
void set_control_lambda(std::function<void(size_t)> lambda) {
|
||||
this->control_lambda_ = lambda;
|
||||
if (this->initial_state_.has_value()) {
|
||||
this->control(this->initial_state_.value());
|
||||
this->initial_state_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void publish_index(size_t index) {
|
||||
auto value = this->at(index);
|
||||
if (value)
|
||||
this->publish_state(value.value());
|
||||
}
|
||||
|
||||
void set_options(const char *str) { this->traits.set_options(split_string(str)); }
|
||||
|
||||
protected:
|
||||
void control(const std::string &value) override {
|
||||
if (this->control_lambda_ != nullptr) {
|
||||
auto index = index_of(value);
|
||||
if (index)
|
||||
this->control_lambda_(index.value());
|
||||
} else {
|
||||
this->initial_state_ = value.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
std::function<void(size_t)> control_lambda_{};
|
||||
optional<const char *> initial_state_{};
|
||||
};
|
||||
|
||||
} // namespace lvgl
|
||||
} // namespace esphome
|
35
esphome/components/lvgl/sensor/__init__.py
Normal file
35
esphome/components/lvgl/sensor/__init__.py
Normal file
@ -0,0 +1,35 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.sensor import Sensor, new_sensor, sensor_schema
|
||||
import esphome.config_validation as cv
|
||||
|
||||
from ..defines import CONF_LVGL_ID, CONF_WIDGET
|
||||
from ..lvcode import EVENT_ARG, LVGL_COMP_ARG, LambdaContext, LvContext, lv_add
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LvNumber
|
||||
from ..widgets import Widget, get_widgets
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
sensor_schema(Sensor)
|
||||
.extend(LVGL_SCHEMA)
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_WIDGET): cv.use_id(LvNumber),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
sensor = await new_sensor(config)
|
||||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
assert isinstance(widget, Widget)
|
||||
async with LambdaContext(EVENT_ARG) as lamb:
|
||||
lv_add(sensor.publish_state(widget.get_value()))
|
||||
async with LvContext(paren, LVGL_COMP_ARG):
|
||||
lv_add(
|
||||
paren.add_event_cb(
|
||||
widget.obj, await lamb.get_lambda(), LV_EVENT.VALUE_CHANGED
|
||||
)
|
||||
)
|
@ -12,10 +12,10 @@ from .defines import (
|
||||
)
|
||||
from .helpers import add_lv_use
|
||||
from .lvcode import LambdaContext, LocalVariable, lv, lv_assign, lv_variable
|
||||
from .obj import obj_spec
|
||||
from .schemas import ALL_STYLES
|
||||
from .types import lv_lambda_t, lv_obj_t, lv_obj_t_ptr
|
||||
from .widget import Widget, add_widgets, set_obj_properties, theme_widget_map
|
||||
from .widgets import Widget, add_widgets, set_obj_properties, theme_widget_map
|
||||
from .widgets.obj import obj_spec
|
||||
|
||||
TOP_LAYER = literal("lv_disp_get_layer_top(lv_component->get_disp())")
|
||||
|
||||
|
54
esphome/components/lvgl/switch/__init__.py
Normal file
54
esphome/components/lvgl/switch/__init__.py
Normal file
@ -0,0 +1,54 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.switch import Switch, new_switch, switch_schema
|
||||
import esphome.config_validation as cv
|
||||
from esphome.cpp_generator import MockObj
|
||||
|
||||
from ..defines import CONF_LVGL_ID, CONF_WIDGET
|
||||
from ..lvcode import (
|
||||
CUSTOM_EVENT,
|
||||
EVENT_ARG,
|
||||
LambdaContext,
|
||||
LvConditional,
|
||||
LvContext,
|
||||
lv,
|
||||
lv_add,
|
||||
)
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LV_STATE, lv_pseudo_button_t, lvgl_ns
|
||||
from ..widgets import get_widgets
|
||||
|
||||
LVGLSwitch = lvgl_ns.class_("LVGLSwitch", Switch)
|
||||
CONFIG_SCHEMA = (
|
||||
switch_schema(LVGLSwitch)
|
||||
.extend(LVGL_SCHEMA)
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_WIDGET): cv.use_id(lv_pseudo_button_t),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
switch = await new_switch(config)
|
||||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
async with LambdaContext(EVENT_ARG) as checked_ctx:
|
||||
checked_ctx.add(switch.publish_state(widget.get_value()))
|
||||
async with LambdaContext([(cg.bool_, "v")]) as control:
|
||||
with LvConditional(MockObj("v")) as cond:
|
||||
widget.add_state(LV_STATE.CHECKED)
|
||||
cond.else_()
|
||||
widget.clear_state(LV_STATE.CHECKED)
|
||||
lv.event_send(widget.obj, CUSTOM_EVENT, cg.nullptr)
|
||||
async with LvContext(paren) as ctx:
|
||||
lv_add(switch.set_control_lambda(await control.get_lambda()))
|
||||
ctx.add(
|
||||
paren.add_event_cb(
|
||||
widget.obj,
|
||||
await checked_ctx.get_lambda(),
|
||||
LV_EVENT.VALUE_CHANGED,
|
||||
)
|
||||
)
|
||||
lv_add(switch.publish_state(widget.get_value()))
|
33
esphome/components/lvgl/switch/lvgl_switch.h
Normal file
33
esphome/components/lvgl/switch/lvgl_switch.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/switch/switch.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace lvgl {
|
||||
|
||||
class LVGLSwitch : public switch_::Switch {
|
||||
public:
|
||||
void set_control_lambda(std::function<void(bool)> state_lambda) {
|
||||
this->state_lambda_ = state_lambda;
|
||||
if (this->initial_state_.has_value()) {
|
||||
this->state_lambda_(this->initial_state_.value());
|
||||
this->initial_state_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void write_state(bool value) {
|
||||
if (this->state_lambda_ != nullptr)
|
||||
this->state_lambda_(value);
|
||||
else
|
||||
this->initial_state_ = value;
|
||||
}
|
||||
std::function<void(bool)> state_lambda_{};
|
||||
optional<bool> initial_state_{};
|
||||
};
|
||||
|
||||
} // namespace lvgl
|
||||
} // namespace esphome
|
39
esphome/components/lvgl/text/__init__.py
Normal file
39
esphome/components/lvgl/text/__init__.py
Normal file
@ -0,0 +1,39 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import text
|
||||
from esphome.components.text import new_text
|
||||
import esphome.config_validation as cv
|
||||
|
||||
from ..defines import CONF_LVGL_ID, CONF_WIDGET
|
||||
from ..lvcode import CUSTOM_EVENT, EVENT_ARG, LambdaContext, LvContext, lv, lv_add
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LvText, lvgl_ns
|
||||
from ..widgets import get_widgets
|
||||
|
||||
LVGLText = lvgl_ns.class_("LVGLText", text.Text)
|
||||
|
||||
CONFIG_SCHEMA = text.TEXT_SCHEMA.extend(LVGL_SCHEMA).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(LVGLText),
|
||||
cv.Required(CONF_WIDGET): cv.use_id(LvText),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
textvar = await new_text(config)
|
||||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
async with LambdaContext([(cg.std_string, "text_value")]) as control:
|
||||
await widget.set_property("text", "text_value.c_str())")
|
||||
lv.event_send(widget.obj, CUSTOM_EVENT, None)
|
||||
async with LambdaContext(EVENT_ARG) as lamb:
|
||||
lv_add(textvar.publish_state(widget.get_value()))
|
||||
async with LvContext(paren):
|
||||
widget.var.set_control_lambda(await control.get_lambda())
|
||||
lv_add(
|
||||
paren.add_event_cb(
|
||||
widget.obj, await lamb.get_lambda(), LV_EVENT.VALUE_CHANGED
|
||||
)
|
||||
)
|
||||
lv_add(textvar.publish_state(widget.get_value()))
|
33
esphome/components/lvgl/text/lvgl_text.h
Normal file
33
esphome/components/lvgl/text/lvgl_text.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/text/text.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace lvgl {
|
||||
|
||||
class LVGLText : public text::Text {
|
||||
public:
|
||||
void set_control_lambda(std::function<void(const std::string)> control_lambda) {
|
||||
this->control_lambda_ = control_lambda;
|
||||
if (this->initial_state_.has_value()) {
|
||||
this->control_lambda_(this->initial_state_.value());
|
||||
this->initial_state_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void control(const std::string &value) {
|
||||
if (this->control_lambda_ != nullptr)
|
||||
this->control_lambda_(value);
|
||||
else
|
||||
this->initial_state_ = value;
|
||||
}
|
||||
std::function<void(const std::string)> control_lambda_{};
|
||||
optional<std::string> initial_state_{};
|
||||
};
|
||||
|
||||
} // namespace lvgl
|
||||
} // namespace esphome
|
40
esphome/components/lvgl/text_sensor/__init__.py
Normal file
40
esphome/components/lvgl/text_sensor/__init__.py
Normal file
@ -0,0 +1,40 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.text_sensor import (
|
||||
TextSensor,
|
||||
new_text_sensor,
|
||||
text_sensor_schema,
|
||||
)
|
||||
import esphome.config_validation as cv
|
||||
|
||||
from ..defines import CONF_LVGL_ID, CONF_WIDGET
|
||||
from ..lvcode import EVENT_ARG, LambdaContext, LvContext
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LV_EVENT, LvText
|
||||
from ..widgets import get_widgets
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
text_sensor_schema(TextSensor)
|
||||
.extend(LVGL_SCHEMA)
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_WIDGET): cv.use_id(LvText),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
sensor = await new_text_sensor(config)
|
||||
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
||||
widget = await get_widgets(config, CONF_WIDGET)
|
||||
widget = widget[0]
|
||||
async with LambdaContext(EVENT_ARG) as pressed_ctx:
|
||||
pressed_ctx.add(sensor.publish_state(widget.get_value()))
|
||||
async with LvContext(paren) as ctx:
|
||||
ctx.add(
|
||||
paren.add_event_cb(
|
||||
widget.obj,
|
||||
await pressed_ctx.get_lambda(),
|
||||
LV_EVENT.VALUE_CHANGED,
|
||||
)
|
||||
)
|
@ -34,7 +34,7 @@ def touchscreen_schema(config):
|
||||
|
||||
|
||||
async def touchscreens_to_code(var, config):
|
||||
for tconf in config.get(CONF_TOUCHSCREENS) or ():
|
||||
for tconf in config.get(CONF_TOUCHSCREENS, ()):
|
||||
lvgl_components_required.add(CONF_TOUCHSCREEN)
|
||||
touchscreen = await cg.get_variable(tconf[CONF_TOUCHSCREEN_ID])
|
||||
lpt = tconf[CONF_LONG_PRESS_TIME].total_milliseconds
|
||||
|
@ -13,7 +13,7 @@ from .defines import (
|
||||
)
|
||||
from .lvcode import EVENT_ARG, LambdaContext, LvConditional, lv, lv_add
|
||||
from .types import LV_EVENT
|
||||
from .widget import widget_map
|
||||
from .widgets import widget_map
|
||||
|
||||
|
||||
async def generate_triggers(lv_component):
|
||||
|
@ -8,7 +8,7 @@ from esphome.core import ID, TimePeriod
|
||||
from esphome.coroutine import FakeAwaitable
|
||||
from esphome.cpp_generator import AssignmentExpression, CallExpression, MockObj
|
||||
|
||||
from .defines import (
|
||||
from ..defines import (
|
||||
CONF_DEFAULT,
|
||||
CONF_FLEX_ALIGN_CROSS,
|
||||
CONF_FLEX_ALIGN_MAIN,
|
||||
@ -32,8 +32,8 @@ from .defines import (
|
||||
join_enums,
|
||||
literal,
|
||||
)
|
||||
from .helpers import add_lv_use
|
||||
from .lvcode import (
|
||||
from ..helpers import add_lv_use
|
||||
from ..lvcode import (
|
||||
LvConditional,
|
||||
add_line_marks,
|
||||
lv,
|
||||
@ -43,8 +43,8 @@ from .lvcode import (
|
||||
lv_obj,
|
||||
lv_Pvariable,
|
||||
)
|
||||
from .schemas import ALL_STYLES, STYLE_REMAP, WIDGET_TYPES
|
||||
from .types import (
|
||||
from ..schemas import ALL_STYLES, STYLE_REMAP, WIDGET_TYPES
|
||||
from ..types import (
|
||||
LV_STATE,
|
||||
LvType,
|
||||
WidgetType,
|
||||
@ -368,7 +368,7 @@ async def add_widgets(parent: Widget, config: dict):
|
||||
:param config: The configuration
|
||||
:return:
|
||||
"""
|
||||
for w in config.get(CONF_WIDGETS) or ():
|
||||
for w in config.get(CONF_WIDGETS, ()):
|
||||
w_type, w_cnfig = next(iter(w.items()))
|
||||
await widget_to_code(w_cnfig, w_type, parent.obj)
|
||||
|
@ -4,15 +4,15 @@ import esphome.config_validation as cv
|
||||
from esphome.const import CONF_DURATION, CONF_ID
|
||||
from esphome.cpp_generator import MockObj
|
||||
|
||||
from .automation import action_to_code
|
||||
from .defines import CONF_AUTO_START, CONF_MAIN, CONF_REPEAT_COUNT, CONF_SRC
|
||||
from .helpers import lvgl_components_required
|
||||
from ..automation import action_to_code
|
||||
from ..defines import CONF_AUTO_START, CONF_MAIN, CONF_REPEAT_COUNT, CONF_SRC
|
||||
from ..helpers import lvgl_components_required
|
||||
from ..lv_validation import lv_image, lv_milliseconds
|
||||
from ..lvcode import lv, lv_expr
|
||||
from ..types import LvType, ObjUpdateAction, void_ptr
|
||||
from . import Widget, WidgetType, get_widgets
|
||||
from .img import CONF_IMAGE
|
||||
from .label import CONF_LABEL
|
||||
from .lv_validation import lv_image, lv_milliseconds
|
||||
from .lvcode import lv, lv_expr
|
||||
from .types import LvType, ObjUpdateAction, void_ptr
|
||||
from .widget import Widget, WidgetType, get_widgets
|
||||
|
||||
CONF_ANIMIMG = "animimg"
|
||||
CONF_SRC_LIST_ID = "src_list_id"
|
@ -8,7 +8,7 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.cpp_types import nullptr
|
||||
|
||||
from .defines import (
|
||||
from ..defines import (
|
||||
ARC_MODES,
|
||||
CONF_ADJUSTABLE,
|
||||
CONF_CHANGE_RATE,
|
||||
@ -19,10 +19,10 @@ from .defines import (
|
||||
CONF_START_ANGLE,
|
||||
literal,
|
||||
)
|
||||
from .lv_validation import angle, get_start_value, lv_float
|
||||
from .lvcode import lv, lv_obj
|
||||
from .types import LvNumber, NumberType
|
||||
from .widget import Widget
|
||||
from ..lv_validation import angle, get_start_value, lv_float
|
||||
from ..lvcode import lv, lv_obj
|
||||
from ..types import LvNumber, NumberType
|
||||
from . import Widget
|
||||
|
||||
CONF_ARC = "arc"
|
||||
ARC_SCHEMA = cv.Schema(
|
@ -1,7 +1,7 @@
|
||||
from esphome.const import CONF_BUTTON
|
||||
|
||||
from .defines import CONF_MAIN
|
||||
from .types import LvBoolean, WidgetType
|
||||
from ..defines import CONF_MAIN
|
||||
from ..types import LvBoolean, WidgetType
|
||||
|
||||
lv_button_t = LvBoolean("lv_btn_t")
|
||||
|
@ -5,9 +5,8 @@ import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_WIDTH
|
||||
from esphome.cpp_generator import MockObj
|
||||
|
||||
from .automation import action_to_code
|
||||
from .button import lv_button_t
|
||||
from .defines import (
|
||||
from ..automation import action_to_code
|
||||
from ..defines import (
|
||||
BUTTONMATRIX_CTRLS,
|
||||
CONF_BUTTONS,
|
||||
CONF_CONTROL,
|
||||
@ -19,11 +18,11 @@ from .defines import (
|
||||
CONF_SELECTED,
|
||||
CONF_TEXT,
|
||||
)
|
||||
from .helpers import lvgl_components_required
|
||||
from .lv_validation import key_code, lv_bool
|
||||
from .lvcode import lv, lv_add, lv_expr
|
||||
from .schemas import automation_schema
|
||||
from .types import (
|
||||
from ..helpers import lvgl_components_required
|
||||
from ..lv_validation import key_code, lv_bool
|
||||
from ..lvcode import lv, lv_add, lv_expr
|
||||
from ..schemas import automation_schema
|
||||
from ..types import (
|
||||
LV_BTNMATRIX_CTRL,
|
||||
LV_STATE,
|
||||
LvBoolean,
|
||||
@ -33,7 +32,8 @@ from .types import (
|
||||
char_ptr,
|
||||
lv_pseudo_button_t,
|
||||
)
|
||||
from .widget import Widget, WidgetType, get_widgets, widget_map
|
||||
from . import Widget, WidgetType, get_widgets, widget_map
|
||||
from .button import lv_button_t
|
||||
|
||||
CONF_BUTTONMATRIX = "buttonmatrix"
|
||||
CONF_BUTTON_TEXT_LIST_ID = "button_text_list_id"
|
||||
@ -151,7 +151,7 @@ async def get_button_data(config, buttonmatrix: Widget):
|
||||
width_list = []
|
||||
key_list = []
|
||||
for row in config:
|
||||
for button_conf in row.get(CONF_BUTTONS) or ():
|
||||
for button_conf in row.get(CONF_BUTTONS, ()):
|
||||
bid = button_conf[CONF_ID]
|
||||
index = len(width_list)
|
||||
MatrixButton.create_button(bid, buttonmatrix, button_conf, index)
|
@ -1,9 +1,9 @@
|
||||
from .defines import CONF_INDICATOR, CONF_MAIN, CONF_TEXT
|
||||
from .lv_validation import lv_text
|
||||
from .lvcode import lv
|
||||
from .schemas import TEXT_SCHEMA
|
||||
from .types import LvBoolean
|
||||
from .widget import Widget, WidgetType
|
||||
from ..defines import CONF_INDICATOR, CONF_MAIN, CONF_TEXT
|
||||
from ..lv_validation import lv_text
|
||||
from ..lvcode import lv
|
||||
from ..schemas import TEXT_SCHEMA
|
||||
from ..types import LvBoolean
|
||||
from . import Widget, WidgetType
|
||||
|
||||
CONF_CHECKBOX = "checkbox"
|
||||
|
@ -2,7 +2,7 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_OPTIONS
|
||||
|
||||
from .defines import (
|
||||
from ..defines import (
|
||||
CONF_DIR,
|
||||
CONF_INDICATOR,
|
||||
CONF_MAIN,
|
||||
@ -11,12 +11,12 @@ from .defines import (
|
||||
DIRECTIONS,
|
||||
literal,
|
||||
)
|
||||
from ..lv_validation import lv_int, lv_text, option_string
|
||||
from ..lvcode import LocalVariable, lv, lv_expr
|
||||
from ..schemas import part_schema
|
||||
from ..types import LvSelect, LvType, lv_obj_t
|
||||
from . import Widget, WidgetType, set_obj_properties
|
||||
from .label import CONF_LABEL
|
||||
from .lv_validation import lv_int, lv_text, option_string
|
||||
from .lvcode import LocalVariable, lv, lv_expr
|
||||
from .schemas import part_schema
|
||||
from .types import LvSelect, LvType, lv_obj_t
|
||||
from .widget import Widget, WidgetType, set_obj_properties
|
||||
|
||||
CONF_DROPDOWN = "dropdown"
|
||||
CONF_DROPDOWN_LIST = "dropdown_list"
|
@ -1,7 +1,7 @@
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ANGLE, CONF_MODE
|
||||
|
||||
from .defines import (
|
||||
from ..defines import (
|
||||
CONF_ANTIALIAS,
|
||||
CONF_MAIN,
|
||||
CONF_OFFSET_X,
|
||||
@ -12,11 +12,11 @@ from .defines import (
|
||||
CONF_ZOOM,
|
||||
LvConstant,
|
||||
)
|
||||
from ..lv_validation import angle, lv_bool, lv_image, size, zoom
|
||||
from ..lvcode import lv
|
||||
from ..types import lv_img_t
|
||||
from . import Widget, WidgetType
|
||||
from .label import CONF_LABEL
|
||||
from .lv_validation import angle, lv_bool, lv_image, size, zoom
|
||||
from .lvcode import lv
|
||||
from .types import lv_img_t
|
||||
from .widget import Widget, WidgetType
|
||||
|
||||
CONF_IMAGE = "image"
|
||||
|
@ -3,11 +3,11 @@ import esphome.config_validation as cv
|
||||
from esphome.const import CONF_MODE
|
||||
from esphome.cpp_types import std_string
|
||||
|
||||
from .defines import CONF_ITEMS, CONF_MAIN, KEYBOARD_MODES, literal
|
||||
from .helpers import add_lv_use, lvgl_components_required
|
||||
from ..defines import CONF_ITEMS, CONF_MAIN, KEYBOARD_MODES, literal
|
||||
from ..helpers import add_lv_use, lvgl_components_required
|
||||
from ..types import LvCompound, LvType
|
||||
from . import Widget, WidgetType, get_widgets
|
||||
from .textarea import CONF_TEXTAREA, lv_textarea_t
|
||||
from .types import LvCompound, LvType
|
||||
from .widget import Widget, WidgetType, get_widgets
|
||||
|
||||
CONF_KEYBOARD = "keyboard"
|
||||
|
@ -1,6 +1,6 @@
|
||||
import esphome.config_validation as cv
|
||||
|
||||
from .defines import (
|
||||
from ..defines import (
|
||||
CONF_LONG_MODE,
|
||||
CONF_MAIN,
|
||||
CONF_RECOLOR,
|
||||
@ -9,10 +9,10 @@ from .defines import (
|
||||
CONF_TEXT,
|
||||
LV_LONG_MODES,
|
||||
)
|
||||
from .lv_validation import lv_bool, lv_text
|
||||
from .schemas import TEXT_SCHEMA
|
||||
from .types import LvText, WidgetType
|
||||
from .widget import Widget
|
||||
from ..lv_validation import lv_bool, lv_text
|
||||
from ..schemas import TEXT_SCHEMA
|
||||
from ..types import LvText, WidgetType
|
||||
from . import Widget
|
||||
|
||||
CONF_LABEL = "label"
|
||||
|
@ -1,11 +1,11 @@
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_BRIGHTNESS, CONF_COLOR, CONF_LED
|
||||
|
||||
from .defines import CONF_MAIN
|
||||
from .lv_validation import lv_brightness, lv_color
|
||||
from .lvcode import lv
|
||||
from .types import LvType
|
||||
from .widget import Widget, WidgetType
|
||||
from ..defines import CONF_MAIN
|
||||
from ..lv_validation import lv_brightness, lv_color
|
||||
from ..lvcode import lv
|
||||
from ..types import LvType
|
||||
from . import Widget, WidgetType
|
||||
|
||||
LED_SCHEMA = cv.Schema(
|
||||
{
|
@ -3,11 +3,10 @@ import functools
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
|
||||
from . import defines as df
|
||||
from .defines import CONF_MAIN, literal
|
||||
from .lvcode import lv
|
||||
from .types import LvType
|
||||
from .widget import Widget, WidgetType
|
||||
from ..defines import CONF_MAIN, literal
|
||||
from ..lvcode import lv
|
||||
from ..types import LvType
|
||||
from . import Widget, WidgetType
|
||||
|
||||
CONF_LINE = "line"
|
||||
CONF_POINTS = "points"
|
||||
@ -32,7 +31,7 @@ def cv_point_list(value):
|
||||
|
||||
|
||||
LINE_SCHEMA = {
|
||||
cv.Required(df.CONF_POINTS): cv_point_list,
|
||||
cv.Required(CONF_POINTS): cv_point_list,
|
||||
cv.GenerateID(CONF_POINT_LIST_ID): cv.declare_id(lv_point_t),
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
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 .lvcode import lv
|
||||
from .types import LvNumber, NumberType
|
||||
from .widget import Widget
|
||||
from ..defines import BAR_MODES, CONF_ANIMATED, CONF_INDICATOR, CONF_MAIN, literal
|
||||
from ..lv_validation import animated, get_start_value, lv_float
|
||||
from ..lvcode import lv
|
||||
from ..types import LvNumber, NumberType
|
||||
from . import Widget
|
||||
|
||||
# Note this file cannot be called "bar.py" because that name is disallowed.
|
||||
|
||||
CONF_BAR = "bar"
|
||||
BAR_MODIFY_SCHEMA = cv.Schema(
|
@ -14,9 +14,8 @@ from esphome.const import (
|
||||
CONF_WIDTH,
|
||||
)
|
||||
|
||||
from .arc import CONF_ARC
|
||||
from .automation import action_to_code
|
||||
from .defines import (
|
||||
from ..automation import action_to_code
|
||||
from ..defines import (
|
||||
CONF_END_VALUE,
|
||||
CONF_MAIN,
|
||||
CONF_PIVOT_X,
|
||||
@ -25,10 +24,8 @@ from .defines import (
|
||||
CONF_START_VALUE,
|
||||
CONF_TICKS,
|
||||
)
|
||||
from .helpers import add_lv_use
|
||||
from .img import CONF_IMAGE
|
||||
from .line import CONF_LINE
|
||||
from .lv_validation import (
|
||||
from ..helpers import add_lv_use
|
||||
from ..lv_validation import (
|
||||
angle,
|
||||
get_end_value,
|
||||
get_start_value,
|
||||
@ -39,10 +36,13 @@ from .lv_validation import (
|
||||
requires_component,
|
||||
size,
|
||||
)
|
||||
from .lvcode import LocalVariable, lv, lv_assign, lv_expr
|
||||
from ..lvcode import LocalVariable, lv, lv_assign, lv_expr
|
||||
from ..types import LvType, ObjUpdateAction
|
||||
from . import Widget, WidgetType, get_widgets
|
||||
from .arc import CONF_ARC
|
||||
from .img import CONF_IMAGE
|
||||
from .line import CONF_LINE
|
||||
from .obj import obj_spec
|
||||
from .types import LvType, ObjUpdateAction
|
||||
from .widget import Widget, WidgetType, get_widgets
|
||||
|
||||
CONF_ANGLE_RANGE = "angle_range"
|
||||
CONF_COLOR_END = "color_end"
|
||||
@ -171,7 +171,7 @@ class MeterType(WidgetType):
|
||||
"""For a meter object, create and set parameters"""
|
||||
|
||||
var = w.obj
|
||||
for scale_conf in config.get(CONF_SCALES) or ():
|
||||
for scale_conf in config.get(CONF_SCALES, ()):
|
||||
rotation = 90 + (360 - scale_conf[CONF_ANGLE_RANGE]) / 2
|
||||
if CONF_ROTATION in scale_conf:
|
||||
rotation = scale_conf[CONF_ROTATION] // 10
|
||||
@ -208,7 +208,7 @@ class MeterType(WidgetType):
|
||||
color,
|
||||
major[CONF_LABEL_GAP],
|
||||
)
|
||||
for indicator in scale_conf.get(CONF_INDICATORS) or ():
|
||||
for indicator in scale_conf.get(CONF_INDICATORS, ()):
|
||||
(t, v) = next(iter(indicator.items()))
|
||||
iid = v[CONF_ID]
|
||||
ivar = cg.new_variable(
|
@ -4,16 +4,7 @@ from esphome.core import ID
|
||||
from esphome.cpp_generator import new_Pvariable, static_const_array
|
||||
from esphome.cpp_types import nullptr
|
||||
|
||||
from .button import button_spec
|
||||
from .buttonmatrix import (
|
||||
BUTTONMATRIX_BUTTON_SCHEMA,
|
||||
CONF_BUTTON_TEXT_LIST_ID,
|
||||
buttonmatrix_spec,
|
||||
get_button_data,
|
||||
lv_buttonmatrix_t,
|
||||
set_btn_data,
|
||||
)
|
||||
from .defines import (
|
||||
from ..defines import (
|
||||
CONF_BODY,
|
||||
CONF_BUTTONS,
|
||||
CONF_CLOSE_BUTTON,
|
||||
@ -23,10 +14,9 @@ from .defines import (
|
||||
TYPE_FLEX,
|
||||
literal,
|
||||
)
|
||||
from .helpers import add_lv_use
|
||||
from .label import CONF_LABEL
|
||||
from .lv_validation import lv_bool, lv_pct, lv_text
|
||||
from .lvcode import (
|
||||
from ..helpers import add_lv_use
|
||||
from ..lv_validation import lv_bool, lv_pct, lv_text
|
||||
from ..lvcode import (
|
||||
EVENT_ARG,
|
||||
LambdaContext,
|
||||
LocalVariable,
|
||||
@ -36,11 +26,21 @@ from .lvcode import (
|
||||
lv_obj,
|
||||
lv_Pvariable,
|
||||
)
|
||||
from ..schemas import STYLE_SCHEMA, STYLED_TEXT_SCHEMA, container_schema
|
||||
from ..styles import TOP_LAYER
|
||||
from ..types import LV_EVENT, char_ptr, lv_obj_t
|
||||
from . import Widget, set_obj_properties
|
||||
from .button import button_spec
|
||||
from .buttonmatrix import (
|
||||
BUTTONMATRIX_BUTTON_SCHEMA,
|
||||
CONF_BUTTON_TEXT_LIST_ID,
|
||||
buttonmatrix_spec,
|
||||
get_button_data,
|
||||
lv_buttonmatrix_t,
|
||||
set_btn_data,
|
||||
)
|
||||
from .label import CONF_LABEL
|
||||
from .obj import obj_spec
|
||||
from .schemas import STYLE_SCHEMA, STYLED_TEXT_SCHEMA, container_schema
|
||||
from .styles import TOP_LAYER
|
||||
from .types import LV_EVENT, char_ptr, lv_obj_t
|
||||
from .widget import Widget, set_obj_properties
|
||||
|
||||
CONF_MSGBOX = "msgbox"
|
||||
MSGBOX_SCHEMA = container_schema(
|
||||
@ -73,15 +73,23 @@ async def msgbox_to_code(conf):
|
||||
*buttonmatrix_spec.get_uses(),
|
||||
*button_spec.get_uses(),
|
||||
)
|
||||
mbid = conf[CONF_ID]
|
||||
outer = lv_Pvariable(lv_obj_t, mbid.id)
|
||||
btnm = new_Pvariable(
|
||||
ID(f"{mbid.id}_btnm_", is_declaration=True, type=lv_buttonmatrix_t)
|
||||
messagebox_id = conf[CONF_ID]
|
||||
outer = lv_Pvariable(lv_obj_t, messagebox_id.id)
|
||||
buttonmatrix = new_Pvariable(
|
||||
ID(
|
||||
f"{messagebox_id.id}_buttonmatrix_",
|
||||
is_declaration=True,
|
||||
type=lv_buttonmatrix_t,
|
||||
)
|
||||
)
|
||||
msgbox = lv_Pvariable(lv_obj_t, f"{messagebox_id.id}_msgbox")
|
||||
outer_widget = Widget.create(messagebox_id, outer, obj_spec, conf)
|
||||
buttonmatrix_widget = Widget.create(
|
||||
str(buttonmatrix), buttonmatrix, buttonmatrix_spec, conf
|
||||
)
|
||||
text_list, ctrl_list, width_list, _ = await get_button_data(
|
||||
(conf,), buttonmatrix_widget
|
||||
)
|
||||
msgbox = lv_Pvariable(lv_obj_t, f"{mbid.id}_msgbox")
|
||||
outer_w = Widget.create(mbid, outer, obj_spec, conf)
|
||||
btnm_widg = Widget.create(str(btnm), btnm, buttonmatrix_spec, conf)
|
||||
text_list, ctrl_list, width_list, _ = await get_button_data((conf,), btnm_widg)
|
||||
text_id = conf[CONF_BUTTON_TEXT_LIST_ID]
|
||||
text_list = static_const_array(text_id, text_list)
|
||||
if (text := conf.get(CONF_BODY)) is not None:
|
||||
@ -97,16 +105,16 @@ async def msgbox_to_code(conf):
|
||||
lv_obj.set_style_border_width(outer, 0, 0)
|
||||
lv_obj.set_style_pad_all(outer, 0, 0)
|
||||
lv_obj.set_style_radius(outer, 0, 0)
|
||||
outer_w.add_flag("LV_OBJ_FLAG_HIDDEN")
|
||||
outer_widget.add_flag("LV_OBJ_FLAG_HIDDEN")
|
||||
lv_assign(
|
||||
msgbox, lv_expr.msgbox_create(outer, title, text, text_list, close_button)
|
||||
)
|
||||
lv_obj.set_style_align(msgbox, literal("LV_ALIGN_CENTER"), 0)
|
||||
lv_add(btnm.set_obj(lv_expr.msgbox_get_btns(msgbox)))
|
||||
await set_obj_properties(outer_w, conf)
|
||||
lv_add(buttonmatrix.set_obj(lv_expr.msgbox_get_btns(msgbox)))
|
||||
await set_obj_properties(outer_widget, conf)
|
||||
if close_button:
|
||||
async with LambdaContext(EVENT_ARG, where=mbid) as context:
|
||||
outer_w.add_flag("LV_OBJ_FLAG_HIDDEN")
|
||||
async with LambdaContext(EVENT_ARG, where=messagebox_id) as context:
|
||||
outer_widget.add_flag("LV_OBJ_FLAG_HIDDEN")
|
||||
with LocalVariable(
|
||||
"close_btn_", lv_obj_t, lv_expr.msgbox_get_close_btn(msgbox)
|
||||
) as close_btn:
|
||||
@ -119,7 +127,7 @@ async def msgbox_to_code(conf):
|
||||
)
|
||||
|
||||
if len(ctrl_list) != 0 or len(width_list) != 0:
|
||||
set_btn_data(btnm.obj, ctrl_list, width_list)
|
||||
set_btn_data(buttonmatrix.obj, ctrl_list, width_list)
|
||||
|
||||
|
||||
async def msgboxes_to_code(config):
|
@ -1,9 +1,9 @@
|
||||
from esphome import automation
|
||||
|
||||
from .automation import update_to_code
|
||||
from .defines import CONF_MAIN, CONF_OBJ
|
||||
from .schemas import create_modify_schema
|
||||
from .types import ObjUpdateAction, WidgetType, lv_obj_t
|
||||
from ..automation import update_to_code
|
||||
from ..defines import CONF_MAIN, CONF_OBJ
|
||||
from ..schemas import create_modify_schema
|
||||
from ..types import ObjUpdateAction, WidgetType, lv_obj_t
|
||||
|
||||
|
||||
class ObjType(WidgetType):
|
@ -2,7 +2,7 @@ from esphome import automation, codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_PAGES, CONF_TIME
|
||||
|
||||
from .defines import (
|
||||
from ..defines import (
|
||||
CONF_ANIMATION,
|
||||
CONF_LVGL_ID,
|
||||
CONF_PAGE,
|
||||
@ -10,11 +10,11 @@ from .defines import (
|
||||
CONF_SKIP,
|
||||
LV_ANIM,
|
||||
)
|
||||
from .lv_validation import lv_bool, lv_milliseconds
|
||||
from .lvcode import LVGL_COMP_ARG, LambdaContext, add_line_marks, lv_add, lvgl_comp
|
||||
from .schemas import LVGL_SCHEMA
|
||||
from .types import LvglAction, lv_page_t
|
||||
from .widget import Widget, WidgetType, add_widgets, set_obj_properties
|
||||
from ..lv_validation import lv_bool, lv_milliseconds
|
||||
from ..lvcode import LVGL_COMP_ARG, LambdaContext, add_line_marks, lv_add, lvgl_comp
|
||||
from ..schemas import LVGL_SCHEMA
|
||||
from ..types import LvglAction, lv_page_t
|
||||
from . import Widget, WidgetType, add_widgets, set_obj_properties
|
||||
|
||||
|
||||
class PageType(WidgetType):
|
@ -2,7 +2,7 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_MODE, CONF_OPTIONS
|
||||
|
||||
from .defines import (
|
||||
from ..defines import (
|
||||
CONF_ANIMATED,
|
||||
CONF_MAIN,
|
||||
CONF_SELECTED,
|
||||
@ -11,11 +11,11 @@ from .defines import (
|
||||
ROLLER_MODES,
|
||||
literal,
|
||||
)
|
||||
from ..lv_validation import animated, lv_int, option_string
|
||||
from ..lvcode import lv
|
||||
from ..types import LvSelect
|
||||
from . import WidgetType
|
||||
from .label import CONF_LABEL
|
||||
from .lv_validation import animated, lv_int, option_string
|
||||
from .lvcode import lv
|
||||
from .types import LvSelect
|
||||
from .widget import WidgetType
|
||||
|
||||
CONF_ROLLER = "roller"
|
||||
lv_roller_t = LvSelect("lv_roller_t")
|
@ -1,7 +1,7 @@
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_MAX_VALUE, CONF_MIN_VALUE, CONF_MODE, CONF_VALUE
|
||||
|
||||
from .defines import (
|
||||
from ..defines import (
|
||||
BAR_MODES,
|
||||
CONF_ANIMATED,
|
||||
CONF_INDICATOR,
|
||||
@ -9,12 +9,12 @@ from .defines import (
|
||||
CONF_MAIN,
|
||||
literal,
|
||||
)
|
||||
from .helpers import add_lv_use
|
||||
from ..helpers import add_lv_use
|
||||
from ..lv_validation import animated, get_start_value, lv_float
|
||||
from ..lvcode import lv
|
||||
from ..types import LvNumber, NumberType
|
||||
from . import Widget
|
||||
from .lv_bar import CONF_BAR
|
||||
from .lv_validation import animated, get_start_value, lv_float
|
||||
from .lvcode import lv
|
||||
from .types import LvNumber, NumberType
|
||||
from .widget import Widget
|
||||
|
||||
CONF_SLIDER = "slider"
|
||||
SLIDER_MODIFY_SCHEMA = cv.Schema(
|
@ -2,8 +2,8 @@ from esphome import automation
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_RANGE_FROM, CONF_RANGE_TO, CONF_STEP, CONF_VALUE
|
||||
|
||||
from .automation import action_to_code, update_to_code
|
||||
from .defines import (
|
||||
from ..automation import action_to_code, update_to_code
|
||||
from ..defines import (
|
||||
CONF_CURSOR,
|
||||
CONF_DECIMAL_PLACES,
|
||||
CONF_DIGITS,
|
||||
@ -13,12 +13,12 @@ from .defines import (
|
||||
CONF_SELECTED,
|
||||
CONF_TEXTAREA_PLACEHOLDER,
|
||||
)
|
||||
from ..lv_validation import lv_bool, lv_float
|
||||
from ..lvcode import lv
|
||||
from ..types import LvNumber, ObjUpdateAction
|
||||
from . import Widget, WidgetType, get_widgets
|
||||
from .label import CONF_LABEL
|
||||
from .lv_validation import lv_bool, lv_float
|
||||
from .lvcode import lv
|
||||
from .textarea import CONF_TEXTAREA
|
||||
from .types import LvNumber, ObjUpdateAction
|
||||
from .widget import Widget, WidgetType, get_widgets
|
||||
|
||||
CONF_SPINBOX = "spinbox"
|
||||
|
@ -1,12 +1,12 @@
|
||||
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 ..lvcode import lv_expr
|
||||
from ..types import LvType
|
||||
from . import Widget, WidgetType
|
||||
from .arc import CONF_ARC
|
||||
from .defines import CONF_ARC_LENGTH, CONF_INDICATOR, CONF_MAIN, CONF_SPIN_TIME
|
||||
from .lv_validation import angle
|
||||
from .lvcode import lv_expr
|
||||
from .types import LvType
|
||||
from .widget import Widget, WidgetType
|
||||
|
||||
CONF_SPINNER = "spinner"
|
||||
|
@ -1,6 +1,6 @@
|
||||
from .defines import CONF_INDICATOR, CONF_KNOB, CONF_MAIN
|
||||
from .types import LvBoolean
|
||||
from .widget import WidgetType
|
||||
from ..defines import CONF_INDICATOR, CONF_KNOB, CONF_MAIN
|
||||
from ..types import LvBoolean
|
||||
from . import WidgetType
|
||||
|
||||
CONF_SWITCH = "switch"
|
||||
|
@ -4,9 +4,8 @@ import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_INDEX, CONF_NAME, CONF_POSITION, CONF_SIZE
|
||||
from esphome.cpp_generator import MockObjClass
|
||||
|
||||
from . import buttonmatrix_spec
|
||||
from .automation import action_to_code
|
||||
from .defines import (
|
||||
from ..automation import action_to_code
|
||||
from ..defines import (
|
||||
CONF_ANIMATED,
|
||||
CONF_MAIN,
|
||||
CONF_TAB_ID,
|
||||
@ -15,12 +14,13 @@ from .defines import (
|
||||
TYPE_FLEX,
|
||||
literal,
|
||||
)
|
||||
from .lv_validation import animated, lv_int, size
|
||||
from .lvcode import LocalVariable, lv, lv_assign, lv_expr
|
||||
from ..lv_validation import animated, lv_int, size
|
||||
from ..lvcode import LocalVariable, lv, lv_assign, lv_expr
|
||||
from ..schemas import container_schema, part_schema
|
||||
from ..types import LV_EVENT, LvType, ObjUpdateAction, lv_obj_t, lv_obj_t_ptr
|
||||
from . import Widget, WidgetType, add_widgets, get_widgets, set_obj_properties
|
||||
from .buttonmatrix import buttonmatrix_spec
|
||||
from .obj import obj_spec
|
||||
from .schemas import container_schema, part_schema
|
||||
from .types import LV_EVENT, LvType, ObjUpdateAction, lv_obj_t, lv_obj_t_ptr
|
||||
from .widget import Widget, WidgetType, add_widgets, get_widgets, set_obj_properties
|
||||
|
||||
CONF_TABVIEW = "tabview"
|
||||
CONF_TAB_STYLE = "tab_style"
|
@ -1,7 +1,7 @@
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_MAX_LENGTH
|
||||
|
||||
from .defines import (
|
||||
from ..defines import (
|
||||
CONF_ACCEPTED_CHARS,
|
||||
CONF_CURSOR,
|
||||
CONF_MAIN,
|
||||
@ -13,10 +13,10 @@ from .defines import (
|
||||
CONF_TEXT,
|
||||
CONF_TEXTAREA_PLACEHOLDER,
|
||||
)
|
||||
from .lv_validation import lv_bool, lv_int, lv_text
|
||||
from .schemas import TEXT_SCHEMA
|
||||
from .types import LvText
|
||||
from .widget import Widget, WidgetType
|
||||
from ..lv_validation import lv_bool, lv_int, lv_text
|
||||
from ..schemas import TEXT_SCHEMA
|
||||
from ..types import LvText
|
||||
from . import Widget, WidgetType
|
||||
|
||||
CONF_TEXTAREA = "textarea"
|
||||
|
@ -3,8 +3,8 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_ON_VALUE, CONF_ROW, CONF_TRIGGER_ID
|
||||
|
||||
from .automation import action_to_code
|
||||
from .defines import (
|
||||
from ..automation import action_to_code
|
||||
from ..defines import (
|
||||
CONF_ANIMATED,
|
||||
CONF_COLUMN,
|
||||
CONF_DIR,
|
||||
@ -14,12 +14,12 @@ from .defines import (
|
||||
TILE_DIRECTIONS,
|
||||
literal,
|
||||
)
|
||||
from .lv_validation import animated, lv_int
|
||||
from .lvcode import lv, lv_assign, lv_expr, lv_obj, lv_Pvariable
|
||||
from ..lv_validation import animated, lv_int
|
||||
from ..lvcode import lv, lv_assign, lv_expr, lv_obj, lv_Pvariable
|
||||
from ..schemas import container_schema
|
||||
from ..types import LV_EVENT, LvType, ObjUpdateAction, lv_obj_t, lv_obj_t_ptr
|
||||
from . import Widget, WidgetType, add_widgets, get_widgets, set_obj_properties
|
||||
from .obj import obj_spec
|
||||
from .schemas import container_schema
|
||||
from .types import LV_EVENT, LvType, ObjUpdateAction, lv_obj_t, lv_obj_t_ptr
|
||||
from .widget import Widget, WidgetType, add_widgets, get_widgets, set_obj_properties
|
||||
|
||||
CONF_TILEVIEW = "tileview"
|
||||
|
||||
@ -68,7 +68,7 @@ class TileviewType(WidgetType):
|
||||
)
|
||||
|
||||
async def to_code(self, w: Widget, config: dict):
|
||||
for tile_conf in config.get(CONF_TILES) or ():
|
||||
for tile_conf in config.get(CONF_TILES, ()):
|
||||
w_id = tile_conf[CONF_ID]
|
||||
tile_obj = lv_Pvariable(lv_obj_t, w_id)
|
||||
tile = Widget.create(w_id, tile_obj, tile_spec, tile_conf)
|
@ -54,3 +54,75 @@ font:
|
||||
"\U000f0084",
|
||||
"\U000f0091",
|
||||
]
|
||||
|
||||
sensor:
|
||||
- platform: lvgl
|
||||
id: lvgl_sensor_id
|
||||
name: "LVGL Arc Sensor"
|
||||
widget: lv_arc
|
||||
- platform: lvgl
|
||||
widget: slider_id
|
||||
name: LVGL Slider
|
||||
- platform: lvgl
|
||||
widget: bar_id
|
||||
id: lvgl_bar_sensor
|
||||
name: LVGL Bar
|
||||
- platform: lvgl
|
||||
widget: spinbox_id
|
||||
name: LVGL Spinbox
|
||||
|
||||
number:
|
||||
- platform: lvgl
|
||||
widget: slider_id
|
||||
name: LVGL Slider
|
||||
- platform: lvgl
|
||||
widget: lv_arc
|
||||
id: lvgl_arc_number
|
||||
name: LVGL Arc
|
||||
- platform: lvgl
|
||||
widget: bar_id
|
||||
id: lvgl_bar_number
|
||||
name: LVGL Bar
|
||||
- platform: lvgl
|
||||
widget: spinbox_id
|
||||
id: lvgl_spinbox_number
|
||||
name: LVGL Spinbox
|
||||
|
||||
light:
|
||||
- platform: lvgl
|
||||
name: LVGL LED
|
||||
id: lv_light
|
||||
led: lv_led
|
||||
|
||||
binary_sensor:
|
||||
- platform: lvgl
|
||||
id: lvgl_pressbutton
|
||||
name: Pressbutton
|
||||
widget: spin_up
|
||||
publish_initial_state: true
|
||||
- platform: lvgl
|
||||
name: ButtonMatrix button
|
||||
widget: button_a
|
||||
- platform: lvgl
|
||||
id: switch_d
|
||||
name: Matrix switch D
|
||||
widget: button_d
|
||||
on_click:
|
||||
then:
|
||||
- lvgl.page.previous:
|
||||
animation: move_right
|
||||
time: 600ms
|
||||
- platform: lvgl
|
||||
id: button_checker
|
||||
name: LVGL button
|
||||
widget: spin_up
|
||||
on_state:
|
||||
then:
|
||||
- lvgl.checkbox.update:
|
||||
id: checkbox_id
|
||||
state:
|
||||
checked: !lambda return x;
|
||||
text: Unchecked
|
||||
- platform: lvgl
|
||||
name: LVGL checkbox
|
||||
widget: checkbox_id
|
||||
|
Loading…
Reference in New Issue
Block a user