esphome 2025.7.5__py3-none-any.whl → 2025.8.0b2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (752) hide show
  1. esphome/__main__.py +189 -82
  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 +102 -52
  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 +488 -118
  73. esphome/components/atm90e32/atm90e32.h +44 -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 +387 -82
  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 +199 -58
  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 +40 -2
  149. esphome/components/esp32_ble/ble.cpp +12 -8
  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 +2 -4
  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/fs3000/fs3000.cpp +0 -2
  209. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
  210. esphome/components/ft63x6/ft63x6.cpp +0 -1
  211. esphome/components/gdk101/gdk101.cpp +0 -1
  212. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
  213. esphome/components/gl_r01_i2c/sensor.py +1 -1
  214. esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
  215. esphome/components/gpio/switch/gpio_switch.cpp +0 -2
  216. esphome/components/gpio_expander/cached_gpio.h +24 -15
  217. esphome/components/gps/__init__.py +6 -2
  218. esphome/components/gps/gps.cpp +50 -49
  219. esphome/components/gps/gps.h +4 -8
  220. esphome/components/gps/time/gps_time.cpp +3 -9
  221. esphome/components/gps/time/gps_time.h +4 -7
  222. esphome/components/graph/__init__.py +1 -1
  223. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
  224. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
  225. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
  227. esphome/components/haier/climate.py +5 -10
  228. esphome/components/haier/haier_base.cpp +0 -1
  229. esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
  230. esphome/components/hdc1080/hdc1080.cpp +0 -2
  231. esphome/components/heatpumpir/climate.py +2 -2
  232. esphome/components/hlw8012/hlw8012.cpp +0 -1
  233. esphome/components/hm3301/hm3301.cpp +0 -1
  234. esphome/components/hmc5883l/hmc5883l.cpp +0 -1
  235. esphome/components/homeassistant/__init__.py +1 -0
  236. esphome/components/homeassistant/number/__init__.py +1 -0
  237. esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
  238. esphome/components/homeassistant/switch/__init__.py +1 -0
  239. esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
  240. esphome/components/honeywellabp/honeywellabp.cpp +1 -4
  241. esphome/components/host/__init__.py +2 -0
  242. esphome/components/hte501/hte501.cpp +0 -1
  243. esphome/components/http_request/__init__.py +2 -3
  244. esphome/components/http_request/http_request_idf.cpp +2 -2
  245. esphome/components/htu21d/htu21d.cpp +0 -2
  246. esphome/components/htu31d/htu31d.cpp +0 -2
  247. esphome/components/hx711/hx711.cpp +0 -1
  248. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
  249. esphome/components/hydreon_rgxx/sensor.py +4 -5
  250. esphome/components/i2c/i2c_bus.h +1 -1
  251. esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
  252. esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
  253. esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
  254. esphome/components/i2s_audio/__init__.py +6 -5
  255. esphome/components/i2s_audio/i2s_audio.cpp +0 -2
  256. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
  257. esphome/components/i2s_audio/microphone/__init__.py +4 -6
  258. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +0 -1
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +2 -2
  260. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
  262. esphome/components/ili9xxx/display.py +4 -3
  263. esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
  264. esphome/components/image/__init__.py +123 -92
  265. esphome/components/improv_serial/__init__.py +7 -8
  266. esphome/components/ina219/ina219.cpp +0 -1
  267. esphome/components/ina226/ina226.cpp +0 -2
  268. esphome/components/ina260/ina260.cpp +0 -2
  269. esphome/components/ina2xx_base/__init__.py +2 -5
  270. esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
  271. esphome/components/ina3221/ina3221.cpp +0 -1
  272. esphome/components/internal_temperature/internal_temperature.cpp +0 -2
  273. esphome/components/interval/interval.h +5 -9
  274. esphome/components/json/__init__.py +1 -1
  275. esphome/components/kmeteriso/kmeteriso.cpp +0 -2
  276. esphome/components/lc709203f/lc709203f.cpp +0 -2
  277. esphome/components/lcd_gpio/display.py +1 -3
  278. esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
  279. esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
  280. esphome/components/ld2410/__init__.py +4 -6
  281. esphome/components/ld2410/binary_sensor.py +4 -0
  282. esphome/components/ld2410/ld2410.cpp +56 -100
  283. esphome/components/ld2410/ld2410.h +17 -15
  284. esphome/components/ld2410/sensor.py +24 -10
  285. esphome/components/ld2412/__init__.py +46 -0
  286. esphome/components/ld2412/binary_sensor.py +70 -0
  287. esphome/components/ld2412/button/__init__.py +74 -0
  288. esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
  289. esphome/components/ld2412/button/factory_reset_button.h +18 -0
  290. esphome/components/ld2412/button/query_button.cpp +9 -0
  291. esphome/components/ld2412/button/query_button.h +18 -0
  292. esphome/components/ld2412/button/restart_button.cpp +9 -0
  293. esphome/components/ld2412/button/restart_button.h +18 -0
  294. esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
  295. esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
  296. esphome/components/ld2412/ld2412.cpp +861 -0
  297. esphome/components/ld2412/ld2412.h +141 -0
  298. esphome/components/ld2412/number/__init__.py +126 -0
  299. esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
  300. esphome/components/ld2412/number/gate_threshold_number.h +19 -0
  301. esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
  302. esphome/components/ld2412/number/light_threshold_number.h +18 -0
  303. esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
  304. esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
  305. esphome/components/ld2412/select/__init__.py +82 -0
  306. esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
  307. esphome/components/ld2412/select/baud_rate_select.h +18 -0
  308. esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
  309. esphome/components/ld2412/select/distance_resolution_select.h +18 -0
  310. esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
  311. esphome/components/ld2412/select/light_out_control_select.h +18 -0
  312. esphome/components/ld2412/sensor.py +124 -0
  313. esphome/components/ld2412/switch/__init__.py +45 -0
  314. esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
  315. esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
  316. esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
  317. esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
  318. esphome/components/ld2412/text_sensor.py +34 -0
  319. esphome/components/ld2420/ld2420.cpp +0 -1
  320. esphome/components/ld2450/__init__.py +3 -4
  321. esphome/components/ld2450/binary_sensor.py +3 -0
  322. esphome/components/ld2450/ld2450.cpp +77 -165
  323. esphome/components/ld2450/ld2450.h +26 -54
  324. esphome/components/ld2450/sensor.py +120 -6
  325. esphome/components/ld2450/text_sensor.py +5 -4
  326. esphome/components/ld24xx/__init__.py +1 -0
  327. esphome/components/ld24xx/ld24xx.h +65 -0
  328. esphome/components/ledc/ledc_output.cpp +0 -1
  329. esphome/components/libretiny/__init__.py +2 -0
  330. esphome/components/light/__init__.py +0 -1
  331. esphome/components/light/effects.py +70 -45
  332. esphome/components/light/light_call.cpp +101 -66
  333. esphome/components/light/light_color_values.h +16 -11
  334. esphome/components/light/light_json_schema.cpp +46 -44
  335. esphome/components/light/light_state.cpp +8 -11
  336. esphome/components/light/light_traits.h +17 -0
  337. esphome/components/lightwaverf/lightwaverf.cpp +0 -2
  338. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
  339. esphome/components/lock/__init__.py +0 -1
  340. esphome/components/logger/__init__.py +31 -9
  341. esphome/components/logger/logger.cpp +12 -7
  342. esphome/components/logger/logger.h +25 -14
  343. esphome/components/logger/logger_esp32.cpp +2 -7
  344. esphome/components/logger/logger_esp8266.cpp +2 -4
  345. esphome/components/logger/logger_host.cpp +2 -4
  346. esphome/components/logger/logger_libretiny.cpp +2 -4
  347. esphome/components/logger/logger_rp2040.cpp +2 -4
  348. esphome/components/logger/logger_zephyr.cpp +86 -0
  349. esphome/components/logger/select/logger_level_select.cpp +2 -4
  350. esphome/components/logger/select/logger_level_select.h +2 -4
  351. esphome/components/logger/task_log_buffer.cpp +2 -4
  352. esphome/components/logger/task_log_buffer.h +2 -4
  353. esphome/components/lps22/sensor.py +5 -5
  354. esphome/components/ltr390/ltr390.cpp +0 -2
  355. esphome/components/ltr501/ltr501.cpp +0 -1
  356. esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
  357. esphome/components/lvgl/__init__.py +14 -13
  358. esphome/components/lvgl/automation.py +2 -4
  359. esphome/components/lvgl/defines.py +0 -2
  360. esphome/components/lvgl/helpers.py +1 -1
  361. esphome/components/lvgl/lv_validation.py +7 -4
  362. esphome/components/lvgl/lvgl_esphome.cpp +2 -3
  363. esphome/components/lvgl/styles.py +2 -2
  364. esphome/components/lvgl/types.py +1 -1
  365. esphome/components/lvgl/widgets/__init__.py +2 -2
  366. esphome/components/lvgl/widgets/arc.py +14 -11
  367. esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
  368. esphome/components/lvgl/widgets/qrcode.py +7 -7
  369. esphome/components/lvgl/widgets/spinner.py +6 -6
  370. esphome/components/lvgl/widgets/switch.py +2 -2
  371. esphome/components/lvgl/widgets/tabview.py +3 -3
  372. esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
  373. esphome/components/matrix_keypad/__init__.py +4 -3
  374. esphome/components/max17043/max17043.cpp +0 -2
  375. esphome/components/max31855/max31855.cpp +1 -4
  376. esphome/components/max31856/max31856.cpp +0 -4
  377. esphome/components/max31865/max31865.cpp +0 -1
  378. esphome/components/max44009/max44009.cpp +0 -1
  379. esphome/components/max6675/max6675.cpp +1 -4
  380. esphome/components/max6956/max6956.cpp +0 -1
  381. esphome/components/max7219/max7219.cpp +0 -1
  382. esphome/components/max7219digit/display.py +1 -1
  383. esphome/components/max7219digit/max7219digit.cpp +0 -1
  384. esphome/components/max9611/max9611.cpp +0 -1
  385. esphome/components/mcp23008/__init__.py +1 -1
  386. esphome/components/mcp23008/mcp23008.cpp +0 -1
  387. esphome/components/mcp23016/mcp23016.cpp +0 -1
  388. esphome/components/mcp23017/__init__.py +1 -1
  389. esphome/components/mcp23017/mcp23017.cpp +0 -1
  390. esphome/components/mcp23s08/__init__.py +1 -1
  391. esphome/components/mcp23s08/mcp23s08.cpp +0 -1
  392. esphome/components/mcp23s17/__init__.py +1 -1
  393. esphome/components/mcp23s17/mcp23s17.cpp +0 -1
  394. esphome/components/mcp23x08_base/__init__.py +2 -0
  395. esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
  396. esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
  397. esphome/components/mcp23x17_base/__init__.py +2 -0
  398. esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
  399. esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
  400. esphome/components/mcp23xxx_base/__init__.py +11 -5
  401. esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
  402. esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
  403. esphome/components/mcp3008/mcp3008.cpp +1 -4
  404. esphome/components/mcp3204/mcp3204.cpp +1 -4
  405. esphome/components/mcp4461/mcp4461.cpp +0 -1
  406. esphome/components/mcp4725/mcp4725.cpp +0 -1
  407. esphome/components/mcp4728/mcp4728.cpp +0 -1
  408. esphome/components/mcp9600/mcp9600.cpp +0 -2
  409. esphome/components/mcp9808/mcp9808.cpp +0 -2
  410. esphome/components/mdns/__init__.py +3 -0
  411. esphome/components/mdns/mdns_component.cpp +2 -0
  412. esphome/components/mdns/mdns_component.h +4 -0
  413. esphome/components/media_player/__init__.py +40 -0
  414. esphome/components/media_player/automation.h +16 -0
  415. esphome/components/media_player/media_player.cpp +13 -0
  416. esphome/components/media_player/media_player.h +50 -3
  417. esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
  418. esphome/components/mics_4514/mics_4514.cpp +1 -6
  419. esphome/components/midea/ir_transmitter.h +4 -4
  420. esphome/components/mipi/__init__.py +416 -0
  421. esphome/components/mipi_dsi/__init__.py +5 -0
  422. esphome/components/mipi_dsi/display.py +233 -0
  423. esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
  424. esphome/components/mipi_dsi/mipi_dsi.h +123 -0
  425. esphome/components/mipi_dsi/models/__init__.py +0 -0
  426. esphome/components/mipi_dsi/models/guition.py +38 -0
  427. esphome/components/mipi_dsi/models/m5stack.py +57 -0
  428. esphome/components/mipi_dsi/models/waveshare.py +105 -0
  429. esphome/components/mipi_rgb/models/lilygo.py +0 -0
  430. esphome/components/mipi_spi/__init__.py +0 -9
  431. esphome/components/mipi_spi/display.py +220 -256
  432. esphome/components/mipi_spi/mipi_spi.cpp +1 -485
  433. esphome/components/mipi_spi/mipi_spi.h +556 -108
  434. esphome/components/mipi_spi/models/__init__.py +0 -65
  435. esphome/components/mipi_spi/models/adafruit.py +30 -0
  436. esphome/components/mipi_spi/models/amoled.py +41 -5
  437. esphome/components/mipi_spi/models/ili.py +5 -5
  438. esphome/components/mipi_spi/models/jc.py +1 -3
  439. esphome/components/mipi_spi/models/lilygo.py +1 -1
  440. esphome/components/mipi_spi/models/waveshare.py +16 -1
  441. esphome/components/mixer/speaker/__init__.py +4 -5
  442. esphome/components/mlx90393/sensor.py +7 -5
  443. esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
  444. esphome/components/mlx90614/mlx90614.cpp +0 -1
  445. esphome/components/mmc5603/mmc5603.cpp +0 -1
  446. esphome/components/mmc5983/mmc5983.cpp +0 -2
  447. esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
  448. esphome/components/mpr121/__init__.py +7 -6
  449. esphome/components/mpr121/mpr121.cpp +0 -1
  450. esphome/components/mpu6050/mpu6050.cpp +0 -1
  451. esphome/components/mpu6886/mpu6886.cpp +0 -1
  452. esphome/components/mqtt/__init__.py +1 -2
  453. esphome/components/mqtt/mqtt_button.cpp +1 -1
  454. esphome/components/mqtt/mqtt_client.cpp +0 -1
  455. esphome/components/mqtt/mqtt_component.cpp +8 -14
  456. esphome/components/mqtt/mqtt_component.h +0 -7
  457. esphome/components/mqtt/mqtt_sensor.cpp +0 -1
  458. esphome/components/mqtt/mqtt_sensor.h +0 -1
  459. esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
  460. esphome/components/mqtt/mqtt_text_sensor.h +0 -1
  461. esphome/components/ms5611/ms5611.cpp +0 -1
  462. esphome/components/ms8607/ms8607.cpp +0 -1
  463. esphome/components/msa3xx/msa3xx.cpp +0 -2
  464. esphome/components/my9231/my9231.cpp +0 -2
  465. esphome/components/nau7802/nau7802.cpp +0 -1
  466. esphome/components/neopixelbus/light.py +3 -0
  467. esphome/components/network/util.cpp +29 -0
  468. esphome/components/nextion/nextion.cpp +0 -1
  469. esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
  470. esphome/components/npi19/npi19.cpp +0 -2
  471. esphome/components/nrf52/__init__.py +223 -0
  472. esphome/components/nrf52/boards.py +34 -0
  473. esphome/components/nrf52/const.py +18 -0
  474. esphome/components/nrf52/gpio.py +79 -0
  475. esphome/components/number/__init__.py +2 -1
  476. esphome/components/one_wire/__init__.py +1 -2
  477. esphome/components/one_wire/one_wire.cpp +0 -2
  478. esphome/components/one_wire/one_wire.h +0 -2
  479. esphome/components/opentherm/hub.cpp +0 -1
  480. esphome/components/opentherm/number/__init__.py +2 -2
  481. esphome/components/openthread/__init__.py +2 -3
  482. esphome/components/openthread/openthread.cpp +30 -13
  483. esphome/components/openthread/openthread.h +3 -0
  484. esphome/components/openthread/openthread_esp.cpp +3 -1
  485. esphome/components/opt3001/sensor.py +2 -6
  486. esphome/components/output/__init__.py +38 -0
  487. esphome/components/output/automation.h +24 -0
  488. esphome/components/output/switch/output_switch.cpp +0 -2
  489. esphome/components/packages/__init__.py +1 -2
  490. esphome/components/packet_transport/__init__.py +4 -3
  491. esphome/components/pca6416a/pca6416a.cpp +0 -1
  492. esphome/components/pca9554/pca9554.cpp +0 -1
  493. esphome/components/pca9685/pca9685_output.cpp +0 -2
  494. esphome/components/pcf85063/pcf85063.cpp +0 -1
  495. esphome/components/pcf8563/pcf8563.cpp +0 -1
  496. esphome/components/pcf8574/pcf8574.cpp +0 -1
  497. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
  498. esphome/components/pipsolar/sensor/__init__.py +1 -1
  499. esphome/components/pm2005/pm2005.cpp +0 -1
  500. esphome/components/pmsa003i/pmsa003i.cpp +0 -2
  501. esphome/components/pmwcs3/sensor.py +1 -2
  502. esphome/components/pn532/pn532.cpp +0 -2
  503. esphome/components/pn532_spi/pn532_spi.cpp +0 -2
  504. esphome/components/power_supply/power_supply.cpp +7 -10
  505. esphome/components/power_supply/power_supply.h +1 -1
  506. esphome/components/psram/__init__.py +6 -1
  507. esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
  508. esphome/components/pulse_counter/sensor.py +9 -6
  509. esphome/components/pylontech/pylontech.cpp +0 -1
  510. esphome/components/qmc5883l/qmc5883l.cpp +0 -1
  511. esphome/components/qmp6988/qmp6988.cpp +0 -2
  512. esphome/components/qspi_dbi/display.py +2 -3
  513. esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
  514. esphome/components/qwiic_pir/binary_sensor.py +2 -3
  515. esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
  516. esphome/components/rc522/rc522.cpp +9 -31
  517. esphome/components/rc522_spi/rc522_spi.cpp +0 -1
  518. esphome/components/remote_base/__init__.py +5 -6
  519. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
  520. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
  521. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
  522. esphome/components/remote_transmitter/__init__.py +26 -0
  523. esphome/components/remote_transmitter/automation.h +18 -0
  524. esphome/components/remote_transmitter/remote_transmitter.h +2 -1
  525. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
  526. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
  527. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
  528. esphome/components/resampler/speaker/__init__.py +4 -5
  529. esphome/components/rf_bridge/__init__.py +4 -8
  530. esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
  531. esphome/components/rp2040/__init__.py +3 -1
  532. esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
  533. esphome/components/rp2040_pio_led_strip/light.py +1 -2
  534. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
  535. esphome/components/rpi_dpi_rgb/display.py +13 -15
  536. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
  537. esphome/components/runtime_stats/__init__.py +34 -0
  538. esphome/components/runtime_stats/runtime_stats.cpp +102 -0
  539. esphome/components/runtime_stats/runtime_stats.h +132 -0
  540. esphome/components/scd30/scd30.cpp +0 -2
  541. esphome/components/scd30/sensor.py +1 -2
  542. esphome/components/scd4x/scd4x.cpp +0 -1
  543. esphome/components/scd4x/sensor.py +1 -3
  544. esphome/components/sdl/display.py +3 -1
  545. esphome/components/sdl/sdl_esphome.cpp +0 -2
  546. esphome/components/sdp3x/sdp3x.cpp +0 -2
  547. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
  548. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
  549. esphome/components/select/__init__.py +2 -3
  550. esphome/components/select/select_traits.cpp +1 -1
  551. esphome/components/select/select_traits.h +1 -1
  552. esphome/components/sen0321/sen0321.cpp +0 -1
  553. esphome/components/sen5x/sen5x.cpp +0 -2
  554. esphome/components/sensor/__init__.py +36 -4
  555. esphome/components/sensor/filter.cpp +49 -10
  556. esphome/components/sensor/filter.h +22 -7
  557. esphome/components/sensor/sensor.cpp +0 -1
  558. esphome/components/sensor/sensor.h +0 -9
  559. esphome/components/sfa30/sfa30.cpp +0 -4
  560. esphome/components/sgp30/sgp30.cpp +0 -2
  561. esphome/components/sgp4x/sensor.py +1 -1
  562. esphome/components/sgp4x/sgp4x.cpp +0 -2
  563. esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
  564. esphome/components/sht3xd/sht3xd.cpp +0 -2
  565. esphome/components/sht4x/sht4x.cpp +0 -2
  566. esphome/components/shtcx/shtcx.cpp +0 -1
  567. esphome/components/sim800l/__init__.py +2 -4
  568. esphome/components/sm16716/sm16716.cpp +0 -1
  569. esphome/components/sm2135/sm2135.cpp +0 -1
  570. esphome/components/sm2235/sm2235.cpp +0 -1
  571. esphome/components/sm2335/sm2335.cpp +0 -1
  572. esphome/components/sn74hc165/sn74hc165.cpp +0 -1
  573. esphome/components/sn74hc595/sn74hc595.cpp +0 -1
  574. esphome/components/sntp/sntp_component.cpp +0 -1
  575. esphome/components/sound_level/sensor.py +1 -1
  576. esphome/components/speaker/media_player/__init__.py +21 -33
  577. esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
  578. esphome/components/spi/__init__.py +29 -13
  579. esphome/components/spi/spi.cpp +0 -2
  580. esphome/components/spi_device/spi_device.cpp +1 -4
  581. esphome/components/sprinkler/__init__.py +4 -4
  582. esphome/components/sps30/sps30.cpp +0 -1
  583. esphome/components/ssd1306_base/__init__.py +11 -11
  584. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  585. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
  586. esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
  587. esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
  588. esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
  589. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
  590. esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
  591. esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
  592. esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
  593. esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
  594. esphome/components/st7567_spi/st7567_spi.cpp +0 -1
  595. esphome/components/st7701s/display.py +10 -14
  596. esphome/components/st7701s/st7701s.cpp +0 -3
  597. esphome/components/st7735/st7735.cpp +0 -1
  598. esphome/components/st7789v/st7789v.cpp +0 -1
  599. esphome/components/st7920/st7920.cpp +0 -1
  600. esphome/components/status_led/light/status_led_light.cpp +0 -2
  601. esphome/components/status_led/status_led.cpp +0 -1
  602. esphome/components/stepper/__init__.py +2 -4
  603. esphome/components/sts3x/sts3x.cpp +0 -1
  604. esphome/components/substitutions/__init__.py +10 -16
  605. esphome/components/substitutions/jinja.py +24 -1
  606. esphome/components/sun/__init__.py +2 -3
  607. esphome/components/switch/__init__.py +31 -1
  608. esphome/components/switch/automation.h +24 -0
  609. esphome/components/switch/switch.cpp +8 -0
  610. esphome/components/switch/switch.h +8 -0
  611. esphome/components/sx126x/sx126x.cpp +0 -2
  612. esphome/components/sx127x/sx127x.cpp +0 -2
  613. esphome/components/sx1509/__init__.py +7 -5
  614. esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
  615. esphome/components/sx1509/sx1509.cpp +0 -2
  616. esphome/components/syslog/esphome_syslog.cpp +1 -1
  617. esphome/components/tc74/tc74.cpp +0 -1
  618. esphome/components/tca9548a/tca9548a.cpp +0 -1
  619. esphome/components/tca9555/tca9555.cpp +0 -1
  620. esphome/components/tcs34725/tcs34725.cpp +0 -1
  621. esphome/components/tee501/tee501.cpp +0 -1
  622. esphome/components/tem3200/tem3200.cpp +0 -2
  623. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
  624. esphome/components/template/cover/template_cover.cpp +0 -1
  625. esphome/components/template/select/template_select.cpp +0 -1
  626. esphome/components/template/text/template_text.cpp +0 -2
  627. esphome/components/template/valve/template_valve.cpp +0 -1
  628. esphome/components/text/__init__.py +0 -1
  629. esphome/components/text/text_traits.h +2 -0
  630. esphome/components/text_sensor/__init__.py +2 -1
  631. esphome/components/text_sensor/text_sensor.cpp +0 -2
  632. esphome/components/text_sensor/text_sensor.h +0 -8
  633. esphome/components/thermostat/climate.py +4 -4
  634. esphome/components/time/__init__.py +7 -4
  635. esphome/components/time/real_time_clock.cpp +16 -3
  636. esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
  637. esphome/components/tlc5947/tlc5947.cpp +0 -2
  638. esphome/components/tlc5971/tlc5971.cpp +0 -2
  639. esphome/components/tm1621/tm1621.cpp +0 -2
  640. esphome/components/tm1637/tm1637.cpp +0 -2
  641. esphome/components/tm1638/tm1638.cpp +0 -2
  642. esphome/components/tm1651/__init__.py +45 -48
  643. esphome/components/tm1651/tm1651.cpp +213 -47
  644. esphome/components/tm1651/tm1651.h +37 -32
  645. esphome/components/tmp117/tmp117.cpp +0 -2
  646. esphome/components/tsl2561/tsl2561.cpp +0 -1
  647. esphome/components/tsl2591/tsl2591.cpp +0 -1
  648. esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
  649. esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
  650. esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
  651. esphome/components/tuya/climate/__init__.py +9 -10
  652. esphome/components/tuya/number/__init__.py +8 -6
  653. esphome/components/tx20/tx20.cpp +0 -1
  654. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
  655. esphome/components/uart/uart_component_esp8266.cpp +0 -1
  656. esphome/components/uart/uart_component_esp_idf.cpp +0 -2
  657. esphome/components/uart/uart_component_libretiny.cpp +0 -2
  658. esphome/components/uart/uart_component_rp2040.cpp +0 -2
  659. esphome/components/udp/__init__.py +1 -1
  660. esphome/components/ufire_ec/sensor.py +1 -2
  661. esphome/components/ufire_ec/ufire_ec.cpp +0 -2
  662. esphome/components/ufire_ise/sensor.py +1 -2
  663. esphome/components/ufire_ise/ufire_ise.cpp +0 -2
  664. esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
  665. esphome/components/update/__init__.py +0 -1
  666. esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
  667. esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
  668. esphome/components/usb_host/usb_host_client.cpp +0 -1
  669. esphome/components/usb_host/usb_host_component.cpp +0 -1
  670. esphome/components/valve/__init__.py +0 -1
  671. esphome/components/veml3235/veml3235.cpp +0 -3
  672. esphome/components/veml7700/veml7700.cpp +0 -2
  673. esphome/components/version/version_text_sensor.cpp +0 -1
  674. esphome/components/version/version_text_sensor.h +0 -1
  675. esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
  676. esphome/components/voice_assistant/voice_assistant.cpp +9 -8
  677. esphome/components/web_server/__init__.py +13 -0
  678. esphome/components/web_server/web_server.cpp +187 -352
  679. esphome/components/web_server/web_server.h +61 -1
  680. esphome/components/web_server_base/__init__.py +1 -1
  681. esphome/components/web_server_base/web_server_base.cpp +2 -0
  682. esphome/components/web_server_base/web_server_base.h +6 -0
  683. esphome/components/web_server_idf/web_server_idf.cpp +10 -8
  684. esphome/components/web_server_idf/web_server_idf.h +2 -0
  685. esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
  686. esphome/components/weikai_spi/weikai_spi.cpp +1 -1
  687. esphome/components/wifi/__init__.py +8 -43
  688. esphome/components/wifi/wifi_component.cpp +100 -36
  689. esphome/components/wifi/wifi_component.h +5 -1
  690. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
  691. esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
  692. esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
  693. esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
  694. esphome/components/wireguard/wireguard.cpp +0 -2
  695. esphome/components/x9c/x9c.cpp +0 -2
  696. esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
  697. esphome/components/xl9535/xl9535.cpp +0 -2
  698. esphome/components/zephyr/__init__.py +252 -0
  699. esphome/components/zephyr/const.py +16 -0
  700. esphome/components/zephyr/core.cpp +90 -0
  701. esphome/components/zephyr/gpio.cpp +120 -0
  702. esphome/components/zephyr/gpio.h +38 -0
  703. esphome/components/zephyr/pre_build.py.script +4 -0
  704. esphome/components/zephyr/preferences.cpp +156 -0
  705. esphome/components/zephyr/preferences.h +13 -0
  706. esphome/config.py +38 -16
  707. esphome/config_helpers.py +1 -2
  708. esphome/config_validation.py +12 -16
  709. esphome/const.py +26 -1
  710. esphome/core/__init__.py +88 -51
  711. esphome/core/application.cpp +75 -21
  712. esphome/core/application.h +106 -171
  713. esphome/core/color.h +10 -0
  714. esphome/core/component.cpp +41 -25
  715. esphome/core/component.h +9 -6
  716. esphome/core/component_iterator.cpp +61 -261
  717. esphome/core/component_iterator.h +15 -0
  718. esphome/core/config.py +26 -11
  719. esphome/core/defines.h +40 -2
  720. esphome/core/entity_base.h +18 -0
  721. esphome/core/entity_helpers.py +45 -10
  722. esphome/core/helpers.cpp +8 -15
  723. esphome/core/helpers.h +60 -6
  724. esphome/core/lock_free_queue.h +1 -1
  725. esphome/core/scheduler.cpp +277 -74
  726. esphome/core/scheduler.h +89 -27
  727. esphome/cpp_generator.py +2 -6
  728. esphome/cpp_helpers.py +1 -1
  729. esphome/dashboard/dashboard.py +2 -3
  730. esphome/dashboard/dns.py +2 -8
  731. esphome/dashboard/web_server.py +34 -19
  732. esphome/espota2.py +1 -4
  733. esphome/git.py +3 -1
  734. esphome/helpers.py +23 -4
  735. esphome/log.py +3 -1
  736. esphome/mqtt.py +3 -5
  737. esphome/platformio_api.py +7 -4
  738. esphome/types.py +12 -0
  739. esphome/util.py +20 -8
  740. esphome/voluptuous_schema.py +4 -3
  741. esphome/vscode.py +1 -2
  742. esphome/wizard.py +1 -4
  743. esphome/writer.py +5 -107
  744. esphome/yaml_util.py +7 -5
  745. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/METADATA +13 -14
  746. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/RECORD +751 -671
  747. esphome/components/mipi_spi/models/commands.py +0 -82
  748. /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
  749. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/WHEEL +0 -0
  750. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/entry_points.txt +0 -0
  751. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/licenses/LICENSE +0 -0
  752. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  import re
