@@ -49,10 +49,10 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
4949 In decimal degrees, east is positive (ISO 19115).
5050 start : datetime like
5151 First timestamp of the requested period. If a timezone is not
52- specified, UTC is assumed. Relative datetime strings are supported.
52+ specified, UTC is assumed.
5353 end : datetime like
5454 Last timestamp of the requested period. If a timezone is not
55- specified, UTC is assumed. Relative datetime strings are supported.
55+ specified, UTC is assumed.
5656 api_key : str
5757 Meteonorm API key.
5858 endpoint : str
@@ -61,7 +61,8 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
6161 * ``'observation/training'`` - historical data with a 7-day delay
6262 * ``'observation/realtime'`` - near-real time (past 7-days)
6363 * ``'forecast/basic'`` - forecast with hourly resolution
64- * ``'forecast/precision'`` - forecast with 15-min resolution
64+ * ``'forecast/precision'`` - forecast with 1-min, 15-min, or hourly
65+ resolution
6566
6667 parameters : list or 'all', default : 'all'
6768 List of parameters to request or `'all'` to get all parameters.
@@ -71,10 +72,9 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
7172 Orientation (azimuth angle) of the (fixed) plane. Clockwise from north
7273 (north=0, east=90, south=180, west=270).
7374 time_step : {'1min', '15min', '1h'}, default : '15min'
74- Frequency of the time series. The parameter is ignored when requesting
75- forcasting data.
75+ Frequency of the time series.
7676 horizon : str or list, default : 'auto'
77- Specification of the horizon line. Can be either a 'flat', 'auto', or
77+ Specification of the horizon line. Can be either 'flat', 'auto', or
7878 a list of 360 integer horizon elevation angles.
7979 interval_index : bool, default : False
8080 Index is pd.DatetimeIndex when False, and pd.IntervalIndex when True.
@@ -103,7 +103,7 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
103103 Examples
104104 --------
105105 >>> # Retrieve historical time series data
106- >>> df, meta = get_meteonorm( # doctest: +SKIP
106+ >>> df, meta = pvlib.iotools. get_meteonorm( # doctest: +SKIP
107107 ... latitude=50, longitude=10, # doctest: +SKIP
108108 ... start='2023-01-01', end='2025-01-01', # doctest: +SKIP
109109 ... api_key='redacted', # doctest: +SKIP
@@ -122,6 +122,7 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
122122 .. [3] `Meteonorm API reference
123123 <https://docs.meteonorm.com/api>`_
124124 """
125+ # Relative date strings are not yet supported
125126 start = pd .Timestamp (start )
126127 end = pd .Timestamp (end )
127128 start = start .tz_localize ('UTC' ) if start .tzinfo is None else start
@@ -136,14 +137,12 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
136137 'surface_tilt' : surface_tilt ,
137138 'surface_azimuth' : surface_azimuth ,
138139 'horizon' : horizon ,
140+ 'response_format' : 'json' ,
139141 }
140142
141143 # Allow specifying single parameters as string
142144 if isinstance (parameters , str ):
143- parameter_list = \
144- list (VARIABLE_MAP .keys ()) + list (VARIABLE_MAP .values ())
145- if parameters in parameter_list :
146- parameters = [parameters ]
145+ parameters = [parameters ]
147146
148147 # convert list to string with values separated by commas
149148 if not isinstance (parameters , (str , type (None ))):
@@ -155,7 +154,7 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
155154 if not isinstance (horizon , str ):
156155 params ['horizon' ] = ',' .join (map (str , horizon ))
157156
158- if 'forecast ' not in endpoint . lower () :
157+ if 'basic ' not in endpoint :
159158 params ['frequency' ] = TIME_STEP_MAP .get (time_step , time_step )
160159
161160 headers = {"Authorization" : f"Bearer { api_key } " }
@@ -165,7 +164,8 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
165164
166165 if not response .ok :
167166 # response.raise_for_status() does not give a useful error message
168- raise requests .HTTPError (response .json ())
167+ raise requests .HTTPError ("Meteonorm API returned an error: "
168+ + response .json ()['error' ]['message' ])
169169
170170 data , meta = _parse_meteonorm (response , interval_index , map_variables )
171171
@@ -177,8 +177,8 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
177177
178178def get_meteonorm_tmy (latitude , longitude , api_key ,
179179 parameters = 'all' , * , surface_tilt = 0 ,
180- surface_azimuth = 180 , time_step = '15min ' , horizon = 'auto' ,
181- terrain = 'open' , albedo = 0.2 , turbidity = 'auto' ,
180+ surface_azimuth = 180 , time_step = '1h ' , horizon = 'auto' ,
181+ terrain = 'open' , albedo = None , turbidity = 'auto' ,
182182 random_seed = None , clear_sky_radiation_model = 'esra' ,
183183 data_version = 'latest' , future_scenario = None ,
184184 future_year = None , interval_index = False ,
@@ -214,8 +214,10 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
214214 Local terrain situation. Must be one of: ['open', 'depression',
215215 'cold_air_lake', 'sea_lake', 'city', 'slope_south',
216216 'slope_west_east'].
217- albedo : float, default : 0.2
218- Ground albedo. Albedo changes due to snow fall are modelled.
217+ albedo : float, optional
218+ Constant ground albedo. If no value is specified a baseline albedo of
219+ 0.2 is used and albedo cahnges due to snow fall is modeled. If a value
220+ is specified, then snow fall is not modeled.
219221 turbidity : list or 'auto', optional
220222 List of 12 monthly mean atmospheric Linke turbidity values. The default
221223 is 'auto'.
@@ -272,7 +274,7 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
272274 'lon' : longitude ,
273275 'surface_tilt' : surface_tilt ,
274276 'surface_azimuth' : surface_azimuth ,
275- 'frequency' : time_step ,
277+ 'frequency' : TIME_STEP_MAP . get ( time_step , time_step ) ,
276278 'parameters' : parameters ,
277279 'horizon' : horizon ,
278280 'situation' : terrain ,
@@ -282,14 +284,12 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
282284 'random_seed' : random_seed ,
283285 'future_scenario' : future_scenario ,
284286 'future_year' : future_year ,
287+ 'response_format' : 'json' ,
285288 }
286289
287290 # Allow specifying single parameters as string
288291 if isinstance (parameters , str ):
289- parameter_list = \
290- list (VARIABLE_MAP .keys ()) + list (VARIABLE_MAP .values ())
291- if parameters in parameter_list :
292- parameters = [parameters ]
292+ parameters = [parameters ]
293293
294294 # convert list to string with values separated by commas
295295 if not isinstance (parameters , (str , type (None ))):
@@ -304,16 +304,15 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
304304 if not isinstance (turbidity , str ):
305305 params ['turbidity' ] = ',' .join (map (str , turbidity ))
306306
307- params ['frequency' ] = TIME_STEP_MAP .get (time_step , time_step )
308-
309307 headers = {"Authorization" : f"Bearer { api_key } " }
310308
311309 response = requests .get (
312310 urljoin (url , TMY_ENDPOINT .lstrip ('/' )), headers = headers , params = params )
313311
314312 if not response .ok :
315313 # response.raise_for_status() does not give a useful error message
316- raise requests .HTTPError (response .json ())
314+ raise requests .HTTPError ("Meteonorm API returned an error: "
315+ + response .json ()['error' ]['message' ])
317316
318317 data , meta = _parse_meteonorm (response , interval_index , map_variables )
319318
0 commit comments