How to? ESPHome Time-of-Flight sensor reporting every 5s and I want to eliminate small variations in the reported value yet respond to a large change on next update

Warning: This might make you scratch your head a bit!!
:thinking:
The Goal: Convert distance patio door is open in meters to a % to open the vertical blind and not have it change from 35% to 40% to 35% to 40% yet have it change within 5s from 35% to 60%.
Input: ESPHome -platform vl53l0x, range 0.00m to 0.80m (0 to 32 inches), every 5s.
Adjust blind position: 0% to 60% in steps of 5%.
So far: I have a template that converts the distance in metres to desired percent, in increments of 5%.
Problem: With the variations every 5s in measured distance, the templated percent can bounce from 35% to 40% to 35% to 40%.
Desired Solution: Figure out how to prevent small fluctuations in measurements from constantly re-adjusting the blind yet immediately adjust the blind when there is a large change!

ESPHome config:

esphome:
  name: patio-door-distance-sensor
  friendly_name: Patio Door Distance Sensor

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "<redacted>"

ota:
  password: "<redacted>"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Patio-Door-Distance"
    password: "<redacted>"

captive_portal:

i2c:
  sda: 21
  scl: 22
  scan: true
  id: bus_a

sensor:
  - platform: vl53l0x
    name: "Patio Door Distance"
    address: 0x29
    update_interval: 5s
    long_range: true
    unit_of_measurement: "m"
    filters:
      - calibrate_linear:
        - 0.0 -> 0.0
        - 0.19 -> 0.24
        - 0.80 -> 0.80

Sensor template:

{{ ((states("sensor.patio_door_distance")|float(0) * 39.37 / 30 * 55) / 5) | round(0) * 5 }}

I have tried a compensation sensor but it requires a numerical input and this one is string.

south_patio_vertical_blind_position:
#  source: sensor.south_patio_door_open_distance
  source: sensor.patio_door_distance
  unit_of_measurement: "%"
  lower_limit: true
  upper_limit: true
  precision: 0
  data_points:
    - [0.2, 80.0]
    - [0, 60]

I also tried - platform: average but it’s too slow to update to large changes.

  - platform: average
    name: Patio Door Position
    unique_id: patio_door_position
    duration: 00:02:00
    entities:
      - sensor.patio_door_distance

In ESPHome use a combination of the delta and throttle filter. For example:

    filters:
      - or:
          - throttle: 30s
          - delta: 24

This will send updates every 30 seconds except if the amount changes by more than 24%, in which case it will send immediately.

Adjust the values as needed.

Adding a windowed average of 10 values can cut down noise too and only slows the response slightly.

sensor:
  - platform: vl53l0x
    name: "Patio Door Distance"
    address: 0x29
    update_interval: 5s
    long_range: true
    unit_of_measurement: "m"
    filters:
      - calibrate_linear:
        - 0.0 -> 0.0
        - 0.19 -> 0.24
        - 0.80 -> 0.80
      - sliding_window_moving_average:
          window_size: 10
          send_every: 1
1 Like

You’re a genius!! I am relatively inexperienced at ESPHome config options and I’ve spent days trying to find something. I am trying the filters: throttle (60s) OR delta (5)…


Thanks!

Still changing but not as often…


Will try the sliding window now…

Still fluctuates…



You appear to be applying that to your raw distance, not the % distance. This means that the delta won’t be used unless you move more than 5m!

So the delta is absolute not %? My % is an HA template therefore delta would be .05 for the absolute meter measurement?

It depends ow you specified it. See: Sensor Component — ESPHome

- delta: 5 # absolute 5 units
- delta: 5% # 5% change from previous value.

I just changed it from “5” to “.05” and it seems stable yet quite responsive to larger changes!

  - platform: vl53l0x
    name: "Patio Door Distance"
    address: 0x29
    update_interval: 5s
    long_range: true
    unit_of_measurement: "m"
    filters:
      - calibrate_linear:
        - 0.0 -> 0.0
        - 0.19 -> 0.24
        - 0.80 -> 0.80
      - or:
          - throttle: 300s
          - delta: 5%

Thank you!

1 Like