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
@@ -24,7 +24,8 @@ static const char *const PROLOGUE_INIT = "NoiseAPIInit";
24
24
  #endif
25
25
  static constexpr size_t PROLOGUE_INIT_LEN = 12; // strlen("NoiseAPIInit")
26
26
 
27
- #define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
27
+ #define HELPER_LOG(msg, ...) \
28
+ ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
28
29
 
29
30
  #ifdef HELPER_LOG_PACKETS
30
31
  #define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
@@ -131,26 +132,16 @@ APIError APINoiseFrameHelper::loop() {
131
132
  return APIFrameHelper::loop();
132
133
  }
133
134
 
134
- /** Read a packet into the rx_buf_. If successful, stores frame data in the frame parameter
135
+ /** Read a packet into the rx_buf_.
135
136
  *
136
- * @param frame: The struct to hold the frame information in.
137
- * msg_start: points to the start of the payload - this pointer is only valid until the next
138
- * try_receive_raw_ call
139
- *
140
- * @return 0 if a full packet is in rx_buf_
141
- * @return -1 if error, check errno.
137
+ * @return APIError::OK if a full packet is in rx_buf_
142
138
  *
143
139
  * errno EWOULDBLOCK: Packet could not be read without blocking. Try again later.
144
140
  * errno ENOMEM: Not enough memory for reading packet.
145
141
  * errno API_ERROR_BAD_INDICATOR: Bad indicator byte at start of frame.
146
142
  * errno API_ERROR_HANDSHAKE_PACKET_LEN: Packet too big for this phase.
147
143
  */
