I recently got a bunch of Everything Presence Lites and they really are amazing as human presence sensors! They are mmWave sensors that can track slight movements from up to 3 distinct targets simultaneously. In my setup, I had to mount one unit in the ceiling above our dining table to track people eating a meal. The trouble is that a pendant light hangs between the sensor and the table, which means that whenever the pendant swings (eg. due to wind), the unit detects the light.
Fortunately they are ESPHome-based, which makes them very moddable. I modified the original code to implement an “ignore zone” where a target that falls within a certain volume of space does not get counted for the purpose of presence detection.
In a local copy of this file, add the following under the number
component. This creates number
entities in Home Assistant where you can specify the coordinates of the volume of space that you want to ignore:
- platform: template
name: "Ignore Target Begin X"
id: ignore_target_begin_x
max_value: 4000
min_value: -4000
unit_of_measurement: "mm"
step: 10
entity_category: config
optimistic: True
restore_value: True
- platform: template
name: "Ignore Target End X"
id: ignore_target_end_x
max_value: 4000
min_value: -4000
unit_of_measurement: "mm"
step: 10
entity_category: config
optimistic: True
restore_value: True
- platform: template
name: "Ignore Target Begin Y"
id: ignore_target_begin_y
max_value: 6000
min_value: 0
unit_of_measurement: "mm"
step: 10
entity_category: config
optimistic: True
restore_value: True
- platform: template
name: "Ignore Target End Y"
id: ignore_target_end_y
max_value: 6000
min_value: 0
unit_of_measurement: "mm"
step: 10
entity_category: config
optimistic: True
restore_value: True
- platform: template
name: "Ignore Target Max Angle"
id: ignore_target_max_angle
max_value: 90
min_value: -90
step: 1
entity_category: config
optimistic: True
restore_value: True
unit_of_measurement: "°"
initial_value: 0
- platform: template
name: "Ignore Target Min Angle"
id: ignore_target_min_angle
max_value: 90
min_value: -90
step: 1
entity_category: config
optimistic: True
restore_value: True
unit_of_measurement: "°"
initial_value: 0
- platform: template
name: "Ignore Target Max Distance"
id: ignore_target_max_distance
max_value: 6000
min_value: 0
step: 10
entity_category: config
optimistic: True
restore_value: True
unit_of_measurement: "mm"
initial_value: 0
- platform: template
name: "Ignore Target Min Distance"
id: ignore_target_min_distance
max_value: 6000
min_value: 0
step: 10
entity_category: config
optimistic: True
restore_value: True
unit_of_measurement: "mm"
initial_value: 0
Under the binary_sensor
component, add the following. These return true
if the corresponding target (total of 3 can be tracked simultaneously) falls inside the ignore zone:
- platform: template
name: Ignore Target 1
id: ignore_target1
lambda: |-
return (id(target1_distance).state >= id(ignore_target_min_distance).state && id(target1_distance).state <= id(ignore_target_max_distance).state &&
id(target1_x).state >= id(ignore_target_begin_x).state && id(target1_x).state <= id(ignore_target_end_x).state &&
id(target1_y).state >= id(ignore_target_begin_y).state && id(target1_y).state <= id(ignore_target_end_y).state &&
id(target1_angle).state >= id(ignore_target_min_angle).state && id(target1_angle).state <= id(ignore_target_max_angle).state);
- platform: template
name: Ignore Target 2
id: ignore_target2
lambda: |-
return (id(target2_distance).state >= id(ignore_target_min_distance).state && id(target2_distance).state <= id(ignore_target_max_distance).state &&
id(target2_x).state >= id(ignore_target_begin_x).state && id(target2_x).state <= id(ignore_target_end_x).state &&
id(target2_y).state >= id(ignore_target_begin_y).state && id(target2_y).state <= id(ignore_target_end_y).state &&
id(target2_angle).state >= id(ignore_target_min_angle).state && id(target2_angle).state <= id(ignore_target_max_angle).state);
- platform: template
name: Ignore Target 3
id: ignore_target3
lambda: |-
return (id(target3_distance).state >= id(ignore_target_min_distance).state && id(target3_distance).state <= id(ignore_target_max_distance).state &&
id(target3_x).state >= id(ignore_target_begin_x).state && id(target3_x).state <= id(ignore_target_end_x).state &&
id(target3_y).state >= id(ignore_target_begin_y).state && id(target3_y).state <= id(ignore_target_end_y).state &&
id(target3_angle).state >= id(ignore_target_min_angle).state && id(target3_angle).state <= id(ignore_target_max_angle).state);
The lambda
of the uart
component outputs the sensor
readings reported to Home Assistant on the target coordinates. Add && not id(ignore_target1).state
, && not id(ignore_target2).state
, && not id(ignore_target3).state
into this section of the lambda
so that targets falling within the ignore zone aren’t counted as presence in that zone (in my case, the ignore zone fall within Zone 1 - a max of 4 zones can be defined).
int zone1_count = 0;
if (id(target1_active).state == true ) {
if ((id(target1_x).state >= id(zone1_begin_x).state && id(target1_x).state <= id(zone1_end_x).state) &&
(id(target1_y).state >= id(zone1_begin_y).state && id(target1_y).state <= id(zone1_end_y).state) &&
not id(ignore_target1).state) {
zone1_count++;
}
}
if (id(target2_active).state == true ) {
if ((id(target2_x).state >= id(zone1_begin_x).state && id(target2_x).state <= id(zone1_end_x).state) &&
(id(target2_y).state >= id(zone1_begin_y).state && id(target2_y).state <= id(zone1_end_y).state) &&
not id(ignore_target2).state) {
zone1_count++;
}
}
if (id(target3_active).state == true ) {
if ((id(target3_x).state >= id(zone1_begin_x).state && id(target3_x).state <= id(zone1_end_x).state) &&
(id(target3_y).state >= id(zone1_begin_y).state && id(target3_y).state <= id(zone1_end_y).state) &&
not id(ignore_target3).state) {
zone1_count++;
}
}
In the ESPHome config for the unit, I then replaced dashboard_import
and packages
with the following (though tbh I am not quite clear what are the consequences of removing dashboard_import
):
packages:
EverythingSmartTechnology.Everything_Presence_Lite.device_base: github://everythingsmarthome/everything-presence-lite/common/everything-presence-lite-base.yaml@main
custom_ld2450: !include path_to_your/local_copy.yaml
EverythingSmartTechnology.Everything_Presence_Lite.bluetooth_base: github://everythingsmarthome/everything-presence-lite/common/bluetooth-base.yaml@main
With that, you can then observe the range of sensor values that the unit reports in Home Assistant when it detects the false positive that you wish to ignore. Set the min and max values of X, Y, angle and distance for the ignore zone accordingly. Then the presence status reported by the sensor will ignore any target that falls within that zone.
Hope this helps to expand your options for where you can mount one of these sensors to be most useful in your setup!