esphome 2025.6.3__py3-none-any.whl → 2025.7.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 (606) 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 +8 -2
  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/as5600/as5600.h +0 -1
  42. esphome/components/async_tcp/__init__.py +14 -5
  43. esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
  44. esphome/components/atm90e32/atm90e32.cpp +2 -1
  45. esphome/components/audio/audio_decoder.cpp +1 -1
  46. esphome/components/audio/audio_transfer_buffer.cpp +2 -2
  47. esphome/components/b_parasite/b_parasite.h +0 -1
  48. esphome/components/bedjet/bedjet_hub.cpp +5 -1
  49. esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
  50. esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
  51. esphome/components/bh1750/bh1750.cpp +5 -5
  52. esphome/components/binary_sensor/__init__.py +82 -5
  53. esphome/components/binary_sensor/automation.h +19 -1
  54. esphome/components/binary_sensor/binary_sensor.cpp +12 -30
  55. esphome/components/binary_sensor/binary_sensor.h +11 -25
  56. esphome/components/binary_sensor/filter.cpp +29 -24
  57. esphome/components/binary_sensor/filter.h +20 -10
  58. esphome/components/ble_client/output/ble_binary_output.h +0 -1
  59. esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
  60. esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
  61. esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
  62. esphome/components/ble_client/sensor/ble_sensor.h +0 -1
  63. esphome/components/ble_client/switch/ble_switch.h +0 -1
  64. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
  65. esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
  66. esphome/components/ble_presence/ble_presence_device.h +0 -1
  67. esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
  68. esphome/components/ble_scanner/ble_scanner.h +0 -1
  69. esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
  70. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
  71. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
  72. esphome/components/bme680/sensor.py +1 -1
  73. esphome/components/bmp581/bmp581.h +0 -2
  74. esphome/components/button/__init__.py +5 -2
  75. esphome/components/camera/__init__.py +1 -0
  76. esphome/components/camera/camera.cpp +22 -0
  77. esphome/components/camera/camera.h +80 -0
  78. esphome/components/canbus/__init__.py +1 -0
  79. esphome/components/cap1188/cap1188.h +0 -1
  80. esphome/components/captive_portal/__init__.py +12 -2
  81. esphome/components/captive_portal/captive_portal.cpp +12 -2
  82. esphome/components/captive_portal/captive_portal.h +5 -2
  83. esphome/components/ccs811/ccs811.h +0 -2
  84. esphome/components/climate/__init__.py +5 -2
  85. esphome/components/cm1106/sensor.py +2 -2
  86. esphome/components/const/__init__.py +2 -0
  87. esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
  88. esphome/components/copy/button/copy_button.h +0 -1
  89. esphome/components/copy/cover/copy_cover.h +0 -1
  90. esphome/components/copy/fan/copy_fan.h +0 -1
  91. esphome/components/copy/lock/copy_lock.h +0 -1
  92. esphome/components/copy/number/copy_number.h +0 -1
  93. esphome/components/copy/select/copy_select.h +0 -1
  94. esphome/components/copy/sensor/copy_sensor.h +0 -1
  95. esphome/components/copy/switch/copy_switch.h +0 -1
  96. esphome/components/copy/text/copy_text.h +0 -1
  97. esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
  98. esphome/components/cover/__init__.py +5 -2
  99. esphome/components/cs5460a/cs5460a.h +0 -1
  100. esphome/components/datetime/__init__.py +4 -2
  101. esphome/components/debug/__init__.py +20 -0
  102. esphome/components/debug/debug_esp32.cpp +2 -0
  103. esphome/components/deep_sleep/__init__.py +43 -9
  104. esphome/components/demo/__init__.py +2 -2
  105. esphome/components/display/display.cpp +4 -3
  106. esphome/components/display/display.h +0 -2
  107. esphome/components/display/display_buffer.cpp +1 -1
  108. esphome/components/ds2484/__init__.py +1 -0
  109. esphome/components/ds2484/ds2484.cpp +209 -0
  110. esphome/components/ds2484/ds2484.h +43 -0
  111. esphome/components/ds2484/one_wire.py +37 -0
  112. esphome/components/duty_time/duty_time_sensor.h +0 -1
  113. esphome/components/ens160_base/ens160_base.h +0 -1
  114. esphome/components/es7210/es7210.h +0 -1
  115. esphome/components/es7243e/es7243e.h +0 -1
  116. esphome/components/es8156/es8156.h +0 -1
  117. esphome/components/es8311/es8311.h +0 -1
  118. esphome/components/es8388/es8388.h +0 -1
  119. esphome/components/esp32/__init__.py +103 -135
  120. esphome/components/esp32/core.cpp +0 -4
  121. esphome/components/esp32/gpio.h +1 -1
  122. esphome/components/esp32/helpers.cpp +69 -0
  123. esphome/components/esp32_ble/ble.cpp +5 -6
  124. esphome/components/esp32_ble/ble.h +29 -14
  125. esphome/components/esp32_ble/ble_event.h +6 -6
  126. esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
  127. esphome/components/esp32_ble_client/ble_client_base.h +24 -9
  128. esphome/components/esp32_ble_tracker/__init__.py +2 -8
  129. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
  130. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
  131. esphome/components/esp32_camera/__init__.py +112 -98
  132. esphome/components/esp32_camera/esp32_camera.cpp +41 -31
  133. esphome/components/esp32_camera/esp32_camera.h +35 -30
  134. esphome/components/esp32_camera_web_server/__init__.py +2 -1
  135. esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
  136. esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
  137. esphome/components/esp32_hall/sensor.py +2 -21
  138. esphome/components/esp32_hosted/__init__.py +101 -0
  139. esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
  140. esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
  141. esphome/components/esp32_rmt/__init__.py +0 -58
  142. esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
  143. esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
  144. esphome/components/esp32_rmt_led_strip/light.py +14 -76
  145. esphome/components/esp32_touch/esp32_touch.h +174 -28
  146. esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
  147. esphome/components/esp32_touch/esp32_touch_v1.cpp +240 -0
  148. esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
  149. esphome/components/esp8266/__init__.py +2 -0
  150. esphome/components/esp8266/gpio.cpp +10 -10
  151. esphome/components/esp8266/helpers.cpp +31 -0
  152. esphome/components/esphome/ota/__init__.py +1 -0
  153. esphome/components/esphome/ota/ota_esphome.cpp +24 -19
  154. esphome/components/ethernet/__init__.py +42 -23
  155. esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
  156. esphome/components/ethernet/ethernet_component.cpp +69 -29
  157. esphome/components/ethernet/ethernet_component.h +18 -10
  158. esphome/components/event/__init__.py +5 -2
  159. esphome/components/ezo/ezo.h +0 -1
  160. esphome/components/ezo_pmp/ezo_pmp.h +0 -1
  161. esphome/components/fan/__init__.py +5 -2
  162. esphome/components/feedback/feedback_cover.h +0 -1
  163. esphome/components/font/__init__.py +92 -82
  164. esphome/components/font/font.cpp +9 -2
  165. esphome/components/font/font.h +20 -5
  166. esphome/components/fs3000/fs3000.h +0 -1
  167. esphome/components/gcja5/gcja5.h +0 -1
  168. esphome/components/gl_r01_i2c/__init__.py +0 -0
  169. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
  170. esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
  171. esphome/components/gl_r01_i2c/sensor.py +36 -0
  172. esphome/components/gp8403/gp8403.h +0 -1
  173. esphome/components/gpio/binary_sensor/__init__.py +17 -0
  174. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
  175. esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
  176. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
  177. esphome/components/he60r/he60r.h +0 -1
  178. esphome/components/heatpumpir/climate.py +2 -1
  179. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  180. esphome/components/heatpumpir/heatpumpir.h +1 -0
  181. esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
  182. esphome/components/host/__init__.py +3 -1
  183. esphome/components/host/helpers.cpp +57 -0
  184. esphome/components/http_request/__init__.py +19 -1
  185. esphome/components/http_request/http_request.h +1 -1
  186. esphome/components/http_request/http_request_arduino.h +1 -0
  187. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  188. esphome/components/http_request/update/http_request_update.cpp +28 -9
  189. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +3 -9
  190. esphome/components/hydreon_rgxx/sensor.py +1 -1
  191. esphome/components/i2c/__init__.py +23 -11
  192. esphome/components/i2c/i2c_bus.h +8 -1
  193. esphome/components/i2c/i2c_bus_arduino.cpp +4 -3
  194. esphome/components/i2c/i2c_bus_arduino.h +6 -3
  195. esphome/components/i2c/i2c_bus_esp_idf.h +5 -3
  196. esphome/components/i2c_device/i2c_device.h +0 -1
  197. esphome/components/i2s_audio/__init__.py +2 -10
  198. esphome/components/i2s_audio/i2s_audio.cpp +1 -5
  199. esphome/components/i2s_audio/media_player/__init__.py +2 -2
  200. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +2 -2
  201. esphome/components/iaqcore/iaqcore.h +0 -2
  202. esphome/components/image/__init__.py +123 -24
  203. esphome/components/improv_serial/improv_serial_component.cpp +0 -4
  204. esphome/components/ina219/ina219.cpp +7 -0
  205. esphome/components/ina219/ina219.h +1 -0
  206. esphome/components/ina260/ina260.h +0 -2
  207. esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h +0 -1
  208. esphome/components/inkplate6/display.py +15 -0
  209. esphome/components/inkplate6/inkplate.cpp +2 -2
  210. esphome/components/integration/integration_sensor.h +0 -1
  211. esphome/components/internal_temperature/internal_temperature.cpp +8 -27
  212. esphome/components/internal_temperature/sensor.py +0 -26
  213. esphome/components/interval/interval.h +0 -2
  214. esphome/components/ld2410/button/__init__.py +3 -3
  215. esphome/components/ld2410/button/factory_reset_button.cpp +9 -0
  216. esphome/components/ld2410/button/{reset_button.h → factory_reset_button.h} +2 -2
  217. esphome/components/ld2410/ld2410.cpp +421 -268
  218. esphome/components/ld2410/ld2410.h +44 -146
  219. esphome/components/ld2410/number/__init__.py +2 -2
  220. esphome/components/ld2410/sensor.py +1 -1
  221. esphome/components/ld2410/switch/__init__.py +1 -1
  222. esphome/components/ld2420/ld2420.cpp +196 -100
  223. esphome/components/ld2420/ld2420.h +46 -118
  224. esphome/components/ld2420/number/__init__.py +2 -2
  225. esphome/components/ld2420/sensor/__init__.py +6 -2
  226. esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
  227. esphome/components/ld2450/button/__init__.py +3 -3
  228. esphome/components/ld2450/button/factory_reset_button.cpp +9 -0
  229. esphome/components/ld2450/button/{reset_button.h → factory_reset_button.h} +2 -2
  230. esphome/components/ld2450/ld2450.cpp +384 -232
  231. esphome/components/ld2450/ld2450.h +60 -69
  232. esphome/components/ld2450/switch/__init__.py +1 -1
  233. esphome/components/ledc/ledc_output.cpp +1 -63
  234. esphome/components/libretiny/__init__.py +5 -3
  235. esphome/components/libretiny/const.py +5 -0
  236. esphome/components/libretiny/generate_components.py +1 -0
  237. esphome/components/libretiny/helpers.cpp +35 -0
  238. esphome/components/libretiny/lt_component.cpp +5 -3
  239. esphome/components/light/__init__.py +4 -2
  240. esphome/components/light/addressable_light.h +3 -3
  241. esphome/components/light/light_call.cpp +180 -243
  242. esphome/components/light/light_call.h +72 -20
  243. esphome/components/light/light_color_values.h +14 -14
  244. esphome/components/light/light_state.h +15 -13
  245. esphome/components/light/transformers.h +2 -2
  246. esphome/components/ln882x/__init__.py +52 -0
  247. esphome/components/ln882x/boards.py +285 -0
  248. esphome/components/lock/__init__.py +5 -2
  249. esphome/components/logger/__init__.py +40 -3
  250. esphome/components/logger/logger.cpp +47 -12
  251. esphome/components/logger/logger.h +80 -49
  252. esphome/components/logger/logger_esp32.cpp +3 -3
  253. esphome/components/lps22/__init__.py +0 -0
  254. esphome/components/lps22/lps22.cpp +75 -0
  255. esphome/components/lps22/lps22.h +27 -0
  256. esphome/components/lps22/sensor.py +58 -0
  257. esphome/components/ltr390/ltr390.h +0 -1
  258. esphome/components/ltr501/ltr501.h +0 -1
  259. esphome/components/ltr_als_ps/ltr_als_ps.h +0 -1
  260. esphome/components/lvgl/__init__.py +1 -1
  261. esphome/components/lvgl/schemas.py +66 -6
  262. esphome/components/lvgl/styles.py +24 -16
  263. esphome/components/lvgl/widgets/__init__.py +12 -2
  264. esphome/components/lvgl/widgets/lv_bar.py +40 -19
  265. esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +1 -1
  266. esphome/components/max9611/max9611.h +0 -1
  267. esphome/components/mcp23016/__init__.py +1 -1
  268. esphome/components/mcp23xxx_base/__init__.py +1 -1
  269. esphome/components/mcp4461/__init__.py +1 -1
  270. esphome/components/mcp4461/output/__init__.py +3 -2
  271. esphome/components/mcp9600/mcp9600.h +0 -2
  272. esphome/components/md5/md5.cpp +3 -3
  273. esphome/components/md5/md5.h +1 -6
  274. esphome/components/mdns/__init__.py +22 -11
  275. esphome/components/media_player/__init__.py +4 -3
  276. esphome/components/micro_wake_word/__init__.py +1 -5
  277. esphome/components/micro_wake_word/streaming_model.cpp +2 -2
  278. esphome/components/microphone/microphone.cpp +7 -9
  279. esphome/components/microphone/microphone.h +0 -2
  280. esphome/components/mipi_spi/display.py +1 -0
  281. esphome/components/mmc5603/mmc5603.cpp +1 -1
  282. esphome/components/modbus/modbus.cpp +33 -15
  283. esphome/components/modbus/modbus.h +9 -0
  284. esphome/components/modbus_controller/__init__.py +42 -10
  285. esphome/components/modbus_controller/modbus_controller.cpp +92 -11
  286. esphome/components/modbus_controller/modbus_controller.h +61 -7
  287. esphome/components/mopeka_pro_check/mopeka_pro_check.h +0 -1
  288. esphome/components/mopeka_std_check/mopeka_std_check.h +0 -1
  289. esphome/components/mpl3115a2/mpl3115a2.h +0 -2
  290. esphome/components/mqtt/__init__.py +16 -0
  291. esphome/components/mqtt/mqtt_backend.h +2 -1
  292. esphome/components/mqtt/mqtt_backend_esp32.cpp +132 -47
  293. esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
  294. esphome/components/mqtt/mqtt_client.cpp +15 -9
  295. esphome/components/mqtt/mqtt_client.h +8 -3
  296. esphome/components/ms8607/ms8607.h +0 -1
  297. esphome/components/neopixelbus/light.py +4 -1
  298. esphome/components/neopixelbus/neopixelbus_light.h +1 -1
  299. esphome/components/network/__init__.py +4 -1
  300. esphome/components/network/ip_address.h +1 -0
  301. esphome/components/nextion/__init__.py +16 -0
  302. esphome/components/nextion/base_component.py +1 -0
  303. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
  304. esphome/components/nextion/display.py +14 -4
  305. esphome/components/nextion/nextion.cpp +166 -101
  306. esphome/components/nextion/nextion.h +84 -53
  307. esphome/components/nextion/nextion_commands.cpp +11 -10
  308. esphome/components/nextion/nextion_component.cpp +28 -28
  309. esphome/components/nextion/nextion_component.h +53 -18
  310. esphome/components/nextion/nextion_component_base.h +3 -0
  311. esphome/components/nextion/nextion_upload.cpp +36 -0
  312. esphome/components/nextion/nextion_upload_arduino.cpp +10 -35
  313. esphome/components/nextion/nextion_upload_idf.cpp +9 -33
  314. esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
  315. esphome/components/nextion/switch/nextion_switch.cpp +1 -1
  316. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
  317. esphome/components/nfc/nfc.cpp +3 -22
  318. esphome/components/nfc/nfc.h +3 -3
  319. esphome/components/number/__init__.py +5 -2
  320. esphome/components/online_image/__init__.py +5 -0
  321. esphome/components/online_image/online_image.cpp +6 -2
  322. esphome/components/online_image/online_image.h +4 -1
  323. esphome/components/opentherm/opentherm.cpp +7 -12
  324. esphome/components/openthread/__init__.py +47 -40
  325. esphome/components/openthread/const.py +1 -0
  326. esphome/components/openthread/openthread_esp.cpp +27 -5
  327. esphome/components/opt3001/__init__.py +0 -0
  328. esphome/components/opt3001/opt3001.cpp +122 -0
  329. esphome/components/opt3001/opt3001.h +27 -0
  330. esphome/components/opt3001/sensor.py +35 -0
  331. esphome/components/ota/__init__.py +17 -0
  332. esphome/components/ota/ota_backend.h +27 -1
  333. esphome/components/ota/ota_backend_arduino_esp32.cpp +12 -2
  334. esphome/components/ota/ota_backend_arduino_esp32.h +3 -0
  335. esphome/components/ota/ota_backend_arduino_esp8266.cpp +18 -4
  336. esphome/components/ota/ota_backend_arduino_esp8266.h +3 -0
  337. esphome/components/ota/ota_backend_arduino_libretiny.cpp +12 -2
  338. esphome/components/ota/ota_backend_arduino_libretiny.h +3 -0
  339. esphome/components/ota/ota_backend_arduino_rp2040.cpp +9 -2
  340. esphome/components/ota/ota_backend_arduino_rp2040.h +3 -0
  341. esphome/components/ota/ota_backend_esp_idf.cpp +10 -16
  342. esphome/components/ota/ota_backend_esp_idf.h +1 -0
  343. esphome/components/packages/__init__.py +5 -2
  344. esphome/components/packet_transport/binary_sensor.py +61 -4
  345. esphome/components/packet_transport/packet_transport.cpp +34 -1
  346. esphome/components/packet_transport/packet_transport.h +11 -5
  347. esphome/components/pcf8574/__init__.py +1 -1
  348. esphome/components/pi4ioe5v6408/__init__.py +84 -0
  349. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +171 -0
  350. esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +70 -0
  351. esphome/components/pmsa003i/pmsa003i.h +0 -1
  352. esphome/components/pmsx003/pmsx003.h +0 -1
  353. esphome/components/pn7150/pn7150.cpp +7 -7
  354. esphome/components/pn7150/pn7150.h +0 -1
  355. esphome/components/pn7160/pn7160.cpp +7 -7
  356. esphome/components/pn7160/pn7160.h +0 -1
  357. esphome/components/preferences/syncer.h +2 -0
  358. esphome/components/prometheus/prometheus_handler.h +1 -1
  359. esphome/components/psram/psram.cpp +0 -20
  360. esphome/components/pulse_counter/pulse_counter_sensor.h +0 -1
  361. esphome/components/pulse_meter/pulse_meter_sensor.cpp +8 -4
  362. esphome/components/pulse_width/pulse_width.h +0 -1
  363. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +0 -4
  364. esphome/components/pvvx_mithermometer/display/pvvx_display.h +0 -2
  365. esphome/components/pvvx_mithermometer/pvvx_mithermometer.h +0 -1
  366. esphome/components/qr_code/__init__.py +13 -10
  367. esphome/components/qwiic_pir/qwiic_pir.h +0 -1
  368. esphome/components/radon_eye_ble/radon_eye_listener.cpp +1 -1
  369. esphome/components/rc522/rc522.h +0 -1
  370. esphome/components/rdm6300/rdm6300.h +0 -2
  371. esphome/components/remote_base/__init__.py +7 -5
  372. esphome/components/remote_base/remote_base.cpp +24 -21
  373. esphome/components/remote_base/remote_base.h +3 -26
  374. esphome/components/remote_receiver/__init__.py +40 -46
  375. esphome/components/remote_receiver/remote_receiver.h +4 -18
  376. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -87
  377. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +1 -1
  378. esphome/components/remote_transmitter/__init__.py +42 -43
  379. esphome/components/remote_transmitter/remote_transmitter.h +2 -14
  380. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -77
  381. esphome/components/resistance/resistance_sensor.h +0 -1
  382. esphome/components/rp2040/__init__.py +2 -0
  383. esphome/components/rp2040/helpers.cpp +55 -0
  384. esphome/components/rp2040_pio_led_strip/led_strip.cpp +2 -2
  385. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -4
  386. esphome/components/rtttl/__init__.py +4 -4
  387. esphome/components/rtttl/rtttl.cpp +10 -1
  388. esphome/components/ruuvitag/ruuvitag.h +0 -1
  389. esphome/components/safe_mode/safe_mode.cpp +2 -0
  390. esphome/components/safe_mode/safe_mode.h +4 -1
  391. esphome/components/scd30/scd30.h +0 -1
  392. esphome/components/scd30/sensor.py +2 -2
  393. esphome/components/scd4x/scd4x.cpp +61 -54
  394. esphome/components/scd4x/scd4x.h +17 -15
  395. esphome/components/scd4x/sensor.py +4 -4
  396. esphome/components/script/script.h +0 -2
  397. esphome/components/sdp3x/sensor.py +1 -1
  398. esphome/components/select/__init__.py +5 -2
  399. esphome/components/sen5x/sen5x.h +0 -1
  400. esphome/components/senseair/senseair.h +0 -1
  401. esphome/components/sensor/__init__.py +4 -2
  402. esphome/components/sensor/filter.cpp +1 -1
  403. esphome/components/sensor/sensor.cpp +12 -6
  404. esphome/components/sensor/sensor.h +13 -5
  405. esphome/components/servo/servo.h +0 -1
  406. esphome/components/sfa30/sfa30.h +0 -1
  407. esphome/components/sgp30/sgp30.h +0 -1
  408. esphome/components/sgp4x/sgp4x.h +0 -1
  409. esphome/components/shelly_dimmer/stm32flash.cpp +1 -2
  410. esphome/components/sht4x/sht4x.h +0 -1
  411. esphome/components/sm300d2/sm300d2.h +0 -2
  412. esphome/components/smt100/sensor.py +8 -4
  413. esphome/components/smt100/smt100.cpp +5 -5
  414. esphome/components/smt100/smt100.h +3 -3
  415. esphome/components/sn74hc595/__init__.py +1 -1
  416. esphome/components/sn74hc595/sn74hc595.cpp +5 -4
  417. esphome/components/sntp/sntp_component.cpp +9 -3
  418. esphome/components/sntp/time.py +2 -0
  419. esphome/components/socket/__init__.py +17 -0
  420. esphome/components/spi/__init__.py +27 -6
  421. esphome/components/spi/spi.cpp +3 -2
  422. esphome/components/spi/spi.h +9 -3
  423. esphome/components/spi/spi_arduino.cpp +3 -5
  424. esphome/components/spi/spi_esp_idf.cpp +40 -21
  425. esphome/components/spi_led_strip/spi_led_strip.cpp +1 -1
  426. esphome/components/sps30/sps30.h +0 -1
  427. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  428. esphome/components/st7701s/st7701s.cpp +0 -4
  429. esphome/components/status/status_binary_sensor.h +0 -2
  430. esphome/components/substitutions/__init__.py +76 -19
  431. esphome/components/substitutions/jinja.py +99 -0
  432. esphome/components/sun/sun.cpp +3 -4
  433. esphome/components/switch/__init__.py +5 -2
  434. esphome/components/switch/binary_sensor/switch_binary_sensor.h +0 -1
  435. esphome/components/sx126x/__init__.py +317 -0
  436. esphome/components/sx126x/automation.h +62 -0
  437. esphome/components/sx126x/packet_transport/__init__.py +26 -0
  438. esphome/components/sx126x/packet_transport/sx126x_transport.cpp +26 -0
  439. esphome/components/sx126x/packet_transport/sx126x_transport.h +25 -0
  440. esphome/components/sx126x/sx126x.cpp +523 -0
  441. esphome/components/sx126x/sx126x.h +140 -0
  442. esphome/components/sx126x/sx126x_reg.h +163 -0
  443. esphome/components/sx127x/__init__.py +325 -0
  444. esphome/components/sx127x/automation.h +62 -0
  445. esphome/components/sx127x/packet_transport/__init__.py +26 -0
  446. esphome/components/sx127x/packet_transport/sx127x_transport.cpp +26 -0
  447. esphome/components/sx127x/packet_transport/sx127x_transport.h +25 -0
  448. esphome/components/sx127x/sx127x.cpp +498 -0
  449. esphome/components/sx127x/sx127x.h +128 -0
  450. esphome/components/sx127x/sx127x_reg.h +295 -0
  451. esphome/components/syslog/esphome_syslog.cpp +5 -3
  452. esphome/components/syslog/esphome_syslog.h +1 -1
  453. esphome/components/tca9555/__init__.py +1 -1
  454. esphome/components/template/binary_sensor/template_binary_sensor.cpp +1 -9
  455. esphome/components/text/__init__.py +5 -2
  456. esphome/components/text_sensor/__init__.py +5 -2
  457. esphome/components/thermostat/thermostat_climate.cpp +34 -31
  458. esphome/components/thermostat/thermostat_climate.h +43 -39
  459. esphome/components/time/__init__.py +16 -2
  460. esphome/components/time/real_time_clock.cpp +4 -0
  461. esphome/components/time/real_time_clock.h +5 -1
  462. esphome/components/tlc5971/tlc5971.cpp +4 -1
  463. esphome/components/tmp1075/tmp1075.h +0 -2
  464. esphome/components/tof10120/tof10120_sensor.h +0 -1
  465. esphome/components/tormatic/tormatic_cover.h +0 -1
  466. esphome/components/total_daily_energy/total_daily_energy.h +0 -1
  467. esphome/components/tsl2591/tsl2591.cpp +1 -1
  468. esphome/components/ttp229_bsf/ttp229_bsf.h +0 -1
  469. esphome/components/ttp229_lsf/ttp229_lsf.h +0 -1
  470. esphome/components/tx20/tx20.cpp +2 -2
  471. esphome/components/uart/__init__.py +18 -0
  472. esphome/components/uart/uart_component_esp_idf.cpp +0 -4
  473. esphome/components/update/__init__.py +5 -2
  474. esphome/components/update/update_entity.h +8 -0
  475. esphome/components/usb_host/__init__.py +5 -2
  476. esphome/components/usb_host/usb_host_client.cpp +10 -10
  477. esphome/components/usb_uart/cp210x.cpp +1 -1
  478. esphome/components/usb_uart/usb_uart.cpp +41 -44
  479. esphome/components/usb_uart/usb_uart.h +4 -3
  480. esphome/components/valve/__init__.py +5 -2
  481. esphome/components/vbus/vbus.h +0 -1
  482. esphome/components/veml3235/veml3235.h +0 -1
  483. esphome/components/veml7700/veml7700.h +0 -1
  484. esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
  485. esphome/components/voice_assistant/voice_assistant.cpp +4 -4
  486. esphome/components/watchdog/watchdog.cpp +0 -4
  487. esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
  488. esphome/components/web_server/__init__.py +34 -19
  489. esphome/components/web_server/ota/__init__.py +32 -0
  490. esphome/components/web_server/ota/ota_web_server.cpp +210 -0
  491. esphome/components/web_server/ota/ota_web_server.h +26 -0
  492. esphome/components/web_server/web_server.cpp +305 -427
  493. esphome/components/web_server/web_server.h +33 -23
  494. esphome/components/web_server/web_server_v1.cpp +4 -5
  495. esphome/components/web_server_base/__init__.py +5 -2
  496. esphome/components/web_server_base/web_server_base.cpp +2 -94
  497. esphome/components/web_server_base/web_server_base.h +5 -25
  498. esphome/components/web_server_idf/multipart.cpp +254 -0
  499. esphome/components/web_server_idf/multipart.h +86 -0
  500. esphome/components/web_server_idf/utils.cpp +32 -0
  501. esphome/components/web_server_idf/utils.h +10 -0
  502. esphome/components/web_server_idf/web_server_idf.cpp +162 -16
  503. esphome/components/web_server_idf/web_server_idf.h +11 -10
  504. esphome/components/wiegand/wiegand.cpp +2 -2
  505. esphome/components/wifi/__init__.py +18 -0
  506. esphome/components/wifi/wifi_component.cpp +17 -22
  507. esphome/components/wifi/wifi_component.h +27 -23
  508. esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
  509. esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
  510. esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
  511. esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
  512. esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
  513. esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
  514. esphome/components/wireguard/__init__.py +2 -11
  515. esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
  516. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  517. esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
  518. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
  519. esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
  520. esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
  521. esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
  522. esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
  523. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
  524. esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
  525. esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
  526. esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
  527. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
  528. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
  529. esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
  530. esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
  531. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
  532. esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
  533. esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
  534. esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
  535. esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
  536. esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
  537. esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
  538. esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
  539. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
  540. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
  541. esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
  542. esphome/components/zyaura/zyaura.h +0 -1
  543. esphome/config.py +88 -22
  544. esphome/config_helpers.py +74 -1
  545. esphome/config_validation.py +12 -1
  546. esphome/const.py +65 -10
  547. esphome/core/__init__.py +18 -2
  548. esphome/core/application.cpp +163 -10
  549. esphome/core/application.h +145 -165
  550. esphome/core/area.h +19 -0
  551. esphome/core/automation.h +58 -9
  552. esphome/core/color.cpp +3 -5
  553. esphome/core/color.h +16 -16
  554. esphome/core/component.cpp +151 -18
  555. esphome/core/component.h +98 -4
  556. esphome/core/component_iterator.cpp +11 -9
  557. esphome/core/component_iterator.h +12 -10
  558. esphome/core/config.py +155 -6
  559. esphome/core/controller.cpp +4 -2
  560. esphome/core/controller.h +1 -1
  561. esphome/core/datatypes.h +2 -2
  562. esphome/core/defines.h +17 -2
  563. esphome/core/device.h +20 -0
  564. esphome/core/entity_base.cpp +20 -15
  565. esphome/core/entity_base.h +76 -0
  566. esphome/core/entity_helpers.py +168 -1
  567. esphome/core/event_pool.h +81 -0
  568. esphome/core/helpers.cpp +75 -230
  569. esphome/core/helpers.h +164 -104
  570. esphome/core/lock_free_queue.h +151 -0
  571. esphome/core/log.cpp +2 -2
  572. esphome/core/log.h +2 -0
  573. esphome/core/optional.h +5 -0
  574. esphome/core/ring_buffer.cpp +2 -2
  575. esphome/core/scheduler.cpp +275 -103
  576. esphome/core/scheduler.h +154 -17
  577. esphome/core/time.cpp +5 -5
  578. esphome/core/time.h +5 -5
  579. esphome/cpp_generator.py +17 -0
  580. esphome/cpp_helpers.py +0 -22
  581. esphome/cpp_types.py +3 -1
  582. esphome/dashboard/entries.py +1 -1
  583. esphome/dashboard/util/text.py +5 -21
  584. esphome/dashboard/web_server.py +9 -1
  585. esphome/helpers.py +47 -0
  586. esphome/loader.py +15 -1
  587. esphome/pins.py +14 -8
  588. esphome/wizard.py +17 -4
  589. esphome/writer.py +21 -3
  590. esphome/yaml_util.py +0 -2
  591. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/METADATA +10 -9
  592. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/RECORD +597 -538
  593. esphome/components/api/api_pb2_size.h +0 -361
  594. esphome/components/esp32_ble/ble_event_pool.h +0 -72
  595. esphome/components/esp32_ble/queue.h +0 -85
  596. esphome/components/esp32_hall/esp32_hall.cpp +0 -25
  597. esphome/components/esp32_hall/esp32_hall.h +0 -23
  598. esphome/components/esp32_touch/esp32_touch.cpp +0 -355
  599. esphome/components/ld2410/button/reset_button.cpp +0 -9
  600. esphome/components/ld2450/button/reset_button.cpp +0 -9
  601. esphome/components/openthread/tlv.py +0 -65
  602. /esphome/{dashboard/enum.py → enum.py} +0 -0
  603. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/WHEEL +0 -0
  604. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/entry_points.txt +0 -0
  605. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/licenses/LICENSE +0 -0
  606. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,7 @@ import logging
4
4
  import os
5
5
  from pathlib import Path
6
6
 
7
- from esphome import git
7
+ from esphome import yaml_util
8
8
  import esphome.codegen as cg
9
9
  import esphome.config_validation as cv
10
10
  from esphome.const import (
@@ -23,7 +23,6 @@ from esphome.const import (
23
23
  CONF_REFRESH,
24
24
  CONF_SOURCE,
25
25
  CONF_TYPE,
26
- CONF_URL,
27
26
  CONF_VARIANT,
28
27
  CONF_VERSION,
29
28
  KEY_CORE,
@@ -32,14 +31,13 @@ from esphome.const import (
32
31
  KEY_TARGET_FRAMEWORK,
33
32
  KEY_TARGET_PLATFORM,
34
33
  PLATFORM_ESP32,
35
- TYPE_GIT,
36
- TYPE_LOCAL,
37
34
  __version__,
38
35
  )
39
36
  from esphome.core import CORE, HexInt, TimePeriod
40
37
  from esphome.cpp_generator import RawExpression
41
38
  import esphome.final_validate as fv
42
39
  from esphome.helpers import copy_file_if_changed, mkdir_p, write_file_if_changed
40
+ from esphome.types import ConfigType
43
41
 
44
42
  from .boards import BOARDS
45
43
  from .const import ( # noqa
@@ -49,10 +47,8 @@ from .const import ( # noqa
49
47
  KEY_EXTRA_BUILD_FILES,
50
48
  KEY_PATH,
51
49
  KEY_REF,
52
- KEY_REFRESH,
53
50
  KEY_REPO,
54
51
  KEY_SDKCONFIG_OPTIONS,
55
- KEY_SUBMODULES,
56
52
  KEY_VARIANT,
57
53
  VARIANT_ESP32,
58
54
  VARIANT_ESP32C2,
@@ -132,6 +128,8 @@ def set_core_data(config):
132
128
  choices = CPU_FREQUENCIES[variant]
133
129
  if "160MHZ" in choices:
134
130
  cpu_frequency = "160MHZ"
131
+ elif "360MHZ" in choices:
132
+ cpu_frequency = "360MHZ"
135
133
  else:
136
134
  cpu_frequency = choices[-1]
137
135
  config[CONF_CPU_FREQUENCY] = cpu_frequency
@@ -191,7 +189,7 @@ def get_download_types(storage_json):
191
189
  ]
192
190
 
193
191
 
194
- def only_on_variant(*, supported=None, unsupported=None):
192
+ def only_on_variant(*, supported=None, unsupported=None, msg_prefix="This feature"):
195
193
  """Config validator for features only available on some ESP32 variants."""
196
194
  if supported is not None and not isinstance(supported, list):
197
195
  supported = [supported]
@@ -202,11 +200,11 @@ def only_on_variant(*, supported=None, unsupported=None):
202
200
  variant = get_esp32_variant()
203
201
  if supported is not None and variant not in supported:
204
202
  raise cv.Invalid(
205
- f"This feature is only available on {', '.join(supported)}"
203
+ f"{msg_prefix} is only available on {', '.join(supported)}"
206
204
  )
207
205
  if unsupported is not None and variant in unsupported:
208
206
  raise cv.Invalid(
209
- f"This feature is not available on {', '.join(unsupported)}"
207
+ f"{msg_prefix} is not available on {', '.join(unsupported)}"
210
208
  )
211
209
  return obj
212
210
 
@@ -233,7 +231,7 @@ def add_idf_sdkconfig_option(name: str, value: SdkconfigValueType):
233
231
  def add_idf_component(
234
232
  *,
235
233
  name: str,
236
- repo: str,
234
+ repo: str = None,
237
235
  ref: str = None,
238
236
  path: str = None,
239
237
  refresh: TimePeriod = None,
@@ -243,30 +241,27 @@ def add_idf_component(
243
241
  """Add an esp-idf component to the project."""
244
242
  if not CORE.using_esp_idf:
245
243
  raise ValueError("Not an esp-idf project")
246
- if components is None:
247
- components = []
248
- if name not in CORE.data[KEY_ESP32][KEY_COMPONENTS]:
244
+ if not repo and not ref and not path:
245
+ raise ValueError("Requires at least one of repo, ref or path")
246
+ if refresh or submodules or components:
247
+ _LOGGER.warning(
248
+ "The refresh, components and submodules parameters in add_idf_component() are "
249
+ "deprecated and will be removed in ESPHome 2026.1. If you are seeing this, report "
250
+ "an issue to the external_component author and ask them to update it."
251
+ )
252
+ if components:
253
+ for comp in components:
254
+ CORE.data[KEY_ESP32][KEY_COMPONENTS][comp] = {
255
+ KEY_REPO: repo,
256
+ KEY_REF: ref,
257
+ KEY_PATH: f"{path}/{comp}" if path else comp,
258
+ }
259
+ else:
249
260
  CORE.data[KEY_ESP32][KEY_COMPONENTS][name] = {
250
261
  KEY_REPO: repo,
251
262
  KEY_REF: ref,
252
263
  KEY_PATH: path,
253
- KEY_REFRESH: refresh,
254
- KEY_COMPONENTS: components,
255
- KEY_SUBMODULES: submodules,
256
264
  }
257
- else:
258
- component_config = CORE.data[KEY_ESP32][KEY_COMPONENTS][name]
259
- if components is not None:
260
- component_config[KEY_COMPONENTS] = list(
261
- set(component_config[KEY_COMPONENTS] + components)
262
- )
263
- if submodules is not None:
264
- if component_config[KEY_SUBMODULES] is None:
265
- component_config[KEY_SUBMODULES] = submodules
266
- else:
267
- component_config[KEY_SUBMODULES] = list(
268
- set(component_config[KEY_SUBMODULES] + submodules)
269
- )
270
265
 
271
266
 
272
267
  def add_extra_script(stage: str, filename: str, path: str):
@@ -289,11 +284,8 @@ def add_extra_build_file(filename: str, path: str) -> bool:
289
284
 
290
285
  def _format_framework_arduino_version(ver: cv.Version) -> str:
291
286
  # format the given arduino (https://github.com/espressif/arduino-esp32/releases) version to
292
- # a PIO platformio/framework-arduinoespressif32 value
293
- # List of package versions: https://api.registry.platformio.org/v3/packages/platformio/tool/framework-arduinoespressif32
294
- if ver <= cv.Version(1, 0, 3):
295
- return f"~2.{ver.major}{ver.minor:02d}{ver.patch:02d}.0"
296
- return f"~3.{ver.major}{ver.minor:02d}{ver.patch:02d}.0"
287
+ # a PIO pioarduino/framework-arduinoespressif32 value
288
+ return f"pioarduino/framework-arduinoespressif32@https://github.com/espressif/arduino-esp32/releases/download/{str(ver)}/esp32-{str(ver)}.zip"
297
289
 
298
290
 
299
291
  def _format_framework_espidf_version(
@@ -317,12 +309,10 @@ def _format_framework_espidf_version(
317
309
 
318
310
  # The default/recommended arduino framework version
319
311
  # - https://github.com/espressif/arduino-esp32/releases
320
- # - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-arduinoespressif32
321
- RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(2, 0, 5)
322
- # The platformio/espressif32 version to use for arduino frameworks
323
- # - https://github.com/platformio/platform-espressif32/releases
324
- # - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
325
- ARDUINO_PLATFORM_VERSION = cv.Version(5, 4, 0)
312
+ RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(3, 1, 3)
313
+ # The platform-espressif32 version to use for arduino frameworks
314
+ # - https://github.com/pioarduino/platform-espressif32/releases
315
+ ARDUINO_PLATFORM_VERSION = cv.Version(53, 3, 13)
326
316
 
327
317
  # The default/recommended esp-idf framework version
328
318
  # - https://github.com/espressif/esp-idf/releases
@@ -351,6 +341,7 @@ SUPPORTED_PLATFORMIO_ESP_IDF_5X = [
351
341
  # List based on https://github.com/pioarduino/esp-idf/releases
352
342
  SUPPORTED_PIOARDUINO_ESP_IDF_5X = [
353
343
  cv.Version(5, 5, 0),
344
+ cv.Version(5, 4, 2),
354
345
  cv.Version(5, 4, 1),
355
346
  cv.Version(5, 4, 0),
356
347
  cv.Version(5, 3, 3),
@@ -365,8 +356,8 @@ SUPPORTED_PIOARDUINO_ESP_IDF_5X = [
365
356
  def _arduino_check_versions(value):
366
357
  value = value.copy()
367
358
  lookups = {
368
- "dev": (cv.Version(2, 1, 0), "https://github.com/espressif/arduino-esp32.git"),
369
- "latest": (cv.Version(2, 0, 9), None),
359
+ "dev": (cv.Version(3, 1, 3), "https://github.com/espressif/arduino-esp32.git"),
360
+ "latest": (cv.Version(3, 1, 3), None),
370
361
  "recommended": (RECOMMENDED_ARDUINO_FRAMEWORK_VERSION, None),
371
362
  }
372
363
 
@@ -388,6 +379,10 @@ def _arduino_check_versions(value):
388
379
  CONF_PLATFORM_VERSION, _parse_platform_version(str(ARDUINO_PLATFORM_VERSION))
389
380
  )
390
381
 
382
+ if value[CONF_SOURCE].startswith("http"):
383
+ # prefix is necessary or platformio will complain with a cryptic error
384
+ value[CONF_SOURCE] = f"framework-arduinoespressif32@{value[CONF_SOURCE]}"
385
+
391
386
  if version != RECOMMENDED_ARDUINO_FRAMEWORK_VERSION:
392
387
  _LOGGER.warning(
393
388
  "The selected Arduino framework version is not the recommended one. "
@@ -416,8 +411,8 @@ def _esp_idf_check_versions(value):
416
411
  version = cv.Version.parse(cv.version_number(value[CONF_VERSION]))
417
412
  source = value.get(CONF_SOURCE, None)
418
413
 
419
- if version < cv.Version(4, 0, 0):
420
- raise cv.Invalid("Only ESP-IDF 4.0+ is supported.")
414
+ if version < cv.Version(5, 0, 0):
415
+ raise cv.Invalid("Only ESP-IDF 5.0+ is supported.")
421
416
 
422
417
  # flag this for later *before* we set value[CONF_PLATFORM_VERSION] below
423
418
  has_platform_ver = CONF_PLATFORM_VERSION in value
@@ -427,20 +422,15 @@ def _esp_idf_check_versions(value):
427
422
  )
428
423
 
429
424
  if (
430
- (is_platformio := _platform_is_platformio(value[CONF_PLATFORM_VERSION]))
431
- and version.major >= 5
432
- and version not in SUPPORTED_PLATFORMIO_ESP_IDF_5X
433
- ):
425
+ is_platformio := _platform_is_platformio(value[CONF_PLATFORM_VERSION])
426
+ ) and version not in SUPPORTED_PLATFORMIO_ESP_IDF_5X:
434
427
  raise cv.Invalid(
435
428
  f"ESP-IDF {str(version)} not supported by platformio/espressif32"
436
429
  )
437
430
 
438
431
  if (
439
- version.major < 5
440
- or (
441
- version in SUPPORTED_PLATFORMIO_ESP_IDF_5X
442
- and version not in SUPPORTED_PIOARDUINO_ESP_IDF_5X
443
- )
432
+ version in SUPPORTED_PLATFORMIO_ESP_IDF_5X
433
+ and version not in SUPPORTED_PIOARDUINO_ESP_IDF_5X
444
434
  ) and not has_platform_ver:
445
435
  raise cv.Invalid(
446
436
  f"ESP-IDF {value[CONF_VERSION]} may be supported by platformio/espressif32; please specify '{CONF_PLATFORM_VERSION}'"
@@ -574,6 +564,17 @@ CONF_ENABLE_LWIP_DHCP_SERVER = "enable_lwip_dhcp_server"
574
564
  CONF_ENABLE_LWIP_MDNS_QUERIES = "enable_lwip_mdns_queries"
575
565
  CONF_ENABLE_LWIP_BRIDGE_INTERFACE = "enable_lwip_bridge_interface"
576
566
 
567
+
568
+ def _validate_idf_component(config: ConfigType) -> ConfigType:
569
+ """Validate IDF component config and warn about deprecated options."""
570
+ if CONF_REFRESH in config:
571
+ _LOGGER.warning(
572
+ "The 'refresh' option for IDF components is deprecated and has no effect. "
573
+ "It will be removed in ESPHome 2026.1. Please remove it from your configuration."
574
+ )
575
+ return config
576
+
577
+
577
578
  ESP_IDF_FRAMEWORK_SCHEMA = cv.All(
578
579
  cv.Schema(
579
580
  {
@@ -613,15 +614,19 @@ ESP_IDF_FRAMEWORK_SCHEMA = cv.All(
613
614
  }
614
615
  ),
615
616
  cv.Optional(CONF_COMPONENTS, default=[]): cv.ensure_list(
616
- cv.Schema(
617
- {
618
- cv.Required(CONF_NAME): cv.string_strict,
619
- cv.Required(CONF_SOURCE): cv.SOURCE_SCHEMA,
620
- cv.Optional(CONF_PATH): cv.string,
621
- cv.Optional(CONF_REFRESH, default="1d"): cv.All(
622
- cv.string, cv.source_refresh
623
- ),
624
- }
617
+ cv.All(
618
+ cv.Schema(
619
+ {
620
+ cv.Required(CONF_NAME): cv.string_strict,
621
+ cv.Optional(CONF_SOURCE): cv.git_ref,
622
+ cv.Optional(CONF_REF): cv.string,
623
+ cv.Optional(CONF_PATH): cv.string,
624
+ cv.Optional(CONF_REFRESH): cv.All(
625
+ cv.string, cv.source_refresh
626
+ ),
627
+ }
628
+ ),
629
+ _validate_idf_component,
625
630
  )
626
631
  ),
627
632
  }
@@ -695,12 +700,14 @@ FINAL_VALIDATE_SCHEMA = cv.Schema(final_validate)
695
700
  async def to_code(config):
696
701
  cg.add_platformio_option("board", config[CONF_BOARD])
697
702
  cg.add_platformio_option("board_upload.flash_size", config[CONF_FLASH_SIZE])
703
+ cg.set_cpp_standard("gnu++20")
698
704
  cg.add_build_flag("-DUSE_ESP32")
699
705
  cg.add_define("ESPHOME_BOARD", config[CONF_BOARD])
700
706
  cg.add_build_flag(f"-DUSE_ESP32_VARIANT_{config[CONF_VARIANT]}")
701
707
  cg.add_define("ESPHOME_VARIANT", VARIANT_FRIENDLY[config[CONF_VARIANT]])
702
708
 
703
709
  cg.add_platformio_option("lib_ldf_mode", "off")
710
+ cg.add_platformio_option("lib_compat_mode", "strict")
704
711
 
705
712
  framework_ver: cv.Version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]
706
713
 
@@ -748,6 +755,9 @@ async def to_code(config):
748
755
  add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0", False)
749
756
  add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1", False)
750
757
 
758
+ # Disable dynamic log level control to save memory
759
+ add_idf_sdkconfig_option("CONFIG_LOG_DYNAMIC_LEVEL_CONTROL", False)
760
+
751
761
  # Set default CPU frequency
752
762
  add_idf_sdkconfig_option(f"CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_{freq}", True)
753
763
 
@@ -787,14 +797,9 @@ async def to_code(config):
787
797
 
788
798
  if advanced.get(CONF_IGNORE_EFUSE_MAC_CRC):
789
799
  add_idf_sdkconfig_option("CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR", True)
790
- if (framework_ver.major, framework_ver.minor) >= (4, 4):
791
- add_idf_sdkconfig_option(
792
- "CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE", False
793
- )
794
- else:
795
- add_idf_sdkconfig_option(
796
- "CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE", False
797
- )
800
+ add_idf_sdkconfig_option(
801
+ "CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE", False
802
+ )
798
803
  if advanced.get(CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES):
799
804
  _LOGGER.warning(
800
805
  "Using experimental features in ESP-IDF may result in unexpected failures."
@@ -812,26 +817,17 @@ async def to_code(config):
812
817
  add_idf_sdkconfig_option(name, RawSdkconfigValue(value))
813
818
 
814
819
  for component in conf[CONF_COMPONENTS]:
815
- source = component[CONF_SOURCE]
816
- if source[CONF_TYPE] == TYPE_GIT:
817
- add_idf_component(
818
- name=component[CONF_NAME],
819
- repo=source[CONF_URL],
820
- ref=source.get(CONF_REF),
821
- path=component.get(CONF_PATH),
822
- refresh=component[CONF_REFRESH],
823
- )
824
- elif source[CONF_TYPE] == TYPE_LOCAL:
825
- _LOGGER.warning("Local components are not implemented yet.")
826
-
820
+ add_idf_component(
821
+ name=component[CONF_NAME],
822
+ repo=component.get(CONF_SOURCE),
823
+ ref=component.get(CONF_REF),
824
+ path=component.get(CONF_PATH),
825
+ )
827
826
  elif conf[CONF_TYPE] == FRAMEWORK_ARDUINO:
828
827
  cg.add_platformio_option("framework", "arduino")
829
828
  cg.add_build_flag("-DUSE_ARDUINO")
830
829
  cg.add_build_flag("-DUSE_ESP32_FRAMEWORK_ARDUINO")
831
- cg.add_platformio_option(
832
- "platform_packages",
833
- [f"platformio/framework-arduinoespressif32@{conf[CONF_SOURCE]}"],
834
- )
830
+ cg.add_platformio_option("platform_packages", [conf[CONF_SOURCE]])
835
831
 
836
832
  if CONF_PARTITIONS in config:
837
833
  cg.add_platformio_option("board_build.partitions", config[CONF_PARTITIONS])
@@ -925,6 +921,26 @@ def _write_sdkconfig():
925
921
  write_file_if_changed(sdk_path, contents)
926
922
 
927
923
 
924
+ def _write_idf_component_yml():
925
+ yml_path = Path(CORE.relative_build_path("src/idf_component.yml"))
926
+ if CORE.data[KEY_ESP32][KEY_COMPONENTS]:
927
+ components: dict = CORE.data[KEY_ESP32][KEY_COMPONENTS]
928
+ dependencies = {}
929
+ for name, component in components.items():
930
+ dependency = {}
931
+ if component[KEY_REF]:
932
+ dependency["version"] = component[KEY_REF]
933
+ if component[KEY_REPO]:
934
+ dependency["git"] = component[KEY_REPO]
935
+ if component[KEY_PATH]:
936
+ dependency["path"] = component[KEY_PATH]
937
+ dependencies[name] = dependency
938
+ contents = yaml_util.dump({"dependencies": dependencies})
939
+ else:
940
+ contents = ""
941
+ write_file_if_changed(yml_path, contents)
942
+
943
+
928
944
  # Called by writer.py
929
945
  def copy_files():
930
946
  if CORE.using_arduino:
@@ -937,6 +953,7 @@ def copy_files():
937
953
  )
938
954
  if CORE.using_esp_idf:
939
955
  _write_sdkconfig()
956
+ _write_idf_component_yml()
940
957
  if "partitions.csv" not in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES]:
941
958
  write_file_if_changed(
942
959
  CORE.relative_build_path("partitions.csv"),
@@ -953,55 +970,6 @@ def copy_files():
953
970
  __version__,
954
971
  )
955
972
 
956
- import shutil
957
-
958
- shutil.rmtree(CORE.relative_build_path("components"), ignore_errors=True)
959
-
960
- if CORE.data[KEY_ESP32][KEY_COMPONENTS]:
961
- components: dict = CORE.data[KEY_ESP32][KEY_COMPONENTS]
962
-
963
- for name, component in components.items():
964
- repo_dir, _ = git.clone_or_update(
965
- url=component[KEY_REPO],
966
- ref=component[KEY_REF],
967
- refresh=component[KEY_REFRESH],
968
- domain="idf_components",
969
- submodules=component[KEY_SUBMODULES],
970
- )
971
- mkdir_p(CORE.relative_build_path("components"))
972
- component_dir = repo_dir
973
- if component[KEY_PATH] is not None:
974
- component_dir = component_dir / component[KEY_PATH]
975
-
976
- if component[KEY_COMPONENTS] == ["*"]:
977
- shutil.copytree(
978
- component_dir,
979
- CORE.relative_build_path("components"),
980
- dirs_exist_ok=True,
981
- ignore=shutil.ignore_patterns(".git*"),
982
- symlinks=True,
983
- ignore_dangling_symlinks=True,
984
- )
985
- elif len(component[KEY_COMPONENTS]) > 0:
986
- for comp in component[KEY_COMPONENTS]:
987
- shutil.copytree(
988
- component_dir / comp,
989
- CORE.relative_build_path(f"components/{comp}"),
990
- dirs_exist_ok=True,
991
- ignore=shutil.ignore_patterns(".git*"),
992
- symlinks=True,
993
- ignore_dangling_symlinks=True,
994
- )
995
- else:
996
- shutil.copytree(
997
- component_dir,
998
- CORE.relative_build_path(f"components/{name}"),
999
- dirs_exist_ok=True,
1000
- ignore=shutil.ignore_patterns(".git*"),
1001
- symlinks=True,
1002
- ignore_dangling_symlinks=True,
1003
- )
1004
-
1005
973
  for _, file in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES].items():
1006
974
  if file[KEY_PATH].startswith("http"):
1007
975
  import requests
@@ -56,11 +56,7 @@ void arch_init() {
56
56
  void IRAM_ATTR HOT arch_feed_wdt() { esp_task_wdt_reset(); }
57
57
 
58
58
  uint8_t progmem_read_byte(const uint8_t *addr) { return *addr; }
59
- #if ESP_IDF_VERSION_MAJOR >= 5
60
59
  uint32_t arch_get_cpu_cycle_count() { return esp_cpu_get_cycle_count(); }
61
- #else
62
- uint32_t arch_get_cpu_cycle_count() { return cpu_hal_get_cycle_count(); }
63
- #endif
64
60
  uint32_t arch_get_cpu_freq_hz() {
65
61
  uint32_t freq = 0;
66
62
  #ifdef USE_ESP_IDF
@@ -29,9 +29,9 @@ class ESP32InternalGPIOPin : public InternalGPIOPin {
29
29
  void attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const override;
30
30
 
31
31
  gpio_num_t pin_;
32
- bool inverted_;
33
32
  gpio_drive_cap_t drive_strength_;
34
33
  gpio::Flags flags_;
34
+ bool inverted_;
35
35
  // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
36
36
  static bool isr_service_installed;
37
37
  };
@@ -0,0 +1,69 @@
1
+ #include "esphome/core/helpers.h"
2
+
3
+ #ifdef USE_ESP32
4
+
5
+ #include "esp_efuse.h"
6
+ #include "esp_efuse_table.h"
7
+ #include "esp_mac.h"
8
+
9
+ #include <freertos/FreeRTOS.h>
10
+ #include <freertos/portmacro.h>
11
+ #include "esp_random.h"
12
+ #include "esp_system.h"
13
+
14
+ namespace esphome {
15
+
16
+ uint32_t random_uint32() { return esp_random(); }
17
+ bool random_bytes(uint8_t *data, size_t len) {
18
+ esp_fill_random(data, len);
19
+ return true;
20
+ }
21
+
22
+ Mutex::Mutex() { handle_ = xSemaphoreCreateMutex(); }
23
+ Mutex::~Mutex() {}
24
+ void Mutex::lock() { xSemaphoreTake(this->handle_, portMAX_DELAY); }
25
+ bool Mutex::try_lock() { return xSemaphoreTake(this->handle_, 0) == pdTRUE; }
26
+ void Mutex::unlock() { xSemaphoreGive(this->handle_); }
27
+
28
+ // only affects the executing core
29
+ // so should not be used as a mutex lock, only to get accurate timing
30
+ IRAM_ATTR InterruptLock::InterruptLock() { portDISABLE_INTERRUPTS(); }
31
+ IRAM_ATTR InterruptLock::~InterruptLock() { portENABLE_INTERRUPTS(); }
32
+
33
+ void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
34
+ #if defined(CONFIG_SOC_IEEE802154_SUPPORTED)
35
+ // When CONFIG_SOC_IEEE802154_SUPPORTED is defined, esp_efuse_mac_get_default
36
+ // returns the 802.15.4 EUI-64 address, so we read directly from eFuse instead.
37
+ if (has_custom_mac_address()) {
38
+ esp_efuse_read_field_blob(ESP_EFUSE_MAC_CUSTOM, mac, 48);
39
+ } else {
40
+ esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, mac, 48);
41
+ }
42
+ #else
43
+ if (has_custom_mac_address()) {
44
+ esp_efuse_mac_get_custom(mac);
45
+ } else {
46
+ esp_efuse_mac_get_default(mac);
47
+ }
48
+ #endif
49
+ }
50
+
51
+ void set_mac_address(uint8_t *mac) { esp_base_mac_addr_set(mac); }
52
+
53
+ bool has_custom_mac_address() {
54
+ #if !defined(USE_ESP32_IGNORE_EFUSE_CUSTOM_MAC)
55
+ uint8_t mac[6];
56
+ // do not use 'esp_efuse_mac_get_custom(mac)' because it drops an error in the logs whenever it fails
57
+ #ifndef USE_ESP32_VARIANT_ESP32
58
+ return (esp_efuse_read_field_blob(ESP_EFUSE_USER_DATA_MAC_CUSTOM, mac, 48) == ESP_OK) && mac_address_is_valid(mac);
59
+ #else
60
+ return (esp_efuse_read_field_blob(ESP_EFUSE_MAC_CUSTOM, mac, 48) == ESP_OK) && mac_address_is_valid(mac);
61
+ #endif
62
+ #else
63
+ return false;
64
+ #endif
65
+ }
66
+
67
+ } // namespace esphome
68
+
69
+ #endif // USE_ESP32
@@ -1,9 +1,9 @@
1
1
  #ifdef USE_ESP32
2
2
 
3
3
  #include "ble.h"
4
- #include "ble_event_pool.h"
5
4
 
6
5
  #include "esphome/core/application.h"
6
+ #include "esphome/core/helpers.h"
7
7
  #include "esphome/core/log.h"
8
8
 
9
9
  #include <esp_bt.h>
@@ -516,13 +516,12 @@ void ESP32BLE::dump_config() {
516
516
  break;
517
517
  }
518
518
  ESP_LOGCONFIG(TAG,
519
- "ESP32 BLE:\n"
520
- " MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n"
519
+ "BLE:\n"
520
+ " MAC address: %s\n"
521
521
  " IO Capability: %s",
522
- mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5],
523
- io_capability_s);
522
+ format_mac_address_pretty(mac_address).c_str(), io_capability_s);
524
523
  } else {
525
- ESP_LOGCONFIG(TAG, "ESP32 BLE: bluetooth stack is not enabled");
524
+ ESP_LOGCONFIG(TAG, "Bluetooth stack is not enabled");
526
525
  }
527
526
  }
528
527
 
@@ -12,8 +12,8 @@
12
12
  #include "esphome/core/helpers.h"
13
13
 
14
14
  #include "ble_event.h"
15
- #include "ble_event_pool.h"
16
- #include "queue.h"
15
+ #include "esphome/core/lock_free_queue.h"
16
+ #include "esphome/core/event_pool.h"
17
17
 
18
18
  #ifdef USE_ESP32
19
19
 
@@ -25,10 +25,15 @@ namespace esphome {
25
25
  namespace esp32_ble {
26
26
 
27
27
  // Maximum number of BLE scan results to buffer
28
+ // Sized to handle bursts of advertisements while allowing for processing delays
29
+ // With 16 advertisements per batch and some safety margin:
30
+ // - Without PSRAM: 24 entries (1.5× batch size)
31
+ // - With PSRAM: 36 entries (2.25× batch size)
32
+ // The reduced structure size (~80 bytes vs ~400 bytes) allows for larger buffers
28
33
  #ifdef USE_PSRAM
29
- static constexpr uint8_t SCAN_RESULT_BUFFER_SIZE = 32;
34
+ static constexpr uint8_t SCAN_RESULT_BUFFER_SIZE = 36;
30
35
  #else
31
- static constexpr uint8_t SCAN_RESULT_BUFFER_SIZE = 20;
36
+ static constexpr uint8_t SCAN_RESULT_BUFFER_SIZE = 24;
32
37
  #endif
33
38
 
34
39
  // Maximum size of the BLE event queue - must be power of 2 for lock-free queue
@@ -51,7 +56,7 @@ enum IoCapability {
51
56
  IO_CAP_KBDISP = ESP_IO_CAP_KBDISP,
52
57
  };
53
58
 
54
- enum BLEComponentState {
59
+ enum BLEComponentState : uint8_t {
55
60
  /** Nothing has been initialized yet. */
56
61
  BLE_COMPONENT_STATE_OFF = 0,
57
62
  /** BLE should be disabled on next loop. */
@@ -141,21 +146,31 @@ class ESP32BLE : public Component {
141
146
  private:
142
147
  template<typename... Args> friend void enqueue_ble_event(Args... args);
143
148
 
149
+ // Vectors (12 bytes each on 32-bit, naturally aligned to 4 bytes)
144
150
  std::vector<GAPEventHandler *> gap_event_handlers_;
145
151
  std::vector<GAPScanEventHandler *> gap_scan_event_handlers_;
146
152
  std::vector<GATTcEventHandler *> gattc_event_handlers_;
147
153
  std::vector<GATTsEventHandler *> gatts_event_handlers_;
148
154
  std::vector<BLEStatusEventHandler *> ble_status_event_handlers_;
149
- BLEComponentState state_{BLE_COMPONENT_STATE_OFF};
150
-
151
- LockFreeQueue<BLEEvent, MAX_BLE_QUEUE_SIZE> ble_events_;
152
- BLEEventPool<MAX_BLE_QUEUE_SIZE> ble_event_pool_;
153
- BLEAdvertising *advertising_{};
154
- esp_ble_io_cap_t io_cap_{ESP_IO_CAP_NONE};
155
- uint32_t advertising_cycle_time_{};
156
- bool enable_on_boot_{};
155
+
156
+ // Large objects (size depends on template parameters, but typically aligned to 4 bytes)
157
+ esphome::LockFreeQueue<BLEEvent, MAX_BLE_QUEUE_SIZE> ble_events_;
158
+ esphome::EventPool<BLEEvent, MAX_BLE_QUEUE_SIZE> ble_event_pool_;
159
+
160
+ // optional<string> (typically 16+ bytes on 32-bit, aligned to 4 bytes)
157
161
  optional<std::string> name_;
158
- uint16_t appearance_{0};
162
+
163
+ // 4-byte aligned members
164
+ BLEAdvertising *advertising_{}; // 4 bytes (pointer)
165
+ esp_ble_io_cap_t io_cap_{ESP_IO_CAP_NONE}; // 4 bytes (enum)
166
+ uint32_t advertising_cycle_time_{}; // 4 bytes
167
+
168
+ // 2-byte aligned members
169
+ uint16_t appearance_{0}; // 2 bytes
170
+
171
+ // 1-byte aligned members (grouped together to minimize padding)
172
+ BLEComponentState state_{BLE_COMPONENT_STATE_OFF}; // 1 byte (uint8_t enum)
173
+ bool enable_on_boot_{}; // 1 byte
159
174
  };
160
175
 
161
176
  // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
@@ -134,13 +134,13 @@ class BLEEvent {
134
134
  }
135
135
 
136
136
  // Destructor to clean up heap allocations
137
- ~BLEEvent() { this->cleanup_heap_data(); }
137
+ ~BLEEvent() { this->release(); }
138
138
 
139
139
  // Default constructor for pre-allocation in pool
140
140
  BLEEvent() : type_(GAP) {}
141
141
 
142
- // Clean up any heap-allocated data
143
- void cleanup_heap_data() {
142
+ // Invoked on return to EventPool - clean up any heap-allocated data
143
+ void release() {
144
144
  if (this->type_ == GAP) {
145
145
  return;
146
146
  }
@@ -161,19 +161,19 @@ class BLEEvent {
161
161
 
162
162
  // Load new event data for reuse (replaces previous event data)
163
163
  void load_gap_event(esp_gap_ble_cb_event_t e, esp_ble_gap_cb_param_t *p) {
164
- this->cleanup_heap_data();
164
+ this->release();
165
165
  this->type_ = GAP;
166
166
  this->init_gap_data_(e, p);
167
167
  }
168
168
 
169
169
  void load_gattc_event(esp_gattc_cb_event_t e, esp_gatt_if_t i, esp_ble_gattc_cb_param_t *p) {
170
- this->cleanup_heap_data();
170
+ this->release();
171
171
  this->type_ = GATTC;
172
172
  this->init_gattc_data_(e, i, p);
173
173
  }
174
174
 
175
175
  void load_gatts_event(esp_gatts_cb_event_t e, esp_gatt_if_t i, esp_ble_gatts_cb_param_t *p) {
176
- this->cleanup_heap_data();
176
+ this->release();
177
177
  this->type_ = GATTS;
178
178
  this->init_gatts_data_(e, i, p);
179
179
  }