esphome 2025.4.2__py3-none-any.whl → 2025.5.0b3__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 (440) 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 +81 -13
  13. esphome/components/api/api_connection.h +13 -1
  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/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/bedjet_hub.cpp +1 -0
  45. esphome/components/bedjet/climate/__init__.py +3 -8
  46. esphome/components/bedjet/fan/__init__.py +2 -11
  47. esphome/components/binary/fan/__init__.py +13 -16
  48. esphome/components/binary_sensor/__init__.py +13 -10
  49. esphome/components/bl0906/constants.h +16 -16
  50. esphome/components/ble_client/text_sensor/__init__.py +3 -5
  51. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
  52. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +136 -21
  53. esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
  54. esphome/components/button/__init__.py +11 -8
  55. esphome/components/canbus/canbus.cpp +3 -0
  56. esphome/components/canbus/canbus.h +16 -0
  57. esphome/components/ccs811/sensor.py +9 -6
  58. esphome/components/climate/__init__.py +35 -2
  59. esphome/components/climate/climate_mode.h +1 -1
  60. esphome/components/climate/climate_traits.h +63 -57
  61. esphome/components/climate_ir/__init__.py +57 -17
  62. esphome/components/climate_ir_lg/climate.py +2 -5
  63. esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
  64. esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
  65. esphome/components/color/__init__.py +2 -0
  66. esphome/components/const/__init__.py +5 -0
  67. esphome/components/coolix/climate.py +2 -9
  68. esphome/components/copy/cover/__init__.py +10 -9
  69. esphome/components/copy/fan/__init__.py +11 -9
  70. esphome/components/copy/lock/__init__.py +11 -9
  71. esphome/components/copy/text/__init__.py +9 -6
  72. esphome/components/cover/__init__.py +37 -2
  73. esphome/components/cse7766/cse7766.cpp +2 -1
  74. esphome/components/cst226/binary_sensor/__init__.py +28 -0
  75. esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
  76. esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
  77. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
  78. esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
  79. esphome/components/current_based/cover.py +37 -36
  80. esphome/components/current_based/current_based_cover.cpp +2 -1
  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/daly_bms/daly_bms.cpp +2 -1
  89. esphome/components/debug/debug_component.cpp +6 -1
  90. esphome/components/debug/debug_component.h +6 -0
  91. esphome/components/debug/debug_esp32.cpp +109 -254
  92. esphome/components/debug/sensor.py +14 -0
  93. esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
  94. esphome/components/delonghi/climate.py +2 -9
  95. esphome/components/demo/__init__.py +18 -20
  96. esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
  97. esphome/components/dps310/sensor.py +6 -6
  98. esphome/components/ee895/sensor.py +9 -9
  99. esphome/components/emmeti/climate.py +2 -9
  100. esphome/components/endstop/cover.py +17 -16
  101. esphome/components/endstop/endstop_cover.cpp +2 -1
  102. esphome/components/ens160_base/__init__.py +12 -9
  103. esphome/components/esp32/__init__.py +60 -3
  104. esphome/components/esp32/core.cpp +11 -5
  105. esphome/components/esp32/gpio.cpp +86 -24
  106. esphome/components/esp32/gpio.py +15 -16
  107. esphome/components/esp32/gpio_esp32.py +1 -2
  108. esphome/components/esp32/gpio_esp32_c2.py +1 -1
  109. esphome/components/esp32/gpio_esp32_c3.py +1 -1
  110. esphome/components/esp32/gpio_esp32_c6.py +1 -1
  111. esphome/components/esp32/gpio_esp32_h2.py +1 -1
  112. esphome/components/esp32_ble/ble.cpp +1 -0
  113. esphome/components/esp32_ble/ble.h +5 -3
  114. esphome/components/esp32_ble/ble_advertising.cpp +2 -1
  115. esphome/components/esp32_ble/ble_advertising.h +1 -0
  116. esphome/components/esp32_ble_server/__init__.py +3 -0
  117. esphome/components/esp32_ble_tracker/__init__.py +7 -1
  118. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
  119. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
  120. esphome/components/esp32_camera/esp32_camera.cpp +2 -1
  121. esphome/components/esp32_camera/esp32_camera.h +1 -1
  122. esphome/components/esp32_can/esp32_can.cpp +1 -1
  123. esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
  124. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  125. esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
  126. esphome/components/esp32_rmt_led_strip/light.py +9 -1
  127. esphome/components/esp32_touch/esp32_touch.cpp +1 -1
  128. esphome/components/esp8266/gpio.cpp +69 -8
  129. esphome/components/ethernet/ethernet_component.cpp +1 -1
  130. esphome/components/event/__init__.py +13 -10
  131. esphome/components/factory_reset/switch/__init__.py +7 -21
  132. esphome/components/fan/__init__.py +52 -5
  133. esphome/components/fastled_base/__init__.py +1 -4
  134. esphome/components/fastled_base/fastled_light.cpp +1 -1
  135. esphome/components/feedback/cover.py +38 -33
  136. esphome/components/feedback/feedback_cover.cpp +2 -1
  137. esphome/components/fujitsu_general/climate.py +2 -9
  138. esphome/components/gcja5/gcja5.cpp +2 -1
  139. esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
  140. esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
  141. esphome/components/gpio_expander/cached_gpio.h +22 -7
  142. esphome/components/gps/__init__.py +47 -17
  143. esphome/components/gps/gps.cpp +42 -23
  144. esphome/components/gps/gps.h +17 -13
  145. esphome/components/graph/__init__.py +1 -2
  146. esphome/components/gree/climate.py +4 -6
  147. esphome/components/gree/gree.cpp +16 -2
  148. esphome/components/gree/gree.h +2 -2
  149. esphome/components/growatt_solar/growatt_solar.cpp +2 -1
  150. esphome/components/haier/climate.py +37 -34
  151. esphome/components/hbridge/fan/__init__.py +19 -17
  152. esphome/components/he60r/cover.py +4 -5
  153. esphome/components/heatpumpir/climate.py +3 -6
  154. esphome/components/hitachi_ac344/climate.py +2 -9
  155. esphome/components/hitachi_ac424/climate.py +2 -9
  156. esphome/components/hm3301/hm3301.h +1 -1
  157. esphome/components/hte501/sensor.py +6 -6
  158. esphome/components/http_request/__init__.py +39 -6
  159. esphome/components/http_request/http_request.cpp +20 -0
  160. esphome/components/http_request/http_request.h +57 -15
  161. esphome/components/http_request/http_request_arduino.cpp +22 -6
  162. esphome/components/http_request/http_request_arduino.h +4 -3
  163. esphome/components/http_request/http_request_host.cpp +141 -0
  164. esphome/components/http_request/http_request_host.h +37 -0
  165. esphome/components/http_request/http_request_idf.cpp +35 -3
  166. esphome/components/http_request/http_request_idf.h +10 -3
  167. esphome/components/http_request/httplib.h +9691 -0
  168. esphome/components/http_request/update/__init__.py +11 -8
  169. esphome/components/hyt271/sensor.py +6 -6
  170. esphome/components/i2c/i2c.h +4 -0
  171. esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
  172. esphome/components/i2s_audio/__init__.py +131 -22
  173. esphome/components/i2s_audio/i2s_audio.h +44 -4
  174. esphome/components/i2s_audio/media_player/__init__.py +19 -9
  175. esphome/components/i2s_audio/microphone/__init__.py +63 -5
  176. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
  177. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
  178. esphome/components/i2s_audio/speaker/__init__.py +31 -5
  179. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
  180. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
  181. esphome/components/ili9xxx/ili9xxx_init.h +1 -1
  182. esphome/components/image/__init__.py +37 -17
  183. esphome/components/image/image.cpp +25 -8
  184. esphome/components/internal_temperature/internal_temperature.cpp +6 -4
  185. esphome/components/key_collector/__init__.py +35 -0
  186. esphome/components/key_collector/key_collector.cpp +8 -0
  187. esphome/components/key_collector/key_collector.h +10 -0
  188. esphome/components/kuntze/kuntze.cpp +2 -1
  189. esphome/components/ld2410/ld2410.h +1 -1
  190. esphome/components/ld2450/ld2450.h +1 -1
  191. esphome/components/light/__init__.py +57 -0
  192. esphome/components/lock/__init__.py +51 -4
  193. esphome/components/lock/automation.h +2 -13
  194. esphome/components/logger/__init__.py +22 -0
  195. esphome/components/logger/logger.cpp +154 -103
  196. esphome/components/logger/logger.h +211 -36
  197. esphome/components/logger/task_log_buffer.cpp +138 -0
  198. esphome/components/logger/task_log_buffer.h +69 -0
  199. esphome/components/lvgl/__init__.py +13 -5
  200. esphome/components/lvgl/automation.py +50 -1
  201. esphome/components/lvgl/defines.py +0 -1
  202. esphome/components/lvgl/lvgl_esphome.cpp +5 -1
  203. esphome/components/lvgl/text/__init__.py +1 -2
  204. esphome/components/mapping/__init__.py +134 -0
  205. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
  206. esphome/components/max7219digit/max7219digit.cpp +28 -27
  207. esphome/components/mdns/__init__.py +11 -5
  208. esphome/components/mdns/mdns_component.cpp +11 -5
  209. esphome/components/mdns/mdns_component.h +3 -2
  210. esphome/components/mdns/mdns_esp32.cpp +4 -3
  211. esphome/components/mdns/mdns_esp8266.cpp +4 -2
  212. esphome/components/mdns/mdns_libretiny.cpp +4 -2
  213. esphome/components/mdns/mdns_rp2040.cpp +4 -2
  214. esphome/components/media_player/__init__.py +33 -1
  215. esphome/components/mhz19/sensor.py +11 -7
  216. esphome/components/micro_wake_word/__init__.py +99 -31
  217. esphome/components/micro_wake_word/automation.h +54 -0
  218. esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
  219. esphome/components/micro_wake_word/micro_wake_word.h +58 -105
  220. esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
  221. esphome/components/micro_wake_word/streaming_model.cpp +158 -41
  222. esphome/components/micro_wake_word/streaming_model.h +85 -13
  223. esphome/components/microphone/__init__.py +139 -9
  224. esphome/components/microphone/automation.h +14 -2
  225. esphome/components/microphone/microphone.cpp +21 -0
  226. esphome/components/microphone/microphone.h +14 -5
  227. esphome/components/microphone/microphone_source.cpp +95 -0
  228. esphome/components/microphone/microphone_source.h +80 -0
  229. esphome/components/mics_4514/sensor.py +25 -14
  230. esphome/components/midea/climate.py +3 -4
  231. esphome/components/midea_ir/climate.py +3 -5
  232. esphome/components/mipi_spi/__init__.py +15 -0
  233. esphome/components/mipi_spi/display.py +474 -0
  234. esphome/components/mipi_spi/mipi_spi.cpp +481 -0
  235. esphome/components/mipi_spi/mipi_spi.h +171 -0
  236. esphome/components/mipi_spi/models/__init__.py +65 -0
  237. esphome/components/mipi_spi/models/amoled.py +72 -0
  238. esphome/components/mipi_spi/models/commands.py +82 -0
  239. esphome/components/mipi_spi/models/cyd.py +10 -0
  240. esphome/components/mipi_spi/models/ili.py +749 -0
  241. esphome/components/mipi_spi/models/jc.py +260 -0
  242. esphome/components/mipi_spi/models/lanbon.py +15 -0
  243. esphome/components/mipi_spi/models/lilygo.py +60 -0
  244. esphome/components/mipi_spi/models/waveshare.py +139 -0
  245. esphome/components/mitsubishi/climate.py +2 -5
  246. esphome/components/mitsubishi/mitsubishi.cpp +9 -9
  247. esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
  248. esphome/components/mixer/speaker/mixer_speaker.h +1 -3
  249. esphome/components/mlx90393/sensor.py +5 -0
  250. esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
  251. esphome/components/mlx90393/sensor_mlx90393.h +21 -4
  252. esphome/components/modbus/modbus.cpp +2 -1
  253. esphome/components/mqtt/__init__.py +1 -1
  254. esphome/components/mqtt/mqtt_client.cpp +6 -2
  255. esphome/components/mqtt/mqtt_const.h +4 -0
  256. esphome/components/mqtt/mqtt_fan.cpp +39 -0
  257. esphome/components/mqtt/mqtt_fan.h +2 -0
  258. esphome/components/ms5611/sensor.py +6 -6
  259. esphome/components/ms8607/sensor.py +3 -3
  260. esphome/components/network/__init__.py +1 -1
  261. esphome/components/nextion/base_component.py +17 -16
  262. esphome/components/nextion/display.py +11 -2
  263. esphome/components/nextion/nextion.cpp +39 -1
  264. esphome/components/nextion/nextion.h +50 -0
  265. esphome/components/noblex/climate.py +2 -9
  266. esphome/components/number/__init__.py +12 -9
  267. esphome/components/one_wire/one_wire_bus.cpp +14 -10
  268. esphome/components/one_wire/one_wire_bus.h +14 -8
  269. esphome/components/online_image/bmp_image.cpp +48 -11
  270. esphome/components/online_image/bmp_image.h +2 -0
  271. esphome/components/opentherm/binary_sensor/__init__.py +2 -4
  272. esphome/components/opentherm/number/__init__.py +11 -20
  273. esphome/components/opentherm/sensor/__init__.py +3 -3
  274. esphome/components/opentherm/switch/__init__.py +3 -5
  275. esphome/components/output/lock/__init__.py +11 -9
  276. esphome/components/packages/__init__.py +33 -31
  277. esphome/components/packet_transport/__init__.py +201 -0
  278. esphome/components/packet_transport/binary_sensor.py +19 -0
  279. esphome/components/packet_transport/packet_transport.cpp +534 -0
  280. esphome/components/packet_transport/packet_transport.h +154 -0
  281. esphome/components/packet_transport/sensor.py +19 -0
  282. esphome/components/pca9685/pca9685_output.cpp +2 -1
  283. esphome/components/pid/climate.py +2 -4
  284. esphome/components/pm2005/__init__.py +1 -0
  285. esphome/components/pm2005/pm2005.cpp +123 -0
  286. esphome/components/pm2005/pm2005.h +46 -0
  287. esphome/components/pm2005/sensor.py +86 -0
  288. esphome/components/pmsa003i/pmsa003i.cpp +43 -16
  289. esphome/components/pmsa003i/pmsa003i.h +25 -25
  290. esphome/components/pmsx003/pmsx003.cpp +195 -230
  291. esphome/components/pmsx003/pmsx003.h +51 -33
  292. esphome/components/pmsx003/sensor.py +21 -11
  293. esphome/components/pn7150/pn7150.h +2 -2
  294. esphome/components/pn7160/pn7160.h +2 -2
  295. esphome/components/prometheus/prometheus_handler.cpp +174 -0
  296. esphome/components/prometheus/prometheus_handler.h +17 -0
  297. esphome/components/psram/__init__.py +7 -5
  298. esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
  299. esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
  300. esphome/components/pzem004t/pzem004t.cpp +2 -1
  301. esphome/components/qspi_dbi/__init__.py +0 -1
  302. esphome/components/qspi_dbi/display.py +2 -1
  303. esphome/components/qspi_dbi/models.py +1 -2
  304. esphome/components/remote_base/__init__.py +91 -0
  305. esphome/components/remote_base/beo4_protocol.cpp +153 -0
  306. esphome/components/remote_base/beo4_protocol.h +43 -0
  307. esphome/components/remote_base/gobox_protocol.cpp +131 -0
  308. esphome/components/remote_base/gobox_protocol.h +54 -0
  309. esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
  310. esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
  311. esphome/components/resampler/speaker/resampler_speaker.h +1 -1
  312. esphome/components/rf_bridge/rf_bridge.cpp +2 -1
  313. esphome/components/scd30/sensor.py +2 -3
  314. esphome/components/scd4x/sensor.py +4 -5
  315. esphome/components/sdp3x/sensor.py +2 -1
  316. esphome/components/sds011/sds011.cpp +2 -1
  317. esphome/components/select/__init__.py +19 -20
  318. esphome/components/sen5x/sen5x.cpp +55 -36
  319. esphome/components/sen5x/sensor.py +1 -1
  320. esphome/components/senseair/sensor.py +3 -3
  321. esphome/components/sensor/__init__.py +158 -14
  322. esphome/components/sensor/filter.cpp +23 -0
  323. esphome/components/sensor/filter.h +22 -0
  324. esphome/components/sgp30/sensor.py +14 -16
  325. esphome/components/sgp4x/sensor.py +1 -1
  326. esphome/components/sht4x/sht4x.cpp +43 -22
  327. esphome/components/sht4x/sht4x.h +1 -1
  328. esphome/components/shtcx/sensor.py +6 -6
  329. esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
  330. esphome/components/sml/text_sensor/__init__.py +4 -6
  331. esphome/components/sound_level/__init__.py +0 -0
  332. esphome/components/sound_level/sensor.py +97 -0
  333. esphome/components/sound_level/sound_level.cpp +194 -0
  334. esphome/components/sound_level/sound_level.h +73 -0
  335. esphome/components/speaker/media_player/__init__.py +4 -8
  336. esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
  337. esphome/components/speaker/media_player/speaker_media_player.h +0 -11
  338. esphome/components/speaker/speaker.h +4 -7
  339. esphome/components/speed/fan/__init__.py +17 -16
  340. esphome/components/spi/spi.h +11 -1
  341. esphome/components/sprinkler/__init__.py +18 -19
  342. esphome/components/sprinkler/sprinkler.cpp +6 -5
  343. esphome/components/switch/__init__.py +32 -42
  344. esphome/components/syslog/__init__.py +41 -0
  345. esphome/components/syslog/esphome_syslog.cpp +49 -0
  346. esphome/components/syslog/esphome_syslog.h +27 -0
  347. esphome/components/t6615/sensor.py +3 -3
  348. esphome/components/t6615/t6615.cpp +2 -1
  349. esphome/components/tca9555/tca9555.cpp +11 -6
  350. esphome/components/tcl112/climate.py +2 -9
  351. esphome/components/template/alarm_control_panel/__init__.py +7 -6
  352. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
  353. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
  354. esphome/components/template/cover/__init__.py +27 -21
  355. esphome/components/template/fan/__init__.py +14 -12
  356. esphome/components/template/lock/__init__.py +20 -25
  357. esphome/components/template/lock/automation.h +18 -0
  358. esphome/components/template/text/__init__.py +4 -3
  359. esphome/components/template/valve/__init__.py +32 -21
  360. esphome/components/template/valve/automation.h +24 -0
  361. esphome/components/text/__init__.py +32 -1
  362. esphome/components/text_sensor/__init__.py +24 -29
  363. esphome/components/thermostat/climate.py +5 -5
  364. esphome/components/time_based/cover.py +17 -16
  365. esphome/components/time_based/time_based_cover.cpp +2 -1
  366. esphome/components/tm1638/switch/__init__.py +10 -7
  367. esphome/components/tormatic/cover.py +4 -5
  368. esphome/components/toshiba/climate.py +3 -5
  369. esphome/components/touchscreen/touchscreen.cpp +3 -1
  370. esphome/components/tuya/climate/__init__.py +5 -6
  371. esphome/components/tuya/cover/__init__.py +6 -11
  372. esphome/components/tuya/select/__init__.py +15 -5
  373. esphome/components/tuya/select/tuya_select.cpp +6 -1
  374. esphome/components/tuya/select/tuya_select.h +5 -1
  375. esphome/components/uart/packet_transport/__init__.py +20 -0
  376. esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
  377. esphome/components/uart/packet_transport/uart_transport.h +41 -0
  378. esphome/components/uart/switch/uart_switch.cpp +2 -1
  379. esphome/components/udp/__init__.py +126 -128
  380. esphome/components/udp/automation.h +40 -0
  381. esphome/components/udp/binary_sensor.py +3 -25
  382. esphome/components/udp/packet_transport/__init__.py +29 -0
  383. esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
  384. esphome/components/udp/packet_transport/udp_transport.h +28 -0
  385. esphome/components/udp/sensor.py +3 -25
  386. esphome/components/udp/udp_component.cpp +26 -470
  387. esphome/components/udp/udp_component.h +21 -128
  388. esphome/components/update/__init__.py +31 -1
  389. esphome/components/uponor_smatrix/climate/__init__.py +4 -9
  390. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
  391. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  392. esphome/components/uptime/text_sensor/__init__.py +47 -7
  393. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
  394. esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
  395. esphome/components/valve/__init__.py +34 -3
  396. esphome/components/valve/automation.h +1 -19
  397. esphome/components/vl53l0x/sensor.py +11 -0
  398. esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
  399. esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
  400. esphome/components/voice_assistant/__init__.py +36 -10
  401. esphome/components/voice_assistant/voice_assistant.cpp +170 -144
  402. esphome/components/voice_assistant/voice_assistant.h +26 -25
  403. esphome/components/waveshare_epaper/display.py +6 -0
  404. esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
  405. esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
  406. esphome/components/whirlpool/climate.py +3 -5
  407. esphome/components/whynter/climate.py +3 -5
  408. esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
  409. esphome/components/yashima/climate.py +6 -6
  410. esphome/components/zhlt01/climate.py +2 -7
  411. esphome/config.py +13 -13
  412. esphome/config_validation.py +38 -58
  413. esphome/const.py +15 -1
  414. esphome/core/__init__.py +2 -0
  415. esphome/core/application.cpp +23 -10
  416. esphome/core/application.h +9 -1
  417. esphome/core/automation.h +4 -3
  418. esphome/core/component.cpp +28 -7
  419. esphome/core/component.h +10 -1
  420. esphome/core/defines.h +23 -17
  421. esphome/core/macros.h +4 -0
  422. esphome/core/scheduler.cpp +7 -1
  423. esphome/cpp_generator.py +6 -2
  424. esphome/dashboard/web_server.py +3 -3
  425. esphome/helpers.py +39 -0
  426. esphome/loader.py +4 -0
  427. esphome/log.py +15 -19
  428. esphome/mqtt.py +23 -10
  429. esphome/platformio_api.py +1 -1
  430. esphome/schema_extractors.py +0 -1
  431. esphome/voluptuous_schema.py +3 -1
  432. esphome/vscode.py +15 -0
  433. esphome/wizard.py +47 -37
  434. esphome/zeroconf.py +7 -3
  435. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/METADATA +10 -11
  436. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/RECORD +440 -380
  437. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/WHEEL +1 -1
  438. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/entry_points.txt +0 -0
  439. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/licenses/LICENSE +0 -0
  440. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/top_level.txt +0 -0
