esphome 2025.5.2__py3-none-any.whl → 2025.6.0b2__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 (746) 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 +753 -379
  29. esphome/components/api/api_connection.h +341 -283
  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 +3 -0
  33. esphome/components/api/api_pb2.h +702 -227
  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 -4
  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 +5 -4
  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 +18 -16
  67. esphome/components/bluetooth_proxy/bluetooth_proxy.h +1 -1
  68. esphome/components/bme280_base/bme280_base.cpp +5 -6
  69. esphome/components/bme680/bme680.cpp +3 -3
  70. esphome/components/bme680/sensor.py +2 -2
  71. esphome/components/bme680_bsec/bme680_bsec.cpp +11 -7
  72. esphome/components/bme680_bsec/sensor.py +7 -3
  73. esphome/components/bme68x_bsec2/__init__.py +6 -5
  74. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +17 -13
  75. esphome/components/bme68x_bsec2/sensor.py +4 -4
  76. esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.cpp +1 -0
  77. esphome/components/bmi160/bmi160.cpp +11 -11
  78. esphome/components/bmp085/bmp085.cpp +2 -2
  79. esphome/components/bmp280_base/bmp280_base.cpp +3 -3
  80. esphome/components/bmp3xx_base/bmp3xx_base.cpp +13 -13
  81. esphome/components/bmp581/bmp581.cpp +33 -27
  82. esphome/components/bp1658cj/bp1658cj.cpp +5 -3
  83. esphome/components/bp5758d/bp5758d.cpp +1 -1
  84. esphome/components/button/__init__.py +1 -0
  85. esphome/components/canbus/canbus.cpp +1 -1
  86. esphome/components/cap1188/cap1188.cpp +6 -4
  87. esphome/components/captive_portal/captive_portal.cpp +1 -1
  88. esphome/components/ccs811/ccs811.cpp +3 -2
  89. esphome/components/cd74hc4067/cd74hc4067.cpp +1 -1
  90. esphome/components/ch422g/ch422g.cpp +2 -2
  91. esphome/components/chsc6x/chsc6x_touchscreen.cpp +6 -4
  92. esphome/components/climate/__init__.py +1 -0
  93. esphome/components/climate/climate.cpp +12 -7
  94. esphome/components/climate/climate.h +1 -1
  95. esphome/components/climate_ir/climate_ir.cpp +7 -4
  96. esphome/components/cm1106/__init__.py +1 -0
  97. esphome/components/cm1106/cm1106.cpp +112 -0
  98. esphome/components/cm1106/cm1106.h +40 -0
  99. esphome/components/cm1106/sensor.py +72 -0
  100. esphome/components/const/__init__.py +1 -0
  101. esphome/components/cover/__init__.py +1 -0
  102. esphome/components/cs5460a/cs5460a.cpp +16 -11
  103. esphome/components/cse7761/cse7761.cpp +2 -2
  104. esphome/components/cse7766/cse7766.cpp +0 -5
  105. esphome/components/cse7766/cse7766.h +5 -1
  106. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +1 -1
  107. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +6 -3
  108. esphome/components/current_based/current_based_cover.cpp +4 -2
  109. esphome/components/dac7678/dac7678_output.cpp +4 -4
  110. esphome/components/dallas_temp/dallas_temp.cpp +2 -3
  111. esphome/components/daly_bms/daly_bms.cpp +2 -1
  112. esphome/components/dashboard_import/__init__.py +1 -2
  113. esphome/components/datetime/__init__.py +3 -1
  114. esphome/components/datetime/date_entity.cpp +5 -5
  115. esphome/components/datetime/datetime_base.h +0 -5
  116. esphome/components/datetime/datetime_entity.cpp +8 -8
  117. esphome/components/datetime/time_entity.cpp +4 -4
  118. esphome/components/debug/debug_component.cpp +1 -1
  119. esphome/components/debug/debug_component.h +1 -1
  120. esphome/components/debug/debug_esp32.cpp +4 -2
  121. esphome/components/deep_sleep/deep_sleep_component.cpp +11 -5
  122. esphome/components/deep_sleep/deep_sleep_esp32.cpp +7 -5
  123. esphome/components/demo/__init__.py +206 -0
  124. esphome/components/demo/demo_alarm_control_panel.h +65 -0
  125. esphome/components/demo/demo_button.h +15 -0
  126. esphome/components/demo/demo_date.h +34 -0
  127. esphome/components/demo/demo_datetime.h +40 -0
  128. esphome/components/demo/demo_lock.h +17 -0
  129. esphome/components/demo/demo_select.h +15 -0
  130. esphome/components/demo/demo_text.h +18 -0
  131. esphome/components/demo/demo_time.h +34 -0
  132. esphome/components/demo/demo_valve.h +54 -0
  133. esphome/components/dfrobot_sen0395/commands.cpp +3 -3
  134. esphome/components/dht/dht.cpp +29 -50
  135. esphome/components/dht12/dht12.cpp +2 -2
  136. esphome/components/display/display.h +5 -3
  137. esphome/components/dps310/dps310.cpp +7 -5
  138. esphome/components/ds1307/ds1307.cpp +2 -2
  139. esphome/components/dsmr/dsmr.cpp +5 -3
  140. esphome/components/duty_cycle/duty_cycle_sensor.cpp +2 -2
  141. esphome/components/duty_time/duty_time_sensor.cpp +5 -3
  142. esphome/components/ee895/ee895.cpp +3 -3
  143. esphome/components/ektf2232/touchscreen/ektf2232.cpp +1 -1
  144. esphome/components/emc2101/emc2101.cpp +11 -9
  145. esphome/components/ens160_base/ens160_base.cpp +2 -2
  146. esphome/components/ens210/ens210.cpp +2 -2
  147. esphome/components/es7210/es7210.cpp +6 -4
  148. esphome/components/es7243e/es7243e.cpp +1 -1
  149. esphome/components/es8156/es8156.cpp +1 -1
  150. esphome/components/es8311/es8311.cpp +8 -6
  151. esphome/components/es8388/__init__.py +0 -0
  152. esphome/components/es8388/audio_dac.py +26 -0
  153. esphome/components/es8388/es8388.cpp +289 -0
  154. esphome/components/es8388/es8388.h +81 -0
  155. esphome/components/es8388/es8388_const.h +83 -0
  156. esphome/components/es8388/select/__init__.py +47 -0
  157. esphome/components/es8388/select/adc_input_mic_select.cpp +12 -0
  158. esphome/components/es8388/select/adc_input_mic_select.h +15 -0
  159. esphome/components/es8388/select/dac_output_select.cpp +12 -0
  160. esphome/components/es8388/select/dac_output_select.h +15 -0
  161. esphome/components/esp32/__init__.py +118 -23
  162. esphome/components/esp32/boards.py +208 -125
  163. esphome/components/esp32/const.py +6 -0
  164. esphome/components/esp32/gpio.py +14 -1
  165. esphome/components/esp32/gpio_esp32_c5.py +45 -0
  166. esphome/components/esp32/gpio_esp32_p4.py +43 -0
  167. esphome/components/esp32/preferences.cpp +7 -7
  168. esphome/components/esp32_ble/__init__.py +115 -0
  169. esphome/components/esp32_ble/ble.cpp +101 -54
  170. esphome/components/esp32_ble/ble.h +24 -5
  171. esphome/components/esp32_ble/ble_event.h +172 -32
  172. esphome/components/esp32_ble/ble_scan_result.h +24 -0
  173. esphome/components/esp32_ble/ble_uuid.h +1 -1
  174. esphome/components/esp32_ble/queue.h +53 -27
  175. esphome/components/esp32_ble_client/ble_client_base.cpp +4 -2
  176. esphome/components/esp32_ble_server/__init__.py +4 -1
  177. esphome/components/esp32_ble_server/ble_characteristic.cpp +1 -0
  178. esphome/components/esp32_ble_server/ble_server.h +0 -1
  179. esphome/components/esp32_ble_tracker/__init__.py +7 -2
  180. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +107 -75
  181. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +16 -16
  182. esphome/components/esp32_camera/esp32_camera.cpp +35 -27
  183. esphome/components/esp32_camera_web_server/camera_web_server.cpp +4 -2
  184. esphome/components/esp32_dac/esp32_dac.cpp +2 -2
  185. esphome/components/esp32_improv/__init__.py +5 -1
  186. esphome/components/esp32_improv/esp32_improv_component.cpp +2 -2
  187. esphome/components/esp32_rmt_led_strip/led_strip.cpp +11 -7
  188. esphome/components/esp32_rmt_led_strip/light.py +5 -1
  189. esphome/components/esp32_touch/esp32_touch.cpp +12 -8
  190. esphome/components/esp8266/preferences.cpp +6 -6
  191. esphome/components/esp8266_pwm/esp8266_pwm.cpp +3 -3
  192. esphome/components/esp_ldo/__init__.py +91 -0
  193. esphome/components/esp_ldo/esp_ldo.cpp +43 -0
  194. esphome/components/esp_ldo/esp_ldo.h +43 -0
  195. esphome/components/esphome/ota/ota_esphome.cpp +15 -8
  196. esphome/components/ethernet/ethernet_component.cpp +38 -26
  197. esphome/components/ethernet/ethernet_component.h +1 -1
  198. esphome/components/event/__init__.py +1 -0
  199. esphome/components/exposure_notifications/exposure_notifications.cpp +1 -1
  200. esphome/components/ezo/ezo.cpp +1 -1
  201. esphome/components/ezo_pmp/ezo_pmp.cpp +1 -1
  202. esphome/components/factory_reset/button/factory_reset_button.cpp +1 -1
  203. esphome/components/factory_reset/switch/factory_reset_switch.cpp +1 -1
  204. esphome/components/fan/__init__.py +1 -0
  205. esphome/components/fan/fan.cpp +30 -19
  206. esphome/components/fastled_base/fastled_light.cpp +7 -5
  207. esphome/components/fingerprint_grow/fingerprint_grow.cpp +8 -6
  208. esphome/components/fs3000/fs3000.cpp +1 -1
  209. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +7 -4
  210. esphome/components/ft63x6/ft63x6.cpp +5 -3
  211. esphome/components/gcja5/gcja5.cpp +0 -12
  212. esphome/components/gcja5/gcja5.h +8 -3
  213. esphome/components/gdk101/gdk101.cpp +2 -2
  214. esphome/components/globals/globals_component.h +13 -10
  215. esphome/components/gp2y1010au0f/gp2y1010au0f.cpp +4 -2
  216. esphome/components/gp8403/gp8403.cpp +4 -2
  217. esphome/components/gp8403/output/gp8403_output.cpp +4 -2
  218. esphome/components/gpio/one_wire/gpio_one_wire.cpp +2 -2
  219. esphome/components/gpio/output/gpio_binary_output.cpp +1 -1
  220. esphome/components/gpio/switch/gpio_switch.cpp +1 -1
  221. esphome/components/graphical_display_menu/graphical_display_menu.cpp +12 -8
  222. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -6
  223. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +1 -1
  224. esphome/components/grove_tb6612fng/grove_tb6612fng.h +1 -1
  225. esphome/components/growatt_solar/growatt_solar.cpp +6 -3
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
  227. esphome/components/haier/haier_base.cpp +2 -2
  228. esphome/components/haier/hon_climate.cpp +13 -6
  229. esphome/components/havells_solar/havells_solar.cpp +5 -2
  230. esphome/components/hbridge/switch/hbridge_switch.cpp +1 -1
  231. esphome/components/hdc1080/hdc1080.cpp +2 -2
  232. esphome/components/he60r/he60r.cpp +4 -2
  233. esphome/components/hlw8012/hlw8012.cpp +6 -4
  234. esphome/components/hm3301/hm3301.cpp +2 -2
  235. esphome/components/hmc5883l/hmc5883l.cpp +2 -2
  236. esphome/components/homeassistant/time/homeassistant_time.cpp +4 -2
  237. esphome/components/honeywell_hih_i2c/honeywell_hih.cpp +4 -4
  238. esphome/components/honeywellabp/honeywellabp.cpp +4 -2
  239. esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +8 -6
  240. esphome/components/hte501/hte501.cpp +3 -2
  241. esphome/components/http_request/__init__.py +2 -2
  242. esphome/components/http_request/http_request.cpp +7 -5
  243. esphome/components/http_request/http_request_idf.cpp +4 -2
  244. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  245. esphome/components/htu21d/htu21d.cpp +2 -2
  246. esphome/components/htu31d/htu31d.cpp +2 -2
  247. esphome/components/hx711/hx711.cpp +2 -2
  248. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +5 -3
  249. esphome/components/hyt271/hyt271.cpp +2 -2
  250. esphome/components/i2c/i2c_bus_arduino.cpp +14 -11
  251. esphome/components/i2c/i2c_bus_esp_idf.cpp +13 -11
  252. esphome/components/i2s_audio/__init__.py +2 -0
  253. esphome/components/i2s_audio/i2s_audio.cpp +3 -4
  254. esphome/components/i2s_audio/i2s_audio.h +1 -1
  255. esphome/components/i2s_audio/media_player/__init__.py +1 -1
  256. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +5 -3
  257. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +13 -10
  258. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  259. esphome/components/iaqcore/iaqcore.cpp +3 -3
  260. esphome/components/ili9xxx/ili9xxx_display.cpp +12 -7
  261. esphome/components/ili9xxx/ili9xxx_display.h +1 -1
  262. esphome/components/image/image.cpp +1 -0
  263. esphome/components/ina219/ina219.cpp +2 -2
  264. esphome/components/ina226/ina226.cpp +8 -5
  265. esphome/components/ina260/ina260.cpp +1 -1
  266. esphome/components/ina2xx_base/ina2xx_base.cpp +13 -9
  267. esphome/components/ina3221/ina3221.cpp +2 -2
  268. esphome/components/inkplate6/display.py +12 -2
  269. esphome/components/inkplate6/inkplate.cpp +13 -9
  270. esphome/components/inkplate6/inkplate.h +7 -6
  271. esphome/components/integration/integration_sensor.cpp +1 -1
  272. esphome/components/internal_temperature/internal_temperature.cpp +4 -4
  273. esphome/components/json/json_util.cpp +4 -5
  274. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +1 -1
  275. esphome/components/key_collector/key_collector.cpp +4 -2
  276. esphome/components/kmeteriso/kmeteriso.cpp +4 -4
  277. esphome/components/kuntze/kuntze.cpp +4 -2
  278. esphome/components/lc709203f/__init__.py +1 -0
  279. esphome/components/lc709203f/lc709203f.cpp +299 -0
  280. esphome/components/lc709203f/lc709203f.h +55 -0
  281. esphome/components/lc709203f/sensor.py +93 -0
  282. esphome/components/lcd_base/lcd_display.cpp +2 -2
  283. esphome/components/lcd_gpio/gpio_lcd_display.cpp +5 -3
  284. esphome/components/lcd_menu/lcd_menu.cpp +6 -4
  285. esphome/components/lcd_pcf8574/pcf8574_display.cpp +6 -4
  286. esphome/components/ld2410/ld2410.cpp +6 -7
  287. esphome/components/ld2420/ld2420.cpp +9 -7
  288. esphome/components/ld2450/ld2450.cpp +6 -4
  289. esphome/components/ld2450/sensor.py +2 -2
  290. esphome/components/ledc/ledc_output.cpp +32 -28
  291. esphome/components/libretiny/const.py +1 -1
  292. esphome/components/libretiny/preferences.cpp +6 -7
  293. esphome/components/light/__init__.py +2 -1
  294. esphome/components/light/esp_hsv_color.h +1 -1
  295. esphome/components/light/light_state.cpp +9 -5
  296. esphome/components/light/light_transformer.h +1 -1
  297. esphome/components/lightwaverf/LwTx.cpp +1 -1
  298. esphome/components/lightwaverf/lightwaverf.cpp +1 -1
  299. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +1 -1
  300. esphome/components/lock/__init__.py +1 -0
  301. esphome/components/lock/lock.h +1 -1
  302. esphome/components/logger/__init__.py +6 -0
  303. esphome/components/logger/logger.cpp +11 -20
  304. esphome/components/logger/logger.h +1 -2
  305. esphome/components/logger/logger_esp32.cpp +5 -5
  306. esphome/components/ltr390/ltr390.cpp +8 -5
  307. esphome/components/ltr501/ltr501.cpp +19 -14
  308. esphome/components/ltr_als_ps/ltr_als_ps.cpp +20 -13
  309. esphome/components/lvgl/__init__.py +2 -2
  310. esphome/components/lvgl/automation.py +5 -4
  311. esphome/components/lvgl/defines.py +0 -2
  312. esphome/components/lvgl/lv_validation.py +1 -3
  313. esphome/components/lvgl/lvcode.py +7 -8
  314. esphome/components/lvgl/lvgl_esphome.cpp +26 -10
  315. esphome/components/lvgl/schemas.py +22 -23
  316. esphome/components/lvgl/trigger.py +8 -3
  317. esphome/components/lvgl/widgets/__init__.py +2 -2
  318. esphome/components/lvgl/widgets/canvas.py +9 -3
  319. esphome/components/lvgl/widgets/line.py +2 -1
  320. esphome/components/lvgl/widgets/tabview.py +7 -0
  321. esphome/components/m5stack_8angle/m5stack_8angle.cpp +3 -3
  322. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -2
  323. esphome/components/max17043/max17043.cpp +2 -2
  324. esphome/components/max31855/max31855.cpp +2 -1
  325. esphome/components/max31856/max31856.cpp +9 -11
  326. esphome/components/max31865/max31865.cpp +6 -4
  327. esphome/components/max44009/max44009.cpp +2 -2
  328. esphome/components/max6675/max6675.cpp +1 -1
  329. esphome/components/max6956/max6956.cpp +5 -3
  330. esphome/components/max7219/max7219.cpp +8 -6
  331. esphome/components/max7219digit/automation.h +52 -0
  332. esphome/components/max7219digit/display.py +93 -1
  333. esphome/components/max7219digit/max7219digit.cpp +16 -13
  334. esphome/components/max9611/max9611.cpp +9 -6
  335. esphome/components/mcp23008/mcp23008.cpp +1 -1
  336. esphome/components/mcp23016/mcp23016.cpp +1 -1
  337. esphome/components/mcp23017/mcp23017.cpp +1 -1
  338. esphome/components/mcp23s08/mcp23s08.cpp +1 -1
  339. esphome/components/mcp23s17/mcp23s17.cpp +1 -1
  340. esphome/components/mcp3008/mcp3008.cpp +1 -1
  341. esphome/components/mcp3008/sensor/mcp3008_sensor.cpp +5 -3
  342. esphome/components/mcp3204/mcp3204.cpp +1 -1
  343. esphome/components/mcp4461/mcp4461.cpp +2 -2
  344. esphome/components/mcp4725/mcp4725.cpp +2 -2
  345. esphome/components/mcp4728/mcp4728.cpp +2 -2
  346. esphome/components/mcp9600/mcp9600.cpp +1 -1
  347. esphome/components/mcp9808/mcp9808.cpp +4 -4
  348. esphome/components/mdns/mdns_component.cpp +8 -2
  349. esphome/components/mdns/mdns_component.h +3 -1
  350. esphome/components/mdns/mdns_esp32.cpp +2 -2
  351. esphome/components/media_player/__init__.py +1 -0
  352. esphome/components/micro_wake_word/micro_wake_word.cpp +1 -1
  353. esphome/components/micro_wake_word/streaming_model.cpp +10 -6
  354. esphome/components/micronova/micronova.h +2 -2
  355. esphome/components/mics_4514/mics_4514.cpp +2 -2
  356. esphome/components/midea/air_conditioner.cpp +7 -5
  357. esphome/components/midea_ir/midea_ir.cpp +1 -1
  358. esphome/components/mipi_spi/mipi_spi.cpp +24 -15
  359. esphome/components/mixer/speaker/mixer_speaker.cpp +8 -4
  360. esphome/components/mlx90393/sensor_mlx90393.cpp +2 -2
  361. esphome/components/mlx90614/mlx90614.cpp +4 -3
  362. esphome/components/mmc5603/mmc5603.cpp +2 -2
  363. esphome/components/mmc5983/mmc5983.cpp +1 -1
  364. esphome/components/modbus/modbus.cpp +7 -5
  365. esphome/components/modbus_controller/modbus_controller.cpp +6 -4
  366. esphome/components/modbus_controller/output/modbus_output.cpp +10 -6
  367. esphome/components/modbus_controller/switch/__init__.py +6 -2
  368. esphome/components/modbus_controller/switch/modbus_switch.cpp +4 -0
  369. esphome/components/modbus_controller/switch/modbus_switch.h +3 -0
  370. esphome/components/mpl3115a2/mpl3115a2.cpp +3 -2
  371. esphome/components/mpr121/mpr121.cpp +2 -2
  372. esphome/components/mpu6050/mpu6050.cpp +6 -6
  373. esphome/components/mpu6886/mpu6886.cpp +6 -6
  374. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +7 -3
  375. esphome/components/mqtt/mqtt_backend_esp32.cpp +1 -1
  376. esphome/components/mqtt/mqtt_client.cpp +31 -24
  377. esphome/components/mqtt/mqtt_component.cpp +3 -3
  378. esphome/components/mqtt/mqtt_cover.cpp +8 -4
  379. esphome/components/mqtt/mqtt_fan.cpp +12 -6
  380. esphome/components/mqtt/mqtt_valve.cpp +4 -2
  381. esphome/components/ms5611/ms5611.cpp +2 -2
  382. esphome/components/ms8607/ms8607.cpp +2 -2
  383. esphome/components/msa3xx/msa3xx.cpp +16 -12
  384. esphome/components/my9231/my9231.cpp +7 -5
  385. esphome/components/nau7802/nau7802.cpp +6 -4
  386. esphome/components/neopixelbus/neopixelbus_light.h +2 -2
  387. esphome/components/network/ip_address.h +1 -1
  388. esphome/components/network/util.cpp +13 -0
  389. esphome/components/nextion/base_component.py +2 -0
  390. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +3 -4
  391. esphome/components/nextion/display.py +34 -22
  392. esphome/components/nextion/nextion.cpp +182 -143
  393. esphome/components/nextion/nextion.h +36 -0
  394. esphome/components/nextion/nextion_commands.cpp +3 -3
  395. esphome/components/nextion/nextion_upload_arduino.cpp +69 -69
  396. esphome/components/nextion/nextion_upload_idf.cpp +79 -80
  397. esphome/components/nextion/sensor/nextion_sensor.cpp +5 -5
  398. esphome/components/nextion/switch/nextion_switch.cpp +2 -2
  399. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +3 -3
  400. esphome/components/nfc/nci_message.h +1 -1
  401. esphome/components/nfc/ndef_record.h +1 -1
  402. esphome/components/nfc/ndef_record_text.h +1 -1
  403. esphome/components/nfc/ndef_record_uri.h +1 -1
  404. esphome/components/nfc/nfc.h +1 -1
  405. esphome/components/nfc/nfc_tag.h +1 -1
  406. esphome/components/noblex/noblex.cpp +1 -1
  407. esphome/components/npi19/npi19.cpp +5 -7
  408. esphome/components/number/__init__.py +11 -0
  409. esphome/components/number/number.cpp +1 -1
  410. esphome/components/number/number.h +0 -4
  411. esphome/components/online_image/__init__.py +13 -1
  412. esphome/components/online_image/online_image.cpp +26 -4
  413. esphome/components/online_image/online_image.h +21 -4
  414. esphome/components/opentherm/generate.py +3 -3
  415. esphome/components/opentherm/hub.cpp +11 -7
  416. esphome/components/opentherm/number/number.cpp +5 -3
  417. esphome/components/opentherm/opentherm.h +1 -1
  418. esphome/components/opentherm/schema.py +13 -13
  419. esphome/components/opentherm/validate.py +1 -1
  420. esphome/components/openthread/__init__.py +146 -0
  421. esphome/components/openthread/const.py +10 -0
  422. esphome/components/openthread/openthread.cpp +206 -0
  423. esphome/components/openthread/openthread.h +68 -0
  424. esphome/components/openthread/openthread_esp.cpp +164 -0
  425. esphome/components/openthread/tlv.py +58 -0
  426. esphome/components/openthread_info/__init__.py +0 -0
  427. esphome/components/openthread_info/openthread_info_text_sensor.cpp +24 -0
  428. esphome/components/openthread_info/openthread_info_text_sensor.h +218 -0
  429. esphome/components/openthread_info/text_sensor.py +105 -0
  430. esphome/components/output/float_output.cpp +1 -1
  431. esphome/components/output/switch/output_switch.cpp +1 -1
  432. esphome/components/packet_transport/packet_transport.cpp +6 -4
  433. esphome/components/pca6416a/pca6416a.cpp +2 -2
  434. esphome/components/pca9554/pca9554.cpp +6 -4
  435. esphome/components/pca9685/pca9685_output.cpp +12 -8
  436. esphome/components/pcd8544/pcd_8544.cpp +1 -1
  437. esphome/components/pcf85063/pcf85063.cpp +2 -2
  438. esphome/components/pcf8563/pcf8563.cpp +2 -2
  439. esphome/components/pcf8574/pcf8574.cpp +2 -2
  440. esphome/components/pid/pid_climate.cpp +8 -5
  441. esphome/components/pid/pid_climate.h +1 -1
  442. esphome/components/pid/sensor/pid_climate_sensor.cpp +1 -1
  443. esphome/components/pipsolar/output/pipsolar_output.cpp +1 -1
  444. esphome/components/pipsolar/pipsolar.cpp +3 -3
  445. esphome/components/pm1006/pm1006.cpp +3 -7
  446. esphome/components/pm1006/pm1006.h +4 -1
  447. esphome/components/pm2005/pm2005.cpp +12 -13
  448. esphome/components/pm2005/sensor.py +1 -1
  449. esphome/components/pmsa003i/pmsa003i.cpp +2 -2
  450. esphome/components/pmsx003/pmsx003.cpp +0 -4
  451. esphome/components/pmsx003/pmsx003.h +5 -2
  452. esphome/components/pmwcs3/pmwcs3.cpp +9 -13
  453. esphome/components/pmwcs3/pmwcs3.h +0 -1
  454. esphome/components/pn532/pn532.cpp +7 -7
  455. esphome/components/pn532/pn532.h +1 -1
  456. esphome/components/pn532_spi/pn532_spi.cpp +1 -1
  457. esphome/components/pn7150/pn7150.cpp +4 -4
  458. esphome/components/pn7160/pn7160.cpp +4 -4
  459. esphome/components/power_supply/power_supply.cpp +6 -4
  460. esphome/components/power_supply/power_supply.h +1 -1
  461. esphome/components/prometheus/__init__.py +0 -1
  462. esphome/components/psram/__init__.py +59 -35
  463. esphome/components/pulse_counter/pulse_counter_sensor.cpp +7 -4
  464. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +8 -5
  465. esphome/components/pylontech/pylontech.cpp +2 -2
  466. esphome/components/pylontech/sensor/pylontech_sensor.cpp +4 -2
  467. esphome/components/pylontech/text_sensor/pylontech_text_sensor.cpp +4 -2
  468. esphome/components/pzemac/pzemac.cpp +4 -2
  469. esphome/components/pzemdc/pzemdc.cpp +4 -2
  470. esphome/components/qmc5883l/qmc5883l.cpp +2 -2
  471. esphome/components/qmp6988/qmp6988.cpp +2 -2
  472. esphome/components/qmp6988/qmp6988.h +1 -1
  473. esphome/components/qr_code/qr_code.cpp +5 -3
  474. esphome/components/qspi_dbi/qspi_dbi.cpp +1 -1
  475. esphome/components/qwiic_pir/qwiic_pir.cpp +26 -28
  476. esphome/components/rc522/rc522.cpp +5 -5
  477. esphome/components/rdm6300/rdm6300.cpp +1 -0
  478. esphome/components/remote_receiver/__init__.py +10 -2
  479. esphome/components/remote_receiver/remote_receiver_esp32.cpp +22 -12
  480. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +10 -7
  481. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +10 -7
  482. esphome/components/remote_transmitter/__init__.py +10 -2
  483. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +10 -6
  484. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +5 -3
  485. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +5 -3
  486. esphome/components/resistance/resistance_sensor.cpp +6 -3
  487. esphome/components/restart/button/restart_button.cpp +1 -1
  488. esphome/components/restart/switch/restart_switch.cpp +1 -1
  489. esphome/components/rotary_encoder/rotary_encoder.cpp +2 -2
  490. esphome/components/rp2040/__init__.py +7 -0
  491. esphome/components/rp2040/core.cpp +8 -1
  492. esphome/components/rp2040/preferences.cpp +3 -3
  493. esphome/components/rp2040_pio_led_strip/led_strip.cpp +11 -8
  494. esphome/components/rp2040_pio_led_strip/light.py +1 -1
  495. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -1
  496. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +1 -1
  497. esphome/components/rtttl/rtttl.cpp +11 -9
  498. esphome/components/safe_mode/button/safe_mode_button.cpp +1 -1
  499. esphome/components/safe_mode/safe_mode.cpp +9 -8
  500. esphome/components/safe_mode/switch/safe_mode_switch.cpp +1 -1
  501. esphome/components/scd30/scd30.cpp +11 -8
  502. esphome/components/scd4x/scd4x.cpp +12 -8
  503. esphome/components/sdl/display.py +40 -0
  504. esphome/components/sdl/sdl_esphome.cpp +2 -2
  505. esphome/components/sdl/sdl_esphome.h +8 -0
  506. esphome/components/sdm_meter/sdm_meter.cpp +5 -2
  507. esphome/components/sdp3x/sdp3x.cpp +11 -11
  508. esphome/components/sds011/sds011.cpp +5 -6
  509. esphome/components/sds011/sds011.h +4 -1
  510. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +3 -2
  511. esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +1 -0
  512. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +3 -2
  513. esphome/components/selec_meter/selec_meter.cpp +5 -2
  514. esphome/components/select/__init__.py +1 -0
  515. esphome/components/select/select.cpp +1 -1
  516. esphome/components/select/select.h +0 -4
  517. esphome/components/sen0321/sen0321.cpp +2 -2
  518. esphome/components/sen21231/sen21231.cpp +1 -1
  519. esphome/components/sen5x/sen5x.cpp +10 -7
  520. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  521. esphome/components/sensirion_common/i2c_sensirion.h +1 -0
  522. esphome/components/sensor/__init__.py +11 -1
  523. esphome/components/sensor/filter.h +1 -1
  524. esphome/components/sensor/sensor.cpp +8 -4
  525. esphome/components/sensor/sensor.h +12 -11
  526. esphome/components/servo/servo.cpp +12 -9
  527. esphome/components/servo/servo.h +1 -1
  528. esphome/components/sfa30/sfa30.cpp +1 -1
  529. esphome/components/sgp30/sgp30.cpp +10 -8
  530. esphome/components/sgp4x/sgp4x.cpp +49 -61
  531. esphome/components/sgp4x/sgp4x.h +0 -1
  532. esphome/components/shelly_dimmer/shelly_dimmer.cpp +11 -7
  533. esphome/components/sht3xd/sht3xd.cpp +1 -1
  534. esphome/components/sht4x/sht4x.cpp +2 -2
  535. esphome/components/shtcx/shtcx.cpp +13 -16
  536. esphome/components/shutdown/button/shutdown_button.cpp +1 -1
  537. esphome/components/shutdown/switch/shutdown_switch.cpp +1 -1
  538. esphome/components/sim800l/sim800l.cpp +2 -2
  539. esphome/components/slow_pwm/slow_pwm_output.cpp +4 -2
  540. esphome/components/sm16716/sm16716.cpp +1 -1
  541. esphome/components/sm2135/sm2135.cpp +1 -1
  542. esphome/components/sm2235/sm2235.cpp +5 -3
  543. esphome/components/sm2335/sm2335.cpp +5 -3
  544. esphome/components/sml/sml.cpp +1 -1
  545. esphome/components/sn74hc165/sn74hc165.cpp +1 -2
  546. esphome/components/sn74hc595/sn74hc595.cpp +1 -2
  547. esphome/components/sntp/sntp_component.cpp +1 -1
  548. esphome/components/socket/__init__.py +2 -0
  549. esphome/components/socket/bsd_sockets_impl.cpp +51 -7
  550. esphome/components/socket/lwip_raw_tcp_impl.cpp +5 -0
  551. esphome/components/socket/lwip_sockets_impl.cpp +51 -7
  552. esphome/components/socket/socket.cpp +31 -0
  553. esphome/components/socket/socket.h +27 -1
  554. esphome/components/sonoff_d1/sonoff_d1.cpp +7 -4
  555. esphome/components/sonoff_d1/sonoff_d1.h +2 -2
  556. esphome/components/sound_level/sound_level.cpp +4 -2
  557. esphome/components/speaker/media_player/__init__.py +3 -0
  558. esphome/components/speaker/media_player/speaker_media_player.cpp +1 -3
  559. esphome/components/speaker/media_player/speaker_media_player.h +6 -0
  560. esphome/components/spi/__init__.py +10 -2
  561. esphome/components/spi/spi.cpp +4 -4
  562. esphome/components/spi_device/spi_device.cpp +1 -2
  563. esphome/components/sprinkler/sprinkler.cpp +9 -6
  564. esphome/components/sps30/sps30.cpp +16 -15
  565. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  566. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +11 -8
  567. esphome/components/ssd1306_spi/ssd1306_spi.cpp +10 -7
  568. esphome/components/ssd1322_base/ssd1322_base.cpp +1 -1
  569. esphome/components/ssd1322_spi/ssd1322_spi.cpp +1 -1
  570. esphome/components/ssd1325_base/ssd1325_base.cpp +1 -1
  571. esphome/components/ssd1325_spi/ssd1325_spi.cpp +1 -1
  572. esphome/components/ssd1327_base/ssd1327_base.cpp +1 -1
  573. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +2 -2
  574. esphome/components/ssd1327_spi/ssd1327_spi.cpp +1 -1
  575. esphome/components/ssd1331_base/ssd1331_base.cpp +1 -1
  576. esphome/components/ssd1331_spi/ssd1331_spi.cpp +1 -1
  577. esphome/components/ssd1351_base/ssd1351_base.cpp +1 -1
  578. esphome/components/ssd1351_spi/ssd1351_spi.cpp +1 -1
  579. esphome/components/st7567_base/st7567_base.cpp +3 -3
  580. esphome/components/st7567_i2c/st7567_i2c.cpp +7 -5
  581. esphome/components/st7567_spi/st7567_spi.cpp +1 -1
  582. esphome/components/st7701s/st7701s.cpp +4 -2
  583. esphome/components/st7735/st7735.cpp +3 -3
  584. esphome/components/st7789v/st7789v.cpp +10 -7
  585. esphome/components/st7920/st7920.cpp +6 -4
  586. esphome/components/statsd/statsd.cpp +9 -5
  587. esphome/components/status_led/light/status_led_light.cpp +3 -3
  588. esphome/components/status_led/light/status_led_light.h +1 -1
  589. esphome/components/status_led/status_led.cpp +1 -1
  590. esphome/components/stepper/stepper.h +5 -3
  591. esphome/components/sts3x/sts3x.cpp +2 -2
  592. esphome/components/switch/__init__.py +1 -0
  593. esphome/components/switch/switch.cpp +18 -12
  594. esphome/components/switch/switch.h +1 -1
  595. esphome/components/sx1509/__init__.py +53 -20
  596. esphome/components/sx1509/sx1509.cpp +29 -5
  597. esphome/components/sx1509/sx1509.h +9 -1
  598. esphome/components/t6615/t6615.cpp +1 -0
  599. esphome/components/tc74/tc74.cpp +1 -1
  600. esphome/components/tca9548a/tca9548a.cpp +1 -1
  601. esphome/components/tca9555/tca9555.cpp +2 -2
  602. esphome/components/tcs34725/tcs34725.cpp +4 -4
  603. esphome/components/tee501/tee501.cpp +3 -2
  604. esphome/components/tem3200/tem3200.cpp +5 -6
  605. esphome/components/template/alarm_control_panel/__init__.py +6 -0
  606. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +43 -12
  607. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +4 -1
  608. esphome/components/template/cover/template_cover.cpp +1 -1
  609. esphome/components/template/select/template_select.cpp +6 -4
  610. esphome/components/template/text/template_text.cpp +2 -3
  611. esphome/components/template/valve/template_valve.cpp +5 -3
  612. esphome/components/text/__init__.py +10 -11
  613. esphome/components/text/text.cpp +1 -1
  614. esphome/components/text/text.h +0 -4
  615. esphome/components/text_sensor/__init__.py +1 -0
  616. esphome/components/text_sensor/text_sensor.cpp +8 -4
  617. esphome/components/text_sensor/text_sensor.h +6 -6
  618. esphome/components/thermostat/thermostat_climate.cpp +67 -43
  619. esphome/components/time/__init__.py +1 -2
  620. esphome/components/time_based/time_based_cover.cpp +4 -2
  621. esphome/components/tlc59208f/tlc59208f_output.cpp +8 -6
  622. esphome/components/tm1621/tm1621.cpp +3 -3
  623. esphome/components/tm1637/tm1637.cpp +9 -7
  624. esphome/components/tm1638/tm1638.cpp +7 -5
  625. esphome/components/tm1651/tm1651.cpp +2 -2
  626. esphome/components/tmp102/tmp102.cpp +1 -3
  627. esphome/components/tmp102/tmp102.h +0 -3
  628. esphome/components/tmp1075/tmp1075.cpp +12 -9
  629. esphome/components/tmp117/tmp117.cpp +2 -2
  630. esphome/components/tof10120/tof10120_sensor.cpp +2 -2
  631. esphome/components/tormatic/tormatic_cover.cpp +4 -2
  632. esphome/components/tsl2561/tsl2561.cpp +7 -5
  633. esphome/components/tsl2591/tsl2591.cpp +25 -27
  634. esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
  635. esphome/components/ttp229_bsf/ttp229_bsf.cpp +1 -1
  636. esphome/components/ttp229_lsf/ttp229_lsf.cpp +2 -2
  637. esphome/components/tuya/select/tuya_select.cpp +5 -3
  638. esphome/components/tx20/tx20.cpp +3 -3
  639. esphome/components/uart/__init__.py +4 -5
  640. esphome/components/uart/button/uart_button.cpp +1 -1
  641. esphome/components/uart/switch/uart_switch.cpp +2 -2
  642. esphome/components/uart/uart.cpp +2 -2
  643. esphome/components/uart/uart_component_esp32_arduino.cpp +8 -6
  644. esphome/components/uart/uart_component_esp8266.cpp +9 -7
  645. esphome/components/uart/uart_component_esp_idf.cpp +9 -7
  646. esphome/components/uart/uart_component_host.cpp +11 -8
  647. esphome/components/uart/uart_component_libretiny.cpp +8 -6
  648. esphome/components/uart/uart_component_rp2040.cpp +8 -6
  649. esphome/components/udp/udp_component.cpp +9 -5
  650. esphome/components/ufire_ec/ufire_ec.cpp +5 -3
  651. esphome/components/ufire_ise/ufire_ise.cpp +1 -1
  652. esphome/components/ultrasonic/ultrasonic_sensor.cpp +5 -3
  653. esphome/components/update/__init__.py +1 -0
  654. esphome/components/update/update_entity.cpp +1 -1
  655. esphome/components/update/update_entity.h +0 -3
  656. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  657. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +4 -2
  658. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  659. esphome/components/uptime/sensor/uptime_timestamp_sensor.cpp +1 -1
  660. esphome/components/usb_host/__init__.py +64 -0
  661. esphome/components/usb_host/usb_host.h +116 -0
  662. esphome/components/usb_host/usb_host_client.cpp +394 -0
  663. esphome/components/usb_host/usb_host_component.cpp +35 -0
  664. esphome/components/usb_uart/__init__.py +134 -0
  665. esphome/components/usb_uart/ch34x.cpp +80 -0
  666. esphome/components/usb_uart/cp210x.cpp +126 -0
  667. esphome/components/usb_uart/usb_uart.cpp +328 -0
  668. esphome/components/usb_uart/usb_uart.h +151 -0
  669. esphome/components/valve/__init__.py +1 -0
  670. esphome/components/veml3235/veml3235.cpp +13 -9
  671. esphome/components/veml7700/veml7700.cpp +10 -6
  672. esphome/components/voice_assistant/voice_assistant.cpp +7 -7
  673. esphome/components/wake_on_lan/wake_on_lan.cpp +1 -1
  674. esphome/components/waveshare_epaper/waveshare_epaper.cpp +1 -1
  675. esphome/components/web_server/server_index_v2.h +632 -630
  676. esphome/components/web_server/server_index_v3.h +411 -409
  677. esphome/components/web_server/web_server.cpp +5 -3
  678. esphome/components/web_server_base/web_server_base.cpp +1 -1
  679. esphome/components/web_server_idf/__init__.py +0 -2
  680. esphome/components/web_server_idf/utils.cpp +1 -1
  681. esphome/components/web_server_idf/web_server_idf.cpp +7 -3
  682. esphome/components/web_server_idf/web_server_idf.h +7 -0
  683. esphome/components/weikai/__init__.py +2 -0
  684. esphome/components/weikai/weikai.cpp +24 -22
  685. esphome/components/weikai_i2c/weikai_i2c.cpp +14 -9
  686. esphome/components/weikai_spi/weikai_spi.cpp +11 -6
  687. esphome/components/wiegand/wiegand.cpp +1 -1
  688. esphome/components/wifi/wifi_component.cpp +50 -37
  689. esphome/components/wifi/wifi_component.h +7 -4
  690. esphome/components/wifi/wifi_component_esp32_arduino.cpp +2 -2
  691. esphome/components/wifi/wifi_component_esp8266.cpp +3 -3
  692. esphome/components/wifi/wifi_component_libretiny.cpp +4 -4
  693. esphome/components/wireguard/wireguard.cpp +21 -21
  694. esphome/components/wl_134/text_sensor.py +1 -2
  695. esphome/components/wled/wled_light_effect.cpp +1 -1
  696. esphome/components/x9c/x9c.cpp +5 -3
  697. esphome/components/xgzp68xx/xgzp68xx.cpp +8 -6
  698. esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp +4 -2
  699. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.cpp +4 -2
  700. esphome/components/xiaomi_cgg1/xiaomi_cgg1.cpp +4 -2
  701. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.cpp +1 -1
  702. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp +4 -2
  703. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp +4 -2
  704. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.cpp +4 -2
  705. esphome/components/xl9535/xl9535.cpp +2 -2
  706. esphome/components/xpt2046/touchscreen/xpt2046.cpp +12 -11
  707. esphome/components/xpt2046/touchscreen/xpt2046.h +2 -2
  708. esphome/config.py +3 -2
  709. esphome/config_validation.py +46 -17
  710. esphome/const.py +10 -1
  711. esphome/core/__init__.py +37 -18
  712. esphome/core/application.cpp +197 -8
  713. esphome/core/application.h +116 -6
  714. esphome/core/component.cpp +36 -15
  715. esphome/core/component.h +43 -13
  716. esphome/core/config.py +12 -0
  717. esphome/core/defines.h +10 -2
  718. esphome/core/entity_base.cpp +4 -16
  719. esphome/core/entity_base.h +27 -13
  720. esphome/core/helpers.cpp +1 -1
  721. esphome/core/helpers.h +5 -5
  722. esphome/core/log.h +2 -0
  723. esphome/core/log_const_en.h +4 -0
  724. esphome/core/scheduler.cpp +2 -2
  725. esphome/coroutine.py +3 -4
  726. esphome/cpp_generator.py +32 -32
  727. esphome/dashboard/core.py +2 -2
  728. esphome/dashboard/web_server.py +2 -2
  729. esphome/git.py +4 -4
  730. esphome/helpers.py +5 -6
  731. esphome/loader.py +8 -7
  732. esphome/log.py +7 -1
  733. esphome/platformio_api.py +2 -3
  734. esphome/storage_json.py +13 -5
  735. esphome/types.py +12 -13
  736. esphome/util.py +1 -2
  737. esphome/wizard.py +0 -16
  738. esphome/writer.py +5 -3
  739. esphome/yaml_util.py +6 -1
  740. esphome/zeroconf.py +1 -1
  741. {esphome-2025.5.2.dist-info → esphome-2025.6.0b2.dist-info}/METADATA +12 -11
  742. {esphome-2025.5.2.dist-info → esphome-2025.6.0b2.dist-info}/RECORD +746 -692
  743. {esphome-2025.5.2.dist-info → esphome-2025.6.0b2.dist-info}/WHEEL +1 -1
  744. {esphome-2025.5.2.dist-info → esphome-2025.6.0b2.dist-info}/entry_points.txt +0 -0
  745. {esphome-2025.5.2.dist-info → esphome-2025.6.0b2.dist-info}/licenses/LICENSE +0 -0
  746. {esphome-2025.5.2.dist-info → esphome-2025.6.0b2.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
  });
@@ -47,7 +66,7 @@ void Application::setup() {
47
66
  [](Component *a, Component *b) { return a->get_loop_priority() > b->get_loop_priority(); });
48
67
 
49
68
  do {
50
- uint32_t new_app_state = STATUS_LED_WARNING;
69
+ uint8_t new_app_state = STATUS_LED_WARNING;
51
70
  this->scheduler.call();
52
71
  this->feed_wdt();
53
72
  for (uint32_t j = 0; j <= i; j++) {
@@ -68,7 +87,7 @@ void Application::setup() {
68
87
  this->calculate_looping_components_();
69
88
  }
70
89
  void Application::loop() {
71
- uint32_t new_app_state = 0;
90
+ uint8_t new_app_state = 0;
72
91
 
73
92
  this->scheduler.call();
74
93
 
@@ -98,7 +117,9 @@ void Application::loop() {
98
117
  // Use the last component's end time instead of calling millis() again
99
118
  auto elapsed = last_op_end_time - this->last_loop_;
100
119
  if (elapsed >= this->loop_interval_ || HighFrequencyLoopRequester::is_high_frequency()) {
101
- yield();
120
+ // Even if we overran the loop interval, we still need to select()
121
+ // to know if any sockets have data ready
122
+ this->yield_with_select_(0);
102
123
  } else {
103
124
  uint32_t delay_time = this->loop_interval_ - elapsed;
104
125
  uint32_t next_schedule = this->scheduler.next_schedule_in().value_or(delay_time);
@@ -106,7 +127,8 @@ void Application::loop() {
106
127
  // otherwise interval=0 schedules result in constant looping with almost no sleep
107
128
  next_schedule = std::max(next_schedule, delay_time / 2);
108
129
  delay_time = std::min(next_schedule, delay_time);
109
- delay(delay_time);
130
+
131
+ this->yield_with_select_(delay_time);
110
132
  }
111
133
  this->last_loop_ = last_op_end_time;
112
134
 
@@ -139,15 +161,17 @@ void IRAM_ATTR HOT Application::feed_wdt(uint32_t time) {
139
161
  }
140
162
  }
141
163
  void Application::reboot() {
142
- ESP_LOGI(TAG, "Forcing a reboot...");
164
+ ESP_LOGI(TAG, "Forcing a reboot");
143
165
  for (auto it = this->components_.rbegin(); it != this->components_.rend(); ++it) {
144
166
  (*it)->on_shutdown();
145
167
  }
146
168
  arch_restart();
147
169
  }
148
170
  void Application::safe_reboot() {
149
- ESP_LOGI(TAG, "Rebooting safely...");
171
+ ESP_LOGI(TAG, "Rebooting safely");
150
172
  run_safe_shutdown_hooks();
173
+ teardown_components(TEARDOWN_TIMEOUT_REBOOT_MS);
174
+ run_powerdown_hooks();
151
175
  arch_restart();
152
176
  }
153
177
 
@@ -160,6 +184,56 @@ void Application::run_safe_shutdown_hooks() {
160
184
  }
161
185
  }
162
186
 
187
+ void Application::run_powerdown_hooks() {
188
+ for (auto it = this->components_.rbegin(); it != this->components_.rend(); ++it) {
189
+ (*it)->on_powerdown();
190
+ }
191
+ }
192
+
193
+ void Application::teardown_components(uint32_t timeout_ms) {
194
+ uint32_t start_time = millis();
195
+
196
+ // Copy all components in reverse order using reverse iterators
197
+ // Reverse order matches the behavior of run_safe_shutdown_hooks() above and ensures
198
+ // components are torn down in the opposite order of their setup_priority (which is
199
+ // used to sort components during Application::setup())
200
+ std::vector<Component *> pending_components(this->components_.rbegin(), this->components_.rend());
201
+
202
+ uint32_t now = start_time;
203
+ while (!pending_components.empty() && (now - start_time) < timeout_ms) {
204
+ // Feed watchdog during teardown to prevent triggering
205
+ this->feed_wdt(now);
206
+
207
+ // Use iterator to safely erase elements
208
+ for (auto it = pending_components.begin(); it != pending_components.end();) {
209
+ if ((*it)->teardown()) {
210
+ // Component finished teardown, erase it
211
+ it = pending_components.erase(it);
212
+ } else {
213
+ // Component still needs time
214
+ ++it;
215
+ }
216
+ }
217
+
218
+ // Give some time for I/O operations if components are still pending
219
+ if (!pending_components.empty()) {
220
+ this->yield_with_select_(1);
221
+ }
222
+
223
+ // Update time for next iteration
224
+ now = millis();
225
+ }
226
+
227
+ if (!pending_components.empty()) {
228
+ // Note: At this point, connections are either disconnected or in a bad state,
229
+ // so this warning will only appear via serial rather than being transmitted to clients
230
+ for (auto *component : pending_components) {
231
+ ESP_LOGW(TAG, "%s did not complete teardown within %" PRIu32 " ms", component->get_component_source(),
232
+ timeout_ms);
233
+ }
234
+ }
235
+ }
236
+
163
237
  void Application::calculate_looping_components_() {
164
238
  for (auto *obj : this->components_) {
165
239
  if (obj->has_overridden_loop())
@@ -167,6 +241,121 @@ void Application::calculate_looping_components_() {
167
241
  }
168
242
  }
169
243
 
244
+ #ifdef USE_SOCKET_SELECT_SUPPORT
245
+ bool Application::register_socket_fd(int fd) {
246
+ // WARNING: This function is NOT thread-safe and must only be called from the main loop
247
+ // It modifies socket_fds_ and related variables without locking
248
+ if (fd < 0)
249
+ return false;
250
+
251
+ if (fd >= FD_SETSIZE) {
252
+ ESP_LOGE(TAG, "Cannot monitor socket fd %d: exceeds FD_SETSIZE (%d)", fd, FD_SETSIZE);
253
+ ESP_LOGE(TAG, "Socket will not be monitored for data - may cause performance issues!");
254
+ return false;
255
+ }
256
+
257
+ this->socket_fds_.push_back(fd);
258
+ this->socket_fds_changed_ = true;
259
+
260
+ if (fd > this->max_fd_) {
261
+ this->max_fd_ = fd;
262
+ }
263
+
264
+ return true;
265
+ }
266
+
267
+ void Application::unregister_socket_fd(int fd) {
268
+ // WARNING: This function is NOT thread-safe and must only be called from the main loop
269
+ // It modifies socket_fds_ and related variables without locking
270
+ if (fd < 0)
271
+ return;
272
+
273
+ auto it = std::find(this->socket_fds_.begin(), this->socket_fds_.end(), fd);
274
+ if (it != this->socket_fds_.end()) {
275
+ // Swap with last element and pop - O(1) removal since order doesn't matter
276
+ if (it != this->socket_fds_.end() - 1) {
277
+ std::swap(*it, this->socket_fds_.back());
278
+ }
279
+ this->socket_fds_.pop_back();
280
+ this->socket_fds_changed_ = true;
281
+
282
+ // Only recalculate max_fd if we removed the current max
283
+ if (fd == this->max_fd_) {
284
+ if (this->socket_fds_.empty()) {
285
+ this->max_fd_ = -1;
286
+ } else {
287
+ // Find new max using std::max_element
288
+ this->max_fd_ = *std::max_element(this->socket_fds_.begin(), this->socket_fds_.end());
289
+ }
290
+ }
291
+ }
292
+ }
293
+
294
+ bool Application::is_socket_ready(int fd) const {
295
+ // This function is thread-safe for reading the result of select()
296
+ // However, it should only be called after select() has been executed in the main loop
297
+ // The read_fds_ is only modified by select() in the main loop
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::yield_with_select_(uint32_t delay_ms) {
306
+ // Delay while monitoring sockets. When delay_ms is 0, always yield() to ensure other tasks run
307
+ // since select() with 0 timeout only polls without yielding.
308
+ #ifdef USE_SOCKET_SELECT_SUPPORT
309
+ if (!this->socket_fds_.empty()) {
310
+ // Update fd_set if socket list has changed
311
+ if (this->socket_fds_changed_) {
312
+ FD_ZERO(&this->base_read_fds_);
313
+ for (int fd : this->socket_fds_) {
314
+ if (fd >= 0 && fd < FD_SETSIZE) {
315
+ FD_SET(fd, &this->base_read_fds_);
316
+ }
317
+ }
318
+ this->socket_fds_changed_ = false;
319
+ }
320
+
321
+ // Copy base fd_set before each select
322
+ this->read_fds_ = this->base_read_fds_;
323
+
324
+ // Convert delay_ms to timeval
325
+ struct timeval tv;
326
+ tv.tv_sec = delay_ms / 1000;
327
+ tv.tv_usec = (delay_ms - tv.tv_sec * 1000) * 1000;
328
+
329
+ // Call select with timeout
330
+ #if defined(USE_SOCKET_IMPL_LWIP_SOCKETS) || (defined(USE_ESP32) && defined(USE_SOCKET_IMPL_BSD_SOCKETS))
331
+ int ret = lwip_select(this->max_fd_ + 1, &this->read_fds_, nullptr, nullptr, &tv);
332
+ #else
333
+ int ret = ::select(this->max_fd_ + 1, &this->read_fds_, nullptr, nullptr, &tv);
334
+ #endif
335
+
336
+ // Process select() result:
337
+ // ret < 0: error (except EINTR which is normal)
338
+ // ret > 0: socket(s) have data ready - normal and expected
339
+ // ret == 0: timeout occurred - normal and expected
340
+ if (ret < 0 && errno != EINTR) {
341
+ // Actual error - log and fall back to delay
342
+ ESP_LOGW(TAG, "select() failed with errno %d", errno);
343
+ delay(delay_ms);
344
+ }
345
+ // When delay_ms is 0, we need to yield since select(0) doesn't yield
346
+ if (delay_ms == 0) {
347
+ yield();
348
+ }
349
+ } else {
350
+ // No sockets registered, use regular delay
351
+ delay(delay_ms);
352
+ }
353
+ #else
354
+ // No select support, use regular delay
355
+ delay(delay_ms);
356
+ #endif
357
+ }
358
+
170
359
  Application App; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
171
360
 
172
361
  } // 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,10 +79,16 @@
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
- void pre_setup(const std::string &name, const std::string &friendly_name, const std::string &area,
81
- const char *comment, const char *compilation_time, bool name_add_mac_suffix) {
90
+ void pre_setup(const std::string &name, const std::string &friendly_name, const char *area, const char *comment,
91
+ const char *compilation_time, bool name_add_mac_suffix) {
82
92
  arch_init();
83
93
  this->name_add_mac_suffix_ = name_add_mac_suffix;
84
94
  if (name_add_mac_suffix) {
@@ -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");
@@ -208,7 +285,7 @@ class Application {
208
285
  const std::string &get_friendly_name() const { return this->friendly_name_; }
209
286
 
210
287
  /// Get the area of this Application set by pre_setup().
211
- const std::string &get_area() const { return this->area_; }
288
+ std::string get_area() const { return this->area_ == nullptr ? "" : this->area_; }
212
289
 
213
290
  /// Get the comment of this Application set by pre_setup().
214
291
  std::string get_comment() const { return this->comment_; }
@@ -247,7 +324,15 @@ class Application {
247
324
 
248
325
  void run_safe_shutdown_hooks();
249
326
 
250
- uint32_t get_app_state() const { return this->app_state_; }
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
+
335
+ uint8_t get_app_state() const { return this->app_state_; }
251
336
 
252
337
  #ifdef USE_BINARY_SENSOR
253
338
  const std::vector<binary_sensor::BinarySensor *> &get_binary_sensors() { return this->binary_sensors_; }
@@ -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 yield_with_select_(uint32_t delay_ms);
579
+
479
580
  std::vector<Component *> components_{};
480
581
  std::vector<Component *> looping_components_{};
481
582
 
@@ -545,16 +646,25 @@ class Application {
545
646
 
546
647
  std::string name_;
547
648
  std::string friendly_name_;
548
- std::string area_;
649
+ const char *area_{nullptr};
549
650
  const char *comment_{nullptr};
550
651
  const char *compilation_time_{nullptr};
551
652
  bool name_add_mac_suffix_;
552
653
  uint32_t last_loop_{0};
553
654
  uint32_t loop_interval_{16};
554
655
  size_t dump_config_at_{SIZE_MAX};
555
- uint32_t app_state_{0};
656
+ uint8_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.