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
@@ -6,9 +6,14 @@
6
6
 
7
7
  #include <string>
8
8
  #include <queue>
9
+ #include <cstring>
9
10
  #include <mqtt_client.h>
11
+ #include <freertos/FreeRTOS.h>
12
+ #include <freertos/task.h>
10
13
  #include "esphome/components/network/ip_address.h"
11
14
  #include "esphome/core/helpers.h"
15
+ #include "esphome/core/lock_free_queue.h"
16
+ #include "esphome/core/event_pool.h"
12
17
 
13
18
  namespace esphome {
14
19
  namespace mqtt {
@@ -42,9 +47,79 @@ struct Event {
42
47
  error_handle(*event.error_handle) {}
43
48
  };
44
49
 
50
+ enum MqttQueueTypeT : uint8_t {
51
+ MQTT_QUEUE_TYPE_NONE = 0,
52
+ MQTT_QUEUE_TYPE_SUBSCRIBE,
53
+ MQTT_QUEUE_TYPE_UNSUBSCRIBE,
54
+ MQTT_QUEUE_TYPE_PUBLISH,
55
+ };
56
+
57
+ struct QueueElement {
58
+ char *topic;
59
+ char *payload;
60
+ uint16_t payload_len; // MQTT max payload is 64KiB
61
+ uint8_t type : 2;
62
+ uint8_t qos : 2; // QoS only needs values 0-2
63
+ uint8_t retain : 1;
64
+ uint8_t reserved : 3; // Reserved for future use
65
+
66
+ QueueElement() : topic(nullptr), payload(nullptr), payload_len(0), qos(0), retain(0), reserved(0) {}
67
+
68
+ // Helper to set topic/payload (uses RAMAllocator)
69
+ bool set_data(const char *topic_str, const char *payload_data, size_t len) {
70
+ // Check payload size limit (MQTT max is 64KiB)
71
+ if (len > std::numeric_limits<uint16_t>::max()) {
72
+ return false;
73
+ }
74
+
75
+ // Use RAMAllocator with default flags (tries external RAM first, falls back to internal)
76
+ RAMAllocator<char> allocator;
77
+
78
+ // Allocate and copy topic
79
+ size_t topic_len = strlen(topic_str) + 1;
80
+ topic = allocator.allocate(topic_len);
81
+ if (!topic)
82
+ return false;
83
+ memcpy(topic, topic_str, topic_len);
84
+
85
+ if (payload_data && len) {
86
+ payload = allocator.allocate(len);
87
+ if (!payload) {
88
+ allocator.deallocate(topic, topic_len);
89
+ topic = nullptr;
90
+ return false;
91
+ }
92
+ memcpy(payload, payload_data, len);
93
+ payload_len = static_cast<uint16_t>(len);
94
+ } else {
95
+ payload = nullptr;
96
+ payload_len = 0;
97
+ }
98
+ return true;
99
+ }
100
+
101
+ // Helper to release (uses RAMAllocator)
102
+ void release() {
103
+ RAMAllocator<char> allocator;
104
+ if (topic) {
105
+ allocator.deallocate(topic, strlen(topic) + 1);
106
+ topic = nullptr;
107
+ }
108
+ if (payload) {
109
+ allocator.deallocate(payload, payload_len);
110
+ payload = nullptr;
111
+ }
112
+ payload_len = 0;
113
+ }
114
+ };
115
+
45
116
  class MQTTBackendESP32 final : public MQTTBackend {
46
117
  public:
47
118
  static const size_t MQTT_BUFFER_SIZE = 4096;
119
+ static const size_t TASK_STACK_SIZE = 3072;
120
+ static const size_t TASK_STACK_SIZE_TLS = 4096; // Larger stack for TLS operations
121
+ static const ssize_t TASK_PRIORITY = 5;
122
+ static const uint8_t MQTT_QUEUE_LENGTH = 30; // 30*12 bytes = 360
48
123
 
49
124
  void set_keep_alive(uint16_t keep_alive) final { this->keep_alive_ = keep_alive; }
50
125
  void set_client_id(const char *client_id) final { this->client_id_ = client_id; }
@@ -105,15 +180,23 @@ class MQTTBackendESP32 final : public MQTTBackend {
105
180
  }
106
181
 
107
182
  bool subscribe(const char *topic, uint8_t qos) final {
183
+ #if defined(USE_MQTT_IDF_ENQUEUE)
184
+ return enqueue_(MQTT_QUEUE_TYPE_SUBSCRIBE, topic, qos);
185
+ #else
108
186
  return esp_mqtt_client_subscribe(handler_.get(), topic, qos) != -1;
187
+ #endif
188
+ }
189
+ bool unsubscribe(const char *topic) final {
190
+ #if defined(USE_MQTT_IDF_ENQUEUE)
191
+ return enqueue_(MQTT_QUEUE_TYPE_UNSUBSCRIBE, topic);
192
+ #else
193
+ return esp_mqtt_client_unsubscribe(handler_.get(), topic) != -1;
194
+ #endif
109
195
  }
110
- bool unsubscribe(const char *topic) final { return esp_mqtt_client_unsubscribe(handler_.get(), topic) != -1; }
111
196
 
112
197
  bool publish(const char *topic, const char *payload, size_t length, uint8_t qos, bool retain) final {
113
198
  #if defined(USE_MQTT_IDF_ENQUEUE)
114
- // use the non-blocking version
115
- // it can delay sending a couple of seconds but won't block
116
- return esp_mqtt_client_enqueue(handler_.get(), topic, payload, length, qos, retain, true) != -1;
199
+ return enqueue_(MQTT_QUEUE_TYPE_PUBLISH, topic, qos, retain, payload, length);
117
200
  #else
118
201
  // might block for several seconds, either due to network timeout (10s)
119
202
  // or if publishing payloads longer than internal buffer (due to message fragmentation)
@@ -129,6 +212,12 @@ class MQTTBackendESP32 final : public MQTTBackend {
129
212
  void set_cl_key(const std::string &key) { cl_key_ = key; }
130
213
  void set_skip_cert_cn_check(bool skip_check) { skip_cert_cn_check_ = skip_check; }
131
214
 
215
+ // No destructor needed: ESPHome components live for the entire device runtime.
216
+ // The MQTT task and queue will run until the device reboots or loses power,
217
+ // at which point the entire process terminates and FreeRTOS cleans up all tasks.
218
+ // Implementing a destructor would add complexity and potential race conditions
219
+ // for a scenario that never occurs in practice.
220
+
132
221
  protected:
133
222
  bool initialize_();
134
223
  void mqtt_event_handler_(const Event &event);
@@ -160,6 +249,14 @@ class MQTTBackendESP32 final : public MQTTBackend {
160
249
  optional<std::string> cl_certificate_;
161
250
  optional<std::string> cl_key_;
162
251
  bool skip_cert_cn_check_{false};
252
+ #if defined(USE_MQTT_IDF_ENQUEUE)
253
+ static void esphome_mqtt_task(void *params);
254
+ EventPool<struct QueueElement, MQTT_QUEUE_LENGTH> mqtt_event_pool_;
255
+ NotifyingLockFreeQueue<struct QueueElement, MQTT_QUEUE_LENGTH> mqtt_queue_;
256
+ TaskHandle_t task_handle_{nullptr};
257
+ bool enqueue_(MqttQueueTypeT type, const char *topic, int qos = 0, bool retain = false, const char *payload = NULL,
258
+ size_t len = 0);
259
+ #endif
163
260
 
164
261
  // callbacks
165
262
  CallbackManager<on_connect_callback_t> on_connect_;
@@ -169,6 +266,11 @@ class MQTTBackendESP32 final : public MQTTBackend {
169
266
  CallbackManager<on_message_callback_t> on_message_;
170
267
  CallbackManager<on_publish_user_callback_t> on_publish_;
171
268
  std::queue<Event> mqtt_events_;
269
+
270
+ #if defined(USE_MQTT_IDF_ENQUEUE)
271
+ uint32_t last_dropped_log_time_{0};
272
+ static constexpr uint32_t DROP_LOG_INTERVAL_MS = 10000; // Log every 10 seconds
273
+ #endif
172
274
  };
173
275
 
174
276
  } // namespace mqtt
@@ -30,6 +30,7 @@ MQTTBinarySensorComponent::MQTTBinarySensorComponent(binary_sensor::BinarySensor
30
30
  }
31
31
 
32
32
  void MQTTBinarySensorComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
33
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
33
34
  if (!this->binary_sensor_->get_device_class().empty())
34
35
  root[MQTT_DEVICE_CLASS] = this->binary_sensor_->get_device_class();
35
36
  if (this->binary_sensor_->is_status_binary_sensor())
@@ -31,9 +31,12 @@ void MQTTButtonComponent::dump_config() {
31
31
  }
32
32
 
33
33
  void MQTTButtonComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
34
+ // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
34
35
  config.state_topic = false;
35
- if (!this->button_->get_device_class().empty())
36
+ if (!this->button_->get_device_class().empty()) {
36
37
  root[MQTT_DEVICE_CLASS] = this->button_->get_device_class();
38
+ }
39
+ // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
37
40
  }
38
41
 
39
42
  std::string MQTTButtonComponent::component_type() const { return "button"; }
@@ -57,14 +57,15 @@ void MQTTClientComponent::setup() {
57
57
  });
58
58
  #ifdef USE_LOGGER
59
59
  if (this->is_log_message_enabled() && logger::global_logger != nullptr) {
60
- logger::global_logger->add_on_log_callback([this](int level, const char *tag, const char *message) {
61
- if (level <= this->log_level_ && this->is_connected()) {
62
- this->publish({.topic = this->log_message_.topic,
63
- .payload = message,
64
- .qos = this->log_message_.qos,
65
- .retain = this->log_message_.retain});
66
- }
67
- });
60
+ logger::global_logger->add_on_log_callback(
61
+ [this](int level, const char *tag, const char *message, size_t message_len) {
62
+ if (level <= this->log_level_ && this->is_connected()) {
63
+ this->publish({.topic = this->log_message_.topic,
64
+ .payload = std::string(message, message_len),
65
+ .qos = this->log_message_.qos,
66
+ .retain = this->log_message_.retain});
67
+ }
68
+ });
68
69
  }
69
70
  #endif
70
71
 
@@ -91,6 +92,7 @@ void MQTTClientComponent::send_device_info_() {
91
92
  std::string topic = "esphome/discover/";
92
93
  topic.append(App.get_name());
93
94
 
95
+ // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
94
96
  this->publish_json(
95
97
  topic,
96
98
  [](JsonObject root) {
@@ -146,6 +148,7 @@ void MQTTClientComponent::send_device_info_() {
146
148
  #endif
147
149
  },
148
150
  2, this->discovery_info_.retain);
151
+ // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
149
152
  }
150
153
 
151
154
  void MQTTClientComponent::dump_config() {
@@ -176,7 +179,8 @@ void MQTTClientComponent::dump_config() {
176
179
  }
177
180
  }
178
181
  bool MQTTClientComponent::can_proceed() {
179
- return network::is_disabled() || this->state_ == MQTT_CLIENT_DISABLED || this->is_connected();
182
+ return network::is_disabled() || this->state_ == MQTT_CLIENT_DISABLED || this->is_connected() ||
183
+ !this->wait_for_connection_;
180
184
  }
181
185
 
182
186
  void MQTTClientComponent::start_dnslookup_() {
@@ -228,6 +232,8 @@ void MQTTClientComponent::check_dnslookup_() {
228
232
  if (this->dns_resolve_error_) {
229
233
  ESP_LOGW(TAG, "Couldn't resolve IP address for '%s'", this->credentials_.address.c_str());
230
234
  this->state_ = MQTT_CLIENT_DISCONNECTED;
235
+ this->disconnect_reason_ = MQTTClientDisconnectReason::DNS_RESOLVE_ERROR;
236
+ this->on_disconnect_.call(MQTTClientDisconnectReason::DNS_RESOLVE_ERROR);
231
237
  return;
232
238
  }
233
239
 
@@ -697,7 +703,9 @@ void MQTTClientComponent::set_on_connect(mqtt_on_connect_callback_t &&callback)
697
703
  }
698
704
 
699
705
  void MQTTClientComponent::set_on_disconnect(mqtt_on_disconnect_callback_t &&callback) {
706
+ auto callback_copy = callback;
700
707
  this->mqtt_backend_.set_on_disconnect(std::forward<mqtt_on_disconnect_callback_t>(callback));
708
+ this->on_disconnect_.add(std::move(callback_copy));
701
709
  }
702
710
 
703
711
  #if ASYNC_TCP_SSL_ENABLED
@@ -4,11 +4,12 @@
4
4
 
5
5
  #ifdef USE_MQTT
6
6
 
7
- #include "esphome/core/component.h"
8
- #include "esphome/core/automation.h"
9
- #include "esphome/core/log.h"
10
7
  #include "esphome/components/json/json_util.h"
11
8
  #include "esphome/components/network/ip_address.h"
9
+ #include "esphome/core/automation.h"
10
+ #include "esphome/core/component.h"
11
+ #include "esphome/core/helpers.h"
12
+ #include "esphome/core/log.h"
12
13
  #if defined(USE_ESP32)
13
14
  #include "mqtt_backend_esp32.h"
14
15
  #elif defined(USE_ESP8266)
@@ -267,6 +268,8 @@ class MQTTClientComponent : public Component {
267
268
  void set_publish_nan_as_none(bool publish_nan_as_none);
268
269
  bool is_publish_nan_as_none() const;
269
270
 
271
+ void set_wait_for_connection(bool wait_for_connection) { this->wait_for_connection_ = wait_for_connection; }
272
+
270
273
  protected:
271
274
  void send_device_info_();
272
275
 
@@ -332,8 +335,10 @@ class MQTTClientComponent : public Component {
332
335
  uint32_t connect_begin_;
333
336
  uint32_t last_connected_{0};
334
337
  optional<MQTTClientDisconnectReason> disconnect_reason_{};
338
+ CallbackManager<MQTTBackend::on_disconnect_callback_t> on_disconnect_;
335
339
 
336
340
  bool publish_nan_as_none_{false};
341
+ bool wait_for_connection_{false};
337
342
  };
338
343
 
339
344
  extern MQTTClientComponent *global_mqtt_client; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
@@ -14,6 +14,7 @@ static const char *const TAG = "mqtt.climate";
14
14
  using namespace esphome::climate;
15
15
 
16
16
  void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
17
+ // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
17
18
  auto traits = this->device_->get_traits();
18
19
  // current_temperature_topic
19
20
  if (traits.get_supports_current_temperature()) {
@@ -28,7 +29,7 @@ void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCo
28
29
  // mode_state_topic
29
30
  root[MQTT_MODE_STATE_TOPIC] = this->get_mode_state_topic();
30
31
  // modes
31
- JsonArray modes = root.createNestedArray(MQTT_MODES);
32
+ JsonArray modes = root[MQTT_MODES].to<JsonArray>();
32
33
  // sort array for nice UI in HA
33
34
  if (traits.supports_mode(CLIMATE_MODE_AUTO))
34
35
  modes.add("auto");
@@ -89,7 +90,7 @@ void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCo
89
90
  // preset_mode_state_topic
90
91
  root[MQTT_PRESET_MODE_STATE_TOPIC] = this->get_preset_state_topic();
91
92
  // presets
92
- JsonArray presets = root.createNestedArray("preset_modes");
93
+ JsonArray presets = root["preset_modes"].to<JsonArray>();
93
94
  if (traits.supports_preset(CLIMATE_PRESET_HOME))
94
95
  presets.add("home");
95
96
  if (traits.supports_preset(CLIMATE_PRESET_AWAY))
@@ -119,7 +120,7 @@ void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCo
119
120
  // fan_mode_state_topic
120
121
  root[MQTT_FAN_MODE_STATE_TOPIC] = this->get_fan_mode_state_topic();
121
122
  // fan_modes
122
- JsonArray fan_modes = root.createNestedArray("fan_modes");
123
+ JsonArray fan_modes = root["fan_modes"].to<JsonArray>();
123
124
  if (traits.supports_fan_mode(CLIMATE_FAN_ON))
124
125
  fan_modes.add("on");
125
126
  if (traits.supports_fan_mode(CLIMATE_FAN_OFF))
@@ -150,7 +151,7 @@ void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCo
150
151
  // swing_mode_state_topic
151
152
  root[MQTT_SWING_MODE_STATE_TOPIC] = this->get_swing_mode_state_topic();
152
153
  // swing_modes
153
- JsonArray swing_modes = root.createNestedArray("swing_modes");
154
+ JsonArray swing_modes = root["swing_modes"].to<JsonArray>();
154
155
  if (traits.supports_swing_mode(CLIMATE_SWING_OFF))
155
156
  swing_modes.add("off");
156
157
  if (traits.supports_swing_mode(CLIMATE_SWING_BOTH))
@@ -163,6 +164,7 @@ void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCo
163
164
 
164
165
  config.state_topic = false;
165
166
  config.command_topic = false;
167
+ // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
166
168
  }
167
169
  void MQTTClimateComponent::setup() {
168
170
  auto traits = this->device_->get_traits();
@@ -70,6 +70,7 @@ bool MQTTComponent::send_discovery_() {
70
70
 
71
71
  ESP_LOGV(TAG, "'%s': Sending discovery", this->friendly_name().c_str());
72
72
 
73
+ // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
73
74
  return global_mqtt_client->publish_json(
74
75
  this->get_discovery_topic_(discovery_info),
75
76
  [this](JsonObject root) {
@@ -155,7 +156,7 @@ bool MQTTComponent::send_discovery_() {
155
156
  }
156
157
  std::string node_area = App.get_area();
157
158
 
158
- JsonObject device_info = root.createNestedObject(MQTT_DEVICE);
159
+ JsonObject device_info = root[MQTT_DEVICE].to<JsonObject>();
159
160
  const auto mac = get_mac_address();
160
161
  device_info[MQTT_DEVICE_IDENTIFIERS] = mac;
161
162
  device_info[MQTT_DEVICE_NAME] = node_friendly_name;
@@ -192,6 +193,7 @@ bool MQTTComponent::send_discovery_() {
192
193
  device_info[MQTT_DEVICE_CONNECTIONS][0][1] = mac;
193
194
  },
194
195
  this->qos_, discovery_info.retain);
196
+ // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
195
197
  }
196
198
 
197
199
  uint8_t MQTTComponent::get_qos() const { return this->qos_; }
@@ -67,6 +67,7 @@ void MQTTCoverComponent::dump_config() {
67
67
  }
68
68
  }
69
69
  void MQTTCoverComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
70
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
70
71
  if (!this->cover_->get_device_class().empty())
71
72
  root[MQTT_DEVICE_CLASS] = this->cover_->get_device_class();
72
73
 
@@ -20,13 +20,13 @@ MQTTDateComponent::MQTTDateComponent(DateEntity *date) : date_(date) {}
20
20
  void MQTTDateComponent::setup() {
21
21
  this->subscribe_json(this->get_command_topic_(), [this](const std::string &topic, JsonObject root) {
22
22
  auto call = this->date_->make_call();
23
- if (root.containsKey("year")) {
23
+ if (root["year"].is<uint16_t>()) {
24
24
  call.set_year(root["year"]);
25
25
  }
26
- if (root.containsKey("month")) {
26
+ if (root["month"].is<uint8_t>()) {
27
27
  call.set_month(root["month"]);
28
28
  }
29
- if (root.containsKey("day")) {
29
+ if (root["day"].is<uint8_t>()) {
30
30
  call.set_day(root["day"]);
31
31
  }
32
32
  call.perform();
@@ -55,6 +55,7 @@ bool MQTTDateComponent::send_initial_state() {
55
55
  }
56
56
  bool MQTTDateComponent::publish_state(uint16_t year, uint8_t month, uint8_t day) {
57
57
  return this->publish_json(this->get_state_topic_(), [year, month, day](JsonObject root) {
58
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
58
59
  root["year"] = year;
59
60
  root["month"] = month;
60
61
  root["day"] = day;
@@ -20,22 +20,22 @@ MQTTDateTimeComponent::MQTTDateTimeComponent(DateTimeEntity *datetime) : datetim
20
20
  void MQTTDateTimeComponent::setup() {
21
21
  this->subscribe_json(this->get_command_topic_(), [this](const std::string &topic, JsonObject root) {
22
22
  auto call = this->datetime_->make_call();
23
- if (root.containsKey("year")) {
23
+ if (root["year"].is<uint16_t>()) {
24
24
  call.set_year(root["year"]);
25
25
  }
26
- if (root.containsKey("month")) {
26
+ if (root["month"].is<uint8_t>()) {
27
27
  call.set_month(root["month"]);
28
28
  }
29
- if (root.containsKey("day")) {
29
+ if (root["day"].is<uint8_t>()) {
30
30
  call.set_day(root["day"]);
31
31
  }
32
- if (root.containsKey("hour")) {
32
+ if (root["hour"].is<uint8_t>()) {
33
33
  call.set_hour(root["hour"]);
34
34
  }
35
- if (root.containsKey("minute")) {
35
+ if (root["minute"].is<uint8_t>()) {
36
36
  call.set_minute(root["minute"]);
37
37
  }
38
- if (root.containsKey("second")) {
38
+ if (root["second"].is<uint8_t>()) {
39
39
  call.set_second(root["second"]);
40
40
  }
41
41
  call.perform();
@@ -68,6 +68,7 @@ bool MQTTDateTimeComponent::send_initial_state() {
68
68
  bool MQTTDateTimeComponent::publish_state(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute,
69
69
  uint8_t second) {
70
70
  return this->publish_json(this->get_state_topic_(), [year, month, day, hour, minute, second](JsonObject root) {
71
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
71
72
  root["year"] = year;
72
73
  root["month"] = month;
73
74
  root["day"] = day;
@@ -16,7 +16,8 @@ using namespace esphome::event;
16
16
  MQTTEventComponent::MQTTEventComponent(event::Event *event) : event_(event) {}
17
17
 
18
18
  void MQTTEventComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
19
- JsonArray event_types = root.createNestedArray(MQTT_EVENT_TYPES);
19
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
20
+ JsonArray event_types = root[MQTT_EVENT_TYPES].to<JsonArray>();
20
21
  for (const auto &event_type : this->event_->get_event_types())
21
22
  event_types.add(event_type);
22
23
 
@@ -40,8 +41,10 @@ void MQTTEventComponent::dump_config() {
40
41
  }
41
42
 
42
43
  bool MQTTEventComponent::publish_event_(const std::string &event_type) {
43
- return this->publish_json(this->get_state_topic_(),
44
- [event_type](JsonObject root) { root[MQTT_EVENT_TYPE] = event_type; });
44
+ return this->publish_json(this->get_state_topic_(), [event_type](JsonObject root) {
45
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
46
+ root[MQTT_EVENT_TYPE] = event_type;
47
+ });
45
48
  }
46
49
 
47
50
  std::string MQTTEventComponent::component_type() const { return "event"; }
@@ -143,6 +143,7 @@ void MQTTFanComponent::dump_config() {
143
143
  bool MQTTFanComponent::send_initial_state() { return this->publish_state(); }
144
144
 
145
145
  void MQTTFanComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
146
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
146
147
  if (this->state_->get_traits().supports_direction()) {
147
148
  root[MQTT_DIRECTION_COMMAND_TOPIC] = this->get_direction_command_topic();
148
149
  root[MQTT_DIRECTION_STATE_TOPIC] = this->get_direction_state_topic();
@@ -32,17 +32,21 @@ void MQTTJSONLightComponent::setup() {
32
32
  MQTTJSONLightComponent::MQTTJSONLightComponent(LightState *state) : state_(state) {}
33
33
 
34
34
  bool MQTTJSONLightComponent::publish_state_() {
35
- return this->publish_json(this->get_state_topic_(),
36
- [this](JsonObject root) { LightJSONSchema::dump_json(*this->state_, root); });
35
+ return this->publish_json(this->get_state_topic_(), [this](JsonObject root) {
36
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
37
+ LightJSONSchema::dump_json(*this->state_, root);
38
+ });
37
39
  }
38
40
  LightState *MQTTJSONLightComponent::get_state() const { return this->state_; }
39
41
 
40
42
  void MQTTJSONLightComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
43
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
41
44
  root["schema"] = "json";
42
45
  auto traits = this->state_->get_traits();
43
46
 
44
47
  root[MQTT_COLOR_MODE] = true;
45
- JsonArray color_modes = root.createNestedArray("supported_color_modes");
48
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
49
+ JsonArray color_modes = root["supported_color_modes"].to<JsonArray>();
46
50
  if (traits.supports_color_mode(ColorMode::ON_OFF))
47
51
  color_modes.add("onoff");
48
52
  if (traits.supports_color_mode(ColorMode::BRIGHTNESS))
@@ -67,7 +71,7 @@ void MQTTJSONLightComponent::send_discovery(JsonObject root, mqtt::SendDiscovery
67
71
 
68
72
  if (this->state_->supports_effects()) {
69
73
  root["effect"] = true;
70
- JsonArray effect_list = root.createNestedArray(MQTT_EFFECT_LIST);
74
+ JsonArray effect_list = root[MQTT_EFFECT_LIST].to<JsonArray>();
71
75
  for (auto *effect : this->state_->get_effects())
72
76
  effect_list.add(effect->get_name());
73
77
  effect_list.add("None");
@@ -38,8 +38,10 @@ void MQTTLockComponent::dump_config() {
38
38
  std::string MQTTLockComponent::component_type() const { return "lock"; }
39
39
  const EntityBase *MQTTLockComponent::get_entity() const { return this->lock_; }
40
40
  void MQTTLockComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
41
- if (this->lock_->traits.get_assumed_state())
41
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
42
+ if (this->lock_->traits.get_assumed_state()) {
42
43
  root[MQTT_OPTIMISTIC] = true;
44
+ }
43
45
  if (this->lock_->traits.get_supports_open())
44
46
  root[MQTT_PAYLOAD_OPEN] = "OPEN";
45
47
  }
@@ -40,6 +40,7 @@ const EntityBase *MQTTNumberComponent::get_entity() const { return this->number_
40
40
  void MQTTNumberComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
41
41
  const auto &traits = number_->traits;
42
42
  // https://www.home-assistant.io/integrations/number.mqtt/
43
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
43
44
  root[MQTT_MIN] = traits.get_min_value();
44
45
  root[MQTT_MAX] = traits.get_max_value();
45
46
  root[MQTT_STEP] = traits.get_step();
@@ -35,7 +35,8 @@ const EntityBase *MQTTSelectComponent::get_entity() const { return this->select_
35
35
  void MQTTSelectComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
36
36
  const auto &traits = select_->traits;
37
37
  // https://www.home-assistant.io/integrations/select.mqtt/
38
- JsonArray options = root.createNestedArray(MQTT_OPTIONS);
38
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
39
+ JsonArray options = root[MQTT_OPTIONS].to<JsonArray>();
39
40
  for (const auto &option : traits.get_options())
40
41
  options.add(option);
41
42
 
@@ -44,8 +44,10 @@ void MQTTSensorComponent::set_expire_after(uint32_t expire_after) { this->expire
44
44
  void MQTTSensorComponent::disable_expire_after() { this->expire_after_ = 0; }
45
45
 
46
46
  void MQTTSensorComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
47
- if (!this->sensor_->get_device_class().empty())
47
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
48
+ if (!this->sensor_->get_device_class().empty()) {
48
49
  root[MQTT_DEVICE_CLASS] = this->sensor_->get_device_class();
50
+ }
49
51
 
50
52
  if (!this->sensor_->get_unit_of_measurement().empty())
51
53
  root[MQTT_UNIT_OF_MEASUREMENT] = this->sensor_->get_unit_of_measurement();
@@ -45,8 +45,10 @@ void MQTTSwitchComponent::dump_config() {
45
45
  std::string MQTTSwitchComponent::component_type() const { return "switch"; }
46
46
  const EntityBase *MQTTSwitchComponent::get_entity() const { return this->switch_; }
47
47
  void MQTTSwitchComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
48
- if (this->switch_->assumed_state())
48
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
49
+ if (this->switch_->assumed_state()) {
49
50
  root[MQTT_OPTIMISTIC] = true;
51
+ }
50
52
  }
51
53
  bool MQTTSwitchComponent::send_initial_state() { return this->publish_state(this->switch_->state); }
52
54
 
@@ -34,6 +34,7 @@ std::string MQTTTextComponent::component_type() const { return "text"; }
34
34
  const EntityBase *MQTTTextComponent::get_entity() const { return this->text_; }
35
35
 
36
36
  void MQTTTextComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
37
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
37
38
  switch (this->text_->traits.get_mode()) {
38
39
  case TEXT_MODE_TEXT:
39
40
  root[MQTT_MODE] = "text";
@@ -15,8 +15,10 @@ using namespace esphome::text_sensor;
15
15
 
16
16
  MQTTTextSensor::MQTTTextSensor(TextSensor *sensor) : sensor_(sensor) {}
17
17
  void MQTTTextSensor::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
18
- if (!this->sensor_->get_device_class().empty())
18
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
19
+ if (!this->sensor_->get_device_class().empty()) {
19
20
  root[MQTT_DEVICE_CLASS] = this->sensor_->get_device_class();
21
+ }
20
22
  config.command_topic = false;
21
23
  }
22
24
  void MQTTTextSensor::setup() {
@@ -20,13 +20,13 @@ MQTTTimeComponent::MQTTTimeComponent(TimeEntity *time) : time_(time) {}
20
20
  void MQTTTimeComponent::setup() {
21
21
  this->subscribe_json(this->get_command_topic_(), [this](const std::string &topic, JsonObject root) {
22
22
  auto call = this->time_->make_call();
23
- if (root.containsKey("hour")) {
23
+ if (root["hour"].is<uint8_t>()) {
24
24
  call.set_hour(root["hour"]);
25
25
  }
26
- if (root.containsKey("minute")) {
26
+ if (root["minute"].is<uint8_t>()) {
27
27
  call.set_minute(root["minute"]);
28
28
  }
29
- if (root.containsKey("second")) {
29
+ if (root["second"].is<uint8_t>()) {
30
30
  call.set_second(root["second"]);
31
31
  }
32
32
  call.perform();
@@ -55,6 +55,7 @@ bool MQTTTimeComponent::send_initial_state() {
55
55
  }
56
56
  bool MQTTTimeComponent::publish_state(uint8_t hour, uint8_t minute, uint8_t second) {
57
57
  return this->publish_json(this->get_state_topic_(), [hour, minute, second](JsonObject root) {
58
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
58
59
  root["hour"] = hour;
59
60
  root["minute"] = minute;
60
61
  root["second"] = second;
@@ -41,6 +41,7 @@ bool MQTTUpdateComponent::publish_state() {
41
41
  }
42
42
 
43
43
  void MQTTUpdateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
44
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
44
45
  root["schema"] = "json";
45
46
  root[MQTT_PAYLOAD_INSTALL] = "INSTALL";
46
47
  }
@@ -49,8 +49,10 @@ void MQTTValveComponent::dump_config() {
49
49
  }
50
50
  }
51
51
  void MQTTValveComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
52
- if (!this->valve_->get_device_class().empty())
52
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
53
+ if (!this->valve_->get_device_class().empty()) {
53
54
  root[MQTT_DEVICE_CLASS] = this->valve_->get_device_class();
55
+ }
54
56
 
55
57
  auto traits = this->valve_->get_traits();
56
58
  if (traits.get_is_assumed_state()) {
@@ -356,7 +356,7 @@ void MS8607Component::read_humidity_(float temperature_float) {
356
356
 
357
357
  // map 16 bit humidity value into range [-6%, 118%]
358
358
  float const humidity_partial = double(humidity) / (1 << 16);
359
- float const humidity_percentage = lerp(humidity_partial, -6.0, 118.0);
359
+ float const humidity_percentage = std::lerp(-6.0, 118.0, humidity_partial);
360
360
  float const compensated_humidity_percentage =
361
361
  humidity_percentage + (20 - temperature_float) * MS8607_H_TEMP_COEFFICIENT;
362
362
  ESP_LOGD(TAG, "Compensated for temperature, humidity=%.2f%%", compensated_humidity_percentage);