esphome 2025.4.2__py3-none-any.whl → 2025.5.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 +16 -14
- esphome/components/ac_dimmer/ac_dimmer.cpp +3 -2
- esphome/components/adc/__init__.py +51 -34
- esphome/components/airthings_wave_base/__init__.py +1 -1
- esphome/components/alarm_control_panel/__init__.py +37 -2
- esphome/components/am43/cover/__init__.py +4 -5
- esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
- esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
- esphome/components/analog_threshold/binary_sensor.py +10 -8
- esphome/components/anova/climate.py +4 -5
- esphome/components/api/__init__.py +25 -8
- esphome/components/api/api_connection.cpp +416 -662
- esphome/components/api/api_connection.h +256 -57
- esphome/components/api/api_frame_helper.cpp +232 -177
- esphome/components/api/api_frame_helper.h +61 -8
- esphome/components/api/api_noise_context.h +13 -4
- esphome/components/api/api_pb2.cpp +1422 -1
- esphome/components/api/api_pb2.h +255 -1
- esphome/components/api/api_pb2_service.cpp +162 -49
- esphome/components/api/api_pb2_service.h +90 -51
- esphome/components/api/api_pb2_size.h +361 -0
- esphome/components/api/api_server.cpp +110 -34
- esphome/components/api/api_server.h +8 -0
- esphome/components/api/proto.h +86 -17
- esphome/components/as7341/as7341.h +1 -1
- esphome/components/at581x/at581x.h +4 -4
- esphome/components/atm90e32/__init__.py +1 -0
- esphome/components/atm90e32/atm90e32.cpp +576 -199
- esphome/components/atm90e32/atm90e32.h +128 -31
- esphome/components/atm90e32/atm90e32_reg.h +4 -2
- esphome/components/atm90e32/button/__init__.py +62 -10
- esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
- esphome/components/atm90e32/button/atm90e32_button.h +36 -4
- esphome/components/atm90e32/number/__init__.py +130 -0
- esphome/components/atm90e32/number/atm90e32_number.h +16 -0
- esphome/components/atm90e32/sensor.py +21 -4
- esphome/components/atm90e32/text_sensor/__init__.py +48 -0
- esphome/components/audio/__init__.py +96 -49
- esphome/components/audio/audio.h +48 -0
- esphome/components/audio/audio_decoder.cpp +1 -1
- esphome/components/audio/audio_resampler.cpp +2 -0
- esphome/components/audio/audio_resampler.h +1 -0
- esphome/components/ballu/climate.py +2 -9
- esphome/components/bang_bang/climate.py +5 -6
- esphome/components/bedjet/bedjet_hub.cpp +1 -0
- esphome/components/bedjet/climate/__init__.py +3 -8
- esphome/components/bedjet/fan/__init__.py +2 -11
- esphome/components/binary/fan/__init__.py +13 -16
- esphome/components/binary_sensor/__init__.py +13 -10
- esphome/components/bl0906/constants.h +16 -16
- esphome/components/ble_client/text_sensor/__init__.py +3 -5
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +136 -21
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
- esphome/components/button/__init__.py +11 -8
- esphome/components/canbus/canbus.cpp +3 -0
- esphome/components/canbus/canbus.h +16 -0
- esphome/components/ccs811/sensor.py +9 -6
- esphome/components/climate/__init__.py +35 -2
- esphome/components/climate/climate_mode.h +1 -1
- esphome/components/climate/climate_traits.h +63 -57
- esphome/components/climate_ir/__init__.py +57 -17
- esphome/components/climate_ir_lg/climate.py +2 -5
- esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
- esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
- esphome/components/color/__init__.py +2 -0
- esphome/components/const/__init__.py +5 -0
- esphome/components/coolix/climate.py +2 -9
- esphome/components/copy/cover/__init__.py +10 -9
- esphome/components/copy/fan/__init__.py +11 -9
- esphome/components/copy/lock/__init__.py +11 -9
- esphome/components/copy/text/__init__.py +9 -6
- esphome/components/cover/__init__.py +37 -2
- esphome/components/cse7766/cse7766.cpp +2 -1
- esphome/components/cst226/binary_sensor/__init__.py +28 -0
- esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
- esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
- esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
- esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
- esphome/components/current_based/cover.py +37 -36
- esphome/components/current_based/current_based_cover.cpp +2 -1
- esphome/components/daikin/climate.py +2 -9
- esphome/components/daikin/daikin.cpp +15 -9
- esphome/components/daikin/daikin.h +5 -5
- esphome/components/daikin_arc/climate.py +2 -7
- esphome/components/daikin_brc/climate.py +3 -5
- esphome/components/dallas_temp/dallas_temp.cpp +17 -24
- esphome/components/dallas_temp/dallas_temp.h +0 -1
- esphome/components/daly_bms/daly_bms.cpp +2 -1
- esphome/components/debug/debug_component.cpp +6 -1
- esphome/components/debug/debug_component.h +8 -0
- esphome/components/debug/debug_esp32.cpp +109 -254
- esphome/components/debug/sensor.py +14 -0
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
- esphome/components/delonghi/climate.py +2 -9
- esphome/components/demo/__init__.py +18 -20
- esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
- esphome/components/dps310/sensor.py +6 -6
- esphome/components/ee895/sensor.py +9 -9
- esphome/components/emmeti/climate.py +2 -9
- esphome/components/endstop/cover.py +17 -16
- esphome/components/endstop/endstop_cover.cpp +2 -1
- esphome/components/ens160_base/__init__.py +12 -9
- esphome/components/esp32/__init__.py +60 -3
- esphome/components/esp32/core.cpp +11 -5
- esphome/components/esp32/gpio.cpp +86 -24
- esphome/components/esp32/gpio.py +15 -16
- esphome/components/esp32/gpio_esp32.py +1 -2
- esphome/components/esp32/gpio_esp32_c2.py +1 -1
- esphome/components/esp32/gpio_esp32_c3.py +1 -1
- esphome/components/esp32/gpio_esp32_c6.py +1 -1
- esphome/components/esp32/gpio_esp32_h2.py +1 -1
- esphome/components/esp32_ble/ble.cpp +1 -0
- esphome/components/esp32_ble/ble.h +5 -3
- esphome/components/esp32_ble/ble_advertising.cpp +2 -1
- esphome/components/esp32_ble/ble_advertising.h +1 -0
- esphome/components/esp32_ble_server/__init__.py +3 -0
- esphome/components/esp32_ble_tracker/__init__.py +7 -1
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
- esphome/components/esp32_camera/__init__.py +1 -1
- esphome/components/esp32_camera/esp32_camera.cpp +2 -10
- esphome/components/esp32_camera/esp32_camera.h +1 -1
- esphome/components/esp32_can/esp32_can.cpp +1 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
- esphome/components/esp32_rmt_led_strip/light.py +9 -1
- esphome/components/esp32_touch/esp32_touch.cpp +1 -1
- esphome/components/esp8266/gpio.cpp +69 -8
- esphome/components/ethernet/ethernet_component.cpp +1 -1
- esphome/components/event/__init__.py +13 -10
- esphome/components/factory_reset/switch/__init__.py +7 -21
- esphome/components/fan/__init__.py +52 -5
- esphome/components/fastled_base/__init__.py +1 -4
- esphome/components/fastled_base/fastled_light.cpp +1 -1
- esphome/components/feedback/cover.py +38 -33
- esphome/components/feedback/feedback_cover.cpp +2 -1
- esphome/components/fujitsu_general/climate.py +2 -9
- esphome/components/gcja5/gcja5.cpp +2 -1
- esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
- esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
- esphome/components/gpio_expander/cached_gpio.h +22 -7
- esphome/components/gps/__init__.py +47 -17
- esphome/components/gps/gps.cpp +42 -23
- esphome/components/gps/gps.h +17 -13
- esphome/components/graph/__init__.py +1 -2
- esphome/components/gree/climate.py +4 -6
- esphome/components/gree/gree.cpp +16 -2
- esphome/components/gree/gree.h +2 -2
- esphome/components/growatt_solar/growatt_solar.cpp +2 -1
- esphome/components/haier/climate.py +37 -34
- esphome/components/hbridge/fan/__init__.py +19 -17
- esphome/components/he60r/cover.py +4 -5
- esphome/components/heatpumpir/climate.py +3 -6
- esphome/components/hitachi_ac344/climate.py +2 -9
- esphome/components/hitachi_ac424/climate.py +2 -9
- esphome/components/hm3301/hm3301.h +1 -1
- esphome/components/hte501/sensor.py +6 -6
- esphome/components/http_request/__init__.py +39 -6
- esphome/components/http_request/http_request.cpp +20 -0
- esphome/components/http_request/http_request.h +57 -15
- esphome/components/http_request/http_request_arduino.cpp +22 -6
- esphome/components/http_request/http_request_arduino.h +4 -3
- esphome/components/http_request/http_request_host.cpp +141 -0
- esphome/components/http_request/http_request_host.h +37 -0
- esphome/components/http_request/http_request_idf.cpp +35 -3
- esphome/components/http_request/http_request_idf.h +10 -3
- esphome/components/http_request/httplib.h +9691 -0
- esphome/components/http_request/update/__init__.py +11 -8
- esphome/components/hyt271/sensor.py +6 -6
- esphome/components/i2c/i2c.h +4 -0
- esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
- esphome/components/i2s_audio/__init__.py +131 -22
- esphome/components/i2s_audio/i2s_audio.h +44 -4
- esphome/components/i2s_audio/media_player/__init__.py +19 -9
- esphome/components/i2s_audio/microphone/__init__.py +63 -5
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
- esphome/components/i2s_audio/speaker/__init__.py +31 -5
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
- esphome/components/ili9xxx/ili9xxx_init.h +1 -1
- esphome/components/image/__init__.py +37 -17
- esphome/components/image/image.cpp +25 -8
- esphome/components/internal_temperature/internal_temperature.cpp +6 -4
- esphome/components/key_collector/__init__.py +35 -0
- esphome/components/key_collector/key_collector.cpp +8 -0
- esphome/components/key_collector/key_collector.h +10 -0
- esphome/components/kuntze/kuntze.cpp +2 -1
- esphome/components/ld2410/ld2410.h +1 -1
- esphome/components/ld2450/ld2450.h +1 -1
- esphome/components/light/__init__.py +57 -0
- esphome/components/lock/__init__.py +51 -4
- esphome/components/lock/automation.h +2 -13
- esphome/components/logger/__init__.py +22 -0
- esphome/components/logger/logger.cpp +154 -103
- esphome/components/logger/logger.h +211 -36
- esphome/components/logger/task_log_buffer.cpp +138 -0
- esphome/components/logger/task_log_buffer.h +69 -0
- esphome/components/lvgl/__init__.py +13 -5
- esphome/components/lvgl/automation.py +50 -1
- esphome/components/lvgl/defines.py +0 -1
- esphome/components/lvgl/lvgl_esphome.cpp +5 -1
- esphome/components/lvgl/text/__init__.py +1 -2
- esphome/components/mapping/__init__.py +134 -0
- esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
- esphome/components/max7219digit/max7219digit.cpp +28 -27
- esphome/components/mdns/__init__.py +11 -5
- esphome/components/mdns/mdns_component.cpp +11 -5
- esphome/components/mdns/mdns_component.h +3 -2
- esphome/components/mdns/mdns_esp32.cpp +4 -3
- esphome/components/mdns/mdns_esp8266.cpp +4 -2
- esphome/components/mdns/mdns_libretiny.cpp +4 -2
- esphome/components/mdns/mdns_rp2040.cpp +4 -2
- esphome/components/media_player/__init__.py +33 -1
- esphome/components/mhz19/sensor.py +11 -7
- esphome/components/micro_wake_word/__init__.py +99 -31
- esphome/components/micro_wake_word/automation.h +54 -0
- esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
- esphome/components/micro_wake_word/micro_wake_word.h +58 -105
- esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
- esphome/components/micro_wake_word/streaming_model.cpp +158 -41
- esphome/components/micro_wake_word/streaming_model.h +85 -13
- esphome/components/microphone/__init__.py +139 -9
- esphome/components/microphone/automation.h +14 -2
- esphome/components/microphone/microphone.cpp +21 -0
- esphome/components/microphone/microphone.h +14 -5
- esphome/components/microphone/microphone_source.cpp +95 -0
- esphome/components/microphone/microphone_source.h +80 -0
- esphome/components/mics_4514/sensor.py +25 -14
- esphome/components/midea/climate.py +3 -4
- esphome/components/midea_ir/climate.py +3 -5
- esphome/components/mipi_spi/__init__.py +15 -0
- esphome/components/mipi_spi/display.py +474 -0
- esphome/components/mipi_spi/mipi_spi.cpp +481 -0
- esphome/components/mipi_spi/mipi_spi.h +171 -0
- esphome/components/mipi_spi/models/__init__.py +65 -0
- esphome/components/mipi_spi/models/amoled.py +72 -0
- esphome/components/mipi_spi/models/commands.py +82 -0
- esphome/components/mipi_spi/models/cyd.py +10 -0
- esphome/components/mipi_spi/models/ili.py +749 -0
- esphome/components/mipi_spi/models/jc.py +260 -0
- esphome/components/mipi_spi/models/lanbon.py +15 -0
- esphome/components/mipi_spi/models/lilygo.py +60 -0
- esphome/components/mipi_spi/models/waveshare.py +139 -0
- esphome/components/mitsubishi/climate.py +2 -5
- esphome/components/mitsubishi/mitsubishi.cpp +9 -9
- esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
- esphome/components/mixer/speaker/mixer_speaker.h +1 -3
- esphome/components/mlx90393/sensor.py +5 -0
- esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
- esphome/components/mlx90393/sensor_mlx90393.h +21 -4
- esphome/components/modbus/modbus.cpp +2 -1
- esphome/components/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +6 -2
- esphome/components/mqtt/mqtt_const.h +4 -0
- esphome/components/mqtt/mqtt_fan.cpp +39 -0
- esphome/components/mqtt/mqtt_fan.h +2 -0
- esphome/components/ms5611/sensor.py +6 -6
- esphome/components/ms8607/sensor.py +3 -3
- esphome/components/network/__init__.py +1 -1
- esphome/components/nextion/base_component.py +17 -16
- esphome/components/nextion/display.py +11 -2
- esphome/components/nextion/nextion.cpp +39 -1
- esphome/components/nextion/nextion.h +50 -0
- esphome/components/noblex/climate.py +2 -9
- esphome/components/number/__init__.py +12 -9
- esphome/components/one_wire/one_wire_bus.cpp +14 -10
- esphome/components/one_wire/one_wire_bus.h +14 -8
- esphome/components/online_image/bmp_image.cpp +48 -11
- esphome/components/online_image/bmp_image.h +2 -0
- esphome/components/opentherm/binary_sensor/__init__.py +2 -4
- esphome/components/opentherm/number/__init__.py +11 -20
- esphome/components/opentherm/sensor/__init__.py +3 -3
- esphome/components/opentherm/switch/__init__.py +3 -5
- esphome/components/output/lock/__init__.py +11 -9
- esphome/components/packages/__init__.py +33 -31
- esphome/components/packet_transport/__init__.py +201 -0
- esphome/components/packet_transport/binary_sensor.py +19 -0
- esphome/components/packet_transport/packet_transport.cpp +534 -0
- esphome/components/packet_transport/packet_transport.h +154 -0
- esphome/components/packet_transport/sensor.py +19 -0
- esphome/components/pca9685/pca9685_output.cpp +2 -1
- esphome/components/pid/climate.py +2 -4
- esphome/components/pm2005/__init__.py +1 -0
- esphome/components/pm2005/pm2005.cpp +123 -0
- esphome/components/pm2005/pm2005.h +46 -0
- esphome/components/pm2005/sensor.py +86 -0
- esphome/components/pmsa003i/pmsa003i.cpp +43 -16
- esphome/components/pmsa003i/pmsa003i.h +25 -25
- esphome/components/pmsx003/pmsx003.cpp +195 -230
- esphome/components/pmsx003/pmsx003.h +51 -33
- esphome/components/pmsx003/sensor.py +21 -11
- esphome/components/pn7150/pn7150.h +2 -2
- esphome/components/pn7160/pn7160.h +2 -2
- esphome/components/prometheus/prometheus_handler.cpp +174 -0
- esphome/components/prometheus/prometheus_handler.h +17 -0
- esphome/components/psram/__init__.py +7 -5
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
- esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
- esphome/components/pzem004t/pzem004t.cpp +2 -1
- esphome/components/qspi_dbi/__init__.py +0 -1
- esphome/components/qspi_dbi/display.py +2 -1
- esphome/components/qspi_dbi/models.py +1 -2
- esphome/components/remote_base/__init__.py +91 -0
- esphome/components/remote_base/beo4_protocol.cpp +153 -0
- esphome/components/remote_base/beo4_protocol.h +43 -0
- esphome/components/remote_base/gobox_protocol.cpp +131 -0
- esphome/components/remote_base/gobox_protocol.h +54 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
- esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
- esphome/components/resampler/speaker/resampler_speaker.h +1 -1
- esphome/components/rf_bridge/rf_bridge.cpp +2 -1
- esphome/components/scd30/sensor.py +2 -3
- esphome/components/scd4x/sensor.py +4 -5
- esphome/components/sdp3x/sensor.py +2 -1
- esphome/components/sds011/sds011.cpp +2 -1
- esphome/components/select/__init__.py +19 -20
- esphome/components/sen5x/sen5x.cpp +55 -36
- esphome/components/sen5x/sensor.py +1 -1
- esphome/components/senseair/sensor.py +3 -3
- esphome/components/sensor/__init__.py +158 -14
- esphome/components/sensor/filter.cpp +23 -0
- esphome/components/sensor/filter.h +22 -0
- esphome/components/sgp30/sensor.py +14 -16
- esphome/components/sgp4x/sensor.py +1 -1
- esphome/components/sht4x/sht4x.cpp +43 -22
- esphome/components/sht4x/sht4x.h +1 -1
- esphome/components/shtcx/sensor.py +6 -6
- esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
- esphome/components/sml/text_sensor/__init__.py +4 -6
- esphome/components/sound_level/__init__.py +0 -0
- esphome/components/sound_level/sensor.py +97 -0
- esphome/components/sound_level/sound_level.cpp +194 -0
- esphome/components/sound_level/sound_level.h +73 -0
- esphome/components/speaker/media_player/__init__.py +4 -8
- esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
- esphome/components/speaker/media_player/speaker_media_player.h +0 -11
- esphome/components/speaker/speaker.h +4 -7
- esphome/components/speed/fan/__init__.py +17 -16
- esphome/components/spi/spi.h +11 -1
- esphome/components/sprinkler/__init__.py +18 -19
- esphome/components/sprinkler/sprinkler.cpp +6 -5
- esphome/components/switch/__init__.py +32 -42
- esphome/components/syslog/__init__.py +41 -0
- esphome/components/syslog/esphome_syslog.cpp +49 -0
- esphome/components/syslog/esphome_syslog.h +27 -0
- esphome/components/t6615/sensor.py +3 -3
- esphome/components/t6615/t6615.cpp +2 -1
- esphome/components/tca9555/tca9555.cpp +11 -6
- esphome/components/tcl112/climate.py +2 -9
- esphome/components/template/alarm_control_panel/__init__.py +7 -6
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
- esphome/components/template/cover/__init__.py +27 -21
- esphome/components/template/fan/__init__.py +14 -12
- esphome/components/template/lock/__init__.py +20 -25
- esphome/components/template/lock/automation.h +18 -0
- esphome/components/template/text/__init__.py +4 -3
- esphome/components/template/valve/__init__.py +32 -21
- esphome/components/template/valve/automation.h +24 -0
- esphome/components/text/__init__.py +32 -1
- esphome/components/text_sensor/__init__.py +24 -29
- esphome/components/thermostat/climate.py +5 -5
- esphome/components/time_based/cover.py +17 -16
- esphome/components/time_based/time_based_cover.cpp +2 -1
- esphome/components/tm1638/switch/__init__.py +10 -7
- esphome/components/tormatic/cover.py +4 -5
- esphome/components/toshiba/climate.py +3 -5
- esphome/components/touchscreen/touchscreen.cpp +3 -1
- esphome/components/tuya/climate/__init__.py +5 -6
- esphome/components/tuya/cover/__init__.py +6 -11
- esphome/components/tuya/select/__init__.py +15 -5
- esphome/components/tuya/select/tuya_select.cpp +6 -1
- esphome/components/tuya/select/tuya_select.h +5 -1
- esphome/components/uart/packet_transport/__init__.py +20 -0
- esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
- esphome/components/uart/packet_transport/uart_transport.h +41 -0
- esphome/components/uart/switch/uart_switch.cpp +2 -1
- esphome/components/udp/__init__.py +126 -128
- esphome/components/udp/automation.h +40 -0
- esphome/components/udp/binary_sensor.py +3 -25
- esphome/components/udp/packet_transport/__init__.py +29 -0
- esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
- esphome/components/udp/packet_transport/udp_transport.h +28 -0
- esphome/components/udp/sensor.py +3 -25
- esphome/components/udp/udp_component.cpp +26 -470
- esphome/components/udp/udp_component.h +21 -128
- esphome/components/update/__init__.py +31 -1
- esphome/components/uponor_smatrix/climate/__init__.py +4 -9
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
- esphome/components/uptime/text_sensor/__init__.py +47 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
- esphome/components/valve/__init__.py +34 -3
- esphome/components/valve/automation.h +1 -19
- esphome/components/vl53l0x/sensor.py +11 -0
- esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
- esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
- esphome/components/voice_assistant/__init__.py +36 -10
- esphome/components/voice_assistant/voice_assistant.cpp +170 -144
- esphome/components/voice_assistant/voice_assistant.h +26 -25
- esphome/components/waveshare_epaper/display.py +6 -0
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
- esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
- esphome/components/weikai/weikai.cpp +0 -52
- esphome/components/whirlpool/climate.py +3 -5
- esphome/components/whynter/climate.py +3 -5
- esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
- esphome/components/yashima/climate.py +6 -6
- esphome/components/zhlt01/climate.py +2 -7
- esphome/config.py +13 -13
- esphome/config_validation.py +38 -58
- esphome/const.py +15 -1
- esphome/core/__init__.py +2 -0
- esphome/core/application.cpp +27 -10
- esphome/core/application.h +9 -1
- esphome/core/automation.h +4 -3
- esphome/core/component.cpp +28 -7
- esphome/core/component.h +10 -1
- esphome/core/defines.h +23 -17
- esphome/core/doxygen.h +13 -0
- esphome/core/macros.h +4 -0
- esphome/core/scheduler.cpp +7 -1
- esphome/cpp_generator.py +6 -2
- esphome/dashboard/web_server.py +3 -3
- esphome/helpers.py +39 -0
- esphome/loader.py +4 -0
- esphome/log.py +15 -19
- esphome/mqtt.py +23 -10
- esphome/platformio_api.py +1 -1
- esphome/schema_extractors.py +0 -1
- esphome/voluptuous_schema.py +3 -1
- esphome/vscode.py +15 -0
- esphome/wizard.py +47 -37
- esphome/zeroconf.py +7 -3
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/METADATA +10 -11
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/RECORD +444 -383
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/WHEEL +1 -1
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
import esphome.codegen as cg
|
2
2
|
from esphome.components import climate_ir
|
3
3
|
import esphome.config_validation as cv
|
4
|
-
from esphome.const import
|
4
|
+
from esphome.const import CONF_MODEL
|
5
5
|
|
6
6
|
AUTO_LOAD = ["climate_ir"]
|
7
7
|
CODEOWNERS = ["@glmnet"]
|
@@ -15,15 +15,13 @@ MODELS = {
|
|
15
15
|
"DG11J1-91": Model.MODEL_DG11J1_91,
|
16
16
|
}
|
17
17
|
|
18
|
-
CONFIG_SCHEMA = climate_ir.
|
18
|
+
CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(WhirlpoolClimate).extend(
|
19
19
|
{
|
20
|
-
cv.GenerateID(): cv.declare_id(WhirlpoolClimate),
|
21
20
|
cv.Optional(CONF_MODEL, default="DG11J1-3A"): cv.enum(MODELS, upper=True),
|
22
21
|
}
|
23
22
|
)
|
24
23
|
|
25
24
|
|
26
25
|
async def to_code(config):
|
27
|
-
var =
|
28
|
-
await climate_ir.register_climate_ir(var, config)
|
26
|
+
var = await climate_ir.new_climate_ir(config)
|
29
27
|
cg.add(var.set_model(config[CONF_MODEL]))
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import esphome.codegen as cg
|
2
2
|
from esphome.components import climate_ir
|
3
3
|
import esphome.config_validation as cv
|
4
|
-
from esphome.const import
|
4
|
+
from esphome.const import CONF_USE_FAHRENHEIT
|
5
5
|
|
6
6
|
AUTO_LOAD = ["climate_ir"]
|
7
7
|
|
@@ -9,15 +9,13 @@ whynter_ns = cg.esphome_ns.namespace("whynter")
|
|
9
9
|
Whynter = whynter_ns.class_("Whynter", climate_ir.ClimateIR)
|
10
10
|
|
11
11
|
|
12
|
-
CONFIG_SCHEMA = climate_ir.
|
12
|
+
CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(Whynter).extend(
|
13
13
|
{
|
14
|
-
cv.GenerateID(): cv.declare_id(Whynter),
|
15
14
|
cv.Optional(CONF_USE_FAHRENHEIT, default=False): cv.boolean,
|
16
15
|
}
|
17
16
|
)
|
18
17
|
|
19
18
|
|
20
19
|
async def to_code(config):
|
21
|
-
var =
|
22
|
-
await climate_ir.register_climate_ir(var, config)
|
20
|
+
var = await climate_ir.new_climate_ir(config)
|
23
21
|
cg.add(var.set_fahrenheit(config[CONF_USE_FAHRENHEIT]))
|
@@ -32,7 +32,7 @@ void XPT2046Component::update_touches() {
|
|
32
32
|
|
33
33
|
int16_t touch_pressure_1 = this->read_adc_(0xB1 /* touch_pressure_1 */);
|
34
34
|
int16_t touch_pressure_2 = this->read_adc_(0xC1 /* touch_pressure_2 */);
|
35
|
-
z_raw = touch_pressure_1 +
|
35
|
+
z_raw = touch_pressure_1 + 0xfff - touch_pressure_2;
|
36
36
|
ESP_LOGVV(TAG, "Touchscreen Update z = %d", z_raw);
|
37
37
|
touch = (z_raw >= this->threshold_);
|
38
38
|
if (touch) {
|
@@ -2,7 +2,7 @@ import esphome.codegen as cg
|
|
2
2
|
from esphome.components import climate, remote_transmitter, sensor
|
3
3
|
from esphome.components.remote_base import CONF_TRANSMITTER_ID
|
4
4
|
import esphome.config_validation as cv
|
5
|
-
from esphome.const import
|
5
|
+
from esphome.const import CONF_SENSOR, CONF_SUPPORTS_COOL, CONF_SUPPORTS_HEAT
|
6
6
|
|
7
7
|
AUTO_LOAD = ["sensor"]
|
8
8
|
|
@@ -10,9 +10,9 @@ yashima_ns = cg.esphome_ns.namespace("yashima")
|
|
10
10
|
YashimaClimate = yashima_ns.class_("YashimaClimate", climate.Climate, cg.Component)
|
11
11
|
|
12
12
|
CONFIG_SCHEMA = cv.All(
|
13
|
-
climate.
|
13
|
+
climate.climate_schema(YashimaClimate)
|
14
|
+
.extend(
|
14
15
|
{
|
15
|
-
cv.GenerateID(): cv.declare_id(YashimaClimate),
|
16
16
|
cv.GenerateID(CONF_TRANSMITTER_ID): cv.use_id(
|
17
17
|
remote_transmitter.RemoteTransmitterComponent
|
18
18
|
),
|
@@ -20,14 +20,14 @@ CONFIG_SCHEMA = cv.All(
|
|
20
20
|
cv.Optional(CONF_SUPPORTS_HEAT, default=True): cv.boolean,
|
21
21
|
cv.Optional(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
22
22
|
}
|
23
|
-
)
|
23
|
+
)
|
24
|
+
.extend(cv.COMPONENT_SCHEMA)
|
24
25
|
)
|
25
26
|
|
26
27
|
|
27
28
|
async def to_code(config):
|
28
|
-
var =
|
29
|
+
var = await climate.new_climate(config)
|
29
30
|
await cg.register_component(var, config)
|
30
|
-
await climate.register_climate(var, config)
|
31
31
|
|
32
32
|
cg.add(var.set_supports_cool(config[CONF_SUPPORTS_COOL]))
|
33
33
|
cg.add(var.set_supports_heat(config[CONF_SUPPORTS_HEAT]))
|
@@ -1,7 +1,5 @@
|
|
1
1
|
import esphome.codegen as cg
|
2
2
|
from esphome.components import climate_ir
|
3
|
-
import esphome.config_validation as cv
|
4
|
-
from esphome.const import CONF_ID
|
5
3
|
|
6
4
|
AUTO_LOAD = ["climate_ir"]
|
7
5
|
CODEOWNERS = ["@cfeenstra1024"]
|
@@ -9,11 +7,8 @@ CODEOWNERS = ["@cfeenstra1024"]
|
|
9
7
|
zhlt01_ns = cg.esphome_ns.namespace("zhlt01")
|
10
8
|
ZHLT01Climate = zhlt01_ns.class_("ZHLT01Climate", climate_ir.ClimateIR)
|
11
9
|
|
12
|
-
CONFIG_SCHEMA = climate_ir.
|
13
|
-
{cv.GenerateID(): cv.declare_id(ZHLT01Climate)}
|
14
|
-
)
|
10
|
+
CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(ZHLT01Climate)
|
15
11
|
|
16
12
|
|
17
13
|
async def to_code(config):
|
18
|
-
|
19
|
-
await climate_ir.register_climate_ir(var, config)
|
14
|
+
await climate_ir.new_climate_ir(config)
|
esphome/config.py
CHANGED
@@ -28,7 +28,7 @@ import esphome.core.config as core_config
|
|
28
28
|
import esphome.final_validate as fv
|
29
29
|
from esphome.helpers import indent
|
30
30
|
from esphome.loader import ComponentManifest, get_component, get_platform
|
31
|
-
from esphome.log import
|
31
|
+
from esphome.log import AnsiFore, color
|
32
32
|
from esphome.types import ConfigFragmentType, ConfigType
|
33
33
|
from esphome.util import OrderedDict, safe_print
|
34
34
|
from esphome.voluptuous_schema import ExtraKeysInvalid
|
@@ -959,7 +959,7 @@ def line_info(config, path, highlight=True):
|
|
959
959
|
if obj:
|
960
960
|
mark = obj.start_mark
|
961
961
|
source = f"[source {mark.document}:{mark.line + 1}]"
|
962
|
-
return color(
|
962
|
+
return color(AnsiFore.CYAN, source)
|
963
963
|
return "None"
|
964
964
|
|
965
965
|
|
@@ -983,7 +983,7 @@ def dump_dict(
|
|
983
983
|
if at_root:
|
984
984
|
error = config.get_error_for_path(path)
|
985
985
|
if error is not None:
|
986
|
-
ret += f"\n{color(
|
986
|
+
ret += f"\n{color(AnsiFore.BOLD_RED, _format_vol_invalid(error, config))}\n"
|
987
987
|
|
988
988
|
if isinstance(conf, (list, tuple)):
|
989
989
|
multiline = True
|
@@ -995,11 +995,11 @@ def dump_dict(
|
|
995
995
|
path_ = path + [i]
|
996
996
|
error = config.get_error_for_path(path_)
|
997
997
|
if error is not None:
|
998
|
-
ret += f"\n{color(
|
998
|
+
ret += f"\n{color(AnsiFore.BOLD_RED, _format_vol_invalid(error, config))}\n"
|
999
999
|
|
1000
1000
|
sep = "- "
|
1001
1001
|
if config.is_in_error_path(path_):
|
1002
|
-
sep = color(
|
1002
|
+
sep = color(AnsiFore.RED, sep)
|
1003
1003
|
msg, _ = dump_dict(config, path_, at_root=False)
|
1004
1004
|
msg = indent(msg)
|
1005
1005
|
inf = line_info(config, path_, highlight=config.is_in_error_path(path_))
|
@@ -1018,11 +1018,11 @@ def dump_dict(
|
|
1018
1018
|
path_ = path + [k]
|
1019
1019
|
error = config.get_error_for_path(path_)
|
1020
1020
|
if error is not None:
|
1021
|
-
ret += f"\n{color(
|
1021
|
+
ret += f"\n{color(AnsiFore.BOLD_RED, _format_vol_invalid(error, config))}\n"
|
1022
1022
|
|
1023
1023
|
st = f"{k}: "
|
1024
1024
|
if config.is_in_error_path(path_):
|
1025
|
-
st = color(
|
1025
|
+
st = color(AnsiFore.RED, st)
|
1026
1026
|
msg, m = dump_dict(config, path_, at_root=False)
|
1027
1027
|
|
1028
1028
|
inf = line_info(config, path_, highlight=config.is_in_error_path(path_))
|
@@ -1044,7 +1044,7 @@ def dump_dict(
|
|
1044
1044
|
if len(conf) > 80:
|
1045
1045
|
conf = f"|-\n{indent(conf)}"
|
1046
1046
|
error = config.get_error_for_path(path)
|
1047
|
-
col =
|
1047
|
+
col = AnsiFore.BOLD_RED if error else AnsiFore.KEEP
|
1048
1048
|
ret += color(col, str(conf))
|
1049
1049
|
elif isinstance(conf, core.Lambda):
|
1050
1050
|
if is_secret(conf):
|
@@ -1052,13 +1052,13 @@ def dump_dict(
|
|
1052
1052
|
|
1053
1053
|
conf = f"!lambda |-\n{indent(str(conf.value))}"
|
1054
1054
|
error = config.get_error_for_path(path)
|
1055
|
-
col =
|
1055
|
+
col = AnsiFore.BOLD_RED if error else AnsiFore.KEEP
|
1056
1056
|
ret += color(col, conf)
|
1057
1057
|
elif conf is None:
|
1058
1058
|
pass
|
1059
1059
|
else:
|
1060
1060
|
error = config.get_error_for_path(path)
|
1061
|
-
col =
|
1061
|
+
col = AnsiFore.BOLD_RED if error else AnsiFore.KEEP
|
1062
1062
|
ret += color(col, str(conf))
|
1063
1063
|
multiline = "\n" in ret
|
1064
1064
|
|
@@ -1100,13 +1100,13 @@ def read_config(command_line_substitutions):
|
|
1100
1100
|
if not CORE.verbose:
|
1101
1101
|
res = strip_default_ids(res)
|
1102
1102
|
|
1103
|
-
safe_print(color(
|
1103
|
+
safe_print(color(AnsiFore.BOLD_RED, "Failed config"))
|
1104
1104
|
safe_print("")
|
1105
1105
|
for path, domain in res.output_paths:
|
1106
1106
|
if not res.is_in_error_path(path):
|
1107
1107
|
continue
|
1108
1108
|
|
1109
|
-
errstr = color(
|
1109
|
+
errstr = color(AnsiFore.BOLD_RED, f"{domain}:")
|
1110
1110
|
errline = line_info(res, path)
|
1111
1111
|
if errline:
|
1112
1112
|
errstr += f" {errline}"
|
@@ -1121,7 +1121,7 @@ def read_config(command_line_substitutions):
|
|
1121
1121
|
safe_print(indent("\n".join(split_dump[:i])))
|
1122
1122
|
|
1123
1123
|
for err in res.errors:
|
1124
|
-
safe_print(color(
|
1124
|
+
safe_print(color(AnsiFore.BOLD_RED, err.msg))
|
1125
1125
|
safe_print("")
|
1126
1126
|
|
1127
1127
|
return None
|
esphome/config_validation.py
CHANGED
@@ -56,7 +56,6 @@ from esphome.const import (
|
|
56
56
|
KEY_CORE,
|
57
57
|
KEY_FRAMEWORK_VERSION,
|
58
58
|
KEY_TARGET_FRAMEWORK,
|
59
|
-
KEY_TARGET_PLATFORM,
|
60
59
|
PLATFORM_ESP32,
|
61
60
|
PLATFORM_ESP8266,
|
62
61
|
PLATFORM_RP2040,
|
@@ -117,7 +116,7 @@ RequiredFieldInvalid = vol.RequiredFieldInvalid
|
|
117
116
|
ROOT_CONFIG_PATH = object()
|
118
117
|
|
119
118
|
RESERVED_IDS = [
|
120
|
-
# C++ keywords
|
119
|
+
# C++ keywords https://en.cppreference.com/w/cpp/keyword
|
121
120
|
"alarm",
|
122
121
|
"alignas",
|
123
122
|
"alignof",
|
@@ -1942,70 +1941,28 @@ def platformio_version_constraint(value):
|
|
1942
1941
|
|
1943
1942
|
def require_framework_version(
|
1944
1943
|
*,
|
1945
|
-
esp_idf=None,
|
1946
|
-
esp32_arduino=None,
|
1947
|
-
esp8266_arduino=None,
|
1948
|
-
rp2040_arduino=None,
|
1949
|
-
bk72xx_libretiny=None,
|
1950
|
-
host=None,
|
1951
1944
|
max_version=False,
|
1952
1945
|
extra_message=None,
|
1946
|
+
**kwargs,
|
1953
1947
|
):
|
1954
1948
|
def validator(value):
|
1955
1949
|
core_data = CORE.data[KEY_CORE]
|
1956
1950
|
framework = core_data[KEY_TARGET_FRAMEWORK]
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
raise Invalid(msg)
|
1963
|
-
required = esp_idf
|
1964
|
-
elif CORE.is_bk72xx and framework == "arduino":
|
1965
|
-
if bk72xx_libretiny is None:
|
1966
|
-
msg = "This feature is incompatible with BK72XX"
|
1967
|
-
if extra_message:
|
1968
|
-
msg += f". {extra_message}"
|
1969
|
-
raise Invalid(msg)
|
1970
|
-
required = bk72xx_libretiny
|
1971
|
-
elif CORE.is_esp32 and framework == "arduino":
|
1972
|
-
if esp32_arduino is None:
|
1973
|
-
msg = "This feature is incompatible with ESP32 using arduino framework"
|
1974
|
-
if extra_message:
|
1975
|
-
msg += f". {extra_message}"
|
1976
|
-
raise Invalid(msg)
|
1977
|
-
required = esp32_arduino
|
1978
|
-
elif CORE.is_esp8266 and framework == "arduino":
|
1979
|
-
if esp8266_arduino is None:
|
1980
|
-
msg = "This feature is incompatible with ESP8266"
|
1981
|
-
if extra_message:
|
1982
|
-
msg += f". {extra_message}"
|
1983
|
-
raise Invalid(msg)
|
1984
|
-
required = esp8266_arduino
|
1985
|
-
elif CORE.is_rp2040 and framework == "arduino":
|
1986
|
-
if rp2040_arduino is None:
|
1987
|
-
msg = "This feature is incompatible with RP2040"
|
1988
|
-
if extra_message:
|
1989
|
-
msg += f". {extra_message}"
|
1990
|
-
raise Invalid(msg)
|
1991
|
-
required = rp2040_arduino
|
1992
|
-
elif CORE.is_host and framework == "host":
|
1993
|
-
if host is None:
|
1994
|
-
msg = "This feature is incompatible with host platform"
|
1995
|
-
if extra_message:
|
1996
|
-
msg += f". {extra_message}"
|
1997
|
-
raise Invalid(msg)
|
1998
|
-
required = host
|
1951
|
+
|
1952
|
+
if CORE.is_host and framework == "host":
|
1953
|
+
key = "host"
|
1954
|
+
elif framework == "esp-idf":
|
1955
|
+
key = "esp_idf"
|
1999
1956
|
else:
|
2000
|
-
|
2001
|
-
f"""
|
2002
|
-
Internal Error: require_framework_version does not support this platform configuration
|
2003
|
-
platform: {core_data[KEY_TARGET_PLATFORM]}
|
2004
|
-
framework: {framework}
|
1957
|
+
key = CORE.target_platform + "_" + framework
|
2005
1958
|
|
2006
|
-
|
2007
|
-
""
|
2008
|
-
|
1959
|
+
if key not in kwargs:
|
1960
|
+
msg = f"This feature is incompatible with {CORE.target_platform.upper()} using {framework} framework"
|
1961
|
+
if extra_message:
|
1962
|
+
msg += f". {extra_message}"
|
1963
|
+
raise Invalid(msg)
|
1964
|
+
|
1965
|
+
required = kwargs[key]
|
2009
1966
|
|
2010
1967
|
if max_version:
|
2011
1968
|
if core_data[KEY_FRAMEWORK_VERSION] > required:
|
@@ -2115,3 +2072,26 @@ def rename_key(old_key, new_key):
|
|
2115
2072
|
return config
|
2116
2073
|
|
2117
2074
|
return validator
|
2075
|
+
|
2076
|
+
|
2077
|
+
# Remove before 2025.11.0
|
2078
|
+
def deprecated_schema_constant(entity_type: str):
|
2079
|
+
def validator(config):
|
2080
|
+
type: str = "unknown"
|
2081
|
+
if (id := config.get(CONF_ID)) is not None and isinstance(id, core.ID):
|
2082
|
+
type = str(id.type).split("::", maxsplit=1)[0]
|
2083
|
+
_LOGGER.warning(
|
2084
|
+
"Using `%s.%s_SCHEMA` is deprecated and will be removed in ESPHome 2025.11.0. "
|
2085
|
+
"Please use `%s.%s_schema(...)` instead. "
|
2086
|
+
"If you are seeing this, report an issue to the external_component author and ask them to update it. "
|
2087
|
+
"https://developers.esphome.io/blog/2025/05/14/_schema-deprecations/. "
|
2088
|
+
"Component using this schema: %s",
|
2089
|
+
entity_type,
|
2090
|
+
entity_type.upper(),
|
2091
|
+
entity_type,
|
2092
|
+
entity_type,
|
2093
|
+
type,
|
2094
|
+
)
|
2095
|
+
return config
|
2096
|
+
|
2097
|
+
return validator
|
esphome/const.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"""Constants used by esphome."""
|
2
2
|
|
3
|
-
__version__ = "2025.
|
3
|
+
__version__ = "2025.5.0"
|
4
4
|
|
5
5
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
6
6
|
VALID_SUBSTITUTIONS_CHARACTERS = (
|
@@ -45,6 +45,8 @@ CONF_ALLOW_OTHER_USES = "allow_other_uses"
|
|
45
45
|
CONF_ALPHA = "alpha"
|
46
46
|
CONF_ALTITUDE = "altitude"
|
47
47
|
CONF_AMBIENT_LIGHT = "ambient_light"
|
48
|
+
CONF_AMBIENT_PRESSURE_COMPENSATION = "ambient_pressure_compensation"
|
49
|
+
CONF_AMBIENT_PRESSURE_COMPENSATION_SOURCE = "ambient_pressure_compensation_source"
|
48
50
|
CONF_AMMONIA = "ammonia"
|
49
51
|
CONF_ANALOG = "analog"
|
50
52
|
CONF_AND = "and"
|
@@ -63,6 +65,7 @@ CONF_AUTH = "auth"
|
|
63
65
|
CONF_AUTO_CLEAR_ENABLED = "auto_clear_enabled"
|
64
66
|
CONF_AUTO_MODE = "auto_mode"
|
65
67
|
CONF_AUTOCONF = "autoconf"
|
68
|
+
CONF_AUTOMATIC_SELF_CALIBRATION = "automatic_self_calibration"
|
66
69
|
CONF_AUTOMATION_ID = "automation_id"
|
67
70
|
CONF_AVAILABILITY = "availability"
|
68
71
|
CONF_AWAY = "away"
|
@@ -157,6 +160,7 @@ CONF_CONDITION = "condition"
|
|
157
160
|
CONF_CONDITION_ID = "condition_id"
|
158
161
|
CONF_CONDUCTIVITY = "conductivity"
|
159
162
|
CONF_CONSTANT_BRIGHTNESS = "constant_brightness"
|
163
|
+
CONF_CONTINUOUS = "continuous"
|
160
164
|
CONF_CONTRAST = "contrast"
|
161
165
|
CONF_COOL_ACTION = "cool_action"
|
162
166
|
CONF_COOL_DEADBAND = "cool_deadband"
|
@@ -217,7 +221,9 @@ CONF_DIMENSIONS = "dimensions"
|
|
217
221
|
CONF_DIO_PIN = "dio_pin"
|
218
222
|
CONF_DIR_PIN = "dir_pin"
|
219
223
|
CONF_DIRECTION = "direction"
|
224
|
+
CONF_DIRECTION_COMMAND_TOPIC = "direction_command_topic"
|
220
225
|
CONF_DIRECTION_OUTPUT = "direction_output"
|
226
|
+
CONF_DIRECTION_STATE_TOPIC = "direction_state_topic"
|
221
227
|
CONF_DISABLE_CRC = "disable_crc"
|
222
228
|
CONF_DISABLED = "disabled"
|
223
229
|
CONF_DISABLED_BY_DEFAULT = "disabled_by_default"
|
@@ -330,6 +336,7 @@ CONF_FULL_SPECTRUM = "full_spectrum"
|
|
330
336
|
CONF_FULL_SPECTRUM_COUNTS = "full_spectrum_counts"
|
331
337
|
CONF_FULL_UPDATE_EVERY = "full_update_every"
|
332
338
|
CONF_GAIN = "gain"
|
339
|
+
CONF_GAIN_FACTOR = "gain_factor"
|
333
340
|
CONF_GAMMA_CORRECT = "gamma_correct"
|
334
341
|
CONF_GAS_RESISTANCE = "gas_resistance"
|
335
342
|
CONF_GATEWAY = "gateway"
|
@@ -401,6 +408,7 @@ CONF_INITIAL_OPTION = "initial_option"
|
|
401
408
|
CONF_INITIAL_STATE = "initial_state"
|
402
409
|
CONF_INITIAL_VALUE = "initial_value"
|
403
410
|
CONF_INPUT = "input"
|
411
|
+
CONF_INT_DATAPOINT = "int_datapoint"
|
404
412
|
CONF_INTEGRATION_TIME = "integration_time"
|
405
413
|
CONF_INTENSITY = "intensity"
|
406
414
|
CONF_INTERLOCK = "interlock"
|
@@ -477,6 +485,7 @@ CONF_MAX_VALUE = "max_value"
|
|
477
485
|
CONF_MAX_VOLTAGE = "max_voltage"
|
478
486
|
CONF_MDNS = "mdns"
|
479
487
|
CONF_MEASUREMENT_DURATION = "measurement_duration"
|
488
|
+
CONF_MEASUREMENT_MODE = "measurement_mode"
|
480
489
|
CONF_MEASUREMENT_SEQUENCE_NUMBER = "measurement_sequence_number"
|
481
490
|
CONF_MEDIA_PLAYER = "media_player"
|
482
491
|
CONF_MEDIUM = "medium"
|
@@ -795,6 +804,7 @@ CONF_SHUTDOWN_MESSAGE = "shutdown_message"
|
|
795
804
|
CONF_SIGNAL_STRENGTH = "signal_strength"
|
796
805
|
CONF_SINGLE_LIGHT_ID = "single_light_id"
|
797
806
|
CONF_SIZE = "size"
|
807
|
+
CONF_SKIP_CERT_CN_CHECK = "skip_cert_cn_check"
|
798
808
|
CONF_SLEEP_DURATION = "sleep_duration"
|
799
809
|
CONF_SLEEP_PIN = "sleep_pin"
|
800
810
|
CONF_SLEEP_WHEN_DONE = "sleep_when_done"
|
@@ -891,6 +901,8 @@ CONF_TIMES = "times"
|
|
891
901
|
CONF_TIMEZONE = "timezone"
|
892
902
|
CONF_TIMING = "timing"
|
893
903
|
CONF_TO = "to"
|
904
|
+
CONF_TO_NTC_RESISTANCE = "to_ntc_resistance"
|
905
|
+
CONF_TO_NTC_TEMPERATURE = "to_ntc_temperature"
|
894
906
|
CONF_TOLERANCE = "tolerance"
|
895
907
|
CONF_TOPIC = "topic"
|
896
908
|
CONF_TOPIC_PREFIX = "topic_prefix"
|
@@ -1080,6 +1092,7 @@ UNIT_KILOWATT = "kW"
|
|
1080
1092
|
UNIT_KILOWATT_HOURS = "kWh"
|
1081
1093
|
UNIT_LITRE = "L"
|
1082
1094
|
UNIT_LUX = "lx"
|
1095
|
+
UNIT_MEGAJOULE = "MJ"
|
1083
1096
|
UNIT_METER = "m"
|
1084
1097
|
UNIT_METER_PER_SECOND_SQUARED = "m/s²"
|
1085
1098
|
UNIT_MICROAMP = "µA"
|
@@ -1093,6 +1106,7 @@ UNIT_MILLIGRAMS_PER_CUBIC_METER = "mg/m³"
|
|
1093
1106
|
UNIT_MILLIMETER = "mm"
|
1094
1107
|
UNIT_MILLISECOND = "ms"
|
1095
1108
|
UNIT_MILLISIEMENS_PER_CENTIMETER = "mS/cm"
|
1109
|
+
UNIT_MILLIVOLT = "mV"
|
1096
1110
|
UNIT_MINUTE = "min"
|
1097
1111
|
UNIT_OHM = "Ω"
|
1098
1112
|
UNIT_PARTS_PER_BILLION = "ppb"
|
esphome/core/__init__.py
CHANGED
esphome/core/application.cpp
CHANGED
@@ -35,6 +35,8 @@ void Application::setup() {
|
|
35
35
|
for (uint32_t i = 0; i < this->components_.size(); i++) {
|
36
36
|
Component *component = this->components_[i];
|
37
37
|
|
38
|
+
// Update loop_component_start_time_ before calling each component during setup
|
39
|
+
this->loop_component_start_time_ = millis();
|
38
40
|
component->call();
|
39
41
|
this->scheduler.process_to_add();
|
40
42
|
this->feed_wdt();
|
@@ -49,6 +51,8 @@ void Application::setup() {
|
|
49
51
|
this->scheduler.call();
|
50
52
|
this->feed_wdt();
|
51
53
|
for (uint32_t j = 0; j <= i; j++) {
|
54
|
+
// Update loop_component_start_time_ right before calling each component
|
55
|
+
this->loop_component_start_time_ = millis();
|
52
56
|
this->components_[j]->call();
|
53
57
|
new_app_state |= this->components_[j]->get_component_state();
|
54
58
|
this->app_state_ |= new_app_state;
|
@@ -67,21 +71,32 @@ void Application::loop() {
|
|
67
71
|
uint32_t new_app_state = 0;
|
68
72
|
|
69
73
|
this->scheduler.call();
|
70
|
-
|
74
|
+
|
75
|
+
// Get the initial loop time at the start
|
76
|
+
uint32_t last_op_end_time = millis();
|
77
|
+
|
78
|
+
// Feed WDT with time
|
79
|
+
this->feed_wdt(last_op_end_time);
|
80
|
+
|
71
81
|
for (Component *component : this->looping_components_) {
|
82
|
+
// Update the cached time before each component runs
|
83
|
+
this->loop_component_start_time_ = last_op_end_time;
|
84
|
+
|
72
85
|
{
|
73
|
-
|
86
|
+
this->set_current_component(component);
|
87
|
+
WarnIfComponentBlockingGuard guard{component, last_op_end_time};
|
74
88
|
component->call();
|
89
|
+
// Use the finish method to get the current time as the end time
|
90
|
+
last_op_end_time = guard.finish();
|
75
91
|
}
|
76
92
|
new_app_state |= component->get_component_state();
|
77
93
|
this->app_state_ |= new_app_state;
|
78
|
-
this->feed_wdt();
|
94
|
+
this->feed_wdt(last_op_end_time);
|
79
95
|
}
|
80
96
|
this->app_state_ = new_app_state;
|
81
97
|
|
82
|
-
|
83
|
-
|
84
|
-
auto elapsed = now - this->last_loop_;
|
98
|
+
// Use the last component's end time instead of calling millis() again
|
99
|
+
auto elapsed = last_op_end_time - this->last_loop_;
|
85
100
|
if (elapsed >= this->loop_interval_ || HighFrequencyLoopRequester::is_high_frequency()) {
|
86
101
|
yield();
|
87
102
|
} else {
|
@@ -93,7 +108,7 @@ void Application::loop() {
|
|
93
108
|
delay_time = std::min(next_schedule, delay_time);
|
94
109
|
delay(delay_time);
|
95
110
|
}
|
96
|
-
this->last_loop_ =
|
111
|
+
this->last_loop_ = last_op_end_time;
|
97
112
|
|
98
113
|
if (this->dump_config_at_ < this->components_.size()) {
|
99
114
|
if (this->dump_config_at_ == 0) {
|
@@ -108,10 +123,12 @@ void Application::loop() {
|
|
108
123
|
}
|
109
124
|
}
|
110
125
|
|
111
|
-
void IRAM_ATTR HOT Application::feed_wdt() {
|
126
|
+
void IRAM_ATTR HOT Application::feed_wdt(uint32_t time) {
|
112
127
|
static uint32_t last_feed = 0;
|
113
|
-
|
114
|
-
|
128
|
+
// Use provided time if available, otherwise get current time
|
129
|
+
uint32_t now = time ? time : millis();
|
130
|
+
// Compare in milliseconds (3ms threshold)
|
131
|
+
if (now - last_feed > 3) {
|
115
132
|
arch_feed_wdt();
|
116
133
|
last_feed = now;
|
117
134
|
#ifdef USE_STATUS_LED
|
esphome/core/application.h
CHANGED
@@ -97,6 +97,9 @@ class Application {
|
|
97
97
|
this->compilation_time_ = compilation_time;
|
98
98
|
}
|
99
99
|
|
100
|
+
void set_current_component(Component *component) { this->current_component_ = component; }
|
101
|
+
Component *get_current_component() { return this->current_component_; }
|
102
|
+
|
100
103
|
#ifdef USE_BINARY_SENSOR
|
101
104
|
void register_binary_sensor(binary_sensor::BinarySensor *binary_sensor) {
|
102
105
|
this->binary_sensors_.push_back(binary_sensor);
|
@@ -214,6 +217,9 @@ class Application {
|
|
214
217
|
|
215
218
|
std::string get_compilation_time() const { return this->compilation_time_; }
|
216
219
|
|
220
|
+
/// Get the cached time in milliseconds from when the current component started its loop execution
|
221
|
+
inline uint32_t IRAM_ATTR HOT get_loop_component_start_time() const { return this->loop_component_start_time_; }
|
222
|
+
|
217
223
|
/** Set the target interval with which to run the loop() calls.
|
218
224
|
* If the loop() method takes longer than the target interval, ESPHome won't
|
219
225
|
* sleep in loop(), but if the time spent in loop() is small than the target, ESPHome
|
@@ -233,7 +239,7 @@ class Application {
|
|
233
239
|
|
234
240
|
void schedule_dump_config() { this->dump_config_at_ = 0; }
|
235
241
|
|
236
|
-
void feed_wdt();
|
242
|
+
void feed_wdt(uint32_t time = 0);
|
237
243
|
|
238
244
|
void reboot();
|
239
245
|
|
@@ -547,6 +553,8 @@ class Application {
|
|
547
553
|
uint32_t loop_interval_{16};
|
548
554
|
size_t dump_config_at_{SIZE_MAX};
|
549
555
|
uint32_t app_state_{0};
|
556
|
+
Component *current_component_{nullptr};
|
557
|
+
uint32_t loop_component_start_time_{0};
|
550
558
|
};
|
551
559
|
|
552
560
|
/// Global storage of Application pointer - only one Application can exist.
|
esphome/core/automation.h
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
|
-
#include <vector>
|
4
3
|
#include "esphome/core/component.h"
|
5
|
-
#include "esphome/core/helpers.h"
|
6
4
|
#include "esphome/core/defines.h"
|
5
|
+
#include "esphome/core/helpers.h"
|
7
6
|
#include "esphome/core/preferences.h"
|
7
|
+
#include <utility>
|
8
|
+
#include <vector>
|
8
9
|
|
9
10
|
namespace esphome {
|
10
11
|
|
@@ -27,7 +28,7 @@ template<typename T, typename... X> class TemplatableValue {
|
|
27
28
|
TemplatableValue() : type_(NONE) {}
|
28
29
|
|
29
30
|
template<typename F, enable_if_t<!is_invocable<F, X...>::value, int> = 0>
|
30
|
-
TemplatableValue(F value) : type_(VALUE), value_(value) {}
|
31
|
+
TemplatableValue(F value) : type_(VALUE), value_(std::move(value)) {}
|
31
32
|
|
32
33
|
template<typename F, enable_if_t<is_invocable<F, X...>::value, int> = 0>
|
33
34
|
TemplatableValue(F f) : type_(LAMBDA), f_(f) {}
|
esphome/core/component.cpp
CHANGED
@@ -39,6 +39,9 @@ const uint32_t STATUS_LED_OK = 0x0000;
|
|
39
39
|
const uint32_t STATUS_LED_WARNING = 0x0100;
|
40
40
|
const uint32_t STATUS_LED_ERROR = 0x0200;
|
41
41
|
|
42
|
+
const uint32_t WARN_IF_BLOCKING_OVER_MS = 50U; ///< Initial blocking time allowed without warning
|
43
|
+
const uint32_t WARN_IF_BLOCKING_INCREMENT_MS = 10U; ///< How long the blocking time must be larger to warn again
|
44
|
+
|
42
45
|
uint32_t global_state = 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
43
46
|
|
44
47
|
float Component::get_loop_priority() const { return 0.0f; }
|
@@ -115,6 +118,13 @@ const char *Component::get_component_source() const {
|
|
115
118
|
return "<unknown>";
|
116
119
|
return this->component_source_;
|
117
120
|
}
|
121
|
+
bool Component::should_warn_of_blocking(uint32_t blocking_time) {
|
122
|
+
if (blocking_time > this->warn_if_blocking_over_) {
|
123
|
+
this->warn_if_blocking_over_ = blocking_time + WARN_IF_BLOCKING_INCREMENT_MS;
|
124
|
+
return true;
|
125
|
+
}
|
126
|
+
return false;
|
127
|
+
}
|
118
128
|
void Component::mark_failed() {
|
119
129
|
ESP_LOGE(TAG, "Component %s was marked as failed.", this->get_component_source());
|
120
130
|
this->component_state_ &= ~COMPONENT_STATE_MASK;
|
@@ -230,16 +240,27 @@ void PollingComponent::stop_poller() {
|
|
230
240
|
uint32_t PollingComponent::get_update_interval() const { return this->update_interval_; }
|
231
241
|
void PollingComponent::set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
|
232
242
|
|
233
|
-
WarnIfComponentBlockingGuard::WarnIfComponentBlockingGuard(Component *component)
|
234
|
-
: started_(
|
235
|
-
WarnIfComponentBlockingGuard
|
236
|
-
uint32_t
|
237
|
-
|
243
|
+
WarnIfComponentBlockingGuard::WarnIfComponentBlockingGuard(Component *component, uint32_t start_time)
|
244
|
+
: started_(start_time), component_(component) {}
|
245
|
+
uint32_t WarnIfComponentBlockingGuard::finish() {
|
246
|
+
uint32_t curr_time = millis();
|
247
|
+
|
248
|
+
uint32_t blocking_time = curr_time - this->started_;
|
249
|
+
bool should_warn;
|
250
|
+
if (this->component_ != nullptr) {
|
251
|
+
should_warn = this->component_->should_warn_of_blocking(blocking_time);
|
252
|
+
} else {
|
253
|
+
should_warn = blocking_time > WARN_IF_BLOCKING_OVER_MS;
|
254
|
+
}
|
255
|
+
if (should_warn) {
|
238
256
|
const char *src = component_ == nullptr ? "<null>" : component_->get_component_source();
|
239
|
-
ESP_LOGW(TAG, "Component %s took a long time for an operation (%" PRIu32 " ms).", src,
|
257
|
+
ESP_LOGW(TAG, "Component %s took a long time for an operation (%" PRIu32 " ms).", src, blocking_time);
|
240
258
|
ESP_LOGW(TAG, "Components should block for at most 30 ms.");
|
241
|
-
;
|
242
259
|
}
|
260
|
+
|
261
|
+
return curr_time;
|
243
262
|
}
|
244
263
|
|
264
|
+
WarnIfComponentBlockingGuard::~WarnIfComponentBlockingGuard() {}
|
265
|
+
|
245
266
|
} // namespace esphome
|