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
@@ -3,14 +3,14 @@
3
3
  #ifdef USE_NEXTION_TFT_UPLOAD
4
4
  #ifdef USE_ESP_IDF
5
5
 
6
+ #include <esp_heap_caps.h>
7
+ #include <esp_http_client.h>
8
+ #include <cinttypes>
9
+ #include "esphome/components/network/util.h"
6
10
  #include "esphome/core/application.h"
7
11
  #include "esphome/core/defines.h"
8
- #include "esphome/core/util.h"
9
12
  #include "esphome/core/log.h"
10
- #include "esphome/components/network/util.h"
11
- #include <cinttypes>
12
- #include <esp_heap_caps.h>
13
- #include <esp_http_client.h>
13
+ #include "esphome/core/util.h"
14
14
 
15
15
  namespace esphome {
16
16
  namespace nextion {
@@ -51,7 +51,7 @@ int Nextion::upload_by_chunks_(esp_http_client_handle_t http_client, uint32_t &r
51
51
  }
52
52
 
53
53
  // Allocate the buffer dynamically
54
- ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
54
+ RAMAllocator<uint8_t> allocator;
55
55
  uint8_t *buffer = allocator.allocate(4096);
56
56
  if (!buffer) {
57
57
  ESP_LOGE(TAG, "Buffer alloc failed");
@@ -155,7 +155,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) {
155
155
  ESP_LOGD(TAG, "Exit reparse: %s", YESNO(exit_reparse));
156
156
  ESP_LOGD(TAG, "URL: %s", this->tft_url_.c_str());
157
157
 
158
- if (this->is_updating_) {
158
+ if (this->connection_state_.is_updating_) {
159
159
  ESP_LOGW(TAG, "Upload in progress");
160
160
  return false;
161
161
  }
@@ -165,7 +165,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) {
165
165
  return false;
166
166
  }
167
167
 
168
- this->is_updating_ = true;
168
+ this->connection_state_.is_updating_ = true;
169
169
 
170
170
  if (exit_reparse) {
171
171
  ESP_LOGD(TAG, "Exit reparse mode");
@@ -246,7 +246,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) {
246
246
 
247
247
  // The Nextion will ignore the upload command if it is sleeping
248
248
  ESP_LOGV(TAG, "Wake-up");
249
- this->ignore_is_setup_ = true;
249
+ this->connection_state_.ignore_is_setup_ = true;
250
250
  this->send_command_("sleep=0");
251
251
  this->send_command_("dim=100");
252
252
  vTaskDelay(pdMS_TO_TICKS(250)); // NOLINT
@@ -335,30 +335,6 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) {
335
335
  return this->upload_end_(true);
336
336
  }
337
337
 
338
- bool Nextion::upload_end_(bool successful) {
339
- ESP_LOGD(TAG, "TFT upload done: %s", YESNO(successful));
340
-
341
- if (successful) {
342
- ESP_LOGD(TAG, "Restart");
343
- delay(1500); // NOLINT
344
- App.safe_reboot();
345
- } else {
346
- ESP_LOGE(TAG, "TFT upload failed");
347
-
348
- this->is_updating_ = false;
349
- this->ignore_is_setup_ = false;
350
-
351
- uint32_t baud_rate = this->parent_->get_baud_rate();
352
- if (baud_rate != this->original_baud_rate_) {
353
- ESP_LOGD(TAG, "Baud back: %" PRIu32 "->%" PRIu32, baud_rate, this->original_baud_rate_);
354
- this->parent_->set_baud_rate(this->original_baud_rate_);
355
- this->parent_->load_settings();
356
- }
357
- }
358
-
359
- return successful;
360
- }
361
-
362
338
  } // namespace nextion
363
339
  } // namespace esphome
364
340
 
@@ -53,7 +53,7 @@ void NextionSensor::set_state(float state, bool publish, bool send_to_nextion) {
53
53
 
54
54
  if (this->wave_chan_id_ == UINT8_MAX) {
55
55
  if (send_to_nextion) {
56
- if (this->nextion_->is_sleeping() || !this->visible_) {
56
+ if (this->nextion_->is_sleeping() || !this->component_flags_.visible) {
57
57
  this->needs_to_send_update_ = true;
58
58
  } else {
59
59
  this->needs_to_send_update_ = false;
@@ -28,7 +28,7 @@ void NextionSwitch::set_state(bool state, bool publish, bool send_to_nextion) {
28
28
  return;
29
29
 
30
30
  if (send_to_nextion) {
31
- if (this->nextion_->is_sleeping() || !this->visible_) {
31
+ if (this->nextion_->is_sleeping() || !this->component_flags_.visible) {
32
32
  this->needs_to_send_update_ = true;
33
33
  } else {
34
34
  this->needs_to_send_update_ = false;
@@ -26,7 +26,7 @@ void NextionTextSensor::set_state(const std::string &state, bool publish, bool s
26
26
  return;
27
27
 
28
28
  if (send_to_nextion) {
29
- if (this->nextion_->is_sleeping() || !this->visible_) {
29
+ if (this->nextion_->is_sleeping() || !this->component_flags_.visible) {
30
30
  this->needs_to_send_update_ = true;
31
31
  } else {
32
32
  this->nextion_->add_no_result_to_queue_with_set(this, state);
@@ -1,5 +1,6 @@
1
1
  #include "nfc.h"
2
2
  #include <cstdio>
3
+ #include "esphome/core/helpers.h"
3
4
  #include "esphome/core/log.h"
4
5
 
5
6
  namespace esphome {
@@ -7,29 +8,9 @@ namespace nfc {
7
8
 
8
9
  static const char *const TAG = "nfc";
9
10
 
10
- std::string format_uid(std::vector<uint8_t> &uid) {
11
- char buf[(uid.size() * 2) + uid.size() - 1];
12
- int offset = 0;
13
- for (size_t i = 0; i < uid.size(); i++) {
14
- const char *format = "%02X";
15
- if (i + 1 < uid.size())
16
- format = "%02X-";
17
- offset += sprintf(buf + offset, format, uid[i]);
18
- }
19
- return std::string(buf);
20
- }
11
+ std::string format_uid(const std::vector<uint8_t> &uid) { return format_hex_pretty(uid, '-', false); }
21
12
 
22
- std::string format_bytes(std::vector<uint8_t> &bytes) {
23
- char buf[(bytes.size() * 2) + bytes.size() - 1];
24
- int offset = 0;
25
- for (size_t i = 0; i < bytes.size(); i++) {
26
- const char *format = "%02X";
27
- if (i + 1 < bytes.size())
28
- format = "%02X ";
29
- offset += sprintf(buf + offset, format, bytes[i]);
30
- }
31
- return std::string(buf);
32
- }
13
+ std::string format_bytes(const std::vector<uint8_t> &bytes) { return format_hex_pretty(bytes, ' ', false); }
33
14
 
34
15
  uint8_t guess_tag_type(uint8_t uid_length) {
35
16
  if (uid_length == 4) {
@@ -2,8 +2,8 @@
2
2
 
3
3
  #include "esphome/core/helpers.h"
4
4
  #include "esphome/core/log.h"
5
- #include "ndef_record.h"
6
5
  #include "ndef_message.h"
6
+ #include "ndef_record.h"
7
7
  #include "nfc_tag.h"
8
8
 
9
9
  #include <vector>
@@ -53,8 +53,8 @@ static const uint8_t DEFAULT_KEY[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
53
53
  static const uint8_t NDEF_KEY[6] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7};
54
54
  static const uint8_t MAD_KEY[6] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
55
55
 
56
- std::string format_uid(std::vector<uint8_t> &uid);
57
- std::string format_bytes(std::vector<uint8_t> &bytes);
56
+ std::string format_uid(const std::vector<uint8_t> &uid);
57
+ std::string format_bytes(const std::vector<uint8_t> &bytes);
58
58
 
59
59
  uint8_t guess_tag_type(uint8_t uid_length);
60
60
  uint8_t get_mifare_classic_ndef_start_index(std::vector<uint8_t> &data);
@@ -76,8 +76,8 @@ from esphome.const import (
76
76
  DEVICE_CLASS_WIND_SPEED,
77
77
  )
78
78
  from esphome.core import CORE, coroutine_with_priority
79
+ from esphome.core.entity_helpers import entity_duplicate_validator, setup_entity
79
80
  from esphome.cpp_generator import MockObjClass
80
- from esphome.cpp_helpers import setup_entity
81
81
 
82
82
  CODEOWNERS = ["@esphome/core"]
83
83
  DEVICE_CLASSES = [
@@ -207,6 +207,9 @@ _NUMBER_SCHEMA = (
207
207
  )
208
208
 
209
209
 
210
+ _NUMBER_SCHEMA.add_extra(entity_duplicate_validator("number"))
211
+
212
+
210
213
  def number_schema(
211
214
  class_: MockObjClass,
212
215
  *,
@@ -237,7 +240,7 @@ NUMBER_SCHEMA.add_extra(cv.deprecated_schema_constant("number"))
237
240
  async def setup_number_core_(
238
241
  var, config, *, min_value: float, max_value: float, step: float
239
242
  ):
240
- await setup_entity(var, config)
243
+ await setup_entity(var, config, "number")
241
244
 
242
245
  cg.add(var.traits.set_min_value(min_value))
243
246
  cg.add(var.traits.set_max_value(max_value))
@@ -2,7 +2,7 @@ import logging
2
2
 
3
3
  from esphome import automation
4
4
  import esphome.codegen as cg
5
- from esphome.components.const import CONF_REQUEST_HEADERS
5
+ from esphome.components.const import CONF_BYTE_ORDER, CONF_REQUEST_HEADERS
6
6
  from esphome.components.http_request import CONF_HTTP_REQUEST_ID, HttpRequestComponent
7
7
  from esphome.components.image import (
8
8
  CONF_INVERT_ALPHA,
@@ -11,6 +11,7 @@ from esphome.components.image import (
11
11
  Image_,
12
12
  get_image_type_enum,
13
13
  get_transparency_enum,
14
+ validate_settings,
14
15
  )
15
16
  import esphome.config_validation as cv
16
17
  from esphome.const import (
@@ -34,6 +35,7 @@ MULTI_CONF = True
34
35
 
35
36
  CONF_ON_DOWNLOAD_FINISHED = "on_download_finished"
36
37
  CONF_PLACEHOLDER = "placeholder"
38
+ CONF_UPDATE = "update"
37
39
 
38
40
  _LOGGER = logging.getLogger(__name__)
39
41
 
@@ -160,6 +162,7 @@ CONFIG_SCHEMA = cv.Schema(
160
162
  rp2040_arduino=cv.Version(0, 0, 0),
161
163
  host=cv.Version(0, 0, 0),
162
164
  ),
165
+ validate_settings,
163
166
  )
164
167
  )
165
168
 
@@ -167,6 +170,7 @@ SET_URL_SCHEMA = cv.Schema(
167
170
  {
168
171
  cv.GenerateID(): cv.use_id(OnlineImage),
169
172
  cv.Required(CONF_URL): cv.templatable(cv.url),
173
+ cv.Optional(CONF_UPDATE, default=True): cv.templatable(bool),
170
174
  }
171
175
  )
172
176
 
@@ -188,6 +192,9 @@ async def online_image_action_to_code(config, action_id, template_arg, args):
188
192
  if CONF_URL in config:
189
193
  template_ = await cg.templatable(config[CONF_URL], args, cg.std_string)
190
194
  cg.add(var.set_url(template_))
195
+ if CONF_UPDATE in config:
196
+ template_ = await cg.templatable(config[CONF_UPDATE], args, bool)
197
+ cg.add(var.set_update(template_))
191
198
  return var
192
199
 
193
200
 
@@ -208,6 +215,7 @@ async def to_code(config):
208
215
  get_image_type_enum(config[CONF_TYPE]),
209
216
  transparent,
210
217
  config[CONF_BUFFER_SIZE],
218
+ config.get(CONF_BYTE_ORDER) != "LITTLE_ENDIAN",
211
219
  )
212
220
  await cg.register_component(var, config)
213
221
  await cg.register_parented(var, config[CONF_HTTP_REQUEST_ID])
@@ -35,14 +35,15 @@ inline bool is_color_on(const Color &color) {
35
35
  }
36
36
 
37
37
  OnlineImage::OnlineImage(const std::string &url, int width, int height, ImageFormat format, ImageType type,
38
- image::Transparency transparency, uint32_t download_buffer_size)
38
+ image::Transparency transparency, uint32_t download_buffer_size, bool is_big_endian)
39
39
  : Image(nullptr, 0, 0, type, transparency),
40
40
  buffer_(nullptr),
41
41
  download_buffer_(download_buffer_size),
42
42
  download_buffer_initial_size_(download_buffer_size),
43
43
  format_(format),
44
44
  fixed_width_(width),
45
- fixed_height_(height) {
45
+ fixed_height_(height),
46
+ is_big_endian_(is_big_endian) {
46
47
  this->set_url(url);
47
48
  }
48
49
 
@@ -178,18 +179,21 @@ void OnlineImage::update() {
178
179
  if (this->format_ == ImageFormat::BMP) {
179
180
  ESP_LOGD(TAG, "Allocating BMP decoder");
180
181
  this->decoder_ = make_unique<BmpDecoder>(this);
182
+ this->enable_loop();
181
183
  }
182
184
  #endif // USE_ONLINE_IMAGE_BMP_SUPPORT
183
185
  #ifdef USE_ONLINE_IMAGE_JPEG_SUPPORT
184
186
  if (this->format_ == ImageFormat::JPEG) {
185
187
  ESP_LOGD(TAG, "Allocating JPEG decoder");
186
188
  this->decoder_ = esphome::make_unique<JpegDecoder>(this);
189
+ this->enable_loop();
187
190
  }
188
191
  #endif // USE_ONLINE_IMAGE_JPEG_SUPPORT
189
192
  #ifdef USE_ONLINE_IMAGE_PNG_SUPPORT
190
193
  if (this->format_ == ImageFormat::PNG) {
191
194
  ESP_LOGD(TAG, "Allocating PNG decoder");
192
195
  this->decoder_ = make_unique<PngDecoder>(this);
196
+ this->enable_loop();
193
197
  }
194
198
  #endif // USE_ONLINE_IMAGE_PNG_SUPPORT
195
199
 
@@ -212,6 +216,7 @@ void OnlineImage::update() {
212
216
  void OnlineImage::loop() {
213
217
  if (!this->decoder_) {
214
218
  // Not decoding at the moment => nothing to do.
219
+ this->disable_loop();
215
220
  return;
216
221
  }
217
222
  if (!this->downloader_ || this->decoder_->is_finished()) {
@@ -220,7 +225,7 @@ void OnlineImage::loop() {
220
225
  this->height_ = buffer_height_;
221
226
  ESP_LOGD(TAG, "Image fully downloaded, read %zu bytes, width/height = %d/%d", this->downloader_->get_bytes_read(),
222
227
  this->width_, this->height_);
223
- ESP_LOGD(TAG, "Total time: %lds", ::time(nullptr) - this->start_time_);
228
+ ESP_LOGD(TAG, "Total time: %" PRIu32 "s", (uint32_t) (::time(nullptr) - this->start_time_));
224
229
  this->etag_ = this->downloader_->get_response_header(ETAG_HEADER_NAME);
225
230
  this->last_modified_ = this->downloader_->get_response_header(LAST_MODIFIED_HEADER_NAME);
226
231
  this->download_finished_callback_.call(false);
@@ -292,7 +297,7 @@ void OnlineImage::draw_pixel_(int x, int y, Color color) {
292
297
  break;
293
298
  }
294
299
  case ImageType::IMAGE_TYPE_GRAYSCALE: {
295
- uint8_t gray = static_cast<uint8_t>(0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b);
300
+ auto gray = static_cast<uint8_t>(0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b);
296
301
  if (this->transparency_ == image::TRANSPARENCY_CHROMA_KEY) {
297
302
  if (gray == 1) {
298
303
  gray = 0;
@@ -310,8 +315,13 @@ void OnlineImage::draw_pixel_(int x, int y, Color color) {
310
315
  case ImageType::IMAGE_TYPE_RGB565: {
311
316
  this->map_chroma_key(color);
312
317
  uint16_t col565 = display::ColorUtil::color_to_565(color);
313
- this->buffer_[pos + 0] = static_cast<uint8_t>((col565 >> 8) & 0xFF);
314
- this->buffer_[pos + 1] = static_cast<uint8_t>(col565 & 0xFF);
318
+ if (this->is_big_endian_) {
319
+ this->buffer_[pos + 0] = static_cast<uint8_t>((col565 >> 8) & 0xFF);
320
+ this->buffer_[pos + 1] = static_cast<uint8_t>(col565 & 0xFF);
321
+ } else {
322
+ this->buffer_[pos + 0] = static_cast<uint8_t>(col565 & 0xFF);
323
+ this->buffer_[pos + 1] = static_cast<uint8_t>((col565 >> 8) & 0xFF);
324
+ }
315
325
  if (this->transparency_ == image::TRANSPARENCY_ALPHA_CHANNEL) {
316
326
  this->buffer_[pos + 2] = color.w;
317
327
  }
@@ -340,7 +350,7 @@ void OnlineImage::end_connection_() {
340
350
  }
341
351
 
342
352
  bool OnlineImage::validate_url_(const std::string &url) {
343
- if ((url.length() < 8) || (url.find("http") != 0) || (url.find("://") == std::string::npos)) {
353
+ if ((url.length() < 8) || !url.starts_with("http") || (url.find("://") == std::string::npos)) {
344
354
  ESP_LOGE(TAG, "URL is invalid and/or must be prefixed with 'http://' or 'https://'");
345
355
  return false;
346
356
  }
@@ -50,7 +50,7 @@ class OnlineImage : public PollingComponent,
50
50
  * @param buffer_size Size of the buffer used to download the image.
51
51
  */
52
52
  OnlineImage(const std::string &url, int width, int height, ImageFormat format, image::ImageType type,
53
- image::Transparency transparency, uint32_t buffer_size);
53
+ image::Transparency transparency, uint32_t buffer_size, bool is_big_endian);
54
54
 
55
55
  void draw(int x, int y, display::Display *display, Color color_on, Color color_off) override;
56
56
 
@@ -164,6 +164,11 @@ class OnlineImage : public PollingComponent,
164
164
  const int fixed_width_;
165
165
  /** height requested on configuration, or 0 if non specified. */
166
166
  const int fixed_height_;
167
+ /**
168
+ * Whether the image is stored in big-endian format.
169
+ * This is used to determine how to store 16 bit colors in the buffer.
170
+ */
171
+ bool is_big_endian_;
167
172
  /**
168
173
  * Actual width of the current image. If fixed_width_ is specified,
169
174
  * this will be equal to it; otherwise it will be set once the decoding
@@ -201,9 +206,12 @@ template<typename... Ts> class OnlineImageSetUrlAction : public Action<Ts...> {
201
206
  public:
202
207
  OnlineImageSetUrlAction(OnlineImage *parent) : parent_(parent) {}
203
208
  TEMPLATABLE_VALUE(std::string, url)
209
+ TEMPLATABLE_VALUE(bool, update)
204
210
  void play(Ts... x) override {
205
211
  this->parent_->set_url(this->url_.value(x...));
206
- this->parent_->update();
212
+ if (this->update_.value(x...)) {
213
+ this->parent_->update();
214
+ }
207
215
  }
208
216
 
209
217
  protected:
@@ -272,18 +272,13 @@ bool OpenTherm::init_esp32_timer_() {
272
272
  this->timer_idx_ = timer_idx;
273
273
 
274
274
  timer_config_t const config = {
275
- .alarm_en = TIMER_ALARM_EN,
276
- .counter_en = TIMER_PAUSE,
277
- .intr_type = TIMER_INTR_LEVEL,
278
- .counter_dir = TIMER_COUNT_UP,
279
- .auto_reload = TIMER_AUTORELOAD_EN,
280
- #if ESP_IDF_VERSION_MAJOR >= 5
281
- .clk_src = TIMER_SRC_CLK_DEFAULT,
282
- #endif
283
- .divider = 80,
284
- #if defined(SOC_TIMER_GROUP_SUPPORT_XTAL) && ESP_IDF_VERSION_MAJOR < 5
285
- .clk_src = TIMER_SRC_CLK_APB
286
- #endif
275
+ .alarm_en = TIMER_ALARM_EN,
276
+ .counter_en = TIMER_PAUSE,
277
+ .intr_type = TIMER_INTR_LEVEL,
278
+ .counter_dir = TIMER_COUNT_UP,
279
+ .auto_reload = TIMER_AUTORELOAD_EN,
280
+ .clk_src = TIMER_SRC_CLK_DEFAULT,
281
+ .divider = 80,
287
282
  };
288
283
 
289
284
  esp_err_t result;
@@ -10,7 +10,7 @@ void opentherm::OpenthermOutput::write_state(float state) {
10
10
  ESP_LOGD(TAG, "Received state: %.2f. Min value: %.2f, max value: %.2f", state, min_value_, max_value_);
11
11
  this->state = state < 0.003 && this->zero_means_zero_
12
12
  ? 0.0
13
- : clamp(lerp(state, min_value_, max_value_), min_value_, max_value_);
13
+ : clamp(std::lerp(min_value_, max_value_, state), min_value_, max_value_);
14
14
  this->has_state_ = true;
15
15
  ESP_LOGD(TAG, "Output %s set to %.2f", this->id_, this->state);
16
16
  }
@@ -11,6 +11,7 @@ from esphome.const import CONF_CHANNEL, CONF_ENABLE_IPV6, CONF_ID
11
11
  import esphome.final_validate as fv
12
12
 
13
13
  from .const import (
14
+ CONF_DEVICE_TYPE,
14
15
  CONF_EXT_PAN_ID,
15
16
  CONF_FORCE_DATASET,
16
17
  CONF_MDNS_ID,
@@ -22,7 +23,6 @@ from .const import (
22
23
  CONF_SRP_ID,
23
24
  CONF_TLV,
24
25
  )
25
- from .tlv import parse_tlv
26
26
 
27
27
  CODEOWNERS = ["@mrene"]
28
28
 
@@ -33,6 +33,11 @@ AUTO_LOAD = ["network"]
33
33
  CONFLICTS_WITH = ["wifi"]
34
34
  DEPENDENCIES = ["esp32"]
35
35
 
36
+ CONF_DEVICE_TYPES = [
37
+ "FTD",
38
+ "MTD",
39
+ ]
40
+
36
41
 
37
42
  def set_sdkconfig_options(config):
38
43
  # and expose options for using SPI/UART RCPs
@@ -43,58 +48,58 @@ def set_sdkconfig_options(config):
43
48
  add_idf_sdkconfig_option("CONFIG_OPENTHREAD_CLI", False)
44
49
 
45
50
  add_idf_sdkconfig_option("CONFIG_OPENTHREAD_ENABLED", True)
46
- add_idf_sdkconfig_option("CONFIG_OPENTHREAD_NETWORK_PANID", config[CONF_PAN_ID])
47
- add_idf_sdkconfig_option("CONFIG_OPENTHREAD_NETWORK_CHANNEL", config[CONF_CHANNEL])
48
- add_idf_sdkconfig_option(
49
- "CONFIG_OPENTHREAD_NETWORK_MASTERKEY", f"{config[CONF_NETWORK_KEY]:X}".lower()
50
- )
51
-
52
- if network_name := config.get(CONF_NETWORK_NAME):
53
- add_idf_sdkconfig_option("CONFIG_OPENTHREAD_NETWORK_NAME", network_name)
54
-
55
- if (ext_pan_id := config.get(CONF_EXT_PAN_ID)) is not None:
56
- add_idf_sdkconfig_option(
57
- "CONFIG_OPENTHREAD_NETWORK_EXTPANID", f"{ext_pan_id:X}".lower()
58
- )
59
- if (mesh_local_prefix := config.get(CONF_MESH_LOCAL_PREFIX)) is not None:
60
- add_idf_sdkconfig_option(
61
- "CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX", f"{mesh_local_prefix}".lower()
62
- )
63
- if (pskc := config.get(CONF_PSKC)) is not None:
64
- add_idf_sdkconfig_option("CONFIG_OPENTHREAD_NETWORK_PSKC", f"{pskc:X}".lower())
65
51
 
66
- if CONF_FORCE_DATASET in config:
67
- if config[CONF_FORCE_DATASET]:
68
- cg.add_define("CONFIG_OPENTHREAD_FORCE_DATASET")
52
+ if tlv := config.get(CONF_TLV):
53
+ cg.add_define("USE_OPENTHREAD_TLVS", tlv)
54
+ else:
55
+ if pan_id := config.get(CONF_PAN_ID):
56
+ add_idf_sdkconfig_option("CONFIG_OPENTHREAD_NETWORK_PANID", pan_id)
57
+
58
+ if channel := config.get(CONF_CHANNEL):
59
+ add_idf_sdkconfig_option("CONFIG_OPENTHREAD_NETWORK_CHANNEL", channel)
60
+
61
+ if network_key := config.get(CONF_NETWORK_KEY):
62
+ add_idf_sdkconfig_option(
63
+ "CONFIG_OPENTHREAD_NETWORK_MASTERKEY", f"{network_key:X}".lower()
64
+ )
65
+
66
+ if network_name := config.get(CONF_NETWORK_NAME):
67
+ add_idf_sdkconfig_option("CONFIG_OPENTHREAD_NETWORK_NAME", network_name)
68
+
69
+ if (ext_pan_id := config.get(CONF_EXT_PAN_ID)) is not None:
70
+ add_idf_sdkconfig_option(
71
+ "CONFIG_OPENTHREAD_NETWORK_EXTPANID", f"{ext_pan_id:X}".lower()
72
+ )
73
+ if (mesh_local_prefix := config.get(CONF_MESH_LOCAL_PREFIX)) is not None:
74
+ add_idf_sdkconfig_option(
75
+ "CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX", f"{mesh_local_prefix}".lower()
76
+ )
77
+ if (pskc := config.get(CONF_PSKC)) is not None:
78
+ add_idf_sdkconfig_option(
79
+ "CONFIG_OPENTHREAD_NETWORK_PSKC", f"{pskc:X}".lower()
80
+ )
81
+
82
+ if force_dataset := config.get(CONF_FORCE_DATASET):
83
+ if force_dataset:
84
+ cg.add_define("USE_OPENTHREAD_FORCE_DATASET")
69
85
 
70
86
  add_idf_sdkconfig_option("CONFIG_OPENTHREAD_DNS64_CLIENT", True)
71
87
  add_idf_sdkconfig_option("CONFIG_OPENTHREAD_SRP_CLIENT", True)
72
88
  add_idf_sdkconfig_option("CONFIG_OPENTHREAD_SRP_CLIENT_MAX_SERVICES", 5)
73
89
 
74
90
  # TODO: Add suport for sleepy end devices
75
- add_idf_sdkconfig_option("CONFIG_OPENTHREAD_FTD", True) # Full Thread Device
91
+ add_idf_sdkconfig_option(f"CONFIG_OPENTHREAD_{config.get(CONF_DEVICE_TYPE)}", True)
76
92
 
77
93
 
78
94
  openthread_ns = cg.esphome_ns.namespace("openthread")
79
95
  OpenThreadComponent = openthread_ns.class_("OpenThreadComponent", cg.Component)
80
96
  OpenThreadSrpComponent = openthread_ns.class_("OpenThreadSrpComponent", cg.Component)
81
97
 
82
-
83
- def _convert_tlv(config):
84
- if tlv := config.get(CONF_TLV):
85
- config = config.copy()
86
- parsed_tlv = parse_tlv(tlv)
87
- validated = _CONNECTION_SCHEMA(parsed_tlv)
88
- config.update(validated)
89
- del config[CONF_TLV]
90
- return config
91
-
92
-
93
98
  _CONNECTION_SCHEMA = cv.Schema(
94
99
  {
95
- cv.Inclusive(CONF_PAN_ID, "manual"): cv.hex_int,
96
- cv.Inclusive(CONF_CHANNEL, "manual"): cv.int_,
97
- cv.Inclusive(CONF_NETWORK_KEY, "manual"): cv.hex_int,
100
+ cv.Optional(CONF_PAN_ID): cv.hex_int,
101
+ cv.Optional(CONF_CHANNEL): cv.int_,
102
+ cv.Optional(CONF_NETWORK_KEY): cv.hex_int,
98
103
  cv.Optional(CONF_EXT_PAN_ID): cv.hex_int,
99
104
  cv.Optional(CONF_NETWORK_NAME): cv.string_strict,
100
105
  cv.Optional(CONF_PSKC): cv.hex_int,
@@ -108,12 +113,14 @@ CONFIG_SCHEMA = cv.All(
108
113
  cv.GenerateID(): cv.declare_id(OpenThreadComponent),
109
114
  cv.GenerateID(CONF_SRP_ID): cv.declare_id(OpenThreadSrpComponent),
110
115
  cv.GenerateID(CONF_MDNS_ID): cv.use_id(MDNSComponent),
116
+ cv.Optional(CONF_DEVICE_TYPE, default="FTD"): cv.one_of(
117
+ *CONF_DEVICE_TYPES, upper=True
118
+ ),
111
119
  cv.Optional(CONF_FORCE_DATASET): cv.boolean,
112
120
  cv.Optional(CONF_TLV): cv.string_strict,
113
121
  }
114
122
  ).extend(_CONNECTION_SCHEMA),
115
- cv.has_exactly_one_key(CONF_PAN_ID, CONF_TLV),
116
- _convert_tlv,
123
+ cv.has_exactly_one_key(CONF_NETWORK_KEY, CONF_TLV),
117
124
  cv.only_with_esp_idf,
118
125
  only_on_variant(supported=[VARIANT_ESP32C6, VARIANT_ESP32H2]),
119
126
  )
@@ -1,3 +1,4 @@
1
+ CONF_DEVICE_TYPE = "device_type"
1
2
  CONF_EXT_PAN_ID = "ext_pan_id"
2
3
  CONF_FORCE_DATASET = "force_dataset"
3
4
  CONF_MDNS_ID = "mdns_id"
@@ -111,14 +111,36 @@ void OpenThreadComponent::ot_main() {
111
111
  esp_openthread_cli_create_task();
112
112
  #endif
113
113
  ESP_LOGI(TAG, "Activating dataset...");
114
- otOperationalDatasetTlvs dataset;
114
+ otOperationalDatasetTlvs dataset = {};
115
115
 
116
- #ifdef CONFIG_OPENTHREAD_FORCE_DATASET
117
- ESP_ERROR_CHECK(esp_openthread_auto_start(NULL));
118
- #else
116
+ #ifndef USE_OPENTHREAD_FORCE_DATASET
117
+ // Check if openthread has a valid dataset from a previous execution
119
118
  otError error = otDatasetGetActiveTlvs(esp_openthread_get_instance(), &dataset);
120
- ESP_ERROR_CHECK(esp_openthread_auto_start((error == OT_ERROR_NONE) ? &dataset : NULL));
119
+ if (error != OT_ERROR_NONE) {
120
+ // Make sure the length is 0 so we fallback to the configuration
121
+ dataset.mLength = 0;
122
+ } else {
123
+ ESP_LOGI(TAG, "Found OpenThread-managed dataset, ignoring esphome configuration");
124
+ ESP_LOGI(TAG, "(set force_dataset: true to override)");
125
+ }
126
+ #endif
127
+
128
+ #ifdef USE_OPENTHREAD_TLVS
129
+ if (dataset.mLength == 0) {
130
+ // If we didn't have an active dataset, and we have tlvs, parse it and pass it to esp_openthread_auto_start
131
+ size_t len = (sizeof(USE_OPENTHREAD_TLVS) - 1) / 2;
132
+ if (len > sizeof(dataset.mTlvs)) {
133
+ ESP_LOGW(TAG, "TLV buffer too small, truncating");
134
+ len = sizeof(dataset.mTlvs);
135
+ }
136
+ parse_hex(USE_OPENTHREAD_TLVS, sizeof(USE_OPENTHREAD_TLVS) - 1, dataset.mTlvs, len);
137
+ dataset.mLength = len;
138
+ }
121
139
  #endif
140
+
141
+ // Pass the existing dataset, or NULL which will use the preprocessor definitions
142
+ ESP_ERROR_CHECK(esp_openthread_auto_start(dataset.mLength > 0 ? &dataset : nullptr));
143
+
122
144
  esp_openthread_launch_mainloop();
123
145
 
124
146
  // Clean up
File without changes