esphome 2025.9.2__py3-none-any.whl → 2025.10.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.
Files changed (344) hide show
  1. esphome/__main__.py +87 -31
  2. esphome/address_cache.py +142 -0
  3. esphome/automation.py +130 -32
  4. esphome/build_gen/platformio.py +1 -3
  5. esphome/codegen.py +1 -0
  6. esphome/components/animation/animation.cpp +2 -2
  7. esphome/components/api/__init__.py +167 -3
  8. esphome/components/api/api_connection.cpp +84 -41
  9. esphome/components/api/api_connection.h +22 -16
  10. esphome/components/api/api_frame_helper.cpp +33 -19
  11. esphome/components/api/api_frame_helper.h +19 -4
  12. esphome/components/api/api_frame_helper_noise.cpp +41 -53
  13. esphome/components/api/api_frame_helper_noise.h +1 -1
  14. esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
  15. esphome/components/api/api_frame_helper_plaintext.h +1 -1
  16. esphome/components/api/api_pb2.cpp +189 -15
  17. esphome/components/api/api_pb2.h +132 -20
  18. esphome/components/api/api_pb2_dump.cpp +97 -9
  19. esphome/components/api/api_pb2_service.cpp +118 -160
  20. esphome/components/api/api_pb2_service.h +31 -3
  21. esphome/components/api/api_server.cpp +78 -11
  22. esphome/components/api/api_server.h +32 -4
  23. esphome/components/api/custom_api_device.h +8 -8
  24. esphome/components/api/homeassistant_service.h +123 -6
  25. esphome/components/api/proto.h +6 -2
  26. esphome/components/api/user_services.h +2 -2
  27. esphome/components/as7341/sensor.py +1 -1
  28. esphome/components/audio/__init__.py +1 -1
  29. esphome/components/audio/audio.cpp +1 -1
  30. esphome/components/audio/audio_decoder.cpp +9 -9
  31. esphome/components/bl0906/bl0906.cpp +2 -2
  32. esphome/components/bl0942/bl0942.cpp +2 -2
  33. esphome/components/ble_client/__init__.py +1 -1
  34. esphome/components/bluetooth_proxy/__init__.py +4 -30
  35. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
  36. esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
  37. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
  38. esphome/components/camera_encoder/__init__.py +2 -4
  39. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
  40. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
  41. esphome/components/canbus/canbus.cpp +7 -5
  42. esphome/components/canbus/canbus.h +4 -4
  43. esphome/components/captive_portal/__init__.py +18 -1
  44. esphome/components/captive_portal/captive_portal.cpp +40 -46
  45. esphome/components/captive_portal/captive_portal.h +20 -22
  46. esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
  47. esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
  48. esphome/components/ccs811/ccs811.cpp +1 -1
  49. esphome/components/climate/climate.cpp +10 -7
  50. esphome/components/cm1106/cm1106.cpp +1 -1
  51. esphome/components/copy/lock/copy_lock.cpp +1 -1
  52. esphome/components/cover/cover.cpp +1 -0
  53. esphome/components/daikin_arc/daikin_arc.cpp +19 -12
  54. esphome/components/deep_sleep/__init__.py +9 -2
  55. esphome/components/deep_sleep/deep_sleep_component.h +11 -9
  56. esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
  57. esphome/components/ektf2232/touchscreen/__init__.py +8 -5
  58. esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
  59. esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
  60. esphome/components/epaper_spi/__init__.py +1 -0
  61. esphome/components/epaper_spi/display.py +80 -0
  62. esphome/components/epaper_spi/epaper_spi.cpp +227 -0
  63. esphome/components/epaper_spi/epaper_spi.h +93 -0
  64. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
  65. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
  66. esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
  67. esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
  68. esphome/components/es7210/es7210.cpp +3 -3
  69. esphome/components/esp32/__init__.py +254 -339
  70. esphome/components/esp32/boards.py +81 -0
  71. esphome/components/esp32/preferences.cpp +23 -17
  72. esphome/components/esp32_ble/__init__.py +159 -44
  73. esphome/components/esp32_ble/ble.cpp +47 -3
  74. esphome/components/esp32_ble/ble.h +18 -0
  75. esphome/components/esp32_ble/ble_advertising.cpp +7 -3
  76. esphome/components/esp32_ble/ble_advertising.h +4 -0
  77. esphome/components/esp32_ble/ble_uuid.cpp +16 -42
  78. esphome/components/esp32_ble_beacon/__init__.py +3 -4
  79. esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
  80. esphome/components/esp32_ble_server/__init__.py +28 -14
  81. esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
  82. esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
  83. esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
  84. esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
  85. esphome/components/esp32_ble_server/ble_server.cpp +59 -24
  86. esphome/components/esp32_ble_server/ble_server.h +38 -20
  87. esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
  88. esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
  89. esphome/components/esp32_ble_tracker/__init__.py +25 -80
  90. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -4
  91. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
  92. esphome/components/esp32_camera/__init__.py +1 -3
  93. esphome/components/esp32_can/esp32_can.cpp +22 -4
  94. esphome/components/esp32_can/esp32_can.h +3 -0
  95. esphome/components/esp32_hosted/__init__.py +2 -1
  96. esphome/components/esp32_improv/esp32_improv_component.cpp +102 -44
  97. esphome/components/esp32_improv/esp32_improv_component.h +6 -1
  98. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  99. esphome/components/esp8266/__init__.py +3 -3
  100. esphome/components/esphome/ota/__init__.py +21 -2
  101. esphome/components/esphome/ota/ota_esphome.cpp +455 -145
  102. esphome/components/esphome/ota/ota_esphome.h +49 -2
  103. esphome/components/ethernet/__init__.py +39 -22
  104. esphome/components/ethernet/ethernet_component.cpp +28 -5
  105. esphome/components/ethernet/ethernet_component.h +5 -1
  106. esphome/components/external_components/__init__.py +8 -6
  107. esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
  108. esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
  109. esphome/components/font/__init__.py +5 -5
  110. esphome/components/graph/graph.cpp +1 -1
  111. esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
  112. esphome/components/haier/hon_climate.cpp +2 -2
  113. esphome/components/haier/hon_climate.h +1 -1
  114. esphome/components/hdc1080/hdc1080.cpp +42 -34
  115. esphome/components/hdc1080/hdc1080.h +1 -3
  116. esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
  117. esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
  118. esphome/components/http_request/__init__.py +3 -3
  119. esphome/components/htu21d/htu21d.cpp +13 -18
  120. esphome/components/htu21d/htu21d.h +1 -1
  121. esphome/components/i2s_audio/__init__.py +1 -2
  122. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  123. esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
  124. esphome/components/improv_serial/improv_serial_component.cpp +12 -15
  125. esphome/components/improv_serial/improv_serial_component.h +6 -8
  126. esphome/components/json/json_util.cpp +35 -43
  127. esphome/components/json/json_util.h +57 -0
  128. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
  129. esphome/components/key_collector/key_collector.h +4 -4
  130. esphome/components/libretiny/__init__.py +6 -6
  131. esphome/components/libretiny/preferences.cpp +23 -16
  132. esphome/components/light/light_call.cpp +98 -120
  133. esphome/components/light/light_call.h +17 -7
  134. esphome/components/lm75b/__init__.py +0 -0
  135. esphome/components/lm75b/lm75b.cpp +39 -0
  136. esphome/components/lm75b/lm75b.h +19 -0
  137. esphome/components/lm75b/sensor.py +34 -0
  138. esphome/components/lock/lock.h +12 -6
  139. esphome/components/logger/__init__.py +15 -27
  140. esphome/components/logger/logger.cpp +10 -20
  141. esphome/components/logger/logger.h +105 -62
  142. esphome/components/logger/logger_esp32.cpp +0 -48
  143. esphome/components/logger/logger_zephyr.cpp +2 -3
  144. esphome/components/logger/select/logger_level_select.cpp +6 -7
  145. esphome/components/logger/select/logger_level_select.h +7 -0
  146. esphome/components/ltr501/ltr501.cpp +7 -6
  147. esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
  148. esphome/components/matrix_keypad/matrix_keypad.h +4 -4
  149. esphome/components/max7219digit/max7219digit.cpp +1 -1
  150. esphome/components/mcp2515/mcp2515.cpp +31 -3
  151. esphome/components/mcp2515/mcp2515_defs.h +3 -1
  152. esphome/components/md5/md5.cpp +0 -26
  153. esphome/components/md5/md5.h +10 -20
  154. esphome/components/mdns/__init__.py +19 -6
  155. esphome/components/mdns/mdns_component.cpp +27 -59
  156. esphome/components/mdns/mdns_component.h +23 -10
  157. esphome/components/mdns/mdns_esp32.cpp +7 -7
  158. esphome/components/mdns/mdns_esp8266.cpp +6 -6
  159. esphome/components/mdns/mdns_libretiny.cpp +3 -3
  160. esphome/components/mdns/mdns_rp2040.cpp +3 -3
  161. esphome/components/mipi/__init__.py +1 -5
  162. esphome/components/mipi_spi/display.py +24 -8
  163. esphome/components/mipi_spi/mipi_spi.h +3 -3
  164. esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
  165. esphome/components/mmc5603/mmc5603.cpp +3 -3
  166. esphome/components/modbus/modbus.cpp +27 -13
  167. esphome/components/modbus/modbus.h +5 -3
  168. esphome/components/modbus/modbus_definitions.h +86 -0
  169. esphome/components/modbus_controller/__init__.py +29 -1
  170. esphome/components/modbus_controller/const.py +4 -0
  171. esphome/components/modbus_controller/modbus_controller.cpp +38 -13
  172. esphome/components/modbus_controller/modbus_controller.h +18 -29
  173. esphome/components/mpr121/mpr121.cpp +41 -42
  174. esphome/components/mpr121/mpr121.h +0 -1
  175. esphome/components/nau7802/nau7802.cpp +2 -2
  176. esphome/components/network/__init__.py +7 -3
  177. esphome/components/nextion/display.py +4 -4
  178. esphome/components/nextion/nextion.cpp +8 -8
  179. esphome/components/number/__init__.py +2 -0
  180. esphome/components/number/number_call.cpp +23 -12
  181. esphome/components/number/number_call.h +5 -0
  182. esphome/components/online_image/bmp_image.cpp +2 -1
  183. esphome/components/online_image/jpeg_image.cpp +4 -2
  184. esphome/components/openthread/openthread.cpp +6 -7
  185. esphome/components/openthread/openthread.h +0 -1
  186. esphome/components/ota/ota_backend.h +1 -0
  187. esphome/components/packages/__init__.py +10 -8
  188. esphome/components/packet_transport/packet_transport.cpp +2 -0
  189. esphome/components/pid/pid_controller.cpp +1 -1
  190. esphome/components/prometheus/prometheus_handler.cpp +239 -239
  191. esphome/components/psram/__init__.py +30 -28
  192. esphome/components/qmc5883l/qmc5883l.cpp +15 -0
  193. esphome/components/qmc5883l/qmc5883l.h +3 -0
  194. esphome/components/qmc5883l/sensor.py +31 -12
  195. esphome/components/remote_base/gobox_protocol.cpp +3 -3
  196. esphome/components/remote_receiver/__init__.py +14 -2
  197. esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
  198. esphome/components/remote_receiver/remote_receiver.h +4 -0
  199. esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
  200. esphome/components/remote_transmitter/__init__.py +2 -2
  201. esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
  202. esphome/components/rp2040/__init__.py +11 -11
  203. esphome/components/rtttl/rtttl.cpp +2 -2
  204. esphome/components/scd30/sensor.py +1 -1
  205. esphome/components/script/__init__.py +1 -1
  206. esphome/components/script/script.h +7 -7
  207. esphome/components/select/select.cpp +5 -4
  208. esphome/components/select/select_call.cpp +1 -1
  209. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  210. esphome/components/sensor/__init__.py +2 -0
  211. esphome/components/sha256/__init__.py +22 -0
  212. esphome/components/sha256/sha256.cpp +116 -0
  213. esphome/components/sha256/sha256.h +60 -0
  214. esphome/components/sim800l/sim800l.cpp +8 -4
  215. esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
  216. esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
  217. esphome/components/spi/__init__.py +0 -3
  218. esphome/components/split_buffer/__init__.py +5 -0
  219. esphome/components/split_buffer/split_buffer.cpp +133 -0
  220. esphome/components/split_buffer/split_buffer.h +40 -0
  221. esphome/components/sps30/sps30.cpp +14 -10
  222. esphome/components/sps30/sps30.h +2 -0
  223. esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
  224. esphome/components/st7789v/st7789v.cpp +3 -2
  225. esphome/components/statsd/statsd.cpp +1 -1
  226. esphome/components/substitutions/__init__.py +3 -1
  227. esphome/components/substitutions/jinja.py +13 -3
  228. esphome/components/sx126x/__init__.py +16 -0
  229. esphome/components/sx126x/sx126x.cpp +15 -1
  230. esphome/components/sx126x/sx126x.h +9 -1
  231. esphome/components/sx126x/sx126x_reg.h +2 -0
  232. esphome/components/text_sensor/text_sensor.cpp +16 -0
  233. esphome/components/text_sensor/text_sensor.h +3 -10
  234. esphome/components/tormatic/tormatic_cover.cpp +1 -1
  235. esphome/components/tuya/select/tuya_select.cpp +1 -1
  236. esphome/components/tuya/tuya.cpp +29 -4
  237. esphome/components/uart/__init__.py +36 -26
  238. esphome/components/uart/uart.h +6 -0
  239. esphome/components/uart/uart_component.cpp +8 -0
  240. esphome/components/uart/uart_component.h +28 -0
  241. esphome/components/uart/uart_component_esp_idf.cpp +64 -10
  242. esphome/components/uart/uart_component_esp_idf.h +5 -2
  243. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  244. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
  245. esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
  246. esphome/components/usb_host/__init__.py +2 -1
  247. esphome/components/usb_host/usb_host.h +82 -13
  248. esphome/components/usb_host/usb_host_client.cpp +180 -24
  249. esphome/components/usb_host/usb_host_component.cpp +1 -1
  250. esphome/components/usb_uart/__init__.py +0 -1
  251. esphome/components/usb_uart/ch34x.cpp +4 -4
  252. esphome/components/usb_uart/cp210x.cpp +3 -3
  253. esphome/components/usb_uart/usb_uart.cpp +88 -32
  254. esphome/components/usb_uart/usb_uart.h +30 -6
  255. esphome/components/valve/valve.cpp +1 -0
  256. esphome/components/veml7700/veml7700.cpp +7 -6
  257. esphome/components/version/version_text_sensor.cpp +2 -1
  258. esphome/components/voice_assistant/voice_assistant.cpp +3 -3
  259. esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
  260. esphome/components/web_server/list_entities.cpp +3 -4
  261. esphome/components/web_server/list_entities.h +8 -10
  262. esphome/components/web_server/ota/__init__.py +1 -1
  263. esphome/components/web_server/ota/ota_web_server.cpp +9 -3
  264. esphome/components/web_server/web_server.cpp +509 -404
  265. esphome/components/web_server/web_server.h +5 -6
  266. esphome/components/web_server/web_server_v1.cpp +21 -19
  267. esphome/components/web_server_base/__init__.py +5 -2
  268. esphome/components/web_server_base/web_server_base.h +27 -7
  269. esphome/components/web_server_idf/__init__.py +1 -1
  270. esphome/components/web_server_idf/multipart.cpp +2 -2
  271. esphome/components/web_server_idf/multipart.h +2 -2
  272. esphome/components/web_server_idf/utils.cpp +2 -2
  273. esphome/components/web_server_idf/utils.h +2 -2
  274. esphome/components/web_server_idf/web_server_idf.cpp +118 -26
  275. esphome/components/web_server_idf/web_server_idf.h +12 -10
  276. esphome/components/wifi/__init__.py +13 -11
  277. esphome/components/wifi/wifi_component.cpp +73 -56
  278. esphome/components/wifi/wifi_component.h +4 -4
  279. esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
  280. esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
  281. esphome/components/wireguard/__init__.py +1 -1
  282. esphome/components/wts01/__init__.py +0 -0
  283. esphome/components/wts01/sensor.py +41 -0
  284. esphome/components/wts01/wts01.cpp +91 -0
  285. esphome/components/wts01/wts01.h +27 -0
  286. esphome/components/zephyr/__init__.py +5 -5
  287. esphome/components/zwave_proxy/__init__.py +43 -0
  288. esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
  289. esphome/components/zwave_proxy/zwave_proxy.h +93 -0
  290. esphome/config.py +79 -24
  291. esphome/config_validation.py +13 -15
  292. esphome/const.py +9 -2
  293. esphome/core/__init__.py +31 -22
  294. esphome/core/component.cpp +28 -18
  295. esphome/core/component_iterator.h +2 -1
  296. esphome/core/config.py +15 -15
  297. esphome/core/defines.h +19 -0
  298. esphome/core/hash_base.h +56 -0
  299. esphome/core/helpers.cpp +19 -3
  300. esphome/core/helpers.h +26 -0
  301. esphome/core/scheduler.cpp +5 -21
  302. esphome/core/scheduler.h +19 -8
  303. esphome/core/string_ref.h +1 -1
  304. esphome/core/time.cpp +5 -5
  305. esphome/cpp_generator.py +4 -29
  306. esphome/dashboard/const.py +21 -4
  307. esphome/dashboard/core.py +10 -8
  308. esphome/dashboard/dns.py +15 -0
  309. esphome/dashboard/entries.py +15 -21
  310. esphome/dashboard/models.py +76 -0
  311. esphome/dashboard/settings.py +7 -7
  312. esphome/dashboard/status/mdns.py +46 -2
  313. esphome/dashboard/web_server.py +367 -93
  314. esphome/espota2.py +111 -31
  315. esphome/external_files.py +6 -7
  316. esphome/git.py +8 -0
  317. esphome/helpers.py +124 -77
  318. esphome/loader.py +8 -9
  319. esphome/platformio_api.py +25 -18
  320. esphome/storage_json.py +26 -21
  321. esphome/types.py +30 -2
  322. esphome/util.py +32 -16
  323. esphome/vscode.py +8 -8
  324. esphome/wizard.py +10 -10
  325. esphome/writer.py +50 -15
  326. esphome/yaml_util.py +37 -31
  327. esphome/zeroconf.py +12 -3
  328. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/METADATA +11 -11
  329. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/RECORD +333 -313
  330. esphome/components/event_emitter/__init__.py +0 -5
  331. esphome/components/event_emitter/event_emitter.cpp +0 -14
  332. esphome/components/event_emitter/event_emitter.h +0 -63
  333. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
  334. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
  335. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
  336. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
  337. esphome/components/uart/uart_component_esp32_arduino.h +0 -60
  338. esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
  339. esphome/core/string_ref.cpp +0 -12
  340. esphome/dashboard/util/file.py +0 -63
  341. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/WHEEL +0 -0
  342. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/entry_points.txt +0 -0
  343. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/licenses/LICENSE +0 -0
  344. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/top_level.txt +0 -0
@@ -81,7 +81,7 @@ enum JsonDetail { DETAIL_ALL, DETAIL_STATE };
81
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
- #ifdef USE_ARDUINO
84
+ #if !defined(USE_ESP32) && defined(USE_ARDUINO)
85
85
  using message_generator_t = std::string(WebServer *, void *);
86
86
 
87
87
  class DeferredUpdateEventSourceList;
@@ -164,7 +164,7 @@ class DeferredUpdateEventSourceList : public std::list<DeferredUpdateEventSource
164
164
  * can be found under https://esphome.io/web-api/index.html.
165
165
  */
166
166
  class WebServer : public Controller, public Component, public AsyncWebHandler {
167
- #ifdef USE_ARDUINO
167
+ #if !defined(USE_ESP32) && defined(USE_ARDUINO)
168
168
  friend class DeferredUpdateEventSourceList;
169
169
  #endif
170
170
 
@@ -559,11 +559,10 @@ class WebServer : public Controller, public Component, public AsyncWebHandler {
559
559
  }
560
560
 
561
561
  web_server_base::WebServerBase *base_;
562
- #ifdef USE_ARDUINO
563
- DeferredUpdateEventSourceList events_;
564
- #endif
565
- #ifdef USE_ESP_IDF
562
+ #ifdef USE_ESP32
566
563
  AsyncEventSource events_{"/events", this};
564
+ #elif USE_ARDUINO
565
+ DeferredUpdateEventSourceList events_;
567
566
  #endif
568
567
 
569
568
  #if USE_WEBSERVER_VERSION == 1
@@ -34,23 +34,23 @@ void WebServer::set_js_url(const char *js_url) { this->js_url_ = js_url; }
34
34
  void WebServer::handle_index_request(AsyncWebServerRequest *request) {
35
35
  AsyncResponseStream *stream = request->beginResponseStream("text/html");
36
36
  const std::string &title = App.get_name();
37
- stream->print(F("<!DOCTYPE html><html lang=\"en\"><head><meta charset=UTF-8><meta "
38
- "name=viewport content=\"width=device-width, initial-scale=1,user-scalable=no\"><title>"));
37
+ stream->print(ESPHOME_F("<!DOCTYPE html><html lang=\"en\"><head><meta charset=UTF-8><meta "
38
+ "name=viewport content=\"width=device-width, initial-scale=1,user-scalable=no\"><title>"));
39
39
  stream->print(title.c_str());
40
- stream->print(F("</title>"));
40
+ stream->print(ESPHOME_F("</title>"));
41
41
  #ifdef USE_WEBSERVER_CSS_INCLUDE
42
- stream->print(F("<link rel=\"stylesheet\" href=\"/0.css\">"));
42
+ stream->print(ESPHOME_F("<link rel=\"stylesheet\" href=\"/0.css\">"));
43
43
  #endif
44
44
  if (strlen(this->css_url_) > 0) {
45
- stream->print(F(R"(<link rel="stylesheet" href=")"));
45
+ stream->print(ESPHOME_F(R"(<link rel="stylesheet" href=")"));
46
46
  stream->print(this->css_url_);
47
- stream->print(F("\">"));
47
+ stream->print(ESPHOME_F("\">"));
48
48
  }
49
- stream->print(F("</head><body>"));
50
- stream->print(F("<article class=\"markdown-body\"><h1>"));
49
+ stream->print(ESPHOME_F("</head><body>"));
50
+ stream->print(ESPHOME_F("<article class=\"markdown-body\"><h1>"));
51
51
  stream->print(title.c_str());
52
- stream->print(F("</h1>"));
53
- stream->print(F("<h2>States</h2><table id=\"states\"><thead><tr><th>Name<th>State<th>Actions<tbody>"));
52
+ stream->print(ESPHOME_F("</h1>"));
53
+ stream->print(ESPHOME_F("<h2>States</h2><table id=\"states\"><thead><tr><th>Name<th>State<th>Actions<tbody>"));
54
54
 
55
55
  #ifdef USE_SENSOR
56
56
  for (auto *obj : App.get_sensors()) {
@@ -190,26 +190,28 @@ void WebServer::handle_index_request(AsyncWebServerRequest *request) {
190
190
  }
191
191
  #endif
192
192
 
193
- stream->print(F("</tbody></table><p>See <a href=\"https://esphome.io/web-api/index.html\">ESPHome Web API</a> for "
194
- "REST API documentation.</p>"));
193
+ stream->print(
194
+ ESPHOME_F("</tbody></table><p>See <a href=\"https://esphome.io/web-api/index.html\">ESPHome Web API</a> for "
195
+ "REST API documentation.</p>"));
195
196
  #if defined(USE_WEBSERVER_OTA) && !defined(USE_WEBSERVER_OTA_DISABLED)
196
197
  // Show OTA form only if web_server OTA is not explicitly disabled
197
198
  // Note: USE_WEBSERVER_OTA_DISABLED only affects web_server, not captive_portal
198
- stream->print(F("<h2>OTA Update</h2><form method=\"POST\" action=\"/update\" enctype=\"multipart/form-data\"><input "
199
- "type=\"file\" name=\"update\"><input type=\"submit\" value=\"Update\"></form>"));
199
+ stream->print(
200
+ ESPHOME_F("<h2>OTA Update</h2><form method=\"POST\" action=\"/update\" enctype=\"multipart/form-data\"><input "
201
+ "type=\"file\" name=\"update\"><input type=\"submit\" value=\"Update\"></form>"));
200
202
  #endif
201
- stream->print(F("<h2>Debug Log</h2><pre id=\"log\"></pre>"));
203
+ stream->print(ESPHOME_F("<h2>Debug Log</h2><pre id=\"log\"></pre>"));
202
204
  #ifdef USE_WEBSERVER_JS_INCLUDE
203
205
  if (this->js_include_ != nullptr) {
204
- stream->print(F("<script type=\"module\" src=\"/0.js\"></script>"));
206
+ stream->print(ESPHOME_F("<script type=\"module\" src=\"/0.js\"></script>"));
205
207
  }
206
208
  #endif
207
209
  if (strlen(this->js_url_) > 0) {
208
- stream->print(F("<script src=\""));
210
+ stream->print(ESPHOME_F("<script src=\""));
209
211
  stream->print(this->js_url_);
210
- stream->print(F("\"></script>"));
212
+ stream->print(ESPHOME_F("\"></script>"));
211
213
  }
212
- stream->print(F("</article></body></html>"));
214
+ stream->print(ESPHOME_F("</article></body></html>"));
213
215
  request->send(stream);
214
216
  }
215
217
 
@@ -9,10 +9,10 @@ DEPENDENCIES = ["network"]
9
9
 
10
10
 
11
11
  def AUTO_LOAD():
12
+ if CORE.is_esp32:
13
+ return ["web_server_idf"]
12
14
  if CORE.using_arduino:
13
15
  return ["async_tcp"]
14
- if CORE.using_esp_idf:
15
- return ["web_server_idf"]
16
16
  return []
17
17
 
18
18
 
@@ -33,6 +33,9 @@ async def to_code(config):
33
33
  await cg.register_component(var, config)
34
34
  cg.add(cg.RawExpression(f"{web_server_base_ns}::global_web_server_base = {var}"))
35
35
 
36
+ if CORE.is_esp32:
37
+ return
38
+
36
39
  if CORE.using_arduino:
37
40
  if CORE.is_esp32:
38
41
  cg.add_library("WiFi", None)
@@ -7,11 +7,31 @@
7
7
 
8
8
  #include "esphome/core/component.h"
9
9
 
10
- #ifdef USE_ARDUINO
11
- #include <ESPAsyncWebServer.h>
12
- #elif USE_ESP_IDF
10
+ // Platform-agnostic macros for web server components
11
+ // On ESP32 (both Arduino and IDF): Use plain strings (no PROGMEM)
12
+ // On ESP8266: Use Arduino's F() macro for PROGMEM strings
13
+ #ifdef USE_ESP32
14
+ #define ESPHOME_F(string_literal) (string_literal)
15
+ #define ESPHOME_PGM_P const char *
16
+ #define ESPHOME_strncpy_P strncpy
17
+ #else
18
+ // ESP8266 uses Arduino macros
19
+ #define ESPHOME_F(string_literal) F(string_literal)
20
+ #define ESPHOME_PGM_P PGM_P
21
+ #define ESPHOME_strncpy_P strncpy_P
22
+ #endif
23
+
24
+ #if USE_ESP32
13
25
  #include "esphome/core/hal.h"
14
26
  #include "esphome/components/web_server_idf/web_server_idf.h"
27
+ #else
28
+ #include <ESPAsyncWebServer.h>
29
+ #endif
30
+
31
+ #if USE_ESP32
32
+ using PlatformString = std::string;
33
+ #elif USE_ARDUINO
34
+ using PlatformString = String;
15
35
  #endif
16
36
 
17
37
  namespace esphome {
@@ -28,8 +48,8 @@ class MiddlewareHandler : public AsyncWebHandler {
28
48
 
29
49
  bool canHandle(AsyncWebServerRequest *request) const override { return next_->canHandle(request); }
30
50
  void handleRequest(AsyncWebServerRequest *request) override { next_->handleRequest(request); }
31
- void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len,
32
- bool final) override {
51
+ void handleUpload(AsyncWebServerRequest *request, const PlatformString &filename, size_t index, uint8_t *data,
52
+ size_t len, bool final) override {
33
53
  next_->handleUpload(request, filename, index, data, len, final);
34
54
  }
35
55
  void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override {
@@ -65,8 +85,8 @@ class AuthMiddlewareHandler : public MiddlewareHandler {
65
85
  return;
66
86
  MiddlewareHandler::handleRequest(request);
67
87
  }
68
- void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len,
69
- bool final) override {
88
+ void handleUpload(AsyncWebServerRequest *request, const PlatformString &filename, size_t index, uint8_t *data,
89
+ size_t len, bool final) override {
70
90
  if (!check_auth(request))
71
91
  return;
72
92
  MiddlewareHandler::handleUpload(request, filename, index, data, len, final);
@@ -5,7 +5,7 @@ CODEOWNERS = ["@dentra"]
5
5
 
6
6
  CONFIG_SCHEMA = cv.All(
7
7
  cv.Schema({}),
8
- cv.only_with_esp_idf,
8
+ cv.only_on_esp32,
9
9
  )
10
10
 
11
11
 
@@ -1,5 +1,5 @@
1
1
  #include "esphome/core/defines.h"
2
- #if defined(USE_ESP_IDF) && defined(USE_WEBSERVER_OTA)
2
+ #if defined(USE_ESP32) && defined(USE_WEBSERVER_OTA)
3
3
  #include "multipart.h"
4
4
  #include "utils.h"
5
5
  #include "esphome/core/log.h"
@@ -251,4 +251,4 @@ std::string str_trim(const std::string &str) {
251
251
 
252
252
  } // namespace web_server_idf
253
253
  } // namespace esphome
254
- #endif // defined(USE_ESP_IDF) && defined(USE_WEBSERVER_OTA)
254
+ #endif // defined(USE_ESP32) && defined(USE_WEBSERVER_OTA)
@@ -1,6 +1,6 @@
1
1
  #pragma once
2
2
  #include "esphome/core/defines.h"
3
- #if defined(USE_ESP_IDF) && defined(USE_WEBSERVER_OTA)
3
+ #if defined(USE_ESP32) && defined(USE_WEBSERVER_OTA)
4
4
 
5
5
  #include <cctype>
6
6
  #include <cstring>
@@ -83,4 +83,4 @@ std::string str_trim(const std::string &str);
83
83
 
84
84
  } // namespace web_server_idf
85
85
  } // namespace esphome
86
- #endif // defined(USE_ESP_IDF) && defined(USE_WEBSERVER_OTA)
86
+ #endif // defined(USE_ESP32) && defined(USE_WEBSERVER_OTA)
@@ -1,4 +1,4 @@
1
- #ifdef USE_ESP_IDF
1
+ #ifdef USE_ESP32
2
2
  #include <memory>
3
3
  #include <cstring>
4
4
  #include <cctype>
@@ -122,4 +122,4 @@ const char *stristr(const char *haystack, const char *needle) {
122
122
 
123
123
  } // namespace web_server_idf
124
124
  } // namespace esphome
125
- #endif // USE_ESP_IDF
125
+ #endif // USE_ESP32
@@ -1,5 +1,5 @@
1
1
  #pragma once
2
- #ifdef USE_ESP_IDF
2
+ #ifdef USE_ESP32
3
3
 
4
4
  #include <esp_http_server.h>
5
5
  #include <string>
@@ -24,4 +24,4 @@ const char *stristr(const char *haystack, const char *needle);
24
24
 
25
25
  } // namespace web_server_idf
26
26
  } // namespace esphome
27
- #endif // USE_ESP_IDF
27
+ #endif // USE_ESP32
@@ -1,4 +1,4 @@
1
- #ifdef USE_ESP_IDF
1
+ #ifdef USE_ESP32
2
2
 
3
3
  #include <cstdarg>
4
4
  #include <memory>
@@ -25,6 +25,10 @@
25
25
  #include "esphome/components/web_server/list_entities.h"
26
26
  #endif // USE_WEBSERVER
27
27
 
28
+ // Include socket headers after Arduino headers to avoid IPADDR_NONE/INADDR_NONE macro conflicts
29
+ #include <cerrno>
30
+ #include <sys/socket.h>
31
+
28
32
  namespace esphome {
29
33
  namespace web_server_idf {
30
34
 
@@ -46,6 +50,42 @@ DefaultHeaders default_headers_instance;
46
50
 
47
51
  DefaultHeaders &DefaultHeaders::Instance() { return default_headers_instance; }
48
52
 
53
+ namespace {
54
+ // Non-blocking send function to prevent watchdog timeouts when TCP buffers are full
55
+ /**
56
+ * Sends data on a socket in non-blocking mode.
57
+ *
58
+ * @param hd HTTP server handle (unused).
59
+ * @param sockfd Socket file descriptor.
60
+ * @param buf Buffer to send.
61
+ * @param buf_len Length of buffer.
62
+ * @param flags Flags for send().
63
+ * @return
64
+ * - Number of bytes sent on success.
65
+ * - HTTPD_SOCK_ERR_INVALID if buf is nullptr.
66
+ * - HTTPD_SOCK_ERR_TIMEOUT if the send buffer is full (EAGAIN/EWOULDBLOCK).
67
+ * - HTTPD_SOCK_ERR_FAIL for other errors.
68
+ */
69
+ int nonblocking_send(httpd_handle_t hd, int sockfd, const char *buf, size_t buf_len, int flags) {
70
+ if (buf == nullptr) {
71
+ return HTTPD_SOCK_ERR_INVALID;
72
+ }
73
+
74
+ // Use MSG_DONTWAIT to prevent blocking when TCP send buffer is full
75
+ int ret = send(sockfd, buf, buf_len, flags | MSG_DONTWAIT);
76
+ if (ret < 0) {
77
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
78
+ // Buffer full - retry later
79
+ return HTTPD_SOCK_ERR_TIMEOUT;
80
+ }
81
+ // Real error
82
+ ESP_LOGD(TAG, "send error: errno %d", errno);
83
+ return HTTPD_SOCK_ERR_FAIL;
84
+ }
85
+ return ret;
86
+ }
87
+ } // namespace
88
+
49
89
  void AsyncWebServer::end() {
50
90
  if (this->server_) {
51
91
  httpd_stop(this->server_);
@@ -164,8 +204,8 @@ esp_err_t AsyncWebServer::request_handler_(AsyncWebServerRequest *request) const
164
204
 
165
205
  AsyncWebServerRequest::~AsyncWebServerRequest() {
166
206
  delete this->rsp_;
167
- for (const auto &pair : this->params_) {
168
- delete pair.second; // NOLINT(cppcoreguidelines-owning-memory)
207
+ for (auto *param : this->params_) {
208
+ delete param; // NOLINT(cppcoreguidelines-owning-memory)
169
209
  }
170
210
  }
171
211
 
@@ -205,10 +245,22 @@ void AsyncWebServerRequest::redirect(const std::string &url) {
205
245
  }
206
246
 
207
247
  void AsyncWebServerRequest::init_response_(AsyncWebServerResponse *rsp, int code, const char *content_type) {
208
- httpd_resp_set_status(*this, code == 200 ? HTTPD_200
209
- : code == 404 ? HTTPD_404
210
- : code == 409 ? HTTPD_409
211
- : to_string(code).c_str());
248
+ // Set status code - use constants for common codes to avoid string allocation
249
+ const char *status = nullptr;
250
+ switch (code) {
251
+ case 200:
252
+ status = HTTPD_200;
253
+ break;
254
+ case 404:
255
+ status = HTTPD_404;
256
+ break;
257
+ case 409:
258
+ status = HTTPD_409;
259
+ break;
260
+ default:
261
+ break;
262
+ }
263
+ httpd_resp_set_status(*this, status == nullptr ? to_string(code).c_str() : status);
212
264
 
213
265
  if (content_type && *content_type) {
214
266
  httpd_resp_set_type(*this, content_type);
@@ -265,11 +317,14 @@ void AsyncWebServerRequest::requestAuthentication(const char *realm) const {
265
317
  #endif
266
318
 
267
319
  AsyncWebParameter *AsyncWebServerRequest::getParam(const std::string &name) {
268
- auto find = this->params_.find(name);
269
- if (find != this->params_.end()) {
270
- return find->second;
320
+ // Check cache first - only successful lookups are cached
321
+ for (auto *param : this->params_) {
322
+ if (param->name() == name) {
323
+ return param;
324
+ }
271
325
  }
272
326
 
327
+ // Look up value from query strings
273
328
  optional<std::string> val = query_key_value(this->post_query_, name);
274
329
  if (!val.has_value()) {
275
330
  auto url_query = request_get_url_query(*this);
@@ -278,11 +333,14 @@ AsyncWebParameter *AsyncWebServerRequest::getParam(const std::string &name) {
278
333
  }
279
334
  }
280
335
 
281
- AsyncWebParameter *param = nullptr;
282
- if (val.has_value()) {
283
- param = new AsyncWebParameter(val.value()); // NOLINT(cppcoreguidelines-owning-memory)
336
+ // Don't cache misses to avoid wasting memory when handlers check for
337
+ // optional parameters that don't exist in the request
338
+ if (!val.has_value()) {
339
+ return nullptr;
284
340
  }
285
- this->params_.insert({name, param});
341
+
342
+ auto *param = new AsyncWebParameter(name, val.value()); // NOLINT(cppcoreguidelines-owning-memory)
343
+ this->params_.push_back(param);
286
344
  return param;
287
345
  }
288
346
 
@@ -317,8 +375,8 @@ AsyncEventSource::~AsyncEventSource() {
317
375
  }
318
376
 
319
377
  void AsyncEventSource::handleRequest(AsyncWebServerRequest *request) {
320
- auto *rsp = // NOLINT(cppcoreguidelines-owning-memory)
321
- new AsyncEventSourceResponse(request, this, this->web_server_);
378
+ // NOLINTNEXTLINE(cppcoreguidelines-owning-memory,clang-analyzer-cplusplus.NewDeleteLeaks)
379
+ auto *rsp = new AsyncEventSourceResponse(request, this, this->web_server_);
322
380
  if (this->on_connect_) {
323
381
  this->on_connect_(rsp);
324
382
  }
@@ -384,6 +442,9 @@ AsyncEventSourceResponse::AsyncEventSourceResponse(const AsyncWebServerRequest *
384
442
  this->hd_ = req->handle;
385
443
  this->fd_.store(httpd_req_to_sockfd(req));
386
444
 
445
+ // Use non-blocking send to prevent watchdog timeouts when TCP buffers are full
446
+ httpd_sess_set_send_override(this->hd_, this->fd_.load(), nonblocking_send);
447
+
387
448
  // Configure reconnect timeout and send config
388
449
  // this should always go through since the tcp send buffer is empty on connect
389
450
  std::string message = ws->get_config_json();
@@ -392,10 +453,11 @@ AsyncEventSourceResponse::AsyncEventSourceResponse(const AsyncWebServerRequest *
392
453
  #ifdef USE_WEBSERVER_SORTING
393
454
  for (auto &group : ws->sorting_groups_) {
394
455
  // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
395
- message = json::build_json([group](JsonObject root) {
396
- root["name"] = group.second.name;
397
- root["sorting_weight"] = group.second.weight;
398
- });
456
+ json::JsonBuilder builder;
457
+ JsonObject root = builder.root();
458
+ root["name"] = group.second.name;
459
+ root["sorting_weight"] = group.second.weight;
460
+ message = builder.serialize();
399
461
  // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
400
462
 
401
463
  // a (very) large number of these should be able to be queued initially without defer
@@ -458,15 +520,45 @@ void AsyncEventSourceResponse::process_buffer_() {
458
520
  return;
459
521
  }
460
522
 
461
- int bytes_sent = httpd_socket_send(this->hd_, this->fd_.load(), event_buffer_.c_str() + event_bytes_sent_,
462
- event_buffer_.size() - event_bytes_sent_, 0);
463
- if (bytes_sent == HTTPD_SOCK_ERR_TIMEOUT || bytes_sent == HTTPD_SOCK_ERR_FAIL) {
464
- // Socket error - just return, the connection will be closed by httpd
465
- // and our destroy callback will be called
523
+ size_t remaining = event_buffer_.size() - event_bytes_sent_;
524
+ int bytes_sent =
525
+ httpd_socket_send(this->hd_, this->fd_.load(), event_buffer_.c_str() + event_bytes_sent_, remaining, 0);
526
+ if (bytes_sent == HTTPD_SOCK_ERR_TIMEOUT) {
527
+ // EAGAIN/EWOULDBLOCK - socket buffer full, try again later
528
+ // NOTE: Similar logic exists in web_server/web_server.cpp in DeferredUpdateEventSource::process_deferred_queue_()
529
+ // The implementations differ due to platform-specific APIs (HTTPD_SOCK_ERR_TIMEOUT vs DISCARDED, fd_.store(0) vs
530
+ // close()), but the failure counting and timeout logic should be kept in sync. If you change this logic, also
531
+ // update the Arduino implementation.
532
+ this->consecutive_send_failures_++;
533
+ if (this->consecutive_send_failures_ >= MAX_CONSECUTIVE_SEND_FAILURES) {
534
+ // Too many failures, connection is likely dead
535
+ ESP_LOGW(TAG, "Closing stuck EventSource connection after %" PRIu16 " failed sends",
536
+ this->consecutive_send_failures_);
537
+ this->fd_.store(0); // Mark for cleanup
538
+ this->deferred_queue_.clear();
539
+ }
540
+ return;
541
+ }
542
+ if (bytes_sent == HTTPD_SOCK_ERR_FAIL) {
543
+ // Real socket error - connection will be closed by httpd and destroy callback will be called
544
+ return;
545
+ }
546
+ if (bytes_sent <= 0) {
547
+ // Unexpected error or zero bytes sent
548
+ ESP_LOGW(TAG, "Unexpected send result: %d", bytes_sent);
466
549
  return;
467
550
  }
551
+
552
+ // Successful send - reset failure counter
553
+ this->consecutive_send_failures_ = 0;
468
554
  event_bytes_sent_ += bytes_sent;
469
555
 
556
+ // Log partial sends for debugging
557
+ if (event_bytes_sent_ < event_buffer_.size()) {
558
+ ESP_LOGV(TAG, "Partial send: %d/%zu bytes (total: %zu/%zu)", bytes_sent, remaining, event_bytes_sent_,
559
+ event_buffer_.size());
560
+ }
561
+
470
562
  if (event_bytes_sent_ == event_buffer_.size()) {
471
563
  event_buffer_.resize(0);
472
564
  event_bytes_sent_ = 0;
@@ -669,4 +761,4 @@ esp_err_t AsyncWebServer::handle_multipart_upload_(httpd_req_t *r, const char *c
669
761
  } // namespace web_server_idf
670
762
  } // namespace esphome
671
763
 
672
- #endif // !defined(USE_ESP_IDF)
764
+ #endif // !defined(USE_ESP32)
@@ -1,5 +1,5 @@
1
1
  #pragma once
2
- #ifdef USE_ESP_IDF
2
+ #ifdef USE_ESP32
3
3
 
4
4
  #include "esphome/core/defines.h"
5
5
  #include <esp_http_server.h>
@@ -22,18 +22,14 @@ class ListEntitiesIterator;
22
22
  #endif
23
23
  namespace web_server_idf {
24
24
 
25
- #define F(string_literal) (string_literal)
26
- #define PGM_P const char *
27
- #define strncpy_P strncpy
28
-
29
- using String = std::string;
30
-
31
25
  class AsyncWebParameter {
32
26
  public:
33
- AsyncWebParameter(std::string value) : value_(std::move(value)) {}
27
+ AsyncWebParameter(std::string name, std::string value) : name_(std::move(name)), value_(std::move(value)) {}
28
+ const std::string &name() const { return this->name_; }
34
29
  const std::string &value() const { return this->value_; }
35
30
 
36
31
  protected:
32
+ std::string name_;
37
33
  std::string value_;
38
34
  };
39
35
 
@@ -174,7 +170,11 @@ class AsyncWebServerRequest {
174
170
  protected:
175
171
  httpd_req_t *req_;
176
172
  AsyncWebServerResponse *rsp_{};
177
- std::map<std::string, AsyncWebParameter *> params_;
173
+ // Use vector instead of map/unordered_map: most requests have 0-3 params, so linear search
174
+ // is faster than tree/hash overhead. AsyncWebParameter stores both name and value to avoid
175
+ // duplicate storage. Only successful lookups are cached to prevent cache pollution when
176
+ // handlers check for optional parameters that don't exist.
177
+ std::vector<AsyncWebParameter *> params_;
178
178
  std::string post_query_;
179
179
  AsyncWebServerRequest(httpd_req_t *req) : req_(req) {}
180
180
  AsyncWebServerRequest(httpd_req_t *req, std::string post_query) : req_(req), post_query_(std::move(post_query)) {}
@@ -283,6 +283,8 @@ class AsyncEventSourceResponse {
283
283
  std::unique_ptr<esphome::web_server::ListEntitiesIterator> entities_iterator_;
284
284
  std::string event_buffer_{""};
285
285
  size_t event_bytes_sent_;
286
+ uint16_t consecutive_send_failures_{0};
287
+ static constexpr uint16_t MAX_CONSECUTIVE_SEND_FAILURES = 2500; // ~20 seconds at 125Hz loop rate
286
288
  };
287
289
 
288
290
  using AsyncEventSourceClient = AsyncEventSourceResponse;
@@ -341,4 +343,4 @@ class DefaultHeaders {
341
343
 
342
344
  using namespace esphome::web_server_idf; // NOLINT(google-global-names-in-headers)
343
345
 
344
- #endif // !defined(USE_ESP_IDF)
346
+ #endif // !defined(USE_ESP32)
@@ -125,8 +125,8 @@ EAP_AUTH_SCHEMA = cv.All(
125
125
  cv.Optional(CONF_USERNAME): cv.string_strict,
126
126
  cv.Optional(CONF_PASSWORD): cv.string_strict,
127
127
  cv.Optional(CONF_CERTIFICATE_AUTHORITY): wpa2_eap.validate_certificate,
128
- cv.SplitDefault(CONF_TTLS_PHASE_2, esp32_idf="mschapv2"): cv.All(
129
- cv.enum(TTLS_PHASE_2), cv.only_with_esp_idf
128
+ cv.SplitDefault(CONF_TTLS_PHASE_2, esp32="mschapv2"): cv.All(
129
+ cv.enum(TTLS_PHASE_2), cv.only_on_esp32
130
130
  ),
131
131
  cv.Inclusive(
132
132
  CONF_CERTIFICATE, "certificate_and_key"
@@ -280,11 +280,11 @@ CONFIG_SCHEMA = cv.All(
280
280
  cv.SplitDefault(CONF_OUTPUT_POWER, esp8266=20.0): cv.All(
281
281
  cv.decibel, cv.float_range(min=8.5, max=20.5)
282
282
  ),
283
- cv.SplitDefault(CONF_ENABLE_BTM, esp32_idf=False): cv.All(
284
- cv.boolean, cv.only_with_esp_idf
283
+ cv.SplitDefault(CONF_ENABLE_BTM, esp32=False): cv.All(
284
+ cv.boolean, cv.only_on_esp32
285
285
  ),
286
- cv.SplitDefault(CONF_ENABLE_RRM, esp32_idf=False): cv.All(
287
- cv.boolean, cv.only_with_esp_idf
286
+ cv.SplitDefault(CONF_ENABLE_RRM, esp32=False): cv.All(
287
+ cv.boolean, cv.only_on_esp32
288
288
  ),
289
289
  cv.Optional(CONF_PASSIVE_SCAN, default=False): cv.boolean,
290
290
  cv.Optional("enable_mdns"): cv.invalid(
@@ -402,7 +402,7 @@ async def to_code(config):
402
402
  add_idf_sdkconfig_option("CONFIG_LWIP_DHCPS", False)
403
403
 
404
404
  # Disable Enterprise WiFi support if no EAP is configured
405
- if CORE.is_esp32 and CORE.using_esp_idf and not has_eap:
405
+ if CORE.is_esp32 and not has_eap:
406
406
  add_idf_sdkconfig_option("CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT", False)
407
407
 
408
408
  cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
@@ -416,10 +416,10 @@ async def to_code(config):
416
416
 
417
417
  if CORE.is_esp8266:
418
418
  cg.add_library("ESP8266WiFi", None)
419
- elif (CORE.is_esp32 and CORE.using_arduino) or CORE.is_rp2040:
419
+ elif CORE.is_rp2040:
420
420
  cg.add_library("WiFi", None)
421
421
 
422
- if CORE.is_esp32 and CORE.using_esp_idf:
422
+ if CORE.is_esp32:
423
423
  if config[CONF_ENABLE_BTM] or config[CONF_ENABLE_RRM]:
424
424
  add_idf_sdkconfig_option("CONFIG_WPA_11KV_SUPPORT", True)
425
425
  cg.add_define("USE_WIFI_11KV_SUPPORT")
@@ -506,8 +506,10 @@ async def wifi_set_sta_to_code(config, action_id, template_arg, args):
506
506
 
507
507
  FILTER_SOURCE_FILES = filter_source_files_from_platform(
508
508
  {
509
- "wifi_component_esp32_arduino.cpp": {PlatformFramework.ESP32_ARDUINO},
510
- "wifi_component_esp_idf.cpp": {PlatformFramework.ESP32_IDF},
509
+ "wifi_component_esp_idf.cpp": {
510
+ PlatformFramework.ESP32_IDF,
511
+ PlatformFramework.ESP32_ARDUINO,
512
+ },
511
513
  "wifi_component_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO},
512
514
  "wifi_component_libretiny.cpp": {
513
515
  PlatformFramework.BK72XX_ARDUINO,