11
11
from pvlib ._deprecation import pvlibDeprecationWarning
12
12
13
13
NSRDB_API_BASE = "https://developer.nrel.gov"
14
- PSM_URL = NSRDB_API_BASE + "/api/nsrdb/v2/solar/psm3-download.csv"
14
+ PSM_URL = NSRDB_API_BASE + "/api/nsrdb/v2/solar/psm3-2-2- download.csv"
15
15
TMY_URL = NSRDB_API_BASE + "/api/nsrdb/v2/solar/psm3-tmy-download.csv"
16
16
PSM5MIN_URL = NSRDB_API_BASE + "/api/nsrdb/v2/solar/psm3-5min-download.csv"
17
17
63
63
64
64
def get_psm3 (latitude , longitude , api_key , email , names = 'tmy' , interval = 60 ,
65
65
attributes = ATTRIBUTES , leap_day = None , full_name = PVLIB_PYTHON ,
66
- affiliation = PVLIB_PYTHON , map_variables = None , timeout = 30 ):
66
+ affiliation = PVLIB_PYTHON , url = None , map_variables = None ,
67
+ timeout = 30 ):
67
68
"""
68
69
Retrieve NSRDB PSM3 timeseries weather data from the PSM3 API. The NSRDB
69
70
is described in [1]_ and the PSM3 API is described in [2]_, [3]_, and [4]_.
@@ -73,6 +74,12 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
73
74
and the second element is a dictionary containing metadata. Previous
74
75
versions of this function had the return values switched.
75
76
77
+ .. versionchanged:: 0.10.0
78
+ The default endpoint for hourly single-year datasets is now v3.2.2.
79
+ The previous datasets can still be accessed (for now) by setting
80
+ the ``url`` parameter to the original API endpoint
81
+ (``"https://developer.nrel.gov/api/nsrdb/v2/solar/psm3-download.csv"``).
82
+
76
83
Parameters
77
84
----------
78
85
latitude : float or int
@@ -85,8 +92,10 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
85
92
NREL API uses this to automatically communicate messages back
86
93
to the user only if necessary
87
94
names : str, default 'tmy'
88
- PSM3 API parameter specifing year or TMY variant to download, see notes
89
- below for options
95
+ PSM3 API parameter specifing year (e.g. ``2020``) or TMY variant
96
+ to download (e.g. ``'tmy'`` or ``'tgy-2019'``). The allowed values
97
+ update periodically, so consult the NSRDB references below for the
98
+ current set of options.
90
99
interval : int, {60, 5, 15, 30}
91
100
interval size in minutes, must be 5, 15, 30 or 60. Must be 60 for
92
101
typical year requests (i.e., tmy/tgy/tdy).
@@ -95,14 +104,18 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
95
104
``pvlib.iotools.psm3.ATTRIBUTES``. See references [2]_, [3]_, and [4]_
96
105
for lists of available fields. Alternatively, pvlib names may also be
97
106
used (e.g. 'ghi' rather than 'GHI'); see :const:`REQUEST_VARIABLE_MAP`.
107
+ To retrieve all available fields, set ``attributes=[]``.
98
108
leap_day : boolean, default False
99
109
include leap day in the results. Only used for single-year requests
100
110
(i.e., it is ignored for tmy/tgy/tdy requests).
101
111
full_name : str, default 'pvlib python'
102
112
optional
103
113
affiliation : str, default 'pvlib python'
104
114
optional
105
- map_variables: boolean, optional
115
+ url : str, optional
116
+ API endpoint URL. If not specified, the endpoint is determined from
117
+ the ``names`` and ``interval`` parameters.
118
+ map_variables : boolean, optional
106
119
When true, renames columns of the Dataframe to pvlib variable names
107
120
where applicable. See variable :const:`VARIABLE_MAP`.
108
121
timeout : int, default 30
@@ -132,21 +145,6 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
132
145
.. warning:: The "DEMO_KEY" `api_key` is severely rate limited and may
133
146
result in rejected requests.
134
147
135
- The PSM3 API `names` parameter must be a single value from one of these
136
- lists:
137
-
138
- +-----------+-------------------------------------------------------------+
139
- | Category | Allowed values |
140
- +===========+=============================================================+
141
- | Year | 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, |
142
- | | 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, |
143
- | | 2018, 2019, 2020 |
144
- +-----------+-------------------------------------------------------------+
145
- | TMY | tmy, tmy-2016, tmy-2017, tdy-2017, tgy-2017, |
146
- | | tmy-2018, tdy-2018, tgy-2018, tmy-2019, tdy-2019, tgy-2019 |
147
- | | tmy-2020, tdy-2020, tgy-2020 |
148
- +-----------+-------------------------------------------------------------+
149
-
150
148
.. warning:: PSM3 is limited to data found in the NSRDB, please consult the
151
149
references below for locations with available data. Additionally,
152
150
querying data with < 30-minute resolution uses a different API endpoint
@@ -161,8 +159,8 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
161
159
162
160
.. [1] `NREL National Solar Radiation Database (NSRDB)
163
161
<https://nsrdb.nrel.gov/>`_
164
- .. [2] `Physical Solar Model (PSM) v3
165
- <https://developer.nrel.gov/docs/solar/nsrdb/psm3-download/>`_
162
+ .. [2] `Physical Solar Model (PSM) v3.2.2
163
+ <https://developer.nrel.gov/docs/solar/nsrdb/psm3-2-2- download/>`_
166
164
.. [3] `Physical Solar Model (PSM) v3 TMY
167
165
<https://developer.nrel.gov/docs/solar/nsrdb/psm3-tmy-download/>`_
168
166
.. [4] `Physical Solar Model (PSM) v3 - Five Minute Temporal Resolution
@@ -205,13 +203,16 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
205
203
'interval' : interval
206
204
}
207
205
# request CSV download from NREL PSM3
208
- if any (prefix in names for prefix in ('tmy' , 'tgy' , 'tdy' )):
209
- URL = TMY_URL
210
- elif interval in (5 , 15 ):
211
- URL = PSM5MIN_URL
212
- else :
213
- URL = PSM_URL
214
- response = requests .get (URL , params = params , timeout = timeout )
206
+ if url is None :
207
+ # determine the endpoint that suits the user inputs
208
+ if any (prefix in names for prefix in ('tmy' , 'tgy' , 'tdy' )):
209
+ url = TMY_URL
210
+ elif interval in (5 , 15 ):
211
+ url = PSM5MIN_URL
212
+ else :
213
+ url = PSM_URL
214
+
215
+ response = requests .get (url , params = params , timeout = timeout )
215
216
if not response .ok :
216
217
# if the API key is rejected, then the response status will be 403
217
218
# Forbidden, and then the error is in the content and there is no JSON
0 commit comments