measure heating oil usage with a Vl53L0X time of flight sensor and display on an energy dashboard
how to make a heating oil tank level sensor that’s more useful than anything you can buy.
This sensor…
- can measure oil level in any unit – litres, kWh, gallons or days until I need to refill the tank
- displays readings on a time graph (uses Home Assistant history graph).
- receive readings or alerts as an email or phone notification or flashing smart bulb in the house.
- help calculate the date when you’ll need to order or tell you how much free space there is in the tank
- show your oil usage on the Home Assistant wnergy dashboard
- uses an infrared based Vl53L0X time of flight sensor (~£5 ebay)
- uses any ESP32 or ESP8266 development board with wifi. I used a nodemcu v3 ESP8266 (~ £6).
- could work outdoors and on battery power with a waterproof electrician’s housing. If you need to use battery power an ESP8266 might be more appropriate. The battery power might be 6 x 18650 cells based on this power pack I made
- this sensor could instead monitor the salt level in a water softener or the water level in a tank (ref Dr Zzz – youtube)
Background: homes like mine use diesel oil as a fuel to keep warm in winter. Over the course of a winter I might need two or three deliveries of oil but I’ve no way to predict when I’ll need more oil or know how much to order. And I really don’t ever want to run out of oil. The oil is burned in a heating boiler in the same way that many homes in the UK burn methane gas. Although we call the liquid ‘heating oil’ it’s more runny than lubricating oil. You may call it diesel or white spirits or turps or paraffin or kerosine.
I asked local firm Shelford Heating to quote a price for an oil level sensor. Their solution involved drilling the steel tank to fit an Apollo wireless kit – but £220 seemed excessive for this need. I could also have bought the kit, which sends an approximate oil level to a display but I really wanted something that could alert me better.
what’s needed for this project
- Vl53L0X time of flight sensor
- coloured Dupont wires or coloured 18 gauge stranded wires if the wires need to be long
- if your tank is outdoors you’ll need waterproofing (eg Kafuter K-705 gel plus a housing) and get a 5v supply to the oil tank
- an ESP8266 or ESP32 development board
- Home Assistant already set up on a Raspberry Pi
- heat shrink tubing and soldering skills if you want to make reliable connections (you do)
- if you want notifications you need your email account server settings (optional)
- if you want to keep long term records you’d need to send the data to Google Sheets (optional)
there are other posts on this topic
- an earlier oil tank level sensor using the ultrasonic JSN-SR04T
- how I mounted and calibrated the sensor for my oil tank
- the final step where I get Home Assistant to calculate when I need to order oil and display that
- the trick to send sensor data from Home Assistant to a spreadsheet
how to connect up an oil level sensor to a ESP32 / ESP8266 development board
This is the current version of my original oil tank level sensor using the ultrasonic JSN-SR04T that has been working reliably for years. It runs in parallel with the older sensor. The limitation of the older ultrasonic sensor is that it cannot measure at short range so it records the same oil level whether the tall is full or 200mm below full. When the level drops by 200mm the readings are still very useful at alerting me to order more oil.
The Vl53L0X time of flight sensor is an inexpensive alternative that works by sending infrared blips to the liquid surface and then measuring the ‘time of flight’ to estimate how far away it is. It can send correct values at short range ie even if the tank is full. You can find versions of this sensor (VL53L0X, TOF10120, VL53L1X, VL6180X) which work best at different distances (eg below). HOWEVER, do check that ESPHome supports it. I chose the Vl53L0X because it’s supported and made for the range 30mm-1200m as suits my tank. (A post at instructables states that the VL53L1X is a better and more expensive sensor – but one year on I’m very happy with the project as follows. But check: is the sensor supported by your software).
The ESPhome software we use can also set the sensor to a long distance remote range of 1500 -2000mm. Wonderfully, when the sensor is hooked up it sends a distance value (in metres) and I can multiply that by a number to get readings in mm or litres or kW or even money. The calculation is simpler if your oil tank has a regular shape but anything is doable.
The Vl53L0X module has six pin connectors – you only need to use four of them. I used Dupont male to female wires because my ESP8266 nodemcu already had pins. I soldered the male pins to the Vl53L0X module and extended the wires with coloured cables (silicone 18 AWG 0.75mm) and covered the join in heat-shrink. GND and VIN connect to GND and 3.3v on an ESP8266 module. Connect SCL to D1 (or GPI05). Connect SDA to D2 (or GPI04). For connections to a ESP32 see the image below
a housing to protect the VL53L0X oil level sensor and ESP
This is where my system will surely be different. A 3D printed part holds the sensor in place with the help of some hot glue. I don’t yet know if the vapour from the oil will damage the VL53L0X so I’m looking to improve the housing.
Getting dirt in the tiny emitter and sensor holes is to be avoided as the emerging pulse or photon can be deflected randomly / cause crosstalk. So I cut a 30mm circle of acetate film (from a phone case) and glued it to the cap I’d made for the sensor. I might have used a piece of phone screen protector and it would wise to test if the cover affects the distance reading. I cover this in my post about mounting and calibration here.
You can protect the sensor with glass, perspex or polycarbonate. The cover should be as thin, flat, parallel, clear and fitted close to the sensor as possible. ST, the chip maker have a video explaining how a more fussy two-piece glass cover pretty much reduces the crosstalk due to dust. I so wish they’ll create a similarly protected chip. The sensor notes are here.
The sensor needs to be fixed so that it points down at the surface of the oil in the tank (photo). I used a tank hole that had housed the dipstick. A suitable cap, as shown below, was made on a 3D printer. A container cap might have worked … as long as it doesn’t wobble and thus affect the readings. You might instead drill a hole for it but I’ve no advice on this.
how to write the program and install it on the ESP 32 / ESP8266 development board
My oil sensor is a ‘connected’ oil sensor. It takes readings, sends them to Home Assistant which will present them in various ways. To gain this connectivity you need a working Home Assistant installation on a Raspberry Pi (shown in an earlier project).
What you do is to assemble a series of instructions (a program) and get the instructions turned into a file (=compiled into a ‘bin file’) that you upload to a ESP dev board via a USB cable. The file is otherwise called firmware. The process of installing the file to the ESP is called flashing the firmware although what you’re doing is akin to installing the program.
- use your browser to interact with Home Assistant on 192.168.x.x:8123
- in Home Assistant go to the Esphome add-on and add a ‘new device’. Follow the process eg it’ll ask you for a name (eg oil level) and you may be asked to fill in wifi details.
- Still in Esphome look for ‘Edit’ next to your new device. Add the following code making changes to suit your setup.
- choose Install to upload this code to your development board.
# THIS IS FOR AN ESP8266 development board # see final version further down this page if your trace is noisy # we produce two entities, one for litres one for kWh esphome: name: oil-tof substitutions: devicename: oil-tof esp8266: board: nodemcuv2 # enable logging logger: # enable Home Assistant API api: encryption: key: "FtKhT5Sf4cwe5bh/N0Kzy6JMM5LG79H38rfceMlBHrE" ota: password: "" wifi: ssid: !secret wifi_ssid password: !secret wifi_password manual_ip: # set this to the IP of the ESP static_ip: 192.168.1.15 # set this to the IP address of the router gateway: 192.168.1.1 # the subnet of the network subnet: 255.255.255.0 # hotspot in case wifi connection fails ap: ssid: "oil-tof fail hotspot" password: !secret wifi_password captive_portal: i2c: sda: D2 #GPI04 orange or green (data) pin 4 scl: D1 #GPI05 yellow or blue (clock) pin 5 scan: true # use this sensor section - it works but to remove noise # see the complicated version further down this page sensor: - platform: vl53l0x name: "oil kW" address: 0x29 id: myoillevel update_interval: 10s long_range: false accuracy_decimals: 0 filters: - lambda: return (x - 0.034) * 1000 * 10; state_class: total device_class: energy unit_of_measurement: "kWh" # post comments below explain my calibration # return (x - 0.034) * 1000 * 10 - you could instead use # return x * 1000 * 10 to get readings as kWh - platform: template name: "oil_level" # update_interval: 60s accuracy_decimals: 0 unit_of_measurement: "L" lambda: |- return -0.1 * id(myoillevel).state ; # negative to get a decreasing oil level switch: - platform: restart name: ${devicename} restart
# THIS IS FOR AN ESP32 development board # see final version further down this page if your trace is noisy # we produce two entities, one for litres one for kWh esphome: name: oil-tof substitutions: devicename: oil-tof esp32: board: esp32dev framework: type: arduino # enable logging logger: # enable Home Assistant API api: encryption: key: "FtKhT5Sf4cwe5bh/N0Kzy6JMM5LG79H38rfceMlBHrE" ota: password: "" wifi: ssid: !secret wifi_ssid password: !secret wifi_password manual_ip: # set this to the IP of the ESP static_ip: 192.168.1.15 # set this to the IP address of the router gateway: 192.168.1.1 # the subnet of the network subnet: 255.255.255.0 # Enable hotspot if case wifi connection fails ap: ssid: "oil-tof fail hotspot" password: !secret wifi_password captive_portal: i2c: sda: 21 # orange or green scl: 22 # yellow or blue scan: true # use this sensor section - it works but to remove noise # see the complicated version further down this page sensor: - platform: vl53l0x name: "oil kW" address: 0x29 id: myoillevel update_interval: 10s long_range: false accuracy_decimals: 0 filters: - lambda: return (x - 0.034) * 1000 * 10; state_class: total device_class: energy unit_of_measurement: "kWh" # use negative below to get negative oil level - platform: template name: "oil_level" # update_interval: 60s accuracy_decimals: 0 unit_of_measurement: "L" lambda: |- return -0.1 * id(myoillevel).state ; # see user comments below for an explanation of # return (x - 0.034) * 1000 * 10 - you could instead use # return x * 1000 * 10 to get readings as kWh switch: - platform: restart name: ${devicename} restart
add your sensor data to the Home Assistant overview
- when the code is installed, power-up the ESP board with a USB power source and go to Home Assistant > Integrations > + > ESPHome. You might have to enter the IP address you chose in the code. You’ll then see the oil level device that has been added to Home Assistant. The device will have an entity named like sensor.oil_level
- go to the Home Assistant Overview where your stuff is normally displayed. Choose Edit dashboard in the top corner.
- add a new card called history graph. On the entity line select your sensor.oil_level
- add a new card called gauge to display your oil level. On the entity line select your sensor.oil_level
*refine the oil level sensor code
handle a few issues:
After several months use I needed to address some issues. Because of these points I modified the code as shown below. You may want to substitute the above ‘sensor:’ section with the following ‘sensor:’ section (explained below)
- maxing out: at low oil levels the sensor is bouncing off a metal strut inside the tank so I need to relocate the sensor somewhere else. My readings plateau when the tank drops to 20% full.
- calibration: the sensor measures in metres so I have to calculate the litres. My tank has a perfectly regular shape from top to bottom – so by measuring dipstick depths, I found that 100cm of tank depth contains 105.3 litres. In the code below the last two lines (filter and lamda) do this calibration. The two lines can be edited or entirely omitted to suit your tank.
- the readings were a bit noisy. To counteract this I calculate the sliding average of an oil level reading. In my final version I replaced the sliding average with a Kalman calculation.
- it was suggested that the ‘oil used’ graph should fall, not rise, so I made the reading negative. This also makes it easier to know how much oil to order. I should rename the sensor ‘oil used’ because the number it returns is the amount of oil I need to buy to fill the tank. Next I really don’t need an oil level reading every 10 seconds so I increased the update interval. The commercially available FoxRadar takes only a few readings per day.
# add a filter to the sensor section to calibrate the sensor. # add a negative sign to produce a falling oil level: #filters:
#- lambda: return x * -1053;
# note: 1053 is 1.053 (fiddle factor for tank) * 1000 (convert to litres) # add a sensor filter to remove noise: filters: - lambda: return x * 1053; - sliding_window_moving_average: window_size: 20 send_every: 10 # if your tank shape is irregular you can put your calibration # graph of distance and volume in the code. SEE THE POST # FROM 'Kev' below where he improved the filter section so: # – calibrate_linear: # – 110 -> 0 # – 95 -> 204 # – 75 -> 544 # – 55 -> 900 # – 35 -> 1320 # – 15 -> 1660 # – 0 -> 1800
when do I need to order more oil?
The first nice consequence is that I now know how much oil I need to order and how much I use. We might now need the following:
- to predict the date when we need to order more oil and get notified – see how I calculate when I need to order more oil using Home Assistant
- to store our oil use in a spreadsheet as well as record the outside temperature – see send sensor data from Home Assistant to a spreadsheet
the trace is very noisy – how to remove noise from the trace
The code below includes ways to remove noise from the readings. The quantile filter removes ‘outliers’ (the readings that are wild). Having removed the outliers we use a kalman calculation to smooth the graph. The results are good however occasionally the oil kWh wavers, goes negative and makes a mess of the Energy Dashboard. We therefore create a sensor that doesn’t go negative. This code produces four entities – only two are needed.
- “oil kw-raw” – the raw reading from the sensor as kWh. Includes a tank fiddle factor (1000) to turn mm into litres
- “oil kalman” – we do a ‘Kalman’ calculation on the raw kW to smooth it
- “oil_level” – we take the smoothed “oil kalman” and convert kWh to litres by dividing it by 10
- “oil_kalkw” – we take the smoothed “oil kalman” and prevent it from producing a lower value than the last reading.
IN ESPHOME - revised code for ESP32 and ESP8266 December 2023 # replace the entire sensor section and add globals sensor: - platform: vl53l0x name: "oil kw-raw" address: 0x29 id: myoilkw # UNFILTEREDKW update_interval: 10s long_range: false accuracy_decimals: 0 unit_of_measurement: "kWh" state_class: total device_class: energy filters: - lambda: return x * 1000 * 10; # - lambda: return x * your-tank-factor * kW/L - platform: template name: "oil_level" id: myoillevel # unFILTEREDL accuracy_decimals: 0 unit_of_measurement: "L" state_class: total lambda: |- return -0.1 * id(mykalmankw).state ; **************** REPLACE THIS ************ - platform: kalman_combinator name: "oil kalman" id: mykalmankw accuracy_decimals: 0 unit_of_measurement: "kWh" state_class: total device_class: energy process_std_dev: 0.001 sources: - source: myoilkw # UNFILTERED error: 1 **************** WITH THIS ********************* - platform: combination type: kalman name: "oil kalman" id: mykalmankw accuracy_decimals: 0 unit_of_measurement: "kWh" state_class: total device_class: energy process_std_dev: 0.001 sources: - source: myoilkw # UNFILTERED error: 1 *********************************************** - platform: copy source_id: mykalmankw name: "oil_kalkw" accuracy_decimals: 0 # filters: to reject a lower value filters: - skip_initial: 50 - quantile: window_size: 6 send_every: 6 send_first_at: 6 quantile: 0.95 - lambda: |- if (abs(x < id(last_good_value))) return {}; id(last_good_value) = x; return x; globals: - id: last_good_value type: int restore_value: no initial_value: '100' - id: counter type: int restore_value: no initial_value: '0' # add the code above in place of the sensor code earlier.
edit the Home Assistant energy dashboard
Go to Settings > Dashboards > Gas Consumption > Add Gas Source and find the entity for oil usage in kWh. In my example above this would be “oil_kalkw” or “oil kalman”. To track the costs enter a number e.g. 0.085 GPB/kWh or create an input number (in Helpers) such as input_number.oil_now_cost with a value of 0.085.
Example: if heating oil costs £0.85 per litre which ideally burns to produce 9 kWh of energy. For simpler maths I call this £0.85 for 10 kWh or £0.085 for 1 kWh. You could tweak this to allow for inefficient burning. If I had a home that didn’t use and leak so much energy I might see the value of pretending to be accurate.
What do the values 1018 or 330 stand for?
– lambda: return (x – 0.034) * 1018 * 10;
Can you explain this line, please?
x = the distance the sensor measures
0.034 = some offset like sensor packaging ???
1018 = ??
10 = ??
Where do you input the tank dimensions for the calculation?
Thanks for writing in with a question. I’ve a few posts on this topic and the explanation* for the factors hasn’t carried over to each post.
x = the distance the sensor measures
0.034 = some offset because values do not reach zero on a calibration graph – this is the intercept
1018 = a tiny fiddle factor specific to my tank based on a few tank top-up refills. It’s 1.018 and because I want litres it’s 1.018 * 1000
10 = convert litres to kW. It should be 9kW per litre but I used 10kW.
* https://www.rogerfrost.com/water-or-oil-tank-level-mounting-a-vl53l0x-time-of-flight-sensor/
There’s a new post coming in the next few days on my success to add Oil consumption to a HA energy dashboard
Is this example actually measuring oil? or not
Did you show an example of how oil can be used with water?
Is this example actually measuring oil? Yes, oil. In litres.
Did you show an example of how oil can be used with water? No. I use the same equipment to monitor the level of a water tank.
Hi Roger
Great write up !
with regards to Current / power reduction / optimisation when on battery.
Does the Vl53L0X board uses standby current when the ESP is in deep sleep? looking at this website “https://www.instructables.com/WiFi-Oil-Tank-Monitor” they use a transistor connected to one of the outputs, thus perhaps an adaptation of this for ESPhome which turns on a dedicated pin to the base of the transistor, hopefully when in deep sleep the pin will be off and transistor not charged?
Do you think this will work?
esphome:
name: oil-sensor
on_boot:
then:
– delay: 5s
– output.turn_on: sample_pin
output:
– platform: gpio
pin: 5
id: sample_pin
deep_sleep:
run_duration: 30s
sleep_duration: 2min
Thank you Stuart. I haven’t yet switched to battery power but I know another contributor on here who has – contact Kev aka this guy on youtube https://www.youtube.com/c/Mr12v
Was creating similar for my mum, then found she had an old Watchman ultrasonic, but I’d planed to use the VL53L0X/1X. Thought I’d combine with the lilygo T-QT Pro, but only for the visual feedback during setup. Found some sensors that had a nice cover on aliexpress, doubt they’re tested for oil fumes but what I ended up with: https://www.aliexpress.com/item/1005003091941068.html (2nd and 3rd variants)
Thank you Tyeth for the link! I’ve incorporated your find in the post. I agree that this cover, or its mount, needs long term testing against oil fumes – in an earlier project using a sonar distance sensor all of the ABS plastic of that sensor has dissolved. One ray of hope is that the PLA plastic used to print a holder mount HAS not perished. I continue to look for a glass/metal casing.
And the use of a Lilygo T-display does indeed make it mum-friendly! That’s good. Those displays are excellent and these days there’s code to have a slideshow of a graph and another output.
(My alert is an email that sends daily / when level is lower – I’m hoping for an automation to put an oil order date in the Google calendar but the maths and coding waits for another lockdown).
Changed this over to use quantile which looks like it really smooths out the curve. Still a bit of noise but looking much better.
I have the device on usb power so i take a lot more samples.
Also, had a different take on measurement. Using the tank’s maximum capacity and a simple formula tells you how much oil is in the tank
sensor:
– platform: vl53l0x
name: “oil_level”
address: 0x29
id: myoillevel
update_interval: 1s
long_range: false
accuracy_decimals: 1
unit_of_measurement: “Gallons Remaining”
filters:
– lambda: return 330.0 – x/1.10*330.0;
# – lambda: return x * 1053;
– quantile:
window_size: 900
send_every: 900
send_first_at: 900
state_class: measurement
Do you find that this sensor is Noisy for you? I’ve extended out the number of reads to once a minute, average for an hour and it still a little up and down.
Thanks for writing in. YES! I’ve added a picture of the output to the post. It is noisy but I’ll return to fix this when my urgent (water level) situation has passed! Let’s know id your config improves on mine.
Thanks for the Reply. I’m currently tweaking window size and the sample frequency.
I’ll have a few tests over a few days and will come back and update this, tonights test is
# to stop reading for a predefined interval
deep_sleep:
run_duration: 10s
sleep_duration: 60min
and this is in the sensor field
– sliding_window_moving_average:
window_size: 10
send_every: 10
I want it to give me an average of the 10 seconds it is awake; but the last log test i just did indicates that it is keeping track of that last 10 checks somewhere else.
SLEEP
I recall a report somewhere that mentioned what happens during sleep – in any case good luck there Dennis.
BATTERY POWER
If you’ve switched over to battery power pls let us all know if battery life is reasonable.
Hello Dennis
Thank you for adding more truth to the idea that this is a noisy sensor. We can’t exclude the idea that the platform / ESP32 might be part of it but no matter, you’ve found a solution for a still very useful sensor.
GRAPH SMOOTHING / NOISE
Well done for finding ‘quantile’ as it seems to more suit what I’m looking for by omitting outliers. I’ll note that you’re taking a fantastic number of readings and doing the maths over 15 minutes – a duration which suits our slow use of heating oil.
In Home Assistant I used a Statistics graph which helped – but by averaging.
CALIBRATION
My tank is old-style metal and rectangular. I will tweak the fiddle-factor when it gets topped up for the first time. Just now the figures are good enough to know how much heating oil is used daily and how much to order.
INDENTING YAML CODE
This web page messes up indents – go to esphome.io to see how to do it: https://esphome.io/components/sensor/index.html
UPDATE:
Cheers for the idea to use a quantile filter and sliding_window_moving_average on the oil tank ‘tof’ sensor.
In an update of my post, near the bottom, you’ll see that I’ve stacked one sensor after the other and the effect is pretty good … or much improved.
The Esphome quantile code removes outliers and this is followed by your second filter: sliding_window_moving_average.
Thank you for the pointers that led to this.
Fantastic stuff!
Please can you share your code for the entity ‘Oil used since 00’ or is this just created in the statistics graph card?
After a lot of headache – I couldn’t get ESPHome Add on to flash my device on my Rpi3B, so had to learn how to install it on a PC via the command line, but nearly there!
Also tried to get a VL53L1X sensor working – unfortunately ESPHome doesn’t support it natively. The instructions for adding custom/external repositories are pretty incomprehensible without prior programming knowledge! So I’ve given up for now. A 0x with long range enabled is fine for me 1.4m tank.
Many thanks
Well done for finding a way to flash it Gareth. I’ve flashed many and conclude that the process is fickle eg some boards need a retry or button press. The upload of a bin file using ESPHome web on a PC is my first thing to try.
***
A link from my post above shows how complicated my thing has become over some years – in fact this blog is my only way to recall what I have done!
***
Pity about your sensor ..1X and yes I don’t go near external libraries without a tutorial. But don’t give up as you need a tank monitor. The following is a tempting polished version that may motivate you to plough on with ESPHome ‘WATCHMAN SENSIT DOMESTIC OIL TANK MONITOR/ GAUGE’
***
When the HA energy dashboard appeared I converted my litres into kWh (multiply times 9) and this made the ‘oil used since midnight’ redundant. However you might create a ‘template sensor’ with this name as below. Get your head around the fact that you use todays midnight level but store this just before midnight as ‘yesterday’s oil level’.
IN BOLD HERE IS A GUESS AT HOW TO CALCULATE USE SINCE MIDNIGHT. ADD THIS TO THE MAIN configuration.yaml
>>>
template:
– sensor:
name: oil_used_since00
unique_id: oil_used_since00
state: >-
{{ states(‘input_number.midnight_oil_level’) | int – states(‘sensor.oil_level’) | int }}
>>>>
***
AS OF NOW THIS IS MY FINAL CODE for an AUTOMATION that runs around midnight. Shout if I can help more.
alias: OIL – oilrecorder
description: save midnight level – all based on input number and current level
trigger:
– platform: time
at: “23:55:05”
action:
– service: input_number.set_value
data_template:
entity_id: input_number.oilusedyesterday
value: >-
{{ states(‘input_number.midnight_oil_level’) | int –
states(‘sensor.oil_level’) | int }}
– service: input_number.set_value
data_template:
entity_id: input_number.oil_level_yesterday
value: “{{ states(‘input_number.midnight_oil_level’) | int }} ”
– data:
event: oil_level
value1: “{{ states(‘sensor.oil_level’)}}”
value2: “{{ states(‘sensor.temperature_weath’)}}”
value3: “{{ states(‘input_number.oilusedyesterday’)}}”
service: ifttt.trigger
– service: input_number.set_value
data_template:
entity_id: input_number.midnight_oil_level
value: “{{ states(‘sensor.oil_level’) | int }} ”
– service: notify.mail_roger
data:
message: >-
oil report at {{ states (‘sensor.time’) }} from boiler room. Order oil
in {{ states (‘sensor.how_many_days_till_i_order’) }} days on date {{
(as_timestamp(now()) +
(states(‘sensor.how_many_days_till_i_order’)|float*24*3600)) |
timestamp_custom(“%d /%m”, True) }}. Presently you can order {{ states
(‘sensor.how_much_oil_do_i_order_today’) }} litre DIFFERENCE in oil
readings {{ states (‘sensor.oil_level’) |int – states
(‘sensor.oil_levelx’) |int }} oil level TOF {{ states
(‘sensor.oil_level’) }} oil level JSR {{ states (‘sensor.oil_levelx’)
}}
title: oil {{ states (‘sensor.oil_level’) }} level
mode: single
Many thanks Roger, I think I’ve got my head around that!
Thankfully the VL53L0X is working great and incorporated into HA with some of your sensors and gauges but currently pointing at the kitchen cupboard! The adapters are currently being printed this minute (In PETG) – I need to print an extra 1.5″ BSP adapter which yours will be glued on top as there is already a hole in the tank to this specification.
I’ve got an ESP32 Feather which has a built in battery connector. Once it’s all working (currently testing with a USB power bank) I’ll turn down the sensor refresh rate and order a 2000mAh battery which will also be housed in the waterproof case.
I may also do the Kalman thing if needed.
Nearly there, but still some work to do!
Great to hear you’re working some magic there. Look forward to hearing .. luckily no hurry for this season!
I have done exactly the same, starting a couple of years ago. Works. I filled the tank with ping-pong balls to ensure there was a reflective surface. Yes, I did check in advance that they didn’t dissolve. I also isolated the sensor from the tank with a microscope slip cover. I had a previous sensor and I think the sensor got killed by the atmosphere in the tank – not sure.
The problem I have is that it appears the sensor locks up. Still testing. A reset solves the problem, maybe for a couple of days. I’m running an ESP8266 with battery and solar so only take a reading every four hours and then go to sleep. It ftps readings to another ESP8266 via wifi that runs as a web server. Currently looking at XSHUT to see if that solves the problem, but that means modifying the hardware (:
For others who try similar.
Thank you for your report and fair warnings. I’m very impressed with your FTP and sleeping device solutions. And of course the ping pong balls – i need something floaty like this to sharpen up my noisy readings – instead of cleaning up the noise as I explained. I have two points that aim to help.
* As shown I put my sensor in a project box and I can vouch for this.
* Two years on, recently one of three sensors (in three tanks) shows an error in the ESPHome logs ‘Component vl53l0x.sensor is marked FAILED’ and I’ve tried several suggestions I read. As this is the only tank sensor that runs on an ESP8266, and the others run on ESP32 boards, I’m perhaps unfairly pointing the blame at the ESP8266’s emulating its lack of a I2C bus. I’ll eventually, and tediously need to re-make this using ESP32 and report here if this fixes it. All the best there – with thanks and cheers.
I have had issues in the past with the i2c bus locking up on a weather station with a BME280. Found some code on the web to reset it which is incorporated in my code, but as far as I can see that has not been my problem. Before I take a reading I check to see if the the VL53LOX is there. The issue is that it will lock up. Log (which it sends to my NAS):
[1725825624], Sun 08 Sep 2024, 20:00 – Oil tank readings taken
[1725825639], Sun 08 Sep 2024, 20:00 – Failed reading=65535
[1725825640], Sun 08 Sep 2024, 20:00 – Failed reading=65535
[1725825641], Sun 08 Sep 2024, 20:00 – Failed reading=65535
[1725825642], Sun 08 Sep 2024, 20:00 – Failed reading=65535
I do have a version with an esp32, which is still in the garage – haven’t had the time or inclination to take it further yet. It’s better on power consumption, could not get the esp8266 sleep modes working reliably so it uses modem sleep = 25mA, the esp32 with light sleep is 10mA. It might be because I’m cycling it in and out of sleep that is causing the problem.
FTP – there are a number of libraries you can download, but try finding an FTP client (that works), I ended up writing my own. As well as what I previously said, it also emails me – restart, low oil level or rapid change in level. No credit there, something I found.
I have OTA installed so can update if needed, okay but when you find you need to modify the hardware…
While I enjoy messing around with arduino projects, the reliability of components and trying to anticipate and trap all the failure modes is a PITA.
You need a LOT of ping pong balls.
Happy to talk further via email if desired.
Andy
Impressed with your expertise there. I’m coming back to this ahead of the heating coming on in October. I’m stalling because the sensor is made never to fall apart or be repaired. Such is the optimism with which we build these things.
Love them ping pong balls.
Yep! I don’t have the luxury of a 3D printer so the sensor is a length of 50mm pipe and pipe flanges, waterproof JB on top. This bolted to the top of the tank. The VL53LOX is araldited to the bottom of the pipe, 4 wires coming up to a connection block. Didn’t think at the time I’d need access to the XSHUT line. This in the hope that toggling that line can reset the sensor and stop lockup. So I’m going to have to build a new sensor unit. Few other jobs first. I’m also going to switch from an ESP8266 to an ESP32.