Tuesday, January 30, 2024

ESPHome Water Softener Salt Level Sensor

Sometime ago I was searching for a way to monitor the level of salt in my water softener and came across this post using a D1 mini and an Ultrasonic Distance Sensor with ESPHome. I don't have many devices connected to ESPHome, and it is quite sparse only about 5 devices. Some temperature/humidity sensors, a string light switch, a bluetooth proxy, and now this water softener sensor.

The configuration from here was working great until the latest update to ESPHome, mostly my fault because I didn't read the release notes. When I went to update the sensor, I could only get the measurements to return and not the percentage. Come to find out that what was missing was the ability for the trigger pin and echo pin to allow to be reused:

- platform: ultrasonic
  trigger_pin: 
    number: D2
    allow_other_uses: true
  echo_pin: 
    number: D1
    allow_other_uses: true

A few modifications that I made (albeit not sure if it makes any difference) was to set a global variable for the maximum distance detected by the sensor

globals:
 - id: maximum_distance
   type: float
   initial_value: '0.83'

Then also to save the measurement as an id salt_level_measurement to be reused for the calculation of percentage and use the maximum_distance variable:

 - platform: ultrasonic
    trigger_pin: 
      number: D2
      allow_other_uses: true
    echo_pin: 
      number: D1
      allow_other_uses: true
    name: Salt level measurement
    update_interval: 60s
    pulse_time: 200ms
    timeout: 4.0m
    id: salt_level_measurement
    filters:
      - lambda: return (id(maximum_distance)-x)*(100/id(maximum_distance));
      - filter_out: nan
    unit_of_measurement: cm

All in all, it works really well. Here is the complete config file for the sensor, the update time is every 60 seconds which may be overkill, but I'll end up adjusting it if need be. Hope this helps!

api:
  encryption:
    key: "redacted"
captive_portal:
esp8266:
  board: d1_mini
esphome:
  name: ${name}
  friendly_name: ${friendly_name}
globals:
 - id: maximum_distance
   type: float
   initial_value: '0.83'
logger:
ota:
  password: "redacted"
sensor:
  - platform: uptime
    name: salt_level_sensor Uptime
  - platform: wifi_signal
    name: salt_level_sensor WiFi Signal
    update_interval: 60s
  - platform: ultrasonic
    trigger_pin: 
      number: D2
      allow_other_uses: true
    echo_pin: 
      number: D1
      allow_other_uses: true
    name: Salt level measurement
    update_interval: 60s
    pulse_time: 200ms
    timeout: 4.0m
    id: salt_level_measurement
    filters:
      - lambda: return (id(maximum_distance)-x)*(100/id(maximum_distance));
      - filter_out: nan
    unit_of_measurement: cm
  - platform: ultrasonic
    trigger_pin: 
      number: D2
      allow_other_uses: true
    echo_pin: 
      number: D1
      allow_other_uses: true
    name: Salt level percent
    update_interval: 60s
    pulse_time: 200ms
    timeout: 4.0m
    filters:
      - lambda: return (id(maximum_distance)-x)*100;
      - filter_out: nan
    unit_of_measurement: "%"
substitutions:
  name: salt-level-sensor
  friendly_name: Water Softener
switch:
  - platform: restart
    name: salt_level_sensor Restart
text_sensor:
  - platform: version
    name: salt_level_sensor ESPHome Version
  - platform: wifi_info
    ip_address:
      name: salt_level_sensor IP
    ssid:
      name: salt_level_sensor SSID
    bssid:
      name: salt_level_sensor BSSID
time:
  - platform: homeassistant
    id: homeassistant_time
web_server:
  port: 80
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "Salt-Level-Sensor"
    password: "redacted"