A very ESPHome Christmas (tree)

I’ve gotten tired of having to remember to check the water reservoir for the Christmas tree, so I’ve used an ESP32 and an ultrasonic sensor to let me know the level of the water under the tree. It’s even got a festive light, and I hung it from a branch using an ornament hook so it’s the first light AND ornament on the tree!

I’ve created some “convenience” sensors to provide details like the % of water remaining from the “max fill” line (I initially put in 5 liters of water, so that’s what I’m considering the max) and the amount of liters remaining based on the % remaining * max_fill, etc… This will really help me keep the tree hydrated this year. The math is made a little easier by the fact that 5 liters is 10cm high in the stand that I have! To keep it safe from the water, the ultrasonic sensor is mounted higher than that, 14cm from the bottom of the stand, so I have a few global variables that help with those calculations.

Screen Shot 2022-12-14 at 1.18.02 PM

This is based on another ESPHome project I have that’s doing relatively the same thing in my water softener in the basement (another thing I neglect to check on regularly).

The configuration is:

esphome:
  name: christmas-tree

esp32:
  board: esp32dev
  framework:
    type: arduino

globals:
  # distance between bottom of container and sensor position
  - id: sensor_height
    type: float
    initial_value: '0.14'

  # distance between max fill line and sensor position
  - id: distance_offset
    type: float
    initial_value: '0.04'

  # distance between bottom of container and max fill line
  - id: max_fill_height
    type: float
    initial_value: '0.10'

  # max volume of container in liters
  - id: max_volume
    type: float
    initial_value: '5.0'

sensor:
  - platform: ultrasonic
    id: "raw_distance"
    trigger_pin: GPIO17
    echo_pin: GPIO18
    name: "Water Level Distance"
    update_interval: 10s
    unit_of_measurement: "m"

  - platform: copy
    source_id: "raw_distance"
    name: "Water Level Distance From Max Fill Line"
    filters:
    # Calculates distance, in centimeters, of the difference between the max fill line height and the current level
    - lambda: return (x - id(distance_offset)) * 100;
    unit_of_measurement: "cm"

  - platform: copy
    source_id: "raw_distance"
    name: "Remaining Water Level"
    filters:
    # Calculates height, in centimeters, of water pellets remaining
    - lambda: return (id(sensor_height) - x) * 100;
    unit_of_measurement: "cm"

  - platform: copy
    source_id: "raw_distance"
    name: "% Remaining Water Level"
    filters:
    # Calculates % of water remaining
    - lambda: return (id(sensor_height) - x) * (100/id(max_fill_height));
    unit_of_measurement: "%"

  - platform: copy
    source_id: "raw_distance"
    name: "Liters Remaining"
    filters:
    # Calculates remaining volume based on % remaining 
    - lambda: return ((id(sensor_height) - x) * (100 / id(max_fill_height)) / 100) * id(max_volume);
    unit_of_measurement: "l"
7 Likes

Good idea. I will also do this for next year :+1: