@@ -27,19 +27,17 @@ 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-
35- # very approximate
3634 # 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
35+ coordinates = [
36+ ( 32.2 , - 111.0 , ' Tucson ' , 700 , ' Etc/GMT+7' ),
37+ ( 35.1 , - 106.6 , ' Albuquerque ' , 1500 , ' Etc/GMT+7 ' ),
38+ ( 37.8 , - 122.4 , ' San Francisco ' , 10 , ' Etc/GMT+8 ' ),
39+ ( 52.5 , 13.4 , ' Berlin ' , 34 , ' Etc/GMT-1 ' ),
40+ ]
4341
4442 # get the module and inverter specifications from SAM
4543 sandia_modules = pvlib.pvsystem.retrieve_sam(' SandiaMod' )
@@ -48,9 +46,32 @@ configuration at a handful of sites listed below.
4846 inverter = sapm_inverters[' ABB__MICRO_0_25_I_OUTD_US_208__208V_' ]
4947 temperature_model_parameters = pvlib.temperature.TEMPERATURE_MODEL_PARAMETERS [' sapm' ][' open_rack_glass_glass' ]
5048
51- # specify constant ambient air temp and wind for simplicity
52- temp_air = 20
53- wind_speed = 0
49+
50+ In order to retrieve meteorological data for the simulation, we can make use of
51+ the :ref: `iotools ` module. In this example we will be using PVGIS, one of the
52+ data sources available, to retrieve a Typical Meteorological Year (TMY) which
53+ includes irradiation, temperature and wind speed.
54+
55+ .. note :: PVGIS uses different naming conventions, so it is required to rename
56+ the weather data variables before using them. Data is already UTC-localized,
57+ so conversion to local timezone is optional.
58+
59+ .. ipython :: python
60+
61+ variables_translation = {
62+ " Gb(n)" : " dni" ,
63+ " G(h)" : " ghi" ,
64+ " Gd(h)" : " dhi" ,
65+ " T2m" : " temp_air" ,
66+ " WS10m" : " wind_speed" ,
67+ }
68+ tmys = []
69+ for location in coordinates:
70+ latitude, longitude, name, altitude, timezone = location
71+ weather = pvlib.iotools.get_pvgis_tmy(latitude, longitude)[0 ]
72+ weather = weather.rename(columns = variables_translation)
73+ weather.index.name = " utc_time"
74+ tmys.append(weather)
5475
5576
5677 Procedural
@@ -69,41 +90,60 @@ to accomplish our system modeling goal:
6990
7091 energies = {}
7192
72- for latitude, longitude, name, altitude, timezone in coordinates:
73- times = naive_times.tz_localize( timezone)
93+ for location, weather in zip ( coordinates, tmys) :
94+ latitude, longitude, name, altitude, timezone = location
7495 system[' surface_tilt' ] = latitude
75- solpos = pvlib.solarposition.get_solarposition(times, latitude, longitude)
76- dni_extra = pvlib.irradiance.get_extra_radiation(times)
96+ solpos = pvlib.solarposition.get_solarposition(
97+ time = weather.index,
98+ latitude = latitude,
99+ longitude = longitude,
100+ altitude = altitude,
101+ temperature = weather[" temp_air" ],
102+ pressure = pvlib.atmosphere.alt2pres(altitude),
103+ )
104+ dni_extra = pvlib.irradiance.get_extra_radiation(weather.index)
77105 airmass = pvlib.atmosphere.get_relative_airmass(solpos[' apparent_zenith' ])
78106 pressure = pvlib.atmosphere.alt2pres(altitude)
79107 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)
108+ aoi = pvlib.irradiance.aoi(
109+ system[' surface_tilt' ],
110+ system[' surface_azimuth' ],
111+ solpos[" apparent_zenith" ],
112+ solpos[" azimuth" ],
113+ )
114+ total_irradiance = pvlib.irradiance.get_total_irradiance(
115+ system[' surface_tilt' ],
116+ system[' surface_azimuth' ],
117+ solpos[' apparent_zenith' ],
118+ solpos[' azimuth' ],
119+ weather[' dni' ],
120+ weather[' ghi' ],
121+ weather[' dhi' ],
122+ dni_extra = dni_extra,
123+ model = ' haydavies' ,
124+ )
125+ cell_temperature = pvlib.temperature.sapm_cell(
126+ total_irradiance[' poa_global' ],
127+ weather[" temp_air" ],
128+ weather[" wind_speed" ],
129+ ** temperature_model_parameters,
130+ )
95131 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)
132+ total_irradiance[' poa_direct' ],
133+ total_irradiance[' poa_diffuse' ],
134+ am_abs,
135+ aoi,
136+ module,
137+ )
138+ dc = pvlib.pvsystem.sapm(effective_irradiance, cell_temperature, module)
99139 ac = pvlib.inverter.sandia(dc[' v_mp' ], dc[' p_mp' ], inverter)
100140 annual_energy = ac.sum()
101141 energies[name] = annual_energy
102142
103143 energies = pd.Series(energies)
104144
105145 # based on the parameters specified above, these are in W*hrs
106- print (energies.round( 0 ) )
146+ print (energies)
107147
108148 energies.plot(kind = ' bar' , rot = 0 )
109149 @savefig proc -energies.png width=6in
@@ -150,28 +190,35 @@ by examining the parameters defined for the module.
150190 from pvlib.location import Location
151191 from pvlib.modelchain import ModelChain
152192
153- system = PVSystem(module_parameters = module,
154- inverter_parameters = inverter,
155- temperature_model_parameters = temperature_model_parameters)
193+ system = PVSystem(
194+ module_parameters = module,
195+ inverter_parameters = inverter,
196+ temperature_model_parameters = temperature_model_parameters,
197+ )
156198
157199 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()
200+ for location, weather in zip (coordinates, tmys):
201+ latitude, longitude, name, altitude, timezone = location
202+ location = Location(
203+ latitude,
204+ longitude,
205+ name = name,
206+ altitude = altitude,
207+ tz = timezone,
208+ )
209+ mc = ModelChain(
210+ system,
211+ location,
212+ orientation_strategy = ' south_at_latitude_tilt' ,
213+ )
214+ results = mc.run_model(weather)
215+ annual_energy = results.ac.sum()
169216 energies[name] = annual_energy
170217
171218 energies = pd.Series(energies)
172219
173220 # based on the parameters specified above, these are in W*hrs
174- print (energies.round( 0 ) )
221+ print (energies)
175222
176223 energies.plot(kind = ' bar' , rot = 0 )
177224 @savefig modelchain -energies.png width=6in
0 commit comments