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
@@ -8,6 +8,9 @@
8
8
  #include "esphome/components/sensor/sensor.h"
9
9
  #endif
10
10
 
11
+ #include "esphome/core/application.h"
12
+
13
+ #define CHECK_BIT(var, pos) (((var) >> (pos)) & 1)
11
14
  #define highbyte(val) (uint8_t)((val) >> 8)
12
15
  #define lowbyte(val) (uint8_t)((val) &0xff)
13
16
 
@@ -15,68 +18,239 @@ namespace esphome {
15
18
  namespace ld2410 {
16
19
 
17
20
  static const char *const TAG = "ld2410";
21
+ static const char *const UNKNOWN_MAC = "unknown";
22
+ static const char *const VERSION_FMT = "%u.%02X.%02X%02X%02X%02X";
23
+
24
+ enum BaudRate : uint8_t {
25
+ BAUD_RATE_9600 = 1,
26
+ BAUD_RATE_19200 = 2,
27
+ BAUD_RATE_38400 = 3,
28
+ BAUD_RATE_57600 = 4,
29
+ BAUD_RATE_115200 = 5,
30
+ BAUD_RATE_230400 = 6,
31
+ BAUD_RATE_256000 = 7,
32
+ BAUD_RATE_460800 = 8,
33
+ };
34
+
35
+ enum DistanceResolution : uint8_t {
36
+ DISTANCE_RESOLUTION_0_2 = 0x01,
37
+ DISTANCE_RESOLUTION_0_75 = 0x00,
38
+ };
39
+
40
+ enum LightFunction : uint8_t {
41
+ LIGHT_FUNCTION_OFF = 0x00,
42
+ LIGHT_FUNCTION_BELOW = 0x01,
43
+ LIGHT_FUNCTION_ABOVE = 0x02,
44
+ };
45
+
46
+ enum OutPinLevel : uint8_t {
47
+ OUT_PIN_LEVEL_LOW = 0x00,
48
+ OUT_PIN_LEVEL_HIGH = 0x01,
49
+ };
50
+
51
+ enum PeriodicData : uint8_t {
52
+ DATA_TYPES = 6,
53
+ TARGET_STATES = 8,
54
+ MOVING_TARGET_LOW = 9,
55
+ MOVING_TARGET_HIGH = 10,
56
+ MOVING_ENERGY = 11,
57
+ STILL_TARGET_LOW = 12,
58
+ STILL_TARGET_HIGH = 13,
59
+ STILL_ENERGY = 14,
60
+ DETECT_DISTANCE_LOW = 15,
61
+ DETECT_DISTANCE_HIGH = 16,
62
+ MOVING_SENSOR_START = 19,
63
+ STILL_SENSOR_START = 28,
64
+ LIGHT_SENSOR = 37,
65
+ OUT_PIN_SENSOR = 38,
66
+ };
67
+
68
+ enum PeriodicDataValue : uint8_t {
69
+ HEADER = 0xAA,
70
+ FOOTER = 0x55,
71
+ CHECK = 0x00,
72
+ };
73
+
74
+ enum AckData : uint8_t {
75
+ COMMAND = 6,
76
+ COMMAND_STATUS = 7,
77
+ };
78
+
79
+ // Memory-efficient lookup tables
80
+ struct StringToUint8 {
81
+ const char *str;
82
+ const uint8_t value;
83
+ };
84
+
85
+ struct Uint8ToString {
86
+ const uint8_t value;
87
+ const char *str;
88
+ };
89
+
90
+ constexpr StringToUint8 BAUD_RATES_BY_STR[] = {
91
+ {"9600", BAUD_RATE_9600}, {"19200", BAUD_RATE_19200}, {"38400", BAUD_RATE_38400},
92
+ {"57600", BAUD_RATE_57600}, {"115200", BAUD_RATE_115200}, {"230400", BAUD_RATE_230400},
93
+ {"256000", BAUD_RATE_256000}, {"460800", BAUD_RATE_460800},
94
+ };
95
+
96
+ constexpr StringToUint8 DISTANCE_RESOLUTIONS_BY_STR[] = {
97
+ {"0.2m", DISTANCE_RESOLUTION_0_2},
98
+ {"0.75m", DISTANCE_RESOLUTION_0_75},
99
+ };
100
+
101
+ constexpr Uint8ToString DISTANCE_RESOLUTIONS_BY_UINT[] = {
102
+ {DISTANCE_RESOLUTION_0_2, "0.2m"},
103
+ {DISTANCE_RESOLUTION_0_75, "0.75m"},
104
+ };
105
+
106
+ constexpr StringToUint8 LIGHT_FUNCTIONS_BY_STR[] = {
107
+ {"off", LIGHT_FUNCTION_OFF},
108
+ {"below", LIGHT_FUNCTION_BELOW},
109
+ {"above", LIGHT_FUNCTION_ABOVE},
110
+ };
111
+
112
+ constexpr Uint8ToString LIGHT_FUNCTIONS_BY_UINT[] = {
113
+ {LIGHT_FUNCTION_OFF, "off"},
114
+ {LIGHT_FUNCTION_BELOW, "below"},
115
+ {LIGHT_FUNCTION_ABOVE, "above"},
116
+ };
117
+
118
+ constexpr StringToUint8 OUT_PIN_LEVELS_BY_STR[] = {
119
+ {"low", OUT_PIN_LEVEL_LOW},
120
+ {"high", OUT_PIN_LEVEL_HIGH},
121
+ };
122
+
123
+ constexpr Uint8ToString OUT_PIN_LEVELS_BY_UINT[] = {
124
+ {OUT_PIN_LEVEL_LOW, "low"},
125
+ {OUT_PIN_LEVEL_HIGH, "high"},
126
+ };
127
+
128
+ // Helper functions for lookups
129
+ template<size_t N> uint8_t find_uint8(const StringToUint8 (&arr)[N], const std::string &str) {
130
+ for (const auto &entry : arr) {
131
+ if (str == entry.str)
132
+ return entry.value;
133
+ }
134
+ return 0xFF; // Not found
135
+ }
136
+
137
+ template<size_t N> const char *find_str(const Uint8ToString (&arr)[N], uint8_t value) {
138
+ for (const auto &entry : arr) {
139
+ if (value == entry.value)
140
+ return entry.str;
141
+ }
142
+ return ""; // Not found
143
+ }
18
144
 
19
- LD2410Component::LD2410Component() {}
145
+ // Commands
146
+ static constexpr uint8_t CMD_ENABLE_CONF = 0xFF;
147
+ static constexpr uint8_t CMD_DISABLE_CONF = 0xFE;
148
+ static constexpr uint8_t CMD_ENABLE_ENG = 0x62;
149
+ static constexpr uint8_t CMD_DISABLE_ENG = 0x63;
150
+ static constexpr uint8_t CMD_MAXDIST_DURATION = 0x60;
151
+ static constexpr uint8_t CMD_QUERY = 0x61;
152
+ static constexpr uint8_t CMD_GATE_SENS = 0x64;
153
+ static constexpr uint8_t CMD_QUERY_VERSION = 0xA0;
154
+ static constexpr uint8_t CMD_QUERY_DISTANCE_RESOLUTION = 0xAB;
155
+ static constexpr uint8_t CMD_SET_DISTANCE_RESOLUTION = 0xAA;
156
+ static constexpr uint8_t CMD_QUERY_LIGHT_CONTROL = 0xAE;
157
+ static constexpr uint8_t CMD_SET_LIGHT_CONTROL = 0xAD;
158
+ static constexpr uint8_t CMD_SET_BAUD_RATE = 0xA1;
159
+ static constexpr uint8_t CMD_BT_PASSWORD = 0xA9;
160
+ static constexpr uint8_t CMD_QUERY_MAC_ADDRESS = 0xA5;
161
+ static constexpr uint8_t CMD_RESET = 0xA2;
162
+ static constexpr uint8_t CMD_RESTART = 0xA3;
163
+ static constexpr uint8_t CMD_BLUETOOTH = 0xA4;
164
+ // Commands values
165
+ static constexpr uint8_t CMD_MAX_MOVE_VALUE = 0x00;
166
+ static constexpr uint8_t CMD_MAX_STILL_VALUE = 0x01;
167
+ static constexpr uint8_t CMD_DURATION_VALUE = 0x02;
168
+ // Header & Footer size
169
+ static constexpr uint8_t HEADER_FOOTER_SIZE = 4;
170
+ // Command Header & Footer
171
+ static constexpr uint8_t CMD_FRAME_HEADER[HEADER_FOOTER_SIZE] = {0xFD, 0xFC, 0xFB, 0xFA};
172
+ static constexpr uint8_t CMD_FRAME_FOOTER[HEADER_FOOTER_SIZE] = {0x04, 0x03, 0x02, 0x01};
173
+ // Data Header & Footer
174
+ static constexpr uint8_t DATA_FRAME_HEADER[HEADER_FOOTER_SIZE] = {0xF4, 0xF3, 0xF2, 0xF1};
175
+ static constexpr uint8_t DATA_FRAME_FOOTER[HEADER_FOOTER_SIZE] = {0xF8, 0xF7, 0xF6, 0xF5};
176
+ // MAC address the module uses when Bluetooth is disabled
177
+ static constexpr uint8_t NO_MAC[] = {0x08, 0x05, 0x04, 0x03, 0x02, 0x01};
178
+
179
+ static inline int two_byte_to_int(char firstbyte, char secondbyte) { return (int16_t) (secondbyte << 8) + firstbyte; }
180
+
181
+ static inline bool validate_header_footer(const uint8_t *header_footer, const uint8_t *buffer) {
182
+ return std::memcmp(header_footer, buffer, HEADER_FOOTER_SIZE) == 0;
183
+ }
20
184
 
21
185
  void LD2410Component::dump_config() {
22
- ESP_LOGCONFIG(TAG, "LD2410:");
186
+ std::string mac_str =
187
+ mac_address_is_valid(this->mac_address_) ? format_mac_address_pretty(this->mac_address_) : UNKNOWN_MAC;
188
+ std::string version = str_sprintf(VERSION_FMT, this->version_[1], this->version_[0], this->version_[5],
189
+ this->version_[4], this->version_[3], this->version_[2]);
190
+ ESP_LOGCONFIG(TAG,
191
+ "LD2410:\n"
192
+ " Firmware version: %s\n"
193
+ " MAC address: %s\n"
194
+ " Throttle: %u ms",
195
+ version.c_str(), mac_str.c_str(), this->throttle_);
23
196
  #ifdef USE_BINARY_SENSOR
24
- LOG_BINARY_SENSOR(" ", "TargetBinarySensor", this->target_binary_sensor_);
25
- LOG_BINARY_SENSOR(" ", "MovingTargetBinarySensor", this->moving_target_binary_sensor_);
26
- LOG_BINARY_SENSOR(" ", "StillTargetBinarySensor", this->still_target_binary_sensor_);
27
- LOG_BINARY_SENSOR(" ", "OutPinPresenceStatusBinarySensor", this->out_pin_presence_status_binary_sensor_);
28
- #endif
29
- #ifdef USE_SWITCH
30
- LOG_SWITCH(" ", "EngineeringModeSwitch", this->engineering_mode_switch_);
31
- LOG_SWITCH(" ", "BluetoothSwitch", this->bluetooth_switch_);
32
- #endif
33
- #ifdef USE_BUTTON
34
- LOG_BUTTON(" ", "ResetButton", this->reset_button_);
35
- LOG_BUTTON(" ", "RestartButton", this->restart_button_);
36
- LOG_BUTTON(" ", "QueryButton", this->query_button_);
197
+ ESP_LOGCONFIG(TAG, "Binary Sensors:");
198
+ LOG_BINARY_SENSOR(" ", "Target", this->target_binary_sensor_);
199
+ LOG_BINARY_SENSOR(" ", "MovingTarget", this->moving_target_binary_sensor_);
200
+ LOG_BINARY_SENSOR(" ", "StillTarget", this->still_target_binary_sensor_);
201
+ LOG_BINARY_SENSOR(" ", "OutPinPresenceStatus", this->out_pin_presence_status_binary_sensor_);
37
202
  #endif
38
203
  #ifdef USE_SENSOR
39
- LOG_SENSOR(" ", "LightSensor", this->light_sensor_);
40
- LOG_SENSOR(" ", "MovingTargetDistanceSensor", this->moving_target_distance_sensor_);
41
- LOG_SENSOR(" ", "StillTargetDistanceSensor", this->still_target_distance_sensor_);
42
- LOG_SENSOR(" ", "MovingTargetEnergySensor", this->moving_target_energy_sensor_);
43
- LOG_SENSOR(" ", "StillTargetEnergySensor", this->still_target_energy_sensor_);
44
- LOG_SENSOR(" ", "DetectionDistanceSensor", this->detection_distance_sensor_);
45
- for (sensor::Sensor *s : this->gate_still_sensors_) {
46
- LOG_SENSOR(" ", "NthGateStillSesnsor", s);
47
- }
204
+ ESP_LOGCONFIG(TAG, "Sensors:");
205
+ LOG_SENSOR(" ", "Light", this->light_sensor_);
206
+ LOG_SENSOR(" ", "DetectionDistance", this->detection_distance_sensor_);
207
+ LOG_SENSOR(" ", "MovingTargetDistance", this->moving_target_distance_sensor_);
208
+ LOG_SENSOR(" ", "MovingTargetEnergy", this->moving_target_energy_sensor_);
209
+ LOG_SENSOR(" ", "StillTargetDistance", this->still_target_distance_sensor_);
210
+ LOG_SENSOR(" ", "StillTargetEnergy", this->still_target_energy_sensor_);
48
211
  for (sensor::Sensor *s : this->gate_move_sensors_) {
49
- LOG_SENSOR(" ", "NthGateMoveSesnsor", s);
212
+ LOG_SENSOR(" ", "GateMove", s);
213
+ }
214
+ for (sensor::Sensor *s : this->gate_still_sensors_) {
215
+ LOG_SENSOR(" ", "GateStill", s);
50
216
  }
51
217
  #endif
52
218
  #ifdef USE_TEXT_SENSOR
53
- LOG_TEXT_SENSOR(" ", "VersionTextSensor", this->version_text_sensor_);
54
- LOG_TEXT_SENSOR(" ", "MacTextSensor", this->mac_text_sensor_);
55
- #endif
56
- #ifdef USE_SELECT
57
- LOG_SELECT(" ", "LightFunctionSelect", this->light_function_select_);
58
- LOG_SELECT(" ", "OutPinLevelSelect", this->out_pin_level_select_);
59
- LOG_SELECT(" ", "DistanceResolutionSelect", this->distance_resolution_select_);
60
- LOG_SELECT(" ", "BaudRateSelect", this->baud_rate_select_);
219
+ ESP_LOGCONFIG(TAG, "Text Sensors:");
220
+ LOG_TEXT_SENSOR(" ", "Mac", this->mac_text_sensor_);
221
+ LOG_TEXT_SENSOR(" ", "Version", this->version_text_sensor_);
61
222
  #endif
62
223
  #ifdef USE_NUMBER
63
- LOG_NUMBER(" ", "LightThresholdNumber", this->light_threshold_number_);
64
- LOG_NUMBER(" ", "MaxStillDistanceGateNumber", this->max_still_distance_gate_number_);
65
- LOG_NUMBER(" ", "MaxMoveDistanceGateNumber", this->max_move_distance_gate_number_);
66
- LOG_NUMBER(" ", "TimeoutNumber", this->timeout_number_);
67
- for (number::Number *n : this->gate_still_threshold_numbers_) {
68
- LOG_NUMBER(" ", "Still Thresholds Number", n);
69
- }
224
+ ESP_LOGCONFIG(TAG, "Numbers:");
225
+ LOG_NUMBER(" ", "LightThreshold", this->light_threshold_number_);
226
+ LOG_NUMBER(" ", "MaxMoveDistanceGate", this->max_move_distance_gate_number_);
227
+ LOG_NUMBER(" ", "MaxStillDistanceGate", this->max_still_distance_gate_number_);
228
+ LOG_NUMBER(" ", "Timeout", this->timeout_number_);
70
229
  for (number::Number *n : this->gate_move_threshold_numbers_) {
71
- LOG_NUMBER(" ", "Move Thresholds Number", n);
230
+ LOG_NUMBER(" ", "MoveThreshold", n);
231
+ }
232
+ for (number::Number *n : this->gate_still_threshold_numbers_) {
233
+ LOG_NUMBER(" ", "StillThreshold", n);
72
234
  }
73
235
  #endif
74
- this->read_all_info();
75
- ESP_LOGCONFIG(TAG,
76
- " Throttle_ : %ums\n"
77
- " MAC Address : %s\n"
78
- " Firmware Version : %s",
79
- this->throttle_, const_cast<char *>(this->mac_.c_str()), const_cast<char *>(this->version_.c_str()));
236
+ #ifdef USE_SELECT
237
+ ESP_LOGCONFIG(TAG, "Selects:");
238
+ LOG_SELECT(" ", "BaudRate", this->baud_rate_select_);
239
+ LOG_SELECT(" ", "DistanceResolution", this->distance_resolution_select_);
240
+ LOG_SELECT(" ", "LightFunction", this->light_function_select_);
241
+ LOG_SELECT(" ", "OutPinLevel", this->out_pin_level_select_);
242
+ #endif
243
+ #ifdef USE_SWITCH
244
+ ESP_LOGCONFIG(TAG, "Switches:");
245
+ LOG_SWITCH(" ", "Bluetooth", this->bluetooth_switch_);
246
+ LOG_SWITCH(" ", "EngineeringMode", this->engineering_mode_switch_);
247
+ #endif
248
+ #ifdef USE_BUTTON
249
+ ESP_LOGCONFIG(TAG, "Buttons:");
250
+ LOG_BUTTON(" ", "FactoryReset", this->factory_reset_button_);
251
+ LOG_BUTTON(" ", "Query", this->query_button_);
252
+ LOG_BUTTON(" ", "Restart", this->restart_button_);
253
+ #endif
80
254
  }
81
255
 
82
256
  void LD2410Component::setup() {
@@ -89,12 +263,12 @@ void LD2410Component::read_all_info() {
89
263
  this->get_version_();
90
264
  this->get_mac_();
91
265
  this->get_distance_resolution_();
92
- this->get_light_control_();
266
+ this->query_light_control_();
93
267
  this->query_parameters_();
94
268
  this->set_config_mode_(false);
95
269
  #ifdef USE_SELECT
96
270
  const auto baud_rate = std::to_string(this->parent_->get_baud_rate());
97
- if (this->baud_rate_select_ != nullptr && this->baud_rate_select_->state != baud_rate) {
271
+ if (this->baud_rate_select_ != nullptr) {
98
272
  this->baud_rate_select_->publish_state(baud_rate);
99
273
  }
100
274
  #endif
@@ -107,66 +281,57 @@ void LD2410Component::restart_and_read_all_info() {
107
281
  }
108
282
 
109
283
  void LD2410Component::loop() {
110
- const int max_line_length = 80;
111
- static uint8_t buffer[max_line_length];
112
-
113
- while (available()) {
114
- this->readline_(read(), buffer, max_line_length);
284
+ while (this->available()) {
285
+ this->readline_(this->read());
115
286
  }
116
287
  }
117
288
 
118
- void LD2410Component::send_command_(uint8_t command, const uint8_t *command_value, int command_value_len) {
289
+ void LD2410Component::send_command_(uint8_t command, const uint8_t *command_value, uint8_t command_value_len) {
119
290
  ESP_LOGV(TAG, "Sending COMMAND %02X", command);
120
- // frame start bytes
121
- this->write_array(CMD_FRAME_HEADER, 4);
291
+ // frame header bytes
292
+ this->write_array(CMD_FRAME_HEADER, sizeof(CMD_FRAME_HEADER));
122
293
  // length bytes
123
- int len = 2;
124
- if (command_value != nullptr)
294
+ uint8_t len = 2;
295
+ if (command_value != nullptr) {
125
296
  len += command_value_len;
126
- this->write_byte(lowbyte(len));
127
- this->write_byte(highbyte(len));
128
-
129
- // command
130
- this->write_byte(lowbyte(command));
131
- this->write_byte(highbyte(command));
132
-
297
+ }
298
+ // 2 length bytes (low, high) + 2 command bytes (low, high)
299
+ uint8_t len_cmd[] = {len, 0x00, command, 0x00};
300
+ this->write_array(len_cmd, sizeof(len_cmd));
133
301
  // command value bytes
134
302
  if (command_value != nullptr) {
135
- for (int i = 0; i < command_value_len; i++) {
136
- this->write_byte(command_value[i]);
137
- }
303
+ this->write_array(command_value, command_value_len);
138
304
  }
139
- // frame end bytes
140
- this->write_array(CMD_FRAME_END, 4);
305
+ // frame footer bytes
306
+ this->write_array(CMD_FRAME_FOOTER, sizeof(CMD_FRAME_FOOTER));
141
307
  // FIXME to remove
142
308
  delay(50); // NOLINT
143
309
  }
144
310
 
145
- void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) {
146
- if (len < 12)
147
- return; // 4 frame start bytes + 2 length bytes + 1 data end byte + 1 crc byte + 4 frame end bytes
148
- if (buffer[0] != 0xF4 || buffer[1] != 0xF3 || buffer[2] != 0xF2 || buffer[3] != 0xF1) // check 4 frame start bytes
311
+ void LD2410Component::handle_periodic_data_() {
312
+ // Reduce data update rate to reduce home assistant database growth
313
+ // Check this first to prevent unnecessary processing done in later checks/parsing
314
+ if (App.get_loop_component_start_time() - this->last_periodic_millis_ < this->throttle_) {
149
315
  return;
150
- if (buffer[7] != HEAD || buffer[len - 6] != END || buffer[len - 5] != CHECK) // Check constant values
151
- return; // data head=0xAA, data end=0x55, crc=0x00
152
-
153
- /*
154
- Reduce data update rate to prevent home assistant database size grow fast
155
- */
156
- int32_t current_millis = millis();
157
- if (current_millis - last_periodic_millis_ < this->throttle_)
316
+ }
317
+ // 4 frame header bytes + 2 length bytes + 1 data end byte + 1 crc byte + 4 frame footer bytes
318
+ // data header=0xAA, data footer=0x55, crc=0x00
319
+ if (this->buffer_pos_ < 12 || !ld2410::validate_header_footer(DATA_FRAME_HEADER, this->buffer_data_) ||
320
+ this->buffer_data_[7] != HEADER || this->buffer_data_[this->buffer_pos_ - 6] != FOOTER ||
321
+ this->buffer_data_[this->buffer_pos_ - 5] != CHECK) {
158
322
  return;
159
- last_periodic_millis_ = current_millis;
323
+ }
324
+ // Save the timestamp after validating the frame so, if invalid, we'll take the next frame immediately
325
+ this->last_periodic_millis_ = App.get_loop_component_start_time();
160
326
 
161
327
  /*
162
328
  Data Type: 7th
163
329
  0x01: Engineering mode
164
330
  0x02: Normal mode
165
331
  */
166
- bool engineering_mode = buffer[DATA_TYPES] == 0x01;
332
+ bool engineering_mode = this->buffer_data_[DATA_TYPES] == 0x01;
167
333
  #ifdef USE_SWITCH
168
- if (this->engineering_mode_switch_ != nullptr &&
169
- current_millis - last_engineering_mode_change_millis_ > this->throttle_) {
334
+ if (this->engineering_mode_switch_ != nullptr) {
170
335
  this->engineering_mode_switch_->publish_state(engineering_mode);
171
336
  }
172
337
  #endif
@@ -178,7 +343,7 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) {
178
343
  0x02 = Still targets
179
344
  0x03 = Moving+Still targets
180
345
  */
181
- char target_state = buffer[TARGET_STATES];
346
+ char target_state = this->buffer_data_[TARGET_STATES];
182
347
  if (this->target_binary_sensor_ != nullptr) {
183
348
  this->target_binary_sensor_->publish_state(target_state != 0x00);
184
349
  }
@@ -198,27 +363,30 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) {
198
363
  */
199
364
  #ifdef USE_SENSOR
200
365
  if (this->moving_target_distance_sensor_ != nullptr) {
201
- int new_moving_target_distance = this->two_byte_to_int_(buffer[MOVING_TARGET_LOW], buffer[MOVING_TARGET_HIGH]);
366
+ int new_moving_target_distance =
367
+ ld2410::two_byte_to_int(this->buffer_data_[MOVING_TARGET_LOW], this->buffer_data_[MOVING_TARGET_HIGH]);
202
368
  if (this->moving_target_distance_sensor_->get_state() != new_moving_target_distance)
203
369
  this->moving_target_distance_sensor_->publish_state(new_moving_target_distance);
204
370
  }
205
371
  if (this->moving_target_energy_sensor_ != nullptr) {
206
- int new_moving_target_energy = buffer[MOVING_ENERGY];
372
+ int new_moving_target_energy = this->buffer_data_[MOVING_ENERGY];
207
373
  if (this->moving_target_energy_sensor_->get_state() != new_moving_target_energy)
208
374
  this->moving_target_energy_sensor_->publish_state(new_moving_target_energy);
209
375
  }
210
376
  if (this->still_target_distance_sensor_ != nullptr) {
211
- int new_still_target_distance = this->two_byte_to_int_(buffer[STILL_TARGET_LOW], buffer[STILL_TARGET_HIGH]);
377
+ int new_still_target_distance =
378
+ ld2410::two_byte_to_int(this->buffer_data_[STILL_TARGET_LOW], this->buffer_data_[STILL_TARGET_HIGH]);
212
379
  if (this->still_target_distance_sensor_->get_state() != new_still_target_distance)
213
380
  this->still_target_distance_sensor_->publish_state(new_still_target_distance);
214
381
  }
215
382
  if (this->still_target_energy_sensor_ != nullptr) {
216
- int new_still_target_energy = buffer[STILL_ENERGY];
383
+ int new_still_target_energy = this->buffer_data_[STILL_ENERGY];
217
384
  if (this->still_target_energy_sensor_->get_state() != new_still_target_energy)
218
385
  this->still_target_energy_sensor_->publish_state(new_still_target_energy);
219
386
  }
220
387
  if (this->detection_distance_sensor_ != nullptr) {
221
- int new_detect_distance = this->two_byte_to_int_(buffer[DETECT_DISTANCE_LOW], buffer[DETECT_DISTANCE_HIGH]);
388
+ int new_detect_distance =
389
+ ld2410::two_byte_to_int(this->buffer_data_[DETECT_DISTANCE_LOW], this->buffer_data_[DETECT_DISTANCE_HIGH]);
222
390
  if (this->detection_distance_sensor_->get_state() != new_detect_distance)
223
391
  this->detection_distance_sensor_->publish_state(new_detect_distance);
224
392
  }
@@ -226,12 +394,12 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) {
226
394
  /*
227
395
  Moving distance range: 18th byte
228
396
  Still distance range: 19th byte
229
- Moving enery: 20~28th bytes
397
+ Moving energy: 20~28th bytes
230
398
  */
231
399
  for (std::vector<sensor::Sensor *>::size_type i = 0; i != this->gate_move_sensors_.size(); i++) {
232
400
  sensor::Sensor *s = this->gate_move_sensors_[i];
233
401
  if (s != nullptr) {
234
- s->publish_state(buffer[MOVING_SENSOR_START + i]);
402
+ s->publish_state(this->buffer_data_[MOVING_SENSOR_START + i]);
235
403
  }
236
404
  }
237
405
  /*
@@ -240,16 +408,17 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) {
240
408
  for (std::vector<sensor::Sensor *>::size_type i = 0; i != this->gate_still_sensors_.size(); i++) {
241
409
  sensor::Sensor *s = this->gate_still_sensors_[i];
242
410
  if (s != nullptr) {
243
- s->publish_state(buffer[STILL_SENSOR_START + i]);
411
+ s->publish_state(this->buffer_data_[STILL_SENSOR_START + i]);
244
412
  }
245
413
  }
246
414
  /*
247
415
  Light sensor: 38th bytes
248
416
  */
249
417
  if (this->light_sensor_ != nullptr) {
250
- int new_light_sensor = buffer[LIGHT_SENSOR];
251
- if (this->light_sensor_->get_state() != new_light_sensor)
418
+ int new_light_sensor = this->buffer_data_[LIGHT_SENSOR];
419
+ if (this->light_sensor_->get_state() != new_light_sensor) {
252
420
  this->light_sensor_->publish_state(new_light_sensor);
421
+ }
253
422
  }
254
423
  } else {
255
424
  for (auto *s : this->gate_move_sensors_) {
@@ -270,7 +439,7 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) {
270
439
  #ifdef USE_BINARY_SENSOR
271
440
  if (engineering_mode) {
272
441
  if (this->out_pin_presence_status_binary_sensor_ != nullptr) {
273
- this->out_pin_presence_status_binary_sensor_->publish_state(buffer[OUT_PIN_SENSOR] == 0x01);
442
+ this->out_pin_presence_status_binary_sensor_->publish_state(this->buffer_data_[OUT_PIN_SENSOR] == 0x01);
274
443
  }
275
444
  } else {
276
445
  if (this->out_pin_presence_status_binary_sensor_ != nullptr) {
@@ -280,163 +449,151 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) {
280
449
  #endif
281
450
  }
282
451
 
283
- const char VERSION_FMT[] = "%u.%02X.%02X%02X%02X%02X";
284
-
285
- std::string format_version(uint8_t *buffer) {
286
- std::string::size_type version_size = 256;
287
- std::string version;
288
- do {
289
- version.resize(version_size + 1);
290
- version_size = std::snprintf(&version[0], version.size(), VERSION_FMT, buffer[13], buffer[12], buffer[17],
291
- buffer[16], buffer[15], buffer[14]);
292
- } while (version_size + 1 > version.size());
293
- version.resize(version_size);
294
- return version;
295
- }
296
-
297
- const char MAC_FMT[] = "%02X:%02X:%02X:%02X:%02X:%02X";
298
-
299
- const std::string UNKNOWN_MAC("unknown");
300
- const std::string NO_MAC("08:05:04:03:02:01");
301
-
302
- std::string format_mac(uint8_t *buffer) {
303
- std::string::size_type mac_size = 256;
304
- std::string mac;
305
- do {
306
- mac.resize(mac_size + 1);
307
- mac_size = std::snprintf(&mac[0], mac.size(), MAC_FMT, buffer[10], buffer[11], buffer[12], buffer[13], buffer[14],
308
- buffer[15]);
309
- } while (mac_size + 1 > mac.size());
310
- mac.resize(mac_size);
311
- if (mac == NO_MAC) {
312
- return UNKNOWN_MAC;
313
- }
314
- return mac;
315
- }
316
-
317
452
  #ifdef USE_NUMBER
318
453
  std::function<void(void)> set_number_value(number::Number *n, float value) {
319
- float normalized_value = value * 1.0;
320
- if (n != nullptr && (!n->has_state() || n->state != normalized_value)) {
321
- n->state = normalized_value;
322
- return [n, normalized_value]() { n->publish_state(normalized_value); };
454
+ if (n != nullptr && (!n->has_state() || n->state != value)) {
455
+ n->state = value;
456
+ return [n, value]() { n->publish_state(value); };
323
457
  }
324
458
  return []() {};
325
459
  }
326
460
  #endif
327
461
 
328
- bool LD2410Component::handle_ack_data_(uint8_t *buffer, int len) {
329
- ESP_LOGV(TAG, "Handling ACK DATA for COMMAND %02X", buffer[COMMAND]);
330
- if (len < 10) {
331
- ESP_LOGE(TAG, "Error with last command : incorrect length");
462
+ bool LD2410Component::handle_ack_data_() {
463
+ ESP_LOGV(TAG, "Handling ACK DATA for COMMAND %02X", this->buffer_data_[COMMAND]);
464
+ if (this->buffer_pos_ < 10) {
465
+ ESP_LOGE(TAG, "Invalid length");
332
466
  return true;
333
467
  }
334
- if (buffer[0] != 0xFD || buffer[1] != 0xFC || buffer[2] != 0xFB || buffer[3] != 0xFA) { // check 4 frame start bytes
335
- ESP_LOGE(TAG, "Error with last command : incorrect Header");
468
+ if (!ld2410::validate_header_footer(CMD_FRAME_HEADER, this->buffer_data_)) {
469
+ ESP_LOGW(TAG, "Invalid header: %s", format_hex_pretty(this->buffer_data_, HEADER_FOOTER_SIZE).c_str());
336
470
  return true;
337
471
  }
338
- if (buffer[COMMAND_STATUS] != 0x01) {
339
- ESP_LOGE(TAG, "Error with last command : status != 0x01");
472
+ if (this->buffer_data_[COMMAND_STATUS] != 0x01) {
473
+ ESP_LOGE(TAG, "Invalid status");
340
474
  return true;
341
475
  }
342
- if (this->two_byte_to_int_(buffer[8], buffer[9]) != 0x00) {
343
- ESP_LOGE(TAG, "Error with last command , last buffer was: %u , %u", buffer[8], buffer[9]);
476
+ if (this->buffer_data_[8] || this->buffer_data_[9]) {
477
+ ESP_LOGW(TAG, "Invalid command: %02X, %02X", this->buffer_data_[8], this->buffer_data_[9]);
344
478
  return true;
345
479
  }
346
480
 
347
- switch (buffer[COMMAND]) {
348
- case lowbyte(CMD_ENABLE_CONF):
349
- ESP_LOGV(TAG, "Handled Enable conf command");
481
+ switch (this->buffer_data_[COMMAND]) {
482
+ case CMD_ENABLE_CONF:
483
+ ESP_LOGV(TAG, "Enable conf");
350
484
  break;
351
- case lowbyte(CMD_DISABLE_CONF):
352
- ESP_LOGV(TAG, "Handled Disabled conf command");
485
+
486
+ case CMD_DISABLE_CONF:
487
+ ESP_LOGV(TAG, "Disabled conf");
353
488
  break;
354
- case lowbyte(CMD_SET_BAUD_RATE):
355
- ESP_LOGV(TAG, "Handled baud rate change command");
489
+
490
+ case CMD_SET_BAUD_RATE:
491
+ ESP_LOGV(TAG, "Baud rate change");
356
492
  #ifdef USE_SELECT
357
493
  if (this->baud_rate_select_ != nullptr) {
358
- ESP_LOGE(TAG, "Change baud rate component config to %s and reinstall", this->baud_rate_select_->state.c_str());
494
+ ESP_LOGE(TAG, "Change baud rate to %s and reinstall", this->baud_rate_select_->state.c_str());
359
495
  }
360
496
  #endif
361
497
  break;
362
- case lowbyte(CMD_VERSION):
363
- this->version_ = format_version(buffer);
364
- ESP_LOGV(TAG, "FW Version is: %s", const_cast<char *>(this->version_.c_str()));
498
+
499
+ case CMD_QUERY_VERSION: {
500
+ std::memcpy(this->version_, &this->buffer_data_[12], sizeof(this->version_));
501
+ std::string version = str_sprintf(VERSION_FMT, this->version_[1], this->version_[0], this->version_[5],
502
+ this->version_[4], this->version_[3], this->version_[2]);
503
+ ESP_LOGV(TAG, "Firmware version: %s", version.c_str());
365
504
  #ifdef USE_TEXT_SENSOR
366
505
  if (this->version_text_sensor_ != nullptr) {
367
- this->version_text_sensor_->publish_state(this->version_);
506
+ this->version_text_sensor_->publish_state(version);
368
507
  }
369
508
  #endif
370
509
  break;
371
- case lowbyte(CMD_QUERY_DISTANCE_RESOLUTION): {
372
- std::string distance_resolution =
373
- DISTANCE_RESOLUTION_INT_TO_ENUM.at(this->two_byte_to_int_(buffer[10], buffer[11]));
374
- ESP_LOGV(TAG, "Distance resolution is: %s", const_cast<char *>(distance_resolution.c_str()));
510
+ }
511
+
512
+ case CMD_QUERY_DISTANCE_RESOLUTION: {
513
+ const auto *distance_resolution = find_str(DISTANCE_RESOLUTIONS_BY_UINT, this->buffer_data_[10]);
514
+ ESP_LOGV(TAG, "Distance resolution: %s", distance_resolution);
375
515
  #ifdef USE_SELECT
376
- if (this->distance_resolution_select_ != nullptr &&
377
- this->distance_resolution_select_->state != distance_resolution) {
516
+ if (this->distance_resolution_select_ != nullptr) {
378
517
  this->distance_resolution_select_->publish_state(distance_resolution);
379
518
  }
380
519
  #endif
381
- } break;
382
- case lowbyte(CMD_QUERY_LIGHT_CONTROL): {
383
- this->light_function_ = LIGHT_FUNCTION_INT_TO_ENUM.at(buffer[10]);
384
- this->light_threshold_ = buffer[11] * 1.0;
385
- this->out_pin_level_ = OUT_PIN_LEVEL_INT_TO_ENUM.at(buffer[12]);
386
- ESP_LOGV(TAG, "Light function is: %s", const_cast<char *>(this->light_function_.c_str()));
387
- ESP_LOGV(TAG, "Light threshold is: %f", this->light_threshold_);
388
- ESP_LOGV(TAG, "Out pin level is: %s", const_cast<char *>(this->out_pin_level_.c_str()));
520
+ break;
521
+ }
522
+
523
+ case CMD_QUERY_LIGHT_CONTROL: {
524
+ this->light_function_ = this->buffer_data_[10];
525
+ this->light_threshold_ = this->buffer_data_[11];
526
+ this->out_pin_level_ = this->buffer_data_[12];
527
+ const auto *light_function_str = find_str(LIGHT_FUNCTIONS_BY_UINT, this->light_function_);
528
+ const auto *out_pin_level_str = find_str(OUT_PIN_LEVELS_BY_UINT, this->out_pin_level_);
529
+ ESP_LOGV(TAG,
530
+ "Light function: %s\n"
531
+ "Light threshold: %u\n"
532
+ "Out pin level: %s",
533
+ light_function_str, this->light_threshold_, out_pin_level_str);
389
534
  #ifdef USE_SELECT
390
- if (this->light_function_select_ != nullptr && this->light_function_select_->state != this->light_function_) {
391
- this->light_function_select_->publish_state(this->light_function_);
535
+ if (this->light_function_select_ != nullptr) {
536
+ this->light_function_select_->publish_state(light_function_str);
392
537
  }
393
- if (this->out_pin_level_select_ != nullptr && this->out_pin_level_select_->state != this->out_pin_level_) {
394
- this->out_pin_level_select_->publish_state(this->out_pin_level_);
538
+ if (this->out_pin_level_select_ != nullptr) {
539
+ this->out_pin_level_select_->publish_state(out_pin_level_str);
395
540
  }
396
541
  #endif
397
542
  #ifdef USE_NUMBER
398
- if (this->light_threshold_number_ != nullptr &&
399
- (!this->light_threshold_number_->has_state() ||
400
- this->light_threshold_number_->state != this->light_threshold_)) {
401
- this->light_threshold_number_->publish_state(this->light_threshold_);
543
+ if (this->light_threshold_number_ != nullptr) {
544
+ this->light_threshold_number_->publish_state(static_cast<float>(this->light_threshold_));
402
545
  }
403
546
  #endif
404
- } break;
405
- case lowbyte(CMD_MAC):
406
- if (len < 20) {
547
+ break;
548
+ }
549
+ case CMD_QUERY_MAC_ADDRESS: {
550
+ if (this->buffer_pos_ < 20) {
407
551
  return false;
408
552
  }
409
- this->mac_ = format_mac(buffer);
410
- ESP_LOGV(TAG, "MAC Address is: %s", const_cast<char *>(this->mac_.c_str()));
553
+
554
+ this->bluetooth_on_ = std::memcmp(&this->buffer_data_[10], NO_MAC, sizeof(NO_MAC)) != 0;
555
+ if (this->bluetooth_on_) {
556
+ std::memcpy(this->mac_address_, &this->buffer_data_[10], sizeof(this->mac_address_));
557
+ }
558
+
559
+ std::string mac_str =
560
+ mac_address_is_valid(this->mac_address_) ? format_mac_address_pretty(this->mac_address_) : UNKNOWN_MAC;
561
+ ESP_LOGV(TAG, "MAC address: %s", mac_str.c_str());
411
562
  #ifdef USE_TEXT_SENSOR
412
563
  if (this->mac_text_sensor_ != nullptr) {
413
- this->mac_text_sensor_->publish_state(this->mac_);
564
+ this->mac_text_sensor_->publish_state(mac_str);
414
565
  }
415
566
  #endif
416
567
  #ifdef USE_SWITCH
417
568
  if (this->bluetooth_switch_ != nullptr) {
418
- this->bluetooth_switch_->publish_state(this->mac_ != UNKNOWN_MAC);
569
+ this->bluetooth_switch_->publish_state(this->bluetooth_on_);
419
570
  }
420
571
  #endif
421
572
  break;
422
- case lowbyte(CMD_GATE_SENS):
423
- ESP_LOGV(TAG, "Handled sensitivity command");
573
+ }
574
+
575
+ case CMD_GATE_SENS:
576
+ ESP_LOGV(TAG, "Sensitivity");
424
577
  break;
425
- case lowbyte(CMD_BLUETOOTH):
426
- ESP_LOGV(TAG, "Handled bluetooth command");
578
+
579
+ case CMD_BLUETOOTH:
580
+ ESP_LOGV(TAG, "Bluetooth");
427
581
  break;
428
- case lowbyte(CMD_SET_DISTANCE_RESOLUTION):
429
- ESP_LOGV(TAG, "Handled set distance resolution command");
582
+
583
+ case CMD_SET_DISTANCE_RESOLUTION:
584
+ ESP_LOGV(TAG, "Set distance resolution");
430
585
  break;
431
- case lowbyte(CMD_SET_LIGHT_CONTROL):
432
- ESP_LOGV(TAG, "Handled set light control command");
586
+
587
+ case CMD_SET_LIGHT_CONTROL:
588
+ ESP_LOGV(TAG, "Set light control");
433
589
  break;
434
- case lowbyte(CMD_BT_PASSWORD):
435
- ESP_LOGV(TAG, "Handled set bluetooth password command");
590
+
591
+ case CMD_BT_PASSWORD:
592
+ ESP_LOGV(TAG, "Set bluetooth password");
436
593
  break;
437
- case lowbyte(CMD_QUERY): // Query parameters response
438
- {
439
- if (buffer[10] != 0xAA)
594
+
595
+ case CMD_QUERY: { // Query parameters response
596
+ if (this->buffer_data_[10] != HEADER)
440
597
  return true; // value head=0xAA
441
598
  #ifdef USE_NUMBER
442
599
  /*
@@ -444,29 +601,31 @@ bool LD2410Component::handle_ack_data_(uint8_t *buffer, int len) {
444
601
  Still distance range: 14th byte
445
602
  */
446
603
  std::vector<std::function<void(void)>> updates;
447
- updates.push_back(set_number_value(this->max_move_distance_gate_number_, buffer[12]));
448
- updates.push_back(set_number_value(this->max_still_distance_gate_number_, buffer[13]));
604
+ updates.push_back(set_number_value(this->max_move_distance_gate_number_, this->buffer_data_[12]));
605
+ updates.push_back(set_number_value(this->max_still_distance_gate_number_, this->buffer_data_[13]));
449
606
  /*
450
607
  Moving Sensitivities: 15~23th bytes
451
608
  */
452
609
  for (std::vector<number::Number *>::size_type i = 0; i != this->gate_move_threshold_numbers_.size(); i++) {
453
- updates.push_back(set_number_value(this->gate_move_threshold_numbers_[i], buffer[14 + i]));
610
+ updates.push_back(set_number_value(this->gate_move_threshold_numbers_[i], this->buffer_data_[14 + i]));
454
611
  }
455
612
  /*
456
613
  Still Sensitivities: 24~32th bytes
457
614
  */
458
615
  for (std::vector<number::Number *>::size_type i = 0; i != this->gate_still_threshold_numbers_.size(); i++) {
459
- updates.push_back(set_number_value(this->gate_still_threshold_numbers_[i], buffer[23 + i]));
616
+ updates.push_back(set_number_value(this->gate_still_threshold_numbers_[i], this->buffer_data_[23 + i]));
460
617
  }
461
618
  /*
462
619
  None Duration: 33~34th bytes
463
620
  */
464
- updates.push_back(set_number_value(this->timeout_number_, this->two_byte_to_int_(buffer[32], buffer[33])));
621
+ updates.push_back(set_number_value(this->timeout_number_,
622
+ ld2410::two_byte_to_int(this->buffer_data_[32], this->buffer_data_[33])));
465
623
  for (auto &update : updates) {
466
624
  update();
467
625
  }
468
626
  #endif
469
- } break;
627
+ break;
628
+ }
470
629
  default:
471
630
  break;
472
631
  }
@@ -474,78 +633,78 @@ bool LD2410Component::handle_ack_data_(uint8_t *buffer, int len) {
474
633
  return true;
475
634
  }
476
635
 
477
- void LD2410Component::readline_(int readch, uint8_t *buffer, int len) {
478
- static int pos = 0;
636
+ void LD2410Component::readline_(int readch) {
637
+ if (readch < 0) {
638
+ return; // No data available
639
+ }
479
640
 
480
- if (readch >= 0) {
481
- if (pos < len - 1) {
482
- buffer[pos++] = readch;
483
- buffer[pos] = 0;
641
+ if (this->buffer_pos_ < MAX_LINE_LENGTH - 1) {
642
+ this->buffer_data_[this->buffer_pos_++] = readch;
643
+ this->buffer_data_[this->buffer_pos_] = 0;
644
+ } else {
645
+ // We should never get here, but just in case...
646
+ ESP_LOGW(TAG, "Max command length exceeded; ignoring");
647
+ this->buffer_pos_ = 0;
648
+ }
649
+ if (this->buffer_pos_ < 4) {
650
+ return; // Not enough data to process yet
651
+ }
652
+ if (ld2410::validate_header_footer(DATA_FRAME_FOOTER, &this->buffer_data_[this->buffer_pos_ - 4])) {
653
+ ESP_LOGV(TAG, "Handling Periodic Data: %s", format_hex_pretty(this->buffer_data_, this->buffer_pos_).c_str());
654
+ this->handle_periodic_data_();
655
+ this->buffer_pos_ = 0; // Reset position index for next message
656
+ } else if (ld2410::validate_header_footer(CMD_FRAME_FOOTER, &this->buffer_data_[this->buffer_pos_ - 4])) {
657
+ ESP_LOGV(TAG, "Handling Ack Data: %s", format_hex_pretty(this->buffer_data_, this->buffer_pos_).c_str());
658
+ if (this->handle_ack_data_()) {
659
+ this->buffer_pos_ = 0; // Reset position index for next message
484
660
  } else {
485
- pos = 0;
486
- }
487
- if (pos >= 4) {
488
- if (buffer[pos - 4] == 0xF8 && buffer[pos - 3] == 0xF7 && buffer[pos - 2] == 0xF6 && buffer[pos - 1] == 0xF5) {
489
- ESP_LOGV(TAG, "Will handle Periodic Data");
490
- this->handle_periodic_data_(buffer, pos);
491
- pos = 0; // Reset position index ready for next time
492
- } else if (buffer[pos - 4] == 0x04 && buffer[pos - 3] == 0x03 && buffer[pos - 2] == 0x02 &&
493
- buffer[pos - 1] == 0x01) {
494
- ESP_LOGV(TAG, "Will handle ACK Data");
495
- if (this->handle_ack_data_(buffer, pos)) {
496
- pos = 0; // Reset position index ready for next time
497
- } else {
498
- ESP_LOGV(TAG, "ACK Data incomplete");
499
- }
500
- }
661
+ ESP_LOGV(TAG, "Ack Data incomplete");
501
662
  }
502
663
  }
503
664
  }
504
665
 
505
666
  void LD2410Component::set_config_mode_(bool enable) {
506
- uint8_t cmd = enable ? CMD_ENABLE_CONF : CMD_DISABLE_CONF;
507
- uint8_t cmd_value[2] = {0x01, 0x00};
508
- this->send_command_(cmd, enable ? cmd_value : nullptr, 2);
667
+ const uint8_t cmd = enable ? CMD_ENABLE_CONF : CMD_DISABLE_CONF;
668
+ const uint8_t cmd_value[2] = {0x01, 0x00};
669
+ this->send_command_(cmd, enable ? cmd_value : nullptr, sizeof(cmd_value));
509
670
  }
510
671
 
511
672
  void LD2410Component::set_bluetooth(bool enable) {
512
673
  this->set_config_mode_(true);
513
- uint8_t enable_cmd_value[2] = {0x01, 0x00};
514
- uint8_t disable_cmd_value[2] = {0x00, 0x00};
515
- this->send_command_(CMD_BLUETOOTH, enable ? enable_cmd_value : disable_cmd_value, 2);
674
+ const uint8_t cmd_value[2] = {enable ? (uint8_t) 0x01 : (uint8_t) 0x00, 0x00};
675
+ this->send_command_(CMD_BLUETOOTH, cmd_value, sizeof(cmd_value));
516
676
  this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
517
677
  }
518
678
 
519
679
  void LD2410Component::set_distance_resolution(const std::string &state) {
520
680
  this->set_config_mode_(true);
521
- uint8_t cmd_value[2] = {DISTANCE_RESOLUTION_ENUM_TO_INT.at(state), 0x00};
522
- this->send_command_(CMD_SET_DISTANCE_RESOLUTION, cmd_value, 2);
681
+ const uint8_t cmd_value[2] = {find_uint8(DISTANCE_RESOLUTIONS_BY_STR, state), 0x00};
682
+ this->send_command_(CMD_SET_DISTANCE_RESOLUTION, cmd_value, sizeof(cmd_value));
523
683
  this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
524
684
  }
525
685
 
526
686
  void LD2410Component::set_baud_rate(const std::string &state) {
527
687
  this->set_config_mode_(true);
528
- uint8_t cmd_value[2] = {BAUD_RATE_ENUM_TO_INT.at(state), 0x00};
529
- this->send_command_(CMD_SET_BAUD_RATE, cmd_value, 2);
688
+ const uint8_t cmd_value[2] = {find_uint8(BAUD_RATES_BY_STR, state), 0x00};
689
+ this->send_command_(CMD_SET_BAUD_RATE, cmd_value, sizeof(cmd_value));
530
690
  this->set_timeout(200, [this]() { this->restart_(); });
531
691
  }
532
692
 
533
693
  void LD2410Component::set_bluetooth_password(const std::string &password) {
534
694
  if (password.length() != 6) {
535
- ESP_LOGE(TAG, "set_bluetooth_password(): invalid password length, must be exactly 6 chars '%s'", password.c_str());
695
+ ESP_LOGE(TAG, "Password must be exactly 6 chars");
536
696
  return;
537
697
  }
538
698
  this->set_config_mode_(true);
539
699
  uint8_t cmd_value[6];
540
700
  std::copy(password.begin(), password.end(), std::begin(cmd_value));
541
- this->send_command_(CMD_BT_PASSWORD, cmd_value, 6);
701
+ this->send_command_(CMD_BT_PASSWORD, cmd_value, sizeof(cmd_value));
542
702
  this->set_config_mode_(false);
543
703
  }
544
704
 
545
705
  void LD2410Component::set_engineering_mode(bool enable) {
706
+ const uint8_t cmd = enable ? CMD_ENABLE_ENG : CMD_DISABLE_ENG;
546
707
  this->set_config_mode_(true);
547
- last_engineering_mode_change_millis_ = millis();
548
- uint8_t cmd = enable ? CMD_ENABLE_ENG : CMD_DISABLE_ENG;
549
708
  this->send_command_(cmd, nullptr, 0);
550
709
  this->set_config_mode_(false);
551
710
  }
@@ -559,14 +718,17 @@ void LD2410Component::factory_reset() {
559
718
  void LD2410Component::restart_() { this->send_command_(CMD_RESTART, nullptr, 0); }
560
719
 
561
720
  void LD2410Component::query_parameters_() { this->send_command_(CMD_QUERY, nullptr, 0); }
562
- void LD2410Component::get_version_() { this->send_command_(CMD_VERSION, nullptr, 0); }
721
+
722
+ void LD2410Component::get_version_() { this->send_command_(CMD_QUERY_VERSION, nullptr, 0); }
723
+
563
724
  void LD2410Component::get_mac_() {
564
- uint8_t cmd_value[2] = {0x01, 0x00};
565
- this->send_command_(CMD_MAC, cmd_value, 2);
725
+ const uint8_t cmd_value[2] = {0x01, 0x00};
726
+ this->send_command_(CMD_QUERY_MAC_ADDRESS, cmd_value, sizeof(cmd_value));
566
727
  }
728
+
567
729
  void LD2410Component::get_distance_resolution_() { this->send_command_(CMD_QUERY_DISTANCE_RESOLUTION, nullptr, 0); }
568
730
 
569
- void LD2410Component::get_light_control_() { this->send_command_(CMD_QUERY_LIGHT_CONTROL, nullptr, 0); }
731
+ void LD2410Component::query_light_control_() { this->send_command_(CMD_QUERY_LIGHT_CONTROL, nullptr, 0); }
570
732
 
571
733
  #ifdef USE_NUMBER
572
734
  void LD2410Component::set_max_distances_timeout() {
@@ -596,8 +758,7 @@ void LD2410Component::set_max_distances_timeout() {
596
758
  0x00,
597
759
  0x00};
598
760
  this->set_config_mode_(true);
599
- this->send_command_(CMD_MAXDIST_DURATION, value, 18);
600
- delay(50); // NOLINT
761
+ this->send_command_(CMD_MAXDIST_DURATION, value, sizeof(value));
601
762
  this->query_parameters_();
602
763
  this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
603
764
  this->set_config_mode_(false);
@@ -626,17 +787,16 @@ void LD2410Component::set_gate_threshold(uint8_t gate) {
626
787
  uint8_t value[18] = {0x00, 0x00, lowbyte(gate), highbyte(gate), 0x00, 0x00,
627
788
  0x01, 0x00, lowbyte(motion), highbyte(motion), 0x00, 0x00,
628
789
  0x02, 0x00, lowbyte(still), highbyte(still), 0x00, 0x00};
629
- this->send_command_(CMD_GATE_SENS, value, 18);
630
- delay(50); // NOLINT
790
+ this->send_command_(CMD_GATE_SENS, value, sizeof(value));
631
791
  this->query_parameters_();
632
792
  this->set_config_mode_(false);
633
793
  }
634
794
 
635
- void LD2410Component::set_gate_still_threshold_number(int gate, number::Number *n) {
795
+ void LD2410Component::set_gate_still_threshold_number(uint8_t gate, number::Number *n) {
636
796
  this->gate_still_threshold_numbers_[gate] = n;
637
797
  }
638
798
 
639
- void LD2410Component::set_gate_move_threshold_number(int gate, number::Number *n) {
799
+ void LD2410Component::set_gate_move_threshold_number(uint8_t gate, number::Number *n) {
640
800
  this->gate_move_threshold_numbers_[gate] = n;
641
801
  }
642
802
  #endif
@@ -644,35 +804,28 @@ void LD2410Component::set_gate_move_threshold_number(int gate, number::Number *n
644
804
  void LD2410Component::set_light_out_control() {
645
805
  #ifdef USE_NUMBER
646
806
  if (this->light_threshold_number_ != nullptr && this->light_threshold_number_->has_state()) {
647
- this->light_threshold_ = this->light_threshold_number_->state;
807
+ this->light_threshold_ = static_cast<uint8_t>(this->light_threshold_number_->state);
648
808
  }
649
809
  #endif
650
810
  #ifdef USE_SELECT
651
811
  if (this->light_function_select_ != nullptr && this->light_function_select_->has_state()) {
652
- this->light_function_ = this->light_function_select_->state;
812
+ this->light_function_ = find_uint8(LIGHT_FUNCTIONS_BY_STR, this->light_function_select_->state);
653
813
  }
654
814
  if (this->out_pin_level_select_ != nullptr && this->out_pin_level_select_->has_state()) {
655
- this->out_pin_level_ = this->out_pin_level_select_->state;
815
+ this->out_pin_level_ = find_uint8(OUT_PIN_LEVELS_BY_STR, this->out_pin_level_select_->state);
656
816
  }
657
817
  #endif
658
- if (this->light_function_.empty() || this->out_pin_level_.empty() || this->light_threshold_ < 0) {
659
- return;
660
- }
661
818
  this->set_config_mode_(true);
662
- uint8_t light_function = LIGHT_FUNCTION_ENUM_TO_INT.at(this->light_function_);
663
- uint8_t light_threshold = static_cast<uint8_t>(this->light_threshold_);
664
- uint8_t out_pin_level = OUT_PIN_LEVEL_ENUM_TO_INT.at(this->out_pin_level_);
665
- uint8_t value[4] = {light_function, light_threshold, out_pin_level, 0x00};
666
- this->send_command_(CMD_SET_LIGHT_CONTROL, value, 4);
667
- delay(50); // NOLINT
668
- this->get_light_control_();
819
+ uint8_t value[4] = {this->light_function_, this->light_threshold_, this->out_pin_level_, 0x00};
820
+ this->send_command_(CMD_SET_LIGHT_CONTROL, value, sizeof(value));
821
+ this->query_light_control_();
669
822
  this->set_timeout(200, [this]() { this->restart_and_read_all_info(); });
670
823
  this->set_config_mode_(false);
671
824
  }
672
825
 
673
826
  #ifdef USE_SENSOR
674
- void LD2410Component::set_gate_move_sensor(int gate, sensor::Sensor *s) { this->gate_move_sensors_[gate] = s; }
675
- void LD2410Component::set_gate_still_sensor(int gate, sensor::Sensor *s) { this->gate_still_sensors_[gate] = s; }
827
+ void LD2410Component::set_gate_move_sensor(uint8_t gate, sensor::Sensor *s) { this->gate_move_sensors_[gate] = s; }
828
+ void LD2410Component::set_gate_still_sensor(uint8_t gate, sensor::Sensor *s) { this->gate_still_sensors_[gate] = s; }
676
829
  #endif
677
830
 
678
831
  } // namespace ld2410