2
+ from typing import Any
2
3
 
3
4
  from esphome import pins
4
5
  import esphome.codegen as cg
@@ -114,9 +115,7 @@ def get_target_platform():
114
115
 
115
116
 
116
117
  def get_target_variant():
117
- return (
118
- CORE.data[KEY_ESP32][KEY_VARIANT] if KEY_VARIANT in CORE.data[KEY_ESP32] else ""
119
- )
118
+ return CORE.data[KEY_ESP32].get(KEY_VARIANT, "")
120
119
 
121
120
 
122
121
  # Get a list of available hardware interfaces based on target and variant.
@@ -139,6 +138,27 @@ def get_hw_interface_list():
139
138
  return []
140
139
 
141
140
 
141
+ def one_of_interface_validator(additional_values: list[str] | None = None) -> Any:
142
+ """Helper to create a one_of validator for SPI interfaces.
143
+
144
+ This delays evaluation of get_hw_interface_list() until validation time,
145
+ avoiding access to CORE.data during module import.
146
+
147
+ Args:
148
+ additional_values: List of additional valid values to include
149
+ """
150
+ if additional_values is None:
151
+ additional_values = []
152
+
153
+ def validator(value: str) -> str:
154
+ return cv.one_of(
155
+ *sum(get_hw_interface_list(), additional_values),
156
+ lower=True,
157
+ )(value)
158
+
159
+ return cv.All(cv.string, validator)
160
+
161
+
142
162
  # Given an SPI name, return the index of it in the available list
143
163
  def get_spi_index(name):
144
164
  for i, ilist in enumerate(get_hw_interface_list()):
@@ -191,9 +211,7 @@ def validate_hw_pins(spi, index=-1):
191
211
  return False
192
212
  if sdo_pin_no not in pin_set[CONF_MOSI_PIN]:
193
213
  return False
194
- if sdi_pin_no not in pin_set[CONF_MISO_PIN]:
195
- return False
196
- return True
214
+ return sdi_pin_no in pin_set[CONF_MISO_PIN]
197
215
  return False
198
216
 
199
217
 
@@ -274,9 +292,8 @@ SPI_SINGLE_SCHEMA = cv.All(
274
292
  cv.Optional(CONF_FORCE_SW): cv.invalid(
275
293
  "force_sw is deprecated - use interface: software"
276
294
  ),
277
- cv.Optional(CONF_INTERFACE, default="any"): cv.one_of(
278
- *sum(get_hw_interface_list(), ["software", "hardware", "any"]),
279
- lower=True,
295
+ cv.Optional(CONF_INTERFACE, default="any"): one_of_interface_validator(
296
+ ["software", "hardware", "any"]
280
297
  ),
281
298
  cv.Optional(CONF_DATA_PINS): cv.invalid(
282
299
  "'data_pins' should be used with 'type: quad or octal' only"
@@ -309,10 +326,9 @@ def spi_mode_schema(mode):
309
326
  cv.ensure_list(pins.internal_gpio_output_pin_number),
310
327
  cv.Length(min=pin_count, max=pin_count),
311
328
  ),
312
- cv.Optional(CONF_INTERFACE, default="hardware"): cv.one_of(
313
- *sum(get_hw_interface_list(), ["hardware"]),
314
- lower=True,
315
- ),
329
+ cv.Optional(
330
+ CONF_INTERFACE, default="hardware"
331
+ ): one_of_interface_validator(["hardware"]),
316
332
  cv.Optional(CONF_MISO_PIN): cv.invalid(
317
333
  f"'miso_pin' should not be used with {mode} SPI"
318
334
  ),
@@ -37,8 +37,6 @@ void SPIComponent::unregister_device(SPIClient *device) {
37
37
  }
38
38
 
39
39
  void SPIComponent::setup() {
40
- ESP_LOGCONFIG(TAG, "Running setup");
41
-
42
40
  if (this->sdo_pin_ == nullptr)
43
41
  this->sdo_pin_ = NullPin::NULL_PIN;
44
42
  if (this->sdi_pin_ == nullptr)
@@ -8,10 +8,7 @@ namespace spi_device {
8
8
 
9
9
  static const char *const TAG = "spi_device";
10
10
 
11
- void SPIDeviceComponent::setup() {
12
- ESP_LOGCONFIG(TAG, "Running setup");
13
- this->spi_setup();
14
- }
11
+ void SPIDeviceComponent::setup() { this->spi_setup(); }
15
12
 
16
13
  void SPIDeviceComponent::dump_config() {
17
14
  ESP_LOGCONFIG(TAG, "SPIDevice");
@@ -130,11 +130,11 @@ def validate_sprinkler(config):
130
130
  if (
131
131
  CONF_PUMP_SWITCH_OFF_DURING_VALVE_OPEN_DELAY in sprinkler_controller
132
132
  and CONF_VALVE_OPEN_DELAY not in sprinkler_controller
133
+ and sprinkler_controller[CONF_PUMP_SWITCH_OFF_DURING_VALVE_OPEN_DELAY]
133
134
  ):
134
- if sprinkler_controller[CONF_PUMP_SWITCH_OFF_DURING_VALVE_OPEN_DELAY]:
135
- raise cv.Invalid(
136
- f"{CONF_VALVE_OPEN_DELAY} must be defined when {CONF_PUMP_SWITCH_OFF_DURING_VALVE_OPEN_DELAY} is enabled"
137
- )
135
+ raise cv.Invalid(
136
+ f"{CONF_VALVE_OPEN_DELAY} must be defined when {CONF_PUMP_SWITCH_OFF_DURING_VALVE_OPEN_DELAY} is enabled"
137
+ )
138
138
 
139
139
  if (
140
140
  CONF_REPEAT in sprinkler_controller
@@ -22,7 +22,6 @@ static const size_t SERIAL_NUMBER_LENGTH = 8;
22
22
  static const uint8_t MAX_SKIPPED_DATA_CYCLES_BEFORE_ERROR = 5;
23
23
 
24
24
  void SPS30Component::setup() {
25
- ESP_LOGCONFIG(TAG, "Running setup");
26
25
  this->write_command(SPS30_CMD_SOFT_RESET);
27
26
  /// Deferred Sensor initialization
28
27
  this->set_timeout(500, [this]() {
@@ -6,6 +6,8 @@ from esphome.const import (
6
6
  CONF_BRIGHTNESS,
7
7
  CONF_CONTRAST,
8
8
  CONF_EXTERNAL_VCC,
9
+ CONF_FLIP_X,
10
+ CONF_FLIP_Y,
9
11
  CONF_INVERT,
10
12
  CONF_LAMBDA,
11
13
  CONF_MODEL,
@@ -18,9 +20,6 @@ ssd1306_base_ns = cg.esphome_ns.namespace("ssd1306_base")
18
20
  SSD1306 = ssd1306_base_ns.class_("SSD1306", cg.PollingComponent, display.DisplayBuffer)
19
21
  SSD1306Model = ssd1306_base_ns.enum("SSD1306Model")
20
22
 
21
- CONF_FLIP_X = "flip_x"
22
- CONF_FLIP_Y = "flip_y"
23
-
24
23
  MODELS = {
25
24
  "SSD1306_128X32": SSD1306Model.SSD1306_MODEL_128_32,
26
25
  "SSD1306_128X64": SSD1306Model.SSD1306_MODEL_128_64,
@@ -43,14 +42,15 @@ SSD1306_MODEL = cv.enum(MODELS, upper=True, space="_")
43
42
 
44
43
  def _validate(value):
45
44
  model = value[CONF_MODEL]
46
- if model not in ("SSD1305_128X32", "SSD1305_128X64"):
47
- # Contrast is default value (1.0) while brightness is not
48
- # Indicates user is using old `brightness` option
49
- if value[CONF_BRIGHTNESS] != 1.0 and value[CONF_CONTRAST] == 1.0:
50
- raise cv.Invalid(
51
- "SSD1306/SH1106 no longer accepts brightness option, "
52
- 'please use "contrast" instead.'
53
- )
45
+ if (
46
+ model not in ("SSD1305_128X32", "SSD1305_128X64")
47
+ and value[CONF_BRIGHTNESS] != 1.0
48
+ and value[CONF_CONTRAST] == 1.0
49
+ ):
50
+ raise cv.Invalid(
51
+ "SSD1306/SH1106 no longer accepts brightness option, "
52
+ 'please use "contrast" instead.'
53
+ )
54
54
 
55
55
  return value
56
56
 
@@ -176,7 +176,7 @@ void SSD1306::setup() {
176
176
  // Disable scrolling mode (0x2E)
177
177
  this->command(SSD1306_COMMAND_DEACTIVATE_SCROLL);
178
178
 
179
- // Contrast and brighrness
179
+ // Contrast and brightness
180
180
  // SSD1306 does not have brightness setting
181
181
  set_contrast(this->contrast_);
182
182
  if (this->is_ssd1305_())
@@ -7,7 +7,6 @@ namespace ssd1306_i2c {
7
7
  static const char *const TAG = "ssd1306_i2c";
8
8
 
9
9
  void I2CSSD1306::setup() {
10
- ESP_LOGCONFIG(TAG, "Running setup");
11
10
  this->init_reset_();
12
11
 
13
12
  auto err = this->write(nullptr, 0);
@@ -8,7 +8,6 @@ namespace ssd1306_spi {
8
8
  static const char *const TAG = "ssd1306_spi";
9
9
 
10
10
  void SPISSD1306::setup() {
11
- ESP_LOGCONFIG(TAG, "Running setup");
12
11
  this->spi_setup();
13
12
  this->dc_pin_->setup(); // OUTPUT
14
13
 
@@ -8,7 +8,6 @@ namespace ssd1322_spi {
8
8
  static const char *const TAG = "ssd1322_spi";
9
9
 
10
10
  void SPISSD1322::setup() {
11
- ESP_LOGCONFIG(TAG, "Running setup");
12
11
  this->spi_setup();
13
12
  this->dc_pin_->setup(); // OUTPUT
14
13
  if (this->cs_)
@@ -8,7 +8,6 @@ namespace ssd1325_spi {
8
8
  static const char *const TAG = "ssd1325_spi";
9
9
 
10
10
  void SPISSD1325::setup() {
11
- ESP_LOGCONFIG(TAG, "Running setup");
12
11
  this->spi_setup();
13
12
  this->dc_pin_->setup(); // OUTPUT
14
13
  if (this->cs_)
@@ -7,7 +7,6 @@ namespace ssd1327_i2c {
7
7
  static const char *const TAG = "ssd1327_i2c";
8
8
 
9
9
  void I2CSSD1327::setup() {
10
- ESP_LOGCONFIG(TAG, "Running setup");
11
10
  this->init_reset_();
12
11
 
13
12
  auto err = this->write(nullptr, 0);
@@ -8,7 +8,6 @@ namespace ssd1327_spi {
8
8
  static const char *const TAG = "ssd1327_spi";
9
9
 
10
10
  void SPISSD1327::setup() {
11
- ESP_LOGCONFIG(TAG, "Running setup");
12
11
  this->spi_setup();
13
12
  this->dc_pin_->setup(); // OUTPUT
14
13
  if (this->cs_)
@@ -8,7 +8,6 @@ namespace ssd1331_spi {
8
8
  static const char *const TAG = "ssd1331_spi";
9
9
 
10
10
  void SPISSD1331::setup() {
11
- ESP_LOGCONFIG(TAG, "Running setup");
12
11
  this->spi_setup();
13
12
  this->dc_pin_->setup(); // OUTPUT
14
13
  if (this->cs_)
@@ -8,7 +8,6 @@ namespace ssd1351_spi {
8
8
  static const char *const TAG = "ssd1351_spi";
9
9
 
10
10
  void SPISSD1351::setup() {
11
- ESP_LOGCONFIG(TAG, "Running setup");
12
11
  this->spi_setup();
13
12
  this->dc_pin_->setup(); // OUTPUT
14
13
  if (this->cs_)
@@ -7,7 +7,6 @@ namespace st7567_i2c {
7
7
  static const char *const TAG = "st7567_i2c";
8
8
 
9
9
  void I2CST7567::setup() {
10
- ESP_LOGCONFIG(TAG, "Running setup");
11
10
  this->init_reset_();
12
11
 
13
12
  auto err = this->write(nullptr, 0);
@@ -7,7 +7,6 @@ namespace st7567_spi {
7
7
  static const char *const TAG = "st7567_spi";
8
8
 
9
9
  void SPIST7567::setup() {
10
- ESP_LOGCONFIG(TAG, "Running setup");
11
10
  this->spi_setup();
12
11
  this->dc_pin_->setup();
13
12
  if (this->cs_)
@@ -2,9 +2,17 @@ from esphome import pins
2
2
  import esphome.codegen as cg
3
3
  from esphome.components import display, spi
4
4
  from esphome.components.esp32 import const, only_on_variant
5
- from esphome.components.rpi_dpi_rgb.display import (
5
+ from esphome.components.mipi import (
6
+ CONF_DE_PIN,
7
+ CONF_HSYNC_BACK_PORCH,
8
+ CONF_HSYNC_FRONT_PORCH,
9
+ CONF_HSYNC_PULSE_WIDTH,
6
10
  CONF_PCLK_FREQUENCY,
7
11
  CONF_PCLK_INVERTED,
12
+ CONF_PCLK_PIN,
13
+ CONF_VSYNC_BACK_PORCH,
14
+ CONF_VSYNC_FRONT_PORCH,
15
+ CONF_VSYNC_PULSE_WIDTH,
8
16
  )
9
17
  import esphome.config_validation as cv
10
18
  from esphome.const import (
@@ -36,16 +44,6 @@ from esphome.core import TimePeriod
36
44
 
37
45
  from .init_sequences import ST7701S_INITS, cmd
38
46
 
39
- CONF_DE_PIN = "de_pin"
40
- CONF_PCLK_PIN = "pclk_pin"
41
-
42
- CONF_HSYNC_PULSE_WIDTH = "hsync_pulse_width"
43
- CONF_HSYNC_BACK_PORCH = "hsync_back_porch"
44
- CONF_HSYNC_FRONT_PORCH = "hsync_front_porch"
45
- CONF_VSYNC_PULSE_WIDTH = "vsync_pulse_width"
46
- CONF_VSYNC_BACK_PORCH = "vsync_back_porch"
47
- CONF_VSYNC_FRONT_PORCH = "vsync_front_porch"
48
-
49
47
  DEPENDENCIES = ["spi", "esp32"]
50
48
 
51
49
  st7701s_ns = cg.esphome_ns.namespace("st7701s")
@@ -191,7 +189,6 @@ async def to_code(config):
191
189
  cg.add(var.set_vsync_front_porch(config[CONF_VSYNC_FRONT_PORCH]))
192
190
  cg.add(var.set_pclk_inverted(config[CONF_PCLK_INVERTED]))
193
191
  cg.add(var.set_pclk_frequency(config[CONF_PCLK_FREQUENCY]))
194
- index = 0
195
192
  dpins = []
196
193
  if CONF_RED in config[CONF_DATA_PINS]:
197
194
  red_pins = config[CONF_DATA_PINS][CONF_RED]
@@ -209,10 +206,9 @@ async def to_code(config):
209
206
  dpins = dpins[8:16] + dpins[0:8]
210
207
  else:
211
208
  dpins = config[CONF_DATA_PINS]
212
- for pin in dpins:
209
+ for index, pin in enumerate(dpins):
213
210
  data_pin = await cg.gpio_pin_expression(pin)
214
211
  cg.add(var.add_data_pin(data_pin, index))
215
- index += 1
216
212
 
217
213
  if dc_pin := config.get(CONF_DC_PIN):
218
214
  dc = await cg.gpio_pin_expression(dc_pin)
@@ -6,7 +6,6 @@ namespace esphome {
6
6
  namespace st7701s {
7
7
 
8
8
  void ST7701S::setup() {
9
- esph_log_config(TAG, "Setting up ST7701S");
10
9
  this->spi_setup();
11
10
  this->write_init_sequence_();
12
11
 
@@ -25,7 +24,6 @@ void ST7701S::setup() {
25
24
  config.timings.flags.pclk_active_neg = this->pclk_inverted_;
26
25
  config.timings.pclk_hz = this->pclk_frequency_;
27
26
  config.clk_src = LCD_CLK_SRC_PLL160M;
28
- config.psram_trans_align = 64;
29
27
  size_t data_pin_count = sizeof(this->data_pins_) / sizeof(this->data_pins_[0]);
30
28
  for (size_t i = 0; i != data_pin_count; i++) {
31
29
  config.data_gpio_nums[i] = this->data_pins_[i]->get_pin();
@@ -42,7 +40,6 @@ void ST7701S::setup() {
42
40
  if (err != ESP_OK) {
43
41
  esph_log_e(TAG, "lcd_new_rgb_panel failed: %s", esp_err_to_name(err));
44
42
  }
45
- esph_log_config(TAG, "ST7701S setup complete");
46
43
  }
47
44
 
48
45
  void ST7701S::loop() {
@@ -233,7 +233,6 @@ ST7735::ST7735(ST7735Model model, int width, int height, int colstart, int rowst
233
233
  height_(height) {}
234
234
 
235
235
  void ST7735::setup() {
236
- ESP_LOGCONFIG(TAG, "Running setup");
237
236
  this->spi_setup();
238
237
 
239
238
  this->dc_pin_->setup(); // OUTPUT
@@ -8,7 +8,6 @@ static const char *const TAG = "st7789v";
8
8
  static const size_t TEMP_BUFFER_SIZE = 128;
9
9
 
10
10
  void ST7789V::setup() {
11
- ESP_LOGCONFIG(TAG, "Running setup");
12
11
  #ifdef USE_POWER_SUPPLY
13
12
  this->power_.request();
14
13
  // the PowerSupply component takes care of post turn-on delay
@@ -32,7 +32,6 @@ static const uint8_t LCD_LINE2 = 0x88;
32
32
  static const uint8_t LCD_LINE3 = 0x98;
33
33
 
34
34
  void ST7920::setup() {
35
- ESP_LOGCONFIG(TAG, "Running setup");
36
35
  this->dump_config();
37
36
  this->spi_setup();
38
37
  this->init_internal_(this->get_buffer_length_());
@@ -53,8 +53,6 @@ void StatusLEDLightOutput::write_state(light::LightState *state) {
53
53
  }
54
54
 
55
55
  void StatusLEDLightOutput::setup() {
56
- ESP_LOGCONFIG(TAG, "Running setup");
57
-
58
56
  if (this->pin_ != nullptr) {
59
57
  this->pin_->setup();
60
58
  this->pin_->digital_write(false);
@@ -11,7 +11,6 @@ StatusLED *global_status_led = nullptr; // NOLINT(cppcoreguidelines-avoid-non-c
11
11
 
12
12
  StatusLED::StatusLED(GPIOPin *pin) : pin_(pin) { global_status_led = this; }
13
13
  void StatusLED::pre_setup() {
14
- ESP_LOGCONFIG(TAG, "Running setup");
15
14
  this->pin_->setup();
16
15
  this->pin_->digital_write(false);
17
16
  }
@@ -27,8 +27,7 @@ SetDecelerationAction = stepper_ns.class_("SetDecelerationAction", automation.Ac
27
27
  def validate_acceleration(value):
28
28
  value = cv.string(value)
29
29
  for suffix in ("steps/s^2", "steps/s*s", "steps/s/s", "steps/ss", "steps/(s*s)"):
30
- if value.endswith(suffix):
31
- value = value[: -len(suffix)]
30
+ value = value.removesuffix(suffix)
32
31
 
33
32
  if value == "inf":
34
33
  return 1e6
@@ -48,8 +47,7 @@ def validate_acceleration(value):
48
47
  def validate_speed(value):
49
48
  value = cv.string(value)
50
49
  for suffix in ("steps/s", "steps/s"):
51
- if value.endswith(suffix):
52
- value = value[: -len(suffix)]
50
+ value = value.removesuffix(suffix)
53
51
 
54
52
  if value == "inf":
55
53
  return 1e6
@@ -18,7 +18,6 @@ static const uint16_t STS3X_COMMAND_HEATER_DISABLE = 0x3066;
18
18
  static const uint16_t STS3X_COMMAND_FETCH_DATA = 0xE000;
19
19
 
20
20
  void STS3XComponent::setup() {
21
- ESP_LOGCONFIG(TAG, "Running setup");
22
21
  if (!this->write_command(STS3X_COMMAND_READ_SERIAL_NUMBER)) {
23
22
  this->mark_failed();
24
23
  return;
@@ -5,13 +5,8 @@ from esphome.config_helpers import Extend, Remove, merge_config
5
5
  import esphome.config_validation as cv
6
6
  from esphome.const import CONF_SUBSTITUTIONS, VALID_SUBSTITUTIONS_CHARACTERS
7
7
  from esphome.yaml_util import ESPHomeDataBase, make_data_base
8
- from .jinja import (
9
- Jinja,
10
- JinjaStr,
11
- has_jinja,
12
- TemplateError,
13
- TemplateRuntimeError,
14
- )
8
+
9
+ from .jinja import Jinja, JinjaStr, TemplateError, TemplateRuntimeError, has_jinja
15
10
 
16
11
  CODEOWNERS = ["@esphome/core"]
17
12
  _LOGGER = logging.getLogger(__name__)
@@ -54,15 +49,14 @@ def _expand_jinja(value, orig_value, path, jinja, ignore_missing):
54
49
  try:
55
50
  # Invoke the jinja engine to evaluate the expression.
56
51
  value, err = jinja.expand(value)
57
- if err is not None:
58
- if not ignore_missing and "password" not in path:
59
- _LOGGER.warning(
60
- "Found '%s' (see %s) which looks like an expression,"
61
- " but could not resolve all the variables: %s",
62
- value,
63
- "->".join(str(x) for x in path),
64
- err.message,
65
- )
52
+ if err is not None and not ignore_missing and "password" not in path:
53
+ _LOGGER.warning(
54
+ "Found '%s' (see %s) which looks like an expression,"
55
+ " but could not resolve all the variables: %s",
56
+ value,
57
+ "->".join(str(x) for x in path),
58
+ err.message,
59
+ )
66
60
  except (
67
61
  TemplateError,
68
62
  TemplateRuntimeError,
@@ -1,6 +1,7 @@
1
1
  import logging
2
2
  import math
3
3
  import re
4
+
4
5
  import jinja2 as jinja
5
6
  from jinja2.nativetypes import NativeEnvironment
6
7
 
@@ -24,6 +25,24 @@ def has_jinja(st):
24
25
  return detect_jinja_re.search(st) is not None
25
26
 
26
27
 
28
+ # SAFE_GLOBAL_FUNCTIONS defines a allowlist of built-in functions that are considered safe to expose
29
+ # in Jinja templates or other sandboxed evaluation contexts. Only functions that do not allow
30
+ # arbitrary code execution, file access, or other security risks are included.
31
+ #
32
+ # The following functions are considered safe:
33
+ # - ord: Converts a character to its Unicode code point integer.
34
+ # - chr: Converts an integer to its corresponding Unicode character.
35
+ # - len: Returns the length of a sequence or collection.
36
+ #
37
+ # These functions were chosen because they are pure, have no side effects, and do not provide access
38
+ # to the file system, environment, or other potentially sensitive resources.
39
+ SAFE_GLOBAL_FUNCTIONS = {
40
+ "ord": ord,
41
+ "chr": chr,
42
+ "len": len,
43
+ }
44
+
45
+
27
46
  class JinjaStr(str):
28
47
  """
29
48
  Wraps a string containing an unresolved Jinja expression,
@@ -65,7 +84,11 @@ class Jinja:
65
84
  self.env.add_extension("jinja2.ext.do")
66
85
  self.env.globals["math"] = math # Inject entire math module
67
86
  self.context_vars = {**context_vars}
68
- self.env.globals = {**self.env.globals, **self.context_vars}
87
+ self.env.globals = {
88
+ **self.env.globals,
89
+ **self.context_vars,
90
+ **SAFE_GLOBAL_FUNCTIONS,
91
+ }
69
92
 
70
93
  def expand(self, content_str):
71
94
  """
@@ -1,3 +1,4 @@
1
+ import contextlib
1
2
  import re
2
3
 
3
4
  from esphome import automation
@@ -41,12 +42,10 @@ ELEVATION_MAP = {
41
42
 
42
43
  def elevation(value):
43
44
  if isinstance(value, str):
44
- try:
45
+ with contextlib.suppress(cv.Invalid):
45
46
  value = ELEVATION_MAP[
46
47
  cv.one_of(*ELEVATION_MAP, lower=True, space="_")(value)
47
48
  ]
48
- except cv.Invalid:
49
- pass
50
49
  value = cv.angle(value)
51
50
  return cv.float_range(min=-180, max=180)(value)
52
51
 
@@ -10,9 +10,11 @@ from esphome.const import (
10
10
  CONF_ID,
11
11
  CONF_INVERTED,
12
12
  CONF_MQTT_ID,
13
+ CONF_ON_STATE,
13
14
  CONF_ON_TURN_OFF,
14
15
  CONF_ON_TURN_ON,
15
16
  CONF_RESTORE_MODE,
17
+ CONF_STATE,
16
18
  CONF_TRIGGER_ID,
17
19
  CONF_WEB_SERVER,
18
20
  DEVICE_CLASS_EMPTY,
@@ -48,12 +50,16 @@ RESTORE_MODES = {
48
50
  }
49
51
 
50
52
 
53
+ ControlAction = switch_ns.class_("ControlAction", automation.Action)
51
54
  ToggleAction = switch_ns.class_("ToggleAction", automation.Action)
52
55
  TurnOffAction = switch_ns.class_("TurnOffAction", automation.Action)
53
56
  TurnOnAction = switch_ns.class_("TurnOnAction", automation.Action)
54
57
  SwitchPublishAction = switch_ns.class_("SwitchPublishAction", automation.Action)
55
58
 
56
59
  SwitchCondition = switch_ns.class_("SwitchCondition", Condition)
60
+ SwitchStateTrigger = switch_ns.class_(
61
+ "SwitchStateTrigger", automation.Trigger.template(bool)
62
+ )
57
63
  SwitchTurnOnTrigger = switch_ns.class_(
58
64
  "SwitchTurnOnTrigger", automation.Trigger.template()
59
65
  )
@@ -75,6 +81,11 @@ _SWITCH_SCHEMA = (
75
81
  cv.Optional(CONF_RESTORE_MODE, default="ALWAYS_OFF"): cv.enum(
76
82
  RESTORE_MODES, upper=True, space="_"
77
83
  ),
84
+ cv.Optional(CONF_ON_STATE): automation.validate_automation(
85
+ {
86
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(SwitchStateTrigger),
87
+ }
88
+ ),
78
89
  cv.Optional(CONF_ON_TURN_ON): automation.validate_automation(
79
90
  {
80
91
  cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(SwitchTurnOnTrigger),
@@ -138,6 +149,9 @@ async def setup_switch_core_(var, config):
138
149
 
139
150
  if (inverted := config.get(CONF_INVERTED)) is not None:
140
151
  cg.add(var.set_inverted(inverted))
152
+ for conf in config.get(CONF_ON_STATE, []):
153
+ trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
154
+ await automation.build_automation(trigger, [(bool, "x")], conf)
141
155
  for conf in config.get(CONF_ON_TURN_ON, []):
142
156
  trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
143
157
  await automation.build_automation(trigger, [], conf)
@@ -177,6 +191,23 @@ SWITCH_ACTION_SCHEMA = maybe_simple_id(
177
191
  cv.Required(CONF_ID): cv.use_id(Switch),
178
192
  }
179
193
  )
194
+ SWITCH_CONTROL_ACTION_SCHEMA = automation.maybe_simple_id(
195
+ {
196
+ cv.Required(CONF_ID): cv.use_id(Switch),
197
+ cv.Required(CONF_STATE): cv.templatable(cv.boolean),
198
+ }
199
+ )
200
+
201
+
202
+ @automation.register_action(
203
+ "switch.control", ControlAction, SWITCH_CONTROL_ACTION_SCHEMA
204
+ )
205
+ async def switch_control_to_code(config, action_id, template_arg, args):
206
+ paren = await cg.get_variable(config[CONF_ID])
207
+ var = cg.new_Pvariable(action_id, template_arg, paren)
208
+ template_ = await cg.templatable(config[CONF_STATE], args, bool)
209
+ cg.add(var.set_state(template_))
210
+ return var
180
211
 
181
212
 
182
213
  @automation.register_action("switch.toggle", ToggleAction, SWITCH_ACTION_SCHEMA)
@@ -202,4 +233,3 @@ async def switch_is_off_to_code(config, condition_id, template_arg, args):
202
233
  @coroutine_with_priority(100.0)
203
234
  async def to_code(config):
204
235
  cg.add_global(switch_ns.using)
205
- cg.add_define("USE_SWITCH")
@@ -37,6 +37,23 @@ template<typename... Ts> class ToggleAction : public Action<Ts...> {
37
37
  Switch *switch_;
38
38
  };
39
39
 
40
+ template<typename... Ts> class ControlAction : public Action<Ts...> {
41
+ public:
42
+ explicit ControlAction(Switch *a_switch) : switch_(a_switch) {}
43
+
44
+ TEMPLATABLE_VALUE(bool, state)
45
+
46
+ void play(Ts... x) override {
47
+ auto state = this->state_.optional_value(x...);
48
+ if (state.has_value()) {
49
+ this->switch_->control(*state);
50
+ }
51
+ }
52
+
53
+ protected:
54
+ Switch *switch_;
55
+ };
56
+
40
57
  template<typename... Ts> class SwitchCondition : public Condition<Ts...> {
41
58
  public:
42
59
  SwitchCondition(Switch *parent, bool state) : parent_(parent), state_(state) {}
@@ -47,6 +64,13 @@ template<typename... Ts> class SwitchCondition : public Condition<Ts...> {
47
64
  bool state_;
48
65
  };
49
66
 
67
+ class SwitchStateTrigger : public Trigger<bool> {
68
+ public:
69
+ SwitchStateTrigger(Switch *a_switch) {
70
+ a_switch->add_on_state_callback([this](bool state) { this->trigger(state); });
71
+ }
72
+ };
73
+
50
74
  class SwitchTurnOnTrigger : public Trigger<> {
51
75
  public:
52
76
  SwitchTurnOnTrigger(Switch *a_switch) {