@@ -27,19 +27,18 @@ configuration at a handful of sites listed below.
2727
2828.. ipython :: python
2929
30+ import pvlib
3031 import pandas as pd
3132 import matplotlib.pyplot as plt
3233
33- naive_times = pd.date_range(start = ' 2015' , end = ' 2016' , freq = ' 1h' )
34-
3534 # very approximate
3635 # latitude, longitude, name, altitude, timezone
37- coordinates = [( 30 , - 110 , ' Tucson ' , 700 , ' Etc/GMT+7 ' ),
38- ( 35 , - 105 , ' Albuquerque ' , 1500 , ' Etc/GMT+7' ),
39- ( 40 , - 120 , ' San Francisco ' , 10 , ' Etc/GMT+8 ' ),
40- ( 50 , 10 , ' Berlin ' , 34 , ' Etc/GMT-1 ' )]
41-
42- import pvlib
36+ coordinates = [
37+ ( 30 , - 110 , ' Tucson ' , 700 , ' Etc/GMT+7' ),
38+ ( 35 , - 105 , ' Albuquerque ' , 1500 , ' Etc/GMT+7 ' ),
39+ ( 40 , - 120 , ' San Francisco ' , 10 , ' Etc/GMT+8 ' ),
40+ ( 50 , 10 , ' Berlin ' , 34 , ' Etc/GMT-1 ' ),
41+ ]
4342
4443 # get the module and inverter specifications from SAM
4544 sandia_modules = pvlib.pvsystem.retrieve_sam(' SandiaMod' )
@@ -48,9 +47,32 @@ configuration at a handful of sites listed below.
4847 inverter = sapm_inverters[' ABB__MICRO_0_25_I_OUTD_US_208__208V_' ]
4948 temperature_model_parameters = pvlib.temperature.TEMPERATURE_MODEL_PARAMETERS [' sapm' ][' open_rack_glass_glass' ]
5049
51- # specify constant ambient air temp and wind for simplicity
52- temp_air = 20
53- wind_speed = 0
50+
51+ In order to retrieve meteorological data for the simulation, we can make use of
52+ the :ref: `iotools ` module. In this example we will be using PVGIS, one of the
53+ data sources available, to retrieve a Typical Meteorological Year (TMY) which
54+ includes irradiation, temperature and wind speed.
55+
56+ .. note :: PVGIS uses different naming conventions, so it is required to rename
57+ the weather data variables before using them. Data is already UTC-localized,
58+ so conversion to local timezone is optional.
59+
60+ .. ipython :: python
61+
62+ variables_translation = {
63+ " Gb(n)" : " dni" ,
64+ " G(h)" : " ghi" ,
65+ " Gd(h)" : " dhi" ,
66+ " T2m" : " temp_air" ,
67+ " WS10m" : " wind_speed" ,
68+ }
69+ tmys = []
70+ for location in coordinates:
71+ latitude, longitude, name, altitude, timezone = location
72+ weather = pvlib.iotools.get_pvgis_tmy(latitude, longitude)[0 ]
73+ weather = weather.rename(columns = variables_translation)
74+ weather.index.name = " utc_time"
75+ tmys.append(weather)
5476
5577
5678 Procedural
@@ -69,41 +91,60 @@ to accomplish our system modeling goal:
6991
7092 energies = {}
7193
72- for latitude, longitude, name, altitude, timezone in coordinates:
73- times = naive_times.tz_localize( timezone)
94+ for location, weather in zip ( coordinates, tmys) :
95+ latitude, longitude, name, altitude, timezone = location
7496 system[' surface_tilt' ] = latitude
75- solpos = pvlib.solarposition.get_solarposition(times, latitude, longitude)
76- dni_extra = pvlib.irradiance.get_extra_radiation(times)
97+ solpos = pvlib.solarposition.get_solarposition(
98+ time = weather.index,
99+ latitude = latitude,
100+ longitude = longitude,
101+ altitude = altitude,
102+ temperature = weather[" temp_air" ],
103+ pressure = pvlib.atmosphere.alt2pres(altitude),
104+ )
105+ dni_extra = pvlib.irradiance.get_extra_radiation(weather.index)
77106 airmass = pvlib.atmosphere.get_relative_airmass(solpos[' apparent_zenith' ])
78107 pressure = pvlib.atmosphere.alt2pres(altitude)
79108 am_abs = pvlib.atmosphere.get_absolute_airmass(airmass, pressure)
80- tl = pvlib.clearsky.lookup_linke_turbidity(times, latitude, longitude)
81- cs = pvlib.clearsky.ineichen(solpos[' apparent_zenith' ], am_abs, tl,
82- dni_extra = dni_extra, altitude = altitude)
83- aoi = pvlib.irradiance.aoi(system[' surface_tilt' ], system[' surface_azimuth' ],
84- solpos[' apparent_zenith' ], solpos[' azimuth' ])
85- total_irrad = pvlib.irradiance.get_total_irradiance(system[' surface_tilt' ],
86- system[' surface_azimuth' ],
87- solpos[' apparent_zenith' ],
88- solpos[' azimuth' ],
89- cs[' dni' ], cs[' ghi' ], cs[' dhi' ],
90- dni_extra = dni_extra,
91- model = ' haydavies' )
92- tcell = pvlib.temperature.sapm_cell(total_irrad[' poa_global' ],
93- temp_air, wind_speed,
94- ** temperature_model_parameters)
109+ aoi = pvlib.irradiance.aoi(
110+ system[' surface_tilt' ],
111+ system[' surface_azimuth' ],
112+ solpos[" apparent_zenith" ],
113+ solpos[" azimuth" ],
114+ )
115+ total_irradiance = pvlib.irradiance.get_total_irradiance(
116+ system[' surface_tilt' ],
117+ system[' surface_azimuth' ],
118+ solpos[' apparent_zenith' ],
119+ solpos[' azimuth' ],
120+ weather[' dni' ],
121+ weather[' ghi' ],
122+ weather[' dhi' ],
123+ dni_extra = dni_extra,
124+ model = ' haydavies' ,
125+ )
126+ cell_temperature = pvlib.temperature.sapm_cell(
127+ total_irradiance[' poa_global' ],
128+ weather[" temp_air" ],
129+ weather[" wind_speed" ],
130+ ** temperature_model_parameters,
131+ )
95132 effective_irradiance = pvlib.pvsystem.sapm_effective_irradiance(
96- total_irrad[' poa_direct' ], total_irrad[' poa_diffuse' ],
97- am_abs, aoi, module)
98- dc = pvlib.pvsystem.sapm(effective_irradiance, tcell, module)
133+ total_irradiance[' poa_direct' ],
134+ total_irradiance[' poa_diffuse' ],
135+ am_abs,
136+ aoi,
137+ module,
138+ )
139+ dc = pvlib.pvsystem.sapm(effective_irradiance, cell_temperature, module)
99140 ac = pvlib.inverter.sandia(dc[' v_mp' ], dc[' p_mp' ], inverter)
100141 annual_energy = ac.sum()
101142 energies[name] = annual_energy
102143
103144 energies = pd.Series(energies)
104145
105146 # based on the parameters specified above, these are in W*hrs
106- print (energies.round( 0 ) )
147+ print (energies)
107148
108149 energies.plot(kind = ' bar' , rot = 0 )
109150 @savefig proc -energies.png width=6in
@@ -150,28 +191,35 @@ by examining the parameters defined for the module.
150191 from pvlib.location import Location
151192 from pvlib.modelchain import ModelChain
152193
153- system = PVSystem(module_parameters = module,
154- inverter_parameters = inverter,
155- temperature_model_parameters = temperature_model_parameters)
194+ system = PVSystem(
195+ module_parameters = module,
196+ inverter_parameters = inverter,
197+ temperature_model_parameters = temperature_model_parameters,
198+ )
156199
157200 energies = {}
158- for latitude, longitude, name, altitude, timezone in coordinates:
159- times = naive_times.tz_localize(timezone)
160- location = Location(latitude, longitude, name = name, altitude = altitude,
161- tz = timezone)
162- weather = location.get_clearsky(times)
163- mc = ModelChain(system, location,
164- orientation_strategy = ' south_at_latitude_tilt' )
165- # model results (ac, dc) and intermediates (aoi, temps, etc.)
166- # assigned as mc object attributes
167- mc.run_model(weather)
168- annual_energy = mc.results.ac.sum()
201+ for location, weather in zip (coordinates, tmys):
202+ latitude, longitude, name, altitude, timezone = location
203+ location = Location(
204+ latitude,
205+ longitude,
206+ name = name,
207+ altitude = altitude,
208+ tz = timezone,
209+ )
210+ mc = ModelChain(
211+ system,
212+ location,
213+ orientation_strategy = ' south_at_latitude_tilt' ,
214+ )
215+ results = mc.run_model(weather)
216+ annual_energy = results.ac.sum()
169217 energies[name] = annual_energy
170218
171219 energies = pd.Series(energies)
172220
173221 # based on the parameters specified above, these are in W*hrs
174- print (energies.round( 0 ) )
222+ print (energies)
175223
176224 energies.plot(kind = ' bar' , rot = 0 )
177225 @savefig modelchain -energies.png width=6in
0 commit comments