esphome 2025.6.2__py3-none-any.whl → 2025.7.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 (648) hide show
  1. esphome/__main__.py +1 -3
  2. esphome/codegen.py +2 -0
  3. esphome/components/ac_dimmer/ac_dimmer.cpp +6 -6
  4. esphome/components/adc/__init__.py +25 -1
  5. esphome/components/adc/adc_sensor.h +11 -11
  6. esphome/components/adc/adc_sensor_common.cpp +1 -1
  7. esphome/components/adc/adc_sensor_esp32.cpp +16 -8
  8. esphome/components/ade7880/ade7880.h +0 -2
  9. esphome/components/ads1115/ads1115.h +0 -1
  10. esphome/components/ads1118/ads1118.h +0 -1
  11. esphome/components/ags10/ags10.h +0 -2
  12. esphome/components/aic3204/aic3204.h +0 -1
  13. esphome/components/alarm_control_panel/__init__.py +5 -2
  14. esphome/components/alpha3/alpha3.h +0 -1
  15. esphome/components/am43/cover/am43_cover.h +0 -1
  16. esphome/components/am43/sensor/am43_sensor.h +0 -1
  17. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +0 -2
  18. esphome/components/anova/anova.cpp +5 -1
  19. esphome/components/anova/anova.h +0 -1
  20. esphome/components/apds9960/apds9960.cpp +1 -1
  21. esphome/components/api/__init__.py +57 -21
  22. esphome/components/api/api_connection.cpp +344 -539
  23. esphome/components/api/api_connection.h +224 -141
  24. esphome/components/api/api_frame_helper.cpp +91 -127
  25. esphome/components/api/api_frame_helper.h +64 -54
  26. esphome/components/api/api_pb2.cpp +1837 -9044
  27. esphome/components/api/api_pb2.h +532 -685
  28. esphome/components/api/api_pb2_dump.cpp +4432 -0
  29. esphome/components/api/api_pb2_service.cpp +184 -425
  30. esphome/components/api/api_pb2_service.h +13 -6
  31. esphome/components/api/api_server.cpp +131 -167
  32. esphome/components/api/api_server.h +38 -10
  33. esphome/components/api/client.py +10 -4
  34. esphome/components/api/custom_api_device.h +8 -0
  35. esphome/components/api/list_entities.cpp +37 -104
  36. esphome/components/api/list_entities.h +33 -23
  37. esphome/components/api/proto.h +532 -26
  38. esphome/components/api/subscribe_state.cpp +23 -29
  39. esphome/components/api/subscribe_state.h +26 -19
  40. esphome/components/api/user_services.h +2 -0
  41. esphome/components/as3935_spi/as3935_spi.h +0 -2
  42. esphome/components/as5600/as5600.h +0 -1
  43. esphome/components/async_tcp/__init__.py +14 -5
  44. esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
  45. esphome/components/atm90e32/atm90e32.cpp +2 -1
  46. esphome/components/audio/audio_decoder.cpp +1 -1
  47. esphome/components/audio/audio_transfer_buffer.cpp +2 -2
  48. esphome/components/b_parasite/b_parasite.h +0 -1
  49. esphome/components/bedjet/bedjet_hub.cpp +5 -1
  50. esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
  51. esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
  52. esphome/components/bh1750/bh1750.cpp +5 -5
  53. esphome/components/binary_sensor/__init__.py +82 -5
  54. esphome/components/binary_sensor/automation.h +19 -1
  55. esphome/components/binary_sensor/binary_sensor.cpp +12 -30
  56. esphome/components/binary_sensor/binary_sensor.h +11 -25
  57. esphome/components/binary_sensor/filter.cpp +29 -24
  58. esphome/components/binary_sensor/filter.h +20 -10
  59. esphome/components/ble_client/output/ble_binary_output.h +0 -1
  60. esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
  61. esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
  62. esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
  63. esphome/components/ble_client/sensor/ble_sensor.h +0 -1
  64. esphome/components/ble_client/switch/ble_switch.h +0 -1
  65. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
  66. esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
  67. esphome/components/ble_presence/ble_presence_device.h +0 -1
  68. esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
  69. esphome/components/ble_scanner/ble_scanner.h +0 -1
  70. esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
  71. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
  72. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
  73. esphome/components/bme680/sensor.py +1 -1
  74. esphome/components/bmp581/bmp581.h +0 -2
  75. esphome/components/button/__init__.py +5 -2
  76. esphome/components/camera/__init__.py +1 -0
  77. esphome/components/camera/camera.cpp +22 -0
  78. esphome/components/camera/camera.h +80 -0
  79. esphome/components/canbus/__init__.py +1 -0
  80. esphome/components/cap1188/cap1188.h +0 -1
  81. esphome/components/captive_portal/__init__.py +12 -2
  82. esphome/components/captive_portal/captive_portal.cpp +12 -2
  83. esphome/components/captive_portal/captive_portal.h +5 -2
  84. esphome/components/ccs811/ccs811.h +0 -2
  85. esphome/components/climate/__init__.py +5 -2
  86. esphome/components/cm1106/sensor.py +2 -2
  87. esphome/components/const/__init__.py +2 -0
  88. esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
  89. esphome/components/copy/button/copy_button.h +0 -1
  90. esphome/components/copy/cover/copy_cover.h +0 -1
  91. esphome/components/copy/fan/copy_fan.h +0 -1
  92. esphome/components/copy/lock/copy_lock.h +0 -1
  93. esphome/components/copy/number/copy_number.h +0 -1
  94. esphome/components/copy/select/copy_select.h +0 -1
  95. esphome/components/copy/sensor/copy_sensor.h +0 -1
  96. esphome/components/copy/switch/copy_switch.h +0 -1
  97. esphome/components/copy/text/copy_text.h +0 -1
  98. esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
  99. esphome/components/cover/__init__.py +5 -2
  100. esphome/components/cs5460a/cs5460a.h +0 -1
  101. esphome/components/datetime/__init__.py +4 -2
  102. esphome/components/debug/__init__.py +20 -0
  103. esphome/components/debug/debug_esp32.cpp +2 -0
  104. esphome/components/deep_sleep/__init__.py +43 -9
  105. esphome/components/demo/__init__.py +2 -2
  106. esphome/components/display/display.cpp +4 -3
  107. esphome/components/display/display.h +0 -2
  108. esphome/components/display/display_buffer.cpp +1 -1
  109. esphome/components/ds2484/__init__.py +1 -0
  110. esphome/components/ds2484/ds2484.cpp +209 -0
  111. esphome/components/ds2484/ds2484.h +43 -0
  112. esphome/components/ds2484/one_wire.py +37 -0
  113. esphome/components/duty_time/duty_time_sensor.h +0 -1
  114. esphome/components/ens160_base/ens160_base.h +0 -1
  115. esphome/components/es7210/es7210.h +0 -1
  116. esphome/components/es7243e/es7243e.h +0 -1
  117. esphome/components/es8156/es8156.h +0 -1
  118. esphome/components/es8311/es8311.h +0 -1
  119. esphome/components/es8388/es8388.h +0 -1
  120. esphome/components/esp32/__init__.py +103 -135
  121. esphome/components/esp32/core.cpp +0 -4
  122. esphome/components/esp32/gpio.h +1 -1
  123. esphome/components/esp32/helpers.cpp +69 -0
  124. esphome/components/esp32_ble/ble.cpp +5 -6
  125. esphome/components/esp32_ble/ble.h +29 -14
  126. esphome/components/esp32_ble/ble_event.h +6 -6
  127. esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
  128. esphome/components/esp32_ble_client/ble_client_base.h +24 -9
  129. esphome/components/esp32_ble_tracker/__init__.py +2 -8
  130. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
  131. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
  132. esphome/components/esp32_camera/__init__.py +112 -98
  133. esphome/components/esp32_camera/esp32_camera.cpp +41 -31
  134. esphome/components/esp32_camera/esp32_camera.h +35 -30
  135. esphome/components/esp32_camera_web_server/__init__.py +2 -1
  136. esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
  137. esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
  138. esphome/components/esp32_hall/sensor.py +2 -21
  139. esphome/components/esp32_hosted/__init__.py +101 -0
  140. esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
  141. esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
  142. esphome/components/esp32_rmt/__init__.py +0 -58
  143. esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
  144. esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
  145. esphome/components/esp32_rmt_led_strip/light.py +14 -76
  146. esphome/components/esp32_touch/esp32_touch.h +174 -28
  147. esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
  148. esphome/components/esp32_touch/esp32_touch_v1.cpp +240 -0
  149. esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
  150. esphome/components/esp8266/__init__.py +2 -0
  151. esphome/components/esp8266/gpio.cpp +10 -10
  152. esphome/components/esp8266/helpers.cpp +31 -0
  153. esphome/components/esp_ldo/__init__.py +10 -8
  154. esphome/components/esp_ldo/esp_ldo.h +3 -0
  155. esphome/components/esphome/ota/__init__.py +1 -0
  156. esphome/components/esphome/ota/ota_esphome.cpp +24 -19
  157. esphome/components/ethernet/__init__.py +42 -23
  158. esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
  159. esphome/components/ethernet/ethernet_component.cpp +69 -29
  160. esphome/components/ethernet/ethernet_component.h +18 -10
  161. esphome/components/event/__init__.py +5 -2
  162. esphome/components/ezo/ezo.h +0 -1
  163. esphome/components/ezo_pmp/ezo_pmp.h +0 -1
  164. esphome/components/fan/__init__.py +5 -2
  165. esphome/components/fan/fan.cpp +4 -0
  166. esphome/components/feedback/feedback_cover.h +0 -1
  167. esphome/components/font/__init__.py +92 -82
  168. esphome/components/font/font.cpp +9 -2
  169. esphome/components/font/font.h +20 -5
  170. esphome/components/fs3000/fs3000.h +0 -1
  171. esphome/components/gcja5/gcja5.h +0 -1
  172. esphome/components/gl_r01_i2c/__init__.py +0 -0
  173. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
  174. esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
  175. esphome/components/gl_r01_i2c/sensor.py +36 -0
  176. esphome/components/gp8403/gp8403.h +0 -1
  177. esphome/components/gpio/binary_sensor/__init__.py +39 -1
  178. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
  179. esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
  180. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
  181. esphome/components/he60r/he60r.h +0 -1
  182. esphome/components/heatpumpir/climate.py +2 -1
  183. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  184. esphome/components/heatpumpir/heatpumpir.h +1 -0
  185. esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
  186. esphome/components/host/__init__.py +3 -1
  187. esphome/components/host/helpers.cpp +57 -0
  188. esphome/components/http_request/__init__.py +19 -1
  189. esphome/components/http_request/http_request.h +1 -1
  190. esphome/components/http_request/http_request_arduino.cpp +0 -1
  191. esphome/components/http_request/http_request_arduino.h +1 -0
  192. esphome/components/http_request/http_request_idf.cpp +0 -1
  193. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  194. esphome/components/http_request/update/http_request_update.cpp +35 -16
  195. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +3 -9
  196. esphome/components/hydreon_rgxx/sensor.py +1 -1
  197. esphome/components/i2c/__init__.py +23 -11
  198. esphome/components/i2c/i2c_bus.h +8 -1
  199. esphome/components/i2c/i2c_bus_arduino.cpp +4 -3
  200. esphome/components/i2c/i2c_bus_arduino.h +6 -3
  201. esphome/components/i2c/i2c_bus_esp_idf.h +5 -3
  202. esphome/components/i2c_device/i2c_device.h +0 -1
  203. esphome/components/i2s_audio/__init__.py +2 -10
  204. esphome/components/i2s_audio/i2s_audio.cpp +1 -5
  205. esphome/components/i2s_audio/media_player/__init__.py +2 -2
  206. esphome/components/i2s_audio/speaker/__init__.py +1 -1
  207. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +2 -2
  208. esphome/components/iaqcore/iaqcore.h +0 -2
  209. esphome/components/image/__init__.py +123 -24
  210. esphome/components/improv_serial/improv_serial_component.cpp +0 -4
  211. esphome/components/ina219/ina219.cpp +7 -0
  212. esphome/components/ina219/ina219.h +1 -0
  213. esphome/components/ina260/ina260.h +0 -2
  214. esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h +0 -1
  215. esphome/components/inkplate6/display.py +15 -0
  216. esphome/components/inkplate6/inkplate.cpp +2 -2
  217. esphome/components/integration/integration_sensor.h +0 -1
  218. esphome/components/internal_temperature/internal_temperature.cpp +8 -27
  219. esphome/components/internal_temperature/sensor.py +0 -26
  220. esphome/components/interval/interval.h +0 -2
  221. esphome/components/json/__init__.py +1 -1
  222. esphome/components/json/json_util.cpp +56 -63
  223. esphome/components/ld2410/button/__init__.py +3 -3
  224. esphome/components/ld2410/button/factory_reset_button.cpp +9 -0
  225. esphome/components/ld2410/button/{reset_button.h → factory_reset_button.h} +2 -2
  226. esphome/components/ld2410/ld2410.cpp +421 -268
  227. esphome/components/ld2410/ld2410.h +44 -146
  228. esphome/components/ld2410/number/__init__.py +2 -2
  229. esphome/components/ld2410/sensor.py +1 -1
  230. esphome/components/ld2410/switch/__init__.py +1 -1
  231. esphome/components/ld2420/binary_sensor/ld2420_binary_sensor.cpp +2 -2
  232. esphome/components/ld2420/button/reconfig_buttons.cpp +1 -1
  233. esphome/components/ld2420/ld2420.cpp +252 -147
  234. esphome/components/ld2420/ld2420.h +52 -126
  235. esphome/components/ld2420/number/__init__.py +2 -2
  236. esphome/components/ld2420/number/gate_config_number.cpp +1 -1
  237. esphome/components/ld2420/select/operating_mode_select.cpp +1 -1
  238. esphome/components/ld2420/sensor/__init__.py +6 -2
  239. esphome/components/ld2420/sensor/ld2420_sensor.cpp +2 -2
  240. esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
  241. esphome/components/ld2420/text_sensor/text_sensor.cpp +2 -2
  242. esphome/components/ld2450/button/__init__.py +3 -3
  243. esphome/components/ld2450/button/factory_reset_button.cpp +9 -0
  244. esphome/components/ld2450/button/{reset_button.h → factory_reset_button.h} +2 -2
  245. esphome/components/ld2450/ld2450.cpp +384 -232
  246. esphome/components/ld2450/ld2450.h +60 -69
  247. esphome/components/ld2450/switch/__init__.py +1 -1
  248. esphome/components/ledc/ledc_output.cpp +1 -63
  249. esphome/components/libretiny/__init__.py +5 -3
  250. esphome/components/libretiny/const.py +5 -0
  251. esphome/components/libretiny/generate_components.py +1 -0
  252. esphome/components/libretiny/helpers.cpp +35 -0
  253. esphome/components/libretiny/lt_component.cpp +5 -3
  254. esphome/components/light/__init__.py +4 -2
  255. esphome/components/light/addressable_light.h +3 -3
  256. esphome/components/light/light_call.cpp +180 -243
  257. esphome/components/light/light_call.h +72 -20
  258. esphome/components/light/light_color_values.h +14 -14
  259. esphome/components/light/light_json_schema.cpp +17 -16
  260. esphome/components/light/light_state.h +15 -13
  261. esphome/components/light/transformers.h +2 -2
  262. esphome/components/ln882x/__init__.py +52 -0
  263. esphome/components/ln882x/boards.py +285 -0
  264. esphome/components/lock/__init__.py +5 -2
  265. esphome/components/logger/__init__.py +40 -3
  266. esphome/components/logger/logger.cpp +47 -12
  267. esphome/components/logger/logger.h +80 -49
  268. esphome/components/logger/logger_esp32.cpp +3 -3
  269. esphome/components/lps22/__init__.py +0 -0
  270. esphome/components/lps22/lps22.cpp +75 -0
  271. esphome/components/lps22/lps22.h +27 -0
  272. esphome/components/lps22/sensor.py +58 -0
  273. esphome/components/ltr390/ltr390.h +0 -1
  274. esphome/components/ltr501/ltr501.h +0 -1
  275. esphome/components/ltr_als_ps/ltr_als_ps.h +0 -1
  276. esphome/components/lvgl/__init__.py +1 -1
  277. esphome/components/lvgl/schemas.py +66 -6
  278. esphome/components/lvgl/styles.py +24 -16
  279. esphome/components/lvgl/widgets/__init__.py +12 -2
  280. esphome/components/lvgl/widgets/lv_bar.py +40 -19
  281. esphome/components/lvgl/widgets/meter.py +20 -13
  282. esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +1 -1
  283. esphome/components/max9611/max9611.h +0 -1
  284. esphome/components/mcp23016/__init__.py +1 -1
  285. esphome/components/mcp23xxx_base/__init__.py +1 -1
  286. esphome/components/mcp4461/__init__.py +1 -1
  287. esphome/components/mcp4461/output/__init__.py +3 -2
  288. esphome/components/mcp9600/mcp9600.h +0 -2
  289. esphome/components/md5/md5.cpp +3 -3
  290. esphome/components/md5/md5.h +1 -6
  291. esphome/components/mdns/__init__.py +22 -11
  292. esphome/components/media_player/__init__.py +4 -3
  293. esphome/components/micro_wake_word/__init__.py +1 -5
  294. esphome/components/micro_wake_word/streaming_model.cpp +2 -2
  295. esphome/components/microphone/microphone.cpp +7 -9
  296. esphome/components/microphone/microphone.h +0 -2
  297. esphome/components/mipi_spi/display.py +1 -0
  298. esphome/components/mmc5603/mmc5603.cpp +1 -1
  299. esphome/components/modbus/modbus.cpp +33 -15
  300. esphome/components/modbus/modbus.h +9 -0
  301. esphome/components/modbus_controller/__init__.py +42 -10
  302. esphome/components/modbus_controller/modbus_controller.cpp +92 -11
  303. esphome/components/modbus_controller/modbus_controller.h +61 -7
  304. esphome/components/mopeka_pro_check/mopeka_pro_check.h +0 -1
  305. esphome/components/mopeka_std_check/mopeka_std_check.h +0 -1
  306. esphome/components/mpl3115a2/mpl3115a2.h +0 -2
  307. esphome/components/mqtt/__init__.py +16 -0
  308. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +2 -1
  309. esphome/components/mqtt/mqtt_backend.h +2 -1
  310. esphome/components/mqtt/mqtt_backend_esp32.cpp +132 -47
  311. esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
  312. esphome/components/mqtt/mqtt_binary_sensor.cpp +1 -0
  313. esphome/components/mqtt/mqtt_button.cpp +4 -1
  314. esphome/components/mqtt/mqtt_client.cpp +17 -9
  315. esphome/components/mqtt/mqtt_client.h +8 -3
  316. esphome/components/mqtt/mqtt_climate.cpp +6 -4
  317. esphome/components/mqtt/mqtt_component.cpp +3 -1
  318. esphome/components/mqtt/mqtt_cover.cpp +1 -0
  319. esphome/components/mqtt/mqtt_date.cpp +4 -3
  320. esphome/components/mqtt/mqtt_datetime.cpp +7 -6
  321. esphome/components/mqtt/mqtt_event.cpp +6 -3
  322. esphome/components/mqtt/mqtt_fan.cpp +1 -0
  323. esphome/components/mqtt/mqtt_light.cpp +8 -4
  324. esphome/components/mqtt/mqtt_lock.cpp +3 -1
  325. esphome/components/mqtt/mqtt_number.cpp +1 -0
  326. esphome/components/mqtt/mqtt_select.cpp +2 -1
  327. esphome/components/mqtt/mqtt_sensor.cpp +3 -1
  328. esphome/components/mqtt/mqtt_switch.cpp +3 -1
  329. esphome/components/mqtt/mqtt_text.cpp +1 -0
  330. esphome/components/mqtt/mqtt_text_sensor.cpp +3 -1
  331. esphome/components/mqtt/mqtt_time.cpp +4 -3
  332. esphome/components/mqtt/mqtt_update.cpp +1 -0
  333. esphome/components/mqtt/mqtt_valve.cpp +3 -1
  334. esphome/components/ms8607/ms8607.cpp +1 -1
  335. esphome/components/ms8607/ms8607.h +0 -1
  336. esphome/components/neopixelbus/light.py +4 -1
  337. esphome/components/neopixelbus/neopixelbus_light.h +1 -1
  338. esphome/components/network/__init__.py +4 -1
  339. esphome/components/network/ip_address.h +1 -0
  340. esphome/components/nextion/__init__.py +16 -0
  341. esphome/components/nextion/base_component.py +1 -0
  342. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
  343. esphome/components/nextion/display.py +14 -4
  344. esphome/components/nextion/nextion.cpp +166 -101
  345. esphome/components/nextion/nextion.h +84 -53
  346. esphome/components/nextion/nextion_commands.cpp +11 -10
  347. esphome/components/nextion/nextion_component.cpp +28 -28
  348. esphome/components/nextion/nextion_component.h +53 -18
  349. esphome/components/nextion/nextion_component_base.h +3 -0
  350. esphome/components/nextion/nextion_upload.cpp +36 -0
  351. esphome/components/nextion/nextion_upload_arduino.cpp +10 -35
  352. esphome/components/nextion/nextion_upload_idf.cpp +9 -33
  353. esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
  354. esphome/components/nextion/switch/nextion_switch.cpp +1 -1
  355. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
  356. esphome/components/nfc/nfc.cpp +3 -22
  357. esphome/components/nfc/nfc.h +3 -3
  358. esphome/components/number/__init__.py +5 -2
  359. esphome/components/online_image/__init__.py +9 -1
  360. esphome/components/online_image/online_image.cpp +17 -7
  361. esphome/components/online_image/online_image.h +10 -2
  362. esphome/components/opentherm/opentherm.cpp +7 -12
  363. esphome/components/opentherm/output/output.cpp +1 -1
  364. esphome/components/openthread/__init__.py +47 -40
  365. esphome/components/openthread/const.py +1 -0
  366. esphome/components/openthread/openthread_esp.cpp +27 -5
  367. esphome/components/opt3001/__init__.py +0 -0
  368. esphome/components/opt3001/opt3001.cpp +122 -0
  369. esphome/components/opt3001/opt3001.h +27 -0
  370. esphome/components/opt3001/sensor.py +35 -0
  371. esphome/components/ota/__init__.py +17 -0
  372. esphome/components/ota/ota_backend.h +27 -1
  373. esphome/components/ota/ota_backend_arduino_esp32.cpp +12 -2
  374. esphome/components/ota/ota_backend_arduino_esp32.h +3 -0
  375. esphome/components/ota/ota_backend_arduino_esp8266.cpp +18 -4
  376. esphome/components/ota/ota_backend_arduino_esp8266.h +3 -0
  377. esphome/components/ota/ota_backend_arduino_libretiny.cpp +12 -2
  378. esphome/components/ota/ota_backend_arduino_libretiny.h +3 -0
  379. esphome/components/ota/ota_backend_arduino_rp2040.cpp +9 -2
  380. esphome/components/ota/ota_backend_arduino_rp2040.h +3 -0
  381. esphome/components/ota/ota_backend_esp_idf.cpp +10 -16
  382. esphome/components/ota/ota_backend_esp_idf.h +1 -0
  383. esphome/components/packages/__init__.py +5 -2
  384. esphome/components/packet_transport/binary_sensor.py +61 -4
  385. esphome/components/packet_transport/packet_transport.cpp +34 -1
  386. esphome/components/packet_transport/packet_transport.h +11 -5
  387. esphome/components/pcf8574/__init__.py +1 -1
  388. esphome/components/pi4ioe5v6408/__init__.py +84 -0
  389. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +171 -0
  390. esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +70 -0
  391. esphome/components/pmsa003i/pmsa003i.h +0 -1
  392. esphome/components/pmsx003/pmsx003.h +0 -1
  393. esphome/components/pn7150/pn7150.cpp +7 -7
  394. esphome/components/pn7150/pn7150.h +0 -1
  395. esphome/components/pn7160/pn7160.cpp +7 -7
  396. esphome/components/pn7160/pn7160.h +0 -1
  397. esphome/components/preferences/syncer.h +2 -0
  398. esphome/components/prometheus/prometheus_handler.h +1 -1
  399. esphome/components/psram/psram.cpp +0 -20
  400. esphome/components/pulse_counter/pulse_counter_sensor.h +0 -1
  401. esphome/components/pulse_meter/pulse_meter_sensor.cpp +8 -4
  402. esphome/components/pulse_width/pulse_width.h +0 -1
  403. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +0 -4
  404. esphome/components/pvvx_mithermometer/display/pvvx_display.h +0 -2
  405. esphome/components/pvvx_mithermometer/pvvx_mithermometer.h +0 -1
  406. esphome/components/qr_code/__init__.py +13 -10
  407. esphome/components/qwiic_pir/qwiic_pir.h +0 -1
  408. esphome/components/radon_eye_ble/radon_eye_listener.cpp +1 -1
  409. esphome/components/rc522/rc522.h +0 -1
  410. esphome/components/rdm6300/rdm6300.h +0 -2
  411. esphome/components/remote_base/__init__.py +7 -5
  412. esphome/components/remote_base/remote_base.cpp +24 -21
  413. esphome/components/remote_base/remote_base.h +3 -26
  414. esphome/components/remote_receiver/__init__.py +40 -46
  415. esphome/components/remote_receiver/remote_receiver.h +4 -18
  416. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -87
  417. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +1 -1
  418. esphome/components/remote_transmitter/__init__.py +42 -43
  419. esphome/components/remote_transmitter/remote_transmitter.h +2 -14
  420. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -77
  421. esphome/components/resistance/resistance_sensor.h +0 -1
  422. esphome/components/rp2040/__init__.py +2 -0
  423. esphome/components/rp2040/helpers.cpp +55 -0
  424. esphome/components/rp2040_pio_led_strip/led_strip.cpp +2 -2
  425. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -4
  426. esphome/components/rtttl/__init__.py +4 -4
  427. esphome/components/rtttl/rtttl.cpp +10 -1
  428. esphome/components/ruuvitag/ruuvitag.h +0 -1
  429. esphome/components/safe_mode/safe_mode.cpp +2 -0
  430. esphome/components/safe_mode/safe_mode.h +4 -1
  431. esphome/components/scd30/scd30.h +0 -1
  432. esphome/components/scd30/sensor.py +2 -2
  433. esphome/components/scd4x/scd4x.cpp +61 -54
  434. esphome/components/scd4x/scd4x.h +17 -15
  435. esphome/components/scd4x/sensor.py +4 -4
  436. esphome/components/script/script.h +0 -2
  437. esphome/components/sdp3x/sensor.py +1 -1
  438. esphome/components/select/__init__.py +5 -2
  439. esphome/components/sen5x/sen5x.h +0 -1
  440. esphome/components/senseair/senseair.h +0 -1
  441. esphome/components/sensor/__init__.py +4 -2
  442. esphome/components/sensor/filter.cpp +1 -1
  443. esphome/components/sensor/sensor.cpp +12 -6
  444. esphome/components/sensor/sensor.h +13 -5
  445. esphome/components/servo/servo.cpp +2 -2
  446. esphome/components/servo/servo.h +0 -1
  447. esphome/components/sfa30/sfa30.h +0 -1
  448. esphome/components/sgp30/sgp30.h +0 -1
  449. esphome/components/sgp4x/sgp4x.h +0 -1
  450. esphome/components/shelly_dimmer/stm32flash.cpp +1 -2
  451. esphome/components/sht4x/sht4x.h +0 -1
  452. esphome/components/sm300d2/sm300d2.h +0 -2
  453. esphome/components/smt100/sensor.py +8 -4
  454. esphome/components/smt100/smt100.cpp +5 -5
  455. esphome/components/smt100/smt100.h +3 -3
  456. esphome/components/sn74hc595/__init__.py +1 -1
  457. esphome/components/sn74hc595/sn74hc595.cpp +5 -4
  458. esphome/components/sntp/sntp_component.cpp +9 -3
  459. esphome/components/sntp/time.py +2 -0
  460. esphome/components/socket/__init__.py +17 -0
  461. esphome/components/spi/__init__.py +27 -6
  462. esphome/components/spi/spi.cpp +3 -2
  463. esphome/components/spi/spi.h +9 -3
  464. esphome/components/spi/spi_arduino.cpp +3 -5
  465. esphome/components/spi/spi_esp_idf.cpp +40 -21
  466. esphome/components/spi_led_strip/spi_led_strip.cpp +1 -1
  467. esphome/components/sps30/sps30.h +0 -1
  468. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  469. esphome/components/st7701s/st7701s.cpp +0 -4
  470. esphome/components/status/status_binary_sensor.h +0 -2
  471. esphome/components/substitutions/__init__.py +81 -21
  472. esphome/components/substitutions/jinja.py +99 -0
  473. esphome/components/sun/sun.cpp +3 -4
  474. esphome/components/switch/__init__.py +5 -2
  475. esphome/components/switch/binary_sensor/switch_binary_sensor.h +0 -1
  476. esphome/components/sx126x/__init__.py +317 -0
  477. esphome/components/sx126x/automation.h +62 -0
  478. esphome/components/sx126x/packet_transport/__init__.py +26 -0
  479. esphome/components/sx126x/packet_transport/sx126x_transport.cpp +26 -0
  480. esphome/components/sx126x/packet_transport/sx126x_transport.h +25 -0
  481. esphome/components/sx126x/sx126x.cpp +523 -0
  482. esphome/components/sx126x/sx126x.h +140 -0
  483. esphome/components/sx126x/sx126x_reg.h +163 -0
  484. esphome/components/sx127x/__init__.py +325 -0
  485. esphome/components/sx127x/automation.h +62 -0
  486. esphome/components/sx127x/packet_transport/__init__.py +26 -0
  487. esphome/components/sx127x/packet_transport/sx127x_transport.cpp +26 -0
  488. esphome/components/sx127x/packet_transport/sx127x_transport.h +25 -0
  489. esphome/components/sx127x/sx127x.cpp +498 -0
  490. esphome/components/sx127x/sx127x.h +128 -0
  491. esphome/components/sx127x/sx127x_reg.h +295 -0
  492. esphome/components/syslog/esphome_syslog.cpp +5 -3
  493. esphome/components/syslog/esphome_syslog.h +1 -1
  494. esphome/components/tca9555/__init__.py +1 -1
  495. esphome/components/template/binary_sensor/template_binary_sensor.cpp +1 -9
  496. esphome/components/text/__init__.py +5 -2
  497. esphome/components/text_sensor/__init__.py +5 -2
  498. esphome/components/thermostat/thermostat_climate.cpp +34 -31
  499. esphome/components/thermostat/thermostat_climate.h +43 -39
  500. esphome/components/time/__init__.py +16 -2
  501. esphome/components/time/real_time_clock.cpp +4 -0
  502. esphome/components/time/real_time_clock.h +5 -1
  503. esphome/components/tlc5971/tlc5971.cpp +4 -1
  504. esphome/components/tmp1075/tmp1075.h +0 -2
  505. esphome/components/tof10120/tof10120_sensor.h +0 -1
  506. esphome/components/tormatic/tormatic_cover.h +0 -1
  507. esphome/components/total_daily_energy/total_daily_energy.h +0 -1
  508. esphome/components/tsl2591/tsl2591.cpp +1 -1
  509. esphome/components/ttp229_bsf/ttp229_bsf.h +0 -1
  510. esphome/components/ttp229_lsf/ttp229_lsf.h +0 -1
  511. esphome/components/tx20/tx20.cpp +2 -2
  512. esphome/components/uart/__init__.py +18 -0
  513. esphome/components/uart/uart_component_esp_idf.cpp +1 -5
  514. esphome/components/update/__init__.py +5 -2
  515. esphome/components/update/update_entity.h +8 -0
  516. esphome/components/usb_host/__init__.py +5 -2
  517. esphome/components/usb_host/usb_host_client.cpp +10 -10
  518. esphome/components/usb_uart/cp210x.cpp +1 -1
  519. esphome/components/usb_uart/usb_uart.cpp +41 -44
  520. esphome/components/usb_uart/usb_uart.h +4 -3
  521. esphome/components/valve/__init__.py +5 -2
  522. esphome/components/vbus/vbus.h +0 -1
  523. esphome/components/veml3235/veml3235.h +0 -1
  524. esphome/components/veml7700/veml7700.h +0 -1
  525. esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
  526. esphome/components/voice_assistant/voice_assistant.cpp +4 -4
  527. esphome/components/watchdog/watchdog.cpp +0 -4
  528. esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
  529. esphome/components/web_server/__init__.py +34 -19
  530. esphome/components/web_server/ota/__init__.py +32 -0
  531. esphome/components/web_server/ota/ota_web_server.cpp +210 -0
  532. esphome/components/web_server/ota/ota_web_server.h +26 -0
  533. esphome/components/web_server/web_server.cpp +324 -439
  534. esphome/components/web_server/web_server.h +33 -23
  535. esphome/components/web_server/web_server_v1.cpp +4 -5
  536. esphome/components/web_server_base/__init__.py +5 -2
  537. esphome/components/web_server_base/web_server_base.cpp +2 -94
  538. esphome/components/web_server_base/web_server_base.h +5 -25
  539. esphome/components/web_server_idf/multipart.cpp +254 -0
  540. esphome/components/web_server_idf/multipart.h +86 -0
  541. esphome/components/web_server_idf/utils.cpp +32 -0
  542. esphome/components/web_server_idf/utils.h +10 -0
  543. esphome/components/web_server_idf/web_server_idf.cpp +164 -16
  544. esphome/components/web_server_idf/web_server_idf.h +11 -10
  545. esphome/components/wiegand/wiegand.cpp +2 -2
  546. esphome/components/wifi/__init__.py +18 -0
  547. esphome/components/wifi/wifi_component.cpp +17 -22
  548. esphome/components/wifi/wifi_component.h +27 -23
  549. esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
  550. esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
  551. esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
  552. esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
  553. esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
  554. esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
  555. esphome/components/wireguard/__init__.py +2 -11
  556. esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
  557. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  558. esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
  559. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
  560. esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
  561. esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
  562. esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
  563. esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
  564. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
  565. esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
  566. esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
  567. esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
  568. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
  569. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
  570. esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
  571. esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
  572. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
  573. esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
  574. esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
  575. esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
  576. esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
  577. esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
  578. esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
  579. esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
  580. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
  581. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
  582. esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
  583. esphome/components/zyaura/zyaura.h +0 -1
  584. esphome/config.py +88 -22
  585. esphome/config_helpers.py +74 -1
  586. esphome/config_validation.py +12 -1
  587. esphome/const.py +65 -10
  588. esphome/core/__init__.py +18 -2
  589. esphome/core/application.cpp +169 -10
  590. esphome/core/application.h +145 -165
  591. esphome/core/area.h +19 -0
  592. esphome/core/automation.h +58 -9
  593. esphome/core/color.cpp +3 -5
  594. esphome/core/color.h +16 -16
  595. esphome/core/component.cpp +156 -22
  596. esphome/core/component.h +98 -4
  597. esphome/core/component_iterator.cpp +11 -9
  598. esphome/core/component_iterator.h +12 -10
  599. esphome/core/config.py +155 -6
  600. esphome/core/controller.cpp +4 -2
  601. esphome/core/controller.h +1 -1
  602. esphome/core/datatypes.h +2 -2
  603. esphome/core/defines.h +17 -2
  604. esphome/core/device.h +20 -0
  605. esphome/core/entity_base.cpp +20 -15
  606. esphome/core/entity_base.h +76 -0
  607. esphome/core/entity_helpers.py +168 -1
  608. esphome/core/event_pool.h +81 -0
  609. esphome/core/helpers.cpp +75 -230
  610. esphome/core/helpers.h +165 -105
  611. esphome/core/lock_free_queue.h +151 -0
  612. esphome/core/log.cpp +2 -2
  613. esphome/core/log.h +2 -0
  614. esphome/core/optional.h +5 -0
  615. esphome/core/ring_buffer.cpp +2 -2
  616. esphome/core/scheduler.cpp +275 -103
  617. esphome/core/scheduler.h +154 -17
  618. esphome/core/time.cpp +5 -5
  619. esphome/core/time.h +5 -5
  620. esphome/cpp_generator.py +17 -0
  621. esphome/cpp_helpers.py +0 -22
  622. esphome/cpp_types.py +3 -1
  623. esphome/dashboard/entries.py +1 -1
  624. esphome/dashboard/util/text.py +5 -21
  625. esphome/dashboard/web_server.py +9 -1
  626. esphome/helpers.py +47 -0
  627. esphome/loader.py +15 -1
  628. esphome/pins.py +14 -8
  629. esphome/platformio_api.py +2 -0
  630. esphome/wizard.py +17 -4
  631. esphome/writer.py +44 -3
  632. esphome/yaml_util.py +0 -2
  633. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/METADATA +10 -9
  634. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/RECORD +639 -580
  635. esphome/components/api/api_pb2_size.h +0 -361
  636. esphome/components/esp32_ble/ble_event_pool.h +0 -72
  637. esphome/components/esp32_ble/queue.h +0 -85
  638. esphome/components/esp32_hall/esp32_hall.cpp +0 -25
  639. esphome/components/esp32_hall/esp32_hall.h +0 -23
  640. esphome/components/esp32_touch/esp32_touch.cpp +0 -355
  641. esphome/components/ld2410/button/reset_button.cpp +0 -9
  642. esphome/components/ld2450/button/reset_button.cpp +0 -9
  643. esphome/components/openthread/tlv.py +0 -65
  644. /esphome/{dashboard/enum.py → enum.py} +0 -0
  645. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/WHEEL +0 -0
  646. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/entry_points.txt +0 -0
  647. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/licenses/LICENSE +0 -0
  648. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,7 @@
4
4
  #include "esphome/core/helpers.h"
5
5
  #include "esphome/core/log.h"
6
6
 
7
+ #include <cassert>
7
8
  #include <vector>
8
9
 
9
10
  #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
@@ -59,7 +60,6 @@ class ProtoVarInt {
59
60
  uint32_t as_uint32() const { return this->value_; }
60
61
  uint64_t as_uint64() const { return this->value_; }
61
62
  bool as_bool() const { return this->value_; }
62
- template<typename T> T as_enum() const { return static_cast<T>(this->as_uint32()); }
63
63
  int32_t as_int32() const {
64
64
  // Not ZigZag encoded
65
65
  return static_cast<int32_t>(this->as_int64());
@@ -133,15 +133,24 @@ class ProtoVarInt {
133
133
  uint64_t value_;
134
134
  };
135
135
 
136
+ // Forward declaration for decode_to_message and encode_to_writer
137
+ class ProtoMessage;
138
+
136
139
  class ProtoLengthDelimited {
137
140
  public:
138
141
  explicit ProtoLengthDelimited(const uint8_t *value, size_t length) : value_(value), length_(length) {}
139
142
  std::string as_string() const { return std::string(reinterpret_cast<const char *>(this->value_), this->length_); }
140
- template<class C> C as_message() const {
141
- auto msg = C();
142
- msg.decode(this->value_, this->length_);
143
- return msg;
144
- }
143
+
144
+ /**
145
+ * Decode the length-delimited data into an existing ProtoMessage instance.
146
+ *
147
+ * This method allows decoding without templates, enabling use in contexts
148
+ * where the message type is not known at compile time. The ProtoMessage's
149
+ * decode() method will be called with the raw data and length.
150
+ *
151
+ * @param msg The ProtoMessage instance to decode into
152
+ */
153
+ void decode_to_message(ProtoMessage &msg) const;
145
154
 
146
155
  protected:
147
156
  const uint8_t *const value_;
@@ -263,9 +272,6 @@ class ProtoWriteBuffer {
263
272
  this->write((value >> 48) & 0xFF);
264
273
  this->write((value >> 56) & 0xFF);
265
274
  }
266
- template<typename T> void encode_enum(uint32_t field_id, T value, bool force = false) {
267
- this->encode_uint32(field_id, static_cast<uint32_t>(value), force);
268
- }
269
275
  void encode_float(uint32_t field_id, float value, bool force = false) {
270
276
  if (value == 0.0f && !force)
271
277
  return;
@@ -306,18 +312,7 @@ class ProtoWriteBuffer {
306
312
  }
307
313
  this->encode_uint64(field_id, uvalue, force);
308
314
  }
309
- template<class C> void encode_message(uint32_t field_id, const C &value, bool force = false) {
310
- this->encode_field_raw(field_id, 2); // type 2: Length-delimited message
311
- size_t begin = this->buffer_->size();
312
-
313
- value.encode(*this);
314
-
315
- const uint32_t nested_length = this->buffer_->size() - begin;
316
- // add size varint
317
- std::vector<uint8_t> var;
318
- ProtoVarInt(nested_length).encode(var);
319
- this->buffer_->insert(this->buffer_->begin() + begin, var.begin(), var.end());
320
- }
315
+ void encode_message(uint32_t field_id, const ProtoMessage &value, bool force = false);
321
316
  std::vector<uint8_t> *get_buffer() const { return buffer_; }
322
317
 
323
318
  protected:
@@ -327,12 +322,15 @@ class ProtoWriteBuffer {
327
322
  class ProtoMessage {
328
323
  public:
329
324
  virtual ~ProtoMessage() = default;
330
- virtual void encode(ProtoWriteBuffer buffer) const = 0;
325
+ // Default implementation for messages with no fields
326
+ virtual void encode(ProtoWriteBuffer buffer) const {}
331
327
  void decode(const uint8_t *buffer, size_t length);
332
- virtual void calculate_size(uint32_t &total_size) const = 0;
328
+ // Default implementation for messages with no fields
329
+ virtual void calculate_size(uint32_t &total_size) const {}
333
330
  #ifdef HAS_PROTO_MESSAGE_DUMP
334
331
  std::string dump() const;
335
332
  virtual void dump_to(std::string &out) const = 0;
333
+ virtual const char *message_name() const { return "unknown"; }
336
334
  #endif
337
335
 
338
336
  protected:
@@ -342,6 +340,494 @@ class ProtoMessage {
342
340
  virtual bool decode_64bit(uint32_t field_id, Proto64Bit value) { return false; }
343
341
  };
344
342
 
343
+ class ProtoSize {
344
+ public:
345
+ /**
346
+ * @brief ProtoSize class for Protocol Buffer serialization size calculation
347
+ *
348
+ * This class provides static methods to calculate the exact byte counts needed
349
+ * for encoding various Protocol Buffer field types. All methods are designed to be
350
+ * efficient for the common case where many fields have default values.
351
+ *
352
+ * Implements Protocol Buffer encoding size calculation according to:
353
+ * https://protobuf.dev/programming-guides/encoding/
354
+ *
355
+ * Key features:
356
+ * - Early-return optimization for zero/default values
357
+ * - Direct total_size updates to avoid unnecessary additions
358
+ * - Specialized handling for different field types according to protobuf spec
359
+ * - Templated helpers for repeated fields and messages
360
+ */
361
+
362
+ /**
363
+ * @brief Calculates the size in bytes needed to encode a uint32_t value as a varint
364
+ *
365
+ * @param value The uint32_t value to calculate size for
366
+ * @return The number of bytes needed to encode the value
367
+ */
368
+ static inline uint32_t varint(uint32_t value) {
369
+ // Optimized varint size calculation using leading zeros
370
+ // Each 7 bits requires one byte in the varint encoding
371
+ if (value < 128)
372
+ return 1; // 7 bits, common case for small values
373
+
374
+ // For larger values, count bytes needed based on the position of the highest bit set
375
+ if (value < 16384) {
376
+ return 2; // 14 bits
377
+ } else if (value < 2097152) {
378
+ return 3; // 21 bits
379
+ } else if (value < 268435456) {
380
+ return 4; // 28 bits
381
+ } else {
382
+ return 5; // 32 bits (maximum for uint32_t)
383
+ }
384
+ }
385
+
386
+ /**
387
+ * @brief Calculates the size in bytes needed to encode a uint64_t value as a varint
388
+ *
389
+ * @param value The uint64_t value to calculate size for
390
+ * @return The number of bytes needed to encode the value
391
+ */
392
+ static inline uint32_t varint(uint64_t value) {
393
+ // Handle common case of values fitting in uint32_t (vast majority of use cases)
394
+ if (value <= UINT32_MAX) {
395
+ return varint(static_cast<uint32_t>(value));
396
+ }
397
+
398
+ // For larger values, determine size based on highest bit position
399
+ if (value < (1ULL << 35)) {
400
+ return 5; // 35 bits
401
+ } else if (value < (1ULL << 42)) {
402
+ return 6; // 42 bits
403
+ } else if (value < (1ULL << 49)) {
404
+ return 7; // 49 bits
405
+ } else if (value < (1ULL << 56)) {
406
+ return 8; // 56 bits
407
+ } else if (value < (1ULL << 63)) {
408
+ return 9; // 63 bits
409
+ } else {
410
+ return 10; // 64 bits (maximum for uint64_t)
411
+ }
412
+ }
413
+
414
+ /**
415
+ * @brief Calculates the size in bytes needed to encode an int32_t value as a varint
416
+ *
417
+ * Special handling is needed for negative values, which are sign-extended to 64 bits
418
+ * in Protocol Buffers, resulting in a 10-byte varint.
419
+ *
420
+ * @param value The int32_t value to calculate size for
421
+ * @return The number of bytes needed to encode the value
422
+ */
423
+ static inline uint32_t varint(int32_t value) {
424
+ // Negative values are sign-extended to 64 bits in protocol buffers,
425
+ // which always results in a 10-byte varint for negative int32
426
+ if (value < 0) {
427
+ return 10; // Negative int32 is always 10 bytes long
428
+ }
429
+ // For non-negative values, use the uint32_t implementation
430
+ return varint(static_cast<uint32_t>(value));
431
+ }
432
+
433
+ /**
434
+ * @brief Calculates the size in bytes needed to encode an int64_t value as a varint
435
+ *
436
+ * @param value The int64_t value to calculate size for
437
+ * @return The number of bytes needed to encode the value
438
+ */
439
+ static inline uint32_t varint(int64_t value) {
440
+ // For int64_t, we convert to uint64_t and calculate the size
441
+ // This works because the bit pattern determines the encoding size,
442
+ // and we've handled negative int32 values as a special case above
443
+ return varint(static_cast<uint64_t>(value));
444
+ }
445
+
446
+ /**
447
+ * @brief Calculates the size in bytes needed to encode a field ID and wire type
448
+ *
449
+ * @param field_id The field identifier
450
+ * @param type The wire type value (from the WireType enum in the protobuf spec)
451
+ * @return The number of bytes needed to encode the field ID and wire type
452
+ */
453
+ static inline uint32_t field(uint32_t field_id, uint32_t type) {
454
+ uint32_t tag = (field_id << 3) | (type & 0b111);
455
+ return varint(tag);
456
+ }
457
+
458
+ /**
459
+ * @brief Common parameters for all add_*_field methods
460
+ *
461
+ * All add_*_field methods follow these common patterns:
462
+ *
463
+ * @param total_size Reference to the total message size to update
464
+ * @param field_id_size Pre-calculated size of the field ID in bytes
465
+ * @param value The value to calculate size for (type varies)
466
+ * @param force Whether to calculate size even if the value is default/zero/empty
467
+ *
468
+ * Each method follows this implementation pattern:
469
+ * 1. Skip calculation if value is default (0, false, empty) and not forced
470
+ * 2. Calculate the size based on the field's encoding rules
471
+ * 3. Add the field_id_size + calculated value size to total_size
472
+ */
473
+
474
+ /**
475
+ * @brief Calculates and adds the size of an int32 field to the total message size
476
+ */
477
+ static inline void add_int32_field(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
478
+ // Skip calculation if value is zero
479
+ if (value == 0) {
480
+ return; // No need to update total_size
481
+ }
482
+
483
+ // Calculate and directly add to total_size
484
+ if (value < 0) {
485
+ // Negative values are encoded as 10-byte varints in protobuf
486
+ total_size += field_id_size + 10;
487
+ } else {
488
+ // For non-negative values, use the standard varint size
489
+ total_size += field_id_size + varint(static_cast<uint32_t>(value));
490
+ }
491
+ }
492
+
493
+ /**
494
+ * @brief Calculates and adds the size of an int32 field to the total message size (repeated field version)
495
+ */
496
+ static inline void add_int32_field_repeated(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
497
+ // Always calculate size for repeated fields
498
+ if (value < 0) {
499
+ // Negative values are encoded as 10-byte varints in protobuf
500
+ total_size += field_id_size + 10;
501
+ } else {
502
+ // For non-negative values, use the standard varint size
503
+ total_size += field_id_size + varint(static_cast<uint32_t>(value));
504
+ }
505
+ }
506
+
507
+ /**
508
+ * @brief Calculates and adds the size of a uint32 field to the total message size
509
+ */
510
+ static inline void add_uint32_field(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
511
+ // Skip calculation if value is zero
512
+ if (value == 0) {
513
+ return; // No need to update total_size
514
+ }
515
+
516
+ // Calculate and directly add to total_size
517
+ total_size += field_id_size + varint(value);
518
+ }
519
+
520
+ /**
521
+ * @brief Calculates and adds the size of a uint32 field to the total message size (repeated field version)
522
+ */
523
+ static inline void add_uint32_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
524
+ // Always calculate size for repeated fields
525
+ total_size += field_id_size + varint(value);
526
+ }
527
+
528
+ /**
529
+ * @brief Calculates and adds the size of a boolean field to the total message size
530
+ */
531
+ static inline void add_bool_field(uint32_t &total_size, uint32_t field_id_size, bool value) {
532
+ // Skip calculation if value is false
533
+ if (!value) {
534
+ return; // No need to update total_size
535
+ }
536
+
537
+ // Boolean fields always use 1 byte when true
538
+ total_size += field_id_size + 1;
539
+ }
540
+
541
+ /**
542
+ * @brief Calculates and adds the size of a boolean field to the total message size (repeated field version)
543
+ */
544
+ static inline void add_bool_field_repeated(uint32_t &total_size, uint32_t field_id_size, bool value) {
545
+ // Always calculate size for repeated fields
546
+ // Boolean fields always use 1 byte
547
+ total_size += field_id_size + 1;
548
+ }
549
+
550
+ /**
551
+ * @brief Calculates and adds the size of a fixed field to the total message size
552
+ *
553
+ * Fixed fields always take exactly N bytes (4 for fixed32/float, 8 for fixed64/double).
554
+ *
555
+ * @tparam NumBytes The number of bytes for this fixed field (4 or 8)
556
+ * @param is_nonzero Whether the value is non-zero
557
+ */
558
+ template<uint32_t NumBytes>
559
+ static inline void add_fixed_field(uint32_t &total_size, uint32_t field_id_size, bool is_nonzero) {
560
+ // Skip calculation if value is zero
561
+ if (!is_nonzero) {
562
+ return; // No need to update total_size
563
+ }
564
+
565
+ // Fixed fields always take exactly NumBytes
566
+ total_size += field_id_size + NumBytes;
567
+ }
568
+
569
+ /**
570
+ * @brief Calculates and adds the size of an enum field to the total message size
571
+ *
572
+ * Enum fields are encoded as uint32 varints.
573
+ */
574
+ static inline void add_enum_field(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
575
+ // Skip calculation if value is zero
576
+ if (value == 0) {
577
+ return; // No need to update total_size
578
+ }
579
+
580
+ // Enums are encoded as uint32
581
+ total_size += field_id_size + varint(value);
582
+ }
583
+
584
+ /**
585
+ * @brief Calculates and adds the size of an enum field to the total message size (repeated field version)
586
+ *
587
+ * Enum fields are encoded as uint32 varints.
588
+ */
589
+ static inline void add_enum_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint32_t value) {
590
+ // Always calculate size for repeated fields
591
+ // Enums are encoded as uint32
592
+ total_size += field_id_size + varint(value);
593
+ }
594
+
595
+ /**
596
+ * @brief Calculates and adds the size of a sint32 field to the total message size
597
+ *
598
+ * Sint32 fields use ZigZag encoding, which is more efficient for negative values.
599
+ */
600
+ static inline void add_sint32_field(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
601
+ // Skip calculation if value is zero
602
+ if (value == 0) {
603
+ return; // No need to update total_size
604
+ }
605
+
606
+ // ZigZag encoding for sint32: (n << 1) ^ (n >> 31)
607
+ uint32_t zigzag = (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
608
+ total_size += field_id_size + varint(zigzag);
609
+ }
610
+
611
+ /**
612
+ * @brief Calculates and adds the size of a sint32 field to the total message size (repeated field version)
613
+ *
614
+ * Sint32 fields use ZigZag encoding, which is more efficient for negative values.
615
+ */
616
+ static inline void add_sint32_field_repeated(uint32_t &total_size, uint32_t field_id_size, int32_t value) {
617
+ // Always calculate size for repeated fields
618
+ // ZigZag encoding for sint32: (n << 1) ^ (n >> 31)
619
+ uint32_t zigzag = (static_cast<uint32_t>(value) << 1) ^ (static_cast<uint32_t>(value >> 31));
620
+ total_size += field_id_size + varint(zigzag);
621
+ }
622
+
623
+ /**
624
+ * @brief Calculates and adds the size of an int64 field to the total message size
625
+ */
626
+ static inline void add_int64_field(uint32_t &total_size, uint32_t field_id_size, int64_t value) {
627
+ // Skip calculation if value is zero
628
+ if (value == 0) {
629
+ return; // No need to update total_size
630
+ }
631
+
632
+ // Calculate and directly add to total_size
633
+ total_size += field_id_size + varint(value);
634
+ }
635
+
636
+ /**
637
+ * @brief Calculates and adds the size of an int64 field to the total message size (repeated field version)
638
+ */
639
+ static inline void add_int64_field_repeated(uint32_t &total_size, uint32_t field_id_size, int64_t value) {
640
+ // Always calculate size for repeated fields
641
+ total_size += field_id_size + varint(value);
642
+ }
643
+
644
+ /**
645
+ * @brief Calculates and adds the size of a uint64 field to the total message size
646
+ */
647
+ static inline void add_uint64_field(uint32_t &total_size, uint32_t field_id_size, uint64_t value) {
648
+ // Skip calculation if value is zero
649
+ if (value == 0) {
650
+ return; // No need to update total_size
651
+ }
652
+
653
+ // Calculate and directly add to total_size
654
+ total_size += field_id_size + varint(value);
655
+ }
656
+
657
+ /**
658
+ * @brief Calculates and adds the size of a uint64 field to the total message size (repeated field version)
659
+ */
660
+ static inline void add_uint64_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint64_t value) {
661
+ // Always calculate size for repeated fields
662
+ total_size += field_id_size + varint(value);
663
+ }
664
+
665
+ /**
666
+ * @brief Calculates and adds the size of a sint64 field to the total message size
667
+ *
668
+ * Sint64 fields use ZigZag encoding, which is more efficient for negative values.
669
+ */
670
+ static inline void add_sint64_field(uint32_t &total_size, uint32_t field_id_size, int64_t value) {
671
+ // Skip calculation if value is zero
672
+ if (value == 0) {
673
+ return; // No need to update total_size
674
+ }
675
+
676
+ // ZigZag encoding for sint64: (n << 1) ^ (n >> 63)
677
+ uint64_t zigzag = (static_cast<uint64_t>(value) << 1) ^ (static_cast<uint64_t>(value >> 63));
678
+ total_size += field_id_size + varint(zigzag);
679
+ }
680
+
681
+ /**
682
+ * @brief Calculates and adds the size of a sint64 field to the total message size (repeated field version)
683
+ *
684
+ * Sint64 fields use ZigZag encoding, which is more efficient for negative values.
685
+ */
686
+ static inline void add_sint64_field_repeated(uint32_t &total_size, uint32_t field_id_size, int64_t value) {
687
+ // Always calculate size for repeated fields
688
+ // ZigZag encoding for sint64: (n << 1) ^ (n >> 63)
689
+ uint64_t zigzag = (static_cast<uint64_t>(value) << 1) ^ (static_cast<uint64_t>(value >> 63));
690
+ total_size += field_id_size + varint(zigzag);
691
+ }
692
+
693
+ /**
694
+ * @brief Calculates and adds the size of a string/bytes field to the total message size
695
+ */
696
+ static inline void add_string_field(uint32_t &total_size, uint32_t field_id_size, const std::string &str) {
697
+ // Skip calculation if string is empty
698
+ if (str.empty()) {
699
+ return; // No need to update total_size
700
+ }
701
+
702
+ // Calculate and directly add to total_size
703
+ const uint32_t str_size = static_cast<uint32_t>(str.size());
704
+ total_size += field_id_size + varint(str_size) + str_size;
705
+ }
706
+
707
+ /**
708
+ * @brief Calculates and adds the size of a string/bytes field to the total message size (repeated field version)
709
+ */
710
+ static inline void add_string_field_repeated(uint32_t &total_size, uint32_t field_id_size, const std::string &str) {
711
+ // Always calculate size for repeated fields
712
+ const uint32_t str_size = static_cast<uint32_t>(str.size());
713
+ total_size += field_id_size + varint(str_size) + str_size;
714
+ }
715
+
716
+ /**
717
+ * @brief Calculates and adds the size of a nested message field to the total message size
718
+ *
719
+ * This helper function directly updates the total_size reference if the nested size
720
+ * is greater than zero.
721
+ *
722
+ * @param nested_size The pre-calculated size of the nested message
723
+ */
724
+ static inline void add_message_field(uint32_t &total_size, uint32_t field_id_size, uint32_t nested_size) {
725
+ // Skip calculation if nested message is empty
726
+ if (nested_size == 0) {
727
+ return; // No need to update total_size
728
+ }
729
+
730
+ // Calculate and directly add to total_size
731
+ // Field ID + length varint + nested message content
732
+ total_size += field_id_size + varint(nested_size) + nested_size;
733
+ }
734
+
735
+ /**
736
+ * @brief Calculates and adds the size of a nested message field to the total message size (repeated field version)
737
+ *
738
+ * @param nested_size The pre-calculated size of the nested message
739
+ */
740
+ static inline void add_message_field_repeated(uint32_t &total_size, uint32_t field_id_size, uint32_t nested_size) {
741
+ // Always calculate size for repeated fields
742
+ // Field ID + length varint + nested message content
743
+ total_size += field_id_size + varint(nested_size) + nested_size;
744
+ }
745
+
746
+ /**
747
+ * @brief Calculates and adds the size of a nested message field to the total message size
748
+ *
749
+ * This version takes a ProtoMessage object, calculates its size internally,
750
+ * and updates the total_size reference. This eliminates the need for a temporary variable
751
+ * at the call site.
752
+ *
753
+ * @param message The nested message object
754
+ */
755
+ static inline void add_message_object(uint32_t &total_size, uint32_t field_id_size, const ProtoMessage &message) {
756
+ uint32_t nested_size = 0;
757
+ message.calculate_size(nested_size);
758
+
759
+ // Use the base implementation with the calculated nested_size
760
+ add_message_field(total_size, field_id_size, nested_size);
761
+ }
762
+
763
+ /**
764
+ * @brief Calculates and adds the size of a nested message field to the total message size (repeated field version)
765
+ *
766
+ * @param message The nested message object
767
+ */
768
+ static inline void add_message_object_repeated(uint32_t &total_size, uint32_t field_id_size,
769
+ const ProtoMessage &message) {
770
+ uint32_t nested_size = 0;
771
+ message.calculate_size(nested_size);
772
+
773
+ // Use the base implementation with the calculated nested_size
774
+ add_message_field_repeated(total_size, field_id_size, nested_size);
775
+ }
776
+
777
+ /**
778
+ * @brief Calculates and adds the sizes of all messages in a repeated field to the total message size
779
+ *
780
+ * This helper processes a vector of message objects, calculating the size for each message
781
+ * and adding it to the total size.
782
+ *
783
+ * @tparam MessageType The type of the nested messages in the vector
784
+ * @param messages Vector of message objects
785
+ */
786
+ template<typename MessageType>
787
+ static inline void add_repeated_message(uint32_t &total_size, uint32_t field_id_size,
788
+ const std::vector<MessageType> &messages) {
789
+ // Skip if the vector is empty
790
+ if (messages.empty()) {
791
+ return;
792
+ }
793
+
794
+ // Use the repeated field version for all messages
795
+ for (const auto &message : messages) {
796
+ add_message_object_repeated(total_size, field_id_size, message);
797
+ }
798
+ }
799
+ };
800
+
801
+ // Implementation of encode_message - must be after ProtoMessage is defined
802
+ inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const ProtoMessage &value, bool force) {
803
+ this->encode_field_raw(field_id, 2); // type 2: Length-delimited message
804
+
805
+ // Calculate the message size first
806
+ uint32_t msg_length_bytes = 0;
807
+ value.calculate_size(msg_length_bytes);
808
+
809
+ // Calculate how many bytes the length varint needs
810
+ uint32_t varint_length_bytes = ProtoSize::varint(msg_length_bytes);
811
+
812
+ // Reserve exact space for the length varint
813
+ size_t begin = this->buffer_->size();
814
+ this->buffer_->resize(this->buffer_->size() + varint_length_bytes);
815
+
816
+ // Write the length varint directly
817
+ ProtoVarInt(msg_length_bytes).encode_to_buffer_unchecked(this->buffer_->data() + begin, varint_length_bytes);
818
+
819
+ // Now encode the message content - it will append to the buffer
820
+ value.encode(*this);
821
+
822
+ // Verify that the encoded size matches what we calculated
823
+ assert(this->buffer_->size() == begin + varint_length_bytes + msg_length_bytes);
824
+ }
825
+
826
+ // Implementation of decode_to_message - must be after ProtoMessage is defined
827
+ inline void ProtoLengthDelimited::decode_to_message(ProtoMessage &msg) const {
828
+ msg.decode(this->value_, this->length_);
829
+ }
830
+
345
831
  template<typename T> const char *proto_enum_to_string(T value);
346
832
 
347
833
  class ProtoService {
@@ -360,11 +846,11 @@ class ProtoService {
360
846
  * @return A ProtoWriteBuffer object with the reserved size.
361
847
  */
362
848
  virtual ProtoWriteBuffer create_buffer(uint32_t reserve_size) = 0;
363
- virtual bool send_buffer(ProtoWriteBuffer buffer, uint16_t message_type) = 0;
364
- virtual bool read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) = 0;
849
+ virtual bool send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) = 0;
850
+ virtual void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) = 0;
365
851
 
366
852
  // Optimized method that pre-allocates buffer based on message size
367
- bool send_message_(const ProtoMessage &msg, uint16_t message_type) {
853
+ bool send_message_(const ProtoMessage &msg, uint8_t message_type) {
368
854
  uint32_t msg_size = 0;
369
855
  msg.calculate_size(msg_size);
370
856
 
@@ -377,6 +863,26 @@ class ProtoService {
377
863
  // Send the buffer
378
864
  return this->send_buffer(buffer, message_type);
379
865
  }
866
+
867
+ // Authentication helper methods
868
+ bool check_connection_setup_() {
869
+ if (!this->is_connection_setup()) {
870
+ this->on_no_setup_connection();
871
+ return false;
872
+ }
873
+ return true;
874
+ }
875
+
876
+ bool check_authenticated_() {
877
+ if (!this->check_connection_setup_()) {
878
+ return false;
879
+ }
880
+ if (!this->is_authenticated()) {
881
+ this->on_unauthenticated_access();
882
+ return false;
883
+ }
884
+ return true;
885
+ }
380
886
  };
381
887
 
382
888
  } // namespace api