148
- APIError APINoiseFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
149
- if (frame == nullptr) {
150
- HELPER_LOG("Bad argument for try_read_frame_");
151
- return APIError::BAD_ARG;
152
- }
153
-
144
+ APIError APINoiseFrameHelper::try_read_frame_() {
154
145
  // read header
155
146
  if (rx_header_buf_len_ < 3) {
156
147
  // no header information yet
@@ -177,16 +168,17 @@ APIError APINoiseFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
177
168
  // read body
178
169
  uint16_t msg_size = (((uint16_t) rx_header_buf_[1]) << 8) | rx_header_buf_[2];
179
170
 
180
- if (state_ != State::DATA && msg_size > 128) {
181
- // for handshake message only permit up to 128 bytes
171
+ // Check against size limits to prevent OOM: MAX_HANDSHAKE_SIZE for handshake, MAX_MESSAGE_SIZE for data
172
+ uint16_t limit = (state_ == State::DATA) ? MAX_MESSAGE_SIZE : MAX_HANDSHAKE_SIZE;
173
+ if (msg_size > limit) {
182
174
  state_ = State::FAILED;
183
- HELPER_LOG("Bad packet len for handshake: %d", msg_size);
184
- return APIError::BAD_HANDSHAKE_PACKET_LEN;
175
+ HELPER_LOG("Bad packet: message size %u exceeds maximum %u", msg_size, limit);
176
+ return (state_ == State::DATA) ? APIError::BAD_DATA_PACKET : APIError::BAD_HANDSHAKE_PACKET_LEN;
185
177
  }
186
178
 
187
- // reserve space for body
188
- if (rx_buf_.size() != msg_size) {
189
- rx_buf_.resize(msg_size);
179
+ // Reserve space for body
180
+ if (this->rx_buf_.size() != msg_size) {
181
+ this->rx_buf_.resize(msg_size);
190
182
  }
191
183
 
192
184
  if (rx_buf_len_ < msg_size) {
@@ -204,12 +196,12 @@ APIError APINoiseFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
204
196
  }
205
197
  }
206
198
 
207
- LOG_PACKET_RECEIVED(rx_buf_);
208
- *frame = std::move(rx_buf_);
209
- // consume msg
210
- rx_buf_ = {};
211
- rx_buf_len_ = 0;
212
- rx_header_buf_len_ = 0;
199
+ LOG_PACKET_RECEIVED(this->rx_buf_);
200
+
201
+ // Clear state for next frame (rx_buf_ still contains data for caller)
202
+ this->rx_buf_len_ = 0;
203
+ this->rx_header_buf_len_ = 0;
204
+
213
205
  return APIError::OK;
214
206
  }
215
207
 
@@ -231,18 +223,17 @@ APIError APINoiseFrameHelper::state_action_() {
231
223
  }
232
224
  if (state_ == State::CLIENT_HELLO) {
233
225
  // waiting for client hello
234
- std::vector<uint8_t> frame;
235
- aerr = try_read_frame_(&frame);
226
+ aerr = this->try_read_frame_();
236
227
  if (aerr != APIError::OK) {
237
228
  return handle_handshake_frame_error_(aerr);
238
229
  }
239
230
  // ignore contents, may be used in future for flags
240
231
  // Resize for: existing prologue + 2 size bytes + frame data
241
- size_t old_size = prologue_.size();
242
- prologue_.resize(old_size + 2 + frame.size());
243
- prologue_[old_size] = (uint8_t) (frame.size() >> 8);
244
- prologue_[old_size + 1] = (uint8_t) frame.size();
245
- std::memcpy(prologue_.data() + old_size + 2, frame.data(), frame.size());
232
+ size_t old_size = this->prologue_.size();
233
+ this->prologue_.resize(old_size + 2 + this->rx_buf_.size());
234
+ this->prologue_[old_size] = (uint8_t) (this->rx_buf_.size() >> 8);
235
+ this->prologue_[old_size + 1] = (uint8_t) this->rx_buf_.size();
236
+ std::memcpy(this->prologue_.data() + old_size + 2, this->rx_buf_.data(), this->rx_buf_.size());
246
237
 
247
238
  state_ = State::SERVER_HELLO;
248
239
  }
@@ -284,24 +275,23 @@ APIError APINoiseFrameHelper::state_action_() {
284
275
  int action = noise_handshakestate_get_action(handshake_);
285
276
  if (action == NOISE_ACTION_READ_MESSAGE) {
286
277
  // waiting for handshake msg
287
- std::vector<uint8_t> frame;
288
- aerr = try_read_frame_(&frame);
278
+ aerr = this->try_read_frame_();
289
279
  if (aerr != APIError::OK) {
290
280
  return handle_handshake_frame_error_(aerr);
291
281
  }
292
282
 
293
- if (frame.empty()) {
283
+ if (this->rx_buf_.empty()) {
294
284
  send_explicit_handshake_reject_(LOG_STR("Empty handshake message"));
295
285
  return APIError::BAD_HANDSHAKE_ERROR_BYTE;
296
- } else if (frame[0] != 0x00) {
297
- HELPER_LOG("Bad handshake error byte: %u", frame[0]);
286
+ } else if (this->rx_buf_[0] != 0x00) {
287
+ HELPER_LOG("Bad handshake error byte: %u", this->rx_buf_[0]);
298
288
  send_explicit_handshake_reject_(LOG_STR("Bad handshake error byte"));
299
289
  return APIError::BAD_HANDSHAKE_ERROR_BYTE;
300
290
  }
301
291
 
302
292
  NoiseBuffer mbuf;
303
293
  noise_buffer_init(mbuf);
304
- noise_buffer_set_input(mbuf, frame.data() + 1, frame.size() - 1);
294
+ noise_buffer_set_input(mbuf, this->rx_buf_.data() + 1, this->rx_buf_.size() - 1);
305
295
  err = noise_handshakestate_read_message(handshake_, &mbuf, nullptr);
306
296
  if (err != 0) {
307
297
  // Special handling for MAC failure
@@ -378,35 +368,33 @@ void APINoiseFrameHelper::send_explicit_handshake_reject_(const LogString *reaso
378
368
  state_ = orig_state;
379
369
  }
380
370
  APIError APINoiseFrameHelper::read_packet(ReadPacketBuffer *buffer) {
381
- int err;
382
- APIError aerr;
383
- aerr = state_action_();
371
+ APIError aerr = this->state_action_();
384
372
  if (aerr != APIError::OK) {
385
373
  return aerr;
386
374
  }
387
375
 
388
- if (state_ != State::DATA) {
376
+ if (this->state_ != State::DATA) {
389
377
  return APIError::WOULD_BLOCK;
390
378
  }
391
379
 
392
- std::vector<uint8_t> frame;
393
- aerr = try_read_frame_(&frame);
380
+ aerr = this->try_read_frame_();
394
381
  if (aerr != APIError::OK)
395
382
  return aerr;
396
383
 
397
384
  NoiseBuffer mbuf;
398
385
  noise_buffer_init(mbuf);
399
- noise_buffer_set_inout(mbuf, frame.data(), frame.size(), frame.size());
400
- err = noise_cipherstate_decrypt(recv_cipher_, &mbuf);
386
+ noise_buffer_set_inout(mbuf, this->rx_buf_.data(), this->rx_buf_.size(), this->rx_buf_.size());
387
+ int err = noise_cipherstate_decrypt(this->recv_cipher_, &mbuf);
401
388
  APIError decrypt_err =
402
389
  handle_noise_error_(err, LOG_STR("noise_cipherstate_decrypt"), APIError::CIPHERSTATE_DECRYPT_FAILED);
403
- if (decrypt_err != APIError::OK)
390
+ if (decrypt_err != APIError::OK) {
404
391
  return decrypt_err;
392
+ }
405
393
 
406
394
  uint16_t msg_size = mbuf.size;
407
- uint8_t *msg_data = frame.data();
395
+ uint8_t *msg_data = this->rx_buf_.data();
408
396
  if (msg_size < 4) {
409
- state_ = State::FAILED;
397
+ this->state_ = State::FAILED;
410
398
  HELPER_LOG("Bad data packet: size %d too short", msg_size);
411
399
  return APIError::BAD_DATA_PACKET;
412
400
  }
@@ -414,12 +402,12 @@ APIError APINoiseFrameHelper::read_packet(ReadPacketBuffer *buffer) {
414
402
  uint16_t type = (((uint16_t) msg_data[0]) << 8) | msg_data[1];
415
403
  uint16_t data_len = (((uint16_t) msg_data[2]) << 8) | msg_data[3];
416
404
  if (data_len > msg_size - 4) {
417
- state_ = State::FAILED;
405
+ this->state_ = State::FAILED;
418
406
  HELPER_LOG("Bad data packet: data_len %u greater than msg_size %u", data_len, msg_size);
419
407
  return APIError::BAD_DATA_PACKET;
420
408
  }
421
409
 
422
- buffer->container = std::move(frame);
410
+ buffer->container = std::move(this->rx_buf_);
423
411
  buffer->data_offset = 4;
424
412
  buffer->data_len = data_len;
425
413
  buffer->type = type;
@@ -28,7 +28,7 @@ class APINoiseFrameHelper final : public APIFrameHelper {
28
28
 
29
29
  protected:
30
30
  APIError state_action_();
31
- APIError try_read_frame_(std::vector<uint8_t> *frame);
31
+ APIError try_read_frame_();
32
32
  APIError write_frame_(const uint8_t *data, uint16_t len);
33
33
  APIError init_handshake_();
34
34
  APIError check_handshake_finished_();
@@ -18,7 +18,8 @@ namespace esphome::api {
18
18
 
19
19
  static const char *const TAG = "api.plaintext";
20
20
 
21
- #define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
21
+ #define HELPER_LOG(msg, ...) \
22
+ ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
22
23
 
23
24
  #ifdef HELPER_LOG_PACKETS
24
25
  #define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
@@ -46,21 +47,13 @@ APIError APIPlaintextFrameHelper::loop() {
46
47
  return APIFrameHelper::loop();
47
48
  }
48
49
 
49
- /** Read a packet into the rx_buf_. If successful, stores frame data in the frame parameter
50
- *
51
- * @param frame: The struct to hold the frame information in.
52
- * msg: store the parsed frame in that struct
50
+ /** Read a packet into the rx_buf_.
53
51
  *
54
52
  * @return See APIError
55
53
  *
56
54
  * error API_ERROR_BAD_INDICATOR: Bad indicator byte at start of frame.
57
55
  */
58
- APIError APIPlaintextFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
59
- if (frame == nullptr) {
60
- HELPER_LOG("Bad argument for try_read_frame_");
61
- return APIError::BAD_ARG;
62
- }
63
-
56
+ APIError APIPlaintextFrameHelper::try_read_frame_() {
64
57
  // read header
65
58
  while (!rx_header_parsed_) {
66
59
  // Now that we know when the socket is ready, we can read up to 3 bytes
@@ -122,10 +115,10 @@ APIError APIPlaintextFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
122
115
  continue;
123
116
  }
124
117
 
125
- if (msg_size_varint->as_uint32() > std::numeric_limits<uint16_t>::max()) {
118
+ if (msg_size_varint->as_uint32() > MAX_MESSAGE_SIZE) {
126
119
  state_ = State::FAILED;
127
120
  HELPER_LOG("Bad packet: message size %" PRIu32 " exceeds maximum %u", msg_size_varint->as_uint32(),
128
- std::numeric_limits<uint16_t>::max());
121
+ MAX_MESSAGE_SIZE);
129
122
  return APIError::BAD_DATA_PACKET;
130
123
  }
131
124
  rx_header_parsed_len_ = msg_size_varint->as_uint16();
@@ -149,9 +142,9 @@ APIError APIPlaintextFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
149
142
  }
150
143
  // header reading done
151
144
 
152
- // reserve space for body
153
- if (rx_buf_.size() != rx_header_parsed_len_) {
154
- rx_buf_.resize(rx_header_parsed_len_);
145
+ // Reserve space for body
146
+ if (this->rx_buf_.size() != this->rx_header_parsed_len_) {
147
+ this->rx_buf_.resize(this->rx_header_parsed_len_);
155
148
  }
156
149
 
157
150
  if (rx_buf_len_ < rx_header_parsed_len_) {
@@ -169,24 +162,22 @@ APIError APIPlaintextFrameHelper::try_read_frame_(std::vector<uint8_t> *frame) {
169
162
  }
170
163
  }
171
164
 
172
- LOG_PACKET_RECEIVED(rx_buf_);
173
- *frame = std::move(rx_buf_);
174
- // consume msg
175
- rx_buf_ = {};
176
- rx_buf_len_ = 0;
177
- rx_header_buf_pos_ = 0;
178
- rx_header_parsed_ = false;
165
+ LOG_PACKET_RECEIVED(this->rx_buf_);
166
+
167
+ // Clear state for next frame (rx_buf_ still contains data for caller)
168
+ this->rx_buf_len_ = 0;
169
+ this->rx_header_buf_pos_ = 0;
170
+ this->rx_header_parsed_ = false;
171
+
179
172
  return APIError::OK;
180
173
  }
181
- APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
182
- APIError aerr;
183
174
 
184
- if (state_ != State::DATA) {
175
+ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
176
+ if (this->state_ != State::DATA) {
185
177
  return APIError::WOULD_BLOCK;
186
178
  }
187
179
 
188
- std::vector<uint8_t> frame;
189
- aerr = try_read_frame_(&frame);
180
+ APIError aerr = this->try_read_frame_();
190
181
  if (aerr != APIError::OK) {
191
182
  if (aerr == APIError::BAD_INDICATOR) {
192
183
  // Make sure to tell the remote that we don't
@@ -219,10 +210,10 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
219
210
  return aerr;
220
211
  }
221
212
 
222
- buffer->container = std::move(frame);
213
+ buffer->container = std::move(this->rx_buf_);
223
214
  buffer->data_offset = 0;
224
- buffer->data_len = rx_header_parsed_len_;
225
- buffer->type = rx_header_parsed_type_;
215
+ buffer->data_len = this->rx_header_parsed_len_;
216
+ buffer->type = this->rx_header_parsed_type_;
226
217
  return APIError::OK;
227
218
  }
228
219
  APIError APIPlaintextFrameHelper::write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) {
@@ -24,7 +24,7 @@ class APIPlaintextFrameHelper final : public APIFrameHelper {
24
24
  APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span<const PacketInfo> packets) override;
25
25
 
26
26
  protected:
27
- APIError try_read_frame_(std::vector<uint8_t> *frame);
27
+ APIError try_read_frame_();
28
28
 
29
29
  // Group 2-byte aligned types
30
30
  uint16_t rx_header_parsed_type_ = 0;
@@ -22,9 +22,12 @@ bool HelloRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
22
22
  }
23
23
  bool HelloRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
24
24
  switch (field_id) {
25
- case 1:
26
- this->client_info = value.as_string();
25
+ case 1: {
26
+ // Use raw data directly to avoid allocation
27
+ this->client_info = value.data();
28
+ this->client_info_len = value.size();
27
29
  break;
30
+ }
28
31
  default:
29
32
  return false;
30
33
  }
@@ -42,18 +45,23 @@ void HelloResponse::calculate_size(ProtoSize &size) const {
42
45
  size.add_length(1, this->server_info_ref_.size());
43
46
  size.add_length(1, this->name_ref_.size());
44
47
  }
45
- bool ConnectRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
48
+ #ifdef USE_API_PASSWORD
49
+ bool AuthenticationRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
46
50
  switch (field_id) {
47
- case 1:
48
- this->password = value.as_string();
51
+ case 1: {
52
+ // Use raw data directly to avoid allocation
53
+ this->password = value.data();
54
+ this->password_len = value.size();
49
55
  break;
56
+ }
50
57
  default:
51
58
  return false;
52
59
  }
53
60
  return true;
54
61
  }
55
- void ConnectResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->invalid_password); }
56
- void ConnectResponse::calculate_size(ProtoSize &size) const { size.add_bool(1, this->invalid_password); }
62
+ void AuthenticationResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->invalid_password); }
63
+ void AuthenticationResponse::calculate_size(ProtoSize &size) const { size.add_bool(1, this->invalid_password); }
64
+ #endif
57
65
  #ifdef USE_AREAS
58
66
  void AreaInfo::encode(ProtoWriteBuffer buffer) const {
59
67
  buffer.encode_uint32(1, this->area_id);
@@ -127,6 +135,12 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const {
127
135
  #ifdef USE_AREAS
128
136
  buffer.encode_message(22, this->area);
129
137
  #endif
138
+ #ifdef USE_ZWAVE_PROXY
139
+ buffer.encode_uint32(23, this->zwave_proxy_feature_flags);
140
+ #endif
141
+ #ifdef USE_ZWAVE_PROXY
142
+ buffer.encode_uint32(24, this->zwave_home_id);
143
+ #endif
130
144
  }
131
145
  void DeviceInfoResponse::calculate_size(ProtoSize &size) const {
132
146
  #ifdef USE_API_PASSWORD
@@ -179,6 +193,12 @@ void DeviceInfoResponse::calculate_size(ProtoSize &size) const {
179
193
  #ifdef USE_AREAS
180
194
  size.add_message_object(2, this->area);
181
195
  #endif
196
+ #ifdef USE_ZWAVE_PROXY
197
+ size.add_uint32(2, this->zwave_proxy_feature_flags);
198
+ #endif
199
+ #ifdef USE_ZWAVE_PROXY
200
+ size.add_uint32(2, this->zwave_home_id);
201
+ #endif
182
202
  }
183
203
  #ifdef USE_BINARY_SENSOR
184
204
  void ListEntitiesBinarySensorResponse::encode(ProtoWriteBuffer buffer) const {
@@ -852,7 +872,7 @@ void HomeassistantServiceMap::calculate_size(ProtoSize &size) const {
852
872
  size.add_length(1, this->key_ref_.size());
853
873
  size.add_length(1, this->value.size());
854
874
  }
855
- void HomeassistantServiceResponse::encode(ProtoWriteBuffer buffer) const {
875
+ void HomeassistantActionRequest::encode(ProtoWriteBuffer buffer) const {
856
876
  buffer.encode_string(1, this->service_ref_);
857
877
  for (auto &it : this->data) {
858
878
  buffer.encode_message(2, it, true);
@@ -864,13 +884,64 @@ void HomeassistantServiceResponse::encode(ProtoWriteBuffer buffer) const {
864
884
  buffer.encode_message(4, it, true);
865
885
  }
866
886
  buffer.encode_bool(5, this->is_event);
887
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
888
+ buffer.encode_uint32(6, this->call_id);
889
+ #endif
890
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
891
+ buffer.encode_bool(7, this->wants_response);
892
+ #endif
893
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
894
+ buffer.encode_string(8, this->response_template);
895
+ #endif
867
896
  }
868
- void HomeassistantServiceResponse::calculate_size(ProtoSize &size) const {
897
+ void HomeassistantActionRequest::calculate_size(ProtoSize &size) const {
869
898
  size.add_length(1, this->service_ref_.size());
870
899
  size.add_repeated_message(1, this->data);
871
900
  size.add_repeated_message(1, this->data_template);
872
901
  size.add_repeated_message(1, this->variables);
873
902
  size.add_bool(1, this->is_event);
903
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
904
+ size.add_uint32(1, this->call_id);
905
+ #endif
906
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
907
+ size.add_bool(1, this->wants_response);
908
+ #endif
909
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
910
+ size.add_length(1, this->response_template.size());
911
+ #endif
912
+ }
913
+ #endif
914
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
915
+ bool HomeassistantActionResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
916
+ switch (field_id) {
917
+ case 1:
918
+ this->call_id = value.as_uint32();
919
+ break;
920
+ case 2:
921
+ this->success = value.as_bool();
922
+ break;
923
+ default:
924
+ return false;
925
+ }
926
+ return true;
927
+ }
928
+ bool HomeassistantActionResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
929
+ switch (field_id) {
930
+ case 3:
931
+ this->error_message = value.as_string();
932
+ break;
933
+ #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
934
+ case 4: {
935
+ // Use raw data directly to avoid allocation
936
+ this->response_data = value.data();
937
+ this->response_data_len = value.size();
938
+ break;
939
+ }
940
+ #endif
941
+ default:
942
+ return false;
943
+ }
944
+ return true;
874
945
  }
875
946
  #endif
876
947
  #ifdef USE_API_HOMEASSISTANT_STATES
@@ -903,9 +974,12 @@ bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDel
903
974
  #endif
904
975
  bool GetTimeResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
905
976
  switch (field_id) {
906
- case 2:
907
- this->timezone = value.as_string();
977
+ case 2: {
978
+ // Use raw data directly to avoid allocation
979
+ this->timezone = value.data();
980
+ this->timezone_len = value.size();
908
981
  break;
982
+ }
909
983
  default:
910
984
  return false;
911
985
  }
@@ -2014,9 +2088,12 @@ bool BluetoothGATTWriteRequest::decode_varint(uint32_t field_id, ProtoVarInt val
2014
2088
  }
2015
2089
  bool BluetoothGATTWriteRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
2016
2090
  switch (field_id) {
2017
- case 4:
2018
- this->data = value.as_string();
2091
+ case 4: {
2092
+ // Use raw data directly to avoid allocation
2093
+ this->data = value.data();
2094
+ this->data_len = value.size();
2019
2095
  break;
2096
+ }
2020
2097
  default:
2021
2098
  return false;
2022
2099
  }
@@ -2050,9 +2127,12 @@ bool BluetoothGATTWriteDescriptorRequest::decode_varint(uint32_t field_id, Proto
2050
2127
  }
2051
2128
  bool BluetoothGATTWriteDescriptorRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
2052
2129
  switch (field_id) {
2053
- case 3:
2054
- this->data = value.as_string();
2130
+ case 3: {
2131
+ // Use raw data directly to avoid allocation
2132
+ this->data = value.data();
2133
+ this->data_len = value.size();
2055
2134
  break;
2135
+ }
2056
2136
  default:
2057
2137
  return false;
2058
2138
  }
@@ -2368,6 +2448,52 @@ void VoiceAssistantWakeWord::calculate_size(ProtoSize &size) const {
2368
2448
  }
2369
2449
  }
2370
2450
  }
2451
+ bool VoiceAssistantExternalWakeWord::decode_varint(uint32_t field_id, ProtoVarInt value) {
2452
+ switch (field_id) {
2453
+ case 5:
2454
+ this->model_size = value.as_uint32();
2455
+ break;
2456
+ default:
2457
+ return false;
2458
+ }
2459
+ return true;
2460
+ }
2461
+ bool VoiceAssistantExternalWakeWord::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
2462
+ switch (field_id) {
2463
+ case 1:
2464
+ this->id = value.as_string();
2465
+ break;
2466
+ case 2:
2467
+ this->wake_word = value.as_string();
2468
+ break;
2469
+ case 3:
2470
+ this->trained_languages.push_back(value.as_string());
2471
+ break;
2472
+ case 4:
2473
+ this->model_type = value.as_string();
2474
+ break;
2475
+ case 6:
2476
+ this->model_hash = value.as_string();
2477
+ break;
2478
+ case 7:
2479
+ this->url = value.as_string();
2480
+ break;
2481
+ default:
2482
+ return false;
2483
+ }
2484
+ return true;
2485
+ }
2486
+ bool VoiceAssistantConfigurationRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
2487
+ switch (field_id) {
2488
+ case 1:
2489
+ this->external_wake_words.emplace_back();
2490
+ value.decode_to_message(this->external_wake_words.back());
2491
+ break;
2492
+ default:
2493
+ return false;
2494
+ }
2495
+ return true;
2496
+ }
2371
2497
  void VoiceAssistantConfigurationResponse::encode(ProtoWriteBuffer buffer) const {
2372
2498
  for (auto &it : this->available_wake_words) {
2373
2499
  buffer.encode_message(1, it, true);
@@ -3011,5 +3137,53 @@ bool UpdateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
3011
3137
  return true;
3012
3138
  }
3013
3139
  #endif
3140
+ #ifdef USE_ZWAVE_PROXY
3141
+ bool ZWaveProxyFrame::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
3142
+ switch (field_id) {
3143
+ case 1: {
3144
+ // Use raw data directly to avoid allocation
3145
+ this->data = value.data();
3146
+ this->data_len = value.size();
3147
+ break;
3148
+ }
3149
+ default:
3150
+ return false;
3151
+ }
3152
+ return true;
3153
+ }
3154
+ void ZWaveProxyFrame::encode(ProtoWriteBuffer buffer) const { buffer.encode_bytes(1, this->data, this->data_len); }
3155
+ void ZWaveProxyFrame::calculate_size(ProtoSize &size) const { size.add_length(1, this->data_len); }
3156
+ bool ZWaveProxyRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
3157
+ switch (field_id) {
3158
+ case 1:
3159
+ this->type = static_cast<enums::ZWaveProxyRequestType>(value.as_uint32());
3160
+ break;
3161
+ default:
3162
+ return false;
3163
+ }
3164
+ return true;
3165
+ }
3166
+ bool ZWaveProxyRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
3167
+ switch (field_id) {
3168
+ case 2: {
3169
+ // Use raw data directly to avoid allocation
3170
+ this->data = value.data();
3171
+ this->data_len = value.size();
3172
+ break;
3173
+ }
3174
+ default:
3175
+ return false;
3176
+ }
3177
+ return true;
3178
+ }
3179
+ void ZWaveProxyRequest::encode(ProtoWriteBuffer buffer) const {
3180
+ buffer.encode_uint32(1, static_cast<uint32_t>(this->type));
3181
+ buffer.encode_bytes(2, this->data, this->data_len);
3182
+ }
3183
+ void ZWaveProxyRequest::calculate_size(ProtoSize &size) const {
3184
+ size.add_uint32(1, static_cast<uint32_t>(this->type));
3185
+ size.add_length(2, this->data_len);
3186
+ }
3187
+ #endif
3014
3188
 
3015
3189
  } // namespace esphome::api