Skip to content

Instantly share code, notes, and snippets.

@kdorff
Last active March 3, 2024 16:11
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kdorff/245ff51463b4845de6239deaaa21445e to your computer and use it in GitHub Desktop.
Save kdorff/245ff51463b4845de6239deaaa21445e to your computer and use it in GitHub Desktop.
Break beam sensor using VL53L0X for Home Assistant using ESPHome
##
## A standard "break beam sensor" uses a laser or LED with a device on both
## sides of an opening and is triggered when something breaks the beam
## (such as a customer walking through the beam). Some garage doors use them.
## Stores often use them at the entrace to ring a chime when a customer enters
## or leaves.
##
## This is my attempt at using a VL53L0X i2c Time of Flight sensor
## as a break beam sensor in Home Assistant using ESPHome.
##
## The binary sensor 'breakbeam_sensor' is
## * A synthetic break beam that is controlled by changes
## to 'breakbeam_sensor_dist'.
## * Should only send changes when the 'beam is broken':
## * 'breakbeam_sensor_dist' becomes < 'minTripDistance' (or)
## * 'breakbeam_sensor_dist' becomes to greater than 'minTripDistance'
##
## The sensor 'breakbeam_sensor_dist' is the actual VL53L0X sensor.
## * The maximum reliable "open" distance seems to be to about 1.5 meters.
## * This sensor is marked intnernal as to not send distance data to HA.
## * When distance first falls less that 'minTripDistance',
## 'breakbeam_sensor' will turned on.
## * When the distance is first greater than 'minTripDistance', the
## 'breakbeam_sensor' will be turned off.
## * This will poll at 0.1s. This seems fast enough, but 1s was not.
##
esphome:
name: distance-sensor-0
esp8266:
board: esp01_1m
# Logging (DEBUG is the standard level)
logger:
level: INFO
# Enable Home Assistant API
api:
ota:
password: "XXXXX"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
fast_connect: true
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Distance-Sensor-0"
password: "XXXXX"
captive_portal:
# the vl53l0x is i2c
i2c:
scan: true
##
## The virutal break beam sensor.
## The state of this will be controlled
## by breakbeam_sensor_dist's lambda as necessary.
##
binary_sensor:
- name: "Breakbeam Sensor"
id: breakbeam_sensor
platform: template
device_class: motion
##
## The actual sensor.
## This sensor's lambda will control the state of our
## virtual break beam sensor, breakbeam_sensor.
##
sensor:
- name: "Breakbeam Sensor Dist"
id: breakbeam_sensor_dist
platform: vl53l0x
address: 0x29
update_interval: 0.1s
long_range: true
internal: true
#
# Only send a value back if breakbeam_sensor changes.
#
filters:
- lambda: !lambda |-
/**
* YOU MIGHT WANT TO CONFIGURE THIS.
* Distance below which to trip the virtual break beam sensor.
* '0.5' meters is about 20 inches.
*/
static double minTripDistance = 0.5;
if (x <= minTripDistance) {
if (id(breakbeam_sensor).state == true) {
// Beam was already broken
return {};
}
// Beam was just broken
id(breakbeam_sensor).publish_state(true);
ESP_LOGI("breakbeam_sensor_dist", "Set breakbeam_sensor to Detected");
return {};
}
else {
if (id(breakbeam_sensor).state == false) {
// Beam was already un-broken
return {};
}
// Beam was just un-broken
id(breakbeam_sensor).publish_state(false);
ESP_LOGI("breakbeam_sensor_dist", "Set breakbeam_sensor to Cleared");
return {};
}
@kdorff
Copy link
Author

kdorff commented Nov 27, 2023

@kerimtrn
It sounds like you want to remember the last 3 readings and only trigger if the current and the previous 3 entries are correct.
I'd keep an array of readings, and keep track where you are writing in the array so you write to the array over and over. Do some reading about creating a circular buffer using an array.

Alternatively, you could look at what I did with data-smoothing.h in https://github.com/kdorff/esphome/blob/main/cat-water-sensor/cat-water-sensor.yaml. My code in data-smoothing.h assumes the data is an int and would need to be changed to double, I imagine.

@kerimtrn
Copy link

Hello

Thank you for your quick answer. I actually think about simpler solution if it is possible to do. Just like a button filtering, can I use a filter to activate the virtual sensor after 0.2 seconds of activity? I use delay_on on my buttons to prevent fluctuations but it did not work for this one when I tried. Maybe I did something wrong or maybe it is not possible for this kind of entity.

@kdorff
Copy link
Author

kdorff commented Nov 30, 2023

The lamda, itself, is a filter. Look at other filtering you can do on sensor https://esphome.io/components/sensor/index.html
Perhaps sliding_window_moving_average could be helpful? or median or quantile? I'm not entirely sure how they would interact with the lambda but the docs may say or just experimentation.

@wizardnl
Copy link

@wizardnl AWESOME! I'm glad you got it all running! Thanks for the heads up about changing address - very useful! I don't think the ESPHome driver did that when I first implemented this (or I missed it). I would have loved to have used just one.

Had to try it to see if it would work with 14 sensors. ;-) In theory, I can now control every step on my stairs individually. I still need to do some intensive testing, but for now, it works. Thanks again for sharing your code.
20231212_223816 (Klein)

@photonclock
Copy link

@wizardnl Looks like you picked up the ball and ran with it. Sure would be appreciated if you shared the code you came up with in a new gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment