esphome 2025.6.2__py3-none-any.whl → 2025.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (648) hide show
  1. esphome/__main__.py +1 -3
  2. esphome/codegen.py +2 -0
  3. esphome/components/ac_dimmer/ac_dimmer.cpp +6 -6
  4. esphome/components/adc/__init__.py +25 -1
  5. esphome/components/adc/adc_sensor.h +11 -11
  6. esphome/components/adc/adc_sensor_common.cpp +1 -1
  7. esphome/components/adc/adc_sensor_esp32.cpp +16 -8
  8. esphome/components/ade7880/ade7880.h +0 -2
  9. esphome/components/ads1115/ads1115.h +0 -1
  10. esphome/components/ads1118/ads1118.h +0 -1
  11. esphome/components/ags10/ags10.h +0 -2
  12. esphome/components/aic3204/aic3204.h +0 -1
  13. esphome/components/alarm_control_panel/__init__.py +5 -2
  14. esphome/components/alpha3/alpha3.h +0 -1
  15. esphome/components/am43/cover/am43_cover.h +0 -1
  16. esphome/components/am43/sensor/am43_sensor.h +0 -1
  17. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +0 -2
  18. esphome/components/anova/anova.cpp +5 -1
  19. esphome/components/anova/anova.h +0 -1
  20. esphome/components/apds9960/apds9960.cpp +1 -1
  21. esphome/components/api/__init__.py +57 -21
  22. esphome/components/api/api_connection.cpp +344 -539
  23. esphome/components/api/api_connection.h +224 -141
  24. esphome/components/api/api_frame_helper.cpp +91 -127
  25. esphome/components/api/api_frame_helper.h +64 -54
  26. esphome/components/api/api_pb2.cpp +1837 -9044
  27. esphome/components/api/api_pb2.h +532 -685
  28. esphome/components/api/api_pb2_dump.cpp +4432 -0
  29. esphome/components/api/api_pb2_service.cpp +184 -425
  30. esphome/components/api/api_pb2_service.h +13 -6
  31. esphome/components/api/api_server.cpp +131 -167
  32. esphome/components/api/api_server.h +38 -10
  33. esphome/components/api/client.py +10 -4
  34. esphome/components/api/custom_api_device.h +8 -0
  35. esphome/components/api/list_entities.cpp +37 -104
  36. esphome/components/api/list_entities.h +33 -23
  37. esphome/components/api/proto.h +532 -26
  38. esphome/components/api/subscribe_state.cpp +23 -29
  39. esphome/components/api/subscribe_state.h +26 -19
  40. esphome/components/api/user_services.h +2 -0
  41. esphome/components/as3935_spi/as3935_spi.h +0 -2
  42. esphome/components/as5600/as5600.h +0 -1
  43. esphome/components/async_tcp/__init__.py +14 -5
  44. esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
  45. esphome/components/atm90e32/atm90e32.cpp +2 -1
  46. esphome/components/audio/audio_decoder.cpp +1 -1
  47. esphome/components/audio/audio_transfer_buffer.cpp +2 -2
  48. esphome/components/b_parasite/b_parasite.h +0 -1
  49. esphome/components/bedjet/bedjet_hub.cpp +5 -1
  50. esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
  51. esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
  52. esphome/components/bh1750/bh1750.cpp +5 -5
  53. esphome/components/binary_sensor/__init__.py +82 -5
  54. esphome/components/binary_sensor/automation.h +19 -1
  55. esphome/components/binary_sensor/binary_sensor.cpp +12 -30
  56. esphome/components/binary_sensor/binary_sensor.h +11 -25
  57. esphome/components/binary_sensor/filter.cpp +29 -24
  58. esphome/components/binary_sensor/filter.h +20 -10
  59. esphome/components/ble_client/output/ble_binary_output.h +0 -1
  60. esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
  61. esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
  62. esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
  63. esphome/components/ble_client/sensor/ble_sensor.h +0 -1
  64. esphome/components/ble_client/switch/ble_switch.h +0 -1
  65. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
  66. esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
  67. esphome/components/ble_presence/ble_presence_device.h +0 -1
  68. esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
  69. esphome/components/ble_scanner/ble_scanner.h +0 -1
  70. esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
  71. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
  72. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
  73. esphome/components/bme680/sensor.py +1 -1
  74. esphome/components/bmp581/bmp581.h +0 -2
  75. esphome/components/button/__init__.py +5 -2
  76. esphome/components/camera/__init__.py +1 -0
  77. esphome/components/camera/camera.cpp +22 -0
  78. esphome/components/camera/camera.h +80 -0
  79. esphome/components/canbus/__init__.py +1 -0
  80. esphome/components/cap1188/cap1188.h +0 -1
  81. esphome/components/captive_portal/__init__.py +12 -2
  82. esphome/components/captive_portal/captive_portal.cpp +12 -2
  83. esphome/components/captive_portal/captive_portal.h +5 -2
  84. esphome/components/ccs811/ccs811.h +0 -2
  85. esphome/components/climate/__init__.py +5 -2
  86. esphome/components/cm1106/sensor.py +2 -2
  87. esphome/components/const/__init__.py +2 -0
  88. esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
  89. esphome/components/copy/button/copy_button.h +0 -1
  90. esphome/components/copy/cover/copy_cover.h +0 -1
  91. esphome/components/copy/fan/copy_fan.h +0 -1
  92. esphome/components/copy/lock/copy_lock.h +0 -1
  93. esphome/components/copy/number/copy_number.h +0 -1
  94. esphome/components/copy/select/copy_select.h +0 -1
  95. esphome/components/copy/sensor/copy_sensor.h +0 -1
  96. esphome/components/copy/switch/copy_switch.h +0 -1
  97. esphome/components/copy/text/copy_text.h +0 -1
  98. esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
  99. esphome/components/cover/__init__.py +5 -2
  100. esphome/components/cs5460a/cs5460a.h +0 -1
  101. esphome/components/datetime/__init__.py +4 -2
  102. esphome/components/debug/__init__.py +20 -0
  103. esphome/components/debug/debug_esp32.cpp +2 -0
  104. esphome/components/deep_sleep/__init__.py +43 -9
  105. esphome/components/demo/__init__.py +2 -2
  106. esphome/components/display/display.cpp +4 -3
  107. esphome/components/display/display.h +0 -2
  108. esphome/components/display/display_buffer.cpp +1 -1
  109. esphome/components/ds2484/__init__.py +1 -0
  110. esphome/components/ds2484/ds2484.cpp +209 -0
  111. esphome/components/ds2484/ds2484.h +43 -0
  112. esphome/components/ds2484/one_wire.py +37 -0
  113. esphome/components/duty_time/duty_time_sensor.h +0 -1
  114. esphome/components/ens160_base/ens160_base.h +0 -1
  115. esphome/components/es7210/es7210.h +0 -1
  116. esphome/components/es7243e/es7243e.h +0 -1
  117. esphome/components/es8156/es8156.h +0 -1
  118. esphome/components/es8311/es8311.h +0 -1
  119. esphome/components/es8388/es8388.h +0 -1
  120. esphome/components/esp32/__init__.py +103 -135
  121. esphome/components/esp32/core.cpp +0 -4
  122. esphome/components/esp32/gpio.h +1 -1
  123. esphome/components/esp32/helpers.cpp +69 -0
  124. esphome/components/esp32_ble/ble.cpp +5 -6
  125. esphome/components/esp32_ble/ble.h +29 -14
  126. esphome/components/esp32_ble/ble_event.h +6 -6
  127. esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
  128. esphome/components/esp32_ble_client/ble_client_base.h +24 -9
  129. esphome/components/esp32_ble_tracker/__init__.py +2 -8
  130. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
  131. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
  132. esphome/components/esp32_camera/__init__.py +112 -98
  133. esphome/components/esp32_camera/esp32_camera.cpp +41 -31
  134. esphome/components/esp32_camera/esp32_camera.h +35 -30
  135. esphome/components/esp32_camera_web_server/__init__.py +2 -1
  136. esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
  137. esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
  138. esphome/components/esp32_hall/sensor.py +2 -21
  139. esphome/components/esp32_hosted/__init__.py +101 -0
  140. esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
  141. esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
  142. esphome/components/esp32_rmt/__init__.py +0 -58
  143. esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
  144. esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
  145. esphome/components/esp32_rmt_led_strip/light.py +14 -76
  146. esphome/components/esp32_touch/esp32_touch.h +174 -28
  147. esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
  148. esphome/components/esp32_touch/esp32_touch_v1.cpp +240 -0
  149. esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
  150. esphome/components/esp8266/__init__.py +2 -0
  151. esphome/components/esp8266/gpio.cpp +10 -10
  152. esphome/components/esp8266/helpers.cpp +31 -0
  153. esphome/components/esp_ldo/__init__.py +10 -8
  154. esphome/components/esp_ldo/esp_ldo.h +3 -0
  155. esphome/components/esphome/ota/__init__.py +1 -0
  156. esphome/components/esphome/ota/ota_esphome.cpp +24 -19
  157. esphome/components/ethernet/__init__.py +42 -23
  158. esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
  159. esphome/components/ethernet/ethernet_component.cpp +69 -29
  160. esphome/components/ethernet/ethernet_component.h +18 -10
  161. esphome/components/event/__init__.py +5 -2
  162. esphome/components/ezo/ezo.h +0 -1
  163. esphome/components/ezo_pmp/ezo_pmp.h +0 -1
  164. esphome/components/fan/__init__.py +5 -2
  165. esphome/components/fan/fan.cpp +4 -0
  166. esphome/components/feedback/feedback_cover.h +0 -1
  167. esphome/components/font/__init__.py +92 -82
  168. esphome/components/font/font.cpp +9 -2
  169. esphome/components/font/font.h +20 -5
  170. esphome/components/fs3000/fs3000.h +0 -1
  171. esphome/components/gcja5/gcja5.h +0 -1
  172. esphome/components/gl_r01_i2c/__init__.py +0 -0
  173. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
  174. esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
  175. esphome/components/gl_r01_i2c/sensor.py +36 -0
  176. esphome/components/gp8403/gp8403.h +0 -1
  177. esphome/components/gpio/binary_sensor/__init__.py +39 -1
  178. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
  179. esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
  180. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
  181. esphome/components/he60r/he60r.h +0 -1
  182. esphome/components/heatpumpir/climate.py +2 -1
  183. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  184. esphome/components/heatpumpir/heatpumpir.h +1 -0
  185. esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
  186. esphome/components/host/__init__.py +3 -1
  187. esphome/components/host/helpers.cpp +57 -0
  188. esphome/components/http_request/__init__.py +19 -1
  189. esphome/components/http_request/http_request.h +1 -1
  190. esphome/components/http_request/http_request_arduino.cpp +0 -1
  191. esphome/components/http_request/http_request_arduino.h +1 -0
  192. esphome/components/http_request/http_request_idf.cpp +0 -1
  193. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  194. esphome/components/http_request/update/http_request_update.cpp +35 -16
  195. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +3 -9
  196. esphome/components/hydreon_rgxx/sensor.py +1 -1
  197. esphome/components/i2c/__init__.py +23 -11
  198. esphome/components/i2c/i2c_bus.h +8 -1
  199. esphome/components/i2c/i2c_bus_arduino.cpp +4 -3
  200. esphome/components/i2c/i2c_bus_arduino.h +6 -3
  201. esphome/components/i2c/i2c_bus_esp_idf.h +5 -3
  202. esphome/components/i2c_device/i2c_device.h +0 -1
  203. esphome/components/i2s_audio/__init__.py +2 -10
  204. esphome/components/i2s_audio/i2s_audio.cpp +1 -5
  205. esphome/components/i2s_audio/media_player/__init__.py +2 -2
  206. esphome/components/i2s_audio/speaker/__init__.py +1 -1
  207. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +2 -2
  208. esphome/components/iaqcore/iaqcore.h +0 -2
  209. esphome/components/image/__init__.py +123 -24
  210. esphome/components/improv_serial/improv_serial_component.cpp +0 -4
  211. esphome/components/ina219/ina219.cpp +7 -0
  212. esphome/components/ina219/ina219.h +1 -0
  213. esphome/components/ina260/ina260.h +0 -2
  214. esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h +0 -1
  215. esphome/components/inkplate6/display.py +15 -0
  216. esphome/components/inkplate6/inkplate.cpp +2 -2
  217. esphome/components/integration/integration_sensor.h +0 -1
  218. esphome/components/internal_temperature/internal_temperature.cpp +8 -27
  219. esphome/components/internal_temperature/sensor.py +0 -26
  220. esphome/components/interval/interval.h +0 -2
  221. esphome/components/json/__init__.py +1 -1
  222. esphome/components/json/json_util.cpp +56 -63
  223. esphome/components/ld2410/button/__init__.py +3 -3
  224. esphome/components/ld2410/button/factory_reset_button.cpp +9 -0
  225. esphome/components/ld2410/button/{reset_button.h → factory_reset_button.h} +2 -2
  226. esphome/components/ld2410/ld2410.cpp +421 -268
  227. esphome/components/ld2410/ld2410.h +44 -146
  228. esphome/components/ld2410/number/__init__.py +2 -2
  229. esphome/components/ld2410/sensor.py +1 -1
  230. esphome/components/ld2410/switch/__init__.py +1 -1
  231. esphome/components/ld2420/binary_sensor/ld2420_binary_sensor.cpp +2 -2
  232. esphome/components/ld2420/button/reconfig_buttons.cpp +1 -1
  233. esphome/components/ld2420/ld2420.cpp +252 -147
  234. esphome/components/ld2420/ld2420.h +52 -126
  235. esphome/components/ld2420/number/__init__.py +2 -2
  236. esphome/components/ld2420/number/gate_config_number.cpp +1 -1
  237. esphome/components/ld2420/select/operating_mode_select.cpp +1 -1
  238. esphome/components/ld2420/sensor/__init__.py +6 -2
  239. esphome/components/ld2420/sensor/ld2420_sensor.cpp +2 -2
  240. esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
  241. esphome/components/ld2420/text_sensor/text_sensor.cpp +2 -2
  242. esphome/components/ld2450/button/__init__.py +3 -3
  243. esphome/components/ld2450/button/factory_reset_button.cpp +9 -0
  244. esphome/components/ld2450/button/{reset_button.h → factory_reset_button.h} +2 -2
  245. esphome/components/ld2450/ld2450.cpp +384 -232
  246. esphome/components/ld2450/ld2450.h +60 -69
  247. esphome/components/ld2450/switch/__init__.py +1 -1
  248. esphome/components/ledc/ledc_output.cpp +1 -63
  249. esphome/components/libretiny/__init__.py +5 -3
  250. esphome/components/libretiny/const.py +5 -0
  251. esphome/components/libretiny/generate_components.py +1 -0
  252. esphome/components/libretiny/helpers.cpp +35 -0
  253. esphome/components/libretiny/lt_component.cpp +5 -3
  254. esphome/components/light/__init__.py +4 -2
  255. esphome/components/light/addressable_light.h +3 -3
  256. esphome/components/light/light_call.cpp +180 -243
  257. esphome/components/light/light_call.h +72 -20
  258. esphome/components/light/light_color_values.h +14 -14
  259. esphome/components/light/light_json_schema.cpp +17 -16
  260. esphome/components/light/light_state.h +15 -13
  261. esphome/components/light/transformers.h +2 -2
  262. esphome/components/ln882x/__init__.py +52 -0
  263. esphome/components/ln882x/boards.py +285 -0
  264. esphome/components/lock/__init__.py +5 -2
  265. esphome/components/logger/__init__.py +40 -3
  266. esphome/components/logger/logger.cpp +47 -12
  267. esphome/components/logger/logger.h +80 -49
  268. esphome/components/logger/logger_esp32.cpp +3 -3
  269. esphome/components/lps22/__init__.py +0 -0
  270. esphome/components/lps22/lps22.cpp +75 -0
  271. esphome/components/lps22/lps22.h +27 -0
  272. esphome/components/lps22/sensor.py +58 -0
  273. esphome/components/ltr390/ltr390.h +0 -1
  274. esphome/components/ltr501/ltr501.h +0 -1
  275. esphome/components/ltr_als_ps/ltr_als_ps.h +0 -1
  276. esphome/components/lvgl/__init__.py +1 -1
  277. esphome/components/lvgl/schemas.py +66 -6
  278. esphome/components/lvgl/styles.py +24 -16
  279. esphome/components/lvgl/widgets/__init__.py +12 -2
  280. esphome/components/lvgl/widgets/lv_bar.py +40 -19
  281. esphome/components/lvgl/widgets/meter.py +20 -13
  282. esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +1 -1
  283. esphome/components/max9611/max9611.h +0 -1
  284. esphome/components/mcp23016/__init__.py +1 -1
  285. esphome/components/mcp23xxx_base/__init__.py +1 -1
  286. esphome/components/mcp4461/__init__.py +1 -1
  287. esphome/components/mcp4461/output/__init__.py +3 -2
  288. esphome/components/mcp9600/mcp9600.h +0 -2
  289. esphome/components/md5/md5.cpp +3 -3
  290. esphome/components/md5/md5.h +1 -6
  291. esphome/components/mdns/__init__.py +22 -11
  292. esphome/components/media_player/__init__.py +4 -3
  293. esphome/components/micro_wake_word/__init__.py +1 -5
  294. esphome/components/micro_wake_word/streaming_model.cpp +2 -2
  295. esphome/components/microphone/microphone.cpp +7 -9
  296. esphome/components/microphone/microphone.h +0 -2
  297. esphome/components/mipi_spi/display.py +1 -0
  298. esphome/components/mmc5603/mmc5603.cpp +1 -1
  299. esphome/components/modbus/modbus.cpp +33 -15
  300. esphome/components/modbus/modbus.h +9 -0
  301. esphome/components/modbus_controller/__init__.py +42 -10
  302. esphome/components/modbus_controller/modbus_controller.cpp +92 -11
  303. esphome/components/modbus_controller/modbus_controller.h +61 -7
  304. esphome/components/mopeka_pro_check/mopeka_pro_check.h +0 -1
  305. esphome/components/mopeka_std_check/mopeka_std_check.h +0 -1
  306. esphome/components/mpl3115a2/mpl3115a2.h +0 -2
  307. esphome/components/mqtt/__init__.py +16 -0
  308. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +2 -1
  309. esphome/components/mqtt/mqtt_backend.h +2 -1
  310. esphome/components/mqtt/mqtt_backend_esp32.cpp +132 -47
  311. esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
  312. esphome/components/mqtt/mqtt_binary_sensor.cpp +1 -0
  313. esphome/components/mqtt/mqtt_button.cpp +4 -1
  314. esphome/components/mqtt/mqtt_client.cpp +17 -9
  315. esphome/components/mqtt/mqtt_client.h +8 -3
  316. esphome/components/mqtt/mqtt_climate.cpp +6 -4
  317. esphome/components/mqtt/mqtt_component.cpp +3 -1
  318. esphome/components/mqtt/mqtt_cover.cpp +1 -0
  319. esphome/components/mqtt/mqtt_date.cpp +4 -3
  320. esphome/components/mqtt/mqtt_datetime.cpp +7 -6
  321. esphome/components/mqtt/mqtt_event.cpp +6 -3
  322. esphome/components/mqtt/mqtt_fan.cpp +1 -0
  323. esphome/components/mqtt/mqtt_light.cpp +8 -4
  324. esphome/components/mqtt/mqtt_lock.cpp +3 -1
  325. esphome/components/mqtt/mqtt_number.cpp +1 -0
  326. esphome/components/mqtt/mqtt_select.cpp +2 -1
  327. esphome/components/mqtt/mqtt_sensor.cpp +3 -1
  328. esphome/components/mqtt/mqtt_switch.cpp +3 -1
  329. esphome/components/mqtt/mqtt_text.cpp +1 -0
  330. esphome/components/mqtt/mqtt_text_sensor.cpp +3 -1
  331. esphome/components/mqtt/mqtt_time.cpp +4 -3
  332. esphome/components/mqtt/mqtt_update.cpp +1 -0
  333. esphome/components/mqtt/mqtt_valve.cpp +3 -1
  334. esphome/components/ms8607/ms8607.cpp +1 -1
  335. esphome/components/ms8607/ms8607.h +0 -1
  336. esphome/components/neopixelbus/light.py +4 -1
  337. esphome/components/neopixelbus/neopixelbus_light.h +1 -1
  338. esphome/components/network/__init__.py +4 -1
  339. esphome/components/network/ip_address.h +1 -0
  340. esphome/components/nextion/__init__.py +16 -0
  341. esphome/components/nextion/base_component.py +1 -0
  342. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
  343. esphome/components/nextion/display.py +14 -4
  344. esphome/components/nextion/nextion.cpp +166 -101
  345. esphome/components/nextion/nextion.h +84 -53
  346. esphome/components/nextion/nextion_commands.cpp +11 -10
  347. esphome/components/nextion/nextion_component.cpp +28 -28
  348. esphome/components/nextion/nextion_component.h +53 -18
  349. esphome/components/nextion/nextion_component_base.h +3 -0
  350. esphome/components/nextion/nextion_upload.cpp +36 -0
  351. esphome/components/nextion/nextion_upload_arduino.cpp +10 -35
  352. esphome/components/nextion/nextion_upload_idf.cpp +9 -33
  353. esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
  354. esphome/components/nextion/switch/nextion_switch.cpp +1 -1
  355. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
  356. esphome/components/nfc/nfc.cpp +3 -22
  357. esphome/components/nfc/nfc.h +3 -3
  358. esphome/components/number/__init__.py +5 -2
  359. esphome/components/online_image/__init__.py +9 -1
  360. esphome/components/online_image/online_image.cpp +17 -7
  361. esphome/components/online_image/online_image.h +10 -2
  362. esphome/components/opentherm/opentherm.cpp +7 -12
  363. esphome/components/opentherm/output/output.cpp +1 -1
  364. esphome/components/openthread/__init__.py +47 -40
  365. esphome/components/openthread/const.py +1 -0
  366. esphome/components/openthread/openthread_esp.cpp +27 -5
  367. esphome/components/opt3001/__init__.py +0 -0
  368. esphome/components/opt3001/opt3001.cpp +122 -0
  369. esphome/components/opt3001/opt3001.h +27 -0
  370. esphome/components/opt3001/sensor.py +35 -0
  371. esphome/components/ota/__init__.py +17 -0
  372. esphome/components/ota/ota_backend.h +27 -1
  373. esphome/components/ota/ota_backend_arduino_esp32.cpp +12 -2
  374. esphome/components/ota/ota_backend_arduino_esp32.h +3 -0
  375. esphome/components/ota/ota_backend_arduino_esp8266.cpp +18 -4
  376. esphome/components/ota/ota_backend_arduino_esp8266.h +3 -0
  377. esphome/components/ota/ota_backend_arduino_libretiny.cpp +12 -2
  378. esphome/components/ota/ota_backend_arduino_libretiny.h +3 -0
  379. esphome/components/ota/ota_backend_arduino_rp2040.cpp +9 -2
  380. esphome/components/ota/ota_backend_arduino_rp2040.h +3 -0
  381. esphome/components/ota/ota_backend_esp_idf.cpp +10 -16
  382. esphome/components/ota/ota_backend_esp_idf.h +1 -0
  383. esphome/components/packages/__init__.py +5 -2
  384. esphome/components/packet_transport/binary_sensor.py +61 -4
  385. esphome/components/packet_transport/packet_transport.cpp +34 -1
  386. esphome/components/packet_transport/packet_transport.h +11 -5
  387. esphome/components/pcf8574/__init__.py +1 -1
  388. esphome/components/pi4ioe5v6408/__init__.py +84 -0
  389. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +171 -0
  390. esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +70 -0
  391. esphome/components/pmsa003i/pmsa003i.h +0 -1
  392. esphome/components/pmsx003/pmsx003.h +0 -1
  393. esphome/components/pn7150/pn7150.cpp +7 -7
  394. esphome/components/pn7150/pn7150.h +0 -1
  395. esphome/components/pn7160/pn7160.cpp +7 -7
  396. esphome/components/pn7160/pn7160.h +0 -1
  397. esphome/components/preferences/syncer.h +2 -0
  398. esphome/components/prometheus/prometheus_handler.h +1 -1
  399. esphome/components/psram/psram.cpp +0 -20
  400. esphome/components/pulse_counter/pulse_counter_sensor.h +0 -1
  401. esphome/components/pulse_meter/pulse_meter_sensor.cpp +8 -4
  402. esphome/components/pulse_width/pulse_width.h +0 -1
  403. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +0 -4
  404. esphome/components/pvvx_mithermometer/display/pvvx_display.h +0 -2
  405. esphome/components/pvvx_mithermometer/pvvx_mithermometer.h +0 -1
  406. esphome/components/qr_code/__init__.py +13 -10
  407. esphome/components/qwiic_pir/qwiic_pir.h +0 -1
  408. esphome/components/radon_eye_ble/radon_eye_listener.cpp +1 -1
  409. esphome/components/rc522/rc522.h +0 -1
  410. esphome/components/rdm6300/rdm6300.h +0 -2
  411. esphome/components/remote_base/__init__.py +7 -5
  412. esphome/components/remote_base/remote_base.cpp +24 -21
  413. esphome/components/remote_base/remote_base.h +3 -26
  414. esphome/components/remote_receiver/__init__.py +40 -46
  415. esphome/components/remote_receiver/remote_receiver.h +4 -18
  416. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -87
  417. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +1 -1
  418. esphome/components/remote_transmitter/__init__.py +42 -43
  419. esphome/components/remote_transmitter/remote_transmitter.h +2 -14
  420. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -77
  421. esphome/components/resistance/resistance_sensor.h +0 -1
  422. esphome/components/rp2040/__init__.py +2 -0
  423. esphome/components/rp2040/helpers.cpp +55 -0
  424. esphome/components/rp2040_pio_led_strip/led_strip.cpp +2 -2
  425. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -4
  426. esphome/components/rtttl/__init__.py +4 -4
  427. esphome/components/rtttl/rtttl.cpp +10 -1
  428. esphome/components/ruuvitag/ruuvitag.h +0 -1
  429. esphome/components/safe_mode/safe_mode.cpp +2 -0
  430. esphome/components/safe_mode/safe_mode.h +4 -1
  431. esphome/components/scd30/scd30.h +0 -1
  432. esphome/components/scd30/sensor.py +2 -2
  433. esphome/components/scd4x/scd4x.cpp +61 -54
  434. esphome/components/scd4x/scd4x.h +17 -15
  435. esphome/components/scd4x/sensor.py +4 -4
  436. esphome/components/script/script.h +0 -2
  437. esphome/components/sdp3x/sensor.py +1 -1
  438. esphome/components/select/__init__.py +5 -2
  439. esphome/components/sen5x/sen5x.h +0 -1
  440. esphome/components/senseair/senseair.h +0 -1
  441. esphome/components/sensor/__init__.py +4 -2
  442. esphome/components/sensor/filter.cpp +1 -1
  443. esphome/components/sensor/sensor.cpp +12 -6
  444. esphome/components/sensor/sensor.h +13 -5
  445. esphome/components/servo/servo.cpp +2 -2
  446. esphome/components/servo/servo.h +0 -1
  447. esphome/components/sfa30/sfa30.h +0 -1
  448. esphome/components/sgp30/sgp30.h +0 -1
  449. esphome/components/sgp4x/sgp4x.h +0 -1
  450. esphome/components/shelly_dimmer/stm32flash.cpp +1 -2
  451. esphome/components/sht4x/sht4x.h +0 -1
  452. esphome/components/sm300d2/sm300d2.h +0 -2
  453. esphome/components/smt100/sensor.py +8 -4
  454. esphome/components/smt100/smt100.cpp +5 -5
  455. esphome/components/smt100/smt100.h +3 -3
  456. esphome/components/sn74hc595/__init__.py +1 -1
  457. esphome/components/sn74hc595/sn74hc595.cpp +5 -4
  458. esphome/components/sntp/sntp_component.cpp +9 -3
  459. esphome/components/sntp/time.py +2 -0
  460. esphome/components/socket/__init__.py +17 -0
  461. esphome/components/spi/__init__.py +27 -6
  462. esphome/components/spi/spi.cpp +3 -2
  463. esphome/components/spi/spi.h +9 -3
  464. esphome/components/spi/spi_arduino.cpp +3 -5
  465. esphome/components/spi/spi_esp_idf.cpp +40 -21
  466. esphome/components/spi_led_strip/spi_led_strip.cpp +1 -1
  467. esphome/components/sps30/sps30.h +0 -1
  468. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  469. esphome/components/st7701s/st7701s.cpp +0 -4
  470. esphome/components/status/status_binary_sensor.h +0 -2
  471. esphome/components/substitutions/__init__.py +81 -21
  472. esphome/components/substitutions/jinja.py +99 -0
  473. esphome/components/sun/sun.cpp +3 -4
  474. esphome/components/switch/__init__.py +5 -2
  475. esphome/components/switch/binary_sensor/switch_binary_sensor.h +0 -1
  476. esphome/components/sx126x/__init__.py +317 -0
  477. esphome/components/sx126x/automation.h +62 -0
  478. esphome/components/sx126x/packet_transport/__init__.py +26 -0
  479. esphome/components/sx126x/packet_transport/sx126x_transport.cpp +26 -0
  480. esphome/components/sx126x/packet_transport/sx126x_transport.h +25 -0
  481. esphome/components/sx126x/sx126x.cpp +523 -0
  482. esphome/components/sx126x/sx126x.h +140 -0
  483. esphome/components/sx126x/sx126x_reg.h +163 -0
  484. esphome/components/sx127x/__init__.py +325 -0
  485. esphome/components/sx127x/automation.h +62 -0
  486. esphome/components/sx127x/packet_transport/__init__.py +26 -0
  487. esphome/components/sx127x/packet_transport/sx127x_transport.cpp +26 -0
  488. esphome/components/sx127x/packet_transport/sx127x_transport.h +25 -0
  489. esphome/components/sx127x/sx127x.cpp +498 -0
  490. esphome/components/sx127x/sx127x.h +128 -0
  491. esphome/components/sx127x/sx127x_reg.h +295 -0
  492. esphome/components/syslog/esphome_syslog.cpp +5 -3
  493. esphome/components/syslog/esphome_syslog.h +1 -1
  494. esphome/components/tca9555/__init__.py +1 -1
  495. esphome/components/template/binary_sensor/template_binary_sensor.cpp +1 -9
  496. esphome/components/text/__init__.py +5 -2
  497. esphome/components/text_sensor/__init__.py +5 -2
  498. esphome/components/thermostat/thermostat_climate.cpp +34 -31
  499. esphome/components/thermostat/thermostat_climate.h +43 -39
  500. esphome/components/time/__init__.py +16 -2
  501. esphome/components/time/real_time_clock.cpp +4 -0
  502. esphome/components/time/real_time_clock.h +5 -1
  503. esphome/components/tlc5971/tlc5971.cpp +4 -1
  504. esphome/components/tmp1075/tmp1075.h +0 -2
  505. esphome/components/tof10120/tof10120_sensor.h +0 -1
  506. esphome/components/tormatic/tormatic_cover.h +0 -1
  507. esphome/components/total_daily_energy/total_daily_energy.h +0 -1
  508. esphome/components/tsl2591/tsl2591.cpp +1 -1
  509. esphome/components/ttp229_bsf/ttp229_bsf.h +0 -1
  510. esphome/components/ttp229_lsf/ttp229_lsf.h +0 -1
  511. esphome/components/tx20/tx20.cpp +2 -2
  512. esphome/components/uart/__init__.py +18 -0
  513. esphome/components/uart/uart_component_esp_idf.cpp +1 -5
  514. esphome/components/update/__init__.py +5 -2
  515. esphome/components/update/update_entity.h +8 -0
  516. esphome/components/usb_host/__init__.py +5 -2
  517. esphome/components/usb_host/usb_host_client.cpp +10 -10
  518. esphome/components/usb_uart/cp210x.cpp +1 -1
  519. esphome/components/usb_uart/usb_uart.cpp +41 -44
  520. esphome/components/usb_uart/usb_uart.h +4 -3
  521. esphome/components/valve/__init__.py +5 -2
  522. esphome/components/vbus/vbus.h +0 -1
  523. esphome/components/veml3235/veml3235.h +0 -1
  524. esphome/components/veml7700/veml7700.h +0 -1
  525. esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
  526. esphome/components/voice_assistant/voice_assistant.cpp +4 -4
  527. esphome/components/watchdog/watchdog.cpp +0 -4
  528. esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
  529. esphome/components/web_server/__init__.py +34 -19
  530. esphome/components/web_server/ota/__init__.py +32 -0
  531. esphome/components/web_server/ota/ota_web_server.cpp +210 -0
  532. esphome/components/web_server/ota/ota_web_server.h +26 -0
  533. esphome/components/web_server/web_server.cpp +324 -439
  534. esphome/components/web_server/web_server.h +33 -23
  535. esphome/components/web_server/web_server_v1.cpp +4 -5
  536. esphome/components/web_server_base/__init__.py +5 -2
  537. esphome/components/web_server_base/web_server_base.cpp +2 -94
  538. esphome/components/web_server_base/web_server_base.h +5 -25
  539. esphome/components/web_server_idf/multipart.cpp +254 -0
  540. esphome/components/web_server_idf/multipart.h +86 -0
  541. esphome/components/web_server_idf/utils.cpp +32 -0
  542. esphome/components/web_server_idf/utils.h +10 -0
  543. esphome/components/web_server_idf/web_server_idf.cpp +164 -16
  544. esphome/components/web_server_idf/web_server_idf.h +11 -10
  545. esphome/components/wiegand/wiegand.cpp +2 -2
  546. esphome/components/wifi/__init__.py +18 -0
  547. esphome/components/wifi/wifi_component.cpp +17 -22
  548. esphome/components/wifi/wifi_component.h +27 -23
  549. esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
  550. esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
  551. esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
  552. esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
  553. esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
  554. esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
  555. esphome/components/wireguard/__init__.py +2 -11
  556. esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
  557. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  558. esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
  559. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
  560. esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
  561. esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
  562. esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
  563. esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
  564. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
  565. esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
  566. esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
  567. esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
  568. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
  569. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
  570. esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
  571. esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
  572. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
  573. esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
  574. esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
  575. esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
  576. esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
  577. esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
  578. esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
  579. esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
  580. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
  581. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
  582. esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
  583. esphome/components/zyaura/zyaura.h +0 -1
  584. esphome/config.py +88 -22
  585. esphome/config_helpers.py +74 -1
  586. esphome/config_validation.py +12 -1
  587. esphome/const.py +65 -10
  588. esphome/core/__init__.py +18 -2
  589. esphome/core/application.cpp +169 -10
  590. esphome/core/application.h +145 -165
  591. esphome/core/area.h +19 -0
  592. esphome/core/automation.h +58 -9
  593. esphome/core/color.cpp +3 -5
  594. esphome/core/color.h +16 -16
  595. esphome/core/component.cpp +156 -22
  596. esphome/core/component.h +98 -4
  597. esphome/core/component_iterator.cpp +11 -9
  598. esphome/core/component_iterator.h +12 -10
  599. esphome/core/config.py +155 -6
  600. esphome/core/controller.cpp +4 -2
  601. esphome/core/controller.h +1 -1
  602. esphome/core/datatypes.h +2 -2
  603. esphome/core/defines.h +17 -2
  604. esphome/core/device.h +20 -0
  605. esphome/core/entity_base.cpp +20 -15
  606. esphome/core/entity_base.h +76 -0
  607. esphome/core/entity_helpers.py +168 -1
  608. esphome/core/event_pool.h +81 -0
  609. esphome/core/helpers.cpp +75 -230
  610. esphome/core/helpers.h +165 -105
  611. esphome/core/lock_free_queue.h +151 -0
  612. esphome/core/log.cpp +2 -2
  613. esphome/core/log.h +2 -0
  614. esphome/core/optional.h +5 -0
  615. esphome/core/ring_buffer.cpp +2 -2
  616. esphome/core/scheduler.cpp +275 -103
  617. esphome/core/scheduler.h +154 -17
  618. esphome/core/time.cpp +5 -5
  619. esphome/core/time.h +5 -5
  620. esphome/cpp_generator.py +17 -0
  621. esphome/cpp_helpers.py +0 -22
  622. esphome/cpp_types.py +3 -1
  623. esphome/dashboard/entries.py +1 -1
  624. esphome/dashboard/util/text.py +5 -21
  625. esphome/dashboard/web_server.py +9 -1
  626. esphome/helpers.py +47 -0
  627. esphome/loader.py +15 -1
  628. esphome/pins.py +14 -8
  629. esphome/platformio_api.py +2 -0
  630. esphome/wizard.py +17 -4
  631. esphome/writer.py +44 -3
  632. esphome/yaml_util.py +0 -2
  633. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/METADATA +10 -9
  634. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/RECORD +639 -580
  635. esphome/components/api/api_pb2_size.h +0 -361
  636. esphome/components/esp32_ble/ble_event_pool.h +0 -72
  637. esphome/components/esp32_ble/queue.h +0 -85
  638. esphome/components/esp32_hall/esp32_hall.cpp +0 -25
  639. esphome/components/esp32_hall/esp32_hall.h +0 -23
  640. esphome/components/esp32_touch/esp32_touch.cpp +0 -355
  641. esphome/components/ld2410/button/reset_button.cpp +0 -9
  642. esphome/components/ld2450/button/reset_button.cpp +0 -9
  643. esphome/components/openthread/tlv.py +0 -65
  644. /esphome/{dashboard/enum.py → enum.py} +0 -0
  645. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/WHEEL +0 -0
  646. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/entry_points.txt +0 -0
  647. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/licenses/LICENSE +0 -0
  648. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,9 @@
