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
@@ -1,13 +1,8 @@
1
1
  #pragma once
2
2
 
3
- #include "esphome/core/component.h"
3
+ #include "esphome/core/defines.h"
4
+ #ifdef USE_NETWORK
4
5
  #include "esphome/components/network/ip_address.h"
5
- #ifdef USE_SENSOR
6
- #include "esphome/components/sensor/sensor.h"
7
- #endif
8
- #ifdef USE_BINARY_SENSOR
9
- #include "esphome/components/binary_sensor/binary_sensor.h"
10
- #endif
11
6
  #if defined(USE_SOCKET_IMPL_BSD_SOCKETS) || defined(USE_SOCKET_IMPL_LWIP_SOCKETS)
12
7
  #include "esphome/components/socket/socket.h"
13
8
  #endif
@@ -15,116 +10,35 @@
15
10
  #include <WiFiUdp.h>
16
11
  #endif
17
12
  #include <vector>
18
- #include <map>
19
13
 
20
14
  namespace esphome {
21
15
  namespace udp {
22
16
 
23
- struct Provider {
24
- std::vector<uint8_t> encryption_key;
25
- const char *name;
26
- uint32_t last_code[2];
27
- };
28
-
29
- #ifdef USE_SENSOR
30
- struct Sensor {
31
- sensor::Sensor *sensor;
32
- const char *id;
33
- bool updated;
34
- };
35
- #endif
36
- #ifdef USE_BINARY_SENSOR
37
- struct BinarySensor {
38
- binary_sensor::BinarySensor *sensor;
39
- const char *id;
40
- bool updated;
41
- };
42
- #endif
43
-
44
- class UDPComponent : public PollingComponent {
17
+ static const size_t MAX_PACKET_SIZE = 508;
18
+ class UDPComponent : public Component {
45
19
  public:
46
- void setup() override;
47
- void loop() override;
48
- void update() override;
49
- void dump_config() override;
50
-
51
- #ifdef USE_SENSOR
52
- void add_sensor(const char *id, sensor::Sensor *sensor) {
53
- Sensor st{sensor, id, true};
54
- this->sensors_.push_back(st);
55
- }
56
- void add_remote_sensor(const char *hostname, const char *remote_id, sensor::Sensor *sensor) {
57
- this->add_provider(hostname);
58
- this->remote_sensors_[hostname][remote_id] = sensor;
59
- }
60
- #endif
61
- #ifdef USE_BINARY_SENSOR
62
- void add_binary_sensor(const char *id, binary_sensor::BinarySensor *sensor) {
63
- BinarySensor st{sensor, id, true};
64
- this->binary_sensors_.push_back(st);
65
- }
66
-
67
- void add_remote_binary_sensor(const char *hostname, const char *remote_id, binary_sensor::BinarySensor *sensor) {
68
- this->add_provider(hostname);
69
- this->remote_binary_sensors_[hostname][remote_id] = sensor;
70
- }
71
- #endif
72
20
  void add_address(const char *addr) { this->addresses_.emplace_back(addr); }
73
- #ifdef USE_NETWORK
74
21
  void set_listen_address(const char *listen_addr) { this->listen_address_ = network::IPAddress(listen_addr); }
75
- #endif
76
- void set_port(uint16_t port) { this->port_ = port; }
77
- float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
78
-
79
- void add_provider(const char *hostname) {
80
- if (this->providers_.count(hostname) == 0) {
81
- Provider provider;
82
- provider.encryption_key = std::vector<uint8_t>{};
83
- provider.last_code[0] = 0;
84
- provider.last_code[1] = 0;
85
- provider.name = hostname;
86
- this->providers_[hostname] = provider;
87
- #ifdef USE_SENSOR
88
- this->remote_sensors_[hostname] = std::map<std::string, sensor::Sensor *>();
89
- #endif
90
- #ifdef USE_BINARY_SENSOR
91
- this->remote_binary_sensors_[hostname] = std::map<std::string, binary_sensor::BinarySensor *>();
92
- #endif
93
- }
94
- }
95
-
96
- void set_encryption_key(std::vector<uint8_t> key) { this->encryption_key_ = std::move(key); }
97
- void set_rolling_code_enable(bool enable) { this->rolling_code_enable_ = enable; }
98
- void set_ping_pong_enable(bool enable) { this->ping_pong_enable_ = enable; }
99
- void set_ping_pong_recycle_time(uint32_t recycle_time) { this->ping_pong_recyle_time_ = recycle_time; }
100
- void set_provider_encryption(const char *name, std::vector<uint8_t> key) {
101
- this->providers_[name].encryption_key = std::move(key);
22
+ void set_listen_port(uint16_t port) { this->listen_port_ = port; }
23
+ void set_broadcast_port(uint16_t port) { this->broadcast_port_ = port; }
24
+ void set_should_broadcast() { this->should_broadcast_ = true; }
25
+ void set_should_listen() { this->should_listen_ = true; }
26
+ void add_listener(std::function<void(std::vector<uint8_t> &)> &&listener) {
27
+ this->packet_listeners_.add(std::move(listener));
102
28
  }
29
+ void setup() override;
30
+ void loop() override;
31
+ void dump_config() override;
32
+ void send_packet(const uint8_t *data, size_t size);
33
+ void send_packet(const std::vector<uint8_t> &buf) { this->send_packet(buf.data(), buf.size()); }
34
+ float get_setup_priority() const override { return setup_priority::AFTER_WIFI; };
103
35
 
104
36
  protected:
105
- void send_data_(bool all);
106
- void process_(uint8_t *buf, size_t len);
107
- void flush_();
108
- void add_data_(uint8_t key, const char *id, float data);
109
- void add_data_(uint8_t key, const char *id, uint32_t data);
110
- void increment_code_();
111
- void add_binary_data_(uint8_t key, const char *id, bool data);
112
- void init_data_();
113
-
114
- bool updated_{};
115
- uint16_t port_{18511};
116
- uint32_t ping_key_{};
117
- uint32_t rolling_code_[2]{};
118
- bool rolling_code_enable_{};
119
- bool ping_pong_enable_{};
120
- uint32_t ping_pong_recyle_time_{};
121
- uint32_t last_key_time_{};
122
- bool resend_ping_key_{};
123
- bool resend_data_{};
124
- bool should_send_{};
125
- const char *name_{};
37
+ uint16_t listen_port_{};
38
+ uint16_t broadcast_port_{};
39
+ bool should_broadcast_{};
126
40
  bool should_listen_{};
127
- ESPPreferenceObject pref_;
41
+ CallbackManager<void(std::vector<uint8_t> &)> packet_listeners_{};
128
42
 
129
43
  #if defined(USE_SOCKET_IMPL_BSD_SOCKETS) || defined(USE_SOCKET_IMPL_LWIP_SOCKETS)
130
44
  std::unique_ptr<socket::Socket> broadcast_socket_ = nullptr;
@@ -135,32 +49,11 @@ class UDPComponent : public PollingComponent {
135
49
  std::vector<IPAddress> ipaddrs_{};
136
50
  WiFiUDP udp_client_{};
137
51
  #endif
138
- std::vector<uint8_t> encryption_key_{};
139
52
  std::vector<std::string> addresses_{};
140
53
 
141
- #ifdef USE_SENSOR
142
- std::vector<Sensor> sensors_{};
143
- std::map<std::string, std::map<std::string, sensor::Sensor *>> remote_sensors_{};
144
- #endif
145
- #ifdef USE_BINARY_SENSOR
146
- std::vector<BinarySensor> binary_sensors_{};
147
- std::map<std::string, std::map<std::string, binary_sensor::BinarySensor *>> remote_binary_sensors_{};
148
- #endif
149
- #ifdef USE_NETWORK
150
54
  optional<network::IPAddress> listen_address_{};
151
- #endif
152
- std::map<std::string, Provider> providers_{};
153
- std::vector<uint8_t> ping_header_{};
154
- std::vector<uint8_t> header_{};
155
- std::vector<uint8_t> data_{};
156
- std::map<const char *, uint32_t> ping_keys_{};
157
- void add_key_(const char *name, uint32_t key);
158
- void send_ping_pong_request_();
159
- void send_packet_(void *data, size_t len);
160
- void process_ping_request_(const char *name, uint8_t *ptr, size_t len);
161
-
162
- inline bool is_encrypted_() { return !this->encryption_key_.empty(); }
163
55
  };
164
56
 
165
57
  } // namespace udp
166
58
  } // namespace esphome
59
+ #endif
@@ -6,6 +6,7 @@ from esphome.const import (
6
6
  CONF_DEVICE_CLASS,
7
7
  CONF_ENTITY_CATEGORY,
8
8
  CONF_FORCE_UPDATE,
9
+ CONF_ICON,
9
10
  CONF_ID,
10
11
  CONF_MQTT_ID,
11
12
  CONF_WEB_SERVER,
@@ -14,6 +15,7 @@ from esphome.const import (
14
15
  ENTITY_CATEGORY_CONFIG,
15
16
  )
16
17
  from esphome.core import CORE, coroutine_with_priority
18
+ from esphome.cpp_generator import MockObjClass
17
19
  from esphome.cpp_helpers import setup_entity
18
20
 
19
21
  CODEOWNERS = ["@jesserockz"]
@@ -38,7 +40,7 @@ DEVICE_CLASSES = [
38
40
 
39
41
  CONF_ON_UPDATE_AVAILABLE = "on_update_available"
40
42
 
41
- UPDATE_SCHEMA = (
43
+ _UPDATE_SCHEMA = (
42
44
  cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
43
45
  .extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA)
44
46
  .extend(
@@ -56,6 +58,34 @@ UPDATE_SCHEMA = (
56
58
  )
57
59
 
58
60
 
61
+ def update_schema(
62
+ class_: MockObjClass = cv.UNDEFINED,
63
+ *,
64
+ icon: str = cv.UNDEFINED,
65
+ device_class: str = cv.UNDEFINED,
66
+ entity_category: str = cv.UNDEFINED,
67
+ ) -> cv.Schema:
68
+ schema = {}
69
+
70
+ if class_ is not cv.UNDEFINED:
71
+ schema[cv.GenerateID()] = cv.declare_id(class_)
72
+
73
+ for key, default, validator in [
74
+ (CONF_ICON, icon, cv.icon),
75
+ (CONF_DEVICE_CLASS, device_class, cv.one_of(*DEVICE_CLASSES, lower=True)),
76
+ (CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
77
+ ]:
78
+ if default is not cv.UNDEFINED:
79
+ schema[cv.Optional(key, default=default)] = validator
80
+
81
+ return _UPDATE_SCHEMA.extend(schema)
82
+
83
+
84
+ # Remove before 2025.11.0
85
+ UPDATE_SCHEMA = update_schema()
86
+ UPDATE_SCHEMA.add_extra(cv.deprecated_schema_constant("update"))
87
+
88
+
59
89
  async def setup_update_core_(var, config):
60
90
  await setup_entity(var, config)
61
91
 
@@ -1,7 +1,5 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import climate
3
- import esphome.config_validation as cv
4
- from esphome.const import CONF_ID
5
3
 
6
4
  from .. import (
7
5
  UPONOR_SMATRIX_DEVICE_SCHEMA,
@@ -19,15 +17,12 @@ UponorSmatrixClimate = uponor_smatrix_ns.class_(
19
17
  UponorSmatrixDevice,
20
18
  )
21
19
 
22
- CONFIG_SCHEMA = climate.CLIMATE_SCHEMA.extend(
23
- {
24
- cv.GenerateID(): cv.declare_id(UponorSmatrixClimate),
25
- }
26
- ).extend(UPONOR_SMATRIX_DEVICE_SCHEMA)
20
+ CONFIG_SCHEMA = climate.climate_schema(UponorSmatrixClimate).extend(
21
+ UPONOR_SMATRIX_DEVICE_SCHEMA
22
+ )
27
23
 
28
24
 
29
25
  async def to_code(config):
30
- var = cg.new_Pvariable(config[CONF_ID])
26
+ var = await climate.new_climate(config)
31
27
  await cg.register_component(var, config)
32
- await climate.register_climate(var, config)
33
28
  await register_uponor_smatrix_device(var, config)
@@ -1,19 +1,59 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import text_sensor
3
3
  import esphome.config_validation as cv
4
- from esphome.const import ENTITY_CATEGORY_DIAGNOSTIC, ICON_TIMER
4
+ from esphome.const import (
5
+ CONF_FORMAT,
6
+ CONF_HOURS,
7
+ CONF_ID,
8
+ CONF_MINUTES,
9
+ CONF_SECONDS,
10
+ ENTITY_CATEGORY_DIAGNOSTIC,
11
+ ICON_TIMER,
12
+ )
5
13
 
6
14
  uptime_ns = cg.esphome_ns.namespace("uptime")
7
15
  UptimeTextSensor = uptime_ns.class_(
8
16
  "UptimeTextSensor", text_sensor.TextSensor, cg.PollingComponent
9
17
  )
10
- CONFIG_SCHEMA = text_sensor.text_sensor_schema(
11
- UptimeTextSensor,
12
- icon=ICON_TIMER,
13
- entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
14
- ).extend(cv.polling_component_schema("30s"))
18
+
19
+ CONF_SEPARATOR = "separator"
20
+ CONF_DAYS = "days"
21
+ CONF_EXPAND = "expand"
22
+
23
+ CONFIG_SCHEMA = (
24
+ text_sensor.text_sensor_schema(
25
+ UptimeTextSensor,
26
+ icon=ICON_TIMER,
27
+ entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
28
+ )
29
+ .extend(
30
+ {
31
+ cv.Optional(CONF_FORMAT, default={}): cv.Schema(
32
+ {
33
+ cv.Optional(CONF_DAYS, default="d"): cv.string_strict,
34
+ cv.Optional(CONF_HOURS, default="h"): cv.string_strict,
35
+ cv.Optional(CONF_MINUTES, default="m"): cv.string_strict,
36
+ cv.Optional(CONF_SECONDS, default="s"): cv.string_strict,
37
+ cv.Optional(CONF_SEPARATOR, default=""): cv.string_strict,
38
+ cv.Optional(CONF_EXPAND, default=False): cv.boolean,
39
+ }
40
+ )
41
+ }
42
+ )
43
+ .extend(cv.polling_component_schema("30s"))
44
+ )
15
45
 
16
46
 
17
47
  async def to_code(config):
18
- var = await text_sensor.new_text_sensor(config)
48
+ format = config[CONF_FORMAT]
49
+ var = cg.new_Pvariable(
50
+ config[CONF_ID],
51
+ format[CONF_DAYS],
52
+ format[CONF_HOURS],
53
+ format[CONF_MINUTES],
54
+ format[CONF_SECONDS],
55
+ format[CONF_SEPARATOR],
56
+ format[CONF_EXPAND],
57
+ )
58
+ await text_sensor.register_text_sensor(var, config)
19
59
  await cg.register_component(var, config)
@@ -16,6 +16,11 @@ void UptimeTextSensor::setup() {
16
16
  this->update();
17
17
  }
18
18
 
19
+ void UptimeTextSensor::insert_buffer_(std::string &buffer, const char *key, unsigned value) const {
20
+ buffer.insert(0, this->separator_);
21
+ buffer.insert(0, str_sprintf("%u%s", value, key));
22
+ }
23
+
19
24
  void UptimeTextSensor::update() {
20
25
  auto now = millis();
21
26
  // get whole seconds since last update. Note that even if the millis count has overflowed between updates,
@@ -32,25 +37,25 @@ void UptimeTextSensor::update() {
32
37
  unsigned remainder = uptime % 60;
33
38
  uptime /= 60;
34
39
  if (interval < 30) {
35
- buffer.insert(0, str_sprintf("%us", remainder));
36
- if (uptime == 0)
40
+ this->insert_buffer_(buffer, this->seconds_text_, remainder);
41
+ if (!this->expand_ && uptime == 0)
37
42
  break;
38
43
  }
39
44
  remainder = uptime % 60;
40
45
  uptime /= 60;
41
46
  if (interval < 1800) {
42
- buffer.insert(0, str_sprintf("%um", remainder));
43
- if (uptime == 0)
47
+ this->insert_buffer_(buffer, this->minutes_text_, remainder);
48
+ if (!this->expand_ && uptime == 0)
44
49
  break;
45
50
  }
46
51
  remainder = uptime % 24;
47
52
  uptime /= 24;
48
53
  if (interval < 12 * 3600) {
49
- buffer.insert(0, str_sprintf("%uh", remainder));
50
- if (uptime == 0)
54
+ this->insert_buffer_(buffer, this->hours_text_, remainder);
55
+ if (!this->expand_ && uptime == 0)
51
56
  break;
52
57
  }
53
- buffer.insert(0, str_sprintf("%ud", (unsigned) uptime));
58
+ this->insert_buffer_(buffer, this->days_text_, (unsigned) uptime);
54
59
  break;
55
60
  }
56
61
  this->publish_state(buffer);
@@ -10,13 +10,32 @@ namespace uptime {
10
10
 
11
11
  class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent {
12
12
  public:
13
+ UptimeTextSensor(const char *days_text, const char *hours_text, const char *minutes_text, const char *seconds_text,
14
+ const char *separator, bool expand)
15
+ : days_text_(days_text),
16
+ hours_text_(hours_text),
17
+ minutes_text_(minutes_text),
18
+ seconds_text_(seconds_text),
19
+ separator_(separator),
20
+ expand_(expand) {}
13
21
  void update() override;
14
22
  void dump_config() override;
15
23
  void setup() override;
16
24
 
17
25
  float get_setup_priority() const override;
26
+ void set_days(const char *days_text) { this->days_text_ = days_text; }
27
+ void set_hours(const char *hours_text) { this->hours_text_ = hours_text; }
28
+ void set_minutes(const char *minutes_text) { this->minutes_text_ = minutes_text; }
29
+ void set_seconds(const char *seconds_text) { this->seconds_text_ = seconds_text; }
18
30
 
19
31
  protected:
32
+ void insert_buffer_(std::string &buffer, const char *key, unsigned value) const;
33
+ const char *days_text_;
34
+ const char *hours_text_;
35
+ const char *minutes_text_;
36
+ const char *seconds_text_;
37
+ const char *separator_;
38
+ bool expand_{};
20
39
  uint32_t uptime_{0}; // uptime in seconds, will overflow after 136 years
21
40
  uint32_t last_ms_{0};
22
41
  };
@@ -5,6 +5,8 @@ from esphome.components import mqtt, web_server
5
5
  import esphome.config_validation as cv
6
6
  from esphome.const import (
7
7
  CONF_DEVICE_CLASS,
8
+ CONF_ENTITY_CATEGORY,
9
+ CONF_ICON,
8
10
  CONF_ID,
9
11
  CONF_MQTT_ID,
10
12
  CONF_ON_OPEN,
@@ -20,6 +22,7 @@ from esphome.const import (
20
22
  DEVICE_CLASS_WATER,
21
23
  )
22
24
  from esphome.core import CORE, coroutine_with_priority
25
+ from esphome.cpp_generator import MockObjClass
23
26
  from esphome.cpp_helpers import setup_entity
24
27
 
25
28
  IS_PLATFORM_COMPONENT = True
@@ -71,7 +74,7 @@ ValveClosedTrigger = valve_ns.class_(
71
74
 
72
75
  CONF_ON_CLOSED = "on_closed"
73
76
 
74
- VALVE_SCHEMA = (
77
+ _VALVE_SCHEMA = (
75
78
  cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
76
79
  .extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA)
77
80
  .extend(
@@ -100,7 +103,35 @@ VALVE_SCHEMA = (
100
103
  )
101
104
 
102
105
 
103
- async def setup_valve_core_(var, config):
106
+ def valve_schema(
107
+ class_: MockObjClass = cv.UNDEFINED,
108
+ *,
109
+ device_class: str = cv.UNDEFINED,
110
+ entity_category: str = cv.UNDEFINED,
111
+ icon: str = cv.UNDEFINED,
112
+ ) -> cv.Schema:
113
+ schema = {}
114
+
115
+ if class_ is not cv.UNDEFINED:
116
+ schema[cv.GenerateID()] = cv.declare_id(class_)
117
+
118
+ for key, default, validator in [
119
+ (CONF_DEVICE_CLASS, device_class, cv.one_of(*DEVICE_CLASSES, lower=True)),
120
+ (CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
121
+ (CONF_ICON, icon, cv.icon),
122
+ ]:
123
+ if default is not cv.UNDEFINED:
124
+ schema[cv.Optional(key, default=default)] = validator
125
+
126
+ return _VALVE_SCHEMA.extend(schema)
127
+
128
+
129
+ # Remove before 2025.11.0
130
+ VALVE_SCHEMA = valve_schema()
131
+ VALVE_SCHEMA.add_extra(cv.deprecated_schema_constant("valve"))
132
+
133
+
134
+ async def _setup_valve_core(var, config):
104
135
  await setup_entity(var, config)
105
136
 
106
137
  if device_class_config := config.get(CONF_DEVICE_CLASS):
@@ -132,7 +163,7 @@ async def register_valve(var, config):
132
163
  if not CORE.has_id(config[CONF_ID]):
133
164
  var = cg.Pvariable(config[CONF_ID], var)
134
165
  cg.add(cg.App.register_valve(var))
135
- await setup_valve_core_(var, config)
166
+ await _setup_valve_core(var, config)
136
167
 
137
168
 
138
169
  async def new_valve(config, *args):
@@ -1,7 +1,7 @@
1
1
  #pragma once
2
2
 
3
- #include "esphome/core/component.h"
4
3
  #include "esphome/core/automation.h"
4
+ #include "esphome/core/component.h"
5
5
  #include "valve.h"
6
6
 
7
7
  namespace esphome {
@@ -67,24 +67,6 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
67
67
  Valve *valve_;
68
68
  };
69
69
 
70
- template<typename... Ts> class ValvePublishAction : public Action<Ts...> {
71
- public:
72
- ValvePublishAction(Valve *valve) : valve_(valve) {}
73
- TEMPLATABLE_VALUE(float, position)
74
- TEMPLATABLE_VALUE(ValveOperation, current_operation)
75
-
76
- void play(Ts... x) override {
77
- if (this->position_.has_value())
78
- this->valve_->position = this->position_.value(x...);
79
- if (this->current_operation_.has_value())
80
- this->valve_->current_operation = this->current_operation_.value(x...);
81
- this->valve_->publish_state();
82
- }
83
-
84
- protected:
85
- Valve *valve_;
86
- };
87
-
88
70
  template<typename... Ts> class ValveIsOpenCondition : public Condition<Ts...> {
89
71
  public:
90
72
  ValveIsOpenCondition(Valve *valve) : valve_(valve) {}
@@ -20,6 +20,7 @@ VL53L0XSensor = vl53l0x_ns.class_(
20
20
 
21
21
  CONF_SIGNAL_RATE_LIMIT = "signal_rate_limit"
22
22
  CONF_LONG_RANGE = "long_range"
23
+ CONF_TIMING_BUDGET = "timing_budget"
23
24
 
24
25
 
25
26
  def check_keys(obj):
@@ -54,6 +55,13 @@ CONFIG_SCHEMA = cv.All(
54
55
  cv.Optional(CONF_LONG_RANGE, default=False): cv.boolean,
55
56
  cv.Optional(CONF_TIMEOUT, default="10ms"): check_timeout,
56
57
  cv.Optional(CONF_ENABLE_PIN): pins.gpio_output_pin_schema,
58
+ cv.Optional(CONF_TIMING_BUDGET): cv.All(
59
+ cv.positive_time_period_microseconds,
60
+ cv.Range(
61
+ min=cv.TimePeriod(microseconds=20000),
62
+ max=cv.TimePeriod(microseconds=4294967295),
63
+ ),
64
+ ),
57
65
  }
58
66
  )
59
67
  .extend(cv.polling_component_schema("60s"))
@@ -73,4 +81,7 @@ async def to_code(config):
73
81
  enable = await cg.gpio_pin_expression(config[CONF_ENABLE_PIN])
74
82
  cg.add(var.set_enable_pin(enable))
75
83
 
84
+ if timing_budget := config.get(CONF_TIMING_BUDGET):
85
+ cg.add(var.set_timing_budget(timing_budget))
86
+
76
87
  await i2c.register_i2c_device(var, config)
@@ -28,6 +28,7 @@ void VL53L0XSensor::dump_config() {
28
28
  LOG_PIN(" Enable Pin: ", this->enable_pin_);
29
29
  }
30
30
  ESP_LOGCONFIG(TAG, " Timeout: %u%s", this->timeout_us_, this->timeout_us_ > 0 ? "us" : " (no timeout)");
31
+ ESP_LOGCONFIG(TAG, " Timing Budget %uus ", this->measurement_timing_budget_us_);
31
32
  }
32
33
 
33
34
  void VL53L0XSensor::setup() {
@@ -230,7 +231,10 @@ void VL53L0XSensor::setup() {
230
231
  reg(0x84) &= ~0x10;
231
232
  reg(0x0B) = 0x01;
232
233
 
233
- measurement_timing_budget_us_ = get_measurement_timing_budget_();
234
+ if (this->measurement_timing_budget_us_ == 0) {
235
+ this->measurement_timing_budget_us_ = this->get_measurement_timing_budget_();
236
+ }
237
+
234
238
  reg(0x01) = 0xE8;
235
239
  set_measurement_timing_budget_(measurement_timing_budget_us_);
236
240
  reg(0x01) = 0x01;
@@ -39,6 +39,7 @@ class VL53L0XSensor : public sensor::Sensor, public PollingComponent, public i2c
39
39
  void set_long_range(bool long_range) { long_range_ = long_range; }
40
40
  void set_timeout_us(uint32_t timeout_us) { this->timeout_us_ = timeout_us; }
41
41
  void set_enable_pin(GPIOPin *enable) { this->enable_pin_ = enable; }
42
+ void set_timing_budget(uint32_t timing_budget) { this->measurement_timing_budget_us_ = timing_budget; }
42
43
 
43
44
  protected:
44
45
  uint32_t get_measurement_timing_budget_();
@@ -59,7 +60,7 @@ class VL53L0XSensor : public sensor::Sensor, public PollingComponent, public i2c
59
60
  float signal_rate_limit_;
60
61
  bool long_range_;
61
62
  GPIOPin *enable_pin_{nullptr};
62
- uint32_t measurement_timing_budget_us_;
63
+ uint32_t measurement_timing_budget_us_{0};
63
64
  bool initiated_read_{false};
64
65
  bool waiting_for_interrupt_{false};
65
66
  uint8_t stop_variable_;
@@ -1,7 +1,7 @@
1
1
  from esphome import automation
2
2
  from esphome.automation import register_action, register_condition
3
3
  import esphome.codegen as cg
4
- from esphome.components import media_player, microphone, speaker
4
+ from esphome.components import media_player, micro_wake_word, microphone, speaker
5
5
  import esphome.config_validation as cv
6
6
  from esphome.const import (
7
7
  CONF_ID,
@@ -41,6 +41,7 @@ CONF_AUTO_GAIN = "auto_gain"
41
41
  CONF_NOISE_SUPPRESSION_LEVEL = "noise_suppression_level"
42
42
  CONF_VOLUME_MULTIPLIER = "volume_multiplier"
43
43
 
44
+ CONF_MICRO_WAKE_WORD = "micro_wake_word"
44
45
  CONF_WAKE_WORD = "wake_word"
45
46
 
46
47
  CONF_CONVERSATION_TIMEOUT = "conversation_timeout"
@@ -88,14 +89,22 @@ CONFIG_SCHEMA = cv.All(
88
89
  cv.Schema(
89
90
  {
90
91
  cv.GenerateID(): cv.declare_id(VoiceAssistant),
91
- cv.GenerateID(CONF_MICROPHONE): cv.use_id(microphone.Microphone),
92
- cv.Exclusive(CONF_SPEAKER, "output"): cv.use_id(speaker.Speaker),
92
+ cv.Optional(
93
+ CONF_MICROPHONE, default={}
94
+ ): microphone.microphone_source_schema(
95
+ min_bits_per_sample=16,
96
+ max_bits_per_sample=16,
97
+ min_channels=1,
98
+ max_channels=1,
99
+ ),
93
100
  cv.Exclusive(CONF_MEDIA_PLAYER, "output"): cv.use_id(
94
101
  media_player.MediaPlayer
95
102
  ),
103
+ cv.Exclusive(CONF_SPEAKER, "output"): cv.use_id(speaker.Speaker),
96
104
  cv.Optional(CONF_USE_WAKE_WORD, default=False): cv.boolean,
97
- cv.Optional(CONF_VAD_THRESHOLD): cv.All(
98
- cv.requires_component("esp_adf"), cv.only_with_esp_idf, cv.uint8_t
105
+ cv.Optional(CONF_MICRO_WAKE_WORD): cv.use_id(micro_wake_word.MicroWakeWord),
106
+ cv.Optional(CONF_VAD_THRESHOLD): cv.invalid(
107
+ "VAD threshold is no longer supported, as it requires the deprecated esp_adf external component. Use an i2s_audio microphone/speaker instead. Additionally, you may need to configure the audio_adc and audio_dac components depending on your hardware."
99
108
  ),
100
109
  cv.Optional(CONF_NOISE_SUPPRESSION_LEVEL, default=0): cv.int_range(0, 4),
101
110
  cv.Optional(CONF_AUTO_GAIN, default="0dBFS"): cv.All(
@@ -163,22 +172,39 @@ CONFIG_SCHEMA = cv.All(
163
172
  tts_stream_validate,
164
173
  )
165
174
 
175
+ FINAL_VALIDATE_SCHEMA = cv.All(
176
+ cv.Schema(
177
+ {
178
+ cv.Optional(
179
+ CONF_MICROPHONE
180
+ ): microphone.final_validate_microphone_source_schema(
181
+ "voice_assistant", sample_rate=16000
182
+ ),
183
+ },
184
+ extra=cv.ALLOW_EXTRA,
185
+ ),
186
+ )
187
+
166
188
 
167
189
  async def to_code(config):
168
190
  var = cg.new_Pvariable(config[CONF_ID])
169
191
  await cg.register_component(var, config)
170
192
 
171
- mic = await cg.get_variable(config[CONF_MICROPHONE])
172
- cg.add(var.set_microphone(mic))
193
+ mic_source = await microphone.microphone_source_to_code(config[CONF_MICROPHONE])
194
+ cg.add(var.set_microphone_source(mic_source))
173
195
 
174
- if CONF_SPEAKER in config:
175
- spkr = await cg.get_variable(config[CONF_SPEAKER])
176
- cg.add(var.set_speaker(spkr))
196
+ if CONF_MICRO_WAKE_WORD in config:
197
+ mww = await cg.get_variable(config[CONF_MICRO_WAKE_WORD])
198
+ cg.add(var.set_micro_wake_word(mww))
177
199
 
178
200
  if CONF_MEDIA_PLAYER in config:
179
201
  mp = await cg.get_variable(config[CONF_MEDIA_PLAYER])
180
202
  cg.add(var.set_media_player(mp))
181
203
 
204
+ if CONF_SPEAKER in config:
205
+ spkr = await cg.get_variable(config[CONF_SPEAKER])
206
+ cg.add(var.set_speaker(spkr))
207
+
182
208
  cg.add(var.set_use_wake_word(config[CONF_USE_WAKE_WORD]))
183
209
 
184
210
  if (vad_threshold := config.get(CONF_VAD_THRESHOLD)) is not None: