esphome 2025.6.3__py3-none-any.whl → 2025.7.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 (606) 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 +57 -21
  22. esphome/components/api/api_connection.cpp +344 -539
  23. esphome/components/api/api_connection.h +224 -141
  24. esphome/components/api/api_frame_helper.cpp +91 -127
  25. esphome/components/api/api_frame_helper.h +64 -54
  26. esphome/components/api/api_pb2.cpp +1837 -9044
  27. esphome/components/api/api_pb2.h +532 -685
  28. esphome/components/api/api_pb2_dump.cpp +4432 -0
  29. esphome/components/api/api_pb2_service.cpp +184 -425
  30. esphome/components/api/api_pb2_service.h +13 -6
  31. esphome/components/api/api_server.cpp +131 -167
  32. esphome/components/api/api_server.h +38 -10
  33. esphome/components/api/client.py +8 -2
  34. esphome/components/api/custom_api_device.h +8 -0
  35. esphome/components/api/list_entities.cpp +37 -104
  36. esphome/components/api/list_entities.h +33 -23
  37. esphome/components/api/proto.h +532 -26
  38. esphome/components/api/subscribe_state.cpp +23 -29
  39. esphome/components/api/subscribe_state.h +26 -19
  40. esphome/components/api/user_services.h +2 -0
  41. esphome/components/as5600/as5600.h +0 -1
  42. esphome/components/async_tcp/__init__.py +14 -5
  43. esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
  44. esphome/components/atm90e32/atm90e32.cpp +2 -1
  45. esphome/components/audio/audio_decoder.cpp +1 -1
  46. esphome/components/audio/audio_transfer_buffer.cpp +2 -2
  47. esphome/components/b_parasite/b_parasite.h +0 -1
  48. esphome/components/bedjet/bedjet_hub.cpp +5 -1
  49. esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
  50. esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
  51. esphome/components/bh1750/bh1750.cpp +5 -5
  52. esphome/components/binary_sensor/__init__.py +82 -5
  53. esphome/components/binary_sensor/automation.h +19 -1
  54. esphome/components/binary_sensor/binary_sensor.cpp +12 -30
  55. esphome/components/binary_sensor/binary_sensor.h +11 -25
  56. esphome/components/binary_sensor/filter.cpp +29 -24
  57. esphome/components/binary_sensor/filter.h +20 -10
  58. esphome/components/ble_client/output/ble_binary_output.h +0 -1
  59. esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
  60. esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
  61. esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
  62. esphome/components/ble_client/sensor/ble_sensor.h +0 -1
  63. esphome/components/ble_client/switch/ble_switch.h +0 -1
  64. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
  65. esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
  66. esphome/components/ble_presence/ble_presence_device.h +0 -1
  67. esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
  68. esphome/components/ble_scanner/ble_scanner.h +0 -1
  69. esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
  70. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
  71. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
  72. esphome/components/bme680/sensor.py +1 -1
  73. esphome/components/bmp581/bmp581.h +0 -2
  74. esphome/components/button/__init__.py +5 -2
  75. esphome/components/camera/__init__.py +1 -0
  76. esphome/components/camera/camera.cpp +22 -0
  77. esphome/components/camera/camera.h +80 -0
  78. esphome/components/canbus/__init__.py +1 -0
  79. esphome/components/cap1188/cap1188.h +0 -1
  80. esphome/components/captive_portal/__init__.py +12 -2
  81. esphome/components/captive_portal/captive_portal.cpp +12 -2
  82. esphome/components/captive_portal/captive_portal.h +5 -2
  83. esphome/components/ccs811/ccs811.h +0 -2
  84. esphome/components/climate/__init__.py +5 -2
  85. esphome/components/cm1106/sensor.py +2 -2
  86. esphome/components/const/__init__.py +2 -0
  87. esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
  88. esphome/components/copy/button/copy_button.h +0 -1
  89. esphome/components/copy/cover/copy_cover.h +0 -1
  90. esphome/components/copy/fan/copy_fan.h +0 -1
  91. esphome/components/copy/lock/copy_lock.h +0 -1
  92. esphome/components/copy/number/copy_number.h +0 -1
  93. esphome/components/copy/select/copy_select.h +0 -1
  94. esphome/components/copy/sensor/copy_sensor.h +0 -1
  95. esphome/components/copy/switch/copy_switch.h +0 -1
  96. esphome/components/copy/text/copy_text.h +0 -1
  97. esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
  98. esphome/components/cover/__init__.py +5 -2
  99. esphome/components/cs5460a/cs5460a.h +0 -1
  100. esphome/components/datetime/__init__.py +4 -2
  101. esphome/components/debug/__init__.py +20 -0
  102. esphome/components/debug/debug_esp32.cpp +2 -0
  103. esphome/components/deep_sleep/__init__.py +43 -9
  104. esphome/components/demo/__init__.py +2 -2
  105. esphome/components/display/display.cpp +4 -3
  106. esphome/components/display/display.h +0 -2
  107. esphome/components/display/display_buffer.cpp +1 -1
  108. esphome/components/ds2484/__init__.py +1 -0
  109. esphome/components/ds2484/ds2484.cpp +209 -0
  110. esphome/components/ds2484/ds2484.h +43 -0
  111. esphome/components/ds2484/one_wire.py +37 -0
  112. esphome/components/duty_time/duty_time_sensor.h +0 -1
  113. esphome/components/ens160_base/ens160_base.h +0 -1
  114. esphome/components/es7210/es7210.h +0 -1
  115. esphome/components/es7243e/es7243e.h +0 -1
  116. esphome/components/es8156/es8156.h +0 -1
  117. esphome/components/es8311/es8311.h +0 -1
  118. esphome/components/es8388/es8388.h +0 -1
  119. esphome/components/esp32/__init__.py +103 -135
  120. esphome/components/esp32/core.cpp +0 -4
  121. esphome/components/esp32/gpio.h +1 -1
  122. esphome/components/esp32/helpers.cpp +69 -0
  123. esphome/components/esp32_ble/ble.cpp +5 -6
  124. esphome/components/esp32_ble/ble.h +29 -14
  125. esphome/components/esp32_ble/ble_event.h +6 -6
  126. esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
  127. esphome/components/esp32_ble_client/ble_client_base.h +24 -9
  128. esphome/components/esp32_ble_tracker/__init__.py +2 -8
  129. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
  130. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
  131. esphome/components/esp32_camera/__init__.py +112 -98
  132. esphome/components/esp32_camera/esp32_camera.cpp +41 -31
  133. esphome/components/esp32_camera/esp32_camera.h +35 -30
  134. esphome/components/esp32_camera_web_server/__init__.py +2 -1
  135. esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
  136. esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
  137. esphome/components/esp32_hall/sensor.py +2 -21
  138. esphome/components/esp32_hosted/__init__.py +101 -0
  139. esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
  140. esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
  141. esphome/components/esp32_rmt/__init__.py +0 -58
  142. esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
  143. esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
  144. esphome/components/esp32_rmt_led_strip/light.py +14 -76
  145. esphome/components/esp32_touch/esp32_touch.h +174 -28
  146. esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
  147. esphome/components/esp32_touch/esp32_touch_v1.cpp +240 -0
  148. esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
  149. esphome/components/esp8266/__init__.py +2 -0
  150. esphome/components/esp8266/gpio.cpp +10 -10
  151. esphome/components/esp8266/helpers.cpp +31 -0
  152. esphome/components/esphome/ota/__init__.py +1 -0
  153. esphome/components/esphome/ota/ota_esphome.cpp +24 -19
  154. esphome/components/ethernet/__init__.py +42 -23
  155. esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
  156. esphome/components/ethernet/ethernet_component.cpp +69 -29
  157. esphome/components/ethernet/ethernet_component.h +18 -10
  158. esphome/components/event/__init__.py +5 -2
  159. esphome/components/ezo/ezo.h +0 -1
  160. esphome/components/ezo_pmp/ezo_pmp.h +0 -1
  161. esphome/components/fan/__init__.py +5 -2
  162. esphome/components/feedback/feedback_cover.h +0 -1
  163. esphome/components/font/__init__.py +92 -82
  164. esphome/components/font/font.cpp +9 -2
  165. esphome/components/font/font.h +20 -5
  166. esphome/components/fs3000/fs3000.h +0 -1
  167. esphome/components/gcja5/gcja5.h +0 -1
  168. esphome/components/gl_r01_i2c/__init__.py +0 -0
  169. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
  170. esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
  171. esphome/components/gl_r01_i2c/sensor.py +36 -0
  172. esphome/components/gp8403/gp8403.h +0 -1
  173. esphome/components/gpio/binary_sensor/__init__.py +17 -0
  174. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
  175. esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
  176. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
  177. esphome/components/he60r/he60r.h +0 -1
  178. esphome/components/heatpumpir/climate.py +2 -1
  179. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  180. esphome/components/heatpumpir/heatpumpir.h +1 -0
  181. esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
  182. esphome/components/host/__init__.py +3 -1
  183. esphome/components/host/helpers.cpp +57 -0
  184. esphome/components/http_request/__init__.py +19 -1
  185. esphome/components/http_request/http_request.h +1 -1
  186. esphome/components/http_request/http_request_arduino.h +1 -0
  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 +421 -268
  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 +5 -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 +132 -47
  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 +34 -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 +2 -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 +0 -4
  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/usb_host/usb_host_client.cpp +10 -10
  477. esphome/components/usb_uart/cp210x.cpp +1 -1
  478. esphome/components/usb_uart/usb_uart.cpp +41 -44
  479. esphome/components/usb_uart/usb_uart.h +4 -3
  480. esphome/components/valve/__init__.py +5 -2
  481. esphome/components/vbus/vbus.h +0 -1
  482. esphome/components/veml3235/veml3235.h +0 -1
  483. esphome/components/veml7700/veml7700.h +0 -1
  484. esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
  485. esphome/components/voice_assistant/voice_assistant.cpp +4 -4
  486. esphome/components/watchdog/watchdog.cpp +0 -4
  487. esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
  488. esphome/components/web_server/__init__.py +34 -19
  489. esphome/components/web_server/ota/__init__.py +32 -0
  490. esphome/components/web_server/ota/ota_web_server.cpp +210 -0
  491. esphome/components/web_server/ota/ota_web_server.h +26 -0
  492. esphome/components/web_server/web_server.cpp +305 -427
  493. esphome/components/web_server/web_server.h +33 -23
  494. esphome/components/web_server/web_server_v1.cpp +4 -5
  495. esphome/components/web_server_base/__init__.py +5 -2
  496. esphome/components/web_server_base/web_server_base.cpp +2 -94
  497. esphome/components/web_server_base/web_server_base.h +5 -25
  498. esphome/components/web_server_idf/multipart.cpp +254 -0
  499. esphome/components/web_server_idf/multipart.h +86 -0
  500. esphome/components/web_server_idf/utils.cpp +32 -0
  501. esphome/components/web_server_idf/utils.h +10 -0
  502. esphome/components/web_server_idf/web_server_idf.cpp +162 -16
  503. esphome/components/web_server_idf/web_server_idf.h +11 -10
  504. esphome/components/wiegand/wiegand.cpp +2 -2
  505. esphome/components/wifi/__init__.py +18 -0
  506. esphome/components/wifi/wifi_component.cpp +17 -22
  507. esphome/components/wifi/wifi_component.h +27 -23
  508. esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
  509. esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
  510. esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
  511. esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
  512. esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
  513. esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
  514. esphome/components/wireguard/__init__.py +2 -11
  515. esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
  516. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  517. esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
  518. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
  519. esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
  520. esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
  521. esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
  522. esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
  523. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
  524. esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
  525. esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
  526. esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
  527. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
  528. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
  529. esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
  530. esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
  531. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
  532. esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
  533. esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
  534. esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
  535. esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
  536. esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
  537. esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
  538. esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
  539. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
  540. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
  541. esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
  542. esphome/components/zyaura/zyaura.h +0 -1
  543. esphome/config.py +88 -22
  544. esphome/config_helpers.py +74 -1
  545. esphome/config_validation.py +12 -1
  546. esphome/const.py +65 -10
  547. esphome/core/__init__.py +18 -2
  548. esphome/core/application.cpp +163 -10
  549. esphome/core/application.h +145 -165
  550. esphome/core/area.h +19 -0
  551. esphome/core/automation.h +58 -9
  552. esphome/core/color.cpp +3 -5
  553. esphome/core/color.h +16 -16
  554. esphome/core/component.cpp +151 -18
  555. esphome/core/component.h +98 -4
  556. esphome/core/component_iterator.cpp +11 -9
  557. esphome/core/component_iterator.h +12 -10
  558. esphome/core/config.py +155 -6
  559. esphome/core/controller.cpp +4 -2
  560. esphome/core/controller.h +1 -1
  561. esphome/core/datatypes.h +2 -2
  562. esphome/core/defines.h +17 -2
  563. esphome/core/device.h +20 -0
  564. esphome/core/entity_base.cpp +20 -15
  565. esphome/core/entity_base.h +76 -0
  566. esphome/core/entity_helpers.py +168 -1
  567. esphome/core/event_pool.h +81 -0
  568. esphome/core/helpers.cpp +75 -230
  569. esphome/core/helpers.h +164 -104
  570. esphome/core/lock_free_queue.h +151 -0
  571. esphome/core/log.cpp +2 -2
  572. esphome/core/log.h +2 -0
  573. esphome/core/optional.h +5 -0
  574. esphome/core/ring_buffer.cpp +2 -2
  575. esphome/core/scheduler.cpp +275 -103
  576. esphome/core/scheduler.h +154 -17
  577. esphome/core/time.cpp +5 -5
  578. esphome/core/time.h +5 -5
  579. esphome/cpp_generator.py +17 -0
  580. esphome/cpp_helpers.py +0 -22
  581. esphome/cpp_types.py +3 -1
  582. esphome/dashboard/entries.py +1 -1
  583. esphome/dashboard/util/text.py +5 -21
  584. esphome/dashboard/web_server.py +9 -1
  585. esphome/helpers.py +47 -0
  586. esphome/loader.py +15 -1
  587. esphome/pins.py +14 -8
  588. esphome/wizard.py +17 -4
  589. esphome/writer.py +21 -3
  590. esphome/yaml_util.py +0 -2
  591. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/METADATA +10 -9
  592. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/RECORD +597 -538
  593. esphome/components/api/api_pb2_size.h +0 -361
  594. esphome/components/esp32_ble/ble_event_pool.h +0 -72
  595. esphome/components/esp32_ble/queue.h +0 -85
  596. esphome/components/esp32_hall/esp32_hall.cpp +0 -25
  597. esphome/components/esp32_hall/esp32_hall.h +0 -23
  598. esphome/components/esp32_touch/esp32_touch.cpp +0 -355
  599. esphome/components/ld2410/button/reset_button.cpp +0 -9
  600. esphome/components/ld2450/button/reset_button.cpp +0 -9
  601. esphome/components/openthread/tlv.py +0 -65
  602. /esphome/{dashboard/enum.py → enum.py} +0 -0
  603. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/WHEEL +0 -0
  604. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/entry_points.txt +0 -0
  605. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/licenses/LICENSE +0 -0
  606. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/top_level.txt +0 -0
