esphome 2025.7.4__py3-none-any.whl → 2025.8.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 (758) hide show
  1. esphome/__main__.py +190 -83
  2. esphome/automation.py +2 -4
  3. esphome/build_gen/__init__.py +0 -0
  4. esphome/build_gen/platformio.py +102 -0
  5. esphome/components/a4988/a4988.cpp +0 -1
  6. esphome/components/absolute_humidity/absolute_humidity.cpp +0 -2
  7. esphome/components/absolute_humidity/sensor.py +2 -2
  8. esphome/components/adc/__init__.py +123 -85
  9. esphome/components/adc/adc_sensor.h +98 -35
  10. esphome/components/adc/adc_sensor_common.cpp +10 -4
  11. esphome/components/adc/adc_sensor_esp32.cpp +291 -123
  12. esphome/components/adc/adc_sensor_esp8266.cpp +1 -4
  13. esphome/components/adc/adc_sensor_libretiny.cpp +1 -2
  14. esphome/components/adc/adc_sensor_rp2040.cpp +1 -2
  15. esphome/components/adc/adc_sensor_zephyr.cpp +207 -0
  16. esphome/components/adc/sensor.py +61 -27
  17. esphome/components/adc128s102/adc128s102.cpp +1 -4
  18. esphome/components/ade7880/sensor.py +75 -49
  19. esphome/components/ads1115/ads1115.cpp +0 -1
  20. esphome/components/ads1118/ads1118.cpp +0 -1
  21. esphome/components/ags10/ags10.cpp +0 -4
  22. esphome/components/aht10/aht10.cpp +0 -4
  23. esphome/components/aic3204/aic3204.cpp +0 -2
  24. esphome/components/airthings_wave_plus/__init__.py +1 -1
  25. esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +22 -4
  26. esphome/components/airthings_wave_plus/airthings_wave_plus.h +10 -1
  27. esphome/components/airthings_wave_plus/sensor.py +55 -28
  28. esphome/components/alarm_control_panel/__init__.py +4 -9
  29. esphome/components/am2315c/am2315c.cpp +0 -2
  30. esphome/components/am2320/am2320.cpp +0 -1
  31. esphome/components/animation/__init__.py +14 -11
  32. esphome/components/apds9306/apds9306.cpp +0 -4
  33. esphome/components/apds9960/apds9960.cpp +0 -1
  34. esphome/components/api/__init__.py +29 -4
  35. esphome/components/api/api_connection.cpp +378 -401
  36. esphome/components/api/api_connection.h +112 -56
  37. esphome/components/api/api_frame_helper.cpp +69 -896
  38. esphome/components/api/api_frame_helper.h +31 -126
  39. esphome/components/api/api_frame_helper_noise.cpp +583 -0
  40. esphome/components/api/api_frame_helper_noise.h +68 -0
  41. esphome/components/api/api_frame_helper_plaintext.cpp +290 -0
  42. esphome/components/api/api_frame_helper_plaintext.h +53 -0
  43. esphome/components/api/api_noise_context.h +2 -4
  44. esphome/components/api/api_pb2.cpp +1601 -1808
  45. esphome/components/api/api_pb2.h +367 -323
  46. esphome/components/api/api_pb2_dump.cpp +1137 -3466
  47. esphome/components/api/api_pb2_includes.h +34 -0
  48. esphome/components/api/api_pb2_service.cpp +94 -105
  49. esphome/components/api/api_pb2_service.h +27 -16
  50. esphome/components/api/api_server.cpp +18 -17
  51. esphome/components/api/api_server.h +8 -5
  52. esphome/components/api/client.py +16 -8
  53. esphome/components/api/custom_api_device.h +68 -14
  54. esphome/components/api/homeassistant_service.h +24 -19
  55. esphome/components/api/list_entities.cpp +3 -5
  56. esphome/components/api/list_entities.h +2 -4
  57. esphome/components/api/proto.cpp +3 -5
  58. esphome/components/api/proto.h +239 -274
  59. esphome/components/api/subscribe_state.cpp +2 -4
  60. esphome/components/api/subscribe_state.h +2 -4
  61. esphome/components/api/user_services.cpp +2 -4
  62. esphome/components/api/user_services.h +8 -8
  63. esphome/components/as3935/as3935.cpp +0 -2
  64. esphome/components/as3935_spi/as3935_spi.cpp +0 -2
  65. esphome/components/as5600/__init__.py +1 -1
  66. esphome/components/as5600/as5600.cpp +0 -2
  67. esphome/components/as5600/sensor/__init__.py +0 -1
  68. esphome/components/as7341/as7341.cpp +0 -1
  69. esphome/components/async_tcp/__init__.py +1 -1
  70. esphome/components/at581x/at581x.cpp +1 -1
  71. esphome/components/atm90e26/atm90e26.cpp +0 -1
  72. esphome/components/atm90e32/atm90e32.cpp +475 -116
  73. esphome/components/atm90e32/atm90e32.h +43 -5
  74. esphome/components/audio/audio.h +2 -2
  75. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +0 -2
  76. esphome/components/beken_spi_led_strip/led_strip.cpp +0 -2
  77. esphome/components/bh1750/bh1750.cpp +0 -1
  78. esphome/components/binary_sensor/__init__.py +14 -12
  79. esphome/components/ble_client/__init__.py +4 -7
  80. esphome/components/bluetooth_proxy/__init__.py +40 -3
  81. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +392 -81
  82. esphome/components/bluetooth_proxy/bluetooth_connection.h +16 -5
  83. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +102 -311
  84. esphome/components/bluetooth_proxy/bluetooth_proxy.h +30 -14
  85. esphome/components/bme280_base/bme280_base.cpp +15 -16
  86. esphome/components/bme680/bme680.cpp +2 -3
  87. esphome/components/bme680_bsec/bme680_bsec.cpp +0 -2
  88. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +0 -2
  89. esphome/components/bmi160/bmi160.cpp +0 -1
  90. esphome/components/bmp085/bmp085.cpp +0 -1
  91. esphome/components/bmp280_base/bmp280_base.cpp +13 -14
  92. esphome/components/bmp3xx_base/bmp3xx_base.cpp +0 -1
  93. esphome/components/bmp581/bmp581.cpp +0 -2
  94. esphome/components/bp1658cj/bp1658cj.cpp +0 -1
  95. esphome/components/bp5758d/bp5758d.cpp +0 -1
  96. esphome/components/button/__init__.py +0 -1
  97. esphome/components/canbus/__init__.py +2 -3
  98. esphome/components/canbus/canbus.cpp +0 -1
  99. esphome/components/cap1188/cap1188.cpp +0 -2
  100. esphome/components/captive_portal/__init__.py +1 -1
  101. esphome/components/cd74hc4067/cd74hc4067.cpp +0 -2
  102. esphome/components/ch422g/ch422g.cpp +0 -1
  103. esphome/components/chsc6x/chsc6x_touchscreen.cpp +0 -3
  104. esphome/components/climate/__init__.py +0 -1
  105. esphome/components/climate/climate_traits.h +24 -0
  106. esphome/components/cm1106/cm1106.cpp +0 -1
  107. esphome/components/const/__init__.py +6 -0
  108. esphome/components/cover/__init__.py +0 -1
  109. esphome/components/cover/cover.cpp +9 -13
  110. esphome/components/cs5460a/cs5460a.cpp +0 -2
  111. esphome/components/cse7761/cse7761.cpp +0 -1
  112. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +0 -2
  113. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +0 -2
  114. esphome/components/dac7678/dac7678_output.cpp +0 -2
  115. esphome/components/dallas_temp/dallas_temp.cpp +0 -1
  116. esphome/components/datetime/__init__.py +0 -2
  117. esphome/components/debug/__init__.py +15 -1
  118. esphome/components/debug/debug_zephyr.cpp +281 -0
  119. esphome/components/debug/sensor.py +2 -1
  120. esphome/components/deep_sleep/deep_sleep_component.cpp +0 -1
  121. esphome/components/deep_sleep/deep_sleep_esp32.cpp +20 -1
  122. esphome/components/dfrobot_sen0395/__init__.py +1 -2
  123. esphome/components/dht/dht.cpp +0 -1
  124. esphome/components/dht12/dht12.cpp +0 -1
  125. esphome/components/display/__init__.py +16 -3
  126. esphome/components/display_menu_base/__init__.py +1 -1
  127. esphome/components/dps310/dps310.cpp +0 -2
  128. esphome/components/ds1307/ds1307.cpp +0 -1
  129. esphome/components/ds2484/ds2484.cpp +0 -1
  130. esphome/components/duty_cycle/duty_cycle_sensor.cpp +0 -1
  131. esphome/components/ee895/ee895.cpp +0 -1
  132. esphome/components/ektf2232/touchscreen/ektf2232.cpp +0 -1
  133. esphome/components/emc2101/emc2101.cpp +0 -2
  134. esphome/components/ens160_base/ens160_base.cpp +0 -2
  135. esphome/components/ens210/ens210.cpp +0 -1
  136. esphome/components/es7210/es7210.cpp +0 -2
  137. esphome/components/es7243e/es7243e.cpp +0 -2
  138. esphome/components/es8156/es8156.cpp +0 -2
  139. esphome/components/es8311/es8311.cpp +0 -2
  140. esphome/components/es8388/es8388.cpp +0 -2
  141. esphome/components/esp32/__init__.py +203 -60
  142. esphome/components/esp32/boards.py +17 -0
  143. esphome/components/esp32/gpio.cpp +0 -1
  144. esphome/components/esp32/gpio.py +1 -2
  145. esphome/components/esp32/gpio_esp32_h2.py +2 -7
  146. esphome/components/esp32/gpio_esp32_p4.py +2 -7
  147. esphome/components/esp32/post_build.py.script +112 -61
  148. esphome/components/esp32_ble/__init__.py +41 -2
  149. esphome/components/esp32_ble/ble.cpp +14 -10
  150. esphome/components/esp32_ble/ble.h +18 -18
  151. esphome/components/esp32_ble/ble_advertising.cpp +5 -5
  152. esphome/components/esp32_ble/ble_advertising.h +7 -5
  153. esphome/components/esp32_ble/ble_event.h +139 -73
  154. esphome/components/esp32_ble/ble_scan_result.h +2 -4
  155. esphome/components/esp32_ble/ble_uuid.cpp +5 -5
  156. esphome/components/esp32_ble/ble_uuid.h +6 -5
  157. esphome/components/esp32_ble_beacon/__init__.py +4 -0
  158. esphome/components/esp32_ble_client/__init__.py +1 -1
  159. esphome/components/esp32_ble_client/ble_characteristic.cpp +4 -4
  160. esphome/components/esp32_ble_client/ble_characteristic.h +6 -4
  161. esphome/components/esp32_ble_client/ble_client_base.cpp +155 -104
  162. esphome/components/esp32_ble_client/ble_client_base.h +17 -6
  163. esphome/components/esp32_ble_client/ble_descriptor.h +6 -4
  164. esphome/components/esp32_ble_client/ble_service.cpp +4 -4
  165. esphome/components/esp32_ble_client/ble_service.h +6 -4
  166. esphome/components/esp32_ble_server/__init__.py +15 -12
  167. esphome/components/esp32_ble_tracker/__init__.py +79 -11
  168. esphome/components/esp32_ble_tracker/automation.h +4 -4
  169. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +264 -261
  170. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +103 -37
  171. esphome/components/esp32_camera/__init__.py +13 -1
  172. esphome/components/esp32_camera/esp32_camera.cpp +7 -2
  173. esphome/components/esp32_camera/esp32_camera.h +1 -0
  174. esphome/components/esp32_dac/esp32_dac.cpp +3 -19
  175. esphome/components/esp32_dac/esp32_dac.h +4 -8
  176. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -6
  177. esphome/components/esp32_rmt_led_strip/light.py +1 -1
  178. esphome/components/esp32_touch/__init__.py +2 -3
  179. esphome/components/esp32_touch/esp32_touch.h +9 -6
  180. esphome/components/esp32_touch/esp32_touch_common.cpp +2 -0
  181. esphome/components/esp32_touch/esp32_touch_v1.cpp +7 -9
  182. esphome/components/esp32_touch/esp32_touch_v2.cpp +10 -6
  183. esphome/components/esp8266/__init__.py +3 -1
  184. esphome/components/esp8266_pwm/esp8266_pwm.cpp +0 -1
  185. esphome/components/esphome/ota/__init__.py +1 -2
  186. esphome/components/esphome/ota/ota_esphome.cpp +150 -77
  187. esphome/components/esphome/ota/ota_esphome.h +8 -1
  188. esphome/components/espnow/__init__.py +309 -0
  189. esphome/components/espnow/automation.h +175 -0
  190. esphome/components/espnow/espnow_component.cpp +468 -0
  191. esphome/components/espnow/espnow_component.h +183 -0
  192. esphome/components/espnow/espnow_err.h +19 -0
  193. esphome/components/espnow/espnow_packet.h +166 -0
  194. esphome/components/ethernet/__init__.py +7 -1
  195. esphome/components/ethernet/esp_eth_phy_jl1101.c +5 -0
  196. esphome/components/ethernet/ethernet_component.cpp +0 -1
  197. esphome/components/ethernet/ethernet_component.h +4 -0
  198. esphome/components/ethernet_info/ethernet_info_text_sensor.h +0 -3
  199. esphome/components/event/__init__.py +0 -1
  200. esphome/components/factory_reset/__init__.py +92 -0
  201. esphome/components/factory_reset/factory_reset.cpp +76 -0
  202. esphome/components/factory_reset/factory_reset.h +43 -0
  203. esphome/components/fan/__init__.py +0 -1
  204. esphome/components/fan/fan_traits.h +16 -0
  205. esphome/components/fastled_base/fastled_light.cpp +0 -1
  206. esphome/components/fastled_spi/light.py +1 -3
  207. esphome/components/fingerprint_grow/fingerprint_grow.cpp +0 -2
  208. esphome/components/font/__init__.py +9 -1
  209. esphome/components/fs3000/fs3000.cpp +0 -2
  210. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
  211. esphome/components/ft63x6/ft63x6.cpp +0 -1
  212. esphome/components/gdk101/gdk101.cpp +0 -1
  213. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
  214. esphome/components/gl_r01_i2c/sensor.py +1 -1
  215. esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
  216. esphome/components/gpio/switch/gpio_switch.cpp +0 -2
  217. esphome/components/gpio_expander/cached_gpio.h +24 -15
  218. esphome/components/gps/__init__.py +6 -2
  219. esphome/components/gps/gps.cpp +50 -49
  220. esphome/components/gps/gps.h +4 -8
  221. esphome/components/gps/time/gps_time.cpp +3 -9
  222. esphome/components/gps/time/gps_time.h +4 -7
  223. esphome/components/graph/__init__.py +1 -1
  224. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
  225. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
  227. esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
  228. esphome/components/haier/climate.py +5 -10
  229. esphome/components/haier/haier_base.cpp +0 -1
  230. esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
  231. esphome/components/hdc1080/hdc1080.cpp +0 -2
  232. esphome/components/heatpumpir/climate.py +2 -2
  233. esphome/components/hlw8012/hlw8012.cpp +0 -1
  234. esphome/components/hm3301/hm3301.cpp +0 -1
  235. esphome/components/hmc5883l/hmc5883l.cpp +0 -1
  236. esphome/components/homeassistant/__init__.py +1 -0
  237. esphome/components/homeassistant/number/__init__.py +1 -0
  238. esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
  239. esphome/components/homeassistant/switch/__init__.py +1 -0
  240. esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
  241. esphome/components/honeywellabp/honeywellabp.cpp +1 -4
  242. esphome/components/host/__init__.py +2 -0
  243. esphome/components/hte501/hte501.cpp +0 -1
  244. esphome/components/http_request/__init__.py +2 -3
  245. esphome/components/http_request/http_request_idf.cpp +2 -2
  246. esphome/components/htu21d/htu21d.cpp +0 -2
  247. esphome/components/htu31d/htu31d.cpp +0 -2
  248. esphome/components/hx711/hx711.cpp +0 -1
  249. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
  250. esphome/components/hydreon_rgxx/sensor.py +4 -5
  251. esphome/components/i2c/i2c_bus.h +1 -1
  252. esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
  253. esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
  254. esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
  255. esphome/components/i2s_audio/__init__.py +6 -5
  256. esphome/components/i2s_audio/i2s_audio.cpp +0 -2
  257. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
  258. esphome/components/i2s_audio/microphone/__init__.py +4 -6
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +46 -19
  260. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +4 -3
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
  262. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
  263. esphome/components/ili9xxx/display.py +4 -3
  264. esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
  265. esphome/components/image/__init__.py +123 -92
  266. esphome/components/improv_serial/__init__.py +7 -8
  267. esphome/components/ina219/ina219.cpp +0 -1
  268. esphome/components/ina226/ina226.cpp +0 -2
  269. esphome/components/ina260/ina260.cpp +0 -2
  270. esphome/components/ina2xx_base/__init__.py +2 -5
  271. esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
  272. esphome/components/ina3221/ina3221.cpp +0 -1
  273. esphome/components/internal_temperature/internal_temperature.cpp +0 -2
  274. esphome/components/interval/interval.h +5 -9
  275. esphome/components/json/__init__.py +1 -1
  276. esphome/components/kmeteriso/kmeteriso.cpp +0 -2
  277. esphome/components/lc709203f/lc709203f.cpp +0 -2
  278. esphome/components/lcd_gpio/display.py +1 -3
  279. esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
  280. esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
  281. esphome/components/ld2410/__init__.py +4 -6
  282. esphome/components/ld2410/binary_sensor.py +4 -0
  283. esphome/components/ld2410/ld2410.cpp +56 -100
  284. esphome/components/ld2410/ld2410.h +17 -15
  285. esphome/components/ld2410/sensor.py +24 -10
  286. esphome/components/ld2412/__init__.py +46 -0
  287. esphome/components/ld2412/binary_sensor.py +70 -0
  288. esphome/components/ld2412/button/__init__.py +74 -0
  289. esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
  290. esphome/components/ld2412/button/factory_reset_button.h +18 -0
  291. esphome/components/ld2412/button/query_button.cpp +9 -0
  292. esphome/components/ld2412/button/query_button.h +18 -0
  293. esphome/components/ld2412/button/restart_button.cpp +9 -0
  294. esphome/components/ld2412/button/restart_button.h +18 -0
  295. esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
  296. esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
  297. esphome/components/ld2412/ld2412.cpp +861 -0
  298. esphome/components/ld2412/ld2412.h +141 -0
  299. esphome/components/ld2412/number/__init__.py +126 -0
  300. esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
  301. esphome/components/ld2412/number/gate_threshold_number.h +19 -0
  302. esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
  303. esphome/components/ld2412/number/light_threshold_number.h +18 -0
  304. esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
  305. esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
  306. esphome/components/ld2412/select/__init__.py +82 -0
  307. esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
  308. esphome/components/ld2412/select/baud_rate_select.h +18 -0
  309. esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
  310. esphome/components/ld2412/select/distance_resolution_select.h +18 -0
  311. esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
  312. esphome/components/ld2412/select/light_out_control_select.h +18 -0
  313. esphome/components/ld2412/sensor.py +124 -0
  314. esphome/components/ld2412/switch/__init__.py +45 -0
  315. esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
  316. esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
  317. esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
  318. esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
  319. esphome/components/ld2412/text_sensor.py +34 -0
  320. esphome/components/ld2420/ld2420.cpp +0 -1
  321. esphome/components/ld2450/__init__.py +3 -4
  322. esphome/components/ld2450/binary_sensor.py +3 -0
  323. esphome/components/ld2450/ld2450.cpp +77 -165
  324. esphome/components/ld2450/ld2450.h +26 -54
  325. esphome/components/ld2450/sensor.py +120 -6
  326. esphome/components/ld2450/text_sensor.py +5 -4
  327. esphome/components/ld24xx/__init__.py +1 -0
  328. esphome/components/ld24xx/ld24xx.h +65 -0
  329. esphome/components/ledc/ledc_output.cpp +0 -1
  330. esphome/components/libretiny/__init__.py +2 -0
  331. esphome/components/light/__init__.py +0 -1
  332. esphome/components/light/effects.py +70 -45
  333. esphome/components/light/light_call.cpp +101 -66
  334. esphome/components/light/light_color_values.h +16 -11
  335. esphome/components/light/light_json_schema.cpp +46 -44
  336. esphome/components/light/light_state.cpp +8 -11
  337. esphome/components/light/light_traits.h +17 -0
  338. esphome/components/lightwaverf/lightwaverf.cpp +0 -2
  339. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
  340. esphome/components/lock/__init__.py +0 -1
  341. esphome/components/logger/__init__.py +31 -9
  342. esphome/components/logger/logger.cpp +12 -7
  343. esphome/components/logger/logger.h +25 -14
  344. esphome/components/logger/logger_esp32.cpp +2 -7
  345. esphome/components/logger/logger_esp8266.cpp +2 -4
  346. esphome/components/logger/logger_host.cpp +2 -4
  347. esphome/components/logger/logger_libretiny.cpp +2 -4
  348. esphome/components/logger/logger_rp2040.cpp +2 -4
  349. esphome/components/logger/logger_zephyr.cpp +86 -0
  350. esphome/components/logger/select/logger_level_select.cpp +2 -4
  351. esphome/components/logger/select/logger_level_select.h +2 -4
  352. esphome/components/logger/task_log_buffer.cpp +2 -4
  353. esphome/components/logger/task_log_buffer.h +2 -4
  354. esphome/components/lps22/sensor.py +5 -5
  355. esphome/components/ltr390/ltr390.cpp +0 -2
  356. esphome/components/ltr501/ltr501.cpp +0 -1
  357. esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
  358. esphome/components/lvgl/__init__.py +14 -13
  359. esphome/components/lvgl/automation.py +2 -4
  360. esphome/components/lvgl/defines.py +0 -2
  361. esphome/components/lvgl/helpers.py +1 -1
  362. esphome/components/lvgl/lv_validation.py +7 -4
  363. esphome/components/lvgl/lvgl_esphome.cpp +2 -3
  364. esphome/components/lvgl/styles.py +2 -2
  365. esphome/components/lvgl/types.py +1 -1
  366. esphome/components/lvgl/widgets/__init__.py +2 -2
  367. esphome/components/lvgl/widgets/arc.py +14 -11
  368. esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
  369. esphome/components/lvgl/widgets/qrcode.py +7 -7
  370. esphome/components/lvgl/widgets/spinner.py +6 -6
  371. esphome/components/lvgl/widgets/switch.py +2 -2
  372. esphome/components/lvgl/widgets/tabview.py +3 -3
  373. esphome/components/lvgl/widgets/tileview.py +15 -7
  374. esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
  375. esphome/components/matrix_keypad/__init__.py +4 -3
  376. esphome/components/max17043/max17043.cpp +0 -2
  377. esphome/components/max31855/max31855.cpp +1 -4
  378. esphome/components/max31856/max31856.cpp +0 -4
  379. esphome/components/max31865/max31865.cpp +0 -1
  380. esphome/components/max44009/max44009.cpp +0 -1
  381. esphome/components/max6675/max6675.cpp +1 -4
  382. esphome/components/max6956/max6956.cpp +0 -1
  383. esphome/components/max7219/max7219.cpp +0 -1
  384. esphome/components/max7219digit/display.py +1 -1
  385. esphome/components/max7219digit/max7219digit.cpp +0 -1
  386. esphome/components/max9611/max9611.cpp +0 -1
  387. esphome/components/mcp23008/__init__.py +1 -1
  388. esphome/components/mcp23008/mcp23008.cpp +0 -1
  389. esphome/components/mcp23016/mcp23016.cpp +0 -1
  390. esphome/components/mcp23017/__init__.py +1 -1
  391. esphome/components/mcp23017/mcp23017.cpp +0 -1
  392. esphome/components/mcp23s08/__init__.py +1 -1
  393. esphome/components/mcp23s08/mcp23s08.cpp +0 -1
  394. esphome/components/mcp23s17/__init__.py +1 -1
  395. esphome/components/mcp23s17/mcp23s17.cpp +0 -1
  396. esphome/components/mcp23x08_base/__init__.py +2 -0
  397. esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
  398. esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
  399. esphome/components/mcp23x17_base/__init__.py +2 -0
  400. esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
  401. esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
  402. esphome/components/mcp23xxx_base/__init__.py +11 -5
  403. esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
  404. esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
  405. esphome/components/mcp3008/mcp3008.cpp +1 -4
  406. esphome/components/mcp3204/mcp3204.cpp +1 -4
  407. esphome/components/mcp4461/mcp4461.cpp +0 -1
  408. esphome/components/mcp4725/mcp4725.cpp +0 -1
  409. esphome/components/mcp4728/mcp4728.cpp +0 -1
  410. esphome/components/mcp9600/mcp9600.cpp +0 -2
  411. esphome/components/mcp9808/mcp9808.cpp +0 -2
  412. esphome/components/mdns/__init__.py +3 -0
  413. esphome/components/mdns/mdns_component.cpp +2 -0
  414. esphome/components/mdns/mdns_component.h +4 -0
  415. esphome/components/media_player/__init__.py +40 -0
  416. esphome/components/media_player/automation.h +16 -0
  417. esphome/components/media_player/media_player.cpp +13 -0
  418. esphome/components/media_player/media_player.h +50 -3
  419. esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
  420. esphome/components/mics_4514/mics_4514.cpp +1 -6
  421. esphome/components/midea/ir_transmitter.h +4 -4
  422. esphome/components/mipi/__init__.py +416 -0
  423. esphome/components/mipi_dsi/__init__.py +5 -0
  424. esphome/components/mipi_dsi/display.py +233 -0
  425. esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
  426. esphome/components/mipi_dsi/mipi_dsi.h +123 -0
  427. esphome/components/mipi_dsi/models/__init__.py +0 -0
  428. esphome/components/mipi_dsi/models/guition.py +38 -0
  429. esphome/components/mipi_dsi/models/m5stack.py +57 -0
  430. esphome/components/mipi_dsi/models/waveshare.py +105 -0
  431. esphome/components/mipi_rgb/models/lilygo.py +0 -0
  432. esphome/components/mipi_spi/__init__.py +0 -9
  433. esphome/components/mipi_spi/display.py +220 -256
  434. esphome/components/mipi_spi/mipi_spi.cpp +1 -485
  435. esphome/components/mipi_spi/mipi_spi.h +556 -108
  436. esphome/components/mipi_spi/models/__init__.py +0 -65
  437. esphome/components/mipi_spi/models/adafruit.py +30 -0
  438. esphome/components/mipi_spi/models/amoled.py +41 -5
  439. esphome/components/mipi_spi/models/ili.py +5 -5
  440. esphome/components/mipi_spi/models/jc.py +1 -3
  441. esphome/components/mipi_spi/models/lilygo.py +1 -1
  442. esphome/components/mipi_spi/models/waveshare.py +16 -1
  443. esphome/components/mixer/speaker/__init__.py +4 -5
  444. esphome/components/mlx90393/sensor.py +7 -5
  445. esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
  446. esphome/components/mlx90614/mlx90614.cpp +0 -1
  447. esphome/components/mmc5603/mmc5603.cpp +0 -1
  448. esphome/components/mmc5983/mmc5983.cpp +0 -2
  449. esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
  450. esphome/components/mpr121/__init__.py +7 -6
  451. esphome/components/mpr121/mpr121.cpp +0 -1
  452. esphome/components/mpu6050/mpu6050.cpp +0 -1
  453. esphome/components/mpu6886/mpu6886.cpp +0 -1
  454. esphome/components/mqtt/__init__.py +1 -2
  455. esphome/components/mqtt/mqtt_button.cpp +1 -1
  456. esphome/components/mqtt/mqtt_client.cpp +0 -1
  457. esphome/components/mqtt/mqtt_component.cpp +8 -14
  458. esphome/components/mqtt/mqtt_component.h +0 -7
  459. esphome/components/mqtt/mqtt_sensor.cpp +0 -1
  460. esphome/components/mqtt/mqtt_sensor.h +0 -1
  461. esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
  462. esphome/components/mqtt/mqtt_text_sensor.h +0 -1
  463. esphome/components/ms5611/ms5611.cpp +0 -1
  464. esphome/components/ms8607/ms8607.cpp +0 -1
  465. esphome/components/msa3xx/msa3xx.cpp +0 -2
  466. esphome/components/my9231/my9231.cpp +0 -2
  467. esphome/components/nau7802/nau7802.cpp +0 -1
  468. esphome/components/neopixelbus/light.py +3 -0
  469. esphome/components/network/util.cpp +29 -0
  470. esphome/components/nextion/nextion.cpp +2 -2
  471. esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
  472. esphome/components/npi19/npi19.cpp +0 -2
  473. esphome/components/nrf52/__init__.py +223 -0
  474. esphome/components/nrf52/boards.py +34 -0
  475. esphome/components/nrf52/const.py +18 -0
  476. esphome/components/nrf52/gpio.py +79 -0
  477. esphome/components/number/__init__.py +2 -1
  478. esphome/components/one_wire/__init__.py +1 -2
  479. esphome/components/one_wire/one_wire.cpp +0 -2
  480. esphome/components/one_wire/one_wire.h +0 -2
  481. esphome/components/opentherm/hub.cpp +0 -1
  482. esphome/components/opentherm/number/__init__.py +2 -2
  483. esphome/components/openthread/__init__.py +2 -3
  484. esphome/components/openthread/openthread.cpp +30 -13
  485. esphome/components/openthread/openthread.h +3 -0
  486. esphome/components/openthread/openthread_esp.cpp +3 -1
  487. esphome/components/opt3001/sensor.py +2 -6
  488. esphome/components/output/__init__.py +38 -0
  489. esphome/components/output/automation.h +24 -0
  490. esphome/components/output/switch/output_switch.cpp +0 -2
  491. esphome/components/packages/__init__.py +1 -2
  492. esphome/components/packet_transport/__init__.py +4 -3
  493. esphome/components/pca6416a/pca6416a.cpp +0 -1
  494. esphome/components/pca9554/pca9554.cpp +0 -1
  495. esphome/components/pca9685/pca9685_output.cpp +0 -2
  496. esphome/components/pcf85063/pcf85063.cpp +0 -1
  497. esphome/components/pcf8563/pcf8563.cpp +0 -1
  498. esphome/components/pcf8574/pcf8574.cpp +0 -1
  499. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
  500. esphome/components/pipsolar/pipsolar.cpp +54 -42
  501. esphome/components/pipsolar/pipsolar.h +5 -4
  502. esphome/components/pipsolar/sensor/__init__.py +1 -1
  503. esphome/components/pm2005/pm2005.cpp +0 -1
  504. esphome/components/pmsa003i/pmsa003i.cpp +0 -2
  505. esphome/components/pmwcs3/sensor.py +1 -2
  506. esphome/components/pn532/pn532.cpp +0 -2
  507. esphome/components/pn532_spi/pn532_spi.cpp +0 -2
  508. esphome/components/power_supply/power_supply.cpp +7 -10
  509. esphome/components/power_supply/power_supply.h +1 -1
  510. esphome/components/psram/__init__.py +6 -1
  511. esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
  512. esphome/components/pulse_counter/sensor.py +9 -6
  513. esphome/components/pylontech/pylontech.cpp +0 -1
  514. esphome/components/qmc5883l/qmc5883l.cpp +0 -1
  515. esphome/components/qmp6988/qmp6988.cpp +0 -2
  516. esphome/components/qspi_dbi/display.py +2 -3
  517. esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
  518. esphome/components/qwiic_pir/binary_sensor.py +2 -3
  519. esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
  520. esphome/components/rc522/rc522.cpp +9 -31
  521. esphome/components/rc522_spi/rc522_spi.cpp +0 -1
  522. esphome/components/remote_base/__init__.py +5 -6
  523. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
  524. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
  525. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
  526. esphome/components/remote_transmitter/__init__.py +26 -0
  527. esphome/components/remote_transmitter/automation.h +18 -0
  528. esphome/components/remote_transmitter/remote_transmitter.h +2 -1
  529. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
  530. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
  531. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
  532. esphome/components/resampler/speaker/__init__.py +4 -5
  533. esphome/components/rf_bridge/__init__.py +4 -8
  534. esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
  535. esphome/components/rp2040/__init__.py +3 -1
  536. esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
  537. esphome/components/rp2040_pio_led_strip/light.py +1 -2
  538. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
  539. esphome/components/rpi_dpi_rgb/display.py +13 -15
  540. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
  541. esphome/components/runtime_stats/__init__.py +34 -0
  542. esphome/components/runtime_stats/runtime_stats.cpp +102 -0
  543. esphome/components/runtime_stats/runtime_stats.h +132 -0
  544. esphome/components/scd30/scd30.cpp +0 -2
  545. esphome/components/scd30/sensor.py +1 -2
  546. esphome/components/scd4x/scd4x.cpp +0 -1
  547. esphome/components/scd4x/sensor.py +1 -3
  548. esphome/components/sdl/display.py +3 -1
  549. esphome/components/sdl/sdl_esphome.cpp +0 -2
  550. esphome/components/sdp3x/sdp3x.cpp +0 -2
  551. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
  552. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
  553. esphome/components/select/__init__.py +2 -3
  554. esphome/components/select/select_traits.cpp +1 -1
  555. esphome/components/select/select_traits.h +1 -1
  556. esphome/components/sen0321/sen0321.cpp +0 -1
  557. esphome/components/sen5x/sen5x.cpp +0 -2
  558. esphome/components/senseair/senseair.cpp +7 -3
  559. esphome/components/senseair/senseair.h +11 -0
  560. esphome/components/sensor/__init__.py +36 -4
  561. esphome/components/sensor/filter.cpp +49 -10
  562. esphome/components/sensor/filter.h +22 -7
  563. esphome/components/sensor/sensor.cpp +0 -1
  564. esphome/components/sensor/sensor.h +0 -9
  565. esphome/components/sfa30/sfa30.cpp +0 -4
  566. esphome/components/sgp30/sgp30.cpp +0 -2
  567. esphome/components/sgp4x/sensor.py +1 -1
  568. esphome/components/sgp4x/sgp4x.cpp +0 -2
  569. esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
  570. esphome/components/sht3xd/sht3xd.cpp +0 -2
  571. esphome/components/sht4x/sht4x.cpp +0 -2
  572. esphome/components/shtcx/shtcx.cpp +0 -1
  573. esphome/components/sim800l/__init__.py +2 -4
  574. esphome/components/sm16716/sm16716.cpp +0 -1
  575. esphome/components/sm2135/sm2135.cpp +0 -1
  576. esphome/components/sm2235/sm2235.cpp +0 -1
  577. esphome/components/sm2335/sm2335.cpp +0 -1
  578. esphome/components/sn74hc165/sn74hc165.cpp +0 -1
  579. esphome/components/sn74hc595/sn74hc595.cpp +0 -1
  580. esphome/components/sntp/sntp_component.cpp +0 -1
  581. esphome/components/sound_level/sensor.py +1 -1
  582. esphome/components/speaker/media_player/__init__.py +21 -33
  583. esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
  584. esphome/components/spi/__init__.py +29 -13
  585. esphome/components/spi/spi.cpp +0 -2
  586. esphome/components/spi_device/spi_device.cpp +1 -4
  587. esphome/components/sprinkler/__init__.py +4 -4
  588. esphome/components/sps30/sps30.cpp +0 -1
  589. esphome/components/ssd1306_base/__init__.py +11 -11
  590. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  591. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
  592. esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
  593. esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
  594. esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
  595. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
  596. esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
  597. esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
  598. esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
  599. esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
  600. esphome/components/st7567_spi/st7567_spi.cpp +0 -1
  601. esphome/components/st7701s/display.py +10 -14
  602. esphome/components/st7701s/st7701s.cpp +0 -3
  603. esphome/components/st7735/st7735.cpp +0 -1
  604. esphome/components/st7789v/st7789v.cpp +0 -1
  605. esphome/components/st7920/st7920.cpp +0 -1
  606. esphome/components/status_led/light/status_led_light.cpp +0 -2
  607. esphome/components/status_led/status_led.cpp +0 -1
  608. esphome/components/stepper/__init__.py +2 -4
  609. esphome/components/sts3x/sts3x.cpp +0 -1
  610. esphome/components/substitutions/__init__.py +10 -16
  611. esphome/components/substitutions/jinja.py +24 -1
  612. esphome/components/sun/__init__.py +2 -3
  613. esphome/components/switch/__init__.py +31 -1
  614. esphome/components/switch/automation.h +24 -0
  615. esphome/components/switch/switch.cpp +8 -0
  616. esphome/components/switch/switch.h +8 -0
  617. esphome/components/sx126x/sx126x.cpp +0 -2
  618. esphome/components/sx127x/sx127x.cpp +0 -2
  619. esphome/components/sx1509/__init__.py +7 -5
  620. esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
  621. esphome/components/sx1509/sx1509.cpp +0 -2
  622. esphome/components/syslog/esphome_syslog.cpp +1 -1
  623. esphome/components/tc74/tc74.cpp +0 -1
  624. esphome/components/tca9548a/tca9548a.cpp +0 -1
  625. esphome/components/tca9555/tca9555.cpp +0 -1
  626. esphome/components/tcs34725/tcs34725.cpp +0 -1
  627. esphome/components/tee501/tee501.cpp +0 -1
  628. esphome/components/tem3200/tem3200.cpp +0 -2
  629. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
  630. esphome/components/template/cover/template_cover.cpp +0 -1
  631. esphome/components/template/select/template_select.cpp +0 -1
  632. esphome/components/template/text/template_text.cpp +0 -2
  633. esphome/components/template/valve/template_valve.cpp +0 -1
  634. esphome/components/text/__init__.py +0 -1
  635. esphome/components/text/text_traits.h +2 -0
  636. esphome/components/text_sensor/__init__.py +2 -1
  637. esphome/components/text_sensor/text_sensor.cpp +0 -2
  638. esphome/components/text_sensor/text_sensor.h +0 -8
  639. esphome/components/thermostat/climate.py +4 -4
  640. esphome/components/time/__init__.py +7 -4
  641. esphome/components/time/real_time_clock.cpp +16 -3
  642. esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
  643. esphome/components/tlc5947/tlc5947.cpp +0 -2
  644. esphome/components/tlc5971/tlc5971.cpp +0 -2
  645. esphome/components/tm1621/tm1621.cpp +0 -2
  646. esphome/components/tm1637/tm1637.cpp +0 -2
  647. esphome/components/tm1638/tm1638.cpp +0 -2
  648. esphome/components/tm1651/__init__.py +45 -48
  649. esphome/components/tm1651/tm1651.cpp +213 -47
  650. esphome/components/tm1651/tm1651.h +37 -32
  651. esphome/components/tmp117/tmp117.cpp +0 -2
  652. esphome/components/tsl2561/tsl2561.cpp +0 -1
  653. esphome/components/tsl2591/tsl2591.cpp +0 -1
  654. esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
  655. esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
  656. esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
  657. esphome/components/tuya/climate/__init__.py +9 -10
  658. esphome/components/tuya/number/__init__.py +8 -6
  659. esphome/components/tx20/tx20.cpp +0 -1
  660. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
  661. esphome/components/uart/uart_component_esp8266.cpp +0 -1
  662. esphome/components/uart/uart_component_esp_idf.cpp +0 -2
  663. esphome/components/uart/uart_component_libretiny.cpp +0 -2
  664. esphome/components/uart/uart_component_rp2040.cpp +0 -2
  665. esphome/components/udp/__init__.py +1 -1
  666. esphome/components/ufire_ec/sensor.py +1 -2
  667. esphome/components/ufire_ec/ufire_ec.cpp +0 -2
  668. esphome/components/ufire_ise/sensor.py +1 -2
  669. esphome/components/ufire_ise/ufire_ise.cpp +0 -2
  670. esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
  671. esphome/components/update/__init__.py +0 -1
  672. esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
  673. esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
  674. esphome/components/usb_host/usb_host_client.cpp +0 -1
  675. esphome/components/usb_host/usb_host_component.cpp +0 -1
  676. esphome/components/valve/__init__.py +0 -1
  677. esphome/components/veml3235/veml3235.cpp +0 -3
  678. esphome/components/veml7700/veml7700.cpp +0 -2
  679. esphome/components/version/version_text_sensor.cpp +0 -1
  680. esphome/components/version/version_text_sensor.h +0 -1
  681. esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
  682. esphome/components/voice_assistant/voice_assistant.cpp +9 -8
  683. esphome/components/web_server/__init__.py +13 -0
  684. esphome/components/web_server/web_server.cpp +188 -353
  685. esphome/components/web_server/web_server.h +61 -1
  686. esphome/components/web_server_base/__init__.py +1 -1
  687. esphome/components/web_server_base/web_server_base.cpp +2 -0
  688. esphome/components/web_server_base/web_server_base.h +6 -0
  689. esphome/components/web_server_idf/web_server_idf.cpp +10 -8
  690. esphome/components/web_server_idf/web_server_idf.h +2 -0
  691. esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
  692. esphome/components/weikai_spi/weikai_spi.cpp +1 -1
  693. esphome/components/wifi/__init__.py +17 -43
  694. esphome/components/wifi/wifi_component.cpp +100 -36
  695. esphome/components/wifi/wifi_component.h +5 -1
  696. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
  697. esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
  698. esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
  699. esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
  700. esphome/components/wireguard/wireguard.cpp +0 -2
  701. esphome/components/x9c/x9c.cpp +0 -2
  702. esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
  703. esphome/components/xl9535/xl9535.cpp +0 -2
  704. esphome/components/zephyr/__init__.py +252 -0
  705. esphome/components/zephyr/const.py +16 -0
  706. esphome/components/zephyr/core.cpp +90 -0
  707. esphome/components/zephyr/gpio.cpp +120 -0
  708. esphome/components/zephyr/gpio.h +38 -0
  709. esphome/components/zephyr/pre_build.py.script +4 -0
  710. esphome/components/zephyr/preferences.cpp +156 -0
  711. esphome/components/zephyr/preferences.h +13 -0
  712. esphome/config.py +38 -16
  713. esphome/config_helpers.py +1 -2
  714. esphome/config_validation.py +12 -16
  715. esphome/const.py +26 -1
  716. esphome/core/__init__.py +92 -51
  717. esphome/core/application.cpp +75 -21
  718. esphome/core/application.h +106 -171
  719. esphome/core/color.h +10 -0
  720. esphome/core/component.cpp +41 -25
  721. esphome/core/component.h +9 -6
  722. esphome/core/component_iterator.cpp +61 -261
  723. esphome/core/component_iterator.h +15 -0
  724. esphome/core/config.py +26 -11
  725. esphome/core/defines.h +40 -2
  726. esphome/core/entity_base.h +18 -0
  727. esphome/core/entity_helpers.py +45 -10
  728. esphome/core/helpers.cpp +8 -15
  729. esphome/core/helpers.h +60 -6
  730. esphome/core/lock_free_queue.h +1 -1
  731. esphome/core/scheduler.cpp +311 -77
  732. esphome/core/scheduler.h +141 -28
  733. esphome/cpp_generator.py +2 -6
  734. esphome/cpp_helpers.py +1 -1
  735. esphome/dashboard/dashboard.py +2 -3
  736. esphome/dashboard/dns.py +2 -8
  737. esphome/dashboard/web_server.py +34 -19
  738. esphome/espota2.py +1 -4
  739. esphome/git.py +3 -1
  740. esphome/helpers.py +23 -4
  741. esphome/log.py +3 -1
  742. esphome/mqtt.py +3 -5
  743. esphome/platformio_api.py +7 -4
  744. esphome/types.py +12 -0
  745. esphome/util.py +20 -8
  746. esphome/voluptuous_schema.py +4 -3
  747. esphome/vscode.py +1 -2
  748. esphome/wizard.py +1 -4
  749. esphome/writer.py +16 -108
  750. esphome/yaml_util.py +7 -5
  751. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/METADATA +13 -14
  752. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/RECORD +757 -677
  753. esphome/components/mipi_spi/models/commands.py +0 -82
  754. /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
  755. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/WHEEL +0 -0
  756. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/entry_points.txt +0 -0
  757. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/licenses/LICENSE +0 -0
  758. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/top_level.txt +0 -0
