esphome 2025.9.3__py3-none-any.whl → 2025.10.0b2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. esphome/__main__.py +94 -31
  2. esphome/address_cache.py +142 -0
  3. esphome/automation.py +130 -32
  4. esphome/build_gen/platformio.py +1 -3
  5. esphome/codegen.py +1 -0
  6. esphome/components/animation/animation.cpp +2 -2
  7. esphome/components/api/__init__.py +166 -3
  8. esphome/components/api/api_connection.cpp +84 -41
  9. esphome/components/api/api_connection.h +22 -16
  10. esphome/components/api/api_frame_helper.cpp +33 -19
  11. esphome/components/api/api_frame_helper.h +19 -4
  12. esphome/components/api/api_frame_helper_noise.cpp +41 -53
  13. esphome/components/api/api_frame_helper_noise.h +1 -1
  14. esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
  15. esphome/components/api/api_frame_helper_plaintext.h +1 -1
  16. esphome/components/api/api_pb2.cpp +189 -15
  17. esphome/components/api/api_pb2.h +132 -20
  18. esphome/components/api/api_pb2_dump.cpp +97 -9
  19. esphome/components/api/api_pb2_service.cpp +118 -160
  20. esphome/components/api/api_pb2_service.h +31 -3
  21. esphome/components/api/api_server.cpp +68 -10
  22. esphome/components/api/api_server.h +32 -4
  23. esphome/components/api/custom_api_device.h +8 -8
  24. esphome/components/api/homeassistant_service.h +123 -6
  25. esphome/components/api/proto.h +6 -2
  26. esphome/components/api/user_services.h +2 -2
  27. esphome/components/as7341/sensor.py +1 -1
  28. esphome/components/audio/__init__.py +1 -1
  29. esphome/components/audio/audio.cpp +1 -1
  30. esphome/components/audio/audio_decoder.cpp +9 -9
  31. esphome/components/bl0906/bl0906.cpp +2 -2
  32. esphome/components/bl0942/bl0942.cpp +2 -2
  33. esphome/components/ble_client/__init__.py +1 -1
  34. esphome/components/bluetooth_proxy/__init__.py +4 -30
  35. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
  36. esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
  37. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
  38. esphome/components/camera_encoder/__init__.py +2 -4
  39. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
  40. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
  41. esphome/components/canbus/canbus.cpp +7 -5
  42. esphome/components/canbus/canbus.h +7 -7
  43. esphome/components/captive_portal/__init__.py +18 -1
  44. esphome/components/captive_portal/captive_portal.cpp +40 -46
  45. esphome/components/captive_portal/captive_portal.h +20 -22
  46. esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
  47. esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
  48. esphome/components/ccs811/ccs811.cpp +1 -1
  49. esphome/components/climate/climate.cpp +10 -7
  50. esphome/components/cm1106/cm1106.cpp +1 -1
  51. esphome/components/copy/lock/copy_lock.cpp +1 -1
  52. esphome/components/cover/cover.cpp +1 -0
  53. esphome/components/daikin_arc/daikin_arc.cpp +19 -12
  54. esphome/components/dashboard_import/dashboard_import.cpp +1 -1
  55. esphome/components/dashboard_import/dashboard_import.h +1 -1
  56. esphome/components/deep_sleep/__init__.py +9 -2
  57. esphome/components/deep_sleep/deep_sleep_component.h +11 -9
  58. esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
  59. esphome/components/ektf2232/touchscreen/__init__.py +8 -5
  60. esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
  61. esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
  62. esphome/components/epaper_spi/__init__.py +1 -0
  63. esphome/components/epaper_spi/display.py +80 -0
  64. esphome/components/epaper_spi/epaper_spi.cpp +227 -0
  65. esphome/components/epaper_spi/epaper_spi.h +93 -0
  66. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
  67. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
  68. esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
  69. esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
  70. esphome/components/es7210/es7210.cpp +3 -3
  71. esphome/components/esp32/__init__.py +256 -340
  72. esphome/components/esp32/boards.py +81 -0
  73. esphome/components/esp32/preferences.cpp +23 -17
  74. esphome/components/esp32_ble/__init__.py +167 -44
  75. esphome/components/esp32_ble/ble.cpp +47 -3
  76. esphome/components/esp32_ble/ble.h +18 -0
  77. esphome/components/esp32_ble/ble_advertising.cpp +7 -3
  78. esphome/components/esp32_ble/ble_advertising.h +4 -0
  79. esphome/components/esp32_ble/ble_uuid.cpp +16 -42
  80. esphome/components/esp32_ble_beacon/__init__.py +3 -4
  81. esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +0 -4
  82. esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
  83. esphome/components/esp32_ble_server/__init__.py +28 -14
  84. esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
  85. esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
  86. esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
  87. esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
  88. esphome/components/esp32_ble_server/ble_server.cpp +59 -24
  89. esphome/components/esp32_ble_server/ble_server.h +38 -20
  90. esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
  91. esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
  92. esphome/components/esp32_ble_tracker/__init__.py +25 -80
  93. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -8
  94. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
  95. esphome/components/esp32_camera/__init__.py +1 -3
  96. esphome/components/esp32_can/esp32_can.cpp +22 -4
  97. esphome/components/esp32_can/esp32_can.h +3 -0
  98. esphome/components/esp32_hosted/__init__.py +2 -1
  99. esphome/components/esp32_improv/esp32_improv_component.cpp +135 -65
  100. esphome/components/esp32_improv/esp32_improv_component.h +7 -1
  101. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  102. esphome/components/esp8266/__init__.py +3 -3
  103. esphome/components/esphome/ota/__init__.py +21 -2
  104. esphome/components/esphome/ota/ota_esphome.cpp +456 -146
  105. esphome/components/esphome/ota/ota_esphome.h +49 -2
  106. esphome/components/ethernet/__init__.py +39 -22
  107. esphome/components/ethernet/ethernet_component.cpp +28 -5
  108. esphome/components/ethernet/ethernet_component.h +5 -1
  109. esphome/components/external_components/__init__.py +8 -6
  110. esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
  111. esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
  112. esphome/components/font/__init__.py +5 -5
  113. esphome/components/graph/graph.cpp +1 -1
  114. esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
  115. esphome/components/haier/hon_climate.cpp +2 -2
  116. esphome/components/haier/hon_climate.h +1 -1
  117. esphome/components/hdc1080/hdc1080.cpp +42 -34
  118. esphome/components/hdc1080/hdc1080.h +1 -3
  119. esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
  120. esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
  121. esphome/components/http_request/__init__.py +3 -3
  122. esphome/components/htu21d/htu21d.cpp +13 -18
  123. esphome/components/htu21d/htu21d.h +1 -1
  124. esphome/components/i2s_audio/__init__.py +1 -2
  125. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  126. esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
  127. esphome/components/improv_serial/improv_serial_component.cpp +12 -15
  128. esphome/components/improv_serial/improv_serial_component.h +6 -8
  129. esphome/components/json/json_util.cpp +42 -44
  130. esphome/components/json/json_util.h +57 -0
  131. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
  132. esphome/components/key_collector/key_collector.h +4 -4
  133. esphome/components/libretiny/__init__.py +6 -6
  134. esphome/components/libretiny/preferences.cpp +23 -16
  135. esphome/components/light/light_call.cpp +98 -120
  136. esphome/components/light/light_call.h +17 -7
  137. esphome/components/lm75b/__init__.py +0 -0
  138. esphome/components/lm75b/lm75b.cpp +39 -0
  139. esphome/components/lm75b/lm75b.h +19 -0
  140. esphome/components/lm75b/sensor.py +34 -0
  141. esphome/components/lock/lock.h +12 -6
  142. esphome/components/logger/__init__.py +15 -27
  143. esphome/components/logger/logger.cpp +10 -20
  144. esphome/components/logger/logger.h +105 -62
  145. esphome/components/logger/logger_esp32.cpp +0 -48
  146. esphome/components/logger/logger_zephyr.cpp +2 -3
  147. esphome/components/logger/select/logger_level_select.cpp +6 -7
  148. esphome/components/logger/select/logger_level_select.h +7 -0
  149. esphome/components/ltr501/ltr501.cpp +7 -6
  150. esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
  151. esphome/components/matrix_keypad/matrix_keypad.h +4 -4
  152. esphome/components/max7219digit/max7219digit.cpp +1 -1
  153. esphome/components/mcp23xxx_base/mcp23xxx_base.h +3 -3
  154. esphome/components/mcp2515/mcp2515.cpp +31 -3
  155. esphome/components/mcp2515/mcp2515_defs.h +3 -1
  156. esphome/components/md5/md5.cpp +0 -26
  157. esphome/components/md5/md5.h +10 -20
  158. esphome/components/mdns/__init__.py +93 -19
  159. esphome/components/mdns/mdns_component.cpp +57 -94
  160. esphome/components/mdns/mdns_component.h +35 -11
  161. esphome/components/mdns/mdns_esp32.cpp +7 -13
  162. esphome/components/mdns/mdns_esp8266.cpp +7 -7
  163. esphome/components/mdns/mdns_libretiny.cpp +3 -4
  164. esphome/components/mdns/mdns_rp2040.cpp +3 -4
  165. esphome/components/mipi/__init__.py +1 -5
  166. esphome/components/mipi_spi/display.py +24 -8
  167. esphome/components/mipi_spi/mipi_spi.h +3 -3
  168. esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
  169. esphome/components/mmc5603/mmc5603.cpp +3 -3
  170. esphome/components/modbus/modbus.cpp +27 -13
  171. esphome/components/modbus/modbus.h +5 -3
  172. esphome/components/modbus/modbus_definitions.h +86 -0
  173. esphome/components/modbus_controller/__init__.py +29 -1
  174. esphome/components/modbus_controller/const.py +4 -0
  175. esphome/components/modbus_controller/modbus_controller.cpp +38 -13
  176. esphome/components/modbus_controller/modbus_controller.h +18 -29
  177. esphome/components/mpr121/mpr121.cpp +41 -42
  178. esphome/components/mpr121/mpr121.h +0 -1
  179. esphome/components/nau7802/nau7802.cpp +2 -2
  180. esphome/components/network/__init__.py +7 -3
  181. esphome/components/nextion/display.py +4 -4
  182. esphome/components/nextion/nextion.cpp +8 -8
  183. esphome/components/number/__init__.py +2 -0
  184. esphome/components/number/number_call.cpp +23 -12
  185. esphome/components/number/number_call.h +5 -0
  186. esphome/components/online_image/bmp_image.cpp +2 -1
  187. esphome/components/online_image/jpeg_image.cpp +4 -2
  188. esphome/components/opentherm/opentherm.cpp +5 -5
  189. esphome/components/opentherm/opentherm.h +3 -3
  190. esphome/components/openthread/openthread.cpp +11 -10
  191. esphome/components/openthread/openthread.h +0 -1
  192. esphome/components/ota/ota_backend.h +1 -0
  193. esphome/components/packages/__init__.py +10 -8
  194. esphome/components/packet_transport/packet_transport.cpp +2 -0
  195. esphome/components/pid/pid_controller.cpp +1 -1
  196. esphome/components/prometheus/prometheus_handler.cpp +239 -239
  197. esphome/components/psram/__init__.py +30 -28
  198. esphome/components/qmc5883l/qmc5883l.cpp +15 -0
  199. esphome/components/qmc5883l/qmc5883l.h +3 -0
  200. esphome/components/qmc5883l/sensor.py +31 -12
  201. esphome/components/remote_base/gobox_protocol.cpp +3 -3
  202. esphome/components/remote_receiver/__init__.py +14 -2
  203. esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
  204. esphome/components/remote_receiver/remote_receiver.h +4 -0
  205. esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
  206. esphome/components/remote_transmitter/__init__.py +2 -2
  207. esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
  208. esphome/components/rp2040/__init__.py +11 -11
  209. esphome/components/rtttl/rtttl.cpp +2 -2
  210. esphome/components/scd30/sensor.py +1 -1
  211. esphome/components/script/__init__.py +1 -1
  212. esphome/components/script/script.h +7 -7
  213. esphome/components/select/select.cpp +5 -4
  214. esphome/components/select/select_call.cpp +1 -1
  215. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  216. esphome/components/sensor/__init__.py +2 -0
  217. esphome/components/sha256/__init__.py +22 -0
  218. esphome/components/sha256/sha256.cpp +116 -0
  219. esphome/components/sha256/sha256.h +60 -0
  220. esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
  221. esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
  222. esphome/components/spi/__init__.py +0 -3
  223. esphome/components/split_buffer/__init__.py +5 -0
  224. esphome/components/split_buffer/split_buffer.cpp +133 -0
  225. esphome/components/split_buffer/split_buffer.h +40 -0
  226. esphome/components/sps30/sps30.cpp +14 -10
  227. esphome/components/sps30/sps30.h +2 -0
  228. esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
  229. esphome/components/st7789v/st7789v.cpp +3 -2
  230. esphome/components/statsd/statsd.cpp +1 -1
  231. esphome/components/substitutions/__init__.py +3 -1
  232. esphome/components/substitutions/jinja.py +13 -3
  233. esphome/components/sx126x/__init__.py +16 -0
  234. esphome/components/sx126x/sx126x.cpp +15 -1
  235. esphome/components/sx126x/sx126x.h +9 -1
  236. esphome/components/sx126x/sx126x_reg.h +2 -0
  237. esphome/components/text_sensor/text_sensor.cpp +16 -0
  238. esphome/components/text_sensor/text_sensor.h +3 -10
  239. esphome/components/tormatic/tormatic_cover.cpp +1 -1
  240. esphome/components/tuya/select/tuya_select.cpp +1 -1
  241. esphome/components/tuya/tuya.cpp +29 -4
  242. esphome/components/uart/__init__.py +37 -27
  243. esphome/components/uart/uart.h +6 -0
  244. esphome/components/uart/uart_component.cpp +8 -0
  245. esphome/components/uart/uart_component.h +28 -0
  246. esphome/components/uart/uart_component_esp_idf.cpp +64 -10
  247. esphome/components/uart/uart_component_esp_idf.h +5 -2
  248. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  249. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
  250. esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
  251. esphome/components/usb_host/__init__.py +12 -2
  252. esphome/components/usb_host/usb_host.h +89 -14
  253. esphome/components/usb_host/usb_host_client.cpp +157 -22
  254. esphome/components/usb_host/usb_host_component.cpp +1 -1
  255. esphome/components/usb_uart/__init__.py +0 -1
  256. esphome/components/usb_uart/ch34x.cpp +4 -4
  257. esphome/components/usb_uart/cp210x.cpp +3 -3
  258. esphome/components/usb_uart/usb_uart.cpp +88 -32
  259. esphome/components/usb_uart/usb_uart.h +30 -6
  260. esphome/components/valve/valve.cpp +1 -0
  261. esphome/components/veml7700/veml7700.cpp +7 -6
  262. esphome/components/version/version_text_sensor.cpp +2 -1
  263. esphome/components/voice_assistant/voice_assistant.cpp +3 -2
  264. esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
  265. esphome/components/web_server/list_entities.cpp +3 -4
  266. esphome/components/web_server/list_entities.h +8 -10
  267. esphome/components/web_server/ota/__init__.py +1 -1
  268. esphome/components/web_server/ota/ota_web_server.cpp +9 -3
  269. esphome/components/web_server/web_server.cpp +509 -404
  270. esphome/components/web_server/web_server.h +5 -6
  271. esphome/components/web_server/web_server_v1.cpp +21 -19
  272. esphome/components/web_server_base/__init__.py +5 -2
  273. esphome/components/web_server_base/web_server_base.h +27 -7
  274. esphome/components/web_server_idf/__init__.py +1 -1
  275. esphome/components/web_server_idf/multipart.cpp +2 -2
  276. esphome/components/web_server_idf/multipart.h +2 -2
  277. esphome/components/web_server_idf/utils.cpp +2 -2
  278. esphome/components/web_server_idf/utils.h +2 -2
  279. esphome/components/web_server_idf/web_server_idf.cpp +118 -26
  280. esphome/components/web_server_idf/web_server_idf.h +12 -10
  281. esphome/components/wifi/__init__.py +13 -11
  282. esphome/components/wifi/wifi_component.cpp +74 -56
  283. esphome/components/wifi/wifi_component.h +4 -4
  284. esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
  285. esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
  286. esphome/components/wireguard/__init__.py +1 -1
  287. esphome/components/wts01/__init__.py +0 -0
  288. esphome/components/wts01/sensor.py +41 -0
  289. esphome/components/wts01/wts01.cpp +91 -0
  290. esphome/components/wts01/wts01.h +27 -0
  291. esphome/components/zephyr/__init__.py +5 -5
  292. esphome/components/zwave_proxy/__init__.py +43 -0
  293. esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
  294. esphome/components/zwave_proxy/zwave_proxy.h +93 -0
  295. esphome/config.py +79 -24
  296. esphome/config_validation.py +13 -15
  297. esphome/const.py +9 -2
  298. esphome/core/__init__.py +33 -22
  299. esphome/core/component.cpp +28 -18
  300. esphome/core/component_iterator.h +2 -1
  301. esphome/core/config.py +15 -15
  302. esphome/core/defines.h +21 -0
  303. esphome/core/entity_helpers.py +9 -6
  304. esphome/core/hash_base.h +56 -0
  305. esphome/core/helpers.cpp +19 -3
  306. esphome/core/helpers.h +26 -0
  307. esphome/core/scheduler.cpp +5 -21
  308. esphome/core/scheduler.h +19 -8
  309. esphome/core/string_ref.h +1 -1
  310. esphome/core/time.cpp +5 -5
  311. esphome/cpp_generator.py +4 -29
  312. esphome/dashboard/const.py +21 -4
  313. esphome/dashboard/core.py +10 -8
  314. esphome/dashboard/dns.py +15 -0
  315. esphome/dashboard/entries.py +15 -21
  316. esphome/dashboard/models.py +76 -0
  317. esphome/dashboard/settings.py +7 -7
  318. esphome/dashboard/status/mdns.py +46 -2
  319. esphome/dashboard/web_server.py +367 -93
  320. esphome/espota2.py +112 -32
  321. esphome/external_files.py +6 -7
  322. esphome/git.py +8 -0
  323. esphome/helpers.py +124 -77
  324. esphome/loader.py +8 -9
  325. esphome/pins.py +2 -2
  326. esphome/platformio_api.py +56 -18
  327. esphome/storage_json.py +26 -21
  328. esphome/types.py +30 -2
  329. esphome/util.py +32 -16
  330. esphome/vscode.py +8 -8
  331. esphome/wizard.py +10 -10
  332. esphome/writer.py +50 -15
  333. esphome/yaml_util.py +37 -31
  334. esphome/zeroconf.py +12 -3
  335. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/METADATA +12 -12
  336. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/RECORD +340 -320
  337. esphome/components/event_emitter/__init__.py +0 -5
  338. esphome/components/event_emitter/event_emitter.cpp +0 -14
  339. esphome/components/event_emitter/event_emitter.h +0 -63
  340. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
  341. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
  342. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
  343. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
  344. esphome/components/uart/uart_component_esp32_arduino.h +0 -60
  345. esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
  346. esphome/core/string_ref.cpp +0 -12
  347. esphome/dashboard/util/file.py +0 -63
  348. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/WHEEL +0 -0
  349. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/entry_points.txt +0 -0
  350. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/licenses/LICENSE +0 -0
  351. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/top_level.txt +0 -0
@@ -16,6 +16,7 @@
16
16
  #include "user_services.h"
17
17
  #endif
18
18
 
19
+ #include <map>
19
20
  #include <vector>
20
21
 
21
22
  namespace esphome::api {
@@ -37,13 +38,15 @@ class APIServer : public Component, public Controller {
37
38
  void on_shutdown() override;
38
39
  bool teardown() override;
39
40
  #ifdef USE_API_PASSWORD
40
- bool check_password(const std::string &password) const;
41
+ bool check_password(const uint8_t *password_data, size_t password_len) const;
41
42
  void set_password(const std::string &password);
42
43
  #endif
43
44
  void set_port(uint16_t port);
44
45
  void set_reboot_timeout(uint32_t reboot_timeout);
45
46
  void set_batch_delay(uint16_t batch_delay);
46
47
  uint16_t get_batch_delay() const { return batch_delay_; }
48
+ void set_listen_backlog(uint8_t listen_backlog) { this->listen_backlog_ = listen_backlog; }
49
+ void set_max_connections(uint8_t max_connections) { this->max_connections_ = max_connections; }
47
50
 
48
51
  // Get reference to shared buffer for API connections
49
52
  std::vector<uint8_t> &get_shared_buffer_ref() { return shared_write_buffer_; }
@@ -107,8 +110,19 @@ class APIServer : public Component, public Controller {
107
110
  void on_media_player_update(media_player::MediaPlayer *obj) override;
108
111
  #endif
109
112
  #ifdef USE_API_HOMEASSISTANT_SERVICES
110
- void send_homeassistant_service_call(const HomeassistantServiceResponse &call);
111
- #endif
113
+ void send_homeassistant_action(const HomeassistantActionRequest &call);
114
+
115
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
116
+ // Action response handling
117
+ using ActionResponseCallback = std::function<void(const class ActionResponse &)>;
118
+ void register_action_response_callback(uint32_t call_id, ActionResponseCallback callback);
119
+ void handle_action_response(uint32_t call_id, bool success, const std::string &error_message);
120
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
121
+ void handle_action_response(uint32_t call_id, bool success, const std::string &error_message,
122
+ const uint8_t *response_data, size_t response_data_len);
123
+ #endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
124
+ #endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES
125
+ #endif // USE_API_HOMEASSISTANT_SERVICES
112
126
  #ifdef USE_API_SERVICES
113
127
  void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); }
114
128
  #endif
@@ -125,6 +139,9 @@ class APIServer : public Component, public Controller {
125
139
  #ifdef USE_UPDATE
126
140
  void on_update(update::UpdateEntity *obj) override;
127
141
  #endif
142
+ #ifdef USE_ZWAVE_PROXY
143
+ void on_zwave_proxy_request(const esphome::api::ProtoMessage &msg);
144
+ #endif
128
145
 
129
146
  bool is_connected() const;
130
147
 
@@ -181,12 +198,23 @@ class APIServer : public Component, public Controller {
181
198
  #ifdef USE_API_SERVICES
182
199
  std::vector<UserServiceDescriptor *> user_services_;
183
200
  #endif
201
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
202
+ struct PendingActionResponse {
203
+ uint32_t call_id;
204
+ ActionResponseCallback callback;
205
+ };
206
+ std::vector<PendingActionResponse> action_response_callbacks_;
207
+ #endif
184
208
 
185
209
  // Group smaller types together
186
210
  uint16_t port_{6053};
187
211
  uint16_t batch_delay_{100};
212
+ // Connection limits - these defaults will be overridden by config values
213
+ // from cv.SplitDefault in __init__.py which sets platform-specific defaults
214
+ uint8_t listen_backlog_{4};
215
+ uint8_t max_connections_{8};
188
216
  bool shutting_down_ = false;
189
- // 5 bytes used, 3 bytes padding
217
+ // 7 bytes used, 1 byte padding
190
218
 
191
219
  #ifdef USE_API_NOISE
192
220
  std::shared_ptr<APINoiseContext> noise_ctx_ = std::make_shared<APINoiseContext>();
@@ -179,9 +179,9 @@ class CustomAPIDevice {
179
179
  * @param service_name The service to call.
180
180
  */
181
181
  void call_homeassistant_service(const std::string &service_name) {
182
- HomeassistantServiceResponse resp;
182
+ HomeassistantActionRequest resp;
183
183
  resp.set_service(StringRef(service_name));
184
- global_api_server->send_homeassistant_service_call(resp);
184
+ global_api_server->send_homeassistant_action(resp);
185
185
  }
186
186
 
187
187
  /** Call a Home Assistant service from ESPHome.
@@ -199,7 +199,7 @@ class CustomAPIDevice {
199
199
  * @param data The data for the service call, mapping from string to string.
200
200
  */
201
201
  void call_homeassistant_service(const std::string &service_name, const std::map<std::string, std::string> &data) {
202
- HomeassistantServiceResponse resp;
202
+ HomeassistantActionRequest resp;
203
203
  resp.set_service(StringRef(service_name));
204
204
  for (auto &it : data) {
205
205
  resp.data.emplace_back();
@@ -207,7 +207,7 @@ class CustomAPIDevice {
207
207
  kv.set_key(StringRef(it.first));
208
208
  kv.value = it.second;
209
209
  }
210
- global_api_server->send_homeassistant_service_call(resp);
210
+ global_api_server->send_homeassistant_action(resp);
211
211
  }
212
212
 
213
213
  /** Fire an ESPHome event in Home Assistant.
@@ -221,10 +221,10 @@ class CustomAPIDevice {
221
221
  * @param event_name The event to fire.
222
222
  */
223
223
  void fire_homeassistant_event(const std::string &event_name) {
224
- HomeassistantServiceResponse resp;
224
+ HomeassistantActionRequest resp;
225
225
  resp.set_service(StringRef(event_name));
226
226
  resp.is_event = true;
227
- global_api_server->send_homeassistant_service_call(resp);
227
+ global_api_server->send_homeassistant_action(resp);
228
228
  }
229
229
 
230
230
  /** Fire an ESPHome event in Home Assistant.
@@ -241,7 +241,7 @@ class CustomAPIDevice {
241
241
  * @param data The data for the event, mapping from string to string.
242
242
  */
243
243
  void fire_homeassistant_event(const std::string &service_name, const std::map<std::string, std::string> &data) {
244
- HomeassistantServiceResponse resp;
244
+ HomeassistantActionRequest resp;
245
245
  resp.set_service(StringRef(service_name));
246
246
  resp.is_event = true;
247
247
  for (auto &it : data) {
@@ -250,7 +250,7 @@ class CustomAPIDevice {
250
250
  kv.set_key(StringRef(it.first));
251
251
  kv.value = it.second;
252
252
  }
253
- global_api_server->send_homeassistant_service_call(resp);
253
+ global_api_server->send_homeassistant_action(resp);
254
254
  }
255
255
  #else
256
256
  template<typename T = void> void call_homeassistant_service(const std::string &service_name) {
@@ -3,10 +3,15 @@
3
3
  #include "api_server.h"
4
4
  #ifdef USE_API
5
5
  #ifdef USE_API_HOMEASSISTANT_SERVICES
6
+ #include <functional>
7
+ #include <utility>
8
+ #include <vector>
6
9
  #include "api_pb2.h"
10
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
11
+ #include "esphome/components/json/json_util.h"
12
+ #endif
7
13
  #include "esphome/core/automation.h"
8
14
  #include "esphome/core/helpers.h"
9
- #include <vector>
10
15
 
11
16
  namespace esphome::api {
12
17
 
@@ -44,9 +49,47 @@ template<typename... Ts> class TemplatableKeyValuePair {
44
49
  TemplatableStringValue<Ts...> value;
45
50
  };
46
51
 
52
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
53
+ // Represents the response data from a Home Assistant action
54
+ class ActionResponse {
55
+ public:
56
+ ActionResponse(bool success, std::string error_message = "")
57
+ : success_(success), error_message_(std::move(error_message)) {}
58
+
59
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
60
+ ActionResponse(bool success, std::string error_message, const uint8_t *data, size_t data_len)
61
+ : success_(success), error_message_(std::move(error_message)) {
62
+ if (data == nullptr || data_len == 0)
63
+ return;
64
+ this->json_document_ = json::parse_json(data, data_len);
65
+ }
66
+ #endif
67
+
68
+ bool is_success() const { return this->success_; }
69
+ const std::string &get_error_message() const { return this->error_message_; }
70
+
71
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
72
+ // Get data as parsed JSON object (const version returns read-only view)
73
+ JsonObjectConst get_json() const { return this->json_document_.as<JsonObjectConst>(); }
74
+ #endif
75
+
76
+ protected:
77
+ bool success_;
78
+ std::string error_message_;
79
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
80
+ JsonDocument json_document_;
81
+ #endif
82
+ };
83
+
84
+ // Callback type for action responses
85
+ template<typename... Ts> using ActionResponseCallback = std::function<void(const ActionResponse &, Ts...)>;
86
+ #endif
87
+
47
88
  template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts...> {
48
89
  public:
49
- explicit HomeAssistantServiceCallAction(APIServer *parent, bool is_event) : parent_(parent), is_event_(is_event) {}
90
+ explicit HomeAssistantServiceCallAction(APIServer *parent, bool is_event) : parent_(parent) {
91
+ this->flags_.is_event = is_event;
92
+ }
50
93
 
51
94
  template<typename T> void set_service(T service) { this->service_ = service; }
52
95
 
@@ -61,11 +104,29 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
61
104
  this->variables_.emplace_back(std::move(key), value);
62
105
  }
63
106
 
107
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
108
+ template<typename T> void set_response_template(T response_template) {
109
+ this->response_template_ = response_template;
110
+ this->flags_.has_response_template = true;
111
+ }
112
+
113
+ void set_wants_status() { this->flags_.wants_status = true; }
114
+ void set_wants_response() { this->flags_.wants_response = true; }
115
+
116
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
117
+ Trigger<JsonObjectConst, Ts...> *get_success_trigger_with_response() const {
118
+ return this->success_trigger_with_response_;
119
+ }
120
+ #endif
121
+ Trigger<Ts...> *get_success_trigger() const { return this->success_trigger_; }
122
+ Trigger<std::string, Ts...> *get_error_trigger() const { return this->error_trigger_; }
123
+ #endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES
124
+
64
125
  void play(Ts... x) override {
65
- HomeassistantServiceResponse resp;
126
+ HomeassistantActionRequest resp;
66
127
  std::string service_value = this->service_.value(x...);
67
128
  resp.set_service(StringRef(service_value));
68
- resp.is_event = this->is_event_;
129
+ resp.is_event = this->flags_.is_event;
69
130
  for (auto &it : this->data_) {
70
131
  resp.data.emplace_back();
71
132
  auto &kv = resp.data.back();
@@ -84,18 +145,74 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
84
145
  kv.set_key(StringRef(it.key));
85
146
  kv.value = it.value.value(x...);
86
147
  }
87
- this->parent_->send_homeassistant_service_call(resp);
148
+
149
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
150
+ if (this->flags_.wants_status) {
151
+ // Generate a unique call ID for this service call
152
+ static uint32_t call_id_counter = 1;
153
+ uint32_t call_id = call_id_counter++;
154
+ resp.call_id = call_id;
155
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
156
+ if (this->flags_.wants_response) {
157
+ resp.wants_response = true;
158
+ // Set response template if provided
159
+ if (this->flags_.has_response_template) {
160
+ std::string response_template_value = this->response_template_.value(x...);
161
+ resp.response_template = response_template_value;
162
+ }
163
+ }
164
+ #endif
165
+
166
+ auto captured_args = std::make_tuple(x...);
167
+ this->parent_->register_action_response_callback(call_id, [this, captured_args](const ActionResponse &response) {
168
+ std::apply(
169
+ [this, &response](auto &&...args) {
170
+ if (response.is_success()) {
171
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
172
+ if (this->flags_.wants_response) {
173
+ this->success_trigger_with_response_->trigger(response.get_json(), args...);
174
+ } else
175
+ #endif
176
+ {
177
+ this->success_trigger_->trigger(args...);
178
+ }
179
+ } else {
180
+ this->error_trigger_->trigger(response.get_error_message(), args...);
181
+ }
182
+ },
183
+ captured_args);
184
+ });
185
+ }
186
+ #endif
187
+
188
+ this->parent_->send_homeassistant_action(resp);
88
189
  }
89
190
 
90
191
  protected:
91
192
  APIServer *parent_;
92
- bool is_event_;
93
193
  TemplatableStringValue<Ts...> service_{};
94
194
  std::vector<TemplatableKeyValuePair<Ts...>> data_;
95
195
  std::vector<TemplatableKeyValuePair<Ts...>> data_template_;
96
196
  std::vector<TemplatableKeyValuePair<Ts...>> variables_;
197
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
198
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
199
+ TemplatableStringValue<Ts...> response_template_{""};
200
+ Trigger<JsonObjectConst, Ts...> *success_trigger_with_response_ = new Trigger<JsonObjectConst, Ts...>();
201
+ #endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
202
+ Trigger<Ts...> *success_trigger_ = new Trigger<Ts...>();
203
+ Trigger<std::string, Ts...> *error_trigger_ = new Trigger<std::string, Ts...>();
204
+ #endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES
205
+
206
+ struct Flags {
207
+ uint8_t is_event : 1;
208
+ uint8_t wants_status : 1;
209
+ uint8_t wants_response : 1;
210
+ uint8_t has_response_template : 1;
211
+ uint8_t reserved : 5;
212
+ } flags_{0};
97
213
  };
98
214
 
99
215
  } // namespace esphome::api
216
+
100
217
  #endif
101
218
  #endif
@@ -182,6 +182,10 @@ class ProtoLengthDelimited {
182
182
  explicit ProtoLengthDelimited(const uint8_t *value, size_t length) : value_(value), length_(length) {}
183
183
  std::string as_string() const { return std::string(reinterpret_cast<const char *>(this->value_), this->length_); }
184
184
 
185
+ // Direct access to raw data without string allocation
186
+ const uint8_t *data() const { return this->value_; }
187
+ size_t size() const { return this->length_; }
188
+
185
189
  /**
186
190
  * Decode the length-delimited data into an existing ProtoDecodableMessage instance.
187
191
  *
@@ -827,7 +831,7 @@ class ProtoService {
827
831
  }
828
832
 
829
833
  // Authentication helper methods
830
- bool check_connection_setup_() {
834
+ inline bool check_connection_setup_() {
831
835
  if (!this->is_connection_setup()) {
832
836
  this->on_no_setup_connection();
833
837
  return false;
@@ -835,7 +839,7 @@ class ProtoService {
835
839
  return true;
836
840
  }
837
841
 
838
- bool check_authenticated_() {
842
+ inline bool check_authenticated_() {
839
843
  #ifdef USE_API_PASSWORD
840
844
  if (!this->check_connection_setup_()) {
841
845
  return false;
@@ -35,7 +35,7 @@ template<typename... Ts> class UserServiceBase : public UserServiceDescriptor {
35
35
  msg.set_name(StringRef(this->name_));
36
36
  msg.key = this->key_;
37
37
  std::array<enums::ServiceArgType, sizeof...(Ts)> arg_types = {to_service_arg_type<Ts>()...};
38
- for (int i = 0; i < sizeof...(Ts); i++) {
38
+ for (size_t i = 0; i < sizeof...(Ts); i++) {
39
39
  msg.args.emplace_back();
40
40
  auto &arg = msg.args.back();
41
41
  arg.type = arg_types[i];
@@ -55,7 +55,7 @@ template<typename... Ts> class UserServiceBase : public UserServiceDescriptor {
55
55
 
56
56
  protected:
57
57
  virtual void execute(Ts... x) = 0;
58
- template<int... S> void execute_(std::vector<ExecuteServiceArgument> args, seq<S...> type) {
58
+ template<int... S> void execute_(const std::vector<ExecuteServiceArgument> &args, seq<S...> type) {
59
59
  this->execute((get_execute_arg_value<Ts>(args[S]))...);
60
60
  }
61
61
 
@@ -2,6 +2,7 @@ import esphome.codegen as cg
2
2
  from esphome.components import i2c, sensor
3
3
  import esphome.config_validation as cv
4
4
  from esphome.const import (
5
+ CONF_CLEAR,
5
6
  CONF_GAIN,
6
7
  CONF_ID,
7
8
  DEVICE_CLASS_ILLUMINANCE,
@@ -29,7 +30,6 @@ CONF_F5 = "f5"
29
30
  CONF_F6 = "f6"
30
31
  CONF_F7 = "f7"
31
32
  CONF_F8 = "f8"
32
- CONF_CLEAR = "clear"
33
33
  CONF_NIR = "nir"
34
34
 
35
35
  UNIT_COUNTS = "#"
@@ -165,4 +165,4 @@ def final_validate_audio_schema(
165
165
 
166
166
 
167
167
  async def to_code(config):
168
- cg.add_library("esphome/esp-audio-libs", "1.1.4")
168
+ cg.add_library("esphome/esp-audio-libs", "2.0.1")
@@ -57,7 +57,7 @@ const char *audio_file_type_to_string(AudioFileType file_type) {
57
57
  void scale_audio_samples(const int16_t *audio_samples, int16_t *output_buffer, int16_t scale_factor,
58
58
  size_t samples_to_scale) {
59
59
  // Note the assembly dsps_mulc function has audio glitches if the input and output buffers are the same.
60
- for (int i = 0; i < samples_to_scale; i++) {
60
+ for (size_t i = 0; i < samples_to_scale; i++) {
61
61
  int32_t acc = (int32_t) audio_samples[i] * (int32_t) scale_factor;
62
62
  output_buffer[i] = (int16_t) (acc >> 15);
63
63
  }
@@ -229,18 +229,18 @@ FileDecoderState AudioDecoder::decode_flac_() {
229
229
  auto result = this->flac_decoder_->read_header(this->input_transfer_buffer_->get_buffer_start(),
230
230
  this->input_transfer_buffer_->available());
231
231
 
232
- if (result == esp_audio_libs::flac::FLAC_DECODER_HEADER_OUT_OF_DATA) {
233
- return FileDecoderState::POTENTIALLY_FAILED;
234
- }
235
-
236
- if (result != esp_audio_libs::flac::FLAC_DECODER_SUCCESS) {
237
- // Couldn't read FLAC header
232
+ if (result > esp_audio_libs::flac::FLAC_DECODER_HEADER_OUT_OF_DATA) {
233
+ // Serrious error reading FLAC header, there is no recovery
238
234
  return FileDecoderState::FAILED;
239
235
  }
240
236
 
241
237
  size_t bytes_consumed = this->flac_decoder_->get_bytes_index();
242
238
  this->input_transfer_buffer_->decrease_buffer_length(bytes_consumed);
243
239
 
240
+ if (result == esp_audio_libs::flac::FLAC_DECODER_HEADER_OUT_OF_DATA) {
241
+ return FileDecoderState::MORE_TO_PROCESS;
242
+ }
243
+
244
244
  // Reallocate the output transfer buffer to the smallest necessary size
245
245
  this->free_buffer_required_ = flac_decoder_->get_output_buffer_size_bytes();
246
246
  if (!this->output_transfer_buffer_->reallocate(this->free_buffer_required_)) {
@@ -256,9 +256,9 @@ FileDecoderState AudioDecoder::decode_flac_() {
256
256
  }
257
257
 
258
258
  uint32_t output_samples = 0;
259
- auto result = this->flac_decoder_->decode_frame(
260
- this->input_transfer_buffer_->get_buffer_start(), this->input_transfer_buffer_->available(),
261
- reinterpret_cast<int16_t *>(this->output_transfer_buffer_->get_buffer_end()), &output_samples);
259
+ auto result = this->flac_decoder_->decode_frame(this->input_transfer_buffer_->get_buffer_start(),
260
+ this->input_transfer_buffer_->available(),
261
+ this->output_transfer_buffer_->get_buffer_end(), &output_samples);
262
262
 
263
263
  if (result == esp_audio_libs::flac::FLAC_DECODER_ERROR_OUT_OF_DATA) {
264
264
  // Not an issue, just needs more data that we'll get next time.
@@ -97,10 +97,10 @@ void BL0906::handle_actions_() {
97
97
  return;
98
98
  }
99
99
  ActionCallbackFuncPtr ptr_func = nullptr;
100
- for (int i = 0; i < this->action_queue_.size(); i++) {
100
+ for (size_t i = 0; i < this->action_queue_.size(); i++) {
101
101
  ptr_func = this->action_queue_[i];
102
102
  if (ptr_func) {
103
- ESP_LOGI(TAG, "HandleActionCallback[%d]", i);
103
+ ESP_LOGI(TAG, "HandleActionCallback[%zu]", i);
104
104
  (this->*ptr_func)();
105
105
  }
106
106
  }
@@ -51,7 +51,7 @@ void BL0942::loop() {
51
51
  if (!avail) {
52
52
  return;
53
53
  }
54
- if (avail < sizeof(buffer)) {
54
+ if (static_cast<size_t>(avail) < sizeof(buffer)) {
55
55
  if (!this->rx_start_) {
56
56
  this->rx_start_ = millis();
57
57
  } else if (millis() > this->rx_start_ + PKT_TIMEOUT_MS) {
@@ -148,7 +148,7 @@ void BL0942::setup() {
148
148
 
149
149
  this->write_reg_(BL0942_REG_USR_WRPROT, 0);
150
150
 
151
- if (this->read_reg_(BL0942_REG_MODE) != mode)
151
+ if (static_cast<uint32_t>(this->read_reg_(BL0942_REG_MODE)) != mode)
152
152
  this->status_set_warning(LOG_STR("BL0942 setup failed!"));
153
153
 
154
154
  this->flush();
@@ -116,7 +116,7 @@ CONFIG_SCHEMA = cv.All(
116
116
  )
117
117
  .extend(cv.COMPONENT_SCHEMA)
118
118
  .extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA),
119
- esp32_ble_tracker.consume_connection_slots(1, "ble_client"),
119
+ esp32_ble.consume_connection_slots(1, "ble_client"),
120
120
  )
121
121
 
122
122
  CONF_BLE_CLIENT_ID = "ble_client_id"
@@ -6,8 +6,6 @@ from esphome.components.esp32 import add_idf_sdkconfig_option
6
6
  from esphome.components.esp32_ble import BTLoggers
7
7
  import esphome.config_validation as cv
8
8
  from esphome.const import CONF_ACTIVE, CONF_ID
9
- from esphome.core import CORE
10
- from esphome.log import AnsiFore, color
11
9
 
12
10
  AUTO_LOAD = ["esp32_ble_client", "esp32_ble_tracker"]
13
11
  DEPENDENCIES = ["api", "esp32"]
@@ -44,29 +42,7 @@ def validate_connections(config):
44
42
  )
45
43
  elif config[CONF_ACTIVE]:
46
44
  connection_slots: int = config[CONF_CONNECTION_SLOTS]
47
- esp32_ble_tracker.consume_connection_slots(connection_slots, "bluetooth_proxy")(
48
- config
49
- )
50
-
51
- # Warn about connection slot waste when using Arduino framework
52
- if CORE.using_arduino and connection_slots:
53
- _LOGGER.warning(
54
- "Bluetooth Proxy with active connections on Arduino framework has suboptimal performance.\n"
55
- "If BLE connections fail, they can waste connection slots for 10 seconds because\n"
56
- "Arduino doesn't allow configuring the BLE connection timeout (fixed at 30s).\n"
57
- "ESP-IDF framework allows setting it to 20s to match client timeouts.\n"
58
- "\n"
59
- "To switch to ESP-IDF, add this to your YAML:\n"
60
- " esp32:\n"
61
- " framework:\n"
62
- " type: esp-idf\n"
63
- "\n"
64
- "For detailed migration instructions, see:\n"
65
- "%s",
66
- color(
67
- AnsiFore.BLUE, "https://esphome.io/guides/esp32_arduino_to_idf.html"
68
- ),
69
- )
45
+ esp32_ble.consume_connection_slots(connection_slots, "bluetooth_proxy")(config)
70
46
 
71
47
  return {
72
48
  **config,
@@ -81,19 +57,17 @@ CONFIG_SCHEMA = cv.All(
81
57
  {
82
58
  cv.GenerateID(): cv.declare_id(BluetoothProxy),
83
59
  cv.Optional(CONF_ACTIVE, default=True): cv.boolean,
84
- cv.SplitDefault(CONF_CACHE_SERVICES, esp32_idf=True): cv.All(
85
- cv.only_with_esp_idf, cv.boolean
86
- ),
60
+ cv.Optional(CONF_CACHE_SERVICES, default=True): cv.boolean,
87
61
  cv.Optional(
88
62
  CONF_CONNECTION_SLOTS,
89
63
  default=DEFAULT_CONNECTION_SLOTS,
90
64
  ): cv.All(
91
65
  cv.positive_int,
92
- cv.Range(min=1, max=esp32_ble_tracker.max_connections()),
66
+ cv.Range(min=1, max=esp32_ble.IDF_MAX_CONNECTIONS),
93
67
  ),
94
68
  cv.Optional(CONF_CONNECTIONS): cv.All(
95
69
  cv.ensure_list(CONNECTION_SCHEMA),
96
- cv.Length(min=1, max=esp32_ble_tracker.max_connections()),
70
+ cv.Length(min=1, max=esp32_ble.IDF_MAX_CONNECTIONS),
97
71
  ),
98
72
  }
99
73
  )
@@ -514,7 +514,8 @@ esp_err_t BluetoothConnection::read_characteristic(uint16_t handle) {
514
514
  return this->check_and_log_error_("esp_ble_gattc_read_char", err);
515
515
  }
516
516
 
517
- esp_err_t BluetoothConnection::write_characteristic(uint16_t handle, const std::string &data, bool response) {
517
+ esp_err_t BluetoothConnection::write_characteristic(uint16_t handle, const uint8_t *data, size_t length,
518
+ bool response) {
518
519
  if (!this->connected()) {
519
520
  this->log_gatt_not_connected_("write", "characteristic");
520
521
  return ESP_GATT_NOT_CONNECTED;
@@ -522,8 +523,11 @@ esp_err_t BluetoothConnection::write_characteristic(uint16_t handle, const std::
522
523
  ESP_LOGV(TAG, "[%d] [%s] Writing GATT characteristic handle %d", this->connection_index_, this->address_str_.c_str(),
523
524
  handle);
524
525
 
526
+ // ESP-IDF's API requires a non-const uint8_t* but it doesn't modify the data
527
+ // The BTC layer immediately copies the data to its own buffer (see btc_gattc.c)
528
+ // const_cast is safe here and was previously hidden by a C-style cast
525
529
  esp_err_t err =
526
- esp_ble_gattc_write_char(this->gattc_if_, this->conn_id_, handle, data.size(), (uint8_t *) data.data(),
530
+ esp_ble_gattc_write_char(this->gattc_if_, this->conn_id_, handle, length, const_cast<uint8_t *>(data),
527
531
  response ? ESP_GATT_WRITE_TYPE_RSP : ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
528
532
  return this->check_and_log_error_("esp_ble_gattc_write_char", err);
529
533
  }
@@ -540,7 +544,7 @@ esp_err_t BluetoothConnection::read_descriptor(uint16_t handle) {
540
544
  return this->check_and_log_error_("esp_ble_gattc_read_char_descr", err);
541
545
  }
542
546
 
543
- esp_err_t BluetoothConnection::write_descriptor(uint16_t handle, const std::string &data, bool response) {
547
+ esp_err_t BluetoothConnection::write_descriptor(uint16_t handle, const uint8_t *data, size_t length, bool response) {
544
548
  if (!this->connected()) {
545
549
  this->log_gatt_not_connected_("write", "descriptor");
546
550
  return ESP_GATT_NOT_CONNECTED;
@@ -548,8 +552,11 @@ esp_err_t BluetoothConnection::write_descriptor(uint16_t handle, const std::stri
548
552
  ESP_LOGV(TAG, "[%d] [%s] Writing GATT descriptor handle %d", this->connection_index_, this->address_str_.c_str(),
549
553
  handle);
550
554
 
555
+ // ESP-IDF's API requires a non-const uint8_t* but it doesn't modify the data
556
+ // The BTC layer immediately copies the data to its own buffer (see btc_gattc.c)
557
+ // const_cast is safe here and was previously hidden by a C-style cast
551
558
  esp_err_t err = esp_ble_gattc_write_char_descr(
552
- this->gattc_if_, this->conn_id_, handle, data.size(), (uint8_t *) data.data(),
559
+ this->gattc_if_, this->conn_id_, handle, length, const_cast<uint8_t *>(data),
553
560
  response ? ESP_GATT_WRITE_TYPE_RSP : ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
554
561
  return this->check_and_log_error_("esp_ble_gattc_write_char_descr", err);
555
562
  }
@@ -18,9 +18,9 @@ class BluetoothConnection final : public esp32_ble_client::BLEClientBase {
18
18
  esp32_ble_tracker::AdvertisementParserType get_advertisement_parser_type() override;
19
19
 
20
20
  esp_err_t read_characteristic(uint16_t handle);
21
- esp_err_t write_characteristic(uint16_t handle, const std::string &data, bool response);
21
+ esp_err_t write_characteristic(uint16_t handle, const uint8_t *data, size_t length, bool response);
22
22
  esp_err_t read_descriptor(uint16_t handle);
23
- esp_err_t write_descriptor(uint16_t handle, const std::string &data, bool response);
23
+ esp_err_t write_descriptor(uint16_t handle, const uint8_t *data, size_t length, bool response);
24
24
 
25
25
  esp_err_t notify_characteristic(uint16_t handle, bool enable);
26
26
 
@@ -305,7 +305,7 @@ void BluetoothProxy::bluetooth_gatt_write(const api::BluetoothGATTWriteRequest &
305
305
  return;
306
306
  }
307
307
 
308
- auto err = connection->write_characteristic(msg.handle, msg.data, msg.response);
308
+ auto err = connection->write_characteristic(msg.handle, msg.data, msg.data_len, msg.response);
309
309
  if (err != ESP_OK) {
310
310
  this->send_gatt_error(msg.address, msg.handle, err);
311
311
  }
@@ -331,7 +331,7 @@ void BluetoothProxy::bluetooth_gatt_write_descriptor(const api::BluetoothGATTWri
331
331
  return;
332
332
  }
333
333
 
334
- auto err = connection->write_descriptor(msg.handle, msg.data, true);
334
+ auto err = connection->write_descriptor(msg.handle, msg.data, msg.data_len, true);
335
335
  if (err != ESP_OK) {
336
336
  this->send_gatt_error(msg.address, msg.handle, err);
337
337
  }
@@ -2,7 +2,6 @@ import esphome.codegen as cg
2
2
  from esphome.components.esp32 import add_idf_component
3
3
  import esphome.config_validation as cv
4
4
  from esphome.const import CONF_BUFFER_SIZE, CONF_ID, CONF_TYPE
5
- from esphome.core import CORE
6
5
  from esphome.types import ConfigType
7
6
 
8
7
  CODEOWNERS = ["@DT-art1"]
@@ -51,9 +50,8 @@ async def to_code(config: ConfigType) -> None:
51
50
  buffer = cg.new_Pvariable(config[CONF_ENCODER_BUFFER_ID])
52
51
  cg.add(buffer.set_buffer_size(config[CONF_BUFFER_SIZE]))
53
52
  if config[CONF_TYPE] == ESP32_CAMERA_ENCODER:
54
- if CORE.using_esp_idf:
55
- add_idf_component(name="espressif/esp32-camera", ref="2.1.0")
56
- cg.add_build_flag("-DUSE_ESP32_CAMERA_JPEG_ENCODER")
53
+ add_idf_component(name="espressif/esp32-camera", ref="2.1.1")
54
+ cg.add_define("USE_ESP32_CAMERA_JPEG_ENCODER")
57
55
  var = cg.new_Pvariable(
58
56
  config[CONF_ID],
59
57
  config[CONF_QUALITY],
@@ -1,3 +1,5 @@
1
+ #include "esphome/core/defines.h"
2
+
1
3
  #ifdef USE_ESP32_CAMERA_JPEG_ENCODER
2
4
 
3
5
  #include "esp32_camera_jpeg_encoder.h"
@@ -15,7 +17,7 @@ camera::EncoderError ESP32CameraJPEGEncoder::encode_pixels(camera::CameraImageSp
15
17
  this->bytes_written_ = 0;
16
18
  this->out_of_output_memory_ = false;
17
19
  bool success = fmt2jpg_cb(pixels->get_data_buffer(), pixels->get_data_length(), spec->width, spec->height,
18
- to_internal_(spec->format), this->quality_, callback_, this);
20
+ to_internal_(spec->format), this->quality_, callback, this);
19
21
 
20
22
  if (!success)
21
23
  return camera::ENCODER_ERROR_CONFIGURATION;
@@ -49,7 +51,7 @@ void ESP32CameraJPEGEncoder::dump_config() {
49
51
  this->output_->get_max_size(), this->quality_, this->buffer_expand_size_);
50
52
  }
51
53
 
52
- size_t ESP32CameraJPEGEncoder::callback_(void *arg, size_t index, const void *data, size_t len) {
54
+ size_t ESP32CameraJPEGEncoder::callback(void *arg, size_t index, const void *data, size_t len) {
53
55
  ESP32CameraJPEGEncoder *that = reinterpret_cast<ESP32CameraJPEGEncoder *>(arg);
54
56
  uint8_t *buffer = that->output_->get_data();
55
57
  size_t buffer_length = that->output_->get_max_size();