Skip to content

Commit c4f41ce

Browse files
committed
update default endpoint to 3.2.2; add url parameter
1 parent 275e671 commit c4f41ce

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

pvlib/iotools/psm3.py

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from pvlib._deprecation import pvlibDeprecationWarning
1212

1313
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"
1515
TMY_URL = NSRDB_API_BASE + "/api/nsrdb/v2/solar/psm3-tmy-download.csv"
1616
PSM5MIN_URL = NSRDB_API_BASE + "/api/nsrdb/v2/solar/psm3-5min-download.csv"
1717

@@ -63,7 +63,8 @@
6363

6464
def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
6565
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):
6768
"""
6869
Retrieve NSRDB PSM3 timeseries weather data from the PSM3 API. The NSRDB
6970
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,
7374
and the second element is a dictionary containing metadata. Previous
7475
versions of this function had the return values switched.
7576
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+
7683
Parameters
7784
----------
7885
latitude : float or int
@@ -85,8 +92,10 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
8592
NREL API uses this to automatically communicate messages back
8693
to the user only if necessary
8794
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.
9099
interval : int, {60, 5, 15, 30}
91100
interval size in minutes, must be 5, 15, 30 or 60. Must be 60 for
92101
typical year requests (i.e., tmy/tgy/tdy).
@@ -95,14 +104,18 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
95104
``pvlib.iotools.psm3.ATTRIBUTES``. See references [2]_, [3]_, and [4]_
96105
for lists of available fields. Alternatively, pvlib names may also be
97106
used (e.g. 'ghi' rather than 'GHI'); see :const:`REQUEST_VARIABLE_MAP`.
107+
To retrieve all available fields, set ``attributes=[]``.
98108
leap_day : boolean, default False
99109
include leap day in the results. Only used for single-year requests
100110
(i.e., it is ignored for tmy/tgy/tdy requests).
101111
full_name : str, default 'pvlib python'
102112
optional
103113
affiliation : str, default 'pvlib python'
104114
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
106119
When true, renames columns of the Dataframe to pvlib variable names
107120
where applicable. See variable :const:`VARIABLE_MAP`.
108121
timeout : int, default 30
@@ -132,21 +145,6 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
132145
.. warning:: The "DEMO_KEY" `api_key` is severely rate limited and may
133146
result in rejected requests.
134147
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-
150148
.. warning:: PSM3 is limited to data found in the NSRDB, please consult the
151149
references below for locations with available data. Additionally,
152150
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,
161159
162160
.. [1] `NREL National Solar Radiation Database (NSRDB)
163161
<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/>`_
166164
.. [3] `Physical Solar Model (PSM) v3 TMY
167165
<https://developer.nrel.gov/docs/solar/nsrdb/psm3-tmy-download/>`_
168166
.. [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,
205203
'interval': interval
206204
}
207205
# 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)
215216
if not response.ok:
216217
# if the API key is rejected, then the response status will be 403
217218
# Forbidden, and then the error is in the content and there is no JSON

0 commit comments

Comments
 (0)