Skip to content

Commit a9ad117

Browse files
Merge pull request #245 from RWTH-EBC/issue242_release
Issue242 release
2 parents 7d682cc + f2e14a0 commit a9ad117

3 files changed

Lines changed: 373 additions & 3 deletions

File tree

README.md

Lines changed: 184 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,190 @@ by adding new .py file and trying to import uesgraphs and pyCity.
7373

7474
Import should be possible without errors.
7575

76-
76+
## Example usage
77+
78+
```Python
79+
import shapely.geometry.point as point
80+
import matplotlib.pyplot as plt
81+
82+
import uesgraphs.visuals as uesvis
83+
84+
import pycity_base.classes.Timer as time
85+
import pycity_base.classes.Weather as weath
86+
import pycity_base.classes.Prices as price
87+
import pycity_base.classes.Environment as env
88+
import pycity_base.classes.demand.Apartment as apart
89+
import pycity_base.classes.demand.Occupancy as occ
90+
import pycity_base.classes.demand.DomesticHotWater as dhw
91+
import pycity_base.classes.demand.ElectricalDemand as eldem
92+
import pycity_base.classes.demand.SpaceHeating as spaceheat
93+
import pycity_base.classes.Building as build
94+
import pycity_base.classes.CityDistrict as citydist
95+
import pycity_base.classes.supply.BES as besys
96+
import pycity_base.classes.supply.Boiler as boil
97+
import pycity_base.classes.supply.PV as pvsys
98+
99+
100+
def main():
101+
# Define the time discretization for the timer object
102+
timestep = 3600 # in seconds
103+
104+
# Define the total number of timesteps (in this case for one year)
105+
nb_timesteps = int(365 * 24 * 3600 / timestep)
106+
107+
# Generate environment with timer, weather, and prices objects
108+
# ######################################################################
109+
timer = time.Timer(timeDiscretization=timestep,
110+
timestepsTotal=nb_timesteps)
111+
weather = weath.Weather(timer=timer)
112+
prices = price.Prices()
113+
114+
environment = env.Environment(timer=timer, weather=weather, prices=prices)
115+
116+
# Generate city district object
117+
# ######################################################################
118+
city_district = citydist.CityDistrict(environment=environment)
119+
# Annotations: To prevent some methods of subclasses uesgraph / nx.Graph
120+
# from failing (e.g. '.subgraph()) environment is set as optional input
121+
# parameter. However, it is necessary to use an environment object as
122+
# input parameter to initialize a working cityDistrict object!
123+
124+
# Empty dictionary for building positions
125+
dict_pos = {}
126+
127+
# Generate shapely point positions
128+
dict_pos[0] = point.Point(0, 0) # (x, y)
129+
dict_pos[1] = point.Point(20, 0)
130+
131+
# Use for loop to generate two identical building objects for city
132+
# district
133+
# ######################################################################
134+
for i in range(2):
135+
living_area = 200 # in m2
136+
spec_sh_dem = 160 # Specific space heating demand in kWh/m2
137+
number_occupants = 3 # Total number of occupants
138+
139+
# Generate space heating demand object (holding loadcurve attribute
140+
# with space heating power)
141+
heat_demand = spaceheat.SpaceHeating(
142+
environment=environment,
143+
method=1, # Standard load profile
144+
livingArea=living_area, # in m2
145+
specificDemand=spec_sh_dem) # in kWh/m2
146+
147+
# Generate occupancy object with stochastic user profile
148+
occupancy = occ.Occupancy(environment=environment,
149+
number_occupants=number_occupants)
150+
151+
# Generate electrical demand object
152+
el_dem_stochastic = eldem.ElectricalDemand(
153+
environment=environment,
154+
method=2, # stochastic Richardson profile (richardsonpy)
155+
total_nb_occupants=number_occupants, # Number of occupants
156+
randomizeAppliances=True, # Random choice of installed appliances
157+
lightConfiguration=10, # Light bulb configuration nb.
158+
occupancy=occupancy.occupancy, # Occupancy profile (600 s resol.)
159+
prev_heat_dev=True, # Prevent space heating and hot water devices
160+
annualDemand=None, # Annual el. demand in kWh could be used for
161+
do_normalization=False) # rescaling (if do_normalization is True)
162+
# Annotation: The calculation of stochastic electric load profiles
163+
# is time consuming. If you prefer a faster method, you can either
164+
# hand over an own array-like load curve (method=0) or generate a
165+
# standardized load profile (SLP) (method=1)
166+
167+
# Generate domestic hot water demand object
168+
dhw_obj = dhw.DomesticHotWater(
169+
environment=environment,
170+
tFlow=60, # DHW output temperature in degree Celsius
171+
method=2, # Stochastic dhw profile
172+
supplyTemperature=25, # DHW inlet flow temperature in degree C.
173+
occupancy=occupancy.occupancy) # Occupancy profile (600 s resol.)
174+
175+
# Generate apartment and add demand durves
176+
apartment = apart.Apartment(environment)
177+
apartment.addMultipleEntities([heat_demand,
178+
el_dem_stochastic,
179+
dhw_obj])
180+
181+
# Generate building and add apartment
182+
building = build.Building(environment)
183+
building.addEntity(apartment)
184+
185+
# Add buildings to city district
186+
city_district.addEntity(entity=building,
187+
position=dict_pos[i])
188+
189+
# Access information on city district object instance
190+
# ######################################################################
191+
print('Get number of building entities:')
192+
print(city_district.get_nb_of_building_entities())
193+
print()
194+
195+
print('Get list with node ids of building entities:')
196+
print(city_district.get_list_build_entity_node_ids())
197+
print()
198+
199+
print('Get city district overall space heating power load curve:')
200+
print(city_district.get_aggr_space_h_power_curve())
201+
print()
202+
203+
# We can use the Visuals class of uesgraphs to plot the city district
204+
205+
# Generate uesgraphs visuals object instance
206+
uesvisuals = uesvis.Visuals(uesgraph=city_district)
207+
208+
fig = plt.figure()
209+
ax = fig.gca()
210+
ax = uesvisuals.create_plot_simple(ax=ax)
211+
plt.show()
212+
plt.close()
213+
214+
# Access buildings
215+
# ######################################################################
216+
# As city_district is a networkx graph object, we can access the building
217+
# entities with the corresponding building node,
218+
# Pointer to building object with id 1001:
219+
building_1001 = city_district.nodes[1001]['entity']
220+
221+
print('Get building 1001 electric load curve:')
222+
print(building_1001.get_electric_power_curve())
223+
print()
224+
225+
# Add energy systems to buildings
226+
# ######################################################################
227+
# We can also add building energy systems (BES) to each building object
228+
229+
# Generate boiler object
230+
boiler = boil.Boiler(environment=environment,
231+
qNominal=10000, # Boiler thermal power in Watt
232+
eta=0.85) # Boiler efficiency
233+
234+
# Generate PV module object
235+
pv = pvsys.PV(environment=environment,
236+
area=30, # Area in m2
237+
eta=0.15) # Electrical efficiency at NOCT conditions
238+
239+
# Instantiate BES (container object for all energy systems)
240+
bes = besys.BES(environment)
241+
242+
# Add energy systems to bes
243+
bes.addMultipleDevices([boiler, pv])
244+
245+
# Add bes to building 1001
246+
building_1001.addEntity(entity=bes)
247+
248+
print('Does building 1001 has a building energy system (BES)?')
249+
print(building_1001.hasBes)
250+
251+
# Access boiler nominal thermal power
252+
print('Nominal thermal power of boiler in kW:')
253+
print(building_1001.bes.boiler.qNominal / 1000)
254+
255+
if __name__ == '__main__':
256+
# Run program
257+
main()
258+
259+
```
77260

78261
## Tutorial
79262

pycity_base/classes/demand/ElectricalDemand.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ def __init__(self,
187187
q_diffuse=q_diffuse,
188188
annual_demand=annualDemand,
189189
is_sfh=singleFamilyHouse,
190-
path_app=None,
191-
path_light=None,
190+
path_app=app_filename,
191+
path_light=light_filename,
192192
randomize_appliances=randomizeAppliances,
193193
prev_heat_dev=prev_heat_dev,
194194
light_config=lightConfiguration,
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
"""
4+
Example script on how to generate a city district with space heating,
5+
user, stochastic electric, and hot water profiles plus energy systems.
6+
"""
7+
from __future__ import division
8+
9+
import shapely.geometry.point as point
10+
import matplotlib.pyplot as plt
11+
12+
import uesgraphs.visuals as uesvis
13+
14+
import pycity_base.classes.Timer as time
15+
import pycity_base.classes.Weather as weath
16+
import pycity_base.classes.Prices as price
17+
import pycity_base.classes.Environment as env
18+
import pycity_base.classes.demand.Apartment as apart
19+
import pycity_base.classes.demand.Occupancy as occ
20+
import pycity_base.classes.demand.DomesticHotWater as dhw
21+
import pycity_base.classes.demand.ElectricalDemand as eldem
22+
import pycity_base.classes.demand.SpaceHeating as spaceheat
23+
import pycity_base.classes.Building as build
24+
import pycity_base.classes.CityDistrict as citydist
25+
import pycity_base.classes.supply.BES as besys
26+
import pycity_base.classes.supply.Boiler as boil
27+
import pycity_base.classes.supply.PV as pvsys
28+
29+
30+
def run_test():
31+
# Define the time discretization for the timer object
32+
timestep = 3600 # in seconds
33+
34+
# Define the total number of timesteps (in this case for one year)
35+
nb_timesteps = int(365 * 24 * 3600 / timestep)
36+
37+
# Generate environment with timer, weather, and prices objects
38+
# ######################################################################
39+
timer = time.Timer(timeDiscretization=timestep,
40+
timestepsTotal=nb_timesteps)
41+
weather = weath.Weather(timer=timer)
42+
prices = price.Prices()
43+
44+
environment = env.Environment(timer=timer, weather=weather, prices=prices)
45+
46+
# Generate city district object
47+
# ######################################################################
48+
city_district = citydist.CityDistrict(environment=environment)
49+
# Annotations: To prevent some methods of subclasses uesgraph / nx.Graph
50+
# from failing (e.g. '.subgraph()) environment is set as optional input
51+
# parameter. However, it is necessary to use an environment object as
52+
# input parameter to initialize a working cityDistrict object!
53+
54+
# Empty dictionary for building positions
55+
dict_pos = {}
56+
57+
# Generate shapely point positions
58+
dict_pos[0] = point.Point(0, 0) # (x, y)
59+
dict_pos[1] = point.Point(20, 0)
60+
61+
# Use for loop to generate two identical building objects for city
62+
# district
63+
# ######################################################################
64+
for i in range(2):
65+
living_area = 200 # in m2
66+
spec_sh_dem = 160 # Specific space heating demand in kWh/m2
67+
number_occupants = 3 # Total number of occupants
68+
69+
# Generate space heating demand object (holding loadcurve attribute
70+
# with space heating power)
71+
heat_demand = spaceheat.SpaceHeating(
72+
environment=environment,
73+
method=1, # Standard load profile
74+
livingArea=living_area, # in m2
75+
specificDemand=spec_sh_dem) # in kWh/m2
76+
77+
# Generate occupancy object with stochastic user profile
78+
occupancy = occ.Occupancy(environment=environment,
79+
number_occupants=number_occupants)
80+
81+
# Generate electrical demand object
82+
el_dem_stochastic = eldem.ElectricalDemand(
83+
environment=environment,
84+
method=2, # stochastic Richardson profile (richardsonpy)
85+
total_nb_occupants=number_occupants, # Number of occupants
86+
randomizeAppliances=True, # Random choice of installed appliances
87+
lightConfiguration=10, # Light bulb configuration nb.
88+
occupancy=occupancy.occupancy, # Occupancy profile (600 s resol.)
89+
prev_heat_dev=True, # Prevent space heating and hot water devices
90+
annualDemand=None, # Annual el. demand in kWh could be used for
91+
do_normalization=False) # rescaling (if do_normalization is True)
92+
# Annotation: The calculation of stochastic electric load profiles
93+
# is time consuming. If you prefer a faster method, you can either
94+
# hand over an own array-like load curve (method=0) or generate a
95+
# standardized load profile (SLP) (method=1)
96+
97+
# Generate domestic hot water demand object
98+
dhw_obj = dhw.DomesticHotWater(
99+
environment=environment,
100+
tFlow=60, # DHW output temperature in degree Celsius
101+
method=2, # Stochastic dhw profile
102+
supplyTemperature=25, # DHW inlet flow temperature in degree C.
103+
occupancy=occupancy.occupancy) # Occupancy profile (600 s resol.)
104+
105+
# Generate apartment and add demand durves
106+
apartment = apart.Apartment(environment)
107+
apartment.addMultipleEntities([heat_demand,
108+
el_dem_stochastic,
109+
dhw_obj])
110+
111+
# Generate building and add apartment
112+
building = build.Building(environment)
113+
building.addEntity(apartment)
114+
115+
# Add buildings to city district
116+
city_district.addEntity(entity=building,
117+
position=dict_pos[i])
118+
119+
# Access information on city district object instance
120+
# ######################################################################
121+
print('Get number of building entities:')
122+
print(city_district.get_nb_of_building_entities())
123+
print()
124+
125+
print('Get list with node ids of building entities:')
126+
print(city_district.get_list_build_entity_node_ids())
127+
print()
128+
129+
print('Get city district overall space heating power load curve:')
130+
print(city_district.get_aggr_space_h_power_curve())
131+
print()
132+
133+
# We can use the Visuals class of uesgraphs to plot the city district
134+
135+
# Generate uesgraphs visuals object instance
136+
uesvisuals = uesvis.Visuals(uesgraph=city_district)
137+
138+
fig = plt.figure()
139+
ax = fig.gca()
140+
ax = uesvisuals.create_plot_simple(ax=ax)
141+
plt.show()
142+
plt.close()
143+
144+
# Access buildings
145+
# ######################################################################
146+
# As city_district is a networkx graph object, we can access the building
147+
# entities with the corresponding building node,
148+
# Pointer to building object with id 1001:
149+
building_1001 = city_district.nodes[1001]['entity']
150+
151+
print('Get building 1001 electric load curve:')
152+
print(building_1001.get_electric_power_curve())
153+
print()
154+
155+
# Add energy systems to buildings
156+
# ######################################################################
157+
# We can also add building energy systems (BES) to each building object
158+
159+
# Generate boiler object
160+
boiler = boil.Boiler(environment=environment,
161+
qNominal=10000, # Boiler thermal power in Watt
162+
eta=0.85) # Boiler efficiency
163+
164+
# Generate PV module object
165+
pv = pvsys.PV(environment=environment,
166+
area=30, # Area in m2
167+
eta=0.15) # Electrical efficiency at NOCT conditions
168+
169+
# Instantiate BES (container object for all energy systems)
170+
bes = besys.BES(environment)
171+
172+
# Add energy systems to bes
173+
bes.addMultipleDevices([boiler, pv])
174+
175+
# Add bes to building 1001
176+
building_1001.addEntity(entity=bes)
177+
178+
print('Does building 1001 has a building energy system (BES)?')
179+
print(building_1001.hasBes)
180+
181+
# Access boiler nominal thermal power
182+
print('Nominal thermal power of boiler in kW:')
183+
print(building_1001.bes.boiler.qNominal / 1000)
184+
185+
if __name__ == '__main__':
186+
# Run program
187+
run_test()

0 commit comments

Comments
 (0)