@@ -279,7 +279,6 @@ std::string WebServer::get_config_json() {
279
279
  }
280
280
 
281
281
  void WebServer::setup() {
282
- ESP_LOGCONFIG(TAG, "Running setup");
283
282
  this->setup_controller(this->include_internal_);
284
283
  this->base_->init();
285
284
 
@@ -377,23 +376,32 @@ void WebServer::handle_js_request(AsyncWebServerRequest *request) {
377
376
  }
378
377
  #endif
379
378
 
380
- #define set_json_id(root, obj, sensor, start_config) \
381
- (root)["id"] = sensor; \
382
- if (((start_config) == DETAIL_ALL)) { \
383
- (root)["name"] = (obj)->get_name(); \
384
- (root)["icon"] = (obj)->get_icon(); \
385
- (root)["entity_category"] = (obj)->get_entity_category(); \
386
- if ((obj)->is_disabled_by_default()) \
387
- (root)["is_disabled_by_default"] = (obj)->is_disabled_by_default(); \
379
+ // Helper functions to reduce code size by avoiding macro expansion
380
+ static void set_json_id(JsonObject &root, EntityBase *obj, const std::string &id, JsonDetail start_config) {
381
+ root["id"] = id;
382
+ if (start_config == DETAIL_ALL) {
383
+ root["name"] = obj->get_name();
384
+ root["icon"] = obj->get_icon();
385
+ root["entity_category"] = obj->get_entity_category();
386
+ bool is_disabled = obj->is_disabled_by_default();
387
+ if (is_disabled)
388
+ root["is_disabled_by_default"] = is_disabled;
388
389
  }
390
+ }
389
391
 
390
- #define set_json_value(root, obj, sensor, value, start_config) \
391
- set_json_id((root), (obj), sensor, start_config); \
392
- (root)["value"] = value;
392
+ template<typename T>
393
+ static void set_json_value(JsonObject &root, EntityBase *obj, const std::string &id, const T &value,
394
+ JsonDetail start_config) {
395
+ set_json_id(root, obj, id, start_config);
396
+ root["value"] = value;
397
+ }
393
398
 
394
- #define set_json_icon_state_value(root, obj, sensor, state, value, start_config) \
395
- set_json_value(root, obj, sensor, value, start_config); \
396
- (root)["state"] = state;
399
+ template<typename T>
400
+ static void set_json_icon_state_value(JsonObject &root, EntityBase *obj, const std::string &id,
401
+ const std::string &state, const T &value, JsonDetail start_config) {
402
+ set_json_value(root, obj, id, value, start_config);
403
+ root["state"] = state;
404
+ }
397
405
 
398
406
  // Helper to get request detail parameter
399
407
  static JsonDetail get_request_detail(AsyncWebServerRequest *request) {
@@ -627,15 +635,8 @@ void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatc
627
635
  } else if (match.method_equals("turn_on") || match.method_equals("turn_off")) {
628
636
  auto call = match.method_equals("turn_on") ? obj->turn_on() : obj->turn_off();
629
637
 
630
- if (request->hasParam("speed_level")) {
631
- auto speed_level = request->getParam("speed_level")->value();
632
- auto val = parse_number<int>(speed_level.c_str());
633
- if (!val.has_value()) {
634
- ESP_LOGW(TAG, "Can't convert '%s' to number!", speed_level.c_str());
635
- return;
636
- }
637
- call.set_speed(*val);
638
- }
638
+ parse_int_param_(request, "speed_level", call, &decltype(call)::set_speed);
639
+
639
640
  if (request->hasParam("oscillation")) {
640
641
  auto speed = request->getParam("oscillation")->value();
641
642
  auto val = parse_on_off(speed.c_str());
@@ -707,69 +708,26 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa
707
708
  request->send(200);
708
709
  } else if (match.method_equals("turn_on")) {
709
710
  auto call = obj->turn_on();
710
- if (request->hasParam("brightness")) {
711
- auto brightness = parse_number<float>(request->getParam("brightness")->value().c_str());
712
- if (brightness.has_value()) {
713
- call.set_brightness(*brightness / 255.0f);
714
- }
715
- }
716
- if (request->hasParam("r")) {
717
- auto r = parse_number<float>(request->getParam("r")->value().c_str());
718
- if (r.has_value()) {
719
- call.set_red(*r / 255.0f);
720
- }
721
- }
722
- if (request->hasParam("g")) {
723
- auto g = parse_number<float>(request->getParam("g")->value().c_str());
724
- if (g.has_value()) {
725
- call.set_green(*g / 255.0f);
726
- }
727
- }
728
- if (request->hasParam("b")) {
729
- auto b = parse_number<float>(request->getParam("b")->value().c_str());
730
- if (b.has_value()) {
731
- call.set_blue(*b / 255.0f);
732
- }
733
- }
734
- if (request->hasParam("white_value")) {
735
- auto white_value = parse_number<float>(request->getParam("white_value")->value().c_str());
736
- if (white_value.has_value()) {
737
- call.set_white(*white_value / 255.0f);
738
- }
739
- }
740
- if (request->hasParam("color_temp")) {
741
- auto color_temp = parse_number<float>(request->getParam("color_temp")->value().c_str());
742
- if (color_temp.has_value()) {
743
- call.set_color_temperature(*color_temp);
744
- }
745
- }
746
- if (request->hasParam("flash")) {
747
- auto flash = parse_number<uint32_t>(request->getParam("flash")->value().c_str());
748
- if (flash.has_value()) {
749
- call.set_flash_length(*flash * 1000);
750
- }
751
- }
752
- if (request->hasParam("transition")) {
753
- auto transition = parse_number<uint32_t>(request->getParam("transition")->value().c_str());
754
- if (transition.has_value()) {
755
- call.set_transition_length(*transition * 1000);
756
- }
757
- }
758
- if (request->hasParam("effect")) {
759
- const char *effect = request->getParam("effect")->value().c_str();
760
- call.set_effect(effect);
761
- }
711
+
712
+ // Parse color parameters
713
+ parse_light_param_(request, "brightness", call, &decltype(call)::set_brightness, 255.0f);
714
+ parse_light_param_(request, "r", call, &decltype(call)::set_red, 255.0f);
715
+ parse_light_param_(request, "g", call, &decltype(call)::set_green, 255.0f);
716
+ parse_light_param_(request, "b", call, &decltype(call)::set_blue, 255.0f);
717
+ parse_light_param_(request, "white_value", call, &decltype(call)::set_white, 255.0f);
718
+ parse_light_param_(request, "color_temp", call, &decltype(call)::set_color_temperature);
719
+
720
+ // Parse timing parameters
721
+ parse_light_param_uint_(request, "flash", call, &decltype(call)::set_flash_length, 1000);
722
+ parse_light_param_uint_(request, "transition", call, &decltype(call)::set_transition_length, 1000);
723
+
724
+ parse_string_param_(request, "effect", call, &decltype(call)::set_effect);
762
725
 
763
726
  this->defer([call]() mutable { call.perform(); });
764
727
  request->send(200);
765
728
  } else if (match.method_equals("turn_off")) {
766
729
  auto call = obj->turn_off();
767
- if (request->hasParam("transition")) {
768
- auto transition = parse_number<uint32_t>(request->getParam("transition")->value().c_str());
769
- if (transition.has_value()) {
770
- call.set_transition_length(*transition * 1000);
771
- }
772
- }
730
+ parse_light_param_uint_(request, "transition", call, &decltype(call)::set_transition_length, 1000);
773
731
  this->defer([call]() mutable { call.perform(); });
774
732
  request->send(200);
775
733
  } else {
@@ -842,18 +800,8 @@ void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMa
842
800
  return;
843
801
  }
844
802
 
845
- if (request->hasParam("position")) {
846
- auto position = parse_number<float>(request->getParam("position")->value().c_str());
847
- if (position.has_value()) {
848
- call.set_position(*position);
849
- }
850
- }
851
- if (request->hasParam("tilt")) {
852
- auto tilt = parse_number<float>(request->getParam("tilt")->value().c_str());
853
- if (tilt.has_value()) {
854
- call.set_tilt(*tilt);
855
- }
856
- }
803
+ parse_float_param_(request, "position", call, &decltype(call)::set_position);
804
+ parse_float_param_(request, "tilt", call, &decltype(call)::set_tilt);
857
805
 
858
806
  this->defer([call]() mutable { call.perform(); });
859
807
  request->send(200);
@@ -865,7 +813,7 @@ std::string WebServer::cover_state_json_generator(WebServer *web_server, void *s
865
813
  return web_server->cover_json((cover::Cover *) (source), DETAIL_STATE);
866
814
  }
867
815
  std::string WebServer::cover_all_json_generator(WebServer *web_server, void *source) {
868
- return web_server->cover_json((cover::Cover *) (source), DETAIL_STATE);
816
+ return web_server->cover_json((cover::Cover *) (source), DETAIL_ALL);
869
817
  }
870
818
  std::string WebServer::cover_json(cover::Cover *obj, JsonDetail start_config) {
871
819
  return json::build_json([this, obj, start_config](JsonObject root) {
@@ -907,11 +855,7 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM
907
855
  }
908
856
 
909
857
  auto call = obj->make_call();
910
- if (request->hasParam("value")) {
911
- auto value = parse_number<float>(request->getParam("value")->value().c_str());
912
- if (value.has_value())
913
- call.set_value(*value);
914
- }
858
+ parse_float_param_(request, "value", call, &decltype(call)::set_value);
915
859
 
916
860
  this->defer([call]() mutable { call.perform(); });
917
861
  request->send(200);
@@ -983,10 +927,7 @@ void WebServer::handle_date_request(AsyncWebServerRequest *request, const UrlMat
983
927
  return;
984
928
  }
985
929
 
986
- if (request->hasParam("value")) {
987
- std::string value = request->getParam("value")->value().c_str(); // NOLINT
988
- call.set_date(value);
989
- }
930
+ parse_string_param_(request, "value", call, &decltype(call)::set_date);
990
931
 
991
932
  this->defer([call]() mutable { call.perform(); });
992
933
  request->send(200);
@@ -1042,10 +983,7 @@ void WebServer::handle_time_request(AsyncWebServerRequest *request, const UrlMat
1042
983
  return;
1043
984
  }
1044
985
 
1045
- if (request->hasParam("value")) {
1046
- std::string value = request->getParam("value")->value().c_str(); // NOLINT
1047
- call.set_time(value);
1048
- }
986
+ parse_string_param_(request, "value", call, &decltype(call)::set_time);
1049
987
 
1050
988
  this->defer([call]() mutable { call.perform(); });
1051
989
  request->send(200);
@@ -1100,10 +1038,7 @@ void WebServer::handle_datetime_request(AsyncWebServerRequest *request, const Ur
1100
1038
  return;
1101
1039
  }
1102
1040
 
1103
- if (request->hasParam("value")) {
1104
- std::string value = request->getParam("value")->value().c_str(); // NOLINT
1105
- call.set_datetime(value);
1106
- }
1041
+ parse_string_param_(request, "value", call, &decltype(call)::set_datetime);
1107
1042
 
1108
1043
  this->defer([call]() mutable { call.perform(); });
1109
1044
  request->send(200);
@@ -1154,10 +1089,7 @@ void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMat
1154
1089
  }
1155
1090
 
1156
1091
  auto call = obj->make_call();
1157
- if (request->hasParam("value")) {
1158
- String value = request->getParam("value")->value();
1159
- call.set_value(value.c_str()); // NOLINT
1160
- }
1092
+ parse_string_param_(request, "value", call, &decltype(call)::set_value);
1161
1093
 
1162
1094
  this->defer([call]() mutable { call.perform(); });
1163
1095
  request->send(200);
@@ -1216,11 +1148,7 @@ void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlM
1216
1148
  }
1217
1149
 
1218
1150
  auto call = obj->make_call();
1219
-
1220
- if (request->hasParam("option")) {
1221
- auto option = request->getParam("option")->value();
1222
- call.set_option(option.c_str()); // NOLINT
1223
- }
1151
+ parse_string_param_(request, "option", call, &decltype(call)::set_option);
1224
1152
 
1225
1153
  this->defer([call]() mutable { call.perform(); });
1226
1154
  request->send(200);
@@ -1276,38 +1204,15 @@ void WebServer::handle_climate_request(AsyncWebServerRequest *request, const Url
1276
1204
 
1277
1205
  auto call = obj->make_call();
1278
1206
 
1279
- if (request->hasParam("mode")) {
1280
- auto mode = request->getParam("mode")->value();
1281
- call.set_mode(mode.c_str()); // NOLINT
1282
- }
1207
+ // Parse string mode parameters
1208
+ parse_string_param_(request, "mode", call, &decltype(call)::set_mode);
1209
+ parse_string_param_(request, "fan_mode", call, &decltype(call)::set_fan_mode);
1210
+ parse_string_param_(request, "swing_mode", call, &decltype(call)::set_swing_mode);
1283
1211
 
1284
- if (request->hasParam("fan_mode")) {
1285
- auto mode = request->getParam("fan_mode")->value();
1286
- call.set_fan_mode(mode.c_str()); // NOLINT
1287
- }
1288
-
1289
- if (request->hasParam("swing_mode")) {
1290
- auto mode = request->getParam("swing_mode")->value();
1291
- call.set_swing_mode(mode.c_str()); // NOLINT
1292
- }
1293
-
1294
- if (request->hasParam("target_temperature_high")) {
1295
- auto target_temperature_high = parse_number<float>(request->getParam("target_temperature_high")->value().c_str());
1296
- if (target_temperature_high.has_value())
1297
- call.set_target_temperature_high(*target_temperature_high);
1298
- }
1299
-
1300
- if (request->hasParam("target_temperature_low")) {
1301
- auto target_temperature_low = parse_number<float>(request->getParam("target_temperature_low")->value().c_str());
1302
- if (target_temperature_low.has_value())
1303
- call.set_target_temperature_low(*target_temperature_low);
1304
- }
1305
-
1306
- if (request->hasParam("target_temperature")) {
1307
- auto target_temperature = parse_number<float>(request->getParam("target_temperature")->value().c_str());
1308
- if (target_temperature.has_value())
1309
- call.set_target_temperature(*target_temperature);
1310
- }
1212
+ // Parse temperature parameters
1213
+ parse_float_param_(request, "target_temperature_high", call, &decltype(call)::set_target_temperature_high);
1214
+ parse_float_param_(request, "target_temperature_low", call, &decltype(call)::set_target_temperature_low);
1215
+ parse_float_param_(request, "target_temperature", call, &decltype(call)::set_target_temperature);
1311
1216
 
1312
1217
  this->defer([call]() mutable { call.perform(); });
1313
1218
  request->send(200);
@@ -1498,12 +1403,7 @@ void WebServer::handle_valve_request(AsyncWebServerRequest *request, const UrlMa
1498
1403
  return;
1499
1404
  }
1500
1405
 
1501
- if (request->hasParam("position")) {
1502
- auto position = parse_number<float>(request->getParam("position")->value().c_str());
1503
- if (position.has_value()) {
1504
- call.set_position(*position);
1505
- }
1506
- }
1406
+ parse_float_param_(request, "position", call, &decltype(call)::set_position);
1507
1407
 
1508
1408
  this->defer([call]() mutable { call.perform(); });
1509
1409
  request->send(200);
@@ -1551,9 +1451,7 @@ void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *reques
1551
1451
  }
1552
1452
 
1553
1453
  auto call = obj->make_call();
1554
- if (request->hasParam("code")) {
1555
- call.set_code(request->getParam("code")->value().c_str()); // NOLINT
1556
- }
1454
+ parse_string_param_(request, "code", call, &decltype(call)::set_code);
1557
1455
 
1558
1456
  if (match.method_equals("disarm")) {
1559
1457
  call.disarm();
@@ -1651,6 +1549,19 @@ std::string WebServer::event_json(event::Event *obj, const std::string &event_ty
1651
1549
  #endif
1652
1550
 
1653
1551
  #ifdef USE_UPDATE
1552
+ static const char *update_state_to_string(update::UpdateState state) {
1553
+ switch (state) {
1554
+ case update::UPDATE_STATE_NO_UPDATE:
1555
+ return "NO UPDATE";
1556
+ case update::UPDATE_STATE_AVAILABLE:
1557
+ return "UPDATE AVAILABLE";
1558
+ case update::UPDATE_STATE_INSTALLING:
1559
+ return "INSTALLING";
1560
+ default:
1561
+ return "UNKNOWN";
1562
+ }
1563
+ }
1564
+
1654
1565
  void WebServer::on_update(update::UpdateEntity *obj) {
1655
1566
  if (this->events_.empty())
1656
1567
  return;
@@ -1690,20 +1601,7 @@ std::string WebServer::update_json(update::UpdateEntity *obj, JsonDetail start_c
1690
1601
  return json::build_json([this, obj, start_config](JsonObject root) {
1691
1602
  set_json_id(root, obj, "update-" + obj->get_object_id(), start_config);
1692
1603
  root["value"] = obj->update_info.latest_version;
1693
- switch (obj->state) {
1694
- case update::UPDATE_STATE_NO_UPDATE:
1695
- root["state"] = "NO UPDATE";
1696
- break;
1697
- case update::UPDATE_STATE_AVAILABLE:
1698
- root["state"] = "UPDATE AVAILABLE";
1699
- break;
1700
- case update::UPDATE_STATE_INSTALLING:
1701
- root["state"] = "INSTALLING";
1702
- break;
1703
- default:
1704
- root["state"] = "UNKNOWN";
1705
- break;
1706
- }
1604
+ root["state"] = update_state_to_string(obj->state);
1707
1605
  if (start_config == DETAIL_ALL) {
1708
1606
  root["current_version"] = obj->update_info.current_version;
1709
1607
  root["title"] = obj->update_info.title;
@@ -1717,162 +1615,161 @@ std::string WebServer::update_json(update::UpdateEntity *obj, JsonDetail start_c
1717
1615
  #endif
1718
1616
 
1719
1617
  bool WebServer::canHandle(AsyncWebServerRequest *request) const {
1720
- if (request->url() == "/")
1618
+ const auto &url = request->url();
1619
+ const auto method = request->method();
1620
+
1621
+ // Simple URL checks
1622
+ if (url == "/")
1721
1623
  return true;
1722
1624
 
1723
1625
  #ifdef USE_ARDUINO
1724
- if (request->url() == "/events") {
1626
+ if (url == "/events")
1725
1627
  return true;
1726
- }
1727
1628
  #endif
1728
1629
 
1729
1630
  #ifdef USE_WEBSERVER_CSS_INCLUDE
1730
- if (request->url() == "/0.css")
1631
+ if (url == "/0.css")
1731
1632
  return true;
1732
1633
  #endif
1733
1634
 
1734
1635
  #ifdef USE_WEBSERVER_JS_INCLUDE
1735
- if (request->url() == "/0.js")
1636
+ if (url == "/0.js")
1736
1637
  return true;
1737
1638
  #endif
1738
1639
 
1739
1640
  #ifdef USE_WEBSERVER_PRIVATE_NETWORK_ACCESS
1740
- if (request->method() == HTTP_OPTIONS && request->hasHeader(HEADER_CORS_REQ_PNA)) {
1641
+ if (method == HTTP_OPTIONS && request->hasHeader(HEADER_CORS_REQ_PNA))
1741
1642
  return true;
1742
- }
1743
1643
  #endif
1744
1644
 
1745
- // Store the URL to prevent temporary string destruction
1746
- // request->url() returns a reference to a String (on Arduino) or std::string (on ESP-IDF)
1747
- // UrlMatch stores pointers to the string's data, so we must ensure the string outlives match_url()
1748
- const auto &url = request->url();
1645
+ // Parse URL for component checks
1749
1646
  UrlMatch match = match_url(url.c_str(), url.length(), true);
1750
1647
  if (!match.valid)
1751
1648
  return false;
1649
+
1650
+ // Common pattern check
1651
+ bool is_get = method == HTTP_GET;
1652
+ bool is_post = method == HTTP_POST;
1653
+ bool is_get_or_post = is_get || is_post;
1654
+
1655
+ if (!is_get_or_post)
1656
+ return false;
1657
+
1658
+ // GET-only components
1659
+ if (is_get) {
1752
1660
  #ifdef USE_SENSOR
1753
- if (request->method() == HTTP_GET && match.domain_equals("sensor"))
1754
- return true;
1661
+ if (match.domain_equals("sensor"))
1662
+ return true;
1663
+ #endif
1664
+ #ifdef USE_BINARY_SENSOR
1665
+ if (match.domain_equals("binary_sensor"))
1666
+ return true;
1755
1667
  #endif
1668
+ #ifdef USE_TEXT_SENSOR
1669
+ if (match.domain_equals("text_sensor"))
1670
+ return true;
1671
+ #endif
1672
+ #ifdef USE_EVENT
1673
+ if (match.domain_equals("event"))
1674
+ return true;
1675
+ #endif
1676
+ }
1756
1677
 
1678
+ // GET+POST components
1679
+ if (is_get_or_post) {
1757
1680
  #ifdef USE_SWITCH
1758
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("switch"))
1759
- return true;
1681
+ if (match.domain_equals("switch"))
1682
+ return true;
1760
1683
  #endif
1761
-
1762
1684
  #ifdef USE_BUTTON
1763
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("button"))
1764
- return true;
1765
- #endif
1766
-
1767
- #ifdef USE_BINARY_SENSOR
1768
- if (request->method() == HTTP_GET && match.domain_equals("binary_sensor"))
1769
- return true;
1685
+ if (match.domain_equals("button"))
1686
+ return true;
1770
1687
  #endif
1771
-
1772
1688
  #ifdef USE_FAN
1773
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("fan"))
1774
- return true;
1689
+ if (match.domain_equals("fan"))
1690
+ return true;
1775
1691
  #endif
1776
-
1777
1692
  #ifdef USE_LIGHT
1778
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("light"))
1779
- return true;
1693
+ if (match.domain_equals("light"))
1694
+ return true;
1780
1695
  #endif
1781
-
1782
- #ifdef USE_TEXT_SENSOR
1783
- if (request->method() == HTTP_GET && match.domain_equals("text_sensor"))
1784
- return true;
1785
- #endif
1786
-
1787
1696
  #ifdef USE_COVER
1788
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("cover"))
1789
- return true;
1697
+ if (match.domain_equals("cover"))
1698
+ return true;
1790
1699
  #endif
1791
-
1792
1700
  #ifdef USE_NUMBER
1793
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("number"))
1794
- return true;
1701
+ if (match.domain_equals("number"))
1702
+ return true;
1795
1703
  #endif
1796
-
1797
1704
  #ifdef USE_DATETIME_DATE
1798
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("date"))
1799
- return true;
1705
+ if (match.domain_equals("date"))
1706
+ return true;
1800
1707
  #endif
1801
-
1802
1708
  #ifdef USE_DATETIME_TIME
1803
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("time"))
1804
- return true;
1709
+ if (match.domain_equals("time"))
1710
+ return true;
1805
1711
  #endif
1806
-
1807
1712
  #ifdef USE_DATETIME_DATETIME
1808
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("datetime"))
1809
- return true;
1713
+ if (match.domain_equals("datetime"))
1714
+ return true;
1810
1715
  #endif
1811
-
1812
1716
  #ifdef USE_TEXT
1813
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("text"))
1814
- return true;
1717
+ if (match.domain_equals("text"))
1718
+ return true;
1815
1719
  #endif
1816
-
1817
1720
  #ifdef USE_SELECT
1818
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("select"))
1819
- return true;
1721
+ if (match.domain_equals("select"))
1722
+ return true;
1820
1723
  #endif
1821
-
1822
1724
  #ifdef USE_CLIMATE
1823
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("climate"))
1824
- return true;
1725
+ if (match.domain_equals("climate"))
1726
+ return true;
1825
1727
  #endif
1826
-
1827
1728
  #ifdef USE_LOCK
1828
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("lock"))
1829
- return true;
1729
+ if (match.domain_equals("lock"))
1730
+ return true;
1830
1731
  #endif
1831
-
1832
1732
  #ifdef USE_VALVE
1833
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("valve"))
1834
- return true;
1733
+ if (match.domain_equals("valve"))
1734
+ return true;
1835
1735
  #endif
1836
-
1837
1736
  #ifdef USE_ALARM_CONTROL_PANEL
1838
- if ((request->method() == HTTP_GET || request->method() == HTTP_POST) && match.domain_equals("alarm_control_panel"))
1839
- return true;
1840
- #endif
1841
-
1842
- #ifdef USE_EVENT
1843
- if (request->method() == HTTP_GET && match.domain_equals("event"))
1844
- return true;
1737
+ if (match.domain_equals("alarm_control_panel"))
1738
+ return true;
1845
1739
  #endif
1846
-
1847
1740
  #ifdef USE_UPDATE
1848
- if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain_equals("update"))
1849
- return true;
1741
+ if (match.domain_equals("update"))
1742
+ return true;
1850
1743
  #endif
1744
+ }
1851
1745
 
1852
1746
  return false;
1853
1747
  }
1854
1748
  void WebServer::handleRequest(AsyncWebServerRequest *request) {
1855
- if (request->url() == "/") {
1749
+ const auto &url = request->url();
1750
+
1751
+ // Handle static routes first
1752
+ if (url == "/") {
1856
1753
  this->handle_index_request(request);
1857
1754
  return;
1858
1755
  }
1859
1756
 
1860
1757
  #ifdef USE_ARDUINO
1861
- if (request->url() == "/events") {
1758
+ if (url == "/events") {
1862
1759
  this->events_.add_new_client(this, request);
1863
1760
  return;
1864
1761
  }
1865
1762
  #endif
1866
1763
 
1867
1764
  #ifdef USE_WEBSERVER_CSS_INCLUDE
1868
- if (request->url() == "/0.css") {
1765
+ if (url == "/0.css") {
1869
1766
  this->handle_css_request(request);
1870
1767
  return;
1871
1768
  }
1872
1769
  #endif
1873
1770
 
1874
1771
  #ifdef USE_WEBSERVER_JS_INCLUDE
1875
- if (request->url() == "/0.js") {
1772
+ if (url == "/0.js") {
1876
1773
  this->handle_js_request(request);
1877
1774
  return;
1878
1775
  }
@@ -1885,147 +1782,85 @@ void WebServer::handleRequest(AsyncWebServerRequest *request) {
1885
1782
  }
1886
1783
  #endif
1887
1784
 
1888
- // See comment in canHandle() for why we store the URL reference
1889
- const auto &url = request->url();
1785
+ // Parse URL for component routing
1890
1786
  UrlMatch match = match_url(url.c_str(), url.length(), false);
1891
1787
 
1788
+ // Component routing using minimal code repetition
1789
+ struct ComponentRoute {
1790
+ const char *domain;
1791
+ void (WebServer::*handler)(AsyncWebServerRequest *, const UrlMatch &);
1792
+ };
1793
+
1794
+ static const ComponentRoute ROUTES[] = {
1892
1795
  #ifdef USE_SENSOR
1893
- if (match.domain_equals("sensor")) {
1894
- this->handle_sensor_request(request, match);
1895
- return;
1896
- }
1796
+ {"sensor", &WebServer::handle_sensor_request},
1897
1797
  #endif
1898
-
1899
1798
  #ifdef USE_SWITCH
1900
- if (match.domain_equals("switch")) {
1901
- this->handle_switch_request(request, match);
1902
- return;
1903
- }
1799
+ {"switch", &WebServer::handle_switch_request},
1904
1800
  #endif
1905
-
1906
1801
  #ifdef USE_BUTTON
1907
- if (match.domain_equals("button")) {
1908
- this->handle_button_request(request, match);
1909
- return;
1910
- }
1802
+ {"button", &WebServer::handle_button_request},
1911
1803
  #endif
1912
-
1913
1804
  #ifdef USE_BINARY_SENSOR
1914
- if (match.domain_equals("binary_sensor")) {
1915
- this->handle_binary_sensor_request(request, match);
1916
- return;
1917
- }
1805
+ {"binary_sensor", &WebServer::handle_binary_sensor_request},
1918
1806
  #endif
1919
-
1920
1807
  #ifdef USE_FAN
1921
- if (match.domain_equals("fan")) {
1922
- this->handle_fan_request(request, match);
1923
- return;
1924
- }
1808
+ {"fan", &WebServer::handle_fan_request},
1925
1809
  #endif
1926
-
1927
1810
  #ifdef USE_LIGHT
1928
- if (match.domain_equals("light")) {
1929
- this->handle_light_request(request, match);
1930
- return;
1931
- }
1811
+ {"light", &WebServer::handle_light_request},
1932
1812
  #endif
1933
-
1934
1813
  #ifdef USE_TEXT_SENSOR
1935
- if (match.domain_equals("text_sensor")) {
1936
- this->handle_text_sensor_request(request, match);
1937
- return;
1938
- }
1814
+ {"text_sensor", &WebServer::handle_text_sensor_request},
1939
1815
  #endif
1940
-
1941
1816
  #ifdef USE_COVER
1942
- if (match.domain_equals("cover")) {
1943
- this->handle_cover_request(request, match);
1944
- return;
1945
- }
1817
+ {"cover", &WebServer::handle_cover_request},
1946
1818
  #endif
1947
-
1948
1819
  #ifdef USE_NUMBER
1949
- if (match.domain_equals("number")) {
1950
- this->handle_number_request(request, match);
1951
- return;
1952
- }
1820
+ {"number", &WebServer::handle_number_request},
1953
1821
  #endif
1954
-
1955
1822
  #ifdef USE_DATETIME_DATE
1956
- if (match.domain_equals("date")) {
1957
- this->handle_date_request(request, match);
1958
- return;
1959
- }
1823
+ {"date", &WebServer::handle_date_request},
1960
1824
  #endif
1961
-
1962
1825
  #ifdef USE_DATETIME_TIME
1963
- if (match.domain_equals("time")) {
1964
- this->handle_time_request(request, match);
1965
- return;
1966
- }
1826
+ {"time", &WebServer::handle_time_request},
1967
1827
  #endif
1968
-
1969
1828
  #ifdef USE_DATETIME_DATETIME
1970
- if (match.domain_equals("datetime")) {
1971
- this->handle_datetime_request(request, match);
1972
- return;
1973
- }
1829
+ {"datetime", &WebServer::handle_datetime_request},
1974
1830
  #endif
1975
-
1976
1831
  #ifdef USE_TEXT
1977
- if (match.domain_equals("text")) {
1978
- this->handle_text_request(request, match);
1979
- return;
1980
- }
1832
+ {"text", &WebServer::handle_text_request},
1981
1833
  #endif
1982
-
1983
1834
  #ifdef USE_SELECT
1984
- if (match.domain_equals("select")) {
1985
- this->handle_select_request(request, match);
1986
- return;
1987
- }
1835
+ {"select", &WebServer::handle_select_request},
1988
1836
  #endif
1989
-
1990
1837
  #ifdef USE_CLIMATE
1991
- if (match.domain_equals("climate")) {
1992
- this->handle_climate_request(request, match);
1993
- return;
1994
- }
1838
+ {"climate", &WebServer::handle_climate_request},
1995
1839
  #endif
1996
-
1997
1840
  #ifdef USE_LOCK
1998
- if (match.domain_equals("lock")) {
1999
- this->handle_lock_request(request, match);
2000
-
2001
- return;
2002
- }
1841
+ {"lock", &WebServer::handle_lock_request},
2003
1842
  #endif
2004
-
2005
1843
  #ifdef USE_VALVE
2006
- if (match.domain_equals("valve")) {
2007
- this->handle_valve_request(request, match);
2008
- return;
2009
- }
1844
+ {"valve", &WebServer::handle_valve_request},
2010
1845
  #endif
2011
-
2012
1846
  #ifdef USE_ALARM_CONTROL_PANEL
2013
- if (match.domain_equals("alarm_control_panel")) {
2014
- this->handle_alarm_control_panel_request(request, match);
2015
-
2016
- return;
2017
- }
1847
+ {"alarm_control_panel", &WebServer::handle_alarm_control_panel_request},
2018
1848
  #endif
2019
-
2020
1849
  #ifdef USE_UPDATE
2021
- if (match.domain_equals("update")) {
2022
- this->handle_update_request(request, match);
2023
- return;
2024
- }
1850
+ {"update", &WebServer::handle_update_request},
2025
1851
  #endif
1852
+ };
1853
+
1854
+ // Check each route
1855
+ for (const auto &route : ROUTES) {
1856
+ if (match.domain_equals(route.domain)) {
1857
+ (this->*route.handler)(request, match);
1858
+ return;
1859
+ }
1860
+ }
2026
1861
 
2027
1862
  // No matching handler found - send 404
2028
- ESP_LOGV(TAG, "Request for unknown URL: %s", request->url().c_str());
1863
+ ESP_LOGV(TAG, "Request for unknown URL: %s", url.c_str());
2029
1864
  request->send(404, "text/plain", "Not Found");
2030
1865
  }
2031
1866