esphome 2025.8.4__py3-none-any.whl → 2025.9.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 +177 -105
- esphome/components/absolute_humidity/absolute_humidity.cpp +3 -5
- esphome/components/adc/__init__.py +1 -26
- esphome/components/adc/adc_sensor_esp32.cpp +29 -6
- esphome/components/adc/sensor.py +20 -0
- esphome/components/ade7880/ade7880.cpp +1 -1
- esphome/components/ags10/ags10.cpp +3 -18
- esphome/components/ags10/ags10.h +2 -12
- esphome/components/aht10/aht10.cpp +3 -3
- esphome/components/airthings_ble/__init__.py +2 -2
- esphome/components/alarm_control_panel/__init__.py +2 -2
- esphome/components/am2315c/am2315c.cpp +1 -17
- esphome/components/am2315c/am2315c.h +2 -3
- esphome/components/api/__init__.py +2 -2
- esphome/components/api/api_connection.cpp +38 -34
- esphome/components/api/api_connection.h +20 -40
- esphome/components/api/api_frame_helper.cpp +25 -25
- esphome/components/api/api_frame_helper.h +3 -3
- esphome/components/api/api_frame_helper_noise.cpp +75 -40
- esphome/components/api/api_frame_helper_noise.h +3 -7
- esphome/components/api/api_frame_helper_plaintext.cpp +17 -4
- esphome/components/api/api_frame_helper_plaintext.h +1 -4
- esphome/components/api/api_pb2.cpp +12 -2
- esphome/components/api/api_pb2.h +144 -143
- esphome/components/api/api_pb2_dump.cpp +6 -1
- esphome/components/api/api_pb2_service.cpp +0 -14
- esphome/components/api/api_pb2_service.h +1 -3
- esphome/components/api/client.py +5 -3
- esphome/components/api/proto.cpp +33 -37
- esphome/components/async_tcp/__init__.py +2 -2
- esphome/components/atm90e26/sensor.py +2 -0
- esphome/components/atm90e32/sensor.py +4 -2
- esphome/components/audio_adc/__init__.py +2 -2
- esphome/components/audio_dac/__init__.py +2 -2
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +1 -1
- esphome/components/bedjet/bedjet_hub.cpp +1 -1
- esphome/components/binary_sensor/__init__.py +2 -2
- esphome/components/binary_sensor/binary_sensor.cpp +13 -0
- esphome/components/binary_sensor/binary_sensor.h +4 -7
- esphome/components/bl0940/__init__.py +6 -1
- esphome/components/bl0940/bl0940.cpp +178 -41
- esphome/components/bl0940/bl0940.h +121 -76
- esphome/components/bl0940/button/__init__.py +27 -0
- esphome/components/bl0940/button/calibration_reset_button.cpp +20 -0
- esphome/components/bl0940/button/calibration_reset_button.h +19 -0
- esphome/components/bl0940/number/__init__.py +94 -0
- esphome/components/bl0940/number/calibration_number.cpp +29 -0
- esphome/components/bl0940/number/calibration_number.h +26 -0
- esphome/components/bl0940/sensor.py +151 -2
- esphome/components/bl0942/bl0942.cpp +1 -1
- esphome/components/ble_client/output/__init__.py +4 -4
- esphome/components/bluetooth_proxy/__init__.py +1 -1
- esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -1
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +15 -7
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +6 -3
- esphome/components/button/__init__.py +2 -2
- esphome/components/button/button.cpp +13 -0
- esphome/components/button/button.h +4 -7
- esphome/components/camera/buffer.h +18 -0
- esphome/components/camera/buffer_impl.cpp +20 -0
- esphome/components/camera/buffer_impl.h +26 -0
- esphome/components/camera/camera.h +43 -0
- esphome/components/camera/encoder.h +69 -0
- esphome/components/camera_encoder/__init__.py +62 -0
- esphome/components/camera_encoder/encoder_buffer_impl.cpp +23 -0
- esphome/components/camera_encoder/encoder_buffer_impl.h +25 -0
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +82 -0
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +39 -0
- esphome/components/captive_portal/__init__.py +2 -2
- esphome/components/captive_portal/captive_index.h +77 -97
- esphome/components/captive_portal/captive_portal.cpp +35 -12
- esphome/components/captive_portal/captive_portal.h +3 -3
- esphome/components/ccs811/ccs811.cpp +3 -3
- esphome/components/climate/__init__.py +2 -2
- esphome/components/climate/climate.cpp +1 -1
- esphome/components/cover/__init__.py +5 -5
- esphome/components/cover/cover.cpp +1 -1
- esphome/components/cover/cover.h +2 -2
- esphome/components/dallas_temp/dallas_temp.cpp +2 -2
- esphome/components/datetime/__init__.py +2 -2
- esphome/components/datetime/date_entity.h +2 -2
- esphome/components/datetime/datetime_entity.h +2 -2
- esphome/components/datetime/time_entity.h +2 -2
- esphome/components/debug/debug_esp32.cpp +1 -1
- esphome/components/display/__init__.py +4 -4
- esphome/components/duty_time/duty_time_sensor.cpp +1 -1
- esphome/components/esp32/__init__.py +0 -5
- esphome/components/esp32/gpio.cpp +27 -23
- esphome/components/esp32/gpio.h +26 -11
- esphome/components/esp32/preferences.cpp +8 -4
- esphome/components/esp32_ble/__init__.py +7 -2
- esphome/components/esp32_ble/ble_uuid.cpp +30 -9
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +4 -3
- esphome/components/esp32_ble_client/ble_client_base.cpp +7 -3
- esphome/components/esp32_ble_client/ble_client_base.h +8 -5
- esphome/components/esp32_ble_tracker/__init__.py +2 -2
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +11 -47
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -14
- esphome/components/esp8266/__init__.py +2 -2
- esphome/components/esp8266/core.cpp +2 -2
- esphome/components/esp8266/gpio.py +4 -4
- esphome/components/esp8266/preferences.cpp +30 -28
- esphome/components/esphome/ota/__init__.py +2 -2
- esphome/components/esphome/ota/ota_esphome.cpp +21 -19
- esphome/components/esphome/ota/ota_esphome.h +6 -5
- esphome/components/ethernet/__init__.py +18 -2
- esphome/components/ethernet/ethernet_component.cpp +53 -3
- esphome/components/ethernet/ethernet_component.h +4 -0
- esphome/components/event/__init__.py +2 -2
- esphome/components/event/event.h +4 -4
- esphome/components/factory_reset/button/factory_reset_button.cpp +18 -1
- esphome/components/factory_reset/button/factory_reset_button.h +6 -1
- esphome/components/factory_reset/switch/factory_reset_switch.cpp +18 -1
- esphome/components/factory_reset/switch/factory_reset_switch.h +5 -1
- esphome/components/fan/__init__.py +2 -2
- esphome/components/fan/fan.cpp +2 -1
- esphome/components/gdk101/gdk101.cpp +4 -4
- esphome/components/globals/__init__.py +2 -2
- esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +19 -18
- esphome/components/gpio_expander/cached_gpio.h +36 -16
- esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -5
- esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
- esphome/components/haier/haier_base.cpp +1 -1
- esphome/components/haier/hon_climate.cpp +1 -1
- esphome/components/hlw8012/hlw8012.cpp +5 -5
- esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +4 -4
- esphome/components/host/preferences.h +3 -2
- esphome/components/hte501/hte501.cpp +3 -21
- esphome/components/hte501/hte501.h +2 -3
- esphome/components/http_request/ota/__init__.py +2 -2
- esphome/components/i2c/__init__.py +2 -2
- esphome/components/i2c/i2c.cpp +13 -9
- esphome/components/i2c/i2c_bus.h +36 -6
- esphome/components/i2s_audio/__init__.py +8 -2
- esphome/components/i2s_audio/media_player/__init__.py +1 -1
- esphome/components/i2s_audio/microphone/__init__.py +1 -1
- esphome/components/i2s_audio/speaker/__init__.py +1 -1
- esphome/components/ina2xx_base/__init__.py +4 -2
- esphome/components/inkplate/__init__.py +1 -0
- esphome/components/inkplate/const.py +105 -0
- esphome/components/inkplate/display.py +238 -0
- esphome/components/{inkplate6 → inkplate}/inkplate.cpp +156 -74
- esphome/components/{inkplate6 → inkplate}/inkplate.h +28 -68
- esphome/components/inkplate6/__init__.py +0 -1
- esphome/components/inkplate6/display.py +2 -211
- esphome/components/integration/integration_sensor.cpp +1 -1
- esphome/components/json/__init__.py +2 -2
- esphome/components/lc709203f/lc709203f.cpp +4 -17
- esphome/components/lc709203f/lc709203f.h +2 -3
- esphome/components/ld2420/text_sensor/{text_sensor.cpp → ld2420_text_sensor.cpp} +1 -1
- esphome/components/ld2450/ld2450.cpp +1 -1
- esphome/components/libretiny/preferences.cpp +13 -5
- esphome/components/light/__init__.py +2 -2
- esphome/components/light/addressable_light_effect.h +7 -0
- esphome/components/light/base_light_effects.h +8 -0
- esphome/components/light/light_call.cpp +22 -20
- esphome/components/light/light_effect.cpp +36 -0
- esphome/components/light/light_effect.h +14 -0
- esphome/components/light/light_json_schema.cpp +9 -1
- esphome/components/light/light_state.cpp +2 -2
- esphome/components/light/light_state.h +38 -0
- esphome/components/lock/__init__.py +2 -2
- esphome/components/lock/lock.h +2 -2
- esphome/components/logger/__init__.py +2 -2
- esphome/components/logger/logger.cpp +25 -4
- esphome/components/logger/logger.h +1 -1
- esphome/components/logger/logger_esp32.cpp +16 -8
- esphome/components/logger/logger_esp8266.cpp +11 -3
- esphome/components/logger/logger_libretiny.cpp +13 -3
- esphome/components/logger/logger_rp2040.cpp +14 -3
- esphome/components/logger/logger_zephyr.cpp +15 -4
- esphome/components/lvgl/defines.py +1 -0
- esphome/components/lvgl/hello_world.py +96 -33
- esphome/components/lvgl/number/lvgl_number.h +1 -1
- esphome/components/lvgl/select/lvgl_select.h +1 -1
- esphome/components/lvgl/widgets/__init__.py +0 -1
- esphome/components/lvgl/widgets/spinbox.py +20 -11
- esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +1 -1
- esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +1 -1
- esphome/components/mapping/__init__.py +13 -5
- esphome/components/mapping/mapping.h +69 -0
- esphome/components/max17043/max17043.cpp +2 -2
- esphome/components/mcp23016/__init__.py +1 -0
- esphome/components/mcp23016/mcp23016.cpp +20 -5
- esphome/components/mcp23016/mcp23016.h +10 -4
- esphome/components/mcp23x08_base/mcp23x08_base.cpp +1 -1
- esphome/components/mcp23x17_base/mcp23x17_base.cpp +2 -2
- esphome/components/md5/md5.cpp +3 -2
- esphome/components/mdns/__init__.py +2 -2
- esphome/components/mdns/mdns_component.cpp +145 -54
- esphome/components/media_player/__init__.py +2 -2
- esphome/components/micro_wake_word/__init__.py +2 -2
- esphome/components/microphone/__init__.py +2 -2
- esphome/components/mipi/__init__.py +77 -33
- esphome/components/mipi_rgb/__init__.py +2 -0
- esphome/components/mipi_rgb/display.py +321 -0
- esphome/components/mipi_rgb/mipi_rgb.cpp +388 -0
- esphome/components/mipi_rgb/mipi_rgb.h +127 -0
- esphome/components/mipi_rgb/models/guition.py +24 -0
- esphome/components/mipi_rgb/models/lilygo.py +228 -0
- esphome/components/mipi_rgb/models/rpi.py +9 -0
- esphome/components/mipi_rgb/models/st7701s.py +214 -0
- esphome/components/mipi_rgb/models/waveshare.py +64 -0
- esphome/components/mipi_spi/models/jc.py +229 -0
- esphome/components/mlx90614/mlx90614.cpp +1 -16
- esphome/components/mlx90614/mlx90614.h +0 -1
- esphome/components/mqtt/__init__.py +2 -2
- esphome/components/mqtt/mqtt_client.cpp +1 -1
- esphome/components/mqtt/mqtt_sensor.cpp +7 -2
- esphome/components/ms5611/ms5611.cpp +7 -6
- esphome/components/network/__init__.py +2 -2
- esphome/components/nextion/nextion_upload.cpp +4 -1
- esphome/components/nrf52/__init__.py +49 -6
- esphome/components/nrf52/const.py +1 -0
- esphome/components/nrf52/dfu.cpp +51 -0
- esphome/components/nrf52/dfu.h +24 -0
- esphome/components/ntc/ntc.cpp +1 -1
- esphome/components/number/__init__.py +2 -2
- esphome/components/number/automation.cpp +1 -1
- esphome/components/number/number.cpp +21 -0
- esphome/components/number/number.h +4 -13
- esphome/components/opentherm/hub.h +6 -6
- esphome/components/opentherm/number/{number.cpp → opentherm_number.cpp} +2 -2
- esphome/components/opentherm/output/{output.cpp → opentherm_output.cpp} +1 -1
- esphome/components/opentherm/switch/{switch.cpp → opentherm_switch.cpp} +1 -1
- esphome/components/openthread/openthread.cpp +41 -7
- esphome/components/openthread/openthread.h +11 -0
- esphome/components/ota/__init__.py +2 -2
- esphome/components/pca6416a/__init__.py +1 -0
- esphome/components/pca6416a/pca6416a.cpp +20 -5
- esphome/components/pca6416a/pca6416a.h +12 -5
- esphome/components/pca9554/__init__.py +2 -1
- esphome/components/pca9554/pca9554.cpp +12 -18
- esphome/components/pca9554/pca9554.h +10 -9
- esphome/components/pcf8574/__init__.py +1 -0
- esphome/components/pcf8574/pcf8574.cpp +14 -5
- esphome/components/pcf8574/pcf8574.h +13 -6
- esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +7 -7
- esphome/components/pipsolar/__init__.py +3 -3
- esphome/components/pipsolar/output/__init__.py +4 -4
- esphome/components/pulse_width/pulse_width.cpp +2 -2
- esphome/components/qmp6988/qmp6988.cpp +81 -126
- esphome/components/qmp6988/qmp6988.h +31 -37
- esphome/components/radon_eye_ble/__init__.py +2 -2
- esphome/components/remote_base/__init__.py +6 -8
- esphome/components/rotary_encoder/rotary_encoder.cpp +1 -1
- esphome/components/rp2040/__init__.py +2 -2
- esphome/components/runtime_stats/runtime_stats.cpp +10 -23
- esphome/components/runtime_stats/runtime_stats.h +4 -10
- esphome/components/safe_mode/__init__.py +2 -2
- esphome/components/safe_mode/safe_mode.cpp +33 -31
- esphome/components/script/script.cpp +6 -0
- esphome/components/script/script.h +19 -5
- esphome/components/sdm_meter/sensor.py +3 -1
- esphome/components/select/__init__.py +2 -2
- esphome/components/select/select.cpp +3 -3
- esphome/components/select/select.h +2 -2
- esphome/components/select/select_call.cpp +1 -1
- esphome/components/sen5x/sen5x.cpp +57 -55
- esphome/components/sen5x/sen5x.h +21 -15
- esphome/components/sen5x/sensor.py +67 -44
- esphome/components/sensirion_common/i2c_sensirion.cpp +18 -47
- esphome/components/sensirion_common/i2c_sensirion.h +39 -55
- esphome/components/sensor/__init__.py +2 -2
- esphome/components/sensor/automation.h +1 -1
- esphome/components/sensor/sensor.cpp +34 -6
- esphome/components/sensor/sensor.h +4 -21
- esphome/components/sgp30/sgp30.cpp +34 -35
- esphome/components/sgp30/sgp30.h +11 -10
- esphome/components/sgp4x/sgp4x.cpp +2 -2
- esphome/components/shelly_dimmer/light.py +7 -7
- esphome/components/sht4x/sht4x.cpp +1 -1
- esphome/components/sntp/sntp_component.cpp +36 -9
- esphome/components/sntp/sntp_component.h +7 -0
- esphome/components/sound_level/sound_level.cpp +1 -1
- esphome/components/speaker/__init__.py +2 -2
- esphome/components/speaker/media_player/__init__.py +2 -2
- esphome/components/speaker/media_player/speaker_media_player.cpp +1 -1
- esphome/components/spi/__init__.py +2 -2
- esphome/components/sprinkler/sprinkler.cpp +1 -1
- esphome/components/sps30/sps30.cpp +18 -23
- esphome/components/sps30/sps30.h +3 -3
- esphome/components/status_led/__init__.py +2 -2
- esphome/components/stepper/__init__.py +2 -2
- esphome/components/switch/__init__.py +2 -2
- esphome/components/switch/switch.cpp +5 -5
- esphome/components/sx1509/__init__.py +1 -1
- esphome/components/sx1509/sx1509.cpp +12 -7
- esphome/components/sx1509/sx1509.h +11 -4
- esphome/components/tca9555/tca9555.cpp +5 -5
- esphome/components/tee501/tee501.cpp +2 -21
- esphome/components/tee501/tee501.h +2 -4
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +1 -1
- esphome/components/template/datetime/template_date.cpp +1 -1
- esphome/components/template/datetime/template_datetime.cpp +2 -2
- esphome/components/template/datetime/template_time.cpp +1 -1
- esphome/components/template/number/template_number.cpp +1 -1
- esphome/components/template/select/template_select.cpp +1 -1
- esphome/components/template/text/template_text.cpp +1 -1
- esphome/components/text/__init__.py +2 -2
- esphome/components/text/text.h +2 -2
- esphome/components/text_sensor/__init__.py +2 -2
- esphome/components/text_sensor/text_sensor.h +4 -4
- esphome/components/thermostat/climate.py +11 -7
- esphome/components/thermostat/thermostat_climate.cpp +237 -206
- esphome/components/thermostat/thermostat_climate.h +52 -41
- esphome/components/time/__init__.py +2 -2
- esphome/components/tmp1075/tmp1075.cpp +1 -1
- esphome/components/total_daily_energy/total_daily_energy.cpp +1 -1
- esphome/components/touchscreen/__init__.py +2 -2
- esphome/components/tuya/number/tuya_number.cpp +1 -1
- esphome/components/udp/udp_component.cpp +3 -3
- esphome/components/ufire_ec/ufire_ec.cpp +4 -4
- esphome/components/ufire_ise/ufire_ise.cpp +4 -4
- esphome/components/update/__init__.py +2 -2
- esphome/components/usb_uart/usb_uart.cpp +1 -1
- esphome/components/valve/__init__.py +5 -5
- esphome/components/valve/valve.cpp +1 -1
- esphome/components/valve/valve.h +2 -2
- esphome/components/wake_on_lan/wake_on_lan.cpp +2 -2
- esphome/components/waveshare_epaper/waveshare_213v3.cpp +1 -1
- esphome/components/web_server/__init__.py +2 -2
- esphome/components/web_server/ota/__init__.py +2 -2
- esphome/components/web_server/ota/ota_web_server.cpp +11 -0
- esphome/components/web_server/server_index_v2.h +149 -149
- esphome/components/web_server/web_server.cpp +58 -12
- esphome/components/web_server_base/__init__.py +2 -2
- esphome/components/wifi/__init__.py +5 -5
- esphome/components/wifi/wifi_component.cpp +4 -4
- esphome/components/wifi/wifi_component_esp_idf.cpp +2 -0
- esphome/components/wifi_info/wifi_info_text_sensor.h +3 -2
- esphome/config_validation.py +2 -2
- esphome/const.py +3 -1
- esphome/core/__init__.py +1 -0
- esphome/core/application.cpp +89 -51
- esphome/core/application.h +1 -0
- esphome/core/component.cpp +41 -19
- esphome/core/component.h +17 -13
- esphome/core/config.py +7 -7
- esphome/core/defines.h +5 -0
- esphome/core/entity_base.cpp +22 -8
- esphome/core/entity_base.h +43 -0
- esphome/core/helpers.cpp +34 -20
- esphome/core/helpers.h +33 -3
- esphome/core/ring_buffer.cpp +6 -2
- esphome/core/ring_buffer.h +2 -1
- esphome/core/scheduler.cpp +178 -97
- esphome/core/scheduler.h +67 -36
- esphome/core/time.cpp +6 -20
- esphome/coroutine.py +80 -3
- esphome/cpp_generator.py +13 -0
- esphome/cpp_helpers.py +2 -2
- esphome/dashboard/web_server.py +69 -15
- esphome/espota2.py +13 -6
- esphome/helpers.py +68 -83
- esphome/resolver.py +67 -0
- esphome/util.py +9 -6
- esphome/wizard.py +81 -34
- esphome/writer.py +13 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/METADATA +9 -9
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/RECORD +369 -338
- /esphome/components/ld2420/text_sensor/{text_sensor.h → ld2420_text_sensor.h} +0 -0
- /esphome/components/opentherm/number/{number.h → opentherm_number.h} +0 -0
- /esphome/components/opentherm/output/{output.h → opentherm_output.h} +0 -0
- /esphome/components/opentherm/switch/{switch.h → opentherm_switch.h} +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/WHEEL +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/top_level.txt +0 -0
@@ -148,7 +148,7 @@ void WiFiComponent::loop() {
|
|
148
148
|
|
149
149
|
switch (this->state_) {
|
150
150
|
case WIFI_COMPONENT_STATE_COOLDOWN: {
|
151
|
-
this->status_set_warning("waiting to reconnect");
|
151
|
+
this->status_set_warning(LOG_STR("waiting to reconnect"));
|
152
152
|
if (millis() - this->action_started_ > 5000) {
|
153
153
|
if (this->fast_connect_ || this->retry_hidden_) {
|
154
154
|
if (!this->selected_ap_.get_bssid().has_value())
|
@@ -161,13 +161,13 @@ void WiFiComponent::loop() {
|
|
161
161
|
break;
|
162
162
|
}
|
163
163
|
case WIFI_COMPONENT_STATE_STA_SCANNING: {
|
164
|
-
this->status_set_warning("scanning for networks");
|
164
|
+
this->status_set_warning(LOG_STR("scanning for networks"));
|
165
165
|
this->check_scanning_finished();
|
166
166
|
break;
|
167
167
|
}
|
168
168
|
case WIFI_COMPONENT_STATE_STA_CONNECTING:
|
169
169
|
case WIFI_COMPONENT_STATE_STA_CONNECTING_2: {
|
170
|
-
this->status_set_warning("associating to network");
|
170
|
+
this->status_set_warning(LOG_STR("associating to network"));
|
171
171
|
this->check_connecting_finished();
|
172
172
|
break;
|
173
173
|
}
|
@@ -593,7 +593,7 @@ void WiFiComponent::check_scanning_finished() {
|
|
593
593
|
for (auto &res : this->scan_result_) {
|
594
594
|
char bssid_s[18];
|
595
595
|
auto bssid = res.get_bssid();
|
596
|
-
|
596
|
+
format_mac_addr_upper(bssid.data(), bssid_s);
|
597
597
|
|
598
598
|
if (res.get_matches()) {
|
599
599
|
ESP_LOGI(TAG, "- '%s' %s" LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(),
|
@@ -654,12 +654,14 @@ const char *get_disconnect_reason_str(uint8_t reason) {
|
|
654
654
|
return "Association comeback time too long";
|
655
655
|
case WIFI_REASON_SA_QUERY_TIMEOUT:
|
656
656
|
return "SA query timeout";
|
657
|
+
#if (ESP_IDF_VERSION_MAJOR >= 5) && (ESP_IDF_VERSION_MINOR >= 2)
|
657
658
|
case WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY:
|
658
659
|
return "No AP found with compatible security";
|
659
660
|
case WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD:
|
660
661
|
return "No AP found in auth mode threshold";
|
661
662
|
case WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD:
|
662
663
|
return "No AP found in RSSI threshold";
|
664
|
+
#endif
|
663
665
|
case WIFI_REASON_UNSPECIFIED:
|
664
666
|
default:
|
665
667
|
return "Unspecified";
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
#include "esphome/core/component.h"
|
4
|
+
#include "esphome/core/helpers.h"
|
4
5
|
#include "esphome/components/text_sensor/text_sensor.h"
|
5
6
|
#include "esphome/components/wifi/wifi_component.h"
|
6
7
|
#ifdef USE_WIFI
|
@@ -106,8 +107,8 @@ class BSSIDWiFiInfo : public PollingComponent, public text_sensor::TextSensor {
|
|
106
107
|
wifi::bssid_t bssid = wifi::global_wifi_component->wifi_bssid();
|
107
108
|
if (memcmp(bssid.data(), last_bssid_.data(), 6) != 0) {
|
108
109
|
std::copy(bssid.begin(), bssid.end(), last_bssid_.begin());
|
109
|
-
char buf[
|
110
|
-
|
110
|
+
char buf[18];
|
111
|
+
format_mac_addr_upper(bssid.data(), buf);
|
111
112
|
this->publish_state(buf);
|
112
113
|
}
|
113
114
|
}
|
esphome/config_validation.py
CHANGED
@@ -1112,8 +1112,8 @@ voltage = float_with_unit("voltage", "(v|V|volt|Volts)?")
|
|
1112
1112
|
distance = float_with_unit("distance", "(m)")
|
1113
1113
|
framerate = float_with_unit("framerate", "(FPS|fps|Fps|FpS|Hz)")
|
1114
1114
|
angle = float_with_unit("angle", "(°|deg)", optional_unit=True)
|
1115
|
-
_temperature_c = float_with_unit("temperature", "(°C|° C
|
1116
|
-
_temperature_k = float_with_unit("temperature", "(°
|
1115
|
+
_temperature_c = float_with_unit("temperature", "(°C|° C|C|°)?")
|
1116
|
+
_temperature_k = float_with_unit("temperature", "(°K|° K|K)?")
|
1117
1117
|
_temperature_f = float_with_unit("temperature", "(°F|° F|F)?")
|
1118
1118
|
decibel = float_with_unit("decibel", "(dB|dBm|db|dbm)", optional_unit=True)
|
1119
1119
|
pressure = float_with_unit("pressure", "(bar|Bar)", optional_unit=True)
|
esphome/const.py
CHANGED
@@ -4,7 +4,7 @@ from enum import Enum
|
|
4
4
|
|
5
5
|
from esphome.enum import StrEnum
|
6
6
|
|
7
|
-
__version__ = "2025.
|
7
|
+
__version__ = "2025.9.0"
|
8
8
|
|
9
9
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
10
10
|
VALID_SUBSTITUTIONS_CHARACTERS = (
|
@@ -114,6 +114,7 @@ CONF_AND = "and"
|
|
114
114
|
CONF_ANGLE = "angle"
|
115
115
|
CONF_ANY = "any"
|
116
116
|
CONF_AP = "ap"
|
117
|
+
CONF_API = "api"
|
117
118
|
CONF_APPARENT_POWER = "apparent_power"
|
118
119
|
CONF_ARDUINO_VERSION = "arduino_version"
|
119
120
|
CONF_AREA = "area"
|
@@ -424,6 +425,7 @@ CONF_HEAD = "head"
|
|
424
425
|
CONF_HEADING = "heading"
|
425
426
|
CONF_HEARTBEAT = "heartbeat"
|
426
427
|
CONF_HEAT_ACTION = "heat_action"
|
428
|
+
CONF_HEAT_COOL_MODE = "heat_cool_mode"
|
427
429
|
CONF_HEAT_DEADBAND = "heat_deadband"
|
428
430
|
CONF_HEAT_MODE = "heat_mode"
|
429
431
|
CONF_HEAT_OVERRUN = "heat_overrun"
|
esphome/core/__init__.py
CHANGED
esphome/core/application.cpp
CHANGED
@@ -34,37 +34,20 @@ namespace esphome {
|
|
34
34
|
|
35
35
|
static const char *const TAG = "app";
|
36
36
|
|
37
|
-
// Helper function for insertion sort of components by
|
37
|
+
// Helper function for insertion sort of components by priority
|
38
38
|
// Using insertion sort instead of std::stable_sort saves ~1.3KB of flash
|
39
39
|
// by avoiding template instantiations (std::rotate, std::stable_sort, lambdas)
|
40
40
|
// IMPORTANT: This sort is stable (preserves relative order of equal elements),
|
41
41
|
// which is necessary to maintain user-defined component order for same priority
|
42
|
-
template<typename Iterator
|
42
|
+
template<typename Iterator, float (Component::*GetPriority)() const>
|
43
|
+
static void insertion_sort_by_priority(Iterator first, Iterator last) {
|
43
44
|
for (auto it = first + 1; it != last; ++it) {
|
44
45
|
auto key = *it;
|
45
|
-
float key_priority = key
|
46
|
+
float key_priority = (key->*GetPriority)();
|
46
47
|
auto j = it - 1;
|
47
48
|
|
48
49
|
// Using '<' (not '<=') ensures stability - equal priority components keep their order
|
49
|
-
while (j >= first && (*j)
|
50
|
-
*(j + 1) = *j;
|
51
|
-
j--;
|
52
|
-
}
|
53
|
-
*(j + 1) = key;
|
54
|
-
}
|
55
|
-
}
|
56
|
-
|
57
|
-
// Helper function for insertion sort of components by loop priority
|
58
|
-
// IMPORTANT: This sort is stable (preserves relative order of equal elements),
|
59
|
-
// which is required when components are re-sorted during setup() if they block
|
60
|
-
template<typename Iterator> static void insertion_sort_by_loop_priority(Iterator first, Iterator last) {
|
61
|
-
for (auto it = first + 1; it != last; ++it) {
|
62
|
-
auto key = *it;
|
63
|
-
float key_priority = key->get_loop_priority();
|
64
|
-
auto j = it - 1;
|
65
|
-
|
66
|
-
// Using '<' (not '<=') ensures stability - equal priority components keep their order
|
67
|
-
while (j >= first && (*j)->get_loop_priority() < key_priority) {
|
50
|
+
while (j >= first && ((*j)->*GetPriority)() < key_priority) {
|
68
51
|
*(j + 1) = *j;
|
69
52
|
j--;
|
70
53
|
}
|
@@ -80,7 +63,7 @@ void Application::register_component_(Component *comp) {
|
|
80
63
|
|
81
64
|
for (auto *c : this->components_) {
|
82
65
|
if (comp == c) {
|
83
|
-
ESP_LOGW(TAG, "Component %s already registered! (%p)", c->
|
66
|
+
ESP_LOGW(TAG, "Component %s already registered! (%p)", LOG_STR_ARG(c->get_component_log_str()), c);
|
84
67
|
return;
|
85
68
|
}
|
86
69
|
}
|
@@ -91,7 +74,8 @@ void Application::setup() {
|
|
91
74
|
ESP_LOGV(TAG, "Sorting components by setup priority");
|
92
75
|
|
93
76
|
// Sort by setup priority using our helper function
|
94
|
-
|
77
|
+
insertion_sort_by_priority<decltype(this->components_.begin()), &Component::get_actual_setup_priority>(
|
78
|
+
this->components_.begin(), this->components_.end());
|
95
79
|
|
96
80
|
// Initialize looping_components_ early so enable_pending_loops_() works during setup
|
97
81
|
this->calculate_looping_components_();
|
@@ -108,7 +92,8 @@ void Application::setup() {
|
|
108
92
|
continue;
|
109
93
|
|
110
94
|
// Sort components 0 through i by loop priority
|
111
|
-
|
95
|
+
insertion_sort_by_priority<decltype(this->components_.begin()), &Component::get_loop_priority>(
|
96
|
+
this->components_.begin(), this->components_.begin() + i + 1);
|
112
97
|
|
113
98
|
do {
|
114
99
|
uint8_t new_app_state = STATUS_LED_WARNING;
|
@@ -256,30 +241,79 @@ void Application::run_powerdown_hooks() {
|
|
256
241
|
void Application::teardown_components(uint32_t timeout_ms) {
|
257
242
|
uint32_t start_time = millis();
|
258
243
|
|
259
|
-
//
|
244
|
+
// Use a StaticVector instead of std::vector to avoid heap allocation
|
245
|
+
// since we know the actual size at compile time
|
246
|
+
StaticVector<Component *, ESPHOME_COMPONENT_COUNT> pending_components;
|
247
|
+
|
248
|
+
// Copy all components in reverse order
|
260
249
|
// Reverse order matches the behavior of run_safe_shutdown_hooks() above and ensures
|
261
250
|
// components are torn down in the opposite order of their setup_priority (which is
|
262
251
|
// used to sort components during Application::setup())
|
263
|
-
|
252
|
+
size_t num_components = this->components_.size();
|
253
|
+
for (size_t i = 0; i < num_components; ++i) {
|
254
|
+
pending_components[i] = this->components_[num_components - 1 - i];
|
255
|
+
}
|
264
256
|
|
265
257
|
uint32_t now = start_time;
|
266
|
-
|
258
|
+
size_t pending_count = num_components;
|
259
|
+
|
260
|
+
// Teardown Algorithm
|
261
|
+
// ==================
|
262
|
+
// We iterate through pending components, calling teardown() on each.
|
263
|
+
// Components that return false (need more time) are copied forward
|
264
|
+
// in the array. Components that return true (finished) are skipped.
|
265
|
+
//
|
266
|
+
// The compaction happens in-place during iteration:
|
267
|
+
// - still_pending tracks the write position (where to put next pending component)
|
268
|
+
// - i tracks the read position (which component we're testing)
|
269
|
+
// - When teardown() returns false, we copy component[i] to component[still_pending]
|
270
|
+
// - When teardown() returns true, we just skip it (don't increment still_pending)
|
271
|
+
//
|
272
|
+
// Example with 4 components where B can teardown immediately:
|
273
|
+
//
|
274
|
+
// Start:
|
275
|
+
// pending_components: [A, B, C, D]
|
276
|
+
// pending_count: 4 ^----------^
|
277
|
+
//
|
278
|
+
// Iteration 1:
|
279
|
+
// i=0: A needs more time → keep at pos 0 (no copy needed)
|
280
|
+
// i=1: B finished → skip
|
281
|
+
// i=2: C needs more time → copy to pos 1
|
282
|
+
// i=3: D needs more time → copy to pos 2
|
283
|
+
//
|
284
|
+
// After iteration 1:
|
285
|
+
// pending_components: [A, C, D | D]
|
286
|
+
// pending_count: 3 ^--------^
|
287
|
+
//
|
288
|
+
// Iteration 2:
|
289
|
+
// i=0: A finished → skip
|
290
|
+
// i=1: C needs more time → copy to pos 0
|
291
|
+
// i=2: D finished → skip
|
292
|
+
//
|
293
|
+
// After iteration 2:
|
294
|
+
// pending_components: [C | C, D, D] (positions 1-3 have old values)
|
295
|
+
// pending_count: 1 ^--^
|
296
|
+
|
297
|
+
while (pending_count > 0 && (now - start_time) < timeout_ms) {
|
267
298
|
// Feed watchdog during teardown to prevent triggering
|
268
299
|
this->feed_wdt(now);
|
269
300
|
|
270
|
-
//
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
301
|
+
// Process components and compact the array, keeping only those still pending
|
302
|
+
size_t still_pending = 0;
|
303
|
+
for (size_t i = 0; i < pending_count; ++i) {
|
304
|
+
if (!pending_components[i]->teardown()) {
|
305
|
+
// Component still needs time, copy it forward
|
306
|
+
if (still_pending != i) {
|
307
|
+
pending_components[still_pending] = pending_components[i];
|
308
|
+
}
|
309
|
+
++still_pending;
|
278
310
|
}
|
311
|
+
// Component finished teardown, skip it (don't increment still_pending)
|
279
312
|
}
|
313
|
+
pending_count = still_pending;
|
280
314
|
|
281
315
|
// Give some time for I/O operations if components are still pending
|
282
|
-
if (
|
316
|
+
if (pending_count > 0) {
|
283
317
|
this->yield_with_select_(1);
|
284
318
|
}
|
285
319
|
|
@@ -287,12 +321,12 @@ void Application::teardown_components(uint32_t timeout_ms) {
|
|
287
321
|
now = millis();
|
288
322
|
}
|
289
323
|
|
290
|
-
if (
|
324
|
+
if (pending_count > 0) {
|
291
325
|
// Note: At this point, connections are either disconnected or in a bad state,
|
292
326
|
// so this warning will only appear via serial rather than being transmitted to clients
|
293
|
-
for (
|
294
|
-
ESP_LOGW(TAG, "%s did not complete teardown within %" PRIu32 " ms",
|
295
|
-
timeout_ms);
|
327
|
+
for (size_t i = 0; i < pending_count; ++i) {
|
328
|
+
ESP_LOGW(TAG, "%s did not complete teardown within %" PRIu32 " ms",
|
329
|
+
LOG_STR_ARG(pending_components[i]->get_component_log_str()), timeout_ms);
|
296
330
|
}
|
297
331
|
}
|
298
332
|
}
|
@@ -312,20 +346,19 @@ void Application::calculate_looping_components_() {
|
|
312
346
|
// Add all components with loop override that aren't already LOOP_DONE
|
313
347
|
// Some components (like logger) may call disable_loop() during initialization
|
314
348
|
// before setup runs, so we need to respect their LOOP_DONE state
|
315
|
-
|
316
|
-
if (obj->has_overridden_loop() &&
|
317
|
-
(obj->get_component_state() & COMPONENT_STATE_MASK) != COMPONENT_STATE_LOOP_DONE) {
|
318
|
-
this->looping_components_.push_back(obj);
|
319
|
-
}
|
320
|
-
}
|
349
|
+
this->add_looping_components_by_state_(false);
|
321
350
|
|
322
351
|
this->looping_components_active_end_ = this->looping_components_.size();
|
323
352
|
|
324
353
|
// Then add any components that are already LOOP_DONE to the inactive section
|
325
354
|
// This handles components that called disable_loop() during initialization
|
355
|
+
this->add_looping_components_by_state_(true);
|
356
|
+
}
|
357
|
+
|
358
|
+
void Application::add_looping_components_by_state_(bool match_loop_done) {
|
326
359
|
for (auto *obj : this->components_) {
|
327
360
|
if (obj->has_overridden_loop() &&
|
328
|
-
(obj->get_component_state() & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE) {
|
361
|
+
((obj->get_component_state() & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE) == match_loop_done) {
|
329
362
|
this->looping_components_.push_back(obj);
|
330
363
|
}
|
331
364
|
}
|
@@ -424,7 +457,7 @@ void Application::enable_pending_loops_() {
|
|
424
457
|
|
425
458
|
// Clear the pending flag and enable the loop
|
426
459
|
component->pending_enable_loop_ = false;
|
427
|
-
ESP_LOGVV(TAG, "%s loop enabled from ISR", component->
|
460
|
+
ESP_LOGVV(TAG, "%s loop enabled from ISR", LOG_STR_ARG(component->get_component_log_str()));
|
428
461
|
component->component_state_ &= ~COMPONENT_STATE_MASK;
|
429
462
|
component->component_state_ |= COMPONENT_STATE_LOOP;
|
430
463
|
|
@@ -475,11 +508,16 @@ bool Application::register_socket_fd(int fd) {
|
|
475
508
|
if (fd < 0)
|
476
509
|
return false;
|
477
510
|
|
511
|
+
#ifndef USE_ESP32
|
512
|
+
// Only check on non-ESP32 platforms
|
513
|
+
// On ESP32 (both Arduino and ESP-IDF), CONFIG_LWIP_MAX_SOCKETS is always <= FD_SETSIZE by design
|
514
|
+
// (LWIP_SOCKET_OFFSET = FD_SETSIZE - CONFIG_LWIP_MAX_SOCKETS per lwipopts.h)
|
515
|
+
// Other platforms may not have this guarantee
|
478
516
|
if (fd >= FD_SETSIZE) {
|
479
|
-
ESP_LOGE(TAG, "
|
480
|
-
ESP_LOGE(TAG, "Socket will not be monitored for data - may cause performance issues!");
|
517
|
+
ESP_LOGE(TAG, "fd %d exceeds FD_SETSIZE %d", fd, FD_SETSIZE);
|
481
518
|
return false;
|
482
519
|
}
|
520
|
+
#endif
|
483
521
|
|
484
522
|
this->socket_fds_.push_back(fd);
|
485
523
|
this->socket_fds_changed_ = true;
|
esphome/core/application.h
CHANGED
@@ -431,6 +431,7 @@ class Application {
|
|
431
431
|
void register_component_(Component *comp);
|
432
432
|
|
433
433
|
void calculate_looping_components_();
|
434
|
+
void add_looping_components_by_state_(bool match_loop_done);
|
434
435
|
|
435
436
|
// These methods are called by Component::disable_loop() and Component::enable_loop()
|
436
437
|
// Components should not call these directly - use this->disable_loop() or this->enable_loop()
|
esphome/core/component.cpp
CHANGED
@@ -16,7 +16,6 @@
|
|
16
16
|
namespace esphome {
|
17
17
|
|
18
18
|
static const char *const TAG = "component";
|
19
|
-
static const char *const UNSPECIFIED_MESSAGE = "unspecified";
|
20
19
|
|
21
20
|
// Global vectors for component data that doesn't belong in every instance.
|
22
21
|
// Using vector instead of unordered_map for both because:
|
@@ -142,8 +141,8 @@ void Component::call_dump_config() {
|
|
142
141
|
}
|
143
142
|
}
|
144
143
|
}
|
145
|
-
ESP_LOGE(TAG, " %s is marked FAILED: %s", this->
|
146
|
-
error_msg ? error_msg :
|
144
|
+
ESP_LOGE(TAG, " %s is marked FAILED: %s", LOG_STR_ARG(this->get_component_log_str()),
|
145
|
+
error_msg ? error_msg : LOG_STR_LITERAL("unspecified"));
|
147
146
|
}
|
148
147
|
}
|
149
148
|
|
@@ -154,14 +153,14 @@ void Component::call() {
|
|
154
153
|
case COMPONENT_STATE_CONSTRUCTION: {
|
155
154
|
// State Construction: Call setup and set state to setup
|
156
155
|
this->set_component_state_(COMPONENT_STATE_SETUP);
|
157
|
-
ESP_LOGV(TAG, "Setup %s", this->
|
156
|
+
ESP_LOGV(TAG, "Setup %s", LOG_STR_ARG(this->get_component_log_str()));
|
158
157
|
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
|
159
158
|
uint32_t start_time = millis();
|
160
159
|
#endif
|
161
160
|
this->call_setup();
|
162
161
|
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
|
163
162
|
uint32_t setup_time = millis() - start_time;
|
164
|
-
ESP_LOGCONFIG(TAG, "Setup %s took %ums", this->
|
163
|
+
ESP_LOGCONFIG(TAG, "Setup %s took %ums", LOG_STR_ARG(this->get_component_log_str()), (unsigned) setup_time);
|
165
164
|
#endif
|
166
165
|
break;
|
167
166
|
}
|
@@ -182,10 +181,8 @@ void Component::call() {
|
|
182
181
|
break;
|
183
182
|
}
|
184
183
|
}
|
185
|
-
const
|
186
|
-
|
187
|
-
return "<unknown>";
|
188
|
-
return this->component_source_;
|
184
|
+
const LogString *Component::get_component_log_str() const {
|
185
|
+
return this->component_source_ == nullptr ? LOG_STR("<unknown>") : this->component_source_;
|
189
186
|
}
|
190
187
|
bool Component::should_warn_of_blocking(uint32_t blocking_time) {
|
191
188
|
if (blocking_time > this->warn_if_blocking_over_) {
|
@@ -201,7 +198,7 @@ bool Component::should_warn_of_blocking(uint32_t blocking_time) {
|
|
201
198
|
return false;
|
202
199
|
}
|
203
200
|
void Component::mark_failed() {
|
204
|
-
ESP_LOGE(TAG, "%s was marked as failed", this->
|
201
|
+
ESP_LOGE(TAG, "%s was marked as failed", LOG_STR_ARG(this->get_component_log_str()));
|
205
202
|
this->set_component_state_(COMPONENT_STATE_FAILED);
|
206
203
|
this->status_set_error();
|
207
204
|
// Also remove from loop since failed components shouldn't loop
|
@@ -213,14 +210,14 @@ void Component::set_component_state_(uint8_t state) {
|
|
213
210
|
}
|
214
211
|
void Component::disable_loop() {
|
215
212
|
if ((this->component_state_ & COMPONENT_STATE_MASK) != COMPONENT_STATE_LOOP_DONE) {
|
216
|
-
ESP_LOGVV(TAG, "%s loop disabled", this->
|
213
|
+
ESP_LOGVV(TAG, "%s loop disabled", LOG_STR_ARG(this->get_component_log_str()));
|
217
214
|
this->set_component_state_(COMPONENT_STATE_LOOP_DONE);
|
218
215
|
App.disable_component_loop_(this);
|
219
216
|
}
|
220
217
|
}
|
221
218
|
void Component::enable_loop() {
|
222
219
|
if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE) {
|
223
|
-
ESP_LOGVV(TAG, "%s loop enabled", this->
|
220
|
+
ESP_LOGVV(TAG, "%s loop enabled", LOG_STR_ARG(this->get_component_log_str()));
|
224
221
|
this->set_component_state_(COMPONENT_STATE_LOOP);
|
225
222
|
App.enable_component_loop_(this);
|
226
223
|
}
|
@@ -240,7 +237,7 @@ void IRAM_ATTR HOT Component::enable_loop_soon_any_context() {
|
|
240
237
|
}
|
241
238
|
void Component::reset_to_construction_state() {
|
242
239
|
if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_FAILED) {
|
243
|
-
ESP_LOGI(TAG, "%s is being reset to construction state", this->
|
240
|
+
ESP_LOGI(TAG, "%s is being reset to construction state", LOG_STR_ARG(this->get_component_log_str()));
|
244
241
|
this->set_component_state_(COMPONENT_STATE_CONSTRUCTION);
|
245
242
|
// Clear error status when resetting
|
246
243
|
this->status_clear_error();
|
@@ -280,20 +277,32 @@ bool Component::is_ready() const {
|
|
280
277
|
bool Component::can_proceed() { return true; }
|
281
278
|
bool Component::status_has_warning() const { return this->component_state_ & STATUS_LED_WARNING; }
|
282
279
|
bool Component::status_has_error() const { return this->component_state_ & STATUS_LED_ERROR; }
|
280
|
+
|
283
281
|
void Component::status_set_warning(const char *message) {
|
284
282
|
// Don't spam the log. This risks missing different warning messages though.
|
285
283
|
if ((this->component_state_ & STATUS_LED_WARNING) != 0)
|
286
284
|
return;
|
287
285
|
this->component_state_ |= STATUS_LED_WARNING;
|
288
286
|
App.app_state_ |= STATUS_LED_WARNING;
|
289
|
-
ESP_LOGW(TAG, "%s set Warning flag: %s", this->
|
287
|
+
ESP_LOGW(TAG, "%s set Warning flag: %s", LOG_STR_ARG(this->get_component_log_str()),
|
288
|
+
message ? message : LOG_STR_LITERAL("unspecified"));
|
289
|
+
}
|
290
|
+
void Component::status_set_warning(const LogString *message) {
|
291
|
+
// Don't spam the log. This risks missing different warning messages though.
|
292
|
+
if ((this->component_state_ & STATUS_LED_WARNING) != 0)
|
293
|
+
return;
|
294
|
+
this->component_state_ |= STATUS_LED_WARNING;
|
295
|
+
App.app_state_ |= STATUS_LED_WARNING;
|
296
|
+
ESP_LOGW(TAG, "%s set Warning flag: %s", LOG_STR_ARG(this->get_component_log_str()),
|
297
|
+
message ? LOG_STR_ARG(message) : LOG_STR_LITERAL("unspecified"));
|
290
298
|
}
|
291
299
|
void Component::status_set_error(const char *message) {
|
292
300
|
if ((this->component_state_ & STATUS_LED_ERROR) != 0)
|
293
301
|
return;
|
294
302
|
this->component_state_ |= STATUS_LED_ERROR;
|
295
303
|
App.app_state_ |= STATUS_LED_ERROR;
|
296
|
-
ESP_LOGE(TAG, "%s set Error flag: %s", this->
|
304
|
+
ESP_LOGE(TAG, "%s set Error flag: %s", LOG_STR_ARG(this->get_component_log_str()),
|
305
|
+
message ? message : LOG_STR_LITERAL("unspecified"));
|
297
306
|
if (message != nullptr) {
|
298
307
|
// Lazy allocate the error messages vector if needed
|
299
308
|
if (!component_error_messages) {
|
@@ -314,13 +323,13 @@ void Component::status_clear_warning() {
|
|
314
323
|
if ((this->component_state_ & STATUS_LED_WARNING) == 0)
|
315
324
|
return;
|
316
325
|
this->component_state_ &= ~STATUS_LED_WARNING;
|
317
|
-
ESP_LOGW(TAG, "%s cleared Warning flag", this->
|
326
|
+
ESP_LOGW(TAG, "%s cleared Warning flag", LOG_STR_ARG(this->get_component_log_str()));
|
318
327
|
}
|
319
328
|
void Component::status_clear_error() {
|
320
329
|
if ((this->component_state_ & STATUS_LED_ERROR) == 0)
|
321
330
|
return;
|
322
331
|
this->component_state_ &= ~STATUS_LED_ERROR;
|
323
|
-
ESP_LOGE(TAG, "%s cleared Error flag", this->
|
332
|
+
ESP_LOGE(TAG, "%s cleared Error flag", LOG_STR_ARG(this->get_component_log_str()));
|
324
333
|
}
|
325
334
|
void Component::status_momentary_warning(const std::string &name, uint32_t length) {
|
326
335
|
this->status_set_warning();
|
@@ -331,6 +340,18 @@ void Component::status_momentary_error(const std::string &name, uint32_t length)
|
|
331
340
|
this->set_timeout(name, length, [this]() { this->status_clear_error(); });
|
332
341
|
}
|
333
342
|
void Component::dump_config() {}
|
343
|
+
|
344
|
+
// Function implementation of LOG_UPDATE_INTERVAL macro to reduce code size
|
345
|
+
void log_update_interval(const char *tag, PollingComponent *component) {
|
346
|
+
uint32_t update_interval = component->get_update_interval();
|
347
|
+
if (update_interval == SCHEDULER_DONT_RUN) {
|
348
|
+
ESP_LOGCONFIG(tag, " Update Interval: never");
|
349
|
+
} else if (update_interval < 100) {
|
350
|
+
ESP_LOGCONFIG(tag, " Update Interval: %.3fs", update_interval / 1000.0f);
|
351
|
+
} else {
|
352
|
+
ESP_LOGCONFIG(tag, " Update Interval: %.1fs", update_interval / 1000.0f);
|
353
|
+
}
|
354
|
+
}
|
334
355
|
float Component::get_actual_setup_priority() const {
|
335
356
|
// Check if there's an override in the global vector
|
336
357
|
if (setup_priority_overrides) {
|
@@ -419,8 +440,9 @@ uint32_t WarnIfComponentBlockingGuard::finish() {
|
|
419
440
|
should_warn = blocking_time > WARN_IF_BLOCKING_OVER_MS;
|
420
441
|
}
|
421
442
|
if (should_warn) {
|
422
|
-
|
423
|
-
|
443
|
+
ESP_LOGW(TAG, "%s took a long time for an operation (%" PRIu32 " ms)",
|
444
|
+
component_ == nullptr ? LOG_STR_LITERAL("<null>") : LOG_STR_ARG(component_->get_component_log_str()),
|
445
|
+
blocking_time);
|
424
446
|
ESP_LOGW(TAG, "Components should block for at most 30 ms");
|
425
447
|
}
|
426
448
|
|
esphome/core/component.h
CHANGED
@@ -5,10 +5,14 @@
|
|
5
5
|
#include <functional>
|
6
6
|
#include <string>
|
7
7
|
|
8
|
+
#include "esphome/core/log.h"
|
8
9
|
#include "esphome/core/optional.h"
|
9
10
|
|
10
11
|
namespace esphome {
|
11
12
|
|
13
|
+
// Forward declaration for LogString
|
14
|
+
struct LogString;
|
15
|
+
|
12
16
|
/** Default setup priorities for components of different types.
|
13
17
|
*
|
14
18
|
* Components should return one of these setup priorities in get_setup_priority.
|
@@ -44,14 +48,13 @@ extern const float LATE;
|
|
44
48
|
|
45
49
|
static const uint32_t SCHEDULER_DONT_RUN = 4294967295UL;
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
}
|
51
|
+
// Forward declaration
|
52
|
+
class PollingComponent;
|
53
|
+
|
54
|
+
// Function declaration for LOG_UPDATE_INTERVAL
|
55
|
+
void log_update_interval(const char *tag, PollingComponent *component);
|
56
|
+
|
57
|
+
#define LOG_UPDATE_INTERVAL(this) log_update_interval(TAG, this)
|
55
58
|
|
56
59
|
extern const uint8_t COMPONENT_STATE_MASK;
|
57
60
|
extern const uint8_t COMPONENT_STATE_CONSTRUCTION;
|
@@ -203,6 +206,7 @@ class Component {
|
|
203
206
|
bool status_has_error() const;
|
204
207
|
|
205
208
|
void status_set_warning(const char *message = nullptr);
|
209
|
+
void status_set_warning(const LogString *message);
|
206
210
|
|
207
211
|
void status_set_error(const char *message = nullptr);
|
208
212
|
|
@@ -220,12 +224,12 @@ class Component {
|
|
220
224
|
*
|
221
225
|
* This is set by the ESPHome core, and should not be called manually.
|
222
226
|
*/
|
223
|
-
void set_component_source(const
|
224
|
-
/** Get the integration where this component was declared as a
|
227
|
+
void set_component_source(const LogString *source) { component_source_ = source; }
|
228
|
+
/** Get the integration where this component was declared as a LogString for logging.
|
225
229
|
*
|
226
|
-
* Returns "<unknown>" if source not set
|
230
|
+
* Returns LOG_STR("<unknown>") if source not set
|
227
231
|
*/
|
228
|
-
const
|
232
|
+
const LogString *get_component_log_str() const;
|
229
233
|
|
230
234
|
bool should_warn_of_blocking(uint32_t blocking_time);
|
231
235
|
|
@@ -405,7 +409,7 @@ class Component {
|
|
405
409
|
bool cancel_defer(const std::string &name); // NOLINT
|
406
410
|
|
407
411
|
// Ordered for optimal packing on 32-bit systems
|
408
|
-
const
|
412
|
+
const LogString *component_source_{nullptr};
|
409
413
|
uint16_t warn_if_blocking_over_{WARN_IF_BLOCKING_OVER_MS}; ///< Warn if blocked for this many ms (max 65.5s)
|
410
414
|
/// State of this component - each bit has a purpose:
|
411
415
|
/// Bits 0-2: Component state (0x00=CONSTRUCTION, 0x01=SETUP, 0x02=LOOP, 0x03=FAILED, 0x04=LOOP_DONE)
|
esphome/core/config.py
CHANGED
@@ -39,7 +39,7 @@ from esphome.const import (
|
|
39
39
|
PlatformFramework,
|
40
40
|
__version__ as ESPHOME_VERSION,
|
41
41
|
)
|
42
|
-
from esphome.core import CORE, coroutine_with_priority
|
42
|
+
from esphome.core import CORE, CoroPriority, coroutine_with_priority
|
43
43
|
from esphome.helpers import (
|
44
44
|
copy_file_if_changed,
|
45
45
|
fnv1a_32bit_hash,
|
@@ -359,7 +359,7 @@ ARDUINO_GLUE_CODE = """\
|
|
359
359
|
"""
|
360
360
|
|
361
361
|
|
362
|
-
@coroutine_with_priority(
|
362
|
+
@coroutine_with_priority(CoroPriority.WORKAROUNDS)
|
363
363
|
async def add_arduino_global_workaround():
|
364
364
|
# The Arduino framework defined these itself in the global
|
365
365
|
# namespace. For the esphome codebase that is not a problem,
|
@@ -376,7 +376,7 @@ async def add_arduino_global_workaround():
|
|
376
376
|
cg.add_global(cg.RawStatement(line))
|
377
377
|
|
378
378
|
|
379
|
-
@coroutine_with_priority(
|
379
|
+
@coroutine_with_priority(CoroPriority.FINAL)
|
380
380
|
async def add_includes(includes):
|
381
381
|
# Add includes at the very end, so that the included files can access global variables
|
382
382
|
for include in includes:
|
@@ -392,7 +392,7 @@ async def add_includes(includes):
|
|
392
392
|
include_file(path, basename)
|
393
393
|
|
394
394
|
|
395
|
-
@coroutine_with_priority(
|
395
|
+
@coroutine_with_priority(CoroPriority.FINAL)
|
396
396
|
async def _add_platformio_options(pio_options):
|
397
397
|
# Add includes at the very end, so that they override everything
|
398
398
|
for key, val in pio_options.items():
|
@@ -401,7 +401,7 @@ async def _add_platformio_options(pio_options):
|
|
401
401
|
cg.add_platformio_option(key, val)
|
402
402
|
|
403
403
|
|
404
|
-
@coroutine_with_priority(
|
404
|
+
@coroutine_with_priority(CoroPriority.AUTOMATION)
|
405
405
|
async def _add_automations(config):
|
406
406
|
for conf in config.get(CONF_ON_BOOT, []):
|
407
407
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], conf.get(CONF_PRIORITY))
|
@@ -423,7 +423,7 @@ async def _add_automations(config):
|
|
423
423
|
DATETIME_SUBTYPES = {"date", "time", "datetime"}
|
424
424
|
|
425
425
|
|
426
|
-
@coroutine_with_priority(
|
426
|
+
@coroutine_with_priority(CoroPriority.FINAL)
|
427
427
|
async def _add_platform_defines() -> None:
|
428
428
|
# Generate compile-time defines for platforms that have actual entities
|
429
429
|
# Only add USE_* and count defines when there are entities
|
@@ -442,7 +442,7 @@ async def _add_platform_defines() -> None:
|
|
442
442
|
cg.add_define(f"USE_{platform_name.upper()}")
|
443
443
|
|
444
444
|
|
445
|
-
@coroutine_with_priority(
|
445
|
+
@coroutine_with_priority(CoroPriority.CORE)
|
446
446
|
async def to_code(config: ConfigType) -> None:
|
447
447
|
cg.add_global(cg.global_ns.namespace("esphome").using)
|
448
448
|
# These can be used by user lambdas, put them to default scope
|