This notebook creates a test scenario for the energy agents simulation. The scenario file contains all necessary information on dwellings and on citizens and simulation parameter. Technically, the scenario file is a SQLite database.
The database has the following tables:
markovChains
: a simple mapping from markov chain id to markov chain table namemarkov_chain001
.. markov_chainXYZ
: one table per heterogeneous markov chain. Name is arbitrary.dwellings
: a table for all dwellings, containing all thermal parameters and a link to UKBuildingspeople
: a table for all people, a simple mapping to a dwelling and a link to the markov chainenvironment
: a table with all environmental time series, currently temperature onlyparameters
: a table with all simulation parameters
In [ ]:
from pathlib import Path
from collections import namedtuple
import random
import math
import numpy as np
import pandas as pd
import sqlalchemy
import matplotlib.pyplot as plt
import pytz
%matplotlib inline
import people
from people import Activity, WeekMarkovChain
In [ ]:
PATH_TO_DB = Path('../target/notebook/test-scenario.db').absolute()
PATH_TO_DB.parent.mkdir(parents=True, exist_ok=True)
MARKOV_CHAIN_INDEX_TABLE_NAME = 'markovChains'
DWELLINGS_TABLE_NAME = 'dwellings'
PEOPLE_TABLE_NAME = 'people'
ENVIRONMENT_TABLE_NAME = 'environment'
PARAMETERS_TABLE_NAME = 'parameters'
In [ ]:
random.seed('test-scenario-creation')
In [ ]:
def df_to_db(df, table_name):
disk_engine = sqlalchemy.create_engine('sqlite:///{}'.format(PATH_TO_DB))
df.to_sql(name=table_name, con=disk_engine)
In [ ]:
from datetime import time, timedelta
def weekday_time_series1():
index = [time(0, 0), time(12, 0)]
values1 = [Activity.HOME, Activity.NOT_AT_HOME]
values2 = [Activity.HOME, Activity.HOME]
values3 = [Activity.NOT_AT_HOME, Activity.NOT_AT_HOME]
return pd.DataFrame(
index=index,
data={'person1': values1, 'person2': values2, 'person3': values3}
)
def weekday_time_series2():
index = [time(0, 0), time(12, 0)]
values1 = [Activity.HOME, Activity.HOME]
values2 = [Activity.HOME, Activity.HOME]
values3 = [Activity.NOT_AT_HOME, Activity.NOT_AT_HOME]
values4 = [Activity.HOME, Activity.NOT_AT_HOME]
return pd.DataFrame(
index=index,
data={'person1': values1, 'person2': values2, 'person3': values3, 'person4': values4}
)
def weekend_day_time_series1():
index = [time(0, 0), time(12, 0)]
values1 = [Activity.HOME, Activity.HOME]
values2 = [Activity.NOT_AT_HOME, Activity.HOME]
values3 = [Activity.HOME, Activity.NOT_AT_HOME]
return pd.DataFrame(
index=index,
data={'person1': values1, 'person2': values2, 'person3': values3}
)
def weekend_day_time_series2():
index = [time(0, 0), time(12, 0)]
values1 = [Activity.HOME, Activity.NOT_AT_HOME]
values2 = [Activity.HOME, Activity.HOME]
values3 = [Activity.NOT_AT_HOME, Activity.NOT_AT_HOME]
values4 = [Activity.HOME, Activity.NOT_AT_HOME]
return pd.DataFrame(
index=index,
data={'person1': values1, 'person2': values2, 'person3': values3, 'person4': values4}
)
def markov_chain(weekday_time_series, weekend_day_time_series):
return WeekMarkovChain(
weekday_time_series=weekday_time_series,
weekend_time_series=weekend_day_time_series,
time_step_size=timedelta(hours=12)
)
def full_chain_to_sql(full_chain, table_name):
df = full_chain.to_dataframe()
df.fromActivity = [str(x) for x in df.fromActivity]
df.toActivity = [str(x) for x in df.toActivity]
df_to_db(df, table_name)
def index_table_to_sql(chain_index):
df = pd.Series(chain_index, name='tablename')
df_to_db(df, MARKOV_CHAIN_INDEX_TABLE_NAME)
In [ ]:
full_chain_to_sql(markov_chain(weekday_time_series1(), weekend_day_time_series1()), 'markov_chain001')
full_chain_to_sql(markov_chain(weekday_time_series2(), weekend_day_time_series2()), 'markov_chain002')
index_table_to_sql({89: 'markov_chain001', 22: 'markov_chain002'})
In [ ]:
class UniformDistributedParameter():
def __init__(self, expected_value, variation_in_percent):
self.__expected_value = expected_value
self.__random_max = expected_value * variation_in_percent / 100
def sample(self):
return self.__expected_value + random.uniform(-self.__random_max, self.__random_max)
CONDITIONED_FLOOR_AREA = 100 # m^2
THERMAL_MASS_CAPACITY = UniformDistributedParameter(165000 * CONDITIONED_FLOOR_AREA, 20.0)
THERMAL_MASS_AREA = UniformDistributedParameter(2.5 * CONDITIONED_FLOOR_AREA, 20.0)
ROOM_HEIGHT = UniformDistributedParameter(3, 20.0)
WINDOW_TO_WALL_RATIO = UniformDistributedParameter(0.19, 20.0)
U_VALUE_WALL = UniformDistributedParameter(0.26, 20.0)
U_VALUE_ROOF = UniformDistributedParameter(0.12, 20.0)
U_VALUE_FLOOR = UniformDistributedParameter(0.40, 20.0)
U_VALUE_WINDOW = UniformDistributedParameter(1.95, 20.0)
TRANSMISSION_ADJUSTMENT_GROUND = UniformDistributedParameter(0.91, 20.0)
NATURAL_VENTILATION_RATE = UniformDistributedParameter(0.65, 20.0)
MAX_HEATING_POWER = 0
INITIAL_TEMPERATURE = UniformDistributedParameter(22, 35.2)
NUMBER_DWELLINGS = 100
In [ ]:
from itertools import chain
def create_dwellings():
ids = list(range(104, NUMBER_DWELLINGS + 104))
return pd.DataFrame(
index=ids,
data = {
'thermalMassCapacity': [THERMAL_MASS_CAPACITY.sample() for unused in ids],
'thermalMassArea': [THERMAL_MASS_AREA.sample() for unused in ids],
'floorArea': CONDITIONED_FLOOR_AREA,
'roomHeight': [ROOM_HEIGHT.sample() for unused in ids],
'windowToWallRatio': [WINDOW_TO_WALL_RATIO.sample() for unused in ids],
'uWall': [U_VALUE_WALL.sample() for unused in ids],
'uRoof': [U_VALUE_ROOF.sample() for unused in ids],
'uFloor': [U_VALUE_FLOOR.sample() for unused in ids],
'uWindow': [U_VALUE_WINDOW.sample() for unused in ids],
'transmissionAdjustmentGround': [TRANSMISSION_ADJUSTMENT_GROUND.sample() for unused in ids],
'naturalVentilationRate': [NATURAL_VENTILATION_RATE.sample() for unused in ids],
'maxHeatingPower': MAX_HEATING_POWER,
'initialTemperature': [INITIAL_TEMPERATURE.sample() for unused in ids],
'heatingControlStrategy': [random.choice(['OFF', 'FLAT', 'TIME_TRIGGERED', 'PRESENCE_TRIGGERED'])
for unused in ids],
'districtId': list(chain(*[[x]*10 for x in range(NUMBER_DWELLINGS // 10)]))
}
)
In [ ]:
dwellings = create_dwellings()
dwellings.head()
In [ ]:
assert len(dwellings.index) == NUMBER_DWELLINGS
In [ ]:
df_to_db(dwellings, DWELLINGS_TABLE_NAME)
In [ ]:
NUMBER_PEOPLE = 200
In [ ]:
def create_people():
ids = list(range(1, NUMBER_PEOPLE * 2, 2))
return pd.DataFrame(
index=ids,
data = {
'markovChainId': [{1: 89, 2:22}[round(random.uniform(1, 2))] for unused in ids],
'dwellingId': [round(random.uniform(104, NUMBER_DWELLINGS + 103)) for unused in ids],
'initialActivity': [{1: 'HOME', 2: 'NOT_AT_HOME'}[round(random.uniform(1, 2))] for unused in ids],
'randomSeed': [123456789 + person_id for person_id in ids],
'activeMetabolicRate': 100.0,
'passiveMetabolicRate': 50.0
}
)
In [ ]:
people = create_people()
people.head()
In [ ]:
assert len(people.index) == NUMBER_PEOPLE
assert all(dwellingId in dwellings.index for dwellingId in people.dwellingId)
In [ ]:
df_to_db(people, PEOPLE_TABLE_NAME)
In [ ]:
def create_temperature_profile():
index = pd.date_range('2015-01-01 00:00', '2015-12-31 12:00', freq='12H')
x = np.linspace(0, len(index) - 1, num=len(index))
return pd.Series(
name='temperature',
index=index,
data=10 + 5 * np.sin(-1 + x / 2 * 2 * math.pi) + 10 * np.sin(-1.5 + x / len(index) * 2 * math.pi)
)
def plot_temperature(df):
fig = plt.figure(figsize=(14, 5))
_ = plt.plot(df)
plt.title("Synthesized temperature profile")
plt.ylabel("temperature [˚C]")
plt.xlabel("datetime")
In [ ]:
temperature = create_temperature_profile()
plot_temperature(temperature)
In [ ]:
df_to_db(temperature, ENVIRONMENT_TABLE_NAME)
In [ ]:
def create_simulation_parameters():
return pd.DataFrame(
index = [1],
data = {
'initialDatetime': temperature.index[0],
'timeStepSize_in_min': timedelta(hours=12).total_seconds() / 60, # timedelta not supported in SQL
'numberTimeSteps': 90,
'logThermalPower': False,
'logTemperature': True,
'logActivity': True,
'logAggregated': False,
'setPointWhileHome': 24.0,
'setPointWhileAsleep': 18.0,
'wakeUpTime': time(8, 0),
'leaveHomeTime': time(9, 0),
'comeHomeTime': time(18, 0),
'bedTime': time(22, 0)
}
)
In [ ]:
simulation_parameters = create_simulation_parameters()
simulation_parameters.head()
In [ ]:
df_to_db(simulation_parameters, PARAMETERS_TABLE_NAME)