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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (601) 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 +42 -20
  22. esphome/components/api/api_connection.cpp +318 -391
  23. esphome/components/api/api_connection.h +206 -126
  24. esphome/components/api/api_frame_helper.cpp +89 -124
  25. esphome/components/api/api_frame_helper.h +57 -45
  26. esphome/components/api/api_pb2.cpp +414 -4350
  27. esphome/components/api/api_pb2.h +287 -198
  28. esphome/components/api/api_pb2_dump.cpp +4333 -0
  29. esphome/components/api/api_pb2_service.cpp +180 -425
  30. esphome/components/api/api_pb2_service.h +7 -6
  31. esphome/components/api/api_pb2_size.h +2 -4
  32. esphome/components/api/api_server.cpp +138 -167
  33. esphome/components/api/api_server.h +66 -12
  34. esphome/components/api/client.py +10 -4
  35. esphome/components/api/list_entities.cpp +36 -105
  36. esphome/components/api/list_entities.h +31 -23
  37. esphome/components/api/proto.h +26 -3
  38. esphome/components/api/subscribe_state.cpp +23 -29
  39. esphome/components/api/subscribe_state.h +26 -19
  40. esphome/components/as5600/as5600.h +0 -1
  41. esphome/components/async_tcp/__init__.py +14 -5
  42. esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
  43. esphome/components/atm90e32/atm90e32.cpp +2 -1
  44. esphome/components/audio/audio_decoder.cpp +1 -1
  45. esphome/components/audio/audio_transfer_buffer.cpp +2 -2
  46. esphome/components/b_parasite/b_parasite.h +0 -1
  47. esphome/components/bedjet/bedjet_hub.cpp +5 -1
  48. esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
  49. esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
  50. esphome/components/bh1750/bh1750.cpp +5 -5
  51. esphome/components/binary_sensor/__init__.py +82 -5
  52. esphome/components/binary_sensor/automation.h +19 -1
  53. esphome/components/binary_sensor/binary_sensor.cpp +12 -30
  54. esphome/components/binary_sensor/binary_sensor.h +11 -25
  55. esphome/components/binary_sensor/filter.cpp +29 -24
  56. esphome/components/binary_sensor/filter.h +20 -10
  57. esphome/components/ble_client/output/ble_binary_output.h +0 -1
  58. esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
  59. esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
  60. esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
  61. esphome/components/ble_client/sensor/ble_sensor.h +0 -1
  62. esphome/components/ble_client/switch/ble_switch.h +0 -1
  63. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
  64. esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
  65. esphome/components/ble_presence/ble_presence_device.h +0 -1
  66. esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
  67. esphome/components/ble_scanner/ble_scanner.h +0 -1
  68. esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
  69. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
  70. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
  71. esphome/components/bme680/sensor.py +1 -1
  72. esphome/components/bmp581/bmp581.h +0 -2
  73. esphome/components/button/__init__.py +5 -2
  74. esphome/components/camera/__init__.py +1 -0
  75. esphome/components/camera/camera.cpp +22 -0
  76. esphome/components/camera/camera.h +80 -0
  77. esphome/components/canbus/__init__.py +1 -0
  78. esphome/components/cap1188/cap1188.h +0 -1
  79. esphome/components/captive_portal/__init__.py +12 -2
  80. esphome/components/captive_portal/captive_portal.cpp +12 -2
  81. esphome/components/captive_portal/captive_portal.h +5 -2
  82. esphome/components/ccs811/ccs811.h +0 -2
  83. esphome/components/climate/__init__.py +5 -2
  84. esphome/components/cm1106/sensor.py +2 -2
  85. esphome/components/const/__init__.py +2 -0
  86. esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
  87. esphome/components/copy/button/copy_button.h +0 -1
  88. esphome/components/copy/cover/copy_cover.h +0 -1
  89. esphome/components/copy/fan/copy_fan.h +0 -1
  90. esphome/components/copy/lock/copy_lock.h +0 -1
  91. esphome/components/copy/number/copy_number.h +0 -1
  92. esphome/components/copy/select/copy_select.h +0 -1
  93. esphome/components/copy/sensor/copy_sensor.h +0 -1
  94. esphome/components/copy/switch/copy_switch.h +0 -1
  95. esphome/components/copy/text/copy_text.h +0 -1
  96. esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
  97. esphome/components/cover/__init__.py +5 -2
  98. esphome/components/cs5460a/cs5460a.h +0 -1
  99. esphome/components/datetime/__init__.py +4 -2
  100. esphome/components/debug/__init__.py +20 -0
  101. esphome/components/deep_sleep/__init__.py +43 -9
  102. esphome/components/demo/__init__.py +2 -2
  103. esphome/components/display/display.cpp +4 -3
  104. esphome/components/display/display.h +0 -2
  105. esphome/components/display/display_buffer.cpp +1 -1
  106. esphome/components/ds2484/__init__.py +1 -0
  107. esphome/components/ds2484/ds2484.cpp +209 -0
  108. esphome/components/ds2484/ds2484.h +43 -0
  109. esphome/components/ds2484/one_wire.py +37 -0
  110. esphome/components/duty_time/duty_time_sensor.h +0 -1
  111. esphome/components/ens160_base/ens160_base.h +0 -1
  112. esphome/components/es7210/es7210.h +0 -1
  113. esphome/components/es7243e/es7243e.h +0 -1
  114. esphome/components/es8156/es8156.h +0 -1
  115. esphome/components/es8311/es8311.h +0 -1
  116. esphome/components/es8388/es8388.h +0 -1
  117. esphome/components/esp32/__init__.py +102 -135
  118. esphome/components/esp32/core.cpp +0 -4
  119. esphome/components/esp32/gpio.h +1 -1
  120. esphome/components/esp32/helpers.cpp +69 -0
  121. esphome/components/esp32_ble/ble.cpp +5 -6
  122. esphome/components/esp32_ble/ble.h +29 -14
  123. esphome/components/esp32_ble/ble_event.h +6 -6
  124. esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
  125. esphome/components/esp32_ble_client/ble_client_base.h +24 -9
  126. esphome/components/esp32_ble_tracker/__init__.py +2 -8
  127. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
  128. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
  129. esphome/components/esp32_camera/__init__.py +111 -97
  130. esphome/components/esp32_camera/esp32_camera.cpp +41 -31
  131. esphome/components/esp32_camera/esp32_camera.h +35 -30
  132. esphome/components/esp32_camera_web_server/__init__.py +2 -1
  133. esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
  134. esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
  135. esphome/components/esp32_hall/sensor.py +2 -21
  136. esphome/components/esp32_hosted/__init__.py +101 -0
  137. esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
  138. esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
  139. esphome/components/esp32_rmt/__init__.py +0 -58
  140. esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
  141. esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
  142. esphome/components/esp32_rmt_led_strip/light.py +14 -76
  143. esphome/components/esp32_touch/esp32_touch.h +174 -28
  144. esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
  145. esphome/components/esp32_touch/esp32_touch_v1.cpp +238 -0
  146. esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
  147. esphome/components/esp8266/__init__.py +1 -0
  148. esphome/components/esp8266/gpio.cpp +10 -10
  149. esphome/components/esp8266/helpers.cpp +31 -0
  150. esphome/components/esphome/ota/__init__.py +1 -0
  151. esphome/components/esphome/ota/ota_esphome.cpp +24 -19
  152. esphome/components/ethernet/__init__.py +42 -23
  153. esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
  154. esphome/components/ethernet/ethernet_component.cpp +69 -29
  155. esphome/components/ethernet/ethernet_component.h +18 -10
  156. esphome/components/event/__init__.py +5 -2
  157. esphome/components/ezo/ezo.h +0 -1
  158. esphome/components/ezo_pmp/ezo_pmp.h +0 -1
  159. esphome/components/fan/__init__.py +5 -2
  160. esphome/components/feedback/feedback_cover.h +0 -1
  161. esphome/components/font/__init__.py +92 -82
  162. esphome/components/font/font.cpp +9 -2
  163. esphome/components/font/font.h +20 -5
  164. esphome/components/fs3000/fs3000.h +0 -1
  165. esphome/components/gcja5/gcja5.h +0 -1
  166. esphome/components/gl_r01_i2c/__init__.py +0 -0
  167. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
  168. esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
  169. esphome/components/gl_r01_i2c/sensor.py +36 -0
  170. esphome/components/gp8403/gp8403.h +0 -1
  171. esphome/components/gpio/binary_sensor/__init__.py +17 -0
  172. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
  173. esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
  174. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
  175. esphome/components/he60r/he60r.h +0 -1
  176. esphome/components/heatpumpir/climate.py +2 -1
  177. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  178. esphome/components/heatpumpir/heatpumpir.h +1 -0
  179. esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
  180. esphome/components/host/__init__.py +2 -1
  181. esphome/components/host/helpers.cpp +57 -0
  182. esphome/components/http_request/__init__.py +19 -1
  183. esphome/components/http_request/http_request.h +1 -1
  184. esphome/components/http_request/http_request_arduino.cpp +0 -1
  185. esphome/components/http_request/http_request_arduino.h +1 -0
  186. esphome/components/http_request/http_request_idf.cpp +0 -1
  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 +430 -261
  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 +4 -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 +126 -45
  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 +31 -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 +1 -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 +1 -5
  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/valve/__init__.py +5 -2
  477. esphome/components/vbus/vbus.h +0 -1
  478. esphome/components/veml3235/veml3235.h +0 -1
  479. esphome/components/veml7700/veml7700.h +0 -1
  480. esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
  481. esphome/components/voice_assistant/voice_assistant.cpp +4 -4
  482. esphome/components/watchdog/watchdog.cpp +0 -4
  483. esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
  484. esphome/components/web_server/__init__.py +34 -19
  485. esphome/components/web_server/ota/__init__.py +32 -0
  486. esphome/components/web_server/ota/ota_web_server.cpp +210 -0
  487. esphome/components/web_server/ota/ota_web_server.h +26 -0
  488. esphome/components/web_server/web_server.cpp +311 -430
  489. esphome/components/web_server/web_server.h +33 -23
  490. esphome/components/web_server/web_server_v1.cpp +4 -5
  491. esphome/components/web_server_base/__init__.py +5 -2
  492. esphome/components/web_server_base/web_server_base.cpp +2 -94
  493. esphome/components/web_server_base/web_server_base.h +5 -25
  494. esphome/components/web_server_idf/multipart.cpp +254 -0
  495. esphome/components/web_server_idf/multipart.h +86 -0
  496. esphome/components/web_server_idf/utils.cpp +32 -0
  497. esphome/components/web_server_idf/utils.h +10 -0
  498. esphome/components/web_server_idf/web_server_idf.cpp +162 -16
  499. esphome/components/web_server_idf/web_server_idf.h +11 -10
  500. esphome/components/wiegand/wiegand.cpp +2 -2
  501. esphome/components/wifi/__init__.py +18 -0
  502. esphome/components/wifi/wifi_component.cpp +17 -22
  503. esphome/components/wifi/wifi_component.h +27 -23
  504. esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
  505. esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
  506. esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
  507. esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
  508. esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
  509. esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
  510. esphome/components/wireguard/__init__.py +2 -11
  511. esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
  512. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  513. esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
  514. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
  515. esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
  516. esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
  517. esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
  518. esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
  519. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
  520. esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
  521. esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
  522. esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
  523. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
  524. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
  525. esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
  526. esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
  527. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
  528. esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
  529. esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
  530. esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
  531. esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
  532. esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
  533. esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
  534. esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
  535. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
  536. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
  537. esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
  538. esphome/components/zyaura/zyaura.h +0 -1
  539. esphome/config.py +88 -22
  540. esphome/config_helpers.py +74 -1
  541. esphome/config_validation.py +12 -1
  542. esphome/const.py +65 -10
  543. esphome/core/__init__.py +18 -2
  544. esphome/core/application.cpp +163 -10
  545. esphome/core/application.h +145 -165
  546. esphome/core/area.h +19 -0
  547. esphome/core/automation.h +58 -9
  548. esphome/core/color.cpp +3 -5
  549. esphome/core/color.h +16 -16
  550. esphome/core/component.cpp +151 -18
  551. esphome/core/component.h +98 -4
  552. esphome/core/component_iterator.cpp +7 -7
  553. esphome/core/component_iterator.h +9 -7
  554. esphome/core/config.py +155 -6
  555. esphome/core/controller.cpp +4 -2
  556. esphome/core/controller.h +1 -1
  557. esphome/core/datatypes.h +2 -2
  558. esphome/core/defines.h +17 -2
  559. esphome/core/device.h +20 -0
  560. esphome/core/entity_base.cpp +20 -15
  561. esphome/core/entity_base.h +76 -0
  562. esphome/core/entity_helpers.py +162 -1
  563. esphome/core/event_pool.h +81 -0
  564. esphome/core/helpers.cpp +75 -230
  565. esphome/core/helpers.h +164 -104
  566. esphome/core/lock_free_queue.h +151 -0
  567. esphome/core/log.cpp +2 -2
  568. esphome/core/log.h +2 -0
  569. esphome/core/optional.h +5 -0
  570. esphome/core/ring_buffer.cpp +2 -2
  571. esphome/core/scheduler.cpp +278 -103
  572. esphome/core/scheduler.h +157 -17
  573. esphome/core/time.cpp +5 -5
  574. esphome/core/time.h +5 -5
  575. esphome/cpp_generator.py +17 -0
  576. esphome/cpp_helpers.py +0 -22
  577. esphome/cpp_types.py +3 -1
  578. esphome/dashboard/entries.py +1 -1
  579. esphome/dashboard/util/text.py +5 -21
  580. esphome/dashboard/web_server.py +9 -1
  581. esphome/helpers.py +47 -0
  582. esphome/loader.py +15 -1
  583. esphome/pins.py +14 -8
  584. esphome/wizard.py +16 -3
  585. esphome/writer.py +21 -3
  586. esphome/yaml_util.py +0 -2
  587. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/METADATA +10 -9
  588. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/RECORD +593 -533
  589. esphome/components/esp32_ble/ble_event_pool.h +0 -72
  590. esphome/components/esp32_ble/queue.h +0 -85
  591. esphome/components/esp32_hall/esp32_hall.cpp +0 -25
  592. esphome/components/esp32_hall/esp32_hall.h +0 -23
  593. esphome/components/esp32_touch/esp32_touch.cpp +0 -355
  594. esphome/components/ld2410/button/reset_button.cpp +0 -9
  595. esphome/components/ld2450/button/reset_button.cpp +0 -9
  596. esphome/components/openthread/tlv.py +0 -65
  597. /esphome/{dashboard/enum.py → enum.py} +0 -0
  598. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/WHEEL +0 -0
  599. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/entry_points.txt +0 -0
  600. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/licenses/LICENSE +0 -0
  601. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/top_level.txt +0 -0
@@ -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
  }
@@ -22,6 +22,16 @@ void BLEClientBase::setup() {
22
22
  this->connection_index_ = connection_index++;
23
23
  }
24
24
 
25
+ void BLEClientBase::set_state(espbt::ClientState st) {
26
+ ESP_LOGV(TAG, "[%d] [%s] Set state %d", this->connection_index_, this->address_str_.c_str(), (int) st);
27
+ ESPBTClient::set_state(st);
28
+
29
+ if (st == espbt::ClientState::READY_TO_CONNECT) {
30
+ // Enable loop when we need to connect
31
+ this->enable_loop();
32
+ }
33
+ }
34
+
25
35
  void BLEClientBase::loop() {
26
36
  if (!esp32_ble::global_ble->is_active()) {
27
37
  this->set_state(espbt::ClientState::INIT);
@@ -37,9 +47,14 @@ void BLEClientBase::loop() {
37
47
  }
38
48
  // READY_TO_CONNECT means we have discovered the device
39
49
  // and the scanner has been stopped by the tracker.
40
- if (this->state_ == espbt::ClientState::READY_TO_CONNECT) {
50
+ else if (this->state_ == espbt::ClientState::READY_TO_CONNECT) {
41
51
  this->connect();
42
52
  }
53
+ // If its idle, we can disable the loop as set_state
54
+ // will enable it again when we need to connect.
55
+ else if (this->state_ == espbt::ClientState::IDLE) {
56
+ this->disable_loop();
57
+ }
43
58
  }
44
59
 
45
60
  float BLEClientBase::get_setup_priority() const { return setup_priority::AFTER_BLUETOOTH; }
@@ -481,17 +496,17 @@ float BLEClientBase::parse_char_value(uint8_t *value, uint16_t length) {
481
496
  if (length > 2) {
482
497
  return (float) encode_uint16(value[1], value[2]);
483
498
  }
484
- // fall through
499
+ [[fallthrough]];
485
500
  case 0x7: // uint24.
486
501
  if (length > 3) {
487
502
  return (float) encode_uint24(value[1], value[2], value[3]);
488
503
  }
489
- // fall through
504
+ [[fallthrough]];
490
505
  case 0x8: // uint32.
491
506
  if (length > 4) {
492
507
  return (float) encode_uint32(value[1], value[2], value[3], value[4]);
493
508
  }
494
- // fall through
509
+ [[fallthrough]];
495
510
  case 0xC: // int8.
496
511
  return (float) ((int8_t) value[1]);
497
512
  case 0xD: // int12.
@@ -499,12 +514,12 @@ float BLEClientBase::parse_char_value(uint8_t *value, uint16_t length) {
499
514
  if (length > 2) {
500
515
  return (float) ((int16_t) (value[1] << 8) + (int16_t) value[2]);
501
516
  }
502
- // fall through
517
+ [[fallthrough]];
503
518
  case 0xF: // int24.
504
519
  if (length > 3) {
505
520
  return (float) ((int32_t) (value[1] << 16) + (int32_t) (value[2] << 8) + (int32_t) (value[3]));
506
521
  }
507
- // fall through
522
+ [[fallthrough]];
508
523
  case 0x10: // int32.
509
524
  if (length > 4) {
510
525
  return (float) ((int32_t) (value[1] << 24) + (int32_t) (value[2] << 16) + (int32_t) (value[3] << 8) +
@@ -93,21 +93,36 @@ class BLEClientBase : public espbt::ESPBTClient, public Component {
93
93
 
94
94
  bool check_addr(esp_bd_addr_t &addr) { return memcmp(addr, this->remote_bda_, sizeof(esp_bd_addr_t)) == 0; }
95
95
 
96
+ void set_state(espbt::ClientState st) override;
97
+
96
98
  protected:
99
+ // Memory optimized layout for 32-bit systems
100
+ // Group 1: 8-byte types
101
+ uint64_t address_{0};
102
+
103
+ // Group 2: Container types (grouped for memory optimization)
104
+ std::string address_str_{};
105
+ std::vector<BLEService *> services_;
106
+
107
+ // Group 3: 4-byte types
97
108
  int gattc_if_;
109
+ esp_gatt_status_t status_{ESP_GATT_OK};
110
+
111
+ // Group 4: Arrays (6 bytes)
98
112
  esp_bd_addr_t remote_bda_;
99
- esp_ble_addr_type_t remote_addr_type_{BLE_ADDR_TYPE_PUBLIC};
113
+
114
+ // Group 5: 2-byte types
100
115
  uint16_t conn_id_{UNSET_CONN_ID};
101
- uint64_t address_{0};
102
- bool auto_connect_{false};
103
- std::string address_str_{};
104
- uint8_t connection_index_;
105
- int16_t service_count_{0};
106
116
  uint16_t mtu_{23};
107
- bool paired_{false};
117
+
118
+ // Group 6: 1-byte types and small enums
119
+ esp_ble_addr_type_t remote_addr_type_{BLE_ADDR_TYPE_PUBLIC};
108
120
  espbt::ConnectionType connection_type_{espbt::ConnectionType::V1};
109
- std::vector<BLEService *> services_;
110
- esp_gatt_status_t status_{ESP_GATT_OK};
121
+ uint8_t connection_index_;
122
+ uint8_t service_count_{0}; // ESP32 has max handles < 255, typical devices have < 50 services
123
+ bool auto_connect_{false};
124
+ bool paired_{false};
125
+ // 6 bytes used, 2 bytes padding
111
126
 
112
127
  void log_event_(const char *name);
113
128
  };
@@ -29,8 +29,6 @@ from esphome.const import (
29
29
  CONF_ON_BLE_SERVICE_DATA_ADVERTISE,
30
30
  CONF_SERVICE_UUID,
31
31
  CONF_TRIGGER_ID,
32
- KEY_CORE,
33
- KEY_FRAMEWORK_VERSION,
34
32
  )
35
33
  from esphome.core import CORE
36
34
 
@@ -323,10 +321,7 @@ async def to_code(config):
323
321
  # https://github.com/espressif/esp-idf/issues/2503
324
322
  # Match arduino CONFIG_BTU_TASK_STACK_SIZE
325
323
  # https://github.com/espressif/arduino-esp32/blob/fd72cf46ad6fc1a6de99c1d83ba8eba17d80a4ee/tools/sdk/esp32/sdkconfig#L1866
326
- if CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] >= cv.Version(4, 4, 6):
327
- add_idf_sdkconfig_option("CONFIG_BT_BTU_TASK_STACK_SIZE", 8192)
328
- else:
329
- add_idf_sdkconfig_option("CONFIG_BTU_TASK_STACK_SIZE", 8192)
324
+ add_idf_sdkconfig_option("CONFIG_BT_BTU_TASK_STACK_SIZE", 8192)
330
325
  add_idf_sdkconfig_option("CONFIG_BT_ACL_CONNECTIONS", 9)
331
326
  add_idf_sdkconfig_option(
332
327
  "CONFIG_BTDM_CTRL_BLE_MAX_CONN", config[CONF_MAX_CONNECTIONS]
@@ -335,8 +330,7 @@ async def to_code(config):
335
330
  # max notifications in 5.x, setting CONFIG_BT_ACL_CONNECTIONS
336
331
  # is enough in 4.x
337
332
  # https://github.com/esphome/issues/issues/6808
338
- if CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] >= cv.Version(5, 0, 0):
339
- add_idf_sdkconfig_option("CONFIG_BT_GATTC_NOTIF_REG_MAX", 9)
333
+ add_idf_sdkconfig_option("CONFIG_BT_GATTC_NOTIF_REG_MAX", 9)
340
334
 
341
335
  cg.add_define("USE_OTA_STATE_CALLBACK") # To be notified when an OTA update starts
342
336
  cg.add_define("USE_ESP32_BLE_CLIENT")
@@ -122,10 +122,10 @@ void ESP32BLETracker::loop() {
122
122
  // Consumer side: This runs in the main loop thread
123
123
  if (this->scanner_state_ == ScannerState::RUNNING) {
124
124
  // Load our own index with relaxed ordering (we're the only writer)
125
- size_t read_idx = this->ring_read_index_.load(std::memory_order_relaxed);
125
+ uint8_t read_idx = this->ring_read_index_.load(std::memory_order_relaxed);
126
126
 
127
127
  // Load producer's index with acquire to see their latest writes
128
- size_t write_idx = this->ring_write_index_.load(std::memory_order_acquire);
128
+ uint8_t write_idx = this->ring_write_index_.load(std::memory_order_acquire);
129
129
 
130
130
  while (read_idx != write_idx) {
131
131
  // Process one result at a time directly from ring buffer
@@ -409,11 +409,11 @@ void ESP32BLETracker::gap_scan_event_handler(const BLEScanResult &scan_result) {
409
409
  // IMPORTANT: Only this thread writes to ring_write_index_
410
410
 
411
411
  // Load our own index with relaxed ordering (we're the only writer)
412
- size_t write_idx = this->ring_write_index_.load(std::memory_order_relaxed);
413
- size_t next_write_idx = (write_idx + 1) % SCAN_RESULT_BUFFER_SIZE;
412
+ uint8_t write_idx = this->ring_write_index_.load(std::memory_order_relaxed);
413
+ uint8_t next_write_idx = (write_idx + 1) % SCAN_RESULT_BUFFER_SIZE;
414
414
 
415
415
  // Load consumer's index with acquire to see their latest updates
416
- size_t read_idx = this->ring_read_index_.load(std::memory_order_acquire);
416
+ uint8_t read_idx = this->ring_read_index_.load(std::memory_order_acquire);
417
417
 
418
418
  // Check if buffer is full
419
419
  if (next_write_idx != read_idx) {
@@ -133,7 +133,7 @@ class ESPBTDeviceListener {
133
133
  ESP32BLETracker *parent_{nullptr};
134
134
  };
135
135
 
136
- enum class ClientState {
136
+ enum class ClientState : uint8_t {
137
137
  // Connection is allocated
138
138
  INIT,
139
139
  // Client is disconnecting
@@ -169,7 +169,7 @@ enum class ScannerState {
169
169
  STOPPED,
170
170
  };
171
171
 
172
- enum class ConnectionType {
172
+ enum class ConnectionType : uint8_t {
173
173
  // The default connection type, we hold all the services in ram
174
174
  // for the duration of the connection.
175
175
  V1,
@@ -197,15 +197,19 @@ class ESPBTClient : public ESPBTDeviceListener {
197
197
  }
198
198
  }
199
199
  ClientState state() const { return state_; }
200
- int app_id;
200
+
201
+ // Memory optimized layout
202
+ uint8_t app_id; // App IDs are small integers assigned sequentially
201
203
 
202
204
  protected:
205
+ // Group 1: 1-byte types
203
206
  ClientState state_{ClientState::INIT};
204
207
  // want_disconnect_ is set to true when a disconnect is requested
205
208
  // while the client is connecting. This is used to disconnect the
206
209
  // client as soon as we get the connection id (conn_id_) from the
207
210
  // ESP_GATTC_OPEN_EVT event.
208
211
  bool want_disconnect_{false};
212
+ // 2 bytes used, 2 bytes padding
209
213
  };
210
214
 
211
215
  class ESP32BLETracker : public Component,
@@ -266,7 +270,7 @@ class ESP32BLETracker : public Component,
266
270
  /// Called to set the scanner state. Will also call callbacks to let listeners know when state is changed.
267
271
  void set_scanner_state_(ScannerState state);
268
272
 
269
- int app_id_{0};
273
+ uint8_t app_id_{0};
270
274
 
271
275
  /// Vector of addresses that have already been printed in print_bt_device_info
272
276
  std::vector<uint64_t> already_discovered_;
@@ -293,9 +297,9 @@ class ESP32BLETracker : public Component,
293
297
  // Consumer: ESPHome main loop (loop() method)
294
298
  // This design ensures zero blocking in the BT callback and prevents scan result loss
295
299
  BLEScanResult *scan_ring_buffer_;
296
- std::atomic<size_t> ring_write_index_{0}; // Written only by BT callback (producer)
297
- std::atomic<size_t> ring_read_index_{0}; // Written only by main loop (consumer)
298
- std::atomic<size_t> scan_results_dropped_{0}; // Tracks buffer overflow events
300
+ std::atomic<uint8_t> ring_write_index_{0}; // Written only by BT callback (producer)
301
+ std::atomic<uint8_t> ring_read_index_{0}; // Written only by main loop (consumer)
302
+ std::atomic<uint16_t> scan_results_dropped_{0}; // Tracks buffer overflow events
299
303
 
300
304
  esp_bt_status_t scan_start_failed_{ESP_BT_STATUS_SUCCESS};
301
305
  esp_bt_status_t scan_set_param_failed_{ESP_BT_STATUS_SUCCESS};
@@ -1,5 +1,6 @@
1
1
  from esphome import automation, pins
2
2
  import esphome.codegen as cg
3
+ from esphome.components import i2c
3
4
  from esphome.components.esp32 import add_idf_component
4
5
  import esphome.config_validation as cv
5
6
  from esphome.const import (
@@ -7,6 +8,7 @@ from esphome.const import (
7
8
  CONF_CONTRAST,
8
9
  CONF_DATA_PINS,
9
10
  CONF_FREQUENCY,
11
+ CONF_I2C_ID,
10
12
  CONF_ID,
11
13
  CONF_PIN,
12
14
  CONF_RESET_PIN,
@@ -17,11 +19,11 @@ from esphome.const import (
17
19
  CONF_VSYNC_PIN,
18
20
  )
19
21
  from esphome.core import CORE
20
- from esphome.cpp_helpers import setup_entity
22
+ from esphome.core.entity_helpers import setup_entity
21
23
 
22
24
  DEPENDENCIES = ["esp32"]
23
25
 
24
- AUTO_LOAD = ["psram"]
26
+ AUTO_LOAD = ["camera", "psram"]
25
27
 
26
28
  esp32_camera_ns = cg.esphome_ns.namespace("esp32_camera")
27
29
  ESP32Camera = esp32_camera_ns.class_("ESP32Camera", cg.PollingComponent, cg.EntityBase)
@@ -149,93 +151,104 @@ CONF_ON_IMAGE = "on_image"
149
151
 
150
152
  camera_range_param = cv.int_range(min=-2, max=2)
151
153
 
152
- CONFIG_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(
153
- {
154
- cv.GenerateID(): cv.declare_id(ESP32Camera),
155
- # pin assignment
156
- cv.Required(CONF_DATA_PINS): cv.All(
157
- [pins.internal_gpio_input_pin_number], cv.Length(min=8, max=8)
158
- ),
159
- cv.Required(CONF_VSYNC_PIN): pins.internal_gpio_input_pin_number,
160
- cv.Required(CONF_HREF_PIN): pins.internal_gpio_input_pin_number,
161
- cv.Required(CONF_PIXEL_CLOCK_PIN): pins.internal_gpio_input_pin_number,
162
- cv.Required(CONF_EXTERNAL_CLOCK): cv.Schema(
163
- {
164
- cv.Required(CONF_PIN): pins.internal_gpio_input_pin_number,
165
- cv.Optional(CONF_FREQUENCY, default="20MHz"): cv.All(
166
- cv.frequency, cv.Range(min=8e6, max=20e6)
167
- ),
168
- }
169
- ),
170
- cv.Required(CONF_I2C_PINS): cv.Schema(
171
- {
172
- cv.Required(CONF_SDA): pins.internal_gpio_output_pin_number,
173
- cv.Required(CONF_SCL): pins.internal_gpio_output_pin_number,
174
- }
175
- ),
176
- cv.Optional(CONF_RESET_PIN): pins.internal_gpio_output_pin_number,
177
- cv.Optional(CONF_POWER_DOWN_PIN): pins.internal_gpio_output_pin_number,
178
- # image
179
- cv.Optional(CONF_RESOLUTION, default="640X480"): cv.enum(
180
- FRAME_SIZES, upper=True
181
- ),
182
- cv.Optional(CONF_JPEG_QUALITY, default=10): cv.int_range(min=6, max=63),
183
- cv.Optional(CONF_CONTRAST, default=0): camera_range_param,
184
- cv.Optional(CONF_BRIGHTNESS, default=0): camera_range_param,
185
- cv.Optional(CONF_SATURATION, default=0): camera_range_param,
186
- cv.Optional(CONF_VERTICAL_FLIP, default=True): cv.boolean,
187
- cv.Optional(CONF_HORIZONTAL_MIRROR, default=True): cv.boolean,
188
- cv.Optional(CONF_SPECIAL_EFFECT, default="NONE"): cv.enum(
189
- ENUM_SPECIAL_EFFECT, upper=True
190
- ),
191
- # exposure
192
- cv.Optional(CONF_AGC_MODE, default="AUTO"): cv.enum(
193
- ENUM_GAIN_CONTROL_MODE, upper=True
194
- ),
195
- cv.Optional(CONF_AEC2, default=False): cv.boolean,
196
- cv.Optional(CONF_AE_LEVEL, default=0): camera_range_param,
197
- cv.Optional(CONF_AEC_VALUE, default=300): cv.int_range(min=0, max=1200),
198
- # gains
199
- cv.Optional(CONF_AEC_MODE, default="AUTO"): cv.enum(
200
- ENUM_GAIN_CONTROL_MODE, upper=True
201
- ),
202
- cv.Optional(CONF_AGC_VALUE, default=0): cv.int_range(min=0, max=30),
203
- cv.Optional(CONF_AGC_GAIN_CEILING, default="2X"): cv.enum(
204
- ENUM_GAIN_CEILING, upper=True
205
- ),
206
- # white balance
207
- cv.Optional(CONF_WB_MODE, default="AUTO"): cv.enum(ENUM_WB_MODE, upper=True),
208
- # test pattern
209
- cv.Optional(CONF_TEST_PATTERN, default=False): cv.boolean,
210
- # framerates
211
- cv.Optional(CONF_MAX_FRAMERATE, default="10 fps"): cv.All(
212
- cv.framerate, cv.Range(min=0, min_included=False, max=60)
213
- ),
214
- cv.Optional(CONF_IDLE_FRAMERATE, default="0.1 fps"): cv.All(
215
- cv.framerate, cv.Range(min=0, max=1)
216
- ),
217
- cv.Optional(CONF_FRAME_BUFFER_COUNT, default=1): cv.int_range(min=1, max=2),
218
- cv.Optional(CONF_ON_STREAM_START): automation.validate_automation(
219
- {
220
- cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
221
- ESP32CameraStreamStartTrigger
222
- ),
223
- }
224
- ),
225
- cv.Optional(CONF_ON_STREAM_STOP): automation.validate_automation(
226
- {
227
- cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
228
- ESP32CameraStreamStopTrigger
229
- ),
230
- }
231
- ),
232
- cv.Optional(CONF_ON_IMAGE): automation.validate_automation(
233
- {
234
- cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ESP32CameraImageTrigger),
235
- }
236
- ),
237
- }
238
- ).extend(cv.COMPONENT_SCHEMA)
154
+ CONFIG_SCHEMA = cv.All(
155
+ cv.ENTITY_BASE_SCHEMA.extend(
156
+ {
157
+ cv.GenerateID(): cv.declare_id(ESP32Camera),
158
+ # pin assignment
159
+ cv.Required(CONF_DATA_PINS): cv.All(
160
+ [pins.internal_gpio_input_pin_number], cv.Length(min=8, max=8)
161
+ ),
162
+ cv.Required(CONF_VSYNC_PIN): pins.internal_gpio_input_pin_number,
163
+ cv.Required(CONF_HREF_PIN): pins.internal_gpio_input_pin_number,
164
+ cv.Required(CONF_PIXEL_CLOCK_PIN): pins.internal_gpio_input_pin_number,
165
+ cv.Required(CONF_EXTERNAL_CLOCK): cv.Schema(
166
+ {
167
+ cv.Required(CONF_PIN): pins.internal_gpio_input_pin_number,
168
+ cv.Optional(CONF_FREQUENCY, default="20MHz"): cv.All(
169
+ cv.frequency, cv.Range(min=8e6, max=20e6)
170
+ ),
171
+ }
172
+ ),
173
+ cv.Optional(CONF_I2C_PINS): cv.Schema(
174
+ {
175
+ cv.Required(CONF_SDA): pins.internal_gpio_output_pin_number,
176
+ cv.Required(CONF_SCL): pins.internal_gpio_output_pin_number,
177
+ }
178
+ ),
179
+ cv.Optional(CONF_I2C_ID): cv.Any(
180
+ cv.use_id(i2c.InternalI2CBus),
181
+ msg="I2C bus must be an internal ESP32 I2C bus",
182
+ ),
183
+ cv.Optional(CONF_RESET_PIN): pins.internal_gpio_output_pin_number,
184
+ cv.Optional(CONF_POWER_DOWN_PIN): pins.internal_gpio_output_pin_number,
185
+ # image
186
+ cv.Optional(CONF_RESOLUTION, default="640X480"): cv.enum(
187
+ FRAME_SIZES, upper=True
188
+ ),
189
+ cv.Optional(CONF_JPEG_QUALITY, default=10): cv.int_range(min=6, max=63),
190
+ cv.Optional(CONF_CONTRAST, default=0): camera_range_param,
191
+ cv.Optional(CONF_BRIGHTNESS, default=0): camera_range_param,
192
+ cv.Optional(CONF_SATURATION, default=0): camera_range_param,
193
+ cv.Optional(CONF_VERTICAL_FLIP, default=True): cv.boolean,
194
+ cv.Optional(CONF_HORIZONTAL_MIRROR, default=True): cv.boolean,
195
+ cv.Optional(CONF_SPECIAL_EFFECT, default="NONE"): cv.enum(
196
+ ENUM_SPECIAL_EFFECT, upper=True
197
+ ),
198
+ # exposure
199
+ cv.Optional(CONF_AGC_MODE, default="AUTO"): cv.enum(
200
+ ENUM_GAIN_CONTROL_MODE, upper=True
201
+ ),
202
+ cv.Optional(CONF_AEC2, default=False): cv.boolean,
203
+ cv.Optional(CONF_AE_LEVEL, default=0): camera_range_param,
204
+ cv.Optional(CONF_AEC_VALUE, default=300): cv.int_range(min=0, max=1200),
205
+ # gains
206
+ cv.Optional(CONF_AEC_MODE, default="AUTO"): cv.enum(
207
+ ENUM_GAIN_CONTROL_MODE, upper=True
208
+ ),
209
+ cv.Optional(CONF_AGC_VALUE, default=0): cv.int_range(min=0, max=30),
210
+ cv.Optional(CONF_AGC_GAIN_CEILING, default="2X"): cv.enum(
211
+ ENUM_GAIN_CEILING, upper=True
212
+ ),
213
+ # white balance
214
+ cv.Optional(CONF_WB_MODE, default="AUTO"): cv.enum(
215
+ ENUM_WB_MODE, upper=True
216
+ ),
217
+ # test pattern
218
+ cv.Optional(CONF_TEST_PATTERN, default=False): cv.boolean,
219
+ # framerates
220
+ cv.Optional(CONF_MAX_FRAMERATE, default="10 fps"): cv.All(
221
+ cv.framerate, cv.Range(min=0, min_included=False, max=60)
222
+ ),
223
+ cv.Optional(CONF_IDLE_FRAMERATE, default="0.1 fps"): cv.All(
224
+ cv.framerate, cv.Range(min=0, max=1)
225
+ ),
226
+ cv.Optional(CONF_FRAME_BUFFER_COUNT, default=1): cv.int_range(min=1, max=2),
227
+ cv.Optional(CONF_ON_STREAM_START): automation.validate_automation(
228
+ {
229
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
230
+ ESP32CameraStreamStartTrigger
231
+ ),
232
+ }
233
+ ),
234
+ cv.Optional(CONF_ON_STREAM_STOP): automation.validate_automation(
235
+ {
236
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
237
+ ESP32CameraStreamStopTrigger
238
+ ),
239
+ }
240
+ ),
241
+ cv.Optional(CONF_ON_IMAGE): automation.validate_automation(
242
+ {
243
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
244
+ ESP32CameraImageTrigger
245
+ ),
246
+ }
247
+ ),
248
+ }
249
+ ).extend(cv.COMPONENT_SCHEMA),
250
+ cv.has_exactly_one_key(CONF_I2C_PINS, CONF_I2C_ID),
251
+ )
239
252
 
240
253
  SETTERS = {
241
254
  # pin assignment
@@ -270,8 +283,9 @@ SETTERS = {
270
283
 
271
284
 
272
285
  async def to_code(config):
286
+ cg.add_define("USE_CAMERA")
273
287
  var = cg.new_Pvariable(config[CONF_ID])
274
- await setup_entity(var, config)
288
+ await setup_entity(var, config, "camera")
275
289
  await cg.register_component(var, config)
276
290
 
277
291
  for key, setter in SETTERS.items():
@@ -280,8 +294,12 @@ async def to_code(config):
280
294
 
281
295
  extclk = config[CONF_EXTERNAL_CLOCK]
282
296
  cg.add(var.set_external_clock(extclk[CONF_PIN], extclk[CONF_FREQUENCY]))
283
- i2c_pins = config[CONF_I2C_PINS]
284
- cg.add(var.set_i2c_pins(i2c_pins[CONF_SDA], i2c_pins[CONF_SCL]))
297
+ if i2c_id := config.get(CONF_I2C_ID):
298
+ i2c_hub = await cg.get_variable(i2c_id)
299
+ cg.add(var.set_i2c_id(i2c_hub))
300
+ else:
301
+ i2c_pins = config[CONF_I2C_PINS]
302
+ cg.add(var.set_i2c_pins(i2c_pins[CONF_SDA], i2c_pins[CONF_SCL]))
285
303
  cg.add(var.set_max_update_interval(1000 / config[CONF_MAX_FRAMERATE]))
286
304
  if config[CONF_IDLE_FRAMERATE] == 0:
287
305
  cg.add(var.set_idle_update_interval(0))
@@ -293,11 +311,7 @@ async def to_code(config):
293
311
  cg.add_define("USE_ESP32_CAMERA")
294
312
 
295
313
  if CORE.using_esp_idf:
296
- add_idf_component(
297
- name="esp32-camera",
298
- repo="https://github.com/espressif/esp32-camera.git",
299
- ref="v2.0.15",
300
- )
314
+ add_idf_component(name="espressif/esp32-camera", ref="2.0.15")
301
315
 
302
316
  for conf in config.get(CONF_ON_STREAM_START, []):
303
317
  trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)