Hello,
In another thread I was asked about my solution to add the heating oil use to the energy dashboard. Instead of going off topic in that thread, I’ll try to describe here how I did it.
Using a sensor to determine the remaining amount of oil:
I’m using an ESPHome powered ESP8266 in addition with a (waterproof) Ultrasonic distance sensor. I had a few extra fuelcaps, so decided to build the sensor in a fuelcap rather than drill a hole in the tank itself. Be sure to keep all electronics outside of the tank and only have the sensor itself in the fuelcap.
I wanted to have all the code condensed on the ESP, so no additional code in the config or any template sensors are necessary. The code measures the distance from the top of the tank to the level of the oil regularly and does some calculations to convert it to liters. The value which is needed for the energy dashboard, however, is only updated once a day (at 2 o clock in the night). This makes it possible to input any new oil delivery before an erroneus result is uploaded to the energy dashboard.
The yaml creates a sensor in liters, an input number for an oil delivery and a button to send the oil delivery to the esp.
The last send oil level is saved in the eeprom, so even after a powercut no data is lost.
Sadly, the energy dashboard doesn’t allow liters so we have to convert it to kwh (1liter = 10kwh). The conversion is easy and is allready included in the esp code. The sensor is allready configured with all necessary classes, so it should pop up in the setup of the energy dashboard. Having oil in the energy dashboard in kwh is a bit less intuitive than having it in liters, but you get used to it pretty fast. Just remember; deviding by 10 gives you the value in liters.
One thing to be aware of, is to input the amount of oil at any new delivery, as well with first setup at the same day it gets delivered (before 2 o clock of the next day). Otherwise you will get an erroneous entry in the ernergy dashboard!
As i was typing this, i realised there is quite a lot to it. If there are any questions left, or if i forgot to explain certain things, feel free to ask .
This setup has been working for me super reliable for almost 2 years now.
If you wish to do something like this youself please keep in mind you do this at your own risk. I take no responsibility for anything going wrong😉.
esphome:
name: oelstand
platform: ESP8266
board: nodemcu
esp8266_restore_from_flash: true
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
password: "xxxxxxxxx"
wifi:
ssid: "xxxxxxxxxxx"
password: "xxxxxxxxxxxx"
manual_ip:
static_ip: 192.168.178.52
gateway: 192.168.178.1
subnet: 255.255.255.0
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Oelstand Fallback Hotspot"
password: "xxxxxxxxxx"
captive_portal:
preferences:
flash_write_interval: 2h
globals:
- id: previous_oelstand
type: float
initial_value: '4000.0'
restore_value: yes
- id: previous_oelverbrauch
type: float
initial_value: '0.0'
restore_value: yes
number:
- platform: template
id: oellieferung_liter
name: Öllieferung in Liter
icon: "mdi:tanker-truck"
step: 0.1
min_value: -4000.0
max_value: 4000.0
optimistic: true
initial_value: 0.0
button:
- platform: template
name: Öllieferung
on_press:
then:
- lambda: |-
id(previous_oelstand) += id(oellieferung_liter).state;
id(oellieferung_liter).state = 0.0;
- platform: template
name: Reset total oelverbrauch
on_press:
then:
- lambda: |-
id(previous_oelverbrauch) = 0.0;
sensor:
- platform: ultrasonic
trigger_pin: D1
echo_pin: D2
name: "oillevel measured distance"
id: oillevel_measured_distance
update_interval: 10min
accuracy_decimals: 3
internal: true
filters:
- filter_out: nan
- max:
window_size: 7
send_every: 4
send_first_at: 3
- platform: template
name: "Test_previous_oelstand"
lambda: |-
return id(previous_oelstand);
update_interval: 1s
unit_of_measurement: "liters"
- platform: template
name: "Test_previous_oelverbrauch"
lambda: |-
return id(previous_oelverbrauch);
update_interval: 1s
- platform: template
name: "Ölstand"
id: oelstand
unit_of_measurement: "liters"
icon: "mdi:hydraulic-oil-level"
update_interval: 10min
accuracy_decimals: 0
lambda: |-
return 1.63 - id(oillevel_measured_distance).state;
filters:
- calibrate_polynomial:
degree: 1
datapoints:
- 0.01 -> 22.0
- 0.02 -> 44.0
- 0.03 -> 66.0
- 0.04 -> 88.0
- 0.05 -> 112.0
- 0.06 -> 134.0
- 0.07 -> 156.0
- 0.08 -> 178.0
- 0.09 -> 200.0
- 0.10 -> 226.0
- 0.11 -> 250.0
- 0.12 -> 276.0
- 0.13 -> 300.0
- 0.14 -> 326.0
- 0.15 -> 350.0
- 0.16 -> 376.0
- 0.17 -> 400.0
- 0.18 -> 426.0
- 0.19 -> 450.0
- 0.20 -> 476.0
- 0.21 -> 500.0
- 0.22 -> 526.0
- 0.23 -> 550.0
- 0.24 -> 576.0
- 0.25 -> 600.0
- 0.26 -> 628.0
- 0.27 -> 658.0
- 0.28 -> 686.0
- 0.29 -> 714.0
- 0.30 -> 742.0
- 0.31 -> 772.0
- 0.32 -> 800.0
- 0.33 -> 828.0
- 0.34 -> 858.0
- 0.35 -> 886.0
- 0.36 -> 914.0
- 0.37 -> 942.0
- 0.38 -> 972.0
- 0.39 -> 1000.0
- 0.40 -> 1022.0
- 0.41 -> 1044.0
- 0.42 -> 1066.0
- 0.43 -> 1088.0
- 0.44 -> 1112.0
- 0.45 -> 1134.0
- 0.46 -> 1156.0
- 0.47 -> 1178.0
- 0.48 -> 1200.0
- 0.49 -> 1222.0
- 0.50 -> 1244.0
- 0.51 -> 1266.0
- 0.52 -> 1288.0
- 0.53 -> 1312.0
- 0.54 -> 1334.0
- 0.55 -> 1356.0
- 0.56 -> 1378.0
- 0.57 -> 1400.0
- 0.58 -> 1420.0
- 0.59 -> 1440.0
- 0.60 -> 1460.0
- 0.61 -> 1480.0
- 0.62 -> 1500.0
- 0.63 -> 1520.0
- 0.64 -> 1540.0
- 0.65 -> 1560.0
- 0.66 -> 1580.0
- 0.67 -> 1600.0
- 0.68 -> 1628.0
- 0.69 -> 1658.0
- 0.70 -> 1686.0
- 0.71 -> 1714.0
- 0.72 -> 1742.0
- 0.73 -> 1772.0
- 0.74 -> 1800.0
- 0.75 -> 1826.0
- 0.76 -> 1850.0
- 0.77 -> 1876.0
- 0.78 -> 1900.0
- 0.79 -> 1926.0
- 0.80 -> 1950.0
- 0.81 -> 1976.0
- 0.82 -> 2000.0
- 0.83 -> 2026.0
- 0.84 -> 2050.0
- 0.85 -> 2076.0
- 0.86 -> 2100.0
- 0.87 -> 2126.0
- 0.88 -> 2150.0
- 0.89 -> 2176.0
- 0.90 -> 2200.0
- 0.91 -> 2222.0
- 0.92 -> 2244.0
- 0.93 -> 2266.0
- 0.94 -> 2288.0
- 0.95 -> 2312.0
- 0.96 -> 2334.0
- 0.97 -> 2356.0
- 0.98 -> 2378.0
- 0.99 -> 2400.0
- 1.00 -> 2422.0
- 1.01 -> 2444.0
- 1.02 -> 2466.0
- 1.03 -> 2488.0
- 1.04 -> 2512.0
- 1.05 -> 2534.0
- 1.06 -> 2556.0
- 1.07 -> 2578.0
- 1.08 -> 2600.0
- 1.09 -> 2626.0
- 1.10 -> 2650.0
- 1.11 -> 2676.0
- 1.12 -> 2700.0
- 1.13 -> 2726.0
- 1.14 -> 2750.0
- 1.15 -> 2776.0
- 1.16 -> 2800.0
- 1.17 -> 2828.0
- 1.18 -> 2858.0
- 1.19 -> 2886.0
- 1.20 -> 2914.0
- 1.21 -> 2942.0
- 1.22 -> 2972.0
- 1.23 -> 3000.0
- 1.24 -> 3028.0
- 1.25 -> 3058.0
- 1.26 -> 3086.0
- 1.27 -> 3114.0
- 1.28 -> 3142.0
- 1.29 -> 3172.0
- 1.30 -> 3200.0
- 1.31 -> 3226.0
- 1.32 -> 3250.0
- 1.33 -> 3276.0
- 1.34 -> 3300.0
- 1.35 -> 3326.0
- 1.36 -> 3350.0
- 1.37 -> 3376.0
- 1.38 -> 3400.0
- 1.39 -> 3422.0
- 1.40 -> 3444.0
- 1.41 -> 3466.0
- 1.42 -> 3488.0
- 1.43 -> 3512.0
- 1.44 -> 3534.0
- 1.45 -> 3556.0
- 1.46 -> 3578.0
- 1.47 -> 3600.0
- 1.48 -> 3626.0
- 1.49 -> 3650.0
- 1.50 -> 3676.0
- 1.51 -> 3700.0
- 1.52 -> 3726.0
- 1.53 -> 3750.0
- 1.54 -> 3776.0
- 1.55 -> 3800.0
- 1.56 -> 3826.0
- 1.57 -> 3850.0
- 1.58 -> 3876.0
- 1.59 -> 3900.0
- 1.60 -> 3926.0
- 1.61 -> 3950.0
- 1.62 -> 3976.0
- 1.63 -> 4000.0
- platform: template
id: oelverbrauch
name: Ölverbrauch
unit_of_measurement: "kWh"
accuracy_decimals: 3
device_class: energy
state_class: total_increasing
time:
- platform: homeassistant
on_time:
- seconds: 0
minutes: 0
hours: 2
then:
- lambda: |-
if id(oelstand).state < id(previous_oelstand){
float calc = ((id(previous_oelstand) - id(oelstand).state)*10.0) + id(previous_oelverbrauch);
id(oelverbrauch).publish_state(calc);
id(previous_oelstand) = id(oelstand).state;
id(previous_oelverbrauch) = id(oelverbrauch).state;
}
else{
}