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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (412) hide show
  1. esphome/components/ac_dimmer/ac_dimmer.cpp +3 -2
  2. esphome/components/adc/__init__.py +51 -34
  3. esphome/components/airthings_wave_base/__init__.py +1 -1
  4. esphome/components/alarm_control_panel/__init__.py +37 -2
  5. esphome/components/am43/cover/__init__.py +4 -5
  6. esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
  7. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
  8. esphome/components/analog_threshold/binary_sensor.py +10 -8
  9. esphome/components/anova/climate.py +4 -5
  10. esphome/components/api/__init__.py +25 -8
  11. esphome/components/api/api_connection.cpp +77 -10
  12. esphome/components/api/api_connection.h +6 -1
  13. esphome/components/api/api_frame_helper.cpp +98 -130
  14. esphome/components/api/api_frame_helper.h +12 -2
  15. esphome/components/api/api_noise_context.h +13 -4
  16. esphome/components/api/api_pb2.cpp +1422 -1
  17. esphome/components/api/api_pb2.h +255 -1
  18. esphome/components/api/api_pb2_service.cpp +162 -49
  19. esphome/components/api/api_pb2_service.h +90 -51
  20. esphome/components/api/api_pb2_size.h +361 -0
  21. esphome/components/api/api_server.cpp +110 -34
  22. esphome/components/api/api_server.h +8 -0
  23. esphome/components/api/proto.h +38 -9
  24. esphome/components/as3935_i2c/as3935_i2c.h +0 -3
  25. esphome/components/as7341/as7341.h +1 -1
  26. esphome/components/atm90e32/__init__.py +1 -0
  27. esphome/components/atm90e32/atm90e32.cpp +576 -199
  28. esphome/components/atm90e32/atm90e32.h +128 -31
  29. esphome/components/atm90e32/atm90e32_reg.h +4 -2
  30. esphome/components/atm90e32/button/__init__.py +62 -10
  31. esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
  32. esphome/components/atm90e32/button/atm90e32_button.h +36 -4
  33. esphome/components/atm90e32/number/__init__.py +130 -0
  34. esphome/components/atm90e32/number/atm90e32_number.h +16 -0
  35. esphome/components/atm90e32/sensor.py +21 -4
  36. esphome/components/atm90e32/text_sensor/__init__.py +48 -0
  37. esphome/components/audio/__init__.py +96 -49
  38. esphome/components/audio/audio.h +48 -0
  39. esphome/components/audio/audio_decoder.cpp +1 -1
  40. esphome/components/audio/audio_resampler.cpp +2 -0
  41. esphome/components/audio/audio_resampler.h +1 -0
  42. esphome/components/ballu/climate.py +2 -9
  43. esphome/components/bang_bang/climate.py +5 -6
  44. esphome/components/bedjet/climate/__init__.py +3 -8
  45. esphome/components/bedjet/fan/__init__.py +2 -11
  46. esphome/components/binary/fan/__init__.py +13 -16
  47. esphome/components/binary_sensor/__init__.py +13 -10
  48. esphome/components/binary_sensor/binary_sensor.cpp +6 -10
  49. esphome/components/binary_sensor/binary_sensor.h +1 -1
  50. esphome/components/binary_sensor/filter.cpp +21 -21
  51. esphome/components/binary_sensor/filter.h +10 -10
  52. esphome/components/bl0906/constants.h +16 -16
  53. esphome/components/ble_client/text_sensor/__init__.py +3 -5
  54. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
  55. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +135 -21
  56. esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
  57. esphome/components/button/__init__.py +11 -8
  58. esphome/components/canbus/canbus.cpp +3 -0
  59. esphome/components/canbus/canbus.h +16 -0
  60. esphome/components/climate/__init__.py +35 -2
  61. esphome/components/climate/climate_mode.h +1 -1
  62. esphome/components/climate/climate_traits.h +63 -57
  63. esphome/components/climate_ir/__init__.py +57 -17
  64. esphome/components/climate_ir_lg/climate.py +2 -5
  65. esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
  66. esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
  67. esphome/components/color/__init__.py +2 -0
  68. esphome/components/const/__init__.py +5 -0
  69. esphome/components/coolix/climate.py +2 -9
  70. esphome/components/copy/cover/__init__.py +10 -9
  71. esphome/components/copy/fan/__init__.py +11 -9
  72. esphome/components/copy/lock/__init__.py +11 -9
  73. esphome/components/copy/text/__init__.py +9 -6
  74. esphome/components/cover/__init__.py +37 -2
  75. esphome/components/cst226/binary_sensor/__init__.py +28 -0
  76. esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
  77. esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
  78. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
  79. esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
  80. esphome/components/current_based/cover.py +37 -36
  81. esphome/components/daikin/climate.py +2 -9
  82. esphome/components/daikin/daikin.cpp +15 -9
  83. esphome/components/daikin/daikin.h +5 -5
  84. esphome/components/daikin_arc/climate.py +2 -7
  85. esphome/components/daikin_brc/climate.py +3 -5
  86. esphome/components/dallas_temp/dallas_temp.cpp +17 -24
  87. esphome/components/dallas_temp/dallas_temp.h +0 -1
  88. esphome/components/debug/debug_component.cpp +5 -0
  89. esphome/components/debug/debug_component.h +6 -0
  90. esphome/components/debug/debug_esp32.cpp +109 -254
  91. esphome/components/debug/sensor.py +14 -0
  92. esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
  93. esphome/components/delonghi/climate.py +2 -9
  94. esphome/components/demo/__init__.py +18 -20
  95. esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
  96. esphome/components/display/rect.cpp +4 -9
  97. esphome/components/display/rect.h +1 -1
  98. esphome/components/emmeti/climate.py +2 -9
  99. esphome/components/endstop/cover.py +17 -16
  100. esphome/components/esp32/__init__.py +60 -3
  101. esphome/components/esp32/core.cpp +11 -5
  102. esphome/components/esp32/gpio.cpp +86 -24
  103. esphome/components/esp32/gpio.py +15 -16
  104. esphome/components/esp32/gpio_esp32.py +1 -2
  105. esphome/components/esp32/gpio_esp32_c2.py +1 -1
  106. esphome/components/esp32/gpio_esp32_c3.py +1 -1
  107. esphome/components/esp32/gpio_esp32_c6.py +1 -1
  108. esphome/components/esp32/gpio_esp32_h2.py +1 -1
  109. esphome/components/esp32_ble/ble.cpp +1 -8
  110. esphome/components/esp32_ble/ble.h +5 -3
  111. esphome/components/esp32_ble/ble_advertising.h +1 -0
  112. esphome/components/esp32_ble_server/__init__.py +3 -0
  113. esphome/components/esp32_ble_tracker/__init__.py +7 -1
  114. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
  115. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
  116. esphome/components/esp32_can/esp32_can.cpp +1 -1
  117. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  118. esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
  119. esphome/components/esp32_rmt_led_strip/light.py +9 -1
  120. esphome/components/esp8266/gpio.cpp +69 -8
  121. esphome/components/event/__init__.py +13 -10
  122. esphome/components/factory_reset/switch/__init__.py +7 -21
  123. esphome/components/fan/__init__.py +52 -5
  124. esphome/components/fastled_base/__init__.py +1 -4
  125. esphome/components/fastled_base/fastled_light.cpp +1 -1
  126. esphome/components/feedback/cover.py +38 -33
  127. esphome/components/fujitsu_general/climate.py +2 -9
  128. esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
  129. esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
  130. esphome/components/gpio_expander/cached_gpio.h +22 -7
  131. esphome/components/gps/__init__.py +11 -2
  132. esphome/components/gps/gps.cpp +11 -8
  133. esphome/components/gps/gps.h +9 -6
  134. esphome/components/graph/__init__.py +1 -2
  135. esphome/components/gree/climate.py +4 -6
  136. esphome/components/gree/gree.cpp +16 -2
  137. esphome/components/gree/gree.h +2 -2
  138. esphome/components/haier/climate.py +37 -34
  139. esphome/components/hbridge/fan/__init__.py +19 -17
  140. esphome/components/he60r/cover.py +4 -5
  141. esphome/components/heatpumpir/climate.py +3 -6
  142. esphome/components/hitachi_ac344/climate.py +2 -9
  143. esphome/components/hitachi_ac424/climate.py +2 -9
  144. esphome/components/hlw8012/hlw8012.cpp +1 -1
  145. esphome/components/hm3301/hm3301.h +1 -1
  146. esphome/components/http_request/__init__.py +39 -6
  147. esphome/components/http_request/http_request.cpp +20 -0
  148. esphome/components/http_request/http_request.h +57 -15
  149. esphome/components/http_request/http_request_arduino.cpp +22 -6
  150. esphome/components/http_request/http_request_arduino.h +4 -3
  151. esphome/components/http_request/http_request_host.cpp +141 -0
  152. esphome/components/http_request/http_request_host.h +37 -0
  153. esphome/components/http_request/http_request_idf.cpp +35 -3
  154. esphome/components/http_request/http_request_idf.h +10 -3
  155. esphome/components/http_request/httplib.h +9691 -0
  156. esphome/components/http_request/update/__init__.py +11 -8
  157. esphome/components/i2c/i2c.h +4 -0
  158. esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
  159. esphome/components/i2s_audio/__init__.py +131 -22
  160. esphome/components/i2s_audio/i2s_audio.h +44 -4
  161. esphome/components/i2s_audio/media_player/__init__.py +19 -9
  162. esphome/components/i2s_audio/microphone/__init__.py +63 -5
  163. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
  164. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
  165. esphome/components/i2s_audio/speaker/__init__.py +31 -5
  166. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
  167. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
  168. esphome/components/ili9xxx/ili9xxx_init.h +1 -1
  169. esphome/components/image/__init__.py +37 -17
  170. esphome/components/image/image.cpp +25 -8
  171. esphome/components/internal_temperature/internal_temperature.cpp +6 -4
  172. esphome/components/key_collector/__init__.py +35 -0
  173. esphome/components/key_collector/key_collector.cpp +8 -0
  174. esphome/components/key_collector/key_collector.h +10 -0
  175. esphome/components/ld2410/ld2410.h +1 -1
  176. esphome/components/ld2450/ld2450.h +1 -1
  177. esphome/components/light/__init__.py +57 -0
  178. esphome/components/lock/__init__.py +51 -4
  179. esphome/components/lock/automation.h +2 -13
  180. esphome/components/logger/__init__.py +21 -0
  181. esphome/components/logger/logger.cpp +125 -95
  182. esphome/components/logger/logger.h +160 -35
  183. esphome/components/logger/task_log_buffer.cpp +138 -0
  184. esphome/components/logger/task_log_buffer.h +69 -0
  185. esphome/components/lvgl/__init__.py +13 -5
  186. esphome/components/lvgl/automation.py +50 -1
  187. esphome/components/lvgl/defines.py +0 -1
  188. esphome/components/lvgl/lv_validation.py +10 -1
  189. esphome/components/lvgl/lvgl_esphome.cpp +5 -1
  190. esphome/components/lvgl/schemas.py +14 -14
  191. esphome/components/lvgl/text/__init__.py +1 -2
  192. esphome/components/lvgl/widgets/arc.py +7 -6
  193. esphome/components/lvgl/widgets/buttonmatrix.py +3 -3
  194. esphome/components/lvgl/widgets/checkbox.py +2 -2
  195. esphome/components/lvgl/widgets/dropdown.py +2 -1
  196. esphome/components/lvgl/widgets/img.py +15 -12
  197. esphome/components/mapping/__init__.py +134 -0
  198. esphome/components/max7219digit/max7219digit.cpp +27 -27
  199. esphome/components/mdns/__init__.py +11 -5
  200. esphome/components/mdns/mdns_component.cpp +11 -5
  201. esphome/components/mdns/mdns_component.h +3 -2
  202. esphome/components/mdns/mdns_esp32.cpp +4 -3
  203. esphome/components/mdns/mdns_esp8266.cpp +4 -2
  204. esphome/components/mdns/mdns_libretiny.cpp +4 -2
  205. esphome/components/mdns/mdns_rp2040.cpp +4 -2
  206. esphome/components/media_player/__init__.py +40 -6
  207. esphome/components/micro_wake_word/__init__.py +99 -31
  208. esphome/components/micro_wake_word/automation.h +54 -0
  209. esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
  210. esphome/components/micro_wake_word/micro_wake_word.h +58 -105
  211. esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
  212. esphome/components/micro_wake_word/streaming_model.cpp +158 -41
  213. esphome/components/micro_wake_word/streaming_model.h +85 -13
  214. esphome/components/microphone/__init__.py +139 -9
  215. esphome/components/microphone/automation.h +14 -2
  216. esphome/components/microphone/microphone.cpp +21 -0
  217. esphome/components/microphone/microphone.h +14 -5
  218. esphome/components/microphone/microphone_source.cpp +95 -0
  219. esphome/components/microphone/microphone_source.h +80 -0
  220. esphome/components/mics_4514/sensor.py +25 -14
  221. esphome/components/midea/climate.py +3 -4
  222. esphome/components/midea_ir/climate.py +3 -5
  223. esphome/components/mipi_spi/__init__.py +15 -0
  224. esphome/components/mipi_spi/display.py +474 -0
  225. esphome/components/mipi_spi/mipi_spi.cpp +481 -0
  226. esphome/components/mipi_spi/mipi_spi.h +171 -0
  227. esphome/components/mipi_spi/models/__init__.py +65 -0
  228. esphome/components/mipi_spi/models/amoled.py +72 -0
  229. esphome/components/mipi_spi/models/commands.py +82 -0
  230. esphome/components/mipi_spi/models/cyd.py +10 -0
  231. esphome/components/mipi_spi/models/ili.py +749 -0
  232. esphome/components/mipi_spi/models/jc.py +260 -0
  233. esphome/components/mipi_spi/models/lanbon.py +15 -0
  234. esphome/components/mipi_spi/models/lilygo.py +60 -0
  235. esphome/components/mipi_spi/models/waveshare.py +139 -0
  236. esphome/components/mitsubishi/climate.py +2 -5
  237. esphome/components/mitsubishi/mitsubishi.cpp +9 -9
  238. esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
  239. esphome/components/mixer/speaker/mixer_speaker.h +1 -3
  240. esphome/components/mlx90393/sensor.py +5 -0
  241. esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
  242. esphome/components/mlx90393/sensor_mlx90393.h +21 -4
  243. esphome/components/mqtt/__init__.py +1 -1
  244. esphome/components/mqtt/mqtt_client.cpp +5 -1
  245. esphome/components/mqtt/mqtt_const.h +4 -0
  246. esphome/components/mqtt/mqtt_fan.cpp +39 -0
  247. esphome/components/mqtt/mqtt_fan.h +2 -0
  248. esphome/components/network/__init__.py +1 -1
  249. esphome/components/nextion/base_component.py +17 -16
  250. esphome/components/nextion/display.py +11 -2
  251. esphome/components/nextion/nextion.cpp +39 -1
  252. esphome/components/nextion/nextion.h +50 -0
  253. esphome/components/noblex/climate.py +2 -9
  254. esphome/components/number/__init__.py +12 -9
  255. esphome/components/one_wire/one_wire_bus.cpp +14 -10
  256. esphome/components/one_wire/one_wire_bus.h +14 -8
  257. esphome/components/online_image/bmp_image.cpp +48 -11
  258. esphome/components/online_image/bmp_image.h +2 -0
  259. esphome/components/opentherm/binary_sensor/__init__.py +2 -4
  260. esphome/components/opentherm/number/__init__.py +11 -20
  261. esphome/components/opentherm/sensor/__init__.py +3 -3
  262. esphome/components/opentherm/switch/__init__.py +3 -5
  263. esphome/components/output/lock/__init__.py +11 -9
  264. esphome/components/packages/__init__.py +33 -31
  265. esphome/components/packet_transport/__init__.py +201 -0
  266. esphome/components/packet_transport/binary_sensor.py +19 -0
  267. esphome/components/packet_transport/packet_transport.cpp +534 -0
  268. esphome/components/packet_transport/packet_transport.h +154 -0
  269. esphome/components/packet_transport/sensor.py +19 -0
  270. esphome/components/pca9685/pca9685_output.cpp +2 -1
  271. esphome/components/pid/climate.py +2 -4
  272. esphome/components/pm2005/__init__.py +1 -0
  273. esphome/components/pm2005/pm2005.cpp +123 -0
  274. esphome/components/pm2005/pm2005.h +46 -0
  275. esphome/components/pm2005/sensor.py +86 -0
  276. esphome/components/pmsa003i/pmsa003i.cpp +43 -16
  277. esphome/components/pmsa003i/pmsa003i.h +25 -25
  278. esphome/components/pmsx003/pmsx003.cpp +193 -229
  279. esphome/components/pmsx003/pmsx003.h +51 -33
  280. esphome/components/pmsx003/sensor.py +21 -11
  281. esphome/components/pn7150/pn7150.h +2 -2
  282. esphome/components/pn7160/pn7160.h +2 -2
  283. esphome/components/prometheus/prometheus_handler.cpp +174 -0
  284. esphome/components/prometheus/prometheus_handler.h +17 -0
  285. esphome/components/psram/__init__.py +7 -5
  286. esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
  287. esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
  288. esphome/components/qspi_dbi/__init__.py +0 -1
  289. esphome/components/qspi_dbi/display.py +2 -1
  290. esphome/components/qspi_dbi/models.py +1 -2
  291. esphome/components/remote_base/__init__.py +91 -0
  292. esphome/components/remote_base/beo4_protocol.cpp +153 -0
  293. esphome/components/remote_base/beo4_protocol.h +43 -0
  294. esphome/components/remote_base/gobox_protocol.cpp +131 -0
  295. esphome/components/remote_base/gobox_protocol.h +54 -0
  296. esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
  297. esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
  298. esphome/components/resampler/speaker/resampler_speaker.h +1 -1
  299. esphome/components/scd30/sensor.py +2 -3
  300. esphome/components/scd4x/sensor.py +4 -5
  301. esphome/components/sdp3x/sensor.py +2 -1
  302. esphome/components/select/__init__.py +19 -20
  303. esphome/components/sen5x/sensor.py +1 -1
  304. esphome/components/sensor/__init__.py +158 -14
  305. esphome/components/sensor/filter.cpp +23 -0
  306. esphome/components/sensor/filter.h +22 -0
  307. esphome/components/sgp4x/sensor.py +1 -1
  308. esphome/components/sht4x/sht4x.cpp +43 -22
  309. esphome/components/sht4x/sht4x.h +1 -1
  310. esphome/components/sml/text_sensor/__init__.py +4 -6
  311. esphome/components/sound_level/__init__.py +0 -0
  312. esphome/components/sound_level/sensor.py +97 -0
  313. esphome/components/sound_level/sound_level.cpp +194 -0
  314. esphome/components/sound_level/sound_level.h +73 -0
  315. esphome/components/speaker/media_player/__init__.py +4 -8
  316. esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
  317. esphome/components/speaker/media_player/speaker_media_player.h +0 -11
  318. esphome/components/speaker/speaker.h +4 -7
  319. esphome/components/speed/fan/__init__.py +17 -16
  320. esphome/components/spi/spi.h +11 -1
  321. esphome/components/sprinkler/__init__.py +18 -19
  322. esphome/components/switch/__init__.py +32 -42
  323. esphome/components/syslog/__init__.py +41 -0
  324. esphome/components/syslog/esphome_syslog.cpp +49 -0
  325. esphome/components/syslog/esphome_syslog.h +27 -0
  326. esphome/components/tca9555/tca9555.cpp +11 -6
  327. esphome/components/tcl112/climate.py +2 -9
  328. esphome/components/template/alarm_control_panel/__init__.py +7 -6
  329. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
  330. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
  331. esphome/components/template/cover/__init__.py +27 -21
  332. esphome/components/template/fan/__init__.py +14 -12
  333. esphome/components/template/lock/__init__.py +20 -25
  334. esphome/components/template/lock/automation.h +18 -0
  335. esphome/components/template/text/__init__.py +4 -3
  336. esphome/components/template/valve/__init__.py +32 -21
  337. esphome/components/template/valve/automation.h +24 -0
  338. esphome/components/text/__init__.py +32 -1
  339. esphome/components/text_sensor/__init__.py +24 -29
  340. esphome/components/thermostat/climate.py +5 -5
  341. esphome/components/time_based/cover.py +17 -16
  342. esphome/components/tm1638/switch/__init__.py +10 -7
  343. esphome/components/tormatic/cover.py +4 -5
  344. esphome/components/toshiba/climate.py +3 -5
  345. esphome/components/touchscreen/touchscreen.cpp +3 -1
  346. esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
  347. esphome/components/tuya/climate/__init__.py +5 -6
  348. esphome/components/tuya/cover/__init__.py +6 -11
  349. esphome/components/tuya/select/__init__.py +15 -5
  350. esphome/components/tuya/select/tuya_select.cpp +6 -1
  351. esphome/components/tuya/select/tuya_select.h +5 -1
  352. esphome/components/uart/packet_transport/__init__.py +20 -0
  353. esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
  354. esphome/components/uart/packet_transport/uart_transport.h +41 -0
  355. esphome/components/udp/__init__.py +126 -128
  356. esphome/components/udp/automation.h +40 -0
  357. esphome/components/udp/binary_sensor.py +3 -25
  358. esphome/components/udp/packet_transport/__init__.py +29 -0
  359. esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
  360. esphome/components/udp/packet_transport/udp_transport.h +28 -0
  361. esphome/components/udp/sensor.py +3 -25
  362. esphome/components/udp/udp_component.cpp +26 -470
  363. esphome/components/udp/udp_component.h +21 -128
  364. esphome/components/update/__init__.py +31 -1
  365. esphome/components/uponor_smatrix/climate/__init__.py +4 -9
  366. esphome/components/uptime/text_sensor/__init__.py +47 -7
  367. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
  368. esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
  369. esphome/components/valve/__init__.py +34 -3
  370. esphome/components/valve/automation.h +1 -19
  371. esphome/components/vl53l0x/sensor.py +11 -0
  372. esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
  373. esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
  374. esphome/components/voice_assistant/__init__.py +36 -10
  375. esphome/components/voice_assistant/voice_assistant.cpp +170 -144
  376. esphome/components/voice_assistant/voice_assistant.h +26 -25
  377. esphome/components/waveshare_epaper/display.py +6 -0
  378. esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
  379. esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
  380. esphome/components/whirlpool/climate.py +3 -5
  381. esphome/components/whynter/climate.py +3 -5
  382. esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
  383. esphome/components/yashima/climate.py +6 -6
  384. esphome/components/zhlt01/climate.py +2 -7
  385. esphome/config_validation.py +38 -58
  386. esphome/const.py +15 -1
  387. esphome/core/__init__.py +2 -0
  388. esphome/core/application.cpp +1 -0
  389. esphome/core/application.h +4 -0
  390. esphome/core/automation.h +4 -3
  391. esphome/core/component.cpp +19 -3
  392. esphome/core/component.h +5 -0
  393. esphome/core/defines.h +23 -17
  394. esphome/core/macros.h +4 -0
  395. esphome/core/scheduler.cpp +3 -0
  396. esphome/cpp_generator.py +6 -2
  397. esphome/dashboard/web_server.py +3 -3
  398. esphome/helpers.py +39 -0
  399. esphome/loader.py +4 -0
  400. esphome/mqtt.py +21 -8
  401. esphome/platformio_api.py +1 -1
  402. esphome/schema_extractors.py +0 -1
  403. esphome/vscode.py +15 -0
  404. esphome/wizard.py +2 -2
  405. esphome/zeroconf.py +7 -3
  406. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/METADATA +10 -11
  407. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/RECORD +411 -352
  408. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/WHEEL +1 -1
  409. esphome/components/esp32_ble/const_esp32c6.h +0 -74
  410. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/entry_points.txt +0 -0
  411. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/licenses/LICENSE +0 -0
  412. {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/top_level.txt +0 -0
@@ -1,20 +1,13 @@
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
  AUTO_LOAD = ["climate_ir"]
7
5
 
8
6
  noblex_ns = cg.esphome_ns.namespace("noblex")
9
7
  NoblexClimate = noblex_ns.class_("NoblexClimate", climate_ir.ClimateIR)
10
8
 
11
- CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
12
- {
13
- cv.GenerateID(): cv.declare_id(NoblexClimate),
14
- }
15
- )
9
+ CONFIG_SCHEMA = climate_ir.climare_ir_with_receiver_schema(NoblexClimate)
16
10
 
17
11
 
18
12
  async def to_code(config):
19
- var = cg.new_Pvariable(config[CONF_ID])
20
- await climate_ir.register_climate_ir(var, config)
13
+ await climate_ir.new_climate_ir(config)
@@ -170,7 +170,7 @@ NUMBER_OPERATION_OPTIONS = {
170
170
  validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
171
171
  validate_unit_of_measurement = cv.string_strict
172
172
 
173
- NUMBER_SCHEMA = (
173
+ _NUMBER_SCHEMA = (
174
174
  cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
175
175
  .extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA)
176
176
  .extend(
@@ -196,16 +196,14 @@ NUMBER_SCHEMA = (
196
196
  )
197
197
  )
198
198
 
199
- _UNDEF = object()
200
-
201
199
 
202
200
  def number_schema(
203
201
  class_: MockObjClass,
204
202
  *,
205
- icon: str = _UNDEF,
206
- entity_category: str = _UNDEF,
207
- device_class: str = _UNDEF,
208
- unit_of_measurement: str = _UNDEF,
203
+ icon: str = cv.UNDEFINED,
204
+ entity_category: str = cv.UNDEFINED,
205
+ device_class: str = cv.UNDEFINED,
206
+ unit_of_measurement: str = cv.UNDEFINED,
209
207
  ) -> cv.Schema:
210
208
  schema = {cv.GenerateID(): cv.declare_id(class_)}
211
209
 
@@ -215,10 +213,15 @@ def number_schema(
215
213
  (CONF_DEVICE_CLASS, device_class, validate_device_class),
216
214
  (CONF_UNIT_OF_MEASUREMENT, unit_of_measurement, validate_unit_of_measurement),
217
215
  ]:
218
- if default is not _UNDEF:
216
+ if default is not cv.UNDEFINED:
219
217
  schema[cv.Optional(key, default=default)] = validator
220
218
 
221
- return NUMBER_SCHEMA.extend(schema)
219
+ return _NUMBER_SCHEMA.extend(schema)
220
+
221
+
222
+ # Remove before 2025.11.0
223
+ NUMBER_SCHEMA = number_schema(Number)
224
+ NUMBER_SCHEMA.add_extra(cv.deprecated_schema_constant("number"))
222
225
 
223
226
 
224
227
  async def setup_number_core_(
@@ -17,8 +17,15 @@ const uint8_t ONE_WIRE_ROM_SEARCH = 0xF0;
17
17
 
18
18
  const std::vector<uint64_t> &OneWireBus::get_devices() { return this->devices_; }
19
19
 
20
+ bool OneWireBus::reset_() {
21
+ int res = this->reset_int();
22
+ if (res == -1)
23
+ ESP_LOGE(TAG, "1-wire bus is held low");
24
+ return res == 1;
25
+ }
26
+
20
27
  bool IRAM_ATTR OneWireBus::select(uint64_t address) {
21
- if (!this->reset())
28
+ if (!this->reset_())
22
29
  return false;
23
30
  this->write8(ONE_WIRE_ROM_SELECT);
24
31
  this->write64(address);
@@ -31,16 +38,13 @@ void OneWireBus::search() {
31
38
  this->reset_search();
32
39
  uint64_t address;
33
40
  while (true) {
34
- {
35
- InterruptLock lock;
36
- if (!this->reset()) {
37
- // Reset failed or no devices present
38
- return;
39
- }
40
-
41
- this->write8(ONE_WIRE_ROM_SEARCH);
42
- address = this->search_int();
41
+ if (!this->reset_()) {
42
+ // Reset failed or no devices present
43
+ return;
43
44
  }
45
+
46
+ this->write8(ONE_WIRE_ROM_SEARCH);
47
+ address = this->search_int();
44
48
  if (address == 0)
45
49
  break;
46
50
  auto *address8 = reinterpret_cast<uint8_t *>(&address);
@@ -9,14 +9,6 @@ namespace one_wire {
9
9
 
10
10
  class OneWireBus {
11
11
  public:
12
- /** Reset the bus, should be done before all write operations.
13
- *
14
- * Takes approximately 1ms.
15
- *
16
- * @return Whether the operation was successful.
17
- */
18
- virtual bool reset() = 0;
19
-
20
12
  /// Write a word to the bus. LSB first.
21
13
  virtual void write8(uint8_t val) = 0;
22
14
 
@@ -50,6 +42,20 @@ class OneWireBus {
50
42
  /// log the found devices
51
43
  void dump_devices_(const char *tag);
52
44
 
45
+ /** Reset the bus, should be done before all write operations.
46
+ *
47
+ * Takes approximately 1ms.
48
+ *
49
+ * @return Whether the operation was successful.
50
+ */
51
+ bool reset_();
52
+
53
+ /**
54
+ * Bus Reset
55
+ * @return -1: signal fail, 0: no device detected, 1: device detected
56
+ */
57
+ virtual int reset_int() = 0;
58
+
53
59
  /// Reset the device search.
54
60
  virtual void reset_search() = 0;
55
61
 
@@ -62,6 +62,13 @@ int HOT BmpDecoder::decode(uint8_t *buffer, size_t size) {
62
62
  case 1:
63
63
  this->width_bytes_ = (this->width_ % 8 == 0) ? (this->width_ / 8) : (this->width_ / 8 + 1);
64
64
  break;
65
+ case 24:
66
+ this->width_bytes_ = this->width_ * 3;
67
+ if (this->width_bytes_ % 4 != 0) {
68
+ this->padding_bytes_ = 4 - (this->width_bytes_ % 4);
69
+ this->width_bytes_ += this->padding_bytes_;
70
+ }
71
+ break;
65
72
  default:
66
73
  ESP_LOGE(TAG, "Unsupported bits per pixel: %d", this->bits_per_pixel_);
67
74
  return DECODE_ERROR_UNSUPPORTED_FORMAT;
@@ -78,18 +85,48 @@ int HOT BmpDecoder::decode(uint8_t *buffer, size_t size) {
78
85
  this->current_index_ = this->data_offset_;
79
86
  index = this->data_offset_;
80
87
  }
81
- while (index < size) {
82
- size_t paint_index = this->current_index_ - this->data_offset_;
83
-
84
- uint8_t current_byte = buffer[index];
85
- for (uint8_t i = 0; i < 8; i++) {
86
- size_t x = (paint_index * 8) % this->width_ + i;
87
- size_t y = (this->height_ - 1) - (paint_index / this->width_bytes_);
88
- Color c = (current_byte & (1 << (7 - i))) ? display::COLOR_ON : display::COLOR_OFF;
89
- this->draw(x, y, 1, 1, c);
88
+ switch (this->bits_per_pixel_) {
89
+ case 1: {
90
+ while (index < size) {
91
+ uint8_t current_byte = buffer[index];
92
+ for (uint8_t i = 0; i < 8; i++) {
93
+ size_t x = (this->paint_index_ % this->width_) + i;
94
+ size_t y = (this->height_ - 1) - (this->paint_index_ / this->width_);
95
+ Color c = (current_byte & (1 << (7 - i))) ? display::COLOR_ON : display::COLOR_OFF;
96
+ this->draw(x, y, 1, 1, c);
97
+ }
98
+ this->paint_index_ += 8;
99
+ this->current_index_++;
100
+ index++;
101
+ }
102
+ break;
90
103
  }
91
- this->current_index_++;
92
- index++;
104
+ case 24: {
105
+ while (index < size) {
106
+ if (index + 2 >= size) {
107
+ this->decoded_bytes_ += index;
108
+ return index;
109
+ }
110
+ uint8_t b = buffer[index];
111
+ uint8_t g = buffer[index + 1];
112
+ uint8_t r = buffer[index + 2];
113
+ size_t x = this->paint_index_ % this->width_;
114
+ size_t y = (this->height_ - 1) - (this->paint_index_ / this->width_);
115
+ Color c = Color(r, g, b);
116
+ this->draw(x, y, 1, 1, c);
117
+ this->paint_index_++;
118
+ this->current_index_ += 3;
119
+ index += 3;
120
+ if (x == this->width_ - 1 && this->padding_bytes_ > 0) {
121
+ index += this->padding_bytes_;
122
+ this->current_index_ += this->padding_bytes_;
123
+ }
124
+ }
125
+ break;
126
+ }
127
+ default:
128
+ ESP_LOGE(TAG, "Unsupported bits per pixel: %d", this->bits_per_pixel_);
129
+ return DECODE_ERROR_UNSUPPORTED_FORMAT;
93
130
  }
94
131
  this->decoded_bytes_ += size;
95
132
  return size;
@@ -24,6 +24,7 @@ class BmpDecoder : public ImageDecoder {
24
24
 
25
25
  protected:
26
26
  size_t current_index_{0};
27
+ size_t paint_index_{0};
27
28
  ssize_t width_{0};
28
29
  ssize_t height_{0};
29
30
  uint16_t bits_per_pixel_{0};
@@ -32,6 +33,7 @@ class BmpDecoder : public ImageDecoder {
32
33
  uint32_t color_table_entries_{0};
33
34
  size_t width_bytes_{0};
34
35
  size_t data_offset_{0};
36
+ uint8_t padding_bytes_{0};
35
37
  };
36
38
 
37
39
  } // namespace online_image
@@ -11,10 +11,8 @@ COMPONENT_TYPE = const.BINARY_SENSOR
11
11
 
12
12
  def get_entity_validation_schema(entity: schema.BinarySensorSchema) -> cv.Schema:
13
13
  return binary_sensor.binary_sensor_schema(
14
- device_class=(
15
- entity.device_class or binary_sensor._UNDEF # pylint: disable=protected-access
16
- ),
17
- icon=(entity.icon or binary_sensor._UNDEF), # pylint: disable=protected-access
14
+ device_class=(entity.device_class or cv.UNDEFINED),
15
+ icon=(entity.icon or cv.UNDEFINED),
18
16
  )
19
17
 
20
18
 
@@ -3,13 +3,7 @@ from typing import Any
3
3
  import esphome.codegen as cg
4
4
  from esphome.components import number
5
5
  import esphome.config_validation as cv
6
- from esphome.const import (
7
- CONF_ID,
8
- CONF_INITIAL_VALUE,
9
- CONF_RESTORE_VALUE,
10
- CONF_STEP,
11
- CONF_UNIT_OF_MEASUREMENT,
12
- )
6
+ from esphome.const import CONF_INITIAL_VALUE, CONF_RESTORE_VALUE, CONF_STEP
13
7
 
14
8
  from .. import const, generate, input, schema, validate
15
9
 
@@ -22,33 +16,30 @@ OpenthermNumber = generate.opentherm_ns.class_(
22
16
 
23
17
 
24
18
  async def new_openthermnumber(config: dict[str, Any]) -> cg.Pvariable:
25
- var = cg.new_Pvariable(config[CONF_ID])
26
- await cg.register_component(var, config)
27
- await number.register_number(
28
- var,
19
+ var = await number.new_number(
29
20
  config,
30
21
  min_value=config[input.CONF_min_value],
31
22
  max_value=config[input.CONF_max_value],
32
23
  step=config[input.CONF_step],
33
24
  )
25
+ await cg.register_component(var, config)
34
26
  input.generate_setters(var, config)
35
27
 
36
- if CONF_INITIAL_VALUE in config:
37
- cg.add(var.set_initial_value(config[CONF_INITIAL_VALUE]))
38
- if CONF_RESTORE_VALUE in config:
39
- cg.add(var.set_restore_value(config[CONF_RESTORE_VALUE]))
28
+ if (initial_value := config.get(CONF_INITIAL_VALUE, None)) is not None:
29
+ cg.add(var.set_initial_value(initial_value))
30
+ if (restore_value := config.get(CONF_RESTORE_VALUE, None)) is not None:
31
+ cg.add(var.set_restore_value(restore_value))
40
32
 
41
33
  return var
42
34
 
43
35
 
44
36
  def get_entity_validation_schema(entity: schema.InputSchema) -> cv.Schema:
45
37
  return (
46
- number.NUMBER_SCHEMA.extend(
38
+ number.number_schema(
39
+ OpenthermNumber, unit_of_measurement=entity.unit_of_measurement
40
+ )
41
+ .extend(
47
42
  {
48
- cv.GenerateID(): cv.declare_id(OpenthermNumber),
49
- cv.Optional(
50
- CONF_UNIT_OF_MEASUREMENT, entity.unit_of_measurement
51
- ): cv.string_strict,
52
43
  cv.Optional(CONF_STEP, entity.step): cv.float_,
53
44
  cv.Optional(CONF_INITIAL_VALUE): cv.float_,
54
45
  cv.Optional(CONF_RESTORE_VALUE): cv.boolean,
@@ -23,10 +23,10 @@ MSG_DATA_TYPES = {
23
23
 
24
24
  def get_entity_validation_schema(entity: schema.SensorSchema) -> cv.Schema:
25
25
  return sensor.sensor_schema(
26
- unit_of_measurement=entity.unit_of_measurement or sensor._UNDEF, # pylint: disable=protected-access
26
+ unit_of_measurement=entity.unit_of_measurement or cv.UNDEFINED, # pylint: disable=protected-access
27
27
  accuracy_decimals=entity.accuracy_decimals,
28
- device_class=entity.device_class or sensor._UNDEF, # pylint: disable=protected-access
29
- icon=entity.icon or sensor._UNDEF, # pylint: disable=protected-access
28
+ device_class=entity.device_class or cv.UNDEFINED, # pylint: disable=protected-access
29
+ icon=entity.icon or cv.UNDEFINED, # pylint: disable=protected-access
30
30
  state_class=entity.state_class,
31
31
  ).extend(
32
32
  {
@@ -3,7 +3,6 @@ from typing import Any
3
3
  import esphome.codegen as cg
4
4
  from esphome.components import switch
5
5
  import esphome.config_validation as cv
6
- from esphome.const import CONF_ID
7
6
 
8
7
  from .. import const, generate, schema, validate
9
8
 
@@ -16,15 +15,14 @@ OpenthermSwitch = generate.opentherm_ns.class_(
16
15
 
17
16
 
18
17
  async def new_openthermswitch(config: dict[str, Any]) -> cg.Pvariable:
19
- var = cg.new_Pvariable(config[CONF_ID])
18
+ var = await switch.new_switch(config)
20
19
  await cg.register_component(var, config)
21
- await switch.register_switch(var, config)
22
20
  return var
23
21
 
24
22
 
25
23
  def get_entity_validation_schema(entity: schema.SwitchSchema) -> cv.Schema:
26
- return switch.SWITCH_SCHEMA.extend(
27
- {cv.GenerateID(): cv.declare_id(OpenthermSwitch)}
24
+ return switch.switch_schema(
25
+ OpenthermSwitch, default_restore_mode=entity.default_mode
28
26
  ).extend(cv.COMPONENT_SCHEMA)
29
27
 
30
28
 
@@ -1,24 +1,26 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import lock, output
3
3
  import esphome.config_validation as cv
4
- from esphome.const import CONF_ID, CONF_OUTPUT
4
+ from esphome.const import CONF_OUTPUT
5
5
 
6
6
  from .. import output_ns
7
7
 
8
8
  OutputLock = output_ns.class_("OutputLock", lock.Lock, cg.Component)
9
9
 
10
- CONFIG_SCHEMA = lock.LOCK_SCHEMA.extend(
11
- {
12
- cv.GenerateID(): cv.declare_id(OutputLock),
13
- cv.Required(CONF_OUTPUT): cv.use_id(output.BinaryOutput),
14
- }
15
- ).extend(cv.COMPONENT_SCHEMA)
10
+ CONFIG_SCHEMA = (
11
+ lock.lock_schema(OutputLock)
12
+ .extend(
13
+ {
14
+ cv.Required(CONF_OUTPUT): cv.use_id(output.BinaryOutput),
15
+ }
16
+ )
17
+ .extend(cv.COMPONENT_SCHEMA)
18
+ )
16
19
 
17
20
 
18
21
  async def to_code(config):
19
- var = cg.new_Pvariable(config[CONF_ID])
22
+ var = await lock.new_lock(config)
20
23
  await cg.register_component(var, config)
21
- await lock.register_lock(var, config)
22
24
 
23
25
  output_ = await cg.get_variable(config[CONF_OUTPUT])
24
26
  cg.add(var.set_output(output_))
@@ -24,22 +24,13 @@ DOMAIN = CONF_PACKAGES
24
24
 
25
25
 
26
26
  def validate_git_package(config: dict):
27
+ if CONF_URL not in config:
28
+ return config
29
+ config = BASE_SCHEMA(config)
27
30
  new_config = config
28
- for key, conf in config.items():
29
- if CONF_URL in conf:
30
- try:
31
- conf = BASE_SCHEMA(conf)
32
- if CONF_FILE in conf:
33
- new_config[key][CONF_FILES] = [conf[CONF_FILE]]
34
- del new_config[key][CONF_FILE]
35
- except cv.MultipleInvalid as e:
36
- with cv.prepend_path([key]):
37
- raise e
38
- except cv.Invalid as e:
39
- raise cv.Invalid(
40
- "Extra keys not allowed in git based package",
41
- path=[key] + e.path,
42
- ) from e
31
+ if CONF_FILE in config:
32
+ new_config[CONF_FILES] = [config[CONF_FILE]]
33
+ del new_config[CONF_FILE]
43
34
  return new_config
44
35
 
45
36
 
@@ -74,8 +65,8 @@ BASE_SCHEMA = cv.All(
74
65
  cv.Required(CONF_URL): cv.url,
75
66
  cv.Optional(CONF_USERNAME): cv.string,
76
67
  cv.Optional(CONF_PASSWORD): cv.string,
77
- cv.Exclusive(CONF_FILE, "files"): validate_yaml_filename,
78
- cv.Exclusive(CONF_FILES, "files"): cv.All(
68
+ cv.Exclusive(CONF_FILE, CONF_FILES): validate_yaml_filename,
69
+ cv.Exclusive(CONF_FILES, CONF_FILES): cv.All(
79
70
  cv.ensure_list(
80
71
  cv.Any(
81
72
  validate_yaml_filename,
@@ -100,14 +91,17 @@ BASE_SCHEMA = cv.All(
100
91
  cv.has_at_least_one_key(CONF_FILE, CONF_FILES),
101
92
  )
102
93
 
94
+ PACKAGE_SCHEMA = cv.All(
95
+ cv.Any(validate_source_shorthand, BASE_SCHEMA, dict), validate_git_package
96
+ )
103
97
 
104
- CONFIG_SCHEMA = cv.All(
98
+ CONFIG_SCHEMA = cv.Any(
105
99
  cv.Schema(
106
100
  {
107
- str: cv.Any(validate_source_shorthand, BASE_SCHEMA, dict),
101
+ str: PACKAGE_SCHEMA,
108
102
  }
109
103
  ),
110
- validate_git_package,
104
+ cv.ensure_list(PACKAGE_SCHEMA),
111
105
  )
112
106
 
113
107
 
@@ -183,25 +177,33 @@ def _process_base_package(config: dict) -> dict:
183
177
  return {"packages": packages}
184
178
 
185
179
 
180
+ def _process_package(package_config, config):
181
+ recursive_package = package_config
182
+ if CONF_URL in package_config:
183
+ package_config = _process_base_package(package_config)
184
+ if isinstance(package_config, dict):
185
+ recursive_package = do_packages_pass(package_config)
186
+ config = merge_config(recursive_package, config)
187
+ return config
188
+
189
+
186
190
  def do_packages_pass(config: dict):
187
191
  if CONF_PACKAGES not in config:
188
192
  return config
189
193
  packages = config[CONF_PACKAGES]
190
194
  with cv.prepend_path(CONF_PACKAGES):
191
195
  packages = CONFIG_SCHEMA(packages)
192
- if not isinstance(packages, dict):
196
+ if isinstance(packages, dict):
197
+ for package_name, package_config in reversed(packages.items()):
198
+ with cv.prepend_path(package_name):
199
+ config = _process_package(package_config, config)
200
+ elif isinstance(packages, list):
201
+ for package_config in reversed(packages):
202
+ config = _process_package(package_config, config)
203
+ else:
193
204
  raise cv.Invalid(
194
- f"Packages must be a key to value mapping, got {type(packages)} instead"
205
+ f"Packages must be a key to value mapping or list, got {type(packages)} instead"
195
206
  )
196
207
 
197
- for package_name, package_config in reversed(packages.items()):
198
- with cv.prepend_path(package_name):
199
- recursive_package = package_config
200
- if CONF_URL in package_config:
201
- package_config = _process_base_package(package_config)
202
- if isinstance(package_config, dict):
203
- recursive_package = do_packages_pass(package_config)
204
- config = merge_config(recursive_package, config)
205
-
206
208
  del config[CONF_PACKAGES]
207
209
  return config