smartspaces

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.

Investigating baseload consumption in the smartspaces buildings

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.

Getting the data

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

In [47]:
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.

In [46]:
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']
Out[46]:
{'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

A simple plot of the raw data shows all is well. The data are half-hourly and cover nearly three years.

In [143]:
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()

Minimum consumption per day and per week

We can resample the pandas dataframe to give the minimum consumption each day.

In [97]:
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.

In [144]:
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

  • Queens building baseload seems to have increased during the winter of 2012/2013 which made the xmas shutdown seem more effective than 2013/2014
  • Hugh Aston is quite variable and is low at the moment
  • Kimberlin Library stands out as having a very variable baseload likely due to its extended occupancy hours. Is there an opportunity here?
  • Campus Centre has seen some changes recently
  • John Whitehead has a significant feature in the summer of 2013 and is on the up now

Quantifying the baseload

So let's try to put a figure on the actual baseload as a proportion of total consumption.

In [138]:
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.

In [ ]: