esphome 2025.5.2__py3-none-any.whl → 2025.6.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 (715) hide show
  1. esphome/__main__.py +20 -14
  2. esphome/components/a4988/a4988.cpp +1 -1
  3. esphome/components/absolute_humidity/absolute_humidity.cpp +6 -4
  4. esphome/components/ac_dimmer/ac_dimmer.cpp +4 -2
  5. esphome/components/adc/adc_sensor_esp32.cpp +5 -3
  6. esphome/components/adc/adc_sensor_esp8266.cpp +5 -3
  7. esphome/components/adc/adc_sensor_libretiny.cpp +5 -3
  8. esphome/components/adc/adc_sensor_rp2040.cpp +5 -3
  9. esphome/components/adc128s102/adc128s102.cpp +1 -1
  10. esphome/components/ade7880/ade7880.cpp +28 -17
  11. esphome/components/ade7953_base/ade7953_base.cpp +12 -9
  12. esphome/components/ade7953_i2c/ade7953_i2c.cpp +1 -1
  13. esphome/components/ade7953_spi/ade7953_spi.cpp +1 -1
  14. esphome/components/ads1115/ads1115.cpp +3 -5
  15. esphome/components/ads1118/ads1118.cpp +2 -1
  16. esphome/components/ags10/ags10.cpp +3 -2
  17. esphome/components/aht10/aht10.cpp +27 -29
  18. esphome/components/aic3204/aic3204.cpp +2 -2
  19. esphome/components/alarm_control_panel/__init__.py +1 -0
  20. esphome/components/am2315c/am2315c.cpp +2 -2
  21. esphome/components/am2320/am2320.cpp +2 -2
  22. esphome/components/am43/am43_base.h +1 -1
  23. esphome/components/am43/cover/am43_cover.cpp +4 -2
  24. esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +4 -2
  25. esphome/components/apds9306/apds9306.cpp +8 -5
  26. esphome/components/apds9960/apds9960.cpp +2 -2
  27. esphome/components/api/__init__.py +5 -0
  28. esphome/components/api/api_connection.cpp +712 -358
  29. esphome/components/api/api_connection.h +343 -284
  30. esphome/components/api/api_frame_helper.cpp +349 -344
  31. esphome/components/api/api_frame_helper.h +121 -94
  32. esphome/components/api/api_pb2.cpp +2 -0
  33. esphome/components/api/api_pb2.h +637 -1
  34. esphome/components/api/api_pb2_service.cpp +12 -688
  35. esphome/components/api/api_pb2_service.h +53 -207
  36. esphome/components/api/api_server.cpp +71 -29
  37. esphome/components/api/api_server.h +9 -0
  38. esphome/components/api/client.py +5 -2
  39. esphome/components/api/homeassistant_service.h +1 -1
  40. esphome/components/api/list_entities.cpp +1 -1
  41. esphome/components/api/proto.cpp +1 -0
  42. esphome/components/api/proto.h +4 -3
  43. esphome/components/api/subscribe_state.cpp +8 -16
  44. esphome/components/as3935/as3935.cpp +3 -3
  45. esphome/components/as5600/as5600.cpp +9 -7
  46. esphome/components/as7341/as7341.cpp +7 -5
  47. esphome/components/at581x/at581x.cpp +13 -10
  48. esphome/components/atm90e26/atm90e26.cpp +2 -2
  49. esphome/components/atm90e32/atm90e32.cpp +3 -3
  50. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +5 -3
  51. esphome/components/bang_bang/bang_bang_climate.cpp +8 -5
  52. esphome/components/bedjet/bedjet_hub.cpp +6 -4
  53. esphome/components/beken_spi_led_strip/led_strip.cpp +11 -7
  54. esphome/components/bh1750/bh1750.cpp +2 -2
  55. esphome/components/binary_sensor/__init__.py +1 -0
  56. esphome/components/binary_sensor/automation.cpp +1 -2
  57. esphome/components/bl0906/bl0906.cpp +1 -1
  58. esphome/components/bl0942/bl0942.cpp +11 -8
  59. esphome/components/bl0942/sensor.py +1 -1
  60. esphome/components/ble_client/__init__.py +5 -1
  61. esphome/components/ble_client/output/ble_binary_output.cpp +6 -3
  62. esphome/components/ble_client/sensor/ble_sensor.cpp +9 -6
  63. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +8 -5
  64. esphome/components/bluetooth_proxy/__init__.py +5 -1
  65. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +5 -5
  66. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -14
  67. esphome/components/bme280_base/bme280_base.cpp +3 -3
  68. esphome/components/bme680/bme680.cpp +3 -3
  69. esphome/components/bme680/sensor.py +2 -2
  70. esphome/components/bme680_bsec/bme680_bsec.cpp +11 -7
  71. esphome/components/bme680_bsec/sensor.py +7 -3
  72. esphome/components/bme68x_bsec2/__init__.py +6 -5
  73. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +17 -13
  74. esphome/components/bme68x_bsec2/sensor.py +4 -4
  75. esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.cpp +1 -0
  76. esphome/components/bmi160/bmi160.cpp +11 -11
  77. esphome/components/bmp085/bmp085.cpp +2 -2
  78. esphome/components/bmp280_base/bmp280_base.cpp +3 -3
  79. esphome/components/bmp3xx_base/bmp3xx_base.cpp +13 -13
  80. esphome/components/bmp581/bmp581.cpp +33 -27
  81. esphome/components/bp1658cj/bp1658cj.cpp +5 -3
  82. esphome/components/bp5758d/bp5758d.cpp +1 -1
  83. esphome/components/button/__init__.py +1 -0
  84. esphome/components/canbus/canbus.cpp +1 -1
  85. esphome/components/cap1188/cap1188.cpp +6 -4
  86. esphome/components/captive_portal/captive_portal.cpp +1 -1
  87. esphome/components/ccs811/ccs811.cpp +3 -2
  88. esphome/components/cd74hc4067/cd74hc4067.cpp +1 -1
  89. esphome/components/ch422g/ch422g.cpp +2 -2
  90. esphome/components/chsc6x/chsc6x_touchscreen.cpp +6 -4
  91. esphome/components/climate/__init__.py +1 -0
  92. esphome/components/climate/climate.cpp +12 -7
  93. esphome/components/climate/climate.h +1 -1
  94. esphome/components/climate_ir/climate_ir.cpp +7 -4
  95. esphome/components/cm1106/__init__.py +1 -0
  96. esphome/components/cm1106/cm1106.cpp +112 -0
  97. esphome/components/cm1106/cm1106.h +40 -0
  98. esphome/components/cm1106/sensor.py +72 -0
  99. esphome/components/const/__init__.py +1 -0
  100. esphome/components/cover/__init__.py +1 -0
  101. esphome/components/cs5460a/cs5460a.cpp +16 -11
  102. esphome/components/cse7761/cse7761.cpp +2 -2
  103. esphome/components/cse7766/cse7766.cpp +0 -5
  104. esphome/components/cse7766/cse7766.h +5 -1
  105. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +1 -1
  106. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +6 -3
  107. esphome/components/current_based/current_based_cover.cpp +4 -2
  108. esphome/components/dac7678/dac7678_output.cpp +4 -4
  109. esphome/components/dallas_temp/dallas_temp.cpp +2 -3
  110. esphome/components/daly_bms/daly_bms.cpp +2 -1
  111. esphome/components/dashboard_import/__init__.py +1 -2
  112. esphome/components/datetime/__init__.py +3 -1
  113. esphome/components/debug/debug_component.cpp +1 -1
  114. esphome/components/debug/debug_component.h +1 -1
  115. esphome/components/debug/debug_esp32.cpp +4 -2
  116. esphome/components/deep_sleep/deep_sleep_component.cpp +11 -5
  117. esphome/components/deep_sleep/deep_sleep_esp32.cpp +7 -5
  118. esphome/components/demo/__init__.py +206 -0
  119. esphome/components/demo/demo_alarm_control_panel.h +65 -0
  120. esphome/components/demo/demo_button.h +15 -0
  121. esphome/components/demo/demo_date.h +34 -0
  122. esphome/components/demo/demo_datetime.h +40 -0
  123. esphome/components/demo/demo_lock.h +17 -0
  124. esphome/components/demo/demo_select.h +15 -0
  125. esphome/components/demo/demo_text.h +18 -0
  126. esphome/components/demo/demo_time.h +34 -0
  127. esphome/components/demo/demo_valve.h +54 -0
  128. esphome/components/dfrobot_sen0395/commands.cpp +3 -3
  129. esphome/components/dht/dht.cpp +29 -50
  130. esphome/components/dht12/dht12.cpp +2 -2
  131. esphome/components/display/display.h +5 -3
  132. esphome/components/dps310/dps310.cpp +7 -5
  133. esphome/components/ds1307/ds1307.cpp +2 -2
  134. esphome/components/dsmr/dsmr.cpp +5 -3
  135. esphome/components/duty_cycle/duty_cycle_sensor.cpp +2 -2
  136. esphome/components/duty_time/duty_time_sensor.cpp +5 -3
  137. esphome/components/ee895/ee895.cpp +3 -3
  138. esphome/components/ektf2232/touchscreen/ektf2232.cpp +1 -1
  139. esphome/components/emc2101/emc2101.cpp +11 -9
  140. esphome/components/ens160_base/ens160_base.cpp +2 -2
  141. esphome/components/ens210/ens210.cpp +2 -2
  142. esphome/components/es7210/es7210.cpp +6 -4
  143. esphome/components/es7243e/es7243e.cpp +1 -1
  144. esphome/components/es8156/es8156.cpp +1 -1
  145. esphome/components/es8311/es8311.cpp +8 -6
  146. esphome/components/es8388/__init__.py +0 -0
  147. esphome/components/es8388/audio_dac.py +26 -0
  148. esphome/components/es8388/es8388.cpp +289 -0
  149. esphome/components/es8388/es8388.h +81 -0
  150. esphome/components/es8388/es8388_const.h +83 -0
  151. esphome/components/es8388/select/__init__.py +47 -0
  152. esphome/components/es8388/select/adc_input_mic_select.cpp +12 -0
  153. esphome/components/es8388/select/adc_input_mic_select.h +15 -0
  154. esphome/components/es8388/select/dac_output_select.cpp +12 -0
  155. esphome/components/es8388/select/dac_output_select.h +15 -0
  156. esphome/components/esp32/__init__.py +88 -20
  157. esphome/components/esp32/boards.py +208 -125
  158. esphome/components/esp32/const.py +6 -0
  159. esphome/components/esp32/gpio.py +14 -1
  160. esphome/components/esp32/gpio_esp32_c5.py +45 -0
  161. esphome/components/esp32/gpio_esp32_p4.py +43 -0
  162. esphome/components/esp32/preferences.cpp +7 -7
  163. esphome/components/esp32_ble/__init__.py +115 -0
  164. esphome/components/esp32_ble/ble.cpp +11 -9
  165. esphome/components/esp32_ble/ble_uuid.h +1 -1
  166. esphome/components/esp32_ble_client/ble_client_base.cpp +4 -2
  167. esphome/components/esp32_ble_server/__init__.py +4 -1
  168. esphome/components/esp32_ble_server/ble_characteristic.cpp +1 -0
  169. esphome/components/esp32_ble_server/ble_server.h +0 -1
  170. esphome/components/esp32_ble_tracker/__init__.py +6 -2
  171. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +12 -9
  172. esphome/components/esp32_camera/esp32_camera.cpp +35 -27
  173. esphome/components/esp32_camera_web_server/camera_web_server.cpp +4 -2
  174. esphome/components/esp32_dac/esp32_dac.cpp +2 -2
  175. esphome/components/esp32_improv/__init__.py +5 -1
  176. esphome/components/esp32_improv/esp32_improv_component.cpp +2 -2
  177. esphome/components/esp32_rmt_led_strip/led_strip.cpp +11 -7
  178. esphome/components/esp32_rmt_led_strip/light.py +5 -1
  179. esphome/components/esp32_touch/esp32_touch.cpp +12 -8
  180. esphome/components/esp8266/preferences.cpp +6 -6
  181. esphome/components/esp8266_pwm/esp8266_pwm.cpp +3 -3
  182. esphome/components/esp_ldo/__init__.py +91 -0
  183. esphome/components/esp_ldo/esp_ldo.cpp +43 -0
  184. esphome/components/esp_ldo/esp_ldo.h +43 -0
  185. esphome/components/esphome/ota/ota_esphome.cpp +15 -8
  186. esphome/components/ethernet/ethernet_component.cpp +38 -26
  187. esphome/components/ethernet/ethernet_component.h +1 -1
  188. esphome/components/event/__init__.py +1 -0
  189. esphome/components/exposure_notifications/exposure_notifications.cpp +1 -1
  190. esphome/components/ezo/ezo.cpp +1 -1
  191. esphome/components/ezo_pmp/ezo_pmp.cpp +1 -1
  192. esphome/components/factory_reset/button/factory_reset_button.cpp +1 -1
  193. esphome/components/factory_reset/switch/factory_reset_switch.cpp +1 -1
  194. esphome/components/fan/__init__.py +1 -0
  195. esphome/components/fan/fan.cpp +4 -2
  196. esphome/components/fastled_base/fastled_light.cpp +7 -5
  197. esphome/components/fingerprint_grow/fingerprint_grow.cpp +8 -6
  198. esphome/components/fs3000/fs3000.cpp +1 -1
  199. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +7 -4
  200. esphome/components/ft63x6/ft63x6.cpp +5 -3
  201. esphome/components/gcja5/gcja5.cpp +0 -12
  202. esphome/components/gcja5/gcja5.h +8 -3
  203. esphome/components/gdk101/gdk101.cpp +2 -2
  204. esphome/components/globals/globals_component.h +13 -10
  205. esphome/components/gp2y1010au0f/gp2y1010au0f.cpp +4 -2
  206. esphome/components/gp8403/gp8403.cpp +4 -2
  207. esphome/components/gp8403/output/gp8403_output.cpp +4 -2
  208. esphome/components/gpio/one_wire/gpio_one_wire.cpp +2 -2
  209. esphome/components/gpio/output/gpio_binary_output.cpp +1 -1
  210. esphome/components/gpio/switch/gpio_switch.cpp +1 -1
  211. esphome/components/graphical_display_menu/graphical_display_menu.cpp +12 -8
  212. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -6
  213. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +1 -1
  214. esphome/components/grove_tb6612fng/grove_tb6612fng.h +1 -1
  215. esphome/components/growatt_solar/growatt_solar.cpp +6 -3
  216. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
  217. esphome/components/haier/haier_base.cpp +2 -2
  218. esphome/components/haier/hon_climate.cpp +13 -6
  219. esphome/components/havells_solar/havells_solar.cpp +5 -2
  220. esphome/components/hbridge/switch/hbridge_switch.cpp +1 -1
  221. esphome/components/hdc1080/hdc1080.cpp +2 -2
  222. esphome/components/he60r/he60r.cpp +4 -2
  223. esphome/components/hlw8012/hlw8012.cpp +6 -4
  224. esphome/components/hm3301/hm3301.cpp +2 -2
  225. esphome/components/hmc5883l/hmc5883l.cpp +2 -2
  226. esphome/components/homeassistant/time/homeassistant_time.cpp +4 -2
  227. esphome/components/honeywell_hih_i2c/honeywell_hih.cpp +4 -4
  228. esphome/components/honeywellabp/honeywellabp.cpp +4 -2
  229. esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +8 -6
  230. esphome/components/hte501/hte501.cpp +3 -2
  231. esphome/components/http_request/__init__.py +2 -2
  232. esphome/components/http_request/http_request.cpp +7 -5
  233. esphome/components/http_request/http_request_idf.cpp +4 -2
  234. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  235. esphome/components/htu21d/htu21d.cpp +2 -2
  236. esphome/components/htu31d/htu31d.cpp +2 -2
  237. esphome/components/hx711/hx711.cpp +2 -2
  238. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +5 -3
  239. esphome/components/hyt271/hyt271.cpp +2 -2
  240. esphome/components/i2c/i2c_bus_arduino.cpp +14 -11
  241. esphome/components/i2c/i2c_bus_esp_idf.cpp +13 -11
  242. esphome/components/i2s_audio/__init__.py +2 -0
  243. esphome/components/i2s_audio/i2s_audio.cpp +3 -4
  244. esphome/components/i2s_audio/i2s_audio.h +1 -1
  245. esphome/components/i2s_audio/media_player/__init__.py +1 -1
  246. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +5 -3
  247. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +1 -1
  248. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  249. esphome/components/iaqcore/iaqcore.cpp +3 -3
  250. esphome/components/ili9xxx/ili9xxx_display.cpp +12 -7
  251. esphome/components/ili9xxx/ili9xxx_display.h +1 -1
  252. esphome/components/image/image.cpp +1 -0
  253. esphome/components/ina219/ina219.cpp +2 -2
  254. esphome/components/ina226/ina226.cpp +8 -5
  255. esphome/components/ina260/ina260.cpp +1 -1
  256. esphome/components/ina2xx_base/ina2xx_base.cpp +13 -9
  257. esphome/components/ina3221/ina3221.cpp +2 -2
  258. esphome/components/inkplate6/display.py +12 -2
  259. esphome/components/inkplate6/inkplate.cpp +13 -9
  260. esphome/components/inkplate6/inkplate.h +7 -6
  261. esphome/components/integration/integration_sensor.cpp +1 -1
  262. esphome/components/internal_temperature/internal_temperature.cpp +4 -4
  263. esphome/components/json/json_util.cpp +4 -5
  264. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +1 -1
  265. esphome/components/key_collector/key_collector.cpp +4 -2
  266. esphome/components/kmeteriso/kmeteriso.cpp +2 -1
  267. esphome/components/kuntze/kuntze.cpp +4 -2
  268. esphome/components/lc709203f/__init__.py +1 -0
  269. esphome/components/lc709203f/lc709203f.cpp +299 -0
  270. esphome/components/lc709203f/lc709203f.h +55 -0
  271. esphome/components/lc709203f/sensor.py +93 -0
  272. esphome/components/lcd_base/lcd_display.cpp +2 -2
  273. esphome/components/lcd_gpio/gpio_lcd_display.cpp +5 -3
  274. esphome/components/lcd_menu/lcd_menu.cpp +6 -4
  275. esphome/components/lcd_pcf8574/pcf8574_display.cpp +6 -4
  276. esphome/components/ld2410/ld2410.cpp +6 -7
  277. esphome/components/ld2420/ld2420.cpp +9 -7
  278. esphome/components/ld2450/ld2450.cpp +6 -4
  279. esphome/components/ld2450/sensor.py +2 -2
  280. esphome/components/ledc/ledc_output.cpp +32 -28
  281. esphome/components/libretiny/const.py +1 -1
  282. esphome/components/libretiny/preferences.cpp +6 -7
  283. esphome/components/light/__init__.py +2 -1
  284. esphome/components/light/esp_hsv_color.h +1 -1
  285. esphome/components/light/light_state.cpp +9 -5
  286. esphome/components/light/light_transformer.h +1 -1
  287. esphome/components/lightwaverf/LwTx.cpp +1 -1
  288. esphome/components/lightwaverf/lightwaverf.cpp +1 -1
  289. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +1 -1
  290. esphome/components/lock/__init__.py +1 -0
  291. esphome/components/lock/lock.h +1 -1
  292. esphome/components/logger/__init__.py +6 -0
  293. esphome/components/logger/logger.cpp +9 -5
  294. esphome/components/logger/logger_esp32.cpp +5 -5
  295. esphome/components/ltr390/ltr390.cpp +8 -5
  296. esphome/components/ltr501/ltr501.cpp +19 -14
  297. esphome/components/ltr_als_ps/ltr_als_ps.cpp +20 -13
  298. esphome/components/lvgl/__init__.py +2 -2
  299. esphome/components/lvgl/automation.py +5 -4
  300. esphome/components/lvgl/defines.py +0 -2
  301. esphome/components/lvgl/lv_validation.py +1 -3
  302. esphome/components/lvgl/lvcode.py +7 -8
  303. esphome/components/lvgl/lvgl_esphome.cpp +26 -10
  304. esphome/components/lvgl/schemas.py +22 -23
  305. esphome/components/lvgl/trigger.py +8 -3
  306. esphome/components/lvgl/widgets/__init__.py +2 -2
  307. esphome/components/lvgl/widgets/canvas.py +9 -3
  308. esphome/components/lvgl/widgets/line.py +2 -1
  309. esphome/components/lvgl/widgets/tabview.py +7 -0
  310. esphome/components/m5stack_8angle/m5stack_8angle.cpp +3 -3
  311. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -2
  312. esphome/components/max17043/max17043.cpp +2 -2
  313. esphome/components/max31855/max31855.cpp +2 -1
  314. esphome/components/max31856/max31856.cpp +9 -11
  315. esphome/components/max31865/max31865.cpp +6 -4
  316. esphome/components/max44009/max44009.cpp +2 -2
  317. esphome/components/max6675/max6675.cpp +1 -1
  318. esphome/components/max6956/max6956.cpp +5 -3
  319. esphome/components/max7219/max7219.cpp +8 -6
  320. esphome/components/max7219digit/automation.h +52 -0
  321. esphome/components/max7219digit/display.py +93 -1
  322. esphome/components/max7219digit/max7219digit.cpp +16 -13
  323. esphome/components/max9611/max9611.cpp +9 -6
  324. esphome/components/mcp23008/mcp23008.cpp +1 -1
  325. esphome/components/mcp23016/mcp23016.cpp +1 -1
  326. esphome/components/mcp23017/mcp23017.cpp +1 -1
  327. esphome/components/mcp23s08/mcp23s08.cpp +1 -1
  328. esphome/components/mcp23s17/mcp23s17.cpp +1 -1
  329. esphome/components/mcp3008/mcp3008.cpp +1 -1
  330. esphome/components/mcp3008/sensor/mcp3008_sensor.cpp +5 -3
  331. esphome/components/mcp3204/mcp3204.cpp +1 -1
  332. esphome/components/mcp4461/mcp4461.cpp +2 -2
  333. esphome/components/mcp4725/mcp4725.cpp +2 -2
  334. esphome/components/mcp4728/mcp4728.cpp +2 -2
  335. esphome/components/mcp9600/mcp9600.cpp +1 -1
  336. esphome/components/mcp9808/mcp9808.cpp +4 -4
  337. esphome/components/mdns/mdns_component.cpp +8 -2
  338. esphome/components/mdns/mdns_component.h +3 -1
  339. esphome/components/mdns/mdns_esp32.cpp +2 -2
  340. esphome/components/media_player/__init__.py +1 -0
  341. esphome/components/micro_wake_word/micro_wake_word.cpp +1 -1
  342. esphome/components/micro_wake_word/streaming_model.cpp +10 -6
  343. esphome/components/micronova/micronova.h +2 -2
  344. esphome/components/mics_4514/mics_4514.cpp +2 -2
  345. esphome/components/midea/air_conditioner.cpp +7 -5
  346. esphome/components/midea_ir/midea_ir.cpp +1 -1
  347. esphome/components/mipi_spi/mipi_spi.cpp +24 -15
  348. esphome/components/mixer/speaker/mixer_speaker.cpp +8 -4
  349. esphome/components/mlx90393/sensor_mlx90393.cpp +2 -2
  350. esphome/components/mlx90614/mlx90614.cpp +4 -3
  351. esphome/components/mmc5603/mmc5603.cpp +2 -2
  352. esphome/components/mmc5983/mmc5983.cpp +1 -1
  353. esphome/components/modbus/modbus.cpp +7 -5
  354. esphome/components/modbus_controller/modbus_controller.cpp +6 -4
  355. esphome/components/modbus_controller/output/modbus_output.cpp +10 -6
  356. esphome/components/modbus_controller/switch/__init__.py +6 -2
  357. esphome/components/modbus_controller/switch/modbus_switch.cpp +4 -0
  358. esphome/components/modbus_controller/switch/modbus_switch.h +3 -0
  359. esphome/components/mpl3115a2/mpl3115a2.cpp +3 -2
  360. esphome/components/mpr121/mpr121.cpp +2 -2
  361. esphome/components/mpu6050/mpu6050.cpp +6 -6
  362. esphome/components/mpu6886/mpu6886.cpp +6 -6
  363. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +7 -3
  364. esphome/components/mqtt/mqtt_backend_esp32.cpp +1 -1
  365. esphome/components/mqtt/mqtt_client.cpp +31 -24
  366. esphome/components/mqtt/mqtt_component.cpp +2 -2
  367. esphome/components/mqtt/mqtt_cover.cpp +8 -4
  368. esphome/components/mqtt/mqtt_fan.cpp +12 -6
  369. esphome/components/mqtt/mqtt_valve.cpp +4 -2
  370. esphome/components/ms5611/ms5611.cpp +2 -2
  371. esphome/components/ms8607/ms8607.cpp +2 -2
  372. esphome/components/msa3xx/msa3xx.cpp +16 -12
  373. esphome/components/my9231/my9231.cpp +7 -5
  374. esphome/components/nau7802/nau7802.cpp +6 -4
  375. esphome/components/neopixelbus/neopixelbus_light.h +2 -2
  376. esphome/components/network/ip_address.h +1 -1
  377. esphome/components/network/util.cpp +13 -0
  378. esphome/components/nextion/base_component.py +2 -0
  379. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +2 -3
  380. esphome/components/nextion/display.py +34 -22
  381. esphome/components/nextion/nextion.cpp +182 -143
  382. esphome/components/nextion/nextion.h +36 -0
  383. esphome/components/nextion/nextion_commands.cpp +3 -3
  384. esphome/components/nextion/nextion_upload_arduino.cpp +58 -61
  385. esphome/components/nextion/nextion_upload_idf.cpp +69 -72
  386. esphome/components/nextion/sensor/nextion_sensor.cpp +4 -4
  387. esphome/components/nextion/switch/nextion_switch.cpp +2 -2
  388. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +2 -2
  389. esphome/components/nfc/nci_message.h +1 -1
  390. esphome/components/nfc/ndef_record.h +1 -1
  391. esphome/components/nfc/ndef_record_text.h +1 -1
  392. esphome/components/nfc/ndef_record_uri.h +1 -1
  393. esphome/components/nfc/nfc.h +1 -1
  394. esphome/components/nfc/nfc_tag.h +1 -1
  395. esphome/components/noblex/noblex.cpp +1 -1
  396. esphome/components/npi19/npi19.cpp +5 -7
  397. esphome/components/number/__init__.py +11 -0
  398. esphome/components/online_image/__init__.py +13 -1
  399. esphome/components/online_image/online_image.cpp +26 -4
  400. esphome/components/online_image/online_image.h +21 -4
  401. esphome/components/opentherm/generate.py +3 -3
  402. esphome/components/opentherm/hub.cpp +11 -7
  403. esphome/components/opentherm/number/number.cpp +5 -3
  404. esphome/components/opentherm/opentherm.h +1 -1
  405. esphome/components/opentherm/schema.py +13 -13
  406. esphome/components/opentherm/validate.py +1 -1
  407. esphome/components/openthread/__init__.py +146 -0
  408. esphome/components/openthread/const.py +10 -0
  409. esphome/components/openthread/openthread.cpp +206 -0
  410. esphome/components/openthread/openthread.h +68 -0
  411. esphome/components/openthread/openthread_esp.cpp +164 -0
  412. esphome/components/openthread/tlv.py +58 -0
  413. esphome/components/openthread_info/__init__.py +0 -0
  414. esphome/components/openthread_info/openthread_info_text_sensor.cpp +24 -0
  415. esphome/components/openthread_info/openthread_info_text_sensor.h +218 -0
  416. esphome/components/openthread_info/text_sensor.py +105 -0
  417. esphome/components/output/float_output.cpp +1 -1
  418. esphome/components/output/switch/output_switch.cpp +1 -1
  419. esphome/components/packet_transport/packet_transport.cpp +6 -4
  420. esphome/components/pca6416a/pca6416a.cpp +2 -2
  421. esphome/components/pca9554/pca9554.cpp +6 -4
  422. esphome/components/pca9685/pca9685_output.cpp +12 -8
  423. esphome/components/pcd8544/pcd_8544.cpp +1 -1
  424. esphome/components/pcf85063/pcf85063.cpp +2 -2
  425. esphome/components/pcf8563/pcf8563.cpp +2 -2
  426. esphome/components/pcf8574/pcf8574.cpp +2 -2
  427. esphome/components/pid/pid_climate.cpp +8 -5
  428. esphome/components/pid/pid_climate.h +1 -1
  429. esphome/components/pid/sensor/pid_climate_sensor.cpp +1 -1
  430. esphome/components/pipsolar/output/pipsolar_output.cpp +1 -1
  431. esphome/components/pipsolar/pipsolar.cpp +3 -3
  432. esphome/components/pm1006/pm1006.cpp +3 -7
  433. esphome/components/pm1006/pm1006.h +4 -1
  434. esphome/components/pm2005/pm2005.cpp +12 -13
  435. esphome/components/pm2005/sensor.py +1 -1
  436. esphome/components/pmsa003i/pmsa003i.cpp +2 -2
  437. esphome/components/pmsx003/pmsx003.cpp +0 -4
  438. esphome/components/pmsx003/pmsx003.h +5 -2
  439. esphome/components/pmwcs3/pmwcs3.cpp +9 -13
  440. esphome/components/pmwcs3/pmwcs3.h +0 -1
  441. esphome/components/pn532/pn532.cpp +7 -7
  442. esphome/components/pn532/pn532.h +1 -1
  443. esphome/components/pn532_spi/pn532_spi.cpp +1 -1
  444. esphome/components/pn7150/pn7150.cpp +4 -4
  445. esphome/components/pn7160/pn7160.cpp +4 -4
  446. esphome/components/power_supply/power_supply.cpp +6 -4
  447. esphome/components/power_supply/power_supply.h +1 -1
  448. esphome/components/psram/__init__.py +59 -35
  449. esphome/components/pulse_counter/pulse_counter_sensor.cpp +7 -4
  450. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +8 -5
  451. esphome/components/pylontech/pylontech.cpp +2 -2
  452. esphome/components/pylontech/sensor/pylontech_sensor.cpp +4 -2
  453. esphome/components/pylontech/text_sensor/pylontech_text_sensor.cpp +4 -2
  454. esphome/components/pzemac/pzemac.cpp +4 -2
  455. esphome/components/pzemdc/pzemdc.cpp +4 -2
  456. esphome/components/qmc5883l/qmc5883l.cpp +2 -2
  457. esphome/components/qmp6988/qmp6988.cpp +2 -2
  458. esphome/components/qmp6988/qmp6988.h +1 -1
  459. esphome/components/qr_code/qr_code.cpp +5 -3
  460. esphome/components/qspi_dbi/qspi_dbi.cpp +1 -1
  461. esphome/components/qwiic_pir/qwiic_pir.cpp +26 -28
  462. esphome/components/rc522/rc522.cpp +5 -5
  463. esphome/components/rdm6300/rdm6300.cpp +1 -0
  464. esphome/components/remote_receiver/__init__.py +10 -2
  465. esphome/components/remote_receiver/remote_receiver_esp32.cpp +22 -12
  466. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +10 -7
  467. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +10 -7
  468. esphome/components/remote_transmitter/__init__.py +10 -2
  469. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +10 -6
  470. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +5 -3
  471. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +5 -3
  472. esphome/components/resistance/resistance_sensor.cpp +6 -3
  473. esphome/components/restart/button/restart_button.cpp +1 -1
  474. esphome/components/restart/switch/restart_switch.cpp +1 -1
  475. esphome/components/rotary_encoder/rotary_encoder.cpp +2 -2
  476. esphome/components/rp2040/__init__.py +7 -0
  477. esphome/components/rp2040/core.cpp +8 -1
  478. esphome/components/rp2040/preferences.cpp +3 -3
  479. esphome/components/rp2040_pio_led_strip/led_strip.cpp +11 -8
  480. esphome/components/rp2040_pio_led_strip/light.py +1 -1
  481. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -1
  482. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +1 -1
  483. esphome/components/rtttl/rtttl.cpp +11 -9
  484. esphome/components/safe_mode/button/safe_mode_button.cpp +1 -1
  485. esphome/components/safe_mode/safe_mode.cpp +9 -8
  486. esphome/components/safe_mode/switch/safe_mode_switch.cpp +1 -1
  487. esphome/components/scd30/scd30.cpp +11 -8
  488. esphome/components/scd4x/scd4x.cpp +12 -8
  489. esphome/components/sdl/display.py +40 -0
  490. esphome/components/sdl/sdl_esphome.cpp +2 -2
  491. esphome/components/sdl/sdl_esphome.h +8 -0
  492. esphome/components/sdm_meter/sdm_meter.cpp +5 -2
  493. esphome/components/sdp3x/sdp3x.cpp +11 -11
  494. esphome/components/sds011/sds011.cpp +5 -6
  495. esphome/components/sds011/sds011.h +4 -1
  496. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +3 -2
  497. esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +1 -0
  498. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +3 -2
  499. esphome/components/selec_meter/selec_meter.cpp +5 -2
  500. esphome/components/select/__init__.py +1 -0
  501. esphome/components/sen0321/sen0321.cpp +2 -2
  502. esphome/components/sen21231/sen21231.cpp +1 -1
  503. esphome/components/sen5x/sen5x.cpp +10 -7
  504. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  505. esphome/components/sensirion_common/i2c_sensirion.h +1 -0
  506. esphome/components/sensor/__init__.py +11 -1
  507. esphome/components/sensor/filter.h +1 -1
  508. esphome/components/sensor/sensor.h +9 -5
  509. esphome/components/servo/servo.cpp +12 -9
  510. esphome/components/servo/servo.h +1 -1
  511. esphome/components/sfa30/sfa30.cpp +1 -1
  512. esphome/components/sgp30/sgp30.cpp +10 -8
  513. esphome/components/sgp4x/sgp4x.cpp +49 -61
  514. esphome/components/sgp4x/sgp4x.h +0 -1
  515. esphome/components/shelly_dimmer/shelly_dimmer.cpp +11 -7
  516. esphome/components/sht3xd/sht3xd.cpp +1 -1
  517. esphome/components/sht4x/sht4x.cpp +2 -2
  518. esphome/components/shtcx/shtcx.cpp +13 -16
  519. esphome/components/shutdown/button/shutdown_button.cpp +1 -1
  520. esphome/components/shutdown/switch/shutdown_switch.cpp +1 -1
  521. esphome/components/sim800l/sim800l.cpp +2 -2
  522. esphome/components/slow_pwm/slow_pwm_output.cpp +4 -2
  523. esphome/components/sm16716/sm16716.cpp +1 -1
  524. esphome/components/sm2135/sm2135.cpp +1 -1
  525. esphome/components/sm2235/sm2235.cpp +5 -3
  526. esphome/components/sm2335/sm2335.cpp +5 -3
  527. esphome/components/sml/sml.cpp +1 -1
  528. esphome/components/sn74hc165/sn74hc165.cpp +1 -2
  529. esphome/components/sn74hc595/sn74hc595.cpp +1 -2
  530. esphome/components/sntp/sntp_component.cpp +1 -1
  531. esphome/components/socket/__init__.py +2 -0
  532. esphome/components/socket/bsd_sockets_impl.cpp +51 -7
  533. esphome/components/socket/lwip_raw_tcp_impl.cpp +5 -0
  534. esphome/components/socket/lwip_sockets_impl.cpp +51 -7
  535. esphome/components/socket/socket.cpp +31 -0
  536. esphome/components/socket/socket.h +27 -1
  537. esphome/components/sonoff_d1/sonoff_d1.cpp +7 -4
  538. esphome/components/sonoff_d1/sonoff_d1.h +2 -2
  539. esphome/components/sound_level/sound_level.cpp +4 -2
  540. esphome/components/speaker/media_player/__init__.py +3 -0
  541. esphome/components/speaker/media_player/speaker_media_player.cpp +1 -3
  542. esphome/components/speaker/media_player/speaker_media_player.h +6 -0
  543. esphome/components/spi/__init__.py +10 -2
  544. esphome/components/spi/spi.cpp +4 -4
  545. esphome/components/spi_device/spi_device.cpp +1 -2
  546. esphome/components/sprinkler/sprinkler.cpp +9 -6
  547. esphome/components/sps30/sps30.cpp +16 -15
  548. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  549. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +11 -8
  550. esphome/components/ssd1306_spi/ssd1306_spi.cpp +10 -7
  551. esphome/components/ssd1322_base/ssd1322_base.cpp +1 -1
  552. esphome/components/ssd1322_spi/ssd1322_spi.cpp +1 -1
  553. esphome/components/ssd1325_base/ssd1325_base.cpp +1 -1
  554. esphome/components/ssd1325_spi/ssd1325_spi.cpp +1 -1
  555. esphome/components/ssd1327_base/ssd1327_base.cpp +1 -1
  556. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +2 -2
  557. esphome/components/ssd1327_spi/ssd1327_spi.cpp +1 -1
  558. esphome/components/ssd1331_base/ssd1331_base.cpp +1 -1
  559. esphome/components/ssd1331_spi/ssd1331_spi.cpp +1 -1
  560. esphome/components/ssd1351_base/ssd1351_base.cpp +1 -1
  561. esphome/components/ssd1351_spi/ssd1351_spi.cpp +1 -1
  562. esphome/components/st7567_base/st7567_base.cpp +3 -3
  563. esphome/components/st7567_i2c/st7567_i2c.cpp +7 -5
  564. esphome/components/st7567_spi/st7567_spi.cpp +1 -1
  565. esphome/components/st7701s/st7701s.cpp +4 -2
  566. esphome/components/st7735/st7735.cpp +3 -3
  567. esphome/components/st7789v/st7789v.cpp +10 -7
  568. esphome/components/st7920/st7920.cpp +6 -4
  569. esphome/components/statsd/statsd.cpp +9 -5
  570. esphome/components/status_led/light/status_led_light.cpp +1 -1
  571. esphome/components/status_led/status_led.cpp +1 -1
  572. esphome/components/stepper/stepper.h +5 -3
  573. esphome/components/sts3x/sts3x.cpp +2 -2
  574. esphome/components/switch/__init__.py +1 -0
  575. esphome/components/switch/switch.cpp +18 -12
  576. esphome/components/switch/switch.h +1 -1
  577. esphome/components/sx1509/__init__.py +53 -20
  578. esphome/components/sx1509/sx1509.cpp +29 -5
  579. esphome/components/sx1509/sx1509.h +9 -1
  580. esphome/components/t6615/t6615.cpp +1 -0
  581. esphome/components/tc74/tc74.cpp +1 -1
  582. esphome/components/tca9548a/tca9548a.cpp +1 -1
  583. esphome/components/tca9555/tca9555.cpp +2 -2
  584. esphome/components/tcs34725/tcs34725.cpp +4 -4
  585. esphome/components/tee501/tee501.cpp +3 -2
  586. esphome/components/tem3200/tem3200.cpp +5 -6
  587. esphome/components/template/alarm_control_panel/__init__.py +6 -0
  588. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +38 -12
  589. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +3 -1
  590. esphome/components/template/cover/template_cover.cpp +1 -1
  591. esphome/components/template/select/template_select.cpp +6 -4
  592. esphome/components/template/text/template_text.cpp +2 -3
  593. esphome/components/template/valve/template_valve.cpp +5 -3
  594. esphome/components/text/__init__.py +10 -11
  595. esphome/components/text_sensor/__init__.py +1 -0
  596. esphome/components/thermostat/thermostat_climate.cpp +67 -43
  597. esphome/components/time/__init__.py +1 -2
  598. esphome/components/time_based/time_based_cover.cpp +4 -2
  599. esphome/components/tlc59208f/tlc59208f_output.cpp +8 -6
  600. esphome/components/tm1621/tm1621.cpp +3 -3
  601. esphome/components/tm1637/tm1637.cpp +9 -7
  602. esphome/components/tm1638/tm1638.cpp +7 -5
  603. esphome/components/tm1651/tm1651.cpp +2 -2
  604. esphome/components/tmp102/tmp102.cpp +1 -3
  605. esphome/components/tmp102/tmp102.h +0 -3
  606. esphome/components/tmp1075/tmp1075.cpp +12 -9
  607. esphome/components/tmp117/tmp117.cpp +2 -2
  608. esphome/components/tof10120/tof10120_sensor.cpp +2 -2
  609. esphome/components/tormatic/tormatic_cover.cpp +4 -2
  610. esphome/components/tsl2561/tsl2561.cpp +7 -5
  611. esphome/components/tsl2591/tsl2591.cpp +25 -27
  612. esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
  613. esphome/components/ttp229_bsf/ttp229_bsf.cpp +1 -1
  614. esphome/components/ttp229_lsf/ttp229_lsf.cpp +2 -2
  615. esphome/components/tuya/select/tuya_select.cpp +5 -3
  616. esphome/components/tx20/tx20.cpp +3 -3
  617. esphome/components/uart/__init__.py +4 -5
  618. esphome/components/uart/button/uart_button.cpp +1 -1
  619. esphome/components/uart/switch/uart_switch.cpp +2 -2
  620. esphome/components/uart/uart.cpp +2 -2
  621. esphome/components/uart/uart_component_esp32_arduino.cpp +8 -6
  622. esphome/components/uart/uart_component_esp8266.cpp +9 -7
  623. esphome/components/uart/uart_component_esp_idf.cpp +9 -7
  624. esphome/components/uart/uart_component_host.cpp +11 -8
  625. esphome/components/uart/uart_component_libretiny.cpp +8 -6
  626. esphome/components/uart/uart_component_rp2040.cpp +8 -6
  627. esphome/components/udp/udp_component.cpp +9 -5
  628. esphome/components/ufire_ec/ufire_ec.cpp +5 -3
  629. esphome/components/ufire_ise/ufire_ise.cpp +1 -1
  630. esphome/components/ultrasonic/ultrasonic_sensor.cpp +5 -3
  631. esphome/components/update/__init__.py +1 -0
  632. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  633. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +4 -2
  634. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  635. esphome/components/usb_host/__init__.py +64 -0
  636. esphome/components/usb_host/usb_host.h +116 -0
  637. esphome/components/usb_host/usb_host_client.cpp +394 -0
  638. esphome/components/usb_host/usb_host_component.cpp +35 -0
  639. esphome/components/usb_uart/__init__.py +134 -0
  640. esphome/components/usb_uart/ch34x.cpp +80 -0
  641. esphome/components/usb_uart/cp210x.cpp +126 -0
  642. esphome/components/usb_uart/usb_uart.cpp +328 -0
  643. esphome/components/usb_uart/usb_uart.h +151 -0
  644. esphome/components/valve/__init__.py +1 -0
  645. esphome/components/veml3235/veml3235.cpp +13 -9
  646. esphome/components/veml7700/veml7700.cpp +10 -6
  647. esphome/components/voice_assistant/voice_assistant.cpp +7 -7
  648. esphome/components/wake_on_lan/wake_on_lan.cpp +1 -1
  649. esphome/components/waveshare_epaper/waveshare_epaper.cpp +1 -1
  650. esphome/components/web_server/server_index_v2.h +632 -630
  651. esphome/components/web_server/server_index_v3.h +411 -409
  652. esphome/components/web_server/web_server.cpp +5 -3
  653. esphome/components/web_server_base/web_server_base.cpp +1 -1
  654. esphome/components/web_server_idf/utils.cpp +1 -1
  655. esphome/components/web_server_idf/web_server_idf.cpp +1 -1
  656. esphome/components/weikai/__init__.py +2 -0
  657. esphome/components/weikai/weikai.cpp +23 -21
  658. esphome/components/weikai_i2c/weikai_i2c.cpp +14 -9
  659. esphome/components/weikai_spi/weikai_spi.cpp +11 -6
  660. esphome/components/wiegand/wiegand.cpp +1 -1
  661. esphome/components/wifi/wifi_component.cpp +50 -37
  662. esphome/components/wifi/wifi_component.h +7 -4
  663. esphome/components/wifi/wifi_component_esp32_arduino.cpp +2 -2
  664. esphome/components/wifi/wifi_component_esp8266.cpp +3 -3
  665. esphome/components/wifi/wifi_component_libretiny.cpp +4 -4
  666. esphome/components/wireguard/wireguard.cpp +21 -21
  667. esphome/components/wl_134/text_sensor.py +1 -2
  668. esphome/components/wled/wled_light_effect.cpp +1 -1
  669. esphome/components/x9c/x9c.cpp +5 -3
  670. esphome/components/xgzp68xx/xgzp68xx.cpp +8 -6
  671. esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp +4 -2
  672. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.cpp +4 -2
  673. esphome/components/xiaomi_cgg1/xiaomi_cgg1.cpp +4 -2
  674. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.cpp +1 -1
  675. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp +4 -2
  676. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp +4 -2
  677. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.cpp +4 -2
  678. esphome/components/xl9535/xl9535.cpp +2 -2
  679. esphome/components/xpt2046/touchscreen/xpt2046.cpp +12 -11
  680. esphome/components/xpt2046/touchscreen/xpt2046.h +2 -2
  681. esphome/config.py +3 -2
  682. esphome/config_validation.py +46 -17
  683. esphome/const.py +10 -1
  684. esphome/core/__init__.py +37 -18
  685. esphome/core/application.cpp +188 -5
  686. esphome/core/application.h +110 -0
  687. esphome/core/component.h +13 -0
  688. esphome/core/config.py +12 -0
  689. esphome/core/defines.h +10 -2
  690. esphome/core/helpers.cpp +1 -1
  691. esphome/core/helpers.h +4 -4
  692. esphome/core/log.h +2 -0
  693. esphome/core/log_const_en.h +4 -0
  694. esphome/core/scheduler.cpp +2 -2
  695. esphome/coroutine.py +3 -4
  696. esphome/cpp_generator.py +32 -32
  697. esphome/dashboard/core.py +2 -2
  698. esphome/dashboard/web_server.py +2 -2
  699. esphome/git.py +4 -4
  700. esphome/helpers.py +5 -6
  701. esphome/loader.py +8 -7
  702. esphome/log.py +7 -1
  703. esphome/platformio_api.py +2 -3
  704. esphome/storage_json.py +13 -5
  705. esphome/types.py +12 -13
  706. esphome/util.py +1 -2
  707. esphome/writer.py +5 -3
  708. esphome/yaml_util.py +6 -1
  709. esphome/zeroconf.py +1 -1
  710. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/METADATA +12 -11
  711. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/RECORD +715 -662
  712. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/WHEEL +1 -1
  713. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/entry_points.txt +0 -0
  714. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/licenses/LICENSE +0 -0
  715. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/top_level.txt +0 -0
esphome/core/__init__.py CHANGED
@@ -1,8 +1,9 @@
1
+ from collections import defaultdict
1
2
  import logging
2
3
  import math
3
4
  import os
4
5
  import re
5
- from typing import TYPE_CHECKING, Optional, Union
6
+ from typing import TYPE_CHECKING
6
7
 
7
8
  from esphome.const import (
8
9
  CONF_COMMENT,
@@ -326,7 +327,7 @@ class ID:
326
327
  else:
327
328
  self.is_manual = is_manual
328
329
  self.is_declaration = is_declaration
329
- self.type: Optional[MockObjClass] = type
330
+ self.type: MockObjClass | None = type
330
331
 
331
332
  def resolve(self, registered_ids):
332
333
  from esphome.config_validation import RESERVED_IDS
@@ -476,20 +477,20 @@ class EsphomeCore:
476
477
  # True if command is run from vscode api
477
478
  self.vscode = False
478
479
  # The name of the node
479
- self.name: Optional[str] = None
480
+ self.name: str | None = None
480
481
  # The friendly name of the node
481
- self.friendly_name: Optional[str] = None
482
+ self.friendly_name: str | None = None
482
483
  # The area / zone of the node
483
- self.area: Optional[str] = None
484
+ self.area: str | None = None
484
485
  # Additional data components can store temporary data in
485
486
  # The first key to this dict should always be the integration name
486
487
  self.data = {}
487
488
  # The relative path to the configuration YAML
488
- self.config_path: Optional[str] = None
489
+ self.config_path: str | None = None
489
490
  # The relative path to where all build files are stored
490
- self.build_path: Optional[str] = None
491
+ self.build_path: str | None = None
491
492
  # The validated configuration, this is None until the config has been validated
492
- self.config: Optional[ConfigType] = None
493
+ self.config: ConfigType | None = None
493
494
  # The pending tasks in the task queue (mostly for C++ generation)
494
495
  # This is a priority queue (with heapq)
495
496
  # Each item is a tuple of form: (-priority, unique number, task)
@@ -509,11 +510,16 @@ class EsphomeCore:
509
510
  # A set of defines to set for the compile process in esphome/core/defines.h
510
511
  self.defines: set[Define] = set()
511
512
  # A map of all platformio options to apply
512
- self.platformio_options: dict[str, Union[str, list[str]]] = {}
513
+ self.platformio_options: dict[str, str | list[str]] = {}
513
514
  # A set of strings of names of loaded integrations, used to find namespace ID conflicts
514
515
  self.loaded_integrations = set()
516
+ # A set of strings for platform/integration combos
517
+ self.loaded_platforms: set[str] = set()
515
518
  # A set of component IDs to track what Component subclasses are declared
516
519
  self.component_ids = set()
520
+ # Dict to track platform entity counts for pre-allocation
521
+ # Key: platform name (e.g. "sensor", "binary_sensor"), Value: count
522
+ self.platform_counts: defaultdict[str, int] = defaultdict(int)
517
523
  # Whether ESPHome was started in verbose mode
518
524
  self.verbose = False
519
525
  # Whether ESPHome was started in quiet mode
@@ -543,10 +549,11 @@ class EsphomeCore:
543
549
  self.platformio_options = {}
544
550
  self.loaded_integrations = set()
545
551
  self.component_ids = set()
552
+ self.platform_counts = defaultdict(int)
546
553
  PIN_SCHEMA_REGISTRY.reset()
547
554
 
548
555
  @property
549
- def address(self) -> Optional[str]:
556
+ def address(self) -> str | None:
550
557
  if self.config is None:
551
558
  raise ValueError("Config has not been loaded yet")
552
559
 
@@ -559,7 +566,7 @@ class EsphomeCore:
559
566
  return None
560
567
 
561
568
  @property
562
- def web_port(self) -> Optional[int]:
569
+ def web_port(self) -> int | None:
563
570
  if self.config is None:
564
571
  raise ValueError("Config has not been loaded yet")
565
572
 
@@ -572,7 +579,7 @@ class EsphomeCore:
572
579
  return None
573
580
 
574
581
  @property
575
- def comment(self) -> Optional[str]:
582
+ def comment(self) -> str | None:
576
583
  if self.config is None:
577
584
  raise ValueError("Config has not been loaded yet")
578
585
 
@@ -667,16 +674,17 @@ class EsphomeCore:
667
674
  def using_esp_idf(self):
668
675
  return self.target_framework == "esp-idf"
669
676
 
670
- def add_job(self, func, *args, **kwargs):
677
+ def add_job(self, func, *args, **kwargs) -> None:
671
678
  self.event_loop.add_job(func, *args, **kwargs)
672
679
 
673
- def flush_tasks(self):
680
+ def flush_tasks(self) -> None:
674
681
  try:
675
682
  self.event_loop.flush_tasks()
676
683
  except RuntimeError as e:
677
684
  raise EsphomeError(str(e)) from e
678
685
 
679
- def add(self, expression):
686
+ def add(self, expression, prepend=False) -> "Statement":
687
+ """Add an expression or statement to the main setup() block."""
680
688
  from esphome.cpp_generator import Expression, Statement, statement
681
689
 
682
690
  if isinstance(expression, Expression):
@@ -686,11 +694,14 @@ class EsphomeCore:
686
694
  f"Add '{expression}' must be expression or statement, not {type(expression)}"
687
695
  )
688
696
 
689
- self.main_statements.append(expression)
697
+ if prepend:
698
+ self.main_statements.insert(0, expression)
699
+ else:
700
+ self.main_statements.append(expression)
690
701
  _LOGGER.debug("Adding: %s", expression)
691
702
  return expression
692
703
 
693
- def add_global(self, expression, prepend=False):
704
+ def add_global(self, expression, prepend=False) -> "Statement":
694
705
  from esphome.cpp_generator import Expression, Statement, statement
695
706
 
696
707
  if isinstance(expression, Expression):
@@ -773,7 +784,7 @@ class EsphomeCore:
773
784
  _LOGGER.debug("Adding define: %s", define)
774
785
  return define
775
786
 
776
- def add_platformio_option(self, key: str, value: Union[str, list[str]]) -> None:
787
+ def add_platformio_option(self, key: str, value: str | list[str]) -> None:
777
788
  new_val = value
778
789
  old_val = self.platformio_options.get(key)
779
790
  if isinstance(old_val, list):
@@ -820,6 +831,14 @@ class EsphomeCore:
820
831
  def has_id(self, id):
821
832
  return id in self.variables
822
833
 
834
+ def register_platform_component(self, platform_name: str, var) -> None:
835
+ """Register a component for a platform and track its count.
836
+
837
+ :param platform_name: The name of the platform (e.g., 'sensor', 'binary_sensor')
838
+ :param var: The variable (component) being registered (currently unused but kept for future use)
839
+ """
840
+ self.platform_counts[platform_name] += 1
841
+
823
842
  @property