@@ -17,17 +17,11 @@ from .. import template_ns
17
17
 
18
18
  TemplateLock = template_ns.class_("TemplateLock", lock.Lock, cg.Component)
19
19
 
20
- LockState = lock.lock_ns.enum("LockState")
21
-
22
- LOCK_STATES = {
23
- "LOCKED": LockState.LOCK_STATE_LOCKED,
24
- "UNLOCKED": LockState.LOCK_STATE_UNLOCKED,
25
- "JAMMED": LockState.LOCK_STATE_JAMMED,
26
- "LOCKING": LockState.LOCK_STATE_LOCKING,
27
- "UNLOCKING": LockState.LOCK_STATE_UNLOCKING,
28
- }
29
-
30
- validate_lock_state = cv.enum(LOCK_STATES, upper=True)
20
+ TemplateLockPublishAction = template_ns.class_(
21
+ "TemplateLockPublishAction",
22
+ automation.Action,
23
+ cg.Parented.template(TemplateLock),
24
+ )
31
25
 
32
26
 
33
27
  def validate(config):
@@ -42,9 +36,9 @@ def validate(config):
42
36
 
43
37
 
44
38
  CONFIG_SCHEMA = cv.All(
45
- lock.LOCK_SCHEMA.extend(
39
+ lock.lock_schema(TemplateLock)
40
+ .extend(
46
41
  {
47
- cv.GenerateID(): cv.declare_id(TemplateLock),
48
42
  cv.Optional(CONF_LAMBDA): cv.returning_lambda,
49
43
  cv.Optional(CONF_OPTIMISTIC, default=False): cv.boolean,
50
44
  cv.Optional(CONF_ASSUMED_STATE, default=False): cv.boolean,
@@ -54,19 +48,19 @@ CONFIG_SCHEMA = cv.All(
54
48
  cv.Optional(CONF_LOCK_ACTION): automation.validate_automation(single=True),
55
49
  cv.Optional(CONF_OPEN_ACTION): automation.validate_automation(single=True),
56
50
  }
57
- ).extend(cv.COMPONENT_SCHEMA),
51
+ )
52
+ .extend(cv.COMPONENT_SCHEMA),
58
53
  validate,
59
54
  )
60
55
 
61
56
 
62
57
  async def to_code(config):
63
- var = cg.new_Pvariable(config[CONF_ID])
58
+ var = await lock.new_lock(config)
64
59
  await cg.register_component(var, config)
65
- await lock.register_lock(var, config)
66
60
 
67
61
  if CONF_LAMBDA in config:
68
62
  template_ = await cg.process_lambda(
69
- config[CONF_LAMBDA], [], return_type=cg.optional.template(LockState)
63
+ config[CONF_LAMBDA], [], return_type=cg.optional.template(lock.LockState)
70
64
  )
71
65
  cg.add(var.set_state_lambda(template_))
72
66
  if CONF_UNLOCK_ACTION in config:
@@ -88,17 +82,18 @@ async def to_code(config):
88
82
 
89
83
  @automation.register_action(
90
84
  "lock.template.publish",
91
- lock.LockPublishAction,
92
- cv.Schema(
85
+ TemplateLockPublishAction,
86
+ cv.maybe_simple_value(
93
87
  {
94
- cv.Required(CONF_ID): cv.use_id(lock.Lock),
95
- cv.Required(CONF_STATE): cv.templatable(validate_lock_state),
96
- }
88
+ cv.GenerateID(): cv.use_id(TemplateLock),
89
+ cv.Required(CONF_STATE): cv.templatable(lock.validate_lock_state),
90
+ },
91
+ key=CONF_STATE,
97
92
  ),
98
93
  )
99
94
  async def lock_template_publish_to_code(config, action_id, template_arg, args):
100
- paren = await cg.get_variable(config[CONF_ID])
101
- var = cg.new_Pvariable(action_id, template_arg, paren)
102
- template_ = await cg.templatable(config[CONF_STATE], args, LockState)
95
+ var = cg.new_Pvariable(action_id, template_arg)
96
+ await cg.register_parented(var, config[CONF_ID])
97
+ template_ = await cg.templatable(config[CONF_STATE], args, lock.LockState)
103
98
  cg.add(var.set_state(template_))
104
99
  return var
@@ -0,0 +1,18 @@
1
+ #pragma once
2
+
3
+ #include "template_lock.h"
4
+
5
+ #include "esphome/core/automation.h"
6
+
7
+ namespace esphome {
8
+ namespace template_ {
9
+
10
+ template<typename... Ts> class TemplateLockPublishAction : public Action<Ts...>, public Parented<TemplateLock> {
11
+ public:
12
+ TEMPLATABLE_VALUE(lock::LockState, state)
13
+
14
+ void play(Ts... x) override { this->parent_->publish_state(this->state_.value(x...)); }
15
+ };
16
+
17
+ } // namespace template_
18
+ } // namespace esphome
@@ -46,9 +46,9 @@ def validate(config):
46
46
 
47
47
 
48
48
  CONFIG_SCHEMA = cv.All(
49
- text.TEXT_SCHEMA.extend(
49
+ text.text_schema(TemplateText)
50
+ .extend(
50
51
  {
51
- cv.GenerateID(): cv.declare_id(TemplateText),
52
52
  cv.Optional(CONF_MIN_LENGTH, default=0): cv.int_range(min=0, max=255),
53
53
  cv.Optional(CONF_MAX_LENGTH, default=255): cv.int_range(min=0, max=255),
54
54
  cv.Optional(CONF_PATTERN): cv.string,
@@ -58,7 +58,8 @@ CONFIG_SCHEMA = cv.All(
58
58
  cv.Optional(CONF_INITIAL_VALUE): cv.string_strict,
59
59
  cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean,
60
60
  }
61
- ).extend(cv.polling_component_schema("60s")),
61
+ )
62
+ .extend(cv.polling_component_schema("60s")),
62
63
  validate,
63
64
  )
64
65
 
@@ -21,6 +21,10 @@ from .. import template_ns
21
21
 
22
22
  TemplateValve = template_ns.class_("TemplateValve", valve.Valve, cg.Component)
23
23
 
24
+ TemplateValvePublishAction = template_ns.class_(
25
+ "TemplateValvePublishAction", automation.Action, cg.Parented.template(TemplateValve)
26
+ )
27
+
24
28
  TemplateValveRestoreMode = template_ns.enum("TemplateValveRestoreMode")
25
29
  RESTORE_MODES = {
26
30
  "NO_RESTORE": TemplateValveRestoreMode.VALVE_NO_RESTORE,
@@ -31,23 +35,30 @@ RESTORE_MODES = {
31
35
  CONF_HAS_POSITION = "has_position"
32
36
  CONF_TOGGLE_ACTION = "toggle_action"
33
37
 
34
- CONFIG_SCHEMA = valve.VALVE_SCHEMA.extend(
35
- {
36
- cv.GenerateID(): cv.declare_id(TemplateValve),
37
- cv.Optional(CONF_LAMBDA): cv.returning_lambda,
38
- cv.Optional(CONF_OPTIMISTIC, default=False): cv.boolean,
39
- cv.Optional(CONF_ASSUMED_STATE, default=False): cv.boolean,
40
- cv.Optional(CONF_HAS_POSITION, default=False): cv.boolean,
41
- cv.Optional(CONF_OPEN_ACTION): automation.validate_automation(single=True),
42
- cv.Optional(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
43
- cv.Optional(CONF_STOP_ACTION): automation.validate_automation(single=True),
44
- cv.Optional(CONF_TOGGLE_ACTION): automation.validate_automation(single=True),
45
- cv.Optional(CONF_POSITION_ACTION): automation.validate_automation(single=True),
46
- cv.Optional(CONF_RESTORE_MODE, default="NO_RESTORE"): cv.enum(
47
- RESTORE_MODES, upper=True
48
- ),
49
- }
50
- ).extend(cv.COMPONENT_SCHEMA)
38
+ CONFIG_SCHEMA = (
39
+ valve.valve_schema(TemplateValve)
40
+ .extend(
41
+ {
42
+ cv.Optional(CONF_LAMBDA): cv.returning_lambda,
43
+ cv.Optional(CONF_OPTIMISTIC, default=False): cv.boolean,
44
+ cv.Optional(CONF_ASSUMED_STATE, default=False): cv.boolean,
45
+ cv.Optional(CONF_HAS_POSITION, default=False): cv.boolean,
46
+ cv.Optional(CONF_OPEN_ACTION): automation.validate_automation(single=True),
47
+ cv.Optional(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
48
+ cv.Optional(CONF_STOP_ACTION): automation.validate_automation(single=True),
49
+ cv.Optional(CONF_TOGGLE_ACTION): automation.validate_automation(
50
+ single=True
51
+ ),
52
+ cv.Optional(CONF_POSITION_ACTION): automation.validate_automation(
53
+ single=True
54
+ ),
55
+ cv.Optional(CONF_RESTORE_MODE, default="NO_RESTORE"): cv.enum(
56
+ RESTORE_MODES, upper=True
57
+ ),
58
+ }
59
+ )
60
+ .extend(cv.COMPONENT_SCHEMA)
61
+ )
51
62
 
52
63
 
53
64
  async def to_code(config):
@@ -90,10 +101,10 @@ async def to_code(config):
90
101
 
91
102
  @automation.register_action(
92
103
  "valve.template.publish",
93
- valve.ValvePublishAction,
104
+ TemplateValvePublishAction,
94
105
  cv.Schema(
95
106
  {
96
- cv.Required(CONF_ID): cv.use_id(valve.Valve),
107
+ cv.GenerateID(): cv.use_id(TemplateValve),
97
108
  cv.Exclusive(CONF_STATE, "pos"): cv.templatable(valve.validate_valve_state),
98
109
  cv.Exclusive(CONF_POSITION, "pos"): cv.templatable(cv.percentage),
99
110
  cv.Optional(CONF_CURRENT_OPERATION): cv.templatable(
@@ -103,8 +114,8 @@ async def to_code(config):
103
114
  ),
104
115
  )
105
116
  async def valve_template_publish_to_code(config, action_id, template_arg, args):
106
- paren = await cg.get_variable(config[CONF_ID])
107
- var = cg.new_Pvariable(action_id, template_arg, paren)
117
+ var = cg.new_Pvariable(action_id, template_arg)
118
+ await cg.register_parented(var, config[CONF_ID])
108
119
  if state_config := config.get(CONF_STATE):
109
120
  template_ = await cg.templatable(state_config, args, float)
110
121
  cg.add(var.set_position(template_))
@@ -0,0 +1,24 @@
1
+ #pragma once
2
+
3
+ #include "template_valve.h"
4
+
5
+ #include "esphome/core/automation.h"
6
+
7
+ namespace esphome {
8
+ namespace template_ {
9
+
10
+ template<typename... Ts> class TemplateValvePublishAction : public Action<Ts...>, public Parented<TemplateValve> {
11
+ TEMPLATABLE_VALUE(float, position)
12
+ TEMPLATABLE_VALUE(valve::ValveOperation, current_operation)
13
+
14
+ void play(Ts... x) override {
15
+ if (this->position_.has_value())
16
+ this->parent_->position = this->position_.value(x...);
17
+ if (this->current_operation_.has_value())
18
+ this->parent_->current_operation = this->current_operation_.value(x...);
19
+ this->parent_->publish_state();
20
+ }
21
+ };
22
+
23
+ } // namespace template_
24
+ } // namespace esphome
@@ -5,6 +5,8 @@ import esphome.codegen as cg
5
5
  from esphome.components import mqtt, web_server
6
6
  import esphome.config_validation as cv
7
7
  from esphome.const import (
8
+ CONF_ENTITY_CATEGORY,
9
+ CONF_ICON,
8
10
  CONF_ID,
9
11
  CONF_MODE,
10
12
  CONF_MQTT_ID,
@@ -14,6 +16,7 @@ from esphome.const import (
14
16
  CONF_WEB_SERVER,
15
17
  )
16
18
  from esphome.core import CORE, coroutine_with_priority
19
+ from esphome.cpp_generator import MockObjClass
17
20
  from esphome.cpp_helpers import setup_entity
18
21
 
19
22
  CODEOWNERS = ["@mauritskorse"]
@@ -39,7 +42,7 @@ TEXT_MODES = {
39
42
  "PASSWORD": TextMode.TEXT_MODE_PASSWORD, # to be implemented for keys, passwords, etc.
40
43
  }
41
44
 
42
- TEXT_SCHEMA = (
45
+ _TEXT_SCHEMA = (
43
46
  cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
44
47
  .extend(cv.MQTT_COMPONENT_SCHEMA)
45
48
  .extend(
@@ -57,6 +60,34 @@ TEXT_SCHEMA = (
57
60
  )
58
61
 
59
62
 
63
+ def text_schema(
64
+ class_: MockObjClass = cv.UNDEFINED,
65
+ *,
66
+ icon: str = cv.UNDEFINED,
67
+ entity_category: str = cv.UNDEFINED,
68
+ mode: str = cv.UNDEFINED,
69
+ ) -> cv.Schema:
70
+ schema = {}
71
+
72
+ if class_ is not cv.UNDEFINED:
73
+ schema[cv.GenerateID()] = cv.declare_id(class_)
74
+
75
+ for key, default, validator in [
76
+ (CONF_ICON, icon, cv.icon),
77
+ (CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
78
+ (CONF_MODE, mode, cv.enum(TEXT_MODES, upper=True)),
79
+ ]:
80
+ if default is not cv.UNDEFINED:
81
+ schema[cv.Optional(key, default=default)] = validator
82
+
83
+ return _TEXT_SCHEMA.extend(schema)
84
+
85
+
86
+ # Remove before 2025.11.0
87
+ TEXT_SCHEMA = text_schema()
88
+ TEXT_SCHEMA.add_extra(cv.deprecated_schema_constant("text"))
89
+
90
+
60
91
  async def setup_text_core_(
61
92
  var,
62
93
  config,
@@ -125,7 +125,7 @@ async def map_filter_to_code(config, filter_id):
125
125
 
126
126
  validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
127
127
 
128
- TEXT_SENSOR_SCHEMA = (
128
+ _TEXT_SENSOR_SCHEMA = (
129
129
  cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
130
130
  .extend(cv.MQTT_COMPONENT_SCHEMA)
131
131
  .extend(
@@ -152,38 +152,33 @@ TEXT_SENSOR_SCHEMA = (
152
152
  )
153
153
  )
154
154
 
155
- _UNDEF = object()
156
-
157
155
 
158
156
  def text_sensor_schema(
159
- class_: MockObjClass = _UNDEF,
157
+ class_: MockObjClass = cv.UNDEFINED,
160
158
  *,
161
- icon: str = _UNDEF,
162
- entity_category: str = _UNDEF,
163
- device_class: str = _UNDEF,
159
+ device_class: str = cv.UNDEFINED,
160
+ entity_category: str = cv.UNDEFINED,
161
+ icon: str = cv.UNDEFINED,
164
162
  ) -> cv.Schema:
165
- schema = TEXT_SENSOR_SCHEMA
166
- if class_ is not _UNDEF:
167
- schema = schema.extend({cv.GenerateID(): cv.declare_id(class_)})
168
- if icon is not _UNDEF:
169
- schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon})
170
- if device_class is not _UNDEF:
171
- schema = schema.extend(
172
- {
173
- cv.Optional(
174
- CONF_DEVICE_CLASS, default=device_class
175
- ): validate_device_class
176
- }
177
- )
178
- if entity_category is not _UNDEF:
179
- schema = schema.extend(
180
- {
181
- cv.Optional(
182
- CONF_ENTITY_CATEGORY, default=entity_category
183
- ): cv.entity_category
184
- }
185
- )
186
- return schema
163
+ schema = {}
164
+
165
+ if class_ is not cv.UNDEFINED:
166
+ schema[cv.GenerateID()] = cv.declare_id(class_)
167
+
168
+ for key, default, validator in [
169
+ (CONF_ICON, icon, cv.icon),
170
+ (CONF_DEVICE_CLASS, device_class, validate_device_class),
171
+ (CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
172
+ ]:
173
+ if default is not cv.UNDEFINED:
174
+ schema[cv.Optional(key, default=default)] = validator
175
+
176
+ return _TEXT_SENSOR_SCHEMA.extend(schema)
177
+
178
+
179
+ # Remove before 2025.11.0
180
+ TEXT_SENSOR_SCHEMA = text_sensor_schema()
181
+ TEXT_SENSOR_SCHEMA.add_extra(cv.deprecated_schema_constant("text_sensor"))
187
182
 
188
183
 
189
184
  async def build_filters(config):
@@ -516,9 +516,9 @@ def validate_thermostat(config):
516
516
 
517
517
 
518
518
  CONFIG_SCHEMA = cv.All(
519
- climate.CLIMATE_SCHEMA.extend(
519
+ climate.climate_schema(ThermostatClimate)
520
+ .extend(
520
521
  {
521
- cv.GenerateID(): cv.declare_id(ThermostatClimate),
522
522
  cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
523
523
  cv.Optional(CONF_HUMIDITY_SENSOR): cv.use_id(sensor.Sensor),
524
524
  cv.Required(CONF_IDLE_ACTION): automation.validate_automation(single=True),
@@ -631,7 +631,8 @@ CONFIG_SCHEMA = cv.All(
631
631
  single=True
632
632
  ),
633
633
  }
634
- ).extend(cv.COMPONENT_SCHEMA),
634
+ )
635
+ .extend(cv.COMPONENT_SCHEMA),
635
636
  cv.has_at_least_one_key(
636
637
  CONF_COOL_ACTION, CONF_DRY_ACTION, CONF_FAN_ONLY_ACTION, CONF_HEAT_ACTION
637
638
  ),
@@ -640,9 +641,8 @@ CONFIG_SCHEMA = cv.All(
640
641
 
641
642
 
642
643
  async def to_code(config):
643
- var = cg.new_Pvariable(config[CONF_ID])
644
+ var = await climate.new_climate(config)
644
645
  await cg.register_component(var, config)
645
- await climate.register_climate(var, config)
646
646
 
647
647
  heat_cool_mode_available = CONF_HEAT_ACTION in config and CONF_COOL_ACTION in config
648
648
  two_points_available = CONF_HEAT_ACTION in config and (
@@ -6,7 +6,6 @@ from esphome.const import (
6
6
  CONF_ASSUMED_STATE,
7
7
  CONF_CLOSE_ACTION,
8
8
  CONF_CLOSE_DURATION,
9
- CONF_ID,
10
9
  CONF_OPEN_ACTION,
11
10
  CONF_OPEN_DURATION,
12
11
  CONF_STOP_ACTION,
@@ -18,25 +17,27 @@ TimeBasedCover = time_based_ns.class_("TimeBasedCover", cover.Cover, cg.Componen
18
17
  CONF_HAS_BUILT_IN_ENDSTOP = "has_built_in_endstop"
19
18
  CONF_MANUAL_CONTROL = "manual_control"
20
19
 
21
- CONFIG_SCHEMA = cover.COVER_SCHEMA.extend(
22
- {
23
- cv.GenerateID(): cv.declare_id(TimeBasedCover),
24
- cv.Required(CONF_STOP_ACTION): automation.validate_automation(single=True),
25
- cv.Required(CONF_OPEN_ACTION): automation.validate_automation(single=True),
26
- cv.Required(CONF_OPEN_DURATION): cv.positive_time_period_milliseconds,
27
- cv.Required(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
28
- cv.Required(CONF_CLOSE_DURATION): cv.positive_time_period_milliseconds,
29
- cv.Optional(CONF_HAS_BUILT_IN_ENDSTOP, default=False): cv.boolean,
30
- cv.Optional(CONF_MANUAL_CONTROL, default=False): cv.boolean,
31
- cv.Optional(CONF_ASSUMED_STATE, default=True): cv.boolean,
32
- }
33
- ).extend(cv.COMPONENT_SCHEMA)
20
+ CONFIG_SCHEMA = (
21
+ cover.cover_schema(TimeBasedCover)
22
+ .extend(
23
+ {
24
+ cv.Required(CONF_STOP_ACTION): automation.validate_automation(single=True),
25
+ cv.Required(CONF_OPEN_ACTION): automation.validate_automation(single=True),
26
+ cv.Required(CONF_OPEN_DURATION): cv.positive_time_period_milliseconds,
27
+ cv.Required(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
28
+ cv.Required(CONF_CLOSE_DURATION): cv.positive_time_period_milliseconds,
29
+ cv.Optional(CONF_HAS_BUILT_IN_ENDSTOP, default=False): cv.boolean,
30
+ cv.Optional(CONF_MANUAL_CONTROL, default=False): cv.boolean,
31
+ cv.Optional(CONF_ASSUMED_STATE, default=True): cv.boolean,
32
+ }
33
+ )
34
+ .extend(cv.COMPONENT_SCHEMA)
35
+ )
34
36
 
35
37
 
36
38
  async def to_code(config):
37
- var = cg.new_Pvariable(config[CONF_ID])
39
+ var = await cover.new_cover(config)
38
40
  await cg.register_component(var, config)
39
- await cover.register_cover(var, config)
40
41
 
41
42
  await automation.build_automation(
42
43
  var.get_stop_trigger(), [], config[CONF_STOP_ACTION]
@@ -1,6 +1,7 @@
1
1
  #include "time_based_cover.h"
2
2
  #include "esphome/core/log.h"
3
3
  #include "esphome/core/hal.h"
4
+ #include "esphome/core/application.h"
4
5
 
5
6
  namespace esphome {
6
7
  namespace time_based {
@@ -26,7 +27,7 @@ void TimeBasedCover::loop() {
26
27
  if (this->current_operation == COVER_OPERATION_IDLE)
27
28
  return;
28
29
 
29
- const uint32_t now = millis();
30
+ const uint32_t now = App.get_loop_component_start_time();
30
31
 
31
32
  // Recompute position every loop cycle
32
33
  this->recompute_position_();
@@ -8,13 +8,16 @@ from ..display import CONF_TM1638_ID, TM1638Component, tm1638_ns
8
8
  TM1638SwitchLed = tm1638_ns.class_("TM1638SwitchLed", switch.Switch, cg.Component)
9
9
 
10
10
 
11
- CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend(
12
- {
13
- cv.GenerateID(): cv.declare_id(TM1638SwitchLed),
14
- cv.GenerateID(CONF_TM1638_ID): cv.use_id(TM1638Component),
15
- cv.Required(CONF_LED): cv.int_range(min=0, max=7),
16
- }
17
- ).extend(cv.COMPONENT_SCHEMA)
11
+ CONFIG_SCHEMA = (
12
+ switch.switch_schema(TM1638SwitchLed)
13
+ .extend(
14
+ {
15
+ cv.GenerateID(CONF_TM1638_ID): cv.use_id(TM1638Component),
16
+ cv.Required(CONF_LED): cv.int_range(min=0, max=7),
17
+ }
18
+ )
19
+ .extend(cv.COMPONENT_SCHEMA)
20
+ )
18
21
 
19
22
 
20
23
  async def to_code(config):
@@ -1,17 +1,17 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import cover, uart
3
3
  import esphome.config_validation as cv
4
- from esphome.const import CONF_CLOSE_DURATION, CONF_ID, CONF_OPEN_DURATION
4
+ from esphome.const import CONF_CLOSE_DURATION, CONF_OPEN_DURATION
5
5
 
6
6
  tormatic_ns = cg.esphome_ns.namespace("tormatic")
7
7
  Tormatic = tormatic_ns.class_("Tormatic", cover.Cover, cg.PollingComponent)
8
8
 
9
9
  CONFIG_SCHEMA = (
10
- cover.COVER_SCHEMA.extend(uart.UART_DEVICE_SCHEMA)
10
+ cover.cover_schema(Tormatic)
11
+ .extend(uart.UART_DEVICE_SCHEMA)
11
12
  .extend(cv.polling_component_schema("300ms"))
12
13
  .extend(
13
14
  {
14
- cv.GenerateID(): cv.declare_id(Tormatic),
15
15
  cv.Optional(
16
16
  CONF_OPEN_DURATION, default="15s"
17
17
  ): cv.positive_time_period_milliseconds,
@@ -34,9 +34,8 @@ FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
34
34
 
35
35
 
36
36
  async def to_code(config):
37
- var = cg.new_Pvariable(config[CONF_ID])
37
+ var = await cover.new_cover(config)
38
38
  await cg.register_component(var, config)
39
- await cover.register_cover(var, config)
40
39
  await uart.register_uart_device(var, config)
41
40
 
42
41
  cg.add(var.set_close_duration(config[CONF_CLOSE_DURATION]))
@@ -1,7 +1,7 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import climate_ir
3
3
  import esphome.config_validation as cv
4
- from esphome.const import CONF_ID, CONF_MODEL
4
+ from esphome.const import CONF_MODEL
5
5
 
6
6
  AUTO_LOAD = ["climate_ir"]
7
7
  CODEOWNERS = ["@kbx81"]
@@ -16,15 +16,13 @@ MODELS = {
16
16
  "RAC-PT1411HWRU-F": Model.MODEL_RAC_PT1411HWRU_F,
17
17
  }
18
18
 
19
- CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
19
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(ToshibaClimate).extend(
20
20
  {
21
- cv.GenerateID(): cv.declare_id(ToshibaClimate),
22
21
  cv.Optional(CONF_MODEL, default="generic"): cv.enum(MODELS, upper=True),
23
22
  }
24
23
  )
25
24
 
26
25
 
27
26
  async def to_code(config):
28
- var = cg.new_Pvariable(config[CONF_ID])
29
- await climate_ir.register_climate_ir(var, config)
27
+ var = await climate_ir.new_climate_ir(config)
30
28
  cg.add(var.set_model(config[CONF_MODEL]))
@@ -50,13 +50,15 @@ void Touchscreen::loop() {
50
50
  tp.second.x_prev = tp.second.x;
51
51
  tp.second.y_prev = tp.second.y;
52
52
  }
53
+ // The interrupt flag must be reset BEFORE calling update_touches, otherwise we might miss an interrupt that was
54
+ // triggered while we were reading touch data.
55
+ this->store_.touched = false;
53
56
  this->update_touches();
54
57
  if (this->skip_update_) {
55
58
  for (auto &tp : this->touches_) {
56
59
  tp.second.state &= ~STATE_RELEASING;
57
60
  }
58
61
  } else {
59
- this->store_.touched = false;
60
62
  this->defer([this]() { this->send_touches_(); });
61
63
  if (this->touch_timeout_ > 0) {
62
64
  // Simulate a touch after <this->touch_timeout_> ms. This will reset any existing timeout operation.
@@ -4,7 +4,6 @@ from esphome.components import climate
4
4
  import esphome.config_validation as cv
5
5
  from esphome.const import (
6
6
  CONF_FAN_MODE,
7
- CONF_ID,
8
7
  CONF_PRESET,
9
8
  CONF_SUPPORTS_COOL,
10
9
  CONF_SUPPORTS_HEAT,
@@ -151,9 +150,9 @@ SWING_MODES = cv.Schema(
151
150
  )
152
151
 
153
152
  CONFIG_SCHEMA = cv.All(
154
- climate.CLIMATE_SCHEMA.extend(
153
+ climate.climate_schema(TuyaClimate)
154
+ .extend(
155
155
  {
156
- cv.GenerateID(): cv.declare_id(TuyaClimate),
157
156
  cv.GenerateID(CONF_TUYA_ID): cv.use_id(Tuya),
158
157
  cv.Optional(CONF_SUPPORTS_HEAT, default=True): cv.boolean,
159
158
  cv.Optional(CONF_SUPPORTS_COOL, default=False): cv.boolean,
@@ -186,7 +185,8 @@ CONFIG_SCHEMA = cv.All(
186
185
  "'eco_temperature' has been moved inside of the 'eco' config block under 'preset' as 'temperature'"
187
186
  ),
188
187
  }
189
- ).extend(cv.COMPONENT_SCHEMA),
188
+ )
189
+ .extend(cv.COMPONENT_SCHEMA),
190
190
  cv.has_at_least_one_key(CONF_TARGET_TEMPERATURE_DATAPOINT, CONF_SWITCH_DATAPOINT),
191
191
  validate_temperature_multipliers,
192
192
  validate_cooling_values,
@@ -194,9 +194,8 @@ CONFIG_SCHEMA = cv.All(
194
194
 
195
195
 
196
196
  async def to_code(config):
197
- var = cg.new_Pvariable(config[CONF_ID])
197
+ var = await climate.new_climate(config)
198
198
  await cg.register_component(var, config)
199
- await climate.register_climate(var, config)
200
199
 
201
200
  paren = await cg.get_variable(config[CONF_TUYA_ID])
202
201
  cg.add(var.set_tuya_parent(paren))
@@ -1,12 +1,7 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import cover
3
3
  import esphome.config_validation as cv
4
- from esphome.const import (
5
- CONF_MAX_VALUE,
6
- CONF_MIN_VALUE,
7
- CONF_OUTPUT_ID,
8
- CONF_RESTORE_MODE,
9
- )
4
+ from esphome.const import CONF_MAX_VALUE, CONF_MIN_VALUE, CONF_RESTORE_MODE
10
5
 
11
6
  from .. import CONF_TUYA_ID, Tuya, tuya_ns
12
7
 
@@ -38,9 +33,9 @@ def validate_range(config):
38
33
 
39
34
 
40
35
  CONFIG_SCHEMA = cv.All(
41
- cover.COVER_SCHEMA.extend(
36
+ cover.cover_schema(TuyaCover)
37
+ .extend(
42
38
  {
43
- cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(TuyaCover),
44
39
  cv.GenerateID(CONF_TUYA_ID): cv.use_id(Tuya),
45
40
  cv.Optional(CONF_CONTROL_DATAPOINT): cv.uint8_t,
46
41
  cv.Optional(CONF_DIRECTION_DATAPOINT): cv.uint8_t,
@@ -54,15 +49,15 @@ CONFIG_SCHEMA = cv.All(
54
49
  RESTORE_MODES, upper=True
55
50
  ),
56
51
  },
57
- ).extend(cv.COMPONENT_SCHEMA),
52
+ )
53
+ .extend(cv.COMPONENT_SCHEMA),
58
54
  validate_range,
59
55
  )
60
56
 
61
57
 
62
58
  async def to_code(config):
63
- var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
59
+ var = await cover.new_cover(config)
64
60
  await cg.register_component(var, config)
65
- await cover.register_cover(var, config)
66
61
 
67
62
  if CONF_CONTROL_DATAPOINT in config:
68
63
  cg.add(var.set_control_id(config[CONF_CONTROL_DATAPOINT]))