esphome 2025.4.1__py3-none-any.whl → 2025.5.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 (412) hide show
  1. esphome/components/ac_dimmer/ac_dimmer.cpp +3 -2
  2. esphome/components/adc/__init__.py +51 -34
  3. esphome/components/airthings_wave_base/__init__.py +1 -1
  4. esphome/components/alarm_control_panel/__init__.py +37 -2
  5. esphome/components/am43/cover/__init__.py +4 -5
  6. esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
  7. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
  8. esphome/components/analog_threshold/binary_sensor.py +10 -8
  9. esphome/components/anova/climate.py +4 -5
  10. esphome/components/api/__init__.py +25 -8
  11. esphome/components/api/api_connection.cpp +77 -10
  12. esphome/components/api/api_connection.h +6 -1
  13. esphome/components/api/api_frame_helper.cpp +98 -130
  14. esphome/components/api/api_frame_helper.h +12 -2
  15. esphome/components/api/api_noise_context.h +13 -4
  16. esphome/components/api/api_pb2.cpp +1422 -1
  17. esphome/components/api/api_pb2.h +255 -1
  18. esphome/components/api/api_pb2_service.cpp +162 -49
  19. esphome/components/api/api_pb2_service.h +90 -51
  20. esphome/components/api/api_pb2_size.h +361 -0
  21. esphome/components/api/api_server.cpp +110 -34
  22. esphome/components/api/api_server.h +8 -0
  23. esphome/components/api/proto.h +38 -9
  24. esphome/components/as3935_i2c/as3935_i2c.h +0 -3
  25. esphome/components/as7341/as7341.h +1 -1
  26. esphome/components/atm90e32/__init__.py +1 -0
  27. esphome/components/atm90e32/atm90e32.cpp +576 -199
  28. esphome/components/atm90e32/atm90e32.h +128 -31
  29. esphome/components/atm90e32/atm90e32_reg.h +4 -2
  30. esphome/components/atm90e32/button/__init__.py +62 -10
  31. esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
  32. esphome/components/atm90e32/button/atm90e32_button.h +36 -4
  33. esphome/components/atm90e32/number/__init__.py +130 -0
  34. esphome/components/atm90e32/number/atm90e32_number.h +16 -0
  35. esphome/components/atm90e32/sensor.py +21 -4
  36. esphome/components/atm90e32/text_sensor/__init__.py +48 -0
  37. esphome/components/audio/__init__.py +96 -49
  38. esphome/components/audio/audio.h +48 -0
  39. esphome/components/audio/audio_decoder.cpp +1 -1
  40. esphome/components/audio/audio_resampler.cpp +2 -0
  41. esphome/components/audio/audio_resampler.h +1 -0
  42. esphome/components/ballu/climate.py +2 -9
  43. esphome/components/bang_bang/climate.py +5 -6
  44. esphome/components/bedjet/climate/__init__.py +3 -8
  45. esphome/components/bedjet/fan/__init__.py +2 -11
  46. esphome/components/binary/fan/__init__.py +13 -16
  47. esphome/components/binary_sensor/__init__.py +13 -10
  48. esphome/components/binary_sensor/binary_sensor.cpp +6 -10
  49. esphome/components/binary_sensor/binary_sensor.h +1 -1
  50. esphome/components/binary_sensor/filter.cpp +21 -21
  51. esphome/components/binary_sensor/filter.h +10 -10
  52. esphome/components/bl0906/constants.h +16 -16
  53. esphome/components/ble_client/text_sensor/__init__.py +3 -5
  54. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
  55. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +135 -21
  56. esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
  57. esphome/components/button/__init__.py +11 -8
  58. esphome/components/canbus/canbus.cpp +3 -0
  59. esphome/components/canbus/canbus.h +16 -0
  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/cst226/binary_sensor/__init__.py +28 -0
  76. esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
  77. esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
  78. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
  79. esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
  80. esphome/components/current_based/cover.py +37 -36
  81. esphome/components/daikin/climate.py +2 -9
  82. esphome/components/daikin/daikin.cpp +15 -9
  83. esphome/components/daikin/daikin.h +5 -5
  84. esphome/components/daikin_arc/climate.py +2 -7
  85. esphome/components/daikin_brc/climate.py +3 -5
  86. esphome/components/dallas_temp/dallas_temp.cpp +17 -24
  87. esphome/components/dallas_temp/dallas_temp.h +0 -1
  88. esphome/components/debug/debug_component.cpp +5 -0
  89. esphome/components/debug/debug_component.h +6 -0
  90. esphome/components/debug/debug_esp32.cpp +109 -254
  91. esphome/components/debug/sensor.py +14 -0
  92. esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
  93. esphome/components/delonghi/climate.py +2 -9
  94. esphome/components/demo/__init__.py +18 -20
  95. esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
  96. esphome/components/display/rect.cpp +4 -9
  97. esphome/components/display/rect.h +1 -1
  98. esphome/components/emmeti/climate.py +2 -9
  99. esphome/components/endstop/cover.py +17 -16
  100. esphome/components/esp32/__init__.py +60 -3
  101. esphome/components/esp32/core.cpp +11 -5
  102. esphome/components/esp32/gpio.cpp +86 -24
  103. esphome/components/esp32/gpio.py +15 -16
  104. esphome/components/esp32/gpio_esp32.py +1 -2
  105. esphome/components/esp32/gpio_esp32_c2.py +1 -1
  106. esphome/components/esp32/gpio_esp32_c3.py +1 -1
  107. esphome/components/esp32/gpio_esp32_c6.py +1 -1
  108. esphome/components/esp32/gpio_esp32_h2.py +1 -1
  109. esphome/components/esp32_ble/ble.cpp +1 -8
  110. esphome/components/esp32_ble/ble.h +5 -3
  111. esphome/components/esp32_ble/ble_advertising.h +1 -0
  112. esphome/components/esp32_ble_server/__init__.py +3 -0
  113. esphome/components/esp32_ble_tracker/__init__.py +7 -1
  114. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
  115. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
  116. esphome/components/esp32_can/esp32_can.cpp +1 -1
  117. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  118. esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
  119. esphome/components/esp32_rmt_led_strip/light.py +9 -1
  120. esphome/components/esp8266/gpio.cpp +69 -8
  121. esphome/components/event/__init__.py +13 -10
  122. esphome/components/factory_reset/switch/__init__.py +7 -21
  123. esphome/components/fan/__init__.py +52 -5
  124. esphome/components/fastled_base/__init__.py +1 -4
  125. esphome/components/fastled_base/fastled_light.cpp +1 -1
  126. esphome/components/feedback/cover.py +38 -33
  127. esphome/components/fujitsu_general/climate.py +2 -9
  128. esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
  129. esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
  130. esphome/components/gpio_expander/cached_gpio.h +22 -7
  131. esphome/components/gps/__init__.py +11 -2
  132. esphome/components/gps/gps.cpp +11 -8
  133. esphome/components/gps/gps.h +9 -6
  134. esphome/components/graph/__init__.py +1 -2
  135. esphome/components/gree/climate.py +4 -6
  136. esphome/components/gree/gree.cpp +16 -2
  137. esphome/components/gree/gree.h +2 -2
  138. esphome/components/haier/climate.py +37 -34
  139. esphome/components/hbridge/fan/__init__.py +19 -17
  140. esphome/components/he60r/cover.py +4 -5
  141. esphome/components/heatpumpir/climate.py +3 -6
  142. esphome/components/hitachi_ac344/climate.py +2 -9
  143. esphome/components/hitachi_ac424/climate.py +2 -9
  144. esphome/components/hlw8012/hlw8012.cpp +1 -1
  145. esphome/components/hm3301/hm3301.h +1 -1
  146. esphome/components/http_request/__init__.py +39 -6
  147. esphome/components/http_request/http_request.cpp +20 -0
  148. esphome/components/http_request/http_request.h +57 -15
  149. esphome/components/http_request/http_request_arduino.cpp +22 -6
  150. esphome/components/http_request/http_request_arduino.h +4 -3
  151. esphome/components/http_request/http_request_host.cpp +141 -0
  152. esphome/components/http_request/http_request_host.h +37 -0
  153. esphome/components/http_request/http_request_idf.cpp +35 -3
  154. esphome/components/http_request/http_request_idf.h +10 -3
  155. esphome/components/http_request/httplib.h +9691 -0
  156. esphome/components/http_request/update/__init__.py +11 -8
  157. esphome/components/i2c/i2c.h +4 -0
  158. esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
  159. esphome/components/i2s_audio/__init__.py +131 -22
  160. esphome/components/i2s_audio/i2s_audio.h +44 -4
  161. esphome/components/i2s_audio/media_player/__init__.py +19 -9
  162. esphome/components/i2s_audio/microphone/__init__.py +63 -5
  163. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
  164. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
  165. esphome/components/i2s_audio/speaker/__init__.py +31 -5
  166. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
  167. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
  168. esphome/components/ili9xxx/ili9xxx_init.h +1 -1
  169. esphome/components/image/__init__.py +37 -17
  170. esphome/components/image/image.cpp +25 -8
  171. esphome/components/internal_temperature/internal_temperature.cpp +6 -4
  172. esphome/components/key_collector/__init__.py +35 -0
  173. esphome/components/key_collector/key_collector.cpp +8 -0
  174. esphome/components/key_collector/key_collector.h +10 -0
  175. esphome/components/ld2410/ld2410.h +1 -1
  176. esphome/components/ld2450/ld2450.h +1 -1
  177. esphome/components/light/__init__.py +57 -0
  178. esphome/components/lock/__init__.py +51 -4
  179. esphome/components/lock/automation.h +2 -13
  180. esphome/components/logger/__init__.py +21 -0
  181. esphome/components/logger/logger.cpp +125 -95
  182. esphome/components/logger/logger.h +160 -35
  183. esphome/components/logger/task_log_buffer.cpp +138 -0
  184. esphome/components/logger/task_log_buffer.h +69 -0
  185. esphome/components/lvgl/__init__.py +13 -5
  186. esphome/components/lvgl/automation.py +50 -1
  187. esphome/components/lvgl/defines.py +0 -1
  188. esphome/components/lvgl/lv_validation.py +10 -1
  189. esphome/components/lvgl/lvgl_esphome.cpp +5 -1
  190. esphome/components/lvgl/schemas.py +14 -14
  191. esphome/components/lvgl/text/__init__.py +1 -2
  192. esphome/components/lvgl/widgets/arc.py +7 -6
  193. esphome/components/lvgl/widgets/buttonmatrix.py +3 -3
  194. esphome/components/lvgl/widgets/checkbox.py +2 -2
  195. esphome/components/lvgl/widgets/dropdown.py +2 -1
  196. esphome/components/lvgl/widgets/img.py +15 -12
  197. esphome/components/mapping/__init__.py +134 -0
  198. esphome/components/max7219digit/max7219digit.cpp +27 -27
  199. esphome/components/mdns/__init__.py +11 -5
  200. esphome/components/mdns/mdns_component.cpp +11 -5
  201. esphome/components/mdns/mdns_component.h +3 -2
  202. esphome/components/mdns/mdns_esp32.cpp +4 -3
  203. esphome/components/mdns/mdns_esp8266.cpp +4 -2
  204. esphome/components/mdns/mdns_libretiny.cpp +4 -2
  205. esphome/components/mdns/mdns_rp2040.cpp +4 -2
  206. esphome/components/media_player/__init__.py +40 -6
  207. esphome/components/micro_wake_word/__init__.py +99 -31
  208. esphome/components/micro_wake_word/automation.h +54 -0
  209. esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
  210. esphome/components/micro_wake_word/micro_wake_word.h +58 -105
  211. esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
  212. esphome/components/micro_wake_word/streaming_model.cpp +158 -41
  213. esphome/components/micro_wake_word/streaming_model.h +85 -13
  214. esphome/components/microphone/__init__.py +139 -9
  215. esphome/components/microphone/automation.h +14 -2
  216. esphome/components/microphone/microphone.cpp +21 -0
  217. esphome/components/microphone/microphone.h +14 -5
  218. esphome/components/microphone/microphone_source.cpp +95 -0
  219. esphome/components/microphone/microphone_source.h +80 -0
  220. esphome/components/mics_4514/sensor.py +25 -14
  221. esphome/components/midea/climate.py +3 -4
  222. esphome/components/midea_ir/climate.py +3 -5
  223. esphome/components/mipi_spi/__init__.py +15 -0
  224. esphome/components/mipi_spi/display.py +474 -0
  225. esphome/components/mipi_spi/mipi_spi.cpp +481 -0
  226. esphome/components/mipi_spi/mipi_spi.h +171 -0
  227. esphome/components/mipi_spi/models/__init__.py +65 -0
  228. esphome/components/mipi_spi/models/amoled.py +72 -0
  229. esphome/components/mipi_spi/models/commands.py +82 -0
  230. esphome/components/mipi_spi/models/cyd.py +10 -0
  231. esphome/components/mipi_spi/models/ili.py +749 -0
  232. esphome/components/mipi_spi/models/jc.py +260 -0
  233. esphome/components/mipi_spi/models/lanbon.py +15 -0
  234. esphome/components/mipi_spi/models/lilygo.py +60 -0
  235. esphome/components/mipi_spi/models/waveshare.py +139 -0
  236. esphome/components/mitsubishi/climate.py +2 -5
  237. esphome/components/mitsubishi/mitsubishi.cpp +9 -9
  238. esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
  239. esphome/components/mixer/speaker/mixer_speaker.h +1 -3
  240. esphome/components/mlx90393/sensor.py +5 -0
  241. esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
  242. esphome/components/mlx90393/sensor_mlx90393.h +21 -4
  243. esphome/components/mqtt/__init__.py +1 -1
  244. esphome/components/mqtt/mqtt_client.cpp +5 -1
  245. esphome/components/mqtt/mqtt_const.h +4 -0
  246. esphome/components/mqtt/mqtt_fan.cpp +39 -0
  247. esphome/components/mqtt/mqtt_fan.h +2 -0
  248. esphome/components/network/__init__.py +1 -1
  249. esphome/components/nextion/base_component.py +17 -16
  250. esphome/components/nextion/display.py +11 -2
  251. esphome/components/nextion/nextion.cpp +39 -1
  252. esphome/components/nextion/nextion.h +50 -0
  253. esphome/components/noblex/climate.py +2 -9
  254. esphome/components/number/__init__.py +12 -9
  255. esphome/components/one_wire/one_wire_bus.cpp +14 -10
  256. esphome/components/one_wire/one_wire_bus.h +14 -8
  257. esphome/components/online_image/bmp_image.cpp +48 -11
  258. esphome/components/online_image/bmp_image.h +2 -0
  259. esphome/components/opentherm/binary_sensor/__init__.py +2 -4
  260. esphome/components/opentherm/number/__init__.py +11 -20
  261. esphome/components/opentherm/sensor/__init__.py +3 -3
  262. esphome/components/opentherm/switch/__init__.py +3 -5
  263. esphome/components/output/lock/__init__.py +11 -9
  264. esphome/components/packages/__init__.py +33 -31
  265. esphome/components/packet_transport/__init__.py +201 -0
  266. esphome/components/packet_transport/binary_sensor.py +19 -0
  267. esphome/components/packet_transport/packet_transport.cpp +534 -0
  268. esphome/components/packet_transport/packet_transport.h +154 -0
  269. esphome/components/packet_transport/sensor.py +19 -0
  270. esphome/components/pca9685/pca9685_output.cpp +2 -1
  271. esphome/components/pid/climate.py +2 -4
  272. esphome/components/pm2005/__init__.py +1 -0
  273. esphome/components/pm2005/pm2005.cpp +123 -0
  274. esphome/components/pm2005/pm2005.h +46 -0
  275. esphome/components/pm2005/sensor.py +86 -0
  276. esphome/components/pmsa003i/pmsa003i.cpp +43 -16
  277. esphome/components/pmsa003i/pmsa003i.h +25 -25
  278. esphome/components/pmsx003/pmsx003.cpp +193 -229
  279. esphome/components/pmsx003/pmsx003.h +51 -33
  280. esphome/components/pmsx003/sensor.py +21 -11
  281. esphome/components/pn7150/pn7150.h +2 -2
  282. esphome/components/pn7160/pn7160.h +2 -2
  283. esphome/components/prometheus/prometheus_handler.cpp +174 -0
  284. esphome/components/prometheus/prometheus_handler.h +17 -0
  285. esphome/components/psram/__init__.py +7 -5
  286. esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
  287. esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
  288. esphome/components/qspi_dbi/__init__.py +0 -1
  289. esphome/components/qspi_dbi/display.py +2 -1
  290. esphome/components/qspi_dbi/models.py +1 -2
  291. esphome/components/remote_base/__init__.py +91 -0
  292. esphome/components/remote_base/beo4_protocol.cpp +153 -0
  293. esphome/components/remote_base/beo4_protocol.h +43 -0
  294. esphome/components/remote_base/gobox_protocol.cpp +131 -0
  295. esphome/components/remote_base/gobox_protocol.h +54 -0
  296. esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
  297. esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
  298. esphome/components/resampler/speaker/resampler_speaker.h +1 -1
  299. esphome/components/scd30/sensor.py +2 -3
  300. esphome/components/scd4x/sensor.py +4 -5
  301. esphome/components/sdp3x/sensor.py +2 -1
  302. esphome/components/select/__init__.py +19 -20
  303. esphome/components/sen5x/sensor.py +1 -1
  304. esphome/components/sensor/__init__.py +158 -14
  305. esphome/components/sensor/filter.cpp +23 -0
  306. esphome/components/sensor/filter.h +22 -0
  307. esphome/components/sgp4x/sensor.py +1 -1
  308. esphome/components/sht4x/sht4x.cpp +43 -22
  309. esphome/components/sht4x/sht4x.h +1 -1
  310. esphome/components/sml/text_sensor/__init__.py +4 -6
  311. esphome/components/sound_level/__init__.py +0 -0
  312. esphome/components/sound_level/sensor.py +97 -0
  313. esphome/components/sound_level/sound_level.cpp +194 -0
  314. esphome/components/sound_level/sound_level.h +73 -0
  315. esphome/components/speaker/media_player/__init__.py +4 -8
  316. esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
  317. esphome/components/speaker/media_player/speaker_media_player.h +0 -11
  318. esphome/components/speaker/speaker.h +4 -7
  319. esphome/components/speed/fan/__init__.py +17 -16
  320. esphome/components/spi/spi.h +11 -1
  321. esphome/components/sprinkler/__init__.py +18 -19
  322. esphome/components/switch/__init__.py +32 -42
  323. esphome/components/syslog/__init__.py +41 -0
  324. esphome/components/syslog/esphome_syslog.cpp +49 -0
  325. esphome/components/syslog/esphome_syslog.h +27 -0
  326. esphome/components/tca9555/tca9555.cpp +11 -6
  327. esphome/components/tcl112/climate.py +2 -9
  328. esphome/components/template/alarm_control_panel/__init__.py +7 -6
  329. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
  330. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
  331. esphome/components/template/cover/__init__.py +27 -21
  332. esphome/components/template/fan/__init__.py +14 -12
  333. esphome/components/template/lock/__init__.py +20 -25
  334. esphome/components/template/lock/automation.h +18 -0
  335. esphome/components/template/text/__init__.py +4 -3
  336. esphome/components/template/valve/__init__.py +32 -21
  337. esphome/components/template/valve/automation.h +24 -0
  338. esphome/components/text/__init__.py +32 -1
  339. esphome/components/text_sensor/__init__.py +24 -29
  340. esphome/components/thermostat/climate.py +5 -5
  341. esphome/components/time_based/cover.py +17 -16
  342. esphome/components/tm1638/switch/__init__.py +10 -7
  343. esphome/components/tormatic/cover.py +4 -5
  344. esphome/components/toshiba/climate.py +3 -5
  345. esphome/components/touchscreen/touchscreen.cpp +3 -1
  346. esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
  347. esphome/components/tuya/climate/__init__.py +5 -6
  348. esphome/components/tuya/cover/__init__.py +6 -11
  349. esphome/components/tuya/select/__init__.py +15 -5
  350. esphome/components/tuya/select/tuya_select.cpp +6 -1
  351. esphome/components/tuya/select/tuya_select.h +5 -1
  352. esphome/components/uart/packet_transport/__init__.py +20 -0
  353. esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
  354. esphome/components/uart/packet_transport/uart_transport.h +41 -0
  355. esphome/components/udp/__init__.py +126 -128
  356. esphome/components/udp/automation.h +40 -0
  357. esphome/components/udp/binary_sensor.py +3 -25
  358. esphome/components/udp/packet_transport/__init__.py +29 -0
  359. esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
  360. esphome/components/udp/packet_transport/udp_transport.h +28 -0
  361. esphome/components/udp/sensor.py +3 -25
  362. esphome/components/udp/udp_component.cpp +26 -470
  363. esphome/components/udp/udp_component.h +21 -128
  364. esphome/components/update/__init__.py +31 -1
  365. esphome/components/uponor_smatrix/climate/__init__.py +4 -9
  366. esphome/components/uptime/text_sensor/__init__.py +47 -7
  367. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
  368. esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
  369. esphome/components/valve/__init__.py +34 -3
  370. esphome/components/valve/automation.h +1 -19
  371. esphome/components/vl53l0x/sensor.py +11 -0
  372. esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
  373. esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
  374. esphome/components/voice_assistant/__init__.py +36 -10
  375. esphome/components/voice_assistant/voice_assistant.cpp +170 -144
  376. esphome/components/voice_assistant/voice_assistant.h +26 -25
  377. esphome/components/waveshare_epaper/display.py +6 -0
  378. esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
  379. esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
  380. esphome/components/whirlpool/climate.py +3 -5
  381. esphome/components/whynter/climate.py +3 -5
  382. esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
  383. esphome/components/yashima/climate.py +6 -6
  384. esphome/components/zhlt01/climate.py +2 -7
  385. esphome/config_validation.py +38 -58
  386. esphome/const.py +15 -1
  387. esphome/core/__init__.py +2 -0
  388. esphome/core/application.cpp +1 -0
  389. esphome/core/application.h +4 -0
  390. esphome/core/automation.h +4 -3
  391. esphome/core/component.cpp +19 -3
  392. esphome/core/component.h +5 -0
  393. esphome/core/defines.h +23 -17
  394. esphome/core/macros.h +4 -0
  395. esphome/core/scheduler.cpp +3 -0
  396. esphome/cpp_generator.py +6 -2
  397. esphome/dashboard/web_server.py +3 -3
  398. esphome/helpers.py +39 -0
  399. esphome/loader.py +4 -0
  400. esphome/mqtt.py +21 -8
  401. esphome/platformio_api.py +1 -1
  402. esphome/schema_extractors.py +0 -1
  403. esphome/vscode.py +15 -0
  404. esphome/wizard.py +2 -2
  405. esphome/zeroconf.py +7 -3
  406. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/METADATA +10 -11
  407. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/RECORD +411 -352
  408. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/WHEEL +1 -1
  409. esphome/components/esp32_ble/const_esp32c6.h +0 -74
  410. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/entry_points.txt +0 -0
  411. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/licenses/LICENSE +0 -0
  412. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@
5
5
  #include "esphome/core/helpers.h"
6
6
  #include "esphome/core/application.h"
7
7
  #include "proto.h"
8
+ #include "api_pb2_size.h"
8
9
  #include <cstring>
9
10
 
10
11
  namespace esphome {
@@ -72,6 +73,91 @@ const char *api_error_to_str(APIError err) {
72
73
  return "UNKNOWN";
73
74
  }
74
75
 
76
+ // Common implementation for writing raw data to socket
77
+ template<typename StateEnum>
78
+ APIError APIFrameHelper::write_raw_(const struct iovec *iov, int iovcnt, socket::Socket *socket,
79
+ std::vector<uint8_t> &tx_buf, const std::string &info, StateEnum &state,
80
+ StateEnum failed_state) {
81
+ // This method writes data to socket or buffers it
82
+ // Returns APIError::OK if successful (or would block, but data has been buffered)
83
+ // Returns APIError::SOCKET_WRITE_FAILED if socket write failed, and sets state to failed_state
84
+
85
+ if (iovcnt == 0)
86
+ return APIError::OK; // Nothing to do, success
87
+
88
+ size_t total_write_len = 0;
89
+ for (int i = 0; i < iovcnt; i++) {
90
+ #ifdef HELPER_LOG_PACKETS
91
+ ESP_LOGVV(TAG, "Sending raw: %s",
92
+ format_hex_pretty(reinterpret_cast<uint8_t *>(iov[i].iov_base), iov[i].iov_len).c_str());
93
+ #endif
94
+ total_write_len += iov[i].iov_len;
95
+ }
96
+
97
+ if (!tx_buf.empty()) {
98
+ // try to empty tx_buf first
99
+ while (!tx_buf.empty()) {
100
+ ssize_t sent = socket->write(tx_buf.data(), tx_buf.size());
101
+ if (is_would_block(sent)) {
102
+ break;
103
+ } else if (sent == -1) {
104
+ ESP_LOGVV(TAG, "%s: Socket write failed with errno %d", info.c_str(), errno);
105
+ state = failed_state;
106
+ return APIError::SOCKET_WRITE_FAILED; // Socket write failed
107
+ }
108
+ // TODO: inefficient if multiple packets in txbuf
109
+ // replace with deque of buffers
110
+ tx_buf.erase(tx_buf.begin(), tx_buf.begin() + sent);
111
+ }
112
+ }
113
+
114
+ if (!tx_buf.empty()) {
115
+ // tx buf not empty, can't write now because then stream would be inconsistent
116
+ // Reserve space upfront to avoid multiple reallocations
117
+ tx_buf.reserve(tx_buf.size() + total_write_len);
118
+ for (int i = 0; i < iovcnt; i++) {
119
+ tx_buf.insert(tx_buf.end(), reinterpret_cast<uint8_t *>(iov[i].iov_base),
120
+ reinterpret_cast<uint8_t *>(iov[i].iov_base) + iov[i].iov_len);
121
+ }
122
+ return APIError::OK; // Success, data buffered
123
+ }
124
+
125
+ ssize_t sent = socket->writev(iov, iovcnt);
126
+ if (is_would_block(sent)) {
127
+ // operation would block, add buffer to tx_buf
128
+ // Reserve space upfront to avoid multiple reallocations
129
+ tx_buf.reserve(tx_buf.size() + total_write_len);
130
+ for (int i = 0; i < iovcnt; i++) {
131
+ tx_buf.insert(tx_buf.end(), reinterpret_cast<uint8_t *>(iov[i].iov_base),
132
+ reinterpret_cast<uint8_t *>(iov[i].iov_base) + iov[i].iov_len);
133
+ }
134
+ return APIError::OK; // Success, data buffered
135
+ } else if (sent == -1) {
136
+ // an error occurred
137
+ ESP_LOGVV(TAG, "%s: Socket write failed with errno %d", info.c_str(), errno);
138
+ state = failed_state;
139
+ return APIError::SOCKET_WRITE_FAILED; // Socket write failed
140
+ } else if ((size_t) sent != total_write_len) {
141
+ // partially sent, add end to tx_buf
142
+ size_t remaining = total_write_len - sent;
143
+ // Reserve space upfront to avoid multiple reallocations
144
+ tx_buf.reserve(tx_buf.size() + remaining);
145
+
146
+ size_t to_consume = sent;
147
+ for (int i = 0; i < iovcnt; i++) {
148
+ if (to_consume >= iov[i].iov_len) {
149
+ to_consume -= iov[i].iov_len;
150
+ } else {
151
+ tx_buf.insert(tx_buf.end(), reinterpret_cast<uint8_t *>(iov[i].iov_base) + to_consume,
152
+ reinterpret_cast<uint8_t *>(iov[i].iov_base) + iov[i].iov_len);
153
+ to_consume = 0;
154
+ }
155
+ }
156
+ return APIError::OK; // Success, data buffered
157
+ }
158
+ return APIError::OK; // Success, all data sent
159
+ }
160
+
75
161
  #define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, info_.c_str(), ##__VA_ARGS__)
76
162
  // uncomment to log raw packets
77
163
  //#define HELPER_LOG_PACKETS
@@ -546,71 +632,6 @@ APIError APINoiseFrameHelper::try_send_tx_buf_() {
546
632
 
547
633
  return APIError::OK;
548
634
  }
549
- /** Write the data to the socket, or buffer it a write would block
550
- *
551
- * @param data The data to write
552
- * @param len The length of data
553
- */
554
- APIError APINoiseFrameHelper::write_raw_(const struct iovec *iov, int iovcnt) {
555
- if (iovcnt == 0)
556
- return APIError::OK;
557
- APIError aerr;
558
-
559
- size_t total_write_len = 0;
560
- for (int i = 0; i < iovcnt; i++) {
561
- #ifdef HELPER_LOG_PACKETS
562
- ESP_LOGVV(TAG, "Sending raw: %s",
563
- format_hex_pretty(reinterpret_cast<uint8_t *>(iov[i].iov_base), iov[i].iov_len).c_str());
564
- #endif
565
- total_write_len += iov[i].iov_len;
566
- }
567
-
568
- if (!tx_buf_.empty()) {
569
- // try to empty tx_buf_ first
570
- aerr = try_send_tx_buf_();
571
- if (aerr != APIError::OK && aerr != APIError::WOULD_BLOCK)
572
- return aerr;
573
- }
574
-
575
- if (!tx_buf_.empty()) {
576
- // tx buf not empty, can't write now because then stream would be inconsistent
577
- for (int i = 0; i < iovcnt; i++) {
578
- tx_buf_.insert(tx_buf_.end(), reinterpret_cast<uint8_t *>(iov[i].iov_base),
579
- reinterpret_cast<uint8_t *>(iov[i].iov_base) + iov[i].iov_len);
580
- }
581
- return APIError::OK;
582
- }
583
-
584
- ssize_t sent = socket_->writev(iov, iovcnt);
585
- if (is_would_block(sent)) {
586
- // operation would block, add buffer to tx_buf
587
- for (int i = 0; i < iovcnt; i++) {
588
- tx_buf_.insert(tx_buf_.end(), reinterpret_cast<uint8_t *>(iov[i].iov_base),
589
- reinterpret_cast<uint8_t *>(iov[i].iov_base) + iov[i].iov_len);
590
- }
591
- return APIError::OK;
592
- } else if (sent == -1) {
593
- // an error occurred
594
- state_ = State::FAILED;
595
- HELPER_LOG("Socket write failed with errno %d", errno);
596
- return APIError::SOCKET_WRITE_FAILED;
597
- } else if ((size_t) sent != total_write_len) {
598
- // partially sent, add end to tx_buf
599
- size_t to_consume = sent;
600
- for (int i = 0; i < iovcnt; i++) {
601
- if (to_consume >= iov[i].iov_len) {
602
- to_consume -= iov[i].iov_len;
603
- } else {
604
- tx_buf_.insert(tx_buf_.end(), reinterpret_cast<uint8_t *>(iov[i].iov_base) + to_consume,
605
- reinterpret_cast<uint8_t *>(iov[i].iov_base) + iov[i].iov_len);
606
- to_consume = 0;
607
- }
608
- }
609
- return APIError::OK;
610
- }
611
- // fully sent
612
- return APIError::OK;
613
- }
614
635
  APIError APINoiseFrameHelper::write_frame_(const uint8_t *data, size_t len) {
615
636
  uint8_t header[3];
616
637
  header[0] = 0x01; // indicator
@@ -744,6 +765,11 @@ void noise_rand_bytes(void *output, size_t len) {
744
765
  }
745
766
  }
746
767
  }
768
+
769
+ // Explicit template instantiation for Noise
770
+ template APIError APIFrameHelper::write_raw_<APINoiseFrameHelper::State>(
771
+ const struct iovec *iov, int iovcnt, socket::Socket *socket, std::vector<uint8_t> &tx_buf_, const std::string &info,
772
+ APINoiseFrameHelper::State &state, APINoiseFrameHelper::State failed_state);
747
773
  #endif // USE_API_NOISE
748
774
 
749
775
  #ifdef USE_API_PLAINTEXT
@@ -933,6 +959,8 @@ APIError APIPlaintextFrameHelper::write_packet(uint16_t type, const uint8_t *pay
933
959
  }
934
960
 
935
961
  std::vector<uint8_t> header;
962
+ header.reserve(1 + api::ProtoSize::varint(static_cast<uint32_t>(payload_len)) +
963
+ api::ProtoSize::varint(static_cast<uint32_t>(type)));
936
964
  header.push_back(0x00);
937
965
  ProtoVarInt(payload_len).encode(header);
938
966
  ProtoVarInt(type).encode(header);
@@ -966,71 +994,6 @@ APIError APIPlaintextFrameHelper::try_send_tx_buf_() {
966
994
 
967
995
  return APIError::OK;
968
996
  }
969
- /** Write the data to the socket, or buffer it a write would block
970
- *
971
- * @param data The data to write
972
- * @param len The length of data
973
- */
974
- APIError APIPlaintextFrameHelper::write_raw_(const struct iovec *iov, int iovcnt) {
975
- if (iovcnt == 0)
976
- return APIError::OK;
977
- APIError aerr;
978
-
979
- size_t total_write_len = 0;
980
- for (int i = 0; i < iovcnt; i++) {
981
- #ifdef HELPER_LOG_PACKETS
982
- ESP_LOGVV(TAG, "Sending raw: %s",
983
- format_hex_pretty(reinterpret_cast<uint8_t *>(iov[i].iov_base), iov[i].iov_len).c_str());
984
- #endif
985
- total_write_len += iov[i].iov_len;
986
- }
987
-
988
- if (!tx_buf_.empty()) {
989
- // try to empty tx_buf_ first
990
- aerr = try_send_tx_buf_();
991
- if (aerr != APIError::OK && aerr != APIError::WOULD_BLOCK)
992
- return aerr;
993
- }
994
-
995
- if (!tx_buf_.empty()) {
996
- // tx buf not empty, can't write now because then stream would be inconsistent
997
- for (int i = 0; i < iovcnt; i++) {
998
- tx_buf_.insert(tx_buf_.end(), reinterpret_cast<uint8_t *>(iov[i].iov_base),
999
- reinterpret_cast<uint8_t *>(iov[i].iov_base) + iov[i].iov_len);
1000
- }
1001
- return APIError::OK;
1002
- }
1003
-
1004
- ssize_t sent = socket_->writev(iov, iovcnt);
1005
- if (is_would_block(sent)) {
1006
- // operation would block, add buffer to tx_buf
1007
- for (int i = 0; i < iovcnt; i++) {
1008
- tx_buf_.insert(tx_buf_.end(), reinterpret_cast<uint8_t *>(iov[i].iov_base),
1009
- reinterpret_cast<uint8_t *>(iov[i].iov_base) + iov[i].iov_len);
1010
- }
1011
- return APIError::OK;
1012
- } else if (sent == -1) {
1013
- // an error occurred
1014
- state_ = State::FAILED;
1015
- HELPER_LOG("Socket write failed with errno %d", errno);
1016
- return APIError::SOCKET_WRITE_FAILED;
1017
- } else if ((size_t) sent != total_write_len) {
1018
- // partially sent, add end to tx_buf
1019
- size_t to_consume = sent;
1020
- for (int i = 0; i < iovcnt; i++) {
1021
- if (to_consume >= iov[i].iov_len) {
1022
- to_consume -= iov[i].iov_len;
1023
- } else {
1024
- tx_buf_.insert(tx_buf_.end(), reinterpret_cast<uint8_t *>(iov[i].iov_base) + to_consume,
1025
- reinterpret_cast<uint8_t *>(iov[i].iov_base) + iov[i].iov_len);
1026
- to_consume = 0;
1027
- }
1028
- }
1029
- return APIError::OK;
1030
- }
1031
- // fully sent
1032
- return APIError::OK;
1033
- }
1034
997
 
1035
998
  APIError APIPlaintextFrameHelper::close() {
1036
999
  state_ = State::CLOSED;
@@ -1048,6 +1011,11 @@ APIError APIPlaintextFrameHelper::shutdown(int how) {
1048
1011
  }
1049
1012
  return APIError::OK;
1050
1013
  }
1014
+
1015
+ // Explicit template instantiation for Plaintext
1016
+ template APIError APIFrameHelper::write_raw_<APIPlaintextFrameHelper::State>(
1017
+ const struct iovec *iov, int iovcnt, socket::Socket *socket, std::vector<uint8_t> &tx_buf_, const std::string &info,
1018
+ APIPlaintextFrameHelper::State &state, APIPlaintextFrameHelper::State failed_state);
1051
1019
  #endif // USE_API_PLAINTEXT
1052
1020
 
1053
1021
  } // namespace api
@@ -72,6 +72,12 @@ class APIFrameHelper {
72
72
  virtual APIError shutdown(int how) = 0;
73
73
  // Give this helper a name for logging
74
74
  virtual void set_log_info(std::string info) = 0;
75
+
76
+ protected:
77
+ // Common implementation for writing raw data to socket
78
+ template<typename StateEnum>
79
+ APIError write_raw_(const struct iovec *iov, int iovcnt, socket::Socket *socket, std::vector<uint8_t> &tx_buf,
80
+ const std::string &info, StateEnum &state, StateEnum failed_state);
75
81
  };
76
82
 
77
83
  #ifdef USE_API_NOISE
@@ -103,7 +109,9 @@ class APINoiseFrameHelper : public APIFrameHelper {
103
109
  APIError try_read_frame_(ParsedFrame *frame);
104
110
  APIError try_send_tx_buf_();
105
111
  APIError write_frame_(const uint8_t *data, size_t len);
106
- APIError write_raw_(const struct iovec *iov, int iovcnt);
112
+ inline APIError write_raw_(const struct iovec *iov, int iovcnt) {
113
+ return APIFrameHelper::write_raw_(iov, iovcnt, socket_.get(), tx_buf_, info_, state_, State::FAILED);
114
+ }
107
115
  APIError init_handshake_();
108
116
  APIError check_handshake_finished_();
109
117
  void send_explicit_handshake_reject_(const std::string &reason);
@@ -164,7 +172,9 @@ class APIPlaintextFrameHelper : public APIFrameHelper {
164
172
 
165
173
  APIError try_read_frame_(ParsedFrame *frame);
166
174
  APIError try_send_tx_buf_();
167
- APIError write_raw_(const struct iovec *iov, int iovcnt);
175
+ inline APIError write_raw_(const struct iovec *iov, int iovcnt) {
176
+ return APIFrameHelper::write_raw_(iov, iovcnt, socket_.get(), tx_buf_, info_, state_, State::FAILED);
177
+ }
168
178
 
169
179
  std::unique_ptr<socket::Socket> socket_;
170
180
 
@@ -1,6 +1,6 @@
1
1
  #pragma once
2
- #include <cstdint>
3
2
  #include <array>
3
+ #include <cstdint>
4
4
  #include "esphome/core/defines.h"
5
5
 
6
6
  namespace esphome {
@@ -11,11 +11,20 @@ using psk_t = std::array<uint8_t, 32>;
11
11
 
12
12
  class APINoiseContext {
13
13
  public:
14
- void set_psk(psk_t psk) { psk_ = psk; }
15
- const psk_t &get_psk() const { return psk_; }
14
+ void set_psk(psk_t psk) {
15
+ this->psk_ = psk;
16
+ bool has_psk = false;
17
+ for (auto i : psk) {
18
+ has_psk |= i;
19
+ }
20
+ this->has_psk_ = has_psk;
21
+ }
22
+ const psk_t &get_psk() const { return this->psk_; }
23
+ bool has_psk() const { return this->has_psk_; }
16
24
 
17
25
  protected:
18
- psk_t psk_;
26
+ psk_t psk_{};
27
+ bool has_psk_{false};
19
28
  };
20
29
  #endif // USE_API_NOISE
21
30