High draw low carbon automation with Home Assistant M0YNG.uk

Created 2023-08-07

Tagged

I'll admit this is a bad a title, but there isn't a snappy way to describe this.

Why do?

Not all electricity is created equal

Maybe you've never thought about this, but not all electricity is created the same way, and every method has a different environmental impact. Plus the way the electricity delivered to your home is generated changes throughout the day, week, month, season, and over years.

For example, as I write this, Scotland is generating 68% of its electricity from Hydro, 11.4% from wind, 10% nuclear, and the rest is imported - a mixture that emits 21 gCO₂ equivalent per kWh of electricity.

In contrast, South Wales is generating 96.9% by gas and 3.2% by wind, emitting 381 gCO₂eq/kWh.

(You can see the real time info for loads of countries at Electricity Maps)

So, if I have a dish washer to run or a load of washing to do right now, it would be best to do that using the Scottish electricity and not the South Wales stuff.

But you can't just plug into different bits of the grid at different times, but you can wait until the local generation is producing as little CO₂eq as possible.

Think of this as "flattening the curve" (remember that from Covid?) we aren't trying to use less electricity, but we are trying to use it when it's most abundant so we don't need to use costly methods of generation. The National Grid experimented with this last winter, paying people for every kWh they didn't use during peak times (compared to that home's average usage at that time of day) when the grid was at risk of having to bring coal plants online.

How do?

There are some problems to solve here:

  1. How do I know how much CO₂eq is being emitted by the grid right now?
  2. How do I know how much is likely to be emitted in the future, so I can decide if I should wait or do it now?
  3. How do I communicate that information?

1 - CO₂eq NOW

This is fairly easy, Carbon Intensity API exists and will give you this info for the current 30 minute chunk and it super easy to use, you can just give it a postcode!

For example, pop over to https://api.carbonintensity.org.uk/regional/postcode/RG10 and you'll get a JSON blob with the CO₂eq value, an "index" from "Very Low" to "Very High" and even a breakdown of what generation sources are in use.

(Electricity Maps also have an API if you're not in the UK, it's not as specific as the National Grid data, and you need a free API key - it's called CO2 Signal)

I have a python script which is run by cron to grab this data and shove it into MQTT where Home Assistant does stuff with it - more on that later.

'''
Gets the current Carbon Intensity data for the region
'''
import requests
import configparser
import paho.mqtt.publish as publish
# load the config
config = configparser.ConfigParser()
config.read('config.ini')
# we need this for every request to the API
headers = {
  'Accept': 'application/json'
}
# a request for the current carbon data
r = requests.get(f"{config['ngci']['baseURL']}regionid/{config['ngci']['regionid']}", headers = headers)
# convert that to something we can use
currentData = r.json()
# print out the data
print(currentData)
# the "messages" we're going to send to MQTT (aka the data from the API)
messages = [
# basic intensity info
        {
            'topic': f"{config['mqtt']['topic']}current/gco2",
            'payload': currentData['data'][0]['data'][0]['intensity']['forecast']
        },
        {
            'topic': f"{config['mqtt']['topic']}current/index",
            'payload': currentData['data'][0]['data'][0]['intensity']['index']
        }
]
# add a message for each of the generation types
for fuel in currentData['data'][0]['data'][0]['generationmix']:
    messages.append({
            'topic': f"{config['mqtt']['topic']}current/{fuel['fuel']}",
            'payload': fuel['perc']
            })
# show me the messages!
print(messages)

# Send the messages off to MQTT
publish.multiple(messages, hostname=config['mqtt']['server'], auth={'username': config['mqtt']['username'], 'password': config['mqtt']['password']})

2 - Future

OK, great, but what if it's currently "Medium" intensity, do I run the dishwasher now because that's as good as it will get, or wait because it's going to get lower later?

It's important for the National Grid to predict demand so they can match it with supply, and to do that they need to be able to predict supply too so there is some pretty good data for this.

Most renewables can be forecast pretty accurately, wind will use weather forecast data for the wind, solar will use a mix of weather, time of day, time of year, etc. and the same API also has endpoints for predicted CO₂eq per 30 minute chunk for the next 24+ hours.

I have another python script which checks this API each morning and sends the data via MQTT to Home Assistant, which sends it on to me via a Matrix room.

'''
Gets the forecasted Carbon Intensity data for the next 24 hours
'''
import configparser
import requests
from datetime import date
from datetime import datetime
from dateutil import tz
import paho.mqtt.publish as publish

config = configparser.ConfigParser()
config.read("config.ini")

to_zone = tz.gettz('Europe/London')

forcastAPI = f'{config["ngci"]["baseURL"]}intensity/{datetime.utcnow().replace(microsecond=0).isoformat()}Z/fw24h/regionid/{config["ngci"]["regionid"]}'

lastHalfIndex = ''
combinedText = ''

r = requests.get(forcastAPI)
for halfhour in r.json()['data']['data']:
    if lastHalfIndex != halfhour['intensity']['index']:
        dtUTC = datetime.strptime(halfhour['from'][:-1], '%Y-%m-%dT%H:%M')
        combinedText += halfhour['intensity']['index'] + ' from ' + dtUTC.astimezone(to_zone).strftime('%H:%M') + '\n'
        lastHalfIndex = halfhour['intensity']['index']

print(combinedText)

publish.single(f"{config['mqtt']['topic']}forecast", payload=combinedText, hostname=config['mqtt']['server'], auth={'username':config['mqtt']['username'], 'password':config['mqtt']['password']})

3 - Communicate

There are two main ways I communicate this, a bot that sits in a Matrix room, and switches attached to the "high draw" machines I want use at different times.

Matrix is triggered by Home Assistant automations looking for changes to those MQTT topics, if the forecast changes, it tells me, if the index goes High or Low it tells me that too. I'm sure there are many ways you can tell yourself stuff and you'll probably already have a favourite.

Each "high draw" machine (dish washer, clothes washing machine, tumble dryer) has an energy monitoring connected switch attached. These are all dumb appliances and I want to keep it that way.

I'm using these tasmota energy monitor switches from Local Bytes as they came pre-flashed, from the UK, and I had already destroyed an identical looking and more expensive device trying to flash ESPHome onto it before.

The main way these switches communicate is by turning the devices on, or off, depending on the index value. The basic logic is simple.

IF index is High or Very High:
    turn switches off
ELSE IF index is Low or Very Low:
    turn switches on
You'll notice there is no consideration for "Medium" intensity, I don't feel this is a "bad enough" or "good enough" index to cause a change, and often the index will go back to what it was before anyway.

This makes the logic slightly more complex because we can't just slam it on or off regardless, so I made a "helper toggle" in Home Assistant called "High Draw Active" and the logic checks it before doing anything, this also prevents it turning off switches that are already off if the index goes from High to Very High.

IF index is High or Very High:
    and "High Draw" is active:
        turn switches off
        turn "High Draw" off
        tell me it was turned off
ELSE IF index is Low or Very Low:
    and "High Draw" is off:
        turn switches on
        turn "High Draw" on
        tell me it was turned on

I could probably break this out into three bits that all listen to or change the "high draw" toggle, but I haven't felt the need ... yet.

It also checks to see if a machine is running before turning it off. I have some "Dropdown" helpers that store the state of each machine (running, finished) and the energy monitoring switches allow me to detect when the machine is running, and when it has finished (and notify me via matrix) Obviously I don't want to turn off a machine that is running so the automation won't do that, but it will tell me that it hasn't turned it off because it is running.

What do?

It has adjusted our habits, more than I thought it might.

The motivation for, and implementation of, this is supported by other people in the house and it has a good "spouse approval rating" - which is helped by the fact that all switches can be overriden if needed.

What impact does it have though?

Some numbers

My dishwasher seems to use around 1kWh per cycle, which is helpful for doing maths.

Since I installed my monitoring sockets the dishwasher has used about 50kWh, so if we use the numbers from before the emissions would be:

That's an 18kg difference in emissions.

Now, I'll admit that I don't have actual numbers for my real usage, in theory I could work them out but I haven't got my head around the maths for that yet (I have dyscalculia) but I think it makes the point!

Completely Pointless

However, this exercise is completely pointless, depending on how you look at it, because:

Completely and utterly pointless

Seriously, it's completely and utterly pointless.

The average private jet emits two tonnes of carbon an hour Flying shame: the scandalous rise of private jets - The Guardian

Therefore that 18kg hypothetical difference is 54 seconds of a private jet.

I'd have to run the dish washer 5,249 times at 381gCO₂eq/kWh to make up 1 hour of private jet use.

If I didn't care and only used the dish washer when the grid is incredibly carbon intensive, and did it every day, at 381gCO₂eq/kWh, it would take 14 years and 4 months and 17 days to emit as much CO₂eq as one hour of private jet usage.

It's the billionaires, there is no way I can make even the smallest scratch in the tiniest dent on the climate crisis when billionaires are emitting a million times more greenhouse gases than the average person - we cannot capitalism our way out of this.

What's next?

We're in the process of getting solar panels and battery storage.

I expect I'll swap the triggers for this to be when the panels are generating, at least in the summer.

Another aspect is cost, if we go on an "economy 7" tariff we get 7 hours of cheaper electricity overnight, which we could use to charge up the battery (especially useful during winter) and run things like the dish washer.

Maybe there will be three triggers to balance, solar generation, electricity cost, and the emissions of the grid.

I'd like to make a "smart carbon meter", like the smart energy meters that show you how much electric/gas you've used and give a budget for the day/week/month it might be interesting to set a "carbon budget" and have a display that shows the emissions, the budget, and the status of the switches and the grid generation intensity. In theory I have all the data, and the hardware (a Lilygo T-Display) but I lack the time/skills to get this working.

Share this post on Mastodon