DIY Human Sensor L12 Base on HLK-LD2412

Hi @Kosy ,
I pushed an update in the Dev branch. Now the gate threshold, gate sensing and light sensor are exposed to home assistant.

Can I ask you a check? I’d like to have a second opinion that everithing works fine before merge it

I’ve been playing with the 2412 a bit. Not tried your code yet, originally tried screek’s but now just using the output pin and configuring with bluetooth. The output pin seems to go high as soon as the stats on the bluetooth debug go high so don’t think there’s any lag on the pin beyond detection time.

One thing I’m trying to work out is the tuning and what triggers “occupancy”. When I’m watching the bluetooth debug it sort of seems that occupancy is triggered when “movement” is seen above the threshold, and occupancy is lost when “still” energy goes under that threshold - but it’s not consistent. At the moment, even with still energy quite low (5) it’s losing me in my living room more than the 2450 is. If you set the threshold much lower it risks being kept alive with “noise”.

Am i misinterpreting how the thresholds should be set? I thought the 2410, 2412 etc were supposed to be better at detecting humans without movement, but seem to need a lot of fiddling to get anywhere near that?

Hi,
Thanks for your feedback. Try to use the function “noise background detection” on the setting menù tk set the background level. It should stabilize your threshold I think. My ld2412 is way more stable with static presence than the LD2450. The ld2412 doesn’t lose me during the night when the ld2450 is instable. Maybe the positioning of your sensore can be improved?

Sorry for late reply. I had stuff come into my way. I see that You already have merged Dev branch I will put it into use any will report back if there is something off.

Edit: I had some issues with setting up same hardware with updated branch. But I will investigate it further when I will have some time to solder new hardware just to be sure everything is fresh and new.

Edit2: Jep its probably me setting LD on uart0 and not disabling logs.

Hi,
if you need help feel free to write here, if I can I’ll help you. Yeah, I merged the branch because I was afraid I would forget about it

1 Like

I tried your code but not work. I’m using esp32 C3 supermini which can connect with LD1152 successfully, but when I connect with LD2412 it’s not working at all. I have found once I connect with LD2412, the wifi will disconnected. If I remove LD2412, wifi is back to normal connected status.

external_components:
  - source:
      type: git
      url: https://github.com/Rihan9/LD2412
      ref: main
    components: [LD2412]

esphome:
  name: ld2412
  friendly_name: ld2412

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: arduino

logger:
  level: DEBUG
  baud_rate: 0

api:

ota:
  - platform: esphome

wifi:
  networks:
  - ssid:
    password: 
  - ssid: 
    password: 

captive_portal:

uart:
  id: uart_bus
  rx_pin: GPIO20
  tx_pin: GPIO21
  baud_rate: 115200
  parity: NONE
  stop_bits: 1

LD2412:
  id: ld2412
  throttle: 3s

binary_sensor:
  - platform: LD2412
    has_target:
      name: Presence
    has_moving_target:
      name: Moving Target
    has_still_target:
      name: Still Target

sensor:
  - platform: LD2412
    moving_distance:
      name : Moving Distance
    still_distance:
      name: Still Distance
    moving_energy:
      name: Move Energy
    still_energy:
      name: Still Energy
    detection_distance:
      name: Detection Distance
    light:
      name: light
    g0:
      move_energy:
        name: g00 move energy
      still_energy:
        name: g00 still energy
    g1:
      move_energy:
        name: g01 move energy
      still_energy:
        name: g01 still energy
    g2:
      move_energy:
        name: g02 move energy
      still_energy:
        name: g02 still energy
    g3:
      move_energy:
        name: g03 move energy
      still_energy:
        name: g03 still energy
    g4:
      move_energy:
        name: g04 move energy
      still_energy:
        name: g04 still energy
    g5:
      move_energy:
        name: g05 move energy
      still_energy:
        name: g05 still energy
    g6:
      move_energy:
        name: g06 move energy
      still_energy:
        name: g06 still energy
    g7:
      move_energy:
        name: g07 move energy
      still_energy:
        name: g07 still energy
    g8:
      move_energy:
        name: g08 move energy
      still_energy:
        name: g08 still energy
    g9:
      move_energy:
        name: g09 move energy
      still_energy:
        name: g09 still energy
    g10:
      move_energy:
        name: g10 move energy
      still_energy:
        name: g10 still energy
    g11:
      move_energy:
        name: g11 move energy
      still_energy:
        name: g11 still energy
    g12:
      move_energy:
        name: g12 move energy
      still_energy:
        name: g12 still energy
    g13:
      move_energy:
        name: g13 move energy
      still_energy:
        name: g13 still energy

number:
  - platform: LD2412
    timeout:
      name: "presence holding"
    min_distance_gate:
      name: "min distance gate"
    max_distance_gate:
      name: "max distance gate"
    g0:
      move_threshold:
        name: g00 move threshold
      still_threshold:
        name: g00 still threshold
    g1:
      move_threshold:
        name: g01 move threshold
      still_threshold:
        name: g01 still threshold
    g2:
      move_threshold:
        name: g02 move threshold
      still_threshold:
        name: g02 still threshold
    g3:
      move_threshold:
        name: g03 move threshold
      still_threshold:
        name: g03 still threshold
    g4:
      move_threshold:
        name: g04 move threshold
      still_threshold:
        name: g04 still threshold
    g5:
      move_threshold:
        name: g05 move threshold
      still_threshold:
        name: g05 still threshold
    g6:
      move_threshold:
        name: g06 move threshold
      still_threshold:
        name: g06 still threshold
    g7:
      move_threshold:
        name: g07 move threshold
      still_threshold:
        name: g07 still threshold
    g8:
      move_threshold:
        name: g08 move threshold
      still_threshold:
        name: g08 still threshold
    g9:
      move_threshold:
        name: g09 move threshold
      still_threshold:
        name: g09 still threshold
    g10:
      move_threshold:
        name: g10 move threshold
      still_threshold:
        name: g10 still threshold
    g11:
      move_threshold:
        name: g11 move threshold
      still_threshold:
        name: g11 still threshold
    g12:
      move_threshold:
        name: g12 move threshold
      still_threshold:
        name: g12 still threshold
    g13:
      move_threshold:
        name: g13 move threshold
      still_threshold:
        name: g13 still threshold
  
select:
  - platform: LD2412
    out_pin_level:
      name: 'Hardware output pin level'
    distance_resolution:
      name: 'Distance resolution'
    baud_rate:
      name: "baud rate"
      on_value:
        - delay: 3s
        - lambda: |-
            id(uart_bus).flush();
            uint32_t new_baud_rate = stoi(x);
            ESP_LOGD("change_baud_rate", "Changing baud rate from %i to %i",id(uart_bus).get_baud_rate(), new_baud_rate);
            if (id(uart_bus).get_baud_rate() != new_baud_rate) {
            id(uart_bus).set_baud_rate(new_baud_rate);
            id(uart_bus).load_settings();
            }
    mode:
      name: "Mode"
button:
  - platform: LD2412
    factory_reset:
      name: "factory reset"
    restart:
      name: "restart"
    query_params:
      name: query params

text_sensor:
  - platform: LD2412
    version:
      name: "firmware version"
    mac_address:
      name: "mac address"

switch:
  - platform: LD2412
    bluetooth:
      name: "Bluetooth"    

Hi @sbeagle25 ,
for me it seems a power problem. The component should’n influence the wifi component, so my guess is the ld2412 is using more power than what the esp can handle. I’mn using the same esp however. Do you have the ld2412 attached on the 3.3v power line? Do you have any other sensor attached on the 3.3V power line?
Have you tried another power supply?

Some version of the esp32c3 supermini board has a build in led, linked in the GPIO8. Use it for the platform light/status_led. The led will blink if the power is enough and the cpu is running, but the wifi couldn’t connect.

I have changed a new esp32 C3 supermini and the wifi problem seems solved. But all the entities are still in unknown status. The board has a build in led but I don’t known how to use it. I have copied the settings in my old LD2410 but not work. The setting in LD2410 is once motion was detected, the light is on.

binary_sensor:
  - platform: ld2410
    has_target:
      name: Presence
    has_moving_target:
      name: Moving Target
    has_still_target:
      name: Still Target
  - platform: gpio
    id: motion
    pin: GPIO16
    name: "entrance motion"
    device_class: motion
    on_state:
     - if:
         condition:
         - binary_sensor.is_on: motion
         then:
         - output.turn_on: device_light
     - if:
         condition: 
         - binary_sensor.is_off: motion
         then:
         - output.turn_off: device_light

sensor:
  - platform: ld2410
    light:
      name: light
    moving_distance:
      name : Moving Distance
    still_distance:
      name: Still Distance
    moving_energy:
      name: Move Energy
    still_energy:
      name: Still Energy
    detection_distance:
      name: Detection Distance
    g0:
      move_energy:
        name: g0 move energy
      still_energy:
        name: g0 still energy
    g1:
      move_energy:
        name: g1 move energy
      still_energy:
        name: g1 still energy
    g2:
      move_energy:
        name: g2 move energy
      still_energy:
        name: g2 still energy
    g3:
      move_energy:
        name: g3 move energy
      still_energy:
        name: g3 still energy
    g4:
      move_energy:
        name: g4 move energy
      still_energy:
        name: g4 still energy
    g5:
      move_energy:
        name: g5 move energy
      still_energy:
        name: g5 still energy
    g6:
      move_energy:
        name: g6 move energy
      still_energy:
        name: g6 still energy
    g7:
      move_energy:
        name: g7 move energy
      still_energy:
        name: g7 still energy
    g8:
      move_energy:
        name: g8 move energy
      still_energy:
        name: g8 still energy

light:
  - platform: binary
    output: "device_light"
    name: "entrance_motion_light"

output:
  - platform: gpio
    id: "device_light"
    pin: GPIO2  #D4
    inverted: true

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

Hi,
use this for the buildin led:

light:
  - platform: status_led
    name: "Status Led"
    pin:
      number: GPIO2  #I guessed it from your previous code.
      inverted: true

the ld2410 platform differ in the communication protocol but the has_target binary sensor should be one of the few things that work. However I don’t know if the incompatible part can cause an error that broke the entire component. Con you double check the uart connections? make sure to connect the rx pin of the sensor to the tx pin on the esp32 and the tx pin of the sensor to the rx pin on the esp. If they are correct, please check the logs to see if the command as sucessfully trasmitted and received. the logger level should be at least “DEBUG”. Are you able to connect to the sensor’s bluetooth?

I’m sure the TX and RX pin are correct. But the log shows nothing.
I can connect to the sensor’s bluetooth via my phone and adjust the setting in the app.

INFO ESPHome 2024.9.2
INFO Reading configuration /config/esphome/new.yaml...
WARNING GPIO8 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
INFO Starting log output from 192.168.50.197 using esphome API
INFO Successfully connected to new @ 192.168.50.197 in 2.113s
WARNING Can't connect to ESPHome API for new @ 192.168.50.197: Timeout waiting for HelloResponse, ConnectResponse after 30.0s (TimeoutAPIError)
INFO Trying to connect to new @ 192.168.50.197 in the background
WARNING new @ 192.168.50.197: Connection error occurred: new @ 192.168.50.197: Connection lost
INFO Successfully connected to new @ 192.168.50.197 in 1.036s
INFO Successful handshake with new @ 192.168.50.197 in 7.309s
[22:46:29][I][app:100]: ESPHome version 2024.9.2 compiled on Oct  6 2024, 21:48:42
[22:46:29][C][wifi:600]: WiFi:
[22:46:29][C][wifi:428]:   Local MAC: D8:3B:DA:24:DA:0C
[22:46:29][C][wifi:433]:   SSID: [redacted]
[22:46:29][C][wifi:436]:   IP Address: 192.168.50.197
[22:46:29][C][wifi:440]:   BSSID: [redacted]
[22:46:29][C][wifi:441]:   Hostname: 'new'
[22:46:29][C][wifi:443]:   Signal strength: -85 dB ▂▄▆█
[22:46:29][C][wifi:447]:   Channel: 3
[22:46:29][C][wifi:448]:   Subnet: 255.255.255.0
[22:46:29][C][wifi:449]:   Gateway: 192.168.50.1
[22:46:29][C][wifi:450]:   DNS1: 192.168.50.1
[22:46:29][C][wifi:451]:   DNS2: 0.0.0.0
[22:46:29][C][logger:185]: Logger:
[22:46:29][C][logger:186]:   Level: DEBUG
[22:46:29][C][logger:188]:   Log Baud Rate: 0

Ok, raise the debug level to VERBOSE and post both you configuration and log, I’ll try to help you

Thanks a lot!!

[00:09:35][I][app:100]: ESPHome version 2024.9.2 compiled on Oct  7 2024, 00:01:55
[00:09:35][C][status_led:065]: Status Led Light:
[00:09:35][C][status_led:066]:   Pin: GPIO8
[00:09:35][C][wifi:600]: WiFi:
[00:09:35][C][wifi:428]:   Local MAC: D8:3B:DA:24:DA:0C
[00:09:35][C][wifi:433]:   SSID: [redacted]
[00:09:35][C][wifi:436]:   IP Address: 192.168.50.197
[00:09:35][C][wifi:440]:   BSSID: [redacted]
[00:09:35][C][wifi:441]:   Hostname: 'new'
[00:09:35][C][wifi:443]:   Signal strength: -75 dB ▂▄▆█
[00:09:35][V][wifi:445]:   Priority: 0.0
[00:09:35][C][wifi:447]:   Channel: 3
[00:09:35][C][wifi:448]:   Subnet: 255.255.255.0
[00:09:35][C][wifi:449]:   Gateway: 192.168.50.1
[00:09:35][C][wifi:450]:   DNS1: 192.168.50.1
[00:09:35][C][wifi:451]:   DNS2: 0.0.0.0
[00:09:36][C][logger:185]: Logger:
[00:09:36][C][uart.arduino_esp32:151]: UART Bus 0:
[00:09:36][C][LD2412:022]: LD2412:
[00:09:36][C][LD2412:024]:     Device Class: 'occupancy'
[00:09:36][V][LD2412:131]: Sending COMMAND A0
[00:09:36][V][LD2412:131]: Sending COMMAND A5
[00:09:36][V][LD2412:131]: Sending COMMAND 11
[00:09:36][V][LD2412:131]: Sending COMMAND 12
[00:09:36][V][LD2412:131]: Sending COMMAND FF
[00:09:36][V][LD2412:131]: Sending COMMAND 1B
[00:09:36][V][LD2412:131]: Sending COMMAND FE
[00:09:36][V][LD2412:131]: Sending COMMAND FF
[00:09:36][V][LD2412:131]: Sending COMMAND 13
[00:09:36][V][LD2412:131]: Sending COMMAND 14
[00:09:36][V][LD2412:131]: Sending COMMAND FE
[00:09:36][V][LD2412:131]: Sending COMMAND FE
[00:09:36][C][LD2412:076]:   Throttle_ : 3000ms
[00:09:36][C][LD2412:077]:   MAC Address : 
[00:09:36][C][LD2412:078]:   Firmware Version : 
[00:09:36][C][captive_portal:089]: Captive Portal:
[00:09:36][C][mdns:116]: mDNS:
[00:09:36][C][mdns:117]:   Hostname: new
[00:09:36][V][mdns:118]:   Services:
[00:09:36][V][mdns:120]:   - _esphomelib, _tcp, 6053
[00:09:36][V][mdns:122]:     TXT: friendly_name = new
[00:09:36][V][mdns:122]:     TXT: version = 2024.9.2
[00:09:36][V][mdns:122]:     TXT: mac = d83bda24da0c
[00:09:36][V][mdns:122]:     TXT: platform = ESP32
[00:09:36][V][mdns:122]:     TXT: board = esp32-c3-devkitm-1
[00:09:36][V][mdns:122]:     TXT: network = wifi
[00:09:36][C][esphome.ota:073]: Over-The-Air updates:
[00:09:36][C][esphome.ota:074]:   Address: new.local:3232
[00:09:36][C][esphome.ota:075]:   Version: 2
[00:09:36][C][safe_mode:018]: Safe Mode:
[00:09:36][C][safe_mode:020]:   Boot considered successful after 60 seconds
[00:09:36][C][safe_mode:021]:   Invoke after 10 boot attempts
[00:09:37][V][api.connection:1533]: Cannot send message because of TCP buffer space
[00:09:37][V][api.connection:1533]: Cannot send message because of TCP buffer space
[00:10:27][I][safe_mode:041]: Boot seems successful; resetting boot loop counter
[00:10:27][D][esp32.preferences:114]: Saving 1 preferences to flash...
[00:10:27][V][esp32.preferences:126]: sync: key: 233825507, len: 4
[00:10:27][D][esp32.preferences:143]: Saving 1 preferences to flash: 0 cached, 1 written, 0 failed
external_components:
  - source:
      type: git
      url: https://github.com/Rihan9/LD2412
      ref: main
    components: [LD2412]

esphome:
  name: new
  friendly_name: new

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: arduino

# Enable logging
logger:
  level: VERBOSE
  baud_rate: 0

# Enable Home Assistant API
api:

ota:
  - platform: esphome

wifi:
  networks:
  - ssid: "YAAA"
    password: "123858499"
  - ssid: "YAYA150"
    password: "047251229"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "C3 Fallback Hotspot"
    password: "123858499"

captive_portal:

uart:
  id: uart_bus
  rx_pin: GPIO6
  tx_pin: GPIO7
  baud_rate: 115200
  parity: NONE
  stop_bits: 1

LD2412:
  id: ld2412
  throttle: 3s

binary_sensor:
  - platform: LD2412
    has_target:
      name: Presence
    has_moving_target:
      name: Moving Target
    has_still_target:
      name: Still Target

