esphome 2025.5.1__py3-none-any.whl → 2025.6.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 (753) 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 +753 -379
  29. esphome/components/api/api_connection.h +341 -283
  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 +5 -0
  33. esphome/components/api/api_pb2.h +703 -227
  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 -4
  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 +5 -4
  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 +18 -16
  67. esphome/components/bluetooth_proxy/bluetooth_proxy.h +1 -1
  68. esphome/components/bme280_base/bme280_base.cpp +5 -6
  69. esphome/components/bme680/bme680.cpp +3 -3
  70. esphome/components/bme680/sensor.py +2 -2
  71. esphome/components/bme680_bsec/bme680_bsec.cpp +11 -7
  72. esphome/components/bme680_bsec/sensor.py +7 -3
  73. esphome/components/bme68x_bsec2/__init__.py +6 -5
  74. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +17 -13
  75. esphome/components/bme68x_bsec2/sensor.py +4 -4
  76. esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.cpp +1 -0
  77. esphome/components/bmi160/bmi160.cpp +11 -11
  78. esphome/components/bmp085/bmp085.cpp +2 -2
  79. esphome/components/bmp280_base/bmp280_base.cpp +3 -3
  80. esphome/components/bmp3xx_base/bmp3xx_base.cpp +13 -13
  81. esphome/components/bmp581/bmp581.cpp +33 -27
  82. esphome/components/bp1658cj/bp1658cj.cpp +5 -3
  83. esphome/components/bp5758d/bp5758d.cpp +1 -1
  84. esphome/components/button/__init__.py +1 -0
  85. esphome/components/canbus/canbus.cpp +1 -1
  86. esphome/components/cap1188/cap1188.cpp +6 -4
  87. esphome/components/captive_portal/captive_portal.cpp +1 -1
  88. esphome/components/ccs811/ccs811.cpp +3 -2
  89. esphome/components/cd74hc4067/cd74hc4067.cpp +1 -1
  90. esphome/components/ch422g/ch422g.cpp +2 -2
  91. esphome/components/chsc6x/chsc6x_touchscreen.cpp +6 -4
  92. esphome/components/climate/__init__.py +1 -0
  93. esphome/components/climate/climate.cpp +12 -7
  94. esphome/components/climate/climate.h +1 -1
  95. esphome/components/climate_ir/climate_ir.cpp +7 -4
  96. esphome/components/cm1106/__init__.py +1 -0
  97. esphome/components/cm1106/cm1106.cpp +112 -0
  98. esphome/components/cm1106/cm1106.h +40 -0
  99. esphome/components/cm1106/sensor.py +72 -0
  100. esphome/components/const/__init__.py +1 -0
  101. esphome/components/cover/__init__.py +1 -0
  102. esphome/components/cs5460a/cs5460a.cpp +16 -11
  103. esphome/components/cse7761/cse7761.cpp +2 -2
  104. esphome/components/cse7766/cse7766.cpp +0 -5
  105. esphome/components/cse7766/cse7766.h +5 -1
  106. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +1 -1
  107. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +6 -3
  108. esphome/components/current_based/current_based_cover.cpp +4 -2
  109. esphome/components/dac7678/dac7678_output.cpp +4 -4
  110. esphome/components/dallas_temp/dallas_temp.cpp +2 -3
  111. esphome/components/daly_bms/daly_bms.cpp +2 -1
  112. esphome/components/dashboard_import/__init__.py +1 -2
  113. esphome/components/datetime/__init__.py +3 -1
  114. esphome/components/datetime/date_entity.cpp +5 -5
  115. esphome/components/datetime/datetime_base.h +0 -5
  116. esphome/components/datetime/datetime_entity.cpp +8 -8
  117. esphome/components/datetime/time_entity.cpp +4 -4
  118. esphome/components/debug/debug_component.cpp +1 -5
  119. esphome/components/debug/debug_component.h +1 -1
  120. esphome/components/debug/debug_esp32.cpp +4 -2
  121. esphome/components/deep_sleep/deep_sleep_component.cpp +11 -5
  122. esphome/components/deep_sleep/deep_sleep_esp32.cpp +7 -5
  123. esphome/components/demo/__init__.py +206 -0
  124. esphome/components/demo/demo_alarm_control_panel.h +65 -0
  125. esphome/components/demo/demo_button.h +15 -0
  126. esphome/components/demo/demo_date.h +34 -0
  127. esphome/components/demo/demo_datetime.h +40 -0
  128. esphome/components/demo/demo_lock.h +17 -0
  129. esphome/components/demo/demo_select.h +15 -0
  130. esphome/components/demo/demo_text.h +18 -0
  131. esphome/components/demo/demo_time.h +34 -0
  132. esphome/components/demo/demo_valve.h +54 -0
  133. esphome/components/dfrobot_sen0395/commands.cpp +3 -3
  134. esphome/components/dht/dht.cpp +29 -50
  135. esphome/components/dht12/dht12.cpp +2 -2
  136. esphome/components/display/display.h +5 -3
  137. esphome/components/dps310/dps310.cpp +7 -5
  138. esphome/components/ds1307/ds1307.cpp +2 -2
  139. esphome/components/dsmr/dsmr.cpp +5 -3
  140. esphome/components/duty_cycle/duty_cycle_sensor.cpp +2 -2
  141. esphome/components/duty_time/duty_time_sensor.cpp +5 -3
  142. esphome/components/ee895/ee895.cpp +3 -3
  143. esphome/components/ektf2232/touchscreen/ektf2232.cpp +1 -1
  144. esphome/components/emc2101/emc2101.cpp +11 -9
  145. esphome/components/ens160_base/ens160_base.cpp +2 -2
  146. esphome/components/ens210/ens210.cpp +2 -2
  147. esphome/components/es7210/es7210.cpp +6 -4
  148. esphome/components/es7243e/es7243e.cpp +1 -1
  149. esphome/components/es8156/es8156.cpp +1 -1
  150. esphome/components/es8311/es8311.cpp +8 -6
  151. esphome/components/es8388/__init__.py +0 -0
  152. esphome/components/es8388/audio_dac.py +26 -0
  153. esphome/components/es8388/es8388.cpp +289 -0
  154. esphome/components/es8388/es8388.h +81 -0
  155. esphome/components/es8388/es8388_const.h +83 -0
  156. esphome/components/es8388/select/__init__.py +47 -0
  157. esphome/components/es8388/select/adc_input_mic_select.cpp +12 -0
  158. esphome/components/es8388/select/adc_input_mic_select.h +15 -0
  159. esphome/components/es8388/select/dac_output_select.cpp +12 -0
  160. esphome/components/es8388/select/dac_output_select.h +15 -0
  161. esphome/components/esp32/__init__.py +118 -23
  162. esphome/components/esp32/boards.py +208 -125
  163. esphome/components/esp32/const.py +6 -0
  164. esphome/components/esp32/gpio.py +14 -1
  165. esphome/components/esp32/gpio_esp32_c5.py +45 -0
  166. esphome/components/esp32/gpio_esp32_p4.py +43 -0
  167. esphome/components/esp32/preferences.cpp +7 -7
  168. esphome/components/esp32_ble/__init__.py +115 -0
  169. esphome/components/esp32_ble/ble.cpp +101 -54
  170. esphome/components/esp32_ble/ble.h +24 -5
  171. esphome/components/esp32_ble/ble_event.h +172 -32
  172. esphome/components/esp32_ble/ble_scan_result.h +24 -0
  173. esphome/components/esp32_ble/ble_uuid.h +1 -1
  174. esphome/components/esp32_ble/queue.h +53 -27
  175. esphome/components/esp32_ble_client/ble_client_base.cpp +4 -2
  176. esphome/components/esp32_ble_server/__init__.py +4 -1
  177. esphome/components/esp32_ble_server/ble_characteristic.cpp +1 -0
  178. esphome/components/esp32_ble_server/ble_server.h +0 -1
  179. esphome/components/esp32_ble_tracker/__init__.py +7 -2
  180. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +107 -75
  181. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +16 -16
  182. esphome/components/esp32_camera/esp32_camera.cpp +35 -27
  183. esphome/components/esp32_camera_web_server/camera_web_server.cpp +4 -2
  184. esphome/components/esp32_dac/esp32_dac.cpp +2 -2
  185. esphome/components/esp32_improv/__init__.py +5 -1
  186. esphome/components/esp32_improv/esp32_improv_component.cpp +2 -2
  187. esphome/components/esp32_rmt_led_strip/led_strip.cpp +11 -7
  188. esphome/components/esp32_rmt_led_strip/light.py +5 -1
  189. esphome/components/esp32_touch/esp32_touch.cpp +12 -8
  190. esphome/components/esp8266/gpio.cpp +10 -1
  191. esphome/components/esp8266/preferences.cpp +6 -6
  192. esphome/components/esp8266_pwm/esp8266_pwm.cpp +3 -3
  193. esphome/components/esp_ldo/__init__.py +91 -0
  194. esphome/components/esp_ldo/esp_ldo.cpp +43 -0
  195. esphome/components/esp_ldo/esp_ldo.h +43 -0
  196. esphome/components/esphome/ota/ota_esphome.cpp +15 -8
  197. esphome/components/ethernet/ethernet_component.cpp +38 -26
  198. esphome/components/ethernet/ethernet_component.h +1 -1
  199. esphome/components/event/__init__.py +1 -0
  200. esphome/components/exposure_notifications/exposure_notifications.cpp +1 -1
  201. esphome/components/ezo/ezo.cpp +1 -1
  202. esphome/components/ezo_pmp/ezo_pmp.cpp +1 -1
  203. esphome/components/factory_reset/button/factory_reset_button.cpp +1 -1
  204. esphome/components/factory_reset/switch/factory_reset_switch.cpp +1 -1
  205. esphome/components/fan/__init__.py +1 -0
  206. esphome/components/fan/fan.cpp +30 -19
  207. esphome/components/fastled_base/fastled_light.cpp +7 -5
  208. esphome/components/fingerprint_grow/fingerprint_grow.cpp +8 -6
  209. esphome/components/fs3000/fs3000.cpp +1 -1
  210. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +7 -4
  211. esphome/components/ft63x6/ft63x6.cpp +5 -3
  212. esphome/components/gcja5/gcja5.cpp +0 -12
  213. esphome/components/gcja5/gcja5.h +8 -3
  214. esphome/components/gdk101/gdk101.cpp +2 -2
  215. esphome/components/globals/globals_component.h +13 -10
  216. esphome/components/gp2y1010au0f/gp2y1010au0f.cpp +4 -2
  217. esphome/components/gp8403/gp8403.cpp +4 -2
  218. esphome/components/gp8403/output/gp8403_output.cpp +4 -2
  219. esphome/components/gpio/one_wire/gpio_one_wire.cpp +2 -2
  220. esphome/components/gpio/output/gpio_binary_output.cpp +1 -1
  221. esphome/components/gpio/switch/gpio_switch.cpp +1 -1
  222. esphome/components/graphical_display_menu/graphical_display_menu.cpp +12 -8
  223. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -6
  224. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +1 -1
  225. esphome/components/grove_tb6612fng/grove_tb6612fng.h +1 -1
  226. esphome/components/growatt_solar/growatt_solar.cpp +6 -3
  227. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
  228. esphome/components/haier/haier_base.cpp +2 -2
  229. esphome/components/haier/hon_climate.cpp +13 -6
  230. esphome/components/havells_solar/havells_solar.cpp +5 -2
  231. esphome/components/hbridge/switch/hbridge_switch.cpp +1 -1
  232. esphome/components/hdc1080/hdc1080.cpp +2 -2
  233. esphome/components/he60r/he60r.cpp +4 -2
  234. esphome/components/hlw8012/hlw8012.cpp +6 -4
  235. esphome/components/hm3301/hm3301.cpp +2 -2
  236. esphome/components/hmc5883l/hmc5883l.cpp +2 -2
  237. esphome/components/homeassistant/time/homeassistant_time.cpp +4 -2
  238. esphome/components/honeywell_hih_i2c/honeywell_hih.cpp +4 -4
  239. esphome/components/honeywellabp/honeywellabp.cpp +4 -2
  240. esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +8 -6
  241. esphome/components/hte501/hte501.cpp +3 -2
  242. esphome/components/http_request/__init__.py +2 -2
  243. esphome/components/http_request/http_request.cpp +7 -5
  244. esphome/components/http_request/http_request_idf.cpp +4 -2
  245. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  246. esphome/components/htu21d/htu21d.cpp +2 -2
  247. esphome/components/htu31d/htu31d.cpp +2 -2
  248. esphome/components/hx711/hx711.cpp +2 -2
  249. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +5 -3
  250. esphome/components/hyt271/hyt271.cpp +2 -2
  251. esphome/components/i2c/i2c_bus_arduino.cpp +14 -11
  252. esphome/components/i2c/i2c_bus_esp_idf.cpp +13 -11
  253. esphome/components/i2s_audio/__init__.py +2 -0
  254. esphome/components/i2s_audio/i2s_audio.cpp +3 -4
  255. esphome/components/i2s_audio/i2s_audio.h +1 -1
  256. esphome/components/i2s_audio/media_player/__init__.py +1 -1
  257. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +5 -3
  258. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +85 -77
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +6 -0
  260. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +29 -11
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +1 -0
  262. esphome/components/iaqcore/iaqcore.cpp +3 -3
  263. esphome/components/ili9xxx/ili9xxx_display.cpp +12 -7
  264. esphome/components/ili9xxx/ili9xxx_display.h +1 -1
  265. esphome/components/image/image.cpp +1 -0
  266. esphome/components/ina219/ina219.cpp +2 -2
  267. esphome/components/ina226/ina226.cpp +8 -5
  268. esphome/components/ina260/ina260.cpp +1 -1
  269. esphome/components/ina2xx_base/ina2xx_base.cpp +13 -9
  270. esphome/components/ina3221/ina3221.cpp +2 -2
  271. esphome/components/inkplate6/display.py +12 -2
  272. esphome/components/inkplate6/inkplate.cpp +13 -9
  273. esphome/components/inkplate6/inkplate.h +7 -6
  274. esphome/components/integration/integration_sensor.cpp +1 -1
  275. esphome/components/internal_temperature/internal_temperature.cpp +4 -4
  276. esphome/components/json/json_util.cpp +4 -5
  277. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +1 -1
  278. esphome/components/key_collector/key_collector.cpp +4 -2
  279. esphome/components/kmeteriso/kmeteriso.cpp +4 -4
  280. esphome/components/kuntze/kuntze.cpp +4 -2
  281. esphome/components/lc709203f/__init__.py +1 -0
  282. esphome/components/lc709203f/lc709203f.cpp +299 -0
  283. esphome/components/lc709203f/lc709203f.h +55 -0
  284. esphome/components/lc709203f/sensor.py +93 -0
  285. esphome/components/lcd_base/lcd_display.cpp +2 -2
  286. esphome/components/lcd_gpio/gpio_lcd_display.cpp +5 -3
  287. esphome/components/lcd_menu/lcd_menu.cpp +6 -4
  288. esphome/components/lcd_pcf8574/pcf8574_display.cpp +6 -4
  289. esphome/components/ld2410/ld2410.cpp +6 -7
  290. esphome/components/ld2420/ld2420.cpp +9 -7
  291. esphome/components/ld2450/ld2450.cpp +6 -4
  292. esphome/components/ld2450/sensor.py +2 -2
  293. esphome/components/ledc/ledc_output.cpp +32 -28
  294. esphome/components/libretiny/const.py +1 -1
  295. esphome/components/libretiny/preferences.cpp +6 -7
  296. esphome/components/light/__init__.py +2 -1
  297. esphome/components/light/esp_hsv_color.h +1 -1
  298. esphome/components/light/light_state.cpp +9 -5
  299. esphome/components/light/light_state.h +15 -15
  300. esphome/components/light/light_transformer.h +1 -1
  301. esphome/components/lightwaverf/LwTx.cpp +1 -1
  302. esphome/components/lightwaverf/lightwaverf.cpp +1 -1
  303. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +1 -1
  304. esphome/components/lock/__init__.py +1 -0
  305. esphome/components/lock/lock.h +1 -1
  306. esphome/components/logger/__init__.py +6 -0
  307. esphome/components/logger/logger.cpp +11 -20
  308. esphome/components/logger/logger.h +5 -6
  309. esphome/components/logger/logger_esp32.cpp +5 -5
  310. esphome/components/ltr390/ltr390.cpp +8 -5
  311. esphome/components/ltr501/ltr501.cpp +19 -14
  312. esphome/components/ltr_als_ps/ltr_als_ps.cpp +20 -13
  313. esphome/components/lvgl/__init__.py +2 -2
  314. esphome/components/lvgl/automation.py +5 -4
  315. esphome/components/lvgl/defines.py +0 -2
  316. esphome/components/lvgl/lv_validation.py +1 -3
  317. esphome/components/lvgl/lvcode.py +7 -8
  318. esphome/components/lvgl/lvgl_esphome.cpp +26 -10
  319. esphome/components/lvgl/schemas.py +22 -23
  320. esphome/components/lvgl/trigger.py +8 -3
  321. esphome/components/lvgl/widgets/__init__.py +2 -2
  322. esphome/components/lvgl/widgets/canvas.py +9 -3
  323. esphome/components/lvgl/widgets/line.py +2 -1
  324. esphome/components/lvgl/widgets/tabview.py +7 -0
  325. esphome/components/m5stack_8angle/m5stack_8angle.cpp +3 -3
  326. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -2
  327. esphome/components/max17043/max17043.cpp +2 -2
  328. esphome/components/max31855/max31855.cpp +2 -1
  329. esphome/components/max31856/max31856.cpp +9 -11
  330. esphome/components/max31865/max31865.cpp +6 -4
  331. esphome/components/max44009/max44009.cpp +2 -2
  332. esphome/components/max6675/max6675.cpp +1 -1
  333. esphome/components/max6956/max6956.cpp +5 -3
  334. esphome/components/max7219/max7219.cpp +8 -6
  335. esphome/components/max7219digit/automation.h +52 -0
  336. esphome/components/max7219digit/display.py +93 -1
  337. esphome/components/max7219digit/max7219digit.cpp +16 -13
  338. esphome/components/max9611/max9611.cpp +9 -6
  339. esphome/components/mcp23008/mcp23008.cpp +1 -1
  340. esphome/components/mcp23016/mcp23016.cpp +1 -1
  341. esphome/components/mcp23017/mcp23017.cpp +1 -1
  342. esphome/components/mcp23s08/mcp23s08.cpp +1 -1
  343. esphome/components/mcp23s17/mcp23s17.cpp +1 -1
  344. esphome/components/mcp3008/mcp3008.cpp +1 -1
  345. esphome/components/mcp3008/sensor/mcp3008_sensor.cpp +5 -3
  346. esphome/components/mcp3204/mcp3204.cpp +1 -1
  347. esphome/components/mcp4461/mcp4461.cpp +2 -2
  348. esphome/components/mcp4725/mcp4725.cpp +2 -2
  349. esphome/components/mcp4728/mcp4728.cpp +2 -2
  350. esphome/components/mcp9600/mcp9600.cpp +1 -1
  351. esphome/components/mcp9808/mcp9808.cpp +4 -4
  352. esphome/components/mdns/mdns_component.cpp +8 -2
  353. esphome/components/mdns/mdns_component.h +3 -1
  354. esphome/components/mdns/mdns_esp32.cpp +2 -2
  355. esphome/components/media_player/__init__.py +1 -0
  356. esphome/components/micro_wake_word/micro_wake_word.cpp +1 -1
  357. esphome/components/micro_wake_word/streaming_model.cpp +10 -6
  358. esphome/components/micronova/micronova.h +2 -2
  359. esphome/components/mics_4514/mics_4514.cpp +2 -2
  360. esphome/components/midea/air_conditioner.cpp +7 -5
  361. esphome/components/midea_ir/midea_ir.cpp +1 -1
  362. esphome/components/mipi_spi/mipi_spi.cpp +24 -15
  363. esphome/components/mixer/speaker/mixer_speaker.cpp +8 -4
  364. esphome/components/mlx90393/sensor_mlx90393.cpp +2 -2
  365. esphome/components/mlx90614/mlx90614.cpp +4 -3
  366. esphome/components/mmc5603/mmc5603.cpp +2 -2
  367. esphome/components/mmc5983/mmc5983.cpp +1 -1
  368. esphome/components/modbus/modbus.cpp +7 -5
  369. esphome/components/modbus_controller/modbus_controller.cpp +6 -4
  370. esphome/components/modbus_controller/output/modbus_output.cpp +10 -6
  371. esphome/components/modbus_controller/switch/__init__.py +6 -2
  372. esphome/components/modbus_controller/switch/modbus_switch.cpp +4 -0
  373. esphome/components/modbus_controller/switch/modbus_switch.h +3 -0
  374. esphome/components/mpl3115a2/mpl3115a2.cpp +3 -2
  375. esphome/components/mpr121/mpr121.cpp +2 -2
  376. esphome/components/mpu6050/mpu6050.cpp +6 -6
  377. esphome/components/mpu6886/mpu6886.cpp +6 -6
  378. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +7 -3
  379. esphome/components/mqtt/mqtt_backend_esp32.cpp +1 -1
  380. esphome/components/mqtt/mqtt_client.cpp +31 -24
  381. esphome/components/mqtt/mqtt_component.cpp +3 -3
  382. esphome/components/mqtt/mqtt_cover.cpp +8 -4
  383. esphome/components/mqtt/mqtt_fan.cpp +12 -6
  384. esphome/components/mqtt/mqtt_valve.cpp +4 -2
  385. esphome/components/ms5611/ms5611.cpp +2 -2
  386. esphome/components/ms8607/ms8607.cpp +2 -2
  387. esphome/components/msa3xx/msa3xx.cpp +16 -12
  388. esphome/components/my9231/my9231.cpp +7 -5
  389. esphome/components/nau7802/nau7802.cpp +6 -4
  390. esphome/components/neopixelbus/neopixelbus_light.h +2 -2
  391. esphome/components/network/ip_address.h +1 -1
  392. esphome/components/network/util.cpp +13 -0
  393. esphome/components/nextion/base_component.py +2 -0
  394. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +3 -4
  395. esphome/components/nextion/display.py +34 -22
  396. esphome/components/nextion/nextion.cpp +182 -143
  397. esphome/components/nextion/nextion.h +36 -0
  398. esphome/components/nextion/nextion_commands.cpp +3 -3
  399. esphome/components/nextion/nextion_upload_arduino.cpp +69 -69
  400. esphome/components/nextion/nextion_upload_idf.cpp +79 -80
  401. esphome/components/nextion/sensor/nextion_sensor.cpp +5 -5
  402. esphome/components/nextion/switch/nextion_switch.cpp +2 -2
  403. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +3 -3
  404. esphome/components/nfc/nci_message.h +1 -1
  405. esphome/components/nfc/ndef_record.h +1 -1
  406. esphome/components/nfc/ndef_record_text.h +1 -1
  407. esphome/components/nfc/ndef_record_uri.h +1 -1
  408. esphome/components/nfc/nfc.h +1 -1
  409. esphome/components/nfc/nfc_tag.h +1 -1
  410. esphome/components/noblex/noblex.cpp +1 -1
  411. esphome/components/npi19/npi19.cpp +5 -7
  412. esphome/components/number/__init__.py +11 -0
  413. esphome/components/number/number.cpp +1 -1
  414. esphome/components/number/number.h +0 -4
  415. esphome/components/online_image/__init__.py +13 -1
  416. esphome/components/online_image/online_image.cpp +26 -4
  417. esphome/components/online_image/online_image.h +21 -4
  418. esphome/components/opentherm/generate.py +3 -3
  419. esphome/components/opentherm/hub.cpp +11 -7
  420. esphome/components/opentherm/number/number.cpp +5 -3
  421. esphome/components/opentherm/opentherm.h +1 -1
  422. esphome/components/opentherm/schema.py +13 -13
  423. esphome/components/opentherm/validate.py +1 -1
  424. esphome/components/openthread/__init__.py +146 -0
  425. esphome/components/openthread/const.py +10 -0
  426. esphome/components/openthread/openthread.cpp +206 -0
  427. esphome/components/openthread/openthread.h +68 -0
  428. esphome/components/openthread/openthread_esp.cpp +164 -0
  429. esphome/components/openthread/tlv.py +58 -0
  430. esphome/components/openthread_info/__init__.py +0 -0
  431. esphome/components/openthread_info/openthread_info_text_sensor.cpp +24 -0
  432. esphome/components/openthread_info/openthread_info_text_sensor.h +218 -0
  433. esphome/components/openthread_info/text_sensor.py +105 -0
  434. esphome/components/output/float_output.cpp +1 -1
  435. esphome/components/output/switch/output_switch.cpp +1 -1
  436. esphome/components/packet_transport/packet_transport.cpp +6 -4
  437. esphome/components/pca6416a/pca6416a.cpp +2 -2
  438. esphome/components/pca9554/pca9554.cpp +6 -4
  439. esphome/components/pca9685/pca9685_output.cpp +12 -8
  440. esphome/components/pcd8544/pcd_8544.cpp +1 -1
  441. esphome/components/pcf85063/pcf85063.cpp +2 -2
  442. esphome/components/pcf8563/pcf8563.cpp +2 -2
  443. esphome/components/pcf8574/pcf8574.cpp +2 -2
  444. esphome/components/pid/pid_climate.cpp +8 -5
  445. esphome/components/pid/pid_climate.h +1 -1
  446. esphome/components/pid/sensor/pid_climate_sensor.cpp +1 -1
  447. esphome/components/pipsolar/output/pipsolar_output.cpp +1 -1
  448. esphome/components/pipsolar/pipsolar.cpp +3 -3
  449. esphome/components/pm1006/pm1006.cpp +3 -7
  450. esphome/components/pm1006/pm1006.h +4 -1
  451. esphome/components/pm2005/pm2005.cpp +12 -13
  452. esphome/components/pm2005/sensor.py +1 -1
  453. esphome/components/pmsa003i/pmsa003i.cpp +2 -2
  454. esphome/components/pmsx003/pmsx003.cpp +0 -4
  455. esphome/components/pmsx003/pmsx003.h +5 -2
  456. esphome/components/pmwcs3/pmwcs3.cpp +9 -13
  457. esphome/components/pmwcs3/pmwcs3.h +0 -1
  458. esphome/components/pn532/pn532.cpp +7 -7
  459. esphome/components/pn532/pn532.h +1 -1
  460. esphome/components/pn532_spi/pn532_spi.cpp +1 -1
  461. esphome/components/pn7150/pn7150.cpp +4 -4
  462. esphome/components/pn7160/pn7160.cpp +4 -4
  463. esphome/components/power_supply/power_supply.cpp +6 -4
  464. esphome/components/power_supply/power_supply.h +1 -1
  465. esphome/components/prometheus/__init__.py +0 -1
  466. esphome/components/psram/__init__.py +59 -35
  467. esphome/components/pulse_counter/pulse_counter_sensor.cpp +7 -4
  468. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +8 -5
  469. esphome/components/pylontech/pylontech.cpp +2 -2
  470. esphome/components/pylontech/sensor/pylontech_sensor.cpp +4 -2
  471. esphome/components/pylontech/text_sensor/pylontech_text_sensor.cpp +4 -2
  472. esphome/components/pzemac/pzemac.cpp +4 -2
  473. esphome/components/pzemdc/pzemdc.cpp +4 -2
  474. esphome/components/qmc5883l/qmc5883l.cpp +2 -2
  475. esphome/components/qmp6988/qmp6988.cpp +2 -2
  476. esphome/components/qmp6988/qmp6988.h +1 -1
  477. esphome/components/qr_code/qr_code.cpp +5 -3
  478. esphome/components/qspi_dbi/qspi_dbi.cpp +1 -1
  479. esphome/components/qwiic_pir/qwiic_pir.cpp +26 -28
  480. esphome/components/rc522/rc522.cpp +5 -5
  481. esphome/components/rdm6300/rdm6300.cpp +1 -0
  482. esphome/components/remote_receiver/__init__.py +10 -2
  483. esphome/components/remote_receiver/remote_receiver_esp32.cpp +22 -12
  484. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +10 -7
  485. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +10 -7
  486. esphome/components/remote_transmitter/__init__.py +10 -2
  487. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +10 -6
  488. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +5 -3
  489. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +5 -3
  490. esphome/components/resistance/resistance_sensor.cpp +6 -3
  491. esphome/components/restart/button/restart_button.cpp +1 -1
  492. esphome/components/restart/switch/restart_switch.cpp +1 -1
  493. esphome/components/rotary_encoder/rotary_encoder.cpp +2 -2
  494. esphome/components/rp2040/__init__.py +7 -0
  495. esphome/components/rp2040/core.cpp +8 -1
  496. esphome/components/rp2040/gpio.cpp +26 -9
  497. esphome/components/rp2040/preferences.cpp +3 -3
  498. esphome/components/rp2040_pio_led_strip/led_strip.cpp +11 -8
  499. esphome/components/rp2040_pio_led_strip/light.py +1 -1
  500. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -1
  501. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +1 -1
  502. esphome/components/rtttl/rtttl.cpp +11 -9
  503. esphome/components/safe_mode/button/safe_mode_button.cpp +1 -1
  504. esphome/components/safe_mode/safe_mode.cpp +9 -8
  505. esphome/components/safe_mode/switch/safe_mode_switch.cpp +1 -1
  506. esphome/components/scd30/scd30.cpp +11 -8
  507. esphome/components/scd4x/scd4x.cpp +12 -8
  508. esphome/components/sdl/display.py +40 -0
  509. esphome/components/sdl/sdl_esphome.cpp +2 -2
  510. esphome/components/sdl/sdl_esphome.h +8 -0
  511. esphome/components/sdm_meter/sdm_meter.cpp +5 -2
  512. esphome/components/sdp3x/sdp3x.cpp +11 -11
  513. esphome/components/sds011/sds011.cpp +5 -6
  514. esphome/components/sds011/sds011.h +4 -1
  515. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +3 -2
  516. esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +1 -0
  517. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +3 -2
  518. esphome/components/selec_meter/selec_meter.cpp +5 -2
  519. esphome/components/select/__init__.py +1 -0
  520. esphome/components/select/select.cpp +1 -1
  521. esphome/components/select/select.h +0 -4
  522. esphome/components/sen0321/sen0321.cpp +2 -2
  523. esphome/components/sen21231/sen21231.cpp +1 -1
  524. esphome/components/sen5x/sen5x.cpp +10 -7
  525. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  526. esphome/components/sensirion_common/i2c_sensirion.h +1 -0
  527. esphome/components/sensor/__init__.py +11 -1
  528. esphome/components/sensor/filter.h +1 -1
  529. esphome/components/sensor/sensor.cpp +8 -4
  530. esphome/components/sensor/sensor.h +12 -11
  531. esphome/components/servo/servo.cpp +12 -9
  532. esphome/components/servo/servo.h +1 -1
  533. esphome/components/sfa30/sfa30.cpp +1 -1
  534. esphome/components/sgp30/sgp30.cpp +10 -8
  535. esphome/components/sgp4x/sgp4x.cpp +49 -61
  536. esphome/components/sgp4x/sgp4x.h +0 -1
  537. esphome/components/shelly_dimmer/shelly_dimmer.cpp +11 -7
  538. esphome/components/sht3xd/sht3xd.cpp +1 -1
  539. esphome/components/sht4x/sht4x.cpp +2 -2
  540. esphome/components/shtcx/shtcx.cpp +13 -16
  541. esphome/components/shutdown/button/shutdown_button.cpp +1 -1
  542. esphome/components/shutdown/switch/shutdown_switch.cpp +1 -1
  543. esphome/components/sim800l/sim800l.cpp +2 -2
  544. esphome/components/slow_pwm/slow_pwm_output.cpp +4 -2
  545. esphome/components/sm16716/sm16716.cpp +1 -1
  546. esphome/components/sm2135/sm2135.cpp +1 -1
  547. esphome/components/sm2235/sm2235.cpp +5 -3
  548. esphome/components/sm2335/sm2335.cpp +5 -3
  549. esphome/components/sml/sml.cpp +1 -1
  550. esphome/components/sn74hc165/sn74hc165.cpp +1 -2
  551. esphome/components/sn74hc595/sn74hc595.cpp +1 -2
  552. esphome/components/sntp/sntp_component.cpp +1 -1
  553. esphome/components/socket/__init__.py +2 -0
  554. esphome/components/socket/bsd_sockets_impl.cpp +51 -7
  555. esphome/components/socket/lwip_raw_tcp_impl.cpp +5 -0
  556. esphome/components/socket/lwip_sockets_impl.cpp +51 -7
  557. esphome/components/socket/socket.cpp +31 -0
  558. esphome/components/socket/socket.h +27 -1
  559. esphome/components/sonoff_d1/sonoff_d1.cpp +7 -4
  560. esphome/components/sonoff_d1/sonoff_d1.h +2 -2
  561. esphome/components/sound_level/sound_level.cpp +4 -2
  562. esphome/components/speaker/media_player/__init__.py +3 -0
  563. esphome/components/speaker/media_player/speaker_media_player.cpp +1 -3
  564. esphome/components/speaker/media_player/speaker_media_player.h +6 -0
  565. esphome/components/spi/__init__.py +10 -2
  566. esphome/components/spi/spi.cpp +4 -4
  567. esphome/components/spi/spi_arduino.cpp +22 -9
  568. esphome/components/spi_device/spi_device.cpp +1 -2
  569. esphome/components/sprinkler/sprinkler.cpp +9 -6
  570. esphome/components/sps30/sps30.cpp +16 -15
  571. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  572. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +11 -8
  573. esphome/components/ssd1306_spi/ssd1306_spi.cpp +10 -7
  574. esphome/components/ssd1322_base/ssd1322_base.cpp +1 -1
  575. esphome/components/ssd1322_spi/ssd1322_spi.cpp +1 -1
  576. esphome/components/ssd1325_base/ssd1325_base.cpp +1 -1
  577. esphome/components/ssd1325_spi/ssd1325_spi.cpp +1 -1
  578. esphome/components/ssd1327_base/ssd1327_base.cpp +1 -1
  579. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +2 -2
  580. esphome/components/ssd1327_spi/ssd1327_spi.cpp +1 -1
  581. esphome/components/ssd1331_base/ssd1331_base.cpp +1 -1
  582. esphome/components/ssd1331_spi/ssd1331_spi.cpp +1 -1
  583. esphome/components/ssd1351_base/ssd1351_base.cpp +1 -1
  584. esphome/components/ssd1351_spi/ssd1351_spi.cpp +1 -1
  585. esphome/components/st7567_base/st7567_base.cpp +3 -3
  586. esphome/components/st7567_i2c/st7567_i2c.cpp +7 -5
  587. esphome/components/st7567_spi/st7567_spi.cpp +1 -1
  588. esphome/components/st7701s/st7701s.cpp +4 -2
  589. esphome/components/st7735/st7735.cpp +3 -3
  590. esphome/components/st7789v/st7789v.cpp +10 -7
  591. esphome/components/st7920/st7920.cpp +6 -4
  592. esphome/components/statsd/statsd.cpp +9 -5
  593. esphome/components/status_led/light/status_led_light.cpp +3 -3
  594. esphome/components/status_led/light/status_led_light.h +1 -1
  595. esphome/components/status_led/status_led.cpp +1 -1
  596. esphome/components/stepper/stepper.h +5 -3
  597. esphome/components/sts3x/sts3x.cpp +2 -2
  598. esphome/components/switch/__init__.py +1 -0
  599. esphome/components/switch/switch.cpp +18 -12
  600. esphome/components/switch/switch.h +14 -8
  601. esphome/components/sx1509/__init__.py +53 -20
  602. esphome/components/sx1509/sx1509.cpp +29 -5
  603. esphome/components/sx1509/sx1509.h +9 -1
  604. esphome/components/t6615/t6615.cpp +1 -0
  605. esphome/components/tc74/tc74.cpp +1 -1
  606. esphome/components/tca9548a/tca9548a.cpp +1 -1
  607. esphome/components/tca9555/tca9555.cpp +2 -2
  608. esphome/components/tcs34725/tcs34725.cpp +4 -4
  609. esphome/components/tee501/tee501.cpp +3 -2
  610. esphome/components/tem3200/tem3200.cpp +5 -6
  611. esphome/components/template/alarm_control_panel/__init__.py +6 -0
  612. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +43 -12
  613. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +4 -1
  614. esphome/components/template/cover/template_cover.cpp +1 -1
  615. esphome/components/template/select/template_select.cpp +6 -4
  616. esphome/components/template/text/template_text.cpp +2 -3
  617. esphome/components/template/valve/template_valve.cpp +5 -3
  618. esphome/components/text/__init__.py +10 -11
  619. esphome/components/text/text.cpp +1 -1
  620. esphome/components/text/text.h +0 -4
  621. esphome/components/text_sensor/__init__.py +1 -0
  622. esphome/components/text_sensor/text_sensor.cpp +8 -4
  623. esphome/components/text_sensor/text_sensor.h +6 -6
  624. esphome/components/thermostat/thermostat_climate.cpp +67 -43
  625. esphome/components/time/__init__.py +1 -2
  626. esphome/components/time_based/time_based_cover.cpp +4 -2
  627. esphome/components/tlc59208f/tlc59208f_output.cpp +8 -6
  628. esphome/components/tm1621/tm1621.cpp +3 -3
  629. esphome/components/tm1637/tm1637.cpp +9 -7
  630. esphome/components/tm1638/tm1638.cpp +7 -5
  631. esphome/components/tm1651/tm1651.cpp +2 -2
  632. esphome/components/tmp102/tmp102.cpp +1 -3
  633. esphome/components/tmp102/tmp102.h +0 -3
  634. esphome/components/tmp1075/tmp1075.cpp +12 -9
  635. esphome/components/tmp117/tmp117.cpp +2 -2
  636. esphome/components/tof10120/tof10120_sensor.cpp +2 -2
  637. esphome/components/tormatic/tormatic_cover.cpp +4 -2
  638. esphome/components/tsl2561/tsl2561.cpp +7 -5
  639. esphome/components/tsl2591/tsl2591.cpp +25 -27
  640. esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
  641. esphome/components/ttp229_bsf/ttp229_bsf.cpp +1 -1
  642. esphome/components/ttp229_lsf/ttp229_lsf.cpp +2 -2
  643. esphome/components/tuya/select/tuya_select.cpp +5 -3
  644. esphome/components/tx20/tx20.cpp +3 -3
  645. esphome/components/uart/__init__.py +4 -5
  646. esphome/components/uart/button/uart_button.cpp +1 -1
  647. esphome/components/uart/switch/uart_switch.cpp +2 -2
  648. esphome/components/uart/uart.cpp +2 -2
  649. esphome/components/uart/uart_component_esp32_arduino.cpp +8 -6
  650. esphome/components/uart/uart_component_esp8266.cpp +9 -7
  651. esphome/components/uart/uart_component_esp_idf.cpp +9 -7
  652. esphome/components/uart/uart_component_host.cpp +11 -8
  653. esphome/components/uart/uart_component_libretiny.cpp +8 -6
  654. esphome/components/uart/uart_component_rp2040.cpp +8 -6
  655. esphome/components/udp/udp_component.cpp +9 -5
  656. esphome/components/ufire_ec/ufire_ec.cpp +5 -3
  657. esphome/components/ufire_ise/ufire_ise.cpp +1 -1
  658. esphome/components/ultrasonic/ultrasonic_sensor.cpp +5 -3
  659. esphome/components/update/__init__.py +1 -0
  660. esphome/components/update/update_entity.cpp +1 -1
  661. esphome/components/update/update_entity.h +0 -3
  662. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  663. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +4 -2
  664. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  665. esphome/components/uptime/sensor/uptime_timestamp_sensor.cpp +1 -1
  666. esphome/components/usb_host/__init__.py +64 -0
  667. esphome/components/usb_host/usb_host.h +116 -0
  668. esphome/components/usb_host/usb_host_client.cpp +394 -0
  669. esphome/components/usb_host/usb_host_component.cpp +35 -0
  670. esphome/components/usb_uart/__init__.py +134 -0
  671. esphome/components/usb_uart/ch34x.cpp +80 -0
  672. esphome/components/usb_uart/cp210x.cpp +126 -0
  673. esphome/components/usb_uart/usb_uart.cpp +328 -0
  674. esphome/components/usb_uart/usb_uart.h +151 -0
  675. esphome/components/valve/__init__.py +1 -0
  676. esphome/components/veml3235/veml3235.cpp +13 -9
  677. esphome/components/veml7700/veml7700.cpp +10 -6
  678. esphome/components/voice_assistant/voice_assistant.cpp +7 -7
  679. esphome/components/wake_on_lan/wake_on_lan.cpp +1 -1
  680. esphome/components/waveshare_epaper/waveshare_epaper.cpp +1 -1
  681. esphome/components/web_server/server_index_v2.h +632 -630
  682. esphome/components/web_server/server_index_v3.h +411 -409
  683. esphome/components/web_server/web_server.cpp +5 -3
  684. esphome/components/web_server_base/web_server_base.cpp +1 -1
  685. esphome/components/web_server_idf/__init__.py +0 -2
  686. esphome/components/web_server_idf/utils.cpp +1 -1
  687. esphome/components/web_server_idf/web_server_idf.cpp +7 -3
  688. esphome/components/web_server_idf/web_server_idf.h +7 -0
  689. esphome/components/weikai/__init__.py +2 -0
  690. esphome/components/weikai/weikai.cpp +24 -22
  691. esphome/components/weikai_i2c/weikai_i2c.cpp +14 -9
  692. esphome/components/weikai_spi/weikai_spi.cpp +11 -6
  693. esphome/components/wiegand/wiegand.cpp +1 -1
  694. esphome/components/wifi/wifi_component.cpp +50 -37
  695. esphome/components/wifi/wifi_component.h +7 -4
  696. esphome/components/wifi/wifi_component_esp32_arduino.cpp +2 -2
  697. esphome/components/wifi/wifi_component_esp8266.cpp +3 -3
  698. esphome/components/wifi/wifi_component_libretiny.cpp +4 -4
  699. esphome/components/wireguard/wireguard.cpp +21 -21
  700. esphome/components/wl_134/text_sensor.py +1 -2
  701. esphome/components/wled/wled_light_effect.cpp +1 -1
  702. esphome/components/x9c/x9c.cpp +5 -3
  703. esphome/components/xgzp68xx/xgzp68xx.cpp +8 -6
  704. esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp +4 -2
  705. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.cpp +4 -2
  706. esphome/components/xiaomi_cgg1/xiaomi_cgg1.cpp +4 -2
  707. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.cpp +1 -1
  708. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp +4 -2
  709. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp +4 -2
  710. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.cpp +4 -2
  711. esphome/components/xl9535/xl9535.cpp +2 -2
  712. esphome/components/xpt2046/touchscreen/xpt2046.cpp +12 -11
  713. esphome/components/xpt2046/touchscreen/xpt2046.h +2 -2
  714. esphome/config.py +3 -2
  715. esphome/config_validation.py +46 -17
  716. esphome/const.py +10 -1
  717. esphome/core/__init__.py +37 -18
  718. esphome/core/application.cpp +197 -8
  719. esphome/core/application.h +116 -6
  720. esphome/core/component.cpp +36 -15
  721. esphome/core/component.h +43 -13
  722. esphome/core/config.py +12 -0
  723. esphome/core/defines.h +10 -2
  724. esphome/core/entity_base.cpp +4 -16
  725. esphome/core/entity_base.h +27 -13
  726. esphome/core/hal.h +5 -0
  727. esphome/core/helpers.cpp +1 -1
  728. esphome/core/helpers.h +5 -5
  729. esphome/core/log.h +2 -0
  730. esphome/core/log_const_en.h +4 -0
  731. esphome/core/scheduler.cpp +2 -2
  732. esphome/coroutine.py +3 -4
  733. esphome/cpp_generator.py +32 -32
  734. esphome/dashboard/core.py +2 -2
  735. esphome/dashboard/web_server.py +2 -2
  736. esphome/git.py +4 -4
  737. esphome/helpers.py +5 -6
  738. esphome/loader.py +8 -7
  739. esphome/log.py +7 -1
  740. esphome/platformio_api.py +2 -3
  741. esphome/storage_json.py +13 -5
  742. esphome/types.py +12 -13
  743. esphome/util.py +1 -2
  744. esphome/wizard.py +0 -16
  745. esphome/writer.py +5 -3
  746. esphome/yaml_util.py +6 -1
  747. esphome/zeroconf.py +1 -1
  748. {esphome-2025.5.1.dist-info → esphome-2025.6.0.dist-info}/METADATA +12 -11
  749. {esphome-2025.5.1.dist-info → esphome-2025.6.0.dist-info}/RECORD +753 -699
  750. {esphome-2025.5.1.dist-info → esphome-2025.6.0.dist-info}/WHEEL +1 -1
  751. {esphome-2025.5.1.dist-info → esphome-2025.6.0.dist-info}/entry_points.txt +0 -0
  752. {esphome-2025.5.1.dist-info → esphome-2025.6.0.dist-info}/licenses/LICENSE +0 -0
  753. {esphome-2025.5.1.dist-info → esphome-2025.6.0.dist-info}/top_level.txt +0 -0
@@ -3,6 +3,8 @@
3
3
  #include <cerrno>
4
4
  #include <cinttypes>
5
5
  #include <utility>
6
+ #include <functional>
7
+ #include <limits>
6
8
  #include "esphome/components/network/util.h"
7
9
  #include "esphome/core/application.h"
8
10
  #include "esphome/core/entity_base.h"
@@ -29,40 +31,8 @@ namespace api {
29
31
  static const char *const TAG = "api.connection";
30
32
  static const int ESP32_CAMERA_STOP_STREAM = 5000;
31
33
 
32
- // helper for allowing only unique entries in the queue
33
- void DeferredMessageQueue::dmq_push_back_with_dedup_(void *source, send_message_t send_message) {
34
- DeferredMessage item(source, send_message);
35
-
36
- auto iter = std::find_if(this->deferred_queue_.begin(), this->deferred_queue_.end(),
37
- [&item](const DeferredMessage &test) -> bool { return test == item; });
38
-
39
- if (iter != this->deferred_queue_.end()) {
40
- (*iter) = item;
41
- } else {
42
- this->deferred_queue_.push_back(item);
43
- }
44
- }
45
-
46
- void DeferredMessageQueue::process_queue() {
47
- while (!deferred_queue_.empty()) {
48
- DeferredMessage &de = deferred_queue_.front();
49
- if ((this->api_connection_->*(de.send_message_))(de.source_)) {
50
- // O(n) but memory efficiency is more important than speed here which is why std::vector was chosen
51
- deferred_queue_.erase(deferred_queue_.begin());
52
- } else {
53
- break;
54
- }
55
- }
56
- }
57
-
58
- void DeferredMessageQueue::defer(void *source, send_message_t send_message) {
59
- this->dmq_push_back_with_dedup_(source, send_message);
60
- }
61
-
62
34
  APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *parent)
63
- : parent_(parent), deferred_message_queue_(this), initial_state_iterator_(this), list_entities_iterator_(this) {
64
- this->proto_write_buffer_.reserve(64);
65
-
35
+ : parent_(parent), initial_state_iterator_(this), list_entities_iterator_(this) {
66
36
  #if defined(USE_API_PLAINTEXT) && defined(USE_API_NOISE)
67
37
  auto noise_ctx = parent->get_noise_ctx();
68
38
  if (noise_ctx->has_psk()) {
@@ -78,6 +48,9 @@ APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *pa
78
48
  #error "No frame helper defined"
79
49
  #endif
80
50
  }
51
+
52
+ uint32_t APIConnection::get_batch_delay_ms_() const { return this->parent_->get_batch_delay(); }
53
+
81
54
  void APIConnection::start() {
82
55
  this->last_traffic_ = App.get_loop_component_start_time();
83
56
 
@@ -118,7 +91,7 @@ void APIConnection::loop() {
118
91
  // when network is disconnected force disconnect immediately
119
92
  // don't wait for timeout
120
93
  this->on_fatal_error();
121
- ESP_LOGW(TAG, "%s: Network unavailable, disconnecting", this->client_combined_info_.c_str());
94
+ ESP_LOGW(TAG, "%s: Network unavailable; disconnecting", this->client_combined_info_.c_str());
122
95
  return;
123
96
  }
124
97
  if (this->next_close_) {
@@ -135,35 +108,41 @@ void APIConnection::loop() {
135
108
  api_error_to_str(err), errno);
136
109
  return;
137
110
  }
138
- ReadPacketBuffer buffer;
139
- err = this->helper_->read_packet(&buffer);
140
- if (err == APIError::WOULD_BLOCK) {
141
- // pass
142
- } else if (err != APIError::OK) {
143
- on_fatal_error();
144
- if (err == APIError::SOCKET_READ_FAILED && errno == ECONNRESET) {
145
- ESP_LOGW(TAG, "%s: Connection reset", this->client_combined_info_.c_str());
146
- } else if (err == APIError::CONNECTION_CLOSED) {
147
- ESP_LOGW(TAG, "%s: Connection closed", this->client_combined_info_.c_str());
148
- } else {
149
- ESP_LOGW(TAG, "%s: Reading failed: %s errno=%d", this->client_combined_info_.c_str(), api_error_to_str(err),
150
- errno);
151
- }
152
- return;
153
- } else {
154
- this->last_traffic_ = App.get_loop_component_start_time();
155
- // read a packet
156
- if (buffer.data_len > 0) {
157
- this->read_message(buffer.data_len, buffer.type, &buffer.container[buffer.data_offset]);
111
+
112
+ // Check if socket has data ready before attempting to read
113
+ if (this->helper_->is_socket_ready()) {
114
+ ReadPacketBuffer buffer;
115
+ err = this->helper_->read_packet(&buffer);
116
+ if (err == APIError::WOULD_BLOCK) {
117
+ // pass
118
+ } else if (err != APIError::OK) {
119
+ on_fatal_error();
120
+ if (err == APIError::SOCKET_READ_FAILED && errno == ECONNRESET) {
121
+ ESP_LOGW(TAG, "%s: Connection reset", this->client_combined_info_.c_str());
122
+ } else if (err == APIError::CONNECTION_CLOSED) {
123
+ ESP_LOGW(TAG, "%s: Connection closed", this->client_combined_info_.c_str());
124
+ } else {
125
+ ESP_LOGW(TAG, "%s: Reading failed: %s errno=%d", this->client_combined_info_.c_str(), api_error_to_str(err),
126
+ errno);
127
+ }
128
+ return;
158
129
  } else {
159
- this->read_message(0, buffer.type, nullptr);
130
+ this->last_traffic_ = App.get_loop_component_start_time();
131
+ // read a packet
132
+ if (buffer.data_len > 0) {
133
+ this->read_message(buffer.data_len, buffer.type, &buffer.container[buffer.data_offset]);
134
+ } else {
135
+ this->read_message(0, buffer.type, nullptr);
136
+ }
137
+ if (this->remove_)
138
+ return;
160
139
  }
161
- if (this->remove_)
162
- return;
163
140
  }
164
141
 
165
- if (!this->deferred_message_queue_.empty() && this->helper_->can_write_without_blocking()) {
166
- this->deferred_message_queue_.process_queue();
142
+ // Process deferred batch if scheduled
143
+ if (this->deferred_batch_.batch_scheduled &&
144
+ App.get_loop_component_start_time() - this->deferred_batch_.batch_start_time >= this->get_batch_delay_ms_()) {
145
+ this->process_batch_();
167
146
  }
168
147
 
169
148
  if (!this->list_entities_iterator_.completed())
@@ -178,42 +157,30 @@ void APIConnection::loop() {
178
157
  // Disconnect if not responded within 2.5*keepalive
179
158
  if (now - this->last_traffic_ > (KEEPALIVE_TIMEOUT_MS * 5) / 2) {
180
159
  on_fatal_error();
181
- ESP_LOGW(TAG, "%s didn't respond to ping request in time. Disconnecting...", this->client_combined_info_.c_str());
160
+ ESP_LOGW(TAG, "%s is unresponsive; disconnecting", this->client_combined_info_.c_str());
182
161
  }
183
162
  } else if (now - this->last_traffic_ > KEEPALIVE_TIMEOUT_MS && now > this->next_ping_retry_) {
184
- ESP_LOGVV(TAG, "Sending keepalive PING...");
185
- this->sent_ping_ = this->send_ping_request(PingRequest());
163
+ ESP_LOGVV(TAG, "Sending keepalive PING");
164
+ this->sent_ping_ = this->send_message(PingRequest());
186
165
  if (!this->sent_ping_) {
187
166
  this->next_ping_retry_ = now + ping_retry_interval;
188
167
  this->ping_retries_++;
168
+ std::string warn_str = str_sprintf("%s: Sending keepalive failed %u time(s);",
169
+ this->client_combined_info_.c_str(), this->ping_retries_);
189
170
  if (this->ping_retries_ >= max_ping_retries) {
190
171
  on_fatal_error();
191
- ESP_LOGE(TAG, "%s: Sending keepalive failed %d time(s). Disconnecting...", this->client_combined_info_.c_str(),
192
- this->ping_retries_);
172
+ ESP_LOGE(TAG, "%s disconnecting", warn_str.c_str());
193
173
  } else if (this->ping_retries_ >= 10) {
194
- ESP_LOGW(TAG, "%s: Sending keepalive failed %d time(s), will retry in %d ms",
195
- this->client_combined_info_.c_str(), this->ping_retries_, ping_retry_interval);
174
+ ESP_LOGW(TAG, "%s retrying in %u ms", warn_str.c_str(), ping_retry_interval);
196
175
  } else {
197
- ESP_LOGD(TAG, "%s: Sending keepalive failed %d time(s), will retry in %d ms",
198
- this->client_combined_info_.c_str(), this->ping_retries_, ping_retry_interval);
176
+ ESP_LOGD(TAG, "%s retrying in %u ms", warn_str.c_str(), ping_retry_interval);
199
177
  }
200
178
  }
201
179
  }
202
180
 
203
181
  #ifdef USE_ESP32_CAMERA
204
182
  if (this->image_reader_.available() && this->helper_->can_write_without_blocking()) {
205
- // Message will use 8 more bytes than the minimum size, and typical
206
- // MTU is 1500. Sometimes users will see as low as 1460 MTU.
207
- // If its IPv6 the header is 40 bytes, and if its IPv4
208
- // the header is 20 bytes. So we have 1460 - 40 = 1420 bytes
209
- // available for the payload. But we also need to add the size of
210
- // the protobuf overhead, which is 8 bytes.
211
- //
212
- // To be safe we pick 1390 bytes as the maximum size
213
- // to send in one go. This is the maximum size of a single packet
214
- // that can be sent over the network.
215
- // This is to avoid fragmentation of the packet.
216
- uint32_t to_send = std::min((size_t) 1390, this->image_reader_.available());
183
+ uint32_t to_send = std::min((size_t) MAX_PACKET_SIZE, this->image_reader_.available());
217
184
  bool done = this->image_reader_.available() == to_send;
218
185
  uint32_t msg_size = 0;
219
186
  ProtoSize::add_fixed_field<4>(msg_size, 1, true);
@@ -251,7 +218,7 @@ void APIConnection::loop() {
251
218
  resp.entity_id = it.entity_id;
252
219
  resp.attribute = it.attribute.value();
253
220
  resp.once = it.once;
254
- if (this->send_subscribe_home_assistant_state_response(resp)) {
221
+ if (this->send_message(resp)) {
255
222
  state_subs_at_++;
256
223
  }
257
224
  }
@@ -266,54 +233,100 @@ DisconnectResponse APIConnection::disconnect(const DisconnectRequest &msg) {
266
233
  // remote initiated disconnect_client
267
234
  // don't close yet, we still need to send the disconnect response
268
235
  // close will happen on next loop
269
- ESP_LOGD(TAG, "%s requested disconnected", this->client_combined_info_.c_str());
236
+ ESP_LOGD(TAG, "%s disconnected", this->client_combined_info_.c_str());
270
237
  this->next_close_ = true;
271
238
  DisconnectResponse resp;
272
239
  return resp;
273
240
  }
274
241
  void APIConnection::on_disconnect_response(const DisconnectResponse &value) {
275
- // pass
242
+ this->helper_->close();
243
+ this->remove_ = true;
244
+ }
245
+
246
+ // Encodes a message to the buffer and returns the total number of bytes used,
247
+ // including header and footer overhead. Returns 0 if the message doesn't fit.
248
+ uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg, uint16_t message_type, APIConnection *conn,
249
+ uint32_t remaining_size, bool is_single) {
250
+ // Calculate size
251
+ uint32_t calculated_size = 0;
252
+ msg.calculate_size(calculated_size);
253
+
254
+ // Cache frame sizes to avoid repeated virtual calls
255
+ const uint8_t header_padding = conn->helper_->frame_header_padding();
256
+ const uint8_t footer_size = conn->helper_->frame_footer_size();
257
+
258
+ // Calculate total size with padding for buffer allocation
259
+ size_t total_calculated_size = calculated_size + header_padding + footer_size;
260
+
261
+ // Check if it fits
262
+ if (total_calculated_size > remaining_size) {
263
+ return 0; // Doesn't fit
264
+ }
265
+
266
+ // Allocate buffer space - pass payload size, allocation functions add header/footer space
267
+ ProtoWriteBuffer buffer = is_single ? conn->allocate_single_message_buffer(calculated_size)
268
+ : conn->allocate_batch_message_buffer(calculated_size);
269
+
270
+ // Get buffer size after allocation (which includes header padding)
271
+ std::vector<uint8_t> &shared_buf = conn->parent_->get_shared_buffer_ref();
272
+ size_t size_before_encode = shared_buf.size();
273
+
274
+ // Encode directly into buffer
275
+ msg.encode(buffer);
276
+
277
+ // Calculate actual encoded size (not including header that was already added)
278
+ size_t actual_payload_size = shared_buf.size() - size_before_encode;
279
+
280
+ // Return actual total size (header + actual payload + footer)
281
+ size_t actual_total_size = header_padding + actual_payload_size + footer_size;
282
+
283
+ // Verify that calculate_size() returned the correct value
284
+ assert(calculated_size == actual_payload_size);
285
+ return static_cast<uint16_t>(actual_total_size);
276
286
  }
277
287
 
278
288
  #ifdef USE_BINARY_SENSOR
279
- bool APIConnection::send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor, bool state) {
280
- return this->send_state_with_value_(binary_sensor, &APIConnection::try_send_binary_sensor_state_,
281
- &APIConnection::try_send_binary_sensor_state_, state);
289
+ bool APIConnection::send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor) {
290
+ return this->schedule_message_(binary_sensor, &APIConnection::try_send_binary_sensor_state,
291
+ BinarySensorStateResponse::MESSAGE_TYPE);
282
292
  }
283
293
  void APIConnection::send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor) {
284
- this->send_info_(static_cast<EntityBase *>(binary_sensor),
285
- reinterpret_cast<send_message_t>(&APIConnection::try_send_binary_sensor_info_));
286
- }
287
- bool APIConnection::try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor) {
288
- return this->try_send_binary_sensor_state_(binary_sensor, binary_sensor->state);
294
+ this->schedule_message_(binary_sensor, &APIConnection::try_send_binary_sensor_info,
295
+ ListEntitiesBinarySensorResponse::MESSAGE_TYPE);
289
296
  }
290
- bool APIConnection::try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor, bool state) {
291
- BinarySensorStateResponse msg;
292
- msg.state = state;
293
- msg.missing_state = !binary_sensor->has_state();
294
- msg.key = binary_sensor->get_object_id_hash();
295
- return this->send_binary_sensor_state_response(msg);
297
+
298
+ uint16_t APIConnection::try_send_binary_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
299
+ bool is_single) {
300
+ auto *binary_sensor = static_cast<binary_sensor::BinarySensor *>(entity);
301
+ BinarySensorStateResponse resp;
302
+ resp.state = binary_sensor->state;
303
+ resp.missing_state = !binary_sensor->has_state();
304
+ fill_entity_state_base(binary_sensor, resp);
305
+ return encode_message_to_buffer(resp, BinarySensorStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
296
306
  }
297
- bool APIConnection::try_send_binary_sensor_info_(binary_sensor::BinarySensor *binary_sensor) {
307
+
308
+ uint16_t APIConnection::try_send_binary_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
309
+ bool is_single) {
310
+ auto *binary_sensor = static_cast<binary_sensor::BinarySensor *>(entity);
298
311
  ListEntitiesBinarySensorResponse msg;
299
312
  msg.device_class = binary_sensor->get_device_class();
300
313
  msg.is_status_binary_sensor = binary_sensor->is_status_binary_sensor();
301
314
  msg.unique_id = get_default_unique_id("binary_sensor", binary_sensor);
302
- return this->try_send_entity_info_(static_cast<EntityBase *>(binary_sensor), msg,
303
- &APIConnection::send_list_entities_binary_sensor_response);
315
+ fill_entity_info_base(binary_sensor, msg);
316
+ return encode_message_to_buffer(msg, ListEntitiesBinarySensorResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
304
317
  }
305
318
  #endif
306
319
 
307
320
  #ifdef USE_COVER
308
321
  bool APIConnection::send_cover_state(cover::Cover *cover) {
309
- return this->send_state_(static_cast<EntityBase *>(cover),
310
- reinterpret_cast<send_message_t>(&APIConnection::try_send_cover_state_));
322
+ return this->schedule_message_(cover, &APIConnection::try_send_cover_state, CoverStateResponse::MESSAGE_TYPE);
311
323
  }
312
324
  void APIConnection::send_cover_info(cover::Cover *cover) {
313
- this->send_info_(static_cast<EntityBase *>(cover),
314
- reinterpret_cast<send_message_t>(&APIConnection::try_send_cover_info_));
325
+ this->schedule_message_(cover, &APIConnection::try_send_cover_info, ListEntitiesCoverResponse::MESSAGE_TYPE);
315
326
  }
316
- bool APIConnection::try_send_cover_state_(cover::Cover *cover) {
327
+ uint16_t APIConnection::try_send_cover_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
328
+ bool is_single) {
329
+ auto *cover = static_cast<cover::Cover *>(entity);
317
330
  CoverStateResponse msg;
318
331
  auto traits = cover->get_traits();
319
332
  msg.legacy_state =
@@ -322,10 +335,12 @@ bool APIConnection::try_send_cover_state_(cover::Cover *cover) {
322
335
  if (traits.get_supports_tilt())
323
336
  msg.tilt = cover->tilt;
324
337
  msg.current_operation = static_cast<enums::CoverOperation>(cover->current_operation);
325
- msg.key = cover->get_object_id_hash();
326
- return this->send_cover_state_response(msg);
338
+ fill_entity_state_base(cover, msg);
339
+ return encode_message_to_buffer(msg, CoverStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
327
340
  }
328
- bool APIConnection::try_send_cover_info_(cover::Cover *cover) {
341
+ uint16_t APIConnection::try_send_cover_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
342
+ bool is_single) {
343
+ auto *cover = static_cast<cover::Cover *>(entity);
329
344
  ListEntitiesCoverResponse msg;
330
345
  auto traits = cover->get_traits();
331
346
  msg.assumed_state = traits.get_is_assumed_state();
@@ -334,8 +349,8 @@ bool APIConnection::try_send_cover_info_(cover::Cover *cover) {
334
349
  msg.supports_stop = traits.get_supports_stop();
335
350
  msg.device_class = cover->get_device_class();
336
351
  msg.unique_id = get_default_unique_id("cover", cover);
337
- return this->try_send_entity_info_(static_cast<EntityBase *>(cover), msg,
338
- &APIConnection::send_list_entities_cover_response);
352
+ fill_entity_info_base(cover, msg);
353
+ return encode_message_to_buffer(msg, ListEntitiesCoverResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
339
354
  }
340
355
  void APIConnection::cover_command(const CoverCommandRequest &msg) {
341
356
  cover::Cover *cover = App.get_cover_by_key(msg.key);
@@ -368,14 +383,14 @@ void APIConnection::cover_command(const CoverCommandRequest &msg) {
368
383
 
369
384
  #ifdef USE_FAN
370
385
  bool APIConnection::send_fan_state(fan::Fan *fan) {
371
- return this->send_state_(static_cast<EntityBase *>(fan),
372
- reinterpret_cast<send_message_t>(&APIConnection::try_send_fan_state_));
386
+ return this->schedule_message_(fan, &APIConnection::try_send_fan_state, FanStateResponse::MESSAGE_TYPE);
373
387
  }
374
388
  void APIConnection::send_fan_info(fan::Fan *fan) {
375
- this->send_info_(static_cast<EntityBase *>(fan),
376
- reinterpret_cast<send_message_t>(&APIConnection::try_send_fan_info_));
389
+ this->schedule_message_(fan, &APIConnection::try_send_fan_info, ListEntitiesFanResponse::MESSAGE_TYPE);
377
390
  }
378
- bool APIConnection::try_send_fan_state_(fan::Fan *fan) {
391
+ uint16_t APIConnection::try_send_fan_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
392
+ bool is_single) {
393
+ auto *fan = static_cast<fan::Fan *>(entity);
379
394
  FanStateResponse msg;
380
395
  auto traits = fan->get_traits();
381
396
  msg.state = fan->state;
@@ -388,10 +403,12 @@ bool APIConnection::try_send_fan_state_(fan::Fan *fan) {
388
403
  msg.direction = static_cast<enums::FanDirection>(fan->direction);
389
404
  if (traits.supports_preset_modes())
390
405
  msg.preset_mode = fan->preset_mode;
391
- msg.key = fan->get_object_id_hash();
392
- return this->send_fan_state_response(msg);
406
+ fill_entity_state_base(fan, msg);
407
+ return encode_message_to_buffer(msg, FanStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
393
408
  }
394
- bool APIConnection::try_send_fan_info_(fan::Fan *fan) {
409
+ uint16_t APIConnection::try_send_fan_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
410
+ bool is_single) {
411
+ auto *fan = static_cast<fan::Fan *>(entity);
395
412
  ListEntitiesFanResponse msg;
396
413
  auto traits = fan->get_traits();
397
414
  msg.supports_oscillation = traits.supports_oscillation();
@@ -401,8 +418,8 @@ bool APIConnection::try_send_fan_info_(fan::Fan *fan) {
401
418
  for (auto const &preset : traits.supported_preset_modes())
402
419
  msg.supported_preset_modes.push_back(preset);
403
420
  msg.unique_id = get_default_unique_id("fan", fan);
404
- return this->try_send_entity_info_(static_cast<EntityBase *>(fan), msg,
405
- &APIConnection::send_list_entities_fan_response);
421
+ fill_entity_info_base(fan, msg);
422
+ return encode_message_to_buffer(msg, ListEntitiesFanResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
406
423
  }
407
424
  void APIConnection::fan_command(const FanCommandRequest &msg) {
408
425
  fan::Fan *fan = App.get_fan_by_key(msg.key);
@@ -428,14 +445,14 @@ void APIConnection::fan_command(const FanCommandRequest &msg) {
428
445
 
429
446
  #ifdef USE_LIGHT
430
447
  bool APIConnection::send_light_state(light::LightState *light) {
431
- return this->send_state_(static_cast<EntityBase *>(light),
432
- reinterpret_cast<send_message_t>(&APIConnection::try_send_light_state_));
448
+ return this->schedule_message_(light, &APIConnection::try_send_light_state, LightStateResponse::MESSAGE_TYPE);
433
449
  }
434
450
  void APIConnection::send_light_info(light::LightState *light) {
435
- this->send_info_(static_cast<EntityBase *>(light),
436
- reinterpret_cast<send_message_t>(&APIConnection::try_send_light_info_));
451
+ this->schedule_message_(light, &APIConnection::try_send_light_info, ListEntitiesLightResponse::MESSAGE_TYPE);
437
452
  }
438
- bool APIConnection::try_send_light_state_(light::LightState *light) {
453
+ uint16_t APIConnection::try_send_light_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
454
+ bool is_single) {
455
+ auto *light = static_cast<light::LightState *>(entity);
439
456
  LightStateResponse resp;
440
457
  auto traits = light->get_traits();
441
458
  auto values = light->remote_values;
@@ -453,10 +470,12 @@ bool APIConnection::try_send_light_state_(light::LightState *light) {
453
470
  resp.warm_white = values.get_warm_white();
454
471
  if (light->supports_effects())
455
472
  resp.effect = light->get_effect_name();
456
- resp.key = light->get_object_id_hash();
457
- return this->send_light_state_response(resp);
473
+ fill_entity_state_base(light, resp);
474
+ return encode_message_to_buffer(resp, LightStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
458
475
  }
459
- bool APIConnection::try_send_light_info_(light::LightState *light) {
476
+ uint16_t APIConnection::try_send_light_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
477
+ bool is_single) {
478
+ auto *light = static_cast<light::LightState *>(entity);
460
479
  ListEntitiesLightResponse msg;
461
480
  auto traits = light->get_traits();
462
481
  for (auto mode : traits.get_supported_color_modes())
@@ -479,8 +498,8 @@ bool APIConnection::try_send_light_info_(light::LightState *light) {
479
498
  }
480
499
  }
481
500
  msg.unique_id = get_default_unique_id("light", light);
482
- return this->try_send_entity_info_(static_cast<EntityBase *>(light), msg,
483
- &APIConnection::send_list_entities_light_response);
501
+ fill_entity_info_base(light, msg);
502
+ return encode_message_to_buffer(msg, ListEntitiesLightResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
484
503
  }
485
504
  void APIConnection::light_command(const LightCommandRequest &msg) {
486
505
  light::LightState *light = App.get_light_by_key(msg.key);
@@ -520,26 +539,26 @@ void APIConnection::light_command(const LightCommandRequest &msg) {
520
539
  #endif
521
540
 
522
541
  #ifdef USE_SENSOR
523
- bool APIConnection::send_sensor_state(sensor::Sensor *sensor, float state) {
524
- return this->send_state_with_value_(sensor, &APIConnection::try_send_sensor_state_,
525
- &APIConnection::try_send_sensor_state_, state);
542
+ bool APIConnection::send_sensor_state(sensor::Sensor *sensor) {
543
+ return this->schedule_message_(sensor, &APIConnection::try_send_sensor_state, SensorStateResponse::MESSAGE_TYPE);
526
544
  }
527
545
  void APIConnection::send_sensor_info(sensor::Sensor *sensor) {
528
- this->send_info_(static_cast<EntityBase *>(sensor),
529
- reinterpret_cast<send_message_t>(&APIConnection::try_send_sensor_info_));
546
+ this->schedule_message_(sensor, &APIConnection::try_send_sensor_info, ListEntitiesSensorResponse::MESSAGE_TYPE);
530
547
  }
531
- bool APIConnection::try_send_sensor_state_(sensor::Sensor *sensor) {
532
- return this->try_send_sensor_state_(sensor, sensor->state);
533
- }
534
- bool APIConnection::try_send_sensor_state_(sensor::Sensor *sensor, float state) {
548
+
549
+ uint16_t APIConnection::try_send_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
550
+ bool is_single) {
551
+ auto *sensor = static_cast<sensor::Sensor *>(entity);
535
552
  SensorStateResponse resp;
536
- resp.state = state;
553
+ resp.state = sensor->state;
537
554
  resp.missing_state = !sensor->has_state();
538
-
539
- resp.key = sensor->get_object_id_hash();
540
- return this->send_sensor_state_response(resp);
555
+ fill_entity_state_base(sensor, resp);
556
+ return encode_message_to_buffer(resp, SensorStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
541
557
  }
542
- bool APIConnection::try_send_sensor_info_(sensor::Sensor *sensor) {
558
+
559
+ uint16_t APIConnection::try_send_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
560
+ bool is_single) {
561
+ auto *sensor = static_cast<sensor::Sensor *>(entity);
543
562
  ListEntitiesSensorResponse msg;
544
563
  msg.unit_of_measurement = sensor->get_unit_of_measurement();
545
564
  msg.accuracy_decimals = sensor->get_accuracy_decimals();
@@ -549,37 +568,37 @@ bool APIConnection::try_send_sensor_info_(sensor::Sensor *sensor) {
549
568
  msg.unique_id = sensor->unique_id();
550
569
  if (msg.unique_id.empty())
551
570
  msg.unique_id = get_default_unique_id("sensor", sensor);
552
- return this->try_send_entity_info_(static_cast<EntityBase *>(sensor), msg,
553
- &APIConnection::send_list_entities_sensor_response);
571
+ fill_entity_info_base(sensor, msg);
572
+ return encode_message_to_buffer(msg, ListEntitiesSensorResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
554
573
  }
555
574
  #endif
556
575
 
557
576
  #ifdef USE_SWITCH
558
- bool APIConnection::send_switch_state(switch_::Switch *a_switch, bool state) {
559
- return this->send_state_with_value_(a_switch, &APIConnection::try_send_switch_state_,
560
- &APIConnection::try_send_switch_state_, state);
577
+ bool APIConnection::send_switch_state(switch_::Switch *a_switch) {
578
+ return this->schedule_message_(a_switch, &APIConnection::try_send_switch_state, SwitchStateResponse::MESSAGE_TYPE);
561
579
  }
562
580
  void APIConnection::send_switch_info(switch_::Switch *a_switch) {
563
- this->send_info_(static_cast<EntityBase *>(a_switch),
564
- reinterpret_cast<send_message_t>(&APIConnection::try_send_switch_info_));
581
+ this->schedule_message_(a_switch, &APIConnection::try_send_switch_info, ListEntitiesSwitchResponse::MESSAGE_TYPE);
565
582
  }
566
- bool APIConnection::try_send_switch_state_(switch_::Switch *a_switch) {
567
- return this->try_send_switch_state_(a_switch, a_switch->state);
568
- }
569
- bool APIConnection::try_send_switch_state_(switch_::Switch *a_switch, bool state) {
570
- SwitchStateResponse resp;
571
- resp.state = state;
572
583
 
573
- resp.key = a_switch->get_object_id_hash();
574
- return this->send_switch_state_response(resp);
584
+ uint16_t APIConnection::try_send_switch_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
585
+ bool is_single) {
586
+ auto *a_switch = static_cast<switch_::Switch *>(entity);
587
+ SwitchStateResponse resp;
588
+ resp.state = a_switch->state;
589
+ fill_entity_state_base(a_switch, resp);
590
+ return encode_message_to_buffer(resp, SwitchStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
575
591
  }
576
- bool APIConnection::try_send_switch_info_(switch_::Switch *a_switch) {
592
+
593
+ uint16_t APIConnection::try_send_switch_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
594
+ bool is_single) {
595
+ auto *a_switch = static_cast<switch_::Switch *>(entity);
577
596
  ListEntitiesSwitchResponse msg;
578
597
  msg.assumed_state = a_switch->assumed_state();
579
598
  msg.device_class = a_switch->get_device_class();
580
599
  msg.unique_id = get_default_unique_id("switch", a_switch);
581
- return this->try_send_entity_info_(static_cast<EntityBase *>(a_switch), msg,
582
- &APIConnection::send_list_entities_switch_response);
600
+ fill_entity_info_base(a_switch, msg);
601
+ return encode_message_to_buffer(msg, ListEntitiesSwitchResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
583
602
  }
584
603
  void APIConnection::switch_command(const SwitchCommandRequest &msg) {
585
604
  switch_::Switch *a_switch = App.get_switch_by_key(msg.key);
@@ -595,48 +614,46 @@ void APIConnection::switch_command(const SwitchCommandRequest &msg) {
595
614
  #endif
596
615
 
597
616
  #ifdef USE_TEXT_SENSOR
598
- bool APIConnection::send_text_sensor_state(text_sensor::TextSensor *text_sensor, std::string state) {
599
- return this->send_state_with_value_(text_sensor, &APIConnection::try_send_text_sensor_state_,
600
- &APIConnection::try_send_text_sensor_state_, std::move(state));
617
+ bool APIConnection::send_text_sensor_state(text_sensor::TextSensor *text_sensor) {
618
+ return this->schedule_message_(text_sensor, &APIConnection::try_send_text_sensor_state,
619
+ TextSensorStateResponse::MESSAGE_TYPE);
601
620
  }
602
621
  void APIConnection::send_text_sensor_info(text_sensor::TextSensor *text_sensor) {
603
- this->send_info_(static_cast<EntityBase *>(text_sensor),
604
- reinterpret_cast<send_message_t>(&APIConnection::try_send_text_sensor_info_));
622
+ this->schedule_message_(text_sensor, &APIConnection::try_send_text_sensor_info,
623
+ ListEntitiesTextSensorResponse::MESSAGE_TYPE);
605
624
  }
606
- bool APIConnection::try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor) {
607
- return this->try_send_text_sensor_state_(text_sensor, text_sensor->state);
608
- }
609
- bool APIConnection::try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor, std::string state) {
625
+
626
+ uint16_t APIConnection::try_send_text_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
627
+ bool is_single) {
628
+ auto *text_sensor = static_cast<text_sensor::TextSensor *>(entity);
610
629
  TextSensorStateResponse resp;
611
- resp.state = std::move(state);
630
+ resp.state = text_sensor->state;
612
631
  resp.missing_state = !text_sensor->has_state();
613
-
614
- resp.key = text_sensor->get_object_id_hash();
615
- return this->send_text_sensor_state_response(resp);
632
+ fill_entity_state_base(text_sensor, resp);
633
+ return encode_message_to_buffer(resp, TextSensorStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
616
634
  }
617
- bool APIConnection::try_send_text_sensor_info_(text_sensor::TextSensor *text_sensor) {
635
+ uint16_t APIConnection::try_send_text_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
636
+ bool is_single) {
637
+ auto *text_sensor = static_cast<text_sensor::TextSensor *>(entity);
618
638
  ListEntitiesTextSensorResponse msg;
619
639
  msg.device_class = text_sensor->get_device_class();
620
640
  msg.unique_id = text_sensor->unique_id();
621
641
  if (msg.unique_id.empty())
622
642
  msg.unique_id = get_default_unique_id("text_sensor", text_sensor);
623
- return this->try_send_entity_info_(static_cast<EntityBase *>(text_sensor), msg,
624
- &APIConnection::send_list_entities_text_sensor_response);
643
+ fill_entity_info_base(text_sensor, msg);
644
+ return encode_message_to_buffer(msg, ListEntitiesTextSensorResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
625
645
  }
626
646
  #endif
627
647
 
628
648
  #ifdef USE_CLIMATE
629
649
  bool APIConnection::send_climate_state(climate::Climate *climate) {
630
- return this->send_state_(static_cast<EntityBase *>(climate),
631
- reinterpret_cast<send_message_t>(&APIConnection::try_send_climate_state_));
650
+ return this->schedule_message_(climate, &APIConnection::try_send_climate_state, ClimateStateResponse::MESSAGE_TYPE);
632
651
  }
633
- void APIConnection::send_climate_info(climate::Climate *climate) {
634
- this->send_info_(static_cast<EntityBase *>(climate),
635
- reinterpret_cast<send_message_t>(&APIConnection::try_send_climate_info_));
636
- }
637
- bool APIConnection::try_send_climate_state_(climate::Climate *climate) {
652
+ uint16_t APIConnection::try_send_climate_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
653
+ bool is_single) {
654
+ auto *climate = static_cast<climate::Climate *>(entity);
638
655
  ClimateStateResponse resp;
639
- resp.key = climate->get_object_id_hash();
656
+ fill_entity_state_base(climate, resp);
640
657
  auto traits = climate->get_traits();
641
658
  resp.mode = static_cast<enums::ClimateMode>(climate->mode);
642
659
  resp.action = static_cast<enums::ClimateAction>(climate->action);
@@ -663,9 +680,14 @@ bool APIConnection::try_send_climate_state_(climate::Climate *climate) {
663
680
  resp.current_humidity = climate->current_humidity;
664
681
  if (traits.get_supports_target_humidity())
665
682
  resp.target_humidity = climate->target_humidity;
666
- return this->send_climate_state_response(resp);
683
+ return encode_message_to_buffer(resp, ClimateStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
684
+ }
685
+ void APIConnection::send_climate_info(climate::Climate *climate) {
686
+ this->schedule_message_(climate, &APIConnection::try_send_climate_info, ListEntitiesClimateResponse::MESSAGE_TYPE);
667
687
  }
668
- bool APIConnection::try_send_climate_info_(climate::Climate *climate) {
688
+ uint16_t APIConnection::try_send_climate_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
689
+ bool is_single) {
690
+ auto *climate = static_cast<climate::Climate *>(entity);
669
691
  ListEntitiesClimateResponse msg;
670
692
  auto traits = climate->get_traits();
671
693
  msg.supports_current_temperature = traits.get_supports_current_temperature();
@@ -693,8 +715,8 @@ bool APIConnection::try_send_climate_info_(climate::Climate *climate) {
693
715
  for (auto swing_mode : traits.get_supported_swing_modes())
694
716
  msg.supported_swing_modes.push_back(static_cast<enums::ClimateSwingMode>(swing_mode));
695
717
  msg.unique_id = get_default_unique_id("climate", climate);
696
- return this->try_send_entity_info_(static_cast<EntityBase *>(climate), msg,
697
- &APIConnection::send_list_entities_climate_response);
718
+ fill_entity_info_base(climate, msg);
719
+ return encode_message_to_buffer(msg, ListEntitiesClimateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
698
720
  }
699
721
  void APIConnection::climate_command(const ClimateCommandRequest &msg) {
700
722
  climate::Climate *climate = App.get_climate_by_key(msg.key);
@@ -727,26 +749,26 @@ void APIConnection::climate_command(const ClimateCommandRequest &msg) {
727
749
  #endif
728
750
 
729
751
  #ifdef USE_NUMBER
730
- bool APIConnection::send_number_state(number::Number *number, float state) {
731
- return this->send_state_with_value_(number, &APIConnection::try_send_number_state_,
732
- &APIConnection::try_send_number_state_, state);
752
+ bool APIConnection::send_number_state(number::Number *number) {
753
+ return this->schedule_message_(number, &APIConnection::try_send_number_state, NumberStateResponse::MESSAGE_TYPE);
733
754
  }
734
755
  void APIConnection::send_number_info(number::Number *number) {
735
- this->send_info_(static_cast<EntityBase *>(number),
736
- reinterpret_cast<send_message_t>(&APIConnection::try_send_number_info_));
756
+ this->schedule_message_(number, &APIConnection::try_send_number_info, ListEntitiesNumberResponse::MESSAGE_TYPE);
737
757
  }
738
- bool APIConnection::try_send_number_state_(number::Number *number) {
739
- return this->try_send_number_state_(number, number->state);
740
- }
741
- bool APIConnection::try_send_number_state_(number::Number *number, float state) {
758
+
759
+ uint16_t APIConnection::try_send_number_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
760
+ bool is_single) {
761
+ auto *number = static_cast<number::Number *>(entity);
742
762
  NumberStateResponse resp;
743
- resp.state = state;
763
+ resp.state = number->state;
744
764
  resp.missing_state = !number->has_state();
745
-
746
- resp.key = number->get_object_id_hash();
747
- return this->send_number_state_response(resp);
765
+ fill_entity_state_base(number, resp);
766
+ return encode_message_to_buffer(resp, NumberStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
748
767
  }
749
- bool APIConnection::try_send_number_info_(number::Number *number) {
768
+
769
+ uint16_t APIConnection::try_send_number_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
770
+ bool is_single) {
771
+ auto *number = static_cast<number::Number *>(entity);
750
772
  ListEntitiesNumberResponse msg;
751
773
  msg.unit_of_measurement = number->traits.get_unit_of_measurement();
752
774
  msg.mode = static_cast<enums::NumberMode>(number->traits.get_mode());
@@ -755,8 +777,8 @@ bool APIConnection::try_send_number_info_(number::Number *number) {
755
777
  msg.max_value = number->traits.get_max_value();
756
778
  msg.step = number->traits.get_step();
757
779
  msg.unique_id = get_default_unique_id("number", number);
758
- return this->try_send_entity_info_(static_cast<EntityBase *>(number), msg,
759
- &APIConnection::send_list_entities_number_response);
780
+ fill_entity_info_base(number, msg);
781
+ return encode_message_to_buffer(msg, ListEntitiesNumberResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
760
782
  }
761
783
  void APIConnection::number_command(const NumberCommandRequest &msg) {
762
784
  number::Number *number = App.get_number_by_key(msg.key);
@@ -771,28 +793,29 @@ void APIConnection::number_command(const NumberCommandRequest &msg) {
771
793
 
772
794
  #ifdef USE_DATETIME_DATE
773
795
  bool APIConnection::send_date_state(datetime::DateEntity *date) {
774
- return this->send_state_(static_cast<EntityBase *>(date),
775
- reinterpret_cast<send_message_t>(&APIConnection::try_send_date_state_));
796
+ return this->schedule_message_(date, &APIConnection::try_send_date_state, DateStateResponse::MESSAGE_TYPE);
776
797
  }
777
- void APIConnection::send_date_info(datetime::DateEntity *date) {
778
- this->send_info_(static_cast<EntityBase *>(date),
779
- reinterpret_cast<send_message_t>(&APIConnection::try_send_date_info_));
780
- }
781
- bool APIConnection::try_send_date_state_(datetime::DateEntity *date) {
798
+ uint16_t APIConnection::try_send_date_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
799
+ bool is_single) {
800
+ auto *date = static_cast<datetime::DateEntity *>(entity);
782
801
  DateStateResponse resp;
783
802
  resp.missing_state = !date->has_state();
784
803
  resp.year = date->year;
785
804
  resp.month = date->month;
786
805
  resp.day = date->day;
787
-
788
- resp.key = date->get_object_id_hash();
789
- return this->send_date_state_response(resp);
806
+ fill_entity_state_base(date, resp);
807
+ return encode_message_to_buffer(resp, DateStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
790
808
  }
791
- bool APIConnection::try_send_date_info_(datetime::DateEntity *date) {
809
+ void APIConnection::send_date_info(datetime::DateEntity *date) {
810
+ this->schedule_message_(date, &APIConnection::try_send_date_info, ListEntitiesDateResponse::MESSAGE_TYPE);
811
+ }
812
+ uint16_t APIConnection::try_send_date_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
813
+ bool is_single) {
814
+ auto *date = static_cast<datetime::DateEntity *>(entity);
792
815
  ListEntitiesDateResponse msg;
793
816
  msg.unique_id = get_default_unique_id("date", date);
794
- return this->try_send_entity_info_(static_cast<EntityBase *>(date), msg,
795
- &APIConnection::send_list_entities_date_response);
817
+ fill_entity_info_base(date, msg);
818
+ return encode_message_to_buffer(msg, ListEntitiesDateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
796
819
  }
797
820
  void APIConnection::date_command(const DateCommandRequest &msg) {
798
821
  datetime::DateEntity *date = App.get_date_by_key(msg.key);
@@ -807,28 +830,29 @@ void APIConnection::date_command(const DateCommandRequest &msg) {
807
830
 
808
831
  #ifdef USE_DATETIME_TIME
809
832
  bool APIConnection::send_time_state(datetime::TimeEntity *time) {
810
- return this->send_state_(static_cast<EntityBase *>(time),
811
- reinterpret_cast<send_message_t>(&APIConnection::try_send_time_state_));
812
- }
813
- void APIConnection::send_time_info(datetime::TimeEntity *time) {
814
- this->send_info_(static_cast<EntityBase *>(time),
815
- reinterpret_cast<send_message_t>(&APIConnection::try_send_time_info_));
833
+ return this->schedule_message_(time, &APIConnection::try_send_time_state, TimeStateResponse::MESSAGE_TYPE);
816
834
  }
817
- bool APIConnection::try_send_time_state_(datetime::TimeEntity *time) {
835
+ uint16_t APIConnection::try_send_time_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
836
+ bool is_single) {
837
+ auto *time = static_cast<datetime::TimeEntity *>(entity);
818
838
  TimeStateResponse resp;
819
839
  resp.missing_state = !time->has_state();
820
840
  resp.hour = time->hour;
821
841
  resp.minute = time->minute;
822
842
  resp.second = time->second;
823
-
824
- resp.key = time->get_object_id_hash();
825
- return this->send_time_state_response(resp);
843
+ fill_entity_state_base(time, resp);
844
+ return encode_message_to_buffer(resp, TimeStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
845
+ }
846
+ void APIConnection::send_time_info(datetime::TimeEntity *time) {
847
+ this->schedule_message_(time, &APIConnection::try_send_time_info, ListEntitiesTimeResponse::MESSAGE_TYPE);
826
848
  }
827
- bool APIConnection::try_send_time_info_(datetime::TimeEntity *time) {
849
+ uint16_t APIConnection::try_send_time_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
850
+ bool is_single) {
851
+ auto *time = static_cast<datetime::TimeEntity *>(entity);
828
852
  ListEntitiesTimeResponse msg;
829
853
  msg.unique_id = get_default_unique_id("time", time);
830
- return this->try_send_entity_info_(static_cast<EntityBase *>(time), msg,
831
- &APIConnection::send_list_entities_time_response);
854
+ fill_entity_info_base(time, msg);
855
+ return encode_message_to_buffer(msg, ListEntitiesTimeResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
832
856
  }
833
857
  void APIConnection::time_command(const TimeCommandRequest &msg) {
834
858
  datetime::TimeEntity *time = App.get_time_by_key(msg.key);
@@ -843,29 +867,31 @@ void APIConnection::time_command(const TimeCommandRequest &msg) {
843
867
 
844
868
  #ifdef USE_DATETIME_DATETIME
845
869
  bool APIConnection::send_datetime_state(datetime::DateTimeEntity *datetime) {
846
- return this->send_state_(static_cast<EntityBase *>(datetime),
847
- reinterpret_cast<send_message_t>(&APIConnection::try_send_datetime_state_));
848
- }
849
- void APIConnection::send_datetime_info(datetime::DateTimeEntity *datetime) {
850
- this->send_info_(static_cast<EntityBase *>(datetime),
851
- reinterpret_cast<send_message_t>(&APIConnection::try_send_datetime_info_));
870
+ return this->schedule_message_(datetime, &APIConnection::try_send_datetime_state,
871
+ DateTimeStateResponse::MESSAGE_TYPE);
852
872
  }
853
- bool APIConnection::try_send_datetime_state_(datetime::DateTimeEntity *datetime) {
873
+ uint16_t APIConnection::try_send_datetime_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
874
+ bool is_single) {
875
+ auto *datetime = static_cast<datetime::DateTimeEntity *>(entity);
854
876
  DateTimeStateResponse resp;
855
877
  resp.missing_state = !datetime->has_state();
856
878
  if (datetime->has_state()) {
857
879
  ESPTime state = datetime->state_as_esptime();
858
880
  resp.epoch_seconds = state.timestamp;
859
881
  }
860
-
861
- resp.key = datetime->get_object_id_hash();
862
- return this->send_date_time_state_response(resp);
882
+ fill_entity_state_base(datetime, resp);
883
+ return encode_message_to_buffer(resp, DateTimeStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
884
+ }
885
+ void APIConnection::send_datetime_info(datetime::DateTimeEntity *datetime) {
886
+ this->schedule_message_(datetime, &APIConnection::try_send_datetime_info, ListEntitiesDateTimeResponse::MESSAGE_TYPE);
863
887
  }
864
- bool APIConnection::try_send_datetime_info_(datetime::DateTimeEntity *datetime) {
888
+ uint16_t APIConnection::try_send_datetime_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
889
+ bool is_single) {
890
+ auto *datetime = static_cast<datetime::DateTimeEntity *>(entity);
865
891
  ListEntitiesDateTimeResponse msg;
866
892
  msg.unique_id = get_default_unique_id("datetime", datetime);
867
- return this->try_send_entity_info_(static_cast<EntityBase *>(datetime), msg,
868
- &APIConnection::send_list_entities_date_time_response);
893
+ fill_entity_info_base(datetime, msg);
894
+ return encode_message_to_buffer(msg, ListEntitiesDateTimeResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
869
895
  }
870
896
  void APIConnection::datetime_command(const DateTimeCommandRequest &msg) {
871
897
  datetime::DateTimeEntity *datetime = App.get_datetime_by_key(msg.key);
@@ -879,32 +905,34 @@ void APIConnection::datetime_command(const DateTimeCommandRequest &msg) {
879
905
  #endif
880
906
 
881
907
  #ifdef USE_TEXT
882
- bool APIConnection::send_text_state(text::Text *text, std::string state) {
883
- return this->send_state_with_value_(text, &APIConnection::try_send_text_state_, &APIConnection::try_send_text_state_,
884
- std::move(state));
908
+ bool APIConnection::send_text_state(text::Text *text) {
909
+ return this->schedule_message_(text, &APIConnection::try_send_text_state, TextStateResponse::MESSAGE_TYPE);
885
910
  }
886
911
  void APIConnection::send_text_info(text::Text *text) {
887
- this->send_info_(static_cast<EntityBase *>(text),
888
- reinterpret_cast<send_message_t>(&APIConnection::try_send_text_info_));
912
+ this->schedule_message_(text, &APIConnection::try_send_text_info, ListEntitiesTextResponse::MESSAGE_TYPE);
889
913
  }
890
- bool APIConnection::try_send_text_state_(text::Text *text) { return this->try_send_text_state_(text, text->state); }
891
- bool APIConnection::try_send_text_state_(text::Text *text, std::string state) {
914
+
915
+ uint16_t APIConnection::try_send_text_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
916
+ bool is_single) {
917
+ auto *text = static_cast<text::Text *>(entity);
892
918
  TextStateResponse resp;
893
- resp.state = std::move(state);
919
+ resp.state = text->state;
894
920
  resp.missing_state = !text->has_state();
895
-
896
- resp.key = text->get_object_id_hash();
897
- return this->send_text_state_response(resp);
921
+ fill_entity_state_base(text, resp);
922
+ return encode_message_to_buffer(resp, TextStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
898
923
  }
899
- bool APIConnection::try_send_text_info_(text::Text *text) {
924
+
925
+ uint16_t APIConnection::try_send_text_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
926
+ bool is_single) {
927
+ auto *text = static_cast<text::Text *>(entity);
900
928
  ListEntitiesTextResponse msg;
901
929
  msg.mode = static_cast<enums::TextMode>(text->traits.get_mode());
902
930
  msg.min_length = text->traits.get_min_length();
903
931
  msg.max_length = text->traits.get_max_length();
904
932
  msg.pattern = text->traits.get_pattern();
905
933
  msg.unique_id = get_default_unique_id("text", text);
906
- return this->try_send_entity_info_(static_cast<EntityBase *>(text), msg,
907
- &APIConnection::send_list_entities_text_response);
934
+ fill_entity_info_base(text, msg);
935
+ return encode_message_to_buffer(msg, ListEntitiesTextResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
908
936
  }
909
937
  void APIConnection::text_command(const TextCommandRequest &msg) {
910
938
  text::Text *text = App.get_text_by_key(msg.key);
@@ -918,32 +946,32 @@ void APIConnection::text_command(const TextCommandRequest &msg) {
918
946
  #endif
919
947
 
920
948
  #ifdef USE_SELECT
921
- bool APIConnection::send_select_state(select::Select *select, std::string state) {
922
- return this->send_state_with_value_(select, &APIConnection::try_send_select_state_,
923
- &APIConnection::try_send_select_state_, std::move(state));
949
+ bool APIConnection::send_select_state(select::Select *select) {
950
+ return this->schedule_message_(select, &APIConnection::try_send_select_state, SelectStateResponse::MESSAGE_TYPE);
924
951
  }
925
952
  void APIConnection::send_select_info(select::Select *select) {
926
- this->send_info_(static_cast<EntityBase *>(select),
927
- reinterpret_cast<send_message_t>(&APIConnection::try_send_select_info_));
928
- }
929
- bool APIConnection::try_send_select_state_(select::Select *select) {
930
- return this->try_send_select_state_(select, select->state);
953
+ this->schedule_message_(select, &APIConnection::try_send_select_info, ListEntitiesSelectResponse::MESSAGE_TYPE);
931
954
  }
932
- bool APIConnection::try_send_select_state_(select::Select *select, std::string state) {
955
+
956
+ uint16_t APIConnection::try_send_select_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
957
+ bool is_single) {
958
+ auto *select = static_cast<select::Select *>(entity);
933
959
  SelectStateResponse resp;
934
- resp.state = std::move(state);
960
+ resp.state = select->state;
935
961
  resp.missing_state = !select->has_state();
936
-
937
- resp.key = select->get_object_id_hash();
938
- return this->send_select_state_response(resp);
962
+ fill_entity_state_base(select, resp);
963
+ return encode_message_to_buffer(resp, SelectStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
939
964
  }
940
- bool APIConnection::try_send_select_info_(select::Select *select) {
965
+
966
+ uint16_t APIConnection::try_send_select_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
967
+ bool is_single) {
968
+ auto *select = static_cast<select::Select *>(entity);
941
969
  ListEntitiesSelectResponse msg;
942
970
  for (const auto &option : select->traits.get_options())
943
971
  msg.options.push_back(option);
944
972
  msg.unique_id = get_default_unique_id("select", select);
945
- return this->try_send_entity_info_(static_cast<EntityBase *>(select), msg,
946
- &APIConnection::send_list_entities_select_response);
973
+ fill_entity_info_base(select, msg);
974
+ return encode_message_to_buffer(msg, ListEntitiesSelectResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
947
975
  }
948
976
  void APIConnection::select_command(const SelectCommandRequest &msg) {
949
977
  select::Select *select = App.get_select_by_key(msg.key);
@@ -958,15 +986,16 @@ void APIConnection::select_command(const SelectCommandRequest &msg) {
958
986
 
959
987
  #ifdef USE_BUTTON
960
988
  void esphome::api::APIConnection::send_button_info(button::Button *button) {
961
- this->send_info_(static_cast<EntityBase *>(button),
962
- reinterpret_cast<send_message_t>(&APIConnection::try_send_button_info_));
989
+ this->schedule_message_(button, &APIConnection::try_send_button_info, ListEntitiesButtonResponse::MESSAGE_TYPE);
963
990
  }
964
- bool esphome::api::APIConnection::try_send_button_info_(button::Button *button) {
991
+ uint16_t APIConnection::try_send_button_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
992
+ bool is_single) {
993
+ auto *button = static_cast<button::Button *>(entity);
965
994
  ListEntitiesButtonResponse msg;
966
995
  msg.device_class = button->get_device_class();
967
996
  msg.unique_id = get_default_unique_id("button", button);
968
- return this->try_send_entity_info_(static_cast<EntityBase *>(button), msg,
969
- &APIConnection::send_list_entities_button_response);
997
+ fill_entity_info_base(button, msg);
998
+ return encode_message_to_buffer(msg, ListEntitiesButtonResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
970
999
  }
971
1000
  void esphome::api::APIConnection::button_command(const ButtonCommandRequest &msg) {
972
1001
  button::Button *button = App.get_button_by_key(msg.key);
@@ -978,32 +1007,32 @@ void esphome::api::APIConnection::button_command(const ButtonCommandRequest &msg
978
1007
  #endif
979
1008
 
980
1009
  #ifdef USE_LOCK
981
- bool APIConnection::send_lock_state(lock::Lock *a_lock, lock::LockState state) {
982
- return this->send_state_with_value_(a_lock, &APIConnection::try_send_lock_state_,
983
- &APIConnection::try_send_lock_state_, state);
1010
+ bool APIConnection::send_lock_state(lock::Lock *a_lock) {
1011
+ return this->schedule_message_(a_lock, &APIConnection::try_send_lock_state, LockStateResponse::MESSAGE_TYPE);
984
1012
  }
985
1013
  void APIConnection::send_lock_info(lock::Lock *a_lock) {
986
- this->send_info_(static_cast<EntityBase *>(a_lock),
987
- reinterpret_cast<send_message_t>(&APIConnection::try_send_lock_info_));
1014
+ this->schedule_message_(a_lock, &APIConnection::try_send_lock_info, ListEntitiesLockResponse::MESSAGE_TYPE);
988
1015
  }
989
- bool APIConnection::try_send_lock_state_(lock::Lock *a_lock) {
990
- return this->try_send_lock_state_(a_lock, a_lock->state);
991
- }
992
- bool APIConnection::try_send_lock_state_(lock::Lock *a_lock, lock::LockState state) {
993
- LockStateResponse resp;
994
- resp.state = static_cast<enums::LockState>(state);
995
1016
 
996
- resp.key = a_lock->get_object_id_hash();
997
- return this->send_lock_state_response(resp);
1017
+ uint16_t APIConnection::try_send_lock_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1018
+ bool is_single) {
1019
+ auto *a_lock = static_cast<lock::Lock *>(entity);
1020
+ LockStateResponse resp;
1021
+ resp.state = static_cast<enums::LockState>(a_lock->state);
1022
+ fill_entity_state_base(a_lock, resp);
1023
+ return encode_message_to_buffer(resp, LockStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
998
1024
  }
999
- bool APIConnection::try_send_lock_info_(lock::Lock *a_lock) {
1025
+
1026
+ uint16_t APIConnection::try_send_lock_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1027
+ bool is_single) {
1028
+ auto *a_lock = static_cast<lock::Lock *>(entity);
1000
1029
  ListEntitiesLockResponse msg;
1001
1030
  msg.assumed_state = a_lock->traits.get_assumed_state();
1002
1031
  msg.supports_open = a_lock->traits.get_supports_open();
1003
1032
  msg.requires_code = a_lock->traits.get_requires_code();
1004
1033
  msg.unique_id = get_default_unique_id("lock", a_lock);
1005
- return this->try_send_entity_info_(static_cast<EntityBase *>(a_lock), msg,
1006
- &APIConnection::send_list_entities_lock_response);
1034
+ fill_entity_info_base(a_lock, msg);
1035
+ return encode_message_to_buffer(msg, ListEntitiesLockResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1007
1036
  }
1008
1037
  void APIConnection::lock_command(const LockCommandRequest &msg) {
1009
1038
  lock::Lock *a_lock = App.get_lock_by_key(msg.key);
@@ -1026,22 +1055,23 @@ void APIConnection::lock_command(const LockCommandRequest &msg) {
1026
1055
 
1027
1056
  #ifdef USE_VALVE
1028
1057
  bool APIConnection::send_valve_state(valve::Valve *valve) {
1029
- return this->send_state_(static_cast<EntityBase *>(valve),
1030
- reinterpret_cast<send_message_t>(&APIConnection::try_send_valve_state_));
1058
+ return this->schedule_message_(valve, &APIConnection::try_send_valve_state, ValveStateResponse::MESSAGE_TYPE);
1031
1059
  }
1032
- void APIConnection::send_valve_info(valve::Valve *valve) {
1033
- this->send_info_(static_cast<EntityBase *>(valve),
1034
- reinterpret_cast<send_message_t>(&APIConnection::try_send_valve_info_));
1035
- }
1036
- bool APIConnection::try_send_valve_state_(valve::Valve *valve) {
1060
+ uint16_t APIConnection::try_send_valve_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1061
+ bool is_single) {
1062
+ auto *valve = static_cast<valve::Valve *>(entity);
1037
1063
  ValveStateResponse resp;
1038
1064
  resp.position = valve->position;
1039
1065
  resp.current_operation = static_cast<enums::ValveOperation>(valve->current_operation);
1040
-
1041
- resp.key = valve->get_object_id_hash();
1042
- return this->send_valve_state_response(resp);
1066
+ fill_entity_state_base(valve, resp);
1067
+ return encode_message_to_buffer(resp, ValveStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1043
1068
  }
1044
- bool APIConnection::try_send_valve_info_(valve::Valve *valve) {
1069
+ void APIConnection::send_valve_info(valve::Valve *valve) {
1070
+ this->schedule_message_(valve, &APIConnection::try_send_valve_info, ListEntitiesValveResponse::MESSAGE_TYPE);
1071
+ }
1072
+ uint16_t APIConnection::try_send_valve_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1073
+ bool is_single) {
1074
+ auto *valve = static_cast<valve::Valve *>(entity);
1045
1075
  ListEntitiesValveResponse msg;
1046
1076
  auto traits = valve->get_traits();
1047
1077
  msg.device_class = valve->get_device_class();
@@ -1049,8 +1079,8 @@ bool APIConnection::try_send_valve_info_(valve::Valve *valve) {
1049
1079
  msg.supports_position = traits.get_supports_position();
1050
1080
  msg.supports_stop = traits.get_supports_stop();
1051
1081
  msg.unique_id = get_default_unique_id("valve", valve);
1052
- return this->try_send_entity_info_(static_cast<EntityBase *>(valve), msg,
1053
- &APIConnection::send_list_entities_valve_response);
1082
+ fill_entity_info_base(valve, msg);
1083
+ return encode_message_to_buffer(msg, ListEntitiesValveResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1054
1084
  }
1055
1085
  void APIConnection::valve_command(const ValveCommandRequest &msg) {
1056
1086
  valve::Valve *valve = App.get_valve_by_key(msg.key);
@@ -1068,14 +1098,12 @@ void APIConnection::valve_command(const ValveCommandRequest &msg) {
1068
1098
 
1069
1099
  #ifdef USE_MEDIA_PLAYER
1070
1100
  bool APIConnection::send_media_player_state(media_player::MediaPlayer *media_player) {
1071
- return this->send_state_(static_cast<EntityBase *>(media_player),
1072
- reinterpret_cast<send_message_t>(&APIConnection::try_send_media_player_state_));
1073
- }
1074
- void APIConnection::send_media_player_info(media_player::MediaPlayer *media_player) {
1075
- this->send_info_(static_cast<EntityBase *>(media_player),
1076
- reinterpret_cast<send_message_t>(&APIConnection::try_send_media_player_info_));
1101
+ return this->schedule_message_(media_player, &APIConnection::try_send_media_player_state,
1102
+ MediaPlayerStateResponse::MESSAGE_TYPE);
1077
1103
  }
1078
- bool APIConnection::try_send_media_player_state_(media_player::MediaPlayer *media_player) {
1104
+ uint16_t APIConnection::try_send_media_player_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1105
+ bool is_single) {
1106
+ auto *media_player = static_cast<media_player::MediaPlayer *>(entity);
1079
1107
  MediaPlayerStateResponse resp;
1080
1108
  media_player::MediaPlayerState report_state = media_player->state == media_player::MEDIA_PLAYER_STATE_ANNOUNCING
1081
1109
  ? media_player::MEDIA_PLAYER_STATE_PLAYING
@@ -1083,11 +1111,16 @@ bool APIConnection::try_send_media_player_state_(media_player::MediaPlayer *medi
1083
1111
  resp.state = static_cast<enums::MediaPlayerState>(report_state);
1084
1112
  resp.volume = media_player->volume;
1085
1113
  resp.muted = media_player->is_muted();
1086
-
1087
- resp.key = media_player->get_object_id_hash();
1088
- return this->send_media_player_state_response(resp);
1114
+ fill_entity_state_base(media_player, resp);
1115
+ return encode_message_to_buffer(resp, MediaPlayerStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1089
1116
  }
1090
- bool APIConnection::try_send_media_player_info_(media_player::MediaPlayer *media_player) {
1117
+ void APIConnection::send_media_player_info(media_player::MediaPlayer *media_player) {
1118
+ this->schedule_message_(media_player, &APIConnection::try_send_media_player_info,
1119
+ ListEntitiesMediaPlayerResponse::MESSAGE_TYPE);
1120
+ }
1121
+ uint16_t APIConnection::try_send_media_player_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1122
+ bool is_single) {
1123
+ auto *media_player = static_cast<media_player::MediaPlayer *>(entity);
1091
1124
  ListEntitiesMediaPlayerResponse msg;
1092
1125
  auto traits = media_player->get_traits();
1093
1126
  msg.supports_pause = traits.get_supports_pause();
@@ -1101,8 +1134,8 @@ bool APIConnection::try_send_media_player_info_(media_player::MediaPlayer *media
1101
1134
  msg.supported_formats.push_back(media_format);
1102
1135
  }
1103
1136
  msg.unique_id = get_default_unique_id("media_player", media_player);
1104
- return this->try_send_entity_info_(static_cast<EntityBase *>(media_player), msg,
1105
- &APIConnection::send_list_entities_media_player_response);
1137
+ fill_entity_info_base(media_player, msg);
1138
+ return encode_message_to_buffer(msg, ListEntitiesMediaPlayerResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1106
1139
  }
1107
1140
  void APIConnection::media_player_command(const MediaPlayerCommandRequest &msg) {
1108
1141
  media_player::MediaPlayer *media_player = App.get_media_player_by_key(msg.key);
@@ -1137,14 +1170,15 @@ void APIConnection::set_camera_state(std::shared_ptr<esp32_camera::CameraImage>
1137
1170
  this->image_reader_.set_image(std::move(image));
1138
1171
  }
1139
1172
  void APIConnection::send_camera_info(esp32_camera::ESP32Camera *camera) {
1140
- this->send_info_(static_cast<EntityBase *>(camera),
1141
- reinterpret_cast<send_message_t>(&APIConnection::try_send_camera_info_));
1173
+ this->schedule_message_(camera, &APIConnection::try_send_camera_info, ListEntitiesCameraResponse::MESSAGE_TYPE);
1142
1174
  }
1143
- bool APIConnection::try_send_camera_info_(esp32_camera::ESP32Camera *camera) {
1175
+ uint16_t APIConnection::try_send_camera_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1176
+ bool is_single) {
1177
+ auto *camera = static_cast<esp32_camera::ESP32Camera *>(entity);
1144
1178
  ListEntitiesCameraResponse msg;
1145
1179
  msg.unique_id = get_default_unique_id("camera", camera);
1146
- return this->try_send_entity_info_(static_cast<EntityBase *>(camera), msg,
1147
- &APIConnection::send_list_entities_camera_response);
1180
+ fill_entity_info_base(camera, msg);
1181
+ return encode_message_to_buffer(msg, ListEntitiesCameraResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1148
1182
  }
1149
1183
  void APIConnection::camera_image(const CameraImageRequest &msg) {
1150
1184
  if (esp32_camera::global_esp32_camera == nullptr)
@@ -1187,9 +1221,9 @@ bool APIConnection::send_bluetooth_le_advertisement(const BluetoothLEAdvertiseme
1187
1221
  manufacturer_data.legacy_data.assign(manufacturer_data.data.begin(), manufacturer_data.data.end());
1188
1222
  manufacturer_data.data.clear();
1189
1223
  }
1190
- return this->send_bluetooth_le_advertisement_response(resp);
1224
+ return this->send_message(resp);
1191
1225
  }
1192
- return this->send_bluetooth_le_advertisement_response(msg);
1226
+ return this->send_message(msg);
1193
1227
  }
1194
1228
  void APIConnection::bluetooth_device_request(const BluetoothDeviceRequest &msg) {
1195
1229
  bluetooth_proxy::global_bluetooth_proxy->bluetooth_device_request(msg);
@@ -1333,28 +1367,32 @@ void APIConnection::voice_assistant_set_configuration(const VoiceAssistantSetCon
1333
1367
 
1334
1368
  #ifdef USE_ALARM_CONTROL_PANEL
1335
1369
  bool APIConnection::send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
1336
- return this->send_state_(static_cast<EntityBase *>(a_alarm_control_panel),
1337
- reinterpret_cast<send_message_t>(&APIConnection::try_send_alarm_control_panel_state_));
1370
+ return this->schedule_message_(a_alarm_control_panel, &APIConnection::try_send_alarm_control_panel_state,
1371
+ AlarmControlPanelStateResponse::MESSAGE_TYPE);
1338
1372
  }
1339
- void APIConnection::send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
1340
- this->send_info_(static_cast<EntityBase *>(a_alarm_control_panel),
1341
- reinterpret_cast<send_message_t>(&APIConnection::try_send_alarm_control_panel_info_));
1342
- }
1343
- bool APIConnection::try_send_alarm_control_panel_state_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
1373
+ uint16_t APIConnection::try_send_alarm_control_panel_state(EntityBase *entity, APIConnection *conn,
1374
+ uint32_t remaining_size, bool is_single) {
1375
+ auto *a_alarm_control_panel = static_cast<alarm_control_panel::AlarmControlPanel *>(entity);
1344
1376
  AlarmControlPanelStateResponse resp;
1345
1377
  resp.state = static_cast<enums::AlarmControlPanelState>(a_alarm_control_panel->get_state());
1346
-
1347
- resp.key = a_alarm_control_panel->get_object_id_hash();
1348
- return this->send_alarm_control_panel_state_response(resp);
1378
+ fill_entity_state_base(a_alarm_control_panel, resp);
1379
+ return encode_message_to_buffer(resp, AlarmControlPanelStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1380
+ }
1381
+ void APIConnection::send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
1382
+ this->schedule_message_(a_alarm_control_panel, &APIConnection::try_send_alarm_control_panel_info,
1383
+ ListEntitiesAlarmControlPanelResponse::MESSAGE_TYPE);
1349
1384
  }
1350
- bool APIConnection::try_send_alarm_control_panel_info_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
1385
+ uint16_t APIConnection::try_send_alarm_control_panel_info(EntityBase *entity, APIConnection *conn,
1386
+ uint32_t remaining_size, bool is_single) {
1387
+ auto *a_alarm_control_panel = static_cast<alarm_control_panel::AlarmControlPanel *>(entity);
1351
1388
  ListEntitiesAlarmControlPanelResponse msg;
1352
1389
  msg.supported_features = a_alarm_control_panel->get_supported_features();
1353
1390
  msg.requires_code = a_alarm_control_panel->get_requires_code();
1354
1391
  msg.requires_code_to_arm = a_alarm_control_panel->get_requires_code_to_arm();
1355
1392
  msg.unique_id = get_default_unique_id("alarm_control_panel", a_alarm_control_panel);
1356
- return this->try_send_entity_info_(static_cast<EntityBase *>(a_alarm_control_panel), msg,
1357
- &APIConnection::send_list_entities_alarm_control_panel_response);
1393
+ fill_entity_info_base(a_alarm_control_panel, msg);
1394
+ return encode_message_to_buffer(msg, ListEntitiesAlarmControlPanelResponse::MESSAGE_TYPE, conn, remaining_size,
1395
+ is_single);
1358
1396
  }
1359
1397
  void APIConnection::alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) {
1360
1398
  alarm_control_panel::AlarmControlPanel *a_alarm_control_panel = App.get_alarm_control_panel_by_key(msg.key);
@@ -1391,45 +1429,40 @@ void APIConnection::alarm_control_panel_command(const AlarmControlPanelCommandRe
1391
1429
  #endif
1392
1430
 
1393
1431
  #ifdef USE_EVENT
1394
- void APIConnection::send_event(event::Event *event, std::string event_type) {
1395
- this->send_state_with_value_(event, &APIConnection::try_send_event_, &APIConnection::try_send_event_,
1396
- std::move(event_type));
1432
+ void APIConnection::send_event(event::Event *event, const std::string &event_type) {
1433
+ this->schedule_message_(event, MessageCreator(event_type, EventResponse::MESSAGE_TYPE), EventResponse::MESSAGE_TYPE);
1397
1434
  }
1398
1435
  void APIConnection::send_event_info(event::Event *event) {
1399
- this->send_info_(static_cast<EntityBase *>(event),
1400
- reinterpret_cast<send_message_t>(&APIConnection::try_send_event_info_));
1436
+ this->schedule_message_(event, &APIConnection::try_send_event_info, ListEntitiesEventResponse::MESSAGE_TYPE);
1401
1437
  }
1402
- bool APIConnection::try_send_event_(event::Event *event) {
1403
- return this->try_send_event_(event, *(event->last_event_type));
1404
- }
1405
- bool APIConnection::try_send_event_(event::Event *event, std::string event_type) {
1438
+ uint16_t APIConnection::try_send_event_response(event::Event *event, const std::string &event_type, APIConnection *conn,
1439
+ uint32_t remaining_size, bool is_single) {
1406
1440
  EventResponse resp;
1407
- resp.event_type = std::move(event_type);
1408
-
1409
- resp.key = event->get_object_id_hash();
1410
- return this->send_event_response(resp);
1441
+ resp.event_type = event_type;
1442
+ fill_entity_state_base(event, resp);
1443
+ return encode_message_to_buffer(resp, EventResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1411
1444
  }
1412
- bool APIConnection::try_send_event_info_(event::Event *event) {
1445
+
1446
+ uint16_t APIConnection::try_send_event_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1447
+ bool is_single) {
1448
+ auto *event = static_cast<event::Event *>(entity);
1413
1449
  ListEntitiesEventResponse msg;
1414
1450
  msg.device_class = event->get_device_class();
1415
1451
  for (const auto &event_type : event->get_event_types())
1416
1452
  msg.event_types.push_back(event_type);
1417
1453
  msg.unique_id = get_default_unique_id("event", event);
1418
- return this->try_send_entity_info_(static_cast<EntityBase *>(event), msg,
1419
- &APIConnection::send_list_entities_event_response);
1454
+ fill_entity_info_base(event, msg);
1455
+ return encode_message_to_buffer(msg, ListEntitiesEventResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1420
1456
  }
1421
1457
  #endif
1422
1458
 
1423
1459
  #ifdef USE_UPDATE
1424
1460
  bool APIConnection::send_update_state(update::UpdateEntity *update) {
1425
- return this->send_state_(static_cast<EntityBase *>(update),
1426
- reinterpret_cast<send_message_t>(&APIConnection::try_send_update_state_));
1461
+ return this->schedule_message_(update, &APIConnection::try_send_update_state, UpdateStateResponse::MESSAGE_TYPE);
1427
1462
  }
1428
- void APIConnection::send_update_info(update::UpdateEntity *update) {
1429
- this->send_info_(static_cast<EntityBase *>(update),
1430
- reinterpret_cast<send_message_t>(&APIConnection::try_send_update_info_));
1431
- }
1432
- bool APIConnection::try_send_update_state_(update::UpdateEntity *update) {
1463
+ uint16_t APIConnection::try_send_update_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1464
+ bool is_single) {
1465
+ auto *update = static_cast<update::UpdateEntity *>(entity);
1433
1466
  UpdateStateResponse resp;
1434
1467
  resp.missing_state = !update->has_state();
1435
1468
  if (update->has_state()) {
@@ -1444,16 +1477,20 @@ bool APIConnection::try_send_update_state_(update::UpdateEntity *update) {
1444
1477
  resp.release_summary = update->update_info.summary;
1445
1478
  resp.release_url = update->update_info.release_url;
1446
1479
  }
1447
-
1448
- resp.key = update->get_object_id_hash();
1449
- return this->send_update_state_response(resp);
1480
+ fill_entity_state_base(update, resp);
1481
+ return encode_message_to_buffer(resp, UpdateStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1450
1482
  }
1451
- bool APIConnection::try_send_update_info_(update::UpdateEntity *update) {
1483
+ void APIConnection::send_update_info(update::UpdateEntity *update) {
1484
+ this->schedule_message_(update, &APIConnection::try_send_update_info, ListEntitiesUpdateResponse::MESSAGE_TYPE);
1485
+ }
1486
+ uint16_t APIConnection::try_send_update_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1487
+ bool is_single) {
1488
+ auto *update = static_cast<update::UpdateEntity *>(entity);
1452
1489
  ListEntitiesUpdateResponse msg;
1453
1490
  msg.device_class = update->get_device_class();
1454
1491
  msg.unique_id = get_default_unique_id("update", update);
1455
- return this->try_send_entity_info_(static_cast<EntityBase *>(update), msg,
1456
- &APIConnection::send_list_entities_update_response);
1492
+ fill_entity_info_base(update, msg);
1493
+ return encode_message_to_buffer(msg, ListEntitiesUpdateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1457
1494
  }
1458
1495
  void APIConnection::update_command(const UpdateCommandRequest &msg) {
1459
1496
  update::UpdateEntity *update = App.get_update_by_key(msg.key);
@@ -1468,7 +1505,7 @@ void APIConnection::update_command(const UpdateCommandRequest &msg) {
1468
1505
  update->check();
1469
1506
  break;
1470
1507
  case enums::UPDATE_COMMAND_NONE:
1471
- ESP_LOGE(TAG, "UPDATE_COMMAND_NONE not handled. Check client is sending the correct command");
1508
+ ESP_LOGE(TAG, "UPDATE_COMMAND_NONE not handled; confirm command is correct");
1472
1509
  break;
1473
1510
  default:
1474
1511
  ESP_LOGW(TAG, "Unknown update command: %" PRIu32, msg.command);
@@ -1501,7 +1538,7 @@ bool APIConnection::try_send_log_message(int level, const char *tag, const char
1501
1538
  buffer.encode_string(3, line, line_length); // string message = 3
1502
1539
 
1503
1540
  // SubscribeLogsResponse - 29
1504
- return this->send_buffer(buffer, 29);
1541
+ return this->send_buffer(buffer, SubscribeLogsResponse::MESSAGE_TYPE);
1505
1542
  }
1506
1543
 
1507
1544
  HelloResponse APIConnection::hello(const HelloRequest &msg) {
@@ -1530,7 +1567,7 @@ ConnectResponse APIConnection::connect(const ConnectRequest &msg) {
1530
1567
  // bool invalid_password = 1;
1531
1568
  resp.invalid_password = !correct;
1532
1569
  if (correct) {
1533
- ESP_LOGD(TAG, "%s: Connected successfully", this->client_combined_info_.c_str());
1570
+ ESP_LOGD(TAG, "%s connected", this->client_combined_info_.c_str());
1534
1571
  this->connection_state_ = ConnectionState::AUTHENTICATED;
1535
1572
  this->parent_->get_client_connected_trigger()->trigger(this->client_info_, this->client_peername_);
1536
1573
  #ifdef USE_HOMEASSISTANT_TIME
@@ -1601,7 +1638,7 @@ void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
1601
1638
  }
1602
1639
  }
1603
1640
  if (!found) {
1604
- ESP_LOGV(TAG, "Could not find matching service!");
1641
+ ESP_LOGV(TAG, "Could not find service");
1605
1642
  }
1606
1643
  }
1607
1644
  #ifdef USE_API_NOISE
@@ -1647,8 +1684,8 @@ bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
1647
1684
  }
1648
1685
  return false;
1649
1686
  }
1650
- bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint32_t message_type) {
1651
- if (!this->try_to_clear_buffer(message_type != 29)) { // SubscribeLogsResponse
1687
+ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint16_t message_type) {
1688
+ if (!this->try_to_clear_buffer(message_type != SubscribeLogsResponse::MESSAGE_TYPE)) { // SubscribeLogsResponse
1652
1689
  return false;
1653
1690
  }
1654
1691
 
@@ -1670,17 +1707,354 @@ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint32_t message_type)
1670
1707
  }
1671
1708
  void APIConnection::on_unauthenticated_access() {
1672
1709
  this->on_fatal_error();
1673
- ESP_LOGD(TAG, "%s: tried to access without authentication.", this->client_combined_info_.c_str());
1710
+ ESP_LOGD(TAG, "%s requested access without authentication", this->client_combined_info_.c_str());
1674
1711
  }
1675
1712
  void APIConnection::on_no_setup_connection() {
1676
1713
  this->on_fatal_error();
1677
- ESP_LOGD(TAG, "%s: tried to access without full connection.", this->client_combined_info_.c_str());
1714
+ ESP_LOGD(TAG, "%s requested access without full connection", this->client_combined_info_.c_str());
1678
1715
  }
1679
1716
  void APIConnection::on_fatal_error() {
1680
1717
  this->helper_->close();
1681
1718
  this->remove_ = true;
1682
1719
  }
1683
1720
 
1721
+ void APIConnection::DeferredBatch::add_item(EntityBase *entity, MessageCreator creator, uint16_t message_type) {
1722
+ // Check if we already have a message of this type for this entity
1723
+ // This provides deduplication per entity/message_type combination
1724
+ // O(n) but optimized for RAM and not performance.
1725
+ for (auto &item : items) {
1726
+ if (item.entity == entity && item.message_type == message_type) {
1727
+ // Update the existing item with the new creator
1728
+ item.creator = std::move(creator);
1729
+ return;
1730
+ }
1731
+ }
1732
+
1733
+ // No existing item found, add new one
1734
+ items.emplace_back(entity, std::move(creator), message_type);
1735
+ }
1736
+
1737
+ bool APIConnection::schedule_batch_() {
1738
+ if (!this->deferred_batch_.batch_scheduled) {
1739
+ this->deferred_batch_.batch_scheduled = true;
1740
+ this->deferred_batch_.batch_start_time = App.get_loop_component_start_time();
1741
+ }
1742
+ return true;
1743
+ }
1744
+
1745
+ ProtoWriteBuffer APIConnection::allocate_single_message_buffer(uint16_t size) { return this->create_buffer(size); }
1746
+
1747
+ ProtoWriteBuffer APIConnection::allocate_batch_message_buffer(uint16_t size) {
1748
+ ProtoWriteBuffer result = this->prepare_message_buffer(size, this->batch_first_message_);
1749
+ this->batch_first_message_ = false;
1750
+ return result;
1751
+ }
1752
+
1753
+ void APIConnection::process_batch_() {
1754
+ if (this->deferred_batch_.empty()) {
1755
+ this->deferred_batch_.batch_scheduled = false;
1756
+ return;
1757
+ }
1758
+
1759
+ // Try to clear buffer first
1760
+ if (!this->try_to_clear_buffer(true)) {
1761
+ // Can't write now, we'll try again later
1762
+ return;
1763
+ }
1764
+
1765
+ size_t num_items = this->deferred_batch_.items.size();
1766
+
1767
+ // Fast path for single message - allocate exact size needed
1768
+ if (num_items == 1) {
1769
+ const auto &item = this->deferred_batch_.items[0];
1770
+
1771
+ // Let the creator calculate size and encode if it fits
1772
+ uint16_t payload_size = item.creator(item.entity, this, std::numeric_limits<uint16_t>::max(), true);
1773
+
1774
+ if (payload_size > 0 &&
1775
+ this->send_buffer(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()}, item.message_type)) {
1776
+ this->deferred_batch_.clear();
1777
+ } else if (payload_size == 0) {
1778
+ // Message too large
1779
+ ESP_LOGW(TAG, "Message too large to send: type=%u", item.message_type);
1780
+ this->deferred_batch_.clear();
1781
+ }
1782
+ return;
1783
+ }
1784
+
1785
+ // Pre-allocate storage for packet info
1786
+ std::vector<PacketInfo> packet_info;
1787
+ packet_info.reserve(num_items);
1788
+
1789
+ // Cache these values to avoid repeated virtual calls
1790
+ const uint8_t header_padding = this->helper_->frame_header_padding();
1791
+ const uint8_t footer_size = this->helper_->frame_footer_size();
1792
+
1793
+ // Initialize buffer and tracking variables
1794
+ this->parent_->get_shared_buffer_ref().clear();
1795
+
1796
+ // Pre-calculate exact buffer size needed based on message types
1797
+ uint32_t total_estimated_size = 0;
1798
+ for (const auto &item : this->deferred_batch_.items) {
1799
+ total_estimated_size += get_estimated_message_size(item.message_type);
1800
+ }
1801
+
1802
+ // Calculate total overhead for all messages
1803
+ uint32_t total_overhead = (header_padding + footer_size) * num_items;
1804
+
1805
+ // Reserve based on estimated size (much more accurate than 24-byte worst-case)
1806
+ this->parent_->get_shared_buffer_ref().reserve(total_estimated_size + total_overhead);
1807
+ this->batch_first_message_ = true;
1808
+
1809
+ size_t items_processed = 0;
1810
+ uint16_t remaining_size = std::numeric_limits<uint16_t>::max();
1811
+
1812
+ // Track where each message's header padding begins in the buffer
1813
+ // For plaintext: this is where the 6-byte header padding starts
1814
+ // For noise: this is where the 7-byte header padding starts
1815
+ // The actual message data follows after the header padding
1816
+ uint32_t current_offset = 0;
1817
+
1818
+ // Process items and encode directly to buffer
1819
+ for (const auto &item : this->deferred_batch_.items) {
1820
+ // Try to encode message
1821
+ // The creator will calculate overhead to determine if the message fits
1822
+ uint16_t payload_size = item.creator(item.entity, this, remaining_size, false);
1823
+
1824
+ if (payload_size == 0) {
1825
+ // Message won't fit, stop processing
1826
+ break;
1827
+ }
1828
+
1829
+ // Message was encoded successfully
1830
+ // payload_size is header_padding + actual payload size + footer_size
1831
+ uint16_t proto_payload_size = payload_size - header_padding - footer_size;
1832
+ packet_info.emplace_back(item.message_type, current_offset, proto_payload_size);
1833
+
1834
+ // Update tracking variables
1835
+ items_processed++;
1836
+ // After first message, set remaining size to MAX_PACKET_SIZE to avoid fragmentation
1837
+ if (items_processed == 1) {
1838
+ remaining_size = MAX_PACKET_SIZE;
1839
+ }
1840
+ remaining_size -= payload_size;
1841
+ // Calculate where the next message's header padding will start
1842
+ // Current buffer size + footer space (that prepare_message_buffer will add for this message)
1843
+ current_offset = this->parent_->get_shared_buffer_ref().size() + footer_size;
1844
+ }
1845
+
1846
+ if (items_processed == 0) {
1847
+ this->deferred_batch_.clear();
1848
+ return;
1849
+ }
1850
+
1851
+ // Add footer space for the last message (for Noise protocol MAC)
1852
+ if (footer_size > 0) {
1853
+ auto &shared_buf = this->parent_->get_shared_buffer_ref();
1854
+ shared_buf.resize(shared_buf.size() + footer_size);
1855
+ }
1856
+
1857
+ // Send all collected packets
1858
+ APIError err =
1859
+ this->helper_->write_protobuf_packets(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()}, packet_info);
1860
+ if (err != APIError::OK && err != APIError::WOULD_BLOCK) {
1861
+ on_fatal_error();
1862
+ if (err == APIError::SOCKET_WRITE_FAILED && errno == ECONNRESET) {
1863
+ ESP_LOGW(TAG, "%s: Connection reset during batch write", this->client_combined_info_.c_str());
1864
+ } else {
1865
+ ESP_LOGW(TAG, "%s: Batch write failed %s errno=%d", this->client_combined_info_.c_str(), api_error_to_str(err),
1866
+ errno);
1867
+ }
1868
+ }
1869
+
1870
+ // Handle remaining items more efficiently
1871
+ if (items_processed < this->deferred_batch_.items.size()) {
1872
+ // Remove processed items from the beginning
1873
+ this->deferred_batch_.items.erase(this->deferred_batch_.items.begin(),
1874
+ this->deferred_batch_.items.begin() + items_processed);
1875
+
1876
+ // Reschedule for remaining items
1877
+ this->schedule_batch_();
1878
+ } else {
1879
+ // All items processed
1880
+ this->deferred_batch_.clear();
1881
+ }
1882
+ }
1883
+
1884
+ uint16_t APIConnection::MessageCreator::operator()(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1885
+ bool is_single) const {
1886
+ switch (message_type_) {
1887
+ case 0: // Function pointer
1888
+ return data_.ptr(entity, conn, remaining_size, is_single);
1889
+
1890
+ #ifdef USE_EVENT
1891
+ case EventResponse::MESSAGE_TYPE: {
1892
+ auto *e = static_cast<event::Event *>(entity);
1893
+ return APIConnection::try_send_event_response(e, *data_.string_ptr, conn, remaining_size, is_single);
1894
+ }
1895
+ #endif
1896
+
1897
+ default:
1898
+ // Should not happen, return 0 to indicate no message
1899
+ return 0;
1900
+ }
1901
+ }
1902
+
1903
+ uint16_t APIConnection::try_send_list_info_done(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1904
+ bool is_single) {
1905
+ ListEntitiesDoneResponse resp;
1906
+ return encode_message_to_buffer(resp, ListEntitiesDoneResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
1907
+ }
1908
+
1909
+ uint16_t APIConnection::try_send_disconnect_request(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
1910
+ bool is_single) {
1911
+ DisconnectRequest req;
1912
+ return encode_message_to_buffer(req, DisconnectRequest::MESSAGE_TYPE, conn, remaining_size, is_single);
1913
+ }
1914
+
1915
+ uint16_t APIConnection::get_estimated_message_size(uint16_t message_type) {
1916
+ // Use generated ESTIMATED_SIZE constants from each message type
1917
+ switch (message_type) {
1918
+ #ifdef USE_BINARY_SENSOR
1919
+ case BinarySensorStateResponse::MESSAGE_TYPE:
1920
+ return BinarySensorStateResponse::ESTIMATED_SIZE;
1921
+ case ListEntitiesBinarySensorResponse::MESSAGE_TYPE:
1922
+ return ListEntitiesBinarySensorResponse::ESTIMATED_SIZE;
1923
+ #endif
1924
+ #ifdef USE_SENSOR
1925
+ case SensorStateResponse::MESSAGE_TYPE:
1926
+ return SensorStateResponse::ESTIMATED_SIZE;
1927
+ case ListEntitiesSensorResponse::MESSAGE_TYPE:
1928
+ return ListEntitiesSensorResponse::ESTIMATED_SIZE;
1929
+ #endif
1930
+ #ifdef USE_SWITCH
1931
+ case SwitchStateResponse::MESSAGE_TYPE:
1932
+ return SwitchStateResponse::ESTIMATED_SIZE;
1933
+ case ListEntitiesSwitchResponse::MESSAGE_TYPE:
1934
+ return ListEntitiesSwitchResponse::ESTIMATED_SIZE;
1935
+ #endif
1936
+ #ifdef USE_TEXT_SENSOR
1937
+ case TextSensorStateResponse::MESSAGE_TYPE:
1938
+ return TextSensorStateResponse::ESTIMATED_SIZE;
1939
+ case ListEntitiesTextSensorResponse::MESSAGE_TYPE:
1940
+ return ListEntitiesTextSensorResponse::ESTIMATED_SIZE;
1941
+ #endif
1942
+ #ifdef USE_NUMBER
1943
+ case NumberStateResponse::MESSAGE_TYPE:
1944
+ return NumberStateResponse::ESTIMATED_SIZE;
1945
+ case ListEntitiesNumberResponse::MESSAGE_TYPE:
1946
+ return ListEntitiesNumberResponse::ESTIMATED_SIZE;
1947
+ #endif
1948
+ #ifdef USE_TEXT
1949
+ case TextStateResponse::MESSAGE_TYPE:
1950
+ return TextStateResponse::ESTIMATED_SIZE;
1951
+ case ListEntitiesTextResponse::MESSAGE_TYPE:
1952
+ return ListEntitiesTextResponse::ESTIMATED_SIZE;
1953
+ #endif
1954
+ #ifdef USE_SELECT
1955
+ case SelectStateResponse::MESSAGE_TYPE:
1956
+ return SelectStateResponse::ESTIMATED_SIZE;
1957
+ case ListEntitiesSelectResponse::MESSAGE_TYPE:
1958
+ return ListEntitiesSelectResponse::ESTIMATED_SIZE;
1959
+ #endif
1960
+ #ifdef USE_LOCK
1961
+ case LockStateResponse::MESSAGE_TYPE:
1962
+ return LockStateResponse::ESTIMATED_SIZE;
1963
+ case ListEntitiesLockResponse::MESSAGE_TYPE:
1964
+ return ListEntitiesLockResponse::ESTIMATED_SIZE;
1965
+ #endif
1966
+ #ifdef USE_EVENT
1967
+ case EventResponse::MESSAGE_TYPE:
1968
+ return EventResponse::ESTIMATED_SIZE;
1969
+ case ListEntitiesEventResponse::MESSAGE_TYPE:
1970
+ return ListEntitiesEventResponse::ESTIMATED_SIZE;
1971
+ #endif
1972
+ #ifdef USE_COVER
1973
+ case CoverStateResponse::MESSAGE_TYPE:
1974
+ return CoverStateResponse::ESTIMATED_SIZE;
1975
+ case ListEntitiesCoverResponse::MESSAGE_TYPE:
1976
+ return ListEntitiesCoverResponse::ESTIMATED_SIZE;
1977
+ #endif
1978
+ #ifdef USE_FAN
1979
+ case FanStateResponse::MESSAGE_TYPE:
1980
+ return FanStateResponse::ESTIMATED_SIZE;
1981
+ case ListEntitiesFanResponse::MESSAGE_TYPE:
1982
+ return ListEntitiesFanResponse::ESTIMATED_SIZE;
1983
+ #endif
1984
+ #ifdef USE_LIGHT
1985
+ case LightStateResponse::MESSAGE_TYPE:
1986
+ return LightStateResponse::ESTIMATED_SIZE;
1987
+ case ListEntitiesLightResponse::MESSAGE_TYPE:
1988
+ return ListEntitiesLightResponse::ESTIMATED_SIZE;
1989
+ #endif
1990
+ #ifdef USE_CLIMATE
1991
+ case ClimateStateResponse::MESSAGE_TYPE:
1992
+ return ClimateStateResponse::ESTIMATED_SIZE;
1993
+ case ListEntitiesClimateResponse::MESSAGE_TYPE:
1994
+ return ListEntitiesClimateResponse::ESTIMATED_SIZE;
1995
+ #endif
1996
+ #ifdef USE_ESP32_CAMERA
1997
+ case ListEntitiesCameraResponse::MESSAGE_TYPE:
1998
+ return ListEntitiesCameraResponse::ESTIMATED_SIZE;
1999
+ #endif
2000
+ #ifdef USE_BUTTON
2001
+ case ListEntitiesButtonResponse::MESSAGE_TYPE:
2002
+ return ListEntitiesButtonResponse::ESTIMATED_SIZE;
2003
+ #endif
2004
+ #ifdef USE_MEDIA_PLAYER
2005
+ case MediaPlayerStateResponse::MESSAGE_TYPE:
2006
+ return MediaPlayerStateResponse::ESTIMATED_SIZE;
2007
+ case ListEntitiesMediaPlayerResponse::MESSAGE_TYPE:
2008
+ return ListEntitiesMediaPlayerResponse::ESTIMATED_SIZE;
2009
+ #endif
2010
+ #ifdef USE_ALARM_CONTROL_PANEL
2011
+ case AlarmControlPanelStateResponse::MESSAGE_TYPE:
2012
+ return AlarmControlPanelStateResponse::ESTIMATED_SIZE;
2013
+ case ListEntitiesAlarmControlPanelResponse::MESSAGE_TYPE:
2014
+ return ListEntitiesAlarmControlPanelResponse::ESTIMATED_SIZE;
2015
+ #endif
2016
+ #ifdef USE_DATETIME_DATE
2017
+ case DateStateResponse::MESSAGE_TYPE:
2018
+ return DateStateResponse::ESTIMATED_SIZE;
2019
+ case ListEntitiesDateResponse::MESSAGE_TYPE:
2020
+ return ListEntitiesDateResponse::ESTIMATED_SIZE;
2021
+ #endif
2022
+ #ifdef USE_DATETIME_TIME
2023
+ case TimeStateResponse::MESSAGE_TYPE:
2024
+ return TimeStateResponse::ESTIMATED_SIZE;
2025
+ case ListEntitiesTimeResponse::MESSAGE_TYPE:
2026
+ return ListEntitiesTimeResponse::ESTIMATED_SIZE;
2027
+ #endif
2028
+ #ifdef USE_DATETIME_DATETIME
2029
+ case DateTimeStateResponse::MESSAGE_TYPE:
2030
+ return DateTimeStateResponse::ESTIMATED_SIZE;
2031
+ case ListEntitiesDateTimeResponse::MESSAGE_TYPE:
2032
+ return ListEntitiesDateTimeResponse::ESTIMATED_SIZE;
2033
+ #endif
2034
+ #ifdef USE_VALVE
2035
+ case ValveStateResponse::MESSAGE_TYPE:
2036
+ return ValveStateResponse::ESTIMATED_SIZE;
2037
+ case ListEntitiesValveResponse::MESSAGE_TYPE:
2038
+ return ListEntitiesValveResponse::ESTIMATED_SIZE;
2039
+ #endif
2040
+ #ifdef USE_UPDATE
2041
+ case UpdateStateResponse::MESSAGE_TYPE:
2042
+ return UpdateStateResponse::ESTIMATED_SIZE;
2043
+ case ListEntitiesUpdateResponse::MESSAGE_TYPE:
2044
+ return ListEntitiesUpdateResponse::ESTIMATED_SIZE;
2045
+ #endif
2046
+ case ListEntitiesServicesResponse::MESSAGE_TYPE:
2047
+ return ListEntitiesServicesResponse::ESTIMATED_SIZE;
2048
+ case ListEntitiesDoneResponse::MESSAGE_TYPE:
2049
+ return ListEntitiesDoneResponse::ESTIMATED_SIZE;
2050
+ case DisconnectRequest::MESSAGE_TYPE:
2051
+ return DisconnectRequest::ESTIMATED_SIZE;
2052
+ default:
2053
+ // Fallback for unknown message types
2054
+ return 24;
2055
+ }
2056
+ }
2057
+
1684
2058
  } // namespace api
1685
2059
  } // namespace esphome
1686
2060
  #endif