esphome 2025.8.4__py3-none-any.whl → 2025.9.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. esphome/__main__.py +36 -42
  2. esphome/components/absolute_humidity/absolute_humidity.cpp +3 -5
  3. esphome/components/adc/adc_sensor_esp32.cpp +29 -6
  4. esphome/components/ags10/ags10.cpp +3 -18
  5. esphome/components/ags10/ags10.h +2 -12
  6. esphome/components/aht10/aht10.cpp +3 -3
  7. esphome/components/airthings_ble/__init__.py +2 -2
  8. esphome/components/alarm_control_panel/__init__.py +2 -2
  9. esphome/components/am2315c/am2315c.cpp +1 -17
  10. esphome/components/am2315c/am2315c.h +2 -3
  11. esphome/components/api/__init__.py +2 -2
  12. esphome/components/api/api_connection.cpp +34 -23
  13. esphome/components/api/api_connection.h +20 -39
  14. esphome/components/api/api_frame_helper.cpp +25 -25
  15. esphome/components/api/api_frame_helper.h +3 -3
  16. esphome/components/api/api_frame_helper_noise.cpp +75 -40
  17. esphome/components/api/api_frame_helper_noise.h +3 -7
  18. esphome/components/api/api_frame_helper_plaintext.cpp +17 -4
  19. esphome/components/api/api_frame_helper_plaintext.h +1 -4
  20. esphome/components/api/api_pb2.cpp +20 -2
  21. esphome/components/api/api_pb2.h +146 -141
  22. esphome/components/api/api_pb2_dump.cpp +12 -1
  23. esphome/components/api/proto.cpp +33 -37
  24. esphome/components/async_tcp/__init__.py +2 -2
  25. esphome/components/atm90e26/sensor.py +2 -0
  26. esphome/components/atm90e32/sensor.py +4 -2
  27. esphome/components/audio_adc/__init__.py +2 -2
  28. esphome/components/audio_dac/__init__.py +2 -2
  29. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +1 -1
  30. esphome/components/bedjet/bedjet_hub.cpp +1 -1
  31. esphome/components/binary_sensor/__init__.py +2 -2
  32. esphome/components/binary_sensor/binary_sensor.cpp +13 -0
  33. esphome/components/binary_sensor/binary_sensor.h +4 -7
  34. esphome/components/bl0940/__init__.py +6 -1
  35. esphome/components/bl0940/bl0940.cpp +178 -41
  36. esphome/components/bl0940/bl0940.h +121 -76
  37. esphome/components/bl0940/button/__init__.py +27 -0
  38. esphome/components/bl0940/button/calibration_reset_button.cpp +20 -0
  39. esphome/components/bl0940/button/calibration_reset_button.h +19 -0
  40. esphome/components/bl0940/number/__init__.py +94 -0
  41. esphome/components/bl0940/number/calibration_number.cpp +29 -0
  42. esphome/components/bl0940/number/calibration_number.h +26 -0
  43. esphome/components/bl0940/sensor.py +151 -2
  44. esphome/components/bl0942/bl0942.cpp +1 -1
  45. esphome/components/ble_client/output/__init__.py +4 -4
  46. esphome/components/bluetooth_proxy/__init__.py +1 -1
  47. esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -1
  48. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +15 -7
  49. esphome/components/bluetooth_proxy/bluetooth_proxy.h +3 -2
  50. esphome/components/button/__init__.py +2 -2
  51. esphome/components/button/button.cpp +13 -0
  52. esphome/components/button/button.h +4 -7
  53. esphome/components/camera/buffer.h +18 -0
  54. esphome/components/camera/buffer_impl.cpp +20 -0
  55. esphome/components/camera/buffer_impl.h +26 -0
  56. esphome/components/camera/camera.h +43 -0
  57. esphome/components/camera/encoder.h +69 -0
  58. esphome/components/camera_encoder/__init__.py +62 -0
  59. esphome/components/camera_encoder/encoder_buffer_impl.cpp +23 -0
  60. esphome/components/camera_encoder/encoder_buffer_impl.h +25 -0
  61. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +82 -0
  62. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +39 -0
  63. esphome/components/captive_portal/__init__.py +2 -2
  64. esphome/components/captive_portal/captive_portal.cpp +35 -12
  65. esphome/components/captive_portal/captive_portal.h +3 -3
  66. esphome/components/ccs811/ccs811.cpp +3 -3
  67. esphome/components/climate/__init__.py +2 -2
  68. esphome/components/climate/climate.cpp +1 -1
  69. esphome/components/cover/__init__.py +5 -5
  70. esphome/components/cover/cover.cpp +1 -1
  71. esphome/components/cover/cover.h +2 -2
  72. esphome/components/dallas_temp/dallas_temp.cpp +2 -2
  73. esphome/components/datetime/__init__.py +2 -2
  74. esphome/components/datetime/date_entity.h +2 -2
  75. esphome/components/datetime/datetime_entity.h +2 -2
  76. esphome/components/datetime/time_entity.h +2 -2
  77. esphome/components/debug/debug_esp32.cpp +1 -1
  78. esphome/components/display/__init__.py +4 -4
  79. esphome/components/duty_time/duty_time_sensor.cpp +1 -1
  80. esphome/components/esp32/__init__.py +0 -5
  81. esphome/components/esp32/gpio.cpp +27 -23
  82. esphome/components/esp32/gpio.h +26 -11
  83. esphome/components/esp32/preferences.cpp +8 -4
  84. esphome/components/esp32_ble/__init__.py +7 -2
  85. esphome/components/esp32_ble_client/ble_client_base.cpp +7 -3
  86. esphome/components/esp32_ble_tracker/__init__.py +2 -2
  87. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +9 -44
  88. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -14
  89. esphome/components/esp8266/__init__.py +2 -2
  90. esphome/components/esp8266/core.cpp +2 -2
  91. esphome/components/esp8266/gpio.py +4 -4
  92. esphome/components/esp8266/preferences.cpp +30 -28
  93. esphome/components/esphome/ota/__init__.py +2 -2
  94. esphome/components/esphome/ota/ota_esphome.cpp +21 -19
  95. esphome/components/esphome/ota/ota_esphome.h +6 -5
  96. esphome/components/ethernet/__init__.py +7 -2
  97. esphome/components/ethernet/ethernet_component.cpp +1 -1
  98. esphome/components/event/__init__.py +2 -2
  99. esphome/components/event/event.h +4 -4
  100. esphome/components/fan/__init__.py +2 -2
  101. esphome/components/fan/fan.cpp +2 -1
  102. esphome/components/gdk101/gdk101.cpp +4 -4
  103. esphome/components/globals/__init__.py +2 -2
  104. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +19 -18
  105. esphome/components/gpio_expander/cached_gpio.h +36 -16
  106. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -5
  107. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
  108. esphome/components/haier/haier_base.cpp +1 -1
  109. esphome/components/haier/hon_climate.cpp +1 -1
  110. esphome/components/hlw8012/hlw8012.cpp +5 -5
  111. esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +4 -4
  112. esphome/components/host/preferences.h +3 -2
  113. esphome/components/hte501/hte501.cpp +3 -21
  114. esphome/components/hte501/hte501.h +2 -3
  115. esphome/components/http_request/ota/__init__.py +2 -2
  116. esphome/components/i2c/__init__.py +2 -2
  117. esphome/components/i2c/i2c.cpp +13 -9
  118. esphome/components/i2c/i2c_bus.h +36 -6
  119. esphome/components/i2s_audio/__init__.py +8 -2
  120. esphome/components/i2s_audio/media_player/__init__.py +1 -1
  121. esphome/components/i2s_audio/microphone/__init__.py +1 -1
  122. esphome/components/i2s_audio/speaker/__init__.py +1 -1
  123. esphome/components/inkplate/__init__.py +1 -0
  124. esphome/components/inkplate/const.py +105 -0
  125. esphome/components/inkplate/display.py +238 -0
  126. esphome/components/{inkplate6 → inkplate}/inkplate.cpp +156 -74
  127. esphome/components/{inkplate6 → inkplate}/inkplate.h +28 -68
  128. esphome/components/inkplate6/__init__.py +0 -1
  129. esphome/components/inkplate6/display.py +2 -211
  130. esphome/components/integration/integration_sensor.cpp +1 -1
  131. esphome/components/json/__init__.py +2 -2
  132. esphome/components/lc709203f/lc709203f.cpp +4 -17
  133. esphome/components/lc709203f/lc709203f.h +2 -3
  134. esphome/components/ld2420/text_sensor/{text_sensor.cpp → ld2420_text_sensor.cpp} +1 -1
  135. esphome/components/ld2450/ld2450.cpp +1 -1
  136. esphome/components/libretiny/preferences.cpp +13 -5
  137. esphome/components/light/__init__.py +2 -2
  138. esphome/components/light/addressable_light_effect.h +7 -0
  139. esphome/components/light/base_light_effects.h +8 -0
  140. esphome/components/light/light_call.cpp +22 -20
  141. esphome/components/light/light_effect.cpp +36 -0
  142. esphome/components/light/light_effect.h +14 -0
  143. esphome/components/light/light_json_schema.cpp +9 -1
  144. esphome/components/light/light_state.cpp +2 -2
  145. esphome/components/light/light_state.h +38 -0
  146. esphome/components/lock/__init__.py +2 -2
  147. esphome/components/lock/lock.h +2 -2
  148. esphome/components/logger/__init__.py +2 -2
  149. esphome/components/logger/logger.cpp +25 -4
  150. esphome/components/logger/logger.h +1 -1
  151. esphome/components/logger/logger_esp32.cpp +16 -8
  152. esphome/components/logger/logger_esp8266.cpp +11 -3
  153. esphome/components/logger/logger_libretiny.cpp +13 -3
  154. esphome/components/logger/logger_rp2040.cpp +14 -3
  155. esphome/components/logger/logger_zephyr.cpp +15 -4
  156. esphome/components/lvgl/defines.py +1 -0
  157. esphome/components/lvgl/hello_world.py +96 -33
  158. esphome/components/lvgl/number/lvgl_number.h +1 -1
  159. esphome/components/lvgl/select/lvgl_select.h +1 -1
  160. esphome/components/lvgl/widgets/__init__.py +0 -1
  161. esphome/components/lvgl/widgets/spinbox.py +20 -11
  162. esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +1 -1
  163. esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +1 -1
  164. esphome/components/mapping/__init__.py +13 -5
  165. esphome/components/mapping/mapping.h +69 -0
  166. esphome/components/max17043/max17043.cpp +2 -2
  167. esphome/components/mcp23016/__init__.py +1 -0
  168. esphome/components/mcp23016/mcp23016.cpp +20 -5
  169. esphome/components/mcp23016/mcp23016.h +10 -4
  170. esphome/components/mcp23x08_base/mcp23x08_base.cpp +1 -1
  171. esphome/components/mcp23x17_base/mcp23x17_base.cpp +2 -2
  172. esphome/components/mdns/__init__.py +2 -2
  173. esphome/components/mdns/mdns_component.cpp +145 -54
  174. esphome/components/media_player/__init__.py +2 -2
  175. esphome/components/micro_wake_word/__init__.py +2 -2
  176. esphome/components/microphone/__init__.py +2 -2
  177. esphome/components/mipi/__init__.py +77 -33
  178. esphome/components/mipi_rgb/__init__.py +2 -0
  179. esphome/components/mipi_rgb/display.py +321 -0
  180. esphome/components/mipi_rgb/mipi_rgb.cpp +388 -0
  181. esphome/components/mipi_rgb/mipi_rgb.h +127 -0
  182. esphome/components/mipi_rgb/models/guition.py +24 -0
  183. esphome/components/mipi_rgb/models/lilygo.py +228 -0
  184. esphome/components/mipi_rgb/models/rpi.py +9 -0
  185. esphome/components/mipi_rgb/models/st7701s.py +214 -0
  186. esphome/components/mipi_rgb/models/waveshare.py +64 -0
  187. esphome/components/mipi_spi/models/jc.py +229 -0
  188. esphome/components/mlx90614/mlx90614.cpp +1 -16
  189. esphome/components/mlx90614/mlx90614.h +0 -1
  190. esphome/components/mqtt/__init__.py +2 -2
  191. esphome/components/mqtt/mqtt_sensor.cpp +7 -2
  192. esphome/components/ms5611/ms5611.cpp +7 -6
  193. esphome/components/network/__init__.py +2 -2
  194. esphome/components/nextion/nextion_upload.cpp +4 -1
  195. esphome/components/nrf52/__init__.py +49 -6
  196. esphome/components/nrf52/const.py +1 -0
  197. esphome/components/nrf52/dfu.cpp +51 -0
  198. esphome/components/nrf52/dfu.h +24 -0
  199. esphome/components/ntc/ntc.cpp +1 -1
  200. esphome/components/number/__init__.py +2 -2
  201. esphome/components/number/automation.cpp +1 -1
  202. esphome/components/number/number.cpp +21 -0
  203. esphome/components/number/number.h +4 -13
  204. esphome/components/opentherm/hub.h +6 -6
  205. esphome/components/opentherm/number/{number.cpp → opentherm_number.cpp} +2 -2
  206. esphome/components/opentherm/output/{output.cpp → opentherm_output.cpp} +1 -1
  207. esphome/components/opentherm/switch/{switch.cpp → opentherm_switch.cpp} +1 -1
  208. esphome/components/ota/__init__.py +2 -2
  209. esphome/components/pca6416a/__init__.py +1 -0
  210. esphome/components/pca6416a/pca6416a.cpp +20 -5
  211. esphome/components/pca6416a/pca6416a.h +12 -5
  212. esphome/components/pca9554/__init__.py +2 -1
  213. esphome/components/pca9554/pca9554.cpp +12 -18
  214. esphome/components/pca9554/pca9554.h +10 -9
  215. esphome/components/pcf8574/__init__.py +1 -0
  216. esphome/components/pcf8574/pcf8574.cpp +14 -5
  217. esphome/components/pcf8574/pcf8574.h +13 -6
  218. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +7 -7
  219. esphome/components/pipsolar/__init__.py +3 -3
  220. esphome/components/pipsolar/output/__init__.py +4 -4
  221. esphome/components/pulse_width/pulse_width.cpp +2 -2
  222. esphome/components/qmp6988/qmp6988.cpp +81 -126
  223. esphome/components/qmp6988/qmp6988.h +31 -37
  224. esphome/components/radon_eye_ble/__init__.py +2 -2
  225. esphome/components/remote_base/__init__.py +6 -8
  226. esphome/components/rotary_encoder/rotary_encoder.cpp +1 -1
  227. esphome/components/rp2040/__init__.py +2 -2
  228. esphome/components/runtime_stats/runtime_stats.cpp +10 -23
  229. esphome/components/runtime_stats/runtime_stats.h +4 -10
  230. esphome/components/safe_mode/__init__.py +2 -2
  231. esphome/components/safe_mode/safe_mode.cpp +33 -31
  232. esphome/components/script/script.cpp +6 -0
  233. esphome/components/script/script.h +19 -5
  234. esphome/components/sdm_meter/sensor.py +3 -1
  235. esphome/components/select/__init__.py +2 -2
  236. esphome/components/select/select.h +2 -2
  237. esphome/components/sen5x/sen5x.cpp +57 -55
  238. esphome/components/sen5x/sen5x.h +21 -15
  239. esphome/components/sen5x/sensor.py +67 -44
  240. esphome/components/sensirion_common/i2c_sensirion.cpp +18 -47
  241. esphome/components/sensirion_common/i2c_sensirion.h +39 -55
  242. esphome/components/sensor/__init__.py +2 -2
  243. esphome/components/sensor/automation.h +1 -1
  244. esphome/components/sensor/sensor.cpp +34 -6
  245. esphome/components/sensor/sensor.h +4 -21
  246. esphome/components/sgp30/sgp30.cpp +34 -35
  247. esphome/components/sgp30/sgp30.h +11 -10
  248. esphome/components/sgp4x/sgp4x.cpp +2 -2
  249. esphome/components/shelly_dimmer/light.py +7 -7
  250. esphome/components/sht4x/sht4x.cpp +1 -1
  251. esphome/components/sntp/sntp_component.cpp +36 -9
  252. esphome/components/sntp/sntp_component.h +7 -0
  253. esphome/components/sound_level/sound_level.cpp +1 -1
  254. esphome/components/speaker/__init__.py +2 -2
  255. esphome/components/speaker/media_player/__init__.py +2 -2
  256. esphome/components/speaker/media_player/speaker_media_player.cpp +1 -1
  257. esphome/components/spi/__init__.py +2 -2
  258. esphome/components/sprinkler/sprinkler.cpp +1 -1
  259. esphome/components/sps30/sps30.cpp +18 -23
  260. esphome/components/sps30/sps30.h +3 -3
  261. esphome/components/status_led/__init__.py +2 -2
  262. esphome/components/stepper/__init__.py +2 -2
  263. esphome/components/switch/__init__.py +2 -2
  264. esphome/components/switch/switch.cpp +5 -5
  265. esphome/components/sx1509/__init__.py +1 -1
  266. esphome/components/sx1509/sx1509.cpp +12 -7
  267. esphome/components/sx1509/sx1509.h +11 -4
  268. esphome/components/tca9555/tca9555.cpp +5 -5
  269. esphome/components/tee501/tee501.cpp +2 -21
  270. esphome/components/tee501/tee501.h +2 -4
  271. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +1 -1
  272. esphome/components/template/datetime/template_date.cpp +1 -1
  273. esphome/components/template/datetime/template_datetime.cpp +2 -2
  274. esphome/components/template/datetime/template_time.cpp +1 -1
  275. esphome/components/template/number/template_number.cpp +1 -1
  276. esphome/components/template/select/template_select.cpp +1 -1
  277. esphome/components/template/text/template_text.cpp +1 -1
  278. esphome/components/text/__init__.py +2 -2
  279. esphome/components/text/text.h +2 -2
  280. esphome/components/text_sensor/__init__.py +2 -2
  281. esphome/components/text_sensor/text_sensor.h +4 -4
  282. esphome/components/thermostat/climate.py +11 -7
  283. esphome/components/thermostat/thermostat_climate.cpp +237 -206
  284. esphome/components/thermostat/thermostat_climate.h +52 -41
  285. esphome/components/time/__init__.py +2 -2
  286. esphome/components/tmp1075/tmp1075.cpp +1 -1
  287. esphome/components/total_daily_energy/total_daily_energy.cpp +1 -1
  288. esphome/components/touchscreen/__init__.py +2 -2
  289. esphome/components/tuya/number/tuya_number.cpp +1 -1
  290. esphome/components/udp/udp_component.cpp +3 -3
  291. esphome/components/ufire_ec/ufire_ec.cpp +4 -4
  292. esphome/components/ufire_ise/ufire_ise.cpp +4 -4
  293. esphome/components/update/__init__.py +2 -2
  294. esphome/components/usb_uart/usb_uart.cpp +1 -1
  295. esphome/components/valve/__init__.py +5 -5
  296. esphome/components/valve/valve.cpp +1 -1
  297. esphome/components/valve/valve.h +2 -2
  298. esphome/components/wake_on_lan/wake_on_lan.cpp +2 -2
  299. esphome/components/waveshare_epaper/waveshare_213v3.cpp +1 -1
  300. esphome/components/web_server/__init__.py +2 -2
  301. esphome/components/web_server/ota/__init__.py +2 -2
  302. esphome/components/web_server/ota/ota_web_server.cpp +11 -0
  303. esphome/components/web_server/web_server.cpp +58 -12
  304. esphome/components/web_server_base/__init__.py +2 -2
  305. esphome/components/wifi/__init__.py +5 -5
  306. esphome/components/wifi/wifi_component.cpp +3 -3
  307. esphome/components/wifi/wifi_component_esp_idf.cpp +2 -0
  308. esphome/config_validation.py +2 -2
  309. esphome/const.py +2 -1
  310. esphome/core/__init__.py +1 -0
  311. esphome/core/application.cpp +89 -51
  312. esphome/core/application.h +1 -0
  313. esphome/core/component.cpp +41 -19
  314. esphome/core/component.h +17 -13
  315. esphome/core/config.py +7 -7
  316. esphome/core/defines.h +4 -0
  317. esphome/core/entity_base.cpp +22 -8
  318. esphome/core/entity_base.h +43 -0
  319. esphome/core/helpers.cpp +26 -13
  320. esphome/core/helpers.h +4 -3
  321. esphome/core/ring_buffer.cpp +6 -2
  322. esphome/core/ring_buffer.h +2 -1
  323. esphome/core/scheduler.cpp +175 -94
  324. esphome/core/scheduler.h +66 -35
  325. esphome/core/time.cpp +6 -20
  326. esphome/coroutine.py +80 -3
  327. esphome/cpp_generator.py +13 -0
  328. esphome/cpp_helpers.py +2 -2
  329. esphome/dashboard/web_server.py +67 -10
  330. esphome/espota2.py +13 -6
  331. esphome/helpers.py +68 -83
  332. esphome/resolver.py +67 -0
  333. esphome/util.py +9 -6
  334. esphome/wizard.py +39 -26
  335. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/METADATA +9 -9
  336. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/RECORD +344 -313
  337. /esphome/components/ld2420/text_sensor/{text_sensor.h → ld2420_text_sensor.h} +0 -0
  338. /esphome/components/opentherm/number/{number.h → opentherm_number.h} +0 -0
  339. /esphome/components/opentherm/output/{output.h → opentherm_output.h} +0 -0
  340. /esphome/components/opentherm/switch/{switch.h → opentherm_switch.h} +0 -0
  341. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/WHEEL +0 -0
  342. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/entry_points.txt +0 -0
  343. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/licenses/LICENSE +0 -0
  344. {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/top_level.txt +0 -0
@@ -23,59 +23,59 @@ static const char *const TAG = "api.frame_helper";
23
23
  #define LOG_PACKET_SENDING(data, len) ((void) 0)
24
24
  #endif
25
25
 
26
- const char *api_error_to_str(APIError err) {
26
+ const LogString *api_error_to_logstr(APIError err) {
27
27
  // not using switch to ensure compiler doesn't try to build a big table out of it
28
28
  if (err == APIError::OK) {
29
- return "OK";
29
+ return LOG_STR("OK");
30
30
  } else if (err == APIError::WOULD_BLOCK) {
31
- return "WOULD_BLOCK";
31
+ return LOG_STR("WOULD_BLOCK");
32
32
  } else if (err == APIError::BAD_INDICATOR) {
33
- return "BAD_INDICATOR";
33
+ return LOG_STR("BAD_INDICATOR");
34
34
  } else if (err == APIError::BAD_DATA_PACKET) {
35
- return "BAD_DATA_PACKET";
35
+ return LOG_STR("BAD_DATA_PACKET");
36
36
  } else if (err == APIError::TCP_NODELAY_FAILED) {
37
- return "TCP_NODELAY_FAILED";
37
+ return LOG_STR("TCP_NODELAY_FAILED");
38
38
  } else if (err == APIError::TCP_NONBLOCKING_FAILED) {
39
- return "TCP_NONBLOCKING_FAILED";
39
+ return LOG_STR("TCP_NONBLOCKING_FAILED");
40
40
  } else if (err == APIError::CLOSE_FAILED) {
41
- return "CLOSE_FAILED";
41
+ return LOG_STR("CLOSE_FAILED");
42
42
  } else if (err == APIError::SHUTDOWN_FAILED) {
43
- return "SHUTDOWN_FAILED";
43
+ return LOG_STR("SHUTDOWN_FAILED");
44
44
  } else if (err == APIError::BAD_STATE) {
45
- return "BAD_STATE";
45
+ return LOG_STR("BAD_STATE");
46
46
  } else if (err == APIError::BAD_ARG) {
47
- return "BAD_ARG";
47
+ return LOG_STR("BAD_ARG");
48
48
  } else if (err == APIError::SOCKET_READ_FAILED) {
49
- return "SOCKET_READ_FAILED";
49
+ return LOG_STR("SOCKET_READ_FAILED");
50
50
  } else if (err == APIError::SOCKET_WRITE_FAILED) {
51
- return "SOCKET_WRITE_FAILED";
51
+ return LOG_STR("SOCKET_WRITE_FAILED");
52
52
  } else if (err == APIError::OUT_OF_MEMORY) {
53
- return "OUT_OF_MEMORY";
53
+ return LOG_STR("OUT_OF_MEMORY");
54
54
  } else if (err == APIError::CONNECTION_CLOSED) {
55
- return "CONNECTION_CLOSED";
55
+ return LOG_STR("CONNECTION_CLOSED");
56
56
  }
57
57
  #ifdef USE_API_NOISE
58
58
  else if (err == APIError::BAD_HANDSHAKE_PACKET_LEN) {
59
- return "BAD_HANDSHAKE_PACKET_LEN";
59
+ return LOG_STR("BAD_HANDSHAKE_PACKET_LEN");
60
60
  } else if (err == APIError::HANDSHAKESTATE_READ_FAILED) {
61
- return "HANDSHAKESTATE_READ_FAILED";
61
+ return LOG_STR("HANDSHAKESTATE_READ_FAILED");
62
62
  } else if (err == APIError::HANDSHAKESTATE_WRITE_FAILED) {
63
- return "HANDSHAKESTATE_WRITE_FAILED";
63
+ return LOG_STR("HANDSHAKESTATE_WRITE_FAILED");
64
64
  } else if (err == APIError::HANDSHAKESTATE_BAD_STATE) {
65
- return "HANDSHAKESTATE_BAD_STATE";
65
+ return LOG_STR("HANDSHAKESTATE_BAD_STATE");
66
66
  } else if (err == APIError::CIPHERSTATE_DECRYPT_FAILED) {
67
- return "CIPHERSTATE_DECRYPT_FAILED";
67
+ return LOG_STR("CIPHERSTATE_DECRYPT_FAILED");
68
68
  } else if (err == APIError::CIPHERSTATE_ENCRYPT_FAILED) {
69
- return "CIPHERSTATE_ENCRYPT_FAILED";
69
+ return LOG_STR("CIPHERSTATE_ENCRYPT_FAILED");
70
70
  } else if (err == APIError::HANDSHAKESTATE_SETUP_FAILED) {
71
- return "HANDSHAKESTATE_SETUP_FAILED";
71
+ return LOG_STR("HANDSHAKESTATE_SETUP_FAILED");
72
72
  } else if (err == APIError::HANDSHAKESTATE_SPLIT_FAILED) {
73
- return "HANDSHAKESTATE_SPLIT_FAILED";
73
+ return LOG_STR("HANDSHAKESTATE_SPLIT_FAILED");
74
74
  } else if (err == APIError::BAD_HANDSHAKE_ERROR_BYTE) {
75
- return "BAD_HANDSHAKE_ERROR_BYTE";
75
+ return LOG_STR("BAD_HANDSHAKE_ERROR_BYTE");
76
76
  }
77
77
  #endif
78
- return "UNKNOWN";
78
+ return LOG_STR("UNKNOWN");
79
79
  }
80
80
 
81
81
  // Default implementation for loop - handles sending buffered data
@@ -66,7 +66,7 @@ enum class APIError : uint16_t {
66
66
  #endif
67
67
  };
68
68
 
69
- const char *api_error_to_str(APIError err);
69
+ const LogString *api_error_to_logstr(APIError err);
70
70
 
71
71
  class APIFrameHelper {
72
72
  public:
@@ -104,9 +104,9 @@ class APIFrameHelper {
104
104
  // The buffer contains all messages with appropriate padding before each
105
105
  virtual APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span<const PacketInfo> packets) = 0;
106
106
  // Get the frame header padding required by this protocol
107
- virtual uint8_t frame_header_padding() = 0;
107
+ uint8_t frame_header_padding() const { return frame_header_padding_; }
108
108
  // Get the frame footer size required by this protocol
109
- virtual uint8_t frame_footer_size() = 0;
109
+ uint8_t frame_footer_size() const { return frame_footer_size_; }
110
110
  // Check if socket has data ready to read
111
111
  bool is_socket_ready() const { return socket_ != nullptr && socket_->ready(); }
112
112
 
@@ -10,10 +10,18 @@
10
10
  #include <cstring>
11
11
  #include <cinttypes>
12
12
 
13
+ #ifdef USE_ESP8266
14
+ #include <pgmspace.h>
15
+ #endif
16
+
13
17
  namespace esphome::api {
14
18
 
15
19
  static const char *const TAG = "api.noise";
20
+ #ifdef USE_ESP8266
21
+ static const char PROLOGUE_INIT[] PROGMEM = "NoiseAPIInit";
22
+ #else
16
23
  static const char *const PROLOGUE_INIT = "NoiseAPIInit";
24
+ #endif
17
25
  static constexpr size_t PROLOGUE_INIT_LEN = 12; // strlen("NoiseAPIInit")
18
26
 
19
27
  #define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
@@ -27,42 +35,42 @@ static constexpr size_t PROLOGUE_INIT_LEN = 12; // strlen("NoiseAPIInit")
27
35
  #endif
28
36
 
29
37
  /// Convert a noise error code to a readable error
30
- std::string noise_err_to_str(int err) {
38
+ const LogString *noise_err_to_logstr(int err) {
31
39
  if (err == NOISE_ERROR_NO_MEMORY)
32
- return "NO_MEMORY";
40
+ return LOG_STR("NO_MEMORY");
33
41
  if (err == NOISE_ERROR_UNKNOWN_ID)
34
- return "UNKNOWN_ID";
42
+ return LOG_STR("UNKNOWN_ID");
35
43
  if (err == NOISE_ERROR_UNKNOWN_NAME)
36
- return "UNKNOWN_NAME";
44
+ return LOG_STR("UNKNOWN_NAME");
37
45
  if (err == NOISE_ERROR_MAC_FAILURE)
38
- return "MAC_FAILURE";
46
+ return LOG_STR("MAC_FAILURE");
39
47
  if (err == NOISE_ERROR_NOT_APPLICABLE)
40
- return "NOT_APPLICABLE";
48
+ return LOG_STR("NOT_APPLICABLE");
41
49
  if (err == NOISE_ERROR_SYSTEM)
42
- return "SYSTEM";
50
+ return LOG_STR("SYSTEM");
43
51
  if (err == NOISE_ERROR_REMOTE_KEY_REQUIRED)
44
- return "REMOTE_KEY_REQUIRED";
52
+ return LOG_STR("REMOTE_KEY_REQUIRED");
45
53
  if (err == NOISE_ERROR_LOCAL_KEY_REQUIRED)
46
- return "LOCAL_KEY_REQUIRED";
54
+ return LOG_STR("LOCAL_KEY_REQUIRED");
47
55
  if (err == NOISE_ERROR_PSK_REQUIRED)
48
- return "PSK_REQUIRED";
56
+ return LOG_STR("PSK_REQUIRED");
49
57
  if (err == NOISE_ERROR_INVALID_LENGTH)
50
- return "INVALID_LENGTH";
58
+ return LOG_STR("INVALID_LENGTH");
51
59
  if (err == NOISE_ERROR_INVALID_PARAM)
52
- return "INVALID_PARAM";
60
+ return LOG_STR("INVALID_PARAM");
53
61
  if (err == NOISE_ERROR_INVALID_STATE)
54
- return "INVALID_STATE";
62
+ return LOG_STR("INVALID_STATE");
55
63
  if (err == NOISE_ERROR_INVALID_NONCE)
56
- return "INVALID_NONCE";
64
+ return LOG_STR("INVALID_NONCE");
57
65
  if (err == NOISE_ERROR_INVALID_PRIVATE_KEY)
58
- return "INVALID_PRIVATE_KEY";
66
+ return LOG_STR("INVALID_PRIVATE_KEY");
59
67
  if (err == NOISE_ERROR_INVALID_PUBLIC_KEY)
60
- return "INVALID_PUBLIC_KEY";
68
+ return LOG_STR("INVALID_PUBLIC_KEY");
61
69
  if (err == NOISE_ERROR_INVALID_FORMAT)
62
- return "INVALID_FORMAT";
70
+ return LOG_STR("INVALID_FORMAT");
63
71
  if (err == NOISE_ERROR_INVALID_SIGNATURE)
64
- return "INVALID_SIGNATURE";
65
- return to_string(err);
72
+ return LOG_STR("INVALID_SIGNATURE");
73
+ return LOG_STR("UNKNOWN");
66
74
  }
67
75
 
68
76
  /// Initialize the frame helper, returns OK if successful.
@@ -75,7 +83,11 @@ APIError APINoiseFrameHelper::init() {
75
83
  // init prologue
76
84
  size_t old_size = prologue_.size();
77
85
  prologue_.resize(old_size + PROLOGUE_INIT_LEN);
86
+ #ifdef USE_ESP8266
87
+ memcpy_P(prologue_.data() + old_size, PROLOGUE_INIT, PROLOGUE_INIT_LEN);
88
+ #else
78
89
  std::memcpy(prologue_.data() + old_size, PROLOGUE_INIT, PROLOGUE_INIT_LEN);
90
+ #endif
79
91
 
80
92
  state_ = State::CLIENT_HELLO;
81
93
  return APIError::OK;
@@ -83,18 +95,18 @@ APIError APINoiseFrameHelper::init() {
83
95
  // Helper for handling handshake frame errors
84
96
  APIError APINoiseFrameHelper::handle_handshake_frame_error_(APIError aerr) {
85
97
  if (aerr == APIError::BAD_INDICATOR) {
86
- send_explicit_handshake_reject_("Bad indicator byte");
98
+ send_explicit_handshake_reject_(LOG_STR("Bad indicator byte"));
87
99
  } else if (aerr == APIError::BAD_HANDSHAKE_PACKET_LEN) {
88
- send_explicit_handshake_reject_("Bad handshake packet len");
100
+ send_explicit_handshake_reject_(LOG_STR("Bad handshake packet len"));
89
101
  }
90
102
  return aerr;
91
103
  }
92
104
 
93
105
  // Helper for handling noise library errors
94
- APIError APINoiseFrameHelper::handle_noise_error_(int err, const char *func_name, APIError api_err) {
106
+ APIError APINoiseFrameHelper::handle_noise_error_(int err, const LogString *func_name, APIError api_err) {
95
107
  if (err != 0) {
96
108
  state_ = State::FAILED;
97
- HELPER_LOG("%s failed: %s", func_name, noise_err_to_str(err).c_str());
109
+ HELPER_LOG("%s failed: %s", LOG_STR_ARG(func_name), LOG_STR_ARG(noise_err_to_logstr(err)));
98
110
  return api_err;
99
111
  }
100
112
  return APIError::OK;
@@ -279,11 +291,11 @@ APIError APINoiseFrameHelper::state_action_() {
279
291
  }
280
292
 
281
293
  if (frame.empty()) {
282
- send_explicit_handshake_reject_("Empty handshake message");
294
+ send_explicit_handshake_reject_(LOG_STR("Empty handshake message"));
283
295
  return APIError::BAD_HANDSHAKE_ERROR_BYTE;
284
296
  } else if (frame[0] != 0x00) {
285
297
  HELPER_LOG("Bad handshake error byte: %u", frame[0]);
286
- send_explicit_handshake_reject_("Bad handshake error byte");
298
+ send_explicit_handshake_reject_(LOG_STR("Bad handshake error byte"));
287
299
  return APIError::BAD_HANDSHAKE_ERROR_BYTE;
288
300
  }
289
301
 
@@ -293,8 +305,10 @@ APIError APINoiseFrameHelper::state_action_() {
293
305
  err = noise_handshakestate_read_message(handshake_, &mbuf, nullptr);
294
306
  if (err != 0) {
295
307
  // Special handling for MAC failure
296
- send_explicit_handshake_reject_(err == NOISE_ERROR_MAC_FAILURE ? "Handshake MAC failure" : "Handshake error");
297
- return handle_noise_error_(err, "noise_handshakestate_read_message", APIError::HANDSHAKESTATE_READ_FAILED);
308
+ send_explicit_handshake_reject_(err == NOISE_ERROR_MAC_FAILURE ? LOG_STR("Handshake MAC failure")
309
+ : LOG_STR("Handshake error"));
310
+ return handle_noise_error_(err, LOG_STR("noise_handshakestate_read_message"),
311
+ APIError::HANDSHAKESTATE_READ_FAILED);
298
312
  }
299
313
 
300
314
  aerr = check_handshake_finished_();
@@ -307,8 +321,8 @@ APIError APINoiseFrameHelper::state_action_() {
307
321
  noise_buffer_set_output(mbuf, buffer + 1, sizeof(buffer) - 1);
308
322
 
309
323
  err = noise_handshakestate_write_message(handshake_, &mbuf, nullptr);
310
- APIError aerr_write =
311
- handle_noise_error_(err, "noise_handshakestate_write_message", APIError::HANDSHAKESTATE_WRITE_FAILED);
324
+ APIError aerr_write = handle_noise_error_(err, LOG_STR("noise_handshakestate_write_message"),
325
+ APIError::HANDSHAKESTATE_WRITE_FAILED);
312
326
  if (aerr_write != APIError::OK)
313
327
  return aerr_write;
314
328
  buffer[0] = 0x00; // success
@@ -331,15 +345,31 @@ APIError APINoiseFrameHelper::state_action_() {
331
345
  }
332
346
  return APIError::OK;
333
347
  }
334
- void APINoiseFrameHelper::send_explicit_handshake_reject_(const std::string &reason) {
348
+ void APINoiseFrameHelper::send_explicit_handshake_reject_(const LogString *reason) {
349
+ #ifdef USE_STORE_LOG_STR_IN_FLASH
350
+ // On ESP8266 with flash strings, we need to use PROGMEM-aware functions
351
+ size_t reason_len = strlen_P(reinterpret_cast<PGM_P>(reason));
335
352
  std::vector<uint8_t> data;
336
- data.resize(reason.length() + 1);
353
+ data.resize(reason_len + 1);
354
+ data[0] = 0x01; // failure
355
+
356
+ // Copy error message from PROGMEM
357
+ if (reason_len > 0) {
358
+ memcpy_P(data.data() + 1, reinterpret_cast<PGM_P>(reason), reason_len);
359
+ }
360
+ #else
361
+ // Normal memory access
362
+ const char *reason_str = LOG_STR_ARG(reason);
363
+ size_t reason_len = strlen(reason_str);
364
+ std::vector<uint8_t> data;
365
+ data.resize(reason_len + 1);
337
366
  data[0] = 0x01; // failure
338
367
 
339
368
  // Copy error message in bulk
340
- if (!reason.empty()) {
341
- std::memcpy(data.data() + 1, reason.c_str(), reason.length());
369
+ if (reason_len > 0) {
370
+ std::memcpy(data.data() + 1, reason_str, reason_len);
342
371
  }
372
+ #endif
343
373
 
344
374
  // temporarily remove failed state
345
375
  auto orig_state = state_;
@@ -368,7 +398,8 @@ APIError APINoiseFrameHelper::read_packet(ReadPacketBuffer *buffer) {
368
398
  noise_buffer_init(mbuf);
369
399
  noise_buffer_set_inout(mbuf, frame.data(), frame.size(), frame.size());
370
400
  err = noise_cipherstate_decrypt(recv_cipher_, &mbuf);
371
- APIError decrypt_err = handle_noise_error_(err, "noise_cipherstate_decrypt", APIError::CIPHERSTATE_DECRYPT_FAILED);
401
+ APIError decrypt_err =
402
+ handle_noise_error_(err, LOG_STR("noise_cipherstate_decrypt"), APIError::CIPHERSTATE_DECRYPT_FAILED);
372
403
  if (decrypt_err != APIError::OK)
373
404
  return decrypt_err;
374
405
 
@@ -450,7 +481,8 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, st
450
481
  4 + packet.payload_size + frame_footer_size_);
451
482
 
452
483
  int err = noise_cipherstate_encrypt(send_cipher_, &mbuf);
453
- APIError aerr = handle_noise_error_(err, "noise_cipherstate_encrypt", APIError::CIPHERSTATE_ENCRYPT_FAILED);
484
+ APIError aerr =
485
+ handle_noise_error_(err, LOG_STR("noise_cipherstate_encrypt"), APIError::CIPHERSTATE_ENCRYPT_FAILED);
454
486
  if (aerr != APIError::OK)
455
487
  return aerr;
456
488
 
@@ -504,25 +536,27 @@ APIError APINoiseFrameHelper::init_handshake_() {
504
536
  nid_.modifier_ids[0] = NOISE_MODIFIER_PSK0;
505
537
 
506
538
  err = noise_handshakestate_new_by_id(&handshake_, &nid_, NOISE_ROLE_RESPONDER);
507
- APIError aerr = handle_noise_error_(err, "noise_handshakestate_new_by_id", APIError::HANDSHAKESTATE_SETUP_FAILED);
539
+ APIError aerr =
540
+ handle_noise_error_(err, LOG_STR("noise_handshakestate_new_by_id"), APIError::HANDSHAKESTATE_SETUP_FAILED);
508
541
  if (aerr != APIError::OK)
509
542
  return aerr;
510
543
 
511
544
  const auto &psk = ctx_->get_psk();
512
545
  err = noise_handshakestate_set_pre_shared_key(handshake_, psk.data(), psk.size());
513
- aerr = handle_noise_error_(err, "noise_handshakestate_set_pre_shared_key", APIError::HANDSHAKESTATE_SETUP_FAILED);
546
+ aerr = handle_noise_error_(err, LOG_STR("noise_handshakestate_set_pre_shared_key"),
547
+ APIError::HANDSHAKESTATE_SETUP_FAILED);
514
548
  if (aerr != APIError::OK)
515
549
  return aerr;
516
550
 
517
551
  err = noise_handshakestate_set_prologue(handshake_, prologue_.data(), prologue_.size());
518
- aerr = handle_noise_error_(err, "noise_handshakestate_set_prologue", APIError::HANDSHAKESTATE_SETUP_FAILED);
552
+ aerr = handle_noise_error_(err, LOG_STR("noise_handshakestate_set_prologue"), APIError::HANDSHAKESTATE_SETUP_FAILED);
519
553
  if (aerr != APIError::OK)
520
554
  return aerr;
521
555
  // set_prologue copies it into handshakestate, so we can get rid of it now
522
556
  prologue_ = {};
523
557
 
524
558
  err = noise_handshakestate_start(handshake_);
525
- aerr = handle_noise_error_(err, "noise_handshakestate_start", APIError::HANDSHAKESTATE_SETUP_FAILED);
559
+ aerr = handle_noise_error_(err, LOG_STR("noise_handshakestate_start"), APIError::HANDSHAKESTATE_SETUP_FAILED);
526
560
  if (aerr != APIError::OK)
527
561
  return aerr;
528
562
  return APIError::OK;
@@ -540,7 +574,8 @@ APIError APINoiseFrameHelper::check_handshake_finished_() {
540
574
  return APIError::HANDSHAKESTATE_BAD_STATE;
541
575
  }
542
576
  int err = noise_handshakestate_split(handshake_, &send_cipher_, &recv_cipher_);
543
- APIError aerr = handle_noise_error_(err, "noise_handshakestate_split", APIError::HANDSHAKESTATE_SPLIT_FAILED);
577
+ APIError aerr =
578
+ handle_noise_error_(err, LOG_STR("noise_handshakestate_split"), APIError::HANDSHAKESTATE_SPLIT_FAILED);
544
579
  if (aerr != APIError::OK)
545
580
  return aerr;
546
581
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  namespace esphome::api {
9
9
 
10
- class APINoiseFrameHelper : public APIFrameHelper {
10
+ class APINoiseFrameHelper final : public APIFrameHelper {
11
11
  public:
12
12
  APINoiseFrameHelper(std::unique_ptr<socket::Socket> socket, std::shared_ptr<APINoiseContext> ctx,
13
13
  const ClientInfo *client_info)
@@ -25,10 +25,6 @@ class APINoiseFrameHelper : public APIFrameHelper {
25
25
  APIError read_packet(ReadPacketBuffer *buffer) override;
26
26
  APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) override;
27
27
  APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span<const PacketInfo> packets) override;
28
- // Get the frame header padding required by this protocol
29
- uint8_t frame_header_padding() override { return frame_header_padding_; }
30
- // Get the frame footer size required by this protocol
31
- uint8_t frame_footer_size() override { return frame_footer_size_; }
32
28
 
33
29
  protected:
34
30
  APIError state_action_();
@@ -36,9 +32,9 @@ class APINoiseFrameHelper : public APIFrameHelper {
36
32
  APIError write_frame_(const uint8_t *data, uint16_t len);
37
33
  APIError init_handshake_();
38
34
  APIError check_handshake_finished_();
39
- void send_explicit_handshake_reject_(const std::string &reason);
35
+ void send_explicit_handshake_reject_(const LogString *reason);
40
36
  APIError handle_handshake_frame_error_(APIError aerr);
41
- APIError handle_noise_error_(int err, const char *func_name, APIError api_err);
37
+ APIError handle_noise_error_(int err, const LogString *func_name, APIError api_err);
42
38
 
43
39
  // Pointers first (4 bytes each)
44
40
  NoiseHandshakeState *handshake_{nullptr};
@@ -10,6 +10,10 @@
10
10
  #include <cstring>
11
11
  #include <cinttypes>
12
12
 
13
+ #ifdef USE_ESP8266
14
+ #include <pgmspace.h>
15
+ #endif
16
+
13
17
  namespace esphome::api {
14
18
 
15
19
  static const char *const TAG = "api.plaintext";
@@ -197,11 +201,20 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
197
201
  // We must send at least 3 bytes to be read, so we add
198
202
  // a message after the indicator byte to ensures its long
199
203
  // enough and can aid in debugging.
200
- const char msg[] = "\x00"
201
- "Bad indicator byte";
204
+ static constexpr uint8_t INDICATOR_MSG_SIZE = 19;
205
+ #ifdef USE_ESP8266
206
+ static const char MSG_PROGMEM[] PROGMEM = "\x00"
207
+ "Bad indicator byte";
208
+ char msg[INDICATOR_MSG_SIZE];
209
+ memcpy_P(msg, MSG_PROGMEM, INDICATOR_MSG_SIZE);
202
210
  iov[0].iov_base = (void *) msg;
203
- iov[0].iov_len = 19;
204
- this->write_raw_(iov, 1, 19);
211
+ #else
212
+ static const char MSG[] = "\x00"
213
+ "Bad indicator byte";
214
+ iov[0].iov_base = (void *) MSG;
215
+ #endif
216
+ iov[0].iov_len = INDICATOR_MSG_SIZE;
217
+ this->write_raw_(iov, 1, INDICATOR_MSG_SIZE);
205
218
  }
206
219
  return aerr;
207
220
  }
@@ -5,7 +5,7 @@
5
5
 
6
6
  namespace esphome::api {
7
7
 
8
- class APIPlaintextFrameHelper : public APIFrameHelper {
8
+ class APIPlaintextFrameHelper final : public APIFrameHelper {
9
9
  public:
10
10
  APIPlaintextFrameHelper(std::unique_ptr<socket::Socket> socket, const ClientInfo *client_info)
11
11
  : APIFrameHelper(std::move(socket), client_info) {
@@ -22,9 +22,6 @@ class APIPlaintextFrameHelper : public APIFrameHelper {
22
22
  APIError read_packet(ReadPacketBuffer *buffer) override;
23
23
  APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) override;
24
24
  APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span<const PacketInfo> packets) override;
25
- uint8_t frame_header_padding() override { return frame_header_padding_; }
26
- // Get the frame footer size required by this protocol
27
- uint8_t frame_footer_size() override { return frame_footer_size_; }
28
25
 
29
26
  protected:
30
27
  APIError try_read_frame_(std::vector<uint8_t> *frame);
@@ -901,6 +901,16 @@ bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDel
901
901
  return true;
902
902
  }
903
903
  #endif
904
+ bool GetTimeResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
905
+ switch (field_id) {
906
+ case 2:
907
+ this->timezone = value.as_string();
908
+ break;
909
+ default:
910
+ return false;
911
+ }
912
+ return true;
913
+ }
904
914
  bool GetTimeResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
905
915
  switch (field_id) {
906
916
  case 1:
@@ -911,8 +921,14 @@ bool GetTimeResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
911
921
  }
912
922
  return true;
913
923
  }
914
- void GetTimeResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_fixed32(1, this->epoch_seconds); }
915
- void GetTimeResponse::calculate_size(ProtoSize &size) const { size.add_fixed32(1, this->epoch_seconds); }
924
+ void GetTimeResponse::encode(ProtoWriteBuffer buffer) const {
925
+ buffer.encode_fixed32(1, this->epoch_seconds);
926
+ buffer.encode_string(2, this->timezone_ref_);
927
+ }
928
+ void GetTimeResponse::calculate_size(ProtoSize &size) const {
929
+ size.add_fixed32(1, this->epoch_seconds);
930
+ size.add_length(1, this->timezone_ref_.size());
931
+ }
916
932
  #ifdef USE_API_SERVICES
917
933
  void ListEntitiesServicesArgument::encode(ProtoWriteBuffer buffer) const {
918
934
  buffer.encode_string(1, this->name_ref_);
@@ -2153,10 +2169,12 @@ void BluetoothDeviceClearCacheResponse::calculate_size(ProtoSize &size) const {
2153
2169
  void BluetoothScannerStateResponse::encode(ProtoWriteBuffer buffer) const {
2154
2170
  buffer.encode_uint32(1, static_cast<uint32_t>(this->state));
2155
2171
  buffer.encode_uint32(2, static_cast<uint32_t>(this->mode));
2172
+ buffer.encode_uint32(3, static_cast<uint32_t>(this->configured_mode));
2156
2173
  }
2157
2174
  void BluetoothScannerStateResponse::calculate_size(ProtoSize &size) const {
2158
2175
  size.add_uint32(1, static_cast<uint32_t>(this->state));
2159
2176
  size.add_uint32(1, static_cast<uint32_t>(this->mode));
2177
+ size.add_uint32(1, static_cast<uint32_t>(this->configured_mode));
2160
2178
  }
2161
2179
  bool BluetoothScannerSetModeRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
2162
2180
  switch (field_id) {