2
2
 
3
3
  #include <cinttypes>
4
4
  #include <limits>
5
+ #include <memory>
5
6
  #include <utility>
7
+ #include <vector>
6
8
  #include "esphome/core/application.h"
7
9
  #include "esphome/core/hal.h"
8
10
  #include "esphome/core/helpers.h"
@@ -12,6 +14,30 @@ namespace esphome {
12
14
 
13
15
  static const char *const TAG = "component";
14
16
 
17
+ // Global vectors for component data that doesn't belong in every instance.
18
+ // Using vector instead of unordered_map for both because:
19
+ // - Much lower memory overhead (8 bytes per entry vs 20+ for unordered_map)
20
+ // - Linear search is fine for small n (typically < 5 entries)
21
+ // - These are rarely accessed (setup only or error cases only)
22
+
23
+ // Component error messages - only stores messages for failed components
24
+ // Lazy allocated since most configs have zero failures
25
+ // Note: We don't clear this vector because:
26
+ // 1. Components are never destroyed in ESPHome
27
+ // 2. Failed components remain failed (no recovery mechanism)
28
+ // 3. Memory usage is minimal (only failures with custom messages are stored)
29
+
30
+ // Using namespace-scope static to avoid guard variables (saves 16 bytes total)
31
+ // This is safe because ESPHome is single-threaded during initialization
32
+ namespace {
33
+ // Error messages for failed components
34
+ // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
35
+ std::unique_ptr<std::vector<std::pair<const Component *, const char *>>> component_error_messages;
36
+ // Setup priority overrides - freed after setup completes
37
+ // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
38
+ std::unique_ptr<std::vector<std::pair<const Component *, float>>> setup_priority_overrides;
39
+ } // namespace
40
+
15
41
  namespace setup_priority {
16
42
 
17
43
  const float BUS = 1000.0f;
@@ -30,17 +56,18 @@ const float LATE = -100.0f;
30
56
 
31
57
  } // namespace setup_priority
32
58
 
33
- // Component state uses bits 0-1 (4 states)
34
- const uint8_t COMPONENT_STATE_MASK = 0x03;
59
+ // Component state uses bits 0-2 (8 states, 5 used)
60
+ const uint8_t COMPONENT_STATE_MASK = 0x07;
35
61
  const uint8_t COMPONENT_STATE_CONSTRUCTION = 0x00;
36
62
  const uint8_t COMPONENT_STATE_SETUP = 0x01;
37
63
  const uint8_t COMPONENT_STATE_LOOP = 0x02;
38
64
  const uint8_t COMPONENT_STATE_FAILED = 0x03;
39
- // Status LED uses bits 2-3
40
- const uint8_t STATUS_LED_MASK = 0x0C;
65
+ const uint8_t COMPONENT_STATE_LOOP_DONE = 0x04;
66
+ // Status LED uses bits 3-4
67
+ const uint8_t STATUS_LED_MASK = 0x18;
41
68
  const uint8_t STATUS_LED_OK = 0x00;
42
- const uint8_t STATUS_LED_WARNING = 0x04; // Bit 2
43
- const uint8_t STATUS_LED_ERROR = 0x08; // Bit 3
69
+ const uint8_t STATUS_LED_WARNING = 0x08; // Bit 3
70
+ const uint8_t STATUS_LED_ERROR = 0x10; // Bit 4
44
71
 
45
72
  const uint16_t WARN_IF_BLOCKING_OVER_MS = 50U; ///< Initial blocking time allowed without warning
46
73
  const uint16_t WARN_IF_BLOCKING_INCREMENT_MS = 10U; ///< How long the blocking time must be larger to warn again
@@ -59,10 +86,18 @@ void Component::set_interval(const std::string &name, uint32_t interval, std::fu
59
86
  App.scheduler.set_interval(this, name, interval, std::move(f));
60
87
  }
61
88
 
89
+ void Component::set_interval(const char *name, uint32_t interval, std::function<void()> &&f) { // NOLINT
90
+ App.scheduler.set_interval(this, name, interval, std::move(f));
91
+ }
92
+
62
93
  bool Component::cancel_interval(const std::string &name) { // NOLINT
63
94
  return App.scheduler.cancel_interval(this, name);
64
95
  }
65
96
 
97
+ bool Component::cancel_interval(const char *name) { // NOLINT
98
+ return App.scheduler.cancel_interval(this, name);
99
+ }
100
+
66
101
  void Component::set_retry(const std::string &name, uint32_t initial_wait_time, uint8_t max_attempts,
67
102
  std::function<RetryResult(uint8_t)> &&f, float backoff_increase_factor) { // NOLINT
68
103
  App.scheduler.set_retry(this, name, initial_wait_time, max_attempts, std::move(f), backoff_increase_factor);
@@ -76,16 +111,34 @@ void Component::set_timeout(const std::string &name, uint32_t timeout, std::func
76
111
  App.scheduler.set_timeout(this, name, timeout, std::move(f));
77
112
  }
78
113
 
114
+ void Component::set_timeout(const char *name, uint32_t timeout, std::function<void()> &&f) { // NOLINT
115
+ App.scheduler.set_timeout(this, name, timeout, std::move(f));
116
+ }
117
+
79
118
  bool Component::cancel_timeout(const std::string &name) { // NOLINT
80
119
  return App.scheduler.cancel_timeout(this, name);
81
120
  }
82
121
 
122
+ bool Component::cancel_timeout(const char *name) { // NOLINT
123
+ return App.scheduler.cancel_timeout(this, name);
124
+ }
125
+
83
126
  void Component::call_loop() { this->loop(); }
84
127
  void Component::call_setup() { this->setup(); }
85
128
  void Component::call_dump_config() {
86
129
  this->dump_config();
87
130
  if (this->is_failed()) {
88
- ESP_LOGE(TAG, " Component %s is marked FAILED: %s", this->get_component_source(), this->error_message_.c_str());
131
+ // Look up error message from global vector
132
+ const char *error_msg = "unspecified";
133
+ if (component_error_messages) {
134
+ for (const auto &pair : *component_error_messages) {
135
+ if (pair.first == this) {
136
+ error_msg = pair.second;
137
+ break;
138
+ }
139
+ }
140
+ }
141
+ ESP_LOGE(TAG, " %s is marked FAILED: %s", this->get_component_source(), error_msg);
89
142
  }
90
143
  }
91
144
 
@@ -112,6 +165,9 @@ void Component::call() {
112
165
  case COMPONENT_STATE_FAILED: // NOLINT(bugprone-branch-clone)
113
166
  // State failed: Do nothing
114
167
  break;
168
+ case COMPONENT_STATE_LOOP_DONE: // NOLINT(bugprone-branch-clone)
169
+ // State loop done: Do nothing, component has finished its work
170
+ break;
115
171
  default:
116
172
  break;
117
173
  }
@@ -135,14 +191,45 @@ bool Component::should_warn_of_blocking(uint32_t blocking_time) {
135
191
  return false;
136
192
  }
137
193
  void Component::mark_failed() {
138
- ESP_LOGE(TAG, "Component %s was marked as failed.", this->get_component_source());
194
+ ESP_LOGE(TAG, "%s was marked as failed", this->get_component_source());
139
195
  this->component_state_ &= ~COMPONENT_STATE_MASK;
140
196
  this->component_state_ |= COMPONENT_STATE_FAILED;
141
197
  this->status_set_error();
198
+ // Also remove from loop since failed components shouldn't loop
199
+ App.disable_component_loop_(this);
200
+ }
201
+ void Component::disable_loop() {
202
+ if ((this->component_state_ & COMPONENT_STATE_MASK) != COMPONENT_STATE_LOOP_DONE) {
203
+ ESP_LOGVV(TAG, "%s loop disabled", this->get_component_source());
204
+ this->component_state_ &= ~COMPONENT_STATE_MASK;
205
+ this->component_state_ |= COMPONENT_STATE_LOOP_DONE;
206
+ App.disable_component_loop_(this);
207
+ }
208
+ }
209
+ void Component::enable_loop() {
210
+ if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE) {
211
+ ESP_LOGVV(TAG, "%s loop enabled", this->get_component_source());
212
+ this->component_state_ &= ~COMPONENT_STATE_MASK;
213
+ this->component_state_ |= COMPONENT_STATE_LOOP;
214
+ App.enable_component_loop_(this);
215
+ }
216
+ }
217
+ void IRAM_ATTR HOT Component::enable_loop_soon_any_context() {
218
+ // This method is thread and ISR-safe because:
219
+ // 1. Only performs simple assignments to volatile variables (atomic on all platforms)
220
+ // 2. No read-modify-write operations that could be interrupted
221
+ // 3. No memory allocation, object construction, or function calls
222
+ // 4. IRAM_ATTR ensures code is in IRAM, not flash (required for ISR execution)
223
+ // 5. Components are never destroyed, so no use-after-free concerns
224
+ // 6. App is guaranteed to be initialized before any ISR could fire
225
+ // 7. Multiple ISR/thread calls are safe - just sets the same flags to true
226
+ // 8. Race condition with main loop is handled by clearing flag before processing
227
+ this->pending_enable_loop_ = true;
228
+ App.has_pending_enable_loop_requests_ = true;
142
229
  }
143
230
  void Component::reset_to_construction_state() {
144
231
  if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_FAILED) {
145
- ESP_LOGI(TAG, "Component %s is being reset to construction state.", this->get_component_source());
232
+ ESP_LOGI(TAG, "%s is being reset to construction state", this->get_component_source());
146
233
  this->component_state_ &= ~COMPONENT_STATE_MASK;
147
234
  this->component_state_ |= COMPONENT_STATE_CONSTRUCTION;
148
235
  // Clear error status when resetting
@@ -153,7 +240,7 @@ bool Component::is_in_loop_state() const {
153
240
  return (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP;
154
241
  }
155
242
  void Component::defer(std::function<void()> &&f) { // NOLINT
156
- App.scheduler.set_timeout(this, "", 0, std::move(f));
243
+ App.scheduler.set_timeout(this, static_cast<const char *>(nullptr), 0, std::move(f));
157
244
  }
158
245
  bool Component::cancel_defer(const std::string &name) { // NOLINT
159
246
  return App.scheduler.cancel_timeout(this, name);
@@ -161,6 +248,9 @@ bool Component::cancel_defer(const std::string &name) { // NOLINT
161
248
  void Component::defer(const std::string &name, std::function<void()> &&f) { // NOLINT
162
249
  App.scheduler.set_timeout(this, name, 0, std::move(f));
163
250
  }
251
+ void Component::defer(const char *name, std::function<void()> &&f) { // NOLINT
252
+ App.scheduler.set_timeout(this, name, 0, std::move(f));
253
+ }
164
254
  void Component::set_timeout(uint32_t timeout, std::function<void()> &&f) { // NOLINT
165
255
  App.scheduler.set_timeout(this, "", timeout, std::move(f));
166
256
  }
@@ -174,6 +264,7 @@ void Component::set_retry(uint32_t initial_wait_time, uint8_t max_attempts, std:
174
264
  bool Component::is_failed() const { return (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_FAILED; }
175
265
  bool Component::is_ready() const {
176
266
  return (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP ||
267
+ (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE ||
177
268
  (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_SETUP;
178
269
  }
179
270
  bool Component::can_proceed() { return true; }
@@ -185,28 +276,41 @@ void Component::status_set_warning(const char *message) {
185
276
  return;
186
277
  this->component_state_ |= STATUS_LED_WARNING;
187
278
  App.app_state_ |= STATUS_LED_WARNING;
188
- ESP_LOGW(TAG, "Component %s set Warning flag: %s", this->get_component_source(), message);
279
+ ESP_LOGW(TAG, "%s set Warning flag: %s", this->get_component_source(), message);
189
280
  }
190
281
  void Component::status_set_error(const char *message) {
191
282
  if ((this->component_state_ & STATUS_LED_ERROR) != 0)
192
283
  return;
193
284
  this->component_state_ |= STATUS_LED_ERROR;
194
285
  App.app_state_ |= STATUS_LED_ERROR;
195
- ESP_LOGE(TAG, "Component %s set Error flag: %s", this->get_component_source(), message);
196
- if (strcmp(message, "unspecified") != 0)
197
- this->error_message_ = message;
286
+ ESP_LOGE(TAG, "%s set Error flag: %s", this->get_component_source(), message);
287
+ if (strcmp(message, "unspecified") != 0) {
288
+ // Lazy allocate the error messages vector if needed
289
+ if (!component_error_messages) {
290
+ component_error_messages = std::make_unique<std::vector<std::pair<const Component *, const char *>>>();
291
+ }
292
+ // Check if this component already has an error message
293
+ for (auto &pair : *component_error_messages) {
294
+ if (pair.first == this) {
295
+ pair.second = message;
296
+ return;
297
+ }
298
+ }
299
+ // Add new error message
300
+ component_error_messages->emplace_back(this, message);
301
+ }
198
302
  }
199
303
  void Component::status_clear_warning() {
200
304
  if ((this->component_state_ & STATUS_LED_WARNING) == 0)
201
305
  return;
202
306
  this->component_state_ &= ~STATUS_LED_WARNING;
203
- ESP_LOGW(TAG, "Component %s cleared Warning flag", this->get_component_source());
307
+ ESP_LOGW(TAG, "%s cleared Warning flag", this->get_component_source());
204
308
  }
205
309
  void Component::status_clear_error() {
206
310
  if ((this->component_state_ & STATUS_LED_ERROR) == 0)
207
311
  return;
208
312
  this->component_state_ &= ~STATUS_LED_ERROR;
209
- ESP_LOGE(TAG, "Component %s cleared Error flag", this->get_component_source());
313
+ ESP_LOGE(TAG, "%s cleared Error flag", this->get_component_source());
210
314
  }
211
315
  void Component::status_momentary_warning(const std::string &name, uint32_t length) {
212
316
  this->status_set_warning();
@@ -218,11 +322,36 @@ void Component::status_momentary_error(const std::string &name, uint32_t length)
218
322
  }
219
323
  void Component::dump_config() {}
220
324
  float Component::get_actual_setup_priority() const {
221
- if (std::isnan(this->setup_priority_override_))
222
- return this->get_setup_priority();
223
- return this->setup_priority_override_;
325
+ // Check if there's an override in the global vector
326
+ if (setup_priority_overrides) {
327
+ // Linear search is fine for small n (typically < 5 overrides)
328
+ for (const auto &pair : *setup_priority_overrides) {
329
+ if (pair.first == this) {
330
+ return pair.second;
331
+ }
332
+ }
333
+ }
334
+ return this->get_setup_priority();
335
+ }
336
+ void Component::set_setup_priority(float priority) {
337
+ // Lazy allocate the vector if needed
338
+ if (!setup_priority_overrides) {
339
+ setup_priority_overrides = std::make_unique<std::vector<std::pair<const Component *, float>>>();
340
+ // Reserve some space to avoid reallocations (most configs have < 10 overrides)
341
+ setup_priority_overrides->reserve(10);
342
+ }
343
+
344
+ // Check if this component already has an override
345
+ for (auto &pair : *setup_priority_overrides) {
346
+ if (pair.first == this) {
347
+ pair.second = priority;
348
+ return;
349
+ }
350
+ }
351
+
352
+ // Add new override
353
+ setup_priority_overrides->emplace_back(this, priority);
224
354
  }
225
- void Component::set_setup_priority(float priority) { this->setup_priority_override_ = priority; }
226
355
 
227
356
  bool Component::has_overridden_loop() const {
228
357
  #if defined(USE_HOST) || defined(CLANG_TIDY)
@@ -275,8 +404,8 @@ uint32_t WarnIfComponentBlockingGuard::finish() {
275
404
  }
276
405
  if (should_warn) {
277
406
  const char *src = component_ == nullptr ? "<null>" : component_->get_component_source();
278
- ESP_LOGW(TAG, "Component %s took a long time for an operation (%" PRIu32 " ms).", src, blocking_time);
279
- ESP_LOGW(TAG, "Components should block for at most 30 ms.");
407
+ ESP_LOGW(TAG, "%s took a long time for an operation (%" PRIu32 " ms)", src, blocking_time);
408
+ ESP_LOGW(TAG, "Components should block for at most 30 ms");
280
409
  }
281
410
 
282
411
  return curr_time;
@@ -284,4 +413,9 @@ uint32_t WarnIfComponentBlockingGuard::finish() {
284
413
 
285
414
  WarnIfComponentBlockingGuard::~WarnIfComponentBlockingGuard() {}
286
415
 
416
+ void clear_setup_priority_overrides() {
417
+ // Free the setup priority map completely
418
+ setup_priority_overrides.reset();
419
+ }
420
+
287
421
  } // namespace esphome
esphome/core/component.h CHANGED
@@ -58,6 +58,7 @@ extern const uint8_t COMPONENT_STATE_CONSTRUCTION;
58
58
  extern const uint8_t COMPONENT_STATE_SETUP;
59
59
  extern const uint8_t COMPONENT_STATE_LOOP;
60
60
  extern const uint8_t COMPONENT_STATE_FAILED;
61
+ extern const uint8_t COMPONENT_STATE_LOOP_DONE;
61
62
  extern const uint8_t STATUS_LED_MASK;
62
63
  extern const uint8_t STATUS_LED_OK;
63
64
  extern const uint8_t STATUS_LED_WARNING;
@@ -150,6 +151,47 @@ class Component {
150
151
  this->mark_failed();
151
152
  }
152
153
 
154
+ /** Disable this component's loop. The loop() method will no longer be called.
155
+ *
156
+ * This is useful for components that only need to run for a certain period of time
157
+ * or when inactive, saving CPU cycles.
158
+ *
159
+ * @note Components should call this->disable_loop() on themselves, not on other components.
160
+ * This ensures the component's state is properly updated along with the loop partition.
161
+ */
162
+ void disable_loop();
163
+
164
+ /** Enable this component's loop. The loop() method will be called normally.
165
+ *
166
+ * This is useful for components that transition between active and inactive states
167
+ * and need to re-enable their loop() method when becoming active again.
168
+ *
169
+ * @note Components should call this->enable_loop() on themselves, not on other components.
170
+ * This ensures the component's state is properly updated along with the loop partition.
171
+ */
172
+ void enable_loop();
173
+
174
+ /** Thread and ISR-safe version of enable_loop() that can be called from any context.
175
+ *
176
+ * This method defers the actual enable via enable_pending_loops_ to the main loop,
177
+ * making it safe to call from ISR handlers, timer callbacks, other threads,
178
+ * or any interrupt context.
179
+ *
180
+ * @note The actual loop enabling will happen on the next main loop iteration.
181
+ * @note Only one pending enable request is tracked per component.
182
+ * @note There is no disable_loop_soon_any_context() on purpose - it would race
183
+ * against enable calls and synchronization would get too complex
184
+ * to provide a safe version that would work for each component.
185
+ *
186
+ * Use disable_loop() from the main thread only.
187
+ *
188
+ * If you need to disable the loop from ISR, carefully implement
189
+ * it in the component itself, with an ISR safe approach, and call
190
+ * disable_loop() in its next ::loop() iteration. Implementations
191
+ * will need to carefully consider all possible race conditions.
192
+ */
193
+ void enable_loop_soon_any_context();
194
+
153
195
  bool is_failed() const;
154
196
 
155
197
  bool is_ready() const;
@@ -218,6 +260,22 @@ class Component {
218
260
  */
219
261
  void set_interval(const std::string &name, uint32_t interval, std::function<void()> &&f); // NOLINT
220
262
 
263
+ /** Set an interval function with a const char* name.
264
+ *
265
+ * IMPORTANT: The provided name pointer must remain valid for the lifetime of the scheduler item.
266
+ * This means the name should be:
267
+ * - A string literal (e.g., "update")
268
+ * - A static const char* variable
269
+ * - A pointer with lifetime >= the scheduled task
270
+ *
271
+ * For dynamic strings, use the std::string overload instead.
272
+ *
273
+ * @param name The identifier for this interval function (must have static lifetime)
274
+ * @param interval The interval in ms
275
+ * @param f The function to call
276
+ */
277
+ void set_interval(const char *name, uint32_t interval, std::function<void()> &&f); // NOLINT
278
+
221
279
  void set_interval(uint32_t interval, std::function<void()> &&f); // NOLINT
222
280
 
223
281
  /** Cancel an interval function.
@@ -226,6 +284,7 @@ class Component {
226
284
  * @return Whether an interval functions was deleted.
227
285
  */
228
286
  bool cancel_interval(const std::string &name); // NOLINT
287
+ bool cancel_interval(const char *name); // NOLINT
229
288
 
230
289
  /** Set an retry function with a unique name. Empty name means no cancelling possible.
231
290
  *
@@ -286,6 +345,22 @@ class Component {
286
345
  */
287
346
  void set_timeout(const std::string &name, uint32_t timeout, std::function<void()> &&f); // NOLINT
288
347
 
348
+ /** Set a timeout function with a const char* name.
349
+ *
350
+ * IMPORTANT: The provided name pointer must remain valid for the lifetime of the scheduler item.
351
+ * This means the name should be:
352
+ * - A string literal (e.g., "init")
353
+ * - A static const char* variable
354
+ * - A pointer with lifetime >= the timeout duration
355
+ *
356
+ * For dynamic strings, use the std::string overload instead.
357
+ *
358
+ * @param name The identifier for this timeout function (must have static lifetime)
359
+ * @param timeout The timeout in ms
360
+ * @param f The function to call
361
+ */
362
+ void set_timeout(const char *name, uint32_t timeout, std::function<void()> &&f); // NOLINT
363
+
289
364
  void set_timeout(uint32_t timeout, std::function<void()> &&f); // NOLINT
290
365
 
291
366
  /** Cancel a timeout function.
@@ -294,6 +369,7 @@ class Component {
294
369
  * @return Whether a timeout functions was deleted.
295
370
  */
296
371
  bool cancel_timeout(const std::string &name); // NOLINT
372
+ bool cancel_timeout(const char *name); // NOLINT
297
373
 
298
374
  /** Defer a callback to the next loop() call.
299
375
  *
@@ -304,22 +380,37 @@ class Component {
304
380
  */
305
381
  void defer(const std::string &name, std::function<void()> &&f); // NOLINT
306
382
 
383
+ /** Defer a callback to the next loop() call with a const char* name.
384
+ *
385
+ * IMPORTANT: The provided name pointer must remain valid for the lifetime of the deferred task.
386
+ * This means the name should be:
387
+ * - A string literal (e.g., "update")
388
+ * - A static const char* variable
389
+ * - A pointer with lifetime >= the deferred execution
390
+ *
391
+ * For dynamic strings, use the std::string overload instead.
392
+ *
393
+ * @param name The name of the defer function (must have static lifetime)
394
+ * @param f The callback
395
+ */
396
+ void defer(const char *name, std::function<void()> &&f); // NOLINT
397
+
307
398
  /// Defer a callback to the next loop() call.
308
399
  void defer(std::function<void()> &&f); // NOLINT
309
400
 
310
401
  /// Cancel a defer callback using the specified name, name must not be empty.
311
402
  bool cancel_defer(const std::string &name); // NOLINT
312
403
 
404
+ // Ordered for optimal packing on 32-bit systems
405
+ const char *component_source_{nullptr};
406
+ uint16_t warn_if_blocking_over_{WARN_IF_BLOCKING_OVER_MS}; ///< Warn if blocked for this many ms (max 65.5s)
313
407
  /// State of this component - each bit has a purpose:
314
408
  /// Bits 0-1: Component state (0x00=CONSTRUCTION, 0x01=SETUP, 0x02=LOOP, 0x03=FAILED)
315
409
  /// Bit 2: STATUS_LED_WARNING
316
410
  /// Bit 3: STATUS_LED_ERROR
317
411
  /// Bits 4-7: Unused - reserved for future expansion (50% of the bits are free)
318
412
  uint8_t component_state_{0x00};
319
- float setup_priority_override_{NAN};
320
- const char *component_source_{nullptr};
321
- uint16_t warn_if_blocking_over_{WARN_IF_BLOCKING_OVER_MS}; ///< Warn if blocked for this many ms (max 65.5s)
322
- std::string error_message_{};
413
+ volatile bool pending_enable_loop_{false}; ///< ISR-safe flag for enable_loop_soon_any_context
323
414
  };
324
415
 
325
416
  /** This class simplifies creating components that periodically check a state.
@@ -381,4 +472,7 @@ class WarnIfComponentBlockingGuard {
381
472
  Component *component_;
382
473
  };
383
474
 
475
+ // Function to clear setup priority overrides after all components are set up
476
+ void clear_setup_priority_overrides();
477
+
384
478
  } // namespace esphome
@@ -4,6 +4,8 @@
4
4
 
5
5
  #ifdef USE_API
6
6
  #include "esphome/components/api/api_server.h"
7
+ #endif
8
+ #ifdef USE_API_SERVICES
7
9
  #include "esphome/components/api/user_services.h"
8
10
  #endif
9
11
 
@@ -148,7 +150,7 @@ void ComponentIterator::advance() {
148
150
  }
149
151
  break;
150
152
  #endif
151
- #ifdef USE_API
153
+ #ifdef USE_API_SERVICES
152
154
  case IteratorState ::SERVICE:
153
155
  if (this->at_ >= api::global_api_server->get_user_services().size()) {
154
156
  advance_platform = true;
@@ -158,16 +160,16 @@ void ComponentIterator::advance() {
158
160
  }
159
161
  break;
160
162
  #endif
161
- #ifdef USE_ESP32_CAMERA
163
+ #ifdef USE_CAMERA
162
164
  case IteratorState::CAMERA:
163
- if (esp32_camera::global_esp32_camera == nullptr) {
165
+ if (camera::Camera::instance() == nullptr) {
164
166
  advance_platform = true;
165
167
  } else {
166
- if (esp32_camera::global_esp32_camera->is_internal() && !this->include_internal_) {
168
+ if (camera::Camera::instance()->is_internal() && !this->include_internal_) {
167
169
  advance_platform = success = true;
168
170
  break;
169
171
  } else {
170
- advance_platform = success = this->on_camera(esp32_camera::global_esp32_camera);
172
+ advance_platform = success = this->on_camera(camera::Camera::instance());
171
173
  }
172
174
  }
173
175
  break;
@@ -375,7 +377,7 @@ void ComponentIterator::advance() {
375
377
  }
376
378
 
377
379
  if (advance_platform) {
378
- this->state_ = static_cast<IteratorState>(static_cast<uint32_t>(this->state_) + 1);
380
+ this->state_ = static_cast<IteratorState>(static_cast<uint8_t>(this->state_) + 1);
379
381
  this->at_ = 0;
380
382
  } else if (success) {
381
383
  this->at_++;
@@ -383,11 +385,11 @@ void ComponentIterator::advance() {
383
385
  }
384
386
  bool ComponentIterator::on_end() { return true; }
385
387
  bool ComponentIterator::on_begin() { return true; }
386
- #ifdef USE_API
388
+ #ifdef USE_API_SERVICES
387
389
  bool ComponentIterator::on_service(api::UserServiceDescriptor *service) { return true; }
388
390
  #endif
389
- #ifdef USE_ESP32_CAMERA
390
- bool ComponentIterator::on_camera(esp32_camera::ESP32Camera *camera) { return true; }
391
+ #ifdef USE_CAMERA
392
+ bool ComponentIterator::on_camera(camera::Camera *camera) { return true; }
391
393
  #endif
392
394
  #ifdef USE_MEDIA_PLAYER
393
395
  bool ComponentIterator::on_media_player(media_player::MediaPlayer *media_player) { return true; }
@@ -4,13 +4,13 @@
4
4
  #include "esphome/core/controller.h"
5
5
  #include "esphome/core/helpers.h"
6
6
 
7
- #ifdef USE_ESP32_CAMERA
8
- #include "esphome/components/esp32_camera/esp32_camera.h"
7
+ #ifdef USE_CAMERA
8
+ #include "esphome/components/camera/camera.h"
9
9
  #endif
10
10
 
11
11
  namespace esphome {
12
12
 
13
- #ifdef USE_API
13
+ #ifdef USE_API_SERVICES
14
14
  namespace api {
15
15
  class UserServiceDescriptor;
16
16
  } // namespace api
@@ -45,11 +45,11 @@ class ComponentIterator {
45
45
  #ifdef USE_TEXT_SENSOR
46
46
  virtual bool on_text_sensor(text_sensor::TextSensor *text_sensor) = 0;
47
47
  #endif
48
- #ifdef USE_API
48
+ #ifdef USE_API_SERVICES
49
49
  virtual bool on_service(api::UserServiceDescriptor *service);
50
50
  #endif
51
- #ifdef USE_ESP32_CAMERA
52
- virtual bool on_camera(esp32_camera::ESP32Camera *camera);
51
+ #ifdef USE_CAMERA
52
+ virtual bool on_camera(camera::Camera *camera);
53
53
  #endif
54
54
  #ifdef USE_CLIMATE
55
55
  virtual bool on_climate(climate::Climate *climate) = 0;
@@ -93,7 +93,9 @@ class ComponentIterator {
93
93
  virtual bool on_end();
94
94
 
95
95
  protected:
96
- enum class IteratorState {
96
+ // Iterates over all ESPHome entities (sensors, switches, lights, etc.)
97
+ // Supports up to 256 entity types and up to 65,535 entities of each type
98
+ enum class IteratorState : uint8_t {
97
99
  NONE = 0,
98
100
  BEGIN,
99
101
  #ifdef USE_BINARY_SENSOR
@@ -120,10 +122,10 @@ class ComponentIterator {
120
122
  #ifdef USE_TEXT_SENSOR
121
123
  TEXT_SENSOR,
122
124
  #endif
123
- #ifdef USE_API
125
+ #ifdef USE_API_SERVICES
124
126
  SERVICE,
125
127
  #endif
126
- #ifdef USE_ESP32_CAMERA
128
+ #ifdef USE_CAMERA
127
129
  CAMERA,
128
130
  #endif
129
131
  #ifdef USE_CLIMATE
@@ -167,7 +169,7 @@ class ComponentIterator {
167
169
  #endif
168
170
  MAX,
169
171
  } state_{IteratorState::NONE};
170
- size_t at_{0};
172
+ uint16_t at_{0}; // Supports up to 65,535 entities per type
171
173
  bool include_internal_{false};
172
174
  };
173
175