esphome 2025.4.1__py3-none-any.whl → 2025.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. esphome/__main__.py +16 -14
  2. esphome/components/ac_dimmer/ac_dimmer.cpp +3 -2
  3. esphome/components/adc/__init__.py +51 -34
  4. esphome/components/airthings_wave_base/__init__.py +1 -1
  5. esphome/components/alarm_control_panel/__init__.py +37 -2
  6. esphome/components/am43/cover/__init__.py +4 -5
  7. esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
  8. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
  9. esphome/components/analog_threshold/binary_sensor.py +10 -8
  10. esphome/components/anova/climate.py +4 -5
  11. esphome/components/api/__init__.py +25 -8
  12. esphome/components/api/api_connection.cpp +416 -662
  13. esphome/components/api/api_connection.h +256 -57
  14. esphome/components/api/api_frame_helper.cpp +232 -177
  15. esphome/components/api/api_frame_helper.h +61 -8
  16. esphome/components/api/api_noise_context.h +13 -4
  17. esphome/components/api/api_pb2.cpp +1422 -1
  18. esphome/components/api/api_pb2.h +255 -1
  19. esphome/components/api/api_pb2_service.cpp +162 -49
  20. esphome/components/api/api_pb2_service.h +90 -51
  21. esphome/components/api/api_pb2_size.h +361 -0
  22. esphome/components/api/api_server.cpp +110 -34
  23. esphome/components/api/api_server.h +8 -0
  24. esphome/components/api/proto.h +86 -17
  25. esphome/components/as3935_i2c/as3935_i2c.h +0 -3
  26. esphome/components/as7341/as7341.h +1 -1
  27. esphome/components/at581x/at581x.h +4 -4
  28. esphome/components/atm90e32/__init__.py +1 -0
  29. esphome/components/atm90e32/atm90e32.cpp +576 -199
  30. esphome/components/atm90e32/atm90e32.h +128 -31
  31. esphome/components/atm90e32/atm90e32_reg.h +4 -2
  32. esphome/components/atm90e32/button/__init__.py +62 -10
  33. esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
  34. esphome/components/atm90e32/button/atm90e32_button.h +36 -4
  35. esphome/components/atm90e32/number/__init__.py +130 -0
  36. esphome/components/atm90e32/number/atm90e32_number.h +16 -0
  37. esphome/components/atm90e32/sensor.py +21 -4
  38. esphome/components/atm90e32/text_sensor/__init__.py +48 -0
  39. esphome/components/audio/__init__.py +96 -49
  40. esphome/components/audio/audio.h +48 -0
  41. esphome/components/audio/audio_decoder.cpp +1 -1
  42. esphome/components/audio/audio_resampler.cpp +2 -0
  43. esphome/components/audio/audio_resampler.h +1 -0
  44. esphome/components/ballu/climate.py +2 -9
  45. esphome/components/bang_bang/climate.py +5 -6
  46. esphome/components/bedjet/bedjet_hub.cpp +1 -0
  47. esphome/components/bedjet/climate/__init__.py +3 -8
  48. esphome/components/bedjet/fan/__init__.py +2 -11
  49. esphome/components/binary/fan/__init__.py +13 -16
  50. esphome/components/binary_sensor/__init__.py +13 -10
  51. esphome/components/bl0906/constants.h +16 -16
  52. esphome/components/ble_client/text_sensor/__init__.py +3 -5
  53. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
  54. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +136 -21
  55. esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
  56. esphome/components/button/__init__.py +11 -8
  57. esphome/components/canbus/canbus.cpp +3 -0
  58. esphome/components/canbus/canbus.h +16 -0
  59. esphome/components/ccs811/sensor.py +9 -6
  60. esphome/components/climate/__init__.py +35 -2
  61. esphome/components/climate/climate_mode.h +1 -1
  62. esphome/components/climate/climate_traits.h +63 -57
  63. esphome/components/climate_ir/__init__.py +57 -17
  64. esphome/components/climate_ir_lg/climate.py +2 -5
  65. esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
  66. esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
  67. esphome/components/color/__init__.py +2 -0
  68. esphome/components/const/__init__.py +5 -0
  69. esphome/components/coolix/climate.py +2 -9
  70. esphome/components/copy/cover/__init__.py +10 -9
  71. esphome/components/copy/fan/__init__.py +11 -9
  72. esphome/components/copy/lock/__init__.py +11 -9
  73. esphome/components/copy/text/__init__.py +9 -6
  74. esphome/components/cover/__init__.py +37 -2
  75. esphome/components/cse7766/cse7766.cpp +2 -1
  76. esphome/components/cst226/binary_sensor/__init__.py +28 -0
  77. esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
  78. esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
  79. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
  80. esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
  81. esphome/components/current_based/cover.py +37 -36
  82. esphome/components/current_based/current_based_cover.cpp +2 -1
  83. esphome/components/daikin/climate.py +2 -9
  84. esphome/components/daikin/daikin.cpp +15 -9
  85. esphome/components/daikin/daikin.h +5 -5
  86. esphome/components/daikin_arc/climate.py +2 -7
  87. esphome/components/daikin_brc/climate.py +3 -5
  88. esphome/components/dallas_temp/dallas_temp.cpp +17 -24
  89. esphome/components/dallas_temp/dallas_temp.h +0 -1
  90. esphome/components/daly_bms/daly_bms.cpp +2 -1
  91. esphome/components/debug/debug_component.cpp +6 -1
  92. esphome/components/debug/debug_component.h +8 -0
  93. esphome/components/debug/debug_esp32.cpp +109 -254
  94. esphome/components/debug/sensor.py +14 -0
  95. esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
  96. esphome/components/delonghi/climate.py +2 -9
  97. esphome/components/demo/__init__.py +18 -20
  98. esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
  99. esphome/components/display/rect.cpp +4 -9
  100. esphome/components/display/rect.h +1 -1
  101. esphome/components/dps310/sensor.py +6 -6
  102. esphome/components/ee895/sensor.py +9 -9
  103. esphome/components/emmeti/climate.py +2 -9
  104. esphome/components/endstop/cover.py +17 -16
  105. esphome/components/endstop/endstop_cover.cpp +2 -1
  106. esphome/components/ens160_base/__init__.py +12 -9
  107. esphome/components/esp32/__init__.py +60 -3
  108. esphome/components/esp32/core.cpp +11 -5
  109. esphome/components/esp32/gpio.cpp +86 -24
  110. esphome/components/esp32/gpio.py +15 -16
  111. esphome/components/esp32/gpio_esp32.py +1 -2
  112. esphome/components/esp32/gpio_esp32_c2.py +1 -1
  113. esphome/components/esp32/gpio_esp32_c3.py +1 -1
  114. esphome/components/esp32/gpio_esp32_c6.py +1 -1
  115. esphome/components/esp32/gpio_esp32_h2.py +1 -1
  116. esphome/components/esp32_ble/ble.cpp +1 -8
  117. esphome/components/esp32_ble/ble.h +5 -3
  118. esphome/components/esp32_ble/ble_advertising.cpp +2 -1
  119. esphome/components/esp32_ble/ble_advertising.h +1 -0
  120. esphome/components/esp32_ble_server/__init__.py +3 -0
  121. esphome/components/esp32_ble_tracker/__init__.py +7 -1
  122. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
  123. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
  124. esphome/components/esp32_camera/__init__.py +1 -1
  125. esphome/components/esp32_camera/esp32_camera.cpp +2 -10
  126. esphome/components/esp32_camera/esp32_camera.h +1 -1
  127. esphome/components/esp32_can/esp32_can.cpp +1 -1
  128. esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
  129. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  130. esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
  131. esphome/components/esp32_rmt_led_strip/light.py +9 -1
  132. esphome/components/esp32_touch/esp32_touch.cpp +1 -1
  133. esphome/components/esp8266/gpio.cpp +69 -8
  134. esphome/components/ethernet/ethernet_component.cpp +1 -1
  135. esphome/components/event/__init__.py +13 -10
  136. esphome/components/factory_reset/switch/__init__.py +7 -21
  137. esphome/components/fan/__init__.py +52 -5
  138. esphome/components/fastled_base/__init__.py +1 -4
  139. esphome/components/fastled_base/fastled_light.cpp +1 -1
  140. esphome/components/feedback/cover.py +38 -33
  141. esphome/components/feedback/feedback_cover.cpp +2 -1
  142. esphome/components/fujitsu_general/climate.py +2 -9
  143. esphome/components/gcja5/gcja5.cpp +2 -1
  144. esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
  145. esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
  146. esphome/components/gpio_expander/cached_gpio.h +22 -7
  147. esphome/components/gps/__init__.py +47 -17
  148. esphome/components/gps/gps.cpp +42 -23
  149. esphome/components/gps/gps.h +17 -13
  150. esphome/components/graph/__init__.py +1 -2
  151. esphome/components/gree/climate.py +4 -6
  152. esphome/components/gree/gree.cpp +16 -2
  153. esphome/components/gree/gree.h +2 -2
  154. esphome/components/growatt_solar/growatt_solar.cpp +2 -1
  155. esphome/components/haier/climate.py +37 -34
  156. esphome/components/hbridge/fan/__init__.py +19 -17
  157. esphome/components/he60r/cover.py +4 -5
  158. esphome/components/heatpumpir/climate.py +3 -6
  159. esphome/components/hitachi_ac344/climate.py +2 -9
  160. esphome/components/hitachi_ac424/climate.py +2 -9
  161. esphome/components/hlw8012/hlw8012.cpp +1 -1
  162. esphome/components/hm3301/hm3301.h +1 -1
  163. esphome/components/hte501/sensor.py +6 -6
  164. esphome/components/http_request/__init__.py +39 -6
  165. esphome/components/http_request/http_request.cpp +20 -0
  166. esphome/components/http_request/http_request.h +57 -15
  167. esphome/components/http_request/http_request_arduino.cpp +22 -6
  168. esphome/components/http_request/http_request_arduino.h +4 -3
  169. esphome/components/http_request/http_request_host.cpp +141 -0
  170. esphome/components/http_request/http_request_host.h +37 -0
  171. esphome/components/http_request/http_request_idf.cpp +35 -3
  172. esphome/components/http_request/http_request_idf.h +10 -3
  173. esphome/components/http_request/httplib.h +9691 -0
  174. esphome/components/http_request/update/__init__.py +11 -8
  175. esphome/components/hyt271/sensor.py +6 -6
  176. esphome/components/i2c/i2c.h +4 -0
  177. esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
  178. esphome/components/i2s_audio/__init__.py +131 -22
  179. esphome/components/i2s_audio/i2s_audio.h +44 -4
  180. esphome/components/i2s_audio/media_player/__init__.py +19 -9
  181. esphome/components/i2s_audio/microphone/__init__.py +63 -5
  182. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
  183. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
  184. esphome/components/i2s_audio/speaker/__init__.py +31 -5
  185. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
  186. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
  187. esphome/components/ili9xxx/ili9xxx_init.h +1 -1
  188. esphome/components/image/__init__.py +37 -17
  189. esphome/components/image/image.cpp +25 -8
  190. esphome/components/internal_temperature/internal_temperature.cpp +6 -4
  191. esphome/components/key_collector/__init__.py +35 -0
  192. esphome/components/key_collector/key_collector.cpp +8 -0
  193. esphome/components/key_collector/key_collector.h +10 -0
  194. esphome/components/kuntze/kuntze.cpp +2 -1
  195. esphome/components/ld2410/ld2410.h +1 -1
  196. esphome/components/ld2450/ld2450.h +1 -1
  197. esphome/components/light/__init__.py +57 -0
  198. esphome/components/lock/__init__.py +51 -4
  199. esphome/components/lock/automation.h +2 -13
  200. esphome/components/logger/__init__.py +22 -0
  201. esphome/components/logger/logger.cpp +154 -103
  202. esphome/components/logger/logger.h +211 -36
  203. esphome/components/logger/task_log_buffer.cpp +138 -0
  204. esphome/components/logger/task_log_buffer.h +69 -0
  205. esphome/components/lvgl/__init__.py +13 -5
  206. esphome/components/lvgl/automation.py +50 -1
  207. esphome/components/lvgl/defines.py +0 -1
  208. esphome/components/lvgl/lv_validation.py +10 -1
  209. esphome/components/lvgl/lvgl_esphome.cpp +5 -1
  210. esphome/components/lvgl/schemas.py +14 -14
  211. esphome/components/lvgl/text/__init__.py +1 -2
  212. esphome/components/lvgl/widgets/arc.py +7 -6
  213. esphome/components/lvgl/widgets/buttonmatrix.py +3 -3
  214. esphome/components/lvgl/widgets/checkbox.py +2 -2
  215. esphome/components/lvgl/widgets/dropdown.py +2 -1
  216. esphome/components/lvgl/widgets/img.py +15 -12
  217. esphome/components/mapping/__init__.py +134 -0
  218. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
  219. esphome/components/max7219digit/max7219digit.cpp +28 -27
  220. esphome/components/mdns/__init__.py +11 -5
  221. esphome/components/mdns/mdns_component.cpp +11 -5
  222. esphome/components/mdns/mdns_component.h +3 -2
  223. esphome/components/mdns/mdns_esp32.cpp +4 -3
  224. esphome/components/mdns/mdns_esp8266.cpp +4 -2
  225. esphome/components/mdns/mdns_libretiny.cpp +4 -2
  226. esphome/components/mdns/mdns_rp2040.cpp +4 -2
  227. esphome/components/media_player/__init__.py +40 -6
  228. esphome/components/mhz19/sensor.py +11 -7
  229. esphome/components/micro_wake_word/__init__.py +99 -31
  230. esphome/components/micro_wake_word/automation.h +54 -0
  231. esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
  232. esphome/components/micro_wake_word/micro_wake_word.h +58 -105
  233. esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
  234. esphome/components/micro_wake_word/streaming_model.cpp +158 -41
  235. esphome/components/micro_wake_word/streaming_model.h +85 -13
  236. esphome/components/microphone/__init__.py +139 -9
  237. esphome/components/microphone/automation.h +14 -2
  238. esphome/components/microphone/microphone.cpp +21 -0
  239. esphome/components/microphone/microphone.h +14 -5
  240. esphome/components/microphone/microphone_source.cpp +95 -0
  241. esphome/components/microphone/microphone_source.h +80 -0
  242. esphome/components/mics_4514/sensor.py +25 -14
  243. esphome/components/midea/climate.py +3 -4
  244. esphome/components/midea_ir/climate.py +3 -5
  245. esphome/components/mipi_spi/__init__.py +15 -0
  246. esphome/components/mipi_spi/display.py +474 -0
  247. esphome/components/mipi_spi/mipi_spi.cpp +481 -0
  248. esphome/components/mipi_spi/mipi_spi.h +171 -0
  249. esphome/components/mipi_spi/models/__init__.py +65 -0
  250. esphome/components/mipi_spi/models/amoled.py +72 -0
  251. esphome/components/mipi_spi/models/commands.py +82 -0
  252. esphome/components/mipi_spi/models/cyd.py +10 -0
  253. esphome/components/mipi_spi/models/ili.py +749 -0
  254. esphome/components/mipi_spi/models/jc.py +260 -0
  255. esphome/components/mipi_spi/models/lanbon.py +15 -0
  256. esphome/components/mipi_spi/models/lilygo.py +60 -0
  257. esphome/components/mipi_spi/models/waveshare.py +139 -0
  258. esphome/components/mitsubishi/climate.py +2 -5
  259. esphome/components/mitsubishi/mitsubishi.cpp +9 -9
  260. esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
  261. esphome/components/mixer/speaker/mixer_speaker.h +1 -3
  262. esphome/components/mlx90393/sensor.py +5 -0
  263. esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
  264. esphome/components/mlx90393/sensor_mlx90393.h +21 -4
  265. esphome/components/modbus/modbus.cpp +2 -1
  266. esphome/components/mqtt/__init__.py +1 -1
  267. esphome/components/mqtt/mqtt_client.cpp +6 -2
  268. esphome/components/mqtt/mqtt_const.h +4 -0
  269. esphome/components/mqtt/mqtt_fan.cpp +39 -0
  270. esphome/components/mqtt/mqtt_fan.h +2 -0
  271. esphome/components/ms5611/sensor.py +6 -6
  272. esphome/components/ms8607/sensor.py +3 -3
  273. esphome/components/network/__init__.py +1 -1
  274. esphome/components/nextion/base_component.py +17 -16
  275. esphome/components/nextion/display.py +11 -2
  276. esphome/components/nextion/nextion.cpp +39 -1
  277. esphome/components/nextion/nextion.h +50 -0
  278. esphome/components/noblex/climate.py +2 -9
  279. esphome/components/number/__init__.py +12 -9
  280. esphome/components/one_wire/one_wire_bus.cpp +14 -10
  281. esphome/components/one_wire/one_wire_bus.h +14 -8
  282. esphome/components/online_image/bmp_image.cpp +48 -11
  283. esphome/components/online_image/bmp_image.h +2 -0
  284. esphome/components/opentherm/binary_sensor/__init__.py +2 -4
  285. esphome/components/opentherm/number/__init__.py +11 -20
  286. esphome/components/opentherm/sensor/__init__.py +3 -3
  287. esphome/components/opentherm/switch/__init__.py +3 -5
  288. esphome/components/output/lock/__init__.py +11 -9
  289. esphome/components/packages/__init__.py +33 -31
  290. esphome/components/packet_transport/__init__.py +201 -0
  291. esphome/components/packet_transport/binary_sensor.py +19 -0
  292. esphome/components/packet_transport/packet_transport.cpp +534 -0
  293. esphome/components/packet_transport/packet_transport.h +154 -0
  294. esphome/components/packet_transport/sensor.py +19 -0
  295. esphome/components/pca9685/pca9685_output.cpp +2 -1
  296. esphome/components/pid/climate.py +2 -4
  297. esphome/components/pm2005/__init__.py +1 -0
  298. esphome/components/pm2005/pm2005.cpp +123 -0
  299. esphome/components/pm2005/pm2005.h +46 -0
  300. esphome/components/pm2005/sensor.py +86 -0
  301. esphome/components/pmsa003i/pmsa003i.cpp +43 -16
  302. esphome/components/pmsa003i/pmsa003i.h +25 -25
  303. esphome/components/pmsx003/pmsx003.cpp +195 -230
  304. esphome/components/pmsx003/pmsx003.h +51 -33
  305. esphome/components/pmsx003/sensor.py +21 -11
  306. esphome/components/pn7150/pn7150.h +2 -2
  307. esphome/components/pn7160/pn7160.h +2 -2
  308. esphome/components/prometheus/prometheus_handler.cpp +174 -0
  309. esphome/components/prometheus/prometheus_handler.h +17 -0
  310. esphome/components/psram/__init__.py +7 -5
  311. esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
  312. esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
  313. esphome/components/pzem004t/pzem004t.cpp +2 -1
  314. esphome/components/qspi_dbi/__init__.py +0 -1
  315. esphome/components/qspi_dbi/display.py +2 -1
  316. esphome/components/qspi_dbi/models.py +1 -2
  317. esphome/components/remote_base/__init__.py +91 -0
  318. esphome/components/remote_base/beo4_protocol.cpp +153 -0
  319. esphome/components/remote_base/beo4_protocol.h +43 -0
  320. esphome/components/remote_base/gobox_protocol.cpp +131 -0
  321. esphome/components/remote_base/gobox_protocol.h +54 -0
  322. esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
  323. esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
  324. esphome/components/resampler/speaker/resampler_speaker.h +1 -1
  325. esphome/components/rf_bridge/rf_bridge.cpp +2 -1
  326. esphome/components/scd30/sensor.py +2 -3
  327. esphome/components/scd4x/sensor.py +4 -5
  328. esphome/components/sdp3x/sensor.py +2 -1
  329. esphome/components/sds011/sds011.cpp +2 -1
  330. esphome/components/select/__init__.py +19 -20
  331. esphome/components/sen5x/sen5x.cpp +55 -36
  332. esphome/components/sen5x/sensor.py +1 -1
  333. esphome/components/senseair/sensor.py +3 -3
  334. esphome/components/sensor/__init__.py +158 -14
  335. esphome/components/sensor/filter.cpp +23 -0
  336. esphome/components/sensor/filter.h +22 -0
  337. esphome/components/sgp30/sensor.py +14 -16
  338. esphome/components/sgp4x/sensor.py +1 -1
  339. esphome/components/sht4x/sht4x.cpp +43 -22
  340. esphome/components/sht4x/sht4x.h +1 -1
  341. esphome/components/shtcx/sensor.py +6 -6
  342. esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
  343. esphome/components/sml/text_sensor/__init__.py +4 -6
  344. esphome/components/sound_level/__init__.py +0 -0
  345. esphome/components/sound_level/sensor.py +97 -0
  346. esphome/components/sound_level/sound_level.cpp +194 -0
  347. esphome/components/sound_level/sound_level.h +73 -0
  348. esphome/components/speaker/media_player/__init__.py +4 -8
  349. esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
  350. esphome/components/speaker/media_player/speaker_media_player.h +0 -11
  351. esphome/components/speaker/speaker.h +4 -7
  352. esphome/components/speed/fan/__init__.py +17 -16
  353. esphome/components/spi/spi.h +11 -1
  354. esphome/components/sprinkler/__init__.py +18 -19
  355. esphome/components/sprinkler/sprinkler.cpp +6 -5
  356. esphome/components/switch/__init__.py +32 -42
  357. esphome/components/syslog/__init__.py +41 -0
  358. esphome/components/syslog/esphome_syslog.cpp +49 -0
  359. esphome/components/syslog/esphome_syslog.h +27 -0
  360. esphome/components/t6615/sensor.py +3 -3
  361. esphome/components/t6615/t6615.cpp +2 -1
  362. esphome/components/tca9555/tca9555.cpp +11 -6
  363. esphome/components/tcl112/climate.py +2 -9
  364. esphome/components/template/alarm_control_panel/__init__.py +7 -6
  365. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
  366. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
  367. esphome/components/template/cover/__init__.py +27 -21
  368. esphome/components/template/fan/__init__.py +14 -12
  369. esphome/components/template/lock/__init__.py +20 -25
  370. esphome/components/template/lock/automation.h +18 -0
  371. esphome/components/template/text/__init__.py +4 -3
  372. esphome/components/template/valve/__init__.py +32 -21
  373. esphome/components/template/valve/automation.h +24 -0
  374. esphome/components/text/__init__.py +32 -1
  375. esphome/components/text_sensor/__init__.py +24 -29
  376. esphome/components/thermostat/climate.py +5 -5
  377. esphome/components/time_based/cover.py +17 -16
  378. esphome/components/time_based/time_based_cover.cpp +2 -1
  379. esphome/components/tm1638/switch/__init__.py +10 -7
  380. esphome/components/tormatic/cover.py +4 -5
  381. esphome/components/toshiba/climate.py +3 -5
  382. esphome/components/touchscreen/touchscreen.cpp +3 -1
  383. esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
  384. esphome/components/tuya/climate/__init__.py +5 -6
  385. esphome/components/tuya/cover/__init__.py +6 -11
  386. esphome/components/tuya/select/__init__.py +15 -5
  387. esphome/components/tuya/select/tuya_select.cpp +6 -1
  388. esphome/components/tuya/select/tuya_select.h +5 -1
  389. esphome/components/uart/packet_transport/__init__.py +20 -0
  390. esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
  391. esphome/components/uart/packet_transport/uart_transport.h +41 -0
  392. esphome/components/uart/switch/uart_switch.cpp +2 -1
  393. esphome/components/udp/__init__.py +126 -128
  394. esphome/components/udp/automation.h +40 -0
  395. esphome/components/udp/binary_sensor.py +3 -25
  396. esphome/components/udp/packet_transport/__init__.py +29 -0
  397. esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
  398. esphome/components/udp/packet_transport/udp_transport.h +28 -0
  399. esphome/components/udp/sensor.py +3 -25
  400. esphome/components/udp/udp_component.cpp +26 -470
  401. esphome/components/udp/udp_component.h +21 -128
  402. esphome/components/update/__init__.py +31 -1
  403. esphome/components/uponor_smatrix/climate/__init__.py +4 -9
  404. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
  405. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  406. esphome/components/uptime/text_sensor/__init__.py +47 -7
  407. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
  408. esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
  409. esphome/components/valve/__init__.py +34 -3
  410. esphome/components/valve/automation.h +1 -19
  411. esphome/components/vl53l0x/sensor.py +11 -0
  412. esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
  413. esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
  414. esphome/components/voice_assistant/__init__.py +36 -10
  415. esphome/components/voice_assistant/voice_assistant.cpp +170 -144
  416. esphome/components/voice_assistant/voice_assistant.h +26 -25
  417. esphome/components/waveshare_epaper/display.py +6 -0
  418. esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
  419. esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
  420. esphome/components/weikai/weikai.cpp +0 -52
  421. esphome/components/whirlpool/climate.py +3 -5
  422. esphome/components/whynter/climate.py +3 -5
  423. esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
  424. esphome/components/yashima/climate.py +6 -6
  425. esphome/components/zhlt01/climate.py +2 -7
  426. esphome/config.py +13 -13
  427. esphome/config_validation.py +38 -58
  428. esphome/const.py +15 -1
  429. esphome/core/__init__.py +2 -0
  430. esphome/core/application.cpp +27 -10
  431. esphome/core/application.h +9 -1
  432. esphome/core/automation.h +4 -3
  433. esphome/core/component.cpp +28 -7
  434. esphome/core/component.h +10 -1
  435. esphome/core/defines.h +23 -17
  436. esphome/core/doxygen.h +13 -0
  437. esphome/core/macros.h +4 -0
  438. esphome/core/scheduler.cpp +7 -1
  439. esphome/cpp_generator.py +6 -2
  440. esphome/dashboard/web_server.py +3 -3
  441. esphome/helpers.py +39 -0
  442. esphome/loader.py +4 -0
  443. esphome/log.py +15 -19
  444. esphome/mqtt.py +23 -10
  445. esphome/platformio_api.py +1 -1
  446. esphome/schema_extractors.py +0 -1
  447. esphome/voluptuous_schema.py +3 -1
  448. esphome/vscode.py +15 -0
  449. esphome/wizard.py +47 -37
  450. esphome/zeroconf.py +7 -3
  451. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/METADATA +10 -11
  452. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/RECORD +456 -396
  453. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/WHEEL +1 -1
  454. esphome/components/esp32_ble/const_esp32c6.h +0 -74
  455. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/entry_points.txt +0 -0
  456. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/licenses/LICENSE +0 -0
  457. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/top_level.txt +0 -0
@@ -8,13 +8,17 @@
8
8
  #include "api_server.h"
9
9
  #include "esphome/core/application.h"
10
10
  #include "esphome/core/component.h"
11
+ #include "esphome/core/entity_base.h"
11
12
 
12
13
  #include <vector>
13
14
 
14
15
  namespace esphome {
15
16
  namespace api {
16
17
 
17
- using send_message_t = bool(APIConnection *, void *);
18
+ // Keepalive timeout in milliseconds
19
+ static constexpr uint32_t KEEPALIVE_TIMEOUT_MS = 60000;
20
+
21
+ using send_message_t = bool (APIConnection::*)(void *);
18
22
 
19
23
  /*
20
24
  This class holds a pointer to the source component that wants to publish a message, and a pointer to a function that
@@ -30,10 +34,10 @@ class DeferredMessageQueue {
30
34
 
31
35
  protected:
32
36
  void *source_;
33
- send_message_t *send_message_;
37
+ send_message_t send_message_;
34
38
 
35
39
  public:
36
- DeferredMessage(void *source, send_message_t *send_message) : source_(source), send_message_(send_message) {}
40
+ DeferredMessage(void *source, send_message_t send_message) : source_(source), send_message_(send_message) {}
37
41
  bool operator==(const DeferredMessage &test) const {
38
42
  return (source_ == test.source_ && send_message_ == test.send_message_);
39
43
  }
@@ -46,12 +50,13 @@ class DeferredMessageQueue {
46
50
  APIConnection *api_connection_;
47
51
 
48
52
  // helper for allowing only unique entries in the queue
49
- void dmq_push_back_with_dedup_(void *source, send_message_t *send_message);
53
+ void dmq_push_back_with_dedup_(void *source, send_message_t send_message);
50
54
 
51
55
  public:
52
56
  DeferredMessageQueue(APIConnection *api_connection) : api_connection_(api_connection) {}
53
57
  void process_queue();
54
- void defer(void *source, send_message_t *send_message);
58
+ void defer(void *source, send_message_t send_message);
59
+ bool empty() const { return deferred_queue_.empty(); }
55
60
  };
56
61
 
57
62
  class APIConnection : public APIServerConnection {
@@ -69,137 +74,213 @@ class APIConnection : public APIServerConnection {
69
74
  #ifdef USE_BINARY_SENSOR
70
75
  bool send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor, bool state);
71
76
  void send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor);
72
- static bool try_send_binary_sensor_state(APIConnection *api, void *v_binary_sensor);
73
- static bool try_send_binary_sensor_state(APIConnection *api, binary_sensor::BinarySensor *binary_sensor, bool state);
74
- static bool try_send_binary_sensor_info(APIConnection *api, void *v_binary_sensor);
77
+
78
+ protected:
79
+ bool try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor);
80
+ bool try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor, bool state);
81
+ bool try_send_binary_sensor_info_(binary_sensor::BinarySensor *binary_sensor);
82
+
83
+ public:
75
84
  #endif
76
85
  #ifdef USE_COVER
77
86
  bool send_cover_state(cover::Cover *cover);
78
87
  void send_cover_info(cover::Cover *cover);
79
- static bool try_send_cover_state(APIConnection *api, void *v_cover);
80
- static bool try_send_cover_info(APIConnection *api, void *v_cover);
81
88
  void cover_command(const CoverCommandRequest &msg) override;
89
+
90
+ protected:
91
+ bool try_send_cover_state_(cover::Cover *cover);
92
+ bool try_send_cover_info_(cover::Cover *cover);
93
+
94
+ public:
82
95
  #endif
83
96
  #ifdef USE_FAN
84
97
  bool send_fan_state(fan::Fan *fan);
85
98
  void send_fan_info(fan::Fan *fan);
86
- static bool try_send_fan_state(APIConnection *api, void *v_fan);
87
- static bool try_send_fan_info(APIConnection *api, void *v_fan);
88
99
  void fan_command(const FanCommandRequest &msg) override;
100
+
101
+ protected:
102
+ bool try_send_fan_state_(fan::Fan *fan);
103
+ bool try_send_fan_info_(fan::Fan *fan);
104
+
105
+ public:
89
106
  #endif
90
107
  #ifdef USE_LIGHT
91
108
  bool send_light_state(light::LightState *light);
92
109
  void send_light_info(light::LightState *light);
93
- static bool try_send_light_state(APIConnection *api, void *v_light);
94
- static bool try_send_light_info(APIConnection *api, void *v_light);
95
110
  void light_command(const LightCommandRequest &msg) override;
111
+
112
+ protected:
113
+ bool try_send_light_state_(light::LightState *light);
114
+ bool try_send_light_info_(light::LightState *light);
115
+
116
+ public:
96
117
  #endif
97
118
  #ifdef USE_SENSOR
98
119
  bool send_sensor_state(sensor::Sensor *sensor, float state);
99
120
  void send_sensor_info(sensor::Sensor *sensor);
100
- static bool try_send_sensor_state(APIConnection *api, void *v_sensor);
101
- static bool try_send_sensor_state(APIConnection *api, sensor::Sensor *sensor, float state);
102
- static bool try_send_sensor_info(APIConnection *api, void *v_sensor);
121
+
122
+ protected:
123
+ bool try_send_sensor_state_(sensor::Sensor *sensor);
124
+ bool try_send_sensor_state_(sensor::Sensor *sensor, float state);
125
+ bool try_send_sensor_info_(sensor::Sensor *sensor);
126
+
127
+ public:
103
128
  #endif
104
129
  #ifdef USE_SWITCH
105
130
  bool send_switch_state(switch_::Switch *a_switch, bool state);
106
131
  void send_switch_info(switch_::Switch *a_switch);
107
- static bool try_send_switch_state(APIConnection *api, void *v_a_switch);
108
- static bool try_send_switch_state(APIConnection *api, switch_::Switch *a_switch, bool state);
109
- static bool try_send_switch_info(APIConnection *api, void *v_a_switch);
110
132
  void switch_command(const SwitchCommandRequest &msg) override;
133
+
134
+ protected:
135
+ bool try_send_switch_state_(switch_::Switch *a_switch);
136
+ bool try_send_switch_state_(switch_::Switch *a_switch, bool state);
137
+ bool try_send_switch_info_(switch_::Switch *a_switch);
138
+
139
+ public:
111
140
  #endif
112
141
  #ifdef USE_TEXT_SENSOR
113
142
  bool send_text_sensor_state(text_sensor::TextSensor *text_sensor, std::string state);
114
143
  void send_text_sensor_info(text_sensor::TextSensor *text_sensor);
115
- static bool try_send_text_sensor_state(APIConnection *api, void *v_text_sensor);
116
- static bool try_send_text_sensor_state(APIConnection *api, text_sensor::TextSensor *text_sensor, std::string state);
117
- static bool try_send_text_sensor_info(APIConnection *api, void *v_text_sensor);
144
+
145
+ protected:
146
+ bool try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor);
147
+ bool try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor, std::string state);
148
+ bool try_send_text_sensor_info_(text_sensor::TextSensor *text_sensor);
149
+
150
+ public:
118
151
  #endif
119
152
  #ifdef USE_ESP32_CAMERA
120
153
  void set_camera_state(std::shared_ptr<esp32_camera::CameraImage> image);
121
154
  void send_camera_info(esp32_camera::ESP32Camera *camera);
122
- static bool try_send_camera_info(APIConnection *api, void *v_camera);
123
155
  void camera_image(const CameraImageRequest &msg) override;
156
+
157
+ protected:
158
+ bool try_send_camera_info_(esp32_camera::ESP32Camera *camera);
159
+
160
+ public:
124
161
  #endif
125
162
  #ifdef USE_CLIMATE
126
163
  bool send_climate_state(climate::Climate *climate);
127
164
  void send_climate_info(climate::Climate *climate);
128
- static bool try_send_climate_state(APIConnection *api, void *v_climate);
129
- static bool try_send_climate_info(APIConnection *api, void *v_climate);
130
165
  void climate_command(const ClimateCommandRequest &msg) override;
166
+
167
+ protected:
168
+ bool try_send_climate_state_(climate::Climate *climate);
169
+ bool try_send_climate_info_(climate::Climate *climate);
170
+
171
+ public:
131
172
  #endif
132
173
  #ifdef USE_NUMBER
133
174
  bool send_number_state(number::Number *number, float state);
134
175
  void send_number_info(number::Number *number);
135
- static bool try_send_number_state(APIConnection *api, void *v_number);
136
- static bool try_send_number_state(APIConnection *api, number::Number *number, float state);
137
- static bool try_send_number_info(APIConnection *api, void *v_number);
138
176
  void number_command(const NumberCommandRequest &msg) override;
177
+
178
+ protected:
179
+ bool try_send_number_state_(number::Number *number);
180
+ bool try_send_number_state_(number::Number *number, float state);
181
+ bool try_send_number_info_(number::Number *number);
182
+
183
+ public:
139
184
  #endif
140
185
  #ifdef USE_DATETIME_DATE
141
186
  bool send_date_state(datetime::DateEntity *date);
142
187
  void send_date_info(datetime::DateEntity *date);
143
- static bool try_send_date_state(APIConnection *api, void *v_date);
144
- static bool try_send_date_info(APIConnection *api, void *v_date);
145
188
  void date_command(const DateCommandRequest &msg) override;
189
+
190
+ protected:
191
+ bool try_send_date_state_(datetime::DateEntity *date);
192
+ bool try_send_date_info_(datetime::DateEntity *date);
193
+
194
+ public:
146
195
  #endif
147
196
  #ifdef USE_DATETIME_TIME
148
197
  bool send_time_state(datetime::TimeEntity *time);
149
198
  void send_time_info(datetime::TimeEntity *time);
150
- static bool try_send_time_state(APIConnection *api, void *v_time);
151
- static bool try_send_time_info(APIConnection *api, void *v_time);
152
199
  void time_command(const TimeCommandRequest &msg) override;
200
+
201
+ protected:
202
+ bool try_send_time_state_(datetime::TimeEntity *time);
203
+ bool try_send_time_info_(datetime::TimeEntity *time);
204
+
205
+ public:
153
206
  #endif
154
207
  #ifdef USE_DATETIME_DATETIME
155
208
  bool send_datetime_state(datetime::DateTimeEntity *datetime);
156
209
  void send_datetime_info(datetime::DateTimeEntity *datetime);
157
- static bool try_send_datetime_state(APIConnection *api, void *v_datetime);
158
- static bool try_send_datetime_info(APIConnection *api, void *v_datetime);
159
210
  void datetime_command(const DateTimeCommandRequest &msg) override;
211
+
212
+ protected:
213
+ bool try_send_datetime_state_(datetime::DateTimeEntity *datetime);
214
+ bool try_send_datetime_info_(datetime::DateTimeEntity *datetime);
215
+
216
+ public:
160
217
  #endif
161
218
  #ifdef USE_TEXT
162
219
  bool send_text_state(text::Text *text, std::string state);
163
220
  void send_text_info(text::Text *text);
164
- static bool try_send_text_state(APIConnection *api, void *v_text);
165
- static bool try_send_text_state(APIConnection *api, text::Text *text, std::string state);
166
- static bool try_send_text_info(APIConnection *api, void *v_text);
167
221
  void text_command(const TextCommandRequest &msg) override;
222
+
223
+ protected:
224
+ bool try_send_text_state_(text::Text *text);
225
+ bool try_send_text_state_(text::Text *text, std::string state);
226
+ bool try_send_text_info_(text::Text *text);
227
+
228
+ public:
168
229
  #endif
169
230
  #ifdef USE_SELECT
170
231
  bool send_select_state(select::Select *select, std::string state);
171
232
  void send_select_info(select::Select *select);
172
- static bool try_send_select_state(APIConnection *api, void *v_select);
173
- static bool try_send_select_state(APIConnection *api, select::Select *select, std::string state);
174
- static bool try_send_select_info(APIConnection *api, void *v_select);
175
233
  void select_command(const SelectCommandRequest &msg) override;
234
+
235
+ protected:
236
+ bool try_send_select_state_(select::Select *select);
237
+ bool try_send_select_state_(select::Select *select, std::string state);
238
+ bool try_send_select_info_(select::Select *select);
239
+
240
+ public:
176
241
  #endif
177
242
  #ifdef USE_BUTTON
178
243
  void send_button_info(button::Button *button);
179
- static bool try_send_button_info(APIConnection *api, void *v_button);
180
244
  void button_command(const ButtonCommandRequest &msg) override;
245
+
246
+ protected:
247
+ bool try_send_button_info_(button::Button *button);
248
+
249
+ public:
181
250
  #endif
182
251
  #ifdef USE_LOCK
183
252
  bool send_lock_state(lock::Lock *a_lock, lock::LockState state);
184
253
  void send_lock_info(lock::Lock *a_lock);
185
- static bool try_send_lock_state(APIConnection *api, void *v_a_lock);
186
- static bool try_send_lock_state(APIConnection *api, lock::Lock *a_lock, lock::LockState state);
187
- static bool try_send_lock_info(APIConnection *api, void *v_a_lock);
188
254
  void lock_command(const LockCommandRequest &msg) override;
255
+
256
+ protected:
257
+ bool try_send_lock_state_(lock::Lock *a_lock);
258
+ bool try_send_lock_state_(lock::Lock *a_lock, lock::LockState state);
259
+ bool try_send_lock_info_(lock::Lock *a_lock);
260
+
261
+ public:
189
262
  #endif
190
263
  #ifdef USE_VALVE
191
264
  bool send_valve_state(valve::Valve *valve);
192
265
  void send_valve_info(valve::Valve *valve);
193
- static bool try_send_valve_state(APIConnection *api, void *v_valve);
194
- static bool try_send_valve_info(APIConnection *api, void *v_valve);
195
266
  void valve_command(const ValveCommandRequest &msg) override;
267
+
268
+ protected:
269
+ bool try_send_valve_state_(valve::Valve *valve);
270
+ bool try_send_valve_info_(valve::Valve *valve);
271
+
272
+ public:
196
273
  #endif
197
274
  #ifdef USE_MEDIA_PLAYER
198
275
  bool send_media_player_state(media_player::MediaPlayer *media_player);
199
276
  void send_media_player_info(media_player::MediaPlayer *media_player);
200
- static bool try_send_media_player_state(APIConnection *api, void *v_media_player);
201
- static bool try_send_media_player_info(APIConnection *api, void *v_media_player);
202
277
  void media_player_command(const MediaPlayerCommandRequest &msg) override;
278
+
279
+ protected:
280
+ bool try_send_media_player_state_(media_player::MediaPlayer *media_player);
281
+ bool try_send_media_player_info_(media_player::MediaPlayer *media_player);
282
+
283
+ public:
203
284
  #endif
204
285
  bool try_send_log_message(int level, const char *tag, const char *line);
205
286
  void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
@@ -221,6 +302,7 @@ class APIConnection : public APIServerConnection {
221
302
  void bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg) override;
222
303
  BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free(
223
304
  const SubscribeBluetoothConnectionsFreeRequest &msg) override;
305
+ void bluetooth_scanner_set_mode(const BluetoothScannerSetModeRequest &msg) override;
224
306
 
225
307
  #endif
226
308
  #ifdef USE_HOMEASSISTANT_TIME
@@ -245,25 +327,37 @@ class APIConnection : public APIServerConnection {
245
327
  #ifdef USE_ALARM_CONTROL_PANEL
246
328
  bool send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
247
329
  void send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
248
- static bool try_send_alarm_control_panel_state(APIConnection *api, void *v_a_alarm_control_panel);
249
- static bool try_send_alarm_control_panel_info(APIConnection *api, void *v_a_alarm_control_panel);
250
330
  void alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) override;
331
+
332
+ protected:
333
+ bool try_send_alarm_control_panel_state_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
334
+ bool try_send_alarm_control_panel_info_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
335
+
336
+ public:
251
337
  #endif
252
338
 
253
339
  #ifdef USE_EVENT
254
340
  void send_event(event::Event *event, std::string event_type);
255
341
  void send_event_info(event::Event *event);
256
- static bool try_send_event(APIConnection *api, void *v_event);
257
- static bool try_send_event(APIConnection *api, event::Event *event, std::string event_type);
258
- static bool try_send_event_info(APIConnection *api, void *v_event);
342
+
343
+ protected:
344
+ bool try_send_event_(event::Event *event);
345
+ bool try_send_event_(event::Event *event, std::string event_type);
346
+ bool try_send_event_info_(event::Event *event);
347
+
348
+ public:
259
349
  #endif
260
350
 
261
351
  #ifdef USE_UPDATE
262
352
  bool send_update_state(update::UpdateEntity *update);
263
353
  void send_update_info(update::UpdateEntity *update);
264
- static bool try_send_update_state(APIConnection *api, void *v_update);
265
- static bool try_send_update_info(APIConnection *api, void *v_update);
266
354
  void update_command(const UpdateCommandRequest &msg) override;
355
+
356
+ protected:
357
+ bool try_send_update_state_(update::UpdateEntity *update);
358
+ bool try_send_update_info_(update::UpdateEntity *update);
359
+
360
+ public:
267
361
  #endif
268
362
 
269
363
  void on_disconnect_response(const DisconnectResponse &value) override;
@@ -300,6 +394,9 @@ class APIConnection : public APIServerConnection {
300
394
  return {};
301
395
  }
302
396
  void execute_service(const ExecuteServiceRequest &msg) override;
397
+ #ifdef USE_API_NOISE
398
+ NoiseEncryptionSetKeyResponse noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) override;
399
+ #endif
303
400
 
304
401
  bool is_authenticated() override { return this->connection_state_ == ConnectionState::AUTHENTICATED; }
305
402
  bool is_connection_setup() override {
@@ -308,11 +405,20 @@ class APIConnection : public APIServerConnection {
308
405
  void on_fatal_error() override;
309
406
  void on_unauthenticated_access() override;
310
407
  void on_no_setup_connection() override;
311
- ProtoWriteBuffer create_buffer() override {
408
+ ProtoWriteBuffer create_buffer(uint32_t reserve_size) override {
312
409
  // FIXME: ensure no recursive writes can happen
313
410
  this->proto_write_buffer_.clear();
411
+ // Get header padding size - used for both reserve and insert
412
+ uint8_t header_padding = this->helper_->frame_header_padding();
413
+ // Reserve space for header padding + message + footer
414
+ // - Header padding: space for protocol headers (7 bytes for Noise, 6 for Plaintext)
415
+ // - Footer: space for MAC (16 bytes for Noise, 0 for Plaintext)
416
+ this->proto_write_buffer_.reserve(reserve_size + header_padding + this->helper_->frame_footer_size());
417
+ // Insert header padding bytes so message encoding starts at the correct position
418
+ this->proto_write_buffer_.insert(this->proto_write_buffer_.begin(), header_padding, 0);
314
419
  return {&this->proto_write_buffer_};
315
420
  }
421
+ bool try_to_clear_buffer(bool log_out_of_space);
316
422
  bool send_buffer(ProtoWriteBuffer buffer, uint32_t message_type) override;
317
423
 
318
424
  std::string get_client_combined_info() const { return this->client_combined_info_; }
@@ -320,6 +426,99 @@ class APIConnection : public APIServerConnection {
320
426
  protected:
321
427
  friend APIServer;
322
428
 
429
+ /**
430
+ * Generic send entity state method to reduce code duplication.
431
+ * Only attempts to build and send the message if the transmit buffer is available.
432
+ *
433
+ * This is the base version for entities that use their current state.
434
+ *
435
+ * @param entity The entity to send state for
436
+ * @param try_send_func The function that tries to send the state
437
+ * @return True on success or message deferred, false if subscription check failed
438
+ */
439
+ bool send_state_(esphome::EntityBase *entity, send_message_t try_send_func) {
440
+ if (!this->state_subscription_)
441
+ return false;
442
+ if (this->try_to_clear_buffer(true) && (this->*try_send_func)(entity)) {
443
+ return true;
444
+ }
445
+ this->deferred_message_queue_.defer(entity, try_send_func);
446
+ return true;
447
+ }
448
+
449
+ /**
450
+ * Send entity state method that handles explicit state values.
451
+ * Only attempts to build and send the message if the transmit buffer is available.
452
+ *
453
+ * This method accepts a state parameter to be used instead of the entity's current state.
454
+ * It attempts to send the state with the provided value first, and if that fails due to buffer constraints,
455
+ * it defers the entity for later processing using the entity-only function.
456
+ *
457
+ * @tparam EntityT The entity type
458
+ * @tparam StateT Type of the state parameter
459
+ * @tparam Args Additional argument types (if any)
460
+ * @param entity The entity to send state for
461
+ * @param try_send_entity_func The function that tries to send the state with entity pointer only
462
+ * @param try_send_state_func The function that tries to send the state with entity and state parameters
463
+ * @param state The state value to send
464
+ * @param args Additional arguments to pass to the try_send_state_func
465
+ * @return True on success or message deferred, false if subscription check failed
466
+ */
467
+ template<typename EntityT, typename StateT, typename... Args>
468
+ bool send_state_with_value_(EntityT *entity, bool (APIConnection::*try_send_entity_func)(EntityT *),
469
+ bool (APIConnection::*try_send_state_func)(EntityT *, StateT, Args...), StateT state,
470
+ Args... args) {
471
+ if (!this->state_subscription_)
472
+ return false;
473
+ if (this->try_to_clear_buffer(true) && (this->*try_send_state_func)(entity, state, args...)) {
474
+ return true;
475
+ }
476
+ this->deferred_message_queue_.defer(entity, reinterpret_cast<send_message_t>(try_send_entity_func));
477
+ return true;
478
+ }
479
+
480
+ /**
481
+ * Generic send entity info method to reduce code duplication.
482
+ * Only attempts to build and send the message if the transmit buffer is available.
483
+ *
484
+ * @param entity The entity to send info for
485
+ * @param try_send_func The function that tries to send the info
486
+ */
487
+ void send_info_(esphome::EntityBase *entity, send_message_t try_send_func) {
488
+ if (this->try_to_clear_buffer(true) && (this->*try_send_func)(entity)) {
489
+ return;
490
+ }
491
+ this->deferred_message_queue_.defer(entity, try_send_func);
492
+ }
493
+
494
+ /**
495
+ * Generic function for generating entity info response messages.
496
+ * This is used to reduce duplication in the try_send_*_info functions.
497
+ *
498
+ * @param entity The entity to generate info for
499
+ * @param response The response object
500
+ * @param send_response_func Function pointer to send the response
501
+ * @return True if the message was sent successfully
502
+ */
503
+ template<typename ResponseT>
504
+ bool try_send_entity_info_(esphome::EntityBase *entity, ResponseT &response,
505
+ bool (APIServerConnectionBase::*send_response_func)(const ResponseT &)) {
506
+ // Set common fields that are shared by all entity types
507
+ response.key = entity->get_object_id_hash();
508
+ response.object_id = entity->get_object_id();
509
+
510
+ if (entity->has_own_name())
511
+ response.name = entity->get_name();
512
+
513
+ // Set common EntityBase properties
514
+ response.icon = entity->get_icon();
515
+ response.disabled_by_default = entity->is_disabled_by_default();
516
+ response.entity_category = static_cast<enums::EntityCategory>(entity->get_entity_category());
517
+
518
+ // Send the response using the provided send method
519
+ return (this->*send_response_func)(response);
520
+ }
521
+
323
522
  bool send_(const void *buf, size_t len, bool force);
324
523
 
325
524
  enum class ConnectionState {