esphome 2025.7.4__py3-none-any.whl → 2025.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (758) hide show
  1. esphome/__main__.py +190 -83
  2. esphome/automation.py +2 -4
  3. esphome/build_gen/__init__.py +0 -0
  4. esphome/build_gen/platformio.py +102 -0
  5. esphome/components/a4988/a4988.cpp +0 -1
  6. esphome/components/absolute_humidity/absolute_humidity.cpp +0 -2
  7. esphome/components/absolute_humidity/sensor.py +2 -2
  8. esphome/components/adc/__init__.py +123 -85
  9. esphome/components/adc/adc_sensor.h +98 -35
  10. esphome/components/adc/adc_sensor_common.cpp +10 -4
  11. esphome/components/adc/adc_sensor_esp32.cpp +291 -123
  12. esphome/components/adc/adc_sensor_esp8266.cpp +1 -4
  13. esphome/components/adc/adc_sensor_libretiny.cpp +1 -2
  14. esphome/components/adc/adc_sensor_rp2040.cpp +1 -2
  15. esphome/components/adc/adc_sensor_zephyr.cpp +207 -0
  16. esphome/components/adc/sensor.py +61 -27
  17. esphome/components/adc128s102/adc128s102.cpp +1 -4
  18. esphome/components/ade7880/sensor.py +75 -49
  19. esphome/components/ads1115/ads1115.cpp +0 -1
  20. esphome/components/ads1118/ads1118.cpp +0 -1
  21. esphome/components/ags10/ags10.cpp +0 -4
  22. esphome/components/aht10/aht10.cpp +0 -4
  23. esphome/components/aic3204/aic3204.cpp +0 -2
  24. esphome/components/airthings_wave_plus/__init__.py +1 -1
  25. esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +22 -4
  26. esphome/components/airthings_wave_plus/airthings_wave_plus.h +10 -1
  27. esphome/components/airthings_wave_plus/sensor.py +55 -28
  28. esphome/components/alarm_control_panel/__init__.py +4 -9
  29. esphome/components/am2315c/am2315c.cpp +0 -2
  30. esphome/components/am2320/am2320.cpp +0 -1
  31. esphome/components/animation/__init__.py +14 -11
  32. esphome/components/apds9306/apds9306.cpp +0 -4
  33. esphome/components/apds9960/apds9960.cpp +0 -1
  34. esphome/components/api/__init__.py +29 -4
  35. esphome/components/api/api_connection.cpp +378 -401
  36. esphome/components/api/api_connection.h +112 -56
  37. esphome/components/api/api_frame_helper.cpp +69 -896
  38. esphome/components/api/api_frame_helper.h +31 -126
  39. esphome/components/api/api_frame_helper_noise.cpp +583 -0
  40. esphome/components/api/api_frame_helper_noise.h +68 -0
  41. esphome/components/api/api_frame_helper_plaintext.cpp +290 -0
  42. esphome/components/api/api_frame_helper_plaintext.h +53 -0
  43. esphome/components/api/api_noise_context.h +2 -4
  44. esphome/components/api/api_pb2.cpp +1601 -1808
  45. esphome/components/api/api_pb2.h +367 -323
  46. esphome/components/api/api_pb2_dump.cpp +1137 -3466
  47. esphome/components/api/api_pb2_includes.h +34 -0
  48. esphome/components/api/api_pb2_service.cpp +94 -105
  49. esphome/components/api/api_pb2_service.h +27 -16
  50. esphome/components/api/api_server.cpp +18 -17
  51. esphome/components/api/api_server.h +8 -5
  52. esphome/components/api/client.py +16 -8
  53. esphome/components/api/custom_api_device.h +68 -14
  54. esphome/components/api/homeassistant_service.h +24 -19
  55. esphome/components/api/list_entities.cpp +3 -5
  56. esphome/components/api/list_entities.h +2 -4
  57. esphome/components/api/proto.cpp +3 -5
  58. esphome/components/api/proto.h +239 -274
  59. esphome/components/api/subscribe_state.cpp +2 -4
  60. esphome/components/api/subscribe_state.h +2 -4
  61. esphome/components/api/user_services.cpp +2 -4
  62. esphome/components/api/user_services.h +8 -8
  63. esphome/components/as3935/as3935.cpp +0 -2
  64. esphome/components/as3935_spi/as3935_spi.cpp +0 -2
  65. esphome/components/as5600/__init__.py +1 -1
  66. esphome/components/as5600/as5600.cpp +0 -2
  67. esphome/components/as5600/sensor/__init__.py +0 -1
  68. esphome/components/as7341/as7341.cpp +0 -1
  69. esphome/components/async_tcp/__init__.py +1 -1
  70. esphome/components/at581x/at581x.cpp +1 -1
  71. esphome/components/atm90e26/atm90e26.cpp +0 -1
  72. esphome/components/atm90e32/atm90e32.cpp +475 -116
  73. esphome/components/atm90e32/atm90e32.h +43 -5
  74. esphome/components/audio/audio.h +2 -2
  75. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +0 -2
  76. esphome/components/beken_spi_led_strip/led_strip.cpp +0 -2
  77. esphome/components/bh1750/bh1750.cpp +0 -1
  78. esphome/components/binary_sensor/__init__.py +14 -12
  79. esphome/components/ble_client/__init__.py +4 -7
  80. esphome/components/bluetooth_proxy/__init__.py +40 -3
  81. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +392 -81
  82. esphome/components/bluetooth_proxy/bluetooth_connection.h +16 -5
  83. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +102 -311
  84. esphome/components/bluetooth_proxy/bluetooth_proxy.h +30 -14
  85. esphome/components/bme280_base/bme280_base.cpp +15 -16
  86. esphome/components/bme680/bme680.cpp +2 -3
  87. esphome/components/bme680_bsec/bme680_bsec.cpp +0 -2
  88. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +0 -2
  89. esphome/components/bmi160/bmi160.cpp +0 -1
  90. esphome/components/bmp085/bmp085.cpp +0 -1
  91. esphome/components/bmp280_base/bmp280_base.cpp +13 -14
  92. esphome/components/bmp3xx_base/bmp3xx_base.cpp +0 -1
  93. esphome/components/bmp581/bmp581.cpp +0 -2
  94. esphome/components/bp1658cj/bp1658cj.cpp +0 -1
  95. esphome/components/bp5758d/bp5758d.cpp +0 -1
  96. esphome/components/button/__init__.py +0 -1
  97. esphome/components/canbus/__init__.py +2 -3
  98. esphome/components/canbus/canbus.cpp +0 -1
  99. esphome/components/cap1188/cap1188.cpp +0 -2
  100. esphome/components/captive_portal/__init__.py +1 -1
  101. esphome/components/cd74hc4067/cd74hc4067.cpp +0 -2
  102. esphome/components/ch422g/ch422g.cpp +0 -1
  103. esphome/components/chsc6x/chsc6x_touchscreen.cpp +0 -3
  104. esphome/components/climate/__init__.py +0 -1
  105. esphome/components/climate/climate_traits.h +24 -0
  106. esphome/components/cm1106/cm1106.cpp +0 -1
  107. esphome/components/const/__init__.py +6 -0
  108. esphome/components/cover/__init__.py +0 -1
  109. esphome/components/cover/cover.cpp +9 -13
  110. esphome/components/cs5460a/cs5460a.cpp +0 -2
  111. esphome/components/cse7761/cse7761.cpp +0 -1
  112. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +0 -2
  113. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +0 -2
  114. esphome/components/dac7678/dac7678_output.cpp +0 -2
  115. esphome/components/dallas_temp/dallas_temp.cpp +0 -1
  116. esphome/components/datetime/__init__.py +0 -2
  117. esphome/components/debug/__init__.py +15 -1
  118. esphome/components/debug/debug_zephyr.cpp +281 -0
  119. esphome/components/debug/sensor.py +2 -1
  120. esphome/components/deep_sleep/deep_sleep_component.cpp +0 -1
  121. esphome/components/deep_sleep/deep_sleep_esp32.cpp +20 -1
  122. esphome/components/dfrobot_sen0395/__init__.py +1 -2
  123. esphome/components/dht/dht.cpp +0 -1
  124. esphome/components/dht12/dht12.cpp +0 -1
  125. esphome/components/display/__init__.py +16 -3
  126. esphome/components/display_menu_base/__init__.py +1 -1
  127. esphome/components/dps310/dps310.cpp +0 -2
  128. esphome/components/ds1307/ds1307.cpp +0 -1
  129. esphome/components/ds2484/ds2484.cpp +0 -1
  130. esphome/components/duty_cycle/duty_cycle_sensor.cpp +0 -1
  131. esphome/components/ee895/ee895.cpp +0 -1
  132. esphome/components/ektf2232/touchscreen/ektf2232.cpp +0 -1
  133. esphome/components/emc2101/emc2101.cpp +0 -2
  134. esphome/components/ens160_base/ens160_base.cpp +0 -2
  135. esphome/components/ens210/ens210.cpp +0 -1
  136. esphome/components/es7210/es7210.cpp +0 -2
  137. esphome/components/es7243e/es7243e.cpp +0 -2
  138. esphome/components/es8156/es8156.cpp +0 -2
  139. esphome/components/es8311/es8311.cpp +0 -2
  140. esphome/components/es8388/es8388.cpp +0 -2
  141. esphome/components/esp32/__init__.py +203 -60
  142. esphome/components/esp32/boards.py +17 -0
  143. esphome/components/esp32/gpio.cpp +0 -1
  144. esphome/components/esp32/gpio.py +1 -2
  145. esphome/components/esp32/gpio_esp32_h2.py +2 -7
  146. esphome/components/esp32/gpio_esp32_p4.py +2 -7
  147. esphome/components/esp32/post_build.py.script +112 -61
  148. esphome/components/esp32_ble/__init__.py +41 -2
  149. esphome/components/esp32_ble/ble.cpp +14 -10
  150. esphome/components/esp32_ble/ble.h +18 -18
  151. esphome/components/esp32_ble/ble_advertising.cpp +5 -5
  152. esphome/components/esp32_ble/ble_advertising.h +7 -5
  153. esphome/components/esp32_ble/ble_event.h +139 -73
  154. esphome/components/esp32_ble/ble_scan_result.h +2 -4
  155. esphome/components/esp32_ble/ble_uuid.cpp +5 -5
  156. esphome/components/esp32_ble/ble_uuid.h +6 -5
  157. esphome/components/esp32_ble_beacon/__init__.py +4 -0
  158. esphome/components/esp32_ble_client/__init__.py +1 -1
  159. esphome/components/esp32_ble_client/ble_characteristic.cpp +4 -4
  160. esphome/components/esp32_ble_client/ble_characteristic.h +6 -4
  161. esphome/components/esp32_ble_client/ble_client_base.cpp +155 -104
  162. esphome/components/esp32_ble_client/ble_client_base.h +17 -6
  163. esphome/components/esp32_ble_client/ble_descriptor.h +6 -4
  164. esphome/components/esp32_ble_client/ble_service.cpp +4 -4
  165. esphome/components/esp32_ble_client/ble_service.h +6 -4
  166. esphome/components/esp32_ble_server/__init__.py +15 -12
  167. esphome/components/esp32_ble_tracker/__init__.py +79 -11
  168. esphome/components/esp32_ble_tracker/automation.h +4 -4
  169. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +264 -261
  170. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +103 -37
  171. esphome/components/esp32_camera/__init__.py +13 -1
  172. esphome/components/esp32_camera/esp32_camera.cpp +7 -2
  173. esphome/components/esp32_camera/esp32_camera.h +1 -0
  174. esphome/components/esp32_dac/esp32_dac.cpp +3 -19
  175. esphome/components/esp32_dac/esp32_dac.h +4 -8
  176. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -6
  177. esphome/components/esp32_rmt_led_strip/light.py +1 -1
  178. esphome/components/esp32_touch/__init__.py +2 -3
  179. esphome/components/esp32_touch/esp32_touch.h +9 -6
  180. esphome/components/esp32_touch/esp32_touch_common.cpp +2 -0
  181. esphome/components/esp32_touch/esp32_touch_v1.cpp +7 -9
  182. esphome/components/esp32_touch/esp32_touch_v2.cpp +10 -6
  183. esphome/components/esp8266/__init__.py +3 -1
  184. esphome/components/esp8266_pwm/esp8266_pwm.cpp +0 -1
  185. esphome/components/esphome/ota/__init__.py +1 -2
  186. esphome/components/esphome/ota/ota_esphome.cpp +150 -77
  187. esphome/components/esphome/ota/ota_esphome.h +8 -1
  188. esphome/components/espnow/__init__.py +309 -0
  189. esphome/components/espnow/automation.h +175 -0
  190. esphome/components/espnow/espnow_component.cpp +468 -0
  191. esphome/components/espnow/espnow_component.h +183 -0
  192. esphome/components/espnow/espnow_err.h +19 -0
  193. esphome/components/espnow/espnow_packet.h +166 -0
  194. esphome/components/ethernet/__init__.py +7 -1
  195. esphome/components/ethernet/esp_eth_phy_jl1101.c +5 -0
  196. esphome/components/ethernet/ethernet_component.cpp +0 -1
  197. esphome/components/ethernet/ethernet_component.h +4 -0
  198. esphome/components/ethernet_info/ethernet_info_text_sensor.h +0 -3
  199. esphome/components/event/__init__.py +0 -1
  200. esphome/components/factory_reset/__init__.py +92 -0
  201. esphome/components/factory_reset/factory_reset.cpp +76 -0
  202. esphome/components/factory_reset/factory_reset.h +43 -0
  203. esphome/components/fan/__init__.py +0 -1
  204. esphome/components/fan/fan_traits.h +16 -0
  205. esphome/components/fastled_base/fastled_light.cpp +0 -1
  206. esphome/components/fastled_spi/light.py +1 -3
  207. esphome/components/fingerprint_grow/fingerprint_grow.cpp +0 -2
  208. esphome/components/font/__init__.py +9 -1
  209. esphome/components/fs3000/fs3000.cpp +0 -2
  210. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
  211. esphome/components/ft63x6/ft63x6.cpp +0 -1
  212. esphome/components/gdk101/gdk101.cpp +0 -1
  213. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
  214. esphome/components/gl_r01_i2c/sensor.py +1 -1
  215. esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
  216. esphome/components/gpio/switch/gpio_switch.cpp +0 -2
  217. esphome/components/gpio_expander/cached_gpio.h +24 -15
  218. esphome/components/gps/__init__.py +6 -2
  219. esphome/components/gps/gps.cpp +50 -49
  220. esphome/components/gps/gps.h +4 -8
  221. esphome/components/gps/time/gps_time.cpp +3 -9
  222. esphome/components/gps/time/gps_time.h +4 -7
  223. esphome/components/graph/__init__.py +1 -1
  224. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
  225. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
  227. esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
  228. esphome/components/haier/climate.py +5 -10
  229. esphome/components/haier/haier_base.cpp +0 -1
  230. esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
  231. esphome/components/hdc1080/hdc1080.cpp +0 -2
  232. esphome/components/heatpumpir/climate.py +2 -2
  233. esphome/components/hlw8012/hlw8012.cpp +0 -1
  234. esphome/components/hm3301/hm3301.cpp +0 -1
  235. esphome/components/hmc5883l/hmc5883l.cpp +0 -1
  236. esphome/components/homeassistant/__init__.py +1 -0
  237. esphome/components/homeassistant/number/__init__.py +1 -0
  238. esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
  239. esphome/components/homeassistant/switch/__init__.py +1 -0
  240. esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
  241. esphome/components/honeywellabp/honeywellabp.cpp +1 -4
  242. esphome/components/host/__init__.py +2 -0
  243. esphome/components/hte501/hte501.cpp +0 -1
  244. esphome/components/http_request/__init__.py +2 -3
  245. esphome/components/http_request/http_request_idf.cpp +2 -2
  246. esphome/components/htu21d/htu21d.cpp +0 -2
  247. esphome/components/htu31d/htu31d.cpp +0 -2
  248. esphome/components/hx711/hx711.cpp +0 -1
  249. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
  250. esphome/components/hydreon_rgxx/sensor.py +4 -5
  251. esphome/components/i2c/i2c_bus.h +1 -1
  252. esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
  253. esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
  254. esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
  255. esphome/components/i2s_audio/__init__.py +6 -5
  256. esphome/components/i2s_audio/i2s_audio.cpp +0 -2
  257. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
  258. esphome/components/i2s_audio/microphone/__init__.py +4 -6
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +46 -19
  260. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +4 -3
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
  262. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
  263. esphome/components/ili9xxx/display.py +4 -3
  264. esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
  265. esphome/components/image/__init__.py +123 -92
  266. esphome/components/improv_serial/__init__.py +7 -8
  267. esphome/components/ina219/ina219.cpp +0 -1
  268. esphome/components/ina226/ina226.cpp +0 -2
  269. esphome/components/ina260/ina260.cpp +0 -2
  270. esphome/components/ina2xx_base/__init__.py +2 -5
  271. esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
  272. esphome/components/ina3221/ina3221.cpp +0 -1
  273. esphome/components/internal_temperature/internal_temperature.cpp +0 -2
  274. esphome/components/interval/interval.h +5 -9
  275. esphome/components/json/__init__.py +1 -1
  276. esphome/components/kmeteriso/kmeteriso.cpp +0 -2
  277. esphome/components/lc709203f/lc709203f.cpp +0 -2
  278. esphome/components/lcd_gpio/display.py +1 -3
  279. esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
  280. esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
  281. esphome/components/ld2410/__init__.py +4 -6
  282. esphome/components/ld2410/binary_sensor.py +4 -0
  283. esphome/components/ld2410/ld2410.cpp +56 -100
  284. esphome/components/ld2410/ld2410.h +17 -15
  285. esphome/components/ld2410/sensor.py +24 -10
  286. esphome/components/ld2412/__init__.py +46 -0
  287. esphome/components/ld2412/binary_sensor.py +70 -0
  288. esphome/components/ld2412/button/__init__.py +74 -0
  289. esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
  290. esphome/components/ld2412/button/factory_reset_button.h +18 -0
  291. esphome/components/ld2412/button/query_button.cpp +9 -0
  292. esphome/components/ld2412/button/query_button.h +18 -0
  293. esphome/components/ld2412/button/restart_button.cpp +9 -0
  294. esphome/components/ld2412/button/restart_button.h +18 -0
  295. esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
  296. esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
  297. esphome/components/ld2412/ld2412.cpp +861 -0
  298. esphome/components/ld2412/ld2412.h +141 -0
  299. esphome/components/ld2412/number/__init__.py +126 -0
  300. esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
  301. esphome/components/ld2412/number/gate_threshold_number.h +19 -0
  302. esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
  303. esphome/components/ld2412/number/light_threshold_number.h +18 -0
  304. esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
  305. esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
  306. esphome/components/ld2412/select/__init__.py +82 -0
  307. esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
  308. esphome/components/ld2412/select/baud_rate_select.h +18 -0
  309. esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
  310. esphome/components/ld2412/select/distance_resolution_select.h +18 -0
  311. esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
  312. esphome/components/ld2412/select/light_out_control_select.h +18 -0
  313. esphome/components/ld2412/sensor.py +124 -0
  314. esphome/components/ld2412/switch/__init__.py +45 -0
  315. esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
  316. esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
  317. esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
  318. esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
  319. esphome/components/ld2412/text_sensor.py +34 -0
  320. esphome/components/ld2420/ld2420.cpp +0 -1
  321. esphome/components/ld2450/__init__.py +3 -4
  322. esphome/components/ld2450/binary_sensor.py +3 -0
  323. esphome/components/ld2450/ld2450.cpp +77 -165
  324. esphome/components/ld2450/ld2450.h +26 -54
  325. esphome/components/ld2450/sensor.py +120 -6
  326. esphome/components/ld2450/text_sensor.py +5 -4
  327. esphome/components/ld24xx/__init__.py +1 -0
  328. esphome/components/ld24xx/ld24xx.h +65 -0
  329. esphome/components/ledc/ledc_output.cpp +0 -1
  330. esphome/components/libretiny/__init__.py +2 -0
  331. esphome/components/light/__init__.py +0 -1
  332. esphome/components/light/effects.py +70 -45
  333. esphome/components/light/light_call.cpp +101 -66
  334. esphome/components/light/light_color_values.h +16 -11
  335. esphome/components/light/light_json_schema.cpp +46 -44
  336. esphome/components/light/light_state.cpp +8 -11
  337. esphome/components/light/light_traits.h +17 -0
  338. esphome/components/lightwaverf/lightwaverf.cpp +0 -2
  339. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
  340. esphome/components/lock/__init__.py +0 -1
  341. esphome/components/logger/__init__.py +31 -9
  342. esphome/components/logger/logger.cpp +12 -7
  343. esphome/components/logger/logger.h +25 -14
  344. esphome/components/logger/logger_esp32.cpp +2 -7
  345. esphome/components/logger/logger_esp8266.cpp +2 -4
  346. esphome/components/logger/logger_host.cpp +2 -4
  347. esphome/components/logger/logger_libretiny.cpp +2 -4
  348. esphome/components/logger/logger_rp2040.cpp +2 -4
  349. esphome/components/logger/logger_zephyr.cpp +86 -0
  350. esphome/components/logger/select/logger_level_select.cpp +2 -4
  351. esphome/components/logger/select/logger_level_select.h +2 -4
  352. esphome/components/logger/task_log_buffer.cpp +2 -4
  353. esphome/components/logger/task_log_buffer.h +2 -4
  354. esphome/components/lps22/sensor.py +5 -5
  355. esphome/components/ltr390/ltr390.cpp +0 -2
  356. esphome/components/ltr501/ltr501.cpp +0 -1
  357. esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
  358. esphome/components/lvgl/__init__.py +14 -13
  359. esphome/components/lvgl/automation.py +2 -4
  360. esphome/components/lvgl/defines.py +0 -2
  361. esphome/components/lvgl/helpers.py +1 -1
  362. esphome/components/lvgl/lv_validation.py +7 -4
  363. esphome/components/lvgl/lvgl_esphome.cpp +2 -3
  364. esphome/components/lvgl/styles.py +2 -2
  365. esphome/components/lvgl/types.py +1 -1
  366. esphome/components/lvgl/widgets/__init__.py +2 -2
  367. esphome/components/lvgl/widgets/arc.py +14 -11
  368. esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
  369. esphome/components/lvgl/widgets/qrcode.py +7 -7
  370. esphome/components/lvgl/widgets/spinner.py +6 -6
  371. esphome/components/lvgl/widgets/switch.py +2 -2
  372. esphome/components/lvgl/widgets/tabview.py +3 -3
  373. esphome/components/lvgl/widgets/tileview.py +15 -7
  374. esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
  375. esphome/components/matrix_keypad/__init__.py +4 -3
  376. esphome/components/max17043/max17043.cpp +0 -2
  377. esphome/components/max31855/max31855.cpp +1 -4
  378. esphome/components/max31856/max31856.cpp +0 -4
  379. esphome/components/max31865/max31865.cpp +0 -1
  380. esphome/components/max44009/max44009.cpp +0 -1
  381. esphome/components/max6675/max6675.cpp +1 -4
  382. esphome/components/max6956/max6956.cpp +0 -1
  383. esphome/components/max7219/max7219.cpp +0 -1
  384. esphome/components/max7219digit/display.py +1 -1
  385. esphome/components/max7219digit/max7219digit.cpp +0 -1
  386. esphome/components/max9611/max9611.cpp +0 -1
  387. esphome/components/mcp23008/__init__.py +1 -1
  388. esphome/components/mcp23008/mcp23008.cpp +0 -1
  389. esphome/components/mcp23016/mcp23016.cpp +0 -1
  390. esphome/components/mcp23017/__init__.py +1 -1
  391. esphome/components/mcp23017/mcp23017.cpp +0 -1
  392. esphome/components/mcp23s08/__init__.py +1 -1
  393. esphome/components/mcp23s08/mcp23s08.cpp +0 -1
  394. esphome/components/mcp23s17/__init__.py +1 -1
  395. esphome/components/mcp23s17/mcp23s17.cpp +0 -1
  396. esphome/components/mcp23x08_base/__init__.py +2 -0
  397. esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
  398. esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
  399. esphome/components/mcp23x17_base/__init__.py +2 -0
  400. esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
  401. esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
  402. esphome/components/mcp23xxx_base/__init__.py +11 -5
  403. esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
  404. esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
  405. esphome/components/mcp3008/mcp3008.cpp +1 -4
  406. esphome/components/mcp3204/mcp3204.cpp +1 -4
  407. esphome/components/mcp4461/mcp4461.cpp +0 -1
  408. esphome/components/mcp4725/mcp4725.cpp +0 -1
  409. esphome/components/mcp4728/mcp4728.cpp +0 -1
  410. esphome/components/mcp9600/mcp9600.cpp +0 -2
  411. esphome/components/mcp9808/mcp9808.cpp +0 -2
  412. esphome/components/mdns/__init__.py +3 -0
  413. esphome/components/mdns/mdns_component.cpp +2 -0
  414. esphome/components/mdns/mdns_component.h +4 -0
  415. esphome/components/media_player/__init__.py +40 -0
  416. esphome/components/media_player/automation.h +16 -0
  417. esphome/components/media_player/media_player.cpp +13 -0
  418. esphome/components/media_player/media_player.h +50 -3
  419. esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
  420. esphome/components/mics_4514/mics_4514.cpp +1 -6
  421. esphome/components/midea/ir_transmitter.h +4 -4
  422. esphome/components/mipi/__init__.py +416 -0
  423. esphome/components/mipi_dsi/__init__.py +5 -0
  424. esphome/components/mipi_dsi/display.py +233 -0
  425. esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
  426. esphome/components/mipi_dsi/mipi_dsi.h +123 -0
  427. esphome/components/mipi_dsi/models/__init__.py +0 -0
  428. esphome/components/mipi_dsi/models/guition.py +38 -0
  429. esphome/components/mipi_dsi/models/m5stack.py +57 -0
  430. esphome/components/mipi_dsi/models/waveshare.py +105 -0
  431. esphome/components/mipi_rgb/models/lilygo.py +0 -0
  432. esphome/components/mipi_spi/__init__.py +0 -9
  433. esphome/components/mipi_spi/display.py +220 -256
  434. esphome/components/mipi_spi/mipi_spi.cpp +1 -485
  435. esphome/components/mipi_spi/mipi_spi.h +556 -108
  436. esphome/components/mipi_spi/models/__init__.py +0 -65
  437. esphome/components/mipi_spi/models/adafruit.py +30 -0
  438. esphome/components/mipi_spi/models/amoled.py +41 -5
  439. esphome/components/mipi_spi/models/ili.py +5 -5
  440. esphome/components/mipi_spi/models/jc.py +1 -3
  441. esphome/components/mipi_spi/models/lilygo.py +1 -1
  442. esphome/components/mipi_spi/models/waveshare.py +16 -1
  443. esphome/components/mixer/speaker/__init__.py +4 -5
  444. esphome/components/mlx90393/sensor.py +7 -5
  445. esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
  446. esphome/components/mlx90614/mlx90614.cpp +0 -1
  447. esphome/components/mmc5603/mmc5603.cpp +0 -1
  448. esphome/components/mmc5983/mmc5983.cpp +0 -2
  449. esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
  450. esphome/components/mpr121/__init__.py +7 -6
  451. esphome/components/mpr121/mpr121.cpp +0 -1
  452. esphome/components/mpu6050/mpu6050.cpp +0 -1
  453. esphome/components/mpu6886/mpu6886.cpp +0 -1
  454. esphome/components/mqtt/__init__.py +1 -2
  455. esphome/components/mqtt/mqtt_button.cpp +1 -1
  456. esphome/components/mqtt/mqtt_client.cpp +0 -1
  457. esphome/components/mqtt/mqtt_component.cpp +8 -14
  458. esphome/components/mqtt/mqtt_component.h +0 -7
  459. esphome/components/mqtt/mqtt_sensor.cpp +0 -1
  460. esphome/components/mqtt/mqtt_sensor.h +0 -1
  461. esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
  462. esphome/components/mqtt/mqtt_text_sensor.h +0 -1
  463. esphome/components/ms5611/ms5611.cpp +0 -1
  464. esphome/components/ms8607/ms8607.cpp +0 -1
  465. esphome/components/msa3xx/msa3xx.cpp +0 -2
  466. esphome/components/my9231/my9231.cpp +0 -2
  467. esphome/components/nau7802/nau7802.cpp +0 -1
  468. esphome/components/neopixelbus/light.py +3 -0
  469. esphome/components/network/util.cpp +29 -0
  470. esphome/components/nextion/nextion.cpp +2 -2
  471. esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
  472. esphome/components/npi19/npi19.cpp +0 -2
  473. esphome/components/nrf52/__init__.py +223 -0
  474. esphome/components/nrf52/boards.py +34 -0
  475. esphome/components/nrf52/const.py +18 -0
  476. esphome/components/nrf52/gpio.py +79 -0
  477. esphome/components/number/__init__.py +2 -1
  478. esphome/components/one_wire/__init__.py +1 -2
  479. esphome/components/one_wire/one_wire.cpp +0 -2
  480. esphome/components/one_wire/one_wire.h +0 -2
  481. esphome/components/opentherm/hub.cpp +0 -1
  482. esphome/components/opentherm/number/__init__.py +2 -2
  483. esphome/components/openthread/__init__.py +2 -3
  484. esphome/components/openthread/openthread.cpp +30 -13
  485. esphome/components/openthread/openthread.h +3 -0
  486. esphome/components/openthread/openthread_esp.cpp +3 -1
  487. esphome/components/opt3001/sensor.py +2 -6
  488. esphome/components/output/__init__.py +38 -0
  489. esphome/components/output/automation.h +24 -0
  490. esphome/components/output/switch/output_switch.cpp +0 -2
  491. esphome/components/packages/__init__.py +1 -2
  492. esphome/components/packet_transport/__init__.py +4 -3
  493. esphome/components/pca6416a/pca6416a.cpp +0 -1
  494. esphome/components/pca9554/pca9554.cpp +0 -1
  495. esphome/components/pca9685/pca9685_output.cpp +0 -2
  496. esphome/components/pcf85063/pcf85063.cpp +0 -1
  497. esphome/components/pcf8563/pcf8563.cpp +0 -1
  498. esphome/components/pcf8574/pcf8574.cpp +0 -1
  499. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
  500. esphome/components/pipsolar/pipsolar.cpp +54 -42
  501. esphome/components/pipsolar/pipsolar.h +5 -4
  502. esphome/components/pipsolar/sensor/__init__.py +1 -1
  503. esphome/components/pm2005/pm2005.cpp +0 -1
  504. esphome/components/pmsa003i/pmsa003i.cpp +0 -2
  505. esphome/components/pmwcs3/sensor.py +1 -2
  506. esphome/components/pn532/pn532.cpp +0 -2
  507. esphome/components/pn532_spi/pn532_spi.cpp +0 -2
  508. esphome/components/power_supply/power_supply.cpp +7 -10
  509. esphome/components/power_supply/power_supply.h +1 -1
  510. esphome/components/psram/__init__.py +6 -1
  511. esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
  512. esphome/components/pulse_counter/sensor.py +9 -6
  513. esphome/components/pylontech/pylontech.cpp +0 -1
  514. esphome/components/qmc5883l/qmc5883l.cpp +0 -1
  515. esphome/components/qmp6988/qmp6988.cpp +0 -2
  516. esphome/components/qspi_dbi/display.py +2 -3
  517. esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
  518. esphome/components/qwiic_pir/binary_sensor.py +2 -3
  519. esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
  520. esphome/components/rc522/rc522.cpp +9 -31
  521. esphome/components/rc522_spi/rc522_spi.cpp +0 -1
  522. esphome/components/remote_base/__init__.py +5 -6
  523. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
  524. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
  525. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
  526. esphome/components/remote_transmitter/__init__.py +26 -0
  527. esphome/components/remote_transmitter/automation.h +18 -0
  528. esphome/components/remote_transmitter/remote_transmitter.h +2 -1
  529. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
  530. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
  531. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
  532. esphome/components/resampler/speaker/__init__.py +4 -5
  533. esphome/components/rf_bridge/__init__.py +4 -8
  534. esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
  535. esphome/components/rp2040/__init__.py +3 -1
  536. esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
  537. esphome/components/rp2040_pio_led_strip/light.py +1 -2
  538. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
  539. esphome/components/rpi_dpi_rgb/display.py +13 -15
  540. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
  541. esphome/components/runtime_stats/__init__.py +34 -0
  542. esphome/components/runtime_stats/runtime_stats.cpp +102 -0
  543. esphome/components/runtime_stats/runtime_stats.h +132 -0
  544. esphome/components/scd30/scd30.cpp +0 -2
  545. esphome/components/scd30/sensor.py +1 -2
  546. esphome/components/scd4x/scd4x.cpp +0 -1
  547. esphome/components/scd4x/sensor.py +1 -3
  548. esphome/components/sdl/display.py +3 -1
  549. esphome/components/sdl/sdl_esphome.cpp +0 -2
  550. esphome/components/sdp3x/sdp3x.cpp +0 -2
  551. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
  552. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
  553. esphome/components/select/__init__.py +2 -3
  554. esphome/components/select/select_traits.cpp +1 -1
  555. esphome/components/select/select_traits.h +1 -1
  556. esphome/components/sen0321/sen0321.cpp +0 -1
  557. esphome/components/sen5x/sen5x.cpp +0 -2
  558. esphome/components/senseair/senseair.cpp +7 -3
  559. esphome/components/senseair/senseair.h +11 -0
  560. esphome/components/sensor/__init__.py +36 -4
  561. esphome/components/sensor/filter.cpp +49 -10
  562. esphome/components/sensor/filter.h +22 -7
  563. esphome/components/sensor/sensor.cpp +0 -1
  564. esphome/components/sensor/sensor.h +0 -9
  565. esphome/components/sfa30/sfa30.cpp +0 -4
  566. esphome/components/sgp30/sgp30.cpp +0 -2
  567. esphome/components/sgp4x/sensor.py +1 -1
  568. esphome/components/sgp4x/sgp4x.cpp +0 -2
  569. esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
  570. esphome/components/sht3xd/sht3xd.cpp +0 -2
  571. esphome/components/sht4x/sht4x.cpp +0 -2
  572. esphome/components/shtcx/shtcx.cpp +0 -1
  573. esphome/components/sim800l/__init__.py +2 -4
  574. esphome/components/sm16716/sm16716.cpp +0 -1
  575. esphome/components/sm2135/sm2135.cpp +0 -1
  576. esphome/components/sm2235/sm2235.cpp +0 -1
  577. esphome/components/sm2335/sm2335.cpp +0 -1
  578. esphome/components/sn74hc165/sn74hc165.cpp +0 -1
  579. esphome/components/sn74hc595/sn74hc595.cpp +0 -1
  580. esphome/components/sntp/sntp_component.cpp +0 -1
  581. esphome/components/sound_level/sensor.py +1 -1
  582. esphome/components/speaker/media_player/__init__.py +21 -33
  583. esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
  584. esphome/components/spi/__init__.py +29 -13
  585. esphome/components/spi/spi.cpp +0 -2
  586. esphome/components/spi_device/spi_device.cpp +1 -4
  587. esphome/components/sprinkler/__init__.py +4 -4
  588. esphome/components/sps30/sps30.cpp +0 -1
  589. esphome/components/ssd1306_base/__init__.py +11 -11
  590. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  591. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
  592. esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
  593. esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
  594. esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
  595. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
  596. esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
  597. esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
  598. esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
  599. esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
  600. esphome/components/st7567_spi/st7567_spi.cpp +0 -1
  601. esphome/components/st7701s/display.py +10 -14
  602. esphome/components/st7701s/st7701s.cpp +0 -3
  603. esphome/components/st7735/st7735.cpp +0 -1
  604. esphome/components/st7789v/st7789v.cpp +0 -1
  605. esphome/components/st7920/st7920.cpp +0 -1
  606. esphome/components/status_led/light/status_led_light.cpp +0 -2
  607. esphome/components/status_led/status_led.cpp +0 -1
  608. esphome/components/stepper/__init__.py +2 -4
  609. esphome/components/sts3x/sts3x.cpp +0 -1
  610. esphome/components/substitutions/__init__.py +10 -16
  611. esphome/components/substitutions/jinja.py +24 -1
  612. esphome/components/sun/__init__.py +2 -3
  613. esphome/components/switch/__init__.py +31 -1
  614. esphome/components/switch/automation.h +24 -0
  615. esphome/components/switch/switch.cpp +8 -0
  616. esphome/components/switch/switch.h +8 -0
  617. esphome/components/sx126x/sx126x.cpp +0 -2
  618. esphome/components/sx127x/sx127x.cpp +0 -2
  619. esphome/components/sx1509/__init__.py +7 -5
  620. esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
  621. esphome/components/sx1509/sx1509.cpp +0 -2
  622. esphome/components/syslog/esphome_syslog.cpp +1 -1
  623. esphome/components/tc74/tc74.cpp +0 -1
  624. esphome/components/tca9548a/tca9548a.cpp +0 -1
  625. esphome/components/tca9555/tca9555.cpp +0 -1
  626. esphome/components/tcs34725/tcs34725.cpp +0 -1
  627. esphome/components/tee501/tee501.cpp +0 -1
  628. esphome/components/tem3200/tem3200.cpp +0 -2
  629. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
  630. esphome/components/template/cover/template_cover.cpp +0 -1
  631. esphome/components/template/select/template_select.cpp +0 -1
  632. esphome/components/template/text/template_text.cpp +0 -2
  633. esphome/components/template/valve/template_valve.cpp +0 -1
  634. esphome/components/text/__init__.py +0 -1
  635. esphome/components/text/text_traits.h +2 -0
  636. esphome/components/text_sensor/__init__.py +2 -1
  637. esphome/components/text_sensor/text_sensor.cpp +0 -2
  638. esphome/components/text_sensor/text_sensor.h +0 -8
  639. esphome/components/thermostat/climate.py +4 -4
  640. esphome/components/time/__init__.py +7 -4
  641. esphome/components/time/real_time_clock.cpp +16 -3
  642. esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
  643. esphome/components/tlc5947/tlc5947.cpp +0 -2
  644. esphome/components/tlc5971/tlc5971.cpp +0 -2
  645. esphome/components/tm1621/tm1621.cpp +0 -2
  646. esphome/components/tm1637/tm1637.cpp +0 -2
  647. esphome/components/tm1638/tm1638.cpp +0 -2
  648. esphome/components/tm1651/__init__.py +45 -48
  649. esphome/components/tm1651/tm1651.cpp +213 -47
  650. esphome/components/tm1651/tm1651.h +37 -32
  651. esphome/components/tmp117/tmp117.cpp +0 -2
  652. esphome/components/tsl2561/tsl2561.cpp +0 -1
  653. esphome/components/tsl2591/tsl2591.cpp +0 -1
  654. esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
  655. esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
  656. esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
  657. esphome/components/tuya/climate/__init__.py +9 -10
  658. esphome/components/tuya/number/__init__.py +8 -6
  659. esphome/components/tx20/tx20.cpp +0 -1
  660. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
  661. esphome/components/uart/uart_component_esp8266.cpp +0 -1
  662. esphome/components/uart/uart_component_esp_idf.cpp +0 -2
  663. esphome/components/uart/uart_component_libretiny.cpp +0 -2
  664. esphome/components/uart/uart_component_rp2040.cpp +0 -2
  665. esphome/components/udp/__init__.py +1 -1
  666. esphome/components/ufire_ec/sensor.py +1 -2
  667. esphome/components/ufire_ec/ufire_ec.cpp +0 -2
  668. esphome/components/ufire_ise/sensor.py +1 -2
  669. esphome/components/ufire_ise/ufire_ise.cpp +0 -2
  670. esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
  671. esphome/components/update/__init__.py +0 -1
  672. esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
  673. esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
  674. esphome/components/usb_host/usb_host_client.cpp +0 -1
  675. esphome/components/usb_host/usb_host_component.cpp +0 -1
  676. esphome/components/valve/__init__.py +0 -1
  677. esphome/components/veml3235/veml3235.cpp +0 -3
  678. esphome/components/veml7700/veml7700.cpp +0 -2
  679. esphome/components/version/version_text_sensor.cpp +0 -1
  680. esphome/components/version/version_text_sensor.h +0 -1
  681. esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
  682. esphome/components/voice_assistant/voice_assistant.cpp +9 -8
  683. esphome/components/web_server/__init__.py +13 -0
  684. esphome/components/web_server/web_server.cpp +188 -353
  685. esphome/components/web_server/web_server.h +61 -1
  686. esphome/components/web_server_base/__init__.py +1 -1
  687. esphome/components/web_server_base/web_server_base.cpp +2 -0
  688. esphome/components/web_server_base/web_server_base.h +6 -0
  689. esphome/components/web_server_idf/web_server_idf.cpp +10 -8
  690. esphome/components/web_server_idf/web_server_idf.h +2 -0
  691. esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
  692. esphome/components/weikai_spi/weikai_spi.cpp +1 -1
  693. esphome/components/wifi/__init__.py +17 -43
  694. esphome/components/wifi/wifi_component.cpp +100 -36
  695. esphome/components/wifi/wifi_component.h +5 -1
  696. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
  697. esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
  698. esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
  699. esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
  700. esphome/components/wireguard/wireguard.cpp +0 -2
  701. esphome/components/x9c/x9c.cpp +0 -2
  702. esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
  703. esphome/components/xl9535/xl9535.cpp +0 -2
  704. esphome/components/zephyr/__init__.py +252 -0
  705. esphome/components/zephyr/const.py +16 -0
  706. esphome/components/zephyr/core.cpp +90 -0
  707. esphome/components/zephyr/gpio.cpp +120 -0
  708. esphome/components/zephyr/gpio.h +38 -0
  709. esphome/components/zephyr/pre_build.py.script +4 -0
  710. esphome/components/zephyr/preferences.cpp +156 -0
  711. esphome/components/zephyr/preferences.h +13 -0
  712. esphome/config.py +38 -16
  713. esphome/config_helpers.py +1 -2
  714. esphome/config_validation.py +12 -16
  715. esphome/const.py +26 -1
  716. esphome/core/__init__.py +92 -51
  717. esphome/core/application.cpp +75 -21
  718. esphome/core/application.h +106 -171
  719. esphome/core/color.h +10 -0
  720. esphome/core/component.cpp +41 -25
  721. esphome/core/component.h +9 -6
  722. esphome/core/component_iterator.cpp +61 -261
  723. esphome/core/component_iterator.h +15 -0
  724. esphome/core/config.py +26 -11
  725. esphome/core/defines.h +40 -2
  726. esphome/core/entity_base.h +18 -0
  727. esphome/core/entity_helpers.py +45 -10
  728. esphome/core/helpers.cpp +8 -15
  729. esphome/core/helpers.h +60 -6
  730. esphome/core/lock_free_queue.h +1 -1
  731. esphome/core/scheduler.cpp +311 -77
  732. esphome/core/scheduler.h +141 -28
  733. esphome/cpp_generator.py +2 -6
  734. esphome/cpp_helpers.py +1 -1
  735. esphome/dashboard/dashboard.py +2 -3
  736. esphome/dashboard/dns.py +2 -8
  737. esphome/dashboard/web_server.py +34 -19
  738. esphome/espota2.py +1 -4
  739. esphome/git.py +3 -1
  740. esphome/helpers.py +23 -4
  741. esphome/log.py +3 -1
  742. esphome/mqtt.py +3 -5
  743. esphome/platformio_api.py +7 -4
  744. esphome/types.py +12 -0
  745. esphome/util.py +20 -8
  746. esphome/voluptuous_schema.py +4 -3
  747. esphome/vscode.py +1 -2
  748. esphome/wizard.py +1 -4
  749. esphome/writer.py +16 -108
  750. esphome/yaml_util.py +7 -5
  751. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/METADATA +13 -14
  752. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/RECORD +757 -677
  753. esphome/components/mipi_spi/models/commands.py +0 -82
  754. /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
  755. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/WHEEL +0 -0
  756. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/entry_points.txt +0 -0
  757. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/licenses/LICENSE +0 -0
  758. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/top_level.txt +0 -0
