LD2410 'Presence' sensor, has_target - on_press not always working

I’m trying to turn a light , on and off basied on the ‘has_target’ property, using the on_press and on_release actions. (see YAML below)

However, sometimes the light does not get turned on.

esphome:
    name: ld2410-esp32
    friendly_name: Motion Sensor LED
  # ...
 
            
esp32:
  variant: esp32s3
  framework:
    type: esp-idf

# Enable logging
logger:
    level: DEBUG
# Enable Home Assistant API
api:

ota:
  - platform: esphome
    password: ""

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  
  
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:

captive_portal:



  
  
light:

  - platform: monochromatic
    name: "White Light"
    output: light_output_white
    id: white_light 
    
 
output:
  - platform: ledc
    pin: GPIO8
    id: light_output_white


 
uart:
  id: ld2410_uart
  tx_pin: GPIO17
  rx_pin: GPIO18
  baud_rate: 256000
  parity: NONE
  stop_bits: 1
 
ld2410:
  uart_id: ld2410_uart
  #throttle: 1500ms
  id: ld2410_comp

 
select:
  - platform: ld2410
    distance_resolution:
      name: distance resolution
    baud_rate:
      name: baud rate
    light_function:
      name: light function
    out_pin_level:
      name: out pin level
 
button:
  - platform: ld2410
    factory_reset:
      name: "factory reset"
    restart:
      name: "restart"
    query_params:
      name: query params
 
number:
  - platform: ld2410
    timeout: 
      name: "Timeout"
      id: ld2410_timeout

    max_move_distance_gate:
      name: max move distance gate
    max_still_distance_gate:
      name: max still distance gate
    g0:
      move_threshold:
        name: g0 move threshold
      still_threshold:
        name: g0 still threshold
    g1:
      move_threshold:
        name: g1 move threshold
      still_threshold:
        name: g1 still threshold
    g2:
      move_threshold:
        name: g2 move threshold
      still_threshold:
        name: g2 still threshold
    g3:
      move_threshold:
        name: g3 move threshold
      still_threshold:
        name: g3 still threshold
    g4:
      move_threshold:
        name: g4 move threshold
      still_threshold:
        name: g4 still threshold
    g5:
      move_threshold:
        name: g5 move threshold
      still_threshold:
        name: g5 still threshold
    g6:
      move_threshold:
        name: g6 move threshold
      still_threshold:
        name: g6 still threshold
    g7:
      move_threshold:
        name: g7 move threshold
      still_threshold:
        name: g7 still threshold
    g8:
      move_threshold:
        name: g8 move threshold
      still_threshold:
        name: g8 still threshold
    light_threshold:
      name: light threshold
 
text_sensor:
  - platform: ld2410
    version:
      name: "presenece sensor version"
    mac_address:
      name: "presenece sensor mac address"
 
switch:
  - platform: ld2410
    engineering_mode:
      name: "engineering mode"
    bluetooth:
      name: control Bluetooth
    
 
sensor:
  - platform: ld2410
    moving_distance:
      # internal: true
      name: "Moving distance (cm)"
    still_distance:
      # internal: true
      name: "Still Distance (cm)"
    moving_energy:
      # internal: true
      name: "Move Energy (%)"
    still_energy:
      # internal: true
      name: "Still Energy (%)"
    detection_distance:
      # internal: true    
      name: "Distance Detection (cm)"
    g0:
      move_energy:
        # internal: true
        name: g0 move energy
      still_energy:
        # internal: true   
        name: g0 still energy
    g1:
      move_energy:
        # internal: true         
        name: g1 move energy
      still_energy:
        # internal: true         
        name: g1 still energy
    g2:
      move_energy:
        # internal: true         
        name: g2 move energy
      still_energy:
        # internal: true         
        name: g2 still energy
    g3:
      move_energy:
        # internal: true         
        name: g3 move energy
      still_energy:
        # internal: true         
        name: g3 still energy
    g4:
      move_energy:
        # internal: true         
        name: g4 move energy
      still_energy:
        # internal: true   
        name: g4 still energy
    g5:
      move_energy:
        # internal: true   
        name: g5 move energy
      still_energy:
        # internal: true   
        name: g5 still energy
    g6:
      move_energy:
        # internal: true   
        name: g6 move energy
      still_energy:
        # internal: true         
        name: g6 still energy
    g7:
      move_energy:
        # internal: true         
        name: g7 move energy
      still_energy:
        # internal: true         
        name: g7 still energy
    g8:
      move_energy:
        # internal: true   
        name: g8 move energy
      still_energy:
        # internal: true   
        name: g8 still energy
    light:
      name: light
      # internal: true   

 
binary_sensor:

  - platform: gpio
    pin: GPIO9
    id: ld2410_gpio_out
           
              
  - platform: ld2410
    has_target:
      name: Presence
      on_press:
        then:
          light.turn_on: 
            id: white_light
            brightness: 100%
            transition_length: 0s

      on_release:
        then:
          light.turn_off:
            id: white_light
            transition_length: 0s

    
    has_moving_target:
      # internal: true
      name: Moving Target

    has_still_target:
      name: Still Target
      # internal: true
    out_pin_presence_status:
      name: Out Pin Status
      id: ld2410_out_pin

i.e If I stand in front of the LD2410 module, I can clearly see on the HA overview, that the ‘Presence’ has been detected, but the light has not turned on

This problem seems to occur if I power cycle or upload new code to the device when a target is already in view.

I’ve also tried using the ‘reset’ function on the HA screen

[08:05:16.405][W][ld2410:596]: Max command length exceeded; ignoring
[08:05:16.653][W][ld2410:596]: Max command length exceeded; ignoring
[08:05:16.831][D][binary_sensor:039]: ‘ld2410_gpio_out’: New state is ON
[08:05:16.954][D][binary_sensor:039]: ‘Moving Target’: New state is OFF
[08:05:16.954][D][binary_sensor:039]: ‘Still Target’: New state is ON
[08:05:17.452][D][select:015]: ‘baud rate’: Sending state 256000 (index 6)
[08:05:17.452][W][ld2410:596]: Max command length exceeded; ignoring
[08:05:17.452][W][ld2410:419]: Invalid header: 08.00.FF.01
[08:05:17.468][D][text_sensor:085]: ‘presenece sensor version’: Sending state ‘2.44.25070917’
[08:05:17.468][D][text_sensor:085]: ‘presenece sensor mac address’: Sending state ‘REDACTED’
[08:05:17.468][D][select:015]: ‘distance resolution’: Sending state 0.75m (index 1)
[08:05:17.468][D][select:015]: ‘light function’: Sending state off (index 0)
[08:05:17.483][D][select:015]: ‘out pin level’: Sending state high (index 1)
[08:05:17.483][D][number:033]: ‘light threshold’: Sending state 128.000000
[08:05:17.510][D][light:089]: ‘White Light’ Setting:
[08:05:17.513][D][light:102]: State: OFF

But this doesn’t work, and I’ve noticed that errors reported of Max command length exceeded; ignoring

My guess, is that possibly the sensor state change for on_press is occurring before the ESP code is ready, but I’m not sure how to do this.

State change triggers (like on_press:or thresholds) only trigger on change. This is true for both ESPHome and HA automation.

If you desperately need the light to come on after reset if presence is detected, add an on_boot: automation at a suitable priority that checks the state of the sensor and then acts accordingly.

@zoogara

Thanks.

I’ve added

  on_boot:
    - priority: 600
      then:
        - lambda: |-
            id(ld2410_comp).restart_and_read_all_info();
            delay(500);
            if(id(ld2410_has_target).state == true)
            {
              id(white_light).turn_on();
            }

And at the moment the led does seem to be turned on immediatly if necessary, but I’ll need to do some more testing to confirm this.

Edit.

This doesn’t always work.
Any ideas whih I did wrong?

Edit 2.

It seems that turn_on() and turn_off() don’t do anything :frowning:

Edit 3

Adding code to on_boot didn’t seem to work.

So my current workaround is

interval:
  - interval: 10min
    startup_delay: 5s
    then:
      - if:
          condition:
            lambda: 'return id(ld2410_has_target).state == true;'
          then:
            - logger.log: "----------------------------Turn light ON"
            - light.turn_on: 
                id: white_light
                brightness: 100%
                transition_length: 0s
          else:
            - logger.log: "Turn Light Off"
            - light.turn_on: 
                id: white_light

This isn’t ideal but I think it seems to be working

I think I need to add much more algorithmic control of the ‘timeout’ depending on which gate thresholds have been triggered, but IMO it looks like this will be best achived by not using Esphome for this specific device, and use Arduino / Playformio instead.

Albeit I loose the reporting of when the light was trigged, but this wasn’t essential.

Alternatively, I’d probably need to write a custom External Component to handle the logic,

So I may use Platformio to create the functionality I want, and then possibly port back to a custom External Component