Created
          August 22, 2025 00:40 
        
      - 
      
 - 
        
Save hump-coder/a733af695d6075289933eb15ef3abb3d to your computer and use it in GitHub Desktop.  
    Transducer ESPHome Yaml for raw and smoothed data.
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | 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