esphome 2025.7.4__py3-none-any.whl → 2025.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (758) hide show
  1. esphome/__main__.py +190 -83
  2. esphome/automation.py +2 -4
  3. esphome/build_gen/__init__.py +0 -0
  4. esphome/build_gen/platformio.py +102 -0
  5. esphome/components/a4988/a4988.cpp +0 -1
  6. esphome/components/absolute_humidity/absolute_humidity.cpp +0 -2
  7. esphome/components/absolute_humidity/sensor.py +2 -2
  8. esphome/components/adc/__init__.py +123 -85
  9. esphome/components/adc/adc_sensor.h +98 -35
  10. esphome/components/adc/adc_sensor_common.cpp +10 -4
  11. esphome/components/adc/adc_sensor_esp32.cpp +291 -123
  12. esphome/components/adc/adc_sensor_esp8266.cpp +1 -4
  13. esphome/components/adc/adc_sensor_libretiny.cpp +1 -2
  14. esphome/components/adc/adc_sensor_rp2040.cpp +1 -2
  15. esphome/components/adc/adc_sensor_zephyr.cpp +207 -0
  16. esphome/components/adc/sensor.py +61 -27
  17. esphome/components/adc128s102/adc128s102.cpp +1 -4
  18. esphome/components/ade7880/sensor.py +75 -49
  19. esphome/components/ads1115/ads1115.cpp +0 -1
  20. esphome/components/ads1118/ads1118.cpp +0 -1
  21. esphome/components/ags10/ags10.cpp +0 -4
  22. esphome/components/aht10/aht10.cpp +0 -4
  23. esphome/components/aic3204/aic3204.cpp +0 -2
  24. esphome/components/airthings_wave_plus/__init__.py +1 -1
  25. esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +22 -4
  26. esphome/components/airthings_wave_plus/airthings_wave_plus.h +10 -1
  27. esphome/components/airthings_wave_plus/sensor.py +55 -28
  28. esphome/components/alarm_control_panel/__init__.py +4 -9
  29. esphome/components/am2315c/am2315c.cpp +0 -2
  30. esphome/components/am2320/am2320.cpp +0 -1
  31. esphome/components/animation/__init__.py +14 -11
  32. esphome/components/apds9306/apds9306.cpp +0 -4
  33. esphome/components/apds9960/apds9960.cpp +0 -1
  34. esphome/components/api/__init__.py +29 -4
  35. esphome/components/api/api_connection.cpp +378 -401
  36. esphome/components/api/api_connection.h +112 -56
  37. esphome/components/api/api_frame_helper.cpp +69 -896
  38. esphome/components/api/api_frame_helper.h +31 -126
  39. esphome/components/api/api_frame_helper_noise.cpp +583 -0
  40. esphome/components/api/api_frame_helper_noise.h +68 -0
  41. esphome/components/api/api_frame_helper_plaintext.cpp +290 -0
  42. esphome/components/api/api_frame_helper_plaintext.h +53 -0
  43. esphome/components/api/api_noise_context.h +2 -4
  44. esphome/components/api/api_pb2.cpp +1601 -1808
  45. esphome/components/api/api_pb2.h +367 -323
  46. esphome/components/api/api_pb2_dump.cpp +1137 -3466
  47. esphome/components/api/api_pb2_includes.h +34 -0
  48. esphome/components/api/api_pb2_service.cpp +94 -105
  49. esphome/components/api/api_pb2_service.h +27 -16
  50. esphome/components/api/api_server.cpp +18 -17
  51. esphome/components/api/api_server.h +8 -5
  52. esphome/components/api/client.py +16 -8
  53. esphome/components/api/custom_api_device.h +68 -14
  54. esphome/components/api/homeassistant_service.h +24 -19
  55. esphome/components/api/list_entities.cpp +3 -5
  56. esphome/components/api/list_entities.h +2 -4
  57. esphome/components/api/proto.cpp +3 -5
  58. esphome/components/api/proto.h +239 -274
  59. esphome/components/api/subscribe_state.cpp +2 -4
  60. esphome/components/api/subscribe_state.h +2 -4
  61. esphome/components/api/user_services.cpp +2 -4
  62. esphome/components/api/user_services.h +8 -8
  63. esphome/components/as3935/as3935.cpp +0 -2
  64. esphome/components/as3935_spi/as3935_spi.cpp +0 -2
  65. esphome/components/as5600/__init__.py +1 -1
  66. esphome/components/as5600/as5600.cpp +0 -2
  67. esphome/components/as5600/sensor/__init__.py +0 -1
  68. esphome/components/as7341/as7341.cpp +0 -1
  69. esphome/components/async_tcp/__init__.py +1 -1
  70. esphome/components/at581x/at581x.cpp +1 -1
  71. esphome/components/atm90e26/atm90e26.cpp +0 -1
  72. esphome/components/atm90e32/atm90e32.cpp +475 -116
  73. esphome/components/atm90e32/atm90e32.h +43 -5
  74. esphome/components/audio/audio.h +2 -2
  75. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +0 -2
  76. esphome/components/beken_spi_led_strip/led_strip.cpp +0 -2
  77. esphome/components/bh1750/bh1750.cpp +0 -1
  78. esphome/components/binary_sensor/__init__.py +14 -12
  79. esphome/components/ble_client/__init__.py +4 -7
  80. esphome/components/bluetooth_proxy/__init__.py +40 -3
  81. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +392 -81
  82. esphome/components/bluetooth_proxy/bluetooth_connection.h +16 -5
  83. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +102 -311
  84. esphome/components/bluetooth_proxy/bluetooth_proxy.h +30 -14
  85. esphome/components/bme280_base/bme280_base.cpp +15 -16
  86. esphome/components/bme680/bme680.cpp +2 -3
  87. esphome/components/bme680_bsec/bme680_bsec.cpp +0 -2
  88. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +0 -2
  89. esphome/components/bmi160/bmi160.cpp +0 -1
  90. esphome/components/bmp085/bmp085.cpp +0 -1
  91. esphome/components/bmp280_base/bmp280_base.cpp +13 -14
  92. esphome/components/bmp3xx_base/bmp3xx_base.cpp +0 -1
  93. esphome/components/bmp581/bmp581.cpp +0 -2
  94. esphome/components/bp1658cj/bp1658cj.cpp +0 -1
  95. esphome/components/bp5758d/bp5758d.cpp +0 -1
  96. esphome/components/button/__init__.py +0 -1
  97. esphome/components/canbus/__init__.py +2 -3
  98. esphome/components/canbus/canbus.cpp +0 -1
  99. esphome/components/cap1188/cap1188.cpp +0 -2
  100. esphome/components/captive_portal/__init__.py +1 -1
  101. esphome/components/cd74hc4067/cd74hc4067.cpp +0 -2
  102. esphome/components/ch422g/ch422g.cpp +0 -1
  103. esphome/components/chsc6x/chsc6x_touchscreen.cpp +0 -3
  104. esphome/components/climate/__init__.py +0 -1
  105. esphome/components/climate/climate_traits.h +24 -0
  106. esphome/components/cm1106/cm1106.cpp +0 -1
  107. esphome/components/const/__init__.py +6 -0
  108. esphome/components/cover/__init__.py +0 -1
  109. esphome/components/cover/cover.cpp +9 -13
  110. esphome/components/cs5460a/cs5460a.cpp +0 -2
  111. esphome/components/cse7761/cse7761.cpp +0 -1
  112. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +0 -2
  113. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +0 -2
  114. esphome/components/dac7678/dac7678_output.cpp +0 -2
  115. esphome/components/dallas_temp/dallas_temp.cpp +0 -1
  116. esphome/components/datetime/__init__.py +0 -2
  117. esphome/components/debug/__init__.py +15 -1
  118. esphome/components/debug/debug_zephyr.cpp +281 -0
  119. esphome/components/debug/sensor.py +2 -1
  120. esphome/components/deep_sleep/deep_sleep_component.cpp +0 -1
  121. esphome/components/deep_sleep/deep_sleep_esp32.cpp +20 -1
  122. esphome/components/dfrobot_sen0395/__init__.py +1 -2
  123. esphome/components/dht/dht.cpp +0 -1
  124. esphome/components/dht12/dht12.cpp +0 -1
  125. esphome/components/display/__init__.py +16 -3
  126. esphome/components/display_menu_base/__init__.py +1 -1
  127. esphome/components/dps310/dps310.cpp +0 -2
  128. esphome/components/ds1307/ds1307.cpp +0 -1
  129. esphome/components/ds2484/ds2484.cpp +0 -1
  130. esphome/components/duty_cycle/duty_cycle_sensor.cpp +0 -1
  131. esphome/components/ee895/ee895.cpp +0 -1
  132. esphome/components/ektf2232/touchscreen/ektf2232.cpp +0 -1
  133. esphome/components/emc2101/emc2101.cpp +0 -2
  134. esphome/components/ens160_base/ens160_base.cpp +0 -2
  135. esphome/components/ens210/ens210.cpp +0 -1
  136. esphome/components/es7210/es7210.cpp +0 -2
  137. esphome/components/es7243e/es7243e.cpp +0 -2
  138. esphome/components/es8156/es8156.cpp +0 -2
  139. esphome/components/es8311/es8311.cpp +0 -2
  140. esphome/components/es8388/es8388.cpp +0 -2
  141. esphome/components/esp32/__init__.py +203 -60
  142. esphome/components/esp32/boards.py +17 -0
  143. esphome/components/esp32/gpio.cpp +0 -1
  144. esphome/components/esp32/gpio.py +1 -2
  145. esphome/components/esp32/gpio_esp32_h2.py +2 -7
  146. esphome/components/esp32/gpio_esp32_p4.py +2 -7
  147. esphome/components/esp32/post_build.py.script +112 -61
  148. esphome/components/esp32_ble/__init__.py +41 -2
  149. esphome/components/esp32_ble/ble.cpp +14 -10
  150. esphome/components/esp32_ble/ble.h +18 -18
  151. esphome/components/esp32_ble/ble_advertising.cpp +5 -5
  152. esphome/components/esp32_ble/ble_advertising.h +7 -5
  153. esphome/components/esp32_ble/ble_event.h +139 -73
  154. esphome/components/esp32_ble/ble_scan_result.h +2 -4
  155. esphome/components/esp32_ble/ble_uuid.cpp +5 -5
  156. esphome/components/esp32_ble/ble_uuid.h +6 -5
  157. esphome/components/esp32_ble_beacon/__init__.py +4 -0
  158. esphome/components/esp32_ble_client/__init__.py +1 -1
  159. esphome/components/esp32_ble_client/ble_characteristic.cpp +4 -4
  160. esphome/components/esp32_ble_client/ble_characteristic.h +6 -4
  161. esphome/components/esp32_ble_client/ble_client_base.cpp +155 -104
  162. esphome/components/esp32_ble_client/ble_client_base.h +17 -6
  163. esphome/components/esp32_ble_client/ble_descriptor.h +6 -4
  164. esphome/components/esp32_ble_client/ble_service.cpp +4 -4
  165. esphome/components/esp32_ble_client/ble_service.h +6 -4
  166. esphome/components/esp32_ble_server/__init__.py +15 -12
  167. esphome/components/esp32_ble_tracker/__init__.py +79 -11
  168. esphome/components/esp32_ble_tracker/automation.h +4 -4
  169. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +264 -261
  170. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +103 -37
  171. esphome/components/esp32_camera/__init__.py +13 -1
  172. esphome/components/esp32_camera/esp32_camera.cpp +7 -2
  173. esphome/components/esp32_camera/esp32_camera.h +1 -0
  174. esphome/components/esp32_dac/esp32_dac.cpp +3 -19
  175. esphome/components/esp32_dac/esp32_dac.h +4 -8
  176. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -6
  177. esphome/components/esp32_rmt_led_strip/light.py +1 -1
  178. esphome/components/esp32_touch/__init__.py +2 -3
  179. esphome/components/esp32_touch/esp32_touch.h +9 -6
  180. esphome/components/esp32_touch/esp32_touch_common.cpp +2 -0
  181. esphome/components/esp32_touch/esp32_touch_v1.cpp +7 -9
  182. esphome/components/esp32_touch/esp32_touch_v2.cpp +10 -6
  183. esphome/components/esp8266/__init__.py +3 -1
  184. esphome/components/esp8266_pwm/esp8266_pwm.cpp +0 -1
  185. esphome/components/esphome/ota/__init__.py +1 -2
  186. esphome/components/esphome/ota/ota_esphome.cpp +150 -77
  187. esphome/components/esphome/ota/ota_esphome.h +8 -1
  188. esphome/components/espnow/__init__.py +309 -0
  189. esphome/components/espnow/automation.h +175 -0
  190. esphome/components/espnow/espnow_component.cpp +468 -0
  191. esphome/components/espnow/espnow_component.h +183 -0
  192. esphome/components/espnow/espnow_err.h +19 -0
  193. esphome/components/espnow/espnow_packet.h +166 -0
  194. esphome/components/ethernet/__init__.py +7 -1
  195. esphome/components/ethernet/esp_eth_phy_jl1101.c +5 -0
  196. esphome/components/ethernet/ethernet_component.cpp +0 -1
  197. esphome/components/ethernet/ethernet_component.h +4 -0
  198. esphome/components/ethernet_info/ethernet_info_text_sensor.h +0 -3
  199. esphome/components/event/__init__.py +0 -1
  200. esphome/components/factory_reset/__init__.py +92 -0
  201. esphome/components/factory_reset/factory_reset.cpp +76 -0
  202. esphome/components/factory_reset/factory_reset.h +43 -0
  203. esphome/components/fan/__init__.py +0 -1
  204. esphome/components/fan/fan_traits.h +16 -0
  205. esphome/components/fastled_base/fastled_light.cpp +0 -1
  206. esphome/components/fastled_spi/light.py +1 -3
  207. esphome/components/fingerprint_grow/fingerprint_grow.cpp +0 -2
  208. esphome/components/font/__init__.py +9 -1
  209. esphome/components/fs3000/fs3000.cpp +0 -2
  210. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
  211. esphome/components/ft63x6/ft63x6.cpp +0 -1
  212. esphome/components/gdk101/gdk101.cpp +0 -1
  213. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
  214. esphome/components/gl_r01_i2c/sensor.py +1 -1
  215. esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
  216. esphome/components/gpio/switch/gpio_switch.cpp +0 -2
  217. esphome/components/gpio_expander/cached_gpio.h +24 -15
  218. esphome/components/gps/__init__.py +6 -2
  219. esphome/components/gps/gps.cpp +50 -49
  220. esphome/components/gps/gps.h +4 -8
  221. esphome/components/gps/time/gps_time.cpp +3 -9
  222. esphome/components/gps/time/gps_time.h +4 -7
  223. esphome/components/graph/__init__.py +1 -1
  224. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
  225. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
  227. esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
  228. esphome/components/haier/climate.py +5 -10
  229. esphome/components/haier/haier_base.cpp +0 -1
  230. esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
  231. esphome/components/hdc1080/hdc1080.cpp +0 -2
  232. esphome/components/heatpumpir/climate.py +2 -2
  233. esphome/components/hlw8012/hlw8012.cpp +0 -1
  234. esphome/components/hm3301/hm3301.cpp +0 -1
  235. esphome/components/hmc5883l/hmc5883l.cpp +0 -1
  236. esphome/components/homeassistant/__init__.py +1 -0
  237. esphome/components/homeassistant/number/__init__.py +1 -0
  238. esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
  239. esphome/components/homeassistant/switch/__init__.py +1 -0
  240. esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
  241. esphome/components/honeywellabp/honeywellabp.cpp +1 -4
  242. esphome/components/host/__init__.py +2 -0
  243. esphome/components/hte501/hte501.cpp +0 -1
  244. esphome/components/http_request/__init__.py +2 -3
  245. esphome/components/http_request/http_request_idf.cpp +2 -2
  246. esphome/components/htu21d/htu21d.cpp +0 -2
  247. esphome/components/htu31d/htu31d.cpp +0 -2
  248. esphome/components/hx711/hx711.cpp +0 -1
  249. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
  250. esphome/components/hydreon_rgxx/sensor.py +4 -5
  251. esphome/components/i2c/i2c_bus.h +1 -1
  252. esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
  253. esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
  254. esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
  255. esphome/components/i2s_audio/__init__.py +6 -5
  256. esphome/components/i2s_audio/i2s_audio.cpp +0 -2
  257. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
  258. esphome/components/i2s_audio/microphone/__init__.py +4 -6
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +46 -19
  260. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +4 -3
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
  262. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
  263. esphome/components/ili9xxx/display.py +4 -3
  264. esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
  265. esphome/components/image/__init__.py +123 -92
  266. esphome/components/improv_serial/__init__.py +7 -8
  267. esphome/components/ina219/ina219.cpp +0 -1
  268. esphome/components/ina226/ina226.cpp +0 -2
  269. esphome/components/ina260/ina260.cpp +0 -2
  270. esphome/components/ina2xx_base/__init__.py +2 -5
  271. esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
  272. esphome/components/ina3221/ina3221.cpp +0 -1
  273. esphome/components/internal_temperature/internal_temperature.cpp +0 -2
  274. esphome/components/interval/interval.h +5 -9
  275. esphome/components/json/__init__.py +1 -1
  276. esphome/components/kmeteriso/kmeteriso.cpp +0 -2
  277. esphome/components/lc709203f/lc709203f.cpp +0 -2
  278. esphome/components/lcd_gpio/display.py +1 -3
  279. esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
  280. esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
  281. esphome/components/ld2410/__init__.py +4 -6
  282. esphome/components/ld2410/binary_sensor.py +4 -0
  283. esphome/components/ld2410/ld2410.cpp +56 -100
  284. esphome/components/ld2410/ld2410.h +17 -15
  285. esphome/components/ld2410/sensor.py +24 -10
  286. esphome/components/ld2412/__init__.py +46 -0
  287. esphome/components/ld2412/binary_sensor.py +70 -0
  288. esphome/components/ld2412/button/__init__.py +74 -0
  289. esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
  290. esphome/components/ld2412/button/factory_reset_button.h +18 -0
  291. esphome/components/ld2412/button/query_button.cpp +9 -0
  292. esphome/components/ld2412/button/query_button.h +18 -0
  293. esphome/components/ld2412/button/restart_button.cpp +9 -0
  294. esphome/components/ld2412/button/restart_button.h +18 -0
  295. esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
  296. esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
  297. esphome/components/ld2412/ld2412.cpp +861 -0
  298. esphome/components/ld2412/ld2412.h +141 -0
  299. esphome/components/ld2412/number/__init__.py +126 -0
  300. esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
  301. esphome/components/ld2412/number/gate_threshold_number.h +19 -0
  302. esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
  303. esphome/components/ld2412/number/light_threshold_number.h +18 -0
  304. esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
  305. esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
  306. esphome/components/ld2412/select/__init__.py +82 -0
  307. esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
  308. esphome/components/ld2412/select/baud_rate_select.h +18 -0
  309. esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
  310. esphome/components/ld2412/select/distance_resolution_select.h +18 -0
  311. esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
  312. esphome/components/ld2412/select/light_out_control_select.h +18 -0
  313. esphome/components/ld2412/sensor.py +124 -0
  314. esphome/components/ld2412/switch/__init__.py +45 -0
  315. esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
  316. esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
  317. esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
  318. esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
  319. esphome/components/ld2412/text_sensor.py +34 -0
  320. esphome/components/ld2420/ld2420.cpp +0 -1
  321. esphome/components/ld2450/__init__.py +3 -4
  322. esphome/components/ld2450/binary_sensor.py +3 -0
  323. esphome/components/ld2450/ld2450.cpp +77 -165
  324. esphome/components/ld2450/ld2450.h +26 -54
  325. esphome/components/ld2450/sensor.py +120 -6
  326. esphome/components/ld2450/text_sensor.py +5 -4
  327. esphome/components/ld24xx/__init__.py +1 -0
  328. esphome/components/ld24xx/ld24xx.h +65 -0
  329. esphome/components/ledc/ledc_output.cpp +0 -1
  330. esphome/components/libretiny/__init__.py +2 -0
  331. esphome/components/light/__init__.py +0 -1
  332. esphome/components/light/effects.py +70 -45
  333. esphome/components/light/light_call.cpp +101 -66
  334. esphome/components/light/light_color_values.h +16 -11
  335. esphome/components/light/light_json_schema.cpp +46 -44
  336. esphome/components/light/light_state.cpp +8 -11
  337. esphome/components/light/light_traits.h +17 -0
  338. esphome/components/lightwaverf/lightwaverf.cpp +0 -2
  339. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
  340. esphome/components/lock/__init__.py +0 -1
  341. esphome/components/logger/__init__.py +31 -9
  342. esphome/components/logger/logger.cpp +12 -7
  343. esphome/components/logger/logger.h +25 -14
  344. esphome/components/logger/logger_esp32.cpp +2 -7
  345. esphome/components/logger/logger_esp8266.cpp +2 -4
  346. esphome/components/logger/logger_host.cpp +2 -4
  347. esphome/components/logger/logger_libretiny.cpp +2 -4
  348. esphome/components/logger/logger_rp2040.cpp +2 -4
  349. esphome/components/logger/logger_zephyr.cpp +86 -0
  350. esphome/components/logger/select/logger_level_select.cpp +2 -4
  351. esphome/components/logger/select/logger_level_select.h +2 -4
  352. esphome/components/logger/task_log_buffer.cpp +2 -4
  353. esphome/components/logger/task_log_buffer.h +2 -4
  354. esphome/components/lps22/sensor.py +5 -5
  355. esphome/components/ltr390/ltr390.cpp +0 -2
  356. esphome/components/ltr501/ltr501.cpp +0 -1
  357. esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
  358. esphome/components/lvgl/__init__.py +14 -13
  359. esphome/components/lvgl/automation.py +2 -4
  360. esphome/components/lvgl/defines.py +0 -2
  361. esphome/components/lvgl/helpers.py +1 -1
  362. esphome/components/lvgl/lv_validation.py +7 -4
  363. esphome/components/lvgl/lvgl_esphome.cpp +2 -3
  364. esphome/components/lvgl/styles.py +2 -2
  365. esphome/components/lvgl/types.py +1 -1
  366. esphome/components/lvgl/widgets/__init__.py +2 -2
  367. esphome/components/lvgl/widgets/arc.py +14 -11
  368. esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
  369. esphome/components/lvgl/widgets/qrcode.py +7 -7
  370. esphome/components/lvgl/widgets/spinner.py +6 -6
  371. esphome/components/lvgl/widgets/switch.py +2 -2
  372. esphome/components/lvgl/widgets/tabview.py +3 -3
  373. esphome/components/lvgl/widgets/tileview.py +15 -7
  374. esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
  375. esphome/components/matrix_keypad/__init__.py +4 -3
  376. esphome/components/max17043/max17043.cpp +0 -2
  377. esphome/components/max31855/max31855.cpp +1 -4
  378. esphome/components/max31856/max31856.cpp +0 -4
  379. esphome/components/max31865/max31865.cpp +0 -1
  380. esphome/components/max44009/max44009.cpp +0 -1
  381. esphome/components/max6675/max6675.cpp +1 -4
  382. esphome/components/max6956/max6956.cpp +0 -1
  383. esphome/components/max7219/max7219.cpp +0 -1
  384. esphome/components/max7219digit/display.py +1 -1
  385. esphome/components/max7219digit/max7219digit.cpp +0 -1
  386. esphome/components/max9611/max9611.cpp +0 -1
  387. esphome/components/mcp23008/__init__.py +1 -1
  388. esphome/components/mcp23008/mcp23008.cpp +0 -1
  389. esphome/components/mcp23016/mcp23016.cpp +0 -1
  390. esphome/components/mcp23017/__init__.py +1 -1
  391. esphome/components/mcp23017/mcp23017.cpp +0 -1
  392. esphome/components/mcp23s08/__init__.py +1 -1
  393. esphome/components/mcp23s08/mcp23s08.cpp +0 -1
  394. esphome/components/mcp23s17/__init__.py +1 -1
  395. esphome/components/mcp23s17/mcp23s17.cpp +0 -1
  396. esphome/components/mcp23x08_base/__init__.py +2 -0
  397. esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
  398. esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
  399. esphome/components/mcp23x17_base/__init__.py +2 -0
  400. esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
  401. esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
  402. esphome/components/mcp23xxx_base/__init__.py +11 -5
  403. esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
  404. esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
  405. esphome/components/mcp3008/mcp3008.cpp +1 -4
  406. esphome/components/mcp3204/mcp3204.cpp +1 -4
  407. esphome/components/mcp4461/mcp4461.cpp +0 -1
  408. esphome/components/mcp4725/mcp4725.cpp +0 -1
  409. esphome/components/mcp4728/mcp4728.cpp +0 -1
  410. esphome/components/mcp9600/mcp9600.cpp +0 -2
  411. esphome/components/mcp9808/mcp9808.cpp +0 -2
  412. esphome/components/mdns/__init__.py +3 -0
  413. esphome/components/mdns/mdns_component.cpp +2 -0
  414. esphome/components/mdns/mdns_component.h +4 -0
  415. esphome/components/media_player/__init__.py +40 -0
  416. esphome/components/media_player/automation.h +16 -0
  417. esphome/components/media_player/media_player.cpp +13 -0
  418. esphome/components/media_player/media_player.h +50 -3
  419. esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
  420. esphome/components/mics_4514/mics_4514.cpp +1 -6
  421. esphome/components/midea/ir_transmitter.h +4 -4
  422. esphome/components/mipi/__init__.py +416 -0
  423. esphome/components/mipi_dsi/__init__.py +5 -0
  424. esphome/components/mipi_dsi/display.py +233 -0
  425. esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
  426. esphome/components/mipi_dsi/mipi_dsi.h +123 -0
  427. esphome/components/mipi_dsi/models/__init__.py +0 -0
  428. esphome/components/mipi_dsi/models/guition.py +38 -0
  429. esphome/components/mipi_dsi/models/m5stack.py +57 -0
  430. esphome/components/mipi_dsi/models/waveshare.py +105 -0
  431. esphome/components/mipi_rgb/models/lilygo.py +0 -0
  432. esphome/components/mipi_spi/__init__.py +0 -9
  433. esphome/components/mipi_spi/display.py +220 -256
  434. esphome/components/mipi_spi/mipi_spi.cpp +1 -485
  435. esphome/components/mipi_spi/mipi_spi.h +556 -108
  436. esphome/components/mipi_spi/models/__init__.py +0 -65
  437. esphome/components/mipi_spi/models/adafruit.py +30 -0
  438. esphome/components/mipi_spi/models/amoled.py +41 -5
  439. esphome/components/mipi_spi/models/ili.py +5 -5
  440. esphome/components/mipi_spi/models/jc.py +1 -3
  441. esphome/components/mipi_spi/models/lilygo.py +1 -1
  442. esphome/components/mipi_spi/models/waveshare.py +16 -1
  443. esphome/components/mixer/speaker/__init__.py +4 -5
  444. esphome/components/mlx90393/sensor.py +7 -5
  445. esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
  446. esphome/components/mlx90614/mlx90614.cpp +0 -1
  447. esphome/components/mmc5603/mmc5603.cpp +0 -1
  448. esphome/components/mmc5983/mmc5983.cpp +0 -2
  449. esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
  450. esphome/components/mpr121/__init__.py +7 -6
  451. esphome/components/mpr121/mpr121.cpp +0 -1
  452. esphome/components/mpu6050/mpu6050.cpp +0 -1
  453. esphome/components/mpu6886/mpu6886.cpp +0 -1
  454. esphome/components/mqtt/__init__.py +1 -2
  455. esphome/components/mqtt/mqtt_button.cpp +1 -1
  456. esphome/components/mqtt/mqtt_client.cpp +0 -1
  457. esphome/components/mqtt/mqtt_component.cpp +8 -14
  458. esphome/components/mqtt/mqtt_component.h +0 -7
  459. esphome/components/mqtt/mqtt_sensor.cpp +0 -1
  460. esphome/components/mqtt/mqtt_sensor.h +0 -1
  461. esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
  462. esphome/components/mqtt/mqtt_text_sensor.h +0 -1
  463. esphome/components/ms5611/ms5611.cpp +0 -1
  464. esphome/components/ms8607/ms8607.cpp +0 -1
  465. esphome/components/msa3xx/msa3xx.cpp +0 -2
  466. esphome/components/my9231/my9231.cpp +0 -2
  467. esphome/components/nau7802/nau7802.cpp +0 -1
  468. esphome/components/neopixelbus/light.py +3 -0
  469. esphome/components/network/util.cpp +29 -0
  470. esphome/components/nextion/nextion.cpp +2 -2
  471. esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
  472. esphome/components/npi19/npi19.cpp +0 -2
  473. esphome/components/nrf52/__init__.py +223 -0
  474. esphome/components/nrf52/boards.py +34 -0
  475. esphome/components/nrf52/const.py +18 -0
  476. esphome/components/nrf52/gpio.py +79 -0
  477. esphome/components/number/__init__.py +2 -1
  478. esphome/components/one_wire/__init__.py +1 -2
  479. esphome/components/one_wire/one_wire.cpp +0 -2
  480. esphome/components/one_wire/one_wire.h +0 -2
  481. esphome/components/opentherm/hub.cpp +0 -1
  482. esphome/components/opentherm/number/__init__.py +2 -2
  483. esphome/components/openthread/__init__.py +2 -3
  484. esphome/components/openthread/openthread.cpp +30 -13
  485. esphome/components/openthread/openthread.h +3 -0
  486. esphome/components/openthread/openthread_esp.cpp +3 -1
  487. esphome/components/opt3001/sensor.py +2 -6
  488. esphome/components/output/__init__.py +38 -0
  489. esphome/components/output/automation.h +24 -0
  490. esphome/components/output/switch/output_switch.cpp +0 -2
  491. esphome/components/packages/__init__.py +1 -2
  492. esphome/components/packet_transport/__init__.py +4 -3
  493. esphome/components/pca6416a/pca6416a.cpp +0 -1
  494. esphome/components/pca9554/pca9554.cpp +0 -1
  495. esphome/components/pca9685/pca9685_output.cpp +0 -2
  496. esphome/components/pcf85063/pcf85063.cpp +0 -1
  497. esphome/components/pcf8563/pcf8563.cpp +0 -1
  498. esphome/components/pcf8574/pcf8574.cpp +0 -1
  499. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
  500. esphome/components/pipsolar/pipsolar.cpp +54 -42
  501. esphome/components/pipsolar/pipsolar.h +5 -4
  502. esphome/components/pipsolar/sensor/__init__.py +1 -1
  503. esphome/components/pm2005/pm2005.cpp +0 -1
  504. esphome/components/pmsa003i/pmsa003i.cpp +0 -2
  505. esphome/components/pmwcs3/sensor.py +1 -2
  506. esphome/components/pn532/pn532.cpp +0 -2
  507. esphome/components/pn532_spi/pn532_spi.cpp +0 -2
  508. esphome/components/power_supply/power_supply.cpp +7 -10
  509. esphome/components/power_supply/power_supply.h +1 -1
  510. esphome/components/psram/__init__.py +6 -1
  511. esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
  512. esphome/components/pulse_counter/sensor.py +9 -6
  513. esphome/components/pylontech/pylontech.cpp +0 -1
  514. esphome/components/qmc5883l/qmc5883l.cpp +0 -1
  515. esphome/components/qmp6988/qmp6988.cpp +0 -2
  516. esphome/components/qspi_dbi/display.py +2 -3
  517. esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
  518. esphome/components/qwiic_pir/binary_sensor.py +2 -3
  519. esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
  520. esphome/components/rc522/rc522.cpp +9 -31
  521. esphome/components/rc522_spi/rc522_spi.cpp +0 -1
  522. esphome/components/remote_base/__init__.py +5 -6
  523. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
  524. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
  525. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
  526. esphome/components/remote_transmitter/__init__.py +26 -0
  527. esphome/components/remote_transmitter/automation.h +18 -0
  528. esphome/components/remote_transmitter/remote_transmitter.h +2 -1
  529. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
  530. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
  531. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
  532. esphome/components/resampler/speaker/__init__.py +4 -5
  533. esphome/components/rf_bridge/__init__.py +4 -8
  534. esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
  535. esphome/components/rp2040/__init__.py +3 -1
  536. esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
  537. esphome/components/rp2040_pio_led_strip/light.py +1 -2
  538. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
  539. esphome/components/rpi_dpi_rgb/display.py +13 -15
  540. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
  541. esphome/components/runtime_stats/__init__.py +34 -0
  542. esphome/components/runtime_stats/runtime_stats.cpp +102 -0
  543. esphome/components/runtime_stats/runtime_stats.h +132 -0
  544. esphome/components/scd30/scd30.cpp +0 -2
  545. esphome/components/scd30/sensor.py +1 -2
  546. esphome/components/scd4x/scd4x.cpp +0 -1
  547. esphome/components/scd4x/sensor.py +1 -3
  548. esphome/components/sdl/display.py +3 -1
  549. esphome/components/sdl/sdl_esphome.cpp +0 -2
  550. esphome/components/sdp3x/sdp3x.cpp +0 -2
  551. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
  552. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
  553. esphome/components/select/__init__.py +2 -3
  554. esphome/components/select/select_traits.cpp +1 -1
  555. esphome/components/select/select_traits.h +1 -1
  556. esphome/components/sen0321/sen0321.cpp +0 -1
  557. esphome/components/sen5x/sen5x.cpp +0 -2
  558. esphome/components/senseair/senseair.cpp +7 -3
  559. esphome/components/senseair/senseair.h +11 -0
  560. esphome/components/sensor/__init__.py +36 -4
  561. esphome/components/sensor/filter.cpp +49 -10
  562. esphome/components/sensor/filter.h +22 -7
  563. esphome/components/sensor/sensor.cpp +0 -1
  564. esphome/components/sensor/sensor.h +0 -9
  565. esphome/components/sfa30/sfa30.cpp +0 -4
  566. esphome/components/sgp30/sgp30.cpp +0 -2
  567. esphome/components/sgp4x/sensor.py +1 -1
  568. esphome/components/sgp4x/sgp4x.cpp +0 -2
  569. esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
  570. esphome/components/sht3xd/sht3xd.cpp +0 -2
  571. esphome/components/sht4x/sht4x.cpp +0 -2
  572. esphome/components/shtcx/shtcx.cpp +0 -1
  573. esphome/components/sim800l/__init__.py +2 -4
  574. esphome/components/sm16716/sm16716.cpp +0 -1
  575. esphome/components/sm2135/sm2135.cpp +0 -1
  576. esphome/components/sm2235/sm2235.cpp +0 -1
  577. esphome/components/sm2335/sm2335.cpp +0 -1
  578. esphome/components/sn74hc165/sn74hc165.cpp +0 -1
  579. esphome/components/sn74hc595/sn74hc595.cpp +0 -1
  580. esphome/components/sntp/sntp_component.cpp +0 -1
  581. esphome/components/sound_level/sensor.py +1 -1
  582. esphome/components/speaker/media_player/__init__.py +21 -33
  583. esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
  584. esphome/components/spi/__init__.py +29 -13
  585. esphome/components/spi/spi.cpp +0 -2
  586. esphome/components/spi_device/spi_device.cpp +1 -4
  587. esphome/components/sprinkler/__init__.py +4 -4
  588. esphome/components/sps30/sps30.cpp +0 -1
  589. esphome/components/ssd1306_base/__init__.py +11 -11
  590. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  591. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
  592. esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
  593. esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
  594. esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
  595. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
  596. esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
  597. esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
  598. esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
  599. esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
  600. esphome/components/st7567_spi/st7567_spi.cpp +0 -1
  601. esphome/components/st7701s/display.py +10 -14
  602. esphome/components/st7701s/st7701s.cpp +0 -3
  603. esphome/components/st7735/st7735.cpp +0 -1
  604. esphome/components/st7789v/st7789v.cpp +0 -1
  605. esphome/components/st7920/st7920.cpp +0 -1
  606. esphome/components/status_led/light/status_led_light.cpp +0 -2
  607. esphome/components/status_led/status_led.cpp +0 -1
  608. esphome/components/stepper/__init__.py +2 -4
  609. esphome/components/sts3x/sts3x.cpp +0 -1
  610. esphome/components/substitutions/__init__.py +10 -16
  611. esphome/components/substitutions/jinja.py +24 -1
  612. esphome/components/sun/__init__.py +2 -3
  613. esphome/components/switch/__init__.py +31 -1
  614. esphome/components/switch/automation.h +24 -0
  615. esphome/components/switch/switch.cpp +8 -0
  616. esphome/components/switch/switch.h +8 -0
  617. esphome/components/sx126x/sx126x.cpp +0 -2
  618. esphome/components/sx127x/sx127x.cpp +0 -2
  619. esphome/components/sx1509/__init__.py +7 -5
  620. esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
  621. esphome/components/sx1509/sx1509.cpp +0 -2
  622. esphome/components/syslog/esphome_syslog.cpp +1 -1
  623. esphome/components/tc74/tc74.cpp +0 -1
  624. esphome/components/tca9548a/tca9548a.cpp +0 -1
  625. esphome/components/tca9555/tca9555.cpp +0 -1
  626. esphome/components/tcs34725/tcs34725.cpp +0 -1
  627. esphome/components/tee501/tee501.cpp +0 -1
  628. esphome/components/tem3200/tem3200.cpp +0 -2
  629. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
  630. esphome/components/template/cover/template_cover.cpp +0 -1
  631. esphome/components/template/select/template_select.cpp +0 -1
  632. esphome/components/template/text/template_text.cpp +0 -2
  633. esphome/components/template/valve/template_valve.cpp +0 -1
  634. esphome/components/text/__init__.py +0 -1
  635. esphome/components/text/text_traits.h +2 -0
  636. esphome/components/text_sensor/__init__.py +2 -1
  637. esphome/components/text_sensor/text_sensor.cpp +0 -2
  638. esphome/components/text_sensor/text_sensor.h +0 -8
  639. esphome/components/thermostat/climate.py +4 -4
  640. esphome/components/time/__init__.py +7 -4
  641. esphome/components/time/real_time_clock.cpp +16 -3
  642. esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
  643. esphome/components/tlc5947/tlc5947.cpp +0 -2
  644. esphome/components/tlc5971/tlc5971.cpp +0 -2
  645. esphome/components/tm1621/tm1621.cpp +0 -2
  646. esphome/components/tm1637/tm1637.cpp +0 -2
  647. esphome/components/tm1638/tm1638.cpp +0 -2
  648. esphome/components/tm1651/__init__.py +45 -48
  649. esphome/components/tm1651/tm1651.cpp +213 -47
  650. esphome/components/tm1651/tm1651.h +37 -32
  651. esphome/components/tmp117/tmp117.cpp +0 -2
  652. esphome/components/tsl2561/tsl2561.cpp +0 -1
  653. esphome/components/tsl2591/tsl2591.cpp +0 -1
  654. esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
  655. esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
  656. esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
  657. esphome/components/tuya/climate/__init__.py +9 -10
  658. esphome/components/tuya/number/__init__.py +8 -6
  659. esphome/components/tx20/tx20.cpp +0 -1
  660. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
  661. esphome/components/uart/uart_component_esp8266.cpp +0 -1
  662. esphome/components/uart/uart_component_esp_idf.cpp +0 -2
  663. esphome/components/uart/uart_component_libretiny.cpp +0 -2
  664. esphome/components/uart/uart_component_rp2040.cpp +0 -2
  665. esphome/components/udp/__init__.py +1 -1
  666. esphome/components/ufire_ec/sensor.py +1 -2
  667. esphome/components/ufire_ec/ufire_ec.cpp +0 -2
  668. esphome/components/ufire_ise/sensor.py +1 -2
  669. esphome/components/ufire_ise/ufire_ise.cpp +0 -2
  670. esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
  671. esphome/components/update/__init__.py +0 -1
  672. esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
  673. esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
  674. esphome/components/usb_host/usb_host_client.cpp +0 -1
  675. esphome/components/usb_host/usb_host_component.cpp +0 -1
  676. esphome/components/valve/__init__.py +0 -1
  677. esphome/components/veml3235/veml3235.cpp +0 -3
  678. esphome/components/veml7700/veml7700.cpp +0 -2
  679. esphome/components/version/version_text_sensor.cpp +0 -1
  680. esphome/components/version/version_text_sensor.h +0 -1
  681. esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
  682. esphome/components/voice_assistant/voice_assistant.cpp +9 -8
  683. esphome/components/web_server/__init__.py +13 -0
  684. esphome/components/web_server/web_server.cpp +188 -353
  685. esphome/components/web_server/web_server.h +61 -1
  686. esphome/components/web_server_base/__init__.py +1 -1
  687. esphome/components/web_server_base/web_server_base.cpp +2 -0
  688. esphome/components/web_server_base/web_server_base.h +6 -0
  689. esphome/components/web_server_idf/web_server_idf.cpp +10 -8
  690. esphome/components/web_server_idf/web_server_idf.h +2 -0
  691. esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
  692. esphome/components/weikai_spi/weikai_spi.cpp +1 -1
  693. esphome/components/wifi/__init__.py +17 -43
  694. esphome/components/wifi/wifi_component.cpp +100 -36
  695. esphome/components/wifi/wifi_component.h +5 -1
  696. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
  697. esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
  698. esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
  699. esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
  700. esphome/components/wireguard/wireguard.cpp +0 -2
  701. esphome/components/x9c/x9c.cpp +0 -2
  702. esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
  703. esphome/components/xl9535/xl9535.cpp +0 -2
  704. esphome/components/zephyr/__init__.py +252 -0
  705. esphome/components/zephyr/const.py +16 -0
  706. esphome/components/zephyr/core.cpp +90 -0
  707. esphome/components/zephyr/gpio.cpp +120 -0
  708. esphome/components/zephyr/gpio.h +38 -0
  709. esphome/components/zephyr/pre_build.py.script +4 -0
  710. esphome/components/zephyr/preferences.cpp +156 -0
  711. esphome/components/zephyr/preferences.h +13 -0
  712. esphome/config.py +38 -16
  713. esphome/config_helpers.py +1 -2
  714. esphome/config_validation.py +12 -16
  715. esphome/const.py +26 -1
  716. esphome/core/__init__.py +92 -51
  717. esphome/core/application.cpp +75 -21
  718. esphome/core/application.h +106 -171
  719. esphome/core/color.h +10 -0
  720. esphome/core/component.cpp +41 -25
  721. esphome/core/component.h +9 -6
  722. esphome/core/component_iterator.cpp +61 -261
  723. esphome/core/component_iterator.h +15 -0
  724. esphome/core/config.py +26 -11
  725. esphome/core/defines.h +40 -2
  726. esphome/core/entity_base.h +18 -0
  727. esphome/core/entity_helpers.py +45 -10
  728. esphome/core/helpers.cpp +8 -15
  729. esphome/core/helpers.h +60 -6
  730. esphome/core/lock_free_queue.h +1 -1
  731. esphome/core/scheduler.cpp +311 -77
  732. esphome/core/scheduler.h +141 -28
  733. esphome/cpp_generator.py +2 -6
  734. esphome/cpp_helpers.py +1 -1
  735. esphome/dashboard/dashboard.py +2 -3
  736. esphome/dashboard/dns.py +2 -8
  737. esphome/dashboard/web_server.py +34 -19
  738. esphome/espota2.py +1 -4
  739. esphome/git.py +3 -1
  740. esphome/helpers.py +23 -4
  741. esphome/log.py +3 -1
  742. esphome/mqtt.py +3 -5
  743. esphome/platformio_api.py +7 -4
  744. esphome/types.py +12 -0
  745. esphome/util.py +20 -8
  746. esphome/voluptuous_schema.py +4 -3
  747. esphome/vscode.py +1 -2
  748. esphome/wizard.py +1 -4
  749. esphome/writer.py +16 -108
  750. esphome/yaml_util.py +7 -5
  751. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/METADATA +13 -14
  752. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/RECORD +757 -677
  753. esphome/components/mipi_spi/models/commands.py +0 -82
  754. /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
  755. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/WHEEL +0 -0
  756. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/entry_points.txt +0 -0
  757. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/licenses/LICENSE +0 -0
  758. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/top_level.txt +0 -0
@@ -3,16 +3,64 @@
3
3
  #include "esphome/core/component.h"
4
4
  #include "esphome/core/helpers.h"
5
5
  #include "esphome/core/log.h"
6
+ #include "esphome/core/string_ref.h"
6
7
 
7
8
  #include <cassert>
9
+ #include <cstring>
8
10
  #include <vector>
9
11
 
10
12
  #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
11
13
  #define HAS_PROTO_MESSAGE_DUMP
12
14
  #endif
13
15
 
14
- namespace esphome {
15
- namespace api {
16
+ namespace esphome::api {
17
+
18
+ // Helper functions for ZigZag encoding/decoding
19
+ inline constexpr uint32_t encode_zigzag32(int32_t value) {
20
+ return (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
21
+ }
22
+
23
+ inline constexpr uint64_t encode_zigzag64(int64_t value) {
24
+ return (static_cast<uint64_t>(value) << 1) ^ (static_cast<uint64_t>(value >> 63));
25
+ }
26
+
27
+ inline constexpr int32_t decode_zigzag32(uint32_t value) {
28
+ return (value & 1) ? static_cast<int32_t>(~(value >> 1)) : static_cast<int32_t>(value >> 1);
29
+ }
30
+
31
+ inline constexpr int64_t decode_zigzag64(uint64_t value) {
32
+ return (value & 1) ? static_cast<int64_t>(~(value >> 1)) : static_cast<int64_t>(value >> 1);
33
+ }
34
+
35
+ /*
36
+ * StringRef Ownership Model for API Protocol Messages
37
+ * ===================================================
38
+ *
39
+ * StringRef is used for zero-copy string handling in outgoing (SOURCE_SERVER) messages.
40
+ * It holds a pointer and length to existing string data without copying.
41
+ *
42
+ * CRITICAL: The referenced string data MUST remain valid until message encoding completes.
43
+ *
44
+ * Safe StringRef Patterns:
45
+ * 1. String literals: StringRef("literal") - Always safe (static storage duration)
46
+ * 2. Member variables: StringRef(this->member_string_) - Safe if object outlives encoding
47
+ * 3. Global/static strings: StringRef(GLOBAL_CONSTANT) - Always safe
48
+ * 4. Local variables: Safe ONLY if encoding happens before function returns:
49
+ * std::string temp = compute_value();
50
+ * msg.set_field(StringRef(temp));
51
+ * return this->send_message(msg); // temp is valid during encoding
52
+ *
53
+ * Unsafe Patterns (WILL cause crashes/corruption):
54
+ * 1. Temporaries: msg.set_field(StringRef(obj.get_string())) // get_string() returns by value
55
+ * 2. Concatenation: msg.set_field(StringRef(str1 + str2)) // Result is temporary
56
+ *
57
+ * For unsafe patterns, store in a local variable first:
58
+ * std::string temp = get_string(); // or str1 + str2
59
+ * msg.set_field(StringRef(temp));
60
+ *
61
+ * The send_*_response pattern ensures proper lifetime management by encoding
62
+ * within the same function scope where temporaries are created.
63
+ */
16
64
 
17
65
  /// Representation of a VarInt - in ProtoBuf should be 64bit but we only use 32bit
18
66
  class ProtoVarInt {
@@ -56,33 +104,25 @@ class ProtoVarInt {
56
104
  return {}; // Incomplete or invalid varint
57
105
  }
58
106
 
59
- uint16_t as_uint16() const { return this->value_; }
60
- uint32_t as_uint32() const { return this->value_; }
61
- uint64_t as_uint64() const { return this->value_; }
62
- bool as_bool() const { return this->value_; }
63
- int32_t as_int32() const {
107
+ constexpr uint16_t as_uint16() const { return this->value_; }
108
+ constexpr uint32_t as_uint32() const { return this->value_; }
109
+ constexpr uint64_t as_uint64() const { return this->value_; }
110
+ constexpr bool as_bool() const { return this->value_; }
111
+ constexpr int32_t as_int32() const {
64
112
  // Not ZigZag encoded
65
113
  return static_cast<int32_t>(this->as_int64());
66
114
  }
67
- int64_t as_int64() const {
115
+ constexpr int64_t as_int64() const {
68
116
  // Not ZigZag encoded
69
117
  return static_cast<int64_t>(this->value_);
70
118
  }
71
- int32_t as_sint32() const {
119
+ constexpr int32_t as_sint32() const {
72
120
  // with ZigZag encoding
73
- if (this->value_ & 1) {
74
- return static_cast<int32_t>(~(this->value_ >> 1));
75
- } else {
76
- return static_cast<int32_t>(this->value_ >> 1);
77
- }
121
+ return decode_zigzag32(static_cast<uint32_t>(this->value_));
78
122
  }
79
- int64_t as_sint64() const {
123
+ constexpr int64_t as_sint64() const {
80
124
  // with ZigZag encoding
81
- if (this->value_ & 1) {
82
- return static_cast<int64_t>(~(this->value_ >> 1));
83
- } else {
84
- return static_cast<int64_t>(this->value_ >> 1);
85
- }
125
+ return decode_zigzag64(this->value_);
86
126
  }
87
127
  /**
88
128
  * Encode the varint value to a pre-allocated buffer without bounds checking.
@@ -135,6 +175,7 @@ class ProtoVarInt {
135
175
 
136
176
  // Forward declaration for decode_to_message and encode_to_writer
137
177
  class ProtoMessage;
178
+ class ProtoDecodableMessage;
138
179
 
139
180
  class ProtoLengthDelimited {
140
181
  public:
@@ -142,15 +183,15 @@ class ProtoLengthDelimited {
142
183
  std::string as_string() const { return std::string(reinterpret_cast<const char *>(this->value_), this->length_); }
143
184
 
144
185
  /**
145
- * Decode the length-delimited data into an existing ProtoMessage instance.
186
+ * Decode the length-delimited data into an existing ProtoDecodableMessage instance.
146
187
  *
147
188
  * This method allows decoding without templates, enabling use in contexts
148
- * where the message type is not known at compile time. The ProtoMessage's
189
+ * where the message type is not known at compile time. The ProtoDecodableMessage's
149
190
  * decode() method will be called with the raw data and length.
150
191
  *
151
- * @param msg The ProtoMessage instance to decode into
192
+ * @param msg The ProtoDecodableMessage instance to decode into
152
193
  */
153
- void decode_to_message(ProtoMessage &msg) const;
194
+ void decode_to_message(ProtoDecodableMessage &msg) const;
154
195
 
155
196
  protected:
156
197
  const uint8_t *const value_;
@@ -175,23 +216,7 @@ class Proto32Bit {
175
216
  const uint32_t value_;
176
217
  };
177
218
 
178
- class Proto64Bit {
179
- public:
180
- explicit Proto64Bit(uint64_t value) : value_(value) {}
181
- uint64_t as_fixed64() const { return this->value_; }
182
- int64_t as_sfixed64() const { return static_cast<int64_t>(this->value_); }
183
- double as_double() const {
184
- union {
185
- uint64_t raw;
186
- double value;
187
- } s{};
188
- s.raw = this->value_;
189
- return s.value;
190
- }
191
-
192
- protected:
193
- const uint64_t value_;
194
- };
219
+ // NOTE: Proto64Bit class removed - wire type 1 (64-bit fixed) not supported
195
220
 
196
221
  class ProtoWriteBuffer {
197
222
  public:
@@ -205,9 +230,9 @@ class ProtoWriteBuffer {
205
230
  * @param field_id Field number (tag) in the protobuf message
206
231
  * @param type Wire type value:
207
232
  * - 0: Varint (int32, int64, uint32, uint64, sint32, sint64, bool, enum)
208
- * - 1: 64-bit (fixed64, sfixed64, double)
209
233
  * - 2: Length-delimited (string, bytes, embedded messages, packed repeated fields)
210
234
  * - 5: 32-bit (fixed32, sfixed32, float)
235
+ * - Note: Wire type 1 (64-bit fixed) is not supported
211
236
  *
212
237
  * Following https://protobuf.dev/programming-guides/encoding/#structure
213
238
  */
@@ -221,12 +246,20 @@ class ProtoWriteBuffer {
221
246
 
222
247
  this->encode_field_raw(field_id, 2); // type 2: Length-delimited string
223
248
  this->encode_varint_raw(len);
224
- auto *data = reinterpret_cast<const uint8_t *>(string);
225
- this->buffer_->insert(this->buffer_->end(), data, data + len);
249
+
250
+ // Using resize + memcpy instead of insert provides significant performance improvement:
251
+ // ~10-11x faster for 16-32 byte strings, ~3x faster for 64-byte strings
252
+ // as it avoids iterator checks and potential element moves that insert performs
253
+ size_t old_size = this->buffer_->size();
254
+ this->buffer_->resize(old_size + len);
255
+ std::memcpy(this->buffer_->data() + old_size, string, len);
226
256
  }
227
257
  void encode_string(uint32_t field_id, const std::string &value, bool force = false) {
228
258
  this->encode_string(field_id, value.data(), value.size(), force);
229
259
  }
260
+ void encode_string(uint32_t field_id, const StringRef &ref, bool force = false) {
261
+ this->encode_string(field_id, ref.c_str(), ref.size(), force);
262
+ }
230
263
  void encode_bytes(uint32_t field_id, const uint8_t *data, size_t len, bool force = false) {
231
264
  this->encode_string(field_id, reinterpret_cast<const char *>(data), len, force);
232
265
  }
@@ -258,20 +291,10 @@ class ProtoWriteBuffer {
258
291
  this->write((value >> 16) & 0xFF);
259
292
  this->write((value >> 24) & 0xFF);
260
293
  }
261
- void encode_fixed64(uint32_t field_id, uint64_t value, bool force = false) {
262
- if (value == 0 && !force)
263
- return;
264
-
265
- this->encode_field_raw(field_id, 1); // type 1: 64-bit fixed64
266
- this->write((value >> 0) & 0xFF);
267
- this->write((value >> 8) & 0xFF);
268
- this->write((value >> 16) & 0xFF);
269
- this->write((value >> 24) & 0xFF);
270
- this->write((value >> 32) & 0xFF);
271
- this->write((value >> 40) & 0xFF);
272
- this->write((value >> 48) & 0xFF);
273
- this->write((value >> 56) & 0xFF);
274
- }
294
+ // NOTE: Wire type 1 (64-bit fixed: double, fixed64, sfixed64) is intentionally
295
+ // not supported to reduce overhead on embedded systems. All ESPHome devices are
296
+ // 32-bit microcontrollers where 64-bit operations are expensive. If 64-bit support
297
+ // is needed in the future, the necessary encoding/decoding functions must be added.
275
298
  void encode_float(uint32_t field_id, float value, bool force = false) {
276
299
  if (value == 0.0f && !force)
277
300
  return;
@@ -295,22 +318,10 @@ class ProtoWriteBuffer {
295
318
  this->encode_uint64(field_id, static_cast<uint64_t>(value), force);
296
319
  }
297
320
  void encode_sint32(uint32_t field_id, int32_t value, bool force = false) {
298
- uint32_t uvalue;
299
- if (value < 0) {
300
- uvalue = ~(value << 1);
301
- } else {
302
- uvalue = value << 1;
303
- }
304
- this->encode_uint32(field_id, uvalue, force);
321
+ this->encode_uint32(field_id, encode_zigzag32(value), force);
305
322
  }
306
323
  void encode_sint64(uint32_t field_id, int64_t value, bool force = false) {
307
- uint64_t uvalue;
308
- if (value < 0) {
309
- uvalue = ~(value << 1);
310
- } else {
311
- uvalue = value << 1;
312
- }
313
- this->encode_uint64(field_id, uvalue, force);
324
+ this->encode_uint64(field_id, encode_zigzag64(value), force);
314
325
  }
315
326
  void encode_message(uint32_t field_id, const ProtoMessage &value, bool force = false);
316
327
  std::vector<uint8_t> *get_buffer() const { return buffer_; }
@@ -319,53 +330,69 @@ class ProtoWriteBuffer {
319
330
  std::vector<uint8_t> *buffer_;
320
331
  };
321
332
 
333
+ // Forward declaration
334
+ class ProtoSize;
335
+
322
336
  class ProtoMessage {
323
337
  public:
324
338
  virtual ~ProtoMessage() = default;
325
339
  // Default implementation for messages with no fields
326
340
  virtual void encode(ProtoWriteBuffer buffer) const {}
327
- void decode(const uint8_t *buffer, size_t length);
328
341
  // Default implementation for messages with no fields
329
- virtual void calculate_size(uint32_t &total_size) const {}
342
+ virtual void calculate_size(ProtoSize &size) const {}
330
343
  #ifdef HAS_PROTO_MESSAGE_DUMP
331
344
  std::string dump() const;
332
345
  virtual void dump_to(std::string &out) const = 0;
333
346
  virtual const char *message_name() const { return "unknown"; }
334
347
  #endif
348
+ };
349
+
350
+ // Base class for messages that support decoding
351
+ class ProtoDecodableMessage : public ProtoMessage {
352
+ public:
353
+ void decode(const uint8_t *buffer, size_t length);
335
354
 
336
355
  protected:
337
356
  virtual bool decode_varint(uint32_t field_id, ProtoVarInt value) { return false; }
338
357
  virtual bool decode_length(uint32_t field_id, ProtoLengthDelimited value) { return false; }
339
358
  virtual bool decode_32bit(uint32_t field_id, Proto32Bit value) { return false; }
340
- virtual bool decode_64bit(uint32_t field_id, Proto64Bit value) { return false; }
359
+ // NOTE: decode_64bit removed - wire type 1 not supported
341
360
  };
342
361
 
343
362
  class ProtoSize {
363
+ private:
364
+ uint32_t total_size_ = 0;
365
+
344
366
  public:
345
367
  /**
346
368
  * @brief ProtoSize class for Protocol Buffer serialization size calculation
347
369
  *
348
- * This class provides static methods to calculate the exact byte counts needed
349
- * for encoding various Protocol Buffer field types. All methods are designed to be
350
- * efficient for the common case where many fields have default values.
370
+ * This class provides methods to calculate the exact byte counts needed
371
+ * for encoding various Protocol Buffer field types. The class now uses an
372
+ * object-based approach to reduce parameter passing overhead while keeping
373
+ * varint calculation methods static for external use.
351
374
  *
352
375
  * Implements Protocol Buffer encoding size calculation according to:
353
376
  * https://protobuf.dev/programming-guides/encoding/
354
377
  *
355
378
  * Key features:
379
+ * - Object-based approach reduces flash usage by eliminating parameter passing
356
380
  * - Early-return optimization for zero/default values
357
- * - Direct total_size updates to avoid unnecessary additions
381
+ * - Static varint methods for external callers
358
382
  * - Specialized handling for different field types according to protobuf spec
359
- * - Templated helpers for repeated fields and messages
360
383
  */
361
384
 
385
+ ProtoSize() = default;
386
+
387
+ uint32_t get_size() const { return total_size_; }
388
+
362
389
  /**
363
390
  * @brief Calculates the size in bytes needed to encode a uint32_t value as a varint
364
391
  *
365
392
  * @param value The uint32_t value to calculate size for
366
393
  * @return The number of bytes needed to encode the value
367
394
  */
368
- static inline uint32_t varint(uint32_t value) {
395
+ static constexpr uint32_t varint(uint32_t value) {
369
396
  // Optimized varint size calculation using leading zeros
370
397
  // Each 7 bits requires one byte in the varint encoding
371
398
  if (value < 128)
@@ -389,7 +416,7 @@ class ProtoSize {
389
416
  * @param value The uint64_t value to calculate size for
390
417
  * @return The number of bytes needed to encode the value
391
418
  */
392
- static inline uint32_t varint(uint64_t value) {
419
+ static constexpr uint32_t varint(uint64_t value) {
393
420
  // Handle common case of values fitting in uint32_t (vast majority of use cases)
394
421
  if (value <= UINT32_MAX) {
395
422
  return varint(static_cast<uint32_t>(value));
@@ -420,7 +447,7 @@ class ProtoSize {
420
447
  * @param value The int32_t value to calculate size for
421
448
  * @return The number of bytes needed to encode the value
422
449
  */
423
- static inline uint32_t varint(int32_t value) {
450
+ static constexpr uint32_t varint(int32_t value) {
424
451
  // Negative values are sign-extended to 64 bits in protocol buffers,
425
452
  // which always results in a 10-byte varint for negative int32
426
453
  if (value < 0) {
@@ -436,7 +463,7 @@ class ProtoSize {
436
463
  * @param value The int64_t value to calculate size for
437
464
  * @return The number of bytes needed to encode the value
438
465
  */
439
- static inline uint32_t varint(int64_t value) {
466
+ static constexpr uint32_t varint(int64_t value) {
440
467
  // For int64_t, we convert to uint64_t and calculate the size
441
468
  // This works because the bit pattern determines the encoding size,
442
469
  // and we've handled negative int32 values as a special case above
@@ -450,7 +477,7 @@ class ProtoSize {
450
477
  * @param type The wire type value (from the WireType enum in the protobuf spec)
451
478
  * @return The number of bytes needed to encode the field ID and wire type
452
479
  */
453
- static inline uint32_t field(uint32_t field_id, uint32_t type) {
480
+ static constexpr uint32_t field(uint32_t field_id, uint32_t type) {
454
481
  uint32_t tag = (field_id << 3) | (type & 0b111);
455
482
  return varint(tag);
456
483
  }
@@ -459,9 +486,7 @@ class ProtoSize {
459
486
  * @brief Common parameters for all add_*_field methods
460
487
  *
461
488
  * All add_*_field methods follow these common patterns:
462
- *
463
- * @param total_size Reference to the total message size to update
464
- * @param field_id_size Pre-calculated size of the field ID in bytes
489
+ * * @param field_id_size Pre-calculated size of the field ID in bytes
465
490
  * @param value The value to calculate size for (type varies)
466
491
  * @param force Whether to calculate size even if the value is default/zero/empty
467
492
  *
@@ -474,244 +499,180 @@ class ProtoSize {
474
499
  /**
475
500
  * @brief Calculates and adds the size of an int32 field to the total message size
476
501
  */
477
- static inline void add_int32_field(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
478
- // Skip calculation if value is zero
479
- if (value == 0) {
480
- return; // No need to update total_size
481
- }
482
-
483
- // Calculate and directly add to total_size
484
- if (value < 0) {
485
- // Negative values are encoded as 10-byte varints in protobuf
486
- total_size += field_id_size + 10;
487
- } else {
488
- // For non-negative values, use the standard varint size
489
- total_size += field_id_size + varint(static_cast<uint32_t>(value));
502
+ inline void add_int32(uint32_t field_id_size, int32_t value) {
503
+ if (value != 0) {
504
+ add_int32_force(field_id_size, value);
490
505
  }
491
506
  }
492
507
 
493
508
  /**
494
- * @brief Calculates and adds the size of an int32 field to the total message size (repeated field version)
509
+ * @brief Calculates and adds the size of an int32 field to the total message size (force version)
495
510
  */
496
- static inline void add_int32_field_repeated(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
497
- // Always calculate size for repeated fields
498
- if (value < 0) {
499
- // Negative values are encoded as 10-byte varints in protobuf
500
- total_size += field_id_size + 10;
501
- } else {
502
- // For non-negative values, use the standard varint size
503
- total_size += field_id_size + varint(static_cast<uint32_t>(value));
504
- }
511
+ inline void add_int32_force(uint32_t field_id_size, int32_t value) {
512
+ // Always calculate size when forced
513
+ // Negative values are encoded as 10-byte varints in protobuf
514
+ total_size_ += field_id_size + (value < 0 ? 10 : varint(static_cast<uint32_t>(value)));
505
515
  }
506
516
 
507
517
  /**
508
518
  * @brief Calculates and adds the size of a uint32 field to the total message size
509
519
  */
510
- static inline void add_uint32_field(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
511
- // Skip calculation if value is zero
512
- if (value == 0) {
513
- return; // No need to update total_size
520
+ inline void add_uint32(uint32_t field_id_size, uint32_t value) {
521
+ if (value != 0) {
522
+ add_uint32_force(field_id_size, value);
514
523
  }
515
-
516
- // Calculate and directly add to total_size
517
- total_size += field_id_size + varint(value);
518
524
  }
519
525
 
520
526
  /**
521
- * @brief Calculates and adds the size of a uint32 field to the total message size (repeated field version)
527
+ * @brief Calculates and adds the size of a uint32 field to the total message size (force version)
522
528
  */
523
- static inline void add_uint32_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
524
- // Always calculate size for repeated fields
525
- total_size += field_id_size + varint(value);
529
+ inline void add_uint32_force(uint32_t field_id_size, uint32_t value) {
530
+ // Always calculate size when force is true
531
+ total_size_ += field_id_size + varint(value);
526
532
  }
527
533
 
528
534
  /**
529
535
  * @brief Calculates and adds the size of a boolean field to the total message size
530
536
  */
531
- static inline void add_bool_field(uint32_t &total_size, uint32_t field_id_size, bool value) {
532
- // Skip calculation if value is false
533
- if (!value) {
534
- return; // No need to update total_size
537
+ inline void add_bool(uint32_t field_id_size, bool value) {
538
+ if (value) {
539
+ // Boolean fields always use 1 byte when true
540
+ total_size_ += field_id_size + 1;
535
541
  }
536
-
537
- // Boolean fields always use 1 byte when true
538
- total_size += field_id_size + 1;
539
542
  }
540
543
 
541
544
  /**
542
- * @brief Calculates and adds the size of a boolean field to the total message size (repeated field version)
545
+ * @brief Calculates and adds the size of a boolean field to the total message size (force version)
543
546
  */
544
- static inline void add_bool_field_repeated(uint32_t &total_size, uint32_t field_id_size, bool value) {
545
- // Always calculate size for repeated fields
547
+ inline void add_bool_force(uint32_t field_id_size, bool value) {
548
+ // Always calculate size when force is true
546
549
  // Boolean fields always use 1 byte
547
- total_size += field_id_size + 1;
550
+ total_size_ += field_id_size + 1;
548
551
  }
549
552
 
550
553
  /**
551
- * @brief Calculates and adds the size of a fixed field to the total message size
552
- *
553
- * Fixed fields always take exactly N bytes (4 for fixed32/float, 8 for fixed64/double).
554
- *
555
- * @tparam NumBytes The number of bytes for this fixed field (4 or 8)
556
- * @param is_nonzero Whether the value is non-zero
557
- */
558
- template<uint32_t NumBytes>
559
- static inline void add_fixed_field(uint32_t &total_size, uint32_t field_id_size, bool is_nonzero) {
560
- // Skip calculation if value is zero
561
- if (!is_nonzero) {
562
- return; // No need to update total_size
554
+ * @brief Calculates and adds the size of a float field to the total message size
555
+ */
556
+ inline void add_float(uint32_t field_id_size, float value) {
557
+ if (value != 0.0f) {
558
+ total_size_ += field_id_size + 4;
563
559
  }
564
-
565
- // Fixed fields always take exactly NumBytes
566
- total_size += field_id_size + NumBytes;
567
560
  }
568
561
 
562
+ // NOTE: add_double_field removed - wire type 1 (64-bit: double) not supported
563
+ // to reduce overhead on embedded systems
564
+
569
565
  /**
570
- * @brief Calculates and adds the size of an enum field to the total message size
571
- *
572
- * Enum fields are encoded as uint32 varints.
566
+ * @brief Calculates and adds the size of a fixed32 field to the total message size
573
567
  */
574
- static inline void add_enum_field(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
575
- // Skip calculation if value is zero
576
- if (value == 0) {
577
- return; // No need to update total_size
568
+ inline void add_fixed32(uint32_t field_id_size, uint32_t value) {
569
+ if (value != 0) {
570
+ total_size_ += field_id_size + 4;
578
571
  }
579
-
580
- // Enums are encoded as uint32
581
- total_size += field_id_size + varint(value);
582
572
  }
583
573
 
574
+ // NOTE: add_fixed64_field removed - wire type 1 (64-bit: fixed64) not supported
575
+ // to reduce overhead on embedded systems
576
+
584
577
  /**
585
- * @brief Calculates and adds the size of an enum field to the total message size (repeated field version)
586
- *
587
- * Enum fields are encoded as uint32 varints.
578
+ * @brief Calculates and adds the size of a sfixed32 field to the total message size
588
579
  */
589
- static inline void add_enum_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
590
- // Always calculate size for repeated fields
591
- // Enums are encoded as uint32
592
- total_size += field_id_size + varint(value);
580
+ inline void add_sfixed32(uint32_t field_id_size, int32_t value) {
581
+ if (value != 0) {
582
+ total_size_ += field_id_size + 4;
583
+ }
593
584
  }
594
585
 
586
+ // NOTE: add_sfixed64_field removed - wire type 1 (64-bit: sfixed64) not supported
587
+ // to reduce overhead on embedded systems
588
+
595
589
  /**
596
590
  * @brief Calculates and adds the size of a sint32 field to the total message size
597
591
  *
598
592
  * Sint32 fields use ZigZag encoding, which is more efficient for negative values.
599
593
  */
600
- static inline void add_sint32_field(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
601
- // Skip calculation if value is zero
602
- if (value == 0) {
603
- return; // No need to update total_size
594
+ inline void add_sint32(uint32_t field_id_size, int32_t value) {
595
+ if (value != 0) {
596
+ add_sint32_force(field_id_size, value);
604
597
  }
605
-
606
- // ZigZag encoding for sint32: (n << 1) ^ (n >> 31)
607
- uint32_t zigzag = (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
608
- total_size += field_id_size + varint(zigzag);
609
598
  }
610
599
 
611
600
  /**
612
- * @brief Calculates and adds the size of a sint32 field to the total message size (repeated field version)
601
+ * @brief Calculates and adds the size of a sint32 field to the total message size (force version)
613
602
  *
614
603
  * Sint32 fields use ZigZag encoding, which is more efficient for negative values.
615
604
  */
616
- static inline void add_sint32_field_repeated(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
617
- // Always calculate size for repeated fields
618
- // ZigZag encoding for sint32: (n << 1) ^ (n >> 31)
619
- uint32_t zigzag = (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
620
- total_size += field_id_size + varint(zigzag);
605
+ inline void add_sint32_force(uint32_t field_id_size, int32_t value) {
606
+ // Always calculate size when force is true
607
+ // ZigZag encoding for sint32
608
+ total_size_ += field_id_size + varint(encode_zigzag32(value));
621
609
  }
622
610
 
623
611
  /**
624
612
  * @brief Calculates and adds the size of an int64 field to the total message size
625
613
  */
626
- static inline void add_int64_field(uint32_t &total_size, uint32_t field_id_size, int64_t value) {
627
- // Skip calculation if value is zero
628
- if (value == 0) {
629
- return; // No need to update total_size
614
+ inline void add_int64(uint32_t field_id_size, int64_t value) {
615
+ if (value != 0) {
616
+ add_int64_force(field_id_size, value);
630
617
  }
631
-
632
- // Calculate and directly add to total_size
633
- total_size += field_id_size + varint(value);
634
618
  }
635
619
 
636
620
  /**
637
- * @brief Calculates and adds the size of an int64 field to the total message size (repeated field version)
621
+ * @brief Calculates and adds the size of an int64 field to the total message size (force version)
638
622
  */
639
- static inline void add_int64_field_repeated(uint32_t &total_size, uint32_t field_id_size, int64_t value) {
640
- // Always calculate size for repeated fields
641
- total_size += field_id_size + varint(value);
623
+ inline void add_int64_force(uint32_t field_id_size, int64_t value) {
624
+ // Always calculate size when force is true
625
+ total_size_ += field_id_size + varint(value);
642
626
  }
643
627
 
644
628
  /**
645
629
  * @brief Calculates and adds the size of a uint64 field to the total message size
646
630
  */
647
- static inline void add_uint64_field(uint32_t &total_size, uint32_t field_id_size, uint64_t value) {
648
- // Skip calculation if value is zero
649
- if (value == 0) {
650
- return; // No need to update total_size
631
+ inline void add_uint64(uint32_t field_id_size, uint64_t value) {
632
+ if (value != 0) {
633
+ add_uint64_force(field_id_size, value);
651
634
  }
652
-
653
- // Calculate and directly add to total_size
654
- total_size += field_id_size + varint(value);
655
635
  }
656
636
 
657
637
  /**
658
- * @brief Calculates and adds the size of a uint64 field to the total message size (repeated field version)
638
+ * @brief Calculates and adds the size of a uint64 field to the total message size (force version)
659
639
  */
660
- static inline void add_uint64_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint64_t value) {
661
- // Always calculate size for repeated fields
662
- total_size += field_id_size + varint(value);
640
+ inline void add_uint64_force(uint32_t field_id_size, uint64_t value) {
641
+ // Always calculate size when force is true
642
+ total_size_ += field_id_size + varint(value);
663
643
  }
664
644
 
665
- /**
666
- * @brief Calculates and adds the size of a sint64 field to the total message size
667
- *
668
- * Sint64 fields use ZigZag encoding, which is more efficient for negative values.
669
- */
670
- static inline void add_sint64_field(uint32_t &total_size, uint32_t field_id_size, int64_t value) {
671
- // Skip calculation if value is zero
672
- if (value == 0) {
673
- return; // No need to update total_size
674
- }
675
-
676
- // ZigZag encoding for sint64: (n << 1) ^ (n >> 63)
677
- uint64_t zigzag = (static_cast<uint64_t>(value) << 1) ^ (static_cast<uint64_t>(value >> 63));
678
- total_size += field_id_size + varint(zigzag);
679
- }
645
+ // NOTE: sint64 support functions (add_sint64_field, add_sint64_field_force) removed
646
+ // sint64 type is not supported by ESPHome API to reduce overhead on embedded systems
680
647
 
681
648
  /**
682
- * @brief Calculates and adds the size of a sint64 field to the total message size (repeated field version)
683
- *
684
- * Sint64 fields use ZigZag encoding, which is more efficient for negative values.
649
+ * @brief Calculates and adds the size of a length-delimited field (string/bytes) to the total message size
685
650
  */
686
- static inline void add_sint64_field_repeated(uint32_t &total_size, uint32_t field_id_size, int64_t value) {
687
- // Always calculate size for repeated fields
688
- // ZigZag encoding for sint64: (n << 1) ^ (n >> 63)
689
- uint64_t zigzag = (static_cast<uint64_t>(value) << 1) ^ (static_cast<uint64_t>(value >> 63));
690
- total_size += field_id_size + varint(zigzag);
651
+ inline void add_length(uint32_t field_id_size, size_t len) {
652
+ if (len != 0) {
653
+ add_length_force(field_id_size, len);
654
+ }
691
655
  }
692
656
 
693
657
  /**
694
- * @brief Calculates and adds the size of a string/bytes field to the total message size
658
+ * @brief Calculates and adds the size of a length-delimited field (string/bytes) to the total message size (repeated
659
+ * field version)
695
660
  */
696
- static inline void add_string_field(uint32_t &total_size, uint32_t field_id_size, const std::string &str) {
697
- // Skip calculation if string is empty
698
- if (str.empty()) {
699
- return; // No need to update total_size
700
- }
701
-
702
- // Calculate and directly add to total_size
703
- const uint32_t str_size = static_cast<uint32_t>(str.size());
704
- total_size += field_id_size + varint(str_size) + str_size;
661
+ inline void add_length_force(uint32_t field_id_size, size_t len) {
662
+ // Always calculate size when force is true
663
+ // Field ID + length varint + data bytes
664
+ total_size_ += field_id_size + varint(static_cast<uint32_t>(len)) + static_cast<uint32_t>(len);
705
665
  }
706
666
 
707
667
  /**
708
- * @brief Calculates and adds the size of a string/bytes field to the total message size (repeated field version)
668
+ * @brief Adds a pre-calculated size directly to the total
669
+ *
670
+ * This is used when we can calculate the total size by multiplying the number
671
+ * of elements by the bytes per element (for repeated fixed-size types like float, fixed32, etc.)
672
+ *
673
+ * @param size The pre-calculated total size to add
709
674
  */
710
- static inline void add_string_field_repeated(uint32_t &total_size, uint32_t field_id_size, const std::string &str) {
711
- // Always calculate size for repeated fields
712
- const uint32_t str_size = static_cast<uint32_t>(str.size());
713
- total_size += field_id_size + varint(str_size) + str_size;
714
- }
675
+ inline void add_precalculated_size(uint32_t size) { total_size_ += size; }
715
676
 
716
677
  /**
717
678
  * @brief Calculates and adds the size of a nested message field to the total message size
@@ -721,26 +682,21 @@ class ProtoSize {
721
682
  *
722
683
  * @param nested_size The pre-calculated size of the nested message
723
684
  */
724
- static inline void add_message_field(uint32_t &total_size, uint32_t field_id_size, uint32_t nested_size) {
725
- // Skip calculation if nested message is empty
726
- if (nested_size == 0) {
727
- return; // No need to update total_size
685
+ inline void add_message_field(uint32_t field_id_size, uint32_t nested_size) {
686
+ if (nested_size != 0) {
687
+ add_message_field_force(field_id_size, nested_size);
728
688
  }
729
-
730
- // Calculate and directly add to total_size
731
- // Field ID + length varint + nested message content
732
- total_size += field_id_size + varint(nested_size) + nested_size;
733
689
  }
734
690
 
735
691
  /**
736
- * @brief Calculates and adds the size of a nested message field to the total message size (repeated field version)
692
+ * @brief Calculates and adds the size of a nested message field to the total message size (force version)
737
693
  *
738
694
  * @param nested_size The pre-calculated size of the nested message
739
695
  */
740
- static inline void add_message_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint32_t nested_size) {
741
- // Always calculate size for repeated fields
696
+ inline void add_message_field_force(uint32_t field_id_size, uint32_t nested_size) {
697
+ // Always calculate size when force is true
742
698
  // Field ID + length varint + nested message content
743
- total_size += field_id_size + varint(nested_size) + nested_size;
699
+ total_size_ += field_id_size + varint(nested_size) + nested_size;
744
700
  }
745
701
 
746
702
  /**
@@ -752,26 +708,29 @@ class ProtoSize {
752
708
  *
753
709
  * @param message The nested message object
754
710
  */
755
- static inline void add_message_object(uint32_t &total_size, uint32_t field_id_size, const ProtoMessage &message) {
756
- uint32_t nested_size = 0;
757
- message.calculate_size(nested_size);
711
+ inline void add_message_object(uint32_t field_id_size, const ProtoMessage &message) {
712
+ // Calculate nested message size by creating a temporary ProtoSize
713
+ ProtoSize nested_calc;
714
+ message.calculate_size(nested_calc);
715
+ uint32_t nested_size = nested_calc.get_size();
758
716
 
759
717
  // Use the base implementation with the calculated nested_size
760
- add_message_field(total_size, field_id_size, nested_size);
718
+ add_message_field(field_id_size, nested_size);
761
719
  }
762
720
 
763
721
  /**
764
- * @brief Calculates and adds the size of a nested message field to the total message size (repeated field version)
722
+ * @brief Calculates and adds the size of a nested message field to the total message size (force version)
765
723
  *
766
724
  * @param message The nested message object
767
725
  */
768
- static inline void add_message_object_repeated(uint32_t &total_size, uint32_t field_id_size,
769
- const ProtoMessage &message) {
770
- uint32_t nested_size = 0;
771
- message.calculate_size(nested_size);
726
+ inline void add_message_object_force(uint32_t field_id_size, const ProtoMessage &message) {
727
+ // Calculate nested message size by creating a temporary ProtoSize
728
+ ProtoSize nested_calc;
729
+ message.calculate_size(nested_calc);
730
+ uint32_t nested_size = nested_calc.get_size();
772
731
 
773
732
  // Use the base implementation with the calculated nested_size
774
- add_message_field_repeated(total_size, field_id_size, nested_size);
733
+ add_message_field_force(field_id_size, nested_size);
775
734
  }
776
735
 
777
736
  /**
@@ -784,16 +743,15 @@ class ProtoSize {
784
743
  * @param messages Vector of message objects
785
744
  */
786
745
  template<typename MessageType>
787
- static inline void add_repeated_message(uint32_t &total_size, uint32_t field_id_size,
788
- const std::vector<MessageType> &messages) {
746
+ inline void add_repeated_message(uint32_t field_id_size, const std::vector<MessageType> &messages) {
789
747
  // Skip if the vector is empty
790
748
  if (messages.empty()) {
791
749
  return;
792
750
  }
793
751
 
794
- // Use the repeated field version for all messages
752
+ // Use the force version for all messages in the repeated field
795
753
  for (const auto &message : messages) {
796
- add_message_object_repeated(total_size, field_id_size, message);
754
+ add_message_object_force(field_id_size, message);
797
755
  }
798
756
  }
799
757
  };
@@ -803,8 +761,9 @@ inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const ProtoMessa
803
761
  this->encode_field_raw(field_id, 2); // type 2: Length-delimited message
804
762
 
805
763
  // Calculate the message size first
806
- uint32_t msg_length_bytes = 0;
807
- value.calculate_size(msg_length_bytes);
764
+ ProtoSize msg_size;
765
+ value.calculate_size(msg_size);
766
+ uint32_t msg_length_bytes = msg_size.get_size();
808
767
 
809
768
  // Calculate how many bytes the length varint needs
810
769
  uint32_t varint_length_bytes = ProtoSize::varint(msg_length_bytes);
@@ -823,8 +782,8 @@ inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const ProtoMessa
823
782
  assert(this->buffer_->size() == begin + varint_length_bytes + msg_length_bytes);
824
783
  }
825
784
 
826
- // Implementation of decode_to_message - must be after ProtoMessage is defined
827
- inline void ProtoLengthDelimited::decode_to_message(ProtoMessage &msg) const {
785
+ // Implementation of decode_to_message - must be after ProtoDecodableMessage is defined
786
+ inline void ProtoLengthDelimited::decode_to_message(ProtoDecodableMessage &msg) const {
828
787
  msg.decode(this->value_, this->length_);
829
788
  }
830
789
 
@@ -836,7 +795,9 @@ class ProtoService {
836
795
  virtual bool is_authenticated() = 0;
837
796
  virtual bool is_connection_setup() = 0;
838
797
  virtual void on_fatal_error() = 0;
798
+ #ifdef USE_API_PASSWORD
839
799
  virtual void on_unauthenticated_access() = 0;
800
+ #endif
840
801
  virtual void on_no_setup_connection() = 0;
841
802
  /**
842
803
  * Create a buffer with a reserved size.
@@ -851,8 +812,9 @@ class ProtoService {
851
812
 
852
813
  // Optimized method that pre-allocates buffer based on message size
853
814
  bool send_message_(const ProtoMessage &msg, uint8_t message_type) {
854
- uint32_t msg_size = 0;
855
- msg.calculate_size(msg_size);
815
+ ProtoSize size;
816
+ msg.calculate_size(size);
817
+ uint32_t msg_size = size.get_size();
856
818
 
857
819
  // Create a pre-sized buffer
858
820
  auto buffer = this->create_buffer(msg_size);
@@ -874,6 +836,7 @@ class ProtoService {
874
836
  }
875
837
 
876
838
  bool check_authenticated_() {
839
+ #ifdef USE_API_PASSWORD
877
840
  if (!this->check_connection_setup_()) {
878
841
  return false;
879
842
  }
@@ -882,8 +845,10 @@ class ProtoService {
882
845
  return false;
883
846
  }
884
847
  return true;
848
+ #else
849
+ return this->check_connection_setup_();
850
+ #endif
885
851
  }
886
852
  };
887
853
 
888
- } // namespace api
889
- } // namespace esphome
854
+ } // namespace esphome::api