824
843
  def cpp_main_section(self):
825
844
  from esphome.cpp_generator import statement
@@ -2,11 +2,30 @@
2
2
  #include "esphome/core/log.h"
3
3
  #include "esphome/core/version.h"
4
4
  #include "esphome/core/hal.h"
5
+ #include <algorithm>
5
6
 
6
7
  #ifdef USE_STATUS_LED
7
8
  #include "esphome/components/status_led/status_led.h"
8
9
  #endif
9
10
 
11
+ #ifdef USE_SOCKET_SELECT_SUPPORT
12
+ #include <cerrno>
13
+
14
+ #ifdef USE_SOCKET_IMPL_LWIP_SOCKETS
15
+ // LWIP sockets implementation
16
+ #include <lwip/sockets.h>
17
+ #elif defined(USE_SOCKET_IMPL_BSD_SOCKETS)
18
+ // BSD sockets implementation
19
+ #ifdef USE_ESP32
20
+ // ESP32 "BSD sockets" are actually LWIP under the hood
21
+ #include <lwip/sockets.h>
22
+ #else
23
+ // True BSD sockets (e.g., host platform)
24
+ #include <sys/select.h>
25
+ #endif
26
+ #endif
27
+ #endif
28
+
10
29
  namespace esphome {
11
30
 
12
31
  static const char *const TAG = "app";
@@ -26,8 +45,8 @@ void Application::register_component_(Component *comp) {
26
45
  this->components_.push_back(comp);
27
46
  }
28
47
  void Application::setup() {
29
- ESP_LOGI(TAG, "Running through setup()...");
30
- ESP_LOGV(TAG, "Sorting components by setup priority...");
48
+ ESP_LOGI(TAG, "Running through setup()");
49
+ ESP_LOGV(TAG, "Sorting components by setup priority");
31
50
  std::stable_sort(this->components_.begin(), this->components_.end(), [](const Component *a, const Component *b) {
32
51
  return a->get_actual_setup_priority() > b->get_actual_setup_priority();
33
52
  });
@@ -106,7 +125,8 @@ void Application::loop() {
106
125
  // otherwise interval=0 schedules result in constant looping with almost no sleep
107
126
  next_schedule = std::max(next_schedule, delay_time / 2);
108
127
  delay_time = std::min(next_schedule, delay_time);
109
- delay(delay_time);
128
+
129
+ this->delay_with_select_(delay_time);
110
130
  }
111
131
  this->last_loop_ = last_op_end_time;
112
132
 
@@ -139,15 +159,17 @@ void IRAM_ATTR HOT Application::feed_wdt(uint32_t time) {
139
159
  }
140
160
  }
141
161
  void Application::reboot() {
142
- ESP_LOGI(TAG, "Forcing a reboot...");
162
+ ESP_LOGI(TAG, "Forcing a reboot");
143
163
  for (auto it = this->components_.rbegin(); it != this->components_.rend(); ++it) {
144
164
  (*it)->on_shutdown();
145
165
  }
146
166
  arch_restart();
147
167
  }
148
168
  void Application::safe_reboot() {
149
- ESP_LOGI(TAG, "Rebooting safely...");
169
+ ESP_LOGI(TAG, "Rebooting safely");
150
170
  run_safe_shutdown_hooks();
171
+ teardown_components(TEARDOWN_TIMEOUT_REBOOT_MS);
172
+ run_powerdown_hooks();
151
173
  arch_restart();
152
174
  }
153
175
 
@@ -160,6 +182,56 @@ void Application::run_safe_shutdown_hooks() {
160
182
  }
161
183
  }