sensor:
  - platform: LD2412
    moving_distance:
      name : Moving Distance
    still_distance:
      name: Still Distance
    moving_energy:
      name: Move Energy
    still_energy:
      name: Still Energy
    detection_distance:
      name: Detection Distance
    light:
      name: light
    g0:
      move_energy:
        name: g00 move energy
      still_energy:
        name: g00 still energy
    g1:
      move_energy:
        name: g01 move energy
      still_energy:
        name: g01 still energy
    g2:
      move_energy:
        name: g02 move energy
      still_energy:
        name: g02 still energy
    g3:
      move_energy:
        name: g03 move energy
      still_energy:
        name: g03 still energy
    g4:
      move_energy:
        name: g04 move energy
      still_energy:
        name: g04 still energy
    g5:
      move_energy:
        name: g05 move energy
      still_energy:
        name: g05 still energy
    g6:
      move_energy:
        name: g06 move energy
      still_energy:
        name: g06 still energy
    g7:
      move_energy:
        name: g07 move energy
      still_energy:
        name: g07 still energy
    g8:
      move_energy:
        name: g08 move energy
      still_energy:
        name: g08 still energy
    g9:
      move_energy:
        name: g09 move energy
      still_energy:
        name: g09 still energy
    g10:
      move_energy:
        name: g10 move energy
      still_energy:
        name: g10 still energy
    g11:
      move_energy:
        name: g11 move energy
      still_energy:
        name: g11 still energy
    g12:
      move_energy:
        name: g12 move energy
      still_energy:
        name: g12 still energy
    g13:
      move_energy:
        name: g13 move energy
      still_energy:
        name: g13 still energy

number:
  - platform: LD2412
    timeout:
      name: "presence holding"
    min_distance_gate:
      name: "min distance gate"
    max_distance_gate:
      name: "max distance gate"
    g0:
      move_threshold:
        name: g00 move threshold
      still_threshold:
        name: g00 still threshold
    g1:
      move_threshold:
        name: g01 move threshold
      still_threshold:
        name: g01 still threshold
    g2:
      move_threshold:
        name: g02 move threshold
      still_threshold:
        name: g02 still threshold
    g3:
      move_threshold:
        name: g03 move threshold
      still_threshold:
        name: g03 still threshold
    g4:
      move_threshold:
        name: g04 move threshold
      still_threshold:
        name: g04 still threshold
    g5:
      move_threshold:
        name: g05 move threshold
      still_threshold:
        name: g05 still threshold
    g6:
      move_threshold:
        name: g06 move threshold
      still_threshold:
        name: g06 still threshold
    g7:
      move_threshold:
        name: g07 move threshold
      still_threshold:
        name: g07 still threshold
    g8:
      move_threshold:
        name: g08 move threshold
      still_threshold:
        name: g08 still threshold
    g9:
      move_threshold:
        name: g09 move threshold
      still_threshold:
        name: g09 still threshold
    g10:
      move_threshold:
        name: g10 move threshold
      still_threshold:
        name: g10 still threshold
    g11:
      move_threshold:
        name: g11 move threshold
      still_threshold:
        name: g11 still threshold
    g12:
      move_threshold:
        name: g12 move threshold
      still_threshold:
        name: g12 still threshold
    g13:
      move_threshold:
        name: g13 move threshold
      still_threshold:
        name: g13 still threshold
  
select:
  - platform: LD2412
    out_pin_level:
      name: 'Hardware output pin level'
    distance_resolution:
      name: 'Distance resolution'
    baud_rate:
      name: "baud rate"
      on_value:
        - delay: 3s
        - lambda: |-
            id(uart_bus).flush();
            uint32_t new_baud_rate = stoi(x);
            ESP_LOGD("change_baud_rate", "Changing baud rate from %i to %i",id(uart_bus).get_baud_rate(), new_baud_rate);
            if (id(uart_bus).get_baud_rate() != new_baud_rate) {
            id(uart_bus).set_baud_rate(new_baud_rate);
            id(uart_bus).load_settings();
            }
    mode:
      name: "Mode"
button:
  - platform: LD2412
    factory_reset:
      name: "factory reset"
    restart:
      name: "restart"
    query_params:
      name: query params

text_sensor:
  - platform: LD2412
    version:
      name: "firmware version"
    mac_address:
      name: "mac address"
switch:
  - platform: LD2412
    bluetooth:
      name: "Bluetooth"    

light:
  - platform: status_led
    name: "Status Led"
    pin:
      number: GPIO8
      inverted: true

I can see in the log the command has been sended succesfully to the LD but I can’t see the response handling, neither the periodic data handling.
Someting is wrong in the LD2412.TX—>ESP32.RX line or the log is truncated.

You can:

  • check the boud rate in the app, to confirm that is the same in both sensor and the esp configuration.
  • try a different pin in the esp32 to check if the pin is damaged/incompatible(esphome should raise a validation error if the pin was incompatible, so I don’t think this is the issue)
  • try the screek-workshop external components, so we can check if an issue of my component.

After setting the baud rate in the app it works!!
But the responce seems a little lag. I’ll keep tring.
Thanks~~

Thanks very much for all the effort.
Here my experience so far with an ESP32:

TLDR:
I am having a worse experience than with the LD2410

I initially bought the LD2412 would give me more range and higher sensitivity. Also the background noise elimination feature appeared appealing.

All info here is gathered from the HLK-App

I have the Sensor mounted on the ceiling at approximately 3.5m height.
The distance constantly jumps between 0 and 6 meters never really stabilizing, even when sitting directly under the sensor.

During testing on the breadboard the distance never went lower than 1.5 meter, which seemed odd, however testing three different sensors, all sensors showed the same behaviour.

Regarding sensitivity:
Apparently there appears to be no / hardly any noise in my house so the elimination did near to nothing. Sadly the peaks, even when sitting directly under the sensor never peaked higher than values between 3-6 making false positive elimination impossible. Also Randomly near to all Gates fired which also seems odd, as the sensor is mounted on the ceiling.

I’m kind of disappointed, is anybody else experiencing issues like this? I have tried jumping firmwares between 1.25 and 1.04 and so on. Also I tried compiling with arduino or idf framework all made no real difference, but shouldn’t be expected as the device should only use uart anyway.

Getting the Sensor to actually work was painful too (in opposition to the LD2410). I could only get the sensor to report values in HA, when, after flashing the ESP32, setting the already selected default baud rate to 15200 again in the HLK app.

The Sensor value update rate also seemed kind of sluggish / not real time like opposed to the LD2410.

I hope I’m doing something gravely wrong, and advice is appreciated. However, the LD2410 simply performed better with way higher peaks in sensitivity detection.

Here my config:

substitutions:
  devicename: 
  upper_devicename: 
  ipaddress: 
  subnet: 
  gateway: 

external_components:
  - source:
      type: git
      url: https://github.com/Rihan9/LD2412
      ref: main
    components: [LD2412]

esphome:
  name: $devicename
  friendly_name: $upper_devicename
  platformio_options:
    build_flags: 
      - -Wno-maybe-uninitialized
  on_boot:
    priority: 600
    then:
      - lambda: |-
          id(uart_bus).set_baud_rate(115200);  

esp32:
  board: nodemcu-32s
  framework:
    #type: esp-idf
    type: arduino

logger:
  logs:
    component: ERROR
#  level: VERBOSE
#  baud_rate: 0

api:
  encryption:
    key: !secret api_encryption 

ota:
  - platform: esphome  
    password: !secret ota

captive_portal:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true
  manual_ip:
    static_ip: ${ipaddress}
    gateway:  ${gateway}
    subnet: ${subnet}

  ap:
    ssid:  ${upper_devicename} Hotspot
    password: !secret ap_password

bluetooth_proxy: 
  active: true

switch:
  - platform: LD2412
    bluetooth:
      name: "Bluetooth"
#    engineering_mode:
#      name: "Engineering Mode"
LD2412:
  id: ld2412
  throttle: 3s

  
uart:
  tx_pin: GPIO17
  rx_pin: GPIO16
  baud_rate: 115200
  parity: NONE
  stop_bits: 1
  id: uart_bus

select:
  - platform: LD2412
    out_pin_level:
      name: 'Hardware output pin level'
    distance_resolution:
      name: 'Distance resolution'
    baud_rate:
      name: "baud rate"
      on_value:
        - delay: 3s
        - lambda: |-
            id(uart_bus).flush();
            uint32_t new_baud_rate = stoi(x);
            ESP_LOGD("change_baud_rate", "Changing baud rate from %i to %i",id(uart_bus).get_baud_rate(), new_baud_rate);
            if (id(uart_bus).get_baud_rate() != new_baud_rate) {
            id(uart_bus).set_baud_rate(new_baud_rate);
            id(uart_bus).load_settings();
            }
    mode:
      name: "Mode"

binary_sensor:
  - platform: gpio
    pin: GPIO26
    name: "${upper_devicename} PIR"
    device_class: motion
  - platform: LD2412
    has_target:
      name: Presence
      id: radar_has_target
    has_moving_target:
      name: Moving Target
    has_still_target:
      name: Still Target

  - platform: template
    name: "Radar Zone 1 Occupancy"
    id: zone1
    device_class: occupancy
    icon: mdi:motion-sensor
    lambda: |-
      if ((id(radar_has_target).state) && (id(radar_detection_distance).state < id(radar_z1_end).state)) {
        id(zone_transition).publish_state("zone1");
        return true;
      } else {
        return false;
      }
    on_state:
      then:
        - script.execute: check_sensors

  - platform: template
    name: "Radar Zone 2 Occupancy"
    device_class: occupancy
    icon: mdi:motion-sensor
    id: zone2
    lambda: |-
      if ((id(radar_has_target).state) && ((id(radar_z1_end).state < id(radar_detection_distance).state) && (id(radar_detection_distance).state < id(radar_z2_end).state))) {
        id(zone_transition).publish_state("zone2");
        return true;
      } else {
        return false;
      }
    on_state:
      then:
        - script.execute: check_sensors      
  - platform: template
    name: "Radar Zone 3 Occupancy"
    device_class: occupancy
    id: zone3
    icon: mdi:motion-sensor
    lambda: |-
      if ((id(radar_has_target).state) && ((id(radar_z2_end).state < id(radar_detection_distance).state) && (id(radar_detection_distance).state < id(radar_z3_end).state))) {
        id(zone_transition).publish_state("zone3");
        return true;
      } else {
        return false;
      }
    on_state:
      then:
        - script.execute: check_sensors      



script:
  - id: check_sensors
    then:
      - lambda: |-
          if (id(zone1).state) {
            id(zone_transition).publish_state("zone1");
          } else if (id(zone2).state) {
            id(zone_transition).publish_state("zone2");
          } else if (id(zone3).state) {
            id(zone_transition).publish_state("zone3");
          } else {
            id(zone_transition).publish_state("unknown");
          }

sensor:
  - platform: LD2412      
    moving_distance:
      name : Moving Distance
    still_distance:
      name: Still Distance
    moving_energy:
      name: Move Energy
    still_energy:
      name: Still Energy
    detection_distance:
      name: Detection Distance
      id: radar_detection_distance
    light:
      name: light
    g0:
      move_energy:
        name: g00 move energy
      still_energy:
        name: g00 still energy
    g1:
      move_energy:
        name: g01 move energy
      still_energy:
        name: g01 still energy
    g2:
      move_energy:
        name: g02 move energy
      still_energy:
        name: g02 still energy
    g3:
      move_energy:
        name: g03 move energy
      still_energy:
        name: g03 still energy
    g4:
      move_energy:
        name: g04 move energy
      still_energy:
        name: g04 still energy
    g5:
      move_energy:
        name: g05 move energy
      still_energy:
        name: g05 still energy
    g6:
      move_energy:
        name: g06 move energy
      still_energy:
        name: g06 still energy
    g7:
      move_energy:
        name: g07 move energy
      still_energy:
        name: g07 still energy
    g8:
      move_energy:
        name: g08 move energy
      still_energy:
        name: g08 still energy
    g9:
      move_energy:
        name: g09 move energy
      still_energy:
        name: g09 still energy
    g10:
      move_energy:
        name: g10 move energy
      still_energy:
        name: g10 still energy
    g11:
      move_energy:
        name: g11 move energy
      still_energy:
        name: g11 still energy
    g12:
      move_energy:
        name: g12 move energy
      still_energy:
        name: g12 still energy
    g13:
      move_energy:
        name: g13 move energy
      still_energy:
        name: g13 still energy

  
  - platform: wifi_signal
    name: ${upper_devicename} WiFi Signal
    update_interval: 120s     

text_sensor:
  - platform: version
    name: ${upper_devicename} ESPHome Version
    hide_timestamp: true
  - platform: wifi_info
    ip_address:
      name: ${upper_devicename} IP
      icon: mdi:ip-network
    ssid:
      name: ${upper_devicename} SSID
      icon: mdi:wifi
    mac_address:
      name: "${upper_devicename} MAC"
      icon: mdi:identifier
  - platform: template
    name: ${upper_devicename} Friendly Name
    icon: 'mdi:information-outline'
    lambda: |-
      return {"$upper_devicename"};
  - platform: template
    name: ${upper_devicename} Uptime
    id: uptime_human
    icon: mdi:clock-start

  - platform: template
    id: zone_transition
    name: "zone_transition"

  - platform: LD2412
    version:
      name: "firmware version"
    mac_address:
      name: "mac address"

number:
  - platform: LD2412
    timeout:
      name: "presence holding"
    min_distance_gate:
      name: "min distance gate"
    max_distance_gate:
      name: "max distance gate"
    g0:
      move_threshold:
        name: g00 move threshold
      still_threshold:
        name: g00 still threshold
    g1:
      move_threshold:
        name: g01 move threshold
      still_threshold:
        name: g01 still threshold
    g2:
      move_threshold:
        name: g02 move threshold
      still_threshold:
        name: g02 still threshold
    g3:
      move_threshold:
        name: g03 move threshold
      still_threshold:
        name: g03 still threshold
    g4:
      move_threshold:
        name: g04 move threshold
      still_threshold:
        name: g04 still threshold
    g5:
      move_threshold:
        name: g05 move threshold
      still_threshold:
        name: g05 still threshold
    g6:
      move_threshold:
        name: g06 move threshold
      still_threshold:
        name: g06 still threshold
    g7:
      move_threshold:
        name: g07 move threshold
      still_threshold:
        name: g07 still threshold
    g8:
      move_threshold:
        name: g08 move threshold
      still_threshold:
        name: g08 still threshold
    g9:
      move_threshold:
        name: g09 move threshold
      still_threshold:
        name: g09 still threshold
    g10:
      move_threshold:
        name: g10 move threshold
      still_threshold:
        name: g10 still threshold
    g11:
      move_threshold:
        name: g11 move threshold
      still_threshold:
        name: g11 still threshold
    g12:
      move_threshold:
        name: g12 move threshold
      still_threshold:
        name: g12 still threshold
    g13:
      move_threshold:
        name: g13 move threshold
      still_threshold:
        name: g13 still threshold

# Setting ending of zone 1 occupancy
  - platform: template
    name: "Radar End Zone 1"
    id: radar_z1_end
    device_class: distance
    min_value: 0
    max_value: 600
    step: 1
    mode: box
    update_interval: never
    optimistic: true
    restore_value: true
    initial_value: 10
    icon: "mdi:arrow-collapse-right"
    entity_category: CONFIG

  # Setting ending of zone 2 occupancy
  - platform: template
    name: "Radar End Zone 2"
    id: radar_z2_end
    device_class: distance
    min_value: 0
    max_value: 600
    step: 1
    mode: box
    update_interval: never
    optimistic: true
    restore_value: true
    initial_value: 36
    icon: "mdi:arrow-collapse-right"
    entity_category: CONFIG

  # Setting ending of zone 3 occupancy
  - platform: template
    name: "Radar End Zone 3"
    id: radar_z3_end
    device_class: distance
    min_value: 0
    max_value: 600
    step: 1
    mode: box
    update_interval: never
    optimistic: true
    restore_value: true
    initial_value: 100
    icon: "mdi:arrow-collapse-right"
    entity_category: CONFIG

button:
  - platform: LD2412
    factory_reset:
      name: "factory reset"
    restart:
      name: "restart"
    query_params:
      name: query params
  - platform: safe_mode
    name: "Restart (Safe OTA Mode)"      
  - platform: restart
    name: "Restart"

I am new to radar sensors and i am also very disappointed by the LD2412. I also have the issues you mentioned, especially the distance jumping. But these aren’t my biggest complain and not that important for me.
The biggest issue is the detection angle. It should be 150° (± 75) and in reality it is far from that. I have mounted a LD2412 on the ceiling at 2.4 m height. With the angle and range from the specs it should detect me anywhere in the (big) room. In reality it triggers if i am only ca. 2m away from it. That’s super underwhelming.

When comparing to 2410 I’m disappointed with the L2412 as well…

  • It doesn’t seem to respect the threshold values. I can see the values being higher than threshold and yet it doesn’t get triggered. (using radar app)
  • it takes a while for the presence to get triggered but once it does it seems to work properly until it gets turned off.

After all the works made to create the integration, I regrettably agree with @yanivf and @lihuuhloi.

The sensor is way too slow to react when a person enter in its range. So much so that is unusable in a hallway or to turn on the light in a dark black room. You literally need to wait for it to see you for like 3 or 4 seconds. It’s ridiculous.

I think I’ll use them to specific tasks, like track my presence on the bed in nighttime or in the sofa, to turn on specific scenes for example. I don’t think I can use them as generic presence sensor for an entire room.

I want to try to connect one of these sensor remotely via bluetooth and use it as a “socondary” sensor. So an ESP32 with a connected ld2410 can manage the main light, and the ld2412 in the specific zone can manage the specific scene, just with a power supply without another esp connected to it.

I just got a few LD2412s to play around with! Wondering which yaml to use? Screek’s or Rihan’s? @screek-workshop or @Rihan. I am guessing they are pretty similar? I am sad to see the performance is not as good as the LD2410c that I have already. Curious to try it out and if Screek knows if Hi-Link can improve the LD2412 in firmware updates? Thank you all for your hard work on all these awesome sensors!