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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. esphome/__main__.py +16 -14
  2. esphome/components/ac_dimmer/ac_dimmer.cpp +3 -2
  3. esphome/components/adc/__init__.py +51 -34
  4. esphome/components/airthings_wave_base/__init__.py +1 -1
  5. esphome/components/alarm_control_panel/__init__.py +37 -2
  6. esphome/components/am43/cover/__init__.py +4 -5
  7. esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
  8. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
  9. esphome/components/analog_threshold/binary_sensor.py +10 -8
  10. esphome/components/anova/climate.py +4 -5
  11. esphome/components/api/__init__.py +25 -8
  12. esphome/components/api/api_connection.cpp +416 -662
  13. esphome/components/api/api_connection.h +256 -57
  14. esphome/components/api/api_frame_helper.cpp +232 -177
  15. esphome/components/api/api_frame_helper.h +61 -8
  16. esphome/components/api/api_noise_context.h +13 -4
  17. esphome/components/api/api_pb2.cpp +1422 -1
  18. esphome/components/api/api_pb2.h +255 -1
  19. esphome/components/api/api_pb2_service.cpp +162 -49
  20. esphome/components/api/api_pb2_service.h +90 -51
  21. esphome/components/api/api_pb2_size.h +361 -0
  22. esphome/components/api/api_server.cpp +110 -34
  23. esphome/components/api/api_server.h +8 -0
  24. esphome/components/api/proto.h +86 -17
  25. esphome/components/as3935_i2c/as3935_i2c.h +0 -3
  26. esphome/components/as7341/as7341.h +1 -1
  27. esphome/components/at581x/at581x.h +4 -4
  28. esphome/components/atm90e32/__init__.py +1 -0
  29. esphome/components/atm90e32/atm90e32.cpp +576 -199
  30. esphome/components/atm90e32/atm90e32.h +128 -31
  31. esphome/components/atm90e32/atm90e32_reg.h +4 -2
  32. esphome/components/atm90e32/button/__init__.py +62 -10
  33. esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
  34. esphome/components/atm90e32/button/atm90e32_button.h +36 -4
  35. esphome/components/atm90e32/number/__init__.py +130 -0
  36. esphome/components/atm90e32/number/atm90e32_number.h +16 -0
  37. esphome/components/atm90e32/sensor.py +21 -4
  38. esphome/components/atm90e32/text_sensor/__init__.py +48 -0
  39. esphome/components/audio/__init__.py +96 -49
  40. esphome/components/audio/audio.h +48 -0
  41. esphome/components/audio/audio_decoder.cpp +1 -1
  42. esphome/components/audio/audio_resampler.cpp +2 -0
  43. esphome/components/audio/audio_resampler.h +1 -0
  44. esphome/components/ballu/climate.py +2 -9
  45. esphome/components/bang_bang/climate.py +5 -6
  46. esphome/components/bedjet/bedjet_hub.cpp +1 -0
  47. esphome/components/bedjet/climate/__init__.py +3 -8
  48. esphome/components/bedjet/fan/__init__.py +2 -11
  49. esphome/components/binary/fan/__init__.py +13 -16
  50. esphome/components/binary_sensor/__init__.py +13 -10
  51. esphome/components/bl0906/constants.h +16 -16
  52. esphome/components/ble_client/text_sensor/__init__.py +3 -5
  53. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
  54. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +136 -21
  55. esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
  56. esphome/components/button/__init__.py +11 -8
  57. esphome/components/canbus/canbus.cpp +3 -0
  58. esphome/components/canbus/canbus.h +16 -0
  59. esphome/components/ccs811/sensor.py +9 -6
  60. esphome/components/climate/__init__.py +35 -2
  61. esphome/components/climate/climate_mode.h +1 -1
  62. esphome/components/climate/climate_traits.h +63 -57
  63. esphome/components/climate_ir/__init__.py +57 -17
  64. esphome/components/climate_ir_lg/climate.py +2 -5
  65. esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
  66. esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
  67. esphome/components/color/__init__.py +2 -0
  68. esphome/components/const/__init__.py +5 -0
  69. esphome/components/coolix/climate.py +2 -9
  70. esphome/components/copy/cover/__init__.py +10 -9
  71. esphome/components/copy/fan/__init__.py +11 -9
  72. esphome/components/copy/lock/__init__.py +11 -9
  73. esphome/components/copy/text/__init__.py +9 -6
  74. esphome/components/cover/__init__.py +37 -2
  75. esphome/components/cse7766/cse7766.cpp +2 -1
  76. esphome/components/cst226/binary_sensor/__init__.py +28 -0
  77. esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
  78. esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
  79. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
  80. esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
  81. esphome/components/current_based/cover.py +37 -36
  82. esphome/components/current_based/current_based_cover.cpp +2 -1
  83. esphome/components/daikin/climate.py +2 -9
  84. esphome/components/daikin/daikin.cpp +15 -9
  85. esphome/components/daikin/daikin.h +5 -5
  86. esphome/components/daikin_arc/climate.py +2 -7
  87. esphome/components/daikin_brc/climate.py +3 -5
  88. esphome/components/dallas_temp/dallas_temp.cpp +17 -24
  89. esphome/components/dallas_temp/dallas_temp.h +0 -1
  90. esphome/components/daly_bms/daly_bms.cpp +2 -1
  91. esphome/components/debug/debug_component.cpp +6 -1
  92. esphome/components/debug/debug_component.h +8 -0
  93. esphome/components/debug/debug_esp32.cpp +109 -254
  94. esphome/components/debug/sensor.py +14 -0
  95. esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
  96. esphome/components/delonghi/climate.py +2 -9
  97. esphome/components/demo/__init__.py +18 -20
  98. esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
  99. esphome/components/display/rect.cpp +4 -9
  100. esphome/components/display/rect.h +1 -1
  101. esphome/components/dps310/sensor.py +6 -6
  102. esphome/components/ee895/sensor.py +9 -9
  103. esphome/components/emmeti/climate.py +2 -9
  104. esphome/components/endstop/cover.py +17 -16
  105. esphome/components/endstop/endstop_cover.cpp +2 -1
  106. esphome/components/ens160_base/__init__.py +12 -9
  107. esphome/components/esp32/__init__.py +60 -3
  108. esphome/components/esp32/core.cpp +11 -5
  109. esphome/components/esp32/gpio.cpp +86 -24
  110. esphome/components/esp32/gpio.py +15 -16
  111. esphome/components/esp32/gpio_esp32.py +1 -2
  112. esphome/components/esp32/gpio_esp32_c2.py +1 -1
  113. esphome/components/esp32/gpio_esp32_c3.py +1 -1
  114. esphome/components/esp32/gpio_esp32_c6.py +1 -1
  115. esphome/components/esp32/gpio_esp32_h2.py +1 -1
  116. esphome/components/esp32_ble/ble.cpp +1 -8
  117. esphome/components/esp32_ble/ble.h +5 -3
  118. esphome/components/esp32_ble/ble_advertising.cpp +2 -1
  119. esphome/components/esp32_ble/ble_advertising.h +1 -0
  120. esphome/components/esp32_ble_server/__init__.py +3 -0
  121. esphome/components/esp32_ble_tracker/__init__.py +7 -1
  122. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
  123. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
  124. esphome/components/esp32_camera/__init__.py +1 -1
  125. esphome/components/esp32_camera/esp32_camera.cpp +2 -10
  126. esphome/components/esp32_camera/esp32_camera.h +1 -1
  127. esphome/components/esp32_can/esp32_can.cpp +1 -1
  128. esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
  129. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  130. esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
  131. esphome/components/esp32_rmt_led_strip/light.py +9 -1
  132. esphome/components/esp32_touch/esp32_touch.cpp +1 -1
  133. esphome/components/esp8266/gpio.cpp +69 -8
  134. esphome/components/ethernet/ethernet_component.cpp +1 -1
  135. esphome/components/event/__init__.py +13 -10
  136. esphome/components/factory_reset/switch/__init__.py +7 -21
  137. esphome/components/fan/__init__.py +52 -5
  138. esphome/components/fastled_base/__init__.py +1 -4
  139. esphome/components/fastled_base/fastled_light.cpp +1 -1
  140. esphome/components/feedback/cover.py +38 -33
  141. esphome/components/feedback/feedback_cover.cpp +2 -1
  142. esphome/components/fujitsu_general/climate.py +2 -9
  143. esphome/components/gcja5/gcja5.cpp +2 -1
  144. esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
  145. esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
  146. esphome/components/gpio_expander/cached_gpio.h +22 -7
  147. esphome/components/gps/__init__.py +47 -17
  148. esphome/components/gps/gps.cpp +42 -23
  149. esphome/components/gps/gps.h +17 -13
  150. esphome/components/graph/__init__.py +1 -2
  151. esphome/components/gree/climate.py +4 -6
  152. esphome/components/gree/gree.cpp +16 -2
  153. esphome/components/gree/gree.h +2 -2
  154. esphome/components/growatt_solar/growatt_solar.cpp +2 -1
  155. esphome/components/haier/climate.py +37 -34
  156. esphome/components/hbridge/fan/__init__.py +19 -17
  157. esphome/components/he60r/cover.py +4 -5
  158. esphome/components/heatpumpir/climate.py +3 -6
  159. esphome/components/hitachi_ac344/climate.py +2 -9
  160. esphome/components/hitachi_ac424/climate.py +2 -9
  161. esphome/components/hlw8012/hlw8012.cpp +1 -1
  162. esphome/components/hm3301/hm3301.h +1 -1
  163. esphome/components/hte501/sensor.py +6 -6
  164. esphome/components/http_request/__init__.py +39 -6
  165. esphome/components/http_request/http_request.cpp +20 -0
  166. esphome/components/http_request/http_request.h +57 -15
  167. esphome/components/http_request/http_request_arduino.cpp +22 -6
  168. esphome/components/http_request/http_request_arduino.h +4 -3
  169. esphome/components/http_request/http_request_host.cpp +141 -0
  170. esphome/components/http_request/http_request_host.h +37 -0
  171. esphome/components/http_request/http_request_idf.cpp +35 -3
  172. esphome/components/http_request/http_request_idf.h +10 -3
  173. esphome/components/http_request/httplib.h +9691 -0
  174. esphome/components/http_request/update/__init__.py +11 -8
  175. esphome/components/hyt271/sensor.py +6 -6
  176. esphome/components/i2c/i2c.h +4 -0
  177. esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
  178. esphome/components/i2s_audio/__init__.py +131 -22
  179. esphome/components/i2s_audio/i2s_audio.h +44 -4
  180. esphome/components/i2s_audio/media_player/__init__.py +19 -9
  181. esphome/components/i2s_audio/microphone/__init__.py +63 -5
  182. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
  183. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
  184. esphome/components/i2s_audio/speaker/__init__.py +31 -5
  185. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
  186. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
  187. esphome/components/ili9xxx/ili9xxx_init.h +1 -1
  188. esphome/components/image/__init__.py +37 -17
  189. esphome/components/image/image.cpp +25 -8
  190. esphome/components/internal_temperature/internal_temperature.cpp +6 -4
  191. esphome/components/key_collector/__init__.py +35 -0
  192. esphome/components/key_collector/key_collector.cpp +8 -0
  193. esphome/components/key_collector/key_collector.h +10 -0
  194. esphome/components/kuntze/kuntze.cpp +2 -1
  195. esphome/components/ld2410/ld2410.h +1 -1
  196. esphome/components/ld2450/ld2450.h +1 -1
  197. esphome/components/light/__init__.py +57 -0
  198. esphome/components/lock/__init__.py +51 -4
  199. esphome/components/lock/automation.h +2 -13
  200. esphome/components/logger/__init__.py +22 -0
  201. esphome/components/logger/logger.cpp +154 -103
  202. esphome/components/logger/logger.h +211 -36
  203. esphome/components/logger/task_log_buffer.cpp +138 -0
  204. esphome/components/logger/task_log_buffer.h +69 -0
  205. esphome/components/lvgl/__init__.py +13 -5
  206. esphome/components/lvgl/automation.py +50 -1
  207. esphome/components/lvgl/defines.py +0 -1
  208. esphome/components/lvgl/lv_validation.py +10 -1
  209. esphome/components/lvgl/lvgl_esphome.cpp +5 -1
  210. esphome/components/lvgl/schemas.py +14 -14
  211. esphome/components/lvgl/text/__init__.py +1 -2
  212. esphome/components/lvgl/widgets/arc.py +7 -6
  213. esphome/components/lvgl/widgets/buttonmatrix.py +3 -3
  214. esphome/components/lvgl/widgets/checkbox.py +2 -2
  215. esphome/components/lvgl/widgets/dropdown.py +2 -1
  216. esphome/components/lvgl/widgets/img.py +15 -12
  217. esphome/components/mapping/__init__.py +134 -0
  218. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
  219. esphome/components/max7219digit/max7219digit.cpp +28 -27
  220. esphome/components/mdns/__init__.py +11 -5
  221. esphome/components/mdns/mdns_component.cpp +11 -5
  222. esphome/components/mdns/mdns_component.h +3 -2
  223. esphome/components/mdns/mdns_esp32.cpp +4 -3
  224. esphome/components/mdns/mdns_esp8266.cpp +4 -2
  225. esphome/components/mdns/mdns_libretiny.cpp +4 -2
  226. esphome/components/mdns/mdns_rp2040.cpp +4 -2
  227. esphome/components/media_player/__init__.py +40 -6
  228. esphome/components/mhz19/sensor.py +11 -7
  229. esphome/components/micro_wake_word/__init__.py +99 -31
  230. esphome/components/micro_wake_word/automation.h +54 -0
  231. esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
  232. esphome/components/micro_wake_word/micro_wake_word.h +58 -105
  233. esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
  234. esphome/components/micro_wake_word/streaming_model.cpp +158 -41
  235. esphome/components/micro_wake_word/streaming_model.h +85 -13
  236. esphome/components/microphone/__init__.py +139 -9
  237. esphome/components/microphone/automation.h +14 -2
  238. esphome/components/microphone/microphone.cpp +21 -0
  239. esphome/components/microphone/microphone.h +14 -5
  240. esphome/components/microphone/microphone_source.cpp +95 -0
  241. esphome/components/microphone/microphone_source.h +80 -0
  242. esphome/components/mics_4514/sensor.py +25 -14
  243. esphome/components/midea/climate.py +3 -4
  244. esphome/components/midea_ir/climate.py +3 -5
  245. esphome/components/mipi_spi/__init__.py +15 -0
  246. esphome/components/mipi_spi/display.py +474 -0
  247. esphome/components/mipi_spi/mipi_spi.cpp +481 -0
  248. esphome/components/mipi_spi/mipi_spi.h +171 -0
  249. esphome/components/mipi_spi/models/__init__.py +65 -0
  250. esphome/components/mipi_spi/models/amoled.py +72 -0
  251. esphome/components/mipi_spi/models/commands.py +82 -0
  252. esphome/components/mipi_spi/models/cyd.py +10 -0
  253. esphome/components/mipi_spi/models/ili.py +749 -0
  254. esphome/components/mipi_spi/models/jc.py +260 -0
  255. esphome/components/mipi_spi/models/lanbon.py +15 -0
  256. esphome/components/mipi_spi/models/lilygo.py +60 -0
  257. esphome/components/mipi_spi/models/waveshare.py +139 -0
  258. esphome/components/mitsubishi/climate.py +2 -5
  259. esphome/components/mitsubishi/mitsubishi.cpp +9 -9
  260. esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
  261. esphome/components/mixer/speaker/mixer_speaker.h +1 -3
  262. esphome/components/mlx90393/sensor.py +5 -0
  263. esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
  264. esphome/components/mlx90393/sensor_mlx90393.h +21 -4
  265. esphome/components/modbus/modbus.cpp +2 -1
  266. esphome/components/mqtt/__init__.py +1 -1
  267. esphome/components/mqtt/mqtt_client.cpp +6 -2
  268. esphome/components/mqtt/mqtt_const.h +4 -0
  269. esphome/components/mqtt/mqtt_fan.cpp +39 -0
  270. esphome/components/mqtt/mqtt_fan.h +2 -0
  271. esphome/components/ms5611/sensor.py +6 -6
  272. esphome/components/ms8607/sensor.py +3 -3
  273. esphome/components/network/__init__.py +1 -1
  274. esphome/components/nextion/base_component.py +17 -16
  275. esphome/components/nextion/display.py +11 -2
  276. esphome/components/nextion/nextion.cpp +39 -1
  277. esphome/components/nextion/nextion.h +50 -0
  278. esphome/components/noblex/climate.py +2 -9
  279. esphome/components/number/__init__.py +12 -9
  280. esphome/components/one_wire/one_wire_bus.cpp +14 -10
  281. esphome/components/one_wire/one_wire_bus.h +14 -8
  282. esphome/components/online_image/bmp_image.cpp +48 -11
  283. esphome/components/online_image/bmp_image.h +2 -0
  284. esphome/components/opentherm/binary_sensor/__init__.py +2 -4
  285. esphome/components/opentherm/number/__init__.py +11 -20
  286. esphome/components/opentherm/sensor/__init__.py +3 -3
  287. esphome/components/opentherm/switch/__init__.py +3 -5
  288. esphome/components/output/lock/__init__.py +11 -9
  289. esphome/components/packages/__init__.py +33 -31
  290. esphome/components/packet_transport/__init__.py +201 -0
  291. esphome/components/packet_transport/binary_sensor.py +19 -0
  292. esphome/components/packet_transport/packet_transport.cpp +534 -0
  293. esphome/components/packet_transport/packet_transport.h +154 -0
  294. esphome/components/packet_transport/sensor.py +19 -0
  295. esphome/components/pca9685/pca9685_output.cpp +2 -1
  296. esphome/components/pid/climate.py +2 -4
  297. esphome/components/pm2005/__init__.py +1 -0
  298. esphome/components/pm2005/pm2005.cpp +123 -0
  299. esphome/components/pm2005/pm2005.h +46 -0
  300. esphome/components/pm2005/sensor.py +86 -0
  301. esphome/components/pmsa003i/pmsa003i.cpp +43 -16
  302. esphome/components/pmsa003i/pmsa003i.h +25 -25
  303. esphome/components/pmsx003/pmsx003.cpp +195 -230
  304. esphome/components/pmsx003/pmsx003.h +51 -33
  305. esphome/components/pmsx003/sensor.py +21 -11
  306. esphome/components/pn7150/pn7150.h +2 -2
  307. esphome/components/pn7160/pn7160.h +2 -2
  308. esphome/components/prometheus/prometheus_handler.cpp +174 -0
  309. esphome/components/prometheus/prometheus_handler.h +17 -0
  310. esphome/components/psram/__init__.py +7 -5
  311. esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
  312. esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
  313. esphome/components/pzem004t/pzem004t.cpp +2 -1
  314. esphome/components/qspi_dbi/__init__.py +0 -1
  315. esphome/components/qspi_dbi/display.py +2 -1
  316. esphome/components/qspi_dbi/models.py +1 -2
  317. esphome/components/remote_base/__init__.py +91 -0
  318. esphome/components/remote_base/beo4_protocol.cpp +153 -0
  319. esphome/components/remote_base/beo4_protocol.h +43 -0
  320. esphome/components/remote_base/gobox_protocol.cpp +131 -0
  321. esphome/components/remote_base/gobox_protocol.h +54 -0
  322. esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
  323. esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
  324. esphome/components/resampler/speaker/resampler_speaker.h +1 -1
  325. esphome/components/rf_bridge/rf_bridge.cpp +2 -1
  326. esphome/components/scd30/sensor.py +2 -3
  327. esphome/components/scd4x/sensor.py +4 -5
  328. esphome/components/sdp3x/sensor.py +2 -1
  329. esphome/components/sds011/sds011.cpp +2 -1
  330. esphome/components/select/__init__.py +19 -20
  331. esphome/components/sen5x/sen5x.cpp +55 -36
  332. esphome/components/sen5x/sensor.py +1 -1
  333. esphome/components/senseair/sensor.py +3 -3
  334. esphome/components/sensor/__init__.py +158 -14
  335. esphome/components/sensor/filter.cpp +23 -0
  336. esphome/components/sensor/filter.h +22 -0
  337. esphome/components/sgp30/sensor.py +14 -16
  338. esphome/components/sgp4x/sensor.py +1 -1
  339. esphome/components/sht4x/sht4x.cpp +43 -22
  340. esphome/components/sht4x/sht4x.h +1 -1
  341. esphome/components/shtcx/sensor.py +6 -6
  342. esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
  343. esphome/components/sml/text_sensor/__init__.py +4 -6
  344. esphome/components/sound_level/__init__.py +0 -0
  345. esphome/components/sound_level/sensor.py +97 -0
  346. esphome/components/sound_level/sound_level.cpp +194 -0
  347. esphome/components/sound_level/sound_level.h +73 -0
  348. esphome/components/speaker/media_player/__init__.py +4 -8
  349. esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
  350. esphome/components/speaker/media_player/speaker_media_player.h +0 -11
  351. esphome/components/speaker/speaker.h +4 -7
  352. esphome/components/speed/fan/__init__.py +17 -16
  353. esphome/components/spi/spi.h +11 -1
  354. esphome/components/sprinkler/__init__.py +18 -19
  355. esphome/components/sprinkler/sprinkler.cpp +6 -5
  356. esphome/components/switch/__init__.py +32 -42
  357. esphome/components/syslog/__init__.py +41 -0
  358. esphome/components/syslog/esphome_syslog.cpp +49 -0
  359. esphome/components/syslog/esphome_syslog.h +27 -0
  360. esphome/components/t6615/sensor.py +3 -3
  361. esphome/components/t6615/t6615.cpp +2 -1
  362. esphome/components/tca9555/tca9555.cpp +11 -6
  363. esphome/components/tcl112/climate.py +2 -9
  364. esphome/components/template/alarm_control_panel/__init__.py +7 -6
  365. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
  366. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
  367. esphome/components/template/cover/__init__.py +27 -21
  368. esphome/components/template/fan/__init__.py +14 -12
  369. esphome/components/template/lock/__init__.py +20 -25
  370. esphome/components/template/lock/automation.h +18 -0
  371. esphome/components/template/text/__init__.py +4 -3
  372. esphome/components/template/valve/__init__.py +32 -21
  373. esphome/components/template/valve/automation.h +24 -0
  374. esphome/components/text/__init__.py +32 -1
  375. esphome/components/text_sensor/__init__.py +24 -29
  376. esphome/components/thermostat/climate.py +5 -5
  377. esphome/components/time_based/cover.py +17 -16
  378. esphome/components/time_based/time_based_cover.cpp +2 -1
  379. esphome/components/tm1638/switch/__init__.py +10 -7
  380. esphome/components/tormatic/cover.py +4 -5
  381. esphome/components/toshiba/climate.py +3 -5
  382. esphome/components/touchscreen/touchscreen.cpp +3 -1
  383. esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
  384. esphome/components/tuya/climate/__init__.py +5 -6
  385. esphome/components/tuya/cover/__init__.py +6 -11
  386. esphome/components/tuya/select/__init__.py +15 -5
  387. esphome/components/tuya/select/tuya_select.cpp +6 -1
  388. esphome/components/tuya/select/tuya_select.h +5 -1
  389. esphome/components/uart/packet_transport/__init__.py +20 -0
  390. esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
  391. esphome/components/uart/packet_transport/uart_transport.h +41 -0
  392. esphome/components/uart/switch/uart_switch.cpp +2 -1
  393. esphome/components/udp/__init__.py +126 -128
  394. esphome/components/udp/automation.h +40 -0
  395. esphome/components/udp/binary_sensor.py +3 -25
  396. esphome/components/udp/packet_transport/__init__.py +29 -0
  397. esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
  398. esphome/components/udp/packet_transport/udp_transport.h +28 -0
  399. esphome/components/udp/sensor.py +3 -25
  400. esphome/components/udp/udp_component.cpp +26 -470
  401. esphome/components/udp/udp_component.h +21 -128
  402. esphome/components/update/__init__.py +31 -1
  403. esphome/components/uponor_smatrix/climate/__init__.py +4 -9
  404. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
  405. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  406. esphome/components/uptime/text_sensor/__init__.py +47 -7
  407. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
  408. esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
  409. esphome/components/valve/__init__.py +34 -3
  410. esphome/components/valve/automation.h +1 -19
  411. esphome/components/vl53l0x/sensor.py +11 -0
  412. esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
  413. esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
  414. esphome/components/voice_assistant/__init__.py +36 -10
  415. esphome/components/voice_assistant/voice_assistant.cpp +170 -144
  416. esphome/components/voice_assistant/voice_assistant.h +26 -25
  417. esphome/components/waveshare_epaper/display.py +6 -0
  418. esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
  419. esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
  420. esphome/components/weikai/weikai.cpp +0 -52
  421. esphome/components/whirlpool/climate.py +3 -5
  422. esphome/components/whynter/climate.py +3 -5
  423. esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
  424. esphome/components/yashima/climate.py +6 -6
  425. esphome/components/zhlt01/climate.py +2 -7
  426. esphome/config.py +13 -13
  427. esphome/config_validation.py +38 -58
  428. esphome/const.py +15 -1
  429. esphome/core/__init__.py +2 -0
  430. esphome/core/application.cpp +27 -10
  431. esphome/core/application.h +9 -1
  432. esphome/core/automation.h +4 -3
  433. esphome/core/component.cpp +28 -7
  434. esphome/core/component.h +10 -1
  435. esphome/core/defines.h +23 -17
  436. esphome/core/doxygen.h +13 -0
  437. esphome/core/macros.h +4 -0
  438. esphome/core/scheduler.cpp +7 -1
  439. esphome/cpp_generator.py +6 -2
  440. esphome/dashboard/web_server.py +3 -3
  441. esphome/helpers.py +39 -0
  442. esphome/loader.py +4 -0
  443. esphome/log.py +15 -19
  444. esphome/mqtt.py +23 -10
  445. esphome/platformio_api.py +1 -1
  446. esphome/schema_extractors.py +0 -1
  447. esphome/voluptuous_schema.py +3 -1
  448. esphome/vscode.py +15 -0
  449. esphome/wizard.py +47 -37
  450. esphome/zeroconf.py +7 -3
  451. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/METADATA +10 -11
  452. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/RECORD +456 -396
  453. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/WHEEL +1 -1
  454. esphome/components/esp32_ble/const_esp32c6.h +0 -74
  455. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/entry_points.txt +0 -0
  456. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/licenses/LICENSE +0 -0
  457. {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/top_level.txt +0 -0
@@ -154,6 +154,21 @@ enum class ClientState {
154
154
  ESTABLISHED,
155
155
  };
156
156
 
157
+ enum class ScannerState {
158
+ // Scanner is idle, init state, set from the main loop when processing STOPPED
159
+ IDLE,
160
+ // Scanner is starting, set from the main loop only
161
+ STARTING,
162
+ // Scanner is running, set from the ESP callback only
163
+ RUNNING,
164
+ // Scanner failed to start, set from the ESP callback only
165
+ FAILED,
166
+ // Scanner is stopping, set from the main loop only
167
+ STOPPING,
168
+ // Scanner is stopped, set from the ESP callback only
169
+ STOPPED,
170
+ };
171
+
157
172
  enum class ConnectionType {
158
173
  // The default connection type, we hold all the services in ram
159
174
  // for the duration of the connection.
@@ -203,6 +218,7 @@ class ESP32BLETracker : public Component,
203
218
  void set_scan_interval(uint32_t scan_interval) { scan_interval_ = scan_interval; }
204
219
  void set_scan_window(uint32_t scan_window) { scan_window_ = scan_window; }
205
220
  void set_scan_active(bool scan_active) { scan_active_ = scan_active; }
221
+ bool get_scan_active() const { return scan_active_; }
206
222
  void set_scan_continuous(bool scan_continuous) { scan_continuous_ = scan_continuous; }
207
223
 
208
224
  /// Setup the FreeRTOS task and the Bluetooth stack.
@@ -226,6 +242,11 @@ class ESP32BLETracker : public Component,
226
242
  void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
227
243
  void ble_before_disabled_event_handler() override;
228
244
 
245
+ void add_scanner_state_callback(std::function<void(ScannerState)> &&callback) {
246
+ this->scanner_state_callbacks_.add(std::move(callback));
247
+ }
248
+ ScannerState get_scanner_state() const { return this->scanner_state_; }
249
+
229
250
  protected:
230
251
  void stop_scan_();
231
252
  /// Start a single scan by setting up the parameters and doing some esp-idf calls.
@@ -240,6 +261,8 @@ class ESP32BLETracker : public Component,
240
261
  void gap_scan_start_complete_(const esp_ble_gap_cb_param_t::ble_scan_start_cmpl_evt_param &param);
241
262
  /// Called when a `ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT` event is received.
242
263
  void gap_scan_stop_complete_(const esp_ble_gap_cb_param_t::ble_scan_stop_cmpl_evt_param &param);
264
+ /// Called to set the scanner state. Will also call callbacks to let listeners know when state is changed.
265
+ void set_scanner_state_(ScannerState state);
243
266
 
244
267
  int app_id_{0};
245
268
 
@@ -257,17 +280,17 @@ class ESP32BLETracker : public Component,
257
280
  uint8_t scan_start_fail_count_{0};
258
281
  bool scan_continuous_;
259
282
  bool scan_active_;
260
- bool scanner_idle_{true};
283
+ ScannerState scanner_state_{ScannerState::IDLE};
284
+ CallbackManager<void(ScannerState)> scanner_state_callbacks_;
261
285
  bool ble_was_disabled_{true};
262
286
  bool raw_advertisements_{false};
263
287
  bool parse_advertisements_{false};
264
288
  SemaphoreHandle_t scan_result_lock_;
265
- SemaphoreHandle_t scan_end_lock_;
266
289
  size_t scan_result_index_{0};
267
290
  #ifdef USE_PSRAM
268
291
  const static u_int8_t SCAN_RESULT_BUFFER_SIZE = 32;
269
292
  #else
270
- const static u_int8_t SCAN_RESULT_BUFFER_SIZE = 16;
293
+ const static u_int8_t SCAN_RESULT_BUFFER_SIZE = 20;
271
294
  #endif // USE_PSRAM
272
295
  esp_ble_gap_cb_param_t::ble_scan_result_evt_param *scan_result_buffer_;
273
296
  esp_bt_status_t scan_start_failed_{ESP_BT_STATUS_SUCCESS};
@@ -276,6 +299,9 @@ class ESP32BLETracker : public Component,
276
299
  int discovered_{0};
277
300
  int searching_{0};
278
301
  int disconnecting_{0};
302
+ #ifdef USE_ESP32_BLE_SOFTWARE_COEXISTENCE
303
+ bool coex_prefer_ble_{false};
304
+ #endif
279
305
  };
280
306
 
281
307
  // NOLINTNEXTLINE
@@ -296,7 +296,7 @@ async def to_code(config):
296
296
  add_idf_component(
297
297
  name="esp32-camera",
298
298
  repo="https://github.com/espressif/esp32-camera.git",
299
- ref="v2.0.9",
299
+ ref="v2.0.15",
300
300
  )
301
301
 
302
302
  for conf in config.get(CONF_ON_STREAM_START, []):
@@ -3,6 +3,7 @@
3
3
  #include "esp32_camera.h"
4
4
  #include "esphome/core/log.h"
5
5
  #include "esphome/core/hal.h"
6
+ #include "esphome/core/application.h"
6
7
 
7
8
  #include <freertos/task.h>
8
9
 
@@ -54,11 +55,7 @@ void ESP32Camera::dump_config() {
54
55
  ESP_LOGCONFIG(TAG, " HREF Pin: %d", conf.pin_href);
55
56
  ESP_LOGCONFIG(TAG, " Pixel Clock Pin: %d", conf.pin_pclk);
56
57
  ESP_LOGCONFIG(TAG, " External Clock: Pin:%d Frequency:%u", conf.pin_xclk, conf.xclk_freq_hz);
57
- #ifdef USE_ESP_IDF // Temporary until the espressif/esp32-camera library is updated
58
- ESP_LOGCONFIG(TAG, " I2C Pins: SDA:%d SCL:%d", conf.pin_sscb_sda, conf.pin_sscb_scl);
59
- #else
60
58
  ESP_LOGCONFIG(TAG, " I2C Pins: SDA:%d SCL:%d", conf.pin_sccb_sda, conf.pin_sccb_scl);
61
- #endif
62
59
  ESP_LOGCONFIG(TAG, " Reset Pin: %d", conf.pin_reset);
63
60
  switch (this->config_.frame_size) {
64
61
  case FRAMESIZE_QQVGA:
@@ -162,7 +159,7 @@ void ESP32Camera::loop() {
162
159
  }
163
160
 
164
161
  // request idle image every idle_update_interval
165
- const uint32_t now = millis();
162
+ const uint32_t now = App.get_loop_component_start_time();
166
163
  if (this->idle_update_interval_ != 0 && now - this->last_idle_request_ > this->idle_update_interval_) {
167
164
  this->last_idle_request_ = now;
168
165
  this->request_image(IDLE);
@@ -238,13 +235,8 @@ void ESP32Camera::set_external_clock(uint8_t pin, uint32_t frequency) {
238
235
  this->config_.xclk_freq_hz = frequency;
239
236
  }
240
237
  void ESP32Camera::set_i2c_pins(uint8_t sda, uint8_t scl) {
241
- #ifdef USE_ESP_IDF // Temporary until the espressif/esp32-camera library is updated
242
- this->config_.pin_sscb_sda = sda;
243
- this->config_.pin_sscb_scl = scl;
244
- #else
245
238
  this->config_.pin_sccb_sda = sda;
246
239
  this->config_.pin_sccb_scl = scl;
247
- #endif
248
240
  }
249
241
  void ESP32Camera::set_reset_pin(uint8_t pin) { this->config_.pin_reset = pin; }
250
242
  void ESP32Camera::set_power_down_pin(uint8_t pin) { this->config_.pin_pwdn = pin; }
@@ -106,7 +106,7 @@ class CameraImageReader {
106
106
  };
107
107
 
108
108
  /* ---------------- ESP32Camera class ---------------- */
109
- class ESP32Camera : public Component, public EntityBase {
109
+ class ESP32Camera : public EntityBase, public Component {
110
110
  public:
111
111
  ESP32Camera();
112
112
 
@@ -17,7 +17,7 @@ static const char *const TAG = "esp32_can";
17
17
  static bool get_bitrate(canbus::CanSpeed bitrate, twai_timing_config_t *t_config) {
18
18
  switch (bitrate) {
19
19
  #if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C3) || \
20
- defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32H6)
20
+ defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32H2)
21
21
  case canbus::CAN_1KBPS:
22
22
  *t_config = (twai_timing_config_t) TWAI_TIMING_CONFIG_1KBITS();
23
23
  return true;
@@ -92,7 +92,7 @@ void ESP32ImprovComponent::loop() {
92
92
 
93
93
  if (!this->incoming_data_.empty())
94
94
  this->process_incoming_data_();
95
- uint32_t now = millis();
95
+ uint32_t now = App.get_loop_component_start_time();
96
96
 
97
97
  switch (this->state_) {
98
98
  case improv::STATE_STOPPED:
@@ -58,7 +58,7 @@ void ESP32RMTLEDStripLightOutput::setup() {
58
58
  channel.flags.io_loop_back = 0;
59
59
  channel.flags.io_od_mode = 0;
60
60
  channel.flags.invert_out = 0;
61
- channel.flags.with_dma = 0;
61
+ channel.flags.with_dma = this->use_dma_;
62
62
  channel.intr_priority = 0;
63
63
  if (rmt_new_tx_channel(&channel, &this->channel_) != ESP_OK) {
64
64
  ESP_LOGE(TAG, "Channel creation failed");
@@ -51,6 +51,7 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
51
51
  void set_num_leds(uint16_t num_leds) { this->num_leds_ = num_leds; }
52
52
  void set_is_rgbw(bool is_rgbw) { this->is_rgbw_ = is_rgbw; }
53
53
  void set_is_wrgb(bool is_wrgb) { this->is_wrgb_ = is_wrgb; }
54
+ void set_use_dma(bool use_dma) { this->use_dma_ = use_dma; }
54
55
  void set_use_psram(bool use_psram) { this->use_psram_ = use_psram; }
55
56
 
56
57
  /// Set a maximum refresh rate in µs as some lights do not like being updated too often.
@@ -85,7 +86,7 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
85
86
  rmt_encoder_handle_t encoder_{nullptr};
86
87
  rmt_symbol_word_t *rmt_buf_{nullptr};
87
88
  rmt_symbol_word_t bit0_, bit1_, reset_;
88
- uint32_t rmt_symbols_;
89
+ uint32_t rmt_symbols_{48};
89
90
  #else
90
91
  rmt_item32_t *rmt_buf_{nullptr};
91
92
  rmt_item32_t bit0_, bit1_, reset_;
@@ -94,11 +95,12 @@ class ESP32RMTLEDStripLightOutput : public light::AddressableLight {
94
95
 
95
96
  uint8_t pin_;
96
97
  uint16_t num_leds_;
97
- bool is_rgbw_;
98
- bool is_wrgb_;
99
- bool use_psram_;
98
+ bool is_rgbw_{false};
99
+ bool is_wrgb_{false};
100
+ bool use_dma_{false};
101
+ bool use_psram_{false};
100
102
 
101
- RGBOrder rgb_order_;
103
+ RGBOrder rgb_order_{ORDER_RGB};
102
104
 
103
105
  uint32_t last_refresh_{0};
104
106
  optional<uint32_t> max_refresh_rate_{};
@@ -3,7 +3,7 @@ import logging
3
3
 
4
4
  from esphome import pins
5
5
  import esphome.codegen as cg
6
- from esphome.components import esp32_rmt, light
6
+ from esphome.components import esp32, esp32_rmt, light
7
7
  import esphome.config_validation as cv
8
8
  from esphome.const import (
9
9
  CONF_CHIPSET,
@@ -15,6 +15,7 @@ from esphome.const import (
15
15
  CONF_RGB_ORDER,
16
16
  CONF_RMT_CHANNEL,
17
17
  CONF_RMT_SYMBOLS,
18
+ CONF_USE_DMA,
18
19
  )
19
20
  from esphome.core import CORE
20
21
 
@@ -138,6 +139,11 @@ CONFIG_SCHEMA = cv.All(
138
139
  cv.Optional(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
139
140
  cv.Optional(CONF_IS_RGBW, default=False): cv.boolean,
140
141
  cv.Optional(CONF_IS_WRGB, default=False): cv.boolean,
142
+ cv.Optional(CONF_USE_DMA): cv.All(
143
+ esp32.only_on_variant(supported=[esp32.const.VARIANT_ESP32S3]),
144
+ cv.only_with_esp_idf,
145
+ cv.boolean,
146
+ ),
141
147
  cv.Optional(CONF_USE_PSRAM, default=True): cv.boolean,
142
148
  cv.Inclusive(
143
149
  CONF_BIT0_HIGH,
@@ -211,6 +217,8 @@ async def to_code(config):
211
217
 
212
218
  if esp32_rmt.use_new_rmt_driver():
213
219
  cg.add(var.set_rmt_symbols(config[CONF_RMT_SYMBOLS]))
220
+ if CONF_USE_DMA in config:
221
+ cg.add(var.set_use_dma(config[CONF_USE_DMA]))
214
222
  else:
215
223
  rmt_channel_t = cg.global_ns.enum("rmt_channel_t")
216
224
  cg.add(
@@ -288,7 +288,7 @@ uint32_t ESP32TouchComponent::component_touch_pad_read(touch_pad_t tp) {
288
288
  }
289
289
 
290
290
  void ESP32TouchComponent::loop() {
291
- const uint32_t now = millis();
291
+ const uint32_t now = App.get_loop_component_start_time();
292
292
  bool should_print = this->setup_mode_ && now - this->setup_mode_last_log_print_ > 250;
293
293
  for (auto *child : this->children_) {
294
294
  child->value_ = this->component_touch_pad_read(child->get_touch_pad());
@@ -8,7 +8,7 @@ namespace esp8266 {
8
8
 
9
9
  static const char *const TAG = "esp8266";
10
10
 
11
- static int IRAM_ATTR flags_to_mode(gpio::Flags flags, uint8_t pin) {
11
+ static int flags_to_mode(gpio::Flags flags, uint8_t pin) {
12
12
  if (flags == gpio::FLAG_INPUT) { // NOLINT(bugprone-branch-clone)
13
13
  return INPUT;
14
14
  } else if (flags == gpio::FLAG_OUTPUT) {
@@ -34,12 +34,36 @@ static int IRAM_ATTR flags_to_mode(gpio::Flags flags, uint8_t pin) {
34
34
  struct ISRPinArg {
35
35
  uint8_t pin;
36
36
  bool inverted;
37
+ volatile uint32_t *in_reg;
38
+ volatile uint32_t *out_set_reg;
39
+ volatile uint32_t *out_clr_reg;
40
+ volatile uint32_t *mode_set_reg;
41
+ volatile uint32_t *mode_clr_reg;
42
+ volatile uint32_t *func_reg;
43
+ uint32_t mask;
37
44
  };
38
45
 
39
46
  ISRInternalGPIOPin ESP8266GPIOPin::to_isr() const {
40
47
  auto *arg = new ISRPinArg{}; // NOLINT(cppcoreguidelines-owning-memory)
41
- arg->pin = pin_;
42
- arg->inverted = inverted_;
48
+ arg->pin = this->pin_;
49
+ arg->inverted = this->inverted_;
50
+ if (this->pin_ < 16) {
51
+ arg->in_reg = &GPI;
52
+ arg->out_set_reg = &GPOS;
53
+ arg->out_clr_reg = &GPOC;
54
+ arg->mode_set_reg = &GPES;
55
+ arg->mode_clr_reg = &GPEC;
56
+ arg->func_reg = &GPF(this->pin_);
57
+ arg->mask = 1 << this->pin_;
58
+ } else {
59
+ arg->in_reg = &GP16I;
60
+ arg->out_set_reg = &GP16O;
61
+ arg->out_clr_reg = nullptr;
62
+ arg->mode_set_reg = &GP16E;
63
+ arg->mode_clr_reg = nullptr;
64
+ arg->func_reg = &GPF16;
65
+ arg->mask = 1;
66
+ }
43
67
  return ISRInternalGPIOPin((void *) arg);
44
68
  }
45
69
 
@@ -88,20 +112,57 @@ void ESP8266GPIOPin::detach_interrupt() const { detachInterrupt(pin_); }
88
112
  using namespace esp8266;
89
113
 
90
114
  bool IRAM_ATTR ISRInternalGPIOPin::digital_read() {
91
- auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
92
- return bool(digitalRead(arg->pin)) != arg->inverted; // NOLINT
115
+ auto *arg = reinterpret_cast<ISRPinArg *>(this->arg_);
116
+ return bool(*arg->in_reg & arg->mask) != arg->inverted;
93
117
  }
118
+
94
119
  void IRAM_ATTR ISRInternalGPIOPin::digital_write(bool value) {
95
120
  auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
96
- digitalWrite(arg->pin, value != arg->inverted ? 1 : 0); // NOLINT
121
+ if (arg->pin < 16) {
122
+ if (value != arg->inverted) {
123
+ *arg->out_set_reg = arg->mask;
124
+ } else {
125
+ *arg->out_clr_reg = arg->mask;
126
+ }
127
+ } else {
128
+ if (value != arg->inverted) {
129
+ *arg->out_set_reg |= 1;
130
+ } else {
131
+ *arg->out_set_reg &= ~1;
132
+ }
133
+ }
97
134
  }
135
+
98
136
  void IRAM_ATTR ISRInternalGPIOPin::clear_interrupt() {
99
137
  auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
100
138
  GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1UL << arg->pin);
101
139
  }
140
+
102
141
  void IRAM_ATTR ISRInternalGPIOPin::pin_mode(gpio::Flags flags) {
103
- auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
104
- pinMode(arg->pin, flags_to_mode(flags, arg->pin)); // NOLINT
142
+ auto *arg = reinterpret_cast<ISRPinArg *>(this->arg_);
143
+ if (arg->pin < 16) {
144
+ if (flags & gpio::FLAG_OUTPUT) {
145
+ *arg->mode_set_reg = arg->mask;
146
+ } else {
147
+ *arg->mode_clr_reg = arg->mask;
148
+ }
149
+ if (flags & gpio::FLAG_PULLUP) {
150
+ *arg->func_reg |= 1 << GPFPU;
151
+ } else {
152
+ *arg->func_reg &= ~(1 << GPFPU);
153
+ }
154
+ } else {
155
+ if (flags & gpio::FLAG_OUTPUT) {
156
+ *arg->mode_set_reg |= 1;
157
+ } else {
158
+ *arg->mode_set_reg &= ~1;
159
+ }
160
+ if (flags & gpio::FLAG_PULLDOWN) {
161
+ *arg->func_reg |= 1 << GP16FPD;
162
+ } else {
163
+ *arg->func_reg &= ~(1 << GP16FPD);
164
+ }
165
+ }
105
166
  }
106
167
 
107
168
  } // namespace esphome
@@ -240,7 +240,7 @@ void EthernetComponent::setup() {
240
240
  }
241
241
 
242
242
  void EthernetComponent::loop() {
243
- const uint32_t now = millis();
243
+ const uint32_t now = App.get_loop_component_start_time();
244
244
 
245
245
  switch (this->state_) {
246
246
  case EthernetComponentState::STOPPED:
@@ -41,7 +41,7 @@ EventTrigger = event_ns.class_("EventTrigger", automation.Trigger.template())
41
41
 
42
42
  validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
43
43
 
44
- EVENT_SCHEMA = (
44
+ _EVENT_SCHEMA = (
45
45
  cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
46
46
  .extend(cv.MQTT_COMPONENT_SCHEMA)
47
47
  .extend(
@@ -58,19 +58,17 @@ EVENT_SCHEMA = (
58
58
  )
59
59
  )
60
60
 
61
- _UNDEF = object()
62
-
63
61
 
64
62
  def event_schema(
65
- class_: MockObjClass = _UNDEF,
63
+ class_: MockObjClass = cv.UNDEFINED,
66
64
  *,
67
- icon: str = _UNDEF,
68
- entity_category: str = _UNDEF,
69
- device_class: str = _UNDEF,
65
+ icon: str = cv.UNDEFINED,
66
+ entity_category: str = cv.UNDEFINED,
67
+ device_class: str = cv.UNDEFINED,
70
68
  ) -> cv.Schema:
71
69
  schema = {}
72
70
 
73
- if class_ is not _UNDEF:
71
+ if class_ is not cv.UNDEFINED:
74
72
  schema[cv.GenerateID()] = cv.declare_id(class_)
75
73
 
76
74
  for key, default, validator in [
@@ -78,10 +76,15 @@ def event_schema(
78
76
  (CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
79
77
  (CONF_DEVICE_CLASS, device_class, validate_device_class),
80
78
  ]:
81
- if default is not _UNDEF:
79
+ if default is not cv.UNDEFINED:
82
80
  schema[cv.Optional(key, default=default)] = validator
83
81
 
84
- return EVENT_SCHEMA.extend(schema)
82
+ return _EVENT_SCHEMA.extend(schema)
83
+
84
+
85
+ # Remove before 2025.11.0
86
+ EVENT_SCHEMA = event_schema()
87
+ EVENT_SCHEMA.add_extra(cv.deprecated_schema_constant("event"))
85
88
 
86
89
 
87
90
  async def setup_event_core_(var, config, *, event_types: list[str]):
@@ -1,14 +1,7 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import switch
3
3
  import esphome.config_validation as cv
4
- from esphome.const import (
5
- CONF_ENTITY_CATEGORY,
6
- CONF_ICON,
7
- CONF_ID,
8
- CONF_INVERTED,
9
- ENTITY_CATEGORY_CONFIG,
10
- ICON_RESTART_ALERT,
11
- )
4
+ from esphome.const import ENTITY_CATEGORY_CONFIG, ICON_RESTART_ALERT
12
5
 
13
6
  from .. import factory_reset_ns
14
7
 
@@ -16,21 +9,14 @@ FactoryResetSwitch = factory_reset_ns.class_(
16
9
  "FactoryResetSwitch", switch.Switch, cg.Component
17
10
  )
18
11
 
19
- CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend(
20
- {
21
- cv.GenerateID(): cv.declare_id(FactoryResetSwitch),
22
- cv.Optional(CONF_INVERTED): cv.invalid(
23
- "Factory Reset switches do not support inverted mode!"
24
- ),
25
- cv.Optional(CONF_ICON, default=ICON_RESTART_ALERT): cv.icon,
26
- cv.Optional(
27
- CONF_ENTITY_CATEGORY, default=ENTITY_CATEGORY_CONFIG
28
- ): cv.entity_category,
29
- }
12
+ CONFIG_SCHEMA = switch.switch_schema(
13
+ FactoryResetSwitch,
14
+ block_inverted=True,
15
+ icon=ICON_RESTART_ALERT,
16
+ entity_category=ENTITY_CATEGORY_CONFIG,
30
17
  ).extend(cv.COMPONENT_SCHEMA)
31
18
 
32
19
 
33
20
  async def to_code(config):
34
- var = cg.new_Pvariable(config[CONF_ID])
21
+ var = await switch.new_switch(config)
35
22
  await cg.register_component(var, config)
36
- await switch.register_switch(var, config)
@@ -5,6 +5,10 @@ from esphome.components import mqtt, web_server
5
5
  import esphome.config_validation as cv
6
6
  from esphome.const import (
7
7
  CONF_DIRECTION,
8
+ CONF_DIRECTION_COMMAND_TOPIC,
9
+ CONF_DIRECTION_STATE_TOPIC,
10
+ CONF_ENTITY_CATEGORY,
11
+ CONF_ICON,
8
12
  CONF_ID,
9
13
  CONF_MQTT_ID,
10
14
  CONF_OFF_SPEED_CYCLE,
@@ -80,16 +84,21 @@ FanPresetSetTrigger = fan_ns.class_(
80
84
  FanIsOnCondition = fan_ns.class_("FanIsOnCondition", automation.Condition.template())
81
85
  FanIsOffCondition = fan_ns.class_("FanIsOffCondition", automation.Condition.template())
82
86
 
83
- FAN_SCHEMA = (
87
+ _FAN_SCHEMA = (
84
88
  cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
85
89
  .extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA)
86
90
  .extend(
87
91
  {
88
- cv.GenerateID(): cv.declare_id(Fan),
89
92
  cv.Optional(CONF_RESTORE_MODE, default="ALWAYS_OFF"): cv.enum(
90
93
  RESTORE_MODES, upper=True, space="_"
91
94
  ),
92
95
  cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTFanComponent),
96
+ cv.Optional(CONF_DIRECTION_STATE_TOPIC): cv.All(
97
+ cv.requires_component("mqtt"), cv.publish_topic
98
+ ),
99
+ cv.Optional(CONF_DIRECTION_COMMAND_TOPIC): cv.All(
100
+ cv.requires_component("mqtt"), cv.subscribe_topic
101
+ ),
93
102
  cv.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.All(
94
103
  cv.requires_component("mqtt"), cv.publish_topic
95
104
  ),
@@ -151,6 +160,37 @@ FAN_SCHEMA = (
151
160
  )
152
161
  )
153
162
 
163
+
164
+ def fan_schema(
165
+ class_: cg.Pvariable,
166
+ *,
167
+ entity_category: str = cv.UNDEFINED,
168
+ icon: str = cv.UNDEFINED,
169
+ default_restore_mode: str = cv.UNDEFINED,
170
+ ) -> cv.Schema:
171
+ schema = {
172
+ cv.GenerateID(): cv.declare_id(class_),
173
+ }
174
+
175
+ for key, default, validator in [
176
+ (CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
177
+ (CONF_ICON, icon, cv.icon),
178
+ (
179
+ CONF_RESTORE_MODE,
180
+ default_restore_mode,
181
+ cv.enum(RESTORE_MODES, upper=True, space="_"),
182
+ ),
183
+ ]:
184
+ if default is not cv.UNDEFINED:
185
+ schema[cv.Optional(key, default=default)] = validator
186
+
187
+ return _FAN_SCHEMA.extend(schema)
188
+
189
+
190
+ # Remove before 2025.11.0
191
+ FAN_SCHEMA = fan_schema(Fan)
192
+ FAN_SCHEMA.add_extra(cv.deprecated_schema_constant("fan"))
193
+
154
194
  _PRESET_MODES_SCHEMA = cv.All(
155
195
  cv.ensure_list(cv.string_strict),
156
196
  cv.Length(min=1),
@@ -193,6 +233,14 @@ async def setup_fan_core_(var, config):
193
233
  mqtt_ = cg.new_Pvariable(mqtt_id, var)
194
234
  await mqtt.register_mqtt_component(mqtt_, config)
195
235
 
236
+ if (
237
+ direction_state_topic := config.get(CONF_DIRECTION_STATE_TOPIC)
238
+ ) is not None:
239
+ cg.add(mqtt_.set_custom_direction_state_topic(direction_state_topic))
240
+ if (
241
+ direction_command_topic := config.get(CONF_DIRECTION_COMMAND_TOPIC)
242
+ ) is not None:
243
+ cg.add(mqtt_.set_custom_direction_command_topic(direction_command_topic))
196
244
  if (
197
245
  oscillation_state_topic := config.get(CONF_OSCILLATION_STATE_TOPIC)
198
246
  ) is not None:
@@ -251,10 +299,9 @@ async def register_fan(var, config):
251
299
  await setup_fan_core_(var, config)
252
300
 
253
301
 
254
- async def create_fan_state(config):
255
- var = cg.new_Pvariable(config[CONF_ID])
302
+ async def new_fan(config, *args):
303
+ var = cg.new_Pvariable(config[CONF_ID], *args)
256
304
  await register_fan(var, config)
257
- await cg.register_component(var, config)
258
305
  return var
259
306
 
260
307
 
@@ -40,9 +40,6 @@ async def new_fastled_light(config):
40
40
  if CONF_MAX_REFRESH_RATE in config:
41
41
  cg.add(var.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE]))
42
42
 
43
+ cg.add_library("fastled/FastLED", "3.9.16")
43
44
  await light.register_light(var, config)
44
- # https://github.com/FastLED/FastLED/blob/master/library.json
45
- # 3.3.3 has an issue on ESP32 with RMT and fastled_clockless:
46
- # https://github.com/esphome/issues/issues/1375
47
- cg.add_library("fastled/FastLED", "3.3.2")
48
45
  return var
@@ -34,7 +34,7 @@ void FastLEDLightOutput::write_state(light::LightState *state) {
34
34
  this->mark_shown_();
35
35
 
36
36
  ESP_LOGVV(TAG, "Writing RGB values to bus...");
37
- this->controller_->showLeds();
37
+ this->controller_->showLeds(this->state_parent_->current_values.get_brightness() * 255);
38
38
  }
39
39
 
40
40
  } // namespace fastled_base