esphome 2025.4.2__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 (444) 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/as7341/as7341.h +1 -1
  26. esphome/components/at581x/at581x.h +4 -4
  27. esphome/components/atm90e32/__init__.py +1 -0
  28. esphome/components/atm90e32/atm90e32.cpp +576 -199
  29. esphome/components/atm90e32/atm90e32.h +128 -31
  30. esphome/components/atm90e32/atm90e32_reg.h +4 -2
  31. esphome/components/atm90e32/button/__init__.py +62 -10
  32. esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
  33. esphome/components/atm90e32/button/atm90e32_button.h +36 -4
  34. esphome/components/atm90e32/number/__init__.py +130 -0
  35. esphome/components/atm90e32/number/atm90e32_number.h +16 -0
  36. esphome/components/atm90e32/sensor.py +21 -4
  37. esphome/components/atm90e32/text_sensor/__init__.py +48 -0
  38. esphome/components/audio/__init__.py +96 -49
  39. esphome/components/audio/audio.h +48 -0
  40. esphome/components/audio/audio_decoder.cpp +1 -1
  41. esphome/components/audio/audio_resampler.cpp +2 -0
  42. esphome/components/audio/audio_resampler.h +1 -0
  43. esphome/components/ballu/climate.py +2 -9
  44. esphome/components/bang_bang/climate.py +5 -6
  45. esphome/components/bedjet/bedjet_hub.cpp +1 -0
  46. esphome/components/bedjet/climate/__init__.py +3 -8
  47. esphome/components/bedjet/fan/__init__.py +2 -11
  48. esphome/components/binary/fan/__init__.py +13 -16
  49. esphome/components/binary_sensor/__init__.py +13 -10
  50. esphome/components/bl0906/constants.h +16 -16
  51. esphome/components/ble_client/text_sensor/__init__.py +3 -5
  52. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
  53. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +136 -21
  54. esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
  55. esphome/components/button/__init__.py +11 -8
  56. esphome/components/canbus/canbus.cpp +3 -0
  57. esphome/components/canbus/canbus.h +16 -0
  58. esphome/components/ccs811/sensor.py +9 -6
  59. esphome/components/climate/__init__.py +35 -2
  60. esphome/components/climate/climate_mode.h +1 -1
  61. esphome/components/climate/climate_traits.h +63 -57
  62. esphome/components/climate_ir/__init__.py +57 -17
  63. esphome/components/climate_ir_lg/climate.py +2 -5
  64. esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
  65. esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
  66. esphome/components/color/__init__.py +2 -0
  67. esphome/components/const/__init__.py +5 -0
  68. esphome/components/coolix/climate.py +2 -9
  69. esphome/components/copy/cover/__init__.py +10 -9
  70. esphome/components/copy/fan/__init__.py +11 -9
  71. esphome/components/copy/lock/__init__.py +11 -9
  72. esphome/components/copy/text/__init__.py +9 -6
  73. esphome/components/cover/__init__.py +37 -2
  74. esphome/components/cse7766/cse7766.cpp +2 -1
  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/current_based/current_based_cover.cpp +2 -1
  82. esphome/components/daikin/climate.py +2 -9
  83. esphome/components/daikin/daikin.cpp +15 -9
  84. esphome/components/daikin/daikin.h +5 -5
  85. esphome/components/daikin_arc/climate.py +2 -7
  86. esphome/components/daikin_brc/climate.py +3 -5
  87. esphome/components/dallas_temp/dallas_temp.cpp +17 -24
  88. esphome/components/dallas_temp/dallas_temp.h +0 -1
  89. esphome/components/daly_bms/daly_bms.cpp +2 -1
  90. esphome/components/debug/debug_component.cpp +6 -1
  91. esphome/components/debug/debug_component.h +8 -0
  92. esphome/components/debug/debug_esp32.cpp +109 -254
  93. esphome/components/debug/sensor.py +14 -0
  94. esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
  95. esphome/components/delonghi/climate.py +2 -9
  96. esphome/components/demo/__init__.py +18 -20
  97. esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
  98. esphome/components/dps310/sensor.py +6 -6
  99. esphome/components/ee895/sensor.py +9 -9
  100. esphome/components/emmeti/climate.py +2 -9
  101. esphome/components/endstop/cover.py +17 -16
  102. esphome/components/endstop/endstop_cover.cpp +2 -1
  103. esphome/components/ens160_base/__init__.py +12 -9
  104. esphome/components/esp32/__init__.py +60 -3
  105. esphome/components/esp32/core.cpp +11 -5
  106. esphome/components/esp32/gpio.cpp +86 -24
  107. esphome/components/esp32/gpio.py +15 -16
  108. esphome/components/esp32/gpio_esp32.py +1 -2
  109. esphome/components/esp32/gpio_esp32_c2.py +1 -1
  110. esphome/components/esp32/gpio_esp32_c3.py +1 -1
  111. esphome/components/esp32/gpio_esp32_c6.py +1 -1
  112. esphome/components/esp32/gpio_esp32_h2.py +1 -1
  113. esphome/components/esp32_ble/ble.cpp +1 -0
  114. esphome/components/esp32_ble/ble.h +5 -3
  115. esphome/components/esp32_ble/ble_advertising.cpp +2 -1
  116. esphome/components/esp32_ble/ble_advertising.h +1 -0
  117. esphome/components/esp32_ble_server/__init__.py +3 -0
  118. esphome/components/esp32_ble_tracker/__init__.py +7 -1
  119. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
  120. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
  121. esphome/components/esp32_camera/__init__.py +1 -1
  122. esphome/components/esp32_camera/esp32_camera.cpp +2 -10
  123. esphome/components/esp32_camera/esp32_camera.h +1 -1
  124. esphome/components/esp32_can/esp32_can.cpp +1 -1
  125. esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
  126. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  127. esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
  128. esphome/components/esp32_rmt_led_strip/light.py +9 -1
  129. esphome/components/esp32_touch/esp32_touch.cpp +1 -1
  130. esphome/components/esp8266/gpio.cpp +69 -8
  131. esphome/components/ethernet/ethernet_component.cpp +1 -1
  132. esphome/components/event/__init__.py +13 -10
  133. esphome/components/factory_reset/switch/__init__.py +7 -21
  134. esphome/components/fan/__init__.py +52 -5
  135. esphome/components/fastled_base/__init__.py +1 -4
  136. esphome/components/fastled_base/fastled_light.cpp +1 -1
  137. esphome/components/feedback/cover.py +38 -33
  138. esphome/components/feedback/feedback_cover.cpp +2 -1
  139. esphome/components/fujitsu_general/climate.py +2 -9
  140. esphome/components/gcja5/gcja5.cpp +2 -1
  141. esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
  142. esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
  143. esphome/components/gpio_expander/cached_gpio.h +22 -7
  144. esphome/components/gps/__init__.py +47 -17
  145. esphome/components/gps/gps.cpp +42 -23
  146. esphome/components/gps/gps.h +17 -13
  147. esphome/components/graph/__init__.py +1 -2
  148. esphome/components/gree/climate.py +4 -6
  149. esphome/components/gree/gree.cpp +16 -2
  150. esphome/components/gree/gree.h +2 -2
  151. esphome/components/growatt_solar/growatt_solar.cpp +2 -1
  152. esphome/components/haier/climate.py +37 -34
  153. esphome/components/hbridge/fan/__init__.py +19 -17
  154. esphome/components/he60r/cover.py +4 -5
  155. esphome/components/heatpumpir/climate.py +3 -6
  156. esphome/components/hitachi_ac344/climate.py +2 -9
  157. esphome/components/hitachi_ac424/climate.py +2 -9
  158. esphome/components/hm3301/hm3301.h +1 -1
  159. esphome/components/hte501/sensor.py +6 -6
  160. esphome/components/http_request/__init__.py +39 -6
  161. esphome/components/http_request/http_request.cpp +20 -0
  162. esphome/components/http_request/http_request.h +57 -15
  163. esphome/components/http_request/http_request_arduino.cpp +22 -6
  164. esphome/components/http_request/http_request_arduino.h +4 -3
  165. esphome/components/http_request/http_request_host.cpp +141 -0
  166. esphome/components/http_request/http_request_host.h +37 -0
  167. esphome/components/http_request/http_request_idf.cpp +35 -3
  168. esphome/components/http_request/http_request_idf.h +10 -3
  169. esphome/components/http_request/httplib.h +9691 -0
  170. esphome/components/http_request/update/__init__.py +11 -8
  171. esphome/components/hyt271/sensor.py +6 -6
  172. esphome/components/i2c/i2c.h +4 -0
  173. esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
  174. esphome/components/i2s_audio/__init__.py +131 -22
  175. esphome/components/i2s_audio/i2s_audio.h +44 -4
  176. esphome/components/i2s_audio/media_player/__init__.py +19 -9
  177. esphome/components/i2s_audio/microphone/__init__.py +63 -5
  178. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
  179. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
  180. esphome/components/i2s_audio/speaker/__init__.py +31 -5
  181. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
  182. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
  183. esphome/components/ili9xxx/ili9xxx_init.h +1 -1
  184. esphome/components/image/__init__.py +37 -17
  185. esphome/components/image/image.cpp +25 -8
  186. esphome/components/internal_temperature/internal_temperature.cpp +6 -4
  187. esphome/components/key_collector/__init__.py +35 -0
  188. esphome/components/key_collector/key_collector.cpp +8 -0
  189. esphome/components/key_collector/key_collector.h +10 -0
  190. esphome/components/kuntze/kuntze.cpp +2 -1
  191. esphome/components/ld2410/ld2410.h +1 -1
  192. esphome/components/ld2450/ld2450.h +1 -1
  193. esphome/components/light/__init__.py +57 -0
  194. esphome/components/lock/__init__.py +51 -4
  195. esphome/components/lock/automation.h +2 -13
  196. esphome/components/logger/__init__.py +22 -0
  197. esphome/components/logger/logger.cpp +154 -103
  198. esphome/components/logger/logger.h +211 -36
  199. esphome/components/logger/task_log_buffer.cpp +138 -0
  200. esphome/components/logger/task_log_buffer.h +69 -0
  201. esphome/components/lvgl/__init__.py +13 -5
  202. esphome/components/lvgl/automation.py +50 -1
  203. esphome/components/lvgl/defines.py +0 -1
  204. esphome/components/lvgl/lvgl_esphome.cpp +5 -1
  205. esphome/components/lvgl/text/__init__.py +1 -2
  206. esphome/components/mapping/__init__.py +134 -0
  207. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
  208. esphome/components/max7219digit/max7219digit.cpp +28 -27
  209. esphome/components/mdns/__init__.py +11 -5
  210. esphome/components/mdns/mdns_component.cpp +11 -5
  211. esphome/components/mdns/mdns_component.h +3 -2
  212. esphome/components/mdns/mdns_esp32.cpp +4 -3
  213. esphome/components/mdns/mdns_esp8266.cpp +4 -2
  214. esphome/components/mdns/mdns_libretiny.cpp +4 -2
  215. esphome/components/mdns/mdns_rp2040.cpp +4 -2
  216. esphome/components/media_player/__init__.py +33 -1
  217. esphome/components/mhz19/sensor.py +11 -7
  218. esphome/components/micro_wake_word/__init__.py +99 -31
  219. esphome/components/micro_wake_word/automation.h +54 -0
  220. esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
  221. esphome/components/micro_wake_word/micro_wake_word.h +58 -105
  222. esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
  223. esphome/components/micro_wake_word/streaming_model.cpp +158 -41
  224. esphome/components/micro_wake_word/streaming_model.h +85 -13
  225. esphome/components/microphone/__init__.py +139 -9
  226. esphome/components/microphone/automation.h +14 -2
  227. esphome/components/microphone/microphone.cpp +21 -0
  228. esphome/components/microphone/microphone.h +14 -5
  229. esphome/components/microphone/microphone_source.cpp +95 -0
  230. esphome/components/microphone/microphone_source.h +80 -0
  231. esphome/components/mics_4514/sensor.py +25 -14
  232. esphome/components/midea/climate.py +3 -4
  233. esphome/components/midea_ir/climate.py +3 -5
  234. esphome/components/mipi_spi/__init__.py +15 -0
  235. esphome/components/mipi_spi/display.py +474 -0
  236. esphome/components/mipi_spi/mipi_spi.cpp +481 -0
  237. esphome/components/mipi_spi/mipi_spi.h +171 -0
  238. esphome/components/mipi_spi/models/__init__.py +65 -0
  239. esphome/components/mipi_spi/models/amoled.py +72 -0
  240. esphome/components/mipi_spi/models/commands.py +82 -0
  241. esphome/components/mipi_spi/models/cyd.py +10 -0
  242. esphome/components/mipi_spi/models/ili.py +749 -0
  243. esphome/components/mipi_spi/models/jc.py +260 -0
  244. esphome/components/mipi_spi/models/lanbon.py +15 -0
  245. esphome/components/mipi_spi/models/lilygo.py +60 -0
  246. esphome/components/mipi_spi/models/waveshare.py +139 -0
  247. esphome/components/mitsubishi/climate.py +2 -5
  248. esphome/components/mitsubishi/mitsubishi.cpp +9 -9
  249. esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
  250. esphome/components/mixer/speaker/mixer_speaker.h +1 -3
  251. esphome/components/mlx90393/sensor.py +5 -0
  252. esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
  253. esphome/components/mlx90393/sensor_mlx90393.h +21 -4
  254. esphome/components/modbus/modbus.cpp +2 -1
  255. esphome/components/mqtt/__init__.py +1 -1
  256. esphome/components/mqtt/mqtt_client.cpp +6 -2
  257. esphome/components/mqtt/mqtt_const.h +4 -0
  258. esphome/components/mqtt/mqtt_fan.cpp +39 -0
  259. esphome/components/mqtt/mqtt_fan.h +2 -0
  260. esphome/components/ms5611/sensor.py +6 -6
  261. esphome/components/ms8607/sensor.py +3 -3
  262. esphome/components/network/__init__.py +1 -1
  263. esphome/components/nextion/base_component.py +17 -16
  264. esphome/components/nextion/display.py +11 -2
  265. esphome/components/nextion/nextion.cpp +39 -1
  266. esphome/components/nextion/nextion.h +50 -0
  267. esphome/components/noblex/climate.py +2 -9
  268. esphome/components/number/__init__.py +12 -9
  269. esphome/components/one_wire/one_wire_bus.cpp +14 -10
  270. esphome/components/one_wire/one_wire_bus.h +14 -8
  271. esphome/components/online_image/bmp_image.cpp +48 -11
  272. esphome/components/online_image/bmp_image.h +2 -0
  273. esphome/components/opentherm/binary_sensor/__init__.py +2 -4
  274. esphome/components/opentherm/number/__init__.py +11 -20
  275. esphome/components/opentherm/sensor/__init__.py +3 -3
  276. esphome/components/opentherm/switch/__init__.py +3 -5
  277. esphome/components/output/lock/__init__.py +11 -9
  278. esphome/components/packages/__init__.py +33 -31
  279. esphome/components/packet_transport/__init__.py +201 -0
  280. esphome/components/packet_transport/binary_sensor.py +19 -0
  281. esphome/components/packet_transport/packet_transport.cpp +534 -0
  282. esphome/components/packet_transport/packet_transport.h +154 -0
  283. esphome/components/packet_transport/sensor.py +19 -0
  284. esphome/components/pca9685/pca9685_output.cpp +2 -1
  285. esphome/components/pid/climate.py +2 -4
  286. esphome/components/pm2005/__init__.py +1 -0
  287. esphome/components/pm2005/pm2005.cpp +123 -0
  288. esphome/components/pm2005/pm2005.h +46 -0
  289. esphome/components/pm2005/sensor.py +86 -0
  290. esphome/components/pmsa003i/pmsa003i.cpp +43 -16
  291. esphome/components/pmsa003i/pmsa003i.h +25 -25
  292. esphome/components/pmsx003/pmsx003.cpp +195 -230
  293. esphome/components/pmsx003/pmsx003.h +51 -33
  294. esphome/components/pmsx003/sensor.py +21 -11
  295. esphome/components/pn7150/pn7150.h +2 -2
  296. esphome/components/pn7160/pn7160.h +2 -2
  297. esphome/components/prometheus/prometheus_handler.cpp +174 -0
  298. esphome/components/prometheus/prometheus_handler.h +17 -0
  299. esphome/components/psram/__init__.py +7 -5
  300. esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
  301. esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
  302. esphome/components/pzem004t/pzem004t.cpp +2 -1
  303. esphome/components/qspi_dbi/__init__.py +0 -1
  304. esphome/components/qspi_dbi/display.py +2 -1
  305. esphome/components/qspi_dbi/models.py +1 -2
  306. esphome/components/remote_base/__init__.py +91 -0
  307. esphome/components/remote_base/beo4_protocol.cpp +153 -0
  308. esphome/components/remote_base/beo4_protocol.h +43 -0
  309. esphome/components/remote_base/gobox_protocol.cpp +131 -0
  310. esphome/components/remote_base/gobox_protocol.h +54 -0
  311. esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
  312. esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
  313. esphome/components/resampler/speaker/resampler_speaker.h +1 -1
  314. esphome/components/rf_bridge/rf_bridge.cpp +2 -1
  315. esphome/components/scd30/sensor.py +2 -3
  316. esphome/components/scd4x/sensor.py +4 -5
  317. esphome/components/sdp3x/sensor.py +2 -1
  318. esphome/components/sds011/sds011.cpp +2 -1
  319. esphome/components/select/__init__.py +19 -20
  320. esphome/components/sen5x/sen5x.cpp +55 -36
  321. esphome/components/sen5x/sensor.py +1 -1
  322. esphome/components/senseair/sensor.py +3 -3
  323. esphome/components/sensor/__init__.py +158 -14
  324. esphome/components/sensor/filter.cpp +23 -0
  325. esphome/components/sensor/filter.h +22 -0
  326. esphome/components/sgp30/sensor.py +14 -16
  327. esphome/components/sgp4x/sensor.py +1 -1
  328. esphome/components/sht4x/sht4x.cpp +43 -22
  329. esphome/components/sht4x/sht4x.h +1 -1
  330. esphome/components/shtcx/sensor.py +6 -6
  331. esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
  332. esphome/components/sml/text_sensor/__init__.py +4 -6
  333. esphome/components/sound_level/__init__.py +0 -0
  334. esphome/components/sound_level/sensor.py +97 -0
  335. esphome/components/sound_level/sound_level.cpp +194 -0
  336. esphome/components/sound_level/sound_level.h +73 -0
  337. esphome/components/speaker/media_player/__init__.py +4 -8
  338. esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
  339. esphome/components/speaker/media_player/speaker_media_player.h +0 -11
  340. esphome/components/speaker/speaker.h +4 -7
  341. esphome/components/speed/fan/__init__.py +17 -16
  342. esphome/components/spi/spi.h +11 -1
  343. esphome/components/sprinkler/__init__.py +18 -19
  344. esphome/components/sprinkler/sprinkler.cpp +6 -5
  345. esphome/components/switch/__init__.py +32 -42
  346. esphome/components/syslog/__init__.py +41 -0
  347. esphome/components/syslog/esphome_syslog.cpp +49 -0
  348. esphome/components/syslog/esphome_syslog.h +27 -0
  349. esphome/components/t6615/sensor.py +3 -3
  350. esphome/components/t6615/t6615.cpp +2 -1
  351. esphome/components/tca9555/tca9555.cpp +11 -6
  352. esphome/components/tcl112/climate.py +2 -9
  353. esphome/components/template/alarm_control_panel/__init__.py +7 -6
  354. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
  355. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
  356. esphome/components/template/cover/__init__.py +27 -21
  357. esphome/components/template/fan/__init__.py +14 -12
  358. esphome/components/template/lock/__init__.py +20 -25
  359. esphome/components/template/lock/automation.h +18 -0
  360. esphome/components/template/text/__init__.py +4 -3
  361. esphome/components/template/valve/__init__.py +32 -21
  362. esphome/components/template/valve/automation.h +24 -0
  363. esphome/components/text/__init__.py +32 -1
  364. esphome/components/text_sensor/__init__.py +24 -29
  365. esphome/components/thermostat/climate.py +5 -5
  366. esphome/components/time_based/cover.py +17 -16
  367. esphome/components/time_based/time_based_cover.cpp +2 -1
  368. esphome/components/tm1638/switch/__init__.py +10 -7
  369. esphome/components/tormatic/cover.py +4 -5
  370. esphome/components/toshiba/climate.py +3 -5
  371. esphome/components/touchscreen/touchscreen.cpp +3 -1
  372. esphome/components/tuya/climate/__init__.py +5 -6
  373. esphome/components/tuya/cover/__init__.py +6 -11
  374. esphome/components/tuya/select/__init__.py +15 -5
  375. esphome/components/tuya/select/tuya_select.cpp +6 -1
  376. esphome/components/tuya/select/tuya_select.h +5 -1
  377. esphome/components/uart/packet_transport/__init__.py +20 -0
  378. esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
  379. esphome/components/uart/packet_transport/uart_transport.h +41 -0
  380. esphome/components/uart/switch/uart_switch.cpp +2 -1
  381. esphome/components/udp/__init__.py +126 -128
  382. esphome/components/udp/automation.h +40 -0
  383. esphome/components/udp/binary_sensor.py +3 -25
  384. esphome/components/udp/packet_transport/__init__.py +29 -0
  385. esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
  386. esphome/components/udp/packet_transport/udp_transport.h +28 -0
  387. esphome/components/udp/sensor.py +3 -25
  388. esphome/components/udp/udp_component.cpp +26 -470
  389. esphome/components/udp/udp_component.h +21 -128
  390. esphome/components/update/__init__.py +31 -1
  391. esphome/components/uponor_smatrix/climate/__init__.py +4 -9
  392. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
  393. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  394. esphome/components/uptime/text_sensor/__init__.py +47 -7
  395. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
  396. esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
  397. esphome/components/valve/__init__.py +34 -3
  398. esphome/components/valve/automation.h +1 -19
  399. esphome/components/vl53l0x/sensor.py +11 -0
  400. esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
  401. esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
  402. esphome/components/voice_assistant/__init__.py +36 -10
  403. esphome/components/voice_assistant/voice_assistant.cpp +170 -144
  404. esphome/components/voice_assistant/voice_assistant.h +26 -25
  405. esphome/components/waveshare_epaper/display.py +6 -0
  406. esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
  407. esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
  408. esphome/components/weikai/weikai.cpp +0 -52
  409. esphome/components/whirlpool/climate.py +3 -5
  410. esphome/components/whynter/climate.py +3 -5
  411. esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
  412. esphome/components/yashima/climate.py +6 -6
  413. esphome/components/zhlt01/climate.py +2 -7
  414. esphome/config.py +13 -13
  415. esphome/config_validation.py +38 -58
  416. esphome/const.py +15 -1
  417. esphome/core/__init__.py +2 -0
  418. esphome/core/application.cpp +27 -10
  419. esphome/core/application.h +9 -1
  420. esphome/core/automation.h +4 -3
  421. esphome/core/component.cpp +28 -7
  422. esphome/core/component.h +10 -1
  423. esphome/core/defines.h +23 -17
  424. esphome/core/doxygen.h +13 -0
  425. esphome/core/macros.h +4 -0
  426. esphome/core/scheduler.cpp +7 -1
  427. esphome/cpp_generator.py +6 -2
  428. esphome/dashboard/web_server.py +3 -3
  429. esphome/helpers.py +39 -0
  430. esphome/loader.py +4 -0
  431. esphome/log.py +15 -19
  432. esphome/mqtt.py +23 -10
  433. esphome/platformio_api.py +1 -1
  434. esphome/schema_extractors.py +0 -1
  435. esphome/voluptuous_schema.py +3 -1
  436. esphome/vscode.py +15 -0
  437. esphome/wizard.py +47 -37
  438. esphome/zeroconf.py +7 -3
  439. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/METADATA +10 -11
  440. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/RECORD +444 -383
  441. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/WHEEL +1 -1
  442. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/entry_points.txt +0 -0
  443. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/licenses/LICENSE +0 -0
  444. {esphome-2025.4.2.dist-info → esphome-2025.5.0.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,6 +1,7 @@
1
1
  #include "uponor_smatrix_climate.h"
2
2
  #include "esphome/core/helpers.h"
3
3
  #include "esphome/core/log.h"
4
+ #include "esphome/core/application.h"
4
5
 
5
6
  namespace esphome {
6
7
  namespace uponor_smatrix {
@@ -13,7 +14,7 @@ void UponorSmatrixClimate::dump_config() {
13
14
  }
14
15
 
15
16
  void UponorSmatrixClimate::loop() {
16
- const uint32_t now = millis();
17
+ const uint32_t now = App.get_loop_component_start_time();
17
18
 
18
19
  // Publish state after all update packets are processed
19
20
  if (this->last_data_ != 0 && (now - this->last_data_ > 100) && this->target_temperature_raw_ != 0) {
@@ -1,5 +1,6 @@
1
1
  #include "uponor_smatrix.h"
2
2
  #include "esphome/core/log.h"
3
+ #include "esphome/core/application.h"
3
4
 
4
5
  namespace esphome {
5
6
  namespace uponor_smatrix {
@@ -35,7 +36,7 @@ void UponorSmatrixComponent::dump_config() {
35
36
  }
36
37
 
37
38
  void UponorSmatrixComponent::loop() {
38
- const uint32_t now = millis();
39
+ const uint32_t now = App.get_loop_component_start_time();
39
40
 
40
41
  // Discard stale data
41
42
  if (!this->rx_buffer_.empty() && (now - this->last_rx_ > 50)) {
@@ -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_;