My setup for my Ultrasonic tank level sensor is based upon ESPHome and the Ultrasonic platform.
I am measuring the distance from the sensor to the top of the fluid in the tank.
Originally I had just one sensor set up in the ESPHome config, measuring distance.
sensor:
- platform: ultrasonic
trigger_pin:
number: GPIO4 #Yellow sensor cable from A02YYUW
echo_pin:
number: GPIO5 #White sensor cable from A02YYUW
name: "Distance to Oil"
id: oil_distance
unit_of_measurement: "m"
accuracy_decimals: 2
update_interval: 1s
timeout: 10.0m
filters:
- sliding_window_moving_average:
window_size: 20
send_every: 20
From this, I created 2 template sensors in HA in order to convert this distance into a % of tank remaining as well as a reading for the number of Litres of fluid remaining.
# Converting calculated % of tank remaining into Litres. Tank holds 1300L when full
- name: "Oil Remaining"
unit_of_measurement: "Litres"
state: "{{ (13 * (states('sensor.oil_level')|float(0))) | round(1) }}"
# Converting measured distance from Ultrasonic sensor into % of tank remaining.
# 1.12m from sensor to bottom of tank, 0.2m air gap from oil when full to sensor
- name: "Oil Level"
unit_of_measurement: "%"
state: "{{ (100 * (1.12 - (states('sensor.distance_to_sensor')|float(0)) + 0.2) / 1.12) | round(1) }}"
As the ‘oil remaining’ value is based on a % of tank being full, it is only an approximation. I have subsequently found a chart for my tank, which lists EXACT volume levels for several given heights.
I thought about changing my setup and creating an extra sensor in my ESPHome config to give me the Litres remaining, based on the measured distance form the sensor, and using the calibrate_linear filter, including all the known data points.
- platform: ultrasonic
trigger_pin:
number: GPIO4 #Yellow sensor cable from A02YYUW
echo_pin:
number: GPIO5 #White sensor cable from A02YYUW
name: "Oil Remaining"
id: oil_remaining
unit_of_measurement: "L"
accuracy_decimals: 0
update_interval: 1s
timeout: 10.0m
filters:
- calibrate_linear:
# Map 0.0 (from sensor) to 0.0 (true value)
- 1.20 -> 93
- 1.10 -> 217
- 1.00 -> 361
- 0.90 -> 516
- 0.8 -> 678
- 0.7 -> 843
- 0.6 -> 1002
- 0.5 -> 1147
- 0.4 -> 1269
- 0.3 -> 1356
- 0.2 -> 1378
Unfortunately this is now giving me incorrect readings. For exapmle, setting the distance at 0.20m, I am getting a reading of 1507 Litres, rather than the 1378 Litres that I entered in the filter for this distance.
After re-reading the ESPHome calibrate_linear documentation, it seems that the entered data point values can actually change if you enter more than 2, as it has to create the linear relationship that fits best.
Can anyone suggest an alternative way of plugging these known data points in, so that only the readings between these known data points are estimated based on a linear scale?