Skip to content

Instantly share code, notes, and snippets.

@hump-coder
Created August 22, 2025 00:40
Show Gist options
  • Save hump-coder/a733af695d6075289933eb15ef3abb3d to your computer and use it in GitHub Desktop.
Save hump-coder/a733af695d6075289933eb15ef3abb3d to your computer and use it in GitHub Desktop.
Transducer ESPHome Yaml for raw and smoothed data.
esphome:
name: pressure-water-level-sensor
friendly_name: Water Tank Level (pressure)
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "YOUR-KEY="
ota:
- platform: esphome
password: "YOUR-PASS"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Water-Tank-Level-Pressure"
password: "YOUR-PASS"
captive_portal:
globals:
- id: raw_adc_voltage
type: float
restore_value: no
initial_value: '0.0'
sensor:
# Raw ADC voltage from pressure sensor
- platform: adc
pin: GPIO33
id: water_tank_voltage
attenuation: 12db
update_interval: 5s
internal: true
on_raw_value:
then:
- lambda: |-
id(raw_adc_voltage) = x;
filters:
- calibrate_linear:
method: least_squares
datapoints:
- 0.14200001 -> 0
- 2.48832 -> 2.856
- 3.3 -> 3.3
- lambda: |-
static std::deque<float> recent_readings;
static const size_t window_size = 300;
recent_readings.push_back(x);
if (recent_readings.size() > window_size) {
recent_readings.pop_front();
}
float sum = 0.0;
for (const auto& reading : recent_readings) {
sum += reading;
}
return sum / recent_readings.size();
- median:
window_size: 20
send_every: 20
send_first_at: 20
# Apply linear calibration filter to raw voltage separately
- platform: template
id: calibrated_raw_voltage
# name: "Calibrated Raw Voltage" # commented to suppress logging
internal: true
update_interval: 10s
lambda: |-
return id(raw_adc_voltage);
filters:
- calibrate_linear:
method: least_squares
datapoints:
- 0.14200001 -> 0
- 2.48832 -> 2.856
- 3.3 -> 3.3
# Calculates water depth in meters
- platform: template
internal: true
#name: "Water Level" # commented to suppress logging
unit_of_measurement: "m"
id: water_level
icon: "mdi:water"
accuracy_decimals: 2
update_interval: 20s
lambda: |-
if(!std::isnan(id(water_tank_voltage).state))
{
float voltage = id(water_tank_voltage).state;
float depth = (voltage / 3.3) * 3.0;
if (depth > 2.4) {
ESP_LOGI("Pressure V", "WAS: %.5f, NOW %.5f", depth, 2.4f);
depth = 2.4;
}
return depth;
}
return {};
# Calculates water volume in liters
- platform: template
name: "Water Volume"
unit_of_measurement: "L"
icon: "mdi:water-percent"
accuracy_decimals: 0
update_interval: 20s
lambda: |-
if(!std::isnan(id(water_level).state))
{
float depth = id(water_level).state;
float volume = (depth / 2.4) * 24000;
return volume;
}
return {};
# Calculates water level as percentage
- platform: template
name: "Water Level Percent"
unit_of_measurement: "%"
icon: "mdi:water-percent"
accuracy_decimals: 2
update_interval: 20s
lambda: |-
if(!std::isnan(id(water_level).state))
{
float depth = id(water_level).state;
float percent = (depth / 2.4) * 100;
if(percent > 100)
return 100;
if(percent < 0)
return 0;
return percent;
}
return {};
# Raw water level percent based on calibrated raw readings
- platform: template
name: "Raw Water Level Percent"
icon: "mdi:water-alert"
unit_of_measurement: "%"
accuracy_decimals: 2
update_interval: 10s
lambda: |-
static std::deque<float> raw_values;
static int reading_count = 0;
int ignore_initial_readings = 2;
int raw_deque_length = 5;
float voltage = id(calibrated_raw_voltage).state;
if (!std::isnan(voltage)) {
reading_count++;
if (reading_count > ignore_initial_readings) {
raw_values.push_back(voltage);
if (raw_values.size() > raw_deque_length) {
raw_values.pop_front();
float sum = 0.0;
for (auto v : raw_values) sum += v;
float avg_voltage = sum / raw_values.size();
float depth = (avg_voltage / 3.3) * 3.0;
if (depth > 2.4) depth = 2.4;
if (depth < 0) depth = 0;
float percent = (depth / 2.4) * 100;
return percent;
}
}
}
return {};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment