@@ -49,10 +49,10 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
49
49
In decimal degrees, east is positive (ISO 19115).
50
50
start : datetime like
51
51
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.
53
53
end : datetime like
54
54
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.
56
56
api_key : str
57
57
Meteonorm API key.
58
58
endpoint : str
@@ -61,7 +61,8 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
61
61
* ``'observation/training'`` - historical data with a 7-day delay
62
62
* ``'observation/realtime'`` - near-real time (past 7-days)
63
63
* ``'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
65
66
66
67
parameters : list or 'all', default : 'all'
67
68
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,
71
72
Orientation (azimuth angle) of the (fixed) plane. Clockwise from north
72
73
(north=0, east=90, south=180, west=270).
73
74
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.
76
76
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
78
78
a list of 360 integer horizon elevation angles.
79
79
interval_index : bool, default : False
80
80
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,
103
103
Examples
104
104
--------
105
105
>>> # Retrieve historical time series data
106
- >>> df, meta = get_meteonorm( # doctest: +SKIP
106
+ >>> df, meta = pvlib.iotools. get_meteonorm( # doctest: +SKIP
107
107
... latitude=50, longitude=10, # doctest: +SKIP
108
108
... start='2023-01-01', end='2025-01-01', # doctest: +SKIP
109
109
... api_key='redacted', # doctest: +SKIP
@@ -122,6 +122,7 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
122
122
.. [3] `Meteonorm API reference
123
123
<https://docs.meteonorm.com/api>`_
124
124
"""
125
+ # Relative date strings are not yet supported
125
126
start = pd .Timestamp (start )
126
127
end = pd .Timestamp (end )
127
128
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,
136
137
'surface_tilt' : surface_tilt ,
137
138
'surface_azimuth' : surface_azimuth ,
138
139
'horizon' : horizon ,
140
+ 'response_format' : 'json' ,
139
141
}
140
142
141
143
# Allow specifying single parameters as string
142
144
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 ]
147
146
148
147
# convert list to string with values separated by commas
149
148
if not isinstance (parameters , (str , type (None ))):
@@ -155,7 +154,7 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
155
154
if not isinstance (horizon , str ):
156
155
params ['horizon' ] = ',' .join (map (str , horizon ))
157
156
158
- if 'forecast ' not in endpoint . lower () :
157
+ if 'basic ' not in endpoint :
159
158
params ['frequency' ] = TIME_STEP_MAP .get (time_step , time_step )
160
159
161
160
headers = {"Authorization" : f"Bearer { api_key } " }
@@ -165,7 +164,8 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
165
164
166
165
if not response .ok :
167
166
# 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' ])
169
169
170
170
data , meta = _parse_meteonorm (response , interval_index , map_variables )
171
171
@@ -177,8 +177,8 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
177
177
178
178
def get_meteonorm_tmy (latitude , longitude , api_key ,
179
179
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' ,
182
182
random_seed = None , clear_sky_radiation_model = 'esra' ,
183
183
data_version = 'latest' , future_scenario = None ,
184
184
future_year = None , interval_index = False ,
@@ -214,8 +214,10 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
214
214
Local terrain situation. Must be one of: ['open', 'depression',
215
215
'cold_air_lake', 'sea_lake', 'city', 'slope_south',
216
216
'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.
219
221
turbidity : list or 'auto', optional
220
222
List of 12 monthly mean atmospheric Linke turbidity values. The default
221
223
is 'auto'.
@@ -272,7 +274,7 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
272
274
'lon' : longitude ,
273
275
'surface_tilt' : surface_tilt ,
274
276
'surface_azimuth' : surface_azimuth ,
275
- 'frequency' : time_step ,
277
+ 'frequency' : TIME_STEP_MAP . get ( time_step , time_step ) ,
276
278
'parameters' : parameters ,
277
279
'horizon' : horizon ,
278
280
'situation' : terrain ,
@@ -282,14 +284,12 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
282
284
'random_seed' : random_seed ,
283
285
'future_scenario' : future_scenario ,
284
286
'future_year' : future_year ,
287
+ 'response_format' : 'json' ,
285
288
}
286
289
287
290
# Allow specifying single parameters as string
288
291
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 ]
293
293
294
294
# convert list to string with values separated by commas
295
295
if not isinstance (parameters , (str , type (None ))):
@@ -304,16 +304,15 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
304
304
if not isinstance (turbidity , str ):
305
305
params ['turbidity' ] = ',' .join (map (str , turbidity ))
306
306
307
- params ['frequency' ] = TIME_STEP_MAP .get (time_step , time_step )
308
-
309
307
headers = {"Authorization" : f"Bearer { api_key } " }
310
308
311
309
response = requests .get (
312
310
urljoin (url , TMY_ENDPOINT .lstrip ('/' )), headers = headers , params = params )
313
311
314
312
if not response .ok :
315
313
# 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' ])
317
316
318
317
data , meta = _parse_meteonorm (response , interval_index , map_variables )
319
318
0 commit comments