162
184
 
185
+ void Application::run_powerdown_hooks() {
186
+ for (auto it = this->components_.rbegin(); it != this->components_.rend(); ++it) {
187
+ (*it)->on_powerdown();
188
+ }
189
+ }
190
+
191
+ void Application::teardown_components(uint32_t timeout_ms) {
192
+ uint32_t start_time = millis();
193
+
194
+ // Copy all components in reverse order using reverse iterators
195
+ // Reverse order matches the behavior of run_safe_shutdown_hooks() above and ensures
196
+ // components are torn down in the opposite order of their setup_priority (which is
197
+ // used to sort components during Application::setup())
198
+ std::vector<Component *> pending_components(this->components_.rbegin(), this->components_.rend());
199
+
200
+ uint32_t now = start_time;
201
+ while (!pending_components.empty() && (now - start_time) < timeout_ms) {
202
+ // Feed watchdog during teardown to prevent triggering
203
+ this->feed_wdt(now);
204
+
205
+ // Use iterator to safely erase elements
206
+ for (auto it = pending_components.begin(); it != pending_components.end();) {
207
+ if ((*it)->teardown()) {
208
+ // Component finished teardown, erase it
209
+ it = pending_components.erase(it);
210
+ } else {
211
+ // Component still needs time
212
+ ++it;
213
+ }
214
+ }
215
+
216
+ // Give some time for I/O operations if components are still pending
217
+ if (!pending_components.empty()) {
218
+ this->delay_with_select_(1);
219
+ }
220
+
221
+ // Update time for next iteration
222
+ now = millis();
223
+ }
224
+
225
+ if (!pending_components.empty()) {
226
+ // Note: At this point, connections are either disconnected or in a bad state,
227
+ // so this warning will only appear via serial rather than being transmitted to clients
228
+ for (auto *component : pending_components) {
229
+ ESP_LOGW(TAG, "%s did not complete teardown within %" PRIu32 " ms", component->get_component_source(),
230
+ timeout_ms);
231
+ }
232
+ }
233
+ }
234
+
163
235
  void Application::calculate_looping_components_() {
164
236
  for (auto *obj : this->components_) {
165
237
  if (obj->has_overridden_loop())
@@ -167,6 +239,117 @@ void Application::calculate_looping_components_() {
167
239
  }
168
240
  }
169
241
 
242
+ #ifdef USE_SOCKET_SELECT_SUPPORT
243
+ bool Application::register_socket_fd(int fd) {
244
+ // WARNING: This function is NOT thread-safe and must only be called from the main loop
245
+ // It modifies socket_fds_ and related variables without locking
246
+ if (fd < 0)
247
+ return false;
248
+
249
+ if (fd >= FD_SETSIZE) {
250
+ ESP_LOGE(TAG, "Cannot monitor socket fd %d: exceeds FD_SETSIZE (%d)", fd, FD_SETSIZE);
251
+ ESP_LOGE(TAG, "Socket will not be monitored for data - may cause performance issues!");
252
+ return false;
253
+ }
254
+
255
+ this->socket_fds_.push_back(fd);
256
+ this->socket_fds_changed_ = true;
257
+
258
+ if (fd > this->max_fd_) {
259
+ this->max_fd_ = fd;
260
+ }
261
+
262
+ return true;
263
+ }
264
+
265
+ void Application::unregister_socket_fd(int fd) {
266
+ // WARNING: This function is NOT thread-safe and must only be called from the main loop
267
+ // It modifies socket_fds_ and related variables without locking
268
+ if (fd < 0)
269
+ return;
270
+
271
+ auto it = std::find(this->socket_fds_.begin(), this->socket_fds_.end(), fd);
272
+ if (it != this->socket_fds_.end()) {
273
+ // Swap with last element and pop - O(1) removal since order doesn't matter
274
+ if (it != this->socket_fds_.end() - 1) {
275
+ std::swap(*it, this->socket_fds_.back());
276
+ }
277
+ this->socket_fds_.pop_back();
278
+ this->socket_fds_changed_ = true;
279
+
280
+ // Only recalculate max_fd if we removed the current max
281
+ if (fd == this->max_fd_) {
282
+ if (this->socket_fds_.empty()) {
283
+ this->max_fd_ = -1;
284
+ } else {
285
+ // Find new max using std::max_element
286
+ this->max_fd_ = *std::max_element(this->socket_fds_.begin(), this->socket_fds_.end());
287
+ }
288
+ }
289
+ }
290
+ }
291
+
292
+ bool Application::is_socket_ready(int fd) const {
293
+ // This function is thread-safe for reading the result of select()
294
+ // However, it should only be called after select() has been executed in the main loop
295
+ // The read_fds_ is only modified by select() in the main loop
296
+ if (HighFrequencyLoopRequester::is_high_frequency())
297
+ return true; // fd sets via select are not updated in high frequency looping - so force true fallback behavior
298
+ if (fd < 0 || fd >= FD_SETSIZE)
299
+ return false;
300
+
301
+ return FD_ISSET(fd, &this->read_fds_);
302
+ }
303
+ #endif
304
+
305
+ void Application::delay_with_select_(uint32_t delay_ms) {
306
+ #ifdef USE_SOCKET_SELECT_SUPPORT
307
+ if (!this->socket_fds_.empty()) {
308
+ // Update fd_set if socket list has changed
309
+ if (this->socket_fds_changed_) {
310
+ FD_ZERO(&this->base_read_fds_);
311
+ for (int fd : this->socket_fds_) {
312
+ if (fd >= 0 && fd < FD_SETSIZE) {
313
+ FD_SET(fd, &this->base_read_fds_);
314
+ }
315
+ }
316
+ this->socket_fds_changed_ = false;
317
+ }
318
+
319
+ // Copy base fd_set before each select
320
+ this->read_fds_ = this->base_read_fds_;
321
+
322
+ // Convert delay_ms to timeval
323
+ struct timeval tv;
324
+ tv.tv_sec = delay_ms / 1000;
325
+ tv.tv_usec = (delay_ms - tv.tv_sec * 1000) * 1000;
326
+
327
+ // Call select with timeout
328
+ #if defined(USE_SOCKET_IMPL_LWIP_SOCKETS) || (defined(USE_ESP32) && defined(USE_SOCKET_IMPL_BSD_SOCKETS))
329
+ int ret = lwip_select(this->max_fd_ + 1, &this->read_fds_, nullptr, nullptr, &tv);
330
+ #else
331
+ int ret = ::select(this->max_fd_ + 1, &this->read_fds_, nullptr, nullptr, &tv);
332
+ #endif
333
+
334
+ // Process select() result:
335
+ // ret < 0: error (except EINTR which is normal)
336
+ // ret > 0: socket(s) have data ready - normal and expected
337
+ // ret == 0: timeout occurred - normal and expected
338
+ if (ret < 0 && errno != EINTR) {
339
+ // Actual error - log and fall back to delay
340
+ ESP_LOGW(TAG, "select() failed with errno %d", errno);
341
+ delay(delay_ms);
342
+ }
343
+ } else {
344
+ // No sockets registered, use regular delay
345
+ delay(delay_ms);
346
+ }
347
+ #else
348
+ // No select support, use regular delay
349
+ delay(delay_ms);
350
+ #endif
351
+ }
352
+
170
353
  Application App; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
171
354
 
172
355
  } // namespace esphome
