esphome 2024.7.2__py3-none-any.whl → 2024.8.0__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 +15 -81
- esphome/automation.py +1 -1
- esphome/codegen.py +53 -53
- esphome/components/ade7953/sensor.py +1 -1
- esphome/components/ade7953_spi/ade7953_spi.cpp +1 -1
- esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +5 -2
- esphome/components/airthings_wave_plus/airthings_wave_plus.h +2 -0
- esphome/components/airthings_wave_plus/sensor.py +12 -0
- esphome/components/alarm_control_panel/__init__.py +75 -66
- esphome/components/apds9306/__init__.py +4 -0
- esphome/components/apds9306/apds9306.cpp +151 -0
- esphome/components/apds9306/apds9306.h +66 -0
- esphome/components/apds9306/sensor.py +95 -0
- esphome/components/api/__init__.py +80 -52
- esphome/components/api/api_connection.cpp +14 -1
- esphome/components/api/api_pb2.cpp +33 -4
- esphome/components/api/api_pb2.h +8 -1
- esphome/components/api/api_server.cpp +10 -0
- esphome/components/api/api_server.h +3 -0
- esphome/components/atm90e32/__init__.py +7 -0
- esphome/components/atm90e32/atm90e32.cpp +68 -16
- esphome/components/atm90e32/atm90e32.h +20 -7
- esphome/components/atm90e32/atm90e32_reg.h +2 -0
- esphome/components/atm90e32/button/__init__.py +43 -0
- esphome/components/atm90e32/button/atm90e32_button.cpp +20 -0
- esphome/components/atm90e32/button/atm90e32_button.h +27 -0
- esphome/components/atm90e32/sensor.py +15 -11
- esphome/components/bedjet/bedjet_codec.h +1 -1
- esphome/components/binary/light/binary_light_output.h +3 -2
- esphome/components/binary_sensor/__init__.py +5 -5
- esphome/components/ble_client/__init__.py +3 -3
- esphome/components/ble_client/output/__init__.py +1 -1
- esphome/components/ble_client/sensor/__init__.py +4 -3
- esphome/components/ble_client/switch/__init__.py +2 -1
- esphome/components/ble_client/text_sensor/__init__.py +4 -3
- esphome/components/ble_presence/binary_sensor.py +3 -3
- esphome/components/ble_rssi/sensor.py +2 -2
- esphome/components/ble_scanner/text_sensor.py +1 -1
- esphome/components/bluetooth_proxy/__init__.py +3 -3
- esphome/components/bme68x_bsec2/__init__.py +196 -0
- esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +523 -0
- esphome/components/bme68x_bsec2/bme68x_bsec2.h +163 -0
- esphome/components/bme68x_bsec2/sensor.py +130 -0
- esphome/components/bme68x_bsec2/text_sensor.py +33 -0
- esphome/components/bme68x_bsec2_i2c/__init__.py +28 -0
- esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.cpp +53 -0
- esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.h +28 -0
- esphome/components/bmp3xx/sensor.py +1 -1
- esphome/components/button/__init__.py +4 -4
- esphome/components/climate/__init__.py +5 -5
- esphome/components/climate/climate.h +1 -1
- esphome/components/cover/__init__.py +8 -8
- esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +11 -7
- esphome/components/cst226/touchscreen/cst226_touchscreen.h +1 -1
- esphome/components/datetime/__init__.py +11 -13
- esphome/components/demo/demo_sensor.h +3 -2
- esphome/components/display/display.cpp +31 -0
- esphome/components/display/display.h +3 -0
- esphome/components/display_menu_base/__init__.py +14 -13
- esphome/components/ens160/sensor.py +1 -1
- esphome/components/esp32/__init__.py +22 -10
- esphome/components/esp32/boards.py +1 -1
- esphome/components/esp32/gpio.py +12 -13
- esphome/components/esp32/gpio_esp32.py +1 -2
- esphome/components/esp32/gpio_esp32_c2.py +1 -2
- esphome/components/esp32/gpio_esp32_c3.py +1 -5
- esphome/components/esp32/gpio_esp32_c6.py +1 -2
- esphome/components/esp32/gpio_esp32_h2.py +1 -2
- esphome/components/esp32/gpio_esp32_s2.py +1 -2
- esphome/components/esp32/gpio_esp32_s3.py +1 -6
- esphome/components/esp32_ble/__init__.py +20 -3
- esphome/components/esp32_ble/ble.cpp +9 -1
- esphome/components/esp32_ble/ble.h +9 -0
- esphome/components/esp32_ble/ble_advertising.cpp +42 -9
- esphome/components/esp32_ble/ble_advertising.h +21 -1
- esphome/components/esp32_ble_beacon/__init__.py +17 -7
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +45 -113
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.h +17 -19
- esphome/components/esp32_ble_client/__init__.py +0 -1
- esphome/components/esp32_ble_server/__init__.py +2 -3
- esphome/components/esp32_ble_tracker/__init__.py +2 -2
- esphome/components/esp32_improv/__init__.py +2 -4
- esphome/components/ethernet/__init__.py +17 -17
- esphome/components/ethernet_info/text_sensor.py +2 -2
- esphome/components/event/__init__.py +5 -5
- esphome/components/fan/__init__.py +14 -14
- esphome/components/fan/fan.cpp +2 -2
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
- esphome/components/fingerprint_grow/fingerprint_grow.h +1 -1
- esphome/components/graphical_display_menu/__init__.py +11 -8
- esphome/components/haier/haier_base.h +2 -2
- esphome/components/homeassistant/__init__.py +8 -1
- esphome/components/homeassistant/number/__init__.py +33 -0
- esphome/components/homeassistant/number/homeassistant_number.cpp +100 -0
- esphome/components/homeassistant/number/homeassistant_number.h +31 -0
- esphome/components/homeassistant/switch/__init__.py +30 -0
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +59 -0
- esphome/components/homeassistant/switch/homeassistant_switch.h +22 -0
- esphome/components/host/__init__.py +3 -7
- esphome/components/http_request/__init__.py +12 -1
- esphome/components/http_request/http_request_arduino.cpp +2 -2
- esphome/components/http_request/http_request_idf.cpp +11 -2
- esphome/components/http_request/http_request_idf.h +10 -0
- esphome/components/http_request/ota/ota_http_request.cpp +1 -1
- esphome/components/http_request/update/http_request_update.cpp +2 -2
- esphome/components/http_request/update/http_request_update.h +2 -1
- esphome/components/hx711/hx711.cpp +10 -1
- esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +1 -1
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +11 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +2 -0
- esphome/components/ili9xxx/ili9xxx_defines.h +3 -1
- esphome/components/ili9xxx/ili9xxx_display.cpp +9 -22
- esphome/components/ili9xxx/ili9xxx_display.h +5 -7
- esphome/components/ili9xxx/ili9xxx_init.h +4 -4
- esphome/components/improv_base/__init__.py +2 -3
- esphome/components/improv_serial/__init__.py +4 -10
- esphome/components/improv_serial/improv_serial_component.cpp +4 -0
- esphome/components/jsn_sr04t/jsn_sr04t.cpp +18 -1
- esphome/components/jsn_sr04t/jsn_sr04t.h +7 -1
- esphome/components/jsn_sr04t/sensor.py +13 -0
- esphome/components/kalman_combinator/sensor.py +1 -1
- esphome/components/light/__init__.py +16 -15
- esphome/components/light/addressable_light_effect.h +12 -8
- esphome/components/light/automation.h +16 -1
- esphome/components/light/automation.py +21 -0
- esphome/components/light/base_light_effects.h +5 -5
- esphome/components/light/esp_color_correction.h +8 -8
- esphome/components/light/types.py +7 -0
- esphome/components/lock/__init__.py +3 -3
- esphome/components/logger/__init__.py +15 -18
- esphome/components/lvgl/__init__.py +346 -0
- esphome/components/lvgl/automation.py +226 -0
- esphome/components/lvgl/binary_sensor/__init__.py +43 -0
- esphome/components/lvgl/defines.py +508 -0
- esphome/components/lvgl/encoders.py +77 -0
- esphome/components/lvgl/font.cpp +76 -0
- esphome/components/lvgl/helpers.py +49 -0
- esphome/components/lvgl/light/__init__.py +32 -0
- esphome/components/lvgl/light/lvgl_light.h +48 -0
- esphome/components/lvgl/lv_validation.py +303 -0
- esphome/components/lvgl/lvcode.py +349 -0
- esphome/components/lvgl/lvgl_esphome.cpp +407 -0
- esphome/components/lvgl/lvgl_esphome.h +274 -0
- esphome/components/lvgl/lvgl_hal.h +21 -0
- esphome/components/lvgl/number/__init__.py +66 -0
- esphome/components/lvgl/number/lvgl_number.h +34 -0
- esphome/components/lvgl/schemas.py +436 -0
- esphome/components/lvgl/select/__init__.py +55 -0
- esphome/components/lvgl/select/lvgl_select.h +62 -0
- esphome/components/lvgl/sensor/__init__.py +47 -0
- esphome/components/lvgl/styles.py +58 -0
- esphome/components/lvgl/switch/__init__.py +56 -0
- esphome/components/lvgl/switch/lvgl_switch.h +34 -0
- esphome/components/lvgl/text/__init__.py +50 -0
- esphome/components/lvgl/text/lvgl_text.h +34 -0
- esphome/components/lvgl/text_sensor/__init__.py +42 -0
- esphome/components/lvgl/touchscreens.py +45 -0
- esphome/components/lvgl/trigger.py +74 -0
- esphome/components/lvgl/types.py +191 -0
- esphome/components/lvgl/widgets/__init__.py +419 -0
- esphome/components/lvgl/widgets/animimg.py +117 -0
- esphome/components/lvgl/widgets/arc.py +78 -0
- esphome/components/lvgl/widgets/button.py +20 -0
- esphome/components/lvgl/widgets/buttonmatrix.py +275 -0
- esphome/components/lvgl/widgets/checkbox.py +27 -0
- esphome/components/lvgl/widgets/dropdown.py +76 -0
- esphome/components/lvgl/widgets/img.py +85 -0
- esphome/components/lvgl/widgets/keyboard.py +49 -0
- esphome/components/lvgl/widgets/label.py +42 -0
- esphome/components/lvgl/widgets/led.py +29 -0
- esphome/components/lvgl/widgets/line.py +50 -0
- esphome/components/lvgl/widgets/lv_bar.py +55 -0
- esphome/components/lvgl/widgets/meter.py +302 -0
- esphome/components/lvgl/widgets/msgbox.py +134 -0
- esphome/components/lvgl/widgets/obj.py +28 -0
- esphome/components/lvgl/widgets/page.py +113 -0
- esphome/components/lvgl/widgets/roller.py +77 -0
- esphome/components/lvgl/widgets/slider.py +63 -0
- esphome/components/lvgl/widgets/spinbox.py +178 -0
- esphome/components/lvgl/widgets/spinner.py +43 -0
- esphome/components/lvgl/widgets/switch.py +20 -0
- esphome/components/lvgl/widgets/tabview.py +114 -0
- esphome/components/lvgl/widgets/textarea.py +66 -0
- esphome/components/lvgl/widgets/tileview.py +128 -0
- esphome/components/m5stack_8angle/__init__.py +33 -0
- esphome/components/m5stack_8angle/binary_sensor/__init__.py +30 -0
- esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +17 -0
- esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.h +19 -0
- esphome/components/m5stack_8angle/light/__init__.py +31 -0
- esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +45 -0
- esphome/components/m5stack_8angle/light/m5stack_8angle_light.h +37 -0
- esphome/components/m5stack_8angle/m5stack_8angle.cpp +74 -0
- esphome/components/m5stack_8angle/m5stack_8angle.h +34 -0
- esphome/components/m5stack_8angle/sensor/__init__.py +66 -0
- esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +24 -0
- esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.h +27 -0
- esphome/components/matrix_keypad/matrix_keypad.cpp +2 -0
- esphome/components/max31856/sensor.py +5 -5
- esphome/components/media_player/__init__.py +3 -5
- esphome/components/media_player/automation.h +31 -27
- esphome/components/micro_wake_word/__init__.py +20 -25
- esphome/components/micro_wake_word/streaming_model.cpp +6 -4
- esphome/components/microphone/microphone.h +4 -1
- esphome/components/mitsubishi/mitsubishi.cpp +7 -1
- esphome/components/modbus_controller/__init__.py +26 -2
- esphome/components/modbus_controller/automation.h +19 -0
- esphome/components/modbus_controller/const.py +1 -0
- esphome/components/modbus_controller/modbus_controller.cpp +8 -0
- esphome/components/modbus_controller/modbus_controller.h +3 -0
- esphome/components/mqtt/__init__.py +20 -9
- esphome/components/mqtt/mqtt_alarm_control_panel.cpp +128 -0
- esphome/components/mqtt/mqtt_alarm_control_panel.h +39 -0
- esphome/components/mqtt/mqtt_backend.h +3 -1
- esphome/components/mqtt/mqtt_backend_esp32.cpp +4 -1
- esphome/components/mqtt/mqtt_backend_esp32.h +3 -1
- esphome/components/mqtt/mqtt_backend_esp8266.h +3 -1
- esphome/components/mqtt/mqtt_backend_libretiny.h +3 -1
- esphome/components/mqtt/mqtt_client.cpp +16 -3
- esphome/components/mqtt/mqtt_client.h +5 -1
- esphome/components/mqtt/mqtt_component.cpp +32 -4
- esphome/components/mqtt/mqtt_const.h +2 -0
- esphome/components/network/__init__.py +15 -12
- esphome/components/network/ip_address.h +3 -0
- esphome/components/network/util.cpp +2 -1
- esphome/components/network/util.h +3 -1
- esphome/components/nextion/base_component.py +5 -8
- esphome/components/number/__init__.py +7 -8
- esphome/components/online_image/__init__.py +167 -0
- esphome/components/online_image/image_decoder.cpp +44 -0
- esphome/components/online_image/image_decoder.h +112 -0
- esphome/components/online_image/online_image.cpp +283 -0
- esphome/components/online_image/online_image.h +195 -0
- esphome/components/online_image/png_image.cpp +68 -0
- esphome/components/online_image/png_image.h +33 -0
- esphome/components/ota/__init__.py +8 -4
- esphome/components/pid/pid_climate.h +2 -0
- esphome/components/pmwcs3/pmwcs3.cpp +31 -30
- esphome/components/remote_base/pronto_protocol.cpp +0 -3
- esphome/components/remote_transmitter/remote_transmitter.h +1 -1
- esphome/components/rgbct/rgbct_light_output.h +3 -2
- esphome/components/rgbw/rgbw_light_output.h +3 -2
- esphome/components/rgbww/rgbww_light_output.h +3 -2
- esphome/components/rp2040_pio_led_strip/led_strip.cpp +31 -5
- esphome/components/rp2040_pio_led_strip/led_strip.h +5 -0
- esphome/components/rtttl/rtttl.cpp +108 -21
- esphome/components/rtttl/rtttl.h +15 -6
- esphome/components/select/__init__.py +7 -7
- esphome/components/sensor/__init__.py +29 -10
- esphome/components/sensor/filter.cpp +8 -0
- esphome/components/sensor/filter.h +9 -0
- esphome/components/sml/sml_parser.cpp +48 -22
- esphome/components/socket/socket.cpp +11 -14
- esphome/components/speaker/__init__.py +14 -5
- esphome/components/speaker/automation.h +10 -0
- esphome/components/speaker/speaker.h +9 -0
- esphome/components/spi/spi.cpp +0 -6
- esphome/components/spi/spi.h +2 -19
- esphome/components/spi_led_strip/spi_led_strip.h +5 -4
- esphome/components/sprinkler/sprinkler.cpp +2 -2
- esphome/components/sprinkler/sprinkler.h +1 -1
- esphome/components/switch/__init__.py +3 -3
- esphome/components/text/__init__.py +5 -5
- esphome/components/text_sensor/__init__.py +7 -7
- esphome/components/time/__init__.py +8 -8
- esphome/components/touchscreen/binary_sensor/__init__.py +24 -10
- esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.cpp +3 -2
- esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.h +4 -2
- esphome/components/uart/uart_component_host.cpp +6 -2
- esphome/components/update/__init__.py +33 -15
- esphome/components/update/automation.h +23 -0
- esphome/components/update/update_entity.h +3 -1
- esphome/components/valve/__init__.py +3 -3
- esphome/components/voice_assistant/__init__.py +7 -8
- esphome/components/wake_on_lan/wake_on_lan.cpp +2 -0
- esphome/components/wake_on_lan/wake_on_lan.h +3 -1
- esphome/components/watchdog/__init__.py +1 -0
- esphome/components/{http_request → watchdog}/watchdog.cpp +0 -2
- esphome/components/{http_request → watchdog}/watchdog.h +0 -2
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +5 -5
- esphome/components/web_server/server_index_v3.h +3615 -3603
- esphome/components/web_server/web_server.cpp +0 -209
- esphome/components/web_server/web_server.h +1 -1
- esphome/components/web_server/web_server_v1.cpp +217 -0
- esphome/components/web_server_base/web_server_base.h +1 -0
- esphome/components/wifi/__init__.py +15 -14
- esphome/components/wifi/wifi_component.cpp +2 -0
- esphome/components/wifi/wifi_component.h +7 -1
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +5 -2
- esphome/components/wifi/wifi_component_esp8266.cpp +2 -0
- esphome/components/wifi/wifi_component_esp_idf.cpp +43 -7
- esphome/components/wifi/wifi_component_libretiny.cpp +2 -0
- esphome/components/wifi/wifi_component_pico_w.cpp +2 -0
- esphome/components/wifi/wpa2_eap.py +6 -7
- esphome/components/wifi_info/text_sensor.py +3 -3
- esphome/components/wifi_info/wifi_info_text_sensor.cpp +2 -0
- esphome/components/wifi_info/wifi_info_text_sensor.h +2 -0
- esphome/components/wifi_signal/sensor.py +1 -1
- esphome/components/wifi_signal/wifi_signal_sensor.cpp +2 -0
- esphome/components/wifi_signal/wifi_signal_sensor.h +2 -1
- esphome/components/xiaomi_ble/xiaomi_ble.cpp +20 -3
- esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
- esphome/components/xiaomi_lywsd02mmc/__init__.py +0 -0
- esphome/components/xiaomi_lywsd02mmc/sensor.py +77 -0
- esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp +73 -0
- esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +37 -0
- esphome/config.py +17 -19
- esphome/config_validation.py +55 -23
- esphome/const.py +25 -9
- esphome/core/__init__.py +17 -14
- esphome/core/application.h +42 -21
- esphome/core/automation.h +5 -3
- esphome/core/base_automation.h +3 -2
- esphome/core/bytebuffer.cpp +134 -0
- esphome/core/bytebuffer.h +96 -0
- esphome/core/color.h +24 -16
- esphome/core/config.py +3 -3
- esphome/core/defines.h +14 -1
- esphome/core/entity_base.h +2 -2
- esphome/core/entity_helpers.py +1 -2
- esphome/core/gpio.h +0 -18
- esphome/core/helpers.h +1 -1
- esphome/core/optional.h +15 -16
- esphome/coroutine.py +1 -1
- esphome/cpp_generator.py +1 -1
- esphome/cpp_helpers.py +3 -5
- esphome/dashboard/core.py +3 -3
- esphome/dashboard/dashboard.py +3 -3
- esphome/dashboard/entries.py +1 -1
- esphome/dashboard/util/file.py +1 -1
- esphome/dashboard/web_server.py +3 -3
- esphome/external_files.py +5 -3
- esphome/final_validate.py +2 -2
- esphome/git.py +4 -4
- esphome/helpers.py +5 -5
- esphome/loader.py +15 -10
- esphome/mqtt.py +4 -8
- esphome/pins.py +6 -6
- esphome/platformio_api.py +5 -5
- esphome/storage_json.py +2 -1
- esphome/types.py +1 -1
- esphome/util.py +2 -3
- esphome/voluptuous_schema.py +1 -0
- esphome/vscode.py +5 -4
- esphome/wizard.py +1 -1
- esphome/writer.py +7 -7
- esphome/yaml_util.py +3 -3
- esphome/zeroconf.py +1 -1
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/METADATA +3 -3
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/RECORD +353 -247
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/LICENSE +0 -0
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/WHEEL +0 -0
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/entry_points.txt +0 -0
- {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,508 @@
|
|
1
|
+
"""
|
2
|
+
This is the base of the import tree for LVGL. It contains constant definitions used elsewhere.
|
3
|
+
Constants already defined in esphome.const are not duplicated here and must be imported where used.
|
4
|
+
|
5
|
+
"""
|
6
|
+
|
7
|
+
from esphome import codegen as cg, config_validation as cv
|
8
|
+
from esphome.const import CONF_ITEMS
|
9
|
+
from esphome.core import Lambda
|
10
|
+
from esphome.cpp_generator import LambdaExpression, MockObj
|
11
|
+
from esphome.cpp_types import uint32
|
12
|
+
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
13
|
+
|
14
|
+
from .helpers import requires_component
|
15
|
+
|
16
|
+
lvgl_ns = cg.esphome_ns.namespace("lvgl")
|
17
|
+
|
18
|
+
|
19
|
+
def literal(arg):
|
20
|
+
if isinstance(arg, str):
|
21
|
+
return MockObj(arg)
|
22
|
+
return arg
|
23
|
+
|
24
|
+
|
25
|
+
def call_lambda(lamb: LambdaExpression):
|
26
|
+
expr = lamb.content.strip()
|
27
|
+
if expr.startswith("return") and expr.endswith(";"):
|
28
|
+
return expr[7:][:-1]
|
29
|
+
return f"{lamb}()"
|
30
|
+
|
31
|
+
|
32
|
+
class LValidator:
|
33
|
+
"""
|
34
|
+
A validator for a particular type used in LVGL. Usable in configs as a validator, also
|
35
|
+
has `process()` to convert a value during code generation
|
36
|
+
"""
|
37
|
+
|
38
|
+
def __init__(self, validator, rtype, retmapper=None, requires=None):
|
39
|
+
self.validator = validator
|
40
|
+
self.rtype = rtype
|
41
|
+
self.retmapper = retmapper
|
42
|
+
self.requires = requires
|
43
|
+
|
44
|
+
def __call__(self, value):
|
45
|
+
if self.requires:
|
46
|
+
value = requires_component(self.requires)(value)
|
47
|
+
if isinstance(value, cv.Lambda):
|
48
|
+
return cv.returning_lambda(value)
|
49
|
+
return self.validator(value)
|
50
|
+
|
51
|
+
async def process(self, value, args=()):
|
52
|
+
if value is None:
|
53
|
+
return None
|
54
|
+
if isinstance(value, Lambda):
|
55
|
+
return cg.RawExpression(
|
56
|
+
call_lambda(
|
57
|
+
await cg.process_lambda(value, args, return_type=self.rtype)
|
58
|
+
)
|
59
|
+
)
|
60
|
+
if self.retmapper is not None:
|
61
|
+
return self.retmapper(value)
|
62
|
+
return cg.safe_exp(value)
|
63
|
+
|
64
|
+
|
65
|
+
class LvConstant(LValidator):
|
66
|
+
"""
|
67
|
+
Allow one of a list of choices, mapped to upper case, and prepend the choice with the prefix.
|
68
|
+
It's also permitted to include the prefix in the value
|
69
|
+
The property `one_of` has the single case validator, and `several_of` allows a list of constants.
|
70
|
+
"""
|
71
|
+
|
72
|
+
def __init__(self, prefix: str, *choices):
|
73
|
+
self.prefix = prefix
|
74
|
+
self.choices = choices
|
75
|
+
prefixed_choices = [prefix + v for v in choices]
|
76
|
+
prefixed_validator = cv.one_of(*prefixed_choices, upper=True)
|
77
|
+
|
78
|
+
@schema_extractor("one_of")
|
79
|
+
def validator(value):
|
80
|
+
if value == SCHEMA_EXTRACT:
|
81
|
+
return self.choices
|
82
|
+
if isinstance(value, str) and value.startswith(self.prefix):
|
83
|
+
return prefixed_validator(value)
|
84
|
+
return self.prefix + cv.one_of(*choices, upper=True)(value)
|
85
|
+
|
86
|
+
super().__init__(validator, rtype=uint32)
|
87
|
+
self.retmapper = self.mapper
|
88
|
+
self.one_of = LValidator(validator, uint32, retmapper=self.mapper)
|
89
|
+
self.several_of = LValidator(
|
90
|
+
cv.ensure_list(self.one_of), uint32, retmapper=self.mapper
|
91
|
+
)
|
92
|
+
|
93
|
+
def mapper(self, value):
|
94
|
+
if not isinstance(value, list):
|
95
|
+
value = [value]
|
96
|
+
return literal(
|
97
|
+
"|".join(
|
98
|
+
[
|
99
|
+
str(v) if str(v).startswith(self.prefix) else self.prefix + str(v)
|
100
|
+
for v in value
|
101
|
+
]
|
102
|
+
).upper()
|
103
|
+
)
|
104
|
+
|
105
|
+
def extend(self, *choices):
|
106
|
+
"""
|
107
|
+
Extend an LVconstant with additional choices.
|
108
|
+
:param choices: The extra choices
|
109
|
+
:return: A new LVConstant instance
|
110
|
+
"""
|
111
|
+
return LvConstant(self.prefix, *(self.choices + choices))
|
112
|
+
|
113
|
+
|
114
|
+
# Parts
|
115
|
+
CONF_MAIN = "main"
|
116
|
+
CONF_SCROLLBAR = "scrollbar"
|
117
|
+
CONF_INDICATOR = "indicator"
|
118
|
+
CONF_KNOB = "knob"
|
119
|
+
CONF_SELECTED = "selected"
|
120
|
+
CONF_TICKS = "ticks"
|
121
|
+
CONF_CURSOR = "cursor"
|
122
|
+
CONF_TEXTAREA_PLACEHOLDER = "textarea_placeholder"
|
123
|
+
|
124
|
+
# Layout types
|
125
|
+
|
126
|
+
TYPE_FLEX = "flex"
|
127
|
+
TYPE_GRID = "grid"
|
128
|
+
TYPE_NONE = "none"
|
129
|
+
|
130
|
+
LV_FONTS = list(f"montserrat_{s}" for s in range(8, 50, 2)) + [
|
131
|
+
"dejavu_16_persian_hebrew",
|
132
|
+
"simsun_16_cjk",
|
133
|
+
"unscii_8",
|
134
|
+
"unscii_16",
|
135
|
+
]
|
136
|
+
|
137
|
+
LV_EVENT_MAP = {
|
138
|
+
"PRESS": "PRESSED",
|
139
|
+
"SHORT_CLICK": "SHORT_CLICKED",
|
140
|
+
"LONG_PRESS": "LONG_PRESSED",
|
141
|
+
"LONG_PRESS_REPEAT": "LONG_PRESSED_REPEAT",
|
142
|
+
"CLICK": "CLICKED",
|
143
|
+
"RELEASE": "RELEASED",
|
144
|
+
"SCROLL_BEGIN": "SCROLL_BEGIN",
|
145
|
+
"SCROLL_END": "SCROLL_END",
|
146
|
+
"SCROLL": "SCROLL",
|
147
|
+
"FOCUS": "FOCUSED",
|
148
|
+
"DEFOCUS": "DEFOCUSED",
|
149
|
+
"READY": "READY",
|
150
|
+
"CANCEL": "CANCEL",
|
151
|
+
}
|
152
|
+
|
153
|
+
LV_EVENT_TRIGGERS = tuple(f"on_{x.lower()}" for x in LV_EVENT_MAP)
|
154
|
+
|
155
|
+
|
156
|
+
LV_ANIM = LvConstant(
|
157
|
+
"LV_SCR_LOAD_ANIM_",
|
158
|
+
"NONE",
|
159
|
+
"OVER_LEFT",
|
160
|
+
"OVER_RIGHT",
|
161
|
+
"OVER_TOP",
|
162
|
+
"OVER_BOTTOM",
|
163
|
+
"MOVE_LEFT",
|
164
|
+
"MOVE_RIGHT",
|
165
|
+
"MOVE_TOP",
|
166
|
+
"MOVE_BOTTOM",
|
167
|
+
"FADE_IN",
|
168
|
+
"FADE_OUT",
|
169
|
+
"OUT_LEFT",
|
170
|
+
"OUT_RIGHT",
|
171
|
+
"OUT_TOP",
|
172
|
+
"OUT_BOTTOM",
|
173
|
+
)
|
174
|
+
|
175
|
+
LOG_LEVELS = (
|
176
|
+
"TRACE",
|
177
|
+
"INFO",
|
178
|
+
"WARN",
|
179
|
+
"ERROR",
|
180
|
+
"USER",
|
181
|
+
"NONE",
|
182
|
+
)
|
183
|
+
|
184
|
+
LV_LONG_MODES = LvConstant(
|
185
|
+
"LV_LABEL_LONG_",
|
186
|
+
"WRAP",
|
187
|
+
"DOT",
|
188
|
+
"SCROLL",
|
189
|
+
"SCROLL_CIRCULAR",
|
190
|
+
"CLIP",
|
191
|
+
)
|
192
|
+
|
193
|
+
STATES = (
|
194
|
+
"default",
|
195
|
+
"checked",
|
196
|
+
"focused",
|
197
|
+
"focus_key",
|
198
|
+
"edited",
|
199
|
+
"hovered",
|
200
|
+
"pressed",
|
201
|
+
"scrolled",
|
202
|
+
"disabled",
|
203
|
+
"user_1",
|
204
|
+
"user_2",
|
205
|
+
"user_3",
|
206
|
+
"user_4",
|
207
|
+
)
|
208
|
+
|
209
|
+
PARTS = (
|
210
|
+
CONF_MAIN,
|
211
|
+
CONF_SCROLLBAR,
|
212
|
+
CONF_INDICATOR,
|
213
|
+
CONF_KNOB,
|
214
|
+
CONF_SELECTED,
|
215
|
+
CONF_ITEMS,
|
216
|
+
CONF_TICKS,
|
217
|
+
CONF_CURSOR,
|
218
|
+
CONF_TEXTAREA_PLACEHOLDER,
|
219
|
+
)
|
220
|
+
|
221
|
+
KEYBOARD_MODES = LvConstant(
|
222
|
+
"LV_KEYBOARD_MODE_",
|
223
|
+
"TEXT_LOWER",
|
224
|
+
"TEXT_UPPER",
|
225
|
+
"SPECIAL",
|
226
|
+
"NUMBER",
|
227
|
+
)
|
228
|
+
ROLLER_MODES = LvConstant("LV_ROLLER_MODE_", "NORMAL", "INFINITE")
|
229
|
+
DIRECTIONS = LvConstant("LV_DIR_", "LEFT", "RIGHT", "BOTTOM", "TOP")
|
230
|
+
TILE_DIRECTIONS = DIRECTIONS.extend("HOR", "VER", "ALL")
|
231
|
+
CHILD_ALIGNMENTS = LvConstant(
|
232
|
+
"LV_ALIGN_",
|
233
|
+
"TOP_LEFT",
|
234
|
+
"TOP_MID",
|
235
|
+
"TOP_RIGHT",
|
236
|
+
"LEFT_MID",
|
237
|
+
"CENTER",
|
238
|
+
"RIGHT_MID",
|
239
|
+
"BOTTOM_LEFT",
|
240
|
+
"BOTTOM_MID",
|
241
|
+
"BOTTOM_RIGHT",
|
242
|
+
)
|
243
|
+
|
244
|
+
SIBLING_ALIGNMENTS = LvConstant(
|
245
|
+
"LV_ALIGN_",
|
246
|
+
"OUT_LEFT_TOP",
|
247
|
+
"OUT_TOP_LEFT",
|
248
|
+
"OUT_TOP_MID",
|
249
|
+
"OUT_TOP_RIGHT",
|
250
|
+
"OUT_RIGHT_TOP",
|
251
|
+
"OUT_LEFT_MID",
|
252
|
+
"OUT_RIGHT_MID",
|
253
|
+
"OUT_LEFT_BOTTOM",
|
254
|
+
"OUT_BOTTOM_LEFT",
|
255
|
+
"OUT_BOTTOM_MID",
|
256
|
+
"OUT_BOTTOM_RIGHT",
|
257
|
+
"OUT_RIGHT_BOTTOM",
|
258
|
+
)
|
259
|
+
ALIGN_ALIGNMENTS = CHILD_ALIGNMENTS.extend(*SIBLING_ALIGNMENTS.choices)
|
260
|
+
|
261
|
+
FLEX_FLOWS = LvConstant(
|
262
|
+
"LV_FLEX_FLOW_",
|
263
|
+
"ROW",
|
264
|
+
"COLUMN",
|
265
|
+
"ROW_WRAP",
|
266
|
+
"COLUMN_WRAP",
|
267
|
+
"ROW_REVERSE",
|
268
|
+
"COLUMN_REVERSE",
|
269
|
+
"ROW_WRAP_REVERSE",
|
270
|
+
"COLUMN_WRAP_REVERSE",
|
271
|
+
)
|
272
|
+
|
273
|
+
OBJ_FLAGS = (
|
274
|
+
"hidden",
|
275
|
+
"clickable",
|
276
|
+
"click_focusable",
|
277
|
+
"checkable",
|
278
|
+
"scrollable",
|
279
|
+
"scroll_elastic",
|
280
|
+
"scroll_momentum",
|
281
|
+
"scroll_one",
|
282
|
+
"scroll_chain_hor",
|
283
|
+
"scroll_chain_ver",
|
284
|
+
"scroll_chain",
|
285
|
+
"scroll_on_focus",
|
286
|
+
"scroll_with_arrow",
|
287
|
+
"snappable",
|
288
|
+
"press_lock",
|
289
|
+
"event_bubble",
|
290
|
+
"gesture_bubble",
|
291
|
+
"adv_hittest",
|
292
|
+
"ignore_layout",
|
293
|
+
"floating",
|
294
|
+
"overflow_visible",
|
295
|
+
"layout_1",
|
296
|
+
"layout_2",
|
297
|
+
"widget_1",
|
298
|
+
"widget_2",
|
299
|
+
"user_1",
|
300
|
+
"user_2",
|
301
|
+
"user_3",
|
302
|
+
"user_4",
|
303
|
+
)
|
304
|
+
|
305
|
+
ARC_MODES = LvConstant("LV_ARC_MODE_", "NORMAL", "REVERSE", "SYMMETRICAL")
|
306
|
+
BAR_MODES = LvConstant("LV_BAR_MODE_", "NORMAL", "SYMMETRICAL", "RANGE")
|
307
|
+
|
308
|
+
BUTTONMATRIX_CTRLS = LvConstant(
|
309
|
+
"LV_BTNMATRIX_CTRL_",
|
310
|
+
"HIDDEN",
|
311
|
+
"NO_REPEAT",
|
312
|
+
"DISABLED",
|
313
|
+
"CHECKABLE",
|
314
|
+
"CHECKED",
|
315
|
+
"CLICK_TRIG",
|
316
|
+
"POPOVER",
|
317
|
+
"RECOLOR",
|
318
|
+
"CUSTOM_1",
|
319
|
+
"CUSTOM_2",
|
320
|
+
)
|
321
|
+
|
322
|
+
LV_BASE_ALIGNMENTS = (
|
323
|
+
"START",
|
324
|
+
"CENTER",
|
325
|
+
"END",
|
326
|
+
)
|
327
|
+
LV_CELL_ALIGNMENTS = LvConstant(
|
328
|
+
"LV_GRID_ALIGN_",
|
329
|
+
*LV_BASE_ALIGNMENTS,
|
330
|
+
)
|
331
|
+
LV_GRID_ALIGNMENTS = LV_CELL_ALIGNMENTS.extend(
|
332
|
+
"STRETCH",
|
333
|
+
"SPACE_EVENLY",
|
334
|
+
"SPACE_AROUND",
|
335
|
+
"SPACE_BETWEEN",
|
336
|
+
)
|
337
|
+
|
338
|
+
LV_FLEX_ALIGNMENTS = LvConstant(
|
339
|
+
"LV_FLEX_ALIGN_",
|
340
|
+
*LV_BASE_ALIGNMENTS,
|
341
|
+
"SPACE_EVENLY",
|
342
|
+
"SPACE_AROUND",
|
343
|
+
"SPACE_BETWEEN",
|
344
|
+
)
|
345
|
+
|
346
|
+
LV_MENU_MODES = LvConstant(
|
347
|
+
"LV_MENU_HEADER_",
|
348
|
+
"TOP_FIXED",
|
349
|
+
"TOP_UNFIXED",
|
350
|
+
"BOTTOM_FIXED",
|
351
|
+
)
|
352
|
+
|
353
|
+
LV_CHART_TYPES = (
|
354
|
+
"NONE",
|
355
|
+
"LINE",
|
356
|
+
"BAR",
|
357
|
+
"SCATTER",
|
358
|
+
)
|
359
|
+
LV_CHART_AXES = (
|
360
|
+
"PRIMARY_Y",
|
361
|
+
"SECONDARY_Y",
|
362
|
+
"PRIMARY_X",
|
363
|
+
"SECONDARY_X",
|
364
|
+
)
|
365
|
+
|
366
|
+
CONF_ACCEPTED_CHARS = "accepted_chars"
|
367
|
+
CONF_ADJUSTABLE = "adjustable"
|
368
|
+
CONF_ALIGN = "align"
|
369
|
+
CONF_ALIGN_TO = "align_to"
|
370
|
+
CONF_ANIMATED = "animated"
|
371
|
+
CONF_ANIMATION = "animation"
|
372
|
+
CONF_ANTIALIAS = "antialias"
|
373
|
+
CONF_ARC_LENGTH = "arc_length"
|
374
|
+
CONF_AUTO_START = "auto_start"
|
375
|
+
CONF_BACKGROUND_STYLE = "background_style"
|
376
|
+
CONF_DECIMAL_PLACES = "decimal_places"
|
377
|
+
CONF_COLUMN = "column"
|
378
|
+
CONF_DIGITS = "digits"
|
379
|
+
CONF_DISP_BG_COLOR = "disp_bg_color"
|
380
|
+
CONF_DISP_BG_IMAGE = "disp_bg_image"
|
381
|
+
CONF_BODY = "body"
|
382
|
+
CONF_BUTTONS = "buttons"
|
383
|
+
CONF_BYTE_ORDER = "byte_order"
|
384
|
+
CONF_CHANGE_RATE = "change_rate"
|
385
|
+
CONF_CLOSE_BUTTON = "close_button"
|
386
|
+
CONF_COLOR_DEPTH = "color_depth"
|
387
|
+
CONF_CONTROL = "control"
|
388
|
+
CONF_DEFAULT = "default"
|
389
|
+
CONF_DEFAULT_FONT = "default_font"
|
390
|
+
CONF_DEFAULT_GROUP = "default_group"
|
391
|
+
CONF_DIR = "dir"
|
392
|
+
CONF_DISPLAYS = "displays"
|
393
|
+
CONF_ENCODERS = "encoders"
|
394
|
+
CONF_END_ANGLE = "end_angle"
|
395
|
+
CONF_END_VALUE = "end_value"
|
396
|
+
CONF_ENTER_BUTTON = "enter_button"
|
397
|
+
CONF_ENTRIES = "entries"
|
398
|
+
CONF_FLAGS = "flags"
|
399
|
+
CONF_FLEX_FLOW = "flex_flow"
|
400
|
+
CONF_FLEX_ALIGN_MAIN = "flex_align_main"
|
401
|
+
CONF_FLEX_ALIGN_CROSS = "flex_align_cross"
|
402
|
+
CONF_FLEX_ALIGN_TRACK = "flex_align_track"
|
403
|
+
CONF_FLEX_GROW = "flex_grow"
|
404
|
+
CONF_FULL_REFRESH = "full_refresh"
|
405
|
+
CONF_GRID_CELL_ROW_POS = "grid_cell_row_pos"
|
406
|
+
CONF_GRID_CELL_COLUMN_POS = "grid_cell_column_pos"
|
407
|
+
CONF_GRID_CELL_ROW_SPAN = "grid_cell_row_span"
|
408
|
+
CONF_GRID_CELL_COLUMN_SPAN = "grid_cell_column_span"
|
409
|
+
CONF_GRID_CELL_X_ALIGN = "grid_cell_x_align"
|
410
|
+
CONF_GRID_CELL_Y_ALIGN = "grid_cell_y_align"
|
411
|
+
CONF_GRID_COLUMN_ALIGN = "grid_column_align"
|
412
|
+
CONF_GRID_COLUMNS = "grid_columns"
|
413
|
+
CONF_GRID_ROW_ALIGN = "grid_row_align"
|
414
|
+
CONF_GRID_ROWS = "grid_rows"
|
415
|
+
CONF_HEADER_MODE = "header_mode"
|
416
|
+
CONF_HOME = "home"
|
417
|
+
CONF_INITIAL_FOCUS = "initial_focus"
|
418
|
+
CONF_KEY_CODE = "key_code"
|
419
|
+
CONF_LAYOUT = "layout"
|
420
|
+
CONF_LEFT_BUTTON = "left_button"
|
421
|
+
CONF_LINE_WIDTH = "line_width"
|
422
|
+
CONF_LOG_LEVEL = "log_level"
|
423
|
+
CONF_LONG_PRESS_TIME = "long_press_time"
|
424
|
+
CONF_LONG_PRESS_REPEAT_TIME = "long_press_repeat_time"
|
425
|
+
CONF_LVGL_ID = "lvgl_id"
|
426
|
+
CONF_LONG_MODE = "long_mode"
|
427
|
+
CONF_MSGBOXES = "msgboxes"
|
428
|
+
CONF_OBJ = "obj"
|
429
|
+
CONF_OFFSET_X = "offset_x"
|
430
|
+
CONF_OFFSET_Y = "offset_y"
|
431
|
+
CONF_ONE_LINE = "one_line"
|
432
|
+
CONF_ON_SELECT = "on_select"
|
433
|
+
CONF_ONE_CHECKED = "one_checked"
|
434
|
+
CONF_NEXT = "next"
|
435
|
+
CONF_PAD_ROW = "pad_row"
|
436
|
+
CONF_PAD_COLUMN = "pad_column"
|
437
|
+
CONF_PAGE = "page"
|
438
|
+
CONF_PAGE_WRAP = "page_wrap"
|
439
|
+
CONF_PASSWORD_MODE = "password_mode"
|
440
|
+
CONF_PIVOT_X = "pivot_x"
|
441
|
+
CONF_PIVOT_Y = "pivot_y"
|
442
|
+
CONF_PLACEHOLDER_TEXT = "placeholder_text"
|
443
|
+
CONF_POINTS = "points"
|
444
|
+
CONF_PREVIOUS = "previous"
|
445
|
+
CONF_REPEAT_COUNT = "repeat_count"
|
446
|
+
CONF_RECOLOR = "recolor"
|
447
|
+
CONF_RIGHT_BUTTON = "right_button"
|
448
|
+
CONF_ROLLOVER = "rollover"
|
449
|
+
CONF_ROOT_BACK_BTN = "root_back_btn"
|
450
|
+
CONF_ROWS = "rows"
|
451
|
+
CONF_SCALE_LINES = "scale_lines"
|
452
|
+
CONF_SCROLLBAR_MODE = "scrollbar_mode"
|
453
|
+
CONF_SELECTED_INDEX = "selected_index"
|
454
|
+
CONF_SHOW_SNOW = "show_snow"
|
455
|
+
CONF_SPIN_TIME = "spin_time"
|
456
|
+
CONF_SRC = "src"
|
457
|
+
CONF_START_ANGLE = "start_angle"
|
458
|
+
CONF_START_VALUE = "start_value"
|
459
|
+
CONF_STATES = "states"
|
460
|
+
CONF_STYLE = "style"
|
461
|
+
CONF_STYLES = "styles"
|
462
|
+
CONF_STYLE_DEFINITIONS = "style_definitions"
|
463
|
+
CONF_STYLE_ID = "style_id"
|
464
|
+
CONF_SKIP = "skip"
|
465
|
+
CONF_SYMBOL = "symbol"
|
466
|
+
CONF_TAB_ID = "tab_id"
|
467
|
+
CONF_TABS = "tabs"
|
468
|
+
CONF_TIME_FORMAT = "time_format"
|
469
|
+
CONF_TILE = "tile"
|
470
|
+
CONF_TILE_ID = "tile_id"
|
471
|
+
CONF_TILES = "tiles"
|
472
|
+
CONF_TITLE = "title"
|
473
|
+
CONF_TOP_LAYER = "top_layer"
|
474
|
+
CONF_TOUCHSCREENS = "touchscreens"
|
475
|
+
CONF_TRANSPARENCY_KEY = "transparency_key"
|
476
|
+
CONF_THEME = "theme"
|
477
|
+
CONF_UPDATE_ON_RELEASE = "update_on_release"
|
478
|
+
CONF_VISIBLE_ROW_COUNT = "visible_row_count"
|
479
|
+
CONF_WIDGET = "widget"
|
480
|
+
CONF_WIDGETS = "widgets"
|
481
|
+
CONF_X = "x"
|
482
|
+
CONF_Y = "y"
|
483
|
+
CONF_ZOOM = "zoom"
|
484
|
+
|
485
|
+
# Keypad keys
|
486
|
+
|
487
|
+
LV_KEYS = LvConstant(
|
488
|
+
"LV_KEY_",
|
489
|
+
"UP",
|
490
|
+
"DOWN",
|
491
|
+
"RIGHT",
|
492
|
+
"LEFT",
|
493
|
+
"ESC",
|
494
|
+
"DEL",
|
495
|
+
"BACKSPACE",
|
496
|
+
"ENTER",
|
497
|
+
"NEXT",
|
498
|
+
"PREV",
|
499
|
+
"HOME",
|
500
|
+
"END",
|
501
|
+
)
|
502
|
+
|
503
|
+
|
504
|
+
DEFAULT_ESPHOME_FONT = "esphome_lv_default_font"
|
505
|
+
|
506
|
+
|
507
|
+
def join_enums(enums, prefix=""):
|
508
|
+
return literal("|".join(f"(int){prefix}{e.upper()}" for e in enums))
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import esphome.codegen as cg
|
2
|
+
from esphome.components.binary_sensor import BinarySensor
|
3
|
+
from esphome.components.rotary_encoder.sensor import RotaryEncoderSensor
|
4
|
+
import esphome.config_validation as cv
|
5
|
+
from esphome.const import CONF_GROUP, CONF_ID, CONF_SENSOR
|
6
|
+
|
7
|
+
from .defines import (
|
8
|
+
CONF_DEFAULT_GROUP,
|
9
|
+
CONF_ENCODERS,
|
10
|
+
CONF_ENTER_BUTTON,
|
11
|
+
CONF_INITIAL_FOCUS,
|
12
|
+
CONF_LEFT_BUTTON,
|
13
|
+
CONF_LONG_PRESS_REPEAT_TIME,
|
14
|
+
CONF_LONG_PRESS_TIME,
|
15
|
+
CONF_RIGHT_BUTTON,
|
16
|
+
)
|
17
|
+
from .helpers import lvgl_components_required, requires_component
|
18
|
+
from .lvcode import lv, lv_add, lv_assign, lv_expr, lv_Pvariable
|
19
|
+
from .schemas import ENCODER_SCHEMA
|
20
|
+
from .types import lv_group_t, lv_indev_type_t
|
21
|
+
|
22
|
+
ENCODERS_CONFIG = cv.ensure_list(
|
23
|
+
ENCODER_SCHEMA.extend(
|
24
|
+
{
|
25
|
+
cv.Required(CONF_ENTER_BUTTON): cv.use_id(BinarySensor),
|
26
|
+
cv.Required(CONF_SENSOR): cv.Any(
|
27
|
+
cv.All(
|
28
|
+
cv.use_id(RotaryEncoderSensor), requires_component("rotary_encoder")
|
29
|
+
),
|
30
|
+
cv.Schema(
|
31
|
+
{
|
32
|
+
cv.Required(CONF_LEFT_BUTTON): cv.use_id(BinarySensor),
|
33
|
+
cv.Required(CONF_RIGHT_BUTTON): cv.use_id(BinarySensor),
|
34
|
+
}
|
35
|
+
),
|
36
|
+
),
|
37
|
+
}
|
38
|
+
)
|
39
|
+
)
|
40
|
+
|
41
|
+
|
42
|
+
async def encoders_to_code(var, config):
|
43
|
+
default_group = lv_Pvariable(lv_group_t, config[CONF_DEFAULT_GROUP])
|
44
|
+
lv_assign(default_group, lv_expr.group_create())
|
45
|
+
lv.group_set_default(default_group)
|
46
|
+
for enc_conf in config[CONF_ENCODERS]:
|
47
|
+
lvgl_components_required.add("KEY_LISTENER")
|
48
|
+
lpt = enc_conf[CONF_LONG_PRESS_TIME].total_milliseconds
|
49
|
+
lprt = enc_conf[CONF_LONG_PRESS_REPEAT_TIME].total_milliseconds
|
50
|
+
listener = cg.new_Pvariable(
|
51
|
+
enc_conf[CONF_ID], lv_indev_type_t.LV_INDEV_TYPE_ENCODER, lpt, lprt
|
52
|
+
)
|
53
|
+
await cg.register_parented(listener, var)
|
54
|
+
if sensor_config := enc_conf.get(CONF_SENSOR):
|
55
|
+
if isinstance(sensor_config, dict):
|
56
|
+
b_sensor = await cg.get_variable(sensor_config[CONF_LEFT_BUTTON])
|
57
|
+
cg.add(listener.set_left_button(b_sensor))
|
58
|
+
b_sensor = await cg.get_variable(sensor_config[CONF_RIGHT_BUTTON])
|
59
|
+
cg.add(listener.set_right_button(b_sensor))
|
60
|
+
else:
|
61
|
+
sensor_config = await cg.get_variable(sensor_config)
|
62
|
+
lv_add(listener.set_sensor(sensor_config))
|
63
|
+
b_sensor = await cg.get_variable(enc_conf[CONF_ENTER_BUTTON])
|
64
|
+
cg.add(listener.set_enter_button(b_sensor))
|
65
|
+
if group := enc_conf.get(CONF_GROUP):
|
66
|
+
group = lv_Pvariable(lv_group_t, group)
|
67
|
+
lv_assign(group, lv_expr.group_create())
|
68
|
+
else:
|
69
|
+
group = default_group
|
70
|
+
lv.indev_set_group(lv_expr.indev_drv_register(listener.get_drv()), group)
|
71
|
+
|
72
|
+
|
73
|
+
async def initial_focus_to_code(config):
|
74
|
+
for enc_conf in config[CONF_ENCODERS]:
|
75
|
+
if default_focus := enc_conf.get(CONF_INITIAL_FOCUS):
|
76
|
+
obj = await cg.get_variable(default_focus)
|
77
|
+
lv.group_focus_obj(obj)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#include "lvgl_esphome.h"
|
2
|
+
|
3
|
+
#ifdef USE_LVGL_FONT
|
4
|
+
namespace esphome {
|
5
|
+
namespace lvgl {
|
6
|
+
|
7
|
+
static const uint8_t *get_glyph_bitmap(const lv_font_t *font, uint32_t unicode_letter) {
|
8
|
+
auto *fe = (FontEngine *) font->dsc;
|
9
|
+
const auto *gd = fe->get_glyph_data(unicode_letter);
|
10
|
+
if (gd == nullptr)
|
11
|
+
return nullptr;
|
12
|
+
// esph_log_d(TAG, "Returning bitmap @ %X", (uint32_t)gd->data);
|
13
|
+
|
14
|
+
return gd->data;
|
15
|
+
}
|
16
|
+
|
17
|
+
static bool get_glyph_dsc_cb(const lv_font_t *font, lv_font_glyph_dsc_t *dsc, uint32_t unicode_letter, uint32_t next) {
|
18
|
+
auto *fe = (FontEngine *) font->dsc;
|
19
|
+
const auto *gd = fe->get_glyph_data(unicode_letter);
|
20
|
+
if (gd == nullptr)
|
21
|
+
return false;
|
22
|
+
dsc->adv_w = gd->offset_x + gd->width;
|
23
|
+
dsc->ofs_x = gd->offset_x;
|
24
|
+
dsc->ofs_y = fe->height - gd->height - gd->offset_y - fe->baseline;
|
25
|
+
dsc->box_w = gd->width;
|
26
|
+
dsc->box_h = gd->height;
|
27
|
+
dsc->is_placeholder = 0;
|
28
|
+
dsc->bpp = fe->bpp;
|
29
|
+
return true;
|
30
|
+
}
|
31
|
+
|
32
|
+
FontEngine::FontEngine(font::Font *esp_font) : font_(esp_font) {
|
33
|
+
this->bpp = esp_font->get_bpp();
|
34
|
+
this->lv_font_.dsc = this;
|
35
|
+
this->lv_font_.line_height = this->height = esp_font->get_height();
|
36
|
+
this->lv_font_.base_line = this->baseline = this->lv_font_.line_height - esp_font->get_baseline();
|
37
|
+
this->lv_font_.get_glyph_dsc = get_glyph_dsc_cb;
|
38
|
+
this->lv_font_.get_glyph_bitmap = get_glyph_bitmap;
|
39
|
+
this->lv_font_.subpx = LV_FONT_SUBPX_NONE;
|
40
|
+
this->lv_font_.underline_position = -1;
|
41
|
+
this->lv_font_.underline_thickness = 1;
|
42
|
+
}
|
43
|
+
|
44
|
+
const lv_font_t *FontEngine::get_lv_font() { return &this->lv_font_; }
|
45
|
+
|
46
|
+
const font::GlyphData *FontEngine::get_glyph_data(uint32_t unicode_letter) {
|
47
|
+
if (unicode_letter == last_letter_)
|
48
|
+
return this->last_data_;
|
49
|
+
uint8_t unicode[5];
|
50
|
+
memset(unicode, 0, sizeof unicode);
|
51
|
+
if (unicode_letter > 0xFFFF) {
|
52
|
+
unicode[0] = 0xF0 + ((unicode_letter >> 18) & 0x7);
|
53
|
+
unicode[1] = 0x80 + ((unicode_letter >> 12) & 0x3F);
|
54
|
+
unicode[2] = 0x80 + ((unicode_letter >> 6) & 0x3F);
|
55
|
+
unicode[3] = 0x80 + (unicode_letter & 0x3F);
|
56
|
+
} else if (unicode_letter > 0x7FF) {
|
57
|
+
unicode[0] = 0xE0 + ((unicode_letter >> 12) & 0xF);
|
58
|
+
unicode[1] = 0x80 + ((unicode_letter >> 6) & 0x3F);
|
59
|
+
unicode[2] = 0x80 + (unicode_letter & 0x3F);
|
60
|
+
} else if (unicode_letter > 0x7F) {
|
61
|
+
unicode[0] = 0xC0 + ((unicode_letter >> 6) & 0x1F);
|
62
|
+
unicode[1] = 0x80 + (unicode_letter & 0x3F);
|
63
|
+
} else {
|
64
|
+
unicode[0] = unicode_letter;
|
65
|
+
}
|
66
|
+
int match_length;
|
67
|
+
int glyph_n = this->font_->match_next_glyph(unicode, &match_length);
|
68
|
+
if (glyph_n < 0)
|
69
|
+
return nullptr;
|
70
|
+
this->last_data_ = this->font_->get_glyphs()[glyph_n].get_glyph_data();
|
71
|
+
this->last_letter_ = unicode_letter;
|
72
|
+
return this->last_data_;
|
73
|
+
}
|
74
|
+
} // namespace lvgl
|
75
|
+
} // namespace esphome
|
76
|
+
#endif // USES_LVGL_FONT
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import re
|
2
|
+
|
3
|
+
from esphome import config_validation as cv
|
4
|
+
from esphome.const import CONF_ARGS, CONF_FORMAT
|
5
|
+
|
6
|
+
lv_uses = {
|
7
|
+
"USER_DATA",
|
8
|
+
"LOG",
|
9
|
+
"STYLE",
|
10
|
+
"FONT_PLACEHOLDER",
|
11
|
+
"THEME_DEFAULT",
|
12
|
+
}
|
13
|
+
|
14
|
+
|
15
|
+
def add_lv_use(*names):
|
16
|
+
for name in names:
|
17
|
+
lv_uses.add(name)
|
18
|
+
|
19
|
+
|
20
|
+
lv_fonts_used = set()
|
21
|
+
esphome_fonts_used = set()
|
22
|
+
lvgl_components_required = set()
|
23
|
+
|
24
|
+
|
25
|
+
def validate_printf(value):
|
26
|
+
cfmt = r"""
|
27
|
+
( # start of capture group 1
|
28
|
+
% # literal "%"
|
29
|
+
(?:[-+0 #]{0,5}) # optional flags
|
30
|
+
(?:\d+|\*)? # width
|
31
|
+
(?:\.(?:\d+|\*))? # precision
|
32
|
+
(?:h|l|ll|w|I|I32|I64)? # size
|
33
|
+
[cCdiouxXeEfgGaAnpsSZ] # type
|
34
|
+
)
|
35
|
+
""" # noqa
|
36
|
+
matches = re.findall(cfmt, value[CONF_FORMAT], flags=re.X)
|
37
|
+
if len(matches) != len(value[CONF_ARGS]):
|
38
|
+
raise cv.Invalid(
|
39
|
+
f"Found {len(matches)} printf-patterns ({', '.join(matches)}), but {len(value[CONF_ARGS])} args were given!"
|
40
|
+
)
|
41
|
+
return value
|
42
|
+
|
43
|
+
|
44
|
+
def requires_component(comp):
|
45
|
+
def validator(value):
|
46
|
+
lvgl_components_required.add(comp)
|
47
|
+
return cv.requires_component(comp)(value)
|
48
|
+
|
49
|
+
return validator
|