esphome 2025.7.4__py3-none-any.whl → 2025.8.0b1__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.

Potentially problematic release.


This version of esphome might be problematic. Click here for more details.

Files changed (754) hide show
  1. esphome/__main__.py +189 -82
  2. esphome/automation.py +2 -4
  3. esphome/build_gen/__init__.py +0 -0
  4. esphome/build_gen/platformio.py +102 -0
  5. esphome/components/a4988/a4988.cpp +0 -1
  6. esphome/components/absolute_humidity/absolute_humidity.cpp +0 -2
  7. esphome/components/absolute_humidity/sensor.py +2 -2
  8. esphome/components/adc/__init__.py +123 -85
  9. esphome/components/adc/adc_sensor.h +98 -35
  10. esphome/components/adc/adc_sensor_common.cpp +10 -4
  11. esphome/components/adc/adc_sensor_esp32.cpp +291 -123
  12. esphome/components/adc/adc_sensor_esp8266.cpp +1 -4
  13. esphome/components/adc/adc_sensor_libretiny.cpp +1 -2
  14. esphome/components/adc/adc_sensor_rp2040.cpp +1 -2
  15. esphome/components/adc/adc_sensor_zephyr.cpp +207 -0
  16. esphome/components/adc/sensor.py +61 -27
  17. esphome/components/adc128s102/adc128s102.cpp +1 -4
  18. esphome/components/ade7880/sensor.py +75 -49
  19. esphome/components/ads1115/ads1115.cpp +0 -1
  20. esphome/components/ads1118/ads1118.cpp +0 -1
  21. esphome/components/ags10/ags10.cpp +0 -4
  22. esphome/components/aht10/aht10.cpp +0 -4
  23. esphome/components/aic3204/aic3204.cpp +0 -2
  24. esphome/components/airthings_wave_plus/__init__.py +1 -1
  25. esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +22 -4
  26. esphome/components/airthings_wave_plus/airthings_wave_plus.h +10 -1
  27. esphome/components/airthings_wave_plus/sensor.py +55 -28
  28. esphome/components/alarm_control_panel/__init__.py +4 -9
  29. esphome/components/am2315c/am2315c.cpp +0 -2
  30. esphome/components/am2320/am2320.cpp +0 -1
  31. esphome/components/animation/__init__.py +14 -11
  32. esphome/components/apds9306/apds9306.cpp +0 -4
  33. esphome/components/apds9960/apds9960.cpp +0 -1
  34. esphome/components/api/__init__.py +29 -4
  35. esphome/components/api/api_connection.cpp +378 -401
  36. esphome/components/api/api_connection.h +112 -56
  37. esphome/components/api/api_frame_helper.cpp +69 -896
  38. esphome/components/api/api_frame_helper.h +31 -126
  39. esphome/components/api/api_frame_helper_noise.cpp +583 -0
  40. esphome/components/api/api_frame_helper_noise.h +68 -0
  41. esphome/components/api/api_frame_helper_plaintext.cpp +290 -0
  42. esphome/components/api/api_frame_helper_plaintext.h +53 -0
  43. esphome/components/api/api_noise_context.h +2 -4
  44. esphome/components/api/api_pb2.cpp +1601 -1808
  45. esphome/components/api/api_pb2.h +367 -323
  46. esphome/components/api/api_pb2_dump.cpp +1137 -3466
  47. esphome/components/api/api_pb2_includes.h +34 -0
  48. esphome/components/api/api_pb2_service.cpp +94 -105
  49. esphome/components/api/api_pb2_service.h +27 -16
  50. esphome/components/api/api_server.cpp +18 -17
  51. esphome/components/api/api_server.h +8 -5
  52. esphome/components/api/client.py +16 -8
  53. esphome/components/api/custom_api_device.h +68 -14
  54. esphome/components/api/homeassistant_service.h +24 -19
  55. esphome/components/api/list_entities.cpp +3 -5
  56. esphome/components/api/list_entities.h +2 -4
  57. esphome/components/api/proto.cpp +3 -5
  58. esphome/components/api/proto.h +239 -274
  59. esphome/components/api/subscribe_state.cpp +2 -4
  60. esphome/components/api/subscribe_state.h +2 -4
  61. esphome/components/api/user_services.cpp +2 -4
  62. esphome/components/api/user_services.h +8 -8
  63. esphome/components/as3935/as3935.cpp +0 -2
  64. esphome/components/as3935_spi/as3935_spi.cpp +0 -2
  65. esphome/components/as5600/__init__.py +1 -1
  66. esphome/components/as5600/as5600.cpp +0 -2
  67. esphome/components/as5600/sensor/__init__.py +0 -1
  68. esphome/components/as7341/as7341.cpp +0 -1
  69. esphome/components/async_tcp/__init__.py +1 -1
  70. esphome/components/at581x/at581x.cpp +1 -1
  71. esphome/components/atm90e26/atm90e26.cpp +0 -1
  72. esphome/components/atm90e32/atm90e32.cpp +488 -118
  73. esphome/components/atm90e32/atm90e32.h +44 -5
  74. esphome/components/audio/audio.h +2 -2
  75. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +0 -2
  76. esphome/components/beken_spi_led_strip/led_strip.cpp +0 -2
  77. esphome/components/bh1750/bh1750.cpp +0 -1
  78. esphome/components/binary_sensor/__init__.py +14 -12
  79. esphome/components/ble_client/__init__.py +4 -7
  80. esphome/components/bluetooth_proxy/__init__.py +40 -3
  81. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +387 -82
  82. esphome/components/bluetooth_proxy/bluetooth_connection.h +16 -5
  83. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +102 -311
  84. esphome/components/bluetooth_proxy/bluetooth_proxy.h +30 -14
  85. esphome/components/bme280_base/bme280_base.cpp +15 -16
  86. esphome/components/bme680/bme680.cpp +2 -3
  87. esphome/components/bme680_bsec/bme680_bsec.cpp +0 -2
  88. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +0 -2
  89. esphome/components/bmi160/bmi160.cpp +0 -1
  90. esphome/components/bmp085/bmp085.cpp +0 -1
  91. esphome/components/bmp280_base/bmp280_base.cpp +13 -14
  92. esphome/components/bmp3xx_base/bmp3xx_base.cpp +0 -1
  93. esphome/components/bmp581/bmp581.cpp +0 -2
  94. esphome/components/bp1658cj/bp1658cj.cpp +0 -1
  95. esphome/components/bp5758d/bp5758d.cpp +0 -1
  96. esphome/components/button/__init__.py +0 -1
  97. esphome/components/canbus/__init__.py +2 -3
  98. esphome/components/canbus/canbus.cpp +0 -1
  99. esphome/components/cap1188/cap1188.cpp +0 -2
  100. esphome/components/captive_portal/__init__.py +1 -1
  101. esphome/components/cd74hc4067/cd74hc4067.cpp +0 -2
  102. esphome/components/ch422g/ch422g.cpp +0 -1
  103. esphome/components/chsc6x/chsc6x_touchscreen.cpp +0 -3
  104. esphome/components/climate/__init__.py +0 -1
  105. esphome/components/climate/climate_traits.h +24 -0
  106. esphome/components/cm1106/cm1106.cpp +0 -1
  107. esphome/components/const/__init__.py +6 -0
  108. esphome/components/cover/__init__.py +0 -1
  109. esphome/components/cover/cover.cpp +9 -13
  110. esphome/components/cs5460a/cs5460a.cpp +0 -2
  111. esphome/components/cse7761/cse7761.cpp +0 -1
  112. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +0 -2
  113. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +0 -2
  114. esphome/components/dac7678/dac7678_output.cpp +0 -2
  115. esphome/components/dallas_temp/dallas_temp.cpp +0 -1
  116. esphome/components/datetime/__init__.py +0 -2
  117. esphome/components/debug/__init__.py +15 -1
  118. esphome/components/debug/debug_zephyr.cpp +281 -0
  119. esphome/components/debug/sensor.py +2 -1
  120. esphome/components/deep_sleep/deep_sleep_component.cpp +0 -1
  121. esphome/components/deep_sleep/deep_sleep_esp32.cpp +20 -1
  122. esphome/components/dfrobot_sen0395/__init__.py +1 -2
  123. esphome/components/dht/dht.cpp +0 -1
  124. esphome/components/dht12/dht12.cpp +0 -1
  125. esphome/components/display/__init__.py +16 -3
  126. esphome/components/display_menu_base/__init__.py +1 -1
  127. esphome/components/dps310/dps310.cpp +0 -2
  128. esphome/components/ds1307/ds1307.cpp +0 -1
  129. esphome/components/ds2484/ds2484.cpp +0 -1
  130. esphome/components/duty_cycle/duty_cycle_sensor.cpp +0 -1
  131. esphome/components/ee895/ee895.cpp +0 -1
  132. esphome/components/ektf2232/touchscreen/ektf2232.cpp +0 -1
  133. esphome/components/emc2101/emc2101.cpp +0 -2
  134. esphome/components/ens160_base/ens160_base.cpp +0 -2
  135. esphome/components/ens210/ens210.cpp +0 -1
  136. esphome/components/es7210/es7210.cpp +0 -2
  137. esphome/components/es7243e/es7243e.cpp +0 -2
  138. esphome/components/es8156/es8156.cpp +0 -2
  139. esphome/components/es8311/es8311.cpp +0 -2
  140. esphome/components/es8388/es8388.cpp +0 -2
  141. esphome/components/esp32/__init__.py +199 -58
  142. esphome/components/esp32/boards.py +17 -0
  143. esphome/components/esp32/gpio.cpp +0 -1
  144. esphome/components/esp32/gpio.py +1 -2
  145. esphome/components/esp32/gpio_esp32_h2.py +2 -7
  146. esphome/components/esp32/gpio_esp32_p4.py +2 -7
  147. esphome/components/esp32/post_build.py.script +112 -61
  148. esphome/components/esp32_ble/__init__.py +40 -2
  149. esphome/components/esp32_ble/ble.cpp +12 -8
  150. esphome/components/esp32_ble/ble.h +18 -18
  151. esphome/components/esp32_ble/ble_advertising.cpp +5 -5
  152. esphome/components/esp32_ble/ble_advertising.h +7 -5
  153. esphome/components/esp32_ble/ble_event.h +2 -4
  154. esphome/components/esp32_ble/ble_scan_result.h +2 -4
  155. esphome/components/esp32_ble/ble_uuid.cpp +5 -5
  156. esphome/components/esp32_ble/ble_uuid.h +6 -5
  157. esphome/components/esp32_ble_beacon/__init__.py +4 -0
  158. esphome/components/esp32_ble_client/__init__.py +1 -1
  159. esphome/components/esp32_ble_client/ble_characteristic.cpp +4 -4
  160. esphome/components/esp32_ble_client/ble_characteristic.h +6 -4
  161. esphome/components/esp32_ble_client/ble_client_base.cpp +155 -104
  162. esphome/components/esp32_ble_client/ble_client_base.h +17 -6
  163. esphome/components/esp32_ble_client/ble_descriptor.h +6 -4
  164. esphome/components/esp32_ble_client/ble_service.cpp +4 -4
  165. esphome/components/esp32_ble_client/ble_service.h +6 -4
  166. esphome/components/esp32_ble_server/__init__.py +15 -12
  167. esphome/components/esp32_ble_tracker/__init__.py +79 -11
  168. esphome/components/esp32_ble_tracker/automation.h +4 -4
  169. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +264 -261
  170. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +103 -37
  171. esphome/components/esp32_camera/__init__.py +13 -1
  172. esphome/components/esp32_camera/esp32_camera.cpp +7 -2
  173. esphome/components/esp32_camera/esp32_camera.h +1 -0
  174. esphome/components/esp32_dac/esp32_dac.cpp +3 -19
  175. esphome/components/esp32_dac/esp32_dac.h +4 -8
  176. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -6
  177. esphome/components/esp32_rmt_led_strip/light.py +1 -1
  178. esphome/components/esp32_touch/__init__.py +2 -3
  179. esphome/components/esp32_touch/esp32_touch.h +9 -6
  180. esphome/components/esp32_touch/esp32_touch_common.cpp +2 -0
  181. esphome/components/esp32_touch/esp32_touch_v1.cpp +7 -9
  182. esphome/components/esp32_touch/esp32_touch_v2.cpp +10 -6
  183. esphome/components/esp8266/__init__.py +3 -1
  184. esphome/components/esp8266_pwm/esp8266_pwm.cpp +0 -1
  185. esphome/components/esphome/ota/__init__.py +1 -2
  186. esphome/components/esphome/ota/ota_esphome.cpp +150 -77
  187. esphome/components/esphome/ota/ota_esphome.h +8 -1
  188. esphome/components/espnow/__init__.py +309 -0
  189. esphome/components/espnow/automation.h +175 -0
  190. esphome/components/espnow/espnow_component.cpp +468 -0
  191. esphome/components/espnow/espnow_component.h +183 -0
  192. esphome/components/espnow/espnow_err.h +19 -0
  193. esphome/components/espnow/espnow_packet.h +166 -0
  194. esphome/components/ethernet/__init__.py +7 -1
  195. esphome/components/ethernet/esp_eth_phy_jl1101.c +5 -0
  196. esphome/components/ethernet/ethernet_component.cpp +0 -1
  197. esphome/components/ethernet/ethernet_component.h +4 -0
  198. esphome/components/ethernet_info/ethernet_info_text_sensor.h +0 -3
  199. esphome/components/event/__init__.py +0 -1
  200. esphome/components/factory_reset/__init__.py +92 -0
  201. esphome/components/factory_reset/factory_reset.cpp +76 -0
  202. esphome/components/factory_reset/factory_reset.h +43 -0
  203. esphome/components/fan/__init__.py +0 -1
  204. esphome/components/fan/fan_traits.h +16 -0
  205. esphome/components/fastled_base/fastled_light.cpp +0 -1
  206. esphome/components/fastled_spi/light.py +1 -3
  207. esphome/components/fingerprint_grow/fingerprint_grow.cpp +0 -2
  208. esphome/components/font/__init__.py +9 -1
  209. esphome/components/fs3000/fs3000.cpp +0 -2
  210. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
  211. esphome/components/ft63x6/ft63x6.cpp +0 -1
  212. esphome/components/gdk101/gdk101.cpp +0 -1
  213. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
  214. esphome/components/gl_r01_i2c/sensor.py +1 -1
  215. esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
  216. esphome/components/gpio/switch/gpio_switch.cpp +0 -2
  217. esphome/components/gpio_expander/cached_gpio.h +24 -15
  218. esphome/components/gps/__init__.py +6 -2
  219. esphome/components/gps/gps.cpp +50 -49
  220. esphome/components/gps/gps.h +4 -8
  221. esphome/components/gps/time/gps_time.cpp +3 -9
  222. esphome/components/gps/time/gps_time.h +4 -7
  223. esphome/components/graph/__init__.py +1 -1
  224. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
  225. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
  227. esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
  228. esphome/components/haier/climate.py +5 -10
  229. esphome/components/haier/haier_base.cpp +0 -1
  230. esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
  231. esphome/components/hdc1080/hdc1080.cpp +0 -2
  232. esphome/components/heatpumpir/climate.py +2 -2
  233. esphome/components/hlw8012/hlw8012.cpp +0 -1
  234. esphome/components/hm3301/hm3301.cpp +0 -1
  235. esphome/components/hmc5883l/hmc5883l.cpp +0 -1
  236. esphome/components/homeassistant/__init__.py +1 -0
  237. esphome/components/homeassistant/number/__init__.py +1 -0
  238. esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
  239. esphome/components/homeassistant/switch/__init__.py +1 -0
  240. esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
  241. esphome/components/honeywellabp/honeywellabp.cpp +1 -4
  242. esphome/components/host/__init__.py +2 -0
  243. esphome/components/hte501/hte501.cpp +0 -1
  244. esphome/components/http_request/__init__.py +2 -3
  245. esphome/components/http_request/http_request_idf.cpp +2 -2
  246. esphome/components/htu21d/htu21d.cpp +0 -2
  247. esphome/components/htu31d/htu31d.cpp +0 -2
  248. esphome/components/hx711/hx711.cpp +0 -1
  249. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
  250. esphome/components/hydreon_rgxx/sensor.py +4 -5
  251. esphome/components/i2c/i2c_bus.h +1 -1
  252. esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
  253. esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
  254. esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
  255. esphome/components/i2s_audio/__init__.py +6 -5
  256. esphome/components/i2s_audio/i2s_audio.cpp +0 -2
  257. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
  258. esphome/components/i2s_audio/microphone/__init__.py +4 -6
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +46 -19
  260. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +4 -3
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
  262. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
  263. esphome/components/ili9xxx/display.py +4 -3
  264. esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
  265. esphome/components/image/__init__.py +123 -92
  266. esphome/components/improv_serial/__init__.py +7 -8
  267. esphome/components/ina219/ina219.cpp +0 -1
  268. esphome/components/ina226/ina226.cpp +0 -2
  269. esphome/components/ina260/ina260.cpp +0 -2
  270. esphome/components/ina2xx_base/__init__.py +2 -5
  271. esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
  272. esphome/components/ina3221/ina3221.cpp +0 -1
  273. esphome/components/internal_temperature/internal_temperature.cpp +0 -2
  274. esphome/components/interval/interval.h +5 -9
  275. esphome/components/json/__init__.py +1 -1
  276. esphome/components/kmeteriso/kmeteriso.cpp +0 -2
  277. esphome/components/lc709203f/lc709203f.cpp +0 -2
  278. esphome/components/lcd_gpio/display.py +1 -3
  279. esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
  280. esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
  281. esphome/components/ld2410/__init__.py +4 -6
  282. esphome/components/ld2410/binary_sensor.py +4 -0
  283. esphome/components/ld2410/ld2410.cpp +56 -100
  284. esphome/components/ld2410/ld2410.h +17 -15
  285. esphome/components/ld2410/sensor.py +24 -10
  286. esphome/components/ld2412/__init__.py +46 -0
  287. esphome/components/ld2412/binary_sensor.py +70 -0
  288. esphome/components/ld2412/button/__init__.py +74 -0
  289. esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
  290. esphome/components/ld2412/button/factory_reset_button.h +18 -0
  291. esphome/components/ld2412/button/query_button.cpp +9 -0
  292. esphome/components/ld2412/button/query_button.h +18 -0
  293. esphome/components/ld2412/button/restart_button.cpp +9 -0
  294. esphome/components/ld2412/button/restart_button.h +18 -0
  295. esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
  296. esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
  297. esphome/components/ld2412/ld2412.cpp +861 -0
  298. esphome/components/ld2412/ld2412.h +141 -0
  299. esphome/components/ld2412/number/__init__.py +126 -0
  300. esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
  301. esphome/components/ld2412/number/gate_threshold_number.h +19 -0
  302. esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
  303. esphome/components/ld2412/number/light_threshold_number.h +18 -0
  304. esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
  305. esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
  306. esphome/components/ld2412/select/__init__.py +82 -0
  307. esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
  308. esphome/components/ld2412/select/baud_rate_select.h +18 -0
  309. esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
  310. esphome/components/ld2412/select/distance_resolution_select.h +18 -0
  311. esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
  312. esphome/components/ld2412/select/light_out_control_select.h +18 -0
  313. esphome/components/ld2412/sensor.py +124 -0
  314. esphome/components/ld2412/switch/__init__.py +45 -0
  315. esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
  316. esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
  317. esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
  318. esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
  319. esphome/components/ld2412/text_sensor.py +34 -0
  320. esphome/components/ld2420/ld2420.cpp +0 -1
  321. esphome/components/ld2450/__init__.py +3 -4
  322. esphome/components/ld2450/binary_sensor.py +3 -0
  323. esphome/components/ld2450/ld2450.cpp +77 -165
  324. esphome/components/ld2450/ld2450.h +26 -54
  325. esphome/components/ld2450/sensor.py +120 -6
  326. esphome/components/ld2450/text_sensor.py +5 -4
  327. esphome/components/ld24xx/__init__.py +1 -0
  328. esphome/components/ld24xx/ld24xx.h +65 -0
  329. esphome/components/ledc/ledc_output.cpp +0 -1
  330. esphome/components/libretiny/__init__.py +2 -0
  331. esphome/components/light/__init__.py +0 -1
  332. esphome/components/light/effects.py +70 -45
  333. esphome/components/light/light_call.cpp +101 -66
  334. esphome/components/light/light_color_values.h +16 -11
  335. esphome/components/light/light_json_schema.cpp +46 -44
  336. esphome/components/light/light_state.cpp +8 -11
  337. esphome/components/light/light_traits.h +17 -0
  338. esphome/components/lightwaverf/lightwaverf.cpp +0 -2
  339. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
  340. esphome/components/lock/__init__.py +0 -1
  341. esphome/components/logger/__init__.py +31 -9
  342. esphome/components/logger/logger.cpp +12 -7
  343. esphome/components/logger/logger.h +25 -14
  344. esphome/components/logger/logger_esp32.cpp +2 -7
  345. esphome/components/logger/logger_esp8266.cpp +2 -4
  346. esphome/components/logger/logger_host.cpp +2 -4
  347. esphome/components/logger/logger_libretiny.cpp +2 -4
  348. esphome/components/logger/logger_rp2040.cpp +2 -4
  349. esphome/components/logger/logger_zephyr.cpp +86 -0
  350. esphome/components/logger/select/logger_level_select.cpp +2 -4
  351. esphome/components/logger/select/logger_level_select.h +2 -4
  352. esphome/components/logger/task_log_buffer.cpp +2 -4
  353. esphome/components/logger/task_log_buffer.h +2 -4
  354. esphome/components/lps22/sensor.py +5 -5
  355. esphome/components/ltr390/ltr390.cpp +0 -2
  356. esphome/components/ltr501/ltr501.cpp +0 -1
  357. esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
  358. esphome/components/lvgl/__init__.py +14 -13
  359. esphome/components/lvgl/automation.py +2 -4
  360. esphome/components/lvgl/defines.py +0 -2
  361. esphome/components/lvgl/helpers.py +1 -1
  362. esphome/components/lvgl/lv_validation.py +7 -4
  363. esphome/components/lvgl/lvgl_esphome.cpp +2 -3
  364. esphome/components/lvgl/styles.py +2 -2
  365. esphome/components/lvgl/types.py +1 -1
  366. esphome/components/lvgl/widgets/__init__.py +2 -2
  367. esphome/components/lvgl/widgets/arc.py +14 -11
  368. esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
  369. esphome/components/lvgl/widgets/qrcode.py +7 -7
  370. esphome/components/lvgl/widgets/spinner.py +6 -6
  371. esphome/components/lvgl/widgets/switch.py +2 -2
  372. esphome/components/lvgl/widgets/tabview.py +3 -3
  373. esphome/components/lvgl/widgets/tileview.py +15 -7
  374. esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
  375. esphome/components/matrix_keypad/__init__.py +4 -3
  376. esphome/components/max17043/max17043.cpp +0 -2
  377. esphome/components/max31855/max31855.cpp +1 -4
  378. esphome/components/max31856/max31856.cpp +0 -4
  379. esphome/components/max31865/max31865.cpp +0 -1
  380. esphome/components/max44009/max44009.cpp +0 -1
  381. esphome/components/max6675/max6675.cpp +1 -4
  382. esphome/components/max6956/max6956.cpp +0 -1
  383. esphome/components/max7219/max7219.cpp +0 -1
  384. esphome/components/max7219digit/display.py +1 -1
  385. esphome/components/max7219digit/max7219digit.cpp +0 -1
  386. esphome/components/max9611/max9611.cpp +0 -1
  387. esphome/components/mcp23008/__init__.py +1 -1
  388. esphome/components/mcp23008/mcp23008.cpp +0 -1
  389. esphome/components/mcp23016/mcp23016.cpp +0 -1
  390. esphome/components/mcp23017/__init__.py +1 -1
  391. esphome/components/mcp23017/mcp23017.cpp +0 -1
  392. esphome/components/mcp23s08/__init__.py +1 -1
  393. esphome/components/mcp23s08/mcp23s08.cpp +0 -1
  394. esphome/components/mcp23s17/__init__.py +1 -1
  395. esphome/components/mcp23s17/mcp23s17.cpp +0 -1
  396. esphome/components/mcp23x08_base/__init__.py +2 -0
  397. esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
  398. esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
  399. esphome/components/mcp23x17_base/__init__.py +2 -0
  400. esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
  401. esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
  402. esphome/components/mcp23xxx_base/__init__.py +11 -5
  403. esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
  404. esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
  405. esphome/components/mcp3008/mcp3008.cpp +1 -4
  406. esphome/components/mcp3204/mcp3204.cpp +1 -4
  407. esphome/components/mcp4461/mcp4461.cpp +0 -1
  408. esphome/components/mcp4725/mcp4725.cpp +0 -1
  409. esphome/components/mcp4728/mcp4728.cpp +0 -1
  410. esphome/components/mcp9600/mcp9600.cpp +0 -2
  411. esphome/components/mcp9808/mcp9808.cpp +0 -2
  412. esphome/components/mdns/__init__.py +3 -0
  413. esphome/components/mdns/mdns_component.cpp +2 -0
  414. esphome/components/mdns/mdns_component.h +4 -0
  415. esphome/components/media_player/__init__.py +40 -0
  416. esphome/components/media_player/automation.h +16 -0
  417. esphome/components/media_player/media_player.cpp +13 -0
  418. esphome/components/media_player/media_player.h +50 -3
  419. esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
  420. esphome/components/mics_4514/mics_4514.cpp +1 -6
  421. esphome/components/midea/ir_transmitter.h +4 -4
  422. esphome/components/mipi/__init__.py +416 -0
  423. esphome/components/mipi_dsi/__init__.py +5 -0
  424. esphome/components/mipi_dsi/display.py +233 -0
  425. esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
  426. esphome/components/mipi_dsi/mipi_dsi.h +123 -0
  427. esphome/components/mipi_dsi/models/__init__.py +0 -0
  428. esphome/components/mipi_dsi/models/guition.py +38 -0
  429. esphome/components/mipi_dsi/models/m5stack.py +57 -0
  430. esphome/components/mipi_dsi/models/waveshare.py +105 -0
  431. esphome/components/mipi_rgb/models/lilygo.py +0 -0
  432. esphome/components/mipi_spi/__init__.py +0 -9
  433. esphome/components/mipi_spi/display.py +220 -256
  434. esphome/components/mipi_spi/mipi_spi.cpp +1 -485
  435. esphome/components/mipi_spi/mipi_spi.h +556 -108
  436. esphome/components/mipi_spi/models/__init__.py +0 -65
  437. esphome/components/mipi_spi/models/adafruit.py +30 -0
  438. esphome/components/mipi_spi/models/amoled.py +41 -5
  439. esphome/components/mipi_spi/models/ili.py +5 -5
  440. esphome/components/mipi_spi/models/jc.py +1 -3
  441. esphome/components/mipi_spi/models/lilygo.py +1 -1
  442. esphome/components/mipi_spi/models/waveshare.py +16 -1
  443. esphome/components/mixer/speaker/__init__.py +4 -5
  444. esphome/components/mlx90393/sensor.py +7 -5
  445. esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
  446. esphome/components/mlx90614/mlx90614.cpp +0 -1
  447. esphome/components/mmc5603/mmc5603.cpp +0 -1
  448. esphome/components/mmc5983/mmc5983.cpp +0 -2
  449. esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
  450. esphome/components/mpr121/__init__.py +7 -6
  451. esphome/components/mpr121/mpr121.cpp +0 -1
  452. esphome/components/mpu6050/mpu6050.cpp +0 -1
  453. esphome/components/mpu6886/mpu6886.cpp +0 -1
  454. esphome/components/mqtt/__init__.py +1 -2
  455. esphome/components/mqtt/mqtt_button.cpp +1 -1
  456. esphome/components/mqtt/mqtt_client.cpp +0 -1
  457. esphome/components/mqtt/mqtt_component.cpp +8 -14
  458. esphome/components/mqtt/mqtt_component.h +0 -7
  459. esphome/components/mqtt/mqtt_sensor.cpp +0 -1
  460. esphome/components/mqtt/mqtt_sensor.h +0 -1
  461. esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
  462. esphome/components/mqtt/mqtt_text_sensor.h +0 -1
  463. esphome/components/ms5611/ms5611.cpp +0 -1
  464. esphome/components/ms8607/ms8607.cpp +0 -1
  465. esphome/components/msa3xx/msa3xx.cpp +0 -2
  466. esphome/components/my9231/my9231.cpp +0 -2
  467. esphome/components/nau7802/nau7802.cpp +0 -1
  468. esphome/components/neopixelbus/light.py +3 -0
  469. esphome/components/network/util.cpp +29 -0
  470. esphome/components/nextion/nextion.cpp +0 -1
  471. esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
  472. esphome/components/npi19/npi19.cpp +0 -2
  473. esphome/components/nrf52/__init__.py +223 -0
  474. esphome/components/nrf52/boards.py +34 -0
  475. esphome/components/nrf52/const.py +18 -0
  476. esphome/components/nrf52/gpio.py +79 -0
  477. esphome/components/number/__init__.py +2 -1
  478. esphome/components/one_wire/__init__.py +1 -2
  479. esphome/components/one_wire/one_wire.cpp +0 -2
  480. esphome/components/one_wire/one_wire.h +0 -2
  481. esphome/components/opentherm/hub.cpp +0 -1
  482. esphome/components/opentherm/number/__init__.py +2 -2
  483. esphome/components/openthread/__init__.py +2 -3
  484. esphome/components/openthread/openthread.cpp +30 -13
  485. esphome/components/openthread/openthread.h +3 -0
  486. esphome/components/openthread/openthread_esp.cpp +3 -1
  487. esphome/components/opt3001/sensor.py +2 -6
  488. esphome/components/output/__init__.py +38 -0
  489. esphome/components/output/automation.h +24 -0
  490. esphome/components/output/switch/output_switch.cpp +0 -2
  491. esphome/components/packages/__init__.py +1 -2
  492. esphome/components/packet_transport/__init__.py +4 -3
  493. esphome/components/pca6416a/pca6416a.cpp +0 -1
  494. esphome/components/pca9554/pca9554.cpp +0 -1
  495. esphome/components/pca9685/pca9685_output.cpp +0 -2
  496. esphome/components/pcf85063/pcf85063.cpp +0 -1
  497. esphome/components/pcf8563/pcf8563.cpp +0 -1
  498. esphome/components/pcf8574/pcf8574.cpp +0 -1
  499. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
  500. esphome/components/pipsolar/sensor/__init__.py +1 -1
  501. esphome/components/pm2005/pm2005.cpp +0 -1
  502. esphome/components/pmsa003i/pmsa003i.cpp +0 -2
  503. esphome/components/pmwcs3/sensor.py +1 -2
  504. esphome/components/pn532/pn532.cpp +0 -2
  505. esphome/components/pn532_spi/pn532_spi.cpp +0 -2
  506. esphome/components/power_supply/power_supply.cpp +7 -10
  507. esphome/components/power_supply/power_supply.h +1 -1
  508. esphome/components/psram/__init__.py +2 -1
  509. esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
  510. esphome/components/pulse_counter/sensor.py +9 -6
  511. esphome/components/pylontech/pylontech.cpp +0 -1
  512. esphome/components/qmc5883l/qmc5883l.cpp +0 -1
  513. esphome/components/qmp6988/qmp6988.cpp +0 -2
  514. esphome/components/qspi_dbi/display.py +2 -3
  515. esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
  516. esphome/components/qwiic_pir/binary_sensor.py +2 -3
  517. esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
  518. esphome/components/rc522/rc522.cpp +9 -31
  519. esphome/components/rc522_spi/rc522_spi.cpp +0 -1
  520. esphome/components/remote_base/__init__.py +5 -6
  521. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
  522. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
  523. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
  524. esphome/components/remote_transmitter/__init__.py +26 -0
  525. esphome/components/remote_transmitter/automation.h +18 -0
  526. esphome/components/remote_transmitter/remote_transmitter.h +2 -1
  527. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
  528. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
  529. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
  530. esphome/components/resampler/speaker/__init__.py +4 -5
  531. esphome/components/rf_bridge/__init__.py +4 -8
  532. esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
  533. esphome/components/rp2040/__init__.py +3 -1
  534. esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
  535. esphome/components/rp2040_pio_led_strip/light.py +1 -2
  536. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
  537. esphome/components/rpi_dpi_rgb/display.py +13 -15
  538. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
  539. esphome/components/runtime_stats/__init__.py +34 -0
  540. esphome/components/runtime_stats/runtime_stats.cpp +102 -0
  541. esphome/components/runtime_stats/runtime_stats.h +132 -0
  542. esphome/components/scd30/scd30.cpp +0 -2
  543. esphome/components/scd30/sensor.py +1 -2
  544. esphome/components/scd4x/scd4x.cpp +0 -1
  545. esphome/components/scd4x/sensor.py +1 -3
  546. esphome/components/sdl/display.py +3 -1
  547. esphome/components/sdl/sdl_esphome.cpp +0 -2
  548. esphome/components/sdp3x/sdp3x.cpp +0 -2
  549. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
  550. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
  551. esphome/components/select/__init__.py +2 -3
  552. esphome/components/select/select_traits.cpp +1 -1
  553. esphome/components/select/select_traits.h +1 -1
  554. esphome/components/sen0321/sen0321.cpp +0 -1
  555. esphome/components/sen5x/sen5x.cpp +0 -2
  556. esphome/components/sensor/__init__.py +36 -4
  557. esphome/components/sensor/filter.cpp +49 -10
  558. esphome/components/sensor/filter.h +22 -7
  559. esphome/components/sensor/sensor.cpp +0 -1
  560. esphome/components/sensor/sensor.h +0 -9
  561. esphome/components/sfa30/sfa30.cpp +0 -4
  562. esphome/components/sgp30/sgp30.cpp +0 -2
  563. esphome/components/sgp4x/sensor.py +1 -1
  564. esphome/components/sgp4x/sgp4x.cpp +0 -2
  565. esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
  566. esphome/components/sht3xd/sht3xd.cpp +0 -2
  567. esphome/components/sht4x/sht4x.cpp +0 -2
  568. esphome/components/shtcx/shtcx.cpp +0 -1
  569. esphome/components/sim800l/__init__.py +2 -4
  570. esphome/components/sm16716/sm16716.cpp +0 -1
  571. esphome/components/sm2135/sm2135.cpp +0 -1
  572. esphome/components/sm2235/sm2235.cpp +0 -1
  573. esphome/components/sm2335/sm2335.cpp +0 -1
  574. esphome/components/sn74hc165/sn74hc165.cpp +0 -1
  575. esphome/components/sn74hc595/sn74hc595.cpp +0 -1
  576. esphome/components/sntp/sntp_component.cpp +0 -1
  577. esphome/components/sound_level/sensor.py +1 -1
  578. esphome/components/speaker/media_player/__init__.py +21 -33
  579. esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
  580. esphome/components/spi/__init__.py +29 -13
  581. esphome/components/spi/spi.cpp +0 -2
  582. esphome/components/spi_device/spi_device.cpp +1 -4
  583. esphome/components/sprinkler/__init__.py +4 -4
  584. esphome/components/sps30/sps30.cpp +0 -1
  585. esphome/components/ssd1306_base/__init__.py +11 -11
  586. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  587. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
  588. esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
  589. esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
  590. esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
  591. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
  592. esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
  593. esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
  594. esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
  595. esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
  596. esphome/components/st7567_spi/st7567_spi.cpp +0 -1
  597. esphome/components/st7701s/display.py +10 -14
  598. esphome/components/st7701s/st7701s.cpp +0 -3
  599. esphome/components/st7735/st7735.cpp +0 -1
  600. esphome/components/st7789v/st7789v.cpp +0 -1
  601. esphome/components/st7920/st7920.cpp +0 -1
  602. esphome/components/status_led/light/status_led_light.cpp +0 -2
  603. esphome/components/status_led/status_led.cpp +0 -1
  604. esphome/components/stepper/__init__.py +2 -4
  605. esphome/components/sts3x/sts3x.cpp +0 -1
  606. esphome/components/substitutions/__init__.py +10 -16
  607. esphome/components/substitutions/jinja.py +24 -1
  608. esphome/components/sun/__init__.py +2 -3
  609. esphome/components/switch/__init__.py +31 -1
  610. esphome/components/switch/automation.h +24 -0
  611. esphome/components/switch/switch.cpp +8 -0
  612. esphome/components/switch/switch.h +8 -0
  613. esphome/components/sx126x/sx126x.cpp +0 -2
  614. esphome/components/sx127x/sx127x.cpp +0 -2
  615. esphome/components/sx1509/__init__.py +7 -5
  616. esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
  617. esphome/components/sx1509/sx1509.cpp +0 -2
  618. esphome/components/syslog/esphome_syslog.cpp +1 -1
  619. esphome/components/tc74/tc74.cpp +0 -1
  620. esphome/components/tca9548a/tca9548a.cpp +0 -1
  621. esphome/components/tca9555/tca9555.cpp +0 -1
  622. esphome/components/tcs34725/tcs34725.cpp +0 -1
  623. esphome/components/tee501/tee501.cpp +0 -1
  624. esphome/components/tem3200/tem3200.cpp +0 -2
  625. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
  626. esphome/components/template/cover/template_cover.cpp +0 -1
  627. esphome/components/template/select/template_select.cpp +0 -1
  628. esphome/components/template/text/template_text.cpp +0 -2
  629. esphome/components/template/valve/template_valve.cpp +0 -1
  630. esphome/components/text/__init__.py +0 -1
  631. esphome/components/text/text_traits.h +2 -0
  632. esphome/components/text_sensor/__init__.py +2 -1
  633. esphome/components/text_sensor/text_sensor.cpp +0 -2
  634. esphome/components/text_sensor/text_sensor.h +0 -8
  635. esphome/components/thermostat/climate.py +4 -4
  636. esphome/components/time/__init__.py +7 -4
  637. esphome/components/time/real_time_clock.cpp +16 -3
  638. esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
  639. esphome/components/tlc5947/tlc5947.cpp +0 -2
  640. esphome/components/tlc5971/tlc5971.cpp +0 -2
  641. esphome/components/tm1621/tm1621.cpp +0 -2
  642. esphome/components/tm1637/tm1637.cpp +0 -2
  643. esphome/components/tm1638/tm1638.cpp +0 -2
  644. esphome/components/tm1651/__init__.py +45 -48
  645. esphome/components/tm1651/tm1651.cpp +213 -47
  646. esphome/components/tm1651/tm1651.h +37 -32
  647. esphome/components/tmp117/tmp117.cpp +0 -2
  648. esphome/components/tsl2561/tsl2561.cpp +0 -1
  649. esphome/components/tsl2591/tsl2591.cpp +0 -1
  650. esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
  651. esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
  652. esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
  653. esphome/components/tuya/climate/__init__.py +9 -10
  654. esphome/components/tuya/number/__init__.py +8 -6
  655. esphome/components/tx20/tx20.cpp +0 -1
  656. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
  657. esphome/components/uart/uart_component_esp8266.cpp +0 -1
  658. esphome/components/uart/uart_component_esp_idf.cpp +0 -2
  659. esphome/components/uart/uart_component_libretiny.cpp +0 -2
  660. esphome/components/uart/uart_component_rp2040.cpp +0 -2
  661. esphome/components/udp/__init__.py +1 -1
  662. esphome/components/ufire_ec/sensor.py +1 -2
  663. esphome/components/ufire_ec/ufire_ec.cpp +0 -2
  664. esphome/components/ufire_ise/sensor.py +1 -2
  665. esphome/components/ufire_ise/ufire_ise.cpp +0 -2
  666. esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
  667. esphome/components/update/__init__.py +0 -1
  668. esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
  669. esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
  670. esphome/components/usb_host/usb_host_client.cpp +0 -1
  671. esphome/components/usb_host/usb_host_component.cpp +0 -1
  672. esphome/components/valve/__init__.py +0 -1
  673. esphome/components/veml3235/veml3235.cpp +0 -3
  674. esphome/components/veml7700/veml7700.cpp +0 -2
  675. esphome/components/version/version_text_sensor.cpp +0 -1
  676. esphome/components/version/version_text_sensor.h +0 -1
  677. esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
  678. esphome/components/voice_assistant/voice_assistant.cpp +9 -8
  679. esphome/components/web_server/__init__.py +13 -0
  680. esphome/components/web_server/web_server.cpp +187 -352
  681. esphome/components/web_server/web_server.h +61 -1
  682. esphome/components/web_server_base/__init__.py +1 -1
  683. esphome/components/web_server_base/web_server_base.cpp +2 -0
  684. esphome/components/web_server_base/web_server_base.h +6 -0
  685. esphome/components/web_server_idf/web_server_idf.cpp +10 -8
  686. esphome/components/web_server_idf/web_server_idf.h +2 -0
  687. esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
  688. esphome/components/weikai_spi/weikai_spi.cpp +1 -1
  689. esphome/components/wifi/__init__.py +8 -43
  690. esphome/components/wifi/wifi_component.cpp +100 -36
  691. esphome/components/wifi/wifi_component.h +5 -1
  692. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
  693. esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
  694. esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
  695. esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
  696. esphome/components/wireguard/wireguard.cpp +0 -2
  697. esphome/components/x9c/x9c.cpp +0 -2
  698. esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
  699. esphome/components/xl9535/xl9535.cpp +0 -2
  700. esphome/components/zephyr/__init__.py +252 -0
  701. esphome/components/zephyr/const.py +16 -0
  702. esphome/components/zephyr/core.cpp +90 -0
  703. esphome/components/zephyr/gpio.cpp +120 -0
  704. esphome/components/zephyr/gpio.h +38 -0
  705. esphome/components/zephyr/pre_build.py.script +4 -0
  706. esphome/components/zephyr/preferences.cpp +156 -0
  707. esphome/components/zephyr/preferences.h +13 -0
  708. esphome/config.py +38 -16
  709. esphome/config_helpers.py +1 -2
  710. esphome/config_validation.py +8 -15
  711. esphome/const.py +26 -1
  712. esphome/core/__init__.py +88 -51
  713. esphome/core/application.cpp +75 -21
  714. esphome/core/application.h +106 -171
  715. esphome/core/color.h +10 -0
  716. esphome/core/component.cpp +41 -25
  717. esphome/core/component.h +9 -6
  718. esphome/core/component_iterator.cpp +61 -261
  719. esphome/core/component_iterator.h +15 -0
  720. esphome/core/config.py +26 -11
  721. esphome/core/defines.h +40 -2
  722. esphome/core/entity_base.h +18 -0
  723. esphome/core/entity_helpers.py +41 -6
  724. esphome/core/helpers.cpp +8 -15
  725. esphome/core/helpers.h +60 -6
  726. esphome/core/lock_free_queue.h +1 -1
  727. esphome/core/scheduler.cpp +277 -74
  728. esphome/core/scheduler.h +89 -27
  729. esphome/cpp_generator.py +2 -6
  730. esphome/cpp_helpers.py +1 -1
  731. esphome/dashboard/dashboard.py +2 -3
  732. esphome/dashboard/dns.py +2 -8
  733. esphome/dashboard/web_server.py +34 -19
  734. esphome/espota2.py +1 -4
  735. esphome/git.py +3 -1
  736. esphome/helpers.py +23 -4
  737. esphome/log.py +3 -1
  738. esphome/mqtt.py +3 -5
  739. esphome/platformio_api.py +7 -4
  740. esphome/types.py +12 -0
  741. esphome/util.py +20 -8
  742. esphome/voluptuous_schema.py +4 -3
  743. esphome/vscode.py +1 -2
  744. esphome/wizard.py +1 -4
  745. esphome/writer.py +5 -107
  746. esphome/yaml_util.py +7 -5
  747. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/METADATA +12 -13
  748. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/RECORD +753 -673
  749. esphome/components/mipi_spi/models/commands.py +0 -82
  750. /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
  751. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/WHEEL +0 -0
  752. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/entry_points.txt +0 -0
  753. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/licenses/LICENSE +0 -0
  754. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/top_level.txt +0 -0
