esphome 2025.5.2__py3-none-any.whl → 2025.6.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (715) hide show
  1. esphome/__main__.py +20 -14
  2. esphome/components/a4988/a4988.cpp +1 -1
  3. esphome/components/absolute_humidity/absolute_humidity.cpp +6 -4
  4. esphome/components/ac_dimmer/ac_dimmer.cpp +4 -2
  5. esphome/components/adc/adc_sensor_esp32.cpp +5 -3
  6. esphome/components/adc/adc_sensor_esp8266.cpp +5 -3
  7. esphome/components/adc/adc_sensor_libretiny.cpp +5 -3
  8. esphome/components/adc/adc_sensor_rp2040.cpp +5 -3
  9. esphome/components/adc128s102/adc128s102.cpp +1 -1
  10. esphome/components/ade7880/ade7880.cpp +28 -17
  11. esphome/components/ade7953_base/ade7953_base.cpp +12 -9
  12. esphome/components/ade7953_i2c/ade7953_i2c.cpp +1 -1
  13. esphome/components/ade7953_spi/ade7953_spi.cpp +1 -1
  14. esphome/components/ads1115/ads1115.cpp +3 -5
  15. esphome/components/ads1118/ads1118.cpp +2 -1
  16. esphome/components/ags10/ags10.cpp +3 -2
  17. esphome/components/aht10/aht10.cpp +27 -29
  18. esphome/components/aic3204/aic3204.cpp +2 -2
  19. esphome/components/alarm_control_panel/__init__.py +1 -0
  20. esphome/components/am2315c/am2315c.cpp +2 -2
  21. esphome/components/am2320/am2320.cpp +2 -2
  22. esphome/components/am43/am43_base.h +1 -1
  23. esphome/components/am43/cover/am43_cover.cpp +4 -2
  24. esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +4 -2
  25. esphome/components/apds9306/apds9306.cpp +8 -5
  26. esphome/components/apds9960/apds9960.cpp +2 -2
  27. esphome/components/api/__init__.py +5 -0
  28. esphome/components/api/api_connection.cpp +712 -358
  29. esphome/components/api/api_connection.h +343 -284
  30. esphome/components/api/api_frame_helper.cpp +349 -344
  31. esphome/components/api/api_frame_helper.h +121 -94
  32. esphome/components/api/api_pb2.cpp +2 -0
  33. esphome/components/api/api_pb2.h +637 -1
  34. esphome/components/api/api_pb2_service.cpp +12 -688
  35. esphome/components/api/api_pb2_service.h +53 -207
  36. esphome/components/api/api_server.cpp +71 -29
  37. esphome/components/api/api_server.h +9 -0
  38. esphome/components/api/client.py +5 -2
  39. esphome/components/api/homeassistant_service.h +1 -1
  40. esphome/components/api/list_entities.cpp +1 -1
  41. esphome/components/api/proto.cpp +1 -0
  42. esphome/components/api/proto.h +4 -3
  43. esphome/components/api/subscribe_state.cpp +8 -16
  44. esphome/components/as3935/as3935.cpp +3 -3
  45. esphome/components/as5600/as5600.cpp +9 -7
  46. esphome/components/as7341/as7341.cpp +7 -5
  47. esphome/components/at581x/at581x.cpp +13 -10
  48. esphome/components/atm90e26/atm90e26.cpp +2 -2
  49. esphome/components/atm90e32/atm90e32.cpp +3 -3
  50. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +5 -3
  51. esphome/components/bang_bang/bang_bang_climate.cpp +8 -5
  52. esphome/components/bedjet/bedjet_hub.cpp +6 -4
  53. esphome/components/beken_spi_led_strip/led_strip.cpp +11 -7
  54. esphome/components/bh1750/bh1750.cpp +2 -2
  55. esphome/components/binary_sensor/__init__.py +1 -0
  56. esphome/components/binary_sensor/automation.cpp +1 -2
  57. esphome/components/bl0906/bl0906.cpp +1 -1
  58. esphome/components/bl0942/bl0942.cpp +11 -8
  59. esphome/components/bl0942/sensor.py +1 -1
  60. esphome/components/ble_client/__init__.py +5 -1
  61. esphome/components/ble_client/output/ble_binary_output.cpp +6 -3
  62. esphome/components/ble_client/sensor/ble_sensor.cpp +9 -6
  63. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +8 -5
  64. esphome/components/bluetooth_proxy/__init__.py +5 -1
  65. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +5 -5
  66. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -14
  67. esphome/components/bme280_base/bme280_base.cpp +3 -3
  68. esphome/components/bme680/bme680.cpp +3 -3
  69. esphome/components/bme680/sensor.py +2 -2
  70. esphome/components/bme680_bsec/bme680_bsec.cpp +11 -7
  71. esphome/components/bme680_bsec/sensor.py +7 -3
  72. esphome/components/bme68x_bsec2/__init__.py +6 -5
  73. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +17 -13
  74. esphome/components/bme68x_bsec2/sensor.py +4 -4
  75. esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.cpp +1 -0
  76. esphome/components/bmi160/bmi160.cpp +11 -11
  77. esphome/components/bmp085/bmp085.cpp +2 -2
  78. esphome/components/bmp280_base/bmp280_base.cpp +3 -3
  79. esphome/components/bmp3xx_base/bmp3xx_base.cpp +13 -13
  80. esphome/components/bmp581/bmp581.cpp +33 -27
  81. esphome/components/bp1658cj/bp1658cj.cpp +5 -3
  82. esphome/components/bp5758d/bp5758d.cpp +1 -1
  83. esphome/components/button/__init__.py +1 -0
  84. esphome/components/canbus/canbus.cpp +1 -1
  85. esphome/components/cap1188/cap1188.cpp +6 -4
  86. esphome/components/captive_portal/captive_portal.cpp +1 -1
  87. esphome/components/ccs811/ccs811.cpp +3 -2
  88. esphome/components/cd74hc4067/cd74hc4067.cpp +1 -1
  89. esphome/components/ch422g/ch422g.cpp +2 -2
  90. esphome/components/chsc6x/chsc6x_touchscreen.cpp +6 -4
  91. esphome/components/climate/__init__.py +1 -0
  92. esphome/components/climate/climate.cpp +12 -7
  93. esphome/components/climate/climate.h +1 -1
  94. esphome/components/climate_ir/climate_ir.cpp +7 -4
  95. esphome/components/cm1106/__init__.py +1 -0
  96. esphome/components/cm1106/cm1106.cpp +112 -0
  97. esphome/components/cm1106/cm1106.h +40 -0
  98. esphome/components/cm1106/sensor.py +72 -0
  99. esphome/components/const/__init__.py +1 -0
  100. esphome/components/cover/__init__.py +1 -0
  101. esphome/components/cs5460a/cs5460a.cpp +16 -11
  102. esphome/components/cse7761/cse7761.cpp +2 -2
  103. esphome/components/cse7766/cse7766.cpp +0 -5
  104. esphome/components/cse7766/cse7766.h +5 -1
  105. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +1 -1
  106. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +6 -3
  107. esphome/components/current_based/current_based_cover.cpp +4 -2
  108. esphome/components/dac7678/dac7678_output.cpp +4 -4
  109. esphome/components/dallas_temp/dallas_temp.cpp +2 -3
  110. esphome/components/daly_bms/daly_bms.cpp +2 -1
  111. esphome/components/dashboard_import/__init__.py +1 -2
  112. esphome/components/datetime/__init__.py +3 -1
  113. esphome/components/debug/debug_component.cpp +1 -1
  114. esphome/components/debug/debug_component.h +1 -1
  115. esphome/components/debug/debug_esp32.cpp +4 -2
  116. esphome/components/deep_sleep/deep_sleep_component.cpp +11 -5
  117. esphome/components/deep_sleep/deep_sleep_esp32.cpp +7 -5
  118. esphome/components/demo/__init__.py +206 -0
  119. esphome/components/demo/demo_alarm_control_panel.h +65 -0
  120. esphome/components/demo/demo_button.h +15 -0
  121. esphome/components/demo/demo_date.h +34 -0
  122. esphome/components/demo/demo_datetime.h +40 -0
  123. esphome/components/demo/demo_lock.h +17 -0
  124. esphome/components/demo/demo_select.h +15 -0
  125. esphome/components/demo/demo_text.h +18 -0
  126. esphome/components/demo/demo_time.h +34 -0
  127. esphome/components/demo/demo_valve.h +54 -0
  128. esphome/components/dfrobot_sen0395/commands.cpp +3 -3
  129. esphome/components/dht/dht.cpp +29 -50
  130. esphome/components/dht12/dht12.cpp +2 -2
  131. esphome/components/display/display.h +5 -3
  132. esphome/components/dps310/dps310.cpp +7 -5
  133. esphome/components/ds1307/ds1307.cpp +2 -2
  134. esphome/components/dsmr/dsmr.cpp +5 -3
  135. esphome/components/duty_cycle/duty_cycle_sensor.cpp +2 -2
  136. esphome/components/duty_time/duty_time_sensor.cpp +5 -3
  137. esphome/components/ee895/ee895.cpp +3 -3
  138. esphome/components/ektf2232/touchscreen/ektf2232.cpp +1 -1
  139. esphome/components/emc2101/emc2101.cpp +11 -9
  140. esphome/components/ens160_base/ens160_base.cpp +2 -2
  141. esphome/components/ens210/ens210.cpp +2 -2
  142. esphome/components/es7210/es7210.cpp +6 -4
  143. esphome/components/es7243e/es7243e.cpp +1 -1
  144. esphome/components/es8156/es8156.cpp +1 -1
  145. esphome/components/es8311/es8311.cpp +8 -6
  146. esphome/components/es8388/__init__.py +0 -0
  147. esphome/components/es8388/audio_dac.py +26 -0
  148. esphome/components/es8388/es8388.cpp +289 -0
  149. esphome/components/es8388/es8388.h +81 -0
  150. esphome/components/es8388/es8388_const.h +83 -0
  151. esphome/components/es8388/select/__init__.py +47 -0
  152. esphome/components/es8388/select/adc_input_mic_select.cpp +12 -0
  153. esphome/components/es8388/select/adc_input_mic_select.h +15 -0
  154. esphome/components/es8388/select/dac_output_select.cpp +12 -0
  155. esphome/components/es8388/select/dac_output_select.h +15 -0
  156. esphome/components/esp32/__init__.py +88 -20
  157. esphome/components/esp32/boards.py +208 -125
  158. esphome/components/esp32/const.py +6 -0
  159. esphome/components/esp32/gpio.py +14 -1
  160. esphome/components/esp32/gpio_esp32_c5.py +45 -0
  161. esphome/components/esp32/gpio_esp32_p4.py +43 -0
  162. esphome/components/esp32/preferences.cpp +7 -7
  163. esphome/components/esp32_ble/__init__.py +115 -0
  164. esphome/components/esp32_ble/ble.cpp +11 -9
  165. esphome/components/esp32_ble/ble_uuid.h +1 -1
  166. esphome/components/esp32_ble_client/ble_client_base.cpp +4 -2
  167. esphome/components/esp32_ble_server/__init__.py +4 -1
  168. esphome/components/esp32_ble_server/ble_characteristic.cpp +1 -0
  169. esphome/components/esp32_ble_server/ble_server.h +0 -1
  170. esphome/components/esp32_ble_tracker/__init__.py +6 -2
  171. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +12 -9
  172. esphome/components/esp32_camera/esp32_camera.cpp +35 -27
  173. esphome/components/esp32_camera_web_server/camera_web_server.cpp +4 -2
  174. esphome/components/esp32_dac/esp32_dac.cpp +2 -2
  175. esphome/components/esp32_improv/__init__.py +5 -1
  176. esphome/components/esp32_improv/esp32_improv_component.cpp +2 -2
  177. esphome/components/esp32_rmt_led_strip/led_strip.cpp +11 -7
  178. esphome/components/esp32_rmt_led_strip/light.py +5 -1
  179. esphome/components/esp32_touch/esp32_touch.cpp +12 -8
  180. esphome/components/esp8266/preferences.cpp +6 -6
  181. esphome/components/esp8266_pwm/esp8266_pwm.cpp +3 -3
  182. esphome/components/esp_ldo/__init__.py +91 -0
  183. esphome/components/esp_ldo/esp_ldo.cpp +43 -0
  184. esphome/components/esp_ldo/esp_ldo.h +43 -0
  185. esphome/components/esphome/ota/ota_esphome.cpp +15 -8
  186. esphome/components/ethernet/ethernet_component.cpp +38 -26
  187. esphome/components/ethernet/ethernet_component.h +1 -1
  188. esphome/components/event/__init__.py +1 -0
  189. esphome/components/exposure_notifications/exposure_notifications.cpp +1 -1
  190. esphome/components/ezo/ezo.cpp +1 -1
  191. esphome/components/ezo_pmp/ezo_pmp.cpp +1 -1
  192. esphome/components/factory_reset/button/factory_reset_button.cpp +1 -1
  193. esphome/components/factory_reset/switch/factory_reset_switch.cpp +1 -1
  194. esphome/components/fan/__init__.py +1 -0
  195. esphome/components/fan/fan.cpp +4 -2
  196. esphome/components/fastled_base/fastled_light.cpp +7 -5
  197. esphome/components/fingerprint_grow/fingerprint_grow.cpp +8 -6
  198. esphome/components/fs3000/fs3000.cpp +1 -1
  199. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +7 -4
  200. esphome/components/ft63x6/ft63x6.cpp +5 -3
  201. esphome/components/gcja5/gcja5.cpp +0 -12
  202. esphome/components/gcja5/gcja5.h +8 -3
  203. esphome/components/gdk101/gdk101.cpp +2 -2
  204. esphome/components/globals/globals_component.h +13 -10
  205. esphome/components/gp2y1010au0f/gp2y1010au0f.cpp +4 -2
  206. esphome/components/gp8403/gp8403.cpp +4 -2
  207. esphome/components/gp8403/output/gp8403_output.cpp +4 -2
  208. esphome/components/gpio/one_wire/gpio_one_wire.cpp +2 -2
  209. esphome/components/gpio/output/gpio_binary_output.cpp +1 -1
  210. esphome/components/gpio/switch/gpio_switch.cpp +1 -1
  211. esphome/components/graphical_display_menu/graphical_display_menu.cpp +12 -8
  212. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -6
  213. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +1 -1
  214. esphome/components/grove_tb6612fng/grove_tb6612fng.h +1 -1
  215. esphome/components/growatt_solar/growatt_solar.cpp +6 -3
  216. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
  217. esphome/components/haier/haier_base.cpp +2 -2
  218. esphome/components/haier/hon_climate.cpp +13 -6
  219. esphome/components/havells_solar/havells_solar.cpp +5 -2
  220. esphome/components/hbridge/switch/hbridge_switch.cpp +1 -1
  221. esphome/components/hdc1080/hdc1080.cpp +2 -2
  222. esphome/components/he60r/he60r.cpp +4 -2
  223. esphome/components/hlw8012/hlw8012.cpp +6 -4
  224. esphome/components/hm3301/hm3301.cpp +2 -2
  225. esphome/components/hmc5883l/hmc5883l.cpp +2 -2
  226. esphome/components/homeassistant/time/homeassistant_time.cpp +4 -2
  227. esphome/components/honeywell_hih_i2c/honeywell_hih.cpp +4 -4
  228. esphome/components/honeywellabp/honeywellabp.cpp +4 -2
  229. esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +8 -6
  230. esphome/components/hte501/hte501.cpp +3 -2
  231. esphome/components/http_request/__init__.py +2 -2
  232. esphome/components/http_request/http_request.cpp +7 -5
  233. esphome/components/http_request/http_request_idf.cpp +4 -2
  234. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  235. esphome/components/htu21d/htu21d.cpp +2 -2
  236. esphome/components/htu31d/htu31d.cpp +2 -2
  237. esphome/components/hx711/hx711.cpp +2 -2
  238. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +5 -3
  239. esphome/components/hyt271/hyt271.cpp +2 -2
  240. esphome/components/i2c/i2c_bus_arduino.cpp +14 -11
  241. esphome/components/i2c/i2c_bus_esp_idf.cpp +13 -11
  242. esphome/components/i2s_audio/__init__.py +2 -0
  243. esphome/components/i2s_audio/i2s_audio.cpp +3 -4
  244. esphome/components/i2s_audio/i2s_audio.h +1 -1
  245. esphome/components/i2s_audio/media_player/__init__.py +1 -1
  246. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +5 -3
  247. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +1 -1
  248. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  249. esphome/components/iaqcore/iaqcore.cpp +3 -3
  250. esphome/components/ili9xxx/ili9xxx_display.cpp +12 -7
  251. esphome/components/ili9xxx/ili9xxx_display.h +1 -1
  252. esphome/components/image/image.cpp +1 -0
  253. esphome/components/ina219/ina219.cpp +2 -2
  254. esphome/components/ina226/ina226.cpp +8 -5
  255. esphome/components/ina260/ina260.cpp +1 -1
  256. esphome/components/ina2xx_base/ina2xx_base.cpp +13 -9
  257. esphome/components/ina3221/ina3221.cpp +2 -2
  258. esphome/components/inkplate6/display.py +12 -2
  259. esphome/components/inkplate6/inkplate.cpp +13 -9
  260. esphome/components/inkplate6/inkplate.h +7 -6
  261. esphome/components/integration/integration_sensor.cpp +1 -1
  262. esphome/components/internal_temperature/internal_temperature.cpp +4 -4
  263. esphome/components/json/json_util.cpp +4 -5
  264. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +1 -1
  265. esphome/components/key_collector/key_collector.cpp +4 -2
  266. esphome/components/kmeteriso/kmeteriso.cpp +2 -1
  267. esphome/components/kuntze/kuntze.cpp +4 -2
  268. esphome/components/lc709203f/__init__.py +1 -0
  269. esphome/components/lc709203f/lc709203f.cpp +299 -0
  270. esphome/components/lc709203f/lc709203f.h +55 -0
  271. esphome/components/lc709203f/sensor.py +93 -0
  272. esphome/components/lcd_base/lcd_display.cpp +2 -2
  273. esphome/components/lcd_gpio/gpio_lcd_display.cpp +5 -3
  274. esphome/components/lcd_menu/lcd_menu.cpp +6 -4
  275. esphome/components/lcd_pcf8574/pcf8574_display.cpp +6 -4
  276. esphome/components/ld2410/ld2410.cpp +6 -7
  277. esphome/components/ld2420/ld2420.cpp +9 -7
  278. esphome/components/ld2450/ld2450.cpp +6 -4
  279. esphome/components/ld2450/sensor.py +2 -2
  280. esphome/components/ledc/ledc_output.cpp +32 -28
  281. esphome/components/libretiny/const.py +1 -1
  282. esphome/components/libretiny/preferences.cpp +6 -7
  283. esphome/components/light/__init__.py +2 -1
  284. esphome/components/light/esp_hsv_color.h +1 -1
  285. esphome/components/light/light_state.cpp +9 -5
  286. esphome/components/light/light_transformer.h +1 -1
  287. esphome/components/lightwaverf/LwTx.cpp +1 -1
  288. esphome/components/lightwaverf/lightwaverf.cpp +1 -1
  289. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +1 -1
  290. esphome/components/lock/__init__.py +1 -0
  291. esphome/components/lock/lock.h +1 -1
  292. esphome/components/logger/__init__.py +6 -0
  293. esphome/components/logger/logger.cpp +9 -5
  294. esphome/components/logger/logger_esp32.cpp +5 -5
  295. esphome/components/ltr390/ltr390.cpp +8 -5
  296. esphome/components/ltr501/ltr501.cpp +19 -14
  297. esphome/components/ltr_als_ps/ltr_als_ps.cpp +20 -13
  298. esphome/components/lvgl/__init__.py +2 -2
  299. esphome/components/lvgl/automation.py +5 -4
  300. esphome/components/lvgl/defines.py +0 -2
  301. esphome/components/lvgl/lv_validation.py +1 -3
  302. esphome/components/lvgl/lvcode.py +7 -8
  303. esphome/components/lvgl/lvgl_esphome.cpp +26 -10
  304. esphome/components/lvgl/schemas.py +22 -23
  305. esphome/components/lvgl/trigger.py +8 -3
  306. esphome/components/lvgl/widgets/__init__.py +2 -2
  307. esphome/components/lvgl/widgets/canvas.py +9 -3
  308. esphome/components/lvgl/widgets/line.py +2 -1
  309. esphome/components/lvgl/widgets/tabview.py +7 -0
  310. esphome/components/m5stack_8angle/m5stack_8angle.cpp +3 -3
  311. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -2
  312. esphome/components/max17043/max17043.cpp +2 -2
  313. esphome/components/max31855/max31855.cpp +2 -1
  314. esphome/components/max31856/max31856.cpp +9 -11
  315. esphome/components/max31865/max31865.cpp +6 -4
  316. esphome/components/max44009/max44009.cpp +2 -2
  317. esphome/components/max6675/max6675.cpp +1 -1
  318. esphome/components/max6956/max6956.cpp +5 -3
  319. esphome/components/max7219/max7219.cpp +8 -6
  320. esphome/components/max7219digit/automation.h +52 -0
  321. esphome/components/max7219digit/display.py +93 -1
  322. esphome/components/max7219digit/max7219digit.cpp +16 -13
  323. esphome/components/max9611/max9611.cpp +9 -6
  324. esphome/components/mcp23008/mcp23008.cpp +1 -1
  325. esphome/components/mcp23016/mcp23016.cpp +1 -1
  326. esphome/components/mcp23017/mcp23017.cpp +1 -1
  327. esphome/components/mcp23s08/mcp23s08.cpp +1 -1
  328. esphome/components/mcp23s17/mcp23s17.cpp +1 -1
  329. esphome/components/mcp3008/mcp3008.cpp +1 -1
  330. esphome/components/mcp3008/sensor/mcp3008_sensor.cpp +5 -3
  331. esphome/components/mcp3204/mcp3204.cpp +1 -1
  332. esphome/components/mcp4461/mcp4461.cpp +2 -2
  333. esphome/components/mcp4725/mcp4725.cpp +2 -2
  334. esphome/components/mcp4728/mcp4728.cpp +2 -2
  335. esphome/components/mcp9600/mcp9600.cpp +1 -1
  336. esphome/components/mcp9808/mcp9808.cpp +4 -4
  337. esphome/components/mdns/mdns_component.cpp +8 -2
  338. esphome/components/mdns/mdns_component.h +3 -1
  339. esphome/components/mdns/mdns_esp32.cpp +2 -2
  340. esphome/components/media_player/__init__.py +1 -0
  341. esphome/components/micro_wake_word/micro_wake_word.cpp +1 -1
  342. esphome/components/micro_wake_word/streaming_model.cpp +10 -6
  343. esphome/components/micronova/micronova.h +2 -2
  344. esphome/components/mics_4514/mics_4514.cpp +2 -2
  345. esphome/components/midea/air_conditioner.cpp +7 -5
  346. esphome/components/midea_ir/midea_ir.cpp +1 -1
  347. esphome/components/mipi_spi/mipi_spi.cpp +24 -15
  348. esphome/components/mixer/speaker/mixer_speaker.cpp +8 -4
  349. esphome/components/mlx90393/sensor_mlx90393.cpp +2 -2
  350. esphome/components/mlx90614/mlx90614.cpp +4 -3
  351. esphome/components/mmc5603/mmc5603.cpp +2 -2
  352. esphome/components/mmc5983/mmc5983.cpp +1 -1
  353. esphome/components/modbus/modbus.cpp +7 -5
  354. esphome/components/modbus_controller/modbus_controller.cpp +6 -4
  355. esphome/components/modbus_controller/output/modbus_output.cpp +10 -6
  356. esphome/components/modbus_controller/switch/__init__.py +6 -2
  357. esphome/components/modbus_controller/switch/modbus_switch.cpp +4 -0
  358. esphome/components/modbus_controller/switch/modbus_switch.h +3 -0
  359. esphome/components/mpl3115a2/mpl3115a2.cpp +3 -2
  360. esphome/components/mpr121/mpr121.cpp +2 -2
  361. esphome/components/mpu6050/mpu6050.cpp +6 -6
  362. esphome/components/mpu6886/mpu6886.cpp +6 -6
  363. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +7 -3
  364. esphome/components/mqtt/mqtt_backend_esp32.cpp +1 -1
  365. esphome/components/mqtt/mqtt_client.cpp +31 -24
  366. esphome/components/mqtt/mqtt_component.cpp +2 -2
  367. esphome/components/mqtt/mqtt_cover.cpp +8 -4
  368. esphome/components/mqtt/mqtt_fan.cpp +12 -6
  369. esphome/components/mqtt/mqtt_valve.cpp +4 -2
  370. esphome/components/ms5611/ms5611.cpp +2 -2
  371. esphome/components/ms8607/ms8607.cpp +2 -2
  372. esphome/components/msa3xx/msa3xx.cpp +16 -12
  373. esphome/components/my9231/my9231.cpp +7 -5
  374. esphome/components/nau7802/nau7802.cpp +6 -4
  375. esphome/components/neopixelbus/neopixelbus_light.h +2 -2
  376. esphome/components/network/ip_address.h +1 -1
  377. esphome/components/network/util.cpp +13 -0
  378. esphome/components/nextion/base_component.py +2 -0
  379. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +2 -3
  380. esphome/components/nextion/display.py +34 -22
  381. esphome/components/nextion/nextion.cpp +182 -143
  382. esphome/components/nextion/nextion.h +36 -0
  383. esphome/components/nextion/nextion_commands.cpp +3 -3
  384. esphome/components/nextion/nextion_upload_arduino.cpp +58 -61
  385. esphome/components/nextion/nextion_upload_idf.cpp +69 -72
  386. esphome/components/nextion/sensor/nextion_sensor.cpp +4 -4
  387. esphome/components/nextion/switch/nextion_switch.cpp +2 -2
  388. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +2 -2
  389. esphome/components/nfc/nci_message.h +1 -1
  390. esphome/components/nfc/ndef_record.h +1 -1
  391. esphome/components/nfc/ndef_record_text.h +1 -1
  392. esphome/components/nfc/ndef_record_uri.h +1 -1
  393. esphome/components/nfc/nfc.h +1 -1
  394. esphome/components/nfc/nfc_tag.h +1 -1
  395. esphome/components/noblex/noblex.cpp +1 -1
  396. esphome/components/npi19/npi19.cpp +5 -7
  397. esphome/components/number/__init__.py +11 -0
  398. esphome/components/online_image/__init__.py +13 -1
  399. esphome/components/online_image/online_image.cpp +26 -4
  400. esphome/components/online_image/online_image.h +21 -4
  401. esphome/components/opentherm/generate.py +3 -3
  402. esphome/components/opentherm/hub.cpp +11 -7
  403. esphome/components/opentherm/number/number.cpp +5 -3
  404. esphome/components/opentherm/opentherm.h +1 -1
  405. esphome/components/opentherm/schema.py +13 -13
  406. esphome/components/opentherm/validate.py +1 -1
  407. esphome/components/openthread/__init__.py +146 -0
  408. esphome/components/openthread/const.py +10 -0
  409. esphome/components/openthread/openthread.cpp +206 -0
  410. esphome/components/openthread/openthread.h +68 -0
  411. esphome/components/openthread/openthread_esp.cpp +164 -0
  412. esphome/components/openthread/tlv.py +58 -0
  413. esphome/components/openthread_info/__init__.py +0 -0
  414. esphome/components/openthread_info/openthread_info_text_sensor.cpp +24 -0
  415. esphome/components/openthread_info/openthread_info_text_sensor.h +218 -0
  416. esphome/components/openthread_info/text_sensor.py +105 -0
  417. esphome/components/output/float_output.cpp +1 -1
  418. esphome/components/output/switch/output_switch.cpp +1 -1
  419. esphome/components/packet_transport/packet_transport.cpp +6 -4
  420. esphome/components/pca6416a/pca6416a.cpp +2 -2
  421. esphome/components/pca9554/pca9554.cpp +6 -4
  422. esphome/components/pca9685/pca9685_output.cpp +12 -8
  423. esphome/components/pcd8544/pcd_8544.cpp +1 -1
  424. esphome/components/pcf85063/pcf85063.cpp +2 -2
  425. esphome/components/pcf8563/pcf8563.cpp +2 -2
  426. esphome/components/pcf8574/pcf8574.cpp +2 -2
  427. esphome/components/pid/pid_climate.cpp +8 -5
  428. esphome/components/pid/pid_climate.h +1 -1
  429. esphome/components/pid/sensor/pid_climate_sensor.cpp +1 -1
  430. esphome/components/pipsolar/output/pipsolar_output.cpp +1 -1
  431. esphome/components/pipsolar/pipsolar.cpp +3 -3
  432. esphome/components/pm1006/pm1006.cpp +3 -7
  433. esphome/components/pm1006/pm1006.h +4 -1
  434. esphome/components/pm2005/pm2005.cpp +12 -13
  435. esphome/components/pm2005/sensor.py +1 -1
  436. esphome/components/pmsa003i/pmsa003i.cpp +2 -2
  437. esphome/components/pmsx003/pmsx003.cpp +0 -4
  438. esphome/components/pmsx003/pmsx003.h +5 -2
  439. esphome/components/pmwcs3/pmwcs3.cpp +9 -13
  440. esphome/components/pmwcs3/pmwcs3.h +0 -1
  441. esphome/components/pn532/pn532.cpp +7 -7
  442. esphome/components/pn532/pn532.h +1 -1
  443. esphome/components/pn532_spi/pn532_spi.cpp +1 -1
  444. esphome/components/pn7150/pn7150.cpp +4 -4
  445. esphome/components/pn7160/pn7160.cpp +4 -4
  446. esphome/components/power_supply/power_supply.cpp +6 -4
  447. esphome/components/power_supply/power_supply.h +1 -1
  448. esphome/components/psram/__init__.py +59 -35
  449. esphome/components/pulse_counter/pulse_counter_sensor.cpp +7 -4
  450. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +8 -5
  451. esphome/components/pylontech/pylontech.cpp +2 -2
  452. esphome/components/pylontech/sensor/pylontech_sensor.cpp +4 -2
  453. esphome/components/pylontech/text_sensor/pylontech_text_sensor.cpp +4 -2
  454. esphome/components/pzemac/pzemac.cpp +4 -2
  455. esphome/components/pzemdc/pzemdc.cpp +4 -2
  456. esphome/components/qmc5883l/qmc5883l.cpp +2 -2
  457. esphome/components/qmp6988/qmp6988.cpp +2 -2
  458. esphome/components/qmp6988/qmp6988.h +1 -1
  459. esphome/components/qr_code/qr_code.cpp +5 -3
  460. esphome/components/qspi_dbi/qspi_dbi.cpp +1 -1
  461. esphome/components/qwiic_pir/qwiic_pir.cpp +26 -28
  462. esphome/components/rc522/rc522.cpp +5 -5
  463. esphome/components/rdm6300/rdm6300.cpp +1 -0
  464. esphome/components/remote_receiver/__init__.py +10 -2
  465. esphome/components/remote_receiver/remote_receiver_esp32.cpp +22 -12
  466. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +10 -7
  467. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +10 -7
  468. esphome/components/remote_transmitter/__init__.py +10 -2
  469. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +10 -6
  470. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +5 -3
  471. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +5 -3
  472. esphome/components/resistance/resistance_sensor.cpp +6 -3
  473. esphome/components/restart/button/restart_button.cpp +1 -1
  474. esphome/components/restart/switch/restart_switch.cpp +1 -1
  475. esphome/components/rotary_encoder/rotary_encoder.cpp +2 -2
  476. esphome/components/rp2040/__init__.py +7 -0
  477. esphome/components/rp2040/core.cpp +8 -1
  478. esphome/components/rp2040/preferences.cpp +3 -3
  479. esphome/components/rp2040_pio_led_strip/led_strip.cpp +11 -8
  480. esphome/components/rp2040_pio_led_strip/light.py +1 -1
  481. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -1
  482. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +1 -1
  483. esphome/components/rtttl/rtttl.cpp +11 -9
  484. esphome/components/safe_mode/button/safe_mode_button.cpp +1 -1
  485. esphome/components/safe_mode/safe_mode.cpp +9 -8
  486. esphome/components/safe_mode/switch/safe_mode_switch.cpp +1 -1
  487. esphome/components/scd30/scd30.cpp +11 -8
  488. esphome/components/scd4x/scd4x.cpp +12 -8
  489. esphome/components/sdl/display.py +40 -0
  490. esphome/components/sdl/sdl_esphome.cpp +2 -2
  491. esphome/components/sdl/sdl_esphome.h +8 -0
  492. esphome/components/sdm_meter/sdm_meter.cpp +5 -2
  493. esphome/components/sdp3x/sdp3x.cpp +11 -11
  494. esphome/components/sds011/sds011.cpp +5 -6
  495. esphome/components/sds011/sds011.h +4 -1
  496. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +3 -2
  497. esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +1 -0
  498. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +3 -2
  499. esphome/components/selec_meter/selec_meter.cpp +5 -2
  500. esphome/components/select/__init__.py +1 -0
  501. esphome/components/sen0321/sen0321.cpp +2 -2
  502. esphome/components/sen21231/sen21231.cpp +1 -1
  503. esphome/components/sen5x/sen5x.cpp +10 -7
  504. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  505. esphome/components/sensirion_common/i2c_sensirion.h +1 -0
  506. esphome/components/sensor/__init__.py +11 -1
  507. esphome/components/sensor/filter.h +1 -1
  508. esphome/components/sensor/sensor.h +9 -5
  509. esphome/components/servo/servo.cpp +12 -9
  510. esphome/components/servo/servo.h +1 -1
  511. esphome/components/sfa30/sfa30.cpp +1 -1
  512. esphome/components/sgp30/sgp30.cpp +10 -8
  513. esphome/components/sgp4x/sgp4x.cpp +49 -61
  514. esphome/components/sgp4x/sgp4x.h +0 -1
  515. esphome/components/shelly_dimmer/shelly_dimmer.cpp +11 -7
  516. esphome/components/sht3xd/sht3xd.cpp +1 -1
  517. esphome/components/sht4x/sht4x.cpp +2 -2
  518. esphome/components/shtcx/shtcx.cpp +13 -16
  519. esphome/components/shutdown/button/shutdown_button.cpp +1 -1
  520. esphome/components/shutdown/switch/shutdown_switch.cpp +1 -1
  521. esphome/components/sim800l/sim800l.cpp +2 -2
  522. esphome/components/slow_pwm/slow_pwm_output.cpp +4 -2
  523. esphome/components/sm16716/sm16716.cpp +1 -1
  524. esphome/components/sm2135/sm2135.cpp +1 -1
  525. esphome/components/sm2235/sm2235.cpp +5 -3
  526. esphome/components/sm2335/sm2335.cpp +5 -3
  527. esphome/components/sml/sml.cpp +1 -1
  528. esphome/components/sn74hc165/sn74hc165.cpp +1 -2
  529. esphome/components/sn74hc595/sn74hc595.cpp +1 -2
  530. esphome/components/sntp/sntp_component.cpp +1 -1
  531. esphome/components/socket/__init__.py +2 -0
  532. esphome/components/socket/bsd_sockets_impl.cpp +51 -7
  533. esphome/components/socket/lwip_raw_tcp_impl.cpp +5 -0
  534. esphome/components/socket/lwip_sockets_impl.cpp +51 -7
  535. esphome/components/socket/socket.cpp +31 -0
  536. esphome/components/socket/socket.h +27 -1
  537. esphome/components/sonoff_d1/sonoff_d1.cpp +7 -4
  538. esphome/components/sonoff_d1/sonoff_d1.h +2 -2
  539. esphome/components/sound_level/sound_level.cpp +4 -2
  540. esphome/components/speaker/media_player/__init__.py +3 -0
  541. esphome/components/speaker/media_player/speaker_media_player.cpp +1 -3
  542. esphome/components/speaker/media_player/speaker_media_player.h +6 -0
  543. esphome/components/spi/__init__.py +10 -2
  544. esphome/components/spi/spi.cpp +4 -4
  545. esphome/components/spi_device/spi_device.cpp +1 -2
  546. esphome/components/sprinkler/sprinkler.cpp +9 -6
  547. esphome/components/sps30/sps30.cpp +16 -15
  548. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  549. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +11 -8
  550. esphome/components/ssd1306_spi/ssd1306_spi.cpp +10 -7
  551. esphome/components/ssd1322_base/ssd1322_base.cpp +1 -1
  552. esphome/components/ssd1322_spi/ssd1322_spi.cpp +1 -1
  553. esphome/components/ssd1325_base/ssd1325_base.cpp +1 -1
  554. esphome/components/ssd1325_spi/ssd1325_spi.cpp +1 -1
  555. esphome/components/ssd1327_base/ssd1327_base.cpp +1 -1
  556. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +2 -2
  557. esphome/components/ssd1327_spi/ssd1327_spi.cpp +1 -1
  558. esphome/components/ssd1331_base/ssd1331_base.cpp +1 -1
  559. esphome/components/ssd1331_spi/ssd1331_spi.cpp +1 -1
  560. esphome/components/ssd1351_base/ssd1351_base.cpp +1 -1
  561. esphome/components/ssd1351_spi/ssd1351_spi.cpp +1 -1
  562. esphome/components/st7567_base/st7567_base.cpp +3 -3
  563. esphome/components/st7567_i2c/st7567_i2c.cpp +7 -5
  564. esphome/components/st7567_spi/st7567_spi.cpp +1 -1
  565. esphome/components/st7701s/st7701s.cpp +4 -2
  566. esphome/components/st7735/st7735.cpp +3 -3
  567. esphome/components/st7789v/st7789v.cpp +10 -7
  568. esphome/components/st7920/st7920.cpp +6 -4
  569. esphome/components/statsd/statsd.cpp +9 -5
  570. esphome/components/status_led/light/status_led_light.cpp +1 -1
  571. esphome/components/status_led/status_led.cpp +1 -1
  572. esphome/components/stepper/stepper.h +5 -3
  573. esphome/components/sts3x/sts3x.cpp +2 -2
  574. esphome/components/switch/__init__.py +1 -0
  575. esphome/components/switch/switch.cpp +18 -12
  576. esphome/components/switch/switch.h +1 -1
  577. esphome/components/sx1509/__init__.py +53 -20
  578. esphome/components/sx1509/sx1509.cpp +29 -5
  579. esphome/components/sx1509/sx1509.h +9 -1
  580. esphome/components/t6615/t6615.cpp +1 -0
  581. esphome/components/tc74/tc74.cpp +1 -1
  582. esphome/components/tca9548a/tca9548a.cpp +1 -1
  583. esphome/components/tca9555/tca9555.cpp +2 -2
  584. esphome/components/tcs34725/tcs34725.cpp +4 -4
  585. esphome/components/tee501/tee501.cpp +3 -2
  586. esphome/components/tem3200/tem3200.cpp +5 -6
  587. esphome/components/template/alarm_control_panel/__init__.py +6 -0
  588. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +38 -12
  589. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +3 -1
  590. esphome/components/template/cover/template_cover.cpp +1 -1
  591. esphome/components/template/select/template_select.cpp +6 -4
  592. esphome/components/template/text/template_text.cpp +2 -3
  593. esphome/components/template/valve/template_valve.cpp +5 -3
  594. esphome/components/text/__init__.py +10 -11
  595. esphome/components/text_sensor/__init__.py +1 -0
  596. esphome/components/thermostat/thermostat_climate.cpp +67 -43
  597. esphome/components/time/__init__.py +1 -2
  598. esphome/components/time_based/time_based_cover.cpp +4 -2
  599. esphome/components/tlc59208f/tlc59208f_output.cpp +8 -6
  600. esphome/components/tm1621/tm1621.cpp +3 -3
  601. esphome/components/tm1637/tm1637.cpp +9 -7
  602. esphome/components/tm1638/tm1638.cpp +7 -5
  603. esphome/components/tm1651/tm1651.cpp +2 -2
  604. esphome/components/tmp102/tmp102.cpp +1 -3
  605. esphome/components/tmp102/tmp102.h +0 -3
  606. esphome/components/tmp1075/tmp1075.cpp +12 -9
  607. esphome/components/tmp117/tmp117.cpp +2 -2
  608. esphome/components/tof10120/tof10120_sensor.cpp +2 -2
  609. esphome/components/tormatic/tormatic_cover.cpp +4 -2
  610. esphome/components/tsl2561/tsl2561.cpp +7 -5
  611. esphome/components/tsl2591/tsl2591.cpp +25 -27
  612. esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
  613. esphome/components/ttp229_bsf/ttp229_bsf.cpp +1 -1
  614. esphome/components/ttp229_lsf/ttp229_lsf.cpp +2 -2
  615. esphome/components/tuya/select/tuya_select.cpp +5 -3
  616. esphome/components/tx20/tx20.cpp +3 -3
  617. esphome/components/uart/__init__.py +4 -5
  618. esphome/components/uart/button/uart_button.cpp +1 -1
  619. esphome/components/uart/switch/uart_switch.cpp +2 -2
  620. esphome/components/uart/uart.cpp +2 -2
  621. esphome/components/uart/uart_component_esp32_arduino.cpp +8 -6
  622. esphome/components/uart/uart_component_esp8266.cpp +9 -7
  623. esphome/components/uart/uart_component_esp_idf.cpp +9 -7
  624. esphome/components/uart/uart_component_host.cpp +11 -8
  625. esphome/components/uart/uart_component_libretiny.cpp +8 -6
  626. esphome/components/uart/uart_component_rp2040.cpp +8 -6
  627. esphome/components/udp/udp_component.cpp +9 -5
  628. esphome/components/ufire_ec/ufire_ec.cpp +5 -3
  629. esphome/components/ufire_ise/ufire_ise.cpp +1 -1
  630. esphome/components/ultrasonic/ultrasonic_sensor.cpp +5 -3
  631. esphome/components/update/__init__.py +1 -0
  632. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  633. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +4 -2
  634. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  635. esphome/components/usb_host/__init__.py +64 -0
  636. esphome/components/usb_host/usb_host.h +116 -0
  637. esphome/components/usb_host/usb_host_client.cpp +394 -0
  638. esphome/components/usb_host/usb_host_component.cpp +35 -0
  639. esphome/components/usb_uart/__init__.py +134 -0
  640. esphome/components/usb_uart/ch34x.cpp +80 -0
  641. esphome/components/usb_uart/cp210x.cpp +126 -0
  642. esphome/components/usb_uart/usb_uart.cpp +328 -0
  643. esphome/components/usb_uart/usb_uart.h +151 -0
  644. esphome/components/valve/__init__.py +1 -0
  645. esphome/components/veml3235/veml3235.cpp +13 -9
  646. esphome/components/veml7700/veml7700.cpp +10 -6
  647. esphome/components/voice_assistant/voice_assistant.cpp +7 -7
  648. esphome/components/wake_on_lan/wake_on_lan.cpp +1 -1
  649. esphome/components/waveshare_epaper/waveshare_epaper.cpp +1 -1
  650. esphome/components/web_server/server_index_v2.h +632 -630
  651. esphome/components/web_server/server_index_v3.h +411 -409
  652. esphome/components/web_server/web_server.cpp +5 -3
  653. esphome/components/web_server_base/web_server_base.cpp +1 -1
  654. esphome/components/web_server_idf/utils.cpp +1 -1
  655. esphome/components/web_server_idf/web_server_idf.cpp +1 -1
  656. esphome/components/weikai/__init__.py +2 -0
  657. esphome/components/weikai/weikai.cpp +23 -21
  658. esphome/components/weikai_i2c/weikai_i2c.cpp +14 -9
  659. esphome/components/weikai_spi/weikai_spi.cpp +11 -6
  660. esphome/components/wiegand/wiegand.cpp +1 -1
  661. esphome/components/wifi/wifi_component.cpp +50 -37
  662. esphome/components/wifi/wifi_component.h +7 -4
  663. esphome/components/wifi/wifi_component_esp32_arduino.cpp +2 -2
  664. esphome/components/wifi/wifi_component_esp8266.cpp +3 -3
  665. esphome/components/wifi/wifi_component_libretiny.cpp +4 -4
  666. esphome/components/wireguard/wireguard.cpp +21 -21
  667. esphome/components/wl_134/text_sensor.py +1 -2
  668. esphome/components/wled/wled_light_effect.cpp +1 -1
  669. esphome/components/x9c/x9c.cpp +5 -3
  670. esphome/components/xgzp68xx/xgzp68xx.cpp +8 -6
  671. esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp +4 -2
  672. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.cpp +4 -2
  673. esphome/components/xiaomi_cgg1/xiaomi_cgg1.cpp +4 -2
  674. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.cpp +1 -1
  675. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp +4 -2
  676. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp +4 -2
  677. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.cpp +4 -2
  678. esphome/components/xl9535/xl9535.cpp +2 -2
  679. esphome/components/xpt2046/touchscreen/xpt2046.cpp +12 -11
  680. esphome/components/xpt2046/touchscreen/xpt2046.h +2 -2
  681. esphome/config.py +3 -2
  682. esphome/config_validation.py +46 -17
  683. esphome/const.py +10 -1
  684. esphome/core/__init__.py +37 -18
  685. esphome/core/application.cpp +188 -5
  686. esphome/core/application.h +110 -0
  687. esphome/core/component.h +13 -0
  688. esphome/core/config.py +12 -0
  689. esphome/core/defines.h +10 -2
  690. esphome/core/helpers.cpp +1 -1
  691. esphome/core/helpers.h +4 -4
  692. esphome/core/log.h +2 -0
  693. esphome/core/log_const_en.h +4 -0
  694. esphome/core/scheduler.cpp +2 -2
  695. esphome/coroutine.py +3 -4
  696. esphome/cpp_generator.py +32 -32
  697. esphome/dashboard/core.py +2 -2
  698. esphome/dashboard/web_server.py +2 -2
  699. esphome/git.py +4 -4
  700. esphome/helpers.py +5 -6
  701. esphome/loader.py +8 -7
  702. esphome/log.py +7 -1
  703. esphome/platformio_api.py +2 -3
  704. esphome/storage_json.py +13 -5
  705. esphome/types.py +12 -13
  706. esphome/util.py +1 -2
  707. esphome/writer.py +5 -3
  708. esphome/yaml_util.py +6 -1
  709. esphome/zeroconf.py +1 -1
  710. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/METADATA +12 -11
  711. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/RECORD +715 -662
  712. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/WHEEL +1 -1
  713. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/entry_points.txt +0 -0
  714. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/licenses/LICENSE +0 -0
  715. {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/top_level.txt +0 -0
@@ -11,6 +11,7 @@
11
11
  #include "esphome/core/entity_base.h"
12
12
 
13
13
  #include <vector>
14
+ #include <functional>
14
15
 
15
16
  namespace esphome {
16
17
  namespace api {
@@ -18,49 +19,9 @@ namespace api {
18
19
  // Keepalive timeout in milliseconds
19
20
  static constexpr uint32_t KEEPALIVE_TIMEOUT_MS = 60000;
20
21
 
21
- using send_message_t = bool (APIConnection::*)(void *);
22
-
23
- /*
24
- This class holds a pointer to the source component that wants to publish a message, and a pointer to a function that
25
- will lazily publish that message. The two pointers allow dedup in the deferred queue if multiple publishes for the
26
- same component are backed up, and take up only 8 bytes of memory. The entry in the deferred queue (a std::vector) is
27
- the DeferredMessage instance itself (not a pointer to one elsewhere in heap) so still only 8 bytes per entry. Even
28
- 100 backed up messages (you'd have to have at least 100 sensors publishing because of dedup) would take up only 0.8
29
- kB.
30
- */
31
- class DeferredMessageQueue {
32
- struct DeferredMessage {
33
- friend class DeferredMessageQueue;
34
-
35
- protected:
36
- void *source_;
37
- send_message_t send_message_;
38
-
39
- public:
40
- DeferredMessage(void *source, send_message_t send_message) : source_(source), send_message_(send_message) {}
41
- bool operator==(const DeferredMessage &test) const {
42
- return (source_ == test.source_ && send_message_ == test.send_message_);
43
- }
44
- } __attribute__((packed));
45
-
46
- protected:
47
- // vector is used very specifically for its zero memory overhead even though items are popped from the front (memory
48
- // footprint is more important than speed here)
49
- std::vector<DeferredMessage> deferred_queue_;
50
- APIConnection *api_connection_;
51
-
52
- // helper for allowing only unique entries in the queue
53
- void dmq_push_back_with_dedup_(void *source, send_message_t send_message);
54
-
55
- public:
56
- DeferredMessageQueue(APIConnection *api_connection) : api_connection_(api_connection) {}
57
- void process_queue();
58
- void defer(void *source, send_message_t send_message);
59
- bool empty() const { return deferred_queue_.empty(); }
60
- };
61
-
62
22
  class APIConnection : public APIServerConnection {
63
23
  public:
24
+ friend class APIServer;
64
25
  APIConnection(std::unique_ptr<socket::Socket> socket, APIServer *parent);
65
26
  virtual ~APIConnection();
66
27
 
@@ -68,225 +29,105 @@ class APIConnection : public APIServerConnection {
68
29
  void loop();
69
30
 
70
31
  bool send_list_info_done() {
71
- ListEntitiesDoneResponse resp;
72
- return this->send_list_entities_done_response(resp);
32
+ return this->schedule_message_(nullptr, &APIConnection::try_send_list_info_done,
33
+ ListEntitiesDoneResponse::MESSAGE_TYPE);
73
34
  }
74
35
  #ifdef USE_BINARY_SENSOR
75
- bool send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor, bool state);
36
+ bool send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor);
76
37
  void send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor);
77
-
78
- protected:
79
- bool try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor);
80
- bool try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor, bool state);
81
- bool try_send_binary_sensor_info_(binary_sensor::BinarySensor *binary_sensor);
82
-
83
- public:
84
38
  #endif
85
39
  #ifdef USE_COVER
86
40
  bool send_cover_state(cover::Cover *cover);
87
41
  void send_cover_info(cover::Cover *cover);
88
42
  void cover_command(const CoverCommandRequest &msg) override;
89
-
90
- protected:
91
- bool try_send_cover_state_(cover::Cover *cover);
92
- bool try_send_cover_info_(cover::Cover *cover);
93
-
94
- public:
95
43
  #endif
96
44
  #ifdef USE_FAN
97
45
  bool send_fan_state(fan::Fan *fan);
98
46
  void send_fan_info(fan::Fan *fan);
99
47
  void fan_command(const FanCommandRequest &msg) override;
100
-
101
- protected:
102
- bool try_send_fan_state_(fan::Fan *fan);
103
- bool try_send_fan_info_(fan::Fan *fan);
104
-
105
- public:
106
48
  #endif
107
49
  #ifdef USE_LIGHT
108
50
  bool send_light_state(light::LightState *light);
109
51
  void send_light_info(light::LightState *light);
110
52
  void light_command(const LightCommandRequest &msg) override;
111
-
112
- protected:
113
- bool try_send_light_state_(light::LightState *light);
114
- bool try_send_light_info_(light::LightState *light);
115
-
116
- public:
117
53
  #endif
118
54
  #ifdef USE_SENSOR
119
- bool send_sensor_state(sensor::Sensor *sensor, float state);
55
+ bool send_sensor_state(sensor::Sensor *sensor);
120
56
  void send_sensor_info(sensor::Sensor *sensor);
121
-
122
- protected:
123
- bool try_send_sensor_state_(sensor::Sensor *sensor);
124
- bool try_send_sensor_state_(sensor::Sensor *sensor, float state);
125
- bool try_send_sensor_info_(sensor::Sensor *sensor);
126
-
127
- public:
128
57
  #endif
129
58
  #ifdef USE_SWITCH
130
- bool send_switch_state(switch_::Switch *a_switch, bool state);
59
+ bool send_switch_state(switch_::Switch *a_switch);
131
60
  void send_switch_info(switch_::Switch *a_switch);
132
61
  void switch_command(const SwitchCommandRequest &msg) override;
133
-
134
- protected:
135
- bool try_send_switch_state_(switch_::Switch *a_switch);
136
- bool try_send_switch_state_(switch_::Switch *a_switch, bool state);
137
- bool try_send_switch_info_(switch_::Switch *a_switch);
138
-
139
- public:
140
62
  #endif
141
63
  #ifdef USE_TEXT_SENSOR
142
- bool send_text_sensor_state(text_sensor::TextSensor *text_sensor, std::string state);
64
+ bool send_text_sensor_state(text_sensor::TextSensor *text_sensor);
143
65
  void send_text_sensor_info(text_sensor::TextSensor *text_sensor);
144
-
145
- protected:
146
- bool try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor);
147
- bool try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor, std::string state);
148
- bool try_send_text_sensor_info_(text_sensor::TextSensor *text_sensor);
149
-
150
- public:
151
66
  #endif
152
67
  #ifdef USE_ESP32_CAMERA
153
68
  void set_camera_state(std::shared_ptr<esp32_camera::CameraImage> image);
154
69
  void send_camera_info(esp32_camera::ESP32Camera *camera);
155
70
  void camera_image(const CameraImageRequest &msg) override;
156
-
157
- protected:
158
- bool try_send_camera_info_(esp32_camera::ESP32Camera *camera);
159
-
160
- public:
161
71
  #endif
162
72
  #ifdef USE_CLIMATE
163
73
  bool send_climate_state(climate::Climate *climate);
164
74
  void send_climate_info(climate::Climate *climate);
165
75
  void climate_command(const ClimateCommandRequest &msg) override;
166
-
167
- protected:
168
- bool try_send_climate_state_(climate::Climate *climate);
169
- bool try_send_climate_info_(climate::Climate *climate);
170
-
171
- public:
172
76
  #endif
173
77
  #ifdef USE_NUMBER
174
- bool send_number_state(number::Number *number, float state);
78
+ bool send_number_state(number::Number *number);
175
79
  void send_number_info(number::Number *number);
176
80
  void number_command(const NumberCommandRequest &msg) override;
177
-
178
- protected:
179
- bool try_send_number_state_(number::Number *number);
180
- bool try_send_number_state_(number::Number *number, float state);
181
- bool try_send_number_info_(number::Number *number);
182
-
183
- public:
184
81
  #endif