@@ -3,30 +3,27 @@
3
3
  #include "esphome/core/log.h"
4
4
  #include "esphome/core/macros.h"
5
5
  #include "esphome/core/application.h"
6
+ #include <cstring>
6
7
 
7
8
  #ifdef USE_ESP32
8
9
 
9
- namespace esphome {
10
- namespace bluetooth_proxy {
10
+ namespace esphome::bluetooth_proxy {
11
11
 
12
12
  static const char *const TAG = "bluetooth_proxy";
13
- static const int DONE_SENDING_SERVICES = -2;
14
-
15
- std::vector<uint64_t> get_128bit_uuid_vec(esp_bt_uuid_t uuid_source) {
16
- esp_bt_uuid_t uuid = espbt::ESPBTUUID::from_uuid(uuid_source).as_128bit().get_uuid();
17
- return std::vector<uint64_t>{((uint64_t) uuid.uuid.uuid128[15] << 56) | ((uint64_t) uuid.uuid.uuid128[14] << 48) |
18
- ((uint64_t) uuid.uuid.uuid128[13] << 40) | ((uint64_t) uuid.uuid.uuid128[12] << 32) |
19
- ((uint64_t) uuid.uuid.uuid128[11] << 24) | ((uint64_t) uuid.uuid.uuid128[10] << 16) |
20
- ((uint64_t) uuid.uuid.uuid128[9] << 8) | ((uint64_t) uuid.uuid.uuid128[8]),
21
- ((uint64_t) uuid.uuid.uuid128[7] << 56) | ((uint64_t) uuid.uuid.uuid128[6] << 48) |
22
- ((uint64_t) uuid.uuid.uuid128[5] << 40) | ((uint64_t) uuid.uuid.uuid128[4] << 32) |
23
- ((uint64_t) uuid.uuid.uuid128[3] << 24) | ((uint64_t) uuid.uuid.uuid128[2] << 16) |
24
- ((uint64_t) uuid.uuid.uuid128[1] << 8) | ((uint64_t) uuid.uuid.uuid128[0])};
25
- }
13
+
14
+ // BLUETOOTH_PROXY_ADVERTISEMENT_BATCH_SIZE is defined during code generation
15
+ // It sets the batch size for BLE advertisements to maximize WiFi efficiency
16
+
17
+ // Verify BLE advertisement data array size matches the BLE specification (31 bytes adv + 31 bytes scan response)
18
+ static_assert(sizeof(((api::BluetoothLERawAdvertisement *) nullptr)->data) == 62,
19
+ "BLE advertisement data array size mismatch");
26
20
 
27
21
  BluetoothProxy::BluetoothProxy() { global_bluetooth_proxy = this; }
28
22
 
29
23
  void BluetoothProxy::setup() {
24
+ this->connections_free_response_.limit = BLUETOOTH_PROXY_MAX_CONNECTIONS;
25
+ this->connections_free_response_.free = BLUETOOTH_PROXY_MAX_CONNECTIONS;
26
+
30
27
  this->parent_->add_scanner_state_callback([this](esp32_ble_tracker::ScannerState state) {
31
28
  if (this->api_connection_ != nullptr) {
32
29
  this->send_bluetooth_scanner_state_(state);
@@ -39,147 +36,95 @@ void BluetoothProxy::send_bluetooth_scanner_state_(esp32_ble_tracker::ScannerSta
39
36
  resp.state = static_cast<api::enums::BluetoothScannerState>(state);
40
37
  resp.mode = this->parent_->get_scan_active() ? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE
41
38
  : api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE;
42
- this->api_connection_->send_message(resp);
39
+ this->api_connection_->send_message(resp, api::BluetoothScannerStateResponse::MESSAGE_TYPE);
43
40
  }
44
41
 
45
- bool BluetoothProxy::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
46
- if (!api::global_api_server->is_connected() || this->api_connection_ == nullptr || this->raw_advertisements_)
47
- return false;
42
+ void BluetoothProxy::log_connection_request_ignored_(BluetoothConnection *connection, espbt::ClientState state) {
43
+ ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, state: %s", connection->get_connection_index(),
44
+ connection->address_str().c_str(), espbt::client_state_to_string(state));
45
+ }
48
46
 
49
- ESP_LOGV(TAG, "Proxying packet from %s - %s. RSSI: %d dB", device.get_name().c_str(), device.address_str().c_str(),
50
- device.get_rssi());
51
- this->send_api_packet_(device);
52
- return true;
47
+ void BluetoothProxy::log_connection_info_(BluetoothConnection *connection, const char *message) {
48
+ ESP_LOGI(TAG, "[%d] [%s] Connecting %s", connection->get_connection_index(), connection->address_str().c_str(),
49
+ message);
53
50
  }
54
51
 
55
- // Batch size for BLE advertisements to maximize WiFi efficiency
56
- // Each advertisement is up to 80 bytes when packaged (including protocol overhead)
57
- // Most advertisements are 20-30 bytes, allowing even more to fit per packet
58
- // 16 advertisements × 80 bytes (worst case) = 1280 bytes out of ~1320 bytes usable payload
59
- // This achieves ~97% WiFi MTU utilization while staying under the limit
60
- static constexpr size_t FLUSH_BATCH_SIZE = 16;
52
+ void BluetoothProxy::log_not_connected_gatt_(const char *action, const char *type) {
53
+ ESP_LOGW(TAG, "Cannot %s GATT %s, not connected", action, type);
54
+ }
61
55
 
62
- namespace {
63
- // Batch buffer in anonymous namespace to avoid guard variable (saves 8 bytes)
64
- // This is initialized at program startup before any threads
65
- // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
66
- std::vector<api::BluetoothLERawAdvertisement> batch_buffer;
67
- } // namespace
56
+ void BluetoothProxy::handle_gatt_not_connected_(uint64_t address, uint16_t handle, const char *action,
57
+ const char *type) {
58
+ this->log_not_connected_gatt_(action, type);
59
+ this->send_gatt_error(address, handle, ESP_GATT_NOT_CONNECTED);
60
+ }
68
61
 
69
- static std::vector<api::BluetoothLERawAdvertisement> &get_batch_buffer() { return batch_buffer; }
62
+ #ifdef USE_ESP32_BLE_DEVICE
63
+ bool BluetoothProxy::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
64
+ // This method should never be called since bluetooth_proxy always uses raw advertisements
65
+ // but we need to provide an implementation to satisfy the virtual method requirement
66
+ return false;
67
+ }
68
+ #endif
70
69
 
71
70
  bool BluetoothProxy::parse_devices(const esp32_ble::BLEScanResult *scan_results, size_t count) {
72
- if (!api::global_api_server->is_connected() || this->api_connection_ == nullptr || !this->raw_advertisements_)
71
+ if (!api::global_api_server->is_connected() || this->api_connection_ == nullptr)
73
72
  return false;
74
73
 
75
- // Get the batch buffer reference
76
- auto &batch_buffer = get_batch_buffer();
74
+ auto &advertisements = this->response_.advertisements;
77
75
 
78
- // Reserve additional capacity if needed
79
- size_t new_size = batch_buffer.size() + count;
80
- if (batch_buffer.capacity() < new_size) {
81
- batch_buffer.reserve(new_size);
82
- }
83
-
84
- // Add new advertisements to the batch buffer
85
76
  for (size_t i = 0; i < count; i++) {
86
77
  auto &result = scan_results[i];
87
78
  uint8_t length = result.adv_data_len + result.scan_rsp_len;
88
79
 
89
- batch_buffer.emplace_back();
90
- auto &adv = batch_buffer.back();
80
+ // Fill in the data directly at current position
81
+ auto &adv = advertisements[this->response_.advertisements_len];
91
82
  adv.address = esp32_ble::ble_addr_to_uint64(result.bda);
92
83
  adv.rssi = result.rssi;
93
84
  adv.address_type = result.ble_addr_type;
94
- adv.data.assign(&result.ble_adv[0], &result.ble_adv[length]);
85
+ adv.data_len = length;
86
+ std::memcpy(adv.data, result.ble_adv, length);
87
+
88
+ this->response_.advertisements_len++;
95
89
 
96
90
  ESP_LOGV(TAG, "Queuing raw packet from %02X:%02X:%02X:%02X:%02X:%02X, length %d. RSSI: %d dB", result.bda[0],
97
91
  result.bda[1], result.bda[2], result.bda[3], result.bda[4], result.bda[5], length, result.rssi);
98
- }
99
92
 
100
- // Only send if we've accumulated a good batch size to maximize batching efficiency
101
- // https://github.com/esphome/backlog/issues/21
102
- if (batch_buffer.size() >= FLUSH_BATCH_SIZE) {
103
- this->flush_pending_advertisements();
93
+ // Flush if we have reached BLUETOOTH_PROXY_ADVERTISEMENT_BATCH_SIZE
94
+ if (this->response_.advertisements_len >= BLUETOOTH_PROXY_ADVERTISEMENT_BATCH_SIZE) {
95
+ this->flush_pending_advertisements();
96
+ }
104
97
  }
105
98
 
106
99
  return true;
107
100
  }
108
101
 
109
102
  void BluetoothProxy::flush_pending_advertisements() {
110
- auto &batch_buffer = get_batch_buffer();
111
- if (batch_buffer.empty() || !api::global_api_server->is_connected() || this->api_connection_ == nullptr)
103
+ if (this->response_.advertisements_len == 0 || !api::global_api_server->is_connected() ||
104
+ this->api_connection_ == nullptr)
112
105
  return;
113
106
 
114
- api::BluetoothLERawAdvertisementsResponse resp;
115
- resp.advertisements.swap(batch_buffer);
116
- this->api_connection_->send_message(resp);
117
- }
118
-
119
- void BluetoothProxy::send_api_packet_(const esp32_ble_tracker::ESPBTDevice &device) {
120
- api::BluetoothLEAdvertisementResponse resp;
121
- resp.address = device.address_uint64();
122
- resp.address_type = device.get_address_type();
123
- if (!device.get_name().empty())
124
- resp.name = device.get_name();
125
- resp.rssi = device.get_rssi();
126
-
127
- // Pre-allocate vectors based on known sizes
128
- auto service_uuids = device.get_service_uuids();
129
- resp.service_uuids.reserve(service_uuids.size());
130
- for (auto &uuid : service_uuids) {
131
- resp.service_uuids.emplace_back(uuid.to_string());
132
- }
133
-
134
- // Pre-allocate service data vector
135
- auto service_datas = device.get_service_datas();
136
- resp.service_data.reserve(service_datas.size());
137
- for (auto &data : service_datas) {
138
- resp.service_data.emplace_back();
139
- auto &service_data = resp.service_data.back();
140
- service_data.uuid = data.uuid.to_string();
141
- service_data.data.assign(data.data.begin(), data.data.end());
142
- }
107
+ // Send the message
108
+ this->api_connection_->send_message(this->response_, api::BluetoothLERawAdvertisementsResponse::MESSAGE_TYPE);
143
109
 
144
- // Pre-allocate manufacturer data vector
145
- auto manufacturer_datas = device.get_manufacturer_datas();
146
- resp.manufacturer_data.reserve(manufacturer_datas.size());
147
- for (auto &data : manufacturer_datas) {
148
- resp.manufacturer_data.emplace_back();
149
- auto &manufacturer_data = resp.manufacturer_data.back();
150
- manufacturer_data.uuid = data.uuid.to_string();
151
- manufacturer_data.data.assign(data.data.begin(), data.data.end());
152
- }
110
+ ESP_LOGV(TAG, "Sent batch of %u BLE advertisements", this->response_.advertisements_len);
153
111
 
154
- this->api_connection_->send_message(resp);
112
+ // Reset the length for the next batch
113
+ this->response_.advertisements_len = 0;
155
114
  }
156
115
 
157
116
  void BluetoothProxy::dump_config() {
158
- ESP_LOGCONFIG(TAG, "Bluetooth Proxy:");
159
117
  ESP_LOGCONFIG(TAG,
118
+ "Bluetooth Proxy:\n"
160
119
  " Active: %s\n"
161
- " Connections: %d\n"
162
- " Raw advertisements: %s",
163
- YESNO(this->active_), this->connections_.size(), YESNO(this->raw_advertisements_));
164
- }
165
-
166
- int BluetoothProxy::get_bluetooth_connections_free() {
167
- int free = 0;
168
- for (auto *connection : this->connections_) {
169
- if (connection->address_ == 0) {
170
- free++;
171
- ESP_LOGV(TAG, "[%d] Free connection", connection->get_connection_index());
172
- } else {
173
- ESP_LOGV(TAG, "[%d] Used connection by [%s]", connection->get_connection_index(),
174
- connection->address_str().c_str());
175
- }
176
- }
177
- return free;
120
+ " Connections: %d",
121
+ YESNO(this->active_), this->connection_count_);
178
122
  }
179
123
 
180
124
  void BluetoothProxy::loop() {
181
125
  if (!api::global_api_server->is_connected() || this->api_connection_ == nullptr) {
182
- for (auto *connection : this->connections_) {
126
+ for (uint8_t i = 0; i < this->connection_count_; i++) {
127
+ auto *connection = this->connections_[i];
183
128
  if (connection->get_address() != 0 && !connection->disconnect_pending()) {
184
129
  connection->disconnect();
185
130
  }
@@ -188,143 +133,22 @@ void BluetoothProxy::loop() {
188
133
  }
189
134
 
190
135
  // Flush any pending BLE advertisements that have been accumulated but not yet sent
191
- if (this->raw_advertisements_) {
192
- static uint32_t last_flush_time = 0;
193
- uint32_t now = App.get_loop_component_start_time();
194
-
195
- // Flush accumulated advertisements every 100ms
196
- if (now - last_flush_time >= 100) {
197
- this->flush_pending_advertisements();
198
- last_flush_time = now;
199
- }
200
- }
201
- for (auto *connection : this->connections_) {
202
- if (connection->send_service_ == connection->service_count_) {
203
- connection->send_service_ = DONE_SENDING_SERVICES;
204
- this->send_gatt_services_done(connection->get_address());
205
- if (connection->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE ||
206
- connection->connection_type_ == espbt::ConnectionType::V3_WITHOUT_CACHE) {
207
- connection->release_services();
208
- }
209
- } else if (connection->send_service_ >= 0) {
210
- esp_gattc_service_elem_t service_result;
211
- uint16_t service_count = 1;
212
- esp_gatt_status_t service_status =
213
- esp_ble_gattc_get_service(connection->get_gattc_if(), connection->get_conn_id(), nullptr, &service_result,
214
- &service_count, connection->send_service_);
215
- connection->send_service_++;
216
- if (service_status != ESP_GATT_OK) {
217
- ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_service error at offset=%d, status=%d",
218
- connection->get_connection_index(), connection->address_str().c_str(), connection->send_service_ - 1,
219
- service_status);
220
- continue;
221
- }
222
- if (service_count == 0) {
223
- ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_service missing, service_count=%d",
224
- connection->get_connection_index(), connection->address_str().c_str(), service_count);
225
- continue;
226
- }
227
- api::BluetoothGATTGetServicesResponse resp;
228
- resp.address = connection->get_address();
229
- resp.services.reserve(1); // Always one service per response in this implementation
230
- api::BluetoothGATTService service_resp;
231
- service_resp.uuid = get_128bit_uuid_vec(service_result.uuid);
232
- service_resp.handle = service_result.start_handle;
233
- uint16_t char_offset = 0;
234
- esp_gattc_char_elem_t char_result;
235
- // Get the number of characteristics directly with one call
236
- uint16_t total_char_count = 0;
237
- esp_gatt_status_t char_count_status = esp_ble_gattc_get_attr_count(
238
- connection->get_gattc_if(), connection->get_conn_id(), ESP_GATT_DB_CHARACTERISTIC,
239
- service_result.start_handle, service_result.end_handle, 0, &total_char_count);
240
-
241
- if (char_count_status == ESP_GATT_OK && total_char_count > 0) {
242
- // Only reserve if we successfully got a count
243
- service_resp.characteristics.reserve(total_char_count);
244
- } else if (char_count_status != ESP_GATT_OK) {
245
- ESP_LOGW(TAG, "[%d] [%s] Error getting characteristic count, status=%d", connection->get_connection_index(),
246
- connection->address_str().c_str(), char_count_status);
247
- }
248
-
249
- // Now process characteristics
250
- while (true) { // characteristics
251
- uint16_t char_count = 1;
252
- esp_gatt_status_t char_status = esp_ble_gattc_get_all_char(
253
- connection->get_gattc_if(), connection->get_conn_id(), service_result.start_handle,
254
- service_result.end_handle, &char_result, &char_count, char_offset);
255
- if (char_status == ESP_GATT_INVALID_OFFSET || char_status == ESP_GATT_NOT_FOUND) {
256
- break;
257
- }
258
- if (char_status != ESP_GATT_OK) {
259
- ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_all_char error, status=%d", connection->get_connection_index(),
260
- connection->address_str().c_str(), char_status);
261
- break;
262
- }
263
- if (char_count == 0) {
264
- break;
265
- }
266
- api::BluetoothGATTCharacteristic characteristic_resp;
267
- characteristic_resp.uuid = get_128bit_uuid_vec(char_result.uuid);
268
- characteristic_resp.handle = char_result.char_handle;
269
- characteristic_resp.properties = char_result.properties;
270
- char_offset++;
271
-
272
- // Get the number of descriptors directly with one call
273
- uint16_t total_desc_count = 0;
274
- esp_gatt_status_t desc_count_status =
275
- esp_ble_gattc_get_attr_count(connection->get_gattc_if(), connection->get_conn_id(), ESP_GATT_DB_DESCRIPTOR,
276
- char_result.char_handle, service_result.end_handle, 0, &total_desc_count);
277
-
278
- if (desc_count_status == ESP_GATT_OK && total_desc_count > 0) {
279
- // Only reserve if we successfully got a count
280
- characteristic_resp.descriptors.reserve(total_desc_count);
281
- } else if (desc_count_status != ESP_GATT_OK) {
282
- ESP_LOGW(TAG, "[%d] [%s] Error getting descriptor count for char handle %d, status=%d",
283
- connection->get_connection_index(), connection->address_str().c_str(), char_result.char_handle,
284
- desc_count_status);
285
- }
136
+ uint32_t now = App.get_loop_component_start_time();
286
137
 
287
- // Now process descriptors
288
- uint16_t desc_offset = 0;
289
- esp_gattc_descr_elem_t desc_result;
290
- while (true) { // descriptors
291
- uint16_t desc_count = 1;
292
- esp_gatt_status_t desc_status =
293
- esp_ble_gattc_get_all_descr(connection->get_gattc_if(), connection->get_conn_id(),
294
- char_result.char_handle, &desc_result, &desc_count, desc_offset);
295
- if (desc_status == ESP_GATT_INVALID_OFFSET || desc_status == ESP_GATT_NOT_FOUND) {
296
- break;
297
- }
298
- if (desc_status != ESP_GATT_OK) {
299
- ESP_LOGE(TAG, "[%d] [%s] esp_ble_gattc_get_all_descr error, status=%d", connection->get_connection_index(),
300
- connection->address_str().c_str(), desc_status);
301
- break;
302
- }
303
- if (desc_count == 0) {
304
- break;
305
- }
306
- api::BluetoothGATTDescriptor descriptor_resp;
307
- descriptor_resp.uuid = get_128bit_uuid_vec(desc_result.uuid);
308
- descriptor_resp.handle = desc_result.handle;
309
- characteristic_resp.descriptors.push_back(std::move(descriptor_resp));
310
- desc_offset++;
311
- }
312
- service_resp.characteristics.push_back(std::move(characteristic_resp));
313
- }
314
- resp.services.push_back(std::move(service_resp));
315
- this->api_connection_->send_message(resp);
316
- }
138
+ // Flush accumulated advertisements every 100ms
139
+ if (now - this->last_advertisement_flush_time_ >= 100) {
140
+ this->flush_pending_advertisements();
141
+ this->last_advertisement_flush_time_ = now;
317
142
  }
318
143
  }
319
144
 
320
145
  esp32_ble_tracker::AdvertisementParserType BluetoothProxy::get_advertisement_parser_type() {
321
- if (this->raw_advertisements_)
322
- return esp32_ble_tracker::AdvertisementParserType::RAW_ADVERTISEMENTS;
323
- return esp32_ble_tracker::AdvertisementParserType::PARSED_ADVERTISEMENTS;
146
+ return esp32_ble_tracker::AdvertisementParserType::RAW_ADVERTISEMENTS;
324
147
  }
325
148
 
326
149
  BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool reserve) {
327
- for (auto *connection : this->connections_) {
150
+ for (uint8_t i = 0; i < this->connection_count_; i++) {
151
+ auto *connection = this->connections_[i];
328
152
  if (connection->get_address() == address)
329
153
  return connection;
330
154
  }
@@ -332,9 +156,10 @@ BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool rese
332
156
  if (!reserve)
333
157
  return nullptr;
334
158
 
335
- for (auto *connection : this->connections_) {
159
+ for (uint8_t i = 0; i < this->connection_count_; i++) {
160
+ auto *connection = this->connections_[i];
336
161
  if (connection->get_address() == 0) {
337
- connection->send_service_ = DONE_SENDING_SERVICES;
162
+ connection->send_service_ = INIT_SENDING_SERVICES;
338
163
  connection->set_address(address);
339
164
  // All connections must start at INIT
340
165
  // We only set the state if we allocate the connection
@@ -351,8 +176,7 @@ BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool rese
351
176
  void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest &msg) {
352
177
  switch (msg.request_type) {
353
178
  case api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE:
354
- case api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE:
355
- case api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT: {
179
+ case api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE: {
356
180
  auto *connection = this->get_connection_(msg.address, true);
357
181
  if (connection == nullptr) {
358
182
  ESP_LOGW(TAG, "No free connections available");
@@ -361,23 +185,10 @@ void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest
361
185
  }
362
186
  if (connection->state() == espbt::ClientState::CONNECTED ||
363
187
  connection->state() == espbt::ClientState::ESTABLISHED) {
364
- ESP_LOGW(TAG, "[%d] [%s] Connection already established", connection->get_connection_index(),
365
- connection->address_str().c_str());
188
+ this->log_connection_request_ignored_(connection, connection->state());
366
189
  this->send_device_connection(msg.address, true);
367
190
  this->send_connections_free();
368
191
  return;
369
- } else if (connection->state() == espbt::ClientState::SEARCHING) {
370
- ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, already searching for device",
371
- connection->get_connection_index(), connection->address_str().c_str());
372
- return;
373
- } else if (connection->state() == espbt::ClientState::DISCOVERED) {
374
- ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, device already discovered",
375
- connection->get_connection_index(), connection->address_str().c_str());
376
- return;
377
- } else if (connection->state() == espbt::ClientState::READY_TO_CONNECT) {
378
- ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, waiting in line to connect",
379
- connection->get_connection_index(), connection->address_str().c_str());
380
- return;
381
192
  } else if (connection->state() == espbt::ClientState::CONNECTING) {
382
193
  if (connection->disconnect_pending()) {
383
194
  ESP_LOGW(TAG, "[%d] [%s] Connection request while pending disconnect, cancelling pending disconnect",
@@ -385,29 +196,18 @@ void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest
385
196
  connection->cancel_pending_disconnect();
386
197
  return;
387
198
  }
388
- ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, already connecting", connection->get_connection_index(),
389
- connection->address_str().c_str());
390
- return;
391
- } else if (connection->state() == espbt::ClientState::DISCONNECTING) {
392
- ESP_LOGW(TAG, "[%d] [%s] Connection request ignored, device is disconnecting",
393
- connection->get_connection_index(), connection->address_str().c_str());
199
+ this->log_connection_request_ignored_(connection, connection->state());
394
200
  return;
395
201
  } else if (connection->state() != espbt::ClientState::INIT) {
396
- ESP_LOGW(TAG, "[%d] [%s] Connection already in progress", connection->get_connection_index(),
397
- connection->address_str().c_str());
202
+ this->log_connection_request_ignored_(connection, connection->state());
398
203
  return;
399
204
  }
400
205
  if (msg.request_type == api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITH_CACHE) {
401
206
  connection->set_connection_type(espbt::ConnectionType::V3_WITH_CACHE);
402
- ESP_LOGI(TAG, "[%d] [%s] Connecting v3 with cache", connection->get_connection_index(),
403
- connection->address_str().c_str());
404
- } else if (msg.request_type == api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE) {
207
+ this->log_connection_info_(connection, "v3 with cache");
208
+ } else { // BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT_V3_WITHOUT_CACHE
405
209
  connection->set_connection_type(espbt::ConnectionType::V3_WITHOUT_CACHE);
406
- ESP_LOGI(TAG, "[%d] [%s] Connecting v3 without cache", connection->get_connection_index(),
407
- connection->address_str().c_str());
408
- } else {
409
- connection->set_connection_type(espbt::ConnectionType::V1);
410
- ESP_LOGI(TAG, "[%d] [%s] Connecting v1", connection->get_connection_index(), connection->address_str().c_str());
210
+ this->log_connection_info_(connection, "v3 without cache");
411
211
  }
412
212
  if (msg.has_address_type) {
413
213
  uint64_to_bd_addr(msg.address, connection->remote_bda_);
@@ -465,18 +265,22 @@ void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest
465
265
  call.success = ret == ESP_OK;
466
266
  call.error = ret;
467
267
 
468
- this->api_connection_->send_message(call);
268
+ this->api_connection_->send_message(call, api::BluetoothDeviceClearCacheResponse::MESSAGE_TYPE);
469
269
 
470
270
  break;
471
271
  }
272
+ case api::enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT: {
273
+ ESP_LOGE(TAG, "V1 connections removed");
274
+ this->send_device_connection(msg.address, false);
275
+ break;
276
+ }
472
277
  }
473
278
  }
474
279
 
475
280
  void BluetoothProxy::bluetooth_gatt_read(const api::BluetoothGATTReadRequest &msg) {
476
281
  auto *connection = this->get_connection_(msg.address, false);
477
282
  if (connection == nullptr) {
478
- ESP_LOGW(TAG, "Cannot read GATT characteristic, not connected");
479
- this->send_gatt_error(msg.address, msg.handle, ESP_GATT_NOT_CONNECTED);
283
+ this->handle_gatt_not_connected_(msg.address, msg.handle, "read", "characteristic");
480
284
  return;
481
285
  }
482
286
 
@@ -489,8 +293,7 @@ void BluetoothProxy::bluetooth_gatt_read(const api::BluetoothGATTReadRequest &ms
489
293
  void BluetoothProxy::bluetooth_gatt_write(const api::BluetoothGATTWriteRequest &msg) {
490
294
  auto *connection = this->get_connection_(msg.address, false);
491
295
  if (connection == nullptr) {
492
- ESP_LOGW(TAG, "Cannot write GATT characteristic, not connected");
493
- this->send_gatt_error(msg.address, msg.handle, ESP_GATT_NOT_CONNECTED);
296
+ this->handle_gatt_not_connected_(msg.address, msg.handle, "write", "characteristic");
494
297
  return;
495
298
  }
496
299
 
@@ -503,8 +306,7 @@ void BluetoothProxy::bluetooth_gatt_write(const api::BluetoothGATTWriteRequest &
503
306
  void BluetoothProxy::bluetooth_gatt_read_descriptor(const api::BluetoothGATTReadDescriptorRequest &msg) {
504
307
  auto *connection = this->get_connection_(msg.address, false);
505
308
  if (connection == nullptr) {
506
- ESP_LOGW(TAG, "Cannot read GATT descriptor, not connected");
507
- this->send_gatt_error(msg.address, msg.handle, ESP_GATT_NOT_CONNECTED);
309
+ this->handle_gatt_not_connected_(msg.address, msg.handle, "read", "descriptor");
508
310
  return;
509
311
  }
510
312
 
@@ -517,8 +319,7 @@ void BluetoothProxy::bluetooth_gatt_read_descriptor(const api::BluetoothGATTRead
517
319
  void BluetoothProxy::bluetooth_gatt_write_descriptor(const api::BluetoothGATTWriteDescriptorRequest &msg) {
518
320
  auto *connection = this->get_connection_(msg.address, false);
519
321
  if (connection == nullptr) {
520
- ESP_LOGW(TAG, "Cannot write GATT descriptor, not connected");
521
- this->send_gatt_error(msg.address, msg.handle, ESP_GATT_NOT_CONNECTED);
322
+ this->handle_gatt_not_connected_(msg.address, msg.handle, "write", "descriptor");
522
323
  return;
523
324
  }
524
325
 
@@ -531,8 +332,7 @@ void BluetoothProxy::bluetooth_gatt_write_descriptor(const api::BluetoothGATTWri
531
332
  void BluetoothProxy::bluetooth_gatt_send_services(const api::BluetoothGATTGetServicesRequest &msg) {
532
333
  auto *connection = this->get_connection_(msg.address, false);
533
334
  if (connection == nullptr || !connection->connected()) {
534
- ESP_LOGW(TAG, "Cannot get GATT services, not connected");
535
- this->send_gatt_error(msg.address, 0, ESP_GATT_NOT_CONNECTED);
335
+ this->handle_gatt_not_connected_(msg.address, 0, "get", "services");
536
336
  return;
537
337
  }
538
338
  if (!connection->service_count_) {
@@ -540,16 +340,14 @@ void BluetoothProxy::bluetooth_gatt_send_services(const api::BluetoothGATTGetSer
540
340
  this->send_gatt_services_done(msg.address);
541
341
  return;
542
342
  }
543
- if (connection->send_service_ ==
544
- DONE_SENDING_SERVICES) // Only start sending services if we're not already sending them
343
+ if (connection->send_service_ == INIT_SENDING_SERVICES) // Start sending services if not started yet
545
344
  connection->send_service_ = 0;
546
345
  }
547
346
 
548
347
  void BluetoothProxy::bluetooth_gatt_notify(const api::BluetoothGATTNotifyRequest &msg) {
549
348
  auto *connection = this->get_connection_(msg.address, false);
550
349
  if (connection == nullptr) {
551
- ESP_LOGW(TAG, "Cannot notify GATT characteristic, not connected");
552
- this->send_gatt_error(msg.address, msg.handle, ESP_GATT_NOT_CONNECTED);
350
+ this->handle_gatt_not_connected_(msg.address, msg.handle, "notify", "characteristic");
553
351
  return;
554
352
  }
555
353
 
@@ -565,7 +363,6 @@ void BluetoothProxy::subscribe_api_connection(api::APIConnection *api_connection
565
363
  return;
566
364
  }
567
365
  this->api_connection_ = api_connection;
568
- this->raw_advertisements_ = flags & BluetoothProxySubscriptionFlag::SUBSCRIPTION_RAW_ADVERTISEMENTS;
569
366
  this->parent_->recalculate_advertisement_parser_types();
570
367
 
571
368
  this->send_bluetooth_scanner_state_(this->parent_->get_scanner_state());
@@ -577,7 +374,6 @@ void BluetoothProxy::unsubscribe_api_connection(api::APIConnection *api_connecti
577
374
  return;
578
375
  }
579
376
  this->api_connection_ = nullptr;
580
- this->raw_advertisements_ = false;
581
377
  this->parent_->recalculate_advertisement_parser_types();
582
378
  }
583
379
 
@@ -589,20 +385,16 @@ void BluetoothProxy::send_device_connection(uint64_t address, bool connected, ui
589
385
  call.connected = connected;
590
386
  call.mtu = mtu;
591
387
  call.error = error;
592
- this->api_connection_->send_message(call);
388
+ this->api_connection_->send_message(call, api::BluetoothDeviceConnectionResponse::MESSAGE_TYPE);
593
389
  }
594
390
  void BluetoothProxy::send_connections_free() {
595
- if (this->api_connection_ == nullptr)
596
- return;
597
- api::BluetoothConnectionsFreeResponse call;
598
- call.free = this->get_bluetooth_connections_free();
599
- call.limit = this->get_bluetooth_connections_limit();
600
- for (auto *connection : this->connections_) {
601
- if (connection->address_ != 0) {
602
- call.allocated.push_back(connection->address_);
603
- }
391
+ if (this->api_connection_ != nullptr) {
392
+ this->send_connections_free(this->api_connection_);
604
393
  }
605
- this->api_connection_->send_message(call);
394
+ }
395
+
396
+ void BluetoothProxy::send_connections_free(api::APIConnection *api_connection) {
397
+ api_connection->send_message(this->connections_free_response_, api::BluetoothConnectionsFreeResponse::MESSAGE_TYPE);
606
398
  }
607
399
 
608
400
  void BluetoothProxy::send_gatt_services_done(uint64_t address) {
@@ -610,7 +402,7 @@ void BluetoothProxy::send_gatt_services_done(uint64_t address) {
610
402
  return;
611
403
  api::BluetoothGATTGetServicesDoneResponse call;
612
404
  call.address = address;
613
- this->api_connection_->send_message(call);
405
+ this->api_connection_->send_message(call, api::BluetoothGATTGetServicesDoneResponse::MESSAGE_TYPE);
614
406
  }
615
407
 
616
408
  void BluetoothProxy::send_gatt_error(uint64_t address, uint16_t handle, esp_err_t error) {
@@ -620,7 +412,7 @@ void BluetoothProxy::send_gatt_error(uint64_t address, uint16_t handle, esp_err_
620
412
  call.address = address;
621
413
  call.handle = handle;
622
414
  call.error = error;
623
- this->api_connection_->send_message(call);
415
+ this->api_connection_->send_message(call, api::BluetoothGATTWriteResponse::MESSAGE_TYPE);
624
416
  }
625
417
 
626
418
  void BluetoothProxy::send_device_pairing(uint64_t address, bool paired, esp_err_t error) {
@@ -629,7 +421,7 @@ void BluetoothProxy::send_device_pairing(uint64_t address, bool paired, esp_err_
629
421
  call.paired = paired;
630
422
  call.error = error;
631
423
 
632
- this->api_connection_->send_message(call);
424
+ this->api_connection_->send_message(call, api::BluetoothDevicePairingResponse::MESSAGE_TYPE);
633
425
  }
634
426
 
635
427
  void BluetoothProxy::send_device_unpairing(uint64_t address, bool success, esp_err_t error) {
@@ -638,7 +430,7 @@ void BluetoothProxy::send_device_unpairing(uint64_t address, bool success, esp_e
638
430
  call.success = success;
639
431
  call.error = error;
640
432
 
641
- this->api_connection_->send_message(call);
433
+ this->api_connection_->send_message(call, api::BluetoothDeviceUnpairingResponse::MESSAGE_TYPE);
642
434
  }
643
435
 
644
436
  void BluetoothProxy::bluetooth_scanner_set_mode(bool active) {
@@ -654,7 +446,6 @@ void BluetoothProxy::bluetooth_scanner_set_mode(bool active) {
654
446
 
655
447
  BluetoothProxy *global_bluetooth_proxy = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
656
448
 
657
- } // namespace bluetooth_proxy
658
- } // namespace esphome
449
+ } // namespace esphome::bluetooth_proxy
659
450
 
660
451
  #endif // USE_ESP32