The EU-funded Smartspaces project is looking at using ICT to save energy in public buildings in 11 pilot sites across Europe. At the Leicester pilot site we have designed a unique live energy feedback system. The system has also made data for 25 public buildings freely available to download.
Baseload consumption is observably very large in some of the smartspaces buildings. This notebook attempts to drill down into the data and put some numbers on it.
Here I am using a simple adapter that downloads the csv file from the smartspaces website and loads the data into a pandas dataframe.
The adapter is available from https://github.com/ggstuart/smartdata
from smartdata import SmartspacesCSVAdapter
adapter = SmartspacesCSVAdapter()
The data doesn't contain the building name so I need to create a mapping to the smartspaces meter_id. Here I load the data into a simple list of dictionaries. The result is shown in the output.
datasets = [
{'lbl': 'Queens', 'id': 3},
{'lbl': 'Hugh Aston', 'id': 6},
{'lbl': 'Kimberlin', 'id': 8},
{'lbl': 'Campus Centre', 'id': 10},
{'lbl': 'John Whitehead', 'id': 12}
]
for dataset in datasets:
dataset['dataframe'] = adapter.dataframe(dataset['id'], 'all')
datasets[0]['dataframe']
{'dataframe': <class 'pandas.core.frame.DataFrame'> DatetimeIndex: 47994 entries, 2011-08-23 15:00:00 to 2014-05-19 11:30:00 Data columns (total 1 columns): consumption (kWh) 47994 non-null values dtypes: float64(1), 'id': 3, 'lbl': 'Queens'}
A simple plot of the raw data shows all is well. The data are half-hourly and cover nearly three years.
fig, axes = subplots(5, 1, figsize=(12, 8))
for i, dataset in enumerate(datasets):
ax = axes[i]
ax.plot(dataset['dataframe'].index, dataset['dataframe'], c="black", lw=0.15)
ax.set_title(dataset['lbl'])
ax.set_ylabel('consumption\n(kWh)')
tight_layout()
We can resample the pandas dataframe to give the minimum consumption each day.
for dataset in datasets:
dataset['daily_min'] = dataset['dataframe'].resample('D', how='min')
dataset['daily_sum'] = dataset['dataframe'].resample('D', how='sum')
dataset['weekly_min'] = dataset['dataframe'].resample('W', how='min')
Now we can plot these minium values, they represent our simple view of the baseload over time.
fmt = mpl.dates.DateFormatter(fmt="%b\n%Y")
loc = mpl.dates.MonthLocator(interval=4)
fig, axes = subplots(5, 1, figsize=(12, 10), sharex=True)
for i, dataset in enumerate(datasets):
axes[i].set_title(dataset['lbl'])
axes[i].plot(dataset['dataframe'].index, dataset['dataframe'], label="raw", lw=0.2, alpha=0.5, c='black')
axes[i].plot(dataset['daily_min'].index, dataset['daily_min'], label="daily", lw=0.2, c='blue')
axes[i].plot(dataset['weekly_min'].index, dataset['weekly_min'], label="weekly", c='red', lw=1)
axes[i].xaxis.set_major_locator(loc)
axes[i].xaxis.set_major_formatter(fmt)
axes[i].set_ylabel('minimum daily/weekly\nconsumption (kWh)')
leg = axes[i].legend(loc=2)
tight_layout()
Some features to note
So let's try to put a figure on the actual baseload as a proportion of total consumption.
fmt = mpl.dates.DateFormatter(fmt="%b\n%Y")
loc = mpl.dates.MonthLocator(interval=4)
fig, axes = subplots(5, 1, figsize=(12, 10), sharex=True)
for i, dataset in enumerate(datasets):
baseload_pct = ((dataset['daily_min'].sum()*48 / dataset['daily_sum'].sum()) * 100)
axes[i].set_title(dataset['lbl'])
# axes[i].plot(dataset['daily_sum'].index, dataset['daily_sum']['consumption (kWh)'], label='occupied load', color='blue')
# axes[i].plot(dataset['daily_min'].index, dataset['daily_min']['consumption (kWh)']*48, label='unoccupied load', color='red')
axes[i].text(0.01, 0.1, "baseload as proportion of total consumption = %3.1f%%" % baseload_pct, transform=axes[i].transAxes)
axes[i].fill_between(dataset['daily_sum'].index, dataset['daily_min']['consumption (kWh)']*48, dataset['daily_sum']['consumption (kWh)'], label='occupied load', color='blue', alpha=0.5, lw=0.2)
axes[i].fill_between(dataset['daily_sum'].index, dataset['daily_min']['consumption (kWh)']*48, label='baseload', color='red', alpha=0.5, lw=0.2)
axes[i].set_ylim(0, axes[i].get_ylim()[1])
axes[i].xaxis.set_major_locator(loc)
axes[i].xaxis.set_major_formatter(fmt)
axes[i].set_ylabel('daily\nconsumption (kWh)')
leg = axes[i].legend(loc=2)
tight_layout()
So we can see that baseload consumption is a significant proportion of consumption in all these buildings. When defined very simply as the lowest consumption observed in a given day. Queens and John Whitehead have very large baseloads at around 80% of total consumption over the whole period. The Kimberline library opens up the prospect of investigating the daily baseload versus the weekly baseload as overnight consumption during winter weekdays is very different from weekends, holidays and summer periods.