@@ -9,6 +9,10 @@
9
9
  #include "esphome/core/preferences.h"
10
10
  #include "esphome/core/scheduler.h"
11
11
 
12
+ #ifdef USE_SOCKET_SELECT_SUPPORT
13
+ #include <sys/select.h>
14
+ #endif
15
+
12
16
  #ifdef USE_BINARY_SENSOR
13
17
  #include "esphome/components/binary_sensor/binary_sensor.h"
14
18
  #endif
@@ -75,6 +79,12 @@
75
79
 
76
80
  namespace esphome {
77
81
 
82
+ // Teardown timeout constant (in milliseconds)
83
+ // For reboots, it's more important to shut down quickly than disconnect cleanly
84
+ // since we're not entering deep sleep. The only consequence of not shutting down
85
+ // cleanly is a warning in the log.
86
+ static const uint32_t TEARDOWN_TIMEOUT_REBOOT_MS = 1000; // 1 second for quick reboot
87
+
78
88
  class Application {
79
89
  public:
80
90
  void pre_setup(const std::string &name, const std::string &friendly_name, const std::string &area,
@@ -188,6 +198,73 @@ class Application {
188
198
  void register_update(update::UpdateEntity *update) { this->updates_.push_back(update); }
189
199
  #endif
190
200
 
201
+ /// Reserve space for components to avoid memory fragmentation
202
+ void reserve_components(size_t count) { this->components_.reserve(count); }
203
+
204
+ #ifdef USE_BINARY_SENSOR
205
+ void reserve_binary_sensor(size_t count) { this->binary_sensors_.reserve(count); }
206
+ #endif
207
+ #ifdef USE_SWITCH
208
+ void reserve_switch(size_t count) { this->switches_.reserve(count); }
209
+ #endif
210
+ #ifdef USE_BUTTON
211
+ void reserve_button(size_t count) { this->buttons_.reserve(count); }
212
+ #endif
213
+ #ifdef USE_SENSOR
214
+ void reserve_sensor(size_t count) { this->sensors_.reserve(count); }
215
+ #endif
216
+ #ifdef USE_TEXT_SENSOR
217
+ void reserve_text_sensor(size_t count) { this->text_sensors_.reserve(count); }
218
+ #endif
219
+ #ifdef USE_FAN
220
+ void reserve_fan(size_t count) { this->fans_.reserve(count); }
221
+ #endif
222
+ #ifdef USE_COVER
223
+ void reserve_cover(size_t count) { this->covers_.reserve(count); }
224
+ #endif
225
+ #ifdef USE_CLIMATE
226
+ void reserve_climate(size_t count) { this->climates_.reserve(count); }
227
+ #endif
228
+ #ifdef USE_LIGHT
229
+ void reserve_light(size_t count) { this->lights_.reserve(count); }
230
+ #endif
231
+ #ifdef USE_NUMBER
232
+ void reserve_number(size_t count) { this->numbers_.reserve(count); }
233
+ #endif
234
+ #ifdef USE_DATETIME_DATE
235
+ void reserve_date(size_t count) { this->dates_.reserve(count); }
236
+ #endif
237
+ #ifdef USE_DATETIME_TIME
238
+ void reserve_time(size_t count) { this->times_.reserve(count); }
239
+ #endif
240
+ #ifdef USE_DATETIME_DATETIME
241
+ void reserve_datetime(size_t count) { this->datetimes_.reserve(count); }
242
+ #endif
243
+ #ifdef USE_SELECT
244
+ void reserve_select(size_t count) { this->selects_.reserve(count); }
245
+ #endif
246
+ #ifdef USE_TEXT
247
+ void reserve_text(size_t count) { this->texts_.reserve(count); }
248
+ #endif
249
+ #ifdef USE_LOCK
250
+ void reserve_lock(size_t count) { this->locks_.reserve(count); }
251
+ #endif
252
+ #ifdef USE_VALVE
253
+ void reserve_valve(size_t count) { this->valves_.reserve(count); }
254
+ #endif
255
+ #ifdef USE_MEDIA_PLAYER
256
+ void reserve_media_player(size_t count) { this->media_players_.reserve(count); }
257
+ #endif
258
+ #ifdef USE_ALARM_CONTROL_PANEL
259
+ void reserve_alarm_control_panel(size_t count) { this->alarm_control_panels_.reserve(count); }
260
+ #endif
261
+ #ifdef USE_EVENT
262
+ void reserve_event(size_t count) { this->events_.reserve(count); }
263
+ #endif
264
+ #ifdef USE_UPDATE
265
+ void reserve_update(size_t count) { this->updates_.reserve(count); }
266
+ #endif
267
+
191
268
  /// Register the component in this Application instance.
192
269
  template<class C> C *register_component(C *c) {
193
270
  static_assert(std::is_base_of<Component, C>::value, "Only Component subclasses can be registered");
@@ -247,6 +324,14 @@ class Application {
247
324
 
248
325
  void run_safe_shutdown_hooks();
249
326
 
327
+ void run_powerdown_hooks();
328
+
329
+ /** Teardown all components with a timeout.
330
+ *
331
+ * @param timeout_ms Maximum time to wait for teardown in milliseconds
332
+ */
333
+ void teardown_components(uint32_t timeout_ms);
334
+
250
335
  uint32_t get_app_state() const { return this->app_state_; }
251
336
 
252
337
  #ifdef USE_BINARY_SENSOR
@@ -467,6 +552,19 @@ class Application {
467
552
 
468
553
  Scheduler scheduler;
469
554
 
555
+ /// Register/unregister a socket file descriptor to be monitored for read events.
556
+ #ifdef USE_SOCKET_SELECT_SUPPORT
557
+ /// These functions update the fd_set used by select() in the main loop.
558
+ /// WARNING: These functions are NOT thread-safe. They must only be called from the main loop.
559
+ /// NOTE: File descriptors >= FD_SETSIZE (typically 10 on ESP) will be rejected with an error.
560
+ /// @return true if registration was successful, false if fd exceeds limits
561
+ bool register_socket_fd(int fd);
562
+ void unregister_socket_fd(int fd);
563
+ /// Check if there's data available on a socket without blocking
564
+ /// This function is thread-safe for reading, but should be called after select() has run
565
+ bool is_socket_ready(int fd) const;
566
+ #endif
567
+
470
568
  protected:
471
569
  friend Component;
472
570
 
@@ -476,6 +574,9 @@ class Application {
476
574
 
477
575
  void feed_wdt_arch_();
478
576
 
577
+ /// Perform a delay while also monitoring socket file descriptors for readiness
578
+ void delay_with_select_(uint32_t delay_ms);
579
+
479
580
  std::vector<Component *> components_{};
480
581
  std::vector<Component *> looping_components_{};
481
582
 
@@ -555,6 +656,15 @@ class Application {
555
656
  uint32_t app_state_{0};
556
657
  Component *current_component_{nullptr};
557
658
  uint32_t loop_component_start_time_{0};
659
+
660
+ #ifdef USE_SOCKET_SELECT_SUPPORT
661
+ // Socket select management
662
+ std::vector<int> socket_fds_; // Vector of all monitored socket file descriptors
663
+ bool socket_fds_changed_{false}; // Flag to rebuild base_read_fds_ when socket_fds_ changes
664
+ int max_fd_{-1}; // Highest file descriptor number for select()
665
+ fd_set base_read_fds_{}; // Cached fd_set rebuilt only when socket_fds_ changes
666
+ fd_set read_fds_{}; // Working fd_set for select(), copied from base_read_fds_
667
+ #endif
558
668
  };
559
669
 
560
670
  /// Global storage of Application pointer - only one Application can exist.
esphome/core/component.h CHANGED
@@ -110,6 +110,19 @@ class Component {
110
110
  virtual void on_shutdown() {}
111
111
  virtual void on_safe_shutdown() {}
112
112
 
113
+ /** Called during teardown to allow component to gracefully finish operations.
114
+ *
115
+ * @return true if teardown is complete, false if more time is needed
116
+ */
117
+ virtual bool teardown() { return true; }
118
+
119
+ /** Called after teardown is complete to power down hardware.
120
+ *
121
+ * This is called after all components have finished their teardown process,
122
+ * making it safe to power down hardware like ethernet PHY.
123
+ */
124
+ virtual void on_powerdown() {}
125
+
113
126
  uint32_t get_component_state() const;
114
127
 
115
128
  /** Mark this component as failed. Any future timeouts/intervals/setup/loop will no longer be called.
esphome/core/config.py CHANGED
@@ -329,6 +329,12 @@ async def _add_automations(config):
329
329
  await automation.build_automation(trigger, [], conf)
330
330
 
331
331
 
332
+ @coroutine_with_priority(-100.0)
333
+ async def _add_platform_reserves() -> None:
334
+ for platform_name, count in sorted(CORE.platform_counts.items()):
335
+ cg.add(cg.RawStatement(f"App.reserve_{platform_name}({count});"), prepend=True)
336
+
337
+
332
338
  @coroutine_with_priority(100.0)
333
339
  async def to_code(config):
334
340
  cg.add_global(cg.global_ns.namespace("esphome").using)
@@ -347,6 +353,12 @@ async def to_code(config):
347
353
  config[CONF_NAME_ADD_MAC_SUFFIX],
348
354
  )
349
355
  )
356
+ # Reserve space for components to avoid reallocation during registration
357
+ cg.add(
358
+ cg.RawStatement(f"App.reserve_components({len(CORE.component_ids)});"),
359
+ )
360
+
361
+ CORE.add_job(_add_platform_reserves)
350
362
 
351
363
  CORE.add_job(_add_automations, config)
352
364
 
esphome/core/defines.h CHANGED
@@ -95,6 +95,7 @@
95
95
 
96
96
  // Feature flags which do not work for zephyr
97
97
  #ifndef USE_ZEPHYR
98
+ #define USE_AUDIO_DAC
98
99
  #define USE_AUDIO_FLAC_SUPPORT
99
100
  #define USE_AUDIO_MP3_SUPPORT
100
101
  #define USE_API
@@ -139,6 +140,7 @@
139
140
  #define USE_MICROPHONE
140
141
  #define USE_PSRAM
141
142
  #define USE_SOCKET_IMPL_BSD_SOCKETS
143
+ #define USE_SOCKET_SELECT_SUPPORT
142
144
  #define USE_SPEAKER
143
145
  #define USE_SPI
144
146
  #define USE_VOICE_ASSISTANT
@@ -152,15 +154,19 @@
152
154
  #endif
153
155
 
154
156
  #ifdef USE_ESP_IDF
155
- #define USE_ESP_IDF_VERSION_CODE VERSION_CODE(5, 1, 6)
157
+ #define USE_ESP_IDF_VERSION_CODE VERSION_CODE(5, 3, 2)
156
158
  #define USE_MICRO_WAKE_WORD
157
159
  #define USE_MICRO_WAKE_WORD_VAD
160
+ #if defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32H2)
161
+ #define USE_OPENTHREAD
162
+ #endif
158
163
  #endif
159
164
 
160
165
  #if defined(USE_ESP32_VARIANT_ESP32S2)
161
166
  #define USE_LOGGER_USB_CDC
162
167
  #elif defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C3) || \
163
- defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32H2)
168
+ defined(USE_ESP32_VARIANT_ESP32C5) || defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32H2) || \
169
+ defined(USE_ESP32_VARIANT_ESP32P4)
164
170
  #define USE_LOGGER_USB_CDC
165
171
  #define USE_LOGGER_USB_SERIAL_JTAG
166
172
  #endif
@@ -197,12 +203,14 @@
197
203
  #ifdef USE_LIBRETINY
198
204
  #define USE_CAPTIVE_PORTAL
199
205
  #define USE_SOCKET_IMPL_LWIP_SOCKETS
206
+ #define USE_SOCKET_SELECT_SUPPORT
200
207
  #define USE_WEBSERVER
201
208
  #define USE_WEBSERVER_PORT 80 // NOLINT
202
209
  #endif
203
210
 
204
211
  #ifdef USE_HOST
205
212
  #define USE_SOCKET_IMPL_BSD_SOCKETS
213
+ #define USE_SOCKET_SELECT_SUPPORT
206
214
  #endif
207
215
 
208
216
  // Disabled feature flags
esphome/core/helpers.cpp CHANGED
@@ -30,7 +30,6 @@
30
30
  #elif defined(USE_ESP_IDF)
31
31
  #include <freertos/FreeRTOS.h>
32
32
  #include <freertos/portmacro.h>
33
- #include "esp_mac.h"
34
33
  #include "esp_random.h"
35
34
  #include "esp_system.h"
36
35
  #elif defined(USE_RP2040)
@@ -45,6 +44,7 @@
45
44
  #endif
46
45
  #ifdef USE_ESP32
47
46
  #include "rom/crc.h"
47
+ #include "esp_mac.h"
48
48
  #include "esp_efuse.h"
49
49
  #include "esp_efuse_table.h"
50
50
  #endif
esphome/core/helpers.h CHANGED
@@ -192,15 +192,15 @@ bool random_bytes(uint8_t *data, size_t len);
192
192
  constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb) {
193
193
  return (static_cast<uint16_t>(msb) << 8) | (static_cast<uint16_t>(lsb));
194
194
  }
195
+ /// Encode a 24-bit value given three bytes in most to least significant byte order.
196
+ constexpr uint32_t encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3) {
197
+ return (static_cast<uint32_t>(byte1) << 16) | (static_cast<uint32_t>(byte2) << 8) | (static_cast<uint32_t>(byte3));
198
+ }
195
199
  /// Encode a 32-bit value given four bytes in most to least significant byte order.
196
200
  constexpr uint32_t encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4) {
197
201
  return (static_cast<uint32_t>(byte1) << 24) | (static_cast<uint32_t>(byte2) << 16) |
198
202
  (static_cast<uint32_t>(byte3) << 8) | (static_cast<uint32_t>(byte4));
199
203
  }
200
- /// Encode a 24-bit value given three bytes in most to least significant byte order.
201
- constexpr uint32_t encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3) {
202
- return ((static_cast<uint32_t>(byte1) << 16) | (static_cast<uint32_t>(byte2) << 8) | (static_cast<uint32_t>(byte3)));
203
- }
204
204
 
205
205
  /// Encode a value from its constituent bytes (from most to least significant) in an array with length sizeof(T).
206
206
  template<typename T, enable_if_t<std::is_unsigned<T>::value, int> = 0>