basic arithmetic in Home Assistant to calculate how much heating oil I need and when I need to order heating oil

My boiler burns heating oil from a tank and unlike the ‘gas’ that most homes burn it’s finite – so when it’s gone I’m cold. Ordering heating oil is tricky because I must say exactly how much I need and estimate when I need it. Two things massively help here: a tank oil level sensor shows how much oil I must order. (I made two ESPhome sensors: here and here). I get Home Assistant to email me the current oil level and store it in a Google spreadsheet (see how this is done here).

A Google spreadsheet was a big help before all this was done in Home Assistant. The spreadsheet stored daily oil levels and calculated when oil was needed based on average daily oil use (which varies somewhat). Furthermore, I must allow for 10 – 14 days for the order to arrive. For example, I might need to order 120 litres more than today’s oil level (10 days * 12 litres /day).

doing calculations in Home Assistant comes with these challenges that we’ll tackle …

Home Assistant features / concepts / skills:

• storing variables – e.g. store yesterday’s oil level so that I can work out how much oil I’ve used since then
• storing constants – as above e.g. the capacity of the oil tank and how many days the order takes to arrive are fairly constant
• email notifications – e.g. sending myself an email with today’s oil status
• recording in a spreadsheet – e.g. keeping a log of oil levels and daily temperatures for interest
• calculating averages over time – e.g. the average daily oil use over several days
• doing a calculation at midnight each day in a Home Assistant Automation
• doing a calculation within a Home Assistant template helper

storing variables and constants in Home Assistant

For example: I need to keep yesterday’s oil level (to work out the amount of oil I’ve used since then). Home Assistant recommend using an input number to store variables and constants. Go to Settings > Devices & Services > Helpers > Create helper > Number

Make these input numbers to use in the calculations:

oilorderdelay = when I order more oil I can chose how urgently I want the oil. Initial value is 10 (days) = cheaper.

oiltanklimit = the size of my oil tank or the lowest level the oil may drop to before ordering more oil. Initial value is 800 (litres). My oil level sensor tells me how much oil I need to order today. The tank capacity is used to calculate when the oil will get used up.

If you don’t use the ‘frontend UI’ to make an input number (as above) you can instead edit your configuration.yaml to create an input number. Here you’re able to set the step size, add units and whether to use a ‘slider’ or ‘box’ to adjust its value if needed.

```# CREATE VARIABLES TO STORE YESTERDAYS OIL LEVEL - USE File Editor TO ADD THIS TEXT TO configuration.yaml
input_number:
midnight_oil_level:
name: midnight oil level
min: -1000
max: 1000
step: 1
unit_of_measurement: L
icon: mdi:oil-level
mode: slider # alternative to 'slider' is 'box'
oil_level_yesterday:
name: oil level yesterday
min: -1000
max: 1000
step: 1
unit_of_measurement: L
icon: mdi:oil-level
mode: slider
oil_used_yesterday:
name: oil used yesterday
min: -1
max: 1000
step: 1
unit_of_measurement: L
icon: mdi:oil-level
mode: slider```

calculate the average amount of oil used over five days

Home Assistant allows us to create a new sensor such as the ‘average daily oil use’ calculated from the last five days of oil use. Edit the Home Assistant file configuration.yaml and add this code to the sensor: section. This new statistics sensor watches the value of the input number we set up earlier.

```sensor:

# USE File Editor TO ADD THIS TEXT TO THE SENSOR SECTION OF configuration.yaml
- platform: statistics
name: "average daily oil use"
entity_id: input_number.oil_used_yesterday
state_characteristic: mean
max_age:
days: 5
precision: 0```

a Home Assistant Automation to do a calculation at midnight each day

At midnight each day I save the oil level and subtract it from the oil level I saved yesterday.

Doing a calculation in Home Assistant involves unreasonably clumsy code. Everytime you want to refer to the oil level you must use a states () statement and enclose the entire calculation inside moustache brackets. For example, this statement calculates the amount of oil_used_yesterday.