185
82
  #ifdef USE_DATETIME_DATE
186
83
  bool send_date_state(datetime::DateEntity *date);
187
84
  void send_date_info(datetime::DateEntity *date);
188
85
  void date_command(const DateCommandRequest &msg) override;
189
-
190
- protected:
191
- bool try_send_date_state_(datetime::DateEntity *date);
192
- bool try_send_date_info_(datetime::DateEntity *date);
193
-
194
- public:
195
86
  #endif
196
87
  #ifdef USE_DATETIME_TIME
197
88
  bool send_time_state(datetime::TimeEntity *time);
198
89
  void send_time_info(datetime::TimeEntity *time);
199
90
  void time_command(const TimeCommandRequest &msg) override;
200
-
201
- protected:
202
- bool try_send_time_state_(datetime::TimeEntity *time);
203
- bool try_send_time_info_(datetime::TimeEntity *time);
204
-
205
- public:
206
91
  #endif
207
92
  #ifdef USE_DATETIME_DATETIME
208
93
  bool send_datetime_state(datetime::DateTimeEntity *datetime);
209
94
  void send_datetime_info(datetime::DateTimeEntity *datetime);
210
95
  void datetime_command(const DateTimeCommandRequest &msg) override;
211
-
212
- protected:
213
- bool try_send_datetime_state_(datetime::DateTimeEntity *datetime);
214
- bool try_send_datetime_info_(datetime::DateTimeEntity *datetime);
215
-
216
- public:
217
96
  #endif