esphome/core/config.py CHANGED
@@ -1,18 +1,25 @@
1
+ from __future__ import annotations
2
+
1
3
  import logging
2
4
  import os
3
5
  from pathlib import Path
4
6
 
5
- from esphome import automation
7
+ from esphome import automation, core
6
8
  import esphome.codegen as cg
9
+ from esphome.config_helpers import filter_source_files_from_platform
7
10
  import esphome.config_validation as cv
8
11
  from esphome.const import (
9
12
  CONF_AREA,
13
+ CONF_AREA_ID,
14
+ CONF_AREAS,
10
15
  CONF_BUILD_PATH,
11
16
  CONF_COMMENT,
12
17
  CONF_COMPILE_PROCESS_LIMIT,
13
18
  CONF_DEBUG_SCHEDULER,
19
+ CONF_DEVICES,
14
20
  CONF_ESPHOME,
15
21
  CONF_FRIENDLY_NAME,
22
+ CONF_ID,
16
23
  CONF_INCLUDES,
17
24
  CONF_LIBRARIES,
18
25
  CONF_MIN_VERSION,
@@ -29,10 +36,17 @@ from esphome.const import (
29
36
  CONF_TRIGGER_ID,
30
37
  CONF_VERSION,
31
38
  KEY_CORE,
39
+ PlatformFramework,
32
40
  __version__ as ESPHOME_VERSION,
33
41
  )
34
42
  from esphome.core import CORE, coroutine_with_priority
35
- from esphome.helpers import copy_file_if_changed, get_str_env, walk_files
43
+ from esphome.helpers import (
44
+ copy_file_if_changed,
45
+ fnv1a_32bit_hash,
46
+ get_str_env,
47
+ walk_files,
48
+ )
49
+ from esphome.types import ConfigType
36
50
 
37
51
  _LOGGER = logging.getLogger(__name__)
38
52
 
@@ -48,7 +62,8 @@ LoopTrigger = cg.esphome_ns.class_(
48
62
  ProjectUpdateTrigger = cg.esphome_ns.class_(
49
63
  "ProjectUpdateTrigger", cg.Component, automation.Trigger.template(cg.std_string)
50
64
  )
51
-
65
+ Device = cg.esphome_ns.class_("Device")
66
+ Area = cg.esphome_ns.class_("Area")
52
67
 
53
68
  VALID_INCLUDE_EXTS = {".h", ".hpp", ".tcc", ".ino", ".cpp", ".c"}
54
69
 
@@ -71,6 +86,56 @@ def validate_hostname(config):
71
86
  return config
72
87
 
73
88
 
89
+ def validate_ids_and_references(config: ConfigType) -> ConfigType:
90
+ """Validate that there are no hash collisions between IDs and that area_id references are valid.
91
+
92
+ This validation is critical because we use 32-bit hashes for performance on microcontrollers.
93
+ By detecting collisions at compile time, we prevent any runtime issues while maintaining
94
+ optimal performance on 32-bit platforms. In practice, with typical deployments having only
95
+ a handful of areas and devices, hash collisions are virtually impossible.
96
+ """
97
+
98
+ # Helper to check hash collisions
99
+ def check_hash_collision(
100
+ id_obj: core.ID,
101
+ hash_dict: dict[int, str],
102
+ item_type: str,
103
+ path: list[str | int],
104
+ ) -> None:
105
+ hash_val: int = fnv1a_32bit_hash(id_obj.id)
106
+ if hash_val in hash_dict and hash_dict[hash_val] != id_obj.id:
107
+ raise cv.Invalid(
108
+ f"{item_type} ID '{id_obj.id}' with hash {hash_val} collides with "
109
+ f"existing {item_type.lower()} ID '{hash_dict[hash_val]}'",
110
+ path=path,
111
+ )
112
+ hash_dict[hash_val] = id_obj.id
113
+
114
+ # Collect all areas
115
+ all_areas: list[dict[str, str | core.ID]] = []
116
+ if CONF_AREA in config:
117
+ all_areas.append(config[CONF_AREA])
118
+ all_areas.extend(config[CONF_AREAS])
119
+
120
+ # Validate area hash collisions and collect IDs
121
+ area_hashes: dict[int, str] = {}
122
+ area_ids: set[str] = set()
123
+ for area in all_areas:
124
+ area_id: core.ID = area[CONF_ID]
125
+ check_hash_collision(area_id, area_hashes, "Area", [CONF_AREAS, area_id.id])
126
+ area_ids.add(area_id.id)
127
+
128
+ # Validate device hash collisions and area references
129
+ device_hashes: dict[int, str] = {}
130
+ for device in config[CONF_DEVICES]:
131
+ device_id: core.ID = device[CONF_ID]
132
+ check_hash_collision(
133
+ device_id, device_hashes, "Device", [CONF_DEVICES, device_id.id]
134
+ )
135
+
136
+ return config
137
+
138
+
74
139
  def valid_include(value):
75
140
  # Look for "<...>" includes
76
141
  if value.startswith("<") and value.endswith(">"):
@@ -111,13 +176,32 @@ if "ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT" in os.environ:
111
176
  else:
112
177
  _compile_process_limit_default = cv.UNDEFINED
113
178
 
179
+ AREA_SCHEMA = cv.Schema(
180
+ {
181
+ cv.GenerateID(CONF_ID): cv.declare_id(Area),
182
+ cv.Required(CONF_NAME): cv.string,
183
+ }
184
+ )
185
+
186
+ DEVICE_SCHEMA = cv.Schema(
187
+ {
188
+ cv.GenerateID(CONF_ID): cv.declare_id(Device),
189
+ cv.Required(CONF_NAME): cv.string,
190
+ cv.Optional(CONF_AREA_ID): cv.use_id(Area),
191
+ }
192
+ )
193
+
194
+
195
+ def validate_area_config(config: dict | str) -> dict[str, str | core.ID]:
196
+ return cv.maybe_simple_value(AREA_SCHEMA, key=CONF_NAME)(config)
197
+
114
198
 
115
199
  CONFIG_SCHEMA = cv.All(
116
200
  cv.Schema(
117
201
  {
118
202
  cv.Required(CONF_NAME): cv.valid_name,
119
203
  cv.Optional(CONF_FRIENDLY_NAME, ""): cv.string,
120
- cv.Optional(CONF_AREA, ""): cv.string,
204
+ cv.Optional(CONF_AREA): validate_area_config,
121
205
  cv.Optional(CONF_COMMENT): cv.string,
122
206
  cv.Required(CONF_BUILD_PATH): cv.string,
123
207
  cv.Optional(CONF_PLATFORMIO_OPTIONS, default={}): cv.Schema(
@@ -167,11 +251,17 @@ CONFIG_SCHEMA = cv.All(
167
251
  cv.Optional(
168
252
  CONF_COMPILE_PROCESS_LIMIT, default=_compile_process_limit_default
169
253
  ): cv.int_range(min=1, max=get_usable_cpu_count()),
254
+ cv.Optional(CONF_AREAS, default=[]): cv.ensure_list(AREA_SCHEMA),
255
+ cv.Optional(CONF_DEVICES, default=[]): cv.ensure_list(DEVICE_SCHEMA),
170
256
  }
171
257
  ),
172
258
  validate_hostname,
173
259
  )
174
260
 
261
+
262
+ FINAL_VALIDATE_SCHEMA = cv.All(validate_ids_and_references)
263
+
264
+
175
265
  PRELOAD_CONFIG_SCHEMA = cv.Schema(
176
266
  {
177
267
  cv.Required(CONF_NAME): cv.valid_name,
@@ -336,7 +426,7 @@ async def _add_platform_reserves() -> None:
336
426
 
337
427
 
338
428
  @coroutine_with_priority(100.0)
339
- async def to_code(config):
429
+ async def to_code(config: ConfigType) -> None:
340
430
  cg.add_global(cg.global_ns.namespace("esphome").using)
341
431
  # These can be used by user lambdas, put them to default scope
342
432
  cg.add_global(cg.RawExpression("using std::isnan"))
@@ -347,7 +437,6 @@ async def to_code(config):
347
437
  cg.App.pre_setup(
348
438
  config[CONF_NAME],
349
439
  config[CONF_FRIENDLY_NAME],
350
- config[CONF_AREA],
351
440
  config.get(CONF_COMMENT, ""),
352
441
  cg.RawExpression('__DATE__ ", " __TIME__'),
353
442
  config[CONF_NAME_ADD_MAC_SUFFIX],
@@ -417,3 +506,63 @@ async def to_code(config):
417
506
 
418
507
  if config[CONF_PLATFORMIO_OPTIONS]:
419
508
  CORE.add_job(_add_platformio_options, config[CONF_PLATFORMIO_OPTIONS])
509
+
510
+ # Process areas
511
+ all_areas: list[dict[str, str | core.ID]] = []
512
+ if CONF_AREA in config:
513
+ all_areas.append(config[CONF_AREA])
514
+ all_areas.extend(config[CONF_AREAS])
515
+
516
+ if all_areas:
517
+ cg.add(cg.RawStatement(f"App.reserve_area({len(all_areas)});"))
518
+ cg.add_define("USE_AREAS")
519
+
520
+ for area_conf in all_areas:
521
+ area_id: core.ID = area_conf[CONF_ID]
522
+ area_id_hash: int = fnv1a_32bit_hash(area_id.id)
523
+ area_name: str = area_conf[CONF_NAME]
524
+
525
+ area_var = cg.new_Pvariable(area_id)
526
+ cg.add(area_var.set_area_id(area_id_hash))
527
+ cg.add(area_var.set_name(area_name))
528
+ cg.add(cg.App.register_area(area_var))
529
+
530
+ # Process devices
531
+ devices: list[dict[str, str | core.ID]] = config[CONF_DEVICES]
532
+ if not devices:
533
+ return
534
+
535
+ # Reserve space for devices
536
+ cg.add(cg.RawStatement(f"App.reserve_device({len(devices)});"))
537
+ cg.add_define("USE_DEVICES")
538
+
539
+ # Process each device
540
+ for dev_conf in devices:
541
+ device_id: core.ID = dev_conf[CONF_ID]
542
+ device_id_hash = fnv1a_32bit_hash(device_id.id)
543
+ device_name: str = dev_conf[CONF_NAME]
544
+
545
+ dev = cg.new_Pvariable(device_id)
546
+ cg.add(dev.set_device_id(device_id_hash))
547
+ cg.add(dev.set_name(device_name))
548
+
549
+ # Set area if specified
550
+ if CONF_AREA_ID in dev_conf:
551
+ area_id: core.ID = dev_conf[CONF_AREA_ID]
552
+ area_id_hash = fnv1a_32bit_hash(area_id.id)
553
+ cg.add(dev.set_area_id(area_id_hash))
554
+
555
+ cg.add(cg.App.register_device(dev))
556
+
557
+
558
+ # Platform-specific source files for core
559
+ FILTER_SOURCE_FILES = filter_source_files_from_platform(
560
+ {
561
+ "ring_buffer.cpp": {
562
+ PlatformFramework.ESP32_ARDUINO,
563
+ PlatformFramework.ESP32_IDF,
564
+ },
565
+ # Note: lock_free_queue.h and event_pool.h are header files and don't need to be filtered
566
+ # as they are only included when needed by the preprocessor
567
+ }
568
+ )
@@ -7,8 +7,10 @@ namespace esphome {
7
7
  void Controller::setup_controller(bool include_internal) {
8
8
  #ifdef USE_BINARY_SENSOR
9
9
  for (auto *obj : App.get_binary_sensors()) {
10
- if (include_internal || !obj->is_internal())
11
- obj->add_on_state_callback([this, obj](bool state) { this->on_binary_sensor_update(obj, state); });
10
+ if (include_internal || !obj->is_internal()) {
11
+ obj->add_full_state_callback(
12
+ [this, obj](optional<bool> previous, optional<bool> state) { this->on_binary_sensor_update(obj); });
13
+ }
12
14
  }
13
15
  #endif
14
16
  #ifdef USE_FAN
esphome/core/controller.h CHANGED
@@ -71,7 +71,7 @@ class Controller {
71
71
  public:
72
72
  void setup_controller(bool include_internal = false);
73
73
  #ifdef USE_BINARY_SENSOR
74
- virtual void on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state){};
74
+ virtual void on_binary_sensor_update(binary_sensor::BinarySensor *obj){};
75
75
  #endif
76
76
  #ifdef USE_FAN
77
77
  virtual void on_fan_update(fan::Fan *obj){};
esphome/core/datatypes.h CHANGED
@@ -11,7 +11,7 @@ namespace internal {
11
11
  /// Wrapper class for memory using big endian data layout, transparently converting it to native order.
12
12
  template<typename T> class BigEndianLayout {
13
13
  public:
14
- constexpr14 operator T() { return convert_big_endian(val_); }
14
+ constexpr operator T() { return convert_big_endian(val_); }
15
15
 
16
16
  private:
17
17
  T val_;
@@ -20,7 +20,7 @@ template<typename T> class BigEndianLayout {
20
20
  /// Wrapper class for memory using big endian data layout, transparently converting it to native order.
21
21
  template<typename T> class LittleEndianLayout {
22
22
  public:
23
- constexpr14 operator T() { return convert_little_endian(val_); }
23
+ constexpr operator T() { return convert_little_endian(val_); }
24
24
 
25
25
  private:
26
26
  T val_;
esphome/core/defines.h CHANGED
@@ -20,8 +20,10 @@
20
20
 
21
21
  // Feature flags
22
22
  #define USE_ALARM_CONTROL_PANEL
23
+ #define USE_AREAS
23
24
  #define USE_BINARY_SENSOR
24
25
  #define USE_BUTTON
26
+ #define USE_CAMERA
25
27
  #define USE_CLIMATE
26
28
  #define USE_COVER
27
29
  #define USE_DATETIME
@@ -29,7 +31,9 @@
29
31
  #define USE_DATETIME_DATETIME
30
32
  #define USE_DATETIME_TIME
31
33
  #define USE_DEEP_SLEEP
34
+ #define USE_DEVICES
32
35
  #define USE_DISPLAY
36
+ #define USE_ENTITY_ICON
33
37
  #define USE_ESP32_IMPROV_STATE_CALLBACK
34
38
  #define USE_EVENT
35
39
  #define USE_FAN
@@ -84,6 +88,7 @@
84
88
  #define USE_SELECT
85
89
  #define USE_SENSOR
86
90
  #define USE_STATUS_LED
91
+ #define USE_STATUS_SENSOR
87
92
  #define USE_SWITCH
88
93
  #define USE_TEXT
89
94
  #define USE_TEXT_SENSOR
@@ -99,8 +104,11 @@
99
104
  #define USE_AUDIO_FLAC_SUPPORT
100
105
  #define USE_AUDIO_MP3_SUPPORT
101
106
  #define USE_API
107
+ #define USE_API_CLIENT_CONNECTED_TRIGGER
108
+ #define USE_API_CLIENT_DISCONNECTED_TRIGGER
102
109
  #define USE_API_NOISE
103
110
  #define USE_API_PLAINTEXT
111
+ #define USE_API_SERVICES
104
112
  #define USE_MD5
105
113
  #define USE_MQTT
106
114
  #define USE_NETWORK
@@ -111,6 +119,7 @@
111
119
  #define USE_OTA_PASSWORD
112
120
  #define USE_OTA_STATE_CALLBACK
113
121
  #define USE_OTA_VERSION 2
122
+ #define USE_TIME_TIMEZONE
114
123
  #define USE_WIFI
115
124
  #define USE_WIFI_AP
116
125
  #define USE_WIREGUARD
@@ -130,12 +139,14 @@
130
139
 
131
140
  // ESP32-specific feature flags
132
141
  #ifdef USE_ESP32
142
+ #define USE_ESPHOME_TASK_LOG_BUFFER
143
+
133
144
  #define USE_BLUETOOTH_PROXY
134
145
  #define USE_CAPTIVE_PORTAL
135
146
  #define USE_ESP32_BLE
136
147
  #define USE_ESP32_BLE_CLIENT
137
148
  #define USE_ESP32_BLE_SERVER
138
- #define USE_ESP32_CAMERA
149
+ #define USE_I2C
139
150
  #define USE_IMPROV
140
151
  #define USE_MICROPHONE
141
152
  #define USE_PSRAM
@@ -145,11 +156,13 @@
145
156
  #define USE_SPI
146
157
  #define USE_VOICE_ASSISTANT
147
158
  #define USE_WEBSERVER
159
+ #define USE_WEBSERVER_OTA
148
160
  #define USE_WEBSERVER_PORT 80 // NOLINT
161
+ #define USE_WEBSERVER_SORTING
149
162
  #define USE_WIFI_11KV_SUPPORT
150
163
 
151
164
  #ifdef USE_ARDUINO
152
- #define USE_ARDUINO_VERSION_CODE VERSION_CODE(2, 0, 5)
165
+ #define USE_ARDUINO_VERSION_CODE VERSION_CODE(3, 1, 3)
153
166
  #define USE_ETHERNET
154
167
  #endif
155
168
 
@@ -179,6 +192,7 @@
179
192
  #define USE_CAPTIVE_PORTAL
180
193
  #define USE_ESP8266_PREFERENCES_FLASH
181
194
  #define USE_HTTP_REQUEST_ESP8266_HTTPS
195
+ #define USE_I2C
182
196
  #define USE_SOCKET_IMPL_LWIP_TCP
183
197
 
184
198
  #define USE_SPI
@@ -195,6 +209,7 @@
195
209
 
196
210
  #ifdef USE_RP2040
197
211
  #define USE_ARDUINO_VERSION_CODE VERSION_CODE(3, 3, 0)
212
+ #define USE_I2C
198
213
  #define USE_LOGGER_USB_CDC
199
214
  #define USE_SOCKET_IMPL_LWIP_TCP
200
215
  #define USE_SPI
esphome/core/device.h ADDED
@@ -0,0 +1,20 @@
1
+ #pragma once
2
+
3
+ namespace esphome {
4
+
5
+ class Device {
6
+ public:
7
+ void set_device_id(uint32_t device_id) { this->device_id_ = device_id; }
8
+ uint32_t get_device_id() { return this->device_id_; }
9
+ void set_name(const char *name) { this->name_ = name; }
10
+ const char *get_name() { return this->name_; }
11
+ void set_area_id(uint32_t area_id) { this->area_id_ = area_id; }
12
+ uint32_t get_area_id() { return this->area_id_; }
13
+
14
+ protected:
15
+ uint32_t device_id_{};
16
+ uint32_t area_id_{};
17
+ const char *name_ = "";
18
+ };
19
+
20
+ } // namespace esphome
@@ -11,7 +11,14 @@ const StringRef &EntityBase::get_name() const { return this->name_; }
11
11
  void EntityBase::set_name(const char *name) {
12
12
  this->name_ = StringRef(name);
13
13
  if (this->name_.empty()) {
14
- this->name_ = StringRef(App.get_friendly_name());
14
+ #ifdef USE_DEVICES
15
+ if (this->device_ != nullptr) {
16
+ this->name_ = StringRef(this->device_->get_name());
17
+ } else
18
+ #endif
19
+ {
20
+ this->name_ = StringRef(App.get_friendly_name());
21
+ }
15
22
  this->flags_.has_own_name = false;
16
23
  } else {
17
24
  this->flags_.has_own_name = true;
@@ -20,12 +27,22 @@ void EntityBase::set_name(const char *name) {
20
27
 
21
28
  // Entity Icon
22
29
  std::string EntityBase::get_icon() const {
30
+ #ifdef USE_ENTITY_ICON
23
31
  if (this->icon_c_str_ == nullptr) {
24
32
  return "";
25
33
  }
26
34
  return this->icon_c_str_;
35
+ #else
36
+ return "";
37
+ #endif
38
+ }
39
+ void EntityBase::set_icon(const char *icon) {
40
+ #ifdef USE_ENTITY_ICON
41
+ this->icon_c_str_ = icon;
42
+ #else
43
+ // No-op when USE_ENTITY_ICON is not defined
44
+ #endif
27
45
  }
28
- void EntityBase::set_icon(const char *icon) { this->icon_c_str_ = icon; }
29
46
 
30
47
  // Entity Object ID
31
48
  std::string EntityBase::get_object_id() const {
@@ -47,19 +64,7 @@ void EntityBase::set_object_id(const char *object_id) {
47
64
  }
48
65
 
49
66
  // Calculate Object ID Hash from Entity Name
50
- void EntityBase::calc_object_id_() {
51
- // Check if `App.get_friendly_name()` is constant or dynamic.
52
- if (!this->flags_.has_own_name && App.is_name_add_mac_suffix_enabled()) {
53
- // `App.get_friendly_name()` is dynamic.
54
- const auto object_id = str_sanitize(str_snake_case(App.get_friendly_name()));
55
- // FNV-1 hash
56
- this->object_id_hash_ = fnv1_hash(object_id);
57
- } else {
58
- // `App.get_friendly_name()` is constant.
59
- // FNV-1 hash
60
- this->object_id_hash_ = fnv1_hash(this->object_id_c_str_);
61
- }
62
- }
67
+ void EntityBase::calc_object_id_() { this->object_id_hash_ = fnv1_hash(this->get_object_id()); }
63
68
 
64
69
  uint32_t EntityBase::get_object_id_hash() { return this->object_id_hash_; }
65
70
 
@@ -3,6 +3,12 @@
3
3
  #include <string>
4
4
  #include <cstdint>
5
5
  #include "string_ref.h"
6
+ #include "helpers.h"
7
+ #include "log.h"
8
+
9
+ #ifdef USE_DEVICES
10
+ #include "device.h"
11
+ #endif
6
12
 
7
13
  namespace esphome {
8
14
 
@@ -49,6 +55,17 @@ class EntityBase {
49
55
  std::string get_icon() const;
50
56
  void set_icon(const char *icon);
51
57
 
58
+ #ifdef USE_DEVICES
59
+ // Get/set this entity's device id
60
+ uint32_t get_device_id() const {
61
+ if (this->device_ == nullptr) {
62
+ return 0; // No device set, return 0
63
+ }
64
+ return this->device_->get_device_id();
65
+ }
66
+ void set_device(Device *device) { this->device_ = device; }
67
+ #endif
68
+
52
69
  // Check if this entity has state
53
70
  bool has_state() const { return this->flags_.has_state; }
54
71
 
@@ -63,8 +80,13 @@ class EntityBase {
63
80
 
64
81
  StringRef name_;
65
82
  const char *object_id_c_str_{nullptr};
83
+ #ifdef USE_ENTITY_ICON
66
84
  const char *icon_c_str_{nullptr};
85
+ #endif
67
86
  uint32_t object_id_hash_{};
87
+ #ifdef USE_DEVICES
88
+ Device *device_{};
89
+ #endif
68
90
 
69
91
  // Bit-packed flags to save memory (1 byte instead of 5)
70
92
  struct EntityFlags {
@@ -99,4 +121,58 @@ class EntityBase_UnitOfMeasurement { // NOLINT(readability-identifier-naming)
99
121
  const char *unit_of_measurement_{nullptr}; ///< Unit of measurement override
100
122
  };
101
123
 
124
+ /**
125
+ * An entity that has a state.
126
+ * @tparam T The type of the state
127
+ */
128
+ template<typename T> class StatefulEntityBase : public EntityBase {
129
+ public:
130
+ virtual bool has_state() const { return this->state_.has_value(); }
131
+ virtual const T &get_state() const { return this->state_.value(); }
132
+ virtual T get_state_default(T default_value) const { return this->state_.value_or(default_value); }
133
+ void invalidate_state() { this->set_state_({}); }
134
+
135
+ void add_full_state_callback(std::function<void(optional<T> previous, optional<T> current)> &&callback) {
136
+ if (this->full_state_callbacks_ == nullptr)
137
+ this->full_state_callbacks_ = new CallbackManager<void(optional<T> previous, optional<T> current)>(); // NOLINT
138
+ this->full_state_callbacks_->add(std::move(callback));
139
+ }
140
+ void add_on_state_callback(std::function<void(T)> &&callback) {
141
+ if (this->state_callbacks_ == nullptr)
142
+ this->state_callbacks_ = new CallbackManager<void(T)>(); // NOLINT
143
+ this->state_callbacks_->add(std::move(callback));
144
+ }
145
+
146
+ void set_trigger_on_initial_state(bool trigger_on_initial_state) {
147
+ this->trigger_on_initial_state_ = trigger_on_initial_state;
148
+ }
149
+
150
+ protected:
151
+ optional<T> state_{};
152
+ /**
153
+ * Set a new state for this entity. This will trigger callbacks only if the new state is different from the previous.
154
+ *
155
+ * @param state The new state.
156
+ * @return True if the state was changed, false if it was the same as before.
157
+ */
158
+ bool set_state_(const optional<T> &state) {
159
+ if (this->state_ != state) {
160
+ // call the full state callbacks with the previous and new state
161
+ if (this->full_state_callbacks_ != nullptr)
162
+ this->full_state_callbacks_->call(this->state_, state);
163
+ // trigger legacy callbacks only if the new state is valid and either the trigger on initial state is enabled or
164
+ // the previous state was valid
165
+ auto had_state = this->has_state();
166
+ this->state_ = state;
167
+ if (this->state_callbacks_ != nullptr && state.has_value() && (this->trigger_on_initial_state_ || had_state))
168
+ this->state_callbacks_->call(state.value());
169
+ return true;
170
+ }
171
+ return false;
172
+ }
173
+ bool trigger_on_initial_state_{true};
174
+ // callbacks with full state and previous state
175
+ CallbackManager<void(optional<T> previous, optional<T> current)> *full_state_callbacks_{};
176
+ CallbackManager<void(T)> *state_callbacks_{};
177
+ };
102
178
  } // namespace esphome