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
@@ -5,7 +5,7 @@
5
5
  #include "esphome/core/component.h"
6
6
  #include "esphome/components/uart/uart.h"
7
7
  #include "esphome/components/sensor/sensor.h"
8
- #include <TinyGPS++.h>
8
+ #include <TinyGPSPlus.h>
9
9
 
10
10
  #include <vector>
11
11
 
@@ -27,12 +27,13 @@ class GPSListener {
27
27
 
28
28
  class GPS : public PollingComponent, public uart::UARTDevice {
29
29
  public:
30
- void set_latitude_sensor(sensor::Sensor *latitude_sensor) { latitude_sensor_ = latitude_sensor; }
31
- void set_longitude_sensor(sensor::Sensor *longitude_sensor) { longitude_sensor_ = longitude_sensor; }
32
- void set_speed_sensor(sensor::Sensor *speed_sensor) { speed_sensor_ = speed_sensor; }
33
- void set_course_sensor(sensor::Sensor *course_sensor) { course_sensor_ = course_sensor; }
34
- void set_altitude_sensor(sensor::Sensor *altitude_sensor) { altitude_sensor_ = altitude_sensor; }
35
- void set_satellites_sensor(sensor::Sensor *satellites_sensor) { satellites_sensor_ = satellites_sensor; }
30
+ void set_latitude_sensor(sensor::Sensor *latitude_sensor) { this->latitude_sensor_ = latitude_sensor; }
31
+ void set_longitude_sensor(sensor::Sensor *longitude_sensor) { this->longitude_sensor_ = longitude_sensor; }
32
+ void set_speed_sensor(sensor::Sensor *speed_sensor) { this->speed_sensor_ = speed_sensor; }
33
+ void set_course_sensor(sensor::Sensor *course_sensor) { this->course_sensor_ = course_sensor; }
34
+ void set_altitude_sensor(sensor::Sensor *altitude_sensor) { this->altitude_sensor_ = altitude_sensor; }
35
+ void set_satellites_sensor(sensor::Sensor *satellites_sensor) { this->satellites_sensor_ = satellites_sensor; }
36
+ void set_hdop_sensor(sensor::Sensor *hdop_sensor) { this->hdop_sensor_ = hdop_sensor; }
36
37
 
37
38
  void register_listener(GPSListener *listener) {
38
39
  listener->parent_ = this;
@@ -40,18 +41,20 @@ class GPS : public PollingComponent, public uart::UARTDevice {
40
41
  }
41
42
  float get_setup_priority() const override { return setup_priority::HARDWARE; }
42
43
 
44
+ void dump_config() override;
43
45
  void loop() override;
44
46
  void update() override;
45
47
 
46
48
  TinyGPSPlus &get_tiny_gps() { return this->tiny_gps_; }
47
49
 
48
50
  protected:
49
- float latitude_ = -1;
50
- float longitude_ = -1;
51
- float speed_ = -1;
52
- float course_ = -1;
53
- float altitude_ = -1;
54
- int satellites_ = -1;
51
+ float latitude_{NAN};
52
+ float longitude_{NAN};
53
+ float speed_{NAN};
54
+ float course_{NAN};
55
+ float altitude_{NAN};
56
+ uint16_t satellites_{0};
57
+ float hdop_{NAN};
55
58
 
56
59
  sensor::Sensor *latitude_sensor_{nullptr};
57
60
  sensor::Sensor *longitude_sensor_{nullptr};
@@ -59,6 +62,7 @@ class GPS : public PollingComponent, public uart::UARTDevice {
59
62
  sensor::Sensor *course_sensor_{nullptr};
60
63
  sensor::Sensor *altitude_sensor_{nullptr};
61
64
  sensor::Sensor *satellites_sensor_{nullptr};
65
+ sensor::Sensor *hdop_sensor_{nullptr};
62
66
 
63
67
  bool has_time_{false};
64
68
  TinyGPSPlus tiny_gps_;
@@ -5,6 +5,7 @@ import esphome.config_validation as cv
5
5
  from esphome.const import (
6
6
  CONF_BORDER,
7
7
  CONF_COLOR,
8
+ CONF_CONTINUOUS,
8
9
  CONF_DIRECTION,
9
10
  CONF_DURATION,
10
11
  CONF_HEIGHT,
@@ -61,8 +62,6 @@ VALUE_POSITION_TYPE = {
61
62
  "BELOW": ValuePositionType.VALUE_POSITION_TYPE_BELOW,
62
63
  }
63
64
 
64
- CONF_CONTINUOUS = "continuous"
65
-
66
65
  GRAPH_TRACE_SCHEMA = cv.Schema(
67
66
  {
68
67
  cv.GenerateID(): cv.declare_id(GraphTrace),
@@ -1,7 +1,7 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import climate_ir
3
3
  import esphome.config_validation as cv
4
- from esphome.const import CONF_ID, CONF_MODEL
4
+ from esphome.const import CONF_MODEL
5
5
 
6
6
  CODEOWNERS = ["@orestismers"]
7
7
 
@@ -18,18 +18,16 @@ MODELS = {
18
18
  "yac": Model.GREE_YAC,
19
19
  "yac1fb9": Model.GREE_YAC1FB9,
20
20
  "yx1ff": Model.GREE_YX1FF,
21
+ "yag": Model.GREE_YAG,
21
22
  }
22
23
 
23
- CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
24
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(GreeClimate).extend(
24
25
  {
25
- cv.GenerateID(): cv.declare_id(GreeClimate),
26
26
  cv.Required(CONF_MODEL): cv.enum(MODELS),
27
27
  }
28
28
  )
29
29
 
30
30
 
31
31
  async def to_code(config):
32
- var = cg.new_Pvariable(config[CONF_ID])
32
+ var = await climate_ir.new_climate_ir(config)
33
33
  cg.add(var.set_model(config[CONF_MODEL]))
34
-
35
- await climate_ir.register_climate_ir(var, config)
@@ -22,13 +22,21 @@ void GreeClimate::transmit_state() {
22
22
  remote_state[0] = this->fan_speed_() | this->operation_mode_();
23
23
  remote_state[1] = this->temperature_();
24
24
 
25
- if (this->model_ == GREE_YAN || this->model_ == GREE_YX1FF) {
25
+ if (this->model_ == GREE_YAN || this->model_ == GREE_YX1FF || this->model_ == GREE_YAG) {
26
26
  remote_state[2] = 0x60;
27
27
  remote_state[3] = 0x50;
28
28
  remote_state[4] = this->vertical_swing_();
29
29
  }
30
30
 
31
- if (this->model_ == GREE_YAC) {
31
+ if (this->model_ == GREE_YAG) {
32
+ remote_state[5] = 0x40;
33
+
34
+ if (this->vertical_swing_() == GREE_VDIR_SWING || this->horizontal_swing_() == GREE_HDIR_SWING) {
35
+ remote_state[0] |= (1 << 6);
36
+ }
37
+ }
38
+
39
+ if (this->model_ == GREE_YAC || this->model_ == GREE_YAG) {
32
40
  remote_state[4] |= (this->horizontal_swing_() << 4);
33
41
  }
34
42
 
@@ -57,6 +65,12 @@ void GreeClimate::transmit_state() {
57
65
  // Calculate the checksum
58
66
  if (this->model_ == GREE_YAN || this->model_ == GREE_YX1FF) {
59
67
  remote_state[7] = ((remote_state[0] << 4) + (remote_state[1] << 4) + 0xC0);
68
+ } else if (this->model_ == GREE_YAG) {
69
+ remote_state[7] =
70
+ ((((remote_state[0] & 0x0F) + (remote_state[1] & 0x0F) + (remote_state[2] & 0x0F) + (remote_state[3] & 0x0F) +
71
+ ((remote_state[4] & 0xF0) >> 4) + ((remote_state[5] & 0xF0) >> 4) + ((remote_state[6] & 0xF0) >> 4) + 0x0A) &
72
+ 0x0F)
73
+ << 4);
60
74
  } else {
61
75
  remote_state[7] =
62
76
  ((((remote_state[0] & 0x0F) + (remote_state[1] & 0x0F) + (remote_state[2] & 0x0F) + (remote_state[3] & 0x0F) +
@@ -58,7 +58,7 @@ const uint8_t GREE_VDIR_MIDDLE = 0x04;
58
58
  const uint8_t GREE_VDIR_MDOWN = 0x05;
59
59
  const uint8_t GREE_VDIR_DOWN = 0x06;
60
60
 
61
- // Only available on YAC
61
+ // Only available on YAC/YAG
62
62
  // Horizontal air directions. Note that these cannot be set on all heat pumps
63
63
  const uint8_t GREE_HDIR_AUTO = 0x00;
64
64
  const uint8_t GREE_HDIR_MANUAL = 0x00;
@@ -78,7 +78,7 @@ const uint8_t GREE_PRESET_SLEEP = 0x01;
78
78
  const uint8_t GREE_PRESET_SLEEP_BIT = 0x80;
79
79
 
80
80
  // Model codes
81
- enum Model { GREE_GENERIC, GREE_YAN, GREE_YAA, GREE_YAC, GREE_YAC1FB9, GREE_YX1FF };
81
+ enum Model { GREE_GENERIC, GREE_YAN, GREE_YAA, GREE_YAC, GREE_YAC1FB9, GREE_YX1FF, GREE_YAG };
82
82
 
83
83
  class GreeClimate : public climate_ir::ClimateIR {
84
84
  public:
@@ -1,5 +1,6 @@
1
1
  #include "growatt_solar.h"
2
2
  #include "esphome/core/log.h"
3
+ #include "esphome/core/application.h"
3
4
 
4
5
  namespace esphome {
5
6
  namespace growatt_solar {
@@ -18,7 +19,7 @@ void GrowattSolar::loop() {
18
19
 
19
20
  void GrowattSolar::update() {
20
21
  // If our last send has had no reply yet, and it wasn't that long ago, do nothing.
21
- uint32_t now = millis();
22
+ const uint32_t now = App.get_loop_component_start_time();
22
23
  if (now - this->last_send_ < this->get_update_interval() / 2) {
23
24
  return;
24
25
  }
@@ -30,6 +30,7 @@ from esphome.const import (
30
30
  CONF_VISUAL,
31
31
  CONF_WIFI,
32
32
  )
33
+ from esphome.cpp_generator import MockObjClass
33
34
  import esphome.final_validate as fv
34
35
 
35
36
  _LOGGER = logging.getLogger(__name__)
@@ -185,42 +186,46 @@ def validate_visual(config):
185
186
  return config
186
187
 
187
188
 
188
- BASE_CONFIG_SCHEMA = (
189
- climate.CLIMATE_SCHEMA.extend(
190
- {
191
- cv.Optional(CONF_SUPPORTED_MODES): cv.ensure_list(
192
- cv.enum(SUPPORTED_CLIMATE_MODES_OPTIONS, upper=True)
193
- ),
194
- cv.Optional(
195
- CONF_SUPPORTED_SWING_MODES,
196
- default=[
197
- "VERTICAL",
198
- "HORIZONTAL",
199
- "BOTH",
200
- ],
201
- ): cv.ensure_list(cv.enum(SUPPORTED_SWING_MODES_OPTIONS, upper=True)),
202
- cv.Optional(CONF_WIFI_SIGNAL, default=False): cv.boolean,
203
- cv.Optional(CONF_DISPLAY): cv.boolean,
204
- cv.Optional(
205
- CONF_ANSWER_TIMEOUT,
206
- ): cv.positive_time_period_milliseconds,
207
- cv.Optional(CONF_ON_STATUS_MESSAGE): automation.validate_automation(
208
- {
209
- cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StatusMessageTrigger),
210
- }
211
- ),
212
- }
189
+ def _base_config_schema(class_: MockObjClass) -> cv.Schema:
190
+ return (
191
+ climate.climate_schema(class_)
192
+ .extend(
193
+ {
194
+ cv.Optional(CONF_SUPPORTED_MODES): cv.ensure_list(
195
+ cv.enum(SUPPORTED_CLIMATE_MODES_OPTIONS, upper=True)
196
+ ),
197
+ cv.Optional(
198
+ CONF_SUPPORTED_SWING_MODES,
199
+ default=[
200
+ "VERTICAL",
201
+ "HORIZONTAL",
202
+ "BOTH",
203
+ ],
204
+ ): cv.ensure_list(cv.enum(SUPPORTED_SWING_MODES_OPTIONS, upper=True)),
205
+ cv.Optional(CONF_WIFI_SIGNAL, default=False): cv.boolean,
206
+ cv.Optional(CONF_DISPLAY): cv.boolean,
207
+ cv.Optional(
208
+ CONF_ANSWER_TIMEOUT,
209
+ ): cv.positive_time_period_milliseconds,
210
+ cv.Optional(CONF_ON_STATUS_MESSAGE): automation.validate_automation(
211
+ {
212
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
213
+ StatusMessageTrigger
214
+ ),
215
+ }
216
+ ),
217
+ }
218
+ )
219
+ .extend(uart.UART_DEVICE_SCHEMA)
220
+ .extend(cv.COMPONENT_SCHEMA)
213
221
  )
214
- .extend(uart.UART_DEVICE_SCHEMA)
215
- .extend(cv.COMPONENT_SCHEMA)
216
- )
222
+
217
223
 
218
224
  CONFIG_SCHEMA = cv.All(
219
225
  cv.typed_schema(
220
226
  {
221
- PROTOCOL_SMARTAIR2: BASE_CONFIG_SCHEMA.extend(
227
+ PROTOCOL_SMARTAIR2: _base_config_schema(Smartair2Climate).extend(
222
228
  {
223
- cv.GenerateID(): cv.declare_id(Smartair2Climate),
224
229
  cv.Optional(
225
230
  CONF_ALTERNATIVE_SWING_CONTROL, default=False
226
231
  ): cv.boolean,
@@ -232,9 +237,8 @@ CONFIG_SCHEMA = cv.All(
232
237
  ),
233
238
  }
234
239
  ),
235
- PROTOCOL_HON: BASE_CONFIG_SCHEMA.extend(
240
+ PROTOCOL_HON: _base_config_schema(HonClimate).extend(
236
241
  {
237
- cv.GenerateID(): cv.declare_id(HonClimate),
238
242
  cv.Optional(
239
243
  CONF_CONTROL_METHOD, default="SET_GROUP_PARAMETERS"
240
244
  ): cv.ensure_list(
@@ -464,10 +468,9 @@ FINAL_VALIDATE_SCHEMA = _final_validate
464
468
 
465
469
  async def to_code(config):
466
470
  cg.add(haier_ns.init_haier_protocol_logging())
467
- var = cg.new_Pvariable(config[CONF_ID])
471
+ var = await climate.new_climate(config)
468
472
  await cg.register_component(var, config)
469
473
  await uart.register_uart_device(var, config)
470
- await climate.register_climate(var, config)
471
474
 
472
475
  cg.add(var.set_send_wifi(config[CONF_WIFI_SIGNAL]))
473
476
  if CONF_CONTROL_METHOD in config:
@@ -30,25 +30,28 @@ DECAY_MODE_OPTIONS = {
30
30
  # Actions
31
31
  BrakeAction = hbridge_ns.class_("BrakeAction", automation.Action)
32
32
 
33
- CONFIG_SCHEMA = fan.FAN_SCHEMA.extend(
34
- {
35
- cv.GenerateID(CONF_ID): cv.declare_id(HBridgeFan),
36
- cv.Required(CONF_PIN_A): cv.use_id(output.FloatOutput),
37
- cv.Required(CONF_PIN_B): cv.use_id(output.FloatOutput),
38
- cv.Optional(CONF_DECAY_MODE, default="SLOW"): cv.enum(
39
- DECAY_MODE_OPTIONS, upper=True
40
- ),
41
- cv.Optional(CONF_SPEED_COUNT, default=100): cv.int_range(min=1),
42
- cv.Optional(CONF_ENABLE_PIN): cv.use_id(output.FloatOutput),
43
- cv.Optional(CONF_PRESET_MODES): validate_preset_modes,
44
- }
45
- ).extend(cv.COMPONENT_SCHEMA)
33
+ CONFIG_SCHEMA = (
34
+ fan.fan_schema(HBridgeFan)
35
+ .extend(
36
+ {
37
+ cv.Required(CONF_PIN_A): cv.use_id(output.FloatOutput),
38
+ cv.Required(CONF_PIN_B): cv.use_id(output.FloatOutput),
39
+ cv.Optional(CONF_DECAY_MODE, default="SLOW"): cv.enum(
40
+ DECAY_MODE_OPTIONS, upper=True
41
+ ),
42
+ cv.Optional(CONF_SPEED_COUNT, default=100): cv.int_range(min=1),
43
+ cv.Optional(CONF_ENABLE_PIN): cv.use_id(output.FloatOutput),
44
+ cv.Optional(CONF_PRESET_MODES): validate_preset_modes,
45
+ }
46
+ )
47
+ .extend(cv.COMPONENT_SCHEMA)
48
+ )
46
49
 
47
50
 
48
51
  @automation.register_action(
49
52
  "fan.hbridge.brake",
50
53
  BrakeAction,
51
- maybe_simple_id({cv.Required(CONF_ID): cv.use_id(HBridgeFan)}),
54
+ maybe_simple_id({cv.GenerateID(): cv.use_id(HBridgeFan)}),
52
55
  )
53
56
  async def fan_hbridge_brake_to_code(config, action_id, template_arg, args):
54
57
  paren = await cg.get_variable(config[CONF_ID])
@@ -56,13 +59,12 @@ async def fan_hbridge_brake_to_code(config, action_id, template_arg, args):
56
59
 
57
60
 
58
61
  async def to_code(config):
59
- var = cg.new_Pvariable(
60
- config[CONF_ID],
62
+ var = await fan.new_fan(
63
+ config,
61
64
  config[CONF_SPEED_COUNT],
62
65
  config[CONF_DECAY_MODE],
63
66
  )
64
67
  await cg.register_component(var, config)
65
- await fan.register_fan(var, config)
66
68
  pin_a_ = await cg.get_variable(config[CONF_PIN_A])
67
69
  cg.add(var.set_pin_a(pin_a_))
68
70
  pin_b_ = await cg.get_variable(config[CONF_PIN_B])
@@ -1,17 +1,17 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import cover, uart
3
3
  import esphome.config_validation as cv
4
- from esphome.const import CONF_CLOSE_DURATION, CONF_ID, CONF_OPEN_DURATION
4
+ from esphome.const import CONF_CLOSE_DURATION, CONF_OPEN_DURATION
5
5
 
6
6
  he60r_ns = cg.esphome_ns.namespace("he60r")
7
7
  HE60rCover = he60r_ns.class_("HE60rCover", cover.Cover, cg.Component)
8
8
 
9
9
  CONFIG_SCHEMA = (
10
- cover.COVER_SCHEMA.extend(uart.UART_DEVICE_SCHEMA)
10
+ cover.cover_schema(HE60rCover)
11
+ .extend(uart.UART_DEVICE_SCHEMA)
11
12
  .extend(cv.COMPONENT_SCHEMA)
12
13
  .extend(
13
14
  {
14
- cv.GenerateID(): cv.declare_id(HE60rCover),
15
15
  cv.Optional(
16
16
  CONF_OPEN_DURATION, default="15s"
17
17
  ): cv.positive_time_period_milliseconds,
@@ -34,9 +34,8 @@ FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
34
34
 
35
35
 
36
36
  async def to_code(config):
37
- var = cg.new_Pvariable(config[CONF_ID])
37
+ var = await cover.new_cover(config)
38
38
  await cg.register_component(var, config)
39
- await cover.register_cover(var, config)
40
39
  await uart.register_uart_device(var, config)
41
40
 
42
41
  cg.add(var.set_close_duration(config[CONF_CLOSE_DURATION]))
@@ -2,7 +2,6 @@ import esphome.codegen as cg
2
2
  from esphome.components import climate_ir
3
3
  import esphome.config_validation as cv
4
4
  from esphome.const import (
5
- CONF_ID,
6
5
  CONF_MAX_TEMPERATURE,
7
6
  CONF_MIN_TEMPERATURE,
8
7
  CONF_PROTOCOL,
@@ -98,9 +97,8 @@ VERTICAL_DIRECTIONS = {
98
97
  }
99
98
 
100
99
  CONFIG_SCHEMA = cv.All(
101
- climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
100
+ climate_ir.climate_ir_with_receiver_schema(HeatpumpIRClimate).extend(
102
101
  {
103
- cv.GenerateID(): cv.declare_id(HeatpumpIRClimate),
104
102
  cv.Required(CONF_PROTOCOL): cv.enum(PROTOCOLS),
105
103
  cv.Required(CONF_HORIZONTAL_DEFAULT): cv.enum(HORIZONTAL_DIRECTIONS),
106
104
  cv.Required(CONF_VERTICAL_DEFAULT): cv.enum(VERTICAL_DIRECTIONS),
@@ -112,8 +110,8 @@ CONFIG_SCHEMA = cv.All(
112
110
  )
113
111
 
114
112
 
115
- def to_code(config):
116
- var = cg.new_Pvariable(config[CONF_ID])
113
+ async def to_code(config):
114
+ var = await climate_ir.new_climate_ir(config)
117
115
  if CONF_VISUAL not in config:
118
116
  config[CONF_VISUAL] = {}
119
117
  visual = config[CONF_VISUAL]
@@ -121,7 +119,6 @@ def to_code(config):
121
119
  visual[CONF_MAX_TEMPERATURE] = config[CONF_MAX_TEMPERATURE]
122
120
  if CONF_MIN_TEMPERATURE not in visual:
123
121
  visual[CONF_MIN_TEMPERATURE] = config[CONF_MIN_TEMPERATURE]
124
- yield climate_ir.register_climate_ir(var, config)
125
122
  cg.add(var.set_protocol(config[CONF_PROTOCOL]))
126
123
  cg.add(var.set_horizontal_default(config[CONF_HORIZONTAL_DEFAULT]))
127
124
  cg.add(var.set_vertical_default(config[CONF_VERTICAL_DEFAULT]))
@@ -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
  hitachi_ac344_ns = cg.esphome_ns.namespace("hitachi_ac344")
9
7
  HitachiClimate = hitachi_ac344_ns.class_("HitachiClimate", climate_ir.ClimateIR)
10
8
 
11
- CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
12
- {
13
- cv.GenerateID(): cv.declare_id(HitachiClimate),
14
- }
15
- )
9
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(HitachiClimate)
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)
@@ -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
  hitachi_ac424_ns = cg.esphome_ns.namespace("hitachi_ac424")
9
7
  HitachiClimate = hitachi_ac424_ns.class_("HitachiClimate", climate_ir.ClimateIR)
10
8
 
11
- CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
12
- {
13
- cv.GenerateID(): cv.declare_id(HitachiClimate),
14
- }
15
- )
9
+ CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(HitachiClimate)
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)
@@ -8,7 +8,7 @@
8
8
  namespace esphome {
9
9
  namespace hm3301 {
10
10
 
11
- static const uint8_t SELECT_COMM_CMD = 0X88;
11
+ static const uint8_t SELECT_COMM_CMD = 0x88;
12
12
 
13
13
  class HM3301Component : public PollingComponent, public i2c::I2CDevice {
14
14
  public:
@@ -25,13 +25,13 @@ CONFIG_SCHEMA = (
25
25
  cv.Schema(
26
26
  {
27
27
  cv.GenerateID(): cv.declare_id(HTE501Component),
28
- cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(
28
+ cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
29
29
  unit_of_measurement=UNIT_CELSIUS,
30
30
  accuracy_decimals=1,
31
31
  device_class=DEVICE_CLASS_TEMPERATURE,
32
32
  state_class=STATE_CLASS_MEASUREMENT,
33
33
  ),
34
- cv.Required(CONF_HUMIDITY): sensor.sensor_schema(
34
+ cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
35
35
  unit_of_measurement=UNIT_PERCENT,
36
36
  accuracy_decimals=1,
37
37
  device_class=DEVICE_CLASS_HUMIDITY,
@@ -49,10 +49,10 @@ async def to_code(config):
49
49
  await cg.register_component(var, config)
50
50
  await i2c.register_i2c_device(var, config)
51
51
 
52
- if CONF_TEMPERATURE in config:
53
- sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
52
+ if temperature := config.get(CONF_TEMPERATURE):
53
+ sens = await sensor.new_sensor(temperature)
54
54
  cg.add(var.set_temperature_sensor(sens))
55
55
 
56
- if CONF_HUMIDITY in config:
57
- sens = await sensor.new_sensor(config[CONF_HUMIDITY])
56
+ if humidity := config.get(CONF_HUMIDITY):
57
+ sens = await sensor.new_sensor(humidity)
58
58
  cg.add(var.set_humidity_sensor(sens))
@@ -10,9 +10,11 @@ from esphome.const import (
10
10
  CONF_TIMEOUT,
11
11
  CONF_TRIGGER_ID,
12
12
  CONF_URL,
13
+ PLATFORM_HOST,
13
14
  __version__,
14
15
  )
15
16
  from esphome.core import CORE, Lambda
17
+ from esphome.helpers import IS_MACOS
16
18
 
17
19
  DEPENDENCIES = ["network"]
18
20
  AUTO_LOAD = ["json", "watchdog"]
@@ -21,6 +23,7 @@ http_request_ns = cg.esphome_ns.namespace("http_request")
21
23
  HttpRequestComponent = http_request_ns.class_("HttpRequestComponent", cg.Component)
22
24
  HttpRequestArduino = http_request_ns.class_("HttpRequestArduino", HttpRequestComponent)
23
25
  HttpRequestIDF = http_request_ns.class_("HttpRequestIDF", HttpRequestComponent)
26
+ HttpRequestHost = http_request_ns.class_("HttpRequestHost", HttpRequestComponent)
24
27
 
25
28
  HttpContainer = http_request_ns.class_("HttpContainer")
26
29
 
@@ -43,10 +46,13 @@ CONF_REDIRECT_LIMIT = "redirect_limit"
43
46
  CONF_WATCHDOG_TIMEOUT = "watchdog_timeout"
44
47
  CONF_BUFFER_SIZE_RX = "buffer_size_rx"
45
48
  CONF_BUFFER_SIZE_TX = "buffer_size_tx"
49
+ CONF_CA_CERTIFICATE_PATH = "ca_certificate_path"
46
50
 
47
51
  CONF_MAX_RESPONSE_BUFFER_SIZE = "max_response_buffer_size"
48
52
  CONF_ON_RESPONSE = "on_response"
49
53
  CONF_HEADERS = "headers"
54
+ CONF_REQUEST_HEADERS = "request_headers"
55
+ CONF_COLLECT_HEADERS = "collect_headers"
50
56
  CONF_BODY = "body"
51
57
  CONF_JSON = "json"
52
58
  CONF_CAPTURE_RESPONSE = "capture_response"
@@ -85,6 +91,8 @@ def validate_ssl_verification(config):
85
91
 
86
92
 
87
93
  def _declare_request_class(value):
94
+ if CORE.is_host:
95
+ return cv.declare_id(HttpRequestHost)(value)
88
96
  if CORE.using_esp_idf:
89
97
  return cv.declare_id(HttpRequestIDF)(value)
90
98
  if CORE.is_esp8266 or CORE.is_esp32 or CORE.is_rp2040:
@@ -119,6 +127,10 @@ CONFIG_SCHEMA = cv.All(
119
127
  cv.SplitDefault(CONF_BUFFER_SIZE_TX, esp32_idf=512): cv.All(
120
128
  cv.uint16_t, cv.only_with_esp_idf
121
129
  ),
130
+ cv.Optional(CONF_CA_CERTIFICATE_PATH): cv.All(
131
+ cv.file_,
132
+ cv.only_on(PLATFORM_HOST),
133
+ ),
122
134
  }
123
135
  ).extend(cv.COMPONENT_SCHEMA),
124
136
  cv.require_framework_version(
@@ -126,6 +138,7 @@ CONFIG_SCHEMA = cv.All(
126
138
  esp32_arduino=cv.Version(0, 0, 0),
127
139
  esp_idf=cv.Version(0, 0, 0),
128
140
  rp2040_arduino=cv.Version(0, 0, 0),
141
+ host=cv.Version(0, 0, 0),
129
142
  ),
130
143
  validate_ssl_verification,
131
144
  )
@@ -168,6 +181,21 @@ async def to_code(config):
168
181
  cg.add_library("ESP8266HTTPClient", None)
169
182
  if CORE.is_rp2040 and CORE.using_arduino:
170
183
  cg.add_library("HTTPClient", None)
184
+ if CORE.is_host:
185
+ if IS_MACOS:
186
+ cg.add_build_flag("-I/opt/homebrew/opt/openssl/include")
187
+ cg.add_build_flag("-L/opt/homebrew/opt/openssl/lib")
188
+ cg.add_build_flag("-lssl")
189
+ cg.add_build_flag("-lcrypto")
190
+ cg.add_build_flag("-Wl,-framework,CoreFoundation")
191
+ cg.add_build_flag("-Wl,-framework,Security")
192
+ cg.add_define("CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN")
193
+ cg.add_define("CPPHTTPLIB_OPENSSL_SUPPORT")
194
+ elif path := config.get(CONF_CA_CERTIFICATE_PATH):
195
+ cg.add_define("CPPHTTPLIB_OPENSSL_SUPPORT")
196
+ cg.add(var.set_ca_path(path))
197
+ cg.add_build_flag("-lssl")
198
+ cg.add_build_flag("-lcrypto")
171
199
 
172
200
  await cg.register_component(var, config)
173
201
 
@@ -176,9 +204,13 @@ HTTP_REQUEST_ACTION_SCHEMA = cv.Schema(
176
204
  {
177
205
  cv.GenerateID(): cv.use_id(HttpRequestComponent),
178
206
  cv.Required(CONF_URL): cv.templatable(validate_url),
179
- cv.Optional(CONF_HEADERS): cv.All(
207
+ cv.Optional(CONF_HEADERS): cv.invalid(
208
+ "The 'headers' options has been renamed to 'request_headers'"
209
+ ),
210
+ cv.Optional(CONF_REQUEST_HEADERS): cv.All(
180
211
  cv.Schema({cv.string: cv.templatable(cv.string)})
181
212
  ),
213
+ cv.Optional(CONF_COLLECT_HEADERS): cv.ensure_list(cv.string),
182
214
  cv.Optional(CONF_VERIFY_SSL): cv.invalid(
183
215
  f"{CONF_VERIFY_SSL} has moved to the base component configuration."
184
216
  ),
@@ -263,11 +295,12 @@ async def http_request_action_to_code(config, action_id, template_arg, args):
263
295
  for key in json_:
264
296
  template_ = await cg.templatable(json_[key], args, cg.std_string)
265
297
  cg.add(var.add_json(key, template_))
266
- for key in config.get(CONF_HEADERS, []):
267
- template_ = await cg.templatable(
268
- config[CONF_HEADERS][key], args, cg.const_char_ptr
269
- )
270
- cg.add(var.add_header(key, template_))
298
+ for key, value in config.get(CONF_REQUEST_HEADERS, {}).items():
299
+ template_ = await cg.templatable(value, args, cg.const_char_ptr)
300
+ cg.add(var.add_request_header(key, template_))
301
+
302
+ for value in config.get(CONF_COLLECT_HEADERS, []):
303
+ cg.add(var.add_collect_header(value))
271
304
 
272
305
  for conf in config.get(CONF_ON_RESPONSE, []):
273
306
  trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID])
@@ -20,5 +20,25 @@ void HttpRequestComponent::dump_config() {
20
20
  }
21
21
  }
22
22
 
23
+ std::string HttpContainer::get_response_header(const std::string &header_name) {
24
+ auto response_headers = this->get_response_headers();
25
+ auto header_name_lower_case = str_lower_case(header_name);
26
+ if (response_headers.count(header_name_lower_case) == 0) {
27
+ ESP_LOGW(TAG, "No header with name %s found", header_name_lower_case.c_str());
28
+ return "";
29
+ } else {
30
+ auto values = response_headers[header_name_lower_case];
31
+ if (values.empty()) {
32
+ ESP_LOGE(TAG, "header with name %s returned an empty list, this shouldn't happen",
33
+ header_name_lower_case.c_str());
34
+ return "";
35
+ } else {
36
+ auto header_value = values.front();
37
+ ESP_LOGD(TAG, "Header with name %s found with value %s", header_name_lower_case.c_str(), header_value.c_str());
38
+ return header_value;
39
+ }
40
+ }
41
+ }
42
+
23
43
  } // namespace http_request
24
44
  } // namespace esphome