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,419 @@
|
|
1
|
+
import sys
|
2
|
+
from typing import Any, Union
|
3
|
+
|
4
|
+
from esphome import codegen as cg, config_validation as cv
|
5
|
+
from esphome.config_validation import Invalid
|
6
|
+
from esphome.const import CONF_GROUP, CONF_ID, CONF_STATE, CONF_TYPE
|
7
|
+
from esphome.core import ID, TimePeriod
|
8
|
+
from esphome.coroutine import FakeAwaitable
|
9
|
+
from esphome.cpp_generator import CallExpression, MockObj
|
10
|
+
|
11
|
+
from ..defines import (
|
12
|
+
CONF_DEFAULT,
|
13
|
+
CONF_FLEX_ALIGN_CROSS,
|
14
|
+
CONF_FLEX_ALIGN_MAIN,
|
15
|
+
CONF_FLEX_ALIGN_TRACK,
|
16
|
+
CONF_FLEX_FLOW,
|
17
|
+
CONF_GRID_COLUMN_ALIGN,
|
18
|
+
CONF_GRID_COLUMNS,
|
19
|
+
CONF_GRID_ROW_ALIGN,
|
20
|
+
CONF_GRID_ROWS,
|
21
|
+
CONF_LAYOUT,
|
22
|
+
CONF_MAIN,
|
23
|
+
CONF_PAD_COLUMN,
|
24
|
+
CONF_PAD_ROW,
|
25
|
+
CONF_SCROLLBAR_MODE,
|
26
|
+
CONF_STYLES,
|
27
|
+
CONF_WIDGETS,
|
28
|
+
OBJ_FLAGS,
|
29
|
+
PARTS,
|
30
|
+
STATES,
|
31
|
+
TYPE_FLEX,
|
32
|
+
TYPE_GRID,
|
33
|
+
LValidator,
|
34
|
+
call_lambda,
|
35
|
+
join_enums,
|
36
|
+
literal,
|
37
|
+
)
|
38
|
+
from ..helpers import add_lv_use
|
39
|
+
from ..lvcode import (
|
40
|
+
LvConditional,
|
41
|
+
add_line_marks,
|
42
|
+
lv,
|
43
|
+
lv_add,
|
44
|
+
lv_assign,
|
45
|
+
lv_expr,
|
46
|
+
lv_obj,
|
47
|
+
lv_Pvariable,
|
48
|
+
)
|
49
|
+
from ..schemas import ALL_STYLES, STYLE_REMAP, WIDGET_TYPES
|
50
|
+
from ..types import LV_STATE, LvType, WidgetType, lv_coord_t, lv_obj_t, lv_obj_t_ptr
|
51
|
+
|
52
|
+
EVENT_LAMB = "event_lamb__"
|
53
|
+
|
54
|
+
theme_widget_map = {}
|
55
|
+
|
56
|
+
|
57
|
+
class LvScrActType(WidgetType):
|
58
|
+
"""
|
59
|
+
A "widget" representing the active screen.
|
60
|
+
"""
|
61
|
+
|
62
|
+
def __init__(self):
|
63
|
+
super().__init__("lv_scr_act()", lv_obj_t, ())
|
64
|
+
|
65
|
+
async def to_code(self, w, config: dict):
|
66
|
+
return []
|
67
|
+
|
68
|
+
|
69
|
+
class Widget:
|
70
|
+
"""
|
71
|
+
Represents a Widget.
|
72
|
+
"""
|
73
|
+
|
74
|
+
widgets_completed = False
|
75
|
+
|
76
|
+
@staticmethod
|
77
|
+
def set_completed():
|
78
|
+
Widget.widgets_completed = True
|
79
|
+
|
80
|
+
def __init__(self, var, wtype: WidgetType, config: dict = None):
|
81
|
+
self.var = var
|
82
|
+
self.type = wtype
|
83
|
+
self.config = config
|
84
|
+
self.scale = 1.0
|
85
|
+
self.step = 1.0
|
86
|
+
self.range_from = -sys.maxsize
|
87
|
+
self.range_to = sys.maxsize
|
88
|
+
if wtype.is_compound():
|
89
|
+
self.obj = MockObj(f"{self.var}->obj")
|
90
|
+
else:
|
91
|
+
self.obj = var
|
92
|
+
|
93
|
+
@staticmethod
|
94
|
+
def create(name, var, wtype: WidgetType, config: dict = None):
|
95
|
+
w = Widget(var, wtype, config)
|
96
|
+
if name is not None:
|
97
|
+
widget_map[name] = w
|
98
|
+
return w
|
99
|
+
|
100
|
+
def add_state(self, state):
|
101
|
+
return lv_obj.add_state(self.obj, literal(state))
|
102
|
+
|
103
|
+
def clear_state(self, state):
|
104
|
+
return lv_obj.clear_state(self.obj, literal(state))
|
105
|
+
|
106
|
+
def has_state(self, state):
|
107
|
+
return (lv_expr.obj_get_state(self.obj) & literal(state)) != 0
|
108
|
+
|
109
|
+
def is_pressed(self):
|
110
|
+
return self.has_state(LV_STATE.PRESSED)
|
111
|
+
|
112
|
+
def is_checked(self):
|
113
|
+
return self.has_state(LV_STATE.CHECKED)
|
114
|
+
|
115
|
+
def add_flag(self, flag):
|
116
|
+
return lv_obj.add_flag(self.obj, literal(flag))
|
117
|
+
|
118
|
+
def clear_flag(self, flag):
|
119
|
+
return lv_obj.clear_flag(self.obj, literal(flag))
|
120
|
+
|
121
|
+
async def set_property(self, prop, value, animated: bool = None):
|
122
|
+
if isinstance(value, dict):
|
123
|
+
value = value.get(prop)
|
124
|
+
if isinstance(ALL_STYLES.get(prop), LValidator):
|
125
|
+
value = await ALL_STYLES[prop].process(value)
|
126
|
+
else:
|
127
|
+
value = literal(value)
|
128
|
+
if value is None:
|
129
|
+
return
|
130
|
+
if isinstance(value, TimePeriod):
|
131
|
+
value = value.total_milliseconds
|
132
|
+
if isinstance(value, str):
|
133
|
+
value = literal(value)
|
134
|
+
if animated is None or self.type.animated is not True:
|
135
|
+
lv.call(f"{self.type.lv_name}_set_{prop}", self.obj, value)
|
136
|
+
else:
|
137
|
+
lv.call(
|
138
|
+
f"{self.type.lv_name}_set_{prop}",
|
139
|
+
self.obj,
|
140
|
+
value,
|
141
|
+
literal("LV_ANIM_ON" if animated else "LV_ANIM_OFF"),
|
142
|
+
)
|
143
|
+
|
144
|
+
def get_property(self, prop, ltype=None):
|
145
|
+
ltype = ltype or self.__type_base()
|
146
|
+
return cg.RawExpression(f"lv_{ltype}_get_{prop}({self.obj})")
|
147
|
+
|
148
|
+
def set_style(self, prop, value, state):
|
149
|
+
if value is None:
|
150
|
+
return
|
151
|
+
lv.call(f"obj_set_style_{prop}", self.obj, value, state)
|
152
|
+
|
153
|
+
def __type_base(self):
|
154
|
+
wtype = self.type.w_type
|
155
|
+
base = str(wtype)
|
156
|
+
if base.startswith("Lv"):
|
157
|
+
return f"{wtype}".removeprefix("Lv").removesuffix("Type").lower()
|
158
|
+
return f"{wtype}".removeprefix("lv_").removesuffix("_t")
|
159
|
+
|
160
|
+
def __str__(self):
|
161
|
+
return f"({self.var}, {self.type})"
|
162
|
+
|
163
|
+
def get_args(self):
|
164
|
+
if isinstance(self.type.w_type, LvType):
|
165
|
+
return self.type.w_type.args
|
166
|
+
return [(lv_obj_t_ptr, "obj")]
|
167
|
+
|
168
|
+
def get_value(self):
|
169
|
+
if isinstance(self.type.w_type, LvType):
|
170
|
+
return self.type.w_type.value(self)
|
171
|
+
return self.obj
|
172
|
+
|
173
|
+
def get_number_value(self):
|
174
|
+
value = self.type.mock_obj.get_value(self.obj)
|
175
|
+
if self.scale == 1.0:
|
176
|
+
return value
|
177
|
+
return value / float(self.scale)
|
178
|
+
|
179
|
+
def is_selected(self):
|
180
|
+
"""
|
181
|
+
Overridable property to determine if the widget is selected. Will be None except
|
182
|
+
for matrix buttons
|
183
|
+
:return:
|
184
|
+
"""
|
185
|
+
return None
|
186
|
+
|
187
|
+
def get_max(self):
|
188
|
+
return self.type.get_max(self.config)
|
189
|
+
|
190
|
+
def get_min(self):
|
191
|
+
return self.type.get_min(self.config)
|
192
|
+
|
193
|
+
def get_step(self):
|
194
|
+
return self.type.get_step(self.config)
|
195
|
+
|
196
|
+
def get_scale(self):
|
197
|
+
return self.type.get_scale(self.config)
|
198
|
+
|
199
|
+
|
200
|
+
# Map of widgets to their config, used for trigger generation
|
201
|
+
widget_map: dict[Any, Widget] = {}
|
202
|
+
|
203
|
+
|
204
|
+
def get_widget_generator(wid):
|
205
|
+
"""
|
206
|
+
Used to wait for a widget during code generation.
|
207
|
+
:param wid:
|
208
|
+
:return:
|
209
|
+
"""
|
210
|
+
while True:
|
211
|
+
if obj := widget_map.get(wid):
|
212
|
+
return obj
|
213
|
+
if Widget.widgets_completed:
|
214
|
+
raise Invalid(
|
215
|
+
f"Widget {wid} not found, yet all widgets should be defined by now"
|
216
|
+
)
|
217
|
+
yield
|
218
|
+
|
219
|
+
|
220
|
+
async def get_widget_(wid: Widget):
|
221
|
+
if obj := widget_map.get(wid):
|
222
|
+
return obj
|
223
|
+
return await FakeAwaitable(get_widget_generator(wid))
|
224
|
+
|
225
|
+
|
226
|
+
async def get_widgets(config: Union[dict, list], id: str = CONF_ID) -> list[Widget]:
|
227
|
+
if not config:
|
228
|
+
return []
|
229
|
+
if not isinstance(config, list):
|
230
|
+
config = [config]
|
231
|
+
return [await get_widget_(c[id]) for c in config if id in c]
|
232
|
+
|
233
|
+
|
234
|
+
def collect_props(config):
|
235
|
+
"""
|
236
|
+
Collect all properties from a configuration
|
237
|
+
:param config:
|
238
|
+
:return:
|
239
|
+
"""
|
240
|
+
props = {}
|
241
|
+
for prop in [*ALL_STYLES, *OBJ_FLAGS, CONF_STYLES, CONF_GROUP]:
|
242
|
+
if prop in config:
|
243
|
+
props[prop] = config[prop]
|
244
|
+
return props
|
245
|
+
|
246
|
+
|
247
|
+
def collect_states(config):
|
248
|
+
"""
|
249
|
+
Collect prperties for each state of a widget
|
250
|
+
:param config:
|
251
|
+
:return:
|
252
|
+
"""
|
253
|
+
states = {CONF_DEFAULT: collect_props(config)}
|
254
|
+
for state in STATES:
|
255
|
+
if state in config:
|
256
|
+
states[state] = collect_props(config[state])
|
257
|
+
return states
|
258
|
+
|
259
|
+
|
260
|
+
def collect_parts(config):
|
261
|
+
"""
|
262
|
+
Collect properties and states for all widget parts
|
263
|
+
:param config:
|
264
|
+
:return:
|
265
|
+
"""
|
266
|
+
parts = {CONF_MAIN: collect_states(config)}
|
267
|
+
for part in PARTS:
|
268
|
+
if part in config:
|
269
|
+
parts[part] = collect_states(config[part])
|
270
|
+
return parts
|
271
|
+
|
272
|
+
|
273
|
+
async def set_obj_properties(w: Widget, config):
|
274
|
+
"""Generate a list of C++ statements to apply properties to an lv_obj_t"""
|
275
|
+
if layout := config.get(CONF_LAYOUT):
|
276
|
+
layout_type: str = layout[CONF_TYPE]
|
277
|
+
add_lv_use(layout_type)
|
278
|
+
lv_obj.set_layout(w.obj, literal(f"LV_LAYOUT_{layout_type.upper()}"))
|
279
|
+
if (pad_row := layout.get(CONF_PAD_ROW)) is not None:
|
280
|
+
w.set_style(CONF_PAD_ROW, pad_row, 0)
|
281
|
+
if (pad_column := layout.get(CONF_PAD_COLUMN)) is not None:
|
282
|
+
w.set_style(CONF_PAD_COLUMN, pad_column, 0)
|
283
|
+
if layout_type == TYPE_GRID:
|
284
|
+
wid = config[CONF_ID]
|
285
|
+
rows = [str(x) for x in layout[CONF_GRID_ROWS]]
|
286
|
+
rows = "{" + ",".join(rows) + ", LV_GRID_TEMPLATE_LAST}"
|
287
|
+
row_id = ID(f"{wid}_row_dsc", is_declaration=True, type=lv_coord_t)
|
288
|
+
row_array = cg.static_const_array(row_id, cg.RawExpression(rows))
|
289
|
+
w.set_style("grid_row_dsc_array", row_array, 0)
|
290
|
+
columns = [str(x) for x in layout[CONF_GRID_COLUMNS]]
|
291
|
+
columns = "{" + ",".join(columns) + ", LV_GRID_TEMPLATE_LAST}"
|
292
|
+
column_id = ID(f"{wid}_column_dsc", is_declaration=True, type=lv_coord_t)
|
293
|
+
column_array = cg.static_const_array(column_id, cg.RawExpression(columns))
|
294
|
+
w.set_style("grid_column_dsc_array", column_array, 0)
|
295
|
+
w.set_style(
|
296
|
+
CONF_GRID_COLUMN_ALIGN, literal(layout.get(CONF_GRID_COLUMN_ALIGN)), 0
|
297
|
+
)
|
298
|
+
w.set_style(
|
299
|
+
CONF_GRID_ROW_ALIGN, literal(layout.get(CONF_GRID_ROW_ALIGN)), 0
|
300
|
+
)
|
301
|
+
if layout_type == TYPE_FLEX:
|
302
|
+
lv_obj.set_flex_flow(w.obj, literal(layout[CONF_FLEX_FLOW]))
|
303
|
+
main = literal(layout[CONF_FLEX_ALIGN_MAIN])
|
304
|
+
cross = literal(layout[CONF_FLEX_ALIGN_CROSS])
|
305
|
+
track = literal(layout[CONF_FLEX_ALIGN_TRACK])
|
306
|
+
lv_obj.set_flex_align(w.obj, main, cross, track)
|
307
|
+
parts = collect_parts(config)
|
308
|
+
for part, states in parts.items():
|
309
|
+
for state, props in states.items():
|
310
|
+
lv_state = join_enums((f"LV_STATE_{state}", f"LV_PART_{part}"))
|
311
|
+
for style_id in props.get(CONF_STYLES, ()):
|
312
|
+
lv_obj.add_style(w.obj, MockObj(style_id), lv_state)
|
313
|
+
for prop, value in {
|
314
|
+
k: v for k, v in props.items() if k in ALL_STYLES
|
315
|
+
}.items():
|
316
|
+
if isinstance(ALL_STYLES[prop], LValidator):
|
317
|
+
value = await ALL_STYLES[prop].process(value)
|
318
|
+
prop_r = STYLE_REMAP.get(prop, prop)
|
319
|
+
w.set_style(prop_r, value, lv_state)
|
320
|
+
if group := config.get(CONF_GROUP):
|
321
|
+
group = await cg.get_variable(group)
|
322
|
+
lv.group_add_obj(group, w.obj)
|
323
|
+
flag_clr = set()
|
324
|
+
flag_set = set()
|
325
|
+
props = parts[CONF_MAIN][CONF_DEFAULT]
|
326
|
+
lambs = {}
|
327
|
+
flag_set = set()
|
328
|
+
flag_clr = set()
|
329
|
+
for prop, value in {k: v for k, v in props.items() if k in OBJ_FLAGS}.items():
|
330
|
+
if isinstance(value, cv.Lambda):
|
331
|
+
lambs[prop] = value
|
332
|
+
elif value:
|
333
|
+
flag_set.add(prop)
|
334
|
+
else:
|
335
|
+
flag_clr.add(prop)
|
336
|
+
if flag_set:
|
337
|
+
adds = join_enums(flag_set, "LV_OBJ_FLAG_")
|
338
|
+
w.add_flag(adds)
|
339
|
+
if flag_clr:
|
340
|
+
clrs = join_enums(flag_clr, "LV_OBJ_FLAG_")
|
341
|
+
w.clear_flag(clrs)
|
342
|
+
for key, value in lambs.items():
|
343
|
+
lamb = await cg.process_lambda(value, [], return_type=cg.bool_)
|
344
|
+
flag = f"LV_OBJ_FLAG_{key.upper()}"
|
345
|
+
with LvConditional(call_lambda(lamb)) as cond:
|
346
|
+
w.add_flag(flag)
|
347
|
+
cond.else_()
|
348
|
+
w.clear_flag(flag)
|
349
|
+
|
350
|
+
if states := config.get(CONF_STATE):
|
351
|
+
adds = set()
|
352
|
+
clears = set()
|
353
|
+
lambs = {}
|
354
|
+
for key, value in states.items():
|
355
|
+
if isinstance(value, cv.Lambda):
|
356
|
+
lambs[key] = value
|
357
|
+
elif value:
|
358
|
+
adds.add(key)
|
359
|
+
else:
|
360
|
+
clears.add(key)
|
361
|
+
if adds:
|
362
|
+
adds = join_enums(adds, "LV_STATE_")
|
363
|
+
w.add_state(adds)
|
364
|
+
if clears:
|
365
|
+
clears = join_enums(clears, "LV_STATE_")
|
366
|
+
w.clear_state(clears)
|
367
|
+
for key, value in lambs.items():
|
368
|
+
lamb = await cg.process_lambda(value, [], return_type=cg.bool_)
|
369
|
+
state = f"LV_STATE_{key.upper()}"
|
370
|
+
with LvConditional(call_lambda(lamb)) as cond:
|
371
|
+
w.add_state(state)
|
372
|
+
cond.else_()
|
373
|
+
w.clear_state(state)
|
374
|
+
await w.set_property(CONF_SCROLLBAR_MODE, config)
|
375
|
+
|
376
|
+
|
377
|
+
async def add_widgets(parent: Widget, config: dict):
|
378
|
+
"""
|
379
|
+
Add all widgets to an object
|
380
|
+
:param parent: The enclosing obj
|
381
|
+
:param config: The configuration
|
382
|
+
:return:
|
383
|
+
"""
|
384
|
+
for w in config.get(CONF_WIDGETS, ()):
|
385
|
+
w_type, w_cnfig = next(iter(w.items()))
|
386
|
+
await widget_to_code(w_cnfig, w_type, parent.obj)
|
387
|
+
|
388
|
+
|
389
|
+
async def widget_to_code(w_cnfig, w_type: WidgetType, parent):
|
390
|
+
"""
|
391
|
+
Converts a Widget definition to C code.
|
392
|
+
:param w_cnfig: The widget configuration
|
393
|
+
:param w_type: The Widget type
|
394
|
+
:param parent: The parent to which the widget should be added
|
395
|
+
:return:
|
396
|
+
"""
|
397
|
+
spec: WidgetType = WIDGET_TYPES[w_type]
|
398
|
+
creator = spec.obj_creator(parent, w_cnfig)
|
399
|
+
add_lv_use(spec.name)
|
400
|
+
add_lv_use(*spec.get_uses())
|
401
|
+
wid = w_cnfig[CONF_ID]
|
402
|
+
add_line_marks(wid)
|
403
|
+
if spec.is_compound():
|
404
|
+
var = cg.new_Pvariable(wid)
|
405
|
+
lv_add(var.set_obj(creator))
|
406
|
+
else:
|
407
|
+
var = lv_Pvariable(lv_obj_t, wid)
|
408
|
+
lv_assign(var, creator)
|
409
|
+
|
410
|
+
w = Widget.create(wid, var, spec, w_cnfig)
|
411
|
+
if theme := theme_widget_map.get(w_type):
|
412
|
+
lv_add(CallExpression(theme, w.obj))
|
413
|
+
await set_obj_properties(w, w_cnfig)
|
414
|
+
await add_widgets(w, w_cnfig)
|
415
|
+
await spec.to_code(w, w_cnfig)
|
416
|
+
|
417
|
+
|
418
|
+
lv_scr_act_spec = LvScrActType()
|
419
|
+
lv_scr_act = Widget.create(None, literal("lv_scr_act()"), lv_scr_act_spec, {})
|
@@ -0,0 +1,117 @@
|
|
1
|
+
from esphome import automation
|
2
|
+
import esphome.codegen as cg
|
3
|
+
import esphome.config_validation as cv
|
4
|
+
from esphome.const import CONF_DURATION, CONF_ID
|
5
|
+
from esphome.cpp_generator import MockObj
|
6
|
+
|
7
|
+
from ..automation import action_to_code
|
8
|
+
from ..defines import CONF_AUTO_START, CONF_MAIN, CONF_REPEAT_COUNT, CONF_SRC
|
9
|
+
from ..helpers import lvgl_components_required
|
10
|
+
from ..lv_validation import lv_image, lv_milliseconds
|
11
|
+
from ..lvcode import lv, lv_expr
|
12
|
+
from ..types import LvType, ObjUpdateAction, void_ptr
|
13
|
+
from . import Widget, WidgetType, get_widgets
|
14
|
+
from .img import CONF_IMAGE
|
15
|
+
from .label import CONF_LABEL
|
16
|
+
|
17
|
+
CONF_ANIMIMG = "animimg"
|
18
|
+
CONF_SRC_LIST_ID = "src_list_id"
|
19
|
+
|
20
|
+
|
21
|
+
def lv_repeat_count(value):
|
22
|
+
if isinstance(value, str) and value.lower() in ("forever", "infinite"):
|
23
|
+
value = 0xFFFF
|
24
|
+
return cv.int_range(min=0, max=0xFFFF)(value)
|
25
|
+
|
26
|
+
|
27
|
+
ANIMIMG_BASE_SCHEMA = cv.Schema(
|
28
|
+
{
|
29
|
+
cv.Optional(CONF_REPEAT_COUNT, default="forever"): lv_repeat_count,
|
30
|
+
cv.Optional(CONF_AUTO_START, default=True): cv.boolean,
|
31
|
+
}
|
32
|
+
)
|
33
|
+
ANIMIMG_SCHEMA = ANIMIMG_BASE_SCHEMA.extend(
|
34
|
+
{
|
35
|
+
cv.Required(CONF_DURATION): lv_milliseconds,
|
36
|
+
cv.Required(CONF_SRC): cv.ensure_list(lv_image),
|
37
|
+
cv.GenerateID(CONF_SRC_LIST_ID): cv.declare_id(void_ptr),
|
38
|
+
}
|
39
|
+
)
|
40
|
+
|
41
|
+
ANIMIMG_MODIFY_SCHEMA = ANIMIMG_BASE_SCHEMA.extend(
|
42
|
+
{
|
43
|
+
cv.Optional(CONF_DURATION): lv_milliseconds,
|
44
|
+
}
|
45
|
+
)
|
46
|
+
|
47
|
+
lv_animimg_t = LvType("lv_animimg_t")
|
48
|
+
|
49
|
+
|
50
|
+
class AnimimgType(WidgetType):
|
51
|
+
def __init__(self):
|
52
|
+
super().__init__(
|
53
|
+
CONF_ANIMIMG,
|
54
|
+
lv_animimg_t,
|
55
|
+
(CONF_MAIN,),
|
56
|
+
ANIMIMG_SCHEMA,
|
57
|
+
ANIMIMG_MODIFY_SCHEMA,
|
58
|
+
)
|
59
|
+
|
60
|
+
async def to_code(self, w: Widget, config):
|
61
|
+
lvgl_components_required.add(CONF_IMAGE)
|
62
|
+
lvgl_components_required.add(CONF_ANIMIMG)
|
63
|
+
if CONF_SRC in config:
|
64
|
+
for x in config[CONF_SRC]:
|
65
|
+
await cg.get_variable(x)
|
66
|
+
srcs = [lv_expr.img_from(MockObj(x)) for x in config[CONF_SRC]]
|
67
|
+
src_id = cg.static_const_array(config[CONF_SRC_LIST_ID], srcs)
|
68
|
+
count = len(config[CONF_SRC])
|
69
|
+
lv.animimg_set_src(w.obj, src_id, count)
|
70
|
+
lv.animimg_set_repeat_count(w.obj, config[CONF_REPEAT_COUNT])
|
71
|
+
lv.animimg_set_duration(w.obj, config[CONF_DURATION])
|
72
|
+
if config.get(CONF_AUTO_START):
|
73
|
+
lv.animimg_start(w.obj)
|
74
|
+
|
75
|
+
def get_uses(self):
|
76
|
+
return CONF_IMAGE, CONF_LABEL
|
77
|
+
|
78
|
+
|
79
|
+
animimg_spec = AnimimgType()
|
80
|
+
|
81
|
+
|
82
|
+
@automation.register_action(
|
83
|
+
"lvgl.animimg.start",
|
84
|
+
ObjUpdateAction,
|
85
|
+
cv.maybe_simple_value(
|
86
|
+
{
|
87
|
+
cv.Required(CONF_ID): cv.use_id(lv_animimg_t),
|
88
|
+
},
|
89
|
+
key=CONF_ID,
|
90
|
+
),
|
91
|
+
)
|
92
|
+
async def animimg_start(config, action_id, template_arg, args):
|
93
|
+
widget = await get_widgets(config)
|
94
|
+
|
95
|
+
async def do_start(w: Widget):
|
96
|
+
lv.animimg_start(w.obj)
|
97
|
+
|
98
|
+
return await action_to_code(widget, do_start, action_id, template_arg, args)
|
99
|
+
|
100
|
+
|
101
|
+
@automation.register_action(
|
102
|
+
"lvgl.animimg.stop",
|
103
|
+
ObjUpdateAction,
|
104
|
+
cv.maybe_simple_value(
|
105
|
+
{
|
106
|
+
cv.Required(CONF_ID): cv.use_id(lv_animimg_t),
|
107
|
+
},
|
108
|
+
key=CONF_ID,
|
109
|
+
),
|
110
|
+
)
|
111
|
+
async def animimg_stop(config, action_id, template_arg, args):
|
112
|
+
widget = await get_widgets(config)
|
113
|
+
|
114
|
+
async def do_stop(w: Widget):
|
115
|
+
lv.animimg_stop(w.obj)
|
116
|
+
|
117
|
+
return await action_to_code(widget, do_stop, action_id, template_arg, args)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import esphome.config_validation as cv
|
2
|
+
from esphome.const import (
|
3
|
+
CONF_MAX_VALUE,
|
4
|
+
CONF_MIN_VALUE,
|
5
|
+
CONF_MODE,
|
6
|
+
CONF_ROTATION,
|
7
|
+
CONF_VALUE,
|
8
|
+
)
|
9
|
+
from esphome.cpp_types import nullptr
|
10
|
+
|
11
|
+
from ..defines import (
|
12
|
+
ARC_MODES,
|
13
|
+
CONF_ADJUSTABLE,
|
14
|
+
CONF_CHANGE_RATE,
|
15
|
+
CONF_END_ANGLE,
|
16
|
+
CONF_INDICATOR,
|
17
|
+
CONF_KNOB,
|
18
|
+
CONF_MAIN,
|
19
|
+
CONF_START_ANGLE,
|
20
|
+
literal,
|
21
|
+
)
|
22
|
+
from ..lv_validation import angle, get_start_value, lv_float
|
23
|
+
from ..lvcode import lv, lv_obj
|
24
|
+
from ..types import LvNumber, NumberType
|
25
|
+
from . import Widget
|
26
|
+
|
27
|
+
CONF_ARC = "arc"
|
28
|
+
ARC_SCHEMA = cv.Schema(
|
29
|
+
{
|
30
|
+
cv.Optional(CONF_VALUE): lv_float,
|
31
|
+
cv.Optional(CONF_MIN_VALUE, default=0): cv.int_,
|
32
|
+
cv.Optional(CONF_MAX_VALUE, default=100): cv.int_,
|
33
|
+
cv.Optional(CONF_START_ANGLE, default=135): angle,
|
34
|
+
cv.Optional(CONF_END_ANGLE, default=45): angle,
|
35
|
+
cv.Optional(CONF_ROTATION, default=0.0): angle,
|
36
|
+
cv.Optional(CONF_ADJUSTABLE, default=False): bool,
|
37
|
+
cv.Optional(CONF_MODE, default="NORMAL"): ARC_MODES.one_of,
|
38
|
+
cv.Optional(CONF_CHANGE_RATE, default=720): cv.uint16_t,
|
39
|
+
}
|
40
|
+
)
|
41
|
+
|
42
|
+
ARC_MODIFY_SCHEMA = cv.Schema(
|
43
|
+
{
|
44
|
+
cv.Optional(CONF_VALUE): lv_float,
|
45
|
+
}
|
46
|
+
)
|
47
|
+
|
48
|
+
|
49
|
+
class ArcType(NumberType):
|
50
|
+
def __init__(self):
|
51
|
+
super().__init__(
|
52
|
+
CONF_ARC,
|
53
|
+
LvNumber("lv_arc_t"),
|
54
|
+
parts=(CONF_MAIN, CONF_INDICATOR, CONF_KNOB),
|
55
|
+
schema=ARC_SCHEMA,
|
56
|
+
modify_schema=ARC_MODIFY_SCHEMA,
|
57
|
+
)
|
58
|
+
|
59
|
+
async def to_code(self, w: Widget, config):
|
60
|
+
if CONF_MIN_VALUE in config:
|
61
|
+
lv.arc_set_range(w.obj, config[CONF_MIN_VALUE], config[CONF_MAX_VALUE])
|
62
|
+
lv.arc_set_bg_angles(
|
63
|
+
w.obj, config[CONF_START_ANGLE] // 10, config[CONF_END_ANGLE] // 10
|
64
|
+
)
|
65
|
+
lv.arc_set_rotation(w.obj, config[CONF_ROTATION] // 10)
|
66
|
+
lv.arc_set_mode(w.obj, literal(config[CONF_MODE]))
|
67
|
+
lv.arc_set_change_rate(w.obj, config[CONF_CHANGE_RATE])
|
68
|
+
|
69
|
+
if config.get(CONF_ADJUSTABLE) is False:
|
70
|
+
lv_obj.remove_style(w.obj, nullptr, literal("LV_PART_KNOB"))
|
71
|
+
w.clear_flag("LV_OBJ_FLAG_CLICKABLE")
|
72
|
+
|
73
|
+
value = await get_start_value(config)
|
74
|
+
if value is not None:
|
75
|
+
lv.arc_set_value(w.obj, value)
|
76
|
+
|
77
|
+
|
78
|
+
arc_spec = ArcType()
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from esphome.const import CONF_BUTTON
|
2
|
+
|
3
|
+
from ..defines import CONF_MAIN
|
4
|
+
from ..types import LvBoolean, WidgetType
|
5
|
+
|
6
|
+
lv_button_t = LvBoolean("lv_btn_t")
|
7
|
+
|
8
|
+
|
9
|
+
class ButtonType(WidgetType):
|
10
|
+
def __init__(self):
|
11
|
+
super().__init__(CONF_BUTTON, lv_button_t, (CONF_MAIN,), lv_name="btn")
|
12
|
+
|
13
|
+
def get_uses(self):
|
14
|
+
return ("btn",)
|
15
|
+
|
16
|
+
async def to_code(self, w, config):
|
17
|
+
return []
|
18
|
+
|
19
|
+
|
20
|
+
button_spec = ButtonType()
|