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,407 @@
|
|
1
|
+
#include "esphome/core/defines.h"
|
2
|
+
#include "esphome/core/log.h"
|
3
|
+
#include "esphome/core/helpers.h"
|
4
|
+
#include "esphome/core/hal.h"
|
5
|
+
#include "lvgl_hal.h"
|
6
|
+
#include "lvgl_esphome.h"
|
7
|
+
|
8
|
+
namespace esphome {
|
9
|
+
namespace lvgl {
|
10
|
+
static const char *const TAG = "lvgl";
|
11
|
+
|
12
|
+
#if LV_USE_LOG
|
13
|
+
static void log_cb(const char *buf) {
|
14
|
+
esp_log_printf_(ESPHOME_LOG_LEVEL_INFO, TAG, 0, "%.*s", (int) strlen(buf) - 1, buf);
|
15
|
+
}
|
16
|
+
#endif // LV_USE_LOG
|
17
|
+
|
18
|
+
static void rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) {
|
19
|
+
// make sure all coordinates are even
|
20
|
+
if (area->x1 & 1)
|
21
|
+
area->x1--;
|
22
|
+
if (!(area->x2 & 1))
|
23
|
+
area->x2++;
|
24
|
+
if (area->y1 & 1)
|
25
|
+
area->y1--;
|
26
|
+
if (!(area->y2 & 1))
|
27
|
+
area->y2++;
|
28
|
+
}
|
29
|
+
|
30
|
+
lv_event_code_t lv_api_event; // NOLINT
|
31
|
+
lv_event_code_t lv_update_event; // NOLINT
|
32
|
+
void LvglComponent::dump_config() { ESP_LOGCONFIG(TAG, "LVGL:"); }
|
33
|
+
void LvglComponent::set_paused(bool paused, bool show_snow) {
|
34
|
+
this->paused_ = paused;
|
35
|
+
this->show_snow_ = show_snow;
|
36
|
+
this->snow_line_ = 0;
|
37
|
+
if (!paused && lv_scr_act() != nullptr) {
|
38
|
+
lv_disp_trig_activity(this->disp_); // resets the inactivity time
|
39
|
+
lv_obj_invalidate(lv_scr_act());
|
40
|
+
}
|
41
|
+
}
|
42
|
+
void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event) {
|
43
|
+
lv_obj_add_event_cb(obj, callback, event, this);
|
44
|
+
}
|
45
|
+
void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1,
|
46
|
+
lv_event_code_t event2) {
|
47
|
+
this->add_event_cb(obj, callback, event1);
|
48
|
+
this->add_event_cb(obj, callback, event2);
|
49
|
+
}
|
50
|
+
void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1,
|
51
|
+
lv_event_code_t event2, lv_event_code_t event3) {
|
52
|
+
this->add_event_cb(obj, callback, event1);
|
53
|
+
this->add_event_cb(obj, callback, event2);
|
54
|
+
this->add_event_cb(obj, callback, event3);
|
55
|
+
}
|
56
|
+
void LvglComponent::add_page(LvPageType *page) {
|
57
|
+
this->pages_.push_back(page);
|
58
|
+
page->setup(this->pages_.size() - 1);
|
59
|
+
}
|
60
|
+
void LvglComponent::show_page(size_t index, lv_scr_load_anim_t anim, uint32_t time) {
|
61
|
+
if (index >= this->pages_.size())
|
62
|
+
return;
|
63
|
+
this->current_page_ = index;
|
64
|
+
lv_scr_load_anim(this->pages_[this->current_page_]->obj, anim, time, 0, false);
|
65
|
+
}
|
66
|
+
void LvglComponent::show_next_page(lv_scr_load_anim_t anim, uint32_t time) {
|
67
|
+
if (this->pages_.empty() || (this->current_page_ == this->pages_.size() - 1 && !this->page_wrap_))
|
68
|
+
return;
|
69
|
+
do {
|
70
|
+
this->current_page_ = (this->current_page_ + 1) % this->pages_.size();
|
71
|
+
} while (this->pages_[this->current_page_]->skip); // skip empty pages()
|
72
|
+
this->show_page(this->current_page_, anim, time);
|
73
|
+
}
|
74
|
+
void LvglComponent::show_prev_page(lv_scr_load_anim_t anim, uint32_t time) {
|
75
|
+
if (this->pages_.empty() || (this->current_page_ == 0 && !this->page_wrap_))
|
76
|
+
return;
|
77
|
+
do {
|
78
|
+
this->current_page_ = (this->current_page_ + this->pages_.size() - 1) % this->pages_.size();
|
79
|
+
} while (this->pages_[this->current_page_]->skip); // skip empty pages()
|
80
|
+
this->show_page(this->current_page_, anim, time);
|
81
|
+
}
|
82
|
+
void LvglComponent::draw_buffer_(const lv_area_t *area, const uint8_t *ptr) {
|
83
|
+
for (auto *display : this->displays_) {
|
84
|
+
display->draw_pixels_at(area->x1, area->y1, lv_area_get_width(area), lv_area_get_height(area), ptr,
|
85
|
+
display::COLOR_ORDER_RGB, LV_BITNESS, LV_COLOR_16_SWAP);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
void LvglComponent::flush_cb_(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) {
|
90
|
+
if (!this->paused_) {
|
91
|
+
auto now = millis();
|
92
|
+
this->draw_buffer_(area, (const uint8_t *) color_p);
|
93
|
+
ESP_LOGV(TAG, "flush_cb, area=%d/%d, %d/%d took %dms", area->x1, area->y1, lv_area_get_width(area),
|
94
|
+
lv_area_get_height(area), (int) (millis() - now));
|
95
|
+
}
|
96
|
+
lv_disp_flush_ready(disp_drv);
|
97
|
+
}
|
98
|
+
IdleTrigger::IdleTrigger(LvglComponent *parent, TemplatableValue<uint32_t> timeout) : timeout_(std::move(timeout)) {
|
99
|
+
parent->add_on_idle_callback([this](uint32_t idle_time) {
|
100
|
+
if (!this->is_idle_ && idle_time > this->timeout_.value()) {
|
101
|
+
this->is_idle_ = true;
|
102
|
+
this->trigger();
|
103
|
+
} else if (this->is_idle_ && idle_time < this->timeout_.value()) {
|
104
|
+
this->is_idle_ = false;
|
105
|
+
}
|
106
|
+
});
|
107
|
+
}
|
108
|
+
|
109
|
+
#ifdef USE_LVGL_TOUCHSCREEN
|
110
|
+
LVTouchListener::LVTouchListener(uint16_t long_press_time, uint16_t long_press_repeat_time) {
|
111
|
+
lv_indev_drv_init(&this->drv_);
|
112
|
+
this->drv_.long_press_repeat_time = long_press_repeat_time;
|
113
|
+
this->drv_.long_press_time = long_press_time;
|
114
|
+
this->drv_.type = LV_INDEV_TYPE_POINTER;
|
115
|
+
this->drv_.user_data = this;
|
116
|
+
this->drv_.read_cb = [](lv_indev_drv_t *d, lv_indev_data_t *data) {
|
117
|
+
auto *l = static_cast<LVTouchListener *>(d->user_data);
|
118
|
+
if (l->touch_pressed_) {
|
119
|
+
data->point.x = l->touch_point_.x;
|
120
|
+
data->point.y = l->touch_point_.y;
|
121
|
+
data->state = LV_INDEV_STATE_PRESSED;
|
122
|
+
} else {
|
123
|
+
data->state = LV_INDEV_STATE_RELEASED;
|
124
|
+
}
|
125
|
+
};
|
126
|
+
}
|
127
|
+
void LVTouchListener::update(const touchscreen::TouchPoints_t &tpoints) {
|
128
|
+
this->touch_pressed_ = !this->parent_->is_paused() && !tpoints.empty();
|
129
|
+
if (this->touch_pressed_)
|
130
|
+
this->touch_point_ = tpoints[0];
|
131
|
+
}
|
132
|
+
#endif // USE_LVGL_TOUCHSCREEN
|
133
|
+
|
134
|
+
#ifdef USE_LVGL_KEY_LISTENER
|
135
|
+
LVEncoderListener::LVEncoderListener(lv_indev_type_t type, uint16_t lpt, uint16_t lprt) {
|
136
|
+
lv_indev_drv_init(&this->drv_);
|
137
|
+
this->drv_.type = type;
|
138
|
+
this->drv_.user_data = this;
|
139
|
+
this->drv_.long_press_time = lpt;
|
140
|
+
this->drv_.long_press_repeat_time = lprt;
|
141
|
+
this->drv_.read_cb = [](lv_indev_drv_t *d, lv_indev_data_t *data) {
|
142
|
+
auto *l = static_cast<LVEncoderListener *>(d->user_data);
|
143
|
+
data->state = l->pressed_ ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
|
144
|
+
data->key = l->key_;
|
145
|
+
data->enc_diff = (int16_t) (l->count_ - l->last_count_);
|
146
|
+
l->last_count_ = l->count_;
|
147
|
+
data->continue_reading = false;
|
148
|
+
};
|
149
|
+
}
|
150
|
+
#endif // USE_LVGL_KEY_LISTENER
|
151
|
+
|
152
|
+
#ifdef USE_LVGL_BUTTONMATRIX
|
153
|
+
void LvButtonMatrixType::set_obj(lv_obj_t *lv_obj) {
|
154
|
+
LvCompound::set_obj(lv_obj);
|
155
|
+
lv_obj_add_event_cb(
|
156
|
+
lv_obj,
|
157
|
+
[](lv_event_t *event) {
|
158
|
+
auto *self = static_cast<LvButtonMatrixType *>(event->user_data);
|
159
|
+
if (self->key_callback_.size() == 0)
|
160
|
+
return;
|
161
|
+
auto key_idx = lv_btnmatrix_get_selected_btn(self->obj);
|
162
|
+
if (key_idx == LV_BTNMATRIX_BTN_NONE)
|
163
|
+
return;
|
164
|
+
if (self->key_map_.count(key_idx) != 0) {
|
165
|
+
self->send_key_(self->key_map_[key_idx]);
|
166
|
+
return;
|
167
|
+
}
|
168
|
+
const auto *str = lv_btnmatrix_get_btn_text(self->obj, key_idx);
|
169
|
+
auto len = strlen(str);
|
170
|
+
while (len--)
|
171
|
+
self->send_key_(*str++);
|
172
|
+
},
|
173
|
+
LV_EVENT_PRESSED, this);
|
174
|
+
}
|
175
|
+
#endif // USE_LVGL_BUTTONMATRIX
|
176
|
+
|
177
|
+
#ifdef USE_LVGL_KEYBOARD
|
178
|
+
static const char *const KB_SPECIAL_KEYS[] = {
|
179
|
+
"abc", "ABC", "1#",
|
180
|
+
// maybe add other special keys here
|
181
|
+
};
|
182
|
+
|
183
|
+
void LvKeyboardType::set_obj(lv_obj_t *lv_obj) {
|
184
|
+
LvCompound::set_obj(lv_obj);
|
185
|
+
lv_obj_add_event_cb(
|
186
|
+
lv_obj,
|
187
|
+
[](lv_event_t *event) {
|
188
|
+
auto *self = static_cast<LvKeyboardType *>(event->user_data);
|
189
|
+
if (self->key_callback_.size() == 0)
|
190
|
+
return;
|
191
|
+
|
192
|
+
auto key_idx = lv_btnmatrix_get_selected_btn(self->obj);
|
193
|
+
if (key_idx == LV_BTNMATRIX_BTN_NONE)
|
194
|
+
return;
|
195
|
+
const char *txt = lv_btnmatrix_get_btn_text(self->obj, key_idx);
|
196
|
+
if (txt == nullptr)
|
197
|
+
return;
|
198
|
+
for (const auto *kb_special_key : KB_SPECIAL_KEYS) {
|
199
|
+
if (strcmp(txt, kb_special_key) == 0)
|
200
|
+
return;
|
201
|
+
}
|
202
|
+
while (*txt != 0)
|
203
|
+
self->send_key_(*txt++);
|
204
|
+
},
|
205
|
+
LV_EVENT_PRESSED, this);
|
206
|
+
}
|
207
|
+
#endif // USE_LVGL_KEYBOARD
|
208
|
+
|
209
|
+
void LvglComponent::write_random_() {
|
210
|
+
// length of 2 lines in 32 bit units
|
211
|
+
// we write 2 lines for the benefit of displays that won't write one line at a time.
|
212
|
+
size_t line_len = this->disp_drv_.hor_res * LV_COLOR_DEPTH / 8 / 4 * 2;
|
213
|
+
for (size_t i = 0; i != line_len; i++) {
|
214
|
+
((uint32_t *) (this->draw_buf_.buf1))[i] = random_uint32();
|
215
|
+
}
|
216
|
+
lv_area_t area;
|
217
|
+
area.x1 = 0;
|
218
|
+
area.x2 = this->disp_drv_.hor_res - 1;
|
219
|
+
if (this->snow_line_ == this->disp_drv_.ver_res / 2) {
|
220
|
+
area.y1 = static_cast<lv_coord_t>(random_uint32() % (this->disp_drv_.ver_res / 2) * 2);
|
221
|
+
} else {
|
222
|
+
area.y1 = this->snow_line_++ * 2;
|
223
|
+
}
|
224
|
+
// write 2 lines
|
225
|
+
area.y2 = area.y1 + 1;
|
226
|
+
this->draw_buffer_(&area, (const uint8_t *) this->draw_buf_.buf1);
|
227
|
+
}
|
228
|
+
|
229
|
+
void LvglComponent::setup() {
|
230
|
+
ESP_LOGCONFIG(TAG, "LVGL Setup starts");
|
231
|
+
#if LV_USE_LOG
|
232
|
+
lv_log_register_print_cb(log_cb);
|
233
|
+
#endif
|
234
|
+
lv_init();
|
235
|
+
lv_update_event = static_cast<lv_event_code_t>(lv_event_register_id());
|
236
|
+
lv_api_event = static_cast<lv_event_code_t>(lv_event_register_id());
|
237
|
+
auto *display = this->displays_[0];
|
238
|
+
size_t buffer_pixels = display->get_width() * display->get_height() / this->buffer_frac_;
|
239
|
+
auto buf_bytes = buffer_pixels * LV_COLOR_DEPTH / 8;
|
240
|
+
auto *buf = lv_custom_mem_alloc(buf_bytes);
|
241
|
+
if (buf == nullptr) {
|
242
|
+
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_ERROR
|
243
|
+
ESP_LOGE(TAG, "Malloc failed to allocate %zu bytes", buf_bytes);
|
244
|
+
#endif
|
245
|
+
this->mark_failed();
|
246
|
+
this->status_set_error("Memory allocation failure");
|
247
|
+
return;
|
248
|
+
}
|
249
|
+
lv_disp_draw_buf_init(&this->draw_buf_, buf, nullptr, buffer_pixels);
|
250
|
+
lv_disp_drv_init(&this->disp_drv_);
|
251
|
+
this->disp_drv_.draw_buf = &this->draw_buf_;
|
252
|
+
this->disp_drv_.user_data = this;
|
253
|
+
this->disp_drv_.full_refresh = this->full_refresh_;
|
254
|
+
this->disp_drv_.flush_cb = static_flush_cb;
|
255
|
+
this->disp_drv_.rounder_cb = rounder_cb;
|
256
|
+
switch (display->get_rotation()) {
|
257
|
+
case display::DISPLAY_ROTATION_0_DEGREES:
|
258
|
+
break;
|
259
|
+
case display::DISPLAY_ROTATION_90_DEGREES:
|
260
|
+
this->disp_drv_.sw_rotate = true;
|
261
|
+
this->disp_drv_.rotated = LV_DISP_ROT_90;
|
262
|
+
break;
|
263
|
+
case display::DISPLAY_ROTATION_180_DEGREES:
|
264
|
+
this->disp_drv_.sw_rotate = true;
|
265
|
+
this->disp_drv_.rotated = LV_DISP_ROT_180;
|
266
|
+
break;
|
267
|
+
case display::DISPLAY_ROTATION_270_DEGREES:
|
268
|
+
this->disp_drv_.sw_rotate = true;
|
269
|
+
this->disp_drv_.rotated = LV_DISP_ROT_270;
|
270
|
+
break;
|
271
|
+
}
|
272
|
+
display->set_rotation(display::DISPLAY_ROTATION_0_DEGREES);
|
273
|
+
this->disp_drv_.hor_res = (lv_coord_t) display->get_width();
|
274
|
+
this->disp_drv_.ver_res = (lv_coord_t) display->get_height();
|
275
|
+
ESP_LOGV(TAG, "sw_rotate = %d, rotated=%d", this->disp_drv_.sw_rotate, this->disp_drv_.rotated);
|
276
|
+
this->disp_ = lv_disp_drv_register(&this->disp_drv_);
|
277
|
+
for (const auto &v : this->init_lambdas_)
|
278
|
+
v(this);
|
279
|
+
this->show_page(0, LV_SCR_LOAD_ANIM_NONE, 0);
|
280
|
+
lv_disp_trig_activity(this->disp_);
|
281
|
+
ESP_LOGCONFIG(TAG, "LVGL Setup complete");
|
282
|
+
}
|
283
|
+
void LvglComponent::update() {
|
284
|
+
// update indicators
|
285
|
+
if (this->paused_) {
|
286
|
+
return;
|
287
|
+
}
|
288
|
+
this->idle_callbacks_.call(lv_disp_get_inactive_time(this->disp_));
|
289
|
+
}
|
290
|
+
void LvglComponent::loop() {
|
291
|
+
if (this->paused_) {
|
292
|
+
if (this->show_snow_)
|
293
|
+
this->write_random_();
|
294
|
+
}
|
295
|
+
lv_timer_handler_run_in_period(5);
|
296
|
+
}
|
297
|
+
|
298
|
+
#ifdef USE_LVGL_IMAGE
|
299
|
+
lv_img_dsc_t *lv_img_from(image::Image *src, lv_img_dsc_t *img_dsc) {
|
300
|
+
if (img_dsc == nullptr)
|
301
|
+
img_dsc = new lv_img_dsc_t(); // NOLINT
|
302
|
+
img_dsc->header.always_zero = 0;
|
303
|
+
img_dsc->header.reserved = 0;
|
304
|
+
img_dsc->header.w = src->get_width();
|
305
|
+
img_dsc->header.h = src->get_height();
|
306
|
+
img_dsc->data = src->get_data_start();
|
307
|
+
img_dsc->data_size = image_type_to_width_stride(img_dsc->header.w * img_dsc->header.h, src->get_type());
|
308
|
+
switch (src->get_type()) {
|
309
|
+
case image::IMAGE_TYPE_BINARY:
|
310
|
+
img_dsc->header.cf = LV_IMG_CF_ALPHA_1BIT;
|
311
|
+
break;
|
312
|
+
|
313
|
+
case image::IMAGE_TYPE_GRAYSCALE:
|
314
|
+
img_dsc->header.cf = LV_IMG_CF_ALPHA_8BIT;
|
315
|
+
break;
|
316
|
+
|
317
|
+
case image::IMAGE_TYPE_RGB24:
|
318
|
+
img_dsc->header.cf = LV_IMG_CF_RGB888;
|
319
|
+
break;
|
320
|
+
|
321
|
+
case image::IMAGE_TYPE_RGB565:
|
322
|
+
#if LV_COLOR_DEPTH == 16
|
323
|
+
img_dsc->header.cf = src->has_transparency() ? LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED : LV_IMG_CF_TRUE_COLOR;
|
324
|
+
#else
|
325
|
+
img_dsc->header.cf = LV_IMG_CF_RGB565;
|
326
|
+
#endif
|
327
|
+
break;
|
328
|
+
|
329
|
+
case image::IMAGE_TYPE_RGBA:
|
330
|
+
#if LV_COLOR_DEPTH == 32
|
331
|
+
img_dsc->header.cf = LV_IMG_CF_TRUE_COLOR;
|
332
|
+
#else
|
333
|
+
img_dsc->header.cf = LV_IMG_CF_RGBA8888;
|
334
|
+
#endif
|
335
|
+
break;
|
336
|
+
}
|
337
|
+
return img_dsc;
|
338
|
+
}
|
339
|
+
#endif // USE_LVGL_IMAGE
|
340
|
+
|
341
|
+
#ifdef USE_LVGL_ANIMIMG
|
342
|
+
void lv_animimg_stop(lv_obj_t *obj) {
|
343
|
+
auto *animg = (lv_animimg_t *) obj;
|
344
|
+
int32_t duration = animg->anim.time;
|
345
|
+
lv_animimg_set_duration(obj, 0);
|
346
|
+
lv_animimg_start(obj);
|
347
|
+
lv_animimg_set_duration(obj, duration);
|
348
|
+
}
|
349
|
+
#endif
|
350
|
+
void LvglComponent::static_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) {
|
351
|
+
reinterpret_cast<LvglComponent *>(disp_drv->user_data)->flush_cb_(disp_drv, area, color_p);
|
352
|
+
}
|
353
|
+
} // namespace lvgl
|
354
|
+
} // namespace esphome
|
355
|
+
|
356
|
+
size_t lv_millis(void) { return esphome::millis(); }
|
357
|
+
|
358
|
+
#if defined(USE_HOST) || defined(USE_RP2040) || defined(USE_ESP8266)
|
359
|
+
void *lv_custom_mem_alloc(size_t size) {
|
360
|
+
auto *ptr = malloc(size); // NOLINT
|
361
|
+
if (ptr == nullptr) {
|
362
|
+
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_ERROR
|
363
|
+
esphome::ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
|
364
|
+
#endif
|
365
|
+
}
|
366
|
+
return ptr;
|
367
|
+
}
|
368
|
+
void lv_custom_mem_free(void *ptr) { return free(ptr); } // NOLINT
|
369
|
+
void *lv_custom_mem_realloc(void *ptr, size_t size) { return realloc(ptr, size); } // NOLINT
|
370
|
+
#else
|
371
|
+
static unsigned cap_bits = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT; // NOLINT
|
372
|
+
|
373
|
+
void *lv_custom_mem_alloc(size_t size) {
|
374
|
+
void *ptr;
|
375
|
+
ptr = heap_caps_malloc(size, cap_bits);
|
376
|
+
if (ptr == nullptr) {
|
377
|
+
cap_bits = MALLOC_CAP_8BIT;
|
378
|
+
ptr = heap_caps_malloc(size, cap_bits);
|
379
|
+
}
|
380
|
+
if (ptr == nullptr) {
|
381
|
+
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_ERROR
|
382
|
+
esphome::ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
|
383
|
+
#endif
|
384
|
+
return nullptr;
|
385
|
+
}
|
386
|
+
#ifdef ESPHOME_LOG_HAS_VERBOSE
|
387
|
+
esphome::ESP_LOGV(esphome::lvgl::TAG, "allocate %zu - > %p", size, ptr);
|
388
|
+
#endif
|
389
|
+
return ptr;
|
390
|
+
}
|
391
|
+
|
392
|
+
void lv_custom_mem_free(void *ptr) {
|
393
|
+
#ifdef ESPHOME_LOG_HAS_VERBOSE
|
394
|
+
esphome::ESP_LOGV(esphome::lvgl::TAG, "free %p", ptr);
|
395
|
+
#endif
|
396
|
+
if (ptr == nullptr)
|
397
|
+
return;
|
398
|
+
heap_caps_free(ptr);
|
399
|
+
}
|
400
|
+
|
401
|
+
void *lv_custom_mem_realloc(void *ptr, size_t size) {
|
402
|
+
#ifdef ESPHOME_LOG_HAS_VERBOSE
|
403
|
+
esphome::ESP_LOGV(esphome::lvgl::TAG, "realloc %p: %zu", ptr, size);
|
404
|
+
#endif
|
405
|
+
return heap_caps_realloc(ptr, size, cap_bits);
|
406
|
+
}
|
407
|
+
#endif
|
@@ -0,0 +1,274 @@
|
|
1
|
+
#pragma once
|
2
|
+
#include "esphome/core/defines.h"
|
3
|
+
|
4
|
+
#ifdef USE_BINARY_SENSOR
|
5
|
+
#include "esphome/components/binary_sensor/binary_sensor.h"
|
6
|
+
#endif // USE_BINARY_SENSOR
|
7
|
+
#ifdef USE_LVGL_ROTARY_ENCODER
|
8
|
+
#include "esphome/components/rotary_encoder/rotary_encoder.h"
|
9
|
+
#endif // USE_LVGL_ROTARY_ENCODER
|
10
|
+
|
11
|
+
// required for clang-tidy
|
12
|
+
#ifndef LV_CONF_H
|
13
|
+
#define LV_CONF_SKIP 1 // NOLINT
|
14
|
+
#endif // LV_CONF_H
|
15
|
+
|
16
|
+
#include "esphome/components/display/display.h"
|
17
|
+
#include "esphome/components/display/display_color_utils.h"
|
18
|
+
#include "esphome/core/component.h"
|
19
|
+
#include "esphome/core/log.h"
|
20
|
+
#include <lvgl.h>
|
21
|
+
#include <vector>
|
22
|
+
#include <map>
|
23
|
+
#ifdef USE_LVGL_IMAGE
|
24
|
+
#include "esphome/components/image/image.h"
|
25
|
+
#endif // USE_LVGL_IMAGE
|
26
|
+
|
27
|
+
#ifdef USE_LVGL_FONT
|
28
|
+
#include "esphome/components/font/font.h"
|
29
|
+
#endif // USE_LVGL_FONT
|
30
|
+
#ifdef USE_LVGL_TOUCHSCREEN
|
31
|
+
#include "esphome/components/touchscreen/touchscreen.h"
|
32
|
+
#endif // USE_LVGL_TOUCHSCREEN
|
33
|
+
|
34
|
+
#if defined(USE_LVGL_BUTTONMATRIX) || defined(USE_LVGL_KEYBOARD)
|
35
|
+
#include "esphome/components/key_provider/key_provider.h"
|
36
|
+
#endif // USE_LVGL_BUTTONMATRIX
|
37
|
+
|
38
|
+
namespace esphome {
|
39
|
+
namespace lvgl {
|
40
|
+
|
41
|
+
extern lv_event_code_t lv_api_event; // NOLINT
|
42
|
+
extern lv_event_code_t lv_update_event; // NOLINT
|
43
|
+
#ifdef USE_LVGL_COLOR
|
44
|
+
inline lv_color_t lv_color_from(Color color) { return lv_color_make(color.red, color.green, color.blue); }
|
45
|
+
#endif // USE_LVGL_COLOR
|
46
|
+
#if LV_COLOR_DEPTH == 16
|
47
|
+
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_565;
|
48
|
+
#elif LV_COLOR_DEPTH == 32
|
49
|
+
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_888;
|
50
|
+
#else // LV_COLOR_DEPTH
|
51
|
+
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_332;
|
52
|
+
#endif // LV_COLOR_DEPTH
|
53
|
+
|
54
|
+
// Parent class for things that wrap an LVGL object
|
55
|
+
class LvCompound {
|
56
|
+
public:
|
57
|
+
virtual void set_obj(lv_obj_t *lv_obj) { this->obj = lv_obj; }
|
58
|
+
lv_obj_t *obj{};
|
59
|
+
};
|
60
|
+
|
61
|
+
class LvPageType {
|
62
|
+
public:
|
63
|
+
LvPageType(bool skip) : skip(skip) {}
|
64
|
+
|
65
|
+
void setup(size_t index) {
|
66
|
+
this->index = index;
|
67
|
+
this->obj = lv_obj_create(nullptr);
|
68
|
+
}
|
69
|
+
lv_obj_t *obj{};
|
70
|
+
size_t index{};
|
71
|
+
bool skip;
|
72
|
+
};
|
73
|
+
|
74
|
+
using LvLambdaType = std::function<void(lv_obj_t *)>;
|
75
|
+
using set_value_lambda_t = std::function<void(float)>;
|
76
|
+
using event_callback_t = void(_lv_event_t *);
|
77
|
+
using text_lambda_t = std::function<const char *()>;
|
78
|
+
|
79
|
+
template<typename... Ts> class ObjUpdateAction : public Action<Ts...> {
|
80
|
+
public:
|
81
|
+
explicit ObjUpdateAction(std::function<void(Ts...)> &&lamb) : lamb_(std::move(lamb)) {}
|
82
|
+
|
83
|
+
void play(Ts... x) override { this->lamb_(x...); }
|
84
|
+
|
85
|
+
protected:
|
86
|
+
std::function<void(Ts...)> lamb_;
|
87
|
+
};
|
88
|
+
#ifdef USE_LVGL_FONT
|
89
|
+
class FontEngine {
|
90
|
+
public:
|
91
|
+
FontEngine(font::Font *esp_font);
|
92
|
+
const lv_font_t *get_lv_font();
|
93
|
+
|
94
|
+
const font::GlyphData *get_glyph_data(uint32_t unicode_letter);
|
95
|
+
uint16_t baseline{};
|
96
|
+
uint16_t height{};
|
97
|
+
uint8_t bpp{};
|
98
|
+
|
99
|
+
protected:
|
100
|
+
font::Font *font_{};
|
101
|
+
uint32_t last_letter_{};
|
102
|
+
const font::GlyphData *last_data_{};
|
103
|
+
lv_font_t lv_font_{};
|
104
|
+
};
|
105
|
+
#endif // USE_LVGL_FONT
|
106
|
+
#ifdef USE_LVGL_IMAGE
|
107
|
+
lv_img_dsc_t *lv_img_from(image::Image *src, lv_img_dsc_t *img_dsc = nullptr);
|
108
|
+
#endif // USE_LVGL_IMAGE
|
109
|
+
|
110
|
+
#ifdef USE_LVGL_ANIMIMG
|
111
|
+
void lv_animimg_stop(lv_obj_t *obj);
|
112
|
+
#endif // USE_LVGL_ANIMIMG
|
113
|
+
|
114
|
+
class LvglComponent : public PollingComponent {
|
115
|
+
constexpr static const char *const TAG = "lvgl";
|
116
|
+
|
117
|
+
public:
|
118
|
+
static void static_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
|
119
|
+
|
120
|
+
float get_setup_priority() const override { return setup_priority::PROCESSOR; }
|
121
|
+
void setup() override;
|
122
|
+
void update() override;
|
123
|
+
void loop() override;
|
124
|
+
void add_on_idle_callback(std::function<void(uint32_t)> &&callback) {
|
125
|
+
this->idle_callbacks_.add(std::move(callback));
|
126
|
+
}
|
127
|
+
void add_display(display::Display *display) { this->displays_.push_back(display); }
|
128
|
+
void add_init_lambda(const std::function<void(LvglComponent *)> &lamb) { this->init_lambdas_.push_back(lamb); }
|
129
|
+
void dump_config() override;
|
130
|
+
void set_full_refresh(bool full_refresh) { this->full_refresh_ = full_refresh; }
|
131
|
+
bool is_idle(uint32_t idle_ms) { return lv_disp_get_inactive_time(this->disp_) > idle_ms; }
|
132
|
+
void set_buffer_frac(size_t frac) { this->buffer_frac_ = frac; }
|
133
|
+
lv_disp_t *get_disp() { return this->disp_; }
|
134
|
+
void set_paused(bool paused, bool show_snow);
|
135
|
+
void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event);
|
136
|
+
void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1, lv_event_code_t event2);
|
137
|
+
void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1, lv_event_code_t event2,
|
138
|
+
lv_event_code_t event3);
|
139
|
+
bool is_paused() const { return this->paused_; }
|
140
|
+
void add_page(LvPageType *page);
|
141
|
+
void show_page(size_t index, lv_scr_load_anim_t anim, uint32_t time);
|
142
|
+
void show_next_page(lv_scr_load_anim_t anim, uint32_t time);
|
143
|
+
void show_prev_page(lv_scr_load_anim_t anim, uint32_t time);
|
144
|
+
void set_page_wrap(bool wrap) { this->page_wrap_ = wrap; }
|
145
|
+
|
146
|
+
protected:
|
147
|
+
void write_random_();
|
148
|
+
void draw_buffer_(const lv_area_t *area, const uint8_t *ptr);
|
149
|
+
void flush_cb_(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
|
150
|
+
std::vector<display::Display *> displays_{};
|
151
|
+
lv_disp_draw_buf_t draw_buf_{};
|
152
|
+
lv_disp_drv_t disp_drv_{};
|
153
|
+
lv_disp_t *disp_{};
|
154
|
+
bool paused_{};
|
155
|
+
std::vector<LvPageType *> pages_{};
|
156
|
+
size_t current_page_{0};
|
157
|
+
bool show_snow_{};
|
158
|
+
lv_coord_t snow_line_{};
|
159
|
+
bool page_wrap_{true};
|
160
|
+
|
161
|
+
std::vector<std::function<void(LvglComponent *lv_component)>> init_lambdas_;
|
162
|
+
CallbackManager<void(uint32_t)> idle_callbacks_{};
|
163
|
+
size_t buffer_frac_{1};
|
164
|
+
bool full_refresh_{};
|
165
|
+
};
|
166
|
+
|
167
|
+
class IdleTrigger : public Trigger<> {
|
168
|
+
public:
|
169
|
+
explicit IdleTrigger(LvglComponent *parent, TemplatableValue<uint32_t> timeout);
|
170
|
+
|
171
|
+
protected:
|
172
|
+
TemplatableValue<uint32_t> timeout_;
|
173
|
+
bool is_idle_{};
|
174
|
+
};
|
175
|
+
|
176
|
+
template<typename... Ts> class LvglAction : public Action<Ts...>, public Parented<LvglComponent> {
|
177
|
+
public:
|
178
|
+
explicit LvglAction(std::function<void(LvglComponent *)> &&lamb) : action_(std::move(lamb)) {}
|
179
|
+
void play(Ts... x) override { this->action_(this->parent_); }
|
180
|
+
|
181
|
+
protected:
|
182
|
+
std::function<void(LvglComponent *)> action_{};
|
183
|
+
};
|
184
|
+
|
185
|
+
template<typename... Ts> class LvglCondition : public Condition<Ts...>, public Parented<LvglComponent> {
|
186
|
+
public:
|
187
|
+
LvglCondition(std::function<bool(LvglComponent *)> &&condition_lambda)
|
188
|
+
: condition_lambda_(std::move(condition_lambda)) {}
|
189
|
+
bool check(Ts... x) override { return this->condition_lambda_(this->parent_); }
|
190
|
+
|
191
|
+
protected:
|
192
|
+
std::function<bool(LvglComponent *)> condition_lambda_{};
|
193
|
+
};
|
194
|
+
|
195
|
+
#ifdef USE_LVGL_TOUCHSCREEN
|
196
|
+
class LVTouchListener : public touchscreen::TouchListener, public Parented<LvglComponent> {
|
197
|
+
public:
|
198
|
+
LVTouchListener(uint16_t long_press_time, uint16_t long_press_repeat_time);
|
199
|
+
void update(const touchscreen::TouchPoints_t &tpoints) override;
|
200
|
+
void release() override { touch_pressed_ = false; }
|
201
|
+
lv_indev_drv_t *get_drv() { return &this->drv_; }
|
202
|
+
|
203
|
+
protected:
|
204
|
+
lv_indev_drv_t drv_{};
|
205
|
+
touchscreen::TouchPoint touch_point_{};
|
206
|
+
bool touch_pressed_{};
|
207
|
+
};
|
208
|
+
#endif // USE_LVGL_TOUCHSCREEN
|
209
|
+
|
210
|
+
#ifdef USE_LVGL_KEY_LISTENER
|
211
|
+
class LVEncoderListener : public Parented<LvglComponent> {
|
212
|
+
public:
|
213
|
+
LVEncoderListener(lv_indev_type_t type, uint16_t lpt, uint16_t lprt);
|
214
|
+
|
215
|
+
void set_left_button(binary_sensor::BinarySensor *left_button) {
|
216
|
+
left_button->add_on_state_callback([this](bool state) { this->event(LV_KEY_LEFT, state); });
|
217
|
+
}
|
218
|
+
void set_right_button(binary_sensor::BinarySensor *right_button) {
|
219
|
+
right_button->add_on_state_callback([this](bool state) { this->event(LV_KEY_RIGHT, state); });
|
220
|
+
}
|
221
|
+
|
222
|
+
void set_enter_button(binary_sensor::BinarySensor *enter_button) {
|
223
|
+
enter_button->add_on_state_callback([this](bool state) { this->event(LV_KEY_ENTER, state); });
|
224
|
+
}
|
225
|
+
|
226
|
+
#ifdef USE_LVGL_ROTARY_ENCODER
|
227
|
+
void set_sensor(rotary_encoder::RotaryEncoderSensor *sensor) {
|
228
|
+
sensor->register_listener([this](int32_t count) { this->set_count(count); });
|
229
|
+
}
|
230
|
+
#endif // USE_LVGL_ROTARY_ENCODER
|
231
|
+
|
232
|
+
void event(int key, bool pressed) {
|
233
|
+
if (!this->parent_->is_paused()) {
|
234
|
+
this->pressed_ = pressed;
|
235
|
+
this->key_ = key;
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
void set_count(int32_t count) {
|
240
|
+
if (!this->parent_->is_paused())
|
241
|
+
this->count_ = count;
|
242
|
+
}
|
243
|
+
|
244
|
+
lv_indev_drv_t *get_drv() { return &this->drv_; }
|
245
|
+
|
246
|
+
protected:
|
247
|
+
lv_indev_drv_t drv_{};
|
248
|
+
bool pressed_{};
|
249
|
+
int32_t count_{};
|
250
|
+
int32_t last_count_{};
|
251
|
+
int key_{};
|
252
|
+
};
|
253
|
+
#endif // USE_LVGL_KEY_LISTENER
|
254
|
+
|
255
|
+
#ifdef USE_LVGL_BUTTONMATRIX
|
256
|
+
class LvButtonMatrixType : public key_provider::KeyProvider, public LvCompound {
|
257
|
+
public:
|
258
|
+
void set_obj(lv_obj_t *lv_obj) override;
|
259
|
+
uint16_t get_selected() { return lv_btnmatrix_get_selected_btn(this->obj); }
|
260
|
+
void set_key(size_t idx, uint8_t key) { this->key_map_[idx] = key; }
|
261
|
+
|
262
|
+
protected:
|
263
|
+
std::map<size_t, uint8_t> key_map_{};
|
264
|
+
};
|
265
|
+
#endif // USE_LVGL_BUTTONMATRIX
|
266
|
+
|
267
|
+
#ifdef USE_LVGL_KEYBOARD
|
268
|
+
class LvKeyboardType : public key_provider::KeyProvider, public LvCompound {
|
269
|
+
public:
|
270
|
+
void set_obj(lv_obj_t *lv_obj) override;
|
271
|
+
};
|
272
|
+
#endif // USE_LVGL_KEYBOARD
|
273
|
+
} // namespace lvgl
|
274
|
+
} // namespace esphome
|
@@ -0,0 +1,21 @@
|
|
1
|
+
//
|
2
|
+
// Created by Clyde Stubbs on 20/9/2023.
|
3
|
+
//
|
4
|
+
|
5
|
+
#pragma once
|
6
|
+
|
7
|
+
#ifdef __cplusplus
|
8
|
+
#define EXTERNC extern "C"
|
9
|
+
#include <cstddef>
|
10
|
+
namespace esphome {
|
11
|
+
namespace lvgl {}
|
12
|
+
} // namespace esphome
|
13
|
+
#else
|
14
|
+
#define EXTERNC extern
|
15
|
+
#include <stddef.h>
|
16
|
+
#endif
|
17
|
+
|
18
|
+
EXTERNC size_t lv_millis(void);
|
19
|
+
EXTERNC void *lv_custom_mem_alloc(size_t size);
|
20
|
+
EXTERNC void lv_custom_mem_free(void *ptr);
|
21
|
+
EXTERNC void *lv_custom_mem_realloc(void *ptr, size_t size);
|