esphome 2025.7.5__py3-none-any.whl → 2025.8.0b2__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 (752) hide show
  1. esphome/__main__.py +189 -82
  2. esphome/automation.py +2 -4
  3. esphome/build_gen/__init__.py +0 -0
  4. esphome/build_gen/platformio.py +102 -0
  5. esphome/components/a4988/a4988.cpp +0 -1
  6. esphome/components/absolute_humidity/absolute_humidity.cpp +0 -2
  7. esphome/components/absolute_humidity/sensor.py +2 -2
  8. esphome/components/adc/__init__.py +123 -85
  9. esphome/components/adc/adc_sensor.h +98 -35
  10. esphome/components/adc/adc_sensor_common.cpp +10 -4
  11. esphome/components/adc/adc_sensor_esp32.cpp +291 -123
  12. esphome/components/adc/adc_sensor_esp8266.cpp +1 -4
  13. esphome/components/adc/adc_sensor_libretiny.cpp +1 -2
  14. esphome/components/adc/adc_sensor_rp2040.cpp +1 -2
  15. esphome/components/adc/adc_sensor_zephyr.cpp +207 -0
  16. esphome/components/adc/sensor.py +61 -27
  17. esphome/components/adc128s102/adc128s102.cpp +1 -4
  18. esphome/components/ade7880/sensor.py +75 -49
  19. esphome/components/ads1115/ads1115.cpp +0 -1
  20. esphome/components/ads1118/ads1118.cpp +0 -1
  21. esphome/components/ags10/ags10.cpp +0 -4
  22. esphome/components/aht10/aht10.cpp +0 -4
  23. esphome/components/aic3204/aic3204.cpp +0 -2
  24. esphome/components/airthings_wave_plus/__init__.py +1 -1
  25. esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +22 -4
  26. esphome/components/airthings_wave_plus/airthings_wave_plus.h +10 -1
  27. esphome/components/airthings_wave_plus/sensor.py +55 -28
  28. esphome/components/alarm_control_panel/__init__.py +4 -9
  29. esphome/components/am2315c/am2315c.cpp +0 -2
  30. esphome/components/am2320/am2320.cpp +0 -1
  31. esphome/components/animation/__init__.py +14 -11
  32. esphome/components/apds9306/apds9306.cpp +0 -4
  33. esphome/components/apds9960/apds9960.cpp +0 -1
  34. esphome/components/api/__init__.py +29 -4
  35. esphome/components/api/api_connection.cpp +378 -401
  36. esphome/components/api/api_connection.h +102 -52
  37. esphome/components/api/api_frame_helper.cpp +69 -896
  38. esphome/components/api/api_frame_helper.h +31 -126
  39. esphome/components/api/api_frame_helper_noise.cpp +583 -0
  40. esphome/components/api/api_frame_helper_noise.h +68 -0
  41. esphome/components/api/api_frame_helper_plaintext.cpp +290 -0
  42. esphome/components/api/api_frame_helper_plaintext.h +53 -0
  43. esphome/components/api/api_noise_context.h +2 -4
  44. esphome/components/api/api_pb2.cpp +1601 -1808
  45. esphome/components/api/api_pb2.h +367 -323
  46. esphome/components/api/api_pb2_dump.cpp +1137 -3466
  47. esphome/components/api/api_pb2_includes.h +34 -0
  48. esphome/components/api/api_pb2_service.cpp +94 -105
  49. esphome/components/api/api_pb2_service.h +27 -16
  50. esphome/components/api/api_server.cpp +18 -17
  51. esphome/components/api/api_server.h +8 -5
  52. esphome/components/api/client.py +16 -8
  53. esphome/components/api/custom_api_device.h +68 -14
  54. esphome/components/api/homeassistant_service.h +24 -19
  55. esphome/components/api/list_entities.cpp +3 -5
  56. esphome/components/api/list_entities.h +2 -4
  57. esphome/components/api/proto.cpp +3 -5
  58. esphome/components/api/proto.h +239 -274
  59. esphome/components/api/subscribe_state.cpp +2 -4
  60. esphome/components/api/subscribe_state.h +2 -4
  61. esphome/components/api/user_services.cpp +2 -4
  62. esphome/components/api/user_services.h +8 -8
  63. esphome/components/as3935/as3935.cpp +0 -2
  64. esphome/components/as3935_spi/as3935_spi.cpp +0 -2
  65. esphome/components/as5600/__init__.py +1 -1
  66. esphome/components/as5600/as5600.cpp +0 -2
  67. esphome/components/as5600/sensor/__init__.py +0 -1
  68. esphome/components/as7341/as7341.cpp +0 -1
  69. esphome/components/async_tcp/__init__.py +1 -1
  70. esphome/components/at581x/at581x.cpp +1 -1
  71. esphome/components/atm90e26/atm90e26.cpp +0 -1
  72. esphome/components/atm90e32/atm90e32.cpp +488 -118
  73. esphome/components/atm90e32/atm90e32.h +44 -5
  74. esphome/components/audio/audio.h +2 -2
  75. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +0 -2
  76. esphome/components/beken_spi_led_strip/led_strip.cpp +0 -2
  77. esphome/components/bh1750/bh1750.cpp +0 -1
  78. esphome/components/binary_sensor/__init__.py +14 -12
  79. esphome/components/ble_client/__init__.py +4 -7
  80. esphome/components/bluetooth_proxy/__init__.py +40 -3
  81. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +387 -82
  82. esphome/components/bluetooth_proxy/bluetooth_connection.h +16 -5
  83. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +102 -311
  84. esphome/components/bluetooth_proxy/bluetooth_proxy.h +30 -14
  85. esphome/components/bme280_base/bme280_base.cpp +15 -16
  86. esphome/components/bme680/bme680.cpp +2 -3
  87. esphome/components/bme680_bsec/bme680_bsec.cpp +0 -2
  88. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +0 -2
  89. esphome/components/bmi160/bmi160.cpp +0 -1
  90. esphome/components/bmp085/bmp085.cpp +0 -1
  91. esphome/components/bmp280_base/bmp280_base.cpp +13 -14
  92. esphome/components/bmp3xx_base/bmp3xx_base.cpp +0 -1
  93. esphome/components/bmp581/bmp581.cpp +0 -2
  94. esphome/components/bp1658cj/bp1658cj.cpp +0 -1
  95. esphome/components/bp5758d/bp5758d.cpp +0 -1
  96. esphome/components/button/__init__.py +0 -1
  97. esphome/components/canbus/__init__.py +2 -3
  98. esphome/components/canbus/canbus.cpp +0 -1
  99. esphome/components/cap1188/cap1188.cpp +0 -2
  100. esphome/components/captive_portal/__init__.py +1 -1
  101. esphome/components/cd74hc4067/cd74hc4067.cpp +0 -2
  102. esphome/components/ch422g/ch422g.cpp +0 -1
  103. esphome/components/chsc6x/chsc6x_touchscreen.cpp +0 -3
  104. esphome/components/climate/__init__.py +0 -1
  105. esphome/components/climate/climate_traits.h +24 -0
  106. esphome/components/cm1106/cm1106.cpp +0 -1
  107. esphome/components/const/__init__.py +6 -0
  108. esphome/components/cover/__init__.py +0 -1
  109. esphome/components/cover/cover.cpp +9 -13
  110. esphome/components/cs5460a/cs5460a.cpp +0 -2
  111. esphome/components/cse7761/cse7761.cpp +0 -1
  112. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +0 -2
  113. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +0 -2
  114. esphome/components/dac7678/dac7678_output.cpp +0 -2
  115. esphome/components/dallas_temp/dallas_temp.cpp +0 -1
  116. esphome/components/datetime/__init__.py +0 -2
  117. esphome/components/debug/__init__.py +15 -1
  118. esphome/components/debug/debug_zephyr.cpp +281 -0
  119. esphome/components/debug/sensor.py +2 -1
  120. esphome/components/deep_sleep/deep_sleep_component.cpp +0 -1
  121. esphome/components/deep_sleep/deep_sleep_esp32.cpp +20 -1
  122. esphome/components/dfrobot_sen0395/__init__.py +1 -2
  123. esphome/components/dht/dht.cpp +0 -1
  124. esphome/components/dht12/dht12.cpp +0 -1
  125. esphome/components/display/__init__.py +16 -3
  126. esphome/components/display_menu_base/__init__.py +1 -1
  127. esphome/components/dps310/dps310.cpp +0 -2
  128. esphome/components/ds1307/ds1307.cpp +0 -1
  129. esphome/components/ds2484/ds2484.cpp +0 -1
  130. esphome/components/duty_cycle/duty_cycle_sensor.cpp +0 -1
  131. esphome/components/ee895/ee895.cpp +0 -1
  132. esphome/components/ektf2232/touchscreen/ektf2232.cpp +0 -1
  133. esphome/components/emc2101/emc2101.cpp +0 -2
  134. esphome/components/ens160_base/ens160_base.cpp +0 -2
  135. esphome/components/ens210/ens210.cpp +0 -1
  136. esphome/components/es7210/es7210.cpp +0 -2
  137. esphome/components/es7243e/es7243e.cpp +0 -2
  138. esphome/components/es8156/es8156.cpp +0 -2
  139. esphome/components/es8311/es8311.cpp +0 -2
  140. esphome/components/es8388/es8388.cpp +0 -2
  141. esphome/components/esp32/__init__.py +199 -58
  142. esphome/components/esp32/boards.py +17 -0
  143. esphome/components/esp32/gpio.cpp +0 -1
  144. esphome/components/esp32/gpio.py +1 -2
  145. esphome/components/esp32/gpio_esp32_h2.py +2 -7
  146. esphome/components/esp32/gpio_esp32_p4.py +2 -7
  147. esphome/components/esp32/post_build.py.script +112 -61
  148. esphome/components/esp32_ble/__init__.py +40 -2
  149. esphome/components/esp32_ble/ble.cpp +12 -8
  150. esphome/components/esp32_ble/ble.h +18 -18
  151. esphome/components/esp32_ble/ble_advertising.cpp +5 -5
  152. esphome/components/esp32_ble/ble_advertising.h +7 -5
  153. esphome/components/esp32_ble/ble_event.h +2 -4
  154. esphome/components/esp32_ble/ble_scan_result.h +2 -4
  155. esphome/components/esp32_ble/ble_uuid.cpp +5 -5
  156. esphome/components/esp32_ble/ble_uuid.h +6 -5
  157. esphome/components/esp32_ble_beacon/__init__.py +4 -0
  158. esphome/components/esp32_ble_client/__init__.py +1 -1
  159. esphome/components/esp32_ble_client/ble_characteristic.cpp +4 -4
  160. esphome/components/esp32_ble_client/ble_characteristic.h +6 -4
  161. esphome/components/esp32_ble_client/ble_client_base.cpp +155 -104
  162. esphome/components/esp32_ble_client/ble_client_base.h +17 -6
  163. esphome/components/esp32_ble_client/ble_descriptor.h +6 -4
  164. esphome/components/esp32_ble_client/ble_service.cpp +4 -4
  165. esphome/components/esp32_ble_client/ble_service.h +6 -4
  166. esphome/components/esp32_ble_server/__init__.py +15 -12
  167. esphome/components/esp32_ble_tracker/__init__.py +79 -11
  168. esphome/components/esp32_ble_tracker/automation.h +4 -4
  169. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +264 -261
  170. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +103 -37
  171. esphome/components/esp32_camera/__init__.py +13 -1
  172. esphome/components/esp32_camera/esp32_camera.cpp +7 -2
  173. esphome/components/esp32_camera/esp32_camera.h +1 -0
  174. esphome/components/esp32_dac/esp32_dac.cpp +3 -19
  175. esphome/components/esp32_dac/esp32_dac.h +4 -8
  176. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -6
  177. esphome/components/esp32_rmt_led_strip/light.py +1 -1
  178. esphome/components/esp32_touch/__init__.py +2 -3
  179. esphome/components/esp32_touch/esp32_touch.h +9 -6
  180. esphome/components/esp32_touch/esp32_touch_common.cpp +2 -0
  181. esphome/components/esp32_touch/esp32_touch_v1.cpp +7 -9
  182. esphome/components/esp32_touch/esp32_touch_v2.cpp +10 -6
  183. esphome/components/esp8266/__init__.py +3 -1
  184. esphome/components/esp8266_pwm/esp8266_pwm.cpp +0 -1
  185. esphome/components/esphome/ota/__init__.py +1 -2
  186. esphome/components/esphome/ota/ota_esphome.cpp +150 -77
  187. esphome/components/esphome/ota/ota_esphome.h +8 -1
  188. esphome/components/espnow/__init__.py +309 -0
  189. esphome/components/espnow/automation.h +175 -0
  190. esphome/components/espnow/espnow_component.cpp +468 -0
  191. esphome/components/espnow/espnow_component.h +183 -0
  192. esphome/components/espnow/espnow_err.h +19 -0
  193. esphome/components/espnow/espnow_packet.h +166 -0
  194. esphome/components/ethernet/__init__.py +7 -1
  195. esphome/components/ethernet/esp_eth_phy_jl1101.c +5 -0
  196. esphome/components/ethernet/ethernet_component.cpp +0 -1
  197. esphome/components/ethernet/ethernet_component.h +4 -0
  198. esphome/components/ethernet_info/ethernet_info_text_sensor.h +0 -3
  199. esphome/components/event/__init__.py +0 -1
  200. esphome/components/factory_reset/__init__.py +92 -0
  201. esphome/components/factory_reset/factory_reset.cpp +76 -0
  202. esphome/components/factory_reset/factory_reset.h +43 -0
  203. esphome/components/fan/__init__.py +0 -1
  204. esphome/components/fan/fan_traits.h +16 -0
  205. esphome/components/fastled_base/fastled_light.cpp +0 -1
  206. esphome/components/fastled_spi/light.py +1 -3
  207. esphome/components/fingerprint_grow/fingerprint_grow.cpp +0 -2
  208. esphome/components/fs3000/fs3000.cpp +0 -2
  209. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
  210. esphome/components/ft63x6/ft63x6.cpp +0 -1
  211. esphome/components/gdk101/gdk101.cpp +0 -1
  212. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
  213. esphome/components/gl_r01_i2c/sensor.py +1 -1
  214. esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
  215. esphome/components/gpio/switch/gpio_switch.cpp +0 -2
  216. esphome/components/gpio_expander/cached_gpio.h +24 -15
  217. esphome/components/gps/__init__.py +6 -2
  218. esphome/components/gps/gps.cpp +50 -49
  219. esphome/components/gps/gps.h +4 -8
  220. esphome/components/gps/time/gps_time.cpp +3 -9
  221. esphome/components/gps/time/gps_time.h +4 -7
  222. esphome/components/graph/__init__.py +1 -1
  223. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
  224. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
  225. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
  227. esphome/components/haier/climate.py +5 -10
  228. esphome/components/haier/haier_base.cpp +0 -1
  229. esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
  230. esphome/components/hdc1080/hdc1080.cpp +0 -2
  231. esphome/components/heatpumpir/climate.py +2 -2
  232. esphome/components/hlw8012/hlw8012.cpp +0 -1
  233. esphome/components/hm3301/hm3301.cpp +0 -1
  234. esphome/components/hmc5883l/hmc5883l.cpp +0 -1
  235. esphome/components/homeassistant/__init__.py +1 -0
  236. esphome/components/homeassistant/number/__init__.py +1 -0
  237. esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
  238. esphome/components/homeassistant/switch/__init__.py +1 -0
  239. esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
  240. esphome/components/honeywellabp/honeywellabp.cpp +1 -4
  241. esphome/components/host/__init__.py +2 -0
  242. esphome/components/hte501/hte501.cpp +0 -1
  243. esphome/components/http_request/__init__.py +2 -3
  244. esphome/components/http_request/http_request_idf.cpp +2 -2
  245. esphome/components/htu21d/htu21d.cpp +0 -2
  246. esphome/components/htu31d/htu31d.cpp +0 -2
  247. esphome/components/hx711/hx711.cpp +0 -1
  248. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
  249. esphome/components/hydreon_rgxx/sensor.py +4 -5
  250. esphome/components/i2c/i2c_bus.h +1 -1
  251. esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
  252. esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
  253. esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
  254. esphome/components/i2s_audio/__init__.py +6 -5
  255. esphome/components/i2s_audio/i2s_audio.cpp +0 -2
  256. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
  257. esphome/components/i2s_audio/microphone/__init__.py +4 -6
  258. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +0 -1
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +2 -2
  260. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
  262. esphome/components/ili9xxx/display.py +4 -3
  263. esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
  264. esphome/components/image/__init__.py +123 -92
  265. esphome/components/improv_serial/__init__.py +7 -8
  266. esphome/components/ina219/ina219.cpp +0 -1
  267. esphome/components/ina226/ina226.cpp +0 -2
  268. esphome/components/ina260/ina260.cpp +0 -2
  269. esphome/components/ina2xx_base/__init__.py +2 -5
  270. esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
  271. esphome/components/ina3221/ina3221.cpp +0 -1
  272. esphome/components/internal_temperature/internal_temperature.cpp +0 -2
  273. esphome/components/interval/interval.h +5 -9
  274. esphome/components/json/__init__.py +1 -1
  275. esphome/components/kmeteriso/kmeteriso.cpp +0 -2
  276. esphome/components/lc709203f/lc709203f.cpp +0 -2
  277. esphome/components/lcd_gpio/display.py +1 -3
  278. esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
  279. esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
  280. esphome/components/ld2410/__init__.py +4 -6
  281. esphome/components/ld2410/binary_sensor.py +4 -0
  282. esphome/components/ld2410/ld2410.cpp +56 -100
  283. esphome/components/ld2410/ld2410.h +17 -15
  284. esphome/components/ld2410/sensor.py +24 -10
  285. esphome/components/ld2412/__init__.py +46 -0
  286. esphome/components/ld2412/binary_sensor.py +70 -0
  287. esphome/components/ld2412/button/__init__.py +74 -0
  288. esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
  289. esphome/components/ld2412/button/factory_reset_button.h +18 -0
  290. esphome/components/ld2412/button/query_button.cpp +9 -0
  291. esphome/components/ld2412/button/query_button.h +18 -0
  292. esphome/components/ld2412/button/restart_button.cpp +9 -0
  293. esphome/components/ld2412/button/restart_button.h +18 -0
  294. esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
  295. esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
  296. esphome/components/ld2412/ld2412.cpp +861 -0
  297. esphome/components/ld2412/ld2412.h +141 -0
  298. esphome/components/ld2412/number/__init__.py +126 -0
  299. esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
  300. esphome/components/ld2412/number/gate_threshold_number.h +19 -0
  301. esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
  302. esphome/components/ld2412/number/light_threshold_number.h +18 -0
  303. esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
  304. esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
  305. esphome/components/ld2412/select/__init__.py +82 -0
  306. esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
  307. esphome/components/ld2412/select/baud_rate_select.h +18 -0
  308. esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
  309. esphome/components/ld2412/select/distance_resolution_select.h +18 -0
  310. esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
  311. esphome/components/ld2412/select/light_out_control_select.h +18 -0
  312. esphome/components/ld2412/sensor.py +124 -0
  313. esphome/components/ld2412/switch/__init__.py +45 -0
  314. esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
  315. esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
  316. esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
  317. esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
  318. esphome/components/ld2412/text_sensor.py +34 -0
  319. esphome/components/ld2420/ld2420.cpp +0 -1
  320. esphome/components/ld2450/__init__.py +3 -4
  321. esphome/components/ld2450/binary_sensor.py +3 -0
  322. esphome/components/ld2450/ld2450.cpp +77 -165
  323. esphome/components/ld2450/ld2450.h +26 -54
  324. esphome/components/ld2450/sensor.py +120 -6
  325. esphome/components/ld2450/text_sensor.py +5 -4
  326. esphome/components/ld24xx/__init__.py +1 -0
  327. esphome/components/ld24xx/ld24xx.h +65 -0
  328. esphome/components/ledc/ledc_output.cpp +0 -1
  329. esphome/components/libretiny/__init__.py +2 -0
  330. esphome/components/light/__init__.py +0 -1
  331. esphome/components/light/effects.py +70 -45
  332. esphome/components/light/light_call.cpp +101 -66
  333. esphome/components/light/light_color_values.h +16 -11
  334. esphome/components/light/light_json_schema.cpp +46 -44
  335. esphome/components/light/light_state.cpp +8 -11
  336. esphome/components/light/light_traits.h +17 -0
  337. esphome/components/lightwaverf/lightwaverf.cpp +0 -2
  338. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
  339. esphome/components/lock/__init__.py +0 -1
  340. esphome/components/logger/__init__.py +31 -9
  341. esphome/components/logger/logger.cpp +12 -7
  342. esphome/components/logger/logger.h +25 -14
  343. esphome/components/logger/logger_esp32.cpp +2 -7
  344. esphome/components/logger/logger_esp8266.cpp +2 -4
  345. esphome/components/logger/logger_host.cpp +2 -4
  346. esphome/components/logger/logger_libretiny.cpp +2 -4
  347. esphome/components/logger/logger_rp2040.cpp +2 -4
  348. esphome/components/logger/logger_zephyr.cpp +86 -0
  349. esphome/components/logger/select/logger_level_select.cpp +2 -4
  350. esphome/components/logger/select/logger_level_select.h +2 -4
  351. esphome/components/logger/task_log_buffer.cpp +2 -4
  352. esphome/components/logger/task_log_buffer.h +2 -4
  353. esphome/components/lps22/sensor.py +5 -5
  354. esphome/components/ltr390/ltr390.cpp +0 -2
  355. esphome/components/ltr501/ltr501.cpp +0 -1
  356. esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
  357. esphome/components/lvgl/__init__.py +14 -13
  358. esphome/components/lvgl/automation.py +2 -4
  359. esphome/components/lvgl/defines.py +0 -2
  360. esphome/components/lvgl/helpers.py +1 -1
  361. esphome/components/lvgl/lv_validation.py +7 -4
  362. esphome/components/lvgl/lvgl_esphome.cpp +2 -3
  363. esphome/components/lvgl/styles.py +2 -2
  364. esphome/components/lvgl/types.py +1 -1
  365. esphome/components/lvgl/widgets/__init__.py +2 -2
  366. esphome/components/lvgl/widgets/arc.py +14 -11
  367. esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
  368. esphome/components/lvgl/widgets/qrcode.py +7 -7
  369. esphome/components/lvgl/widgets/spinner.py +6 -6
  370. esphome/components/lvgl/widgets/switch.py +2 -2
  371. esphome/components/lvgl/widgets/tabview.py +3 -3
  372. esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
  373. esphome/components/matrix_keypad/__init__.py +4 -3
  374. esphome/components/max17043/max17043.cpp +0 -2
  375. esphome/components/max31855/max31855.cpp +1 -4
  376. esphome/components/max31856/max31856.cpp +0 -4
  377. esphome/components/max31865/max31865.cpp +0 -1
  378. esphome/components/max44009/max44009.cpp +0 -1
  379. esphome/components/max6675/max6675.cpp +1 -4
  380. esphome/components/max6956/max6956.cpp +0 -1
  381. esphome/components/max7219/max7219.cpp +0 -1
  382. esphome/components/max7219digit/display.py +1 -1
  383. esphome/components/max7219digit/max7219digit.cpp +0 -1
  384. esphome/components/max9611/max9611.cpp +0 -1
  385. esphome/components/mcp23008/__init__.py +1 -1
  386. esphome/components/mcp23008/mcp23008.cpp +0 -1
  387. esphome/components/mcp23016/mcp23016.cpp +0 -1
  388. esphome/components/mcp23017/__init__.py +1 -1
  389. esphome/components/mcp23017/mcp23017.cpp +0 -1
  390. esphome/components/mcp23s08/__init__.py +1 -1
  391. esphome/components/mcp23s08/mcp23s08.cpp +0 -1
  392. esphome/components/mcp23s17/__init__.py +1 -1
  393. esphome/components/mcp23s17/mcp23s17.cpp +0 -1
  394. esphome/components/mcp23x08_base/__init__.py +2 -0
  395. esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
  396. esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
  397. esphome/components/mcp23x17_base/__init__.py +2 -0
  398. esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
  399. esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
  400. esphome/components/mcp23xxx_base/__init__.py +11 -5
  401. esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
  402. esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
  403. esphome/components/mcp3008/mcp3008.cpp +1 -4
  404. esphome/components/mcp3204/mcp3204.cpp +1 -4
  405. esphome/components/mcp4461/mcp4461.cpp +0 -1
  406. esphome/components/mcp4725/mcp4725.cpp +0 -1
  407. esphome/components/mcp4728/mcp4728.cpp +0 -1
  408. esphome/components/mcp9600/mcp9600.cpp +0 -2
  409. esphome/components/mcp9808/mcp9808.cpp +0 -2
  410. esphome/components/mdns/__init__.py +3 -0
  411. esphome/components/mdns/mdns_component.cpp +2 -0
  412. esphome/components/mdns/mdns_component.h +4 -0
  413. esphome/components/media_player/__init__.py +40 -0
  414. esphome/components/media_player/automation.h +16 -0
  415. esphome/components/media_player/media_player.cpp +13 -0
  416. esphome/components/media_player/media_player.h +50 -3
  417. esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
  418. esphome/components/mics_4514/mics_4514.cpp +1 -6
  419. esphome/components/midea/ir_transmitter.h +4 -4
  420. esphome/components/mipi/__init__.py +416 -0
  421. esphome/components/mipi_dsi/__init__.py +5 -0
  422. esphome/components/mipi_dsi/display.py +233 -0
  423. esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
  424. esphome/components/mipi_dsi/mipi_dsi.h +123 -0
  425. esphome/components/mipi_dsi/models/__init__.py +0 -0
  426. esphome/components/mipi_dsi/models/guition.py +38 -0
  427. esphome/components/mipi_dsi/models/m5stack.py +57 -0
  428. esphome/components/mipi_dsi/models/waveshare.py +105 -0
  429. esphome/components/mipi_rgb/models/lilygo.py +0 -0
  430. esphome/components/mipi_spi/__init__.py +0 -9
  431. esphome/components/mipi_spi/display.py +220 -256
  432. esphome/components/mipi_spi/mipi_spi.cpp +1 -485
  433. esphome/components/mipi_spi/mipi_spi.h +556 -108
  434. esphome/components/mipi_spi/models/__init__.py +0 -65
  435. esphome/components/mipi_spi/models/adafruit.py +30 -0
  436. esphome/components/mipi_spi/models/amoled.py +41 -5
  437. esphome/components/mipi_spi/models/ili.py +5 -5
  438. esphome/components/mipi_spi/models/jc.py +1 -3
  439. esphome/components/mipi_spi/models/lilygo.py +1 -1
  440. esphome/components/mipi_spi/models/waveshare.py +16 -1
  441. esphome/components/mixer/speaker/__init__.py +4 -5
  442. esphome/components/mlx90393/sensor.py +7 -5
  443. esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
  444. esphome/components/mlx90614/mlx90614.cpp +0 -1
  445. esphome/components/mmc5603/mmc5603.cpp +0 -1
  446. esphome/components/mmc5983/mmc5983.cpp +0 -2
  447. esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
  448. esphome/components/mpr121/__init__.py +7 -6
  449. esphome/components/mpr121/mpr121.cpp +0 -1
  450. esphome/components/mpu6050/mpu6050.cpp +0 -1
  451. esphome/components/mpu6886/mpu6886.cpp +0 -1
  452. esphome/components/mqtt/__init__.py +1 -2
  453. esphome/components/mqtt/mqtt_button.cpp +1 -1
  454. esphome/components/mqtt/mqtt_client.cpp +0 -1
  455. esphome/components/mqtt/mqtt_component.cpp +8 -14
  456. esphome/components/mqtt/mqtt_component.h +0 -7
  457. esphome/components/mqtt/mqtt_sensor.cpp +0 -1
  458. esphome/components/mqtt/mqtt_sensor.h +0 -1
  459. esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
  460. esphome/components/mqtt/mqtt_text_sensor.h +0 -1
  461. esphome/components/ms5611/ms5611.cpp +0 -1
  462. esphome/components/ms8607/ms8607.cpp +0 -1
  463. esphome/components/msa3xx/msa3xx.cpp +0 -2
  464. esphome/components/my9231/my9231.cpp +0 -2
  465. esphome/components/nau7802/nau7802.cpp +0 -1
  466. esphome/components/neopixelbus/light.py +3 -0
  467. esphome/components/network/util.cpp +29 -0
  468. esphome/components/nextion/nextion.cpp +0 -1
  469. esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
  470. esphome/components/npi19/npi19.cpp +0 -2
  471. esphome/components/nrf52/__init__.py +223 -0
  472. esphome/components/nrf52/boards.py +34 -0
  473. esphome/components/nrf52/const.py +18 -0
  474. esphome/components/nrf52/gpio.py +79 -0
  475. esphome/components/number/__init__.py +2 -1
  476. esphome/components/one_wire/__init__.py +1 -2
  477. esphome/components/one_wire/one_wire.cpp +0 -2
  478. esphome/components/one_wire/one_wire.h +0 -2
  479. esphome/components/opentherm/hub.cpp +0 -1
  480. esphome/components/opentherm/number/__init__.py +2 -2
  481. esphome/components/openthread/__init__.py +2 -3
  482. esphome/components/openthread/openthread.cpp +30 -13
  483. esphome/components/openthread/openthread.h +3 -0
  484. esphome/components/openthread/openthread_esp.cpp +3 -1
  485. esphome/components/opt3001/sensor.py +2 -6
  486. esphome/components/output/__init__.py +38 -0
  487. esphome/components/output/automation.h +24 -0
  488. esphome/components/output/switch/output_switch.cpp +0 -2
  489. esphome/components/packages/__init__.py +1 -2
  490. esphome/components/packet_transport/__init__.py +4 -3
  491. esphome/components/pca6416a/pca6416a.cpp +0 -1
  492. esphome/components/pca9554/pca9554.cpp +0 -1
  493. esphome/components/pca9685/pca9685_output.cpp +0 -2
  494. esphome/components/pcf85063/pcf85063.cpp +0 -1
  495. esphome/components/pcf8563/pcf8563.cpp +0 -1
  496. esphome/components/pcf8574/pcf8574.cpp +0 -1
  497. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
  498. esphome/components/pipsolar/sensor/__init__.py +1 -1
  499. esphome/components/pm2005/pm2005.cpp +0 -1
  500. esphome/components/pmsa003i/pmsa003i.cpp +0 -2
  501. esphome/components/pmwcs3/sensor.py +1 -2
  502. esphome/components/pn532/pn532.cpp +0 -2
  503. esphome/components/pn532_spi/pn532_spi.cpp +0 -2
  504. esphome/components/power_supply/power_supply.cpp +7 -10
  505. esphome/components/power_supply/power_supply.h +1 -1
  506. esphome/components/psram/__init__.py +6 -1
  507. esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
  508. esphome/components/pulse_counter/sensor.py +9 -6
  509. esphome/components/pylontech/pylontech.cpp +0 -1
  510. esphome/components/qmc5883l/qmc5883l.cpp +0 -1
  511. esphome/components/qmp6988/qmp6988.cpp +0 -2
  512. esphome/components/qspi_dbi/display.py +2 -3
  513. esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
  514. esphome/components/qwiic_pir/binary_sensor.py +2 -3
  515. esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
  516. esphome/components/rc522/rc522.cpp +9 -31
  517. esphome/components/rc522_spi/rc522_spi.cpp +0 -1
  518. esphome/components/remote_base/__init__.py +5 -6
  519. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
  520. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
  521. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
  522. esphome/components/remote_transmitter/__init__.py +26 -0
  523. esphome/components/remote_transmitter/automation.h +18 -0
  524. esphome/components/remote_transmitter/remote_transmitter.h +2 -1
  525. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
  526. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
  527. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
  528. esphome/components/resampler/speaker/__init__.py +4 -5
  529. esphome/components/rf_bridge/__init__.py +4 -8
  530. esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
  531. esphome/components/rp2040/__init__.py +3 -1
  532. esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
  533. esphome/components/rp2040_pio_led_strip/light.py +1 -2
  534. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
  535. esphome/components/rpi_dpi_rgb/display.py +13 -15
  536. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
  537. esphome/components/runtime_stats/__init__.py +34 -0
  538. esphome/components/runtime_stats/runtime_stats.cpp +102 -0
  539. esphome/components/runtime_stats/runtime_stats.h +132 -0
  540. esphome/components/scd30/scd30.cpp +0 -2
  541. esphome/components/scd30/sensor.py +1 -2
  542. esphome/components/scd4x/scd4x.cpp +0 -1
  543. esphome/components/scd4x/sensor.py +1 -3
  544. esphome/components/sdl/display.py +3 -1
  545. esphome/components/sdl/sdl_esphome.cpp +0 -2
  546. esphome/components/sdp3x/sdp3x.cpp +0 -2
  547. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
  548. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
  549. esphome/components/select/__init__.py +2 -3
  550. esphome/components/select/select_traits.cpp +1 -1
  551. esphome/components/select/select_traits.h +1 -1
  552. esphome/components/sen0321/sen0321.cpp +0 -1
  553. esphome/components/sen5x/sen5x.cpp +0 -2
  554. esphome/components/sensor/__init__.py +36 -4
  555. esphome/components/sensor/filter.cpp +49 -10
  556. esphome/components/sensor/filter.h +22 -7
  557. esphome/components/sensor/sensor.cpp +0 -1
  558. esphome/components/sensor/sensor.h +0 -9
  559. esphome/components/sfa30/sfa30.cpp +0 -4
  560. esphome/components/sgp30/sgp30.cpp +0 -2
  561. esphome/components/sgp4x/sensor.py +1 -1
  562. esphome/components/sgp4x/sgp4x.cpp +0 -2
  563. esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
  564. esphome/components/sht3xd/sht3xd.cpp +0 -2
  565. esphome/components/sht4x/sht4x.cpp +0 -2
  566. esphome/components/shtcx/shtcx.cpp +0 -1
  567. esphome/components/sim800l/__init__.py +2 -4
  568. esphome/components/sm16716/sm16716.cpp +0 -1
  569. esphome/components/sm2135/sm2135.cpp +0 -1
  570. esphome/components/sm2235/sm2235.cpp +0 -1
  571. esphome/components/sm2335/sm2335.cpp +0 -1
  572. esphome/components/sn74hc165/sn74hc165.cpp +0 -1
  573. esphome/components/sn74hc595/sn74hc595.cpp +0 -1
  574. esphome/components/sntp/sntp_component.cpp +0 -1
  575. esphome/components/sound_level/sensor.py +1 -1
  576. esphome/components/speaker/media_player/__init__.py +21 -33
  577. esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
  578. esphome/components/spi/__init__.py +29 -13
  579. esphome/components/spi/spi.cpp +0 -2
  580. esphome/components/spi_device/spi_device.cpp +1 -4
  581. esphome/components/sprinkler/__init__.py +4 -4
  582. esphome/components/sps30/sps30.cpp +0 -1
  583. esphome/components/ssd1306_base/__init__.py +11 -11
  584. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  585. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
  586. esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
  587. esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
  588. esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
  589. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
  590. esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
  591. esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
  592. esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
  593. esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
  594. esphome/components/st7567_spi/st7567_spi.cpp +0 -1
  595. esphome/components/st7701s/display.py +10 -14
  596. esphome/components/st7701s/st7701s.cpp +0 -3
  597. esphome/components/st7735/st7735.cpp +0 -1
  598. esphome/components/st7789v/st7789v.cpp +0 -1
  599. esphome/components/st7920/st7920.cpp +0 -1
  600. esphome/components/status_led/light/status_led_light.cpp +0 -2
  601. esphome/components/status_led/status_led.cpp +0 -1
  602. esphome/components/stepper/__init__.py +2 -4
  603. esphome/components/sts3x/sts3x.cpp +0 -1
  604. esphome/components/substitutions/__init__.py +10 -16
  605. esphome/components/substitutions/jinja.py +24 -1
  606. esphome/components/sun/__init__.py +2 -3
  607. esphome/components/switch/__init__.py +31 -1
  608. esphome/components/switch/automation.h +24 -0
  609. esphome/components/switch/switch.cpp +8 -0
  610. esphome/components/switch/switch.h +8 -0
  611. esphome/components/sx126x/sx126x.cpp +0 -2
  612. esphome/components/sx127x/sx127x.cpp +0 -2
  613. esphome/components/sx1509/__init__.py +7 -5
  614. esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
  615. esphome/components/sx1509/sx1509.cpp +0 -2
  616. esphome/components/syslog/esphome_syslog.cpp +1 -1
  617. esphome/components/tc74/tc74.cpp +0 -1
  618. esphome/components/tca9548a/tca9548a.cpp +0 -1
  619. esphome/components/tca9555/tca9555.cpp +0 -1
  620. esphome/components/tcs34725/tcs34725.cpp +0 -1
  621. esphome/components/tee501/tee501.cpp +0 -1
  622. esphome/components/tem3200/tem3200.cpp +0 -2
  623. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
  624. esphome/components/template/cover/template_cover.cpp +0 -1
  625. esphome/components/template/select/template_select.cpp +0 -1
  626. esphome/components/template/text/template_text.cpp +0 -2
  627. esphome/components/template/valve/template_valve.cpp +0 -1
  628. esphome/components/text/__init__.py +0 -1
  629. esphome/components/text/text_traits.h +2 -0
  630. esphome/components/text_sensor/__init__.py +2 -1
  631. esphome/components/text_sensor/text_sensor.cpp +0 -2
  632. esphome/components/text_sensor/text_sensor.h +0 -8
  633. esphome/components/thermostat/climate.py +4 -4
  634. esphome/components/time/__init__.py +7 -4
  635. esphome/components/time/real_time_clock.cpp +16 -3
  636. esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
  637. esphome/components/tlc5947/tlc5947.cpp +0 -2
  638. esphome/components/tlc5971/tlc5971.cpp +0 -2
  639. esphome/components/tm1621/tm1621.cpp +0 -2
  640. esphome/components/tm1637/tm1637.cpp +0 -2
  641. esphome/components/tm1638/tm1638.cpp +0 -2
  642. esphome/components/tm1651/__init__.py +45 -48
  643. esphome/components/tm1651/tm1651.cpp +213 -47
  644. esphome/components/tm1651/tm1651.h +37 -32
  645. esphome/components/tmp117/tmp117.cpp +0 -2
  646. esphome/components/tsl2561/tsl2561.cpp +0 -1
  647. esphome/components/tsl2591/tsl2591.cpp +0 -1
  648. esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
  649. esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
  650. esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
  651. esphome/components/tuya/climate/__init__.py +9 -10
  652. esphome/components/tuya/number/__init__.py +8 -6
  653. esphome/components/tx20/tx20.cpp +0 -1
  654. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
  655. esphome/components/uart/uart_component_esp8266.cpp +0 -1
  656. esphome/components/uart/uart_component_esp_idf.cpp +0 -2
  657. esphome/components/uart/uart_component_libretiny.cpp +0 -2
  658. esphome/components/uart/uart_component_rp2040.cpp +0 -2
  659. esphome/components/udp/__init__.py +1 -1
  660. esphome/components/ufire_ec/sensor.py +1 -2
  661. esphome/components/ufire_ec/ufire_ec.cpp +0 -2
  662. esphome/components/ufire_ise/sensor.py +1 -2
  663. esphome/components/ufire_ise/ufire_ise.cpp +0 -2
  664. esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
  665. esphome/components/update/__init__.py +0 -1
  666. esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
  667. esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
  668. esphome/components/usb_host/usb_host_client.cpp +0 -1
  669. esphome/components/usb_host/usb_host_component.cpp +0 -1
  670. esphome/components/valve/__init__.py +0 -1
  671. esphome/components/veml3235/veml3235.cpp +0 -3
  672. esphome/components/veml7700/veml7700.cpp +0 -2
  673. esphome/components/version/version_text_sensor.cpp +0 -1
  674. esphome/components/version/version_text_sensor.h +0 -1
  675. esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
  676. esphome/components/voice_assistant/voice_assistant.cpp +9 -8
  677. esphome/components/web_server/__init__.py +13 -0
  678. esphome/components/web_server/web_server.cpp +187 -352
  679. esphome/components/web_server/web_server.h +61 -1
  680. esphome/components/web_server_base/__init__.py +1 -1
  681. esphome/components/web_server_base/web_server_base.cpp +2 -0
  682. esphome/components/web_server_base/web_server_base.h +6 -0
  683. esphome/components/web_server_idf/web_server_idf.cpp +10 -8
  684. esphome/components/web_server_idf/web_server_idf.h +2 -0
  685. esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
  686. esphome/components/weikai_spi/weikai_spi.cpp +1 -1
  687. esphome/components/wifi/__init__.py +8 -43
  688. esphome/components/wifi/wifi_component.cpp +100 -36
  689. esphome/components/wifi/wifi_component.h +5 -1
  690. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
  691. esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
  692. esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
  693. esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
  694. esphome/components/wireguard/wireguard.cpp +0 -2
  695. esphome/components/x9c/x9c.cpp +0 -2
  696. esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
  697. esphome/components/xl9535/xl9535.cpp +0 -2
  698. esphome/components/zephyr/__init__.py +252 -0
  699. esphome/components/zephyr/const.py +16 -0
  700. esphome/components/zephyr/core.cpp +90 -0
  701. esphome/components/zephyr/gpio.cpp +120 -0
  702. esphome/components/zephyr/gpio.h +38 -0
  703. esphome/components/zephyr/pre_build.py.script +4 -0
  704. esphome/components/zephyr/preferences.cpp +156 -0
  705. esphome/components/zephyr/preferences.h +13 -0
  706. esphome/config.py +38 -16
  707. esphome/config_helpers.py +1 -2
  708. esphome/config_validation.py +12 -16
  709. esphome/const.py +26 -1
  710. esphome/core/__init__.py +88 -51
  711. esphome/core/application.cpp +75 -21
  712. esphome/core/application.h +106 -171
  713. esphome/core/color.h +10 -0
  714. esphome/core/component.cpp +41 -25
  715. esphome/core/component.h +9 -6
  716. esphome/core/component_iterator.cpp +61 -261
  717. esphome/core/component_iterator.h +15 -0
  718. esphome/core/config.py +26 -11
  719. esphome/core/defines.h +40 -2
  720. esphome/core/entity_base.h +18 -0
  721. esphome/core/entity_helpers.py +45 -10
  722. esphome/core/helpers.cpp +8 -15
  723. esphome/core/helpers.h +60 -6
  724. esphome/core/lock_free_queue.h +1 -1
  725. esphome/core/scheduler.cpp +277 -74
  726. esphome/core/scheduler.h +89 -27
  727. esphome/cpp_generator.py +2 -6
  728. esphome/cpp_helpers.py +1 -1
  729. esphome/dashboard/dashboard.py +2 -3
  730. esphome/dashboard/dns.py +2 -8
  731. esphome/dashboard/web_server.py +34 -19
  732. esphome/espota2.py +1 -4
  733. esphome/git.py +3 -1
  734. esphome/helpers.py +23 -4
  735. esphome/log.py +3 -1
  736. esphome/mqtt.py +3 -5
  737. esphome/platformio_api.py +7 -4
  738. esphome/types.py +12 -0
  739. esphome/util.py +20 -8
  740. esphome/voluptuous_schema.py +4 -3
  741. esphome/vscode.py +1 -2
  742. esphome/wizard.py +1 -4
  743. esphome/writer.py +5 -107
  744. esphome/yaml_util.py +7 -5
  745. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/METADATA +13 -14
  746. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/RECORD +751 -671
  747. esphome/components/mipi_spi/models/commands.py +0 -82
  748. /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
  749. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/WHEEL +0 -0
  750. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/entry_points.txt +0 -0
  751. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/licenses/LICENSE +0 -0
  752. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,861 @@
1
+ #include "ld2412.h"
2
+
3
+ #ifdef USE_NUMBER
4
+ #include "esphome/components/number/number.h"
5
+ #endif
6
+ #ifdef USE_SENSOR
7
+ #include "esphome/components/sensor/sensor.h"
8
+ #endif
9
+
10
+ #include "esphome/core/application.h"
11
+ #include "esphome/core/helpers.h"
12
+
13
+ namespace esphome {
14
+ namespace ld2412 {
15
+
16
+ static const char *const TAG = "ld2412";
17
+ static const char *const UNKNOWN_MAC = "unknown";
18
+ static const char *const VERSION_FMT = "%u.%02X.%02X%02X%02X%02X";
19
+
20
+ enum BaudRate : uint8_t {
21
+ BAUD_RATE_9600 = 1,
22
+ BAUD_RATE_19200 = 2,
23
+ BAUD_RATE_38400 = 3,
24
+ BAUD_RATE_57600 = 4,
25
+ BAUD_RATE_115200 = 5,
26
+ BAUD_RATE_230400 = 6,
27
+ BAUD_RATE_256000 = 7,
28
+ BAUD_RATE_460800 = 8,
29
+ };
30
+
31
+ enum DistanceResolution : uint8_t {
32
+ DISTANCE_RESOLUTION_0_2 = 0x03,
33
+ DISTANCE_RESOLUTION_0_5 = 0x01,
34
+ DISTANCE_RESOLUTION_0_75 = 0x00,
35
+ };
36
+
37
+ enum LightFunction : uint8_t {
38
+ LIGHT_FUNCTION_OFF = 0x00,
39
+ LIGHT_FUNCTION_BELOW = 0x01,
40
+ LIGHT_FUNCTION_ABOVE = 0x02,
41
+ };
42
+
43
+ enum OutPinLevel : uint8_t {
44
+ OUT_PIN_LEVEL_LOW = 0x01,
45
+ OUT_PIN_LEVEL_HIGH = 0x00,
46
+ };
47
+
48
+ /*
49
+ Data Type: 6th byte
50
+ Target states: 9th byte
51
+ Moving target distance: 10~11th bytes
52
+ Moving target energy: 12th byte
53
+ Still target distance: 13~14th bytes
54
+ Still target energy: 15th byte
55
+ Detect distance: 16~17th bytes
56
+ */
57
+ enum PeriodicData : uint8_t {
58
+ DATA_TYPES = 6,
59
+ TARGET_STATES = 8,
60
+ MOVING_TARGET_LOW = 9,
61
+ MOVING_TARGET_HIGH = 10,
62
+ MOVING_ENERGY = 11,
63
+ STILL_TARGET_LOW = 12,
64
+ STILL_TARGET_HIGH = 13,
65
+ STILL_ENERGY = 14,
66
+ MOVING_SENSOR_START = 17,
67
+ STILL_SENSOR_START = 31,
68
+ LIGHT_SENSOR = 45,
69
+ OUT_PIN_SENSOR = 38,
70
+ };
71
+
72
+ enum PeriodicDataValue : uint8_t {
73
+ HEADER = 0XAA,
74
+ FOOTER = 0x55,
75
+ CHECK = 0x00,
76
+ };
77
+
78
+ enum AckData : uint8_t {
79
+ COMMAND = 6,
80
+ COMMAND_STATUS = 7,
81
+ };
82
+
83
+ // Memory-efficient lookup tables
84
+ struct StringToUint8 {
85
+ const char *str;
86
+ const uint8_t value;
87
+ };
88
+
89
+ struct Uint8ToString {
90
+ const uint8_t value;
91
+ const char *str;
92
+ };
93
+
94
+ constexpr StringToUint8 BAUD_RATES_BY_STR[] = {
95
+ {"9600", BAUD_RATE_9600}, {"19200", BAUD_RATE_19200}, {"38400", BAUD_RATE_38400},
96
+ {"57600", BAUD_RATE_57600}, {"115200", BAUD_RATE_115200}, {"230400", BAUD_RATE_230400},
97
+ {"256000", BAUD_RATE_256000}, {"460800", BAUD_RATE_460800},
98
+ };
99
+
100
+ constexpr StringToUint8 DISTANCE_RESOLUTIONS_BY_STR[] = {
101
+ {"0.2m", DISTANCE_RESOLUTION_0_2},
102
+ {"0.5m", DISTANCE_RESOLUTION_0_5},
103
+ {"0.75m", DISTANCE_RESOLUTION_0_75},
104
+ };
105
+
106
+ constexpr Uint8ToString DISTANCE_RESOLUTIONS_BY_UINT[] = {
107
+ {DISTANCE_RESOLUTION_0_2, "0.2m"},
108
+ {DISTANCE_RESOLUTION_0_5, "0.5m"},
109
+ {DISTANCE_RESOLUTION_0_75, "0.75m"},
110
+ };
111
+
112
+ constexpr StringToUint8 LIGHT_FUNCTIONS_BY_STR[] = {
113
+ {"off", LIGHT_FUNCTION_OFF},
114
+ {"below", LIGHT_FUNCTION_BELOW},
115
+ {"above", LIGHT_FUNCTION_ABOVE},
116
+ };
117
+
118
+ constexpr Uint8ToString LIGHT_FUNCTIONS_BY_UINT[] = {
119
+ {LIGHT_FUNCTION_OFF, "off"},
120
+ {LIGHT_FUNCTION_BELOW, "below"},
121
+ {LIGHT_FUNCTION_ABOVE, "above"},
122
+ };
123
+
124
+ constexpr StringToUint8 OUT_PIN_LEVELS_BY_STR[] = {
125
+ {"low", OUT_PIN_LEVEL_LOW},
126
+ {"high", OUT_PIN_LEVEL_HIGH},
127
+ };
128
+
129
+ constexpr Uint8ToString OUT_PIN_LEVELS_BY_UINT[] = {
130
+ {OUT_PIN_LEVEL_LOW, "low"},
131
+ {OUT_PIN_LEVEL_HIGH, "high"},
132
+ };
133
+
134
+ // Helper functions for lookups
135
+ template<size_t N> uint8_t find_uint8(const StringToUint8 (&arr)[N], const std::string &str) {
136
+ for (const auto &entry : arr) {
137
+ if (str == entry.str) {
138
+ return entry.value;
139
+ }
140
+ }
141
+ return 0xFF; // Not found
142
+ }
143
+
144
+ template<size_t N> const char *find_str(const Uint8ToString (&arr)[N], uint8_t value) {
145
+ for (const auto &entry : arr) {
146
+ if (value == entry.value) {
147
+ return entry.str;
148
+ }
149
+ }
150
+ return ""; // Not found
151
+ }
152
+
153
+ static constexpr uint8_t DEFAULT_PRESENCE_TIMEOUT = 5; // Default used when number component is not defined
154
+ // Commands
155
+ static constexpr uint8_t CMD_ENABLE_CONF = 0xFF;
156
+ static constexpr uint8_t CMD_DISABLE_CONF = 0xFE;
157
+ static constexpr uint8_t CMD_ENABLE_ENG = 0x62;
158
+ static constexpr uint8_t CMD_DISABLE_ENG = 0x63;
159
+ static constexpr uint8_t CMD_QUERY_BASIC_CONF = 0x12;
160
+ static constexpr uint8_t CMD_BASIC_CONF = 0x02;
161
+ static constexpr uint8_t CMD_QUERY_VERSION = 0xA0;
162
+ static constexpr uint8_t CMD_QUERY_DISTANCE_RESOLUTION = 0x11;
163
+ static constexpr uint8_t CMD_SET_DISTANCE_RESOLUTION = 0x01;
164
+ static constexpr uint8_t CMD_QUERY_LIGHT_CONTROL = 0x1C;
165
+ static constexpr uint8_t CMD_SET_LIGHT_CONTROL = 0x0C;
166
+ static constexpr uint8_t CMD_SET_BAUD_RATE = 0xA1;
167
+ static constexpr uint8_t CMD_QUERY_MAC_ADDRESS = 0xA5;
168
+ static constexpr uint8_t CMD_FACTORY_RESET = 0xA2;
169
+ static constexpr uint8_t CMD_RESTART = 0xA3;
170
+ static constexpr uint8_t CMD_BLUETOOTH = 0xA4;
171
+ static constexpr uint8_t CMD_DYNAMIC_BACKGROUND_CORRECTION = 0x0B;
172
+ static constexpr uint8_t CMD_QUERY_DYNAMIC_BACKGROUND_CORRECTION = 0x1B;
173
+ static constexpr uint8_t CMD_MOTION_GATE_SENS = 0x03;
174
+ static constexpr uint8_t CMD_QUERY_MOTION_GATE_SENS = 0x13;
175
+ static constexpr uint8_t CMD_STATIC_GATE_SENS = 0x04;
176
+ static constexpr uint8_t CMD_QUERY_STATIC_GATE_SENS = 0x14;
177
+ static constexpr uint8_t CMD_NONE = 0x00;
178
+ // Commands values
179
+ static constexpr uint8_t CMD_MAX_MOVE_VALUE = 0x00;
180
+ static constexpr uint8_t CMD_MAX_STILL_VALUE = 0x01;
181
+ static constexpr uint8_t CMD_DURATION_VALUE = 0x02;
182
+ // Bitmasks for target states
183
+ static constexpr uint8_t MOVE_BITMASK = 0x01;
184
+ static constexpr uint8_t STILL_BITMASK = 0x02;
185
+ // Header & Footer size
186
+ static constexpr uint8_t HEADER_FOOTER_SIZE = 4;
187
+ // Command Header & Footer
188
+ static constexpr uint8_t CMD_FRAME_HEADER[HEADER_FOOTER_SIZE] = {0xFD, 0xFC, 0xFB, 0xFA};
189
+ static constexpr uint8_t CMD_FRAME_FOOTER[HEADER_FOOTER_SIZE] = {0x04, 0x03, 0x02, 0x01};
190
+ // Data Header & Footer
191
+ static constexpr uint8_t DATA_FRAME_HEADER[HEADER_FOOTER_SIZE] = {0xF4, 0xF3, 0xF2, 0xF1};
192
+ static constexpr uint8_t DATA_FRAME_FOOTER[HEADER_FOOTER_SIZE] = {0xF8, 0xF7, 0xF6, 0xF5};
193
+ // MAC address the module uses when Bluetooth is disabled
194
+ static constexpr uint8_t NO_MAC[] = {0x08, 0x05, 0x04, 0x03, 0x02, 0x01};
195
+
196
+ static inline int two_byte_to_int(char firstbyte, char secondbyte) { return (int16_t) (secondbyte << 8) + firstbyte; }
197
+
198
+ static inline bool validate_header_footer(const uint8_t *header_footer, const uint8_t *buffer) {
199
+ return std::memcmp(header_footer, buffer, HEADER_FOOTER_SIZE) == 0;
200
+ }
201
+
202
+ void LD2412Component::dump_config() {
203
+ std::string mac_str =
204
+ mac_address_is_valid(this->mac_address_) ? format_mac_address_pretty(this->mac_address_) : UNKNOWN_MAC;
205
+ std::string version = str_sprintf(VERSION_FMT, this->version_[1], this->version_[0], this->version_[5],
206
+ this->version_[4], this->version_[3], this->version_[2]);
207
+ ESP_LOGCONFIG(TAG,
208
+ "LD2412:\n"
209
+ " Firmware version: %s\n"
210
+ " MAC address: %s",
211
+ version.c_str(), mac_str.c_str());
212
+ #ifdef USE_BINARY_SENSOR
213
+ ESP_LOGCONFIG(TAG, "Binary Sensors:");
214
+ LOG_BINARY_SENSOR(" ", "DynamicBackgroundCorrectionStatus",
215
+ this->dynamic_background_correction_status_binary_sensor_);
216
+ LOG_BINARY_SENSOR(" ", "MovingTarget", this->moving_target_binary_sensor_);
217
+ LOG_BINARY_SENSOR(" ", "StillTarget", this->still_target_binary_sensor_);
218
+ LOG_BINARY_SENSOR(" ", "Target", this->target_binary_sensor_);
219
+ #endif
220
+ #ifdef USE_SENSOR
221
+ ESP_LOGCONFIG(TAG, "Sensors:");
222
+ LOG_SENSOR_WITH_DEDUP_SAFE(" ", "Light", this->light_sensor_);
223
+ LOG_SENSOR_WITH_DEDUP_SAFE(" ", "DetectionDistance", this->detection_distance_sensor_);
224
+ LOG_SENSOR_WITH_DEDUP_SAFE(" ", "MovingTargetDistance", this->moving_target_distance_sensor_);
225
+ LOG_SENSOR_WITH_DEDUP_SAFE(" ", "MovingTargetEnergy", this->moving_target_energy_sensor_);
226
+ LOG_SENSOR_WITH_DEDUP_SAFE(" ", "StillTargetDistance", this->still_target_distance_sensor_);
227
+ LOG_SENSOR_WITH_DEDUP_SAFE(" ", "StillTargetEnergy", this->still_target_energy_sensor_);
228
+ for (auto &s : this->gate_still_sensors_) {
229
+ LOG_SENSOR_WITH_DEDUP_SAFE(" ", "GateStill", s);
230
+ }
231
+ for (auto &s : this->gate_move_sensors_) {
232
+ LOG_SENSOR_WITH_DEDUP_SAFE(" ", "GateMove", s);
233
+ }
234
+ #endif
235
+ #ifdef USE_TEXT_SENSOR
236
+ ESP_LOGCONFIG(TAG, "Text Sensors:");
237
+ LOG_TEXT_SENSOR(" ", "MAC address", this->mac_text_sensor_);
238
+ LOG_TEXT_SENSOR(" ", "Version", this->version_text_sensor_);
239
+ #endif
240
+ #ifdef USE_NUMBER
241
+ ESP_LOGCONFIG(TAG, "Numbers:");
242
+ LOG_NUMBER(" ", "LightThreshold", this->light_threshold_number_);
243
+ LOG_NUMBER(" ", "MaxDistanceGate", this->max_distance_gate_number_);
244
+ LOG_NUMBER(" ", "MinDistanceGate", this->min_distance_gate_number_);
245
+ LOG_NUMBER(" ", "Timeout", this->timeout_number_);
246
+ for (number::Number *n : this->gate_move_threshold_numbers_) {
247
+ LOG_NUMBER(" ", "Move Thresholds", n);
248
+ }
249
+ for (number::Number *n : this->gate_still_threshold_numbers_) {
250
+ LOG_NUMBER(" ", "Still Thresholds", n);
251
+ }
252
+ #endif
253
+ #ifdef USE_SELECT
254
+ ESP_LOGCONFIG(TAG, "Selects:");
255
+ LOG_SELECT(" ", "BaudRate", this->baud_rate_select_);
256
+ LOG_SELECT(" ", "DistanceResolution", this->distance_resolution_select_);
257
+ LOG_SELECT(" ", "LightFunction", this->light_function_select_);
258
+ LOG_SELECT(" ", "OutPinLevel", this->out_pin_level_select_);
259
+ #endif
260
+ #ifdef USE_SWITCH
261
+ ESP_LOGCONFIG(TAG, "Switches:");
262
+ LOG_SWITCH(" ", "Bluetooth", this->bluetooth_switch_);
263
+ LOG_SWITCH(" ", "EngineeringMode", this->engineering_mode_switch_);
264
+ #endif
265
+ #ifdef USE_BUTTON
266
+ ESP_LOGCONFIG(TAG, "Buttons:");
267
+ LOG_BUTTON(" ", "FactoryReset", this->factory_reset_button_);
268
+ LOG_BUTTON(" ", "Query", this->query_button_);
269
+ LOG_BUTTON(" ", "Restart", this->restart_button_);
270
+ LOG_BUTTON(" ", "StartDynamicBackgroundCorrection", this->start_dynamic_background_correction_button_);
271
+ #endif
272
+ }
273
+
274
+ void LD2412Component::setup() {
275
+ ESP_LOGCONFIG(TAG, "Running setup");
276
+ this->read_all_info();
277
+ }
278
+
279
+ void LD2412Component::read_all_info() {
280
+ this->set_config_mode_(true);
281
+ this->get_version_();
282
+ delay(10); // NOLINT
283
+ this->get_mac_();
284
+ delay(10); // NOLINT
285
+ this->get_distance_resolution_();
286
+ delay(10); // NOLINT
287
+ this->query_parameters_();
288
+ delay(10); // NOLINT
289
+ this->query_dynamic_background_correction_();
290
+ delay(10); // NOLINT
291
+ this->query_light_control_();
292
+ delay(10); // NOLINT
293
+ #ifdef USE_NUMBER
294
+ this->get_gate_threshold();
295
+ delay(10); // NOLINT
296
+ #endif
297
+ this->set_config_mode_(false);
298
+ #ifdef USE_SELECT
299
+ const auto baud_rate = std::to_string(this->parent_->get_baud_rate());
300
+ if (this->baud_rate_select_ != nullptr) {
301
+ this->baud_rate_select_->publish_state(baud_rate);
302
+ }
303
+ #endif
304
+ }
305
+
306
+ void LD2412Component::restart_and_read_all_info() {
307
+ this->set_config_mode_(true);
308
+ this->restart_();
309
+ this->set_timeout(1000, [this]() { this->read_all_info(); });
310
+ }
311
+
312
+ void LD2412Component::loop() {
313
+ while (this->available()) {
314
+ this->readline_(this->read());
315
+ }
316
+ }
317
+
318
+ void LD2412Component::send_command_(uint8_t command, const uint8_t *command_value, uint8_t command_value_len) {
319
+ ESP_LOGV(TAG, "Sending COMMAND %02X", command);
320
+ // frame header bytes
321
+ this->write_array(CMD_FRAME_HEADER, HEADER_FOOTER_SIZE);
322
+ // length bytes
323
+ uint8_t len = 2;
324
+ if (command_value != nullptr) {
325
+ len += command_value_len;
326
+ }
327
+ // 2 length bytes (low, high) + 2 command bytes (low, high)
328
+ uint8_t len_cmd[] = {len, 0x00, command, 0x00};
329
+ this->write_array(len_cmd, sizeof(len_cmd));
330
+
331
+ // command value bytes
332
+ if (command_value != nullptr) {
333
+ this->write_array(command_value, command_value_len);
334
+ }
335
+ // frame footer bytes
336
+ this->write_array(CMD_FRAME_FOOTER, HEADER_FOOTER_SIZE);
337
+
338
+ if (command != CMD_ENABLE_CONF && command != CMD_DISABLE_CONF) {
339
+ delay(30); // NOLINT
340
+ }
341
+ delay(20); // NOLINT
342
+ }
343
+
344
+ void LD2412Component::handle_periodic_data_() {
345
+ // 4 frame header bytes + 2 length bytes + 1 data end byte + 1 crc byte + 4 frame footer bytes
346
+ // data header=0xAA, data footer=0x55, crc=0x00
347
+ if (this->buffer_pos_ < 12 || !ld2412::validate_header_footer(DATA_FRAME_HEADER, this->buffer_data_) ||
348
+ this->buffer_data_[7] != HEADER || this->buffer_data_[this->buffer_pos_ - 6] != FOOTER) {
349
+ return;
350
+ }
351
+ /*
352
+ Data Type: 7th
353
+ 0x01: Engineering mode
354
+ 0x02: Normal mode
355
+ */
356
+ bool engineering_mode = this->buffer_data_[DATA_TYPES] == 0x01;
357
+ #ifdef USE_SWITCH
358
+ if (this->engineering_mode_switch_ != nullptr) {
359
+ this->engineering_mode_switch_->publish_state(engineering_mode);
360
+ }
361
+ #endif
362
+
363
+ #ifdef USE_BINARY_SENSOR
364
+ /*
365
+ Target states: 9th
366
+ 0x00 = No target
367
+ 0x01 = Moving targets
368
+ 0x02 = Still targets
369
+ 0x03 = Moving+Still targets
370
+ */
371
+ char target_state = this->buffer_data_[TARGET_STATES];
372
+ if (this->target_binary_sensor_ != nullptr) {
373
+ this->target_binary_sensor_->publish_state(target_state != 0x00);
374
+ }
375
+ if (this->moving_target_binary_sensor_ != nullptr) {
376
+ this->moving_target_binary_sensor_->publish_state(target_state & MOVE_BITMASK);
377
+ }
378
+ if (this->still_target_binary_sensor_ != nullptr) {
379
+ this->still_target_binary_sensor_->publish_state(target_state & STILL_BITMASK);
380
+ }
381
+ #endif
382
+ /*
383
+ Moving target distance: 10~11th bytes
384
+ Moving target energy: 12th byte
385
+ Still target distance: 13~14th bytes
386
+ Still target energy: 15th byte
387
+ Detect distance: 16~17th bytes
388
+ */
389
+ #ifdef USE_SENSOR
390
+ SAFE_PUBLISH_SENSOR(
391
+ this->moving_target_distance_sensor_,
392
+ ld2412::two_byte_to_int(this->buffer_data_[MOVING_TARGET_LOW], this->buffer_data_[MOVING_TARGET_HIGH]))
393
+ SAFE_PUBLISH_SENSOR(this->moving_target_energy_sensor_, this->buffer_data_[MOVING_ENERGY])
394
+ SAFE_PUBLISH_SENSOR(
395
+ this->still_target_distance_sensor_,
396
+ ld2412::two_byte_to_int(this->buffer_data_[STILL_TARGET_LOW], this->buffer_data_[STILL_TARGET_HIGH]))
397
+ SAFE_PUBLISH_SENSOR(this->still_target_energy_sensor_, this->buffer_data_[STILL_ENERGY])
398
+ if (this->detection_distance_sensor_ != nullptr) {
399
+ int new_detect_distance = 0;
400
+ if (target_state != 0x00 && (target_state & MOVE_BITMASK)) {
401
+ new_detect_distance =
402
+ ld2412::two_byte_to_int(this->buffer_data_[MOVING_TARGET_LOW], this->buffer_data_[MOVING_TARGET_HIGH]);
403
+ } else if (target_state != 0x00) {
404
+ new_detect_distance =
405
+ ld2412::two_byte_to_int(this->buffer_data_[STILL_TARGET_LOW], this->buffer_data_[STILL_TARGET_HIGH]);
406
+ }
407
+ this->detection_distance_sensor_->publish_state_if_not_dup(new_detect_distance);
408
+ }
409
+ if (engineering_mode) {
410
+ /*
411
+ Moving distance range: 18th byte
412
+ Still distance range: 19th byte
413
+ Moving energy: 20~28th bytes
414
+ */
415
+ for (uint8_t i = 0; i < TOTAL_GATES; i++) {
416
+ SAFE_PUBLISH_SENSOR(this->gate_move_sensors_[i], this->buffer_data_[MOVING_SENSOR_START + i])
417
+ }
418
+ /*
419
+ Still energy: 29~37th bytes
420
+ */
421
+ for (uint8_t i = 0; i < TOTAL_GATES; i++) {
422
+ SAFE_PUBLISH_SENSOR(this->gate_still_sensors_[i], this->buffer_data_[STILL_SENSOR_START + i])
423
+ }
424
+ /*
425
+ Light sensor: 38th bytes
426
+ */
427
+ SAFE_PUBLISH_SENSOR(this->light_sensor_, this->buffer_data_[LIGHT_SENSOR])
428
+ } else {
429
+ for (auto &gate_move_sensor : this->gate_move_sensors_) {
430
+ SAFE_PUBLISH_SENSOR_UNKNOWN(gate_move_sensor)
431
+ }
432
+ for (auto &gate_still_sensor : this->gate_still_sensors_) {
433
+ SAFE_PUBLISH_SENSOR_UNKNOWN(gate_still_sensor)
434
+ }
435
+ SAFE_PUBLISH_SENSOR_UNKNOWN(this->light_sensor_)
436
+ }
437
+ #endif
438
+ // the radar module won't tell us when it's done, so we just have to keep polling...
439
+ if (this->dynamic_background_correction_active_) {
440
+ this->set_config_mode_(true);
441
+ this->query_dynamic_background_correction_();
442
+ this->set_config_mode_(false);
443
+ }
444
+ }
445
+
446
+ #ifdef USE_NUMBER
447
+ std::function<void(void)> set_number_value(number::Number *n, float value) {
448
+ if (n != nullptr && (!n->has_state() || n->state != value)) {
449
+ n->state = value;
450
+ return [n, value]() { n->publish_state(value); };
451
+ }
452
+ return []() {};
453
+ }
454
+ #endif
455
+
456
+ bool LD2412Component::handle_ack_data_() {
457
+ ESP_LOGV(TAG, "Handling ACK DATA for COMMAND %02X", this->buffer_data_[COMMAND]);
458
+ if (this->buffer_pos_ < 10) {
459
+ ESP_LOGW(TAG, "Invalid length");
460
+ return true;
461
+ }
462
+ if (!ld2412::validate_header_footer(CMD_FRAME_HEADER, this->buffer_data_)) {
463
+ ESP_LOGW(TAG, "Invalid header: %s", format_hex_pretty(this->buffer_data_, HEADER_FOOTER_SIZE).c_str());
464
+ return true;
465
+ }
466
+ if (this->buffer_data_[COMMAND_STATUS] != 0x01) {
467
+ ESP_LOGW(TAG, "Invalid status");
468
+ return true;
469
+ }
470
+ if (this->buffer_data_[8] || this->buffer_data_[9]) {
471
+ ESP_LOGW(TAG, "Invalid command: %02X, %02X", this->buffer_data_[8], this->buffer_data_[9]);
472
+ return true;
473
+ }
474
+
475
+ switch (this->buffer_data_[COMMAND]) {
476
+ case CMD_ENABLE_CONF:
477
+ ESP_LOGV(TAG, "Enable conf");
478
+ break;
479
+
480
+ case CMD_DISABLE_CONF:
481
+ ESP_LOGV(TAG, "Disabled conf");
482
+ break;
483
+
484
+ case CMD_SET_BAUD_RATE:
485
+ ESP_LOGV(TAG, "Baud rate change");
486
+ #ifdef USE_SELECT
487
+ if (this->baud_rate_select_ != nullptr) {
488
+ ESP_LOGW(TAG, "Change baud rate to %s and reinstall", this->baud_rate_select_->state.c_str());
489
+ }
490
+ #endif
491
+ break;
492
+
493
+ case CMD_QUERY_VERSION: {
494
+ std::memcpy(this->version_, &this->buffer_data_[12], sizeof(this->version_));
495
+ std::string version = str_sprintf(VERSION_FMT, this->version_[1], this->version_[0], this->version_[5],
496
+ this->version_[4], this->version_[3], this->version_[2]);
497
+ ESP_LOGV(TAG, "Firmware version: %s", version.c_str());
498
+ #ifdef USE_TEXT_SENSOR
499
+ if (this->version_text_sensor_ != nullptr) {
500
+ this->version_text_sensor_->publish_state(version);
501
+ }
502
+ #endif
503
+ break;
504
+ }
505
+ case CMD_QUERY_DISTANCE_RESOLUTION: {
506
+ const auto *distance_resolution = find_str(DISTANCE_RESOLUTIONS_BY_UINT, this->buffer_data_[10]);
507
+ ESP_LOGV(TAG, "Distance resolution: %s", distance_resolution);
508
+ #ifdef USE_SELECT
509
+ if (this->distance_resolution_select_ != nullptr) {
510
+ this->distance_resolution_select_->publish_state(distance_resolution);
511
+ }
512
+ #endif
513
+ break;
514
+ }
515
+
516
+ case CMD_QUERY_LIGHT_CONTROL: {
517
+ this->light_function_ = this->buffer_data_[10];
518
+ this->light_threshold_ = this->buffer_data_[11];
519
+ const auto *light_function_str = find_str(LIGHT_FUNCTIONS_BY_UINT, this->light_function_);
520
+ ESP_LOGV(TAG,
521
+ "Light function: %s\n"
522
+ "Light threshold: %u",
523
+ light_function_str, this->light_threshold_);
524
+ #ifdef USE_SELECT
525
+ if (this->light_function_select_ != nullptr) {
526
+ this->light_function_select_->publish_state(light_function_str);
527
+ }
528
+ #endif
529
+ #ifdef USE_NUMBER
530
+ if (this->light_threshold_number_ != nullptr) {
531
+ this->light_threshold_number_->publish_state(static_cast<float>(this->light_threshold_));
532
+ }
533
+ #endif
534
+ break;
535
+ }
536
+
537
+ case CMD_QUERY_MAC_ADDRESS: {
538
+ if (this->buffer_pos_ < 20) {
539
+ return false;
540
+ }
541
+
542
+ this->bluetooth_on_ = std::memcmp(&this->buffer_data_[10], NO_MAC, sizeof(NO_MAC)) != 0;
543
+ if (this->bluetooth_on_) {
544
+ std::memcpy(this->mac_address_, &this->buffer_data_[10], sizeof(this->mac_address_));
545
+ }
546
+
547
+ std::string mac_str =
548
+ mac_address_is_valid(this->mac_address_) ? format_mac_address_pretty(this->mac_address_) : UNKNOWN_MAC;
549
+ ESP_LOGV(TAG, "MAC address: %s", mac_str.c_str());
550
+ #ifdef USE_TEXT_SENSOR
551
+ if (this->mac_text_sensor_ != nullptr) {
552
+ this->mac_text_sensor_->publish_state(mac_str);
553
+ }
554
+ #endif
555
+ #ifdef USE_SWITCH
556
+ if (this->bluetooth_switch_ != nullptr) {
557
+ this->bluetooth_switch_->publish_state(this->bluetooth_on_);
558
+ }
559
+ #endif
560
+ break;
561
+ }
562
+
563
+ case CMD_SET_DISTANCE_RESOLUTION:
564
+ ESP_LOGV(TAG, "Handled set distance resolution command");
565
+ break;
566
+
567
+ case CMD_QUERY_DYNAMIC_BACKGROUND_CORRECTION: {
568
+ ESP_LOGV(TAG, "Handled query dynamic background correction");
569
+ bool dynamic_background_correction_active = (this->buffer_data_[10] != 0x00);
570
+ #ifdef USE_BINARY_SENSOR
571
+ if (this->dynamic_background_correction_status_binary_sensor_ != nullptr) {
572
+ this->dynamic_background_correction_status_binary_sensor_->publish_state(dynamic_background_correction_active);
573
+ }
574
+ #endif
575
+ this->dynamic_background_correction_active_ = dynamic_background_correction_active;
576
+ break;
577
+ }
578
+
579
+ case CMD_BLUETOOTH:
580
+ ESP_LOGV(TAG, "Handled bluetooth command");
581
+ break;
582
+
583
+ case CMD_SET_LIGHT_CONTROL:
584
+ ESP_LOGV(TAG, "Handled set light control command");
585
+ break;
586
+
587
+ case CMD_QUERY_MOTION_GATE_SENS: {
588
+ #ifdef USE_NUMBER
589
+ std::vector<std::function<void(void)>> updates;
590
+ updates.reserve(this->gate_still_threshold_numbers_.size());
591
+ for (size_t i = 0; i < this->gate_still_threshold_numbers_.size(); i++) {
592
+ updates.push_back(set_number_value(this->gate_move_threshold_numbers_[i], this->buffer_data_[10 + i]));
593
+ }
594
+ for (auto &update : updates) {
595
+ update();
596
+ }
597
+ #endif
598
+ break;
599
+ }
600
+
601
+ case CMD_QUERY_STATIC_GATE_SENS: {
602
+ #ifdef USE_NUMBER
603
+ std::vector<std::function<void(void)>> updates;
604
+ updates.reserve(this->gate_still_threshold_numbers_.size());
605
+ for (size_t i = 0; i < this->gate_still_threshold_numbers_.size(); i++) {
606
+ updates.push_back(set_number_value(this->gate_still_threshold_numbers_[i], this->buffer_data_[10 + i]));
607
+ }
608
+ for (auto &update : updates) {
609
+ update();
610
+ }
611
+ #endif
612
+ break;
613
+ }
614
+
615
+ case CMD_QUERY_BASIC_CONF: // Query parameters response
616
+ {
617
+ #ifdef USE_NUMBER
618
+ /*
619
+ Moving distance range: 9th byte
620
+ Still distance range: 10th byte
621
+ */
622
+ std::vector<std::function<void(void)>> updates;
623
+ updates.push_back(set_number_value(this->min_distance_gate_number_, this->buffer_data_[10]));
624
+ updates.push_back(set_number_value(this->max_distance_gate_number_, this->buffer_data_[11] - 1));
625
+ ESP_LOGV(TAG, "min_distance_gate_number_: %u, max_distance_gate_number_ %u", this->buffer_data_[10],
626
+ this->buffer_data_[11]);
627
+ /*
628
+ None Duration: 11~12th bytes
629
+ */
630
+ updates.push_back(set_number_value(this->timeout_number_,
631
+ ld2412::two_byte_to_int(this->buffer_data_[12], this->buffer_data_[13])));
632
+ ESP_LOGV(TAG, "timeout_number_: %u", ld2412::two_byte_to_int(this->buffer_data_[12], this->buffer_data_[13]));
633
+ /*
634
+ Output pin configuration: 13th bytes
635
+ */
636
+ this->out_pin_level_ = this->buffer_data_[14];
637
+ #ifdef USE_SELECT
638
+ const auto *out_pin_level_str = find_str(OUT_PIN_LEVELS_BY_UINT, this->out_pin_level_);
639
+ if (this->out_pin_level_select_ != nullptr) {
640
+ this->out_pin_level_select_->publish_state(out_pin_level_str);
641
+ }
642
+ #endif
643
+ for (auto &update : updates) {
644
+ update();
645
+ }
646
+ #endif
647
+ } break;
648
+ default:
649
+ break;
650
+ }
651
+
652
+ return true;
653
+ }
654
+
655
+ void LD2412Component::readline_(int readch) {
656
+ if (readch < 0) {
657
+ return; // No data available
658
+ }
659
+ if (this->buffer_pos_ < HEADER_FOOTER_SIZE && readch != DATA_FRAME_HEADER[this->buffer_pos_] &&
660
+ readch != CMD_FRAME_HEADER[this->buffer_pos_]) {
661
+ this->buffer_pos_ = 0;
662
+ return;
663
+ }
664
+ if (this->buffer_pos_ < MAX_LINE_LENGTH - 1) {
665
+ this->buffer_data_[this->buffer_pos_++] = readch;
666
+ this->buffer_data_[this->buffer_pos_] = 0;
667
+ } else {
668
+ // We should never get here, but just in case...
669
+ ESP_LOGW(TAG, "Max command length exceeded; ignoring");
670
+ this->buffer_pos_ = 0;
671
+ }
672
+ if (this->buffer_pos_ < 4) {
673
+ return; // Not enough data to process yet
674
+ }
675
+ if (ld2412::validate_header_footer(DATA_FRAME_FOOTER, &this->buffer_data_[this->buffer_pos_ - 4])) {
676
+ ESP_LOGV(TAG, "Handling Periodic Data: %s", format_hex_pretty(this->buffer_data_, this->buffer_pos_).c_str());
677
+ this->handle_periodic_data_();
678
+ this->buffer_pos_ = 0; // Reset position index for next message
679
+ } else if (ld2412::validate_header_footer(CMD_FRAME_FOOTER, &this->buffer_data_[this->buffer_pos_ - 4])) {
680
+ ESP_LOGV(TAG, "Handling Ack Data: %s", format_hex_pretty(this->buffer_data_, this->buffer_pos_).c_str());
681
+ if (this->handle_ack_data_()) {
682
+ this->buffer_pos_ = 0; // Reset position index for next message
683
+ } else {
684
+ ESP_LOGV(TAG, "Ack Data incomplete");
685
+ }
686
+ }
687
+ }
688
+
689
+ void LD2412Component::set_config_mode_(bool enable) {
690
+ const uint8_t cmd = enable ? CMD_ENABLE_CONF : CMD_DISABLE_CONF;
691
+ const uint8_t cmd_value[2] = {0x01, 0x00};
692
+ this->send_command_(cmd, enable ? cmd_value : nullptr, sizeof(cmd_value));
693
+ }
694
+
695
+ void LD2412Component::set_bluetooth(bool enable) {
696
+ this->set_config_mode_(true);
697
+ const uint8_t cmd_value[2] = {enable ? (uint8_t) 0x01 : (uint8_t) 0x00, 0x00};
698
+ this->send_command_(CMD_BLUETOOTH, cmd_value, sizeof(cmd_value));
699
+ this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
700
+ }
701
+
702
+ void LD2412Component::set_distance_resolution(const std::string &state) {
703
+ this->set_config_mode_(true);
704
+ const uint8_t cmd_value[6] = {find_uint8(DISTANCE_RESOLUTIONS_BY_STR, state), 0x00, 0x00, 0x00, 0x00, 0x00};
705
+ this->send_command_(CMD_SET_DISTANCE_RESOLUTION, cmd_value, sizeof(cmd_value));
706
+ this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
707
+ }
708
+
709
+ void LD2412Component::set_baud_rate(const std::string &state) {
710
+ this->set_config_mode_(true);
711
+ const uint8_t cmd_value[2] = {find_uint8(BAUD_RATES_BY_STR, state), 0x00};
712
+ this->send_command_(CMD_SET_BAUD_RATE, cmd_value, sizeof(cmd_value));
713
+ this->set_timeout(200, [this]() { this->restart_(); });
714
+ }
715
+
716
+ void LD2412Component::query_dynamic_background_correction_() {
717
+ this->send_command_(CMD_QUERY_DYNAMIC_BACKGROUND_CORRECTION, nullptr, 0);
718
+ }
719
+
720
+ void LD2412Component::start_dynamic_background_correction() {
721
+ if (this->dynamic_background_correction_active_) {
722
+ return; // Already in progress
723
+ }
724
+ #ifdef USE_BINARY_SENSOR
725
+ if (this->dynamic_background_correction_status_binary_sensor_ != nullptr) {
726
+ this->dynamic_background_correction_status_binary_sensor_->publish_state(true);
727
+ }
728
+ #endif
729
+ this->dynamic_background_correction_active_ = true;
730
+ this->set_config_mode_(true);
731
+ this->send_command_(CMD_DYNAMIC_BACKGROUND_CORRECTION, nullptr, 0);
732
+ this->set_config_mode_(false);
733
+ }
734
+
735
+ void LD2412Component::set_engineering_mode(bool enable) {
736
+ const uint8_t cmd = enable ? CMD_ENABLE_ENG : CMD_DISABLE_ENG;
737
+ this->set_config_mode_(true);
738
+ this->send_command_(cmd, nullptr, 0);
739
+ this->set_config_mode_(false);
740
+ }
741
+
742
+ void LD2412Component::factory_reset() {
743
+ this->set_config_mode_(true);
744
+ this->send_command_(CMD_FACTORY_RESET, nullptr, 0);
745
+ this->set_timeout(2000, [this]() { this->restart_and_read_all_info(); });
746
+ }
747
+
748
+ void LD2412Component::restart_() { this->send_command_(CMD_RESTART, nullptr, 0); }
749
+
750
+ void LD2412Component::query_parameters_() { this->send_command_(CMD_QUERY_BASIC_CONF, nullptr, 0); }
751
+
752
+ void LD2412Component::get_version_() { this->send_command_(CMD_QUERY_VERSION, nullptr, 0); }
753
+
754
+ void LD2412Component::get_mac_() {
755
+ const uint8_t cmd_value[2] = {0x01, 0x00};
756
+ this->send_command_(CMD_QUERY_MAC_ADDRESS, cmd_value, sizeof(cmd_value));
757
+ }
758
+
759
+ void LD2412Component::get_distance_resolution_() { this->send_command_(CMD_QUERY_DISTANCE_RESOLUTION, nullptr, 0); }
760
+
761
+ void LD2412Component::query_light_control_() { this->send_command_(CMD_QUERY_LIGHT_CONTROL, nullptr, 0); }
762
+
763
+ void LD2412Component::set_basic_config() {
764
+ #ifdef USE_NUMBER
765
+ if (!this->min_distance_gate_number_->has_state() || !this->max_distance_gate_number_->has_state() ||
766
+ !this->timeout_number_->has_state()) {
767
+ return;
768
+ }
769
+ #endif
770
+ #ifdef USE_SELECT
771
+ if (!this->out_pin_level_select_->has_state()) {
772
+ return;
773
+ }
774
+ #endif
775
+
776
+ uint8_t value[5] = {
777
+ #ifdef USE_NUMBER
778
+ lowbyte(static_cast<int>(this->min_distance_gate_number_->state)),
779
+ lowbyte(static_cast<int>(this->max_distance_gate_number_->state) + 1),
780
+ lowbyte(static_cast<int>(this->timeout_number_->state)),
781
+ highbyte(static_cast<int>(this->timeout_number_->state)),
782
+ #else
783
+ 1, TOTAL_GATES, DEFAULT_PRESENCE_TIMEOUT, 0,
784
+ #endif
785
+ #ifdef USE_SELECT
786
+ find_uint8(OUT_PIN_LEVELS_BY_STR, this->out_pin_level_select_->state),
787
+ #else
788
+ 0x01, // Default value if not using select
789
+ #endif
790
+ };
791
+ this->set_config_mode_(true);
792
+ this->send_command_(CMD_BASIC_CONF, value, sizeof(value));
793
+ this->set_config_mode_(false);
794
+ }
795
+
796
+ #ifdef USE_NUMBER
797
+ void LD2412Component::set_gate_threshold() {
798
+ if (this->gate_move_threshold_numbers_.empty() && this->gate_still_threshold_numbers_.empty()) {
799
+ return; // No gate threshold numbers set; nothing to do here
800
+ }
801
+ uint8_t value[TOTAL_GATES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
802
+ this->set_config_mode_(true);
803
+ if (!this->gate_move_threshold_numbers_.empty()) {
804
+ for (size_t i = 0; i < this->gate_move_threshold_numbers_.size(); i++) {
805
+ value[i] = lowbyte(static_cast<int>(this->gate_move_threshold_numbers_[i]->state));
806
+ }
807
+ this->send_command_(CMD_MOTION_GATE_SENS, value, sizeof(value));
808
+ }
809
+ if (!this->gate_still_threshold_numbers_.empty()) {
810
+ for (size_t i = 0; i < this->gate_still_threshold_numbers_.size(); i++) {
811
+ value[i] = lowbyte(static_cast<int>(this->gate_still_threshold_numbers_[i]->state));
812
+ }
813
+ this->send_command_(CMD_STATIC_GATE_SENS, value, sizeof(value));
814
+ }
815
+ this->set_config_mode_(false);
816
+ }
817
+
818
+ void LD2412Component::get_gate_threshold() {
819
+ this->send_command_(CMD_QUERY_MOTION_GATE_SENS, nullptr, 0);
820
+ this->send_command_(CMD_QUERY_STATIC_GATE_SENS, nullptr, 0);
821
+ }
822
+
823
+ void LD2412Component::set_gate_still_threshold_number(uint8_t gate, number::Number *n) {
824
+ this->gate_still_threshold_numbers_[gate] = n;
825
+ }
826
+
827
+ void LD2412Component::set_gate_move_threshold_number(uint8_t gate, number::Number *n) {
828
+ this->gate_move_threshold_numbers_[gate] = n;
829
+ }
830
+ #endif
831
+
832
+ void LD2412Component::set_light_out_control() {
833
+ #ifdef USE_NUMBER
834
+ if (this->light_threshold_number_ != nullptr && this->light_threshold_number_->has_state()) {
835
+ this->light_threshold_ = static_cast<uint8_t>(this->light_threshold_number_->state);
836
+ }
837
+ #endif
838
+ #ifdef USE_SELECT
839
+ if (this->light_function_select_ != nullptr && this->light_function_select_->has_state()) {
840
+ this->light_function_ = find_uint8(LIGHT_FUNCTIONS_BY_STR, this->light_function_select_->state);
841
+ }
842
+ #endif
843
+ uint8_t value[2] = {this->light_function_, this->light_threshold_};
844
+ this->set_config_mode_(true);
845
+ this->send_command_(CMD_SET_LIGHT_CONTROL, value, sizeof(value));
846
+ this->query_light_control_();
847
+ this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
848
+ }
849
+
850
+ #ifdef USE_SENSOR
851
+ // These could leak memory, but they are only set once prior to 'setup()' and should never be used again.
852
+ void LD2412Component::set_gate_move_sensor(uint8_t gate, sensor::Sensor *s) {
853
+ this->gate_move_sensors_[gate] = new SensorWithDedup<uint8_t>(s);
854
+ }
855
+ void LD2412Component::set_gate_still_sensor(uint8_t gate, sensor::Sensor *s) {
856
+ this->gate_still_sensors_[gate] = new SensorWithDedup<uint8_t>(s);
857
+ }
858
+ #endif
859
+
860
+ } // namespace ld2412
861
+ } // namespace esphome