esphome 2024.10.3__py3-none-any.whl → 2024.11.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +22 -4
- esphome/automation.py +29 -2
- esphome/components/animation/__init__.py +5 -8
- esphome/components/animation/animation.cpp +1 -1
- esphome/components/audio/__init__.py +9 -0
- esphome/components/audio/audio.h +21 -0
- esphome/components/axs15231/__init__.py +6 -0
- esphome/components/axs15231/touchscreen/__init__.py +36 -0
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +64 -0
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.h +27 -0
- esphome/components/bme68x_bsec2/__init__.py +1 -1
- esphome/components/bytebuffer/__init__.py +5 -0
- esphome/components/bytebuffer/bytebuffer.h +421 -0
- esphome/components/climate/__init__.py +14 -13
- esphome/components/datetime/__init__.py +3 -3
- esphome/components/debug/debug_esp32.cpp +16 -8
- esphome/components/dfplayer/dfplayer.cpp +132 -6
- esphome/components/dfplayer/dfplayer.h +19 -53
- esphome/components/display/display.cpp +142 -0
- esphome/components/display/display.h +7 -0
- esphome/components/es8311/__init__.py +0 -0
- esphome/components/es8311/audio_dac.py +70 -0
- esphome/components/es8311/es8311.cpp +227 -0
- esphome/components/es8311/es8311.h +135 -0
- esphome/components/es8311/es8311_const.h +195 -0
- esphome/components/esp32/boards.py +199 -1
- esphome/components/esp32/gpio.py +3 -1
- esphome/components/esp32_ble/const_esp32c6.h +7 -0
- esphome/components/esp32_ble_client/ble_client_base.h +1 -1
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +2 -2
- esphome/components/esp32_rmt_led_strip/led_strip.h +2 -0
- esphome/components/esp32_rmt_led_strip/light.py +3 -1
- esphome/components/esp8266/gpio.py +7 -5
- esphome/components/ethernet/__init__.py +55 -1
- esphome/components/ethernet/ethernet_component.cpp +14 -1
- esphome/components/ethernet/ethernet_component.h +7 -1
- esphome/components/font/__init__.py +213 -108
- esphome/components/gp8403/output/__init__.py +1 -1
- esphome/components/host/gpio.py +6 -4
- esphome/components/http_request/__init__.py +12 -0
- esphome/components/http_request/http_request.h +65 -3
- esphome/components/http_request/http_request_arduino.cpp +2 -3
- esphome/components/http_request/http_request_idf.cpp +6 -14
- esphome/components/http_request/ota/ota_http_request.cpp +1 -1
- esphome/components/http_request/update/http_request_update.cpp +1 -1
- esphome/components/i2c_device/__init__.py +26 -0
- esphome/components/i2c_device/i2c_device.cpp +17 -0
- esphome/components/i2c_device/i2c_device.h +18 -0
- esphome/components/i2s_audio/__init__.py +1 -3
- esphome/components/i2s_audio/speaker/__init__.py +12 -4
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +432 -197
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +91 -32
- esphome/components/ili9xxx/display.py +5 -1
- esphome/components/image/__init__.py +5 -8
- esphome/components/image/image.cpp +14 -14
- esphome/components/image/image.h +20 -24
- esphome/components/internal_temperature/internal_temperature.cpp +51 -2
- esphome/components/internal_temperature/internal_temperature.h +1 -0
- esphome/components/libretiny/gpio.py +4 -2
- esphome/components/light/__init__.py +32 -1
- esphome/components/light/automation.py +39 -32
- esphome/components/light/effects.py +36 -36
- esphome/components/light/light_state.cpp +6 -16
- esphome/components/light/light_state.h +34 -0
- esphome/components/light/types.py +3 -1
- esphome/components/logger/logger_esp32.cpp +15 -0
- esphome/components/lvgl/__init__.py +202 -95
- esphome/components/lvgl/automation.py +42 -40
- esphome/components/lvgl/binary_sensor/__init__.py +8 -15
- esphome/components/lvgl/defines.py +14 -8
- esphome/components/lvgl/encoders.py +11 -8
- esphome/components/lvgl/keypads.py +77 -0
- esphome/components/lvgl/light/__init__.py +6 -8
- esphome/components/lvgl/lv_validation.py +2 -4
- esphome/components/lvgl/lvcode.py +3 -9
- esphome/components/lvgl/lvgl_esphome.cpp +210 -89
- esphome/components/lvgl/lvgl_esphome.h +113 -30
- esphome/components/lvgl/lvgl_proxy.h +17 -0
- esphome/components/lvgl/number/__init__.py +10 -15
- esphome/components/lvgl/schemas.py +4 -2
- esphome/components/lvgl/select/__init__.py +12 -37
- esphome/components/lvgl/select/lvgl_select.h +27 -33
- esphome/components/lvgl/sensor/__init__.py +8 -14
- esphome/components/lvgl/styles.py +3 -4
- esphome/components/lvgl/switch/__init__.py +8 -13
- esphome/components/lvgl/text/__init__.py +5 -6
- esphome/components/lvgl/text_sensor/__init__.py +15 -15
- esphome/components/lvgl/touchscreens.py +2 -3
- esphome/components/lvgl/trigger.py +7 -9
- esphome/components/lvgl/types.py +9 -3
- esphome/components/lvgl/widgets/__init__.py +32 -21
- esphome/components/lvgl/widgets/dropdown.py +22 -10
- esphome/components/lvgl/widgets/msgbox.py +6 -5
- esphome/components/lvgl/widgets/obj.py +4 -2
- esphome/components/lvgl/widgets/page.py +3 -2
- esphome/components/lvgl/widgets/qrcode.py +54 -0
- esphome/components/lvgl/widgets/roller.py +21 -14
- esphome/components/lvgl/widgets/tileview.py +2 -1
- esphome/components/max17043/__init__.py +1 -0
- esphome/components/max17043/automation.h +20 -0
- esphome/components/max17043/max17043.cpp +98 -0
- esphome/components/max17043/max17043.h +29 -0
- esphome/components/max17043/sensor.py +77 -0
- esphome/components/media_player/__init__.py +11 -0
- esphome/components/media_player/automation.h +10 -0
- esphome/components/media_player/media_player.cpp +4 -0
- esphome/components/midea/air_conditioner.cpp +17 -1
- esphome/components/mlx90393/sensor.py +1 -1
- esphome/components/modbus_controller/__init__.py +31 -1
- esphome/components/modbus_controller/automation.h +16 -0
- esphome/components/modbus_controller/const.py +2 -0
- esphome/components/modbus_controller/modbus_controller.cpp +14 -2
- esphome/components/modbus_controller/modbus_controller.h +9 -0
- esphome/components/mopeka_pro_check/mopeka_pro_check.cpp +40 -21
- esphome/components/mopeka_pro_check/mopeka_pro_check.h +9 -2
- esphome/components/mopeka_pro_check/sensor.py +41 -0
- esphome/components/mqtt/__init__.py +36 -0
- esphome/components/mqtt/mqtt_client.cpp +27 -3
- esphome/components/mqtt/mqtt_client.h +27 -2
- esphome/components/mqtt/mqtt_climate.cpp +4 -2
- esphome/components/mqtt/mqtt_component.cpp +6 -0
- esphome/components/mqtt/mqtt_component.h +4 -0
- esphome/components/mqtt/mqtt_const.h +6 -0
- esphome/components/online_image/online_image.cpp +2 -8
- esphome/components/online_image/online_image.h +2 -6
- esphome/components/opentherm/__init__.py +35 -9
- esphome/components/opentherm/binary_sensor/__init__.py +33 -0
- esphome/components/opentherm/const.py +11 -0
- esphome/components/opentherm/generate.py +142 -0
- esphome/components/opentherm/hub.cpp +130 -24
- esphome/components/opentherm/hub.h +62 -9
- esphome/components/opentherm/input.h +18 -0
- esphome/components/opentherm/input.py +51 -0
- esphome/components/opentherm/number/__init__.py +74 -0
- esphome/components/opentherm/number/number.cpp +40 -0
- esphome/components/opentherm/number/number.h +31 -0
- esphome/components/opentherm/opentherm.cpp +30 -0
- esphome/components/opentherm/opentherm.h +34 -2
- esphome/components/opentherm/opentherm_macros.h +151 -0
- esphome/components/opentherm/output/__init__.py +47 -0
- esphome/components/opentherm/output/output.cpp +18 -0
- esphome/components/opentherm/output/output.h +33 -0
- esphome/components/opentherm/schema.py +814 -0
- esphome/components/opentherm/sensor/__init__.py +51 -0
- esphome/components/opentherm/switch/__init__.py +43 -0
- esphome/components/opentherm/switch/switch.cpp +28 -0
- esphome/components/opentherm/switch/switch.h +20 -0
- esphome/components/opentherm/validate.py +31 -0
- esphome/components/pcd8544/display.py +8 -4
- esphome/components/prometheus/prometheus_handler.cpp +176 -14
- esphome/components/prometheus/prometheus_handler.h +25 -7
- esphome/components/qspi_amoled/display.py +1 -141
- esphome/components/qspi_dbi/display.py +185 -0
- esphome/components/qspi_dbi/models.py +64 -0
- esphome/components/{qspi_amoled/qspi_amoled.cpp → qspi_dbi/qspi_dbi.cpp} +95 -46
- esphome/components/{qspi_amoled/qspi_amoled.h → qspi_dbi/qspi_dbi.h} +26 -15
- esphome/components/rp2040/__init__.py +6 -3
- esphome/components/rp2040/gpio.py +5 -3
- esphome/components/rtttl/rtttl.cpp +4 -1
- esphome/components/rtttl/rtttl.h +1 -0
- esphome/components/sdl/sdl_esphome.cpp +22 -5
- esphome/components/sdl/sdl_esphome.h +1 -0
- esphome/components/sensor/__init__.py +18 -8
- esphome/components/sensor/filter.cpp +19 -18
- esphome/components/sensor/filter.h +9 -10
- esphome/components/sgp4x/sgp4x.cpp +40 -74
- esphome/components/sgp4x/sgp4x.h +5 -3
- esphome/components/speaker/__init__.py +51 -5
- esphome/components/speaker/automation.h +25 -0
- esphome/components/speaker/speaker.h +72 -1
- esphome/components/spi/__init__.py +15 -14
- esphome/components/spi_device/__init__.py +4 -15
- esphome/components/ssd1306_spi/display.py +6 -2
- esphome/components/ssd1322_spi/display.py +6 -2
- esphome/components/ssd1325_spi/display.py +6 -2
- esphome/components/ssd1327_spi/display.py +6 -2
- esphome/components/ssd1331_spi/display.py +6 -2
- esphome/components/ssd1351_spi/display.py +6 -2
- esphome/components/st7567_spi/display.py +6 -2
- esphome/components/st7701s/display.py +5 -1
- esphome/components/st7735/display.py +10 -5
- esphome/components/st7789v/display.py +12 -7
- esphome/components/statsd/statsd.cpp +2 -0
- esphome/components/statsd/statsd.h +2 -0
- esphome/components/sun/sun.h +3 -0
- esphome/components/tc74/__init__.py +1 -0
- esphome/components/tc74/sensor.py +32 -0
- esphome/components/tc74/tc74.cpp +68 -0
- esphome/components/tc74/tc74.h +28 -0
- esphome/components/touchscreen/__init__.py +41 -50
- esphome/components/touchscreen/touchscreen.h +4 -8
- esphome/components/udp/udp_component.cpp +6 -3
- esphome/components/udp/udp_component.h +4 -2
- esphome/components/waveshare_epaper/display.py +6 -2
- esphome/components/web_server/web_server.cpp +22 -0
- esphome/components/web_server/web_server.h +3 -0
- esphome/components/weikai/weikai.h +2 -2
- esphome/components/wifi/wifi_component.cpp +2 -2
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +4 -4
- esphome/components/wifi/wifi_component_esp8266.cpp +4 -4
- esphome/components/wifi/wifi_component_esp_idf.cpp +2 -2
- esphome/components/xpt2046/touchscreen/__init__.py +7 -32
- esphome/config_validation.py +3 -1
- esphome/const.py +8 -1
- esphome/core/defines.h +8 -2
- esphome/core/helpers.cpp +32 -17
- esphome/core/helpers.h +32 -16
- esphome/core/ring_buffer.cpp +2 -2
- esphome/core/ring_buffer.h +2 -2
- esphome/dashboard/core.py +25 -0
- esphome/dashboard/status/mdns.py +3 -4
- esphome/dashboard/web_server.py +54 -19
- esphome/espota2.py +36 -35
- esphome/helpers.py +68 -16
- esphome/mqtt.py +9 -2
- esphome/storage_json.py +4 -0
- esphome/writer.py +7 -18
- esphome/zeroconf.py +8 -6
- {esphome-2024.10.3.dist-info → esphome-2024.11.0b1.dist-info}/METADATA +7 -5
- {esphome-2024.10.3.dist-info → esphome-2024.11.0b1.dist-info}/RECORD +226 -180
- esphome/core/bytebuffer.cpp +0 -167
- esphome/core/bytebuffer.h +0 -144
- /esphome/components/{qspi_amoled → qspi_dbi}/__init__.py +0 -0
- {esphome-2024.10.3.dist-info → esphome-2024.11.0b1.dist-info}/LICENSE +0 -0
- {esphome-2024.10.3.dist-info → esphome-2024.11.0b1.dist-info}/WHEEL +0 -0
- {esphome-2024.10.3.dist-info → esphome-2024.11.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2024.10.3.dist-info → esphome-2024.11.0b1.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,7 @@ from esphome.components import number
|
|
3
3
|
import esphome.config_validation as cv
|
4
4
|
from esphome.cpp_generator import MockObj
|
5
5
|
|
6
|
-
from ..defines import CONF_ANIMATED,
|
6
|
+
from ..defines import CONF_ANIMATED, CONF_UPDATE_ON_RELEASE, CONF_WIDGET
|
7
7
|
from ..lv_validation import animated
|
8
8
|
from ..lvcode import (
|
9
9
|
API_EVENT,
|
@@ -13,28 +13,23 @@ from ..lvcode import (
|
|
13
13
|
LvContext,
|
14
14
|
lv,
|
15
15
|
lv_add,
|
16
|
+
lvgl_static,
|
16
17
|
)
|
17
|
-
from ..schemas import LVGL_SCHEMA
|
18
18
|
from ..types import LV_EVENT, LvNumber, lvgl_ns
|
19
19
|
from ..widgets import get_widgets, wait_for_widgets
|
20
20
|
|
21
21
|
LVGLNumber = lvgl_ns.class_("LVGLNumber", number.Number)
|
22
22
|
|
23
|
-
CONFIG_SCHEMA = (
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
cv.Optional(CONF_ANIMATED, default=True): animated,
|
30
|
-
cv.Optional(CONF_UPDATE_ON_RELEASE, default=False): cv.boolean,
|
31
|
-
}
|
32
|
-
)
|
23
|
+
CONFIG_SCHEMA = number.number_schema(LVGLNumber).extend(
|
24
|
+
{
|
25
|
+
cv.Required(CONF_WIDGET): cv.use_id(LvNumber),
|
26
|
+
cv.Optional(CONF_ANIMATED, default=True): animated,
|
27
|
+
cv.Optional(CONF_UPDATE_ON_RELEASE, default=False): cv.boolean,
|
28
|
+
}
|
33
29
|
)
|
34
30
|
|
35
31
|
|
36
32
|
async def to_code(config):
|
37
|
-
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
38
33
|
widget = await get_widgets(config, CONF_WIDGET)
|
39
34
|
widget = widget[0]
|
40
35
|
var = await number.new_number(
|
@@ -58,10 +53,10 @@ async def to_code(config):
|
|
58
53
|
if not config[CONF_UPDATE_ON_RELEASE]
|
59
54
|
else LV_EVENT.RELEASED
|
60
55
|
)
|
61
|
-
async with LvContext(
|
56
|
+
async with LvContext():
|
62
57
|
lv_add(var.set_control_lambda(await control.get_lambda()))
|
63
58
|
lv_add(
|
64
|
-
|
59
|
+
lvgl_static.add_event_cb(
|
65
60
|
widget.obj, await event.get_lambda(), UPDATE_EVENT, event_code
|
66
61
|
)
|
67
62
|
)
|
@@ -216,7 +216,7 @@ def automation_schema(typ: LvType):
|
|
216
216
|
events = df.LV_EVENT_TRIGGERS + (CONF_ON_VALUE,)
|
217
217
|
else:
|
218
218
|
events = df.LV_EVENT_TRIGGERS
|
219
|
-
args =
|
219
|
+
args = typ.get_arg_type() if isinstance(typ, LvType) else []
|
220
220
|
args.append(lv_event_t_ptr)
|
221
221
|
return {
|
222
222
|
cv.Optional(event): validate_automation(
|
@@ -391,7 +391,9 @@ def container_validator(schema, widget_type: WidgetType):
|
|
391
391
|
add_lv_use(ltype)
|
392
392
|
if value == SCHEMA_EXTRACT:
|
393
393
|
return result
|
394
|
-
result = result.extend(
|
394
|
+
result = result.extend(
|
395
|
+
LAYOUT_SCHEMAS.get(ltype.lower(), LAYOUT_SCHEMAS[df.TYPE_NONE])
|
396
|
+
)
|
395
397
|
return result(value)
|
396
398
|
|
397
399
|
return validator
|
@@ -1,33 +1,19 @@
|
|
1
|
-
import esphome.codegen as cg
|
2
1
|
from esphome.components import select
|
3
2
|
import esphome.config_validation as cv
|
4
3
|
from esphome.const import CONF_OPTIONS
|
5
4
|
|
6
|
-
from ..defines import CONF_ANIMATED,
|
7
|
-
from ..lvcode import
|
8
|
-
|
9
|
-
EVENT_ARG,
|
10
|
-
UPDATE_EVENT,
|
11
|
-
LambdaContext,
|
12
|
-
LvContext,
|
13
|
-
lv,
|
14
|
-
lv_add,
|
15
|
-
)
|
16
|
-
from ..schemas import LVGL_SCHEMA
|
17
|
-
from ..types import LV_EVENT, LvSelect, lvgl_ns
|
5
|
+
from ..defines import CONF_ANIMATED, CONF_WIDGET, literal
|
6
|
+
from ..lvcode import LvContext
|
7
|
+
from ..types import LvSelect, lvgl_ns
|
18
8
|
from ..widgets import get_widgets, wait_for_widgets
|
19
9
|
|
20
10
|
LVGLSelect = lvgl_ns.class_("LVGLSelect", select.Select)
|
21
11
|
|
22
|
-
CONFIG_SCHEMA = (
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
cv.Required(CONF_WIDGET): cv.use_id(LvSelect),
|
28
|
-
cv.Optional(CONF_ANIMATED, default=False): cv.boolean,
|
29
|
-
}
|
30
|
-
)
|
12
|
+
CONFIG_SCHEMA = select.select_schema(LVGLSelect).extend(
|
13
|
+
{
|
14
|
+
cv.Required(CONF_WIDGET): cv.use_id(LvSelect),
|
15
|
+
cv.Optional(CONF_ANIMATED, default=False): cv.boolean,
|
16
|
+
}
|
31
17
|
)
|
32
18
|
|
33
19
|
|
@@ -36,22 +22,11 @@ async def to_code(config):
|
|
36
22
|
widget = widget[0]
|
37
23
|
options = widget.config.get(CONF_OPTIONS, [])
|
38
24
|
selector = await select.new_select(config, options=options)
|
39
|
-
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
40
25
|
await wait_for_widgets()
|
41
|
-
async with
|
42
|
-
pub_ctx.add(selector.publish_index(widget.get_value()))
|
43
|
-
async with LambdaContext([(cg.uint16, "v")]) as control:
|
44
|
-
await widget.set_property("selected", "v", animated=config[CONF_ANIMATED])
|
45
|
-
lv.event_send(widget.obj, API_EVENT, cg.nullptr)
|
46
|
-
control.add(selector.publish_index(widget.get_value()))
|
47
|
-
async with LvContext(paren) as ctx:
|
48
|
-
lv_add(selector.set_control_lambda(await control.get_lambda()))
|
26
|
+
async with LvContext() as ctx:
|
49
27
|
ctx.add(
|
50
|
-
|
51
|
-
widget.
|
52
|
-
|
53
|
-
LV_EVENT.VALUE_CHANGED,
|
54
|
-
UPDATE_EVENT,
|
28
|
+
selector.set_widget(
|
29
|
+
widget.var,
|
30
|
+
literal("LV_ANIM_ON" if config[CONF_ANIMATED] else "LV_ANIM_OFF"),
|
55
31
|
)
|
56
32
|
)
|
57
|
-
lv_add(selector.publish_index(widget.get_value()))
|
@@ -6,58 +6,52 @@
|
|
6
6
|
#include "esphome/core/automation.h"
|
7
7
|
#include "esphome/core/component.h"
|
8
8
|
#include "esphome/core/preferences.h"
|
9
|
+
#include "../lvgl.h"
|
9
10
|
|
10
11
|
namespace esphome {
|
11
12
|
namespace lvgl {
|
12
13
|
|
13
|
-
static std::vector<std::string> split_string(const std::string &str) {
|
14
|
-
std::vector<std::string> strings;
|
15
|
-
auto delimiter = std::string("\n");
|
16
|
-
|
17
|
-
std::string::size_type pos;
|
18
|
-
std::string::size_type prev = 0;
|
19
|
-
while ((pos = str.find(delimiter, prev)) != std::string::npos) {
|
20
|
-
strings.push_back(str.substr(prev, pos - prev));
|
21
|
-
prev = pos + delimiter.size();
|
22
|
-
}
|
23
|
-
|
24
|
-
// To get the last substring (or only, if delimiter is not found)
|
25
|
-
strings.push_back(str.substr(prev));
|
26
|
-
|
27
|
-
return strings;
|
28
|
-
}
|
29
|
-
|
30
14
|
class LVGLSelect : public select::Select {
|
31
15
|
public:
|
32
|
-
void
|
33
|
-
this->
|
16
|
+
void set_widget(LvSelectable *widget, lv_anim_enable_t anim = LV_ANIM_OFF) {
|
17
|
+
this->widget_ = widget;
|
18
|
+
this->anim_ = anim;
|
19
|
+
this->set_options_();
|
20
|
+
lv_obj_add_event_cb(
|
21
|
+
this->widget_->obj,
|
22
|
+
[](lv_event_t *e) {
|
23
|
+
auto *it = static_cast<LVGLSelect *>(e->user_data);
|
24
|
+
it->set_options_();
|
25
|
+
},
|
26
|
+
LV_EVENT_REFRESH, this);
|
34
27
|
if (this->initial_state_.has_value()) {
|
35
28
|
this->control(this->initial_state_.value());
|
36
29
|
this->initial_state_.reset();
|
37
30
|
}
|
31
|
+
this->publish();
|
32
|
+
auto lamb = [](lv_event_t *e) {
|
33
|
+
auto *self = static_cast<LVGLSelect *>(e->user_data);
|
34
|
+
self->publish();
|
35
|
+
};
|
36
|
+
lv_obj_add_event_cb(this->widget_->obj, lamb, LV_EVENT_VALUE_CHANGED, this);
|
37
|
+
lv_obj_add_event_cb(this->widget_->obj, lamb, lv_update_event, this);
|
38
38
|
}
|
39
39
|
|
40
|
-
void
|
41
|
-
auto value = this->at(index);
|
42
|
-
if (value)
|
43
|
-
this->publish_state(value.value());
|
44
|
-
}
|
45
|
-
|
46
|
-
void set_options(const char *str) { this->traits.set_options(split_string(str)); }
|
40
|
+
void publish() { this->publish_state(this->widget_->get_selected_text()); }
|
47
41
|
|
48
42
|
protected:
|
49
43
|
void control(const std::string &value) override {
|
50
|
-
if (this->
|
51
|
-
|
52
|
-
if (index)
|
53
|
-
this->control_lambda_(index.value());
|
44
|
+
if (this->widget_ != nullptr) {
|
45
|
+
this->widget_->set_selected_text(value, this->anim_);
|
54
46
|
} else {
|
55
|
-
this->initial_state_ = value
|
47
|
+
this->initial_state_ = value;
|
56
48
|
}
|
57
49
|
}
|
50
|
+
void set_options_() { this->traits.set_options(this->widget_->get_options()); }
|
58
51
|
|
59
|
-
|
60
|
-
optional<
|
52
|
+
LvSelectable *widget_{};
|
53
|
+
optional<std::string> initial_state_{};
|
54
|
+
lv_anim_enable_t anim_{LV_ANIM_OFF};
|
61
55
|
};
|
62
56
|
|
63
57
|
} // namespace lvgl
|
@@ -1,8 +1,7 @@
|
|
1
|
-
import esphome.codegen as cg
|
2
1
|
from esphome.components.sensor import Sensor, new_sensor, sensor_schema
|
3
2
|
import esphome.config_validation as cv
|
4
3
|
|
5
|
-
from ..defines import
|
4
|
+
from ..defines import CONF_WIDGET
|
6
5
|
from ..lvcode import (
|
7
6
|
API_EVENT,
|
8
7
|
EVENT_ARG,
|
@@ -11,34 +10,29 @@ from ..lvcode import (
|
|
11
10
|
LambdaContext,
|
12
11
|
LvContext,
|
13
12
|
lv_add,
|
13
|
+
lvgl_static,
|
14
14
|
)
|
15
|
-
from ..schemas import LVGL_SCHEMA
|
16
15
|
from ..types import LV_EVENT, LvNumber
|
17
16
|
from ..widgets import Widget, get_widgets, wait_for_widgets
|
18
17
|
|
19
|
-
CONFIG_SCHEMA = (
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
{
|
24
|
-
cv.Required(CONF_WIDGET): cv.use_id(LvNumber),
|
25
|
-
}
|
26
|
-
)
|
18
|
+
CONFIG_SCHEMA = sensor_schema(Sensor).extend(
|
19
|
+
{
|
20
|
+
cv.Required(CONF_WIDGET): cv.use_id(LvNumber),
|
21
|
+
}
|
27
22
|
)
|
28
23
|
|
29
24
|
|
30
25
|
async def to_code(config):
|
31
26
|
sensor = await new_sensor(config)
|
32
|
-
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
33
27
|
widget = await get_widgets(config, CONF_WIDGET)
|
34
28
|
widget = widget[0]
|
35
29
|
assert isinstance(widget, Widget)
|
36
30
|
await wait_for_widgets()
|
37
31
|
async with LambdaContext(EVENT_ARG) as lamb:
|
38
32
|
lv_add(sensor.publish_state(widget.get_value()))
|
39
|
-
async with LvContext(
|
33
|
+
async with LvContext(LVGL_COMP_ARG):
|
40
34
|
lv_add(
|
41
|
-
|
35
|
+
lvgl_static.add_event_cb(
|
42
36
|
widget.obj,
|
43
37
|
await lamb.get_lambda(),
|
44
38
|
LV_EVENT.VALUE_CHANGED,
|
@@ -17,8 +17,6 @@ from .types import lv_lambda_t, lv_obj_t, lv_obj_t_ptr
|
|
17
17
|
from .widgets import Widget, add_widgets, set_obj_properties, theme_widget_map
|
18
18
|
from .widgets.obj import obj_spec
|
19
19
|
|
20
|
-
TOP_LAYER = literal("lv_disp_get_layer_top(lv_component->get_disp())")
|
21
|
-
|
22
20
|
|
23
21
|
async def styles_to_code(config):
|
24
22
|
"""Convert styles to C__ code."""
|
@@ -51,9 +49,10 @@ async def theme_to_code(config):
|
|
51
49
|
lv_assign(apply, await context.get_lambda())
|
52
50
|
|
53
51
|
|
54
|
-
async def add_top_layer(config):
|
52
|
+
async def add_top_layer(lv_component, config):
|
53
|
+
top_layer = lv.disp_get_layer_top(lv_component.get_disp())
|
55
54
|
if top_conf := config.get(CONF_TOP_LAYER):
|
56
|
-
with LocalVariable("top_layer", lv_obj_t,
|
55
|
+
with LocalVariable("top_layer", lv_obj_t, top_layer) as top_layer_obj:
|
57
56
|
top_w = Widget(top_layer_obj, obj_spec, top_conf)
|
58
57
|
await set_obj_properties(top_w, top_conf)
|
59
58
|
await add_widgets(top_w, top_conf)
|
@@ -3,7 +3,7 @@ from esphome.components.switch import Switch, new_switch, switch_schema
|
|
3
3
|
import esphome.config_validation as cv
|
4
4
|
from esphome.cpp_generator import MockObj
|
5
5
|
|
6
|
-
from ..defines import
|
6
|
+
from ..defines import CONF_WIDGET, literal
|
7
7
|
from ..lvcode import (
|
8
8
|
API_EVENT,
|
9
9
|
EVENT_ARG,
|
@@ -13,26 +13,21 @@ from ..lvcode import (
|
|
13
13
|
LvContext,
|
14
14
|
lv,
|
15
15
|
lv_add,
|
16
|
+
lvgl_static,
|
16
17
|
)
|
17
|
-
from ..schemas import LVGL_SCHEMA
|
18
18
|
from ..types import LV_EVENT, LV_STATE, lv_pseudo_button_t, lvgl_ns
|
19
19
|
from ..widgets import get_widgets, wait_for_widgets
|
20
20
|
|
21
21
|
LVGLSwitch = lvgl_ns.class_("LVGLSwitch", Switch)
|
22
|
-
CONFIG_SCHEMA = (
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
{
|
27
|
-
cv.Required(CONF_WIDGET): cv.use_id(lv_pseudo_button_t),
|
28
|
-
}
|
29
|
-
)
|
22
|
+
CONFIG_SCHEMA = switch_schema(LVGLSwitch).extend(
|
23
|
+
{
|
24
|
+
cv.Required(CONF_WIDGET): cv.use_id(lv_pseudo_button_t),
|
25
|
+
}
|
30
26
|
)
|
31
27
|
|
32
28
|
|
33
29
|
async def to_code(config):
|
34
30
|
switch = await new_switch(config)
|
35
|
-
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
36
31
|
widget = await get_widgets(config, CONF_WIDGET)
|
37
32
|
widget = widget[0]
|
38
33
|
await wait_for_widgets()
|
@@ -45,10 +40,10 @@ async def to_code(config):
|
|
45
40
|
widget.clear_state(LV_STATE.CHECKED)
|
46
41
|
lv.event_send(widget.obj, API_EVENT, cg.nullptr)
|
47
42
|
control.add(switch.publish_state(literal("v")))
|
48
|
-
async with LvContext(
|
43
|
+
async with LvContext() as ctx:
|
49
44
|
lv_add(switch.set_control_lambda(await control.get_lambda()))
|
50
45
|
ctx.add(
|
51
|
-
|
46
|
+
lvgl_static.add_event_cb(
|
52
47
|
widget.obj,
|
53
48
|
await checked_ctx.get_lambda(),
|
54
49
|
LV_EVENT.VALUE_CHANGED,
|
@@ -3,7 +3,7 @@ from esphome.components import text
|
|
3
3
|
from esphome.components.text import new_text
|
4
4
|
import esphome.config_validation as cv
|
5
5
|
|
6
|
-
from ..defines import
|
6
|
+
from ..defines import CONF_WIDGET
|
7
7
|
from ..lvcode import (
|
8
8
|
API_EVENT,
|
9
9
|
EVENT_ARG,
|
@@ -12,14 +12,14 @@ from ..lvcode import (
|
|
12
12
|
LvContext,
|
13
13
|
lv,
|
14
14
|
lv_add,
|
15
|
+
lvgl_static,
|
15
16
|
)
|
16
|
-
from ..schemas import LVGL_SCHEMA
|
17
17
|
from ..types import LV_EVENT, LvText, lvgl_ns
|
18
18
|
from ..widgets import get_widgets, wait_for_widgets
|
19
19
|
|
20
20
|
LVGLText = lvgl_ns.class_("LVGLText", text.Text)
|
21
21
|
|
22
|
-
CONFIG_SCHEMA = text.TEXT_SCHEMA.extend(
|
22
|
+
CONFIG_SCHEMA = text.TEXT_SCHEMA.extend(
|
23
23
|
{
|
24
24
|
cv.GenerateID(): cv.declare_id(LVGLText),
|
25
25
|
cv.Required(CONF_WIDGET): cv.use_id(LvText),
|
@@ -29,7 +29,6 @@ CONFIG_SCHEMA = text.TEXT_SCHEMA.extend(LVGL_SCHEMA).extend(
|
|
29
29
|
|
30
30
|
async def to_code(config):
|
31
31
|
textvar = await new_text(config)
|
32
|
-
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
33
32
|
widget = await get_widgets(config, CONF_WIDGET)
|
34
33
|
widget = widget[0]
|
35
34
|
await wait_for_widgets()
|
@@ -39,10 +38,10 @@ async def to_code(config):
|
|
39
38
|
control.add(textvar.publish_state(widget.get_value()))
|
40
39
|
async with LambdaContext(EVENT_ARG) as lamb:
|
41
40
|
lv_add(textvar.publish_state(widget.get_value()))
|
42
|
-
async with LvContext(
|
41
|
+
async with LvContext():
|
43
42
|
lv_add(textvar.set_control_lambda(await control.get_lambda()))
|
44
43
|
lv_add(
|
45
|
-
|
44
|
+
lvgl_static.add_event_cb(
|
46
45
|
widget.obj,
|
47
46
|
await lamb.get_lambda(),
|
48
47
|
LV_EVENT.VALUE_CHANGED,
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import esphome.codegen as cg
|
2
1
|
from esphome.components.text_sensor import (
|
3
2
|
TextSensor,
|
4
3
|
new_text_sensor,
|
@@ -6,34 +5,35 @@ from esphome.components.text_sensor import (
|
|
6
5
|
)
|
7
6
|
import esphome.config_validation as cv
|
8
7
|
|
9
|
-
from ..defines import
|
10
|
-
from ..lvcode import
|
11
|
-
|
8
|
+
from ..defines import CONF_WIDGET
|
9
|
+
from ..lvcode import (
|
10
|
+
API_EVENT,
|
11
|
+
EVENT_ARG,
|
12
|
+
UPDATE_EVENT,
|
13
|
+
LambdaContext,
|
14
|
+
LvContext,
|
15
|
+
lvgl_static,
|
16
|
+
)
|
12
17
|
from ..types import LV_EVENT, LvText
|
13
18
|
from ..widgets import get_widgets, wait_for_widgets
|
14
19
|
|
15
|
-
CONFIG_SCHEMA = (
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
{
|
20
|
-
cv.Required(CONF_WIDGET): cv.use_id(LvText),
|
21
|
-
}
|
22
|
-
)
|
20
|
+
CONFIG_SCHEMA = text_sensor_schema(TextSensor).extend(
|
21
|
+
{
|
22
|
+
cv.Required(CONF_WIDGET): cv.use_id(LvText),
|
23
|
+
}
|
23
24
|
)
|
24
25
|
|
25
26
|
|
26
27
|
async def to_code(config):
|
27
28
|
sensor = await new_text_sensor(config)
|
28
|
-
paren = await cg.get_variable(config[CONF_LVGL_ID])
|
29
29
|
widget = await get_widgets(config, CONF_WIDGET)
|
30
30
|
widget = widget[0]
|
31
31
|
await wait_for_widgets()
|
32
32
|
async with LambdaContext(EVENT_ARG) as pressed_ctx:
|
33
33
|
pressed_ctx.add(sensor.publish_state(widget.get_value()))
|
34
|
-
async with LvContext(
|
34
|
+
async with LvContext() as ctx:
|
35
35
|
ctx.add(
|
36
|
-
|
36
|
+
lvgl_static.add_event_cb(
|
37
37
|
widget.obj,
|
38
38
|
await pressed_ctx.get_lambda(),
|
39
39
|
LV_EVENT.VALUE_CHANGED,
|
@@ -33,13 +33,12 @@ def touchscreen_schema(config):
|
|
33
33
|
return [TOUCHSCREENS_CONFIG(config)]
|
34
34
|
|
35
35
|
|
36
|
-
async def touchscreens_to_code(
|
36
|
+
async def touchscreens_to_code(lv_component, config):
|
37
37
|
for tconf in config[CONF_TOUCHSCREENS]:
|
38
38
|
lvgl_components_required.add(CONF_TOUCHSCREEN)
|
39
39
|
touchscreen = await cg.get_variable(tconf[CONF_TOUCHSCREEN_ID])
|
40
40
|
lpt = tconf[CONF_LONG_PRESS_TIME].total_milliseconds
|
41
41
|
lprt = tconf[CONF_LONG_PRESS_REPEAT_TIME].total_milliseconds
|
42
|
-
listener = cg.new_Pvariable(tconf[CONF_ID], lpt, lprt)
|
43
|
-
await cg.register_parented(listener, var)
|
42
|
+
listener = cg.new_Pvariable(tconf[CONF_ID], lpt, lprt, lv_component)
|
44
43
|
lv.indev_drv_register(listener.get_drv())
|
45
44
|
cg.add(touchscreen.register_listener(listener))
|
@@ -20,17 +20,16 @@ from .lvcode import (
|
|
20
20
|
lv,
|
21
21
|
lv_add,
|
22
22
|
lv_event_t_ptr,
|
23
|
+
lvgl_static,
|
23
24
|
)
|
24
25
|
from .types import LV_EVENT
|
25
26
|
from .widgets import widget_map
|
26
27
|
|
27
28
|
|
28
|
-
async def generate_triggers(
|
29
|
+
async def generate_triggers():
|
29
30
|
"""
|
30
31
|
Generate LVGL triggers for all defined widgets
|
31
32
|
Must be done after all widgets completed
|
32
|
-
:param lv_component: The parent component
|
33
|
-
:return:
|
34
33
|
"""
|
35
34
|
|
36
35
|
for w in widget_map.values():
|
@@ -43,11 +42,10 @@ async def generate_triggers(lv_component):
|
|
43
42
|
conf = conf[0]
|
44
43
|
w.add_flag("LV_OBJ_FLAG_CLICKABLE")
|
45
44
|
event = literal("LV_EVENT_" + LV_EVENT_MAP[event[3:].upper()])
|
46
|
-
await add_trigger(conf,
|
45
|
+
await add_trigger(conf, w, event)
|
47
46
|
for conf in w.config.get(CONF_ON_VALUE, ()):
|
48
47
|
await add_trigger(
|
49
48
|
conf,
|
50
|
-
lv_component,
|
51
49
|
w,
|
52
50
|
LV_EVENT.VALUE_CHANGED,
|
53
51
|
API_EVENT,
|
@@ -63,13 +61,13 @@ async def generate_triggers(lv_component):
|
|
63
61
|
lv.obj_align_to(w.obj, target, align, x, y)
|
64
62
|
|
65
63
|
|
66
|
-
async def add_trigger(conf,
|
64
|
+
async def add_trigger(conf, w, *events):
|
67
65
|
tid = conf[CONF_TRIGGER_ID]
|
68
66
|
trigger = cg.new_Pvariable(tid)
|
69
67
|
args = w.get_args() + [(lv_event_t_ptr, "event")]
|
70
|
-
value = w.
|
68
|
+
value = w.get_values()
|
71
69
|
await automation.build_automation(trigger, args, conf)
|
72
70
|
async with LambdaContext(EVENT_ARG, where=tid) as context:
|
73
71
|
with LvConditional(w.is_selected()):
|
74
|
-
lv_add(trigger.trigger(value, literal("event")))
|
75
|
-
lv_add(
|
72
|
+
lv_add(trigger.trigger(*value, literal("event")))
|
73
|
+
lv_add(lvgl_static.add_event_cb(w.obj, await context.get_lambda(), *events))
|
esphome/components/lvgl/types.py
CHANGED
@@ -18,7 +18,9 @@ class LvType(cg.MockObjClass):
|
|
18
18
|
self.value_property = None
|
19
19
|
|
20
20
|
def get_arg_type(self):
|
21
|
-
|
21
|
+
if len(self.args) == 0:
|
22
|
+
return None
|
23
|
+
return [arg[0] for arg in self.args]
|
22
24
|
|
23
25
|
|
24
26
|
class LvNumber(LvType):
|
@@ -38,8 +40,10 @@ void_ptr = cg.void.operator("ptr")
|
|
38
40
|
lv_coord_t = cg.global_ns.namespace("lv_coord_t")
|
39
41
|
lv_event_code_t = cg.global_ns.enum("lv_event_code_t")
|
40
42
|
lv_indev_type_t = cg.global_ns.enum("lv_indev_type_t")
|
43
|
+
lv_key_t = cg.global_ns.enum("lv_key_t")
|
41
44
|
FontEngine = lvgl_ns.class_("FontEngine")
|
42
45
|
IdleTrigger = lvgl_ns.class_("IdleTrigger", automation.Trigger.template())
|
46
|
+
PauseTrigger = lvgl_ns.class_("PauseTrigger", automation.Trigger.template())
|
43
47
|
ObjUpdateAction = lvgl_ns.class_("ObjUpdateAction", automation.Action)
|
44
48
|
LvglCondition = lvgl_ns.class_("LvglCondition", automation.Condition)
|
45
49
|
LvglAction = lvgl_ns.class_("LvglAction", automation.Action)
|
@@ -91,11 +95,13 @@ class LvBoolean(LvType):
|
|
91
95
|
|
92
96
|
class LvSelect(LvType):
|
93
97
|
def __init__(self, *args, **kwargs):
|
98
|
+
parens = kwargs.pop("parents", ()) + (LvCompound,)
|
94
99
|
super().__init__(
|
95
100
|
*args,
|
96
|
-
largs=[(cg.int_, "x")],
|
97
|
-
lvalue=lambda w: w.
|
101
|
+
largs=[(cg.int_, "x"), (cg.std_string, "text")],
|
102
|
+
lvalue=lambda w: [w.var.get_selected_index(), w.var.get_selected_text()],
|
98
103
|
has_on_value=True,
|
104
|
+
parents=parens,
|
99
105
|
**kwargs,
|
100
106
|
)
|
101
107
|
|
@@ -55,29 +55,14 @@ theme_widget_map = {}
|
|
55
55
|
styles_used = set()
|
56
56
|
|
57
57
|
|
58
|
-
class LvScrActType(WidgetType):
|
59
|
-
"""
|
60
|
-
A "widget" representing the active screen.
|
61
|
-
"""
|
62
|
-
|
63
|
-
def __init__(self):
|
64
|
-
super().__init__("lv_scr_act()", lv_obj_t, ())
|
65
|
-
|
66
|
-
async def to_code(self, w, config: dict):
|
67
|
-
return []
|
68
|
-
|
69
|
-
|
70
58
|
class Widget:
|
71
59
|
"""
|
72
60
|
Represents a Widget.
|
61
|
+
This class has a lot of methods. Adding any more runs foul of lint checks ("too many public methods").
|
73
62
|
"""
|
74
63
|
|
75
64
|
widgets_completed = False
|
76
65
|
|
77
|
-
@staticmethod
|
78
|
-
def set_completed():
|
79
|
-
Widget.widgets_completed = True
|
80
|
-
|
81
66
|
def __init__(self, var, wtype: WidgetType, config: dict = None):
|
82
67
|
self.var = var
|
83
68
|
self.type = wtype
|
@@ -179,9 +164,20 @@ class Widget:
|
|
179
164
|
|
180
165
|
def get_value(self):
|
181
166
|
if isinstance(self.type.w_type, LvType):
|
182
|
-
|
167
|
+
result = self.type.w_type.value(self)
|
168
|
+
if isinstance(result, list):
|
169
|
+
return result[0]
|
170
|
+
return result
|
183
171
|
return self.obj
|
184
172
|
|
173
|
+
def get_values(self):
|
174
|
+
if isinstance(self.type.w_type, LvType):
|
175
|
+
result = self.type.w_type.value(self)
|
176
|
+
if isinstance(result, list):
|
177
|
+
return result
|
178
|
+
return [result]
|
179
|
+
return [self.obj]
|
180
|
+
|
185
181
|
def get_number_value(self):
|
186
182
|
value = self.type.mock_obj.get_value(self.obj)
|
187
183
|
if self.scale == 1.0:
|
@@ -213,6 +209,25 @@ class Widget:
|
|
213
209
|
widget_map: dict[Any, Widget] = {}
|
214
210
|
|
215
211
|
|
212
|
+
class LvScrActType(WidgetType):
|
213
|
+
"""
|
214
|
+
A "widget" representing the active screen.
|
215
|
+
"""
|
216
|
+
|
217
|
+
def __init__(self):
|
218
|
+
super().__init__("lv_scr_act()", lv_obj_t, ())
|
219
|
+
|
220
|
+
async def to_code(self, w, config: dict):
|
221
|
+
return []
|
222
|
+
|
223
|
+
|
224
|
+
lv_scr_act_spec = LvScrActType()
|
225
|
+
|
226
|
+
|
227
|
+
def get_scr_act(lv_comp: MockObj) -> Widget:
|
228
|
+
return Widget.create(None, lv_comp.get_scr_act(), lv_scr_act_spec, {})
|
229
|
+
|
230
|
+
|
216
231
|
def get_widget_generator(wid):
|
217
232
|
"""
|
218
233
|
Used to wait for a widget during code generation.
|
@@ -443,7 +458,3 @@ async def widget_to_code(w_cnfig, w_type: WidgetType, parent):
|
|
443
458
|
await set_obj_properties(w, w_cnfig)
|
444
459
|
await add_widgets(w, w_cnfig)
|
445
460
|
await spec.to_code(w, w_cnfig)
|
446
|
-
|
447
|
-
|
448
|
-
lv_scr_act_spec = LvScrActType()
|
449
|
-
lv_scr_act = Widget.create(None, literal("lv_scr_act()"), lv_scr_act_spec, {})
|