esphome 2025.3.2__py3-none-any.whl → 2025.4.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 +34 -10
- esphome/components/a01nyub/sensor.py +2 -2
- esphome/components/a02yyuw/sensor.py +2 -2
- esphome/components/a4988/stepper.py +1 -2
- esphome/components/absolute_humidity/sensor.py +3 -3
- esphome/components/ac_dimmer/output.py +3 -3
- esphome/components/adalight/__init__.py +2 -2
- esphome/components/adc128s102/__init__.py +1 -1
- esphome/components/adc128s102/sensor/__init__.py +3 -3
- esphome/components/addressable_light/display.py +5 -5
- esphome/components/ade7880/sensor.py +2 -2
- esphome/components/ade7953_base/__init__.py +10 -10
- esphome/components/ade7953_i2c/sensor.py +1 -2
- esphome/components/ade7953_spi/sensor.py +1 -2
- esphome/components/ads1115/__init__.py +1 -1
- esphome/components/ads1115/sensor/__init__.py +4 -3
- esphome/components/ads1118/__init__.py +1 -1
- esphome/components/ads1118/sensor/__init__.py +5 -4
- esphome/components/ags10/sensor.py +9 -9
- esphome/components/aht10/sensor.py +2 -2
- esphome/components/airthings_ble/__init__.py +1 -1
- esphome/components/airthings_wave_base/__init__.py +2 -3
- esphome/components/airthings_wave_mini/sensor.py +2 -5
- esphome/components/airthings_wave_plus/sensor.py +8 -9
- esphome/components/alpha3/sensor.py +5 -5
- esphome/components/am2315c/am2315c.cpp +4 -4
- esphome/components/am2315c/sensor.py +1 -1
- esphome/components/am2320/sensor.py +1 -1
- esphome/components/am43/cover/__init__.py +1 -1
- esphome/components/am43/sensor/__init__.py +3 -3
- esphome/components/analog_threshold/binary_sensor.py +2 -5
- esphome/components/anova/climate.py +1 -1
- esphome/components/apds9306/sensor.py +1 -1
- esphome/components/apds9960/__init__.py +1 -1
- esphome/components/apds9960/binary_sensor.py +2 -1
- esphome/components/apds9960/sensor.py +3 -2
- esphome/components/api/api_frame_helper.cpp +25 -1
- esphome/components/as3935/__init__.py +3 -3
- esphome/components/as3935/binary_sensor.py +2 -1
- esphome/components/as3935/sensor.py +4 -3
- esphome/components/as3935_i2c/__init__.py +1 -1
- esphome/components/as3935_spi/__init__.py +1 -1
- esphome/components/as5600/__init__.py +2 -2
- esphome/components/as5600/sensor/__init__.py +10 -9
- esphome/components/as7341/sensor.py +1 -2
- esphome/components/at581x/__init__.py +4 -8
- esphome/components/at581x/switch/__init__.py +2 -4
- esphome/components/atc_mithermometer/sensor.py +3 -3
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +7 -3
- esphome/components/b_parasite/sensor.py +2 -2
- esphome/components/ballu/climate.py +1 -1
- esphome/components/bang_bang/climate.py +2 -2
- esphome/components/bedjet/__init__.py +2 -6
- esphome/components/bedjet/climate/__init__.py +3 -6
- esphome/components/bedjet/fan/__init__.py +4 -9
- esphome/components/bedjet/sensor/__init__.py +3 -6
- esphome/components/beken_spi_led_strip/light.py +2 -2
- esphome/components/bh1750/sensor.py +2 -6
- esphome/components/binary/fan/__init__.py +2 -1
- esphome/components/binary/light/__init__.py +3 -2
- esphome/components/binary_sensor_map/sensor.py +5 -6
- esphome/components/bl0939/sensor.py +1 -1
- esphome/components/bl0940/sensor.py +3 -3
- esphome/components/ble_client/__init__.py +3 -2
- esphome/components/ble_client/sensor/__init__.py +1 -1
- esphome/components/ble_client/text_sensor/__init__.py +1 -1
- esphome/components/bluetooth_proxy/__init__.py +35 -23
- esphome/components/bme280_base/__init__.py +1 -1
- esphome/components/bme280_i2c/sensor.py +3 -2
- esphome/components/bme280_spi/sensor.py +3 -2
- esphome/components/bme680/sensor.py +4 -4
- esphome/components/bme680_bsec/__init__.py +1 -1
- esphome/components/bme680_bsec/sensor.py +3 -6
- esphome/components/bme680_bsec/text_sensor.py +3 -2
- esphome/components/bmi160/sensor.py +6 -6
- esphome/components/bmp085/sensor.py +1 -1
- esphome/components/bmp280_base/__init__.py +1 -1
- esphome/components/bmp280_i2c/sensor.py +3 -2
- esphome/components/bmp280_spi/sensor.py +3 -2
- esphome/components/bmp3xx_base/__init__.py +1 -1
- esphome/components/bmp3xx_i2c/sensor.py +2 -1
- esphome/components/bmp3xx_spi/sensor.py +2 -1
- esphome/components/bmp581/sensor.py +2 -1
- esphome/components/bp1658cj/__init__.py +2 -6
- esphome/components/bp1658cj/output.py +2 -1
- esphome/components/bp5758d/__init__.py +2 -6
- esphome/components/bp5758d/output.py +3 -2
- esphome/components/canbus/__init__.py +13 -2
- esphome/components/canbus/canbus.cpp +7 -1
- esphome/components/cap1188/__init__.py +2 -2
- esphome/components/cap1188/binary_sensor.py +3 -2
- esphome/components/captive_portal/__init__.py +3 -3
- esphome/components/ccs811/sensor.py +10 -10
- esphome/components/cd74hc4067/__init__.py +2 -5
- esphome/components/cd74hc4067/sensor.py +6 -5
- esphome/components/climate_ir/__init__.py +2 -2
- esphome/components/climate_ir_lg/climate.py +1 -1
- esphome/components/color/__init__.py +1 -2
- esphome/components/color_temperature/light.py +2 -2
- esphome/components/combination/sensor.py +1 -1
- esphome/components/coolix/climate.py +1 -1
- esphome/components/copy/binary_sensor/__init__.py +1 -1
- esphome/components/copy/button/__init__.py +1 -1
- esphome/components/copy/cover/__init__.py +1 -1
- esphome/components/copy/fan/__init__.py +2 -7
- esphome/components/copy/lock/__init__.py +2 -7
- esphome/components/copy/number/__init__.py +1 -1
- esphome/components/copy/select/__init__.py +2 -7
- esphome/components/copy/sensor/__init__.py +2 -2
- esphome/components/copy/switch/__init__.py +1 -1
- esphome/components/copy/text/__init__.py +2 -7
- esphome/components/copy/text_sensor/__init__.py +2 -6
- esphome/components/cs5460a/sensor.py +7 -7
- esphome/components/cse7761/sensor.py +2 -2
- esphome/components/cse7766/sensor.py +1 -1
- esphome/components/cst226/touchscreen/__init__.py +3 -4
- esphome/components/ct_clamp/sensor.py +1 -1
- esphome/components/current_based/cover.py +3 -4
- esphome/components/cwww/light.py +3 -3
- esphome/components/dac7678/__init__.py +1 -1
- esphome/components/dac7678/output.py +2 -1
- esphome/components/daikin/climate.py +1 -1
- esphome/components/daikin_arc/climate.py +1 -1
- esphome/components/daikin_brc/climate.py +1 -1
- esphome/components/dallas_temp/sensor.py +1 -1
- esphome/components/daly_bms/__init__.py +2 -2
- esphome/components/daly_bms/binary_sensor.py +3 -2
- esphome/components/daly_bms/sensor.py +14 -13
- esphome/components/daly_bms/text_sensor.py +3 -2
- esphome/components/dashboard_import/__init__.py +5 -5
- esphome/components/debug/sensor.py +7 -6
- esphome/components/debug/text_sensor.py +1 -1
- esphome/components/deep_sleep/__init__.py +12 -13
- esphome/components/delonghi/climate.py +1 -1
- esphome/components/demo/__init__.py +1 -1
- esphome/components/dfplayer/__init__.py +3 -3
- esphome/components/dfrobot_sen0395/__init__.py +3 -3
- esphome/components/dfrobot_sen0395/binary_sensor.py +2 -1
- esphome/components/dfrobot_sen0395/switch/__init__.py +2 -3
- esphome/components/dht/sensor.py +4 -5
- esphome/components/dht12/sensor.py +3 -3
- esphome/components/display/display.cpp +2 -2
- esphome/components/dps310/sensor.py +3 -3
- esphome/components/ds1307/time.py +2 -3
- esphome/components/dsmr/__init__.py +3 -7
- esphome/components/dsmr/sensor.py +5 -4
- esphome/components/dsmr/text_sensor.py +3 -2
- esphome/components/duty_cycle/sensor.py +3 -8
- esphome/components/duty_time/sensor.py +7 -7
- esphome/components/e131/__init__.py +3 -3
- esphome/components/ee895/sensor.py +5 -5
- esphome/components/ektf2232/touchscreen/__init__.py +2 -3
- esphome/components/emc2101/__init__.py +1 -1
- esphome/components/emc2101/output/__init__.py +3 -2
- esphome/components/emc2101/sensor/__init__.py +4 -3
- esphome/components/emmeti/climate.py +1 -1
- esphome/components/endstop/cover.py +3 -3
- esphome/components/ens160_base/__init__.py +1 -1
- esphome/components/ens160_i2c/sensor.py +2 -1
- esphome/components/ens160_spi/sensor.py +2 -1
- esphome/components/ens210/sensor.py +1 -1
- esphome/components/esp32/__init__.py +10 -0
- esphome/components/esp32_ble_tracker/__init__.py +135 -51
- esphome/components/esp32_camera/__init__.py +7 -8
- esphome/components/esp32_camera_web_server/__init__.py +2 -2
- esphome/components/esp32_can/canbus.py +21 -0
- esphome/components/esp32_can/esp32_can.cpp +1 -1
- esphome/components/esp32_can/esp32_can.h +4 -0
- esphome/components/esp32_dac/output.py +2 -2
- esphome/components/esp32_hall/sensor.py +2 -6
- esphome/components/esp32_touch/__init__.py +7 -7
- esphome/components/esp32_touch/binary_sensor.py +4 -7
- esphome/components/esp8266_pwm/output.py +3 -8
- esphome/components/ethernet/__init__.py +1 -0
- esphome/components/ethernet/ethernet_component.cpp +1 -1
- esphome/components/ethernet_info/ethernet_info_text_sensor.h +1 -0
- esphome/components/exposure_notifications/__init__.py +2 -2
- esphome/components/external_components/__init__.py +1 -1
- esphome/components/ezo/sensor.py +2 -2
- esphome/components/ezo_pmp/__init__.py +4 -4
- esphome/components/ezo_pmp/binary_sensor.py +4 -4
- esphome/components/ezo_pmp/sensor.py +4 -5
- esphome/components/ezo_pmp/text_sensor.py +2 -6
- esphome/components/factory_reset/button/__init__.py +2 -1
- esphome/components/factory_reset/switch/__init__.py +3 -2
- esphome/components/fastled_base/__init__.py +3 -3
- esphome/components/fastled_clockless/light.py +2 -2
- esphome/components/fastled_spi/light.py +2 -2
- esphome/components/feedback/cover.py +3 -3
- esphome/components/fingerprint_grow/__init__.py +5 -6
- esphome/components/fingerprint_grow/binary_sensor.py +2 -1
- esphome/components/fingerprint_grow/sensor.py +2 -1
- esphome/components/fs3000/sensor.py +2 -6
- esphome/components/ft5x06/touchscreen/__init__.py +2 -2
- esphome/components/ft63x6/touchscreen.py +2 -3
- esphome/components/fujitsu_general/climate.py +1 -1
- esphome/components/gcja5/sensor.py +4 -4
- esphome/components/gdk101/__init__.py +1 -1
- esphome/components/gdk101/binary_sensor.py +2 -1
- esphome/components/gdk101/sensor.py +5 -4
- esphome/components/globals/__init__.py +1 -2
- esphome/components/gp2y1010au0f/sensor.py +3 -3
- esphome/components/gp8403/__init__.py +1 -2
- esphome/components/gp8403/output/__init__.py +3 -4
- esphome/components/gpio/binary_sensor/__init__.py +3 -2
- esphome/components/gpio/one_wire/__init__.py +3 -2
- esphome/components/gpio/output/__init__.py +3 -2
- esphome/components/gpio/switch/__init__.py +3 -2
- esphome/components/gps/__init__.py +4 -5
- esphome/components/gps/time/__init__.py +3 -2
- esphome/components/graph/__init__.py +12 -12
- esphome/components/grove_tb6612fng/__init__.py +5 -6
- esphome/components/growatt_solar/sensor.py +1 -1
- esphome/components/gt911/binary_sensor/__init__.py +2 -2
- esphome/components/haier/binary_sensor/__init__.py +4 -10
- esphome/components/haier/button/__init__.py +3 -6
- esphome/components/haier/sensor/__init__.py +4 -6
- esphome/components/haier/switch/__init__.py +4 -7
- esphome/components/haier/text_sensor/__init__.py +4 -9
- esphome/components/havells_solar/sensor.py +1 -1
- esphome/components/hbridge/fan/__init__.py +6 -6
- esphome/components/hbridge/light/__init__.py +2 -1
- esphome/components/hdc1080/sensor.py +1 -1
- esphome/components/he60r/cover.py +2 -6
- esphome/components/heatpumpir/climate.py +1 -1
- esphome/components/hitachi_ac344/climate.py +1 -1
- esphome/components/hitachi_ac424/climate.py +1 -1
- esphome/components/hlw8012/sensor.py +6 -6
- esphome/components/hm3301/sensor.py +3 -3
- esphome/components/hmc5883l/sensor.py +4 -4
- esphome/components/homeassistant/time/__init__.py +2 -1
- esphome/components/honeywell_hih_i2c/sensor.py +3 -3
- esphome/components/honeywellabp/sensor.py +1 -2
- esphome/components/honeywellabp2_i2c/sensor.py +1 -2
- esphome/components/host/time/__init__.py +2 -2
- esphome/components/hrxl_maxsonar_wr/sensor.py +1 -1
- esphome/components/hte501/sensor.py +3 -3
- esphome/components/http_request/ota/__init__.py +5 -9
- esphome/components/http_request/update/__init__.py +3 -7
- esphome/components/htu21d/sensor.py +6 -6
- esphome/components/htu31d/sensor.py +1 -1
- esphome/components/hx711/sensor.py +3 -8
- esphome/components/hydreon_rgxx/binary_sensor.py +3 -7
- esphome/components/hydreon_rgxx/sensor.py +4 -4
- esphome/components/hyt271/sensor.py +1 -1
- esphome/components/i2c_device/__init__.py +1 -1
- esphome/components/i2s_audio/media_player/__init__.py +6 -8
- esphome/components/iaqcore/sensor.py +2 -2
- esphome/components/ina219/sensor.py +2 -2
- esphome/components/ina226/sensor.py +4 -4
- esphome/components/ina260/sensor.py +4 -4
- esphome/components/ina2xx_base/__init__.py +2 -2
- esphome/components/ina2xx_i2c/sensor.py +1 -1
- esphome/components/ina2xx_spi/sensor.py +1 -1
- esphome/components/ina3221/sensor.py +3 -3
- esphome/components/inkbird_ibsth1_mini/sensor.py +2 -2
- esphome/components/inkplate6/display.py +2 -2
- esphome/components/integration/sensor.py +4 -4
- esphome/components/internal_temperature/sensor.py +5 -7
- esphome/components/interval/__init__.py +1 -1
- esphome/components/jsn_sr04t/sensor.py +3 -3
- esphome/components/kamstrup_kmp/sensor.py +1 -1
- esphome/components/key_collector/__init__.py +2 -2
- esphome/components/kmeteriso/sensor.py +2 -2
- esphome/components/kuntze/sensor.py +5 -5
- esphome/components/lcd_base/__init__.py +2 -2
- esphome/components/lcd_gpio/display.py +4 -4
- esphome/components/lcd_menu/__init__.py +3 -7
- esphome/components/lcd_pcf8574/display.py +1 -1
- esphome/components/ld2410/__init__.py +4 -4
- esphome/components/ld2410/binary_sensor.py +5 -4
- esphome/components/ld2410/button/__init__.py +3 -2
- esphome/components/ld2410/number/__init__.py +5 -4
- esphome/components/ld2410/select/__init__.py +4 -3
- esphome/components/ld2410/sensor.py +6 -5
- esphome/components/ld2410/switch/__init__.py +2 -1
- esphome/components/ld2410/text_sensor.py +3 -2
- esphome/components/ld2420/__init__.py +1 -1
- esphome/components/ld2420/binary_sensor/__init__.py +4 -3
- esphome/components/ld2420/button/__init__.py +3 -2
- esphome/components/ld2420/number/__init__.py +3 -2
- esphome/components/ld2420/select/__init__.py +1 -0
- esphome/components/ld2420/sensor/__init__.py +3 -2
- esphome/components/ld2420/text_sensor/__init__.py +2 -6
- esphome/components/ld2450/__init__.py +2 -5
- esphome/components/ledc/output.py +3 -3
- esphome/components/libretiny/text_sensor.py +1 -1
- esphome/components/libretiny_pwm/output.py +3 -7
- esphome/components/lightwaverf/__init__.py +6 -8
- esphome/components/lilygo_t5_47/touchscreen/__init__.py +2 -3
- esphome/components/ltr390/sensor.py +1 -1
- esphome/components/ltr501/sensor.py +2 -2
- esphome/components/ltr_als_ps/sensor.py +2 -2
- esphome/components/lvgl/__init__.py +9 -12
- esphome/components/lvgl/automation.py +15 -3
- esphome/components/lvgl/defines.py +5 -2
- esphome/components/lvgl/encoders.py +3 -2
- esphome/components/lvgl/lv_validation.py +17 -9
- esphome/components/lvgl/lvcode.py +11 -9
- esphome/components/lvgl/lvgl_esphome.h +21 -0
- esphome/components/lvgl/number/__init__.py +23 -20
- esphome/components/lvgl/number/lvgl_number.h +27 -14
- esphome/components/lvgl/schemas.py +70 -19
- esphome/components/lvgl/select/__init__.py +11 -13
- esphome/components/lvgl/select/lvgl_select.h +25 -18
- esphome/components/lvgl/styles.py +42 -11
- esphome/components/lvgl/switch/__init__.py +13 -8
- esphome/components/lvgl/switch/lvgl_switch.h +5 -16
- esphome/components/lvgl/trigger.py +10 -1
- esphome/components/lvgl/widgets/__init__.py +1 -2
- esphome/components/lvgl/widgets/buttonmatrix.py +2 -2
- esphome/components/lvgl/widgets/canvas.py +407 -0
- esphome/components/lvgl/widgets/line.py +22 -32
- esphome/components/lvgl/widgets/meter.py +3 -1
- esphome/components/m5stack_8angle/__init__.py +1 -2
- esphome/components/m5stack_8angle/binary_sensor/__init__.py +2 -3
- esphome/components/m5stack_8angle/light/__init__.py +2 -4
- esphome/components/m5stack_8angle/sensor/__init__.py +2 -4
- esphome/components/matrix_keypad/binary_sensor/__init__.py +4 -3
- esphome/components/max31855/sensor.py +1 -1
- esphome/components/max31865/sensor.py +1 -1
- esphome/components/max44009/sensor.py +1 -1
- esphome/components/max6675/sensor.py +1 -1
- esphome/components/max6956/__init__.py +5 -5
- esphome/components/max6956/output/__init__.py +4 -3
- esphome/components/max7219/display.py +1 -1
- esphome/components/max7219digit/display.py +1 -1
- esphome/components/max9611/sensor.py +10 -10
- esphome/components/mcp23008/__init__.py +1 -1
- esphome/components/mcp23016/__init__.py +4 -4
- esphome/components/mcp23017/__init__.py +1 -1
- esphome/components/mcp23s08/__init__.py +1 -1
- esphome/components/mcp23s17/__init__.py +1 -1
- esphome/components/mcp23xxx_base/__init__.py +4 -4
- esphome/components/mcp2515/canbus.py +2 -2
- esphome/components/mcp3008/__init__.py +1 -1
- esphome/components/mcp3008/sensor/__init__.py +4 -4
- esphome/components/mcp3204/__init__.py +1 -1
- esphome/components/mcp3204/sensor/__init__.py +3 -2
- esphome/components/mcp4461/__init__.py +42 -0
- esphome/components/mcp4461/mcp4461.cpp +618 -0
- esphome/components/mcp4461/mcp4461.h +171 -0
- esphome/components/mcp4461/output/__init__.py +60 -0
- esphome/components/mcp4461/output/mcp4461_output.cpp +73 -0
- esphome/components/mcp4461/output/mcp4461_output.h +49 -0
- esphome/components/mcp4725/output.py +2 -2
- esphome/components/mcp4728/__init__.py +1 -1
- esphome/components/mcp4728/output/__init__.py +4 -3
- esphome/components/mcp47a1/output.py +2 -2
- esphome/components/mcp9808/sensor.py +1 -1
- esphome/components/mdns/__init__.py +1 -1
- esphome/components/mhz19/sensor.py +4 -4
- esphome/components/micronova/__init__.py +3 -5
- esphome/components/micronova/button/__init__.py +5 -5
- esphome/components/micronova/number/__init__.py +6 -10
- esphome/components/micronova/sensor/__init__.py +6 -6
- esphome/components/micronova/switch/__init__.py +6 -8
- esphome/components/micronova/text_sensor/__init__.py +5 -5
- esphome/components/microphone/__init__.py +2 -4
- esphome/components/midea/climate.py +6 -10
- esphome/components/midea_ir/climate.py +1 -1
- esphome/components/mitsubishi/climate.py +1 -1
- esphome/components/mlx90614/sensor.py +1 -1
- esphome/components/mmc5603/sensor.py +4 -4
- esphome/components/mmc5983/sensor.py +1 -1
- esphome/components/modbus/__init__.py +5 -9
- esphome/components/modbus_controller/__init__.py +1 -1
- esphome/components/monochromatic/light.py +2 -2
- esphome/components/mopeka_ble/__init__.py +1 -1
- esphome/components/mopeka_pro_check/sensor.py +12 -12
- esphome/components/mopeka_std_check/sensor.py +8 -8
- esphome/components/mpl3115a2/sensor.py +1 -1
- esphome/components/mpr121/__init__.py +3 -3
- esphome/components/mpr121/binary_sensor/__init__.py +5 -4
- esphome/components/mpu6050/sensor.py +4 -4
- esphome/components/mpu6886/sensor.py +4 -4
- esphome/components/mqtt_subscribe/sensor/__init__.py +3 -5
- esphome/components/mqtt_subscribe/text_sensor/__init__.py +1 -1
- esphome/components/ms5611/sensor.py +2 -2
- esphome/components/ms8607/sensor.py +1 -1
- esphome/components/my9231/__init__.py +1 -1
- esphome/components/my9231/output.py +2 -1
- esphome/components/nau7802/nau7802.cpp +0 -4
- esphome/components/nau7802/nau7802.h +0 -2
- esphome/components/neopixelbus/_methods.py +11 -9
- esphome/components/neopixelbus/light.py +11 -18
- esphome/components/nextion/binary_sensor/__init__.py +6 -14
- esphome/components/nextion/sensor/__init__.py +7 -10
- esphome/components/nextion/switch/__init__.py +3 -5
- esphome/components/nextion/text_sensor/__init__.py +3 -7
- esphome/components/noblex/climate.py +1 -1
- esphome/components/ntc/sensor.py +1 -1
- esphome/components/opentherm/__init__.py +6 -6
- esphome/components/opentherm/input.py +2 -1
- esphome/components/opentherm/number/__init__.py +5 -4
- esphome/components/opentherm/output/__init__.py +3 -2
- esphome/components/opentherm/schema.py +7 -7
- esphome/components/opentherm/switch/__init__.py +3 -2
- esphome/components/opentherm/validate.py +1 -1
- esphome/components/output/__init__.py +2 -3
- esphome/components/output/button/__init__.py +3 -2
- esphome/components/output/lock/__init__.py +2 -1
- esphome/components/output/switch/__init__.py +2 -1
- esphome/components/partition/light.py +4 -4
- esphome/components/pca6416a/__init__.py +4 -4
- esphome/components/pca9554/__init__.py +4 -4
- esphome/components/pca9685/__init__.py +2 -2
- esphome/components/pca9685/output.py +2 -1
- esphome/components/pcf85063/time.py +2 -3
- esphome/components/pcf8563/time.py +2 -2
- esphome/components/pcf8574/__init__.py +4 -4
- esphome/components/pid/climate.py +2 -2
- esphome/components/pid/sensor/__init__.py +4 -8
- esphome/components/pipsolar/__init__.py +1 -1
- esphome/components/pipsolar/binary_sensor/__init__.py +2 -2
- esphome/components/pipsolar/output/__init__.py +4 -3
- esphome/components/pipsolar/sensor/__init__.py +5 -4
- esphome/components/pipsolar/switch/__init__.py +2 -1
- esphome/components/pipsolar/text_sensor/__init__.py +2 -1
- esphome/components/pm1006/sensor.py +2 -2
- esphome/components/pmsa003i/sensor.py +4 -4
- esphome/components/pmsx003/sensor.py +10 -11
- esphome/components/pmwcs3/sensor.py +5 -5
- esphome/components/pn532/__init__.py +3 -3
- esphome/components/pn532_i2c/__init__.py +1 -1
- esphome/components/pn532_spi/__init__.py +1 -1
- esphome/components/pn7150/__init__.py +2 -2
- esphome/components/pn7150_i2c/__init__.py +1 -1
- esphome/components/pn7160/__init__.py +2 -2
- esphome/components/pn7160_i2c/__init__.py +1 -1
- esphome/components/pn7160_spi/__init__.py +1 -1
- esphome/components/power_supply/__init__.py +1 -1
- esphome/components/prometheus/__init__.py +3 -8
- esphome/components/psram/__init__.py +75 -11
- esphome/components/psram/psram.cpp +18 -7
- esphome/components/pulse_counter/sensor.py +4 -4
- esphome/components/pulse_meter/sensor.py +3 -3
- esphome/components/pulse_width/sensor.py +3 -8
- esphome/components/pvvx_mithermometer/display/__init__.py +1 -1
- esphome/components/pvvx_mithermometer/sensor.py +3 -3
- esphome/components/pylontech/__init__.py +1 -0
- esphome/components/pylontech/sensor/__init__.py +8 -13
- esphome/components/pylontech/text_sensor/__init__.py +2 -7
- esphome/components/pzem004t/sensor.py +3 -3
- esphome/components/pzemac/sensor.py +9 -9
- esphome/components/pzemdc/sensor.py +6 -6
- esphome/components/qmc5883l/sensor.py +5 -5
- esphome/components/qmp6988/sensor.py +3 -3
- esphome/components/qr_code/__init__.py +1 -1
- esphome/components/qspi_dbi/display.py +1 -1
- esphome/components/qspi_dbi/qspi_dbi.cpp +1 -1
- esphome/components/qspi_dbi/qspi_dbi.h +1 -1
- esphome/components/qwiic_pir/binary_sensor.py +2 -5
- esphome/components/radon_eye_ble/__init__.py +1 -1
- esphome/components/radon_eye_rd200/sensor.py +3 -4
- esphome/components/rc522/__init__.py +3 -3
- esphome/components/rc522_i2c/__init__.py +1 -1
- esphome/components/rc522_spi/__init__.py +1 -1
- esphome/components/rdm6300/__init__.py +2 -2
- esphome/components/rdm6300/binary_sensor.py +2 -1
- esphome/components/resistance/sensor.py +2 -2
- esphome/components/restart/button/__init__.py +1 -1
- esphome/components/restart/switch/__init__.py +2 -5
- esphome/components/rf_bridge/__init__.py +3 -3
- esphome/components/rgb/light.py +2 -2
- esphome/components/rgbct/light.py +3 -3
- esphome/components/rgbw/light.py +2 -2
- esphome/components/rgbww/light.py +4 -4
- esphome/components/rotary_encoder/sensor.py +8 -8
- esphome/components/rp2040_pio/__init__.py +0 -1
- esphome/components/rp2040_pio_led_strip/light.py +2 -4
- esphome/components/rp2040_pwm/output.py +3 -7
- esphome/components/rtttl/__init__.py +6 -6
- esphome/components/ruuvi_ble/__init__.py +1 -1
- esphome/components/ruuvitag/sensor.py +15 -15
- esphome/components/safe_mode/__init__.py +2 -3
- esphome/components/safe_mode/button/__init__.py +3 -2
- esphome/components/safe_mode/switch/__init__.py +4 -7
- esphome/components/scd30/sensor.py +5 -6
- esphome/components/scd4x/sensor.py +6 -8
- esphome/components/script/__init__.py +2 -2
- esphome/components/sdl/display.py +3 -3
- esphome/components/sdl/touchscreen/__init__.py +2 -2
- esphome/components/sdm_meter/sensor.py +3 -3
- esphome/components/sdp3x/sensor.py +1 -2
- esphome/components/sds011/sensor.py +4 -4
- esphome/components/seeed_mr24hpc1/__init__.py +1 -1
- esphome/components/seeed_mr24hpc1/binary_sensor.py +2 -5
- esphome/components/seeed_mr24hpc1/button/__init__.py +1 -0
- esphome/components/seeed_mr24hpc1/number/__init__.py +2 -4
- esphome/components/seeed_mr24hpc1/select/__init__.py +2 -3
- esphome/components/seeed_mr24hpc1/sensor.py +1 -0
- esphome/components/seeed_mr24hpc1/switch/__init__.py +2 -4
- esphome/components/seeed_mr24hpc1/text_sensor.py +1 -0
- esphome/components/seeed_mr60bha2/binary_sensor.py +2 -4
- esphome/components/seeed_mr60bha2/sensor.py +1 -1
- esphome/components/seeed_mr60fda2/button/__init__.py +1 -1
- esphome/components/seeed_mr60fda2/select/__init__.py +0 -1
- esphome/components/selec_meter/sensor.py +1 -1
- esphome/components/sen0321/sensor.py +2 -2
- esphome/components/sen21231/sensor.py +1 -1
- esphome/components/senseair/sensor.py +3 -3
- esphome/components/sensirion_common/__init__.py +0 -2
- esphome/components/servo/__init__.py +3 -3
- esphome/components/sfa30/sensor.py +4 -5
- esphome/components/sgp4x/sensor.py +2 -2
- esphome/components/shelly_dimmer/light.py +16 -16
- esphome/components/sht3xd/sensor.py +1 -1
- esphome/components/sht4x/sensor.py +6 -6
- esphome/components/shtcx/sensor.py +1 -1
- esphome/components/shutdown/button/__init__.py +2 -6
- esphome/components/shutdown/switch/__init__.py +2 -5
- esphome/components/sigma_delta_output/output.py +2 -7
- esphome/components/sim800l/__init__.py +3 -7
- esphome/components/sim800l/binary_sensor.py +3 -5
- esphome/components/sim800l/sensor.py +2 -1
- esphome/components/slow_pwm/output.py +4 -5
- esphome/components/sm10bit_base/__init__.py +2 -6
- esphome/components/sm16716/__init__.py +1 -1
- esphome/components/sm16716/output.py +2 -1
- esphome/components/sm2135/__init__.py +2 -6
- esphome/components/sm2135/output.py +2 -1
- esphome/components/sm2235/__init__.py +1 -1
- esphome/components/sm2235/output.py +2 -1
- esphome/components/sm2335/__init__.py +1 -1
- esphome/components/sm2335/output.py +2 -1
- esphome/components/sm300d2/sensor.py +13 -13
- esphome/components/sml/__init__.py +1 -1
- esphome/components/sml/sensor/__init__.py +1 -1
- esphome/components/sml/sml.cpp +8 -6
- esphome/components/sml/sml.h +1 -1
- esphome/components/sml/sml_parser.cpp +16 -18
- esphome/components/sml/sml_parser.h +42 -12
- esphome/components/sml/text_sensor/__init__.py +1 -1
- esphome/components/smt100/sensor.py +5 -6
- esphome/components/sn74hc165/__init__.py +5 -5
- esphome/components/sn74hc595/__init__.py +5 -5
- esphome/components/socket/__init__.py +1 -1
- esphome/components/sonoff_d1/light.py +2 -6
- esphome/components/speaker/media_player/audio_pipeline.cpp +3 -2
- esphome/components/speaker/media_player/speaker_media_player.cpp +47 -12
- esphome/components/speed/fan/__init__.py +2 -2
- esphome/components/spi/__init__.py +45 -36
- esphome/components/spi/spi.h +1 -0
- esphome/components/spi/spi_esp_idf.cpp +13 -5
- esphome/components/sprinkler/__init__.py +4 -5
- esphome/components/sps30/sensor.py +8 -8
- esphome/components/ssd1306_i2c/display.py +2 -2
- esphome/components/ssd1322_base/__init__.py +2 -2
- esphome/components/ssd1325_base/__init__.py +2 -2
- esphome/components/ssd1327_base/__init__.py +2 -2
- esphome/components/ssd1327_i2c/display.py +1 -1
- esphome/components/ssd1331_base/__init__.py +2 -2
- esphome/components/ssd1351_base/__init__.py +2 -2
- esphome/components/st7567_base/__init__.py +4 -4
- esphome/components/st7567_i2c/display.py +1 -1
- esphome/components/st7920/display.py +2 -2
- esphome/components/statsd/__init__.py +3 -3
- esphome/components/status/binary_sensor.py +2 -5
- esphome/components/status_led/__init__.py +1 -1
- esphome/components/status_led/light/__init__.py +2 -1
- esphome/components/stepper/__init__.py +2 -2
- esphome/components/sts3x/sensor.py +1 -1
- esphome/components/substitutions/__init__.py +2 -2
- esphome/components/sun/__init__.py +4 -4
- esphome/components/sun/sensor/__init__.py +4 -7
- esphome/components/sun/text_sensor/__init__.py +5 -4
- esphome/components/sun_gtil2/__init__.py +1 -1
- esphome/components/sun_gtil2/sensor.py +7 -6
- esphome/components/sun_gtil2/text_sensor.py +3 -2
- esphome/components/sx1509/__init__.py +5 -5
- esphome/components/sx1509/binary_sensor/__init__.py +3 -3
- esphome/components/sx1509/output/__init__.py +4 -3
- esphome/components/t6615/sensor.py +1 -1
- esphome/components/tca9548a/__init__.py +1 -1
- esphome/components/tcl112/climate.py +1 -1
- esphome/components/tcs34725/sensor.py +4 -4
- esphome/components/tee501/sensor.py +1 -1
- esphome/components/teleinfo/__init__.py +1 -1
- esphome/components/teleinfo/sensor/__init__.py +1 -7
- esphome/components/teleinfo/text_sensor/__init__.py +1 -1
- esphome/components/tem3200/sensor.py +1 -2
- esphome/components/template/alarm_control_panel/__init__.py +3 -10
- esphome/components/template/cover/__init__.py +4 -3
- esphome/components/template/datetime/__init__.py +8 -9
- esphome/components/template/event/__init__.py +2 -5
- esphome/components/template/fan/__init__.py +2 -6
- esphome/components/template/lock/__init__.py +3 -2
- esphome/components/template/number/__init__.py +3 -2
- esphome/components/template/output/__init__.py +4 -3
- esphome/components/template/select/__init__.py +3 -2
- esphome/components/template/sensor/__init__.py +4 -7
- esphome/components/template/switch/__init__.py +3 -2
- esphome/components/template/text/__init__.py +4 -3
- esphome/components/template/text_sensor/__init__.py +3 -2
- esphome/components/template/valve/__init__.py +3 -2
- esphome/components/time/real_time_clock.cpp +0 -4
- esphome/components/time/real_time_clock.h +4 -3
- esphome/components/time_based/cover.py +3 -3
- esphome/components/tlc59208f/__init__.py +1 -1
- esphome/components/tlc59208f/output.py +2 -1
- esphome/components/tlc5947/__init__.py +1 -1
- esphome/components/tlc5947/output/__init__.py +2 -1
- esphome/components/tlc5971/__init__.py +2 -8
- esphome/components/tlc5971/output/__init__.py +2 -1
- esphome/components/tm1621/display.py +3 -3
- esphome/components/tm1637/binary_sensor.py +1 -1
- esphome/components/tm1637/display.py +3 -3
- esphome/components/tm1651/__init__.py +4 -4
- esphome/components/tmp102/sensor.py +1 -1
- esphome/components/tmp1075/sensor.py +2 -2
- esphome/components/tmp117/sensor.py +1 -1
- esphome/components/tof10120/sensor.py +2 -2
- esphome/components/tormatic/cover.py +2 -6
- esphome/components/toshiba/climate.py +1 -1
- esphome/components/total_daily_energy/sensor.py +4 -4
- esphome/components/tsl2561/sensor.py +1 -1
- esphome/components/tsl2591/sensor.py +9 -9
- esphome/components/tt21100/binary_sensor/__init__.py +2 -2
- esphome/components/tt21100/touchscreen/__init__.py +2 -3
- esphome/components/ttp229_bsf/__init__.py +2 -2
- esphome/components/ttp229_bsf/binary_sensor.py +3 -2
- esphome/components/ttp229_lsf/__init__.py +1 -1
- esphome/components/ttp229_lsf/binary_sensor.py +3 -2
- esphome/components/tuya/__init__.py +3 -5
- esphome/components/tuya/binary_sensor/__init__.py +2 -2
- esphome/components/tuya/climate/__init__.py +6 -5
- esphome/components/tuya/cover/__init__.py +5 -4
- esphome/components/tuya/fan/__init__.py +3 -2
- esphome/components/tuya/light/__init__.py +9 -8
- esphome/components/tuya/number/__init__.py +6 -5
- esphome/components/tuya/select/__init__.py +4 -3
- esphome/components/tuya/sensor/__init__.py +3 -2
- esphome/components/tuya/switch/__init__.py +3 -2
- esphome/components/tuya/text_sensor/__init__.py +3 -2
- esphome/components/tx20/sensor.py +6 -6
- esphome/components/uart/__init__.py +20 -19
- esphome/components/uart/button/__init__.py +2 -1
- esphome/components/uart/switch/__init__.py +2 -1
- esphome/components/ufire_ise/sensor.py +2 -2
- esphome/components/uln2003/stepper.py +2 -2
- esphome/components/ultrasonic/sensor.py +4 -4
- esphome/components/uponor_smatrix/__init__.py +2 -6
- esphome/components/uponor_smatrix/climate/__init__.py +3 -3
- esphome/components/vbus/__init__.py +1 -1
- esphome/components/vbus/binary_sensor/__init__.py +7 -6
- esphome/components/vbus/sensor/__init__.py +7 -6
- esphome/components/veml3235/sensor.py +1 -1
- esphome/components/veml7700/sensor.py +1 -1
- esphome/components/version/text_sensor.py +2 -6
- esphome/components/vl53l0x/sensor.py +6 -6
- esphome/components/web_server_base/__init__.py +2 -2
- esphome/components/web_server_idf/__init__.py +1 -1
- esphome/components/weikai/__init__.py +1 -1
- esphome/components/whirlpool/climate.py +1 -1
- esphome/components/whynter/climate.py +1 -1
- esphome/components/wireguard/binary_sensor.py +1 -1
- esphome/components/wireguard/sensor.py +2 -5
- esphome/components/wireguard/text_sensor.py +2 -5
- esphome/components/wk2132_i2c/__init__.py +1 -1
- esphome/components/wk2132_spi/__init__.py +1 -2
- esphome/components/wk2168_i2c/__init__.py +3 -8
- esphome/components/wk2168_spi/__init__.py +3 -8
- esphome/components/wk2204_i2c/__init__.py +1 -1
- esphome/components/wk2204_spi/__init__.py +1 -1
- esphome/components/wk2212_i2c/__init__.py +3 -8
- esphome/components/wk2212_spi/__init__.py +3 -8
- esphome/components/wl_134/text_sensor.py +2 -4
- esphome/components/wled/__init__.py +2 -2
- esphome/components/x9c/output.py +4 -4
- esphome/components/xgzp68xx/sensor.py +5 -5
- esphome/components/xiaomi_ble/__init__.py +1 -1
- esphome/components/xiaomi_cgd1/sensor.py +3 -3
- esphome/components/xiaomi_cgdk2/sensor.py +3 -3
- esphome/components/xiaomi_cgg1/sensor.py +2 -2
- esphome/components/xiaomi_cgpr1/binary_sensor.py +6 -6
- esphome/components/xiaomi_gcls002/sensor.py +7 -7
- esphome/components/xiaomi_hhccjcy01/sensor.py +9 -9
- esphome/components/xiaomi_hhccjcy10/sensor.py +9 -9
- esphome/components/xiaomi_hhccpot002/sensor.py +7 -7
- esphome/components/xiaomi_jqjcy01ym/sensor.py +6 -6
- esphome/components/xiaomi_lywsd02/sensor.py +4 -4
- esphome/components/xiaomi_lywsd02mmc/sensor.py +5 -5
- esphome/components/xiaomi_lywsd03mmc/sensor.py +6 -6
- esphome/components/xiaomi_lywsdcgq/sensor.py +5 -5
- esphome/components/xiaomi_mhoc303/sensor.py +4 -4
- esphome/components/xiaomi_mhoc401/sensor.py +6 -6
- esphome/components/xiaomi_miscale/sensor.py +6 -6
- esphome/components/xiaomi_mjyd02yla/binary_sensor.py +8 -8
- esphome/components/xiaomi_mue4094rt/binary_sensor.py +2 -7
- esphome/components/xiaomi_rtcgq02lm/__init__.py +2 -3
- esphome/components/xiaomi_rtcgq02lm/binary_sensor.py +3 -3
- esphome/components/xiaomi_rtcgq02lm/sensor.py +3 -3
- esphome/components/xiaomi_wx08zm/binary_sensor.py +2 -3
- esphome/components/xl9535/__init__.py +2 -2
- esphome/components/yashima/climate.py +1 -1
- esphome/components/zhlt01/climate.py +1 -1
- esphome/components/zio_ultrasonic/sensor.py +2 -5
- esphome/components/zyaura/sensor.py +7 -7
- esphome/config_validation.py +0 -42
- esphome/const.py +3 -1
- esphome/core/__init__.py +0 -1
- esphome/core/component.cpp +3 -1
- esphome/core/component.h +15 -2
- esphome/core/config.py +4 -0
- esphome/core/defines.h +21 -0
- esphome/core/helpers.cpp +6 -7
- esphome/core/scheduler.cpp +34 -67
- esphome/core/scheduler.h +7 -17
- esphome/dashboard/status/mqtt.py +0 -2
- esphome/vscode.py +27 -8
- esphome/yaml_util.py +75 -39
- {esphome-2025.3.2.dist-info → esphome-2025.4.0.dist-info}/METADATA +45 -44
- {esphome-2025.3.2.dist-info → esphome-2025.4.0.dist-info}/RECORD +718 -711
- {esphome-2025.3.2.dist-info → esphome-2025.4.0.dist-info}/WHEEL +1 -1
- {esphome-2025.3.2.dist-info → esphome-2025.4.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.3.2.dist-info → esphome-2025.4.0.dist-info/licenses}/LICENSE +0 -0
- {esphome-2025.3.2.dist-info → esphome-2025.4.0.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,7 @@ from esphome import automation
|
|
4
4
|
import esphome.codegen as cg
|
5
5
|
import esphome.config_validation as cv
|
6
6
|
from esphome.const import CONF_ACTION, CONF_GROUP, CONF_ID, CONF_TIMEOUT
|
7
|
+
from esphome.core import Lambda
|
7
8
|
from esphome.cpp_generator import TemplateArguments, get_variable
|
8
9
|
from esphome.cpp_types import nullptr
|
9
10
|
|
@@ -17,6 +18,7 @@ from .defines import (
|
|
17
18
|
CONF_SHOW_SNOW,
|
18
19
|
PARTS,
|
19
20
|
literal,
|
21
|
+
static_cast,
|
20
22
|
)
|
21
23
|
from .lv_validation import lv_bool, lv_color, lv_image, opacity
|
22
24
|
from .lvcode import (
|
@@ -32,7 +34,6 @@ from .lvcode import (
|
|
32
34
|
lv_expr,
|
33
35
|
lv_obj,
|
34
36
|
lvgl_comp,
|
35
|
-
static_cast,
|
36
37
|
)
|
37
38
|
from .schemas import DISP_BG_SCHEMA, LIST_ACTION_SCHEMA, LVGL_SCHEMA, base_update_schema
|
38
39
|
from .types import (
|
@@ -64,7 +65,14 @@ async def action_to_code(
|
|
64
65
|
action_id,
|
65
66
|
template_arg,
|
66
67
|
args,
|
68
|
+
config=None,
|
67
69
|
):
|
70
|
+
# Ensure all required ids have been processed, so our LambdaContext doesn't get context-switched.
|
71
|
+
if config:
|
72
|
+
for lamb in config.values():
|
73
|
+
if isinstance(lamb, Lambda):
|
74
|
+
for id_ in lamb.requires_ids:
|
75
|
+
await get_variable(id_)
|
68
76
|
await wait_for_widgets()
|
69
77
|
async with LambdaContext(parameters=args, where=action_id) as context:
|
70
78
|
for widget in widgets:
|
@@ -84,7 +92,9 @@ async def update_to_code(config, action_id, template_arg, args):
|
|
84
92
|
lv.event_send(widget.obj, UPDATE_EVENT, nullptr)
|
85
93
|
|
86
94
|
widgets = await get_widgets(config[CONF_ID])
|
87
|
-
return await action_to_code(
|
95
|
+
return await action_to_code(
|
96
|
+
widgets, do_update, action_id, template_arg, args, config
|
97
|
+
)
|
88
98
|
|
89
99
|
|
90
100
|
@automation.register_condition(
|
@@ -348,4 +358,6 @@ async def obj_update_to_code(config, action_id, template_arg, args):
|
|
348
358
|
await set_obj_properties(widget, config)
|
349
359
|
|
350
360
|
widgets = await get_widgets(config[CONF_ID])
|
351
|
-
return await action_to_code(
|
361
|
+
return await action_to_code(
|
362
|
+
widgets, do_update, action_id, template_arg, args, config
|
363
|
+
)
|
@@ -29,12 +29,16 @@ def add_define(macro, value="1"):
|
|
29
29
|
lv_defines[macro] = value
|
30
30
|
|
31
31
|
|
32
|
-
def literal(arg):
|
32
|
+
def literal(arg) -> MockObj:
|
33
33
|
if isinstance(arg, str):
|
34
34
|
return MockObj(arg)
|
35
35
|
return arg
|
36
36
|
|
37
37
|
|
38
|
+
def static_cast(type, value):
|
39
|
+
return literal(f"static_cast<{type}>({value})")
|
40
|
+
|
41
|
+
|
38
42
|
def call_lambda(lamb: LambdaExpression):
|
39
43
|
expr = lamb.content.strip()
|
40
44
|
if expr.startswith("return") and expr.endswith(";"):
|
@@ -416,7 +420,6 @@ CONF_CHANGE_RATE = "change_rate"
|
|
416
420
|
CONF_CLOSE_BUTTON = "close_button"
|
417
421
|
CONF_COLOR_DEPTH = "color_depth"
|
418
422
|
CONF_CONTROL = "control"
|
419
|
-
CONF_DEFAULT = "default"
|
420
423
|
CONF_DEFAULT_FONT = "default_font"
|
421
424
|
CONF_DEFAULT_GROUP = "default_group"
|
422
425
|
CONF_DIR = "dir"
|
@@ -18,6 +18,7 @@ from .helpers import lvgl_components_required, requires_component
|
|
18
18
|
from .lvcode import lv, lv_add, lv_assign, lv_expr, lv_Pvariable
|
19
19
|
from .schemas import ENCODER_SCHEMA
|
20
20
|
from .types import lv_group_t, lv_indev_type_t, lv_key_t
|
21
|
+
from .widgets import get_widgets
|
21
22
|
|
22
23
|
ENCODERS_CONFIG = cv.ensure_list(
|
23
24
|
ENCODER_SCHEMA.extend(
|
@@ -76,5 +77,5 @@ async def encoders_to_code(var, config, default_group):
|
|
76
77
|
async def initial_focus_to_code(config):
|
77
78
|
for enc_conf in config[CONF_ENCODERS]:
|
78
79
|
if default_focus := enc_conf.get(CONF_INITIAL_FOCUS):
|
79
|
-
|
80
|
-
lv.group_focus_obj(obj)
|
80
|
+
widget = await get_widgets(default_focus)
|
81
|
+
lv.group_focus_obj(widget[0].obj)
|
@@ -254,11 +254,27 @@ def pixels_or_percent_validator(value):
|
|
254
254
|
pixels_or_percent = LValidator(pixels_or_percent_validator, uint32, retmapper=literal)
|
255
255
|
|
256
256
|
|
257
|
-
def
|
257
|
+
def pixels_validator(value):
|
258
|
+
if isinstance(value, str) and value.lower().endswith("px"):
|
259
|
+
value = value[:-2]
|
260
|
+
return cv.positive_int(value)
|
261
|
+
|
262
|
+
|
263
|
+
pixels = LValidator(pixels_validator, uint32, retmapper=literal)
|
264
|
+
|
265
|
+
|
266
|
+
def zoom_validator(value):
|
258
267
|
value = cv.float_range(0.1, 10.0)(value)
|
268
|
+
return value
|
269
|
+
|
270
|
+
|
271
|
+
def zoom_retmapper(value):
|
259
272
|
return int(value * 256)
|
260
273
|
|
261
274
|
|
275
|
+
zoom = LValidator(zoom_validator, uint32, retmapper=zoom_retmapper)
|
276
|
+
|
277
|
+
|
262
278
|
def angle(value):
|
263
279
|
"""
|
264
280
|
Validation for an angle in degrees, converted to an integer representing 0.1deg units
|
@@ -286,14 +302,6 @@ def size_validator(value):
|
|
286
302
|
size = LValidator(size_validator, uint32, retmapper=literal)
|
287
303
|
|
288
304
|
|
289
|
-
def pixels_validator(value):
|
290
|
-
if isinstance(value, str) and value.lower().endswith("px"):
|
291
|
-
return cv.int_(value[:-2])
|
292
|
-
return cv.int_(value)
|
293
|
-
|
294
|
-
|
295
|
-
pixels = LValidator(pixels_validator, uint32, retmapper=literal)
|
296
|
-
|
297
305
|
radius_consts = LvConstant("LV_RADIUS_", "CIRCLE")
|
298
306
|
|
299
307
|
|
@@ -173,7 +173,8 @@ class LambdaContext(CodeContext):
|
|
173
173
|
|
174
174
|
class LvContext(LambdaContext):
|
175
175
|
"""
|
176
|
-
Code generation into the LVGL initialisation code
|
176
|
+
Code generation into the LVGL initialisation code, called before setup() and loop()
|
177
|
+
Basically just does cg.add, so now fairly redundant.
|
177
178
|
"""
|
178
179
|
|
179
180
|
added_lambda_count = 0
|
@@ -206,11 +207,16 @@ class LocalVariable(MockObj):
|
|
206
207
|
|
207
208
|
def __enter__(self):
|
208
209
|
CodeContext.start_block()
|
209
|
-
CodeContext.append(
|
210
|
-
VariableDeclarationExpression(self.base.type, self.modifier, self.base.id)
|
211
|
-
)
|
212
210
|
if self.rhs is not None:
|
213
|
-
CodeContext.append(
|
211
|
+
CodeContext.append(
|
212
|
+
AssignmentExpression(self.base.type, self.modifier, self.base, self.rhs)
|
213
|
+
)
|
214
|
+
else:
|
215
|
+
CodeContext.append(
|
216
|
+
VariableDeclarationExpression(
|
217
|
+
self.base.type, self.modifier, self.base.id
|
218
|
+
)
|
219
|
+
)
|
214
220
|
return MockObj(self.base)
|
215
221
|
|
216
222
|
def __exit__(self, *args):
|
@@ -285,10 +291,6 @@ class LvExpr(MockLv):
|
|
285
291
|
pass
|
286
292
|
|
287
293
|
|
288
|
-
def static_cast(type, value):
|
289
|
-
return literal(f"static_cast<{type}>({value})")
|
290
|
-
|
291
|
-
|
292
294
|
# Top level mock for generic lv_ calls to be recorded
|
293
295
|
lv = MockLv("lv_")
|
294
296
|
# Just generate an expression
|
@@ -63,6 +63,13 @@ inline void lv_disp_set_bg_image(lv_disp_t *disp, esphome::image::Image *image)
|
|
63
63
|
inline void lv_obj_set_style_bg_img_src(lv_obj_t *obj, esphome::image::Image *image, lv_style_selector_t selector) {
|
64
64
|
lv_obj_set_style_bg_img_src(obj, image->get_lv_img_dsc(), selector);
|
65
65
|
}
|
66
|
+
#ifdef USE_LVGL_CANVAS
|
67
|
+
inline void lv_canvas_draw_img(lv_obj_t *canvas, lv_coord_t x, lv_coord_t y, image::Image *image,
|
68
|
+
lv_draw_img_dsc_t *dsc) {
|
69
|
+
lv_canvas_draw_img(canvas, x, y, image->get_lv_img_dsc(), dsc);
|
70
|
+
}
|
71
|
+
#endif
|
72
|
+
|
66
73
|
#ifdef USE_LVGL_METER
|
67
74
|
inline lv_meter_indicator_t *lv_meter_add_needle_img(lv_obj_t *obj, lv_meter_scale_t *scale, esphome::image::Image *src,
|
68
75
|
lv_coord_t pivot_x, lv_coord_t pivot_y) {
|
@@ -90,6 +97,7 @@ inline void lv_animimg_set_src(lv_obj_t *img, std::vector<image::Image *> images
|
|
90
97
|
// Parent class for things that wrap an LVGL object
|
91
98
|
class LvCompound {
|
92
99
|
public:
|
100
|
+
virtual ~LvCompound() = default;
|
93
101
|
virtual void set_obj(lv_obj_t *lv_obj) { this->obj = lv_obj; }
|
94
102
|
lv_obj_t *obj{};
|
95
103
|
};
|
@@ -330,6 +338,19 @@ class LVEncoderListener : public Parented<LvglComponent> {
|
|
330
338
|
};
|
331
339
|
#endif // USE_LVGL_KEY_LISTENER
|
332
340
|
|
341
|
+
#ifdef USE_LVGL_LINE
|
342
|
+
class LvLineType : public LvCompound {
|
343
|
+
public:
|
344
|
+
std::vector<lv_point_t> get_points() { return this->points_; }
|
345
|
+
void set_points(std::vector<lv_point_t> points) {
|
346
|
+
this->points_ = std::move(points);
|
347
|
+
lv_line_set_points(this->obj, this->points_.data(), this->points_.size());
|
348
|
+
}
|
349
|
+
|
350
|
+
protected:
|
351
|
+
std::vector<lv_point_t> points_{};
|
352
|
+
};
|
353
|
+
#endif
|
333
354
|
#if defined(USE_LVGL_DROPDOWN) || defined(LV_USE_ROLLER)
|
334
355
|
class LvSelectable : public LvCompound {
|
335
356
|
public:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import esphome.codegen as cg
|
2
2
|
from esphome.components import number
|
3
3
|
import esphome.config_validation as cv
|
4
|
+
from esphome.const import CONF_RESTORE_VALUE
|
4
5
|
from esphome.cpp_generator import MockObj
|
5
6
|
|
6
7
|
from ..defines import CONF_ANIMATED, CONF_UPDATE_ON_RELEASE, CONF_WIDGET
|
@@ -10,21 +11,21 @@ from ..lvcode import (
|
|
10
11
|
EVENT_ARG,
|
11
12
|
UPDATE_EVENT,
|
12
13
|
LambdaContext,
|
13
|
-
|
14
|
+
ReturnStatement,
|
14
15
|
lv,
|
15
|
-
lv_add,
|
16
16
|
lvgl_static,
|
17
17
|
)
|
18
18
|
from ..types import LV_EVENT, LvNumber, lvgl_ns
|
19
19
|
from ..widgets import get_widgets, wait_for_widgets
|
20
20
|
|
21
|
-
LVGLNumber = lvgl_ns.class_("LVGLNumber", number.Number)
|
21
|
+
LVGLNumber = lvgl_ns.class_("LVGLNumber", number.Number, cg.Component)
|
22
22
|
|
23
23
|
CONFIG_SCHEMA = number.number_schema(LVGLNumber).extend(
|
24
24
|
{
|
25
25
|
cv.Required(CONF_WIDGET): cv.use_id(LvNumber),
|
26
26
|
cv.Optional(CONF_ANIMATED, default=True): animated,
|
27
27
|
cv.Optional(CONF_UPDATE_ON_RELEASE, default=False): cv.boolean,
|
28
|
+
cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean,
|
28
29
|
}
|
29
30
|
)
|
30
31
|
|
@@ -32,32 +33,34 @@ CONFIG_SCHEMA = number.number_schema(LVGLNumber).extend(
|
|
32
33
|
async def to_code(config):
|
33
34
|
widget = await get_widgets(config, CONF_WIDGET)
|
34
35
|
widget = widget[0]
|
35
|
-
var = await number.new_number(
|
36
|
-
config,
|
37
|
-
max_value=widget.get_max(),
|
38
|
-
min_value=widget.get_min(),
|
39
|
-
step=widget.get_step(),
|
40
|
-
)
|
41
|
-
|
42
36
|
await wait_for_widgets()
|
37
|
+
async with LambdaContext([], return_type=cg.float_) as value:
|
38
|
+
value.add(ReturnStatement(widget.get_value()))
|
43
39
|
async with LambdaContext([(cg.float_, "v")]) as control:
|
44
40
|
await widget.set_property(
|
45
41
|
"value", MockObj("v") * MockObj(widget.get_scale()), config[CONF_ANIMATED]
|
46
42
|
)
|
47
43
|
lv.event_send(widget.obj, API_EVENT, cg.nullptr)
|
48
|
-
control.add(var.publish_state(widget.get_value()))
|
49
|
-
async with LambdaContext(EVENT_ARG) as event:
|
50
|
-
event.add(var.publish_state(widget.get_value()))
|
51
44
|
event_code = (
|
52
45
|
LV_EVENT.VALUE_CHANGED
|
53
46
|
if not config[CONF_UPDATE_ON_RELEASE]
|
54
47
|
else LV_EVENT.RELEASED
|
55
48
|
)
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
49
|
+
var = await number.new_number(
|
50
|
+
config,
|
51
|
+
await control.get_lambda(),
|
52
|
+
await value.get_lambda(),
|
53
|
+
event_code,
|
54
|
+
config[CONF_RESTORE_VALUE],
|
55
|
+
max_value=widget.get_max(),
|
56
|
+
min_value=widget.get_min(),
|
57
|
+
step=widget.get_step(),
|
58
|
+
)
|
59
|
+
async with LambdaContext(EVENT_ARG) as event:
|
60
|
+
event.add(var.on_value())
|
61
|
+
await cg.register_component(var, config)
|
62
|
+
cg.add(
|
63
|
+
lvgl_static.add_event_cb(
|
64
|
+
widget.obj, await event.get_lambda(), UPDATE_EVENT, event_code
|
62
65
|
)
|
63
|
-
|
66
|
+
)
|
@@ -3,33 +3,46 @@
|
|
3
3
|
#include <utility>
|
4
4
|
|
5
5
|
#include "esphome/components/number/number.h"
|
6
|
-
#include "esphome/core/automation.h"
|
7
6
|
#include "esphome/core/component.h"
|
8
7
|
#include "esphome/core/preferences.h"
|
9
8
|
|
10
9
|
namespace esphome {
|
11
10
|
namespace lvgl {
|
12
11
|
|
13
|
-
class LVGLNumber : public number::Number {
|
12
|
+
class LVGLNumber : public number::Number, public Component {
|
14
13
|
public:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
LVGLNumber(std::function<void(float)> control_lambda, std::function<float()> value_lambda, lv_event_code_t event,
|
15
|
+
bool restore)
|
16
|
+
: control_lambda_(std::move(control_lambda)),
|
17
|
+
value_lambda_(std::move(value_lambda)),
|
18
|
+
event_(event),
|
19
|
+
restore_(restore) {}
|
20
|
+
|
21
|
+
void setup() override {
|
22
|
+
float value = this->value_lambda_();
|
23
|
+
if (this->restore_) {
|
24
|
+
this->pref_ = global_preferences->make_preference<float>(this->get_object_id_hash());
|
25
|
+
if (this->pref_.load(&value)) {
|
26
|
+
this->control_lambda_(value);
|
27
|
+
}
|
20
28
|
}
|
29
|
+
this->publish_state(value);
|
21
30
|
}
|
22
31
|
|
32
|
+
void on_value() { this->publish_state(this->value_lambda_()); }
|
33
|
+
|
23
34
|
protected:
|
24
35
|
void control(float value) override {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
this->
|
29
|
-
}
|
36
|
+
this->control_lambda_(value);
|
37
|
+
this->publish_state(value);
|
38
|
+
if (this->restore_)
|
39
|
+
this->pref_.save(&value);
|
30
40
|
}
|
31
|
-
std::function<void(float)> control_lambda_
|
32
|
-
|
41
|
+
std::function<void(float)> control_lambda_;
|
42
|
+
std::function<float()> value_lambda_;
|
43
|
+
lv_event_code_t event_;
|
44
|
+
bool restore_;
|
45
|
+
ESPPreferenceObject pref_{};
|
33
46
|
};
|
34
47
|
|
35
48
|
} // namespace lvgl
|
@@ -6,6 +6,7 @@ from esphome.const import (
|
|
6
6
|
CONF_FORMAT,
|
7
7
|
CONF_GROUP,
|
8
8
|
CONF_ID,
|
9
|
+
CONF_ON_BOOT,
|
9
10
|
CONF_ON_VALUE,
|
10
11
|
CONF_STATE,
|
11
12
|
CONF_TEXT,
|
@@ -14,10 +15,11 @@ from esphome.const import (
|
|
14
15
|
CONF_TYPE,
|
15
16
|
)
|
16
17
|
from esphome.core import TimePeriod
|
18
|
+
from esphome.core.config import StartupTrigger
|
17
19
|
from esphome.schema_extractors import SCHEMA_EXTRACT
|
18
20
|
|
19
21
|
from . import defines as df, lv_validation as lvalid
|
20
|
-
from .defines import CONF_TIME_FORMAT, LV_GRAD_DIR
|
22
|
+
from .defines import CONF_TIME_FORMAT, CONF_X, CONF_Y, LV_GRAD_DIR
|
21
23
|
from .helpers import add_lv_use, requires_component, validate_printf
|
22
24
|
from .lv_validation import lv_color, lv_font, lv_gradient, lv_image, opacity
|
23
25
|
from .lvcode import LvglComponent, lv_event_t_ptr
|
@@ -79,12 +81,39 @@ ENCODER_SCHEMA = cv.Schema(
|
|
79
81
|
cv.declare_id(LVEncoderListener), requires_component("binary_sensor")
|
80
82
|
),
|
81
83
|
cv.Optional(CONF_GROUP): cv.declare_id(lv_group_t),
|
82
|
-
cv.Optional(df.CONF_INITIAL_FOCUS): cv.
|
84
|
+
cv.Optional(df.CONF_INITIAL_FOCUS): cv.All(
|
85
|
+
LIST_ACTION_SCHEMA, cv.Length(min=1, max=1)
|
86
|
+
),
|
83
87
|
cv.Optional(df.CONF_LONG_PRESS_TIME, default="400ms"): PRESS_TIME,
|
84
88
|
cv.Optional(df.CONF_LONG_PRESS_REPEAT_TIME, default="100ms"): PRESS_TIME,
|
85
89
|
}
|
86
90
|
)
|
87
91
|
|
92
|
+
POINT_SCHEMA = cv.Schema(
|
93
|
+
{
|
94
|
+
cv.Required(CONF_X): cv.templatable(cv.int_),
|
95
|
+
cv.Required(CONF_Y): cv.templatable(cv.int_),
|
96
|
+
}
|
97
|
+
)
|
98
|
+
|
99
|
+
|
100
|
+
def point_schema(value):
|
101
|
+
"""
|
102
|
+
A shorthand for a point in the form of x,y
|
103
|
+
:param value: The value to check
|
104
|
+
:return: The value as a tuple of x,y
|
105
|
+
"""
|
106
|
+
if isinstance(value, dict):
|
107
|
+
return POINT_SCHEMA(value)
|
108
|
+
try:
|
109
|
+
x, y = map(int, value.split(","))
|
110
|
+
return {CONF_X: x, CONF_Y: y}
|
111
|
+
except ValueError:
|
112
|
+
pass
|
113
|
+
# not raising this in the catch block because pylint doesn't like it
|
114
|
+
raise cv.Invalid("Invalid point format, should be <x_int>, <y_int>")
|
115
|
+
|
116
|
+
|
88
117
|
# All LVGL styles and their validators
|
89
118
|
STYLE_PROPS = {
|
90
119
|
"align": df.CHILD_ALIGNMENTS.one_of,
|
@@ -103,6 +132,7 @@ STYLE_PROPS = {
|
|
103
132
|
"bg_image_recolor": lvalid.lv_color,
|
104
133
|
"bg_image_recolor_opa": lvalid.opacity,
|
105
134
|
"bg_image_src": lvalid.lv_image,
|
135
|
+
"bg_image_tiled": lvalid.lv_bool,
|
106
136
|
"bg_main_stop": lvalid.stop_value,
|
107
137
|
"bg_opa": lvalid.opacity,
|
108
138
|
"border_color": lvalid.lv_color,
|
@@ -117,9 +147,9 @@ STYLE_PROPS = {
|
|
117
147
|
"height": lvalid.size,
|
118
148
|
"image_recolor": lvalid.lv_color,
|
119
149
|
"image_recolor_opa": lvalid.opacity,
|
120
|
-
"line_width":
|
121
|
-
"line_dash_width":
|
122
|
-
"line_dash_gap":
|
150
|
+
"line_width": lvalid.lv_positive_int,
|
151
|
+
"line_dash_width": lvalid.lv_positive_int,
|
152
|
+
"line_dash_gap": lvalid.lv_positive_int,
|
123
153
|
"line_rounded": lvalid.lv_bool,
|
124
154
|
"line_color": lvalid.lv_color,
|
125
155
|
"opa": lvalid.opacity,
|
@@ -147,8 +177,8 @@ STYLE_PROPS = {
|
|
147
177
|
"LV_TEXT_DECOR_", "NONE", "UNDERLINE", "STRIKETHROUGH"
|
148
178
|
).several_of,
|
149
179
|
"text_font": lv_font,
|
150
|
-
"text_letter_space":
|
151
|
-
"text_line_space":
|
180
|
+
"text_letter_space": lvalid.lv_positive_int,
|
181
|
+
"text_line_space": lvalid.lv_positive_int,
|
152
182
|
"text_opa": lvalid.opacity,
|
153
183
|
"transform_angle": lvalid.lv_angle,
|
154
184
|
"transform_height": lvalid.pixels_or_percent,
|
@@ -172,10 +202,15 @@ STYLE_REMAP = {
|
|
172
202
|
"bg_image_recolor": "bg_img_recolor",
|
173
203
|
"bg_image_recolor_opa": "bg_img_recolor_opa",
|
174
204
|
"bg_image_src": "bg_img_src",
|
205
|
+
"bg_image_tiled": "bg_img_tiled",
|
175
206
|
"image_recolor": "img_recolor",
|
176
207
|
"image_recolor_opa": "img_recolor_opa",
|
177
208
|
}
|
178
209
|
|
210
|
+
cell_alignments = df.LV_CELL_ALIGNMENTS.one_of
|
211
|
+
grid_alignments = df.LV_GRID_ALIGNMENTS.one_of
|
212
|
+
flex_alignments = df.LV_FLEX_ALIGNMENTS.one_of
|
213
|
+
|
179
214
|
# Complete object style schema
|
180
215
|
STYLE_SCHEMA = cv.Schema({cv.Optional(k): v for k, v in STYLE_PROPS.items()}).extend(
|
181
216
|
{
|
@@ -186,6 +221,16 @@ STYLE_SCHEMA = cv.Schema({cv.Optional(k): v for k, v in STYLE_PROPS.items()}).ex
|
|
186
221
|
}
|
187
222
|
)
|
188
223
|
|
224
|
+
# Also allow widget specific properties for use in style definitions
|
225
|
+
FULL_STYLE_SCHEMA = STYLE_SCHEMA.extend(
|
226
|
+
{
|
227
|
+
cv.Optional(df.CONF_GRID_CELL_X_ALIGN): grid_alignments,
|
228
|
+
cv.Optional(df.CONF_GRID_CELL_Y_ALIGN): grid_alignments,
|
229
|
+
cv.Optional(df.CONF_PAD_ROW): lvalid.pixels,
|
230
|
+
cv.Optional(df.CONF_PAD_COLUMN): lvalid.pixels,
|
231
|
+
}
|
232
|
+
)
|
233
|
+
|
189
234
|
# Object states. Top level properties apply to MAIN
|
190
235
|
STATE_SCHEMA = cv.Schema(
|
191
236
|
{cv.Optional(state): STYLE_SCHEMA for state in df.STATES}
|
@@ -216,14 +261,24 @@ def automation_schema(typ: LvType):
|
|
216
261
|
events = events + (CONF_ON_VALUE,)
|
217
262
|
args = typ.get_arg_type() if isinstance(typ, LvType) else []
|
218
263
|
args.append(lv_event_t_ptr)
|
219
|
-
return
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
264
|
+
return cv.Schema(
|
265
|
+
{
|
266
|
+
cv.Optional(event): validate_automation(
|
267
|
+
{
|
268
|
+
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
269
|
+
Trigger.template(*args)
|
270
|
+
),
|
271
|
+
}
|
272
|
+
)
|
273
|
+
for event in events
|
274
|
+
}
|
275
|
+
).extend(
|
276
|
+
{
|
277
|
+
cv.Optional(CONF_ON_BOOT): validate_automation(
|
278
|
+
{cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StartupTrigger)}
|
279
|
+
)
|
280
|
+
}
|
281
|
+
)
|
227
282
|
|
228
283
|
|
229
284
|
def base_update_schema(widget_type, parts):
|
@@ -307,10 +362,6 @@ grid_spec = cv.Any(
|
|
307
362
|
lvalid.size, df.LvConstant("LV_GRID_", "CONTENT").one_of, grid_free_space
|
308
363
|
)
|
309
364
|
|
310
|
-
cell_alignments = df.LV_CELL_ALIGNMENTS.one_of
|
311
|
-
grid_alignments = df.LV_GRID_ALIGNMENTS.one_of
|
312
|
-
flex_alignments = df.LV_FLEX_ALIGNMENTS.one_of
|
313
|
-
|
314
365
|
LAYOUT_SCHEMA = {
|
315
366
|
cv.Optional(df.CONF_LAYOUT): cv.typed_schema(
|
316
367
|
{
|
@@ -1,18 +1,19 @@
|
|
1
|
+
import esphome.codegen as cg
|
1
2
|
from esphome.components import select
|
2
3
|
import esphome.config_validation as cv
|
3
|
-
from esphome.const import CONF_OPTIONS
|
4
|
+
from esphome.const import CONF_ID, CONF_OPTIONS, CONF_RESTORE_VALUE
|
4
5
|
|
5
6
|
from ..defines import CONF_ANIMATED, CONF_WIDGET, literal
|
6
|
-
from ..lvcode import LvContext
|
7
7
|
from ..types import LvSelect, lvgl_ns
|
8
|
-
from ..widgets import get_widgets
|
8
|
+
from ..widgets import get_widgets
|
9
9
|
|
10
|
-
LVGLSelect = lvgl_ns.class_("LVGLSelect", select.Select)
|
10
|
+
LVGLSelect = lvgl_ns.class_("LVGLSelect", select.Select, cg.Component)
|
11
11
|
|
12
12
|
CONFIG_SCHEMA = select.select_schema(LVGLSelect).extend(
|
13
13
|
{
|
14
14
|
cv.Required(CONF_WIDGET): cv.use_id(LvSelect),
|
15
15
|
cv.Optional(CONF_ANIMATED, default=False): cv.boolean,
|
16
|
+
cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean,
|
16
17
|
}
|
17
18
|
)
|
18
19
|
|
@@ -21,12 +22,9 @@ async def to_code(config):
|
|
21
22
|
widget = await get_widgets(config, CONF_WIDGET)
|
22
23
|
widget = widget[0]
|
23
24
|
options = widget.config.get(CONF_OPTIONS, [])
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
literal("LV_ANIM_ON" if config[CONF_ANIMATED] else "LV_ANIM_OFF"),
|
31
|
-
)
|
32
|
-
)
|
25
|
+
animated = literal("LV_ANIM_ON" if config[CONF_ANIMATED] else "LV_ANIM_OFF")
|
26
|
+
selector = cg.new_Pvariable(
|
27
|
+
config[CONF_ID], widget.var, animated, config[CONF_RESTORE_VALUE]
|
28
|
+
)
|
29
|
+
await select.register_select(selector, config, options=options)
|
30
|
+
await cg.register_component(selector, config)
|
@@ -11,12 +11,20 @@
|
|
11
11
|
namespace esphome {
|
12
12
|
namespace lvgl {
|
13
13
|
|
14
|
-
class LVGLSelect : public select::Select {
|
14
|
+
class LVGLSelect : public select::Select, public Component {
|
15
15
|
public:
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
LVGLSelect(LvSelectable *widget, lv_anim_enable_t anim, bool restore)
|
17
|
+
: widget_(widget), anim_(anim), restore_(restore) {}
|
18
|
+
|
19
|
+
void setup() override {
|
19
20
|
this->set_options_();
|
21
|
+
if (this->restore_) {
|
22
|
+
size_t index;
|
23
|
+
this->pref_ = global_preferences->make_preference<size_t>(this->get_object_id_hash());
|
24
|
+
if (this->pref_.load(&index))
|
25
|
+
this->widget_->set_selected_index(index, LV_ANIM_OFF);
|
26
|
+
}
|
27
|
+
this->publish();
|
20
28
|
lv_obj_add_event_cb(
|
21
29
|
this->widget_->obj,
|
22
30
|
[](lv_event_t *e) {
|
@@ -24,11 +32,6 @@ class LVGLSelect : public select::Select {
|
|
24
32
|
it->set_options_();
|
25
33
|
},
|
26
34
|
LV_EVENT_REFRESH, this);
|
27
|
-
if (this->initial_state_.has_value()) {
|
28
|
-
this->control(this->initial_state_.value());
|
29
|
-
this->initial_state_.reset();
|
30
|
-
}
|
31
|
-
this->publish();
|
32
35
|
auto lamb = [](lv_event_t *e) {
|
33
36
|
auto *self = static_cast<LVGLSelect *>(e->user_data);
|
34
37
|
self->publish();
|
@@ -37,21 +40,25 @@ class LVGLSelect : public select::Select {
|
|
37
40
|
lv_obj_add_event_cb(this->widget_->obj, lamb, lv_update_event, this);
|
38
41
|
}
|
39
42
|
|
40
|
-
void publish() {
|
43
|
+
void publish() {
|
44
|
+
this->publish_state(this->widget_->get_selected_text());
|
45
|
+
if (this->restore_) {
|
46
|
+
auto index = this->widget_->get_selected_index();
|
47
|
+
this->pref_.save(&index);
|
48
|
+
}
|
49
|
+
}
|
41
50
|
|
42
51
|
protected:
|
43
52
|
void control(const std::string &value) override {
|
44
|
-
|
45
|
-
|
46
|
-
} else {
|
47
|
-
this->initial_state_ = value;
|
48
|
-
}
|
53
|
+
this->widget_->set_selected_text(value, this->anim_);
|
54
|
+
this->publish();
|
49
55
|
}
|
50
56
|
void set_options_() { this->traits.set_options(this->widget_->get_options()); }
|
51
57
|
|
52
|
-
LvSelectable *widget_
|
53
|
-
|
54
|
-
|
58
|
+
LvSelectable *widget_;
|
59
|
+
lv_anim_enable_t anim_;
|
60
|
+
bool restore_;
|
61
|
+
ESPPreferenceObject pref_{};
|
55
62
|
};
|
56
63
|
|
57
64
|
} // namespace lvgl
|