esphome 2025.6.2__py3-none-any.whl → 2025.7.0b1__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 (601) hide show
  1. esphome/__main__.py +1 -3
  2. esphome/codegen.py +2 -0
  3. esphome/components/ac_dimmer/ac_dimmer.cpp +6 -6
  4. esphome/components/adc/__init__.py +25 -1
  5. esphome/components/adc/adc_sensor.h +11 -11
  6. esphome/components/adc/adc_sensor_common.cpp +1 -1
  7. esphome/components/adc/adc_sensor_esp32.cpp +16 -8
  8. esphome/components/ade7880/ade7880.h +0 -2
  9. esphome/components/ads1115/ads1115.h +0 -1
  10. esphome/components/ads1118/ads1118.h +0 -1
  11. esphome/components/ags10/ags10.h +0 -2
  12. esphome/components/aic3204/aic3204.h +0 -1
  13. esphome/components/alarm_control_panel/__init__.py +5 -2
  14. esphome/components/alpha3/alpha3.h +0 -1
  15. esphome/components/am43/cover/am43_cover.h +0 -1
  16. esphome/components/am43/sensor/am43_sensor.h +0 -1
  17. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +0 -2
  18. esphome/components/anova/anova.cpp +5 -1
  19. esphome/components/anova/anova.h +0 -1
  20. esphome/components/apds9960/apds9960.cpp +1 -1
  21. esphome/components/api/__init__.py +42 -20
  22. esphome/components/api/api_connection.cpp +318 -391
  23. esphome/components/api/api_connection.h +206 -126
  24. esphome/components/api/api_frame_helper.cpp +89 -124
  25. esphome/components/api/api_frame_helper.h +57 -45
  26. esphome/components/api/api_pb2.cpp +414 -4350
  27. esphome/components/api/api_pb2.h +287 -198
  28. esphome/components/api/api_pb2_dump.cpp +4333 -0
  29. esphome/components/api/api_pb2_service.cpp +180 -425
  30. esphome/components/api/api_pb2_service.h +7 -6
  31. esphome/components/api/api_pb2_size.h +2 -4
  32. esphome/components/api/api_server.cpp +138 -167
  33. esphome/components/api/api_server.h +66 -12
  34. esphome/components/api/client.py +10 -4
  35. esphome/components/api/list_entities.cpp +36 -105
  36. esphome/components/api/list_entities.h +31 -23
  37. esphome/components/api/proto.h +26 -3
  38. esphome/components/api/subscribe_state.cpp +23 -29
  39. esphome/components/api/subscribe_state.h +26 -19
  40. esphome/components/as5600/as5600.h +0 -1
  41. esphome/components/async_tcp/__init__.py +14 -5
  42. esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
  43. esphome/components/atm90e32/atm90e32.cpp +2 -1
  44. esphome/components/audio/audio_decoder.cpp +1 -1
  45. esphome/components/audio/audio_transfer_buffer.cpp +2 -2
  46. esphome/components/b_parasite/b_parasite.h +0 -1
  47. esphome/components/bedjet/bedjet_hub.cpp +5 -1
  48. esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
  49. esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
  50. esphome/components/bh1750/bh1750.cpp +5 -5
  51. esphome/components/binary_sensor/__init__.py +82 -5
  52. esphome/components/binary_sensor/automation.h +19 -1
  53. esphome/components/binary_sensor/binary_sensor.cpp +12 -30
  54. esphome/components/binary_sensor/binary_sensor.h +11 -25
  55. esphome/components/binary_sensor/filter.cpp +29 -24
  56. esphome/components/binary_sensor/filter.h +20 -10
  57. esphome/components/ble_client/output/ble_binary_output.h +0 -1
  58. esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
  59. esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
  60. esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
  61. esphome/components/ble_client/sensor/ble_sensor.h +0 -1
  62. esphome/components/ble_client/switch/ble_switch.h +0 -1
  63. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
  64. esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
  65. esphome/components/ble_presence/ble_presence_device.h +0 -1
  66. esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
  67. esphome/components/ble_scanner/ble_scanner.h +0 -1
  68. esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
  69. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
  70. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
  71. esphome/components/bme680/sensor.py +1 -1
  72. esphome/components/bmp581/bmp581.h +0 -2
  73. esphome/components/button/__init__.py +5 -2
  74. esphome/components/camera/__init__.py +1 -0
  75. esphome/components/camera/camera.cpp +22 -0
  76. esphome/components/camera/camera.h +80 -0
  77. esphome/components/canbus/__init__.py +1 -0
  78. esphome/components/cap1188/cap1188.h +0 -1
  79. esphome/components/captive_portal/__init__.py +12 -2
  80. esphome/components/captive_portal/captive_portal.cpp +12 -2
  81. esphome/components/captive_portal/captive_portal.h +5 -2
  82. esphome/components/ccs811/ccs811.h +0 -2
  83. esphome/components/climate/__init__.py +5 -2
  84. esphome/components/cm1106/sensor.py +2 -2
  85. esphome/components/const/__init__.py +2 -0
  86. esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
  87. esphome/components/copy/button/copy_button.h +0 -1
  88. esphome/components/copy/cover/copy_cover.h +0 -1
  89. esphome/components/copy/fan/copy_fan.h +0 -1
  90. esphome/components/copy/lock/copy_lock.h +0 -1
  91. esphome/components/copy/number/copy_number.h +0 -1
  92. esphome/components/copy/select/copy_select.h +0 -1
  93. esphome/components/copy/sensor/copy_sensor.h +0 -1
  94. esphome/components/copy/switch/copy_switch.h +0 -1
  95. esphome/components/copy/text/copy_text.h +0 -1
  96. esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
  97. esphome/components/cover/__init__.py +5 -2
  98. esphome/components/cs5460a/cs5460a.h +0 -1
  99. esphome/components/datetime/__init__.py +4 -2
  100. esphome/components/debug/__init__.py +20 -0
  101. esphome/components/deep_sleep/__init__.py +43 -9
  102. esphome/components/demo/__init__.py +2 -2
  103. esphome/components/display/display.cpp +4 -3
  104. esphome/components/display/display.h +0 -2
  105. esphome/components/display/display_buffer.cpp +1 -1
  106. esphome/components/ds2484/__init__.py +1 -0
  107. esphome/components/ds2484/ds2484.cpp +209 -0
  108. esphome/components/ds2484/ds2484.h +43 -0
  109. esphome/components/ds2484/one_wire.py +37 -0
  110. esphome/components/duty_time/duty_time_sensor.h +0 -1
  111. esphome/components/ens160_base/ens160_base.h +0 -1
  112. esphome/components/es7210/es7210.h +0 -1
  113. esphome/components/es7243e/es7243e.h +0 -1
  114. esphome/components/es8156/es8156.h +0 -1
  115. esphome/components/es8311/es8311.h +0 -1
  116. esphome/components/es8388/es8388.h +0 -1
  117. esphome/components/esp32/__init__.py +102 -135
  118. esphome/components/esp32/core.cpp +0 -4
  119. esphome/components/esp32/gpio.h +1 -1
  120. esphome/components/esp32/helpers.cpp +69 -0
  121. esphome/components/esp32_ble/ble.cpp +5 -6
  122. esphome/components/esp32_ble/ble.h +29 -14
  123. esphome/components/esp32_ble/ble_event.h +6 -6
  124. esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
  125. esphome/components/esp32_ble_client/ble_client_base.h +24 -9
  126. esphome/components/esp32_ble_tracker/__init__.py +2 -8
  127. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
  128. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
  129. esphome/components/esp32_camera/__init__.py +111 -97
  130. esphome/components/esp32_camera/esp32_camera.cpp +41 -31
  131. esphome/components/esp32_camera/esp32_camera.h +35 -30
  132. esphome/components/esp32_camera_web_server/__init__.py +2 -1
  133. esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
  134. esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
  135. esphome/components/esp32_hall/sensor.py +2 -21
  136. esphome/components/esp32_hosted/__init__.py +101 -0
  137. esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
  138. esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
  139. esphome/components/esp32_rmt/__init__.py +0 -58
  140. esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
  141. esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
  142. esphome/components/esp32_rmt_led_strip/light.py +14 -76
  143. esphome/components/esp32_touch/esp32_touch.h +174 -28
  144. esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
  145. esphome/components/esp32_touch/esp32_touch_v1.cpp +238 -0
  146. esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
  147. esphome/components/esp8266/__init__.py +1 -0
  148. esphome/components/esp8266/gpio.cpp +10 -10
  149. esphome/components/esp8266/helpers.cpp +31 -0
  150. esphome/components/esphome/ota/__init__.py +1 -0
  151. esphome/components/esphome/ota/ota_esphome.cpp +24 -19
  152. esphome/components/ethernet/__init__.py +42 -23
  153. esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
  154. esphome/components/ethernet/ethernet_component.cpp +69 -29
  155. esphome/components/ethernet/ethernet_component.h +18 -10
  156. esphome/components/event/__init__.py +5 -2
  157. esphome/components/ezo/ezo.h +0 -1
  158. esphome/components/ezo_pmp/ezo_pmp.h +0 -1
  159. esphome/components/fan/__init__.py +5 -2
  160. esphome/components/feedback/feedback_cover.h +0 -1
  161. esphome/components/font/__init__.py +92 -82
  162. esphome/components/font/font.cpp +9 -2
  163. esphome/components/font/font.h +20 -5
  164. esphome/components/fs3000/fs3000.h +0 -1
  165. esphome/components/gcja5/gcja5.h +0 -1
  166. esphome/components/gl_r01_i2c/__init__.py +0 -0
  167. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
  168. esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
  169. esphome/components/gl_r01_i2c/sensor.py +36 -0
  170. esphome/components/gp8403/gp8403.h +0 -1
  171. esphome/components/gpio/binary_sensor/__init__.py +17 -0
  172. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
  173. esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
  174. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
  175. esphome/components/he60r/he60r.h +0 -1
  176. esphome/components/heatpumpir/climate.py +2 -1
  177. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  178. esphome/components/heatpumpir/heatpumpir.h +1 -0
  179. esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
  180. esphome/components/host/__init__.py +2 -1
  181. esphome/components/host/helpers.cpp +57 -0
  182. esphome/components/http_request/__init__.py +19 -1
  183. esphome/components/http_request/http_request.h +1 -1
  184. esphome/components/http_request/http_request_arduino.cpp +0 -1
  185. esphome/components/http_request/http_request_arduino.h +1 -0
  186. esphome/components/http_request/http_request_idf.cpp +0 -1
  187. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  188. esphome/components/http_request/update/http_request_update.cpp +28 -9
  189. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +3 -9
  190. esphome/components/hydreon_rgxx/sensor.py +1 -1
  191. esphome/components/i2c/__init__.py +23 -11
  192. esphome/components/i2c/i2c_bus.h +8 -1
  193. esphome/components/i2c/i2c_bus_arduino.cpp +4 -3
  194. esphome/components/i2c/i2c_bus_arduino.h +6 -3
  195. esphome/components/i2c/i2c_bus_esp_idf.h +5 -3
  196. esphome/components/i2c_device/i2c_device.h +0 -1
  197. esphome/components/i2s_audio/__init__.py +2 -10
  198. esphome/components/i2s_audio/i2s_audio.cpp +1 -5
  199. esphome/components/i2s_audio/media_player/__init__.py +2 -2
  200. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +2 -2
  201. esphome/components/iaqcore/iaqcore.h +0 -2
  202. esphome/components/image/__init__.py +123 -24
  203. esphome/components/improv_serial/improv_serial_component.cpp +0 -4
  204. esphome/components/ina219/ina219.cpp +7 -0
  205. esphome/components/ina219/ina219.h +1 -0
  206. esphome/components/ina260/ina260.h +0 -2
  207. esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h +0 -1
  208. esphome/components/inkplate6/display.py +15 -0
  209. esphome/components/inkplate6/inkplate.cpp +2 -2
  210. esphome/components/integration/integration_sensor.h +0 -1
  211. esphome/components/internal_temperature/internal_temperature.cpp +8 -27
  212. esphome/components/internal_temperature/sensor.py +0 -26
  213. esphome/components/interval/interval.h +0 -2
  214. esphome/components/ld2410/button/__init__.py +3 -3
  215. esphome/components/ld2410/button/factory_reset_button.cpp +9 -0
  216. esphome/components/ld2410/button/{reset_button.h → factory_reset_button.h} +2 -2
  217. esphome/components/ld2410/ld2410.cpp +430 -261
  218. esphome/components/ld2410/ld2410.h +44 -146
  219. esphome/components/ld2410/number/__init__.py +2 -2
  220. esphome/components/ld2410/sensor.py +1 -1
  221. esphome/components/ld2410/switch/__init__.py +1 -1
  222. esphome/components/ld2420/ld2420.cpp +196 -100
  223. esphome/components/ld2420/ld2420.h +46 -118
  224. esphome/components/ld2420/number/__init__.py +2 -2
  225. esphome/components/ld2420/sensor/__init__.py +6 -2
  226. esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
  227. esphome/components/ld2450/button/__init__.py +3 -3
  228. esphome/components/ld2450/button/factory_reset_button.cpp +9 -0
  229. esphome/components/ld2450/button/{reset_button.h → factory_reset_button.h} +2 -2
  230. esphome/components/ld2450/ld2450.cpp +384 -232
  231. esphome/components/ld2450/ld2450.h +60 -69
  232. esphome/components/ld2450/switch/__init__.py +1 -1
  233. esphome/components/ledc/ledc_output.cpp +1 -63
  234. esphome/components/libretiny/__init__.py +4 -3
  235. esphome/components/libretiny/const.py +5 -0
  236. esphome/components/libretiny/generate_components.py +1 -0
  237. esphome/components/libretiny/helpers.cpp +35 -0
  238. esphome/components/libretiny/lt_component.cpp +5 -3
  239. esphome/components/light/__init__.py +4 -2
  240. esphome/components/light/addressable_light.h +3 -3
  241. esphome/components/light/light_call.cpp +180 -243
  242. esphome/components/light/light_call.h +72 -20
  243. esphome/components/light/light_color_values.h +14 -14
  244. esphome/components/light/light_state.h +15 -13
  245. esphome/components/light/transformers.h +2 -2
  246. esphome/components/ln882x/__init__.py +52 -0
  247. esphome/components/ln882x/boards.py +285 -0
  248. esphome/components/lock/__init__.py +5 -2
  249. esphome/components/logger/__init__.py +40 -3
  250. esphome/components/logger/logger.cpp +47 -12
  251. esphome/components/logger/logger.h +80 -49
  252. esphome/components/logger/logger_esp32.cpp +3 -3
  253. esphome/components/lps22/__init__.py +0 -0
  254. esphome/components/lps22/lps22.cpp +75 -0
  255. esphome/components/lps22/lps22.h +27 -0
  256. esphome/components/lps22/sensor.py +58 -0
  257. esphome/components/ltr390/ltr390.h +0 -1
  258. esphome/components/ltr501/ltr501.h +0 -1
  259. esphome/components/ltr_als_ps/ltr_als_ps.h +0 -1
  260. esphome/components/lvgl/__init__.py +1 -1
  261. esphome/components/lvgl/schemas.py +66 -6
  262. esphome/components/lvgl/styles.py +24 -16
  263. esphome/components/lvgl/widgets/__init__.py +12 -2
  264. esphome/components/lvgl/widgets/lv_bar.py +40 -19
  265. esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +1 -1
  266. esphome/components/max9611/max9611.h +0 -1
  267. esphome/components/mcp23016/__init__.py +1 -1
  268. esphome/components/mcp23xxx_base/__init__.py +1 -1
  269. esphome/components/mcp4461/__init__.py +1 -1
  270. esphome/components/mcp4461/output/__init__.py +3 -2
  271. esphome/components/mcp9600/mcp9600.h +0 -2
  272. esphome/components/md5/md5.cpp +3 -3
  273. esphome/components/md5/md5.h +1 -6
  274. esphome/components/mdns/__init__.py +22 -11
  275. esphome/components/media_player/__init__.py +4 -3
  276. esphome/components/micro_wake_word/__init__.py +1 -5
  277. esphome/components/micro_wake_word/streaming_model.cpp +2 -2
  278. esphome/components/microphone/microphone.cpp +7 -9
  279. esphome/components/microphone/microphone.h +0 -2
  280. esphome/components/mipi_spi/display.py +1 -0
  281. esphome/components/mmc5603/mmc5603.cpp +1 -1
  282. esphome/components/modbus/modbus.cpp +33 -15
  283. esphome/components/modbus/modbus.h +9 -0
  284. esphome/components/modbus_controller/__init__.py +42 -10
  285. esphome/components/modbus_controller/modbus_controller.cpp +92 -11
  286. esphome/components/modbus_controller/modbus_controller.h +61 -7
  287. esphome/components/mopeka_pro_check/mopeka_pro_check.h +0 -1
  288. esphome/components/mopeka_std_check/mopeka_std_check.h +0 -1
  289. esphome/components/mpl3115a2/mpl3115a2.h +0 -2
  290. esphome/components/mqtt/__init__.py +16 -0
  291. esphome/components/mqtt/mqtt_backend.h +2 -1
  292. esphome/components/mqtt/mqtt_backend_esp32.cpp +126 -45
  293. esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
  294. esphome/components/mqtt/mqtt_client.cpp +15 -9
  295. esphome/components/mqtt/mqtt_client.h +8 -3
  296. esphome/components/ms8607/ms8607.h +0 -1
  297. esphome/components/neopixelbus/light.py +4 -1
  298. esphome/components/neopixelbus/neopixelbus_light.h +1 -1
  299. esphome/components/network/__init__.py +4 -1
  300. esphome/components/network/ip_address.h +1 -0
  301. esphome/components/nextion/__init__.py +16 -0
  302. esphome/components/nextion/base_component.py +1 -0
  303. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
  304. esphome/components/nextion/display.py +14 -4
  305. esphome/components/nextion/nextion.cpp +166 -101
  306. esphome/components/nextion/nextion.h +84 -53
  307. esphome/components/nextion/nextion_commands.cpp +11 -10
  308. esphome/components/nextion/nextion_component.cpp +28 -28
  309. esphome/components/nextion/nextion_component.h +53 -18
  310. esphome/components/nextion/nextion_component_base.h +3 -0
  311. esphome/components/nextion/nextion_upload.cpp +36 -0
  312. esphome/components/nextion/nextion_upload_arduino.cpp +10 -35
  313. esphome/components/nextion/nextion_upload_idf.cpp +9 -33
  314. esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
  315. esphome/components/nextion/switch/nextion_switch.cpp +1 -1
  316. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
  317. esphome/components/nfc/nfc.cpp +3 -22
  318. esphome/components/nfc/nfc.h +3 -3
  319. esphome/components/number/__init__.py +5 -2
  320. esphome/components/online_image/__init__.py +5 -0
  321. esphome/components/online_image/online_image.cpp +6 -2
  322. esphome/components/online_image/online_image.h +4 -1
  323. esphome/components/opentherm/opentherm.cpp +7 -12
  324. esphome/components/openthread/__init__.py +47 -40
  325. esphome/components/openthread/const.py +1 -0
  326. esphome/components/openthread/openthread_esp.cpp +27 -5
  327. esphome/components/opt3001/__init__.py +0 -0
  328. esphome/components/opt3001/opt3001.cpp +122 -0
  329. esphome/components/opt3001/opt3001.h +27 -0
  330. esphome/components/opt3001/sensor.py +35 -0
  331. esphome/components/ota/__init__.py +17 -0
  332. esphome/components/ota/ota_backend.h +27 -1
  333. esphome/components/ota/ota_backend_arduino_esp32.cpp +12 -2
  334. esphome/components/ota/ota_backend_arduino_esp32.h +3 -0
  335. esphome/components/ota/ota_backend_arduino_esp8266.cpp +18 -4
  336. esphome/components/ota/ota_backend_arduino_esp8266.h +3 -0
  337. esphome/components/ota/ota_backend_arduino_libretiny.cpp +12 -2
  338. esphome/components/ota/ota_backend_arduino_libretiny.h +3 -0
  339. esphome/components/ota/ota_backend_arduino_rp2040.cpp +9 -2
  340. esphome/components/ota/ota_backend_arduino_rp2040.h +3 -0
  341. esphome/components/ota/ota_backend_esp_idf.cpp +10 -16
  342. esphome/components/ota/ota_backend_esp_idf.h +1 -0
  343. esphome/components/packages/__init__.py +5 -2
  344. esphome/components/packet_transport/binary_sensor.py +61 -4
  345. esphome/components/packet_transport/packet_transport.cpp +31 -1
  346. esphome/components/packet_transport/packet_transport.h +11 -5
  347. esphome/components/pcf8574/__init__.py +1 -1
  348. esphome/components/pi4ioe5v6408/__init__.py +84 -0
  349. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +171 -0
  350. esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +70 -0
  351. esphome/components/pmsa003i/pmsa003i.h +0 -1
  352. esphome/components/pmsx003/pmsx003.h +0 -1
  353. esphome/components/pn7150/pn7150.cpp +7 -7
  354. esphome/components/pn7150/pn7150.h +0 -1
  355. esphome/components/pn7160/pn7160.cpp +7 -7
  356. esphome/components/pn7160/pn7160.h +0 -1
  357. esphome/components/preferences/syncer.h +2 -0
  358. esphome/components/prometheus/prometheus_handler.h +1 -1
  359. esphome/components/psram/psram.cpp +0 -20
  360. esphome/components/pulse_counter/pulse_counter_sensor.h +0 -1
  361. esphome/components/pulse_meter/pulse_meter_sensor.cpp +8 -4
  362. esphome/components/pulse_width/pulse_width.h +0 -1
  363. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +0 -4
  364. esphome/components/pvvx_mithermometer/display/pvvx_display.h +0 -2
  365. esphome/components/pvvx_mithermometer/pvvx_mithermometer.h +0 -1
  366. esphome/components/qr_code/__init__.py +13 -10
  367. esphome/components/qwiic_pir/qwiic_pir.h +0 -1
  368. esphome/components/radon_eye_ble/radon_eye_listener.cpp +1 -1
  369. esphome/components/rc522/rc522.h +0 -1
  370. esphome/components/rdm6300/rdm6300.h +0 -2
  371. esphome/components/remote_base/__init__.py +7 -5
  372. esphome/components/remote_base/remote_base.cpp +24 -21
  373. esphome/components/remote_base/remote_base.h +3 -26
  374. esphome/components/remote_receiver/__init__.py +40 -46
  375. esphome/components/remote_receiver/remote_receiver.h +4 -18
  376. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -87
  377. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +1 -1
  378. esphome/components/remote_transmitter/__init__.py +42 -43
  379. esphome/components/remote_transmitter/remote_transmitter.h +2 -14
  380. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -77
  381. esphome/components/resistance/resistance_sensor.h +0 -1
  382. esphome/components/rp2040/__init__.py +1 -0
  383. esphome/components/rp2040/helpers.cpp +55 -0
  384. esphome/components/rp2040_pio_led_strip/led_strip.cpp +2 -2
  385. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -4
  386. esphome/components/rtttl/__init__.py +4 -4
  387. esphome/components/rtttl/rtttl.cpp +10 -1
  388. esphome/components/ruuvitag/ruuvitag.h +0 -1
  389. esphome/components/safe_mode/safe_mode.cpp +2 -0
  390. esphome/components/safe_mode/safe_mode.h +4 -1
  391. esphome/components/scd30/scd30.h +0 -1
  392. esphome/components/scd30/sensor.py +2 -2
  393. esphome/components/scd4x/scd4x.cpp +61 -54
  394. esphome/components/scd4x/scd4x.h +17 -15
  395. esphome/components/scd4x/sensor.py +4 -4
  396. esphome/components/script/script.h +0 -2
  397. esphome/components/sdp3x/sensor.py +1 -1
  398. esphome/components/select/__init__.py +5 -2
  399. esphome/components/sen5x/sen5x.h +0 -1
  400. esphome/components/senseair/senseair.h +0 -1
  401. esphome/components/sensor/__init__.py +4 -2
  402. esphome/components/sensor/filter.cpp +1 -1
  403. esphome/components/sensor/sensor.cpp +12 -6
  404. esphome/components/sensor/sensor.h +13 -5
  405. esphome/components/servo/servo.h +0 -1
  406. esphome/components/sfa30/sfa30.h +0 -1
  407. esphome/components/sgp30/sgp30.h +0 -1
  408. esphome/components/sgp4x/sgp4x.h +0 -1
  409. esphome/components/shelly_dimmer/stm32flash.cpp +1 -2
  410. esphome/components/sht4x/sht4x.h +0 -1
  411. esphome/components/sm300d2/sm300d2.h +0 -2
  412. esphome/components/smt100/sensor.py +8 -4
  413. esphome/components/smt100/smt100.cpp +5 -5
  414. esphome/components/smt100/smt100.h +3 -3
  415. esphome/components/sn74hc595/__init__.py +1 -1
  416. esphome/components/sn74hc595/sn74hc595.cpp +5 -4
  417. esphome/components/sntp/sntp_component.cpp +9 -3
  418. esphome/components/sntp/time.py +2 -0
  419. esphome/components/socket/__init__.py +17 -0
  420. esphome/components/spi/__init__.py +27 -6
  421. esphome/components/spi/spi.cpp +3 -2
  422. esphome/components/spi/spi.h +9 -3
  423. esphome/components/spi/spi_arduino.cpp +3 -5
  424. esphome/components/spi/spi_esp_idf.cpp +40 -21
  425. esphome/components/spi_led_strip/spi_led_strip.cpp +1 -1
  426. esphome/components/sps30/sps30.h +0 -1
  427. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  428. esphome/components/st7701s/st7701s.cpp +0 -4
  429. esphome/components/status/status_binary_sensor.h +0 -2
  430. esphome/components/substitutions/__init__.py +76 -19
  431. esphome/components/substitutions/jinja.py +99 -0
  432. esphome/components/sun/sun.cpp +3 -4
  433. esphome/components/switch/__init__.py +5 -2
  434. esphome/components/switch/binary_sensor/switch_binary_sensor.h +0 -1
  435. esphome/components/sx126x/__init__.py +317 -0
  436. esphome/components/sx126x/automation.h +62 -0
  437. esphome/components/sx126x/packet_transport/__init__.py +26 -0
  438. esphome/components/sx126x/packet_transport/sx126x_transport.cpp +26 -0
  439. esphome/components/sx126x/packet_transport/sx126x_transport.h +25 -0
  440. esphome/components/sx126x/sx126x.cpp +523 -0
  441. esphome/components/sx126x/sx126x.h +140 -0
  442. esphome/components/sx126x/sx126x_reg.h +163 -0
  443. esphome/components/sx127x/__init__.py +325 -0
  444. esphome/components/sx127x/automation.h +62 -0
  445. esphome/components/sx127x/packet_transport/__init__.py +26 -0
  446. esphome/components/sx127x/packet_transport/sx127x_transport.cpp +26 -0
  447. esphome/components/sx127x/packet_transport/sx127x_transport.h +25 -0
  448. esphome/components/sx127x/sx127x.cpp +498 -0
  449. esphome/components/sx127x/sx127x.h +128 -0
  450. esphome/components/sx127x/sx127x_reg.h +295 -0
  451. esphome/components/syslog/esphome_syslog.cpp +5 -3
  452. esphome/components/syslog/esphome_syslog.h +1 -1
  453. esphome/components/tca9555/__init__.py +1 -1
  454. esphome/components/template/binary_sensor/template_binary_sensor.cpp +1 -9
  455. esphome/components/text/__init__.py +5 -2
  456. esphome/components/text_sensor/__init__.py +5 -2
  457. esphome/components/thermostat/thermostat_climate.cpp +34 -31
  458. esphome/components/thermostat/thermostat_climate.h +43 -39
  459. esphome/components/time/__init__.py +16 -2
  460. esphome/components/time/real_time_clock.cpp +4 -0
  461. esphome/components/time/real_time_clock.h +5 -1
  462. esphome/components/tlc5971/tlc5971.cpp +4 -1
  463. esphome/components/tmp1075/tmp1075.h +0 -2
  464. esphome/components/tof10120/tof10120_sensor.h +0 -1
  465. esphome/components/tormatic/tormatic_cover.h +0 -1
  466. esphome/components/total_daily_energy/total_daily_energy.h +0 -1
  467. esphome/components/tsl2591/tsl2591.cpp +1 -1
  468. esphome/components/ttp229_bsf/ttp229_bsf.h +0 -1
  469. esphome/components/ttp229_lsf/ttp229_lsf.h +0 -1
  470. esphome/components/tx20/tx20.cpp +2 -2
  471. esphome/components/uart/__init__.py +18 -0
  472. esphome/components/uart/uart_component_esp_idf.cpp +1 -5
  473. esphome/components/update/__init__.py +5 -2
  474. esphome/components/update/update_entity.h +8 -0
  475. esphome/components/usb_host/__init__.py +5 -2
  476. esphome/components/valve/__init__.py +5 -2
  477. esphome/components/vbus/vbus.h +0 -1
  478. esphome/components/veml3235/veml3235.h +0 -1
  479. esphome/components/veml7700/veml7700.h +0 -1
  480. esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
  481. esphome/components/voice_assistant/voice_assistant.cpp +4 -4
  482. esphome/components/watchdog/watchdog.cpp +0 -4
  483. esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
  484. esphome/components/web_server/__init__.py +34 -19
  485. esphome/components/web_server/ota/__init__.py +32 -0
  486. esphome/components/web_server/ota/ota_web_server.cpp +210 -0
  487. esphome/components/web_server/ota/ota_web_server.h +26 -0
  488. esphome/components/web_server/web_server.cpp +311 -430
  489. esphome/components/web_server/web_server.h +33 -23
  490. esphome/components/web_server/web_server_v1.cpp +4 -5
  491. esphome/components/web_server_base/__init__.py +5 -2
  492. esphome/components/web_server_base/web_server_base.cpp +2 -94
  493. esphome/components/web_server_base/web_server_base.h +5 -25
  494. esphome/components/web_server_idf/multipart.cpp +254 -0
  495. esphome/components/web_server_idf/multipart.h +86 -0
  496. esphome/components/web_server_idf/utils.cpp +32 -0
  497. esphome/components/web_server_idf/utils.h +10 -0
  498. esphome/components/web_server_idf/web_server_idf.cpp +162 -16
  499. esphome/components/web_server_idf/web_server_idf.h +11 -10
  500. esphome/components/wiegand/wiegand.cpp +2 -2
  501. esphome/components/wifi/__init__.py +18 -0
  502. esphome/components/wifi/wifi_component.cpp +17 -22
  503. esphome/components/wifi/wifi_component.h +27 -23
  504. esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
  505. esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
  506. esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
  507. esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
  508. esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
  509. esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
  510. esphome/components/wireguard/__init__.py +2 -11
  511. esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
  512. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  513. esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
  514. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
  515. esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
  516. esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
  517. esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
  518. esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
  519. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
  520. esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
  521. esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
  522. esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
  523. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
  524. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
  525. esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
  526. esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
  527. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
  528. esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
  529. esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
  530. esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
  531. esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
  532. esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
  533. esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
  534. esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
  535. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
  536. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
  537. esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
  538. esphome/components/zyaura/zyaura.h +0 -1
  539. esphome/config.py +88 -22
  540. esphome/config_helpers.py +74 -1
  541. esphome/config_validation.py +12 -1
  542. esphome/const.py +65 -10
  543. esphome/core/__init__.py +18 -2
  544. esphome/core/application.cpp +163 -10
  545. esphome/core/application.h +145 -165
  546. esphome/core/area.h +19 -0
  547. esphome/core/automation.h +58 -9
  548. esphome/core/color.cpp +3 -5
  549. esphome/core/color.h +16 -16
  550. esphome/core/component.cpp +151 -18
  551. esphome/core/component.h +98 -4
  552. esphome/core/component_iterator.cpp +7 -7
  553. esphome/core/component_iterator.h +9 -7
  554. esphome/core/config.py +155 -6
  555. esphome/core/controller.cpp +4 -2
  556. esphome/core/controller.h +1 -1
  557. esphome/core/datatypes.h +2 -2
  558. esphome/core/defines.h +17 -2
  559. esphome/core/device.h +20 -0
  560. esphome/core/entity_base.cpp +20 -15
  561. esphome/core/entity_base.h +76 -0
  562. esphome/core/entity_helpers.py +162 -1
  563. esphome/core/event_pool.h +81 -0
  564. esphome/core/helpers.cpp +75 -230
  565. esphome/core/helpers.h +164 -104
  566. esphome/core/lock_free_queue.h +151 -0
  567. esphome/core/log.cpp +2 -2
  568. esphome/core/log.h +2 -0
  569. esphome/core/optional.h +5 -0
  570. esphome/core/ring_buffer.cpp +2 -2
  571. esphome/core/scheduler.cpp +278 -103
  572. esphome/core/scheduler.h +157 -17
  573. esphome/core/time.cpp +5 -5
  574. esphome/core/time.h +5 -5
  575. esphome/cpp_generator.py +17 -0
  576. esphome/cpp_helpers.py +0 -22
  577. esphome/cpp_types.py +3 -1
  578. esphome/dashboard/entries.py +1 -1
  579. esphome/dashboard/util/text.py +5 -21
  580. esphome/dashboard/web_server.py +9 -1
  581. esphome/helpers.py +47 -0
  582. esphome/loader.py +15 -1
  583. esphome/pins.py +14 -8
  584. esphome/wizard.py +16 -3
  585. esphome/writer.py +21 -3
  586. esphome/yaml_util.py +0 -2
  587. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/METADATA +10 -9
  588. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/RECORD +593 -533
  589. esphome/components/esp32_ble/ble_event_pool.h +0 -72
  590. esphome/components/esp32_ble/queue.h +0 -85
  591. esphome/components/esp32_hall/esp32_hall.cpp +0 -25
  592. esphome/components/esp32_hall/esp32_hall.h +0 -23
  593. esphome/components/esp32_touch/esp32_touch.cpp +0 -355
  594. esphome/components/ld2410/button/reset_button.cpp +0 -9
  595. esphome/components/ld2450/button/reset_button.cpp +0 -9
  596. esphome/components/openthread/tlv.py +0 -65
  597. /esphome/{dashboard/enum.py → enum.py} +0 -0
  598. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/WHEEL +0 -0
  599. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/entry_points.txt +0 -0
  600. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/licenses/LICENSE +0 -0
  601. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/top_level.txt +0 -0
@@ -95,7 +95,7 @@ SN74HC595_PIN_SCHEMA = pins.gpio_base_schema(
95
95
  cv.int_range(min=0, max=2047),
96
96
  modes=[CONF_OUTPUT],
97
97
  mode_validator=_validate_output_mode,
98
- invertable=True,
98
+ invertible=True,
99
99
  ).extend(
100
100
  {
101
101
  cv.Required(CONF_SN74HC595): cv.use_id(SN74HC595Component),
@@ -1,5 +1,6 @@
1
1
  #include "sn74hc595.h"
2
2
  #include "esphome/core/log.h"
3
+ #include <ranges>
3
4
 
4
5
  namespace esphome {
5
6
  namespace sn74hc595 {
@@ -55,9 +56,9 @@ void SN74HC595Component::digital_write_(uint16_t pin, bool value) {
55
56
  }
56
57
 
57
58
  void SN74HC595GPIOComponent::write_gpio() {
58
- for (auto byte = this->output_bytes_.rbegin(); byte != this->output_bytes_.rend(); byte++) {
59
+ for (uint8_t &output_byte : std::ranges::reverse_view(this->output_bytes_)) {
59
60
  for (int8_t i = 7; i >= 0; i--) {
60
- bool bit = (*byte >> i) & 1;
61
+ bool bit = (output_byte >> i) & 1;
61
62
  this->data_pin_->digital_write(bit);
62
63
  this->clock_pin_->digital_write(true);
63
64
  this->clock_pin_->digital_write(false);
@@ -68,9 +69,9 @@ void SN74HC595GPIOComponent::write_gpio() {
68
69
 
69
70
  #ifdef USE_SPI
70
71
  void SN74HC595SPIComponent::write_gpio() {
71
- for (auto byte = this->output_bytes_.rbegin(); byte != this->output_bytes_.rend(); byte++) {
72
+ for (uint8_t &output_byte : std::ranges::reverse_view(this->output_bytes_)) {
72
73
  this->enable();
73
- this->transfer_byte(*byte);
74
+ this->transfer_byte(output_byte);
74
75
  this->disable();
75
76
  }
76
77
  SN74HC595Component::write_gpio();
@@ -1,7 +1,7 @@
1
1
  #include "sntp_component.h"
2
2
  #include "esphome/core/log.h"
3
3
 
4
- #ifdef USE_ESP_IDF
4
+ #ifdef USE_ESP32
5
5
  #include "esp_sntp.h"
6
6
  #elif USE_ESP8266
7
7
  #include "sntp.h"
@@ -16,7 +16,7 @@ static const char *const TAG = "sntp";
16
16
 
17
17
  void SNTPComponent::setup() {
18
18
  ESP_LOGCONFIG(TAG, "Running setup");
19
- #if defined(USE_ESP_IDF)
19
+ #if defined(USE_ESP32)
20
20
  if (esp_sntp_enabled()) {
21
21
  esp_sntp_stop();
22
22
  }
@@ -46,7 +46,7 @@ void SNTPComponent::dump_config() {
46
46
  }
47
47
  }
48
48
  void SNTPComponent::update() {
49
- #if !defined(USE_ESP_IDF)
49
+ #if !defined(USE_ESP32)
50
50
  // force resync
51
51
  if (sntp_enabled()) {
52
52
  sntp_stop();
@@ -67,6 +67,12 @@ void SNTPComponent::loop() {
67
67
  time.minute, time.second);
68
68
  this->time_sync_callback_.call();
69
69
  this->has_time_ = true;
70
+
71
+ #ifdef USE_ESP_IDF
72
+ // On ESP-IDF, time sync is permanent and update() doesn't force resync
73
+ // Time is now synchronized, no need to check anymore
74
+ this->disable_loop();
75
+ #endif
70
76
  }
71
77
 
72
78
  } // namespace sntp
@@ -7,6 +7,7 @@ from esphome.const import (
7
7
  PLATFORM_BK72XX,
8
8
  PLATFORM_ESP32,
9
9
  PLATFORM_ESP8266,
10
+ PLATFORM_LN882X,
10
11
  PLATFORM_RP2040,
11
12
  PLATFORM_RTL87XX,
12
13
  )
@@ -33,6 +34,7 @@ CONFIG_SCHEMA = cv.All(
33
34
  PLATFORM_ESP8266,
34
35
  PLATFORM_RP2040,
35
36
  PLATFORM_BK72XX,
37
+ PLATFORM_LN882X,
36
38
  PLATFORM_RTL87XX,
37
39
  ]
38
40
  ),
@@ -1,5 +1,6 @@
1
1
  import esphome.codegen as cg
2
2
  import esphome.config_validation as cv
3
+ from esphome.core import CORE
3
4
 
4
5
  CODEOWNERS = ["@esphome/core"]
5
6
 
@@ -16,6 +17,7 @@ CONFIG_SCHEMA = cv.Schema(
16
17
  esp32=IMPLEMENTATION_BSD_SOCKETS,
17
18
  rp2040=IMPLEMENTATION_LWIP_TCP,
18
19
  bk72xx=IMPLEMENTATION_LWIP_SOCKETS,
20
+ ln882x=IMPLEMENTATION_LWIP_SOCKETS,
19
21
  rtl87xx=IMPLEMENTATION_LWIP_SOCKETS,
20
22
  host=IMPLEMENTATION_BSD_SOCKETS,
21
23
  ): cv.one_of(
@@ -39,3 +41,18 @@ async def to_code(config):
39
41
  elif impl == IMPLEMENTATION_BSD_SOCKETS:
40
42
  cg.add_define("USE_SOCKET_IMPL_BSD_SOCKETS")
41
43
  cg.add_define("USE_SOCKET_SELECT_SUPPORT")
44
+
45
+
46
+ def FILTER_SOURCE_FILES() -> list[str]:
47
+ """Return list of socket implementation files that aren't selected by the user."""
48
+ impl = CORE.config["socket"][CONF_IMPLEMENTATION]
49
+
50
+ # Build list of files to exclude based on selected implementation
51
+ excluded = []
52
+ if impl != IMPLEMENTATION_LWIP_TCP:
53
+ excluded.append("lwip_raw_tcp_impl.cpp")
54
+ if impl != IMPLEMENTATION_BSD_SOCKETS:
55
+ excluded.append("bsd_sockets_impl.cpp")
56
+ if impl != IMPLEMENTATION_LWIP_SOCKETS:
57
+ excluded.append("lwip_sockets_impl.cpp")
58
+ return excluded
@@ -13,6 +13,7 @@ from esphome.components.esp32.const import (
13
13
  VARIANT_ESP32S2,
14
14
  VARIANT_ESP32S3,
15
15
  )
16
+ from esphome.config_helpers import filter_source_files_from_platform
16
17
  import esphome.config_validation as cv
17
18
  from esphome.const import (
18
19
  CONF_CLK_PIN,
@@ -31,6 +32,7 @@ from esphome.const import (
31
32
  PLATFORM_ESP32,
32
33
  PLATFORM_ESP8266,
33
34
  PLATFORM_RP2040,
35
+ PlatformFramework,
34
36
  )
35
37
  from esphome.core import CORE, coroutine_with_priority
36
38
  import esphome.final_validate as fv
@@ -79,6 +81,7 @@ CONF_SPI_MODE = "spi_mode"
79
81
  CONF_FORCE_SW = "force_sw"
80
82
  CONF_INTERFACE = "interface"
81
83
  CONF_INTERFACE_INDEX = "interface_index"
84
+ CONF_RELEASE_DEVICE = "release_device"
82
85
  TYPE_SINGLE = "single"
83
86
  TYPE_QUAD = "quad"
84
87
  TYPE_OCTAL = "octal"
@@ -378,6 +381,7 @@ def spi_device_schema(
378
381
  cv.Optional(CONF_SPI_MODE, default=default_mode): cv.enum(
379
382
  SPI_MODE_OPTIONS, upper=True
380
383
  ),
384
+ cv.Optional(CONF_RELEASE_DEVICE): cv.All(cv.boolean, cv.only_with_esp_idf),
381
385
  }
382
386
  if cs_pin_required:
383
387
  schema[cv.Required(CONF_CS_PIN)] = pins.gpio_output_pin_schema
@@ -389,13 +393,15 @@ def spi_device_schema(
389
393
  async def register_spi_device(var, config):
390
394
  parent = await cg.get_variable(config[CONF_SPI_ID])
391
395
  cg.add(var.set_spi_parent(parent))
392
- if CONF_CS_PIN in config:
393
- pin = await cg.gpio_pin_expression(config[CONF_CS_PIN])
396
+ if cs_pin := config.get(CONF_CS_PIN):
397
+ pin = await cg.gpio_pin_expression(cs_pin)
394
398
  cg.add(var.set_cs_pin(pin))
395
- if CONF_DATA_RATE in config:
396
- cg.add(var.set_data_rate(config[CONF_DATA_RATE]))
397
- if CONF_SPI_MODE in config:
398
- cg.add(var.set_mode(config[CONF_SPI_MODE]))
399
+ if data_rate := config.get(CONF_DATA_RATE):
400
+ cg.add(var.set_data_rate(data_rate))
401
+ if spi_mode := config.get(CONF_SPI_MODE):
402
+ cg.add(var.set_mode(spi_mode))
403
+ if release_device := config.get(CONF_RELEASE_DEVICE):
404
+ cg.add(var.set_release_device(release_device))
399
405
 
400
406
 
401
407
  def final_validate_device_schema(name: str, *, require_mosi: bool, require_miso: bool):
@@ -419,3 +425,18 @@ def final_validate_device_schema(name: str, *, require_mosi: bool, require_miso:
419
425
  {cv.Required(CONF_SPI_ID): fv.id_declaration_match_schema(hub_schema)},
420
426
  extra=cv.ALLOW_EXTRA,
421
427
  )
428
+
429
+
430
+ FILTER_SOURCE_FILES = filter_source_files_from_platform(
431
+ {
432
+ "spi_arduino.cpp": {
433
+ PlatformFramework.ESP32_ARDUINO,
434
+ PlatformFramework.ESP8266_ARDUINO,
435
+ PlatformFramework.RP2040_ARDUINO,
436
+ PlatformFramework.BK72XX_ARDUINO,
437
+ PlatformFramework.RTL87XX_ARDUINO,
438
+ PlatformFramework.LN882X_ARDUINO,
439
+ },
440
+ "spi_esp_idf.cpp": {PlatformFramework.ESP32_IDF},
441
+ }
442
+ )
@@ -16,12 +16,13 @@ bool SPIDelegate::is_ready() { return true; }
16
16
  GPIOPin *const NullPin::NULL_PIN = new NullPin(); // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
17
17
 
18
18
  SPIDelegate *SPIComponent::register_device(SPIClient *device, SPIMode mode, SPIBitOrder bit_order, uint32_t data_rate,
19
- GPIOPin *cs_pin) {
19
+ GPIOPin *cs_pin, bool release_device, bool write_only) {
20
20
  if (this->devices_.count(device) != 0) {
21
21
  ESP_LOGE(TAG, "Device already registered");
22
22
  return this->devices_[device];
23
23
  }
24
- SPIDelegate *delegate = this->spi_bus_->get_delegate(data_rate, bit_order, mode, cs_pin); // NOLINT
24
+ SPIDelegate *delegate =
25
+ this->spi_bus_->get_delegate(data_rate, bit_order, mode, cs_pin, release_device, write_only); // NOLINT
25
26
  this->devices_[device] = delegate;
26
27
  return delegate;
27
28
  }
@@ -317,7 +317,8 @@ class SPIBus {
317
317
 
318
318
  SPIBus(GPIOPin *clk, GPIOPin *sdo, GPIOPin *sdi) : clk_pin_(clk), sdo_pin_(sdo), sdi_pin_(sdi) {}
319
319
 
320
- virtual SPIDelegate *get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin) {
320
+ virtual SPIDelegate *get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin,
321
+ bool release_device, bool write_only) {
321
322
  return new SPIDelegateBitBash(data_rate, bit_order, mode, cs_pin, this->clk_pin_, this->sdo_pin_, this->sdi_pin_);
322
323
  }
323
324
 
@@ -334,7 +335,7 @@ class SPIClient;
334
335
  class SPIComponent : public Component {
335
336
  public:
336
337
  SPIDelegate *register_device(SPIClient *device, SPIMode mode, SPIBitOrder bit_order, uint32_t data_rate,
337
- GPIOPin *cs_pin);
338
+ GPIOPin *cs_pin, bool release_device, bool write_only);
338
339
  void unregister_device(SPIClient *device);
339
340
 
340
341
  void set_clk(GPIOPin *clk) { this->clk_pin_ = clk; }
@@ -390,7 +391,8 @@ class SPIClient {
390
391
 
391
392
  virtual void spi_setup() {
392
393
  esph_log_d("spi_device", "mode %u, data_rate %ukHz", (unsigned) this->mode_, (unsigned) (this->data_rate_ / 1000));
393
- this->delegate_ = this->parent_->register_device(this, this->mode_, this->bit_order_, this->data_rate_, this->cs_);
394
+ this->delegate_ = this->parent_->register_device(this, this->mode_, this->bit_order_, this->data_rate_, this->cs_,
395
+ this->release_device_, this->write_only_);
394
396
  }
395
397
 
396
398
  virtual void spi_teardown() {
@@ -399,6 +401,8 @@ class SPIClient {
399
401
  }
400
402
 
401
403
  bool spi_is_ready() { return this->delegate_->is_ready(); }
404
+ void set_release_device(bool release) { this->release_device_ = release; }
405
+ void set_write_only(bool write_only) { this->write_only_ = write_only; }
402
406
 
403
407
  protected:
404
408
  SPIBitOrder bit_order_{BIT_ORDER_MSB_FIRST};
@@ -406,6 +410,8 @@ class SPIClient {
406
410
  uint32_t data_rate_{1000000};
407
411
  SPIComponent *parent_{nullptr};
408
412
  GPIOPin *cs_{nullptr};
413
+ bool release_device_{false};
414
+ bool write_only_{false};
409
415
  SPIDelegate *delegate_{SPIDelegate::NULL_DELEGATE};
410
416
  };
411
417
 
@@ -43,10 +43,7 @@ class SPIDelegateHw : public SPIDelegate {
43
43
  return;
44
44
  }
45
45
  #ifdef USE_RP2040
46
- // avoid overwriting the supplied buffer. Use vector for automatic deallocation
47
- auto rxbuf = std::vector<uint8_t>(length);
48
- memcpy(rxbuf.data(), ptr, length);
49
- this->channel_->transfer((void *) rxbuf.data(), length);
46
+ this->channel_->transfer(ptr, nullptr, length);
50
47
  #elif defined(USE_ESP8266)
51
48
  // ESP8266 SPI library requires the pointer to be word aligned, but the data may not be
52
49
  // so we need to copy the data to a temporary buffer
@@ -89,7 +86,8 @@ class SPIBusHw : public SPIBus {
89
86
  #endif
90
87
  }
91
88
 
92
- SPIDelegate *get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin) override {
89
+ SPIDelegate *get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin,
90
+ bool release_device, bool write_only) override {
93
91
  return new SPIDelegateHw(this->channel_, data_rate, bit_order, mode, cs_pin);
94
92
  }
95
93
 
@@ -11,34 +11,26 @@ static const size_t MAX_TRANSFER_SIZE = 4092; // dictated by ESP-IDF API.
11
11
  class SPIDelegateHw : public SPIDelegate {
12
12
  public:
13
13
  SPIDelegateHw(SPIInterface channel, uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin,
14
- bool write_only)
15
- : SPIDelegate(data_rate, bit_order, mode, cs_pin), channel_(channel), write_only_(write_only) {
16
- spi_device_interface_config_t config = {};
17
- config.mode = static_cast<uint8_t>(mode);
18
- config.clock_speed_hz = static_cast<int>(data_rate);
19
- config.spics_io_num = -1;
20
- config.flags = 0;
21
- config.queue_size = 1;
22
- config.pre_cb = nullptr;
23
- config.post_cb = nullptr;
24
- if (bit_order == BIT_ORDER_LSB_FIRST)
25
- config.flags |= SPI_DEVICE_BIT_LSBFIRST;
26
- if (write_only)
27
- config.flags |= SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_NO_DUMMY;
28
- esp_err_t const err = spi_bus_add_device(channel, &config, &this->handle_);
29
- if (err != ESP_OK)
30
- ESP_LOGE(TAG, "Add device failed - err %X", err);
14
+ bool release_device, bool write_only)
15
+ : SPIDelegate(data_rate, bit_order, mode, cs_pin),
16
+ channel_(channel),
17
+ release_device_(release_device),
18
+ write_only_(write_only) {
19
+ if (!this->release_device_)
20
+ add_device_();
31
21
  }
32
22
 
33
23
  bool is_ready() override { return this->handle_ != nullptr; }
34
24
 
35
25
  void begin_transaction() override {
26
+ if (this->release_device_)
27
+ this->add_device_();
36
28
  if (this->is_ready()) {
37
29
  if (spi_device_acquire_bus(this->handle_, portMAX_DELAY) != ESP_OK)
38
30
  ESP_LOGE(TAG, "Failed to acquire SPI bus");
39
31
  SPIDelegate::begin_transaction();
40
32
  } else {
41
- ESP_LOGW(TAG, "spi_setup called before initialisation");
33
+ ESP_LOGW(TAG, "SPI device not ready, cannot begin transaction");
42
34
  }
43
35
  }
44
36
 
@@ -46,6 +38,10 @@ class SPIDelegateHw : public SPIDelegate {
46
38
  if (this->is_ready()) {
47
39
  SPIDelegate::end_transaction();
48
40
  spi_device_release_bus(this->handle_);
41
+ if (this->release_device_) {
42
+ spi_bus_remove_device(this->handle_);
43
+ this->handle_ = nullptr; // reset handle to indicate no device is registered
44
+ }
49
45
  }
50
46
  }
51
47
 
@@ -189,8 +185,30 @@ class SPIDelegateHw : public SPIDelegate {
189
185
  void read_array(uint8_t *ptr, size_t length) override { this->transfer(nullptr, ptr, length); }
190
186
 
191
187
  protected:
188
+ bool add_device_() {
189
+ spi_device_interface_config_t config = {};
190
+ config.mode = static_cast<uint8_t>(this->mode_);
191
+ config.clock_speed_hz = static_cast<int>(this->data_rate_);
192
+ config.spics_io_num = -1;
193
+ config.flags = 0;
194
+ config.queue_size = 1;
195
+ config.pre_cb = nullptr;
196
+ config.post_cb = nullptr;
197
+ if (this->bit_order_ == BIT_ORDER_LSB_FIRST)
198
+ config.flags |= SPI_DEVICE_BIT_LSBFIRST;
199
+ if (this->write_only_)
200
+ config.flags |= SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_NO_DUMMY;
201
+ esp_err_t const err = spi_bus_add_device(this->channel_, &config, &this->handle_);
202
+ if (err != ESP_OK) {
203
+ ESP_LOGE(TAG, "Add device failed - err %X", err);
204
+ return false;
205
+ }
206
+ return true;
207
+ }
208
+
192
209
  SPIInterface channel_{};
193
210
  spi_device_handle_t handle_{};
211
+ bool release_device_{false};
194
212
  bool write_only_{false};
195
213
  };
196
214
 
@@ -231,9 +249,10 @@ class SPIBusHw : public SPIBus {
231
249
  ESP_LOGE(TAG, "Bus init failed - err %X", err);
232
250
  }
233
251
 
234
- SPIDelegate *get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin) override {
235
- return new SPIDelegateHw(this->channel_, data_rate, bit_order, mode, cs_pin,
236
- Utility::get_pin_no(this->sdi_pin_) == -1);
252
+ SPIDelegate *get_delegate(uint32_t data_rate, SPIBitOrder bit_order, SPIMode mode, GPIOPin *cs_pin,
253
+ bool release_device, bool write_only) override {
254
+ return new SPIDelegateHw(this->channel_, data_rate, bit_order, mode, cs_pin, release_device,
255
+ write_only || Utility::get_pin_no(this->sdi_pin_) == -1);
237
256
  }
238
257
 
239
258
  protected:
@@ -5,7 +5,7 @@ namespace spi_led_strip {
5
5
 
6
6
  SpiLedStrip::SpiLedStrip(uint16_t num_leds) {
7
7
  this->num_leds_ = num_leds;
8
- ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
8
+ RAMAllocator<uint8_t> allocator;
9
9
  this->buffer_size_ = num_leds * 4 + 8;
10
10
  this->buf_ = allocator.allocate(this->buffer_size_);
11
11
  if (this->buf_ == nullptr) {
@@ -26,7 +26,6 @@ class SPS30Component : public PollingComponent, public sensirion_common::Sensiri
26
26
  void setup() override;
27
27
  void update() override;
28
28
  void dump_config() override;
29
- float get_setup_priority() const override { return setup_priority::DATA; }
30
29
 
31
30
  bool start_fan_cleaning();
32
31
 
@@ -224,7 +224,7 @@ bool SSD1306::is_sh1106_() const {
224
224
  }
225
225
  bool SSD1306::is_sh1107_() const { return this->model_ == SH1107_MODEL_128_64 || this->model_ == SH1107_MODEL_128_128; }
226
226
  bool SSD1306::is_ssd1305_() const {
227
- return this->model_ == SSD1305_MODEL_128_64 || this->model_ == SSD1305_MODEL_128_64;
227
+ return this->model_ == SSD1305_MODEL_128_64 || this->model_ == SSD1305_MODEL_128_32;
228
228
  }
229
229
  void SSD1306::update() {
230
230
  this->do_update_();
@@ -12,10 +12,8 @@ void ST7701S::setup() {
12
12
 
13
13
  esp_lcd_rgb_panel_config_t config{};
14
14
  config.flags.fb_in_psram = 1;
15
- #if ESP_IDF_VERSION_MAJOR >= 5
16
15
  config.bounce_buffer_size_px = this->width_ * 10;
17
16
  config.num_fbs = 1;
18
- #endif // ESP_IDF_VERSION_MAJOR
19
17
  config.timings.h_res = this->width_;
20
18
  config.timings.v_res = this->height_;
21
19
  config.timings.hsync_pulse_width = this->hsync_pulse_width_;
@@ -48,10 +46,8 @@ void ST7701S::setup() {
48
46
  }
49
47
 
50
48
  void ST7701S::loop() {
51
- #if ESP_IDF_VERSION_MAJOR >= 5
52
49
  if (this->handle_ != nullptr)
53
50
  esp_lcd_rgb_panel_restart(this->handle_);
54
- #endif // ESP_IDF_VERSION_MAJOR
55
51
  }
56
52
 
57
53
  void ST7701S::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order,
@@ -13,8 +13,6 @@ class StatusBinarySensor : public binary_sensor::BinarySensor, public Component
13
13
  void setup() override;
14
14
  void dump_config() override;
15
15
 
16
- float get_setup_priority() const override { return setup_priority::DATA; }
17
-
18
16
  bool is_status_binary_sensor() const override { return true; }
19
17
  };
20
18
 
@@ -5,6 +5,13 @@ 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
15
 
9
16
  CODEOWNERS = ["@esphome/core"]
10
17
  _LOGGER = logging.getLogger(__name__)
@@ -28,7 +35,7 @@ def validate_substitution_key(value):
28
35
 
29
36
  CONFIG_SCHEMA = cv.Schema(
30
37
  {
31
- validate_substitution_key: cv.string_strict,
38
+ validate_substitution_key: object,
32
39
  }
33
40
  )
34
41
 
@@ -37,7 +44,42 @@ async def to_code(config):
37
44
  pass
38
45
 
39
46
 
40
- def _expand_substitutions(substitutions, value, path, ignore_missing):
47
+ def _expand_jinja(value, orig_value, path, jinja, ignore_missing):
48
+ if has_jinja(value):
49
+ # If the original value passed in to this function is a JinjaStr, it means it contains an unresolved
50
+ # Jinja expression from a previous pass.
51
+ if isinstance(orig_value, JinjaStr):
52
+ # Rebuild the JinjaStr in case it was lost while replacing substitutions.
53
+ value = JinjaStr(value, orig_value.upvalues)
54
+ try:
55
+ # Invoke the jinja engine to evaluate the expression.
56
+ 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
+ )
66
+ except (
67
+ TemplateError,
68
+ TemplateRuntimeError,
69
+ RuntimeError,
70
+ ArithmeticError,
71
+ AttributeError,
72
+ TypeError,
73
+ ) as err:
74
+ raise cv.Invalid(
75
+ f"{type(err).__name__} Error evaluating jinja expression '{value}': {str(err)}."
76
+ f" See {'->'.join(str(x) for x in path)}",
77
+ path,
78
+ )
79
+ return value
80
+
81
+
82
+ def _expand_substitutions(substitutions, value, path, jinja, ignore_missing):
41
83
  if "$" not in value:
42
84
  return value
43
85
 
@@ -47,7 +89,8 @@ def _expand_substitutions(substitutions, value, path, ignore_missing):
47
89
  while True:
48
90
  m = cv.VARIABLE_PROG.search(value, i)
49
91
  if not m:
50
- # Nothing more to match. Done
92
+ # No more variable substitutions found. See if the remainder looks like a jinja template
93
+ value = _expand_jinja(value, orig_value, path, jinja, ignore_missing)
51
94
  break
52
95
 
53
96
  i, j = m.span(0)
@@ -67,8 +110,15 @@ def _expand_substitutions(substitutions, value, path, ignore_missing):
67
110
  continue
68
111
 
69
112
  sub = substitutions[name]
113
+
114
+ if i == 0 and j == len(value):
115
+ # The variable spans the whole expression, e.g., "${varName}". Return its resolved value directly
116
+ # to conserve its type.
117
+ value = sub
118
+ break
119
+
70
120
  tail = value[j:]
71
- value = value[:i] + sub
121
+ value = value[:i] + str(sub)
72
122
  i = len(value)
73
123
  value += tail
74
124
 
@@ -77,36 +127,40 @@ def _expand_substitutions(substitutions, value, path, ignore_missing):
77
127
  if isinstance(orig_value, ESPHomeDataBase):
78
128
  # even though string can get larger or smaller, the range should point
79
129
  # to original document marks
80
- return make_data_base(value, orig_value)
130
+ value = make_data_base(value, orig_value)
81
131
 
82
132
  return value
83
133
 
84
134
 
85
- def _substitute_item(substitutions, item, path, ignore_missing):
135
+ def _substitute_item(substitutions, item, path, jinja, ignore_missing):
86
136
  if isinstance(item, list):
87
137
  for i, it in enumerate(item):
88
- sub = _substitute_item(substitutions, it, path + [i], ignore_missing)
138
+ sub = _substitute_item(substitutions, it, path + [i], jinja, ignore_missing)
89
139
  if sub is not None:
90
140
  item[i] = sub
91
141
  elif isinstance(item, dict):
92
142
  replace_keys = []
93
143
  for k, v in item.items():
94
144
  if path or k != CONF_SUBSTITUTIONS:
95
- sub = _substitute_item(substitutions, k, path + [k], ignore_missing)
145
+ sub = _substitute_item(
146
+ substitutions, k, path + [k], jinja, ignore_missing
147
+ )
96
148
  if sub is not None:
97
149
  replace_keys.append((k, sub))
98
- sub = _substitute_item(substitutions, v, path + [k], ignore_missing)
150
+ sub = _substitute_item(substitutions, v, path + [k], jinja, ignore_missing)
99
151
  if sub is not None:
100
152
  item[k] = sub
101
153
  for old, new in replace_keys:
102
154
  item[new] = merge_config(item.get(old), item.get(new))
103
155
  del item[old]
104
156
  elif isinstance(item, str):
105
- sub = _expand_substitutions(substitutions, item, path, ignore_missing)
106
- if sub != item:
157
+ sub = _expand_substitutions(substitutions, item, path, jinja, ignore_missing)
158
+ if isinstance(sub, JinjaStr) or sub != item:
107
159
  return sub
108
160
  elif isinstance(item, (core.Lambda, Extend, Remove)):
109
- sub = _expand_substitutions(substitutions, item.value, path, ignore_missing)
161
+ sub = _expand_substitutions(
162
+ substitutions, item.value, path, jinja, ignore_missing
163
+ )
110
164
  if sub != item:
111
165
  item.value = sub
112
166
  return None
@@ -116,11 +170,11 @@ def do_substitution_pass(config, command_line_substitutions, ignore_missing=Fals
116
170
  if CONF_SUBSTITUTIONS not in config and not command_line_substitutions:
117
171
  return
118
172
 
119
- substitutions = config.get(CONF_SUBSTITUTIONS)
120
- if substitutions is None:
121
- substitutions = command_line_substitutions
122
- elif command_line_substitutions:
123
- substitutions = {**substitutions, **command_line_substitutions}
173
+ # Merge substitutions in config, overriding with substitutions coming from command line:
174
+ substitutions = {
175
+ **config.get(CONF_SUBSTITUTIONS, {}),
176
+ **(command_line_substitutions or {}),
177
+ }
124
178
  with cv.prepend_path("substitutions"):
125
179
  if not isinstance(substitutions, dict):
126
180
  raise cv.Invalid(
@@ -133,7 +187,7 @@ def do_substitution_pass(config, command_line_substitutions, ignore_missing=Fals
133
187
  sub = validate_substitution_key(key)
134
188
  if sub != key:
135
189
  replace_keys.append((key, sub))
136
- substitutions[key] = cv.string_strict(value)
190
+ substitutions[key] = value
137
191
  for old, new in replace_keys:
138
192
  substitutions[new] = substitutions[old]
139
193
  del substitutions[old]
@@ -141,4 +195,7 @@ def do_substitution_pass(config, command_line_substitutions, ignore_missing=Fals
141
195
  config[CONF_SUBSTITUTIONS] = substitutions
142
196
  # Move substitutions to the first place to replace substitutions in them correctly
143
197
  config.move_to_end(CONF_SUBSTITUTIONS, False)
144
- _substitute_item(substitutions, config, [], ignore_missing)
198
+
199
+ # Create a Jinja environment that will consider substitutions in scope:
200
+ jinja = Jinja(substitutions)
201
+ _substitute_item(substitutions, config, [], jinja, ignore_missing)