{{ states(‘input_number.midnight_oil_level’) | int – states(‘sensor.oil_level’) | int }}

```# IT'S NOW POSSIBLE TO USE THE FOLLOWING IN AN AUTOMATION IN THE IU. ALTERNATIVELY YOU CAN
# SAVE THE FOLLOWING AS A FILE CALLED oil.yaml INSIDE THE HOME ASSISTANT 'automations' FOLDER
#id: '696998989' # YOU NEED A RANDOM ID NUMBER IF YOU CREATE AN AUTOMATION AS A FILE.
alias: OIL - oil recorder
description: save oil level at midnight as a 'input number'
trigger:
- platform: time
at: "23:55:05"
action:
- service: input_number.set_value
data_template:
entity_id: input_number.oil_used_yesterday
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 }}  "

# THE CODE BELOW SENDS ME AN EMAIL AS WELL AS POST TO A GOOGLE SPREADSHEET eg via IFTTT
- data:
event: oil_level
value1: "{{ states('sensor.oil_level')}}"
value2: "{{ states('sensor.temperature_weath')}}"
value3: "{{ states('input_number.oil_used_yesterday')}}"
service: ifttt.trigger
- service: input_number.set_value
data_template:
entity_id: input_number.midnight_oil_level
value: "{{ states('sensor.oil_level') | int }} "

# THE CODE BELOW SENDS ME AN EMAIL
- 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
title: oil {{ states ('sensor.oil_level') }} level
mode: single```

doing calculations using Home Assistant’s template feature

As well as do a calculation in an Automation you can also do calculations in Home Assistant inside a template helper. When I do a calculation in an Automation as above it’s done once a day. When you do calculations in Home Assistant inside a template helper the calculation is done continuously (which is unnecessary to be frank). Either way the code is clumsy. Go to Settings > Devices & Services > Helpers > Create helper > Template. Name the sensor ‘how much oil do I order today‘ and paste this code in the ‘state template’ box. (I’ll explain how the calculation works in the next section).

```{{
- (states('sensor.oil_level')|int
- states ('sensor.average_daily_oil_use')|int
* states ('input_number.oilorderdelay')|int)
}}```

Make another Template Helper: name the sensor ‘how many days till I order’ and paste this code in the ‘state template’ box.

```{{ ((states('sensor.oil_level')|int
- ((states('input_number.oiltanklimit')|int
+ states ('sensor.average_daily_oil_use')|int
* states ('input_number.oilorderdelay')|int )) )
/ states ('sensor.average_daily_oil_use')|int) |int }}```

notifications – send an email to yourself

It’s wise to set up Home Assistant with more that one notification method. This is partly because over time one of these methods will break and partly because an email notification at my desk suits notifying me about ordering oil. The email notifier requires the SMTP settings from your email service. Put the following section in your configuration.yaml

```# PUT THIS IN configuration.yaml
notify:

- name: mail_roger
platform: smtp
server: smtp.my_provider.co.uk
port: 587
timeout: 15
sender: !secret email@
encryption: starttls
recipient: !secret email@
sender_name: home assistant notify

# PUT THESE TWO LINES IN secrets.yaml

#the-protected_thing-goes_outside: the-secret-goes-inside
```

Lastly, put the following in an Automation that fires off once a day.

`  - 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      title: oil {{ states ('sensor.oil_level') }} level`

the variables and the calculation explained

All of the above serves to calculate two things: ‘how many days till I order’ and ‘how much oil do I order today’.

I used Home Assistant input_numbers to store a number of variables including the oil level yesterday, the amount of oil I used yesterday, how much oil the tank can store and how many days until the oil company delivers the order. The first thing I calculate is how much oil I use while waiting for the order to arrive – I add this extra amount to the order. The amount affects the point where the oil level reminds me to order more oil.

I calculate ‘how many days till I order’ knowing the current oil level and divide this by the average daily use use. I add in the order delay in days.

I calculate ‘how much oil do I order today’. knowing the size of the oil tank, the current oil level and I add in the order delay.