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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (444) hide show
  1. esphome/__main__.py +16 -14
  2. esphome/components/ac_dimmer/ac_dimmer.cpp +3 -2
  3. esphome/components/adc/__init__.py +51 -34
  4. esphome/components/airthings_wave_base/__init__.py +1 -1
  5. esphome/components/alarm_control_panel/__init__.py +37 -2
  6. esphome/components/am43/cover/__init__.py +4 -5
  7. esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
  8. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
  9. esphome/components/analog_threshold/binary_sensor.py +10 -8
  10. esphome/components/anova/climate.py +4 -5
  11. esphome/components/api/__init__.py +25 -8
  12. esphome/components/api/api_connection.cpp +416 -662
  13. esphome/components/api/api_connection.h +256 -57
  14. esphome/components/api/api_frame_helper.cpp +232 -177
  15. esphome/components/api/api_frame_helper.h +61 -8
  16. esphome/components/api/api_noise_context.h +13 -4
  17. esphome/components/api/api_pb2.cpp +1422 -1
  18. esphome/components/api/api_pb2.h +255 -1
  19. esphome/components/api/api_pb2_service.cpp +162 -49
  20. esphome/components/api/api_pb2_service.h +90 -51
  21. esphome/components/api/api_pb2_size.h +361 -0
  22. esphome/components/api/api_server.cpp +110 -34
  23. esphome/components/api/api_server.h +8 -0
  24. esphome/components/api/proto.h +86 -17
  25. esphome/components/as7341/as7341.h +1 -1
  26. esphome/components/at581x/at581x.h +4 -4
  27. esphome/components/atm90e32/__init__.py +1 -0
  28. esphome/components/atm90e32/atm90e32.cpp +576 -199
  29. esphome/components/atm90e32/atm90e32.h +128 -31
  30. esphome/components/atm90e32/atm90e32_reg.h +4 -2
  31. esphome/components/atm90e32/button/__init__.py +62 -10
  32. esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
  33. esphome/components/atm90e32/button/atm90e32_button.h +36 -4
  34. esphome/components/atm90e32/number/__init__.py +130 -0
  35. esphome/components/atm90e32/number/atm90e32_number.h +16 -0
  36. esphome/components/atm90e32/sensor.py +21 -4
  37. esphome/components/atm90e32/text_sensor/__init__.py +48 -0
  38. esphome/components/audio/__init__.py +96 -49
  39. esphome/components/audio/audio.h +48 -0
  40. esphome/components/audio/audio_decoder.cpp +1 -1
  41. esphome/components/audio/audio_resampler.cpp +2 -0
  42. esphome/components/audio/audio_resampler.h +1 -0
  43. esphome/components/ballu/climate.py +2 -9
  44. esphome/components/bang_bang/climate.py +5 -6
  45. esphome/components/bedjet/bedjet_hub.cpp +1 -0
  46. esphome/components/bedjet/climate/__init__.py +3 -8
  47. esphome/components/bedjet/fan/__init__.py +2 -11
  48. esphome/components/binary/fan/__init__.py +13 -16
  49. esphome/components/binary_sensor/__init__.py +13 -10
  50. esphome/components/bl0906/constants.h +16 -16
  51. esphome/components/ble_client/text_sensor/__init__.py +3 -5
  52. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
  53. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +136 -21
  54. esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
  55. esphome/components/button/__init__.py +11 -8
  56. esphome/components/canbus/canbus.cpp +3 -0
  57. esphome/components/canbus/canbus.h +16 -0
  58. esphome/components/ccs811/sensor.py +9 -6
  59. esphome/components/climate/__init__.py +35 -2
  60. esphome/components/climate/climate_mode.h +1 -1
  61. esphome/components/climate/climate_traits.h +63 -57
  62. esphome/components/climate_ir/__init__.py +57 -17
  63. esphome/components/climate_ir_lg/climate.py +2 -5
  64. esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
  65. esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
  66. esphome/components/color/__init__.py +2 -0
  67. esphome/components/const/__init__.py +5 -0
  68. esphome/components/coolix/climate.py +2 -9
  69. esphome/components/copy/cover/__init__.py +10 -9
  70. esphome/components/copy/fan/__init__.py +11 -9
  71. esphome/components/copy/lock/__init__.py +11 -9
  72. esphome/components/copy/text/__init__.py +9 -6
  73. esphome/components/cover/__init__.py +37 -2
  74. esphome/components/cse7766/cse7766.cpp +2 -1
  75. esphome/components/cst226/binary_sensor/__init__.py +28 -0
  76. esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
  77. esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
  78. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
  79. esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
  80. esphome/components/current_based/cover.py +37 -36
  81. esphome/components/current_based/current_based_cover.cpp +2 -1
  82. esphome/components/daikin/climate.py +2 -9
  83. esphome/components/daikin/daikin.cpp +15 -9
  84. esphome/components/daikin/daikin.h +5 -5
  85. esphome/components/daikin_arc/climate.py +2 -7
  86. esphome/components/daikin_brc/climate.py +3 -5
  87. esphome/components/dallas_temp/dallas_temp.cpp +17 -24
  88. esphome/components/dallas_temp/dallas_temp.h +0 -1
  89. esphome/components/daly_bms/daly_bms.cpp +2 -1
  90. esphome/components/debug/debug_component.cpp +6 -1
  91. esphome/components/debug/debug_component.h +8 -0
  92. esphome/components/debug/debug_esp32.cpp +109 -254
  93. esphome/components/debug/sensor.py +14 -0
  94. esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
  95. esphome/components/delonghi/climate.py +2 -9
  96. esphome/components/demo/__init__.py +18 -20
  97. esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
  98. esphome/components/dps310/sensor.py +6 -6
  99. esphome/components/ee895/sensor.py +9 -9
  100. esphome/components/emmeti/climate.py +2 -9
  101. esphome/components/endstop/cover.py +17 -16
  102. esphome/components/endstop/endstop_cover.cpp +2 -1
  103. esphome/components/ens160_base/__init__.py +12 -9
  104. esphome/components/esp32/__init__.py +60 -3
  105. esphome/components/esp32/core.cpp +11 -5
  106. esphome/components/esp32/gpio.cpp +86 -24
  107. esphome/components/esp32/gpio.py +15 -16
  108. esphome/components/esp32/gpio_esp32.py +1 -2
  109. esphome/components/esp32/gpio_esp32_c2.py +1 -1
  110. esphome/components/esp32/gpio_esp32_c3.py +1 -1
  111. esphome/components/esp32/gpio_esp32_c6.py +1 -1
  112. esphome/components/esp32/gpio_esp32_h2.py +1 -1
  113. esphome/components/esp32_ble/ble.cpp +1 -0
  114. esphome/components/esp32_ble/ble.h +5 -3
  115. esphome/components/esp32_ble/ble_advertising.cpp +2 -1
  116. esphome/components/esp32_ble/ble_advertising.h +1 -0
  117. esphome/components/esp32_ble_server/__init__.py +3 -0
  118. esphome/components/esp32_ble_tracker/__init__.py +7 -1
  119. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
  120. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
  121. esphome/components/esp32_camera/__init__.py +1 -1
  122. esphome/components/esp32_camera/esp32_camera.cpp +2 -10
  123. esphome/components/esp32_camera/esp32_camera.h +1 -1
  124. esphome/components/esp32_can/esp32_can.cpp +1 -1
  125. esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
  126. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  127. esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
  128. esphome/components/esp32_rmt_led_strip/light.py +9 -1
  129. esphome/components/esp32_touch/esp32_touch.cpp +1 -1
  130. esphome/components/esp8266/gpio.cpp +69 -8
  131. esphome/components/ethernet/ethernet_component.cpp +1 -1
  132. esphome/components/event/__init__.py +13 -10
  133. esphome/components/factory_reset/switch/__init__.py +7 -21
  134. esphome/components/fan/__init__.py +52 -5
  135. esphome/components/fastled_base/__init__.py +1 -4
  136. esphome/components/fastled_base/fastled_light.cpp +1 -1
  137. esphome/components/feedback/cover.py +38 -33
  138. esphome/components/feedback/feedback_cover.cpp +2 -1
  139. esphome/components/fujitsu_general/climate.py +2 -9
  140. esphome/components/gcja5/gcja5.cpp +2 -1
  141. esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
  142. esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
  143. esphome/components/gpio_expander/cached_gpio.h +22 -7
  144. esphome/components/gps/__init__.py +47 -17
  145. esphome/components/gps/gps.cpp +42 -23
  146. esphome/components/gps/gps.h +17 -13
  147. esphome/components/graph/__init__.py +1 -2
  148. esphome/components/gree/climate.py +4 -6
  149. esphome/components/gree/gree.cpp +16 -2
  150. esphome/components/gree/gree.h +2 -2
  151. esphome/components/growatt_solar/growatt_solar.cpp +2 -1
  152. esphome/components/haier/climate.py +37 -34
  153. esphome/components/hbridge/fan/__init__.py +19 -17
  154. esphome/components/he60r/cover.py +4 -5
  155. esphome/components/heatpumpir/climate.py +3 -6
  156. esphome/components/hitachi_ac344/climate.py +2 -9
  157. esphome/components/hitachi_ac424/climate.py +2 -9
  158. esphome/components/hm3301/hm3301.h +1 -1
  159. esphome/components/hte501/sensor.py +6 -6
  160. esphome/components/http_request/__init__.py +39 -6
  161. esphome/components/http_request/http_request.cpp +20 -0
  162. esphome/components/http_request/http_request.h +57 -15
  163. esphome/components/http_request/http_request_arduino.cpp +22 -6
  164. esphome/components/http_request/http_request_arduino.h +4 -3
  165. esphome/components/http_request/http_request_host.cpp +141 -0
  166. esphome/components/http_request/http_request_host.h +37 -0
  167. esphome/components/http_request/http_request_idf.cpp +35 -3
  168. esphome/components/http_request/http_request_idf.h +10 -3
  169. esphome/components/http_request/httplib.h +9691 -0
  170. esphome/components/http_request/update/__init__.py +11 -8
  171. esphome/components/hyt271/sensor.py +6 -6
  172. esphome/components/i2c/i2c.h +4 -0
  173. esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
  174. esphome/components/i2s_audio/__init__.py +131 -22
  175. esphome/components/i2s_audio/i2s_audio.h +44 -4
  176. esphome/components/i2s_audio/media_player/__init__.py +19 -9
  177. esphome/components/i2s_audio/microphone/__init__.py +63 -5
  178. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
  179. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
  180. esphome/components/i2s_audio/speaker/__init__.py +31 -5
  181. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
  182. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
  183. esphome/components/ili9xxx/ili9xxx_init.h +1 -1
  184. esphome/components/image/__init__.py +37 -17
  185. esphome/components/image/image.cpp +25 -8
  186. esphome/components/internal_temperature/internal_temperature.cpp +6 -4
  187. esphome/components/key_collector/__init__.py +35 -0
  188. esphome/components/key_collector/key_collector.cpp +8 -0
  189. esphome/components/key_collector/key_collector.h +10 -0
  190. esphome/components/kuntze/kuntze.cpp +2 -1
  191. esphome/components/ld2410/ld2410.h +1 -1
  192. esphome/components/ld2450/ld2450.h +1 -1
  193. esphome/components/light/__init__.py +57 -0
  194. esphome/components/lock/__init__.py +51 -4
  195. esphome/components/lock/automation.h +2 -13
  196. esphome/components/logger/__init__.py +22 -0
  197. esphome/components/logger/logger.cpp +154 -103
  198. esphome/components/logger/logger.h +211 -36
  199. esphome/components/logger/task_log_buffer.cpp +138 -0
  200. esphome/components/logger/task_log_buffer.h +69 -0
  201. esphome/components/lvgl/__init__.py +13 -5
  202. esphome/components/lvgl/automation.py +50 -1
  203. esphome/components/lvgl/defines.py +0 -1
  204. esphome/components/lvgl/lvgl_esphome.cpp +5 -1
  205. esphome/components/lvgl/text/__init__.py +1 -2
  206. esphome/components/mapping/__init__.py +134 -0
  207. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
  208. esphome/components/max7219digit/max7219digit.cpp +28 -27
  209. esphome/components/mdns/__init__.py +11 -5
  210. esphome/components/mdns/mdns_component.cpp +11 -5
  211. esphome/components/mdns/mdns_component.h +3 -2
  212. esphome/components/mdns/mdns_esp32.cpp +4 -3
  213. esphome/components/mdns/mdns_esp8266.cpp +4 -2
  214. esphome/components/mdns/mdns_libretiny.cpp +4 -2
  215. esphome/components/mdns/mdns_rp2040.cpp +4 -2
  216. esphome/components/media_player/__init__.py +33 -1
  217. esphome/components/mhz19/sensor.py +11 -7
  218. esphome/components/micro_wake_word/__init__.py +99 -31
  219. esphome/components/micro_wake_word/automation.h +54 -0
  220. esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
  221. esphome/components/micro_wake_word/micro_wake_word.h +58 -105
  222. esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
  223. esphome/components/micro_wake_word/streaming_model.cpp +158 -41
  224. esphome/components/micro_wake_word/streaming_model.h +85 -13
  225. esphome/components/microphone/__init__.py +139 -9
  226. esphome/components/microphone/automation.h +14 -2
  227. esphome/components/microphone/microphone.cpp +21 -0
  228. esphome/components/microphone/microphone.h +14 -5
  229. esphome/components/microphone/microphone_source.cpp +95 -0
  230. esphome/components/microphone/microphone_source.h +80 -0
  231. esphome/components/mics_4514/sensor.py +25 -14
  232. esphome/components/midea/climate.py +3 -4
  233. esphome/components/midea_ir/climate.py +3 -5
  234. esphome/components/mipi_spi/__init__.py +15 -0
  235. esphome/components/mipi_spi/display.py +474 -0
  236. esphome/components/mipi_spi/mipi_spi.cpp +481 -0
  237. esphome/components/mipi_spi/mipi_spi.h +171 -0
  238. esphome/components/mipi_spi/models/__init__.py +65 -0
  239. esphome/components/mipi_spi/models/amoled.py +72 -0
  240. esphome/components/mipi_spi/models/commands.py +82 -0
  241. esphome/components/mipi_spi/models/cyd.py +10 -0
  242. esphome/components/mipi_spi/models/ili.py +749 -0
  243. esphome/components/mipi_spi/models/jc.py +260 -0
  244. esphome/components/mipi_spi/models/lanbon.py +15 -0
  245. esphome/components/mipi_spi/models/lilygo.py +60 -0
  246. esphome/components/mipi_spi/models/waveshare.py +139 -0
  247. esphome/components/mitsubishi/climate.py +2 -5
  248. esphome/components/mitsubishi/mitsubishi.cpp +9 -9
  249. esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
  250. esphome/components/mixer/speaker/mixer_speaker.h +1 -3
  251. esphome/components/mlx90393/sensor.py +5 -0
  252. esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
  253. esphome/components/mlx90393/sensor_mlx90393.h +21 -4
  254. esphome/components/modbus/modbus.cpp +2 -1
  255. esphome/components/mqtt/__init__.py +1 -1
  256. esphome/components/mqtt/mqtt_client.cpp +6 -2
  257. esphome/components/mqtt/mqtt_const.h +4 -0
  258. esphome/components/mqtt/mqtt_fan.cpp +39 -0
  259. esphome/components/mqtt/mqtt_fan.h +2 -0
  260. esphome/components/ms5611/sensor.py +6 -6
  261. esphome/components/ms8607/sensor.py +3 -3
  262. esphome/components/network/__init__.py +1 -1
  263. esphome/components/nextion/base_component.py +17 -16
  264. esphome/components/nextion/display.py +11 -2
  265. esphome/components/nextion/nextion.cpp +39 -1
  266. esphome/components/nextion/nextion.h +50 -0
  267. esphome/components/noblex/climate.py +2 -9
  268. esphome/components/number/__init__.py +12 -9
  269. esphome/components/one_wire/one_wire_bus.cpp +14 -10
  270. esphome/components/one_wire/one_wire_bus.h +14 -8
  271. esphome/components/online_image/bmp_image.cpp +48 -11
  272. esphome/components/online_image/bmp_image.h +2 -0
  273. esphome/components/opentherm/binary_sensor/__init__.py +2 -4
  274. esphome/components/opentherm/number/__init__.py +11 -20
  275. esphome/components/opentherm/sensor/__init__.py +3 -3
  276. esphome/components/opentherm/switch/__init__.py +3 -5
  277. esphome/components/output/lock/__init__.py +11 -9
  278. esphome/components/packages/__init__.py +33 -31
  279. esphome/components/packet_transport/__init__.py +201 -0
  280. esphome/components/packet_transport/binary_sensor.py +19 -0
  281. esphome/components/packet_transport/packet_transport.cpp +534 -0
  282. esphome/components/packet_transport/packet_transport.h +154 -0
  283. esphome/components/packet_transport/sensor.py +19 -0
  284. esphome/components/pca9685/pca9685_output.cpp +2 -1
  285. esphome/components/pid/climate.py +2 -4
  286. esphome/components/pm2005/__init__.py +1 -0
  287. esphome/components/pm2005/pm2005.cpp +123 -0
  288. esphome/components/pm2005/pm2005.h +46 -0
  289. esphome/components/pm2005/sensor.py +86 -0
  290. esphome/components/pmsa003i/pmsa003i.cpp +43 -16
  291. esphome/components/pmsa003i/pmsa003i.h +25 -25
  292. esphome/components/pmsx003/pmsx003.cpp +195 -230
  293. esphome/components/pmsx003/pmsx003.h +51 -33
  294. esphome/components/pmsx003/sensor.py +21 -11
  295. esphome/components/pn7150/pn7150.h +2 -2
  296. esphome/components/pn7160/pn7160.h +2 -2
  297. esphome/components/prometheus/prometheus_handler.cpp +174 -0
  298. esphome/components/prometheus/prometheus_handler.h +17 -0
  299. esphome/components/psram/__init__.py +7 -5
  300. esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
  301. esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
  302. esphome/components/pzem004t/pzem004t.cpp +2 -1
  303. esphome/components/qspi_dbi/__init__.py +0 -1
  304. esphome/components/qspi_dbi/display.py +2 -1
  305. esphome/components/qspi_dbi/models.py +1 -2
  306. esphome/components/remote_base/__init__.py +91 -0
  307. esphome/components/remote_base/beo4_protocol.cpp +153 -0
  308. esphome/components/remote_base/beo4_protocol.h +43 -0
  309. esphome/components/remote_base/gobox_protocol.cpp +131 -0
  310. esphome/components/remote_base/gobox_protocol.h +54 -0
  311. esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
  312. esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
  313. esphome/components/resampler/speaker/resampler_speaker.h +1 -1
  314. esphome/components/rf_bridge/rf_bridge.cpp +2 -1
  315. esphome/components/scd30/sensor.py +2 -3
  316. esphome/components/scd4x/sensor.py +4 -5
  317. esphome/components/sdp3x/sensor.py +2 -1
  318. esphome/components/sds011/sds011.cpp +2 -1
  319. esphome/components/select/__init__.py +19 -20
  320. esphome/components/sen5x/sen5x.cpp +55 -36
  321. esphome/components/sen5x/sensor.py +1 -1
  322. esphome/components/senseair/sensor.py +3 -3
  323. esphome/components/sensor/__init__.py +158 -14
  324. esphome/components/sensor/filter.cpp +23 -0
  325. esphome/components/sensor/filter.h +22 -0
  326. esphome/components/sgp30/sensor.py +14 -16
  327. esphome/components/sgp4x/sensor.py +1 -1
  328. esphome/components/sht4x/sht4x.cpp +43 -22
  329. esphome/components/sht4x/sht4x.h +1 -1
  330. esphome/components/shtcx/sensor.py +6 -6
  331. esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
  332. esphome/components/sml/text_sensor/__init__.py +4 -6
  333. esphome/components/sound_level/__init__.py +0 -0
  334. esphome/components/sound_level/sensor.py +97 -0
  335. esphome/components/sound_level/sound_level.cpp +194 -0
  336. esphome/components/sound_level/sound_level.h +73 -0
  337. esphome/components/speaker/media_player/__init__.py +4 -8
  338. esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
  339. esphome/components/speaker/media_player/speaker_media_player.h +0 -11
  340. esphome/components/speaker/speaker.h +4 -7
  341. esphome/components/speed/fan/__init__.py +17 -16
  342. esphome/components/spi/spi.h +11 -1
  343. esphome/components/sprinkler/__init__.py +18 -19
  344. esphome/components/sprinkler/sprinkler.cpp +6 -5
  345. esphome/components/switch/__init__.py +32 -42
  346. esphome/components/syslog/__init__.py +41 -0
  347. esphome/components/syslog/esphome_syslog.cpp +49 -0
  348. esphome/components/syslog/esphome_syslog.h +27 -0
  349. esphome/components/t6615/sensor.py +3 -3
  350. esphome/components/t6615/t6615.cpp +2 -1
  351. esphome/components/tca9555/tca9555.cpp +11 -6
  352. esphome/components/tcl112/climate.py +2 -9
  353. esphome/components/template/alarm_control_panel/__init__.py +7 -6
  354. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
  355. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
  356. esphome/components/template/cover/__init__.py +27 -21
  357. esphome/components/template/fan/__init__.py +14 -12
  358. esphome/components/template/lock/__init__.py +20 -25
  359. esphome/components/template/lock/automation.h +18 -0
  360. esphome/components/template/text/__init__.py +4 -3
  361. esphome/components/template/valve/__init__.py +32 -21
  362. esphome/components/template/valve/automation.h +24 -0
  363. esphome/components/text/__init__.py +32 -1
  364. esphome/components/text_sensor/__init__.py +24 -29
  365. esphome/components/thermostat/climate.py +5 -5
  366. esphome/components/time_based/cover.py +17 -16
  367. esphome/components/time_based/time_based_cover.cpp +2 -1
  368. esphome/components/tm1638/switch/__init__.py +10 -7
  369. esphome/components/tormatic/cover.py +4 -5
  370. esphome/components/toshiba/climate.py +3 -5
  371. esphome/components/touchscreen/touchscreen.cpp +3 -1
  372. esphome/components/tuya/climate/__init__.py +5 -6
  373. esphome/components/tuya/cover/__init__.py +6 -11
  374. esphome/components/tuya/select/__init__.py +15 -5
  375. esphome/components/tuya/select/tuya_select.cpp +6 -1
  376. esphome/components/tuya/select/tuya_select.h +5 -1
  377. esphome/components/uart/packet_transport/__init__.py +20 -0
  378. esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
  379. esphome/components/uart/packet_transport/uart_transport.h +41 -0
  380. esphome/components/uart/switch/uart_switch.cpp +2 -1
  381. esphome/components/udp/__init__.py +126 -128
  382. esphome/components/udp/automation.h +40 -0
  383. esphome/components/udp/binary_sensor.py +3 -25
  384. esphome/components/udp/packet_transport/__init__.py +29 -0
  385. esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
  386. esphome/components/udp/packet_transport/udp_transport.h +28 -0
  387. esphome/components/udp/sensor.py +3 -25
  388. esphome/components/udp/udp_component.cpp +26 -470
  389. esphome/components/udp/udp_component.h +21 -128
  390. esphome/components/update/__init__.py +31 -1
  391. esphome/components/uponor_smatrix/climate/__init__.py +4 -9
  392. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
  393. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  394. esphome/components/uptime/text_sensor/__init__.py +47 -7
  395. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
  396. esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
  397. esphome/components/valve/__init__.py +34 -3
  398. esphome/components/valve/automation.h +1 -19
  399. esphome/components/vl53l0x/sensor.py +11 -0
  400. esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
  401. esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
  402. esphome/components/voice_assistant/__init__.py +36 -10
  403. esphome/components/voice_assistant/voice_assistant.cpp +170 -144
  404. esphome/components/voice_assistant/voice_assistant.h +26 -25
  405. esphome/components/waveshare_epaper/display.py +6 -0
  406. esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
  407. esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
  408. esphome/components/weikai/weikai.cpp +0 -52
  409. esphome/components/whirlpool/climate.py +3 -5
  410. esphome/components/whynter/climate.py +3 -5
  411. esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
  412. esphome/components/yashima/climate.py +6 -6
  413. esphome/components/zhlt01/climate.py +2 -7
  414. esphome/config.py +13 -13
  415. esphome/config_validation.py +38 -58
  416. esphome/const.py +15 -1
  417. esphome/core/__init__.py +2 -0
  418. esphome/core/application.cpp +27 -10
  419. esphome/core/application.h +9 -1
  420. esphome/core/automation.h +4 -3
  421. esphome/core/component.cpp +28 -7
  422. esphome/core/component.h +10 -1
  423. esphome/core/defines.h +23 -17
  424. esphome/core/doxygen.h +13 -0
  425. esphome/core/macros.h +4 -0
  426. esphome/core/scheduler.cpp +7 -1
  427. esphome/cpp_generator.py +6 -2
  428. esphome/dashboard/web_server.py +3 -3
  429. esphome/helpers.py +39 -0
  430. esphome/loader.py +4 -0
  431. esphome/log.py +15 -19
  432. esphome/mqtt.py +23 -10
  433. esphome/platformio_api.py +1 -1
  434. esphome/schema_extractors.py +0 -1
  435. esphome/voluptuous_schema.py +3 -1
  436. esphome/vscode.py +15 -0
  437. esphome/wizard.py +47 -37
  438. esphome/zeroconf.py +7 -3
  439. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/METADATA +10 -11
  440. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/RECORD +444 -383
  441. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/WHEEL +1 -1
  442. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/entry_points.txt +0 -0
  443. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/licenses/LICENSE +0 -0
  444. {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/top_level.txt +0 -0
@@ -27,14 +27,14 @@ CONFIG_SCHEMA = (
27
27
  cv.Schema(
28
28
  {
29
29
  cv.GenerateID(): cv.declare_id(DPS310Component),
30
- cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(
30
+ cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
31
31
  unit_of_measurement=UNIT_CELSIUS,
32
32
  icon=ICON_THERMOMETER,
33
33
  accuracy_decimals=1,
34
34
  device_class=DEVICE_CLASS_TEMPERATURE,
35
35
  state_class=STATE_CLASS_MEASUREMENT,
36
36
  ),
37
- cv.Required(CONF_PRESSURE): sensor.sensor_schema(
37
+ cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
38
38
  unit_of_measurement=UNIT_HECTOPASCAL,
39
39
  icon=ICON_GAUGE,
40
40
  accuracy_decimals=1,
@@ -53,10 +53,10 @@ async def to_code(config):
53
53
  await cg.register_component(var, config)
54
54
  await i2c.register_i2c_device(var, config)
55
55
 
56
- if CONF_TEMPERATURE in config:
57
- sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
56
+ if temperature := config.get(CONF_TEMPERATURE):
57
+ sens = await sensor.new_sensor(temperature)
58
58
  cg.add(var.set_temperature_sensor(sens))
59
59
 
60
- if CONF_PRESSURE in config:
61
- sens = await sensor.new_sensor(config[CONF_PRESSURE])
60
+ if pressure := config.get(CONF_PRESSURE):
61
+ sens = await sensor.new_sensor(pressure)
62
62
  cg.add(var.set_pressure_sensor(sens))
@@ -26,19 +26,19 @@ CONFIG_SCHEMA = (
26
26
  cv.Schema(
27
27
  {
28
28
  cv.GenerateID(): cv.declare_id(EE895Component),
29
- cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(
29
+ cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
30
30
  unit_of_measurement=UNIT_CELSIUS,
31
31
  accuracy_decimals=1,
32
32
  device_class=DEVICE_CLASS_TEMPERATURE,
33
33
  state_class=STATE_CLASS_MEASUREMENT,
34
34
  ),
35
- cv.Required(CONF_CO2): sensor.sensor_schema(
35
+ cv.Optional(CONF_CO2): sensor.sensor_schema(
36
36
  unit_of_measurement=UNIT_PARTS_PER_MILLION,
37
37
  icon=ICON_MOLECULE_CO2,
38
38
  accuracy_decimals=0,
39
39
  state_class=STATE_CLASS_MEASUREMENT,
40
40
  ),
41
- cv.Required(CONF_PRESSURE): sensor.sensor_schema(
41
+ cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
42
42
  unit_of_measurement=UNIT_HECTOPASCAL,
43
43
  accuracy_decimals=1,
44
44
  device_class=DEVICE_CLASS_PRESSURE,
@@ -56,14 +56,14 @@ async def to_code(config):
56
56
  await cg.register_component(var, config)
57
57
  await i2c.register_i2c_device(var, config)
58
58
 
59
- if CONF_TEMPERATURE in config:
60
- sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
59
+ if temperature := config.get(CONF_TEMPERATURE):
60
+ sens = await sensor.new_sensor(temperature)
61
61
  cg.add(var.set_temperature_sensor(sens))
62
62
 
63
- if CONF_CO2 in config:
64
- sens = await sensor.new_sensor(config[CONF_CO2])
63
+ if co2 := config.get(CONF_CO2):
64
+ sens = await sensor.new_sensor(co2)
65
65
  cg.add(var.set_co2_sensor(sens))
66
66
 
67
- if CONF_PRESSURE in config:
68
- sens = await sensor.new_sensor(config[CONF_PRESSURE])
67
+ if pressure := config.get(CONF_PRESSURE):
68
+ sens = await sensor.new_sensor(pressure)
69
69
  cg.add(var.set_pressure_sensor(sens))
@@ -1,7 +1,5 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import climate_ir
3
- import esphome.config_validation as cv
4
- from esphome.const import CONF_ID
5
3
 
6
4
  CODEOWNERS = ["@E440QF"]
7
5
  AUTO_LOAD = ["climate_ir"]
@@ -9,13 +7,8 @@ AUTO_LOAD = ["climate_ir"]
9
7
  emmeti_ns = cg.esphome_ns.namespace("emmeti")
10
8
  EmmetiClimate = emmeti_ns.class_("EmmetiClimate", climate_ir.ClimateIR)
11
9
 
12
- CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
13
- {
14
- cv.GenerateID(): cv.declare_id(EmmetiClimate),
15
- }
16
- )
10
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(EmmetiClimate)
17
11
 
18
12
 
19
13
  async def to_code(config):
20
- var = cg.new_Pvariable(config[CONF_ID])
21
- await climate_ir.register_climate_ir(var, config)
14
+ await climate_ir.new_climate_ir(config)
@@ -6,7 +6,6 @@ from esphome.const import (
6
6
  CONF_CLOSE_ACTION,
7
7
  CONF_CLOSE_DURATION,
8
8
  CONF_CLOSE_ENDSTOP,
9
- CONF_ID,
10
9
  CONF_MAX_DURATION,
11
10
  CONF_OPEN_ACTION,
12
11
  CONF_OPEN_DURATION,
@@ -17,25 +16,27 @@ from esphome.const import (
17
16
  endstop_ns = cg.esphome_ns.namespace("endstop")
18
17
  EndstopCover = endstop_ns.class_("EndstopCover", cover.Cover, cg.Component)
19
18
 
20
- CONFIG_SCHEMA = cover.COVER_SCHEMA.extend(
21
- {
22
- cv.GenerateID(): cv.declare_id(EndstopCover),
23
- cv.Required(CONF_STOP_ACTION): automation.validate_automation(single=True),
24
- cv.Required(CONF_OPEN_ENDSTOP): cv.use_id(binary_sensor.BinarySensor),
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_ENDSTOP): cv.use_id(binary_sensor.BinarySensor),
29
- cv.Required(CONF_CLOSE_DURATION): cv.positive_time_period_milliseconds,
30
- cv.Optional(CONF_MAX_DURATION): cv.positive_time_period_milliseconds,
31
- }
32
- ).extend(cv.COMPONENT_SCHEMA)
19
+ CONFIG_SCHEMA = (
20
+ cover.cover_schema(EndstopCover)
21
+ .extend(
22
+ {
23
+ cv.Required(CONF_STOP_ACTION): automation.validate_automation(single=True),
24
+ cv.Required(CONF_OPEN_ENDSTOP): cv.use_id(binary_sensor.BinarySensor),
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_ENDSTOP): cv.use_id(binary_sensor.BinarySensor),
29
+ cv.Required(CONF_CLOSE_DURATION): cv.positive_time_period_milliseconds,
30
+ cv.Optional(CONF_MAX_DURATION): cv.positive_time_period_milliseconds,
31
+ }
32
+ )
33
+ .extend(cv.COMPONENT_SCHEMA)
34
+ )
33
35
 
34
36
 
35
37
  async def to_code(config):
36
- var = cg.new_Pvariable(config[CONF_ID])
38
+ var = await cover.new_cover(config)
37
39
  await cg.register_component(var, config)
38
- await cover.register_cover(var, config)
39
40
 
40
41
  await automation.build_automation(
41
42
  var.get_stop_trigger(), [], config[CONF_STOP_ACTION]
@@ -1,6 +1,7 @@
1
1
  #include "endstop_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 endstop {
@@ -65,7 +66,7 @@ void EndstopCover::loop() {
65
66
  if (this->current_operation == COVER_OPERATION_IDLE)
66
67
  return;
67
68
 
68
- const uint32_t now = millis();
69
+ const uint32_t now = App.get_loop_component_start_time();
69
70
 
70
71
  if (this->current_operation == COVER_OPERATION_OPENING && this->is_open_()) {
71
72
  float dur = (now - this->start_dir_time_) / 1e3f;
@@ -28,21 +28,21 @@ UNIT_INDEX = "index"
28
28
 
29
29
  CONFIG_SCHEMA_BASE = cv.Schema(
30
30
  {
31
- cv.Required(CONF_ECO2): sensor.sensor_schema(
31
+ cv.Optional(CONF_ECO2): sensor.sensor_schema(
32
32
  unit_of_measurement=UNIT_PARTS_PER_MILLION,
33
33
  icon=ICON_MOLECULE_CO2,
34
34
  accuracy_decimals=0,
35
35
  device_class=DEVICE_CLASS_CARBON_DIOXIDE,
36
36
  state_class=STATE_CLASS_MEASUREMENT,
37
37
  ),
38
- cv.Required(CONF_TVOC): sensor.sensor_schema(
38
+ cv.Optional(CONF_TVOC): sensor.sensor_schema(
39
39
  unit_of_measurement=UNIT_PARTS_PER_BILLION,
40
40
  icon=ICON_RADIATOR,
41
41
  accuracy_decimals=0,
42
42
  device_class=DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
43
43
  state_class=STATE_CLASS_MEASUREMENT,
44
44
  ),
45
- cv.Required(CONF_AQI): sensor.sensor_schema(
45
+ cv.Optional(CONF_AQI): sensor.sensor_schema(
46
46
  icon=ICON_CHEMICAL_WEAPON,
47
47
  accuracy_decimals=0,
48
48
  device_class=DEVICE_CLASS_AQI,
@@ -62,12 +62,15 @@ async def to_code_base(config):
62
62
  var = cg.new_Pvariable(config[CONF_ID])
63
63
  await cg.register_component(var, config)
64
64
 
65
- sens = await sensor.new_sensor(config[CONF_ECO2])
66
- cg.add(var.set_co2(sens))
67
- sens = await sensor.new_sensor(config[CONF_TVOC])
68
- cg.add(var.set_tvoc(sens))
69
- sens = await sensor.new_sensor(config[CONF_AQI])
70
- cg.add(var.set_aqi(sens))
65
+ if eco2_config := config.get(CONF_ECO2):
66
+ sens = await sensor.new_sensor(eco2_config)
67
+ cg.add(var.set_co2(sens))
68
+ if tvoc_config := config.get(CONF_TVOC):
69
+ sens = await sensor.new_sensor(tvoc_config)
70
+ cg.add(var.set_tvoc(sens))
71
+ if aqi_config := config.get(CONF_AQI):
72
+ sens = await sensor.new_sensor(aqi_config)
73
+ cg.add(var.set_aqi(sens))
71
74
 
72
75
  if compensation_config := config.get(CONF_COMPENSATION):
73
76
  sens = await cg.get_variable(compensation_config[CONF_TEMPERATURE])
@@ -1,4 +1,5 @@
1
1
  from dataclasses import dataclass
2
+ import itertools
2
3
  import logging
3
4
  import os
4
5
  from pathlib import Path
@@ -37,6 +38,7 @@ from esphome.const import (
37
38
  __version__,
38
39
  )
39
40
  from esphome.core import CORE, HexInt, TimePeriod
41
+ from esphome.cpp_generator import RawExpression
40
42
  import esphome.final_validate as fv
41
43
  from esphome.helpers import copy_file_if_changed, mkdir_p, write_file_if_changed
42
44
 
@@ -54,6 +56,12 @@ from .const import ( # noqa
54
56
  KEY_SUBMODULES,
55
57
  KEY_VARIANT,
56
58
  VARIANT_ESP32,
59
+ VARIANT_ESP32C2,
60
+ VARIANT_ESP32C3,
61
+ VARIANT_ESP32C6,
62
+ VARIANT_ESP32H2,
63
+ VARIANT_ESP32S2,
64
+ VARIANT_ESP32S3,
57
65
  VARIANT_FRIENDLY,
58
66
  VARIANTS,
59
67
  )
@@ -70,7 +78,43 @@ CONF_RELEASE = "release"
70
78
  CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES = "enable_idf_experimental_features"
71
79
 
72
80
 
81
+ def get_cpu_frequencies(*frequencies):
82
+ return [str(x) + "MHZ" for x in frequencies]
83
+
84
+
85
+ CPU_FREQUENCIES = {
86
+ VARIANT_ESP32: get_cpu_frequencies(80, 160, 240),
87
+ VARIANT_ESP32S2: get_cpu_frequencies(80, 160, 240),
88
+ VARIANT_ESP32S3: get_cpu_frequencies(80, 160, 240),
89
+ VARIANT_ESP32C2: get_cpu_frequencies(80, 120),
90
+ VARIANT_ESP32C3: get_cpu_frequencies(80, 160),
91
+ VARIANT_ESP32C6: get_cpu_frequencies(80, 120, 160),
92
+ VARIANT_ESP32H2: get_cpu_frequencies(16, 32, 48, 64, 96),
93
+ }
94
+
95
+ # Make sure not missed here if a new variant added.
96
+ assert all(v in CPU_FREQUENCIES for v in VARIANTS)
97
+
98
+ FULL_CPU_FREQUENCIES = set(itertools.chain.from_iterable(CPU_FREQUENCIES.values()))
99
+
100
+
73
101
  def set_core_data(config):
102
+ cpu_frequency = config.get(CONF_CPU_FREQUENCY, None)
103
+ variant = config[CONF_VARIANT]
104
+ # if not specified in config, set to 160MHz if supported, the fastest otherwise
105
+ if cpu_frequency is None:
106
+ choices = CPU_FREQUENCIES[variant]
107
+ if "160MHZ" in choices:
108
+ cpu_frequency = "160MHZ"
109
+ else:
110
+ cpu_frequency = choices[-1]
111
+ config[CONF_CPU_FREQUENCY] = cpu_frequency
112
+ elif cpu_frequency not in CPU_FREQUENCIES[variant]:
113
+ raise cv.Invalid(
114
+ f"Invalid CPU frequency '{cpu_frequency}' for {config[CONF_VARIANT]}",
115
+ path=[CONF_CPU_FREQUENCY],
116
+ )
117
+
74
118
  CORE.data[KEY_ESP32] = {}
75
119
  CORE.data[KEY_CORE][KEY_TARGET_PLATFORM] = PLATFORM_ESP32
76
120
  conf = config[CONF_FRAMEWORK]
@@ -83,6 +127,7 @@ def set_core_data(config):
83
127
  CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] = cv.Version.parse(
84
128
  config[CONF_FRAMEWORK][CONF_VERSION]
85
129
  )
130
+
86
131
  CORE.data[KEY_ESP32][KEY_BOARD] = config[CONF_BOARD]
87
132
  CORE.data[KEY_ESP32][KEY_VARIANT] = config[CONF_VARIANT]
88
133
  CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES] = {}
@@ -251,7 +296,7 @@ ARDUINO_PLATFORM_VERSION = cv.Version(5, 4, 0)
251
296
  # The default/recommended esp-idf framework version
252
297
  # - https://github.com/espressif/esp-idf/releases
253
298
  # - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
254
- RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(5, 1, 5)
299
+ RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(5, 1, 6)
255
300
  # The platformio/espressif32 version to use for esp-idf frameworks
256
301
  # - https://github.com/platformio/platform-espressif32/releases
257
302
  # - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
@@ -274,12 +319,15 @@ SUPPORTED_PLATFORMIO_ESP_IDF_5X = [
274
319
  # pioarduino versions that don't require a release number
275
320
  # List based on https://github.com/pioarduino/esp-idf/releases
276
321
  SUPPORTED_PIOARDUINO_ESP_IDF_5X = [
322
+ cv.Version(5, 5, 0),
277
323
  cv.Version(5, 4, 1),
278
324
  cv.Version(5, 4, 0),
325
+ cv.Version(5, 3, 3),
279
326
  cv.Version(5, 3, 2),
280
327
  cv.Version(5, 3, 1),
281
328
  cv.Version(5, 3, 0),
282
329
  cv.Version(5, 1, 5),
330
+ cv.Version(5, 1, 6),
283
331
  ]
284
332
 
285
333
 
@@ -321,8 +369,8 @@ def _arduino_check_versions(value):
321
369
  def _esp_idf_check_versions(value):
322
370
  value = value.copy()
323
371
  lookups = {
324
- "dev": (cv.Version(5, 1, 5), "https://github.com/espressif/esp-idf.git"),
325
- "latest": (cv.Version(5, 1, 5), None),
372
+ "dev": (cv.Version(5, 1, 6), "https://github.com/espressif/esp-idf.git"),
373
+ "latest": (cv.Version(5, 1, 6), None),
326
374
  "recommended": (RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION, None),
327
375
  }
328
376
 
@@ -550,11 +598,15 @@ FLASH_SIZES = [
550
598
  ]
551
599
 
552
600
  CONF_FLASH_SIZE = "flash_size"
601
+ CONF_CPU_FREQUENCY = "cpu_frequency"
553
602
  CONF_PARTITIONS = "partitions"
554
603
  CONFIG_SCHEMA = cv.All(
555
604
  cv.Schema(
556
605
  {
557
606
  cv.Required(CONF_BOARD): cv.string_strict,
607
+ cv.Optional(CONF_CPU_FREQUENCY): cv.one_of(
608
+ *FULL_CPU_FREQUENCIES, upper=True
609
+ ),
558
610
  cv.Optional(CONF_FLASH_SIZE, default="4MB"): cv.one_of(
559
611
  *FLASH_SIZES, upper=True
560
612
  ),
@@ -595,6 +647,7 @@ async def to_code(config):
595
647
  os.path.join(os.path.dirname(__file__), "post_build.py.script"),
596
648
  )
597
649
 
650
+ freq = config[CONF_CPU_FREQUENCY][:-3]
598
651
  if conf[CONF_TYPE] == FRAMEWORK_ESP_IDF:
599
652
  cg.add_platformio_option("framework", "espidf")
600
653
  cg.add_build_flag("-DUSE_ESP_IDF")
@@ -628,6 +681,9 @@ async def to_code(config):
628
681
  add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0", False)
629
682
  add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1", False)
630
683
 
684
+ # Set default CPU frequency
685
+ add_idf_sdkconfig_option(f"CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_{freq}", True)
686
+
631
687
  cg.add_platformio_option("board_build.partitions", "partitions.csv")
632
688
  if CONF_PARTITIONS in config:
633
689
  add_extra_build_file(
@@ -693,6 +749,7 @@ async def to_code(config):
693
749
  f"VERSION_CODE({framework_ver.major}, {framework_ver.minor}, {framework_ver.patch})"
694
750
  ),
695
751
  )
752
+ cg.add(RawExpression(f"setCpuFrequencyMhz({freq})"))
696
753
 
697
754
 
698
755
  APP_PARTITION_SIZES = {
@@ -13,11 +13,13 @@
13
13
  #include <hal/cpu_hal.h>
14
14
 
15
15
  #ifdef USE_ARDUINO
16
- #include <esp32-hal.h>
17
- #endif
16
+ #include <Esp.h>
17
+ #else
18
+ #include <esp_clk_tree.h>
18
19
 
19
20
  void setup();
20
21
  void loop();
22
+ #endif
21
23
 
22
24
  namespace esphome {
23
25
 
@@ -59,9 +61,13 @@ uint32_t arch_get_cpu_cycle_count() { return esp_cpu_get_cycle_count(); }
59
61
  uint32_t arch_get_cpu_cycle_count() { return cpu_hal_get_cycle_count(); }
60
62
  #endif
61
63
  uint32_t arch_get_cpu_freq_hz() {
62
- rtc_cpu_freq_config_t config;
63
- rtc_clk_cpu_freq_get_config(&config);
64
- return config.freq_mhz * 1000000U;
64
+ uint32_t freq = 0;
65
+ #ifdef USE_ESP_IDF
66
+ esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_CPU, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &freq);
67
+ #elif defined(USE_ARDUINO)
68
+ freq = ESP.getCpuFreqMHz() * 1000000;
69
+ #endif
70
+ return freq;
65
71
  }
66
72
 
67
73
  #ifdef USE_ESP_IDF
@@ -2,42 +2,66 @@
2
2
 
3
3
  #include "gpio.h"
4
4
  #include "esphome/core/log.h"
5
+ #include "driver/gpio.h"
6
+ #include "driver/rtc_io.h"
7
+ #include "hal/gpio_hal.h"
8
+ #include "soc/soc_caps.h"
9
+ #include "soc/gpio_periph.h"
5
10
  #include <cinttypes>
6
11
 
12
+ #if (SOC_RTCIO_PIN_COUNT > 0)
13
+ #include "hal/rtc_io_hal.h"
14
+ #endif
15
+
16
+ #ifndef SOC_GPIO_SUPPORT_RTC_INDEPENDENT
17
+ #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT 0 // NOLINT
18
+ #endif
19
+
7
20
  namespace esphome {
8
21
  namespace esp32 {
9
22
 
10
23
  static const char *const TAG = "esp32";
11
24
 
25
+ static const gpio_hal_context_t GPIO_HAL = {.dev = GPIO_HAL_GET_HW(GPIO_PORT_0)};
26
+
12
27
  bool ESP32InternalGPIOPin::isr_service_installed = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
13
28
 
14
- static gpio_mode_t IRAM_ATTR flags_to_mode(gpio::Flags flags) {
29
+ static gpio_mode_t flags_to_mode(gpio::Flags flags) {
15
30
  flags = (gpio::Flags)(flags & ~(gpio::FLAG_PULLUP | gpio::FLAG_PULLDOWN));
16
- if (flags == gpio::FLAG_INPUT) {
31
+ if (flags == gpio::FLAG_INPUT)
17
32
  return GPIO_MODE_INPUT;
18
- } else if (flags == gpio::FLAG_OUTPUT) {
33
+ if (flags == gpio::FLAG_OUTPUT)
19
34
  return GPIO_MODE_OUTPUT;
20
- } else if (flags == (gpio::FLAG_OUTPUT | gpio::FLAG_OPEN_DRAIN)) {
35
+ if (flags == (gpio::FLAG_OUTPUT | gpio::FLAG_OPEN_DRAIN))
21
36
  return GPIO_MODE_OUTPUT_OD;
22
- } else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_OUTPUT | gpio::FLAG_OPEN_DRAIN)) {
37
+ if (flags == (gpio::FLAG_INPUT | gpio::FLAG_OUTPUT | gpio::FLAG_OPEN_DRAIN))
23
38
  return GPIO_MODE_INPUT_OUTPUT_OD;
24
- } else if (flags == (gpio::FLAG_INPUT | gpio::FLAG_OUTPUT)) {
39
+ if (flags == (gpio::FLAG_INPUT | gpio::FLAG_OUTPUT))
25
40
  return GPIO_MODE_INPUT_OUTPUT;
26
- } else {
27
- // unsupported or gpio::FLAG_NONE
28
- return GPIO_MODE_DISABLE;
29
- }
41
+ // unsupported or gpio::FLAG_NONE
42
+ return GPIO_MODE_DISABLE;
30
43
  }
31
44
 
32
45
  struct ISRPinArg {
33
46
  gpio_num_t pin;
47
+ gpio::Flags flags;
34
48
  bool inverted;
49
+ #if defined(USE_ESP32_VARIANT_ESP32)
50
+ bool use_rtc;
51
+ int rtc_pin;
52
+ #endif
35
53
  };
36
54
 
37
55
  ISRInternalGPIOPin ESP32InternalGPIOPin::to_isr() const {
38
56
  auto *arg = new ISRPinArg{}; // NOLINT(cppcoreguidelines-owning-memory)
39
- arg->pin = pin_;
57
+ arg->pin = this->pin_;
58
+ arg->flags = gpio::FLAG_NONE;
40
59
  arg->inverted = inverted_;
60
+ #if defined(USE_ESP32_VARIANT_ESP32)
61
+ arg->use_rtc = rtc_gpio_is_valid_gpio(this->pin_);
62
+ if (arg->use_rtc)
63
+ arg->rtc_pin = rtc_io_number_get(this->pin_);
64
+ #endif
41
65
  return ISRInternalGPIOPin((void *) arg);
42
66
  }
43
67
 
@@ -90,6 +114,7 @@ void ESP32InternalGPIOPin::setup() {
90
114
  if (flags_ & gpio::FLAG_OUTPUT) {
91
115
  gpio_set_drive_capability(pin_, drive_strength_);
92
116
  }
117
+ ESP_LOGD(TAG, "rtc: %d", SOC_GPIO_SUPPORT_RTC_INDEPENDENT);
93
118
  }
94
119
 
95
120
  void ESP32InternalGPIOPin::pin_mode(gpio::Flags flags) {
@@ -115,28 +140,65 @@ void ESP32InternalGPIOPin::detach_interrupt() const { gpio_intr_disable(pin_); }
115
140
  using namespace esp32;
116
141
 
117
142
  bool IRAM_ATTR ISRInternalGPIOPin::digital_read() {
118
- auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
119
- return bool(gpio_get_level(arg->pin)) != arg->inverted;
143
+ auto *arg = reinterpret_cast<ISRPinArg *>(this->arg_);
144
+ return bool(gpio_hal_get_level(&GPIO_HAL, arg->pin)) != arg->inverted;
120
145
  }
146
+
121
147
  void IRAM_ATTR ISRInternalGPIOPin::digital_write(bool value) {
122
- auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
123
- gpio_set_level(arg->pin, value != arg->inverted ? 1 : 0);
148
+ auto *arg = reinterpret_cast<ISRPinArg *>(this->arg_);
149
+ gpio_hal_set_level(&GPIO_HAL, arg->pin, value != arg->inverted);
124
150
  }
151
+
125
152
  void IRAM_ATTR ISRInternalGPIOPin::clear_interrupt() {
126
153
  // not supported
127
154
  }
155
+
128
156
  void IRAM_ATTR ISRInternalGPIOPin::pin_mode(gpio::Flags flags) {
129
157
  auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
130
- gpio_set_direction(arg->pin, flags_to_mode(flags));
131
- gpio_pull_mode_t pull_mode = GPIO_FLOATING;
132
- if ((flags & gpio::FLAG_PULLUP) && (flags & gpio::FLAG_PULLDOWN)) {
133
- pull_mode = GPIO_PULLUP_PULLDOWN;
134
- } else if (flags & gpio::FLAG_PULLUP) {
135
- pull_mode = GPIO_PULLUP_ONLY;
136
- } else if (flags & gpio::FLAG_PULLDOWN) {
137
- pull_mode = GPIO_PULLDOWN_ONLY;
158
+ gpio::Flags diff = (gpio::Flags)(flags ^ arg->flags);
159
+ if (diff & gpio::FLAG_OUTPUT) {
160
+ if (flags & gpio::FLAG_OUTPUT) {
161
+ gpio_hal_output_enable(&GPIO_HAL, arg->pin);
162
+ if (flags & gpio::FLAG_OPEN_DRAIN)
163
+ gpio_hal_od_enable(&GPIO_HAL, arg->pin);
164
+ } else {
165
+ gpio_hal_output_disable(&GPIO_HAL, arg->pin);
166
+ }
167
+ }
168
+ if (diff & gpio::FLAG_INPUT) {
169
+ if (flags & gpio::FLAG_INPUT) {
170
+ gpio_hal_input_enable(&GPIO_HAL, arg->pin);
171
+ #if defined(USE_ESP32_VARIANT_ESP32)
172
+ if (arg->use_rtc) {
173
+ if (flags & gpio::FLAG_PULLUP) {
174
+ rtcio_hal_pullup_enable(arg->rtc_pin);
175
+ } else {
176
+ rtcio_hal_pullup_disable(arg->rtc_pin);
177
+ }
178
+ if (flags & gpio::FLAG_PULLDOWN) {
179
+ rtcio_hal_pulldown_enable(arg->rtc_pin);
180
+ } else {
181
+ rtcio_hal_pulldown_disable(arg->rtc_pin);
182
+ }
183
+ } else
184
+ #endif
185
+ {
186
+ if (flags & gpio::FLAG_PULLUP) {
187
+ gpio_hal_pullup_en(&GPIO_HAL, arg->pin);
188
+ } else {
189
+ gpio_hal_pullup_dis(&GPIO_HAL, arg->pin);
190
+ }
191
+ if (flags & gpio::FLAG_PULLDOWN) {
192
+ gpio_hal_pulldown_en(&GPIO_HAL, arg->pin);
193
+ } else {
194
+ gpio_hal_pulldown_dis(&GPIO_HAL, arg->pin);
195
+ }
196
+ }
197
+ } else {
198
+ gpio_hal_input_disable(&GPIO_HAL, arg->pin);
199
+ }
138
200
  }
139
- gpio_set_pull_mode(arg->pin, pull_mode);
201
+ arg->flags = flags;
140
202
  }
141
203
 
142
204
  } // namespace esphome
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
  import logging
3
- from typing import Any
3
+ from typing import Any, Callable
4
4
 
5
5
  from esphome import pins
6
6
  import esphome.codegen as cg
@@ -64,8 +64,7 @@ def _lookup_pin(value):
64
64
  def _translate_pin(value):
65
65
  if isinstance(value, dict) or value is None:
66
66
  raise cv.Invalid(
67
- "This variable only supports pin numbers, not full pin schemas "
68
- "(with inverted and mode)."
67
+ "This variable only supports pin numbers, not full pin schemas (with inverted and mode)."
69
68
  )
70
69
  if isinstance(value, int) and not isinstance(value, bool):
71
70
  return value
@@ -82,30 +81,22 @@ def _translate_pin(value):
82
81
 
83
82
  @dataclass
84
83
  class ESP32ValidationFunctions:
85
- pin_validation: Any
86
- usage_validation: Any
84
+ pin_validation: Callable[[Any], Any]
85
+ usage_validation: Callable[[Any], Any]
87
86
 
88
87
 
89
88
  _esp32_validations = {
90
89
  VARIANT_ESP32: ESP32ValidationFunctions(
91
90
  pin_validation=esp32_validate_gpio_pin, usage_validation=esp32_validate_supports
92
91
  ),
93
- VARIANT_ESP32S2: ESP32ValidationFunctions(
94
- pin_validation=esp32_s2_validate_gpio_pin,
95
- usage_validation=esp32_s2_validate_supports,
92
+ VARIANT_ESP32C2: ESP32ValidationFunctions(
93
+ pin_validation=esp32_c2_validate_gpio_pin,
94
+ usage_validation=esp32_c2_validate_supports,
96
95
  ),
97
96
  VARIANT_ESP32C3: ESP32ValidationFunctions(
98
97
  pin_validation=esp32_c3_validate_gpio_pin,
99
98
  usage_validation=esp32_c3_validate_supports,
100
99
  ),
101
- VARIANT_ESP32S3: ESP32ValidationFunctions(
102
- pin_validation=esp32_s3_validate_gpio_pin,
103
- usage_validation=esp32_s3_validate_supports,
104
- ),
105
- VARIANT_ESP32C2: ESP32ValidationFunctions(
106
- pin_validation=esp32_c2_validate_gpio_pin,
107
- usage_validation=esp32_c2_validate_supports,
108
- ),
109
100
  VARIANT_ESP32C6: ESP32ValidationFunctions(
110
101
  pin_validation=esp32_c6_validate_gpio_pin,
111
102
  usage_validation=esp32_c6_validate_supports,
@@ -114,6 +105,14 @@ _esp32_validations = {
114
105
  pin_validation=esp32_h2_validate_gpio_pin,
115
106
  usage_validation=esp32_h2_validate_supports,
116
107
  ),
108
+ VARIANT_ESP32S2: ESP32ValidationFunctions(
109
+ pin_validation=esp32_s2_validate_gpio_pin,
110
+ usage_validation=esp32_s2_validate_supports,
111
+ ),
112
+ VARIANT_ESP32S3: ESP32ValidationFunctions(
113
+ pin_validation=esp32_s3_validate_gpio_pin,
114
+ usage_validation=esp32_s3_validate_supports,
115
+ ),
117
116
  }
118
117
 
119
118
 
@@ -31,8 +31,7 @@ def esp32_validate_gpio_pin(value):
31
31
  )
32
32
  if 9 <= value <= 10:
33
33
  _LOGGER.warning(
34
- "Pin %s (9-10) might already be used by the "
35
- "flash interface in QUAD IO flash mode.",
34
+ "Pin %s (9-10) might already be used by the flash interface in QUAD IO flash mode.",
36
35
  value,
37
36
  )
38
37
  if value in (24, 28, 29, 30, 31):
@@ -22,7 +22,7 @@ def esp32_c2_validate_supports(value):
22
22
  is_input = mode[CONF_INPUT]
23
23
 
24
24
  if num < 0 or num > 20:
25
- raise cv.Invalid(f"Invalid pin number: {value} (must be 0-20)")
25
+ raise cv.Invalid(f"Invalid pin number: {num} (must be 0-20)")
26
26
 
27
27
  if is_input:
28
28
  # All ESP32 pins support input mode
@@ -35,7 +35,7 @@ def esp32_c3_validate_supports(value):
35
35
  is_input = mode[CONF_INPUT]
36
36
 
37
37
  if num < 0 or num > 21:
38
- raise cv.Invalid(f"Invalid pin number: {value} (must be 0-21)")
38
+ raise cv.Invalid(f"Invalid pin number: {num} (must be 0-21)")
39
39
 
40
40
  if is_input:
41
41
  # All ESP32 pins support input mode