@@ -78,7 +78,7 @@ enum JsonDetail { DETAIL_ALL, DETAIL_STATE };
78
78
  This is because only minimal changes were made to the ESPAsyncWebServer lib_dep, it was undesirable to put deferred
79
79
  update logic into that library. We need one deferred queue per connection so instead of one AsyncEventSource with
80
80
  multiple clients, we have multiple event sources with one client each. This is slightly awkward which is why it's
81
- implemented in a more straightforward way for ESP-IDF. Arudino platform will eventually go away and this workaround
81
+ implemented in a more straightforward way for ESP-IDF. Arduino platform will eventually go away and this workaround
82
82
  can be forgotten.
83
83
  */
84
84
  #ifdef USE_ARDUINO
@@ -498,6 +498,66 @@ class WebServer : public Controller, public Component, public AsyncWebHandler {
498
498
 
499
499
  protected:
500
500
  void add_sorting_info_(JsonObject &root, EntityBase *entity);
501
+
502
+ #ifdef USE_LIGHT
503
+ // Helper to parse and apply a float parameter with optional scaling
504
+ template<typename T, typename Ret>
505
+ void parse_light_param_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret (T::*setter)(float),
506
+ float scale = 1.0f) {
507
+ if (request->hasParam(param_name)) {
508
+ auto value = parse_number<float>(request->getParam(param_name)->value().c_str());
509
+ if (value.has_value()) {
510
+ (call.*setter)(*value / scale);
511
+ }
512
+ }
513
+ }
514
+
515
+ // Helper to parse and apply a uint32_t parameter with optional scaling
516
+ template<typename T, typename Ret>
517
+ void parse_light_param_uint_(AsyncWebServerRequest *request, const char *param_name, T &call,
518
+ Ret (T::*setter)(uint32_t), uint32_t scale = 1) {
519
+ if (request->hasParam(param_name)) {
520
+ auto value = parse_number<uint32_t>(request->getParam(param_name)->value().c_str());
521
+ if (value.has_value()) {
522
+ (call.*setter)(*value * scale);
523
+ }
524
+ }
525
+ }
526
+ #endif
527
+
528
+ // Generic helper to parse and apply a float parameter
529
+ template<typename T, typename Ret>
530
+ void parse_float_param_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret (T::*setter)(float)) {
531
+ if (request->hasParam(param_name)) {
532
+ auto value = parse_number<float>(request->getParam(param_name)->value().c_str());
533
+ if (value.has_value()) {
534
+ (call.*setter)(*value);
535
+ }
536
+ }
537
+ }
538
+
539
+ // Generic helper to parse and apply an int parameter
540
+ template<typename T, typename Ret>
541
+ void parse_int_param_(AsyncWebServerRequest *request, const char *param_name, T &call, Ret (T::*setter)(int)) {
542
+ if (request->hasParam(param_name)) {
543
+ auto value = parse_number<int>(request->getParam(param_name)->value().c_str());
544
+ if (value.has_value()) {
545
+ (call.*setter)(*value);
546
+ }
547
+ }
548
+ }
549
+
550
+ // Generic helper to parse and apply a string parameter
551
+ template<typename T, typename Ret>
552
+ void parse_string_param_(AsyncWebServerRequest *request, const char *param_name, T &call,
553
+ Ret (T::*setter)(const std::string &)) {
554
+ if (request->hasParam(param_name)) {
555
+ // .c_str() is required for Arduino framework where value() returns Arduino String instead of std::string
556
+ std::string value = request->getParam(param_name)->value().c_str(); // NOLINT(readability-redundant-string-cstr)
557
+ (call.*setter)(value);
558
+ }
559
+ }
560
+
501
561
  web_server_base::WebServerBase *base_;
502
562
  #ifdef USE_ARDUINO
503
563
  DeferredUpdateEventSourceList events_;
@@ -3,7 +3,7 @@ import esphome.config_validation as cv
3
3
  from esphome.const import CONF_ID
4
4
  from esphome.core import CORE, coroutine_with_priority
5
5
 
6
- CODEOWNERS = ["@OttoWinter"]
6
+ CODEOWNERS = ["@esphome/core"]
7
7
  DEPENDENCIES = ["network"]
8
8
 
9
9
 
@@ -14,9 +14,11 @@ WebServerBase *global_web_server_base = nullptr; // NOLINT(cppcoreguidelines-av
14
14
  void WebServerBase::add_handler(AsyncWebHandler *handler) {
15
15
  // remove all handlers
16
16
 
17
+ #ifdef USE_WEBSERVER_AUTH
17
18
  if (!credentials_.username.empty()) {
18
19
  handler = new internal::AuthMiddlewareHandler(handler, &credentials_);
19
20
  }
21
+ #endif
20
22
  this->handlers_.push_back(handler);
21
23
  if (this->server_ != nullptr) {
22
24
  this->server_->addHandler(handler);
@@ -41,6 +41,7 @@ class MiddlewareHandler : public AsyncWebHandler {
41
41
  AsyncWebHandler *next_;
42
42
  };
43
43
 
44
+ #ifdef USE_WEBSERVER_AUTH
44
45
  struct Credentials {
45
46
  std::string username;
46
47
  std::string password;
@@ -79,6 +80,7 @@ class AuthMiddlewareHandler : public MiddlewareHandler {
79
80
  protected:
80
81
  Credentials *credentials_;
81
82
  };
83
+ #endif
82
84
 
83
85
  } // namespace internal
84
86
 
@@ -108,8 +110,10 @@ class WebServerBase : public Component {
108
110
  std::shared_ptr<AsyncWebServer> get_server() const { return server_; }
109
111
  float get_setup_priority() const override;
110
112
 
113
+ #ifdef USE_WEBSERVER_AUTH
111
114
  void set_auth_username(std::string auth_username) { credentials_.username = std::move(auth_username); }
112
115
  void set_auth_password(std::string auth_password) { credentials_.password = std::move(auth_password); }
116
+ #endif
113
117
 
114
118
  void add_handler(AsyncWebHandler *handler);
115
119
 
@@ -121,7 +125,9 @@ class WebServerBase : public Component {
121
125
  uint16_t port_{80};
122
126
  std::shared_ptr<AsyncWebServer> server_{nullptr};
123
127
  std::vector<AsyncWebHandler *> handlers_;
128
+ #ifdef USE_WEBSERVER_AUTH
124
129
  internal::Credentials credentials_;
130
+ #endif
125
131
  };
126
132
 
127
133
  } // namespace web_server_base
@@ -116,7 +116,7 @@ esp_err_t AsyncWebServer::request_post_handler(httpd_req_t *r) {
116
116
  }
117
117
 
118
118
  // Handle regular form data
119
- if (r->content_len > HTTPD_MAX_REQ_HDR_LEN) {
119
+ if (r->content_len > CONFIG_HTTPD_MAX_REQ_HDR_LEN) {
120
120
  ESP_LOGW(TAG, "Request size is to big: %zu", r->content_len);
121
121
  httpd_resp_send_err(r, HTTPD_400_BAD_REQUEST, nullptr);
122
122
  return ESP_FAIL;
@@ -223,6 +223,7 @@ void AsyncWebServerRequest::init_response_(AsyncWebServerResponse *rsp, int code
223
223
  this->rsp_ = rsp;
224
224
  }
225
225
 
226
+ #ifdef USE_WEBSERVER_AUTH
226
227
  bool AsyncWebServerRequest::authenticate(const char *username, const char *password) const {
227
228
  if (username == nullptr || password == nullptr || *username == 0) {
228
229
  return true;
@@ -261,6 +262,7 @@ void AsyncWebServerRequest::requestAuthentication(const char *realm) const {
261
262
  httpd_resp_set_hdr(*this, "WWW-Authenticate", auth_val.c_str());
262
263
  httpd_resp_send_err(*this, HTTPD_401_UNAUTHORIZED, nullptr);
263
264
  }
265
+ #endif
264
266
 
265
267
  AsyncWebParameter *AsyncWebServerRequest::getParam(const std::string &name) {
266
268
  auto find = this->params_.find(name);
@@ -423,14 +425,14 @@ void AsyncEventSourceResponse::destroy(void *ptr) {
423
425
  void AsyncEventSourceResponse::deq_push_back_with_dedup_(void *source, message_generator_t *message_generator) {
424
426
  DeferredEvent item(source, message_generator);
425
427
 
426
- auto iter = std::find_if(this->deferred_queue_.begin(), this->deferred_queue_.end(),
427
- [&item](const DeferredEvent &test) -> bool { return test == item; });
428
-
429
- if (iter != this->deferred_queue_.end()) {
430
- (*iter) = item;
431
- } else {
432
- this->deferred_queue_.push_back(item);
428
+ // Use range-based for loop instead of std::find_if to reduce template instantiation overhead and binary size
429
+ for (auto &event : this->deferred_queue_) {
430
+ if (event == item) {
431
+ event = item;
432
+ return;
433
+ }
433
434
  }
435
+ this->deferred_queue_.push_back(item);
434
436
  }
435
437
 
436
438
  void AsyncEventSourceResponse::process_deferred_queue_() {
@@ -115,9 +115,11 @@ class AsyncWebServerRequest {
115
115
  // NOLINTNEXTLINE(readability-identifier-naming)
116
116
  size_t contentLength() const { return this->req_->content_len; }
117
117
 
118
+ #ifdef USE_WEBSERVER_AUTH
118
119
  bool authenticate(const char *username, const char *password) const;
119
120
  // NOLINTNEXTLINE(readability-identifier-naming)
120
121
  void requestAuthentication(const char *realm = nullptr) const;
122
+ #endif
121
123
 
122
124
  void redirect(const std::string &url);
123
125
 
@@ -142,8 +142,7 @@ void WeikaiRegisterI2C::write_fifo(uint8_t *data, size_t length) {
142
142
  void WeikaiComponentI2C::setup() {
143
143
  // before any manipulation we store the address to base_address_ for future use
144
144
  this->base_address_ = this->address_;
145
- ESP_LOGCONFIG(TAG, "Running setup for '%s' with %d UARTs at @%02X", this->get_name(), this->children_.size(),
146
- this->base_address_);
145
+ ESP_LOGCONFIG(TAG, "Setup %s (%d UARTs) @ 0x%02X", this->get_name(), this->children_.size(), this->base_address_);
147
146
 
148
147
  // enable all channels
149
148
  this->reg(WKREG_GENA, 0) = GENA_C1EN | GENA_C2EN | GENA_C3EN | GENA_C4EN;
@@ -156,7 +156,7 @@ void WeikaiRegisterSPI::write_fifo(uint8_t *data, size_t length) {
156
156
  ///////////////////////////////////////////////////////////////////////////////
157
157
  void WeikaiComponentSPI::setup() {
158
158
  using namespace weikai;
159
- ESP_LOGCONFIG(TAG, "Running setup for '%s' with %d UARTs", this->get_name(), this->children_.size());
159
+ ESP_LOGCONFIG(TAG, "Setup %s (%d UARTs)", this->get_name(), this->children_.size());
160
160
  this->spi_setup();
161
161
  // enable all channels
162
162
  this->reg(WKREG_GENA, 0) = GENA_C1EN | GENA_C2EN | GENA_C3EN | GENA_C4EN;
@@ -1,10 +1,12 @@
1
1
  from esphome import automation
2
2
  from esphome.automation import Condition
3
3
  import esphome.codegen as cg
4
+ from esphome.components.const import CONF_USE_PSRAM
4
5
  from esphome.components.esp32 import add_idf_sdkconfig_option, const, get_esp32_variant
5
6
  from esphome.components.network import IPAddress
6
7
  from esphome.config_helpers import filter_source_files_from_platform
7
8
  import esphome.config_validation as cv
9
+ from esphome.config_validation import only_with_esp_idf
8
10
  from esphome.const import (
9
11
  CONF_AP,
10
12
  CONF_BSSID,
@@ -192,45 +194,7 @@ def final_validate(config):
192
194
  )
193
195
 
194
196
 
195
- def final_validate_power_esp32_ble(value):
196
- if not CORE.is_esp32:
197
- return
198
- if value != "NONE":
199
- # WiFi should be in modem sleep (!=NONE) with BLE coexistence
200
- # https://docs.espressif.com/projects/esp-idf/en/v3.3.5/api-guides/wifi.html#station-sleep
201
- return
202
- for conflicting in [
203
- "esp32_ble",
204
- "esp32_ble_beacon",
205
- "esp32_ble_server",
206
- "esp32_ble_tracker",
207
- ]:
208
- if conflicting not in fv.full_config.get():
209
- continue
210
-
211
- try:
212
- # Only arduino 1.0.5+ and esp-idf impacted
213
- cv.require_framework_version(
214
- esp32_arduino=cv.Version(1, 0, 5),
215
- esp_idf=cv.Version(4, 0, 0),
216
- )(None)
217
- except cv.Invalid:
218
- pass
219
- else:
220
- raise cv.Invalid(
221
- f"power_save_mode NONE is incompatible with {conflicting}. "
222
- f"Please remove the power save mode. See also "
223
- f"https://github.com/esphome/issues/issues/2141#issuecomment-865688582"
224
- )
225
-
226
-
227
197
  FINAL_VALIDATE_SCHEMA = cv.All(
228
- cv.Schema(
229
- {
230
- cv.Optional(CONF_POWER_SAVE_MODE): final_validate_power_esp32_ble,
231
- },
232
- extra=cv.ALLOW_EXTRA,
233
- ),
234
198
  final_validate,
235
199
  validate_variant,
236
200
  )
@@ -263,8 +227,6 @@ def _validate(config):
263
227
  networks = config.get(CONF_NETWORKS, [])
264
228
  if not networks:
265
229
  raise cv.Invalid("At least one network required for fast_connect!")
266
- if len(networks) != 1:
267
- raise cv.Invalid("Fast connect can only be used with one network!")
268
230
 
269
231
  if CONF_USE_ADDRESS not in config:
270
232
  use_address = CORE.name + config[CONF_DOMAIN]
@@ -334,6 +296,9 @@ CONFIG_SCHEMA = cv.All(
334
296
  cv.Optional(CONF_ON_DISCONNECT): automation.validate_automation(
335
297
  single=True
336
298
  ),
299
+ cv.Optional(CONF_USE_PSRAM): cv.All(
300
+ only_with_esp_idf, cv.requires_component("psram"), cv.boolean
301
+ ),
337
302
  }
338
303
  ),
339
304
  _validate,
@@ -442,9 +407,7 @@ async def to_code(config):
442
407
 
443
408
  if CORE.is_esp8266:
444
409
  cg.add_library("ESP8266WiFi", None)
445
- elif CORE.is_esp32 and CORE.using_arduino:
446
- cg.add_library("WiFi", None)
447
- elif CORE.is_rp2040:
410
+ elif (CORE.is_esp32 and CORE.using_arduino) or CORE.is_rp2040:
448
411
  cg.add_library("WiFi", None)
449
412
 
450
413
  if CORE.is_esp32 and CORE.using_esp_idf:
@@ -456,6 +419,8 @@ async def to_code(config):
456
419
  if config[CONF_ENABLE_RRM]:
457
420
  cg.add(var.set_rrm(config[CONF_ENABLE_RRM]))
458
421
 
422
+ if config.get(CONF_USE_PSRAM):
423
+ add_idf_sdkconfig_option("CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP", True)
459
424
  cg.add_define("USE_WIFI")
460
425
 
461
426
  # must register before OTA safe mode check
@@ -45,7 +45,6 @@ static const char *const TAG = "wifi";
45
45
  float WiFiComponent::get_setup_priority() const { return setup_priority::WIFI; }
46
46
 
47
47
  void WiFiComponent::setup() {
48
- ESP_LOGCONFIG(TAG, "Running setup");
49
48
  this->wifi_pre_setup_();
50
49
  if (this->enable_on_boot_) {
51
50
  this->start();
@@ -92,8 +91,11 @@ void WiFiComponent::start() {
92
91
  }
93
92
 
94
93
  if (this->fast_connect_) {
95
- this->selected_ap_ = this->sta_[0];
96
- this->load_fast_connect_settings_();
94
+ this->trying_loaded_ap_ = this->load_fast_connect_settings_();
95
+ if (!this->trying_loaded_ap_) {
96
+ this->ap_index_ = 0;
97
+ this->selected_ap_ = this->sta_[this->ap_index_];
98
+ }
97
99
  this->start_connecting(this->selected_ap_, false);
98
100
  } else {
99
101
  this->start_scanning();
@@ -122,6 +124,14 @@ void WiFiComponent::start() {
122
124
  this->wifi_apply_hostname_();
123
125
  }
124
126
 
127
+ void WiFiComponent::restart_adapter() {
128
+ ESP_LOGW(TAG, "Restarting adapter");
129
+ this->wifi_mode_(false, {});
130
+ delay(100); // NOLINT
131
+ this->num_retried_ = 0;
132
+ this->retry_hidden_ = false;
133
+ }
134
+
125
135
  void WiFiComponent::loop() {
126
136
  this->wifi_loop_();
127
137
  const uint32_t now = App.get_loop_component_start_time();
@@ -141,7 +151,7 @@ void WiFiComponent::loop() {
141
151
  this->status_set_warning("waiting to reconnect");
142
152
  if (millis() - this->action_started_ > 5000) {
143
153
  if (this->fast_connect_ || this->retry_hidden_) {
144
- this->start_connecting(this->sta_[0], false);
154
+ this->start_connecting(this->selected_ap_, false);
145
155
  } else {
146
156
  this->start_scanning();
147
157
  }
@@ -261,10 +271,8 @@ void WiFiComponent::setup_ap_config_() {
261
271
  }
262
272
  this->ap_.set_ssid(name);
263
273
  }
264
-
265
- ESP_LOGCONFIG(TAG, "Setting up AP");
266
-
267
274
  ESP_LOGCONFIG(TAG,
275
+ "Setting up AP:\n"
268
276
  " AP SSID: '%s'\n"
269
277
  " AP Password: '%s'",
270
278
  this->ap_.get_ssid().c_str(), this->ap_.get_password().c_str());
@@ -449,9 +457,11 @@ void WiFiComponent::print_connect_params_() {
449
457
  " Signal strength: %d dB %s",
450
458
  bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5], App.get_name().c_str(), rssi,
451
459
  LOG_STR_ARG(get_signal_bars(rssi)));
460
+ #ifdef ESPHOME_LOG_HAS_VERBOSE
452
461
  if (this->selected_ap_.get_bssid().has_value()) {
453
462
  ESP_LOGV(TAG, " Priority: %.1f", this->get_sta_priority(*this->selected_ap_.get_bssid()));
454
463
  }
464
+ #endif
455
465
  ESP_LOGCONFIG(TAG,
456
466
  " Channel: %" PRId32 "\n"
457
467
  " Subnet: %s\n"
@@ -497,6 +507,54 @@ void WiFiComponent::start_scanning() {
497
507
  this->state_ = WIFI_COMPONENT_STATE_STA_SCANNING;
498
508
  }
499
509
 
510
+ // Helper function for WiFi scan result comparison
511
+ // Returns true if 'a' should be placed before 'b' in the sorted order
512
+ [[nodiscard]] inline static bool wifi_scan_result_is_better(const WiFiScanResult &a, const WiFiScanResult &b) {
513
+ // Matching networks always come before non-matching
514
+ if (a.get_matches() && !b.get_matches())
515
+ return true;
516
+ if (!a.get_matches() && b.get_matches())
517
+ return false;
518
+
519
+ if (a.get_matches() && b.get_matches()) {
520
+ // For APs with the same SSID, always prefer stronger signal
521
+ // This helps with mesh networks and multiple APs
522
+ if (a.get_ssid() == b.get_ssid()) {
523
+ return a.get_rssi() > b.get_rssi();
524
+ }
525
+
526
+ // For different SSIDs, check priority first
527
+ if (a.get_priority() != b.get_priority())
528
+ return a.get_priority() > b.get_priority();
529
+ // If priorities are equal, prefer stronger signal
530
+ return a.get_rssi() > b.get_rssi();
531
+ }
532
+
533
+ // Both don't match - sort by signal strength
534
+ return a.get_rssi() > b.get_rssi();
535
+ }
536
+
537
+ // Helper function for insertion sort of WiFi scan results
538
+ // Using insertion sort instead of std::stable_sort saves flash memory
539
+ // by avoiding template instantiations (std::rotate, std::stable_sort, lambdas)
540
+ // IMPORTANT: This sort is stable (preserves relative order of equal elements)
541
+ static void insertion_sort_scan_results(std::vector<WiFiScanResult> &results) {
542
+ const size_t size = results.size();
543
+ for (size_t i = 1; i < size; i++) {
544
+ // Make a copy to avoid issues with move semantics during comparison
545
+ WiFiScanResult key = results[i];
546
+ int32_t j = i - 1;
547
+
548
+ // Move elements that are worse than key to the right
549
+ // For stability, we only move if key is strictly better than results[j]
550
+ while (j >= 0 && wifi_scan_result_is_better(key, results[j])) {
551
+ results[j + 1] = results[j];
552
+ j--;
553
+ }
554
+ results[j + 1] = key;
555
+ }
556
+ }
557
+
500
558
  void WiFiComponent::check_scanning_finished() {
501
559
  if (!this->scan_done_) {
502
560
  if (millis() - this->action_started_ > 30000) {
@@ -527,22 +585,8 @@ void WiFiComponent::check_scanning_finished() {
527
585
  }
528
586
  }
529
587
 
530
- std::stable_sort(this->scan_result_.begin(), this->scan_result_.end(),
531
- [](const WiFiScanResult &a, const WiFiScanResult &b) {
532
- // return true if a is better than b
533
- if (a.get_matches() && !b.get_matches())
534
- return true;
535
- if (!a.get_matches() && b.get_matches())
536
- return false;
537
-
538
- if (a.get_matches() && b.get_matches()) {
539
- // if both match, check priority
540
- if (a.get_priority() != b.get_priority())
541
- return a.get_priority() > b.get_priority();
542
- }
543
-
544
- return a.get_rssi() > b.get_rssi();
545
- });
588
+ // Sort scan results using insertion sort for better memory efficiency
589
+ insertion_sort_scan_results(this->scan_result_);
546
590
 
547
591
  for (auto &res : this->scan_result_) {
548
592
  char bssid_s[18];
@@ -552,8 +596,10 @@ void WiFiComponent::check_scanning_finished() {
552
596
  if (res.get_matches()) {
553
597
  ESP_LOGI(TAG, "- '%s' %s" LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(),
554
598
  res.get_is_hidden() ? "(HIDDEN) " : "", bssid_s, LOG_STR_ARG(get_signal_bars(res.get_rssi())));
555
- ESP_LOGD(TAG, " Channel: %u", res.get_channel());
556
- ESP_LOGD(TAG, " RSSI: %d dB", res.get_rssi());
599
+ ESP_LOGD(TAG,
600
+ " Channel: %u\n"
601
+ " RSSI: %d dB",
602
+ res.get_channel(), res.get_rssi());
557
603
  } else {
558
604
  ESP_LOGD(TAG, "- " LOG_SECRET("'%s'") " " LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(), bssid_s,
559
605
  LOG_STR_ARG(get_signal_bars(res.get_rssi())));
@@ -698,18 +744,30 @@ void WiFiComponent::retry_connect() {
698
744
  delay(10);
699
745
  if (!this->is_captive_portal_active_() && !this->is_esp32_improv_active_() &&
700
746
  (this->num_retried_ > 3 || this->error_from_callback_)) {
701
- if (this->num_retried_ > 5) {
702
- // If retry failed for more than 5 times, let's restart STA
703
- ESP_LOGW(TAG, "Restarting adapter");
704
- this->wifi_mode_(false, {});
705
- delay(100); // NOLINT
747
+ if (this->fast_connect_) {
748
+ if (this->trying_loaded_ap_) {
749
+ this->trying_loaded_ap_ = false;
750
+ this->ap_index_ = 0; // Retry from the first configured AP
751
+ } else if (this->ap_index_ >= this->sta_.size() - 1) {
752
+ ESP_LOGW(TAG, "No more APs to try");
753
+ this->ap_index_ = 0;
754
+ this->restart_adapter();
755
+ } else {
756
+ // Try next AP
757
+ this->ap_index_++;
758
+ }
706
759
  this->num_retried_ = 0;
707
- this->retry_hidden_ = false;
760
+ this->selected_ap_ = this->sta_[this->ap_index_];
708
761
  } else {
709
- // Try hidden networks after 3 failed retries
710
- ESP_LOGD(TAG, "Retrying with hidden networks");
711
- this->retry_hidden_ = true;
712
- this->num_retried_++;
762
+ if (this->num_retried_ > 5) {
763
+ // If retry failed for more than 5 times, let's restart STA
764
+ this->restart_adapter();
765
+ } else {
766
+ // Try hidden networks after 3 failed retries
767
+ ESP_LOGD(TAG, "Retrying with hidden networks");
768
+ this->retry_hidden_ = true;
769
+ this->num_retried_++;
770
+ }
713
771
  }
714
772
  } else {
715
773
  this->num_retried_++;
@@ -756,17 +814,22 @@ bool WiFiComponent::is_esp32_improv_active_() {
756
814
  #endif
757
815
  }
758
816
 
759
- void WiFiComponent::load_fast_connect_settings_() {
817
+ bool WiFiComponent::load_fast_connect_settings_() {
760
818
  SavedWifiFastConnectSettings fast_connect_save{};
761
819
 
762
820
  if (this->fast_connect_pref_.load(&fast_connect_save)) {
763
821
  bssid_t bssid{};
764
822
  std::copy(fast_connect_save.bssid, fast_connect_save.bssid + 6, bssid.begin());
823
+ this->ap_index_ = fast_connect_save.ap_index;
824
+ this->selected_ap_ = this->sta_[this->ap_index_];
765
825
  this->selected_ap_.set_bssid(bssid);
766
826
  this->selected_ap_.set_channel(fast_connect_save.channel);
767
827
 
768
828
  ESP_LOGD(TAG, "Loaded fast_connect settings");
829
+ return true;
769
830
  }
831
+
832
+ return false;
770
833
  }
771
834
 
772
835
  void WiFiComponent::save_fast_connect_settings_() {
@@ -778,6 +841,7 @@ void WiFiComponent::save_fast_connect_settings_() {
778
841
 
779
842
  memcpy(fast_connect_save.bssid, bssid.data(), 6);
780
843
  fast_connect_save.channel = channel;
844
+ fast_connect_save.ap_index = this->ap_index_;
781
845
 
782
846
  this->fast_connect_pref_.save(&fast_connect_save);
783
847
 
@@ -60,6 +60,7 @@ struct SavedWifiSettings {
60
60
  struct SavedWifiFastConnectSettings {
61
61
  uint8_t bssid[6];
62
62
  uint8_t channel;
63
+ int8_t ap_index;
63
64
  } PACKED; // NOLINT
64
65
 
65
66
  enum WiFiComponentState : uint8_t {
@@ -256,6 +257,7 @@ class WiFiComponent : public Component {
256
257
  void setup() override;
257
258
  void start();
258
259
  void dump_config() override;
260
+ void restart_adapter();
259
261
  /// WIFI setup_priority.
260
262
  float get_setup_priority() const override;
261
263
  float get_loop_priority() const override;
@@ -353,7 +355,7 @@ class WiFiComponent : public Component {
353
355
  bool is_captive_portal_active_();
354
356
  bool is_esp32_improv_active_();
355
357
 
356
- void load_fast_connect_settings_();
358
+ bool load_fast_connect_settings_();
357
359
  void save_fast_connect_settings_();
358
360
 
359
361
  #ifdef USE_ESP8266
@@ -400,12 +402,14 @@ class WiFiComponent : public Component {
400
402
  WiFiComponentState state_{WIFI_COMPONENT_STATE_OFF};
401
403
  WiFiPowerSaveMode power_save_{WIFI_POWER_SAVE_NONE};
402
404
  uint8_t num_retried_{0};
405
+ uint8_t ap_index_{0};
403
406
  #if USE_NETWORK_IPV6
404
407
  uint8_t num_ipv6_addresses_{0};
405
408
  #endif /* USE_NETWORK_IPV6 */
406
409
 
407
410
  // Group all boolean values together
408
411
  bool fast_connect_{false};
412
+ bool trying_loaded_ap_{false};
409
413
  bool retry_hidden_{false};
410
414
  bool has_ap_{false};
411
415
  bool handled_connected_state_{false};
@@ -283,6 +283,12 @@ bool WiFiComponent::wifi_sta_ip_config_(optional<ManualIP> manual_ip) {
283
283
  if (!this->wifi_mode_(true, {}))
284
284
  return false;
285
285
 
286
+ // Check if the STA interface is initialized before using it
287
+ if (s_sta_netif == nullptr) {
288
+ ESP_LOGW(TAG, "STA interface not initialized");
289
+ return false;
290
+ }
291
+
286
292
  esp_netif_dhcp_status_t dhcp_status;
287
293
  esp_err_t err = esp_netif_dhcpc_get_status(s_sta_netif, &dhcp_status);
288
294
  if (err != ESP_OK) {
@@ -474,8 +480,20 @@ const char *get_disconnect_reason_str(uint8_t reason) {
474
480
  return "Handshake Failed";
475
481
  case WIFI_REASON_CONNECTION_FAIL:
476
482
  return "Connection Failed";
483
+ case WIFI_REASON_AP_TSF_RESET:
484
+ return "AP TSF reset";
477
485
  case WIFI_REASON_ROAMING:
478
486
  return "Station Roaming";
487
+ case WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG:
488
+ return "Association comeback time too long";
489
+ case WIFI_REASON_SA_QUERY_TIMEOUT:
490
+ return "SA query timeout";
491
+ case WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY:
492
+ return "No AP found with compatible security";
493
+ case WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD:
494
+ return "No AP found in auth mode threshold";
495
+ case WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD:
496
+ return "No AP found in RSSI threshold";
479
497
  case WIFI_REASON_UNSPECIFIED:
480
498
  default:
481
499
  return "Unspecified";
@@ -529,6 +547,8 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
529
547
  }
530
548
  case ESPHOME_EVENT_ID_WIFI_STA_STOP: {
531
549
  ESP_LOGV(TAG, "STA stop");
550
+ // Clear the STA interface handle to prevent use-after-free
551
+ s_sta_netif = nullptr;
532
552
  break;
533
553
  }
534
554
  case ESPHOME_EVENT_ID_WIFI_STA_CONNECTED: {
@@ -618,6 +638,10 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
618
638
  }
619
639
  case ESPHOME_EVENT_ID_WIFI_AP_STOP: {
620
640
  ESP_LOGV(TAG, "AP stop");
641
+ #ifdef USE_WIFI_AP
642
+ // Clear the AP interface handle to prevent use-after-free
643
+ s_ap_netif = nullptr;
644
+ #endif
621
645
  break;
622
646
  }
623
647
  case ESPHOME_EVENT_ID_WIFI_AP_STACONNECTED: {
@@ -707,6 +731,12 @@ bool WiFiComponent::wifi_ap_ip_config_(optional<ManualIP> manual_ip) {
707
731
  if (!this->wifi_mode_({}, true))
708
732
  return false;
709
733
 
734
+ // Check if the AP interface is initialized before using it
735
+ if (s_ap_netif == nullptr) {
736
+ ESP_LOGW(TAG, "AP interface not initialized");
737
+ return false;
738
+ }
739
+
710
740
  esp_netif_ip_info_t info;
711
741
  if (manual_ip.has_value()) {
712
742
  info.ip = manual_ip->static_ip;