218
97
  #ifdef USE_TEXT
219
- bool send_text_state(text::Text *text, std::string state);
98
+ bool send_text_state(text::Text *text);
220
99
  void send_text_info(text::Text *text);
221
100
  void text_command(const TextCommandRequest &msg) override;
222
-
223
- protected:
224
- bool try_send_text_state_(text::Text *text);
225
- bool try_send_text_state_(text::Text *text, std::string state);
226
- bool try_send_text_info_(text::Text *text);
227
-
228
- public:
229
101
  #endif
230
102
  #ifdef USE_SELECT
231
- bool send_select_state(select::Select *select, std::string state);
103
+ bool send_select_state(select::Select *select);
232
104
  void send_select_info(select::Select *select);
233
105
  void select_command(const SelectCommandRequest &msg) override;
234
-
235
- protected:
236
- bool try_send_select_state_(select::Select *select);
237
- bool try_send_select_state_(select::Select *select, std::string state);
238
- bool try_send_select_info_(select::Select *select);
239
-
240
- public:
241
106
  #endif
242
107
  #ifdef USE_BUTTON
243
108
  void send_button_info(button::Button *button);
244
109
  void button_command(const ButtonCommandRequest &msg) override;
245
-
246
- protected:
247
- bool try_send_button_info_(button::Button *button);
248
-
249
- public:
250
110
  #endif
251
111
  #ifdef USE_LOCK
252
- bool send_lock_state(lock::Lock *a_lock, lock::LockState state);
112
+ bool send_lock_state(lock::Lock *a_lock);
253
113
  void send_lock_info(lock::Lock *a_lock);
254
114
  void lock_command(const LockCommandRequest &msg) override;
255
-
256
- protected:
257
- bool try_send_lock_state_(lock::Lock *a_lock);
258
- bool try_send_lock_state_(lock::Lock *a_lock, lock::LockState state);
259
- bool try_send_lock_info_(lock::Lock *a_lock);
260
-
261
- public:
262
115
  #endif
263
116
  #ifdef USE_VALVE
264
117
  bool send_valve_state(valve::Valve *valve);
265
118
  void send_valve_info(valve::Valve *valve);
266
119
  void valve_command(const ValveCommandRequest &msg) override;
267
-
268
- protected:
269
- bool try_send_valve_state_(valve::Valve *valve);
270
- bool try_send_valve_info_(valve::Valve *valve);
271
-
272
- public:
273
120
  #endif
274
121
  #ifdef USE_MEDIA_PLAYER
275
122
  bool send_media_player_state(media_player::MediaPlayer *media_player);
276
123
  void send_media_player_info(media_player::MediaPlayer *media_player);
277
124
  void media_player_command(const MediaPlayerCommandRequest &msg) override;
278
-
279
- protected:
280
- bool try_send_media_player_state_(media_player::MediaPlayer *media_player);
281
- bool try_send_media_player_info_(media_player::MediaPlayer *media_player);
282
-
283
- public:
284
125
  #endif
285
126
  bool try_send_log_message(int level, const char *tag, const char *line);
286
127
  void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
287
128
  if (!this->service_call_subscription_)
288
129
  return;
289
- this->send_homeassistant_service_response(call);
130
+ this->send_message(call);
290
131
  }
291
132
  #ifdef USE_BLUETOOTH_PROXY
292
133
  void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override;
@@ -308,7 +149,7 @@ class APIConnection : public APIServerConnection {
308
149
  #ifdef USE_HOMEASSISTANT_TIME
309
150
  void send_time_request() {
310
151
  GetTimeRequest req;
311
- this->send_get_time_request(req);
152
+ this->send_message(req);
312
153
  }
313
154
  #endif
314
155
 
@@ -328,36 +169,17 @@ class APIConnection : public APIServerConnection {
328
169
  bool send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
329
170
  void send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
330
171
  void alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) override;
331
-
332
- protected:
333
- bool try_send_alarm_control_panel_state_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
334
- bool try_send_alarm_control_panel_info_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
335
-
336
- public:
337
172
  #endif
338
173
 
339
174
  #ifdef USE_EVENT
340
- void send_event(event::Event *event, std::string event_type);
175
+ void send_event(event::Event *event, const std::string &event_type);
341
176
  void send_event_info(event::Event *event);
342
-
343
- protected:
344
- bool try_send_event_(event::Event *event);
345
- bool try_send_event_(event::Event *event, std::string event_type);
346
- bool try_send_event_info_(event::Event *event);
347
-
348
- public:
349
177
  #endif
350
178
 
351
179
  #ifdef USE_UPDATE
352
180
  bool send_update_state(update::UpdateEntity *update);
353
181
  void send_update_info(update::UpdateEntity *update);
354
182
  void update_command(const UpdateCommandRequest &msg) override;
355
-
356
- protected:
357
- bool try_send_update_state_(update::UpdateEntity *update);
358
- bool try_send_update_info_(update::UpdateEntity *update);
359
-
360
- public:
361
183
  #endif
362
184
 
363
185
  void on_disconnect_response(const DisconnectResponse &value) override;
@@ -407,102 +229,67 @@ class APIConnection : public APIServerConnection {
407
229
  void on_no_setup_connection() override;
408
230
  ProtoWriteBuffer create_buffer(uint32_t reserve_size) override {
409
231
  // FIXME: ensure no recursive writes can happen
410
- this->proto_write_buffer_.clear();
232
+
411
233
  // Get header padding size - used for both reserve and insert
412
234
  uint8_t header_padding = this->helper_->frame_header_padding();
235
+
236
+ // Get shared buffer from parent server
237
+ std::vector<uint8_t> &shared_buf = this->parent_->get_shared_buffer_ref();
238
+ shared_buf.clear();
413
239
  // Reserve space for header padding + message + footer
414
240
  // - Header padding: space for protocol headers (7 bytes for Noise, 6 for Plaintext)
415
241
  // - Footer: space for MAC (16 bytes for Noise, 0 for Plaintext)
416
- this->proto_write_buffer_.reserve(reserve_size + header_padding + this->helper_->frame_footer_size());
242
+ shared_buf.reserve(reserve_size + header_padding + this->helper_->frame_footer_size());
417
243
  // Insert header padding bytes so message encoding starts at the correct position
418
- this->proto_write_buffer_.insert(this->proto_write_buffer_.begin(), header_padding, 0);
419
- return {&this->proto_write_buffer_};
244
+ shared_buf.insert(shared_buf.begin(), header_padding, 0);
245
+ return {&shared_buf};
420
246
  }
421
- bool try_to_clear_buffer(bool log_out_of_space);
422
- bool send_buffer(ProtoWriteBuffer buffer, uint32_t message_type) override;
423
247
 
424
- std::string get_client_combined_info() const { return this->client_combined_info_; }
425
-
426
- protected:
427
- friend APIServer;
428
-
429
- /**
430
- * Generic send entity state method to reduce code duplication.
431
- * Only attempts to build and send the message if the transmit buffer is available.
432
- *
433
- * This is the base version for entities that use their current state.
434
- *
435
- * @param entity The entity to send state for
436
- * @param try_send_func The function that tries to send the state
437
- * @return True on success or message deferred, false if subscription check failed
438
- */
439
- bool send_state_(esphome::EntityBase *entity, send_message_t try_send_func) {
440
- if (!this->state_subscription_)
441
- return false;
442
- if (this->try_to_clear_buffer(true) && (this->*try_send_func)(entity)) {
443
- return true;
248
+ // Prepare buffer for next message in batch
249
+ ProtoWriteBuffer prepare_message_buffer(uint16_t message_size, bool is_first_message) {
250
+ // Get reference to shared buffer (it maintains state between batch messages)
251
+ std::vector<uint8_t> &shared_buf = this->parent_->get_shared_buffer_ref();
252
+ size_t current_size = shared_buf.size();
253
+
254
+ if (is_first_message) {
255
+ // For first message, initialize buffer with header padding
256
+ uint8_t header_padding = this->helper_->frame_header_padding();
257
+ shared_buf.clear();
258
+ shared_buf.reserve(message_size + header_padding);
259
+ shared_buf.resize(header_padding);
260
+ // Fill header padding with zeros
261
+ std::fill(shared_buf.begin(), shared_buf.end(), 0);
262
+ } else {
263
+ // For subsequent messages, add footer space for previous message and header for this message
264
+ uint8_t footer_size = this->helper_->frame_footer_size();
265
+ uint8_t header_padding = this->helper_->frame_header_padding();
266
+
267
+ // Reserve additional space for everything
268
+ shared_buf.reserve(current_size + footer_size + header_padding + message_size);
269
+
270
+ // Single resize to add both footer and header padding
271
+ size_t new_size = current_size + footer_size + header_padding;
272
+ shared_buf.resize(new_size);
273
+
274
+ // Fill the newly added bytes with zeros (footer + header padding)
275
+ std::fill(shared_buf.begin() + current_size, shared_buf.end(), 0);
444
276
  }
445
- this->deferred_message_queue_.defer(entity, try_send_func);
446
- return true;
447
- }
448
277
 
449
- /**
450
- * Send entity state method that handles explicit state values.
451
- * Only attempts to build and send the message if the transmit buffer is available.
452
- *
453
- * This method accepts a state parameter to be used instead of the entity's current state.
454
- * It attempts to send the state with the provided value first, and if that fails due to buffer constraints,
455
- * it defers the entity for later processing using the entity-only function.
456
- *
457
- * @tparam EntityT The entity type
458
- * @tparam StateT Type of the state parameter
459
- * @tparam Args Additional argument types (if any)
460
- * @param entity The entity to send state for
461
- * @param try_send_entity_func The function that tries to send the state with entity pointer only
462
- * @param try_send_state_func The function that tries to send the state with entity and state parameters
463
- * @param state The state value to send
464
- * @param args Additional arguments to pass to the try_send_state_func
465
- * @return True on success or message deferred, false if subscription check failed
466
- */
467
- template<typename EntityT, typename StateT, typename... Args>
468
- bool send_state_with_value_(EntityT *entity, bool (APIConnection::*try_send_entity_func)(EntityT *),
469
- bool (APIConnection::*try_send_state_func)(EntityT *, StateT, Args...), StateT state,
470
- Args... args) {
471
- if (!this->state_subscription_)
472
- return false;
473
- if (this->try_to_clear_buffer(true) && (this->*try_send_state_func)(entity, state, args...)) {
474
- return true;
475
- }
476
- this->deferred_message_queue_.defer(entity, reinterpret_cast<send_message_t>(try_send_entity_func));
477
- return true;
278
+ return {&shared_buf};
478
279
  }
479
280
 
480
- /**
481
- * Generic send entity info method to reduce code duplication.
482
- * Only attempts to build and send the message if the transmit buffer is available.
483
- *
484
- * @param entity The entity to send info for
485
- * @param try_send_func The function that tries to send the info
486
- */
487
- void send_info_(esphome::EntityBase *entity, send_message_t try_send_func) {
488
- if (this->try_to_clear_buffer(true) && (this->*try_send_func)(entity)) {
489
- return;
490
- }
491
- this->deferred_message_queue_.defer(entity, try_send_func);
492
- }
281
+ bool try_to_clear_buffer(bool log_out_of_space);
282
+ bool send_buffer(ProtoWriteBuffer buffer, uint16_t message_type) override;
493
283
 
494
- /**
495
- * Generic function for generating entity info response messages.
496
- * This is used to reduce duplication in the try_send_*_info functions.
497
- *
498
- * @param entity The entity to generate info for
499
- * @param response The response object
500
- * @param send_response_func Function pointer to send the response
501
- * @return True if the message was sent successfully
502
- */
503
- template<typename ResponseT>
504
- bool try_send_entity_info_(esphome::EntityBase *entity, ResponseT &response,
505
- bool (APIServerConnectionBase::*send_response_func)(const ResponseT &)) {
284
+ std::string get_client_combined_info() const { return this->client_combined_info_; }
285
+
286
+ // Buffer allocator methods for batch processing
287
+ ProtoWriteBuffer allocate_single_message_buffer(uint16_t size);
288
+ ProtoWriteBuffer allocate_batch_message_buffer(uint16_t size);
289
+
290
+ protected:
291
+ // Helper function to fill common entity fields
292
+ template<typename ResponseT> static void fill_entity_info_base(esphome::EntityBase *entity, ResponseT &response) {
506
293
  // Set common fields that are shared by all entity types
507
294
  response.key = entity->get_object_id_hash();
508
295
  response.object_id = entity->get_object_id();
@@ -514,12 +301,137 @@ class APIConnection : public APIServerConnection {
514
301
  response.icon = entity->get_icon();
515
302
  response.disabled_by_default = entity->is_disabled_by_default();
516
303
  response.entity_category = static_cast<enums::EntityCategory>(entity->get_entity_category());
517
-
518
- // Send the response using the provided send method
519
- return (this->*send_response_func)(response);
520
304
  }
521
305
 
522
- bool send_(const void *buf, size_t len, bool force);
306
+ // Non-template helper to encode any ProtoMessage
307
+ static uint16_t encode_message_to_buffer(ProtoMessage &msg, uint16_t message_type, APIConnection *conn,
308
+ uint32_t remaining_size, bool is_single);
309
+
310
+ #ifdef USE_BINARY_SENSOR
311
+ static uint16_t try_send_binary_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
312
+ bool is_single);
313
+ static uint16_t try_send_binary_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
314
+ bool is_single);
315
+ #endif
316
+ #ifdef USE_COVER
317
+ static uint16_t try_send_cover_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
318
+ bool is_single);
319
+ static uint16_t try_send_cover_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
320
+ #endif
321
+ #ifdef USE_FAN
322
+ static uint16_t try_send_fan_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
323
+ static uint16_t try_send_fan_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
324
+ #endif
325
+ #ifdef USE_LIGHT
326
+ static uint16_t try_send_light_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
327
+ bool is_single);
328
+ static uint16_t try_send_light_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
329
+ #endif
330
+ #ifdef USE_SENSOR
331
+ static uint16_t try_send_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
332
+ bool is_single);
333
+ static uint16_t try_send_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
334
+ bool is_single);
335
+ #endif
336
+ #ifdef USE_SWITCH
337
+ static uint16_t try_send_switch_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
338
+ bool is_single);
339
+ static uint16_t try_send_switch_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
340
+ bool is_single);
341
+ #endif
342
+ #ifdef USE_TEXT_SENSOR
343
+ static uint16_t try_send_text_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
344
+ bool is_single);
345
+ static uint16_t try_send_text_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
346
+ bool is_single);
347
+ #endif
348
+ #ifdef USE_CLIMATE
349
+ static uint16_t try_send_climate_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
350
+ bool is_single);
351
+ static uint16_t try_send_climate_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
352
+ bool is_single);
353
+ #endif
354
+ #ifdef USE_NUMBER
355
+ static uint16_t try_send_number_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
356
+ bool is_single);
357
+ static uint16_t try_send_number_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
358
+ bool is_single);
359
+ #endif
360
+ #ifdef USE_DATETIME_DATE
361
+ static uint16_t try_send_date_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
362
+ static uint16_t try_send_date_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
363
+ #endif
364
+ #ifdef USE_DATETIME_TIME
365
+ static uint16_t try_send_time_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
366
+ static uint16_t try_send_time_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
367
+ #endif
368
+ #ifdef USE_DATETIME_DATETIME
369
+ static uint16_t try_send_datetime_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
370
+ bool is_single);
371
+ static uint16_t try_send_datetime_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
372
+ bool is_single);
373
+ #endif
374
+ #ifdef USE_TEXT
375
+ static uint16_t try_send_text_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
376
+ static uint16_t try_send_text_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
377
+ #endif
378
+ #ifdef USE_SELECT
379
+ static uint16_t try_send_select_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
380
+ bool is_single);
381
+ static uint16_t try_send_select_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
382
+ bool is_single);
383
+ #endif
384
+ #ifdef USE_BUTTON
385
+ static uint16_t try_send_button_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
386
+ bool is_single);
387
+ #endif
388
+ #ifdef USE_LOCK
389
+ static uint16_t try_send_lock_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
390
+ static uint16_t try_send_lock_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
391
+ #endif
392
+ #ifdef USE_VALVE
393
+ static uint16_t try_send_valve_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
394
+ bool is_single);
395
+ static uint16_t try_send_valve_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
396
+ #endif
397
+ #ifdef USE_MEDIA_PLAYER
398
+ static uint16_t try_send_media_player_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
399
+ bool is_single);
400
+ static uint16_t try_send_media_player_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
401
+ bool is_single);
402
+ #endif
403
+ #ifdef USE_ALARM_CONTROL_PANEL
404
+ static uint16_t try_send_alarm_control_panel_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
405
+ bool is_single);
406
+ static uint16_t try_send_alarm_control_panel_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
407
+ bool is_single);
408
+ #endif
409
+ #ifdef USE_EVENT
410
+ static uint16_t try_send_event_response(event::Event *event, const std::string &event_type, APIConnection *conn,
411
+ uint32_t remaining_size, bool is_single);
412
+ static uint16_t try_send_event_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
413
+ #endif
414
+ #ifdef USE_UPDATE
415
+ static uint16_t try_send_update_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
416
+ bool is_single);
417
+ static uint16_t try_send_update_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
418
+ bool is_single);
419
+ #endif
420
+ #ifdef USE_ESP32_CAMERA
421
+ static uint16_t try_send_camera_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
422
+ bool is_single);
423
+ #endif
424
+
425
+ // Method for ListEntitiesDone batching
426
+ static uint16_t try_send_list_info_done(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
427
+ bool is_single);
428
+
429
+ // Method for DisconnectRequest batching
430
+ static uint16_t try_send_disconnect_request(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
431
+ bool is_single);
432
+
433
+ // Helper function to get estimated message size for buffer pre-allocation
434
+ static uint16_t get_estimated_message_size(uint16_t message_type);
523
435
 
524
436
  enum class ConnectionState {
525
437
  WAITING_FOR_HELLO,
@@ -529,9 +441,6 @@ class APIConnection : public APIServerConnection {
529
441
 
530
442
  bool remove_{false};
531
443
 
532
- // Buffer used to encode proto messages
533
- // Re-use to prevent allocations
534
- std::vector<uint8_t> proto_write_buffer_;
535
444
  std::unique_ptr<APIFrameHelper> helper_;
536
445
 
537
446
  std::string client_info_;
@@ -552,10 +461,160 @@ class APIConnection : public APIServerConnection {
552
461
  bool service_call_subscription_{false};
553
462
  bool next_close_ = false;
554
463
  APIServer *parent_;
555
- DeferredMessageQueue deferred_message_queue_;
556
464
  InitialStateIterator initial_state_iterator_;
557
465
  ListEntitiesIterator list_entities_iterator_;
558
466
  int state_subs_at_ = -1;
467
+
468
+ // Function pointer type for message encoding
469
+ using MessageCreatorPtr = uint16_t (*)(EntityBase *, APIConnection *, uint32_t remaining_size, bool is_single);
470
+
471
+ // Optimized MessageCreator class using union dispatch
472
+ class MessageCreator {
473
+ public:
474
+ // Constructor for function pointer (message_type = 0)
475
+ MessageCreator(MessageCreatorPtr ptr) : message_type_(0) { data_.ptr = ptr; }
476
+
477
+ // Constructor for string state capture
478
+ MessageCreator(const std::string &value, uint16_t msg_type) : message_type_(msg_type) {
479
+ data_.string_ptr = new std::string(value);
480
+ }
481
+
482
+ // Destructor
483
+ ~MessageCreator() {
484
+ // Clean up string data for string-based message types
485
+ if (uses_string_data_()) {
486
+ delete data_.string_ptr;
487
+ }
488
+ }
489
+
490
+ // Copy constructor
491
+ MessageCreator(const MessageCreator &other) : message_type_(other.message_type_) {
492
+ if (message_type_ == 0) {
493
+ data_.ptr = other.data_.ptr;
494
+ } else if (uses_string_data_()) {
495
+ data_.string_ptr = new std::string(*other.data_.string_ptr);
496
+ } else {
497
+ data_ = other.data_; // For POD types
498
+ }
499
+ }
500
+
501
+ // Move constructor
502
+ MessageCreator(MessageCreator &&other) noexcept : data_(other.data_), message_type_(other.message_type_) {
503
+ other.message_type_ = 0; // Reset other to function pointer type
504
+ other.data_.ptr = nullptr;
505
+ }
506
+
507
+ // Assignment operators (needed for batch deduplication)
508
+ MessageCreator &operator=(const MessageCreator &other) {
509
+ if (this != &other) {
510
+ // Clean up current string data if needed
511
+ if (uses_string_data_()) {
512
+ delete data_.string_ptr;
513
+ }
514
+ // Copy new data
515
+ message_type_ = other.message_type_;
516
+ if (other.message_type_ == 0) {
517
+ data_.ptr = other.data_.ptr;
518
+ } else if (other.uses_string_data_()) {
519
+ data_.string_ptr = new std::string(*other.data_.string_ptr);
520
+ } else {
521
+ data_ = other.data_;
522
+ }
523
+ }
524
+ return *this;
525
+ }
526
+
527
+ MessageCreator &operator=(MessageCreator &&other) noexcept {
528
+ if (this != &other) {
529
+ // Clean up current string data if needed
530
+ if (uses_string_data_()) {
531
+ delete data_.string_ptr;
532
+ }
533
+ // Move data
534
+ message_type_ = other.message_type_;
535
+ data_ = other.data_;
536
+ // Reset other to safe state
537
+ other.message_type_ = 0;
538
+ other.data_.ptr = nullptr;
539
+ }
540
+ return *this;
541
+ }
542
+
543
+ // Call operator
544
+ uint16_t operator()(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single) const;
545
+
546
+ private:
547
+ // Helper to check if this message type uses heap-allocated strings
548
+ bool uses_string_data_() const { return message_type_ == EventResponse::MESSAGE_TYPE; }
549
+ union CreatorData {
550
+ MessageCreatorPtr ptr; // 8 bytes
551
+ std::string *string_ptr; // 8 bytes
552
+ } data_; // 8 bytes
553
+ uint16_t message_type_; // 2 bytes (0 = function ptr, >0 = state capture)
554
+ };
555
+
556
+ // Generic batching mechanism for both state updates and entity info
557
+ struct DeferredBatch {
558
+ struct BatchItem {
559
+ EntityBase *entity; // Entity pointer
560
+ MessageCreator creator; // Function that creates the message when needed
561
+ uint16_t message_type; // Message type for overhead calculation
562
+
563
+ // Constructor for creating BatchItem
564
+ BatchItem(EntityBase *entity, MessageCreator creator, uint16_t message_type)
565
+ : entity(entity), creator(std::move(creator)), message_type(message_type) {}
566
+ };
567
+
568
+ std::vector<BatchItem> items;
569
+ uint32_t batch_start_time{0};
570
+ bool batch_scheduled{false};
571
+
572
+ DeferredBatch() {
573
+ // Pre-allocate capacity for typical batch sizes to avoid reallocation
574
+ items.reserve(8);
575
+ }
576
+
577
+ // Add item to the batch
578
+ void add_item(EntityBase *entity, MessageCreator creator, uint16_t message_type);
579
+ void clear() {
580
+ items.clear();
581
+ batch_scheduled = false;
582
+ batch_start_time = 0;
583
+ }
584
+ bool empty() const { return items.empty(); }
585
+ };
586
+
587
+ DeferredBatch deferred_batch_;
588
+ uint32_t get_batch_delay_ms_() const;
589
+ // Message will use 8 more bytes than the minimum size, and typical
590
+ // MTU is 1500. Sometimes users will see as low as 1460 MTU.
591
+ // If its IPv6 the header is 40 bytes, and if its IPv4
592
+ // the header is 20 bytes. So we have 1460 - 40 = 1420 bytes
593
+ // available for the payload. But we also need to add the size of
594
+ // the protobuf overhead, which is 8 bytes.
595
+ //
596
+ // To be safe we pick 1390 bytes as the maximum size
597
+ // to send in one go. This is the maximum size of a single packet
598
+ // that can be sent over the network.
599
+ // This is to avoid fragmentation of the packet.
600
+ static constexpr size_t MAX_PACKET_SIZE = 1390; // MTU
601
+
602
+ bool schedule_batch_();
603
+ void process_batch_();
604
+
605
+ // State for batch buffer allocation
606
+ bool batch_first_message_{false};
607
+
608
+ // Helper function to schedule a deferred message with known message type
609
+ bool schedule_message_(EntityBase *entity, MessageCreator creator, uint16_t message_type) {
610
+ this->deferred_batch_.add_item(entity, std::move(creator), message_type);
611
+ return this->schedule_batch_();
612
+ }
613
+
614
+ // Overload for function pointers (for info messages and current state reads)
615
+ bool schedule_message_(EntityBase *entity, MessageCreatorPtr function_ptr, uint16_t message_type) {
616
+ return schedule_message_(entity, MessageCreator(function_ptr), message_type);
617
+ }
559
618
  };
560
619
 
561
620
  } // namespace api