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 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

See the note in the code above and then see this page explaining how to use IFTTT to save values in a Google spreadsheet.

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
    username: !secret email@
    password: !secret email@password
    recipient: !secret email@
    sender_name: home assistant notify


# PUT THESE TWO LINES IN secrets.yaml 

email@: emailaddress-here
email@password: password-here
#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.

above: the many variables I use to keep an eye on my oil tank. If you recognise the above as a node red flow it is non-functional because I failed to made it work. I concluded that Node Red is more dreadfuller than Home Assistant for doing simple arithmetic.

Leave a Reply

Your email address will not be published. Required fields are marked *