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,275 @@
|
|
1
|
+
from esphome import automation
|
2
|
+
import esphome.codegen as cg
|
3
|
+
from esphome.components.key_provider import KeyProvider
|
4
|
+
import esphome.config_validation as cv
|
5
|
+
from esphome.const import CONF_ID, CONF_ITEMS, CONF_TEXT, CONF_WIDTH
|
6
|
+
from esphome.cpp_generator import MockObj
|
7
|
+
|
8
|
+
from ..automation import action_to_code
|
9
|
+
from ..defines import (
|
10
|
+
BUTTONMATRIX_CTRLS,
|
11
|
+
CONF_BUTTONS,
|
12
|
+
CONF_CONTROL,
|
13
|
+
CONF_KEY_CODE,
|
14
|
+
CONF_MAIN,
|
15
|
+
CONF_ONE_CHECKED,
|
16
|
+
CONF_ROWS,
|
17
|
+
CONF_SELECTED,
|
18
|
+
)
|
19
|
+
from ..helpers import lvgl_components_required
|
20
|
+
from ..lv_validation import key_code, lv_bool
|
21
|
+
from ..lvcode import lv, lv_add, lv_expr
|
22
|
+
from ..schemas import automation_schema
|
23
|
+
from ..types import (
|
24
|
+
LV_BTNMATRIX_CTRL,
|
25
|
+
LV_STATE,
|
26
|
+
LvBoolean,
|
27
|
+
LvCompound,
|
28
|
+
LvType,
|
29
|
+
ObjUpdateAction,
|
30
|
+
char_ptr,
|
31
|
+
lv_pseudo_button_t,
|
32
|
+
)
|
33
|
+
from . import Widget, WidgetType, get_widgets, widget_map
|
34
|
+
from .button import lv_button_t
|
35
|
+
|
36
|
+
CONF_BUTTONMATRIX = "buttonmatrix"
|
37
|
+
CONF_BUTTON_TEXT_LIST_ID = "button_text_list_id"
|
38
|
+
|
39
|
+
LvButtonMatrixButton = LvBoolean(
|
40
|
+
str(cg.uint16),
|
41
|
+
parents=(lv_pseudo_button_t,),
|
42
|
+
)
|
43
|
+
BUTTONMATRIX_BUTTON_SCHEMA = cv.Schema(
|
44
|
+
{
|
45
|
+
cv.Optional(CONF_TEXT): cv.string,
|
46
|
+
cv.Optional(CONF_KEY_CODE): key_code,
|
47
|
+
cv.GenerateID(): cv.declare_id(LvButtonMatrixButton),
|
48
|
+
cv.Optional(CONF_WIDTH, default=1): cv.positive_int,
|
49
|
+
cv.Optional(CONF_CONTROL): cv.ensure_list(
|
50
|
+
cv.Schema(
|
51
|
+
{cv.Optional(k.lower()): cv.boolean for k in BUTTONMATRIX_CTRLS.choices}
|
52
|
+
)
|
53
|
+
),
|
54
|
+
}
|
55
|
+
).extend(automation_schema(lv_button_t))
|
56
|
+
|
57
|
+
BUTTONMATRIX_SCHEMA = cv.Schema(
|
58
|
+
{
|
59
|
+
cv.Optional(CONF_ONE_CHECKED, default=False): lv_bool,
|
60
|
+
cv.GenerateID(CONF_BUTTON_TEXT_LIST_ID): cv.declare_id(char_ptr),
|
61
|
+
cv.Required(CONF_ROWS): cv.ensure_list(
|
62
|
+
cv.Schema(
|
63
|
+
{
|
64
|
+
cv.Required(CONF_BUTTONS): cv.ensure_list(
|
65
|
+
BUTTONMATRIX_BUTTON_SCHEMA
|
66
|
+
),
|
67
|
+
}
|
68
|
+
)
|
69
|
+
),
|
70
|
+
}
|
71
|
+
)
|
72
|
+
|
73
|
+
|
74
|
+
class ButtonmatrixButtonType(WidgetType):
|
75
|
+
"""
|
76
|
+
A pseudo-widget for the matrix buttons
|
77
|
+
"""
|
78
|
+
|
79
|
+
def __init__(self):
|
80
|
+
super().__init__("btnmatrix_btn", LvButtonMatrixButton, (), {}, {})
|
81
|
+
|
82
|
+
async def to_code(self, w, config: dict):
|
83
|
+
return []
|
84
|
+
|
85
|
+
|
86
|
+
btn_btn_spec = ButtonmatrixButtonType()
|
87
|
+
|
88
|
+
|
89
|
+
class MatrixButton(Widget):
|
90
|
+
"""
|
91
|
+
Describes a button within a button matrix.
|
92
|
+
"""
|
93
|
+
|
94
|
+
@staticmethod
|
95
|
+
def create_button(id, parent, config: dict, index):
|
96
|
+
w = MatrixButton(id, parent, config, index)
|
97
|
+
widget_map[id] = w
|
98
|
+
return w
|
99
|
+
|
100
|
+
def __init__(self, id, parent: Widget, config, index):
|
101
|
+
super().__init__(id, btn_btn_spec, config)
|
102
|
+
self.parent = parent
|
103
|
+
self.index = index
|
104
|
+
self.obj = parent.obj
|
105
|
+
|
106
|
+
def is_selected(self):
|
107
|
+
return self.parent.var.get_selected() == MockObj(self.var)
|
108
|
+
|
109
|
+
@staticmethod
|
110
|
+
def map_ctrls(state):
|
111
|
+
state = str(state).upper().removeprefix("LV_STATE_")
|
112
|
+
assert state in BUTTONMATRIX_CTRLS.choices
|
113
|
+
return getattr(LV_BTNMATRIX_CTRL, state)
|
114
|
+
|
115
|
+
def has_state(self, state):
|
116
|
+
state = self.map_ctrls(state)
|
117
|
+
return lv_expr.btnmatrix_has_btn_ctrl(self.obj, self.index, state)
|
118
|
+
|
119
|
+
def add_state(self, state):
|
120
|
+
state = self.map_ctrls(state)
|
121
|
+
return lv.btnmatrix_set_btn_ctrl(self.obj, self.index, state)
|
122
|
+
|
123
|
+
def clear_state(self, state):
|
124
|
+
state = self.map_ctrls(state)
|
125
|
+
return lv.btnmatrix_clear_btn_ctrl(self.obj, self.index, state)
|
126
|
+
|
127
|
+
def is_pressed(self):
|
128
|
+
return self.is_selected() & self.parent.has_state(LV_STATE.PRESSED)
|
129
|
+
|
130
|
+
def is_checked(self):
|
131
|
+
return self.has_state(LV_STATE.CHECKED)
|
132
|
+
|
133
|
+
def get_value(self):
|
134
|
+
return self.is_checked()
|
135
|
+
|
136
|
+
def check_null(self):
|
137
|
+
return None
|
138
|
+
|
139
|
+
|
140
|
+
async def get_button_data(config, buttonmatrix: Widget):
|
141
|
+
"""
|
142
|
+
Process a button matrix button list
|
143
|
+
:param config: The row list
|
144
|
+
:param buttonmatrix: The parent variable
|
145
|
+
:return: text array id, control list, width list
|
146
|
+
"""
|
147
|
+
text_list = []
|
148
|
+
ctrl_list = []
|
149
|
+
width_list = []
|
150
|
+
key_list = []
|
151
|
+
for row in config:
|
152
|
+
for button_conf in row.get(CONF_BUTTONS, ()):
|
153
|
+
bid = button_conf[CONF_ID]
|
154
|
+
index = len(width_list)
|
155
|
+
MatrixButton.create_button(bid, buttonmatrix, button_conf, index)
|
156
|
+
cg.new_variable(bid, index)
|
157
|
+
text_list.append(button_conf.get(CONF_TEXT) or "")
|
158
|
+
key_list.append(button_conf.get(CONF_KEY_CODE) or 0)
|
159
|
+
width_list.append(button_conf[CONF_WIDTH])
|
160
|
+
ctrl = ["LV_BTNMATRIX_CTRL_CLICK_TRIG"]
|
161
|
+
for item in button_conf.get(CONF_CONTROL, ()):
|
162
|
+
ctrl.extend([k for k, v in item.items() if v])
|
163
|
+
ctrl_list.append(await BUTTONMATRIX_CTRLS.process(ctrl))
|
164
|
+
text_list.append("\n")
|
165
|
+
text_list = text_list[:-1]
|
166
|
+
text_list.append(cg.nullptr)
|
167
|
+
return text_list, ctrl_list, width_list, key_list
|
168
|
+
|
169
|
+
|
170
|
+
lv_buttonmatrix_t = LvType(
|
171
|
+
"LvButtonMatrixType",
|
172
|
+
parents=(KeyProvider, LvCompound),
|
173
|
+
largs=[(cg.uint16, "x")],
|
174
|
+
lvalue=lambda w: w.var.get_selected(),
|
175
|
+
)
|
176
|
+
|
177
|
+
|
178
|
+
class ButtonMatrixType(WidgetType):
|
179
|
+
def __init__(self):
|
180
|
+
super().__init__(
|
181
|
+
CONF_BUTTONMATRIX,
|
182
|
+
lv_buttonmatrix_t,
|
183
|
+
(CONF_MAIN, CONF_ITEMS),
|
184
|
+
BUTTONMATRIX_SCHEMA,
|
185
|
+
{},
|
186
|
+
lv_name="btnmatrix",
|
187
|
+
)
|
188
|
+
|
189
|
+
async def to_code(self, w: Widget, config):
|
190
|
+
lvgl_components_required.add("BUTTONMATRIX")
|
191
|
+
if CONF_ROWS not in config:
|
192
|
+
return []
|
193
|
+
text_list, ctrl_list, width_list, key_list = await get_button_data(
|
194
|
+
config[CONF_ROWS], w
|
195
|
+
)
|
196
|
+
text_id = config[CONF_BUTTON_TEXT_LIST_ID]
|
197
|
+
text_id = cg.static_const_array(text_id, text_list)
|
198
|
+
lv.btnmatrix_set_map(w.obj, text_id)
|
199
|
+
set_btn_data(w.obj, ctrl_list, width_list)
|
200
|
+
lv.btnmatrix_set_one_checked(w.obj, config[CONF_ONE_CHECKED])
|
201
|
+
for index, key in enumerate(key_list):
|
202
|
+
if key != 0:
|
203
|
+
lv_add(w.var.set_key(index, key))
|
204
|
+
|
205
|
+
def get_uses(self):
|
206
|
+
return ("btnmatrix",)
|
207
|
+
|
208
|
+
|
209
|
+
def set_btn_data(obj, ctrl_list, width_list):
|
210
|
+
for index, ctrl in enumerate(ctrl_list):
|
211
|
+
lv.btnmatrix_set_btn_ctrl(obj, index, ctrl)
|
212
|
+
for index, width in enumerate(width_list):
|
213
|
+
lv.btnmatrix_set_btn_width(obj, index, width)
|
214
|
+
|
215
|
+
|
216
|
+
buttonmatrix_spec = ButtonMatrixType()
|
217
|
+
|
218
|
+
|
219
|
+
@automation.register_action(
|
220
|
+
"lvgl.matrix.button.update",
|
221
|
+
ObjUpdateAction,
|
222
|
+
cv.Schema(
|
223
|
+
{
|
224
|
+
cv.Optional(CONF_WIDTH): cv.positive_int,
|
225
|
+
cv.Optional(CONF_CONTROL): cv.ensure_list(
|
226
|
+
cv.Schema(
|
227
|
+
{
|
228
|
+
cv.Optional(k.lower()): cv.boolean
|
229
|
+
for k in BUTTONMATRIX_CTRLS.choices
|
230
|
+
}
|
231
|
+
),
|
232
|
+
),
|
233
|
+
cv.Required(CONF_ID): cv.ensure_list(
|
234
|
+
cv.maybe_simple_value(
|
235
|
+
{
|
236
|
+
cv.Required(CONF_ID): cv.use_id(LvButtonMatrixButton),
|
237
|
+
},
|
238
|
+
key=CONF_ID,
|
239
|
+
)
|
240
|
+
),
|
241
|
+
cv.Optional(CONF_SELECTED): lv_bool,
|
242
|
+
}
|
243
|
+
),
|
244
|
+
)
|
245
|
+
async def button_update_to_code(config, action_id, template_arg, args):
|
246
|
+
widgets = await get_widgets(config[CONF_ID])
|
247
|
+
assert all(isinstance(w, MatrixButton) for w in widgets)
|
248
|
+
|
249
|
+
async def do_button_update(w: MatrixButton):
|
250
|
+
if (width := config.get(CONF_WIDTH)) is not None:
|
251
|
+
lv.btnmatrix_set_btn_width(w.obj, w.index, width)
|
252
|
+
if config.get(CONF_SELECTED):
|
253
|
+
lv.btnmatrix_set_selected_btn(w.obj, w.index)
|
254
|
+
if controls := config.get(CONF_CONTROL):
|
255
|
+
adds = []
|
256
|
+
clrs = []
|
257
|
+
for item in controls:
|
258
|
+
adds.extend(
|
259
|
+
[f"LV_BTNMATRIX_CTRL_{k.upper()}" for k, v in item.items() if v]
|
260
|
+
)
|
261
|
+
clrs.extend(
|
262
|
+
[f"LV_BTNMATRIX_CTRL_{k.upper()}" for k, v in item.items() if not v]
|
263
|
+
)
|
264
|
+
if adds:
|
265
|
+
lv.btnmatrix_set_btn_ctrl(
|
266
|
+
w.obj, w.index, await BUTTONMATRIX_CTRLS.process(adds)
|
267
|
+
)
|
268
|
+
if clrs:
|
269
|
+
lv.btnmatrix_clear_btn_ctrl(
|
270
|
+
w.obj, w.index, await BUTTONMATRIX_CTRLS.process(clrs)
|
271
|
+
)
|
272
|
+
|
273
|
+
return await action_to_code(
|
274
|
+
widgets, do_button_update, action_id, template_arg, args
|
275
|
+
)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from esphome.const import CONF_TEXT
|
2
|
+
|
3
|
+
from ..defines import CONF_INDICATOR, CONF_MAIN
|
4
|
+
from ..lv_validation import lv_text
|
5
|
+
from ..lvcode import lv
|
6
|
+
from ..schemas import TEXT_SCHEMA
|
7
|
+
from ..types import LvBoolean
|
8
|
+
from . import Widget, WidgetType
|
9
|
+
|
10
|
+
CONF_CHECKBOX = "checkbox"
|
11
|
+
|
12
|
+
|
13
|
+
class CheckboxType(WidgetType):
|
14
|
+
def __init__(self):
|
15
|
+
super().__init__(
|
16
|
+
CONF_CHECKBOX,
|
17
|
+
LvBoolean("lv_checkbox_t"),
|
18
|
+
(CONF_MAIN, CONF_INDICATOR),
|
19
|
+
TEXT_SCHEMA,
|
20
|
+
)
|
21
|
+
|
22
|
+
async def to_code(self, w: Widget, config):
|
23
|
+
if (value := config.get(CONF_TEXT)) is not None:
|
24
|
+
lv.checkbox_set_text(w.obj, await lv_text.process(value))
|
25
|
+
|
26
|
+
|
27
|
+
checkbox_spec = CheckboxType()
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import esphome.codegen as cg
|
2
|
+
import esphome.config_validation as cv
|
3
|
+
from esphome.const import CONF_OPTIONS
|
4
|
+
|
5
|
+
from ..defines import (
|
6
|
+
CONF_DIR,
|
7
|
+
CONF_INDICATOR,
|
8
|
+
CONF_MAIN,
|
9
|
+
CONF_SELECTED_INDEX,
|
10
|
+
CONF_SYMBOL,
|
11
|
+
DIRECTIONS,
|
12
|
+
literal,
|
13
|
+
)
|
14
|
+
from ..lv_validation import lv_int, lv_text, option_string
|
15
|
+
from ..lvcode import LocalVariable, lv, lv_expr
|
16
|
+
from ..schemas import part_schema
|
17
|
+
from ..types import LvSelect, LvType, lv_obj_t
|
18
|
+
from . import Widget, WidgetType, set_obj_properties
|
19
|
+
from .label import CONF_LABEL
|
20
|
+
|
21
|
+
CONF_DROPDOWN = "dropdown"
|
22
|
+
CONF_DROPDOWN_LIST = "dropdown_list"
|
23
|
+
|
24
|
+
lv_dropdown_t = LvSelect("lv_dropdown_t")
|
25
|
+
lv_dropdown_list_t = LvType("lv_dropdown_list_t")
|
26
|
+
dropdown_list_spec = WidgetType(CONF_DROPDOWN_LIST, lv_dropdown_list_t, (CONF_MAIN,))
|
27
|
+
|
28
|
+
DROPDOWN_BASE_SCHEMA = cv.Schema(
|
29
|
+
{
|
30
|
+
cv.Optional(CONF_SYMBOL): lv_text,
|
31
|
+
cv.Optional(CONF_SELECTED_INDEX): cv.templatable(cv.int_),
|
32
|
+
cv.Optional(CONF_DIR, default="BOTTOM"): DIRECTIONS.one_of,
|
33
|
+
cv.Optional(CONF_DROPDOWN_LIST): part_schema(dropdown_list_spec),
|
34
|
+
}
|
35
|
+
)
|
36
|
+
|
37
|
+
DROPDOWN_SCHEMA = DROPDOWN_BASE_SCHEMA.extend(
|
38
|
+
{
|
39
|
+
cv.Required(CONF_OPTIONS): cv.ensure_list(option_string),
|
40
|
+
}
|
41
|
+
)
|
42
|
+
|
43
|
+
|
44
|
+
class DropdownType(WidgetType):
|
45
|
+
def __init__(self):
|
46
|
+
super().__init__(
|
47
|
+
CONF_DROPDOWN,
|
48
|
+
lv_dropdown_t,
|
49
|
+
(CONF_MAIN, CONF_INDICATOR),
|
50
|
+
DROPDOWN_SCHEMA,
|
51
|
+
DROPDOWN_BASE_SCHEMA,
|
52
|
+
)
|
53
|
+
|
54
|
+
async def to_code(self, w: Widget, config):
|
55
|
+
if options := config.get(CONF_OPTIONS):
|
56
|
+
text = cg.safe_exp("\n".join(options))
|
57
|
+
lv.dropdown_set_options(w.obj, text)
|
58
|
+
if symbol := config.get(CONF_SYMBOL):
|
59
|
+
lv.dropdown_set_symbol(w.obj, await lv_text.process(symbol))
|
60
|
+
if (selected := config.get(CONF_SELECTED_INDEX)) is not None:
|
61
|
+
value = await lv_int.process(selected)
|
62
|
+
lv.dropdown_set_selected(w.obj, value)
|
63
|
+
if dirn := config.get(CONF_DIR):
|
64
|
+
lv.dropdown_set_dir(w.obj, literal(dirn))
|
65
|
+
if dlist := config.get(CONF_DROPDOWN_LIST):
|
66
|
+
with LocalVariable(
|
67
|
+
"dropdown_list", lv_obj_t, lv_expr.dropdown_get_list(w.obj)
|
68
|
+
) as dlist_obj:
|
69
|
+
dwid = Widget(dlist_obj, dropdown_list_spec, dlist)
|
70
|
+
await set_obj_properties(dwid, dlist)
|
71
|
+
|
72
|
+
def get_uses(self):
|
73
|
+
return (CONF_LABEL,)
|
74
|
+
|
75
|
+
|
76
|
+
dropdown_spec = DropdownType()
|
@@ -0,0 +1,85 @@
|
|
1
|
+
import esphome.config_validation as cv
|
2
|
+
from esphome.const import CONF_ANGLE, CONF_MODE
|
3
|
+
|
4
|
+
from ..defines import (
|
5
|
+
CONF_ANTIALIAS,
|
6
|
+
CONF_MAIN,
|
7
|
+
CONF_OFFSET_X,
|
8
|
+
CONF_OFFSET_Y,
|
9
|
+
CONF_PIVOT_X,
|
10
|
+
CONF_PIVOT_Y,
|
11
|
+
CONF_SRC,
|
12
|
+
CONF_ZOOM,
|
13
|
+
LvConstant,
|
14
|
+
)
|
15
|
+
from ..lv_validation import angle, lv_bool, lv_image, size, zoom
|
16
|
+
from ..lvcode import lv
|
17
|
+
from ..types import lv_img_t
|
18
|
+
from . import Widget, WidgetType
|
19
|
+
from .label import CONF_LABEL
|
20
|
+
|
21
|
+
CONF_IMAGE = "image"
|
22
|
+
|
23
|
+
BASE_IMG_SCHEMA = cv.Schema(
|
24
|
+
{
|
25
|
+
cv.Optional(CONF_PIVOT_X, default="50%"): size,
|
26
|
+
cv.Optional(CONF_PIVOT_Y, default="50%"): size,
|
27
|
+
cv.Optional(CONF_ANGLE): angle,
|
28
|
+
cv.Optional(CONF_ZOOM): zoom,
|
29
|
+
cv.Optional(CONF_OFFSET_X): size,
|
30
|
+
cv.Optional(CONF_OFFSET_Y): size,
|
31
|
+
cv.Optional(CONF_ANTIALIAS): lv_bool,
|
32
|
+
cv.Optional(CONF_MODE): LvConstant(
|
33
|
+
"LV_IMG_SIZE_MODE_", "VIRTUAL", "REAL"
|
34
|
+
).one_of,
|
35
|
+
}
|
36
|
+
)
|
37
|
+
|
38
|
+
IMG_SCHEMA = BASE_IMG_SCHEMA.extend(
|
39
|
+
{
|
40
|
+
cv.Required(CONF_SRC): lv_image,
|
41
|
+
}
|
42
|
+
)
|
43
|
+
|
44
|
+
IMG_MODIFY_SCHEMA = BASE_IMG_SCHEMA.extend(
|
45
|
+
{
|
46
|
+
cv.Optional(CONF_SRC): lv_image,
|
47
|
+
}
|
48
|
+
)
|
49
|
+
|
50
|
+
|
51
|
+
class ImgType(WidgetType):
|
52
|
+
def __init__(self):
|
53
|
+
super().__init__(
|
54
|
+
CONF_IMAGE,
|
55
|
+
lv_img_t,
|
56
|
+
(CONF_MAIN,),
|
57
|
+
IMG_SCHEMA,
|
58
|
+
IMG_MODIFY_SCHEMA,
|
59
|
+
lv_name="img",
|
60
|
+
)
|
61
|
+
|
62
|
+
def get_uses(self):
|
63
|
+
return "img", CONF_LABEL
|
64
|
+
|
65
|
+
async def to_code(self, w: Widget, config):
|
66
|
+
if src := config.get(CONF_SRC):
|
67
|
+
lv.img_set_src(w.obj, await lv_image.process(src))
|
68
|
+
if (cf_angle := config.get(CONF_ANGLE)) is not None:
|
69
|
+
pivot_x = config[CONF_PIVOT_X]
|
70
|
+
pivot_y = config[CONF_PIVOT_Y]
|
71
|
+
lv.img_set_pivot(w.obj, pivot_x, pivot_y)
|
72
|
+
lv.img_set_angle(w.obj, cf_angle)
|
73
|
+
if (img_zoom := config.get(CONF_ZOOM)) is not None:
|
74
|
+
lv.img_set_zoom(w.obj, img_zoom)
|
75
|
+
if (offset := config.get(CONF_OFFSET_X)) is not None:
|
76
|
+
lv.img_set_offset_x(w.obj, offset)
|
77
|
+
if (offset := config.get(CONF_OFFSET_Y)) is not None:
|
78
|
+
lv.img_set_offset_y(w.obj, offset)
|
79
|
+
if CONF_ANTIALIAS in config:
|
80
|
+
lv.img_set_antialias(w.obj, config[CONF_ANTIALIAS])
|
81
|
+
if mode := config.get(CONF_MODE):
|
82
|
+
lv.img_set_mode(w.obj, mode)
|
83
|
+
|
84
|
+
|
85
|
+
img_spec = ImgType()
|
@@ -0,0 +1,49 @@
|
|
1
|
+
from esphome.components.key_provider import KeyProvider
|
2
|
+
import esphome.config_validation as cv
|
3
|
+
from esphome.const import CONF_ITEMS, CONF_MODE
|
4
|
+
from esphome.cpp_types import std_string
|
5
|
+
|
6
|
+
from ..defines import CONF_MAIN, KEYBOARD_MODES, literal
|
7
|
+
from ..helpers import add_lv_use, lvgl_components_required
|
8
|
+
from ..types import LvCompound, LvType
|
9
|
+
from . import Widget, WidgetType, get_widgets
|
10
|
+
from .textarea import CONF_TEXTAREA, lv_textarea_t
|
11
|
+
|
12
|
+
CONF_KEYBOARD = "keyboard"
|
13
|
+
|
14
|
+
KEYBOARD_SCHEMA = {
|
15
|
+
cv.Optional(CONF_MODE, default="TEXT_UPPER"): KEYBOARD_MODES.one_of,
|
16
|
+
cv.Optional(CONF_TEXTAREA): cv.use_id(lv_textarea_t),
|
17
|
+
}
|
18
|
+
|
19
|
+
lv_keyboard_t = LvType(
|
20
|
+
"LvKeyboardType",
|
21
|
+
parents=(KeyProvider, LvCompound),
|
22
|
+
largs=[(std_string, "text")],
|
23
|
+
has_on_value=True,
|
24
|
+
lvalue=lambda w: literal(f"lv_textarea_get_text({w.obj})"),
|
25
|
+
)
|
26
|
+
|
27
|
+
|
28
|
+
class KeyboardType(WidgetType):
|
29
|
+
def __init__(self):
|
30
|
+
super().__init__(
|
31
|
+
CONF_KEYBOARD,
|
32
|
+
lv_keyboard_t,
|
33
|
+
(CONF_MAIN, CONF_ITEMS),
|
34
|
+
KEYBOARD_SCHEMA,
|
35
|
+
)
|
36
|
+
|
37
|
+
def get_uses(self):
|
38
|
+
return CONF_KEYBOARD, CONF_TEXTAREA
|
39
|
+
|
40
|
+
async def to_code(self, w: Widget, config: dict):
|
41
|
+
lvgl_components_required.add("KEY_LISTENER")
|
42
|
+
lvgl_components_required.add(CONF_KEYBOARD)
|
43
|
+
add_lv_use("btnmatrix")
|
44
|
+
await w.set_property(CONF_MODE, await KEYBOARD_MODES.process(config[CONF_MODE]))
|
45
|
+
if ta := await get_widgets(config, CONF_TEXTAREA):
|
46
|
+
await w.set_property(CONF_TEXTAREA, ta[0].obj)
|
47
|
+
|
48
|
+
|
49
|
+
keyboard_spec = KeyboardType()
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import esphome.config_validation as cv
|
2
|
+
from esphome.const import CONF_TEXT
|
3
|
+
|
4
|
+
from ..defines import (
|
5
|
+
CONF_LONG_MODE,
|
6
|
+
CONF_MAIN,
|
7
|
+
CONF_RECOLOR,
|
8
|
+
CONF_SCROLLBAR,
|
9
|
+
CONF_SELECTED,
|
10
|
+
LV_LONG_MODES,
|
11
|
+
)
|
12
|
+
from ..lv_validation import lv_bool, lv_text
|
13
|
+
from ..schemas import TEXT_SCHEMA
|
14
|
+
from ..types import LvText, WidgetType
|
15
|
+
from . import Widget
|
16
|
+
|
17
|
+
CONF_LABEL = "label"
|
18
|
+
|
19
|
+
|
20
|
+
class LabelType(WidgetType):
|
21
|
+
def __init__(self):
|
22
|
+
super().__init__(
|
23
|
+
CONF_LABEL,
|
24
|
+
LvText("lv_label_t"),
|
25
|
+
(CONF_MAIN, CONF_SCROLLBAR, CONF_SELECTED),
|
26
|
+
TEXT_SCHEMA.extend(
|
27
|
+
{
|
28
|
+
cv.Optional(CONF_RECOLOR): lv_bool,
|
29
|
+
cv.Optional(CONF_LONG_MODE): LV_LONG_MODES.one_of,
|
30
|
+
}
|
31
|
+
),
|
32
|
+
)
|
33
|
+
|
34
|
+
async def to_code(self, w: Widget, config):
|
35
|
+
"""For a text object, create and set text"""
|
36
|
+
if value := config.get(CONF_TEXT):
|
37
|
+
await w.set_property(CONF_TEXT, await lv_text.process(value))
|
38
|
+
await w.set_property(CONF_LONG_MODE, config)
|
39
|
+
await w.set_property(CONF_RECOLOR, config)
|
40
|
+
|
41
|
+
|
42
|
+
label_spec = LabelType()
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import esphome.config_validation as cv
|
2
|
+
from esphome.const import CONF_BRIGHTNESS, CONF_COLOR, CONF_LED
|
3
|
+
|
4
|
+
from ..defines import CONF_MAIN
|
5
|
+
from ..lv_validation import lv_brightness, lv_color
|
6
|
+
from ..lvcode import lv
|
7
|
+
from ..types import LvType
|
8
|
+
from . import Widget, WidgetType
|
9
|
+
|
10
|
+
LED_SCHEMA = cv.Schema(
|
11
|
+
{
|
12
|
+
cv.Optional(CONF_COLOR): lv_color,
|
13
|
+
cv.Optional(CONF_BRIGHTNESS): lv_brightness,
|
14
|
+
}
|
15
|
+
)
|
16
|
+
|
17
|
+
|
18
|
+
class LedType(WidgetType):
|
19
|
+
def __init__(self):
|
20
|
+
super().__init__(CONF_LED, LvType("lv_led_t"), (CONF_MAIN,), LED_SCHEMA)
|
21
|
+
|
22
|
+
async def to_code(self, w: Widget, config):
|
23
|
+
if (color := config.get(CONF_COLOR)) is not None:
|
24
|
+
lv.led_set_color(w.obj, await lv_color.process(color))
|
25
|
+
if (brightness := config.get(CONF_BRIGHTNESS)) is not None:
|
26
|
+
lv.led_set_brightness(w.obj, await lv_brightness.process(brightness))
|
27
|
+
|
28
|
+
|
29
|
+
led_spec = LedType()
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import functools
|
2
|
+
|
3
|
+
import esphome.codegen as cg
|
4
|
+
import esphome.config_validation as cv
|
5
|
+
|
6
|
+
from ..defines import CONF_MAIN, literal
|
7
|
+
from ..lvcode import lv
|
8
|
+
from ..types import LvType
|
9
|
+
from . import Widget, WidgetType
|
10
|
+
|
11
|
+
CONF_LINE = "line"
|
12
|
+
CONF_POINTS = "points"
|
13
|
+
CONF_POINT_LIST_ID = "point_list_id"
|
14
|
+
|
15
|
+
lv_point_t = cg.global_ns.struct("lv_point_t")
|
16
|
+
|
17
|
+
|
18
|
+
def point_list(il):
|
19
|
+
il = cv.string(il)
|
20
|
+
nl = il.replace(" ", "").split(",")
|
21
|
+
return [int(n) for n in nl]
|
22
|
+
|
23
|
+
|
24
|
+
def cv_point_list(value):
|
25
|
+
if not isinstance(value, list):
|
26
|
+
raise cv.Invalid("List of points required")
|
27
|
+
values = [point_list(v) for v in value]
|
28
|
+
if not functools.reduce(lambda f, v: f and len(v) == 2, values, True):
|
29
|
+
raise cv.Invalid("Points must be a list of x,y integer pairs")
|
30
|
+
return values
|
31
|
+
|
32
|
+
|
33
|
+
LINE_SCHEMA = {
|
34
|
+
cv.Required(CONF_POINTS): cv_point_list,
|
35
|
+
cv.GenerateID(CONF_POINT_LIST_ID): cv.declare_id(lv_point_t),
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
class LineType(WidgetType):
|
40
|
+
def __init__(self):
|
41
|
+
super().__init__(CONF_LINE, LvType("lv_line_t"), (CONF_MAIN,), LINE_SCHEMA)
|
42
|
+
|
43
|
+
async def to_code(self, w: Widget, config):
|
44
|
+
"""For a line object, create and add the points"""
|
45
|
+
data = literal(config[CONF_POINTS])
|
46
|
+
points = cg.static_const_array(config[CONF_POINT_LIST_ID], data)
|
47
|
+
lv.line_set_points(w.obj, points, len(data))
|
48
|
+
|
49
|
+
|
50
|
+
line_spec = LineType()
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import esphome.config_validation as cv
|
2
|
+
from esphome.const import CONF_MAX_VALUE, CONF_MIN_VALUE, CONF_MODE, CONF_VALUE
|
3
|
+
|
4
|
+
from ..defines import BAR_MODES, CONF_ANIMATED, CONF_INDICATOR, CONF_MAIN, literal
|
5
|
+
from ..lv_validation import animated, get_start_value, lv_float
|
6
|
+
from ..lvcode import lv
|
7
|
+
from ..types import LvNumber, NumberType
|
8
|
+
from . import Widget
|
9
|
+
|
10
|
+
# Note this file cannot be called "bar.py" because that name is disallowed.
|
11
|
+
|
12
|
+
CONF_BAR = "bar"
|
13
|
+
BAR_MODIFY_SCHEMA = cv.Schema(
|
14
|
+
{
|
15
|
+
cv.Optional(CONF_VALUE): lv_float,
|
16
|
+
cv.Optional(CONF_ANIMATED, default=True): animated,
|
17
|
+
}
|
18
|
+
)
|
19
|
+
|
20
|
+
BAR_SCHEMA = cv.Schema(
|
21
|
+
{
|
22
|
+
cv.Optional(CONF_VALUE): lv_float,
|
23
|
+
cv.Optional(CONF_MIN_VALUE, default=0): cv.int_,
|
24
|
+
cv.Optional(CONF_MAX_VALUE, default=100): cv.int_,
|
25
|
+
cv.Optional(CONF_MODE, default="NORMAL"): BAR_MODES.one_of,
|
26
|
+
cv.Optional(CONF_ANIMATED, default=True): animated,
|
27
|
+
}
|
28
|
+
)
|
29
|
+
|
30
|
+
|
31
|
+
class BarType(NumberType):
|
32
|
+
def __init__(self):
|
33
|
+
super().__init__(
|
34
|
+
CONF_BAR,
|
35
|
+
LvNumber("lv_bar_t"),
|
36
|
+
parts=(CONF_MAIN, CONF_INDICATOR),
|
37
|
+
schema=BAR_SCHEMA,
|
38
|
+
modify_schema=BAR_MODIFY_SCHEMA,
|
39
|
+
)
|
40
|
+
|
41
|
+
async def to_code(self, w: Widget, config):
|
42
|
+
var = w.obj
|
43
|
+
if CONF_MIN_VALUE in config:
|
44
|
+
lv.bar_set_range(var, config[CONF_MIN_VALUE], config[CONF_MAX_VALUE])
|
45
|
+
lv.bar_set_mode(var, literal(config[CONF_MODE]))
|
46
|
+
value = await get_start_value(config)
|
47
|
+
if value is not None:
|
48
|
+
lv.bar_set_value(var, value, literal(config[CONF_ANIMATED]))
|
49
|
+
|
50
|
+
@property
|
51
|
+
def animated(self):
|
52
|
+
return True
|
53
|
+
|
54
|
+
|
55
|
+
bar_spec = BarType()
|