esphome 2025.3.3__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/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/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/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/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.3.dist-info → esphome-2025.4.0.dist-info}/METADATA +45 -44
- {esphome-2025.3.3.dist-info → esphome-2025.4.0.dist-info}/RECORD +713 -706
- {esphome-2025.3.3.dist-info → esphome-2025.4.0.dist-info}/WHEEL +1 -1
- {esphome-2025.3.3.dist-info → esphome-2025.4.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.3.3.dist-info → esphome-2025.4.0.dist-info/licenses}/LICENSE +0 -0
- {esphome-2025.3.3.dist-info → esphome-2025.4.0.dist-info}/top_level.txt +0 -0
esphome/core/scheduler.cpp
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#include "scheduler.h"
|
2
|
+
#include "esphome/core/defines.h"
|
2
3
|
#include "esphome/core/log.h"
|
3
4
|
#include "esphome/core/helpers.h"
|
4
5
|
#include "esphome/core/hal.h"
|
@@ -21,7 +22,7 @@ static const uint32_t MAX_LOGICALLY_DELETED_ITEMS = 10;
|
|
21
22
|
|
22
23
|
void HOT Scheduler::set_timeout(Component *component, const std::string &name, uint32_t timeout,
|
23
24
|
std::function<void()> func) {
|
24
|
-
const
|
25
|
+
const auto now = this->millis_();
|
25
26
|
|
26
27
|
if (!name.empty())
|
27
28
|
this->cancel_timeout(component, name);
|
@@ -29,17 +30,16 @@ void HOT Scheduler::set_timeout(Component *component, const std::string &name, u
|
|
29
30
|
if (timeout == SCHEDULER_DONT_RUN)
|
30
31
|
return;
|
31
32
|
|
32
|
-
ESP_LOGVV(TAG, "set_timeout(name='%s', timeout=%" PRIu32 ")", name.c_str(), timeout);
|
33
|
-
|
34
33
|
auto item = make_unique<SchedulerItem>();
|
35
34
|
item->component = component;
|
36
35
|
item->name = name;
|
37
36
|
item->type = SchedulerItem::TIMEOUT;
|
38
|
-
item->
|
39
|
-
item->last_execution = now;
|
40
|
-
item->last_execution_major = this->millis_major_;
|
37
|
+
item->next_execution_ = now + timeout;
|
41
38
|
item->callback = std::move(func);
|
42
39
|
item->remove = false;
|
40
|
+
#ifdef ESPHOME_DEBUG_SCHEDULER
|
41
|
+
ESP_LOGD(TAG, "set_timeout(name='%s/%s', timeout=%" PRIu32 ")", item->get_source(), name.c_str(), timeout);
|
42
|
+
#endif
|
43
43
|
this->push_(std::move(item));
|
44
44
|
}
|
45
45
|
bool HOT Scheduler::cancel_timeout(Component *component, const std::string &name) {
|
@@ -47,7 +47,7 @@ bool HOT Scheduler::cancel_timeout(Component *component, const std::string &name
|
|
47
47
|
}
|
48
48
|
void HOT Scheduler::set_interval(Component *component, const std::string &name, uint32_t interval,
|
49
49
|
std::function<void()> func) {
|
50
|
-
const
|
50
|
+
const auto now = this->millis_();
|
51
51
|
|
52
52
|
if (!name.empty())
|
53
53
|
this->cancel_interval(component, name);
|
@@ -60,19 +60,18 @@ void HOT Scheduler::set_interval(Component *component, const std::string &name,
|
|
60
60
|
if (interval != 0)
|
61
61
|
offset = (random_uint32() % interval) / 2;
|
62
62
|
|
63
|
-
ESP_LOGVV(TAG, "set_interval(name='%s', interval=%" PRIu32 ", offset=%" PRIu32 ")", name.c_str(), interval, offset);
|
64
|
-
|
65
63
|
auto item = make_unique<SchedulerItem>();
|
66
64
|
item->component = component;
|
67
65
|
item->name = name;
|
68
66
|
item->type = SchedulerItem::INTERVAL;
|
69
67
|
item->interval = interval;
|
70
|
-
item->
|
71
|
-
item->last_execution_major = this->millis_major_;
|
72
|
-
if (item->last_execution > now)
|
73
|
-
item->last_execution_major--;
|
68
|
+
item->next_execution_ = now + offset;
|
74
69
|
item->callback = std::move(func);
|
75
70
|
item->remove = false;
|
71
|
+
#ifdef ESPHOME_DEBUG_SCHEDULER
|
72
|
+
ESP_LOGD(TAG, "set_interval(name='%s/%s', interval=%" PRIu32 ", offset=%" PRIu32 ")", item->get_source(),
|
73
|
+
name.c_str(), interval, offset);
|
74
|
+
#endif
|
76
75
|
this->push_(std::move(item));
|
77
76
|
}
|
78
77
|
bool HOT Scheduler::cancel_interval(Component *component, const std::string &name) {
|
@@ -138,36 +137,36 @@ optional<uint32_t> HOT Scheduler::next_schedule_in() {
|
|
138
137
|
if (this->empty_())
|
139
138
|
return {};
|
140
139
|
auto &item = this->items_[0];
|
141
|
-
const
|
142
|
-
|
143
|
-
if (next_time < now)
|
140
|
+
const auto now = this->millis_();
|
141
|
+
if (item->next_execution_ < now)
|
144
142
|
return 0;
|
145
|
-
return
|
143
|
+
return item->next_execution_ - now;
|
146
144
|
}
|
147
145
|
void HOT Scheduler::call() {
|
148
|
-
const
|
146
|
+
const auto now = this->millis_();
|
149
147
|
this->process_to_add();
|
150
148
|
|
151
149
|
#ifdef ESPHOME_DEBUG_SCHEDULER
|
152
|
-
static
|
150
|
+
static uint64_t last_print = 0;
|
153
151
|
|
154
152
|
if (now - last_print > 2000) {
|
155
153
|
last_print = now;
|
156
154
|
std::vector<std::unique_ptr<SchedulerItem>> old_items;
|
157
|
-
|
155
|
+
ESP_LOGD(TAG, "Items: count=%u, now=%" PRIu64 " (%u, %" PRIu32 ")", this->items_.size(), now, this->millis_major_,
|
156
|
+
this->last_millis_);
|
158
157
|
while (!this->empty_()) {
|
159
158
|
this->lock_.lock();
|
160
159
|
auto item = std::move(this->items_[0]);
|
161
160
|
this->pop_raw_();
|
162
161
|
this->lock_.unlock();
|
163
162
|
|
164
|
-
|
165
|
-
|
166
|
-
|
163
|
+
ESP_LOGD(TAG, " %s '%s/%s' interval=%" PRIu32 " next_execution in %" PRIu64 "ms at %" PRIu64,
|
164
|
+
item->get_type_str(), item->get_source(), item->name.c_str(), item->interval,
|
165
|
+
item->next_execution_ - now, item->next_execution_);
|
167
166
|
|
168
167
|
old_items.push_back(std::move(item));
|
169
168
|
}
|
170
|
-
|
169
|
+
ESP_LOGD(TAG, "\n");
|
171
170
|
|
172
171
|
{
|
173
172
|
LockGuard guard{this->lock_};
|
@@ -206,14 +205,10 @@ void HOT Scheduler::call() {
|
|
206
205
|
{
|
207
206
|
// Don't copy-by value yet
|
208
207
|
auto &item = this->items_[0];
|
209
|
-
if (
|
208
|
+
if (item->next_execution_ > now) {
|
210
209
|
// Not reached timeout yet, done for this call
|
211
210
|
break;
|
212
211
|
}
|
213
|
-
uint8_t major = item->next_execution_major();
|
214
|
-
if (this->millis_major_ - major > 1)
|
215
|
-
break;
|
216
|
-
|
217
212
|
// Don't run on failed components
|
218
213
|
if (item->component != nullptr && item->component->is_failed()) {
|
219
214
|
LockGuard guard{this->lock_};
|
@@ -221,9 +216,10 @@ void HOT Scheduler::call() {
|
|
221
216
|
continue;
|
222
217
|
}
|
223
218
|
|
224
|
-
#ifdef
|
225
|
-
|
226
|
-
|
219
|
+
#ifdef ESPHOME_DEBUG_SCHEDULER
|
220
|
+
ESP_LOGV(TAG, "Running %s '%s/%s' with interval=%" PRIu32 " next_execution=%" PRIu64 " (now=%" PRIu64 ")",
|
221
|
+
item->get_type_str(), item->get_source(), item->name.c_str(), item->interval, item->next_execution_,
|
222
|
+
now);
|
227
223
|
#endif
|
228
224
|
|
229
225
|
// Warning: During callback(), a lot of stuff can happen, including:
|
@@ -254,13 +250,7 @@ void HOT Scheduler::call() {
|
|
254
250
|
}
|
255
251
|
|
256
252
|
if (item->type == SchedulerItem::INTERVAL) {
|
257
|
-
|
258
|
-
const uint32_t before = item->last_execution;
|
259
|
-
const uint32_t amount = (now - item->last_execution) / item->interval;
|
260
|
-
item->last_execution += amount * item->interval;
|
261
|
-
if (item->last_execution < before)
|
262
|
-
item->last_execution_major++;
|
263
|
-
}
|
253
|
+
item->next_execution_ = now + item->interval;
|
264
254
|
this->push_(std::move(item));
|
265
255
|
}
|
266
256
|
}
|
@@ -322,43 +312,20 @@ bool HOT Scheduler::cancel_item_(Component *component, const std::string &name,
|
|
322
312
|
|
323
313
|
return ret;
|
324
314
|
}
|
325
|
-
|
315
|
+
uint64_t Scheduler::millis_() {
|
326
316
|
const uint32_t now = millis();
|
327
317
|
if (now < this->last_millis_) {
|
328
|
-
ESP_LOGD(TAG, "Incrementing scheduler major");
|
329
318
|
this->millis_major_++;
|
319
|
+
ESP_LOGD(TAG, "Incrementing scheduler major at %" PRIu64 "ms",
|
320
|
+
now + (static_cast<uint64_t>(this->millis_major_) << 32));
|
330
321
|
}
|
331
322
|
this->last_millis_ = now;
|
332
|
-
return now;
|
323
|
+
return now + (static_cast<uint64_t>(this->millis_major_) << 32);
|
333
324
|
}
|
334
325
|
|
335
326
|
bool HOT Scheduler::SchedulerItem::cmp(const std::unique_ptr<SchedulerItem> &a,
|
336
327
|
const std::unique_ptr<SchedulerItem> &b) {
|
337
|
-
|
338
|
-
// return true if *a* will happen after *b*
|
339
|
-
uint32_t a_next_exec = a->next_execution();
|
340
|
-
uint8_t a_next_exec_major = a->next_execution_major();
|
341
|
-
uint32_t b_next_exec = b->next_execution();
|
342
|
-
uint8_t b_next_exec_major = b->next_execution_major();
|
343
|
-
|
344
|
-
if (a_next_exec_major != b_next_exec_major) {
|
345
|
-
// The "major" calculation is quite complicated.
|
346
|
-
// Basically, we need to check if the major value lies in the future or
|
347
|
-
//
|
348
|
-
|
349
|
-
// Here are some cases to think about:
|
350
|
-
// Format: a_major,b_major -> expected result (a-b, b-a)
|
351
|
-
// a=255,b=0 -> false (255, 1)
|
352
|
-
// a=0,b=1 -> false (255, 1)
|
353
|
-
// a=1,b=0 -> true (1, 255)
|
354
|
-
// a=0,b=255 -> true (1, 255)
|
355
|
-
|
356
|
-
uint8_t diff1 = a_next_exec_major - b_next_exec_major;
|
357
|
-
uint8_t diff2 = b_next_exec_major - a_next_exec_major;
|
358
|
-
return diff1 < diff2;
|
359
|
-
}
|
360
|
-
|
361
|
-
return a_next_exec > b_next_exec;
|
328
|
+
return a->next_execution_ > b->next_execution_;
|
362
329
|
}
|
363
330
|
|
364
331
|
} // namespace esphome
|
esphome/core/scheduler.h
CHANGED
@@ -32,23 +32,10 @@ class Scheduler {
|
|
32
32
|
Component *component;
|
33
33
|
std::string name;
|
34
34
|
enum Type { TIMEOUT, INTERVAL } type;
|
35
|
-
|
36
|
-
|
37
|
-
uint32_t timeout;
|
38
|
-
};
|
39
|
-
uint32_t last_execution;
|
35
|
+
uint32_t interval;
|
36
|
+
uint64_t next_execution_;
|
40
37
|
std::function<void()> callback;
|
41
38
|
bool remove;
|
42
|
-
uint8_t last_execution_major;
|
43
|
-
|
44
|
-
inline uint32_t next_execution() { return this->last_execution + this->timeout; }
|
45
|
-
inline uint8_t next_execution_major() {
|
46
|
-
uint32_t next_exec = this->next_execution();
|
47
|
-
uint8_t next_exec_major = this->last_execution_major;
|
48
|
-
if (next_exec < this->last_execution)
|
49
|
-
next_exec_major++;
|
50
|
-
return next_exec_major;
|
51
|
-
}
|
52
39
|
|
53
40
|
static bool cmp(const std::unique_ptr<SchedulerItem> &a, const std::unique_ptr<SchedulerItem> &b);
|
54
41
|
const char *get_type_str() {
|
@@ -61,9 +48,12 @@ class Scheduler {
|
|
61
48
|
return "";
|
62
49
|
}
|
63
50
|
}
|
51
|
+
const char *get_source() {
|
52
|
+
return this->component != nullptr ? this->component->get_component_source() : "unknown";
|
53
|
+
}
|
64
54
|
};
|
65
55
|
|
66
|
-
|
56
|
+
uint64_t millis_();
|
67
57
|
void cleanup_();
|
68
58
|
void pop_raw_();
|
69
59
|
void push_(std::unique_ptr<SchedulerItem> item);
|
@@ -77,7 +67,7 @@ class Scheduler {
|
|
77
67
|
std::vector<std::unique_ptr<SchedulerItem>> items_;
|
78
68
|
std::vector<std::unique_ptr<SchedulerItem>> to_add_;
|
79
69
|
uint32_t last_millis_{0};
|
80
|
-
|
70
|
+
uint16_t millis_major_{0};
|
81
71
|
uint32_t to_remove_{0};
|
82
72
|
};
|
83
73
|
|
esphome/dashboard/status/mqtt.py
CHANGED
@@ -32,8 +32,6 @@ class MqttStatusThread(threading.Thread):
|
|
32
32
|
topic = "esphome/discover/#"
|
33
33
|
|
34
34
|
def on_message(client, userdata, msg):
|
35
|
-
nonlocal current_entries
|
36
|
-
|
37
35
|
payload = msg.payload.decode(errors="backslashreplace")
|
38
36
|
if len(payload) > 0:
|
39
37
|
data = json.loads(payload)
|
esphome/vscode.py
CHANGED
@@ -78,28 +78,47 @@ def _print_file_read_event(path: str) -> None:
|
|
78
78
|
)
|
79
79
|
|
80
80
|
|
81
|
+
def _request_and_get_stream_on_stdin(fname: str) -> StringIO:
|
82
|
+
_print_file_read_event(fname)
|
83
|
+
raw_yaml_stream = StringIO(_read_file_content_from_json_on_stdin())
|
84
|
+
return raw_yaml_stream
|
85
|
+
|
86
|
+
|
87
|
+
def _vscode_loader(fname: str) -> dict[str, Any]:
|
88
|
+
raw_yaml_stream = _request_and_get_stream_on_stdin(fname)
|
89
|
+
# it is required to set the name on StringIO so document on start_mark
|
90
|
+
# is set properly. Otherwise it is initialized with "<file>"
|
91
|
+
raw_yaml_stream.name = fname
|
92
|
+
return parse_yaml(fname, raw_yaml_stream, _vscode_loader)
|
93
|
+
|
94
|
+
|
95
|
+
def _ace_loader(fname: str) -> dict[str, Any]:
|
96
|
+
raw_yaml_stream = _request_and_get_stream_on_stdin(fname)
|
97
|
+
return parse_yaml(fname, raw_yaml_stream)
|
98
|
+
|
99
|
+
|
81
100
|
def read_config(args):
|
82
101
|
while True:
|
83
102
|
CORE.reset()
|
84
103
|
data = json.loads(input())
|
85
|
-
assert data["type"] == "validate"
|
104
|
+
assert data["type"] == "validate" or data["type"] == "exit"
|
105
|
+
if data["type"] == "exit":
|
106
|
+
return
|
86
107
|
CORE.vscode = True
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
CORE.config_path = os.path.join(args.configuration, f)
|
108
|
+
if args.ace: # Running from ESPHome Compiler dashboard, not vscode
|
109
|
+
CORE.config_path = os.path.join(args.configuration, data["file"])
|
110
|
+
loader = _ace_loader
|
91
111
|
else:
|
92
112
|
CORE.config_path = data["file"]
|
113
|
+
loader = _vscode_loader
|
93
114
|
|
94
115
|
file_name = CORE.config_path
|
95
|
-
_print_file_read_event(file_name)
|
96
|
-
raw_yaml = _read_file_content_from_json_on_stdin()
|
97
116
|
command_line_substitutions: dict[str, Any] = (
|
98
117
|
dict(args.substitution) if args.substitution else {}
|
99
118
|
)
|
100
119
|
vs = VSCodeResult()
|
101
120
|
try:
|
102
|
-
config =
|
121
|
+
config = loader(file_name)
|
103
122
|
res = validate_config(config, command_line_substitutions)
|
104
123
|
except Exception as err: # pylint: disable=broad-except
|
105
124
|
vs.add_yaml_error(str(err))
|
esphome/yaml_util.py
CHANGED
@@ -3,12 +3,12 @@ from __future__ import annotations
|
|
3
3
|
import fnmatch
|
4
4
|
import functools
|
5
5
|
import inspect
|
6
|
-
from io import TextIOWrapper
|
6
|
+
from io import BytesIO, TextIOBase, TextIOWrapper
|
7
7
|
from ipaddress import _BaseAddress
|
8
8
|
import logging
|
9
9
|
import math
|
10
10
|
import os
|
11
|
-
from typing import Any
|
11
|
+
from typing import Any, Callable
|
12
12
|
import uuid
|
13
13
|
|
14
14
|
import yaml
|
@@ -69,7 +69,10 @@ class ESPForceValue:
|
|
69
69
|
pass
|
70
70
|
|
71
71
|
|
72
|
-
def make_data_base(
|
72
|
+
def make_data_base(
|
73
|
+
value, from_database: ESPHomeDataBase = None
|
74
|
+
) -> ESPHomeDataBase | Any:
|
75
|
+
"""Wrap a value in a ESPHomeDataBase object."""
|
73
76
|
try:
|
74
77
|
value = add_class_to_obj(value, ESPHomeDataBase)
|
75
78
|
if from_database is not None:
|
@@ -102,6 +105,11 @@ def _add_data_ref(fn):
|
|
102
105
|
class ESPHomeLoaderMixin:
|
103
106
|
"""Loader class that keeps track of line numbers."""
|
104
107
|
|
108
|
+
def __init__(self, name: str, yaml_loader: Callable[[str], dict[str, Any]]) -> None:
|
109
|
+
"""Initialize the loader."""
|
110
|
+
self.name = name
|
111
|
+
self.yaml_loader = yaml_loader
|
112
|
+
|
105
113
|
@_add_data_ref
|
106
114
|
def construct_yaml_int(self, node):
|
107
115
|
return super().construct_yaml_int(node)
|
@@ -127,7 +135,7 @@ class ESPHomeLoaderMixin:
|
|
127
135
|
return super().construct_yaml_seq(node)
|
128
136
|
|
129
137
|
@_add_data_ref
|
130
|
-
def construct_yaml_map(self, node):
|
138
|
+
def construct_yaml_map(self, node: yaml.MappingNode) -> OrderedDict[str, Any]:
|
131
139
|
"""Traverses the given mapping node and returns a list of constructed key-value pairs."""
|
132
140
|
assert isinstance(node, yaml.MappingNode)
|
133
141
|
# A list of key-value pairs we find in the current mapping
|
@@ -231,7 +239,7 @@ class ESPHomeLoaderMixin:
|
|
231
239
|
return OrderedDict(pairs)
|
232
240
|
|
233
241
|
@_add_data_ref
|
234
|
-
def construct_env_var(self, node):
|
242
|
+
def construct_env_var(self, node: yaml.Node) -> str:
|
235
243
|
args = node.value.split()
|
236
244
|
# Check for a default value
|
237
245
|
if len(args) > 1:
|
@@ -243,23 +251,23 @@ class ESPHomeLoaderMixin:
|
|
243
251
|
)
|
244
252
|
|
245
253
|
@property
|
246
|
-
def _directory(self):
|
254
|
+
def _directory(self) -> str:
|
247
255
|
return os.path.dirname(self.name)
|
248
256
|
|
249
|
-
def _rel_path(self, *args):
|
257
|
+
def _rel_path(self, *args: str) -> str:
|
250
258
|
return os.path.join(self._directory, *args)
|
251
259
|
|
252
260
|
@_add_data_ref
|
253
|
-
def construct_secret(self, node):
|
261
|
+
def construct_secret(self, node: yaml.Node) -> str:
|
254
262
|
try:
|
255
|
-
secrets =
|
263
|
+
secrets = self.yaml_loader(self._rel_path(SECRET_YAML))
|
256
264
|
except EsphomeError as e:
|
257
265
|
if self.name == CORE.config_path:
|
258
266
|
raise e
|
259
267
|
try:
|
260
268
|
main_config_dir = os.path.dirname(CORE.config_path)
|
261
269
|
main_secret_yml = os.path.join(main_config_dir, SECRET_YAML)
|
262
|
-
secrets =
|
270
|
+
secrets = self.yaml_loader(main_secret_yml)
|
263
271
|
except EsphomeError as er:
|
264
272
|
raise EsphomeError(f"{e}\n{er}") from er
|
265
273
|
|
@@ -272,7 +280,9 @@ class ESPHomeLoaderMixin:
|
|
272
280
|
return val
|
273
281
|
|
274
282
|
@_add_data_ref
|
275
|
-
def construct_include(
|
283
|
+
def construct_include(
|
284
|
+
self, node: yaml.Node
|
285
|
+
) -> dict[str, Any] | OrderedDict[str, Any]:
|
276
286
|
from esphome.const import CONF_VARS
|
277
287
|
|
278
288
|
def extract_file_vars(node):
|
@@ -290,71 +300,93 @@ class ESPHomeLoaderMixin:
|
|
290
300
|
else:
|
291
301
|
file, vars = node.value, None
|
292
302
|
|
293
|
-
result =
|
303
|
+
result = self.yaml_loader(self._rel_path(file))
|
294
304
|
if not vars:
|
295
305
|
vars = {}
|
296
306
|
result = substitute_vars(result, vars)
|
297
307
|
return result
|
298
308
|
|
299
309
|
@_add_data_ref
|
300
|
-
def construct_include_dir_list(self, node):
|
310
|
+
def construct_include_dir_list(self, node: yaml.Node) -> list[dict[str, Any]]:
|
301
311
|
files = filter_yaml_files(_find_files(self._rel_path(node.value), "*.yaml"))
|
302
|
-
return [
|
312
|
+
return [self.yaml_loader(f) for f in files]
|
303
313
|
|
304
314
|
@_add_data_ref
|
305
|
-
def construct_include_dir_merge_list(self, node):
|
315
|
+
def construct_include_dir_merge_list(self, node: yaml.Node) -> list[dict[str, Any]]:
|
306
316
|
files = filter_yaml_files(_find_files(self._rel_path(node.value), "*.yaml"))
|
307
317
|
merged_list = []
|
308
318
|
for fname in files:
|
309
|
-
loaded_yaml =
|
319
|
+
loaded_yaml = self.yaml_loader(fname)
|
310
320
|
if isinstance(loaded_yaml, list):
|
311
321
|
merged_list.extend(loaded_yaml)
|
312
322
|
return merged_list
|
313
323
|
|
314
324
|
@_add_data_ref
|
315
|
-
def construct_include_dir_named(
|
325
|
+
def construct_include_dir_named(
|
326
|
+
self, node: yaml.Node
|
327
|
+
) -> OrderedDict[str, dict[str, Any]]:
|
316
328
|
files = filter_yaml_files(_find_files(self._rel_path(node.value), "*.yaml"))
|
317
329
|
mapping = OrderedDict()
|
318
330
|
for fname in files:
|
319
331
|
filename = os.path.splitext(os.path.basename(fname))[0]
|
320
|
-
mapping[filename] =
|
332
|
+
mapping[filename] = self.yaml_loader(fname)
|
321
333
|
return mapping
|
322
334
|
|
323
335
|
@_add_data_ref
|
324
|
-
def construct_include_dir_merge_named(
|
336
|
+
def construct_include_dir_merge_named(
|
337
|
+
self, node: yaml.Node
|
338
|
+
) -> OrderedDict[str, dict[str, Any]]:
|
325
339
|
files = filter_yaml_files(_find_files(self._rel_path(node.value), "*.yaml"))
|
326
340
|
mapping = OrderedDict()
|
327
341
|
for fname in files:
|
328
|
-
loaded_yaml =
|
342
|
+
loaded_yaml = self.yaml_loader(fname)
|
329
343
|
if isinstance(loaded_yaml, dict):
|
330
344
|
mapping.update(loaded_yaml)
|
331
345
|
return mapping
|
332
346
|
|
333
347
|
@_add_data_ref
|
334
|
-
def construct_lambda(self, node):
|
348
|
+
def construct_lambda(self, node: yaml.Node) -> Lambda:
|
335
349
|
return Lambda(str(node.value))
|
336
350
|
|
337
351
|
@_add_data_ref
|
338
|
-
def construct_force(self, node):
|
352
|
+
def construct_force(self, node: yaml.Node) -> ESPForceValue:
|
339
353
|
obj = self.construct_scalar(node)
|
340
354
|
return add_class_to_obj(obj, ESPForceValue)
|
341
355
|
|
342
356
|
@_add_data_ref
|
343
|
-
def construct_extend(self, node):
|
357
|
+
def construct_extend(self, node: yaml.Node) -> Extend:
|
344
358
|
return Extend(str(node.value))
|
345
359
|
|
346
360
|
@_add_data_ref
|
347
|
-
def construct_remove(self, node):
|
361
|
+
def construct_remove(self, node: yaml.Node) -> Remove:
|
348
362
|
return Remove(str(node.value))
|
349
363
|
|
350
364
|
|
351
365
|
class ESPHomeLoader(ESPHomeLoaderMixin, FastestAvailableSafeLoader):
|
352
366
|
"""Loader class that keeps track of line numbers."""
|
353
367
|
|
368
|
+
def __init__(
|
369
|
+
self,
|
370
|
+
stream: TextIOBase | BytesIO,
|
371
|
+
name: str,
|
372
|
+
yaml_loader: Callable[[str], dict[str, Any]],
|
373
|
+
) -> None:
|
374
|
+
FastestAvailableSafeLoader.__init__(self, stream)
|
375
|
+
ESPHomeLoaderMixin.__init__(self, name, yaml_loader)
|
376
|
+
|
354
377
|
|
355
378
|
class ESPHomePurePythonLoader(ESPHomeLoaderMixin, PurePythonLoader):
|
356
379
|
"""Loader class that keeps track of line numbers."""
|
357
380
|
|
381
|
+
def __init__(
|
382
|
+
self,
|
383
|
+
stream: TextIOBase | BytesIO,
|
384
|
+
name: str,
|
385
|
+
yaml_loader: Callable[[str], dict[str, Any]],
|
386
|
+
) -> None:
|
387
|
+
PurePythonLoader.__init__(self, stream)
|
388
|
+
ESPHomeLoaderMixin.__init__(self, name, yaml_loader)
|
389
|
+
|
358
390
|
|
359
391
|
for _loader in (ESPHomeLoader, ESPHomePurePythonLoader):
|
360
392
|
_loader.add_constructor("tag:yaml.org,2002:int", _loader.construct_yaml_int)
|
@@ -388,17 +420,30 @@ def load_yaml(fname: str, clear_secrets: bool = True) -> Any:
|
|
388
420
|
return _load_yaml_internal(fname)
|
389
421
|
|
390
422
|
|
391
|
-
def
|
423
|
+
def _load_yaml_internal(fname: str) -> Any:
|
424
|
+
"""Load a YAML file."""
|
425
|
+
try:
|
426
|
+
with open(fname, encoding="utf-8") as f_handle:
|
427
|
+
return parse_yaml(fname, f_handle)
|
428
|
+
except (UnicodeDecodeError, OSError) as err:
|
429
|
+
raise EsphomeError(f"Error reading file {fname}: {err}") from err
|
430
|
+
|
431
|
+
|
432
|
+
def parse_yaml(
|
433
|
+
file_name: str, file_handle: TextIOWrapper, yaml_loader=_load_yaml_internal
|
434
|
+
) -> Any:
|
392
435
|
"""Parse a YAML file."""
|
393
436
|
try:
|
394
|
-
return _load_yaml_internal_with_type(
|
437
|
+
return _load_yaml_internal_with_type(
|
438
|
+
ESPHomeLoader, file_name, file_handle, yaml_loader
|
439
|
+
)
|
395
440
|
except EsphomeError:
|
396
441
|
# Loading failed, so we now load with the Python loader which has more
|
397
442
|
# readable exceptions
|
398
443
|
# Rewind the stream so we can try again
|
399
444
|
file_handle.seek(0, 0)
|
400
445
|
return _load_yaml_internal_with_type(
|
401
|
-
ESPHomePurePythonLoader, file_name, file_handle
|
446
|
+
ESPHomePurePythonLoader, file_name, file_handle, yaml_loader
|
402
447
|
)
|
403
448
|
|
404
449
|
|
@@ -435,23 +480,14 @@ def substitute_vars(config, vars):
|
|
435
480
|
return result
|
436
481
|
|
437
482
|
|
438
|
-
def _load_yaml_internal(fname: str) -> Any:
|
439
|
-
"""Load a YAML file."""
|
440
|
-
try:
|
441
|
-
with open(fname, encoding="utf-8") as f_handle:
|
442
|
-
return parse_yaml(fname, f_handle)
|
443
|
-
except (UnicodeDecodeError, OSError) as err:
|
444
|
-
raise EsphomeError(f"Error reading file {fname}: {err}") from err
|
445
|
-
|
446
|
-
|
447
483
|
def _load_yaml_internal_with_type(
|
448
484
|
loader_type: type[ESPHomeLoader] | type[ESPHomePurePythonLoader],
|
449
485
|
fname: str,
|
450
486
|
content: TextIOWrapper,
|
487
|
+
yaml_loader: Any,
|
451
488
|
) -> Any:
|
452
489
|
"""Load a YAML file."""
|
453
|
-
loader = loader_type(content)
|
454
|
-
loader.name = fname
|
490
|
+
loader = loader_type(content, fname, yaml_loader)
|
455
491
|
try:
|
456
492
|
return loader.get_single_data() or OrderedDict()
|
457
493
|
except yaml.YAMLError as exc:
|
@@ -470,7 +506,7 @@ def dump(dict_, show_secrets=False):
|
|
470
506
|
)
|
471
507
|
|
472
508
|
|
473
|
-
def _is_file_valid(name):
|
509
|
+
def _is_file_valid(name: str) -> bool:
|
474
510
|
"""Decide if a file is valid."""
|
475
511
|
return not name.startswith(".")
|
476
512
|
|