Skip to content

Commit adda4cf

Browse files
committed
Full test coverage
1 parent ef4f838 commit adda4cf

File tree

2 files changed

+130
-10
lines changed

2 files changed

+130
-10
lines changed

pvlib/iotools/meteonorm.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
7575
forcasting data.
7676
horizon : str or list, default : 'auto'
7777
Specification of the horizon line. Can be either a 'flat', 'auto', or
78-
a list of 360 horizon elevation angles.
78+
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.
8181
This is an experimental feature which may be removed without warning.
@@ -131,7 +131,8 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
131131

132132
# Allow specifying single parameters as string
133133
if isinstance(parameters, str):
134-
parameter_list = list(VARIABLE_MAP.keys()) + list(VARIABLE_MAP.values())
134+
parameter_list = \
135+
list(VARIABLE_MAP.keys()) + list(VARIABLE_MAP.values())
135136
if parameters in parameter_list:
136137
parameters = [parameters]
137138

@@ -198,7 +199,7 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
198199
Frequency of the time series.
199200
horizon : str, optional
200201
Specification of the horizon line. Can be either 'flat' or 'auto', or
201-
specified as a list of 360 horizon elevation angles.
202+
specified as a list of 360 integer horizon elevation angles.
202203
'auto'.
203204
terrain : str, default : 'open'
204205
Local terrain situation. Must be one of: ['open', 'depression',
@@ -265,7 +266,7 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
265266
'frequency': time_step,
266267
'parameters': parameters,
267268
'horizon': horizon,
268-
'terrain': terrain,
269+
'situation': terrain,
269270
'turbidity': turbidity,
270271
'clear_sky_radiation_model': clear_sky_radiation_model,
271272
'data_version': data_version,
@@ -276,7 +277,8 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
276277

277278
# Allow specifying single parameters as string
278279
if isinstance(parameters, str):
279-
parameter_list = list(VARIABLE_MAP.keys()) + list(VARIABLE_MAP.values())
280+
parameter_list = \
281+
list(VARIABLE_MAP.keys()) + list(VARIABLE_MAP.values())
280282
if parameters in parameter_list:
281283
parameters = [parameters]
282284

@@ -287,12 +289,14 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
287289
parameters = [parameter_dict.get(p, p) for p in parameters]
288290
params['parameters'] = ','.join(parameters)
289291

290-
if isinstance(horizon, str):
292+
if not isinstance(horizon, str):
291293
params['horizon'] = ','.join(map(str, horizon))
292294

293-
if isinstance(turbidity, str):
295+
if not isinstance(turbidity, str):
294296
params['turbidity'] = ','.join(map(str, turbidity))
295297

298+
params['frequency'] = TIME_STEP_MAP.get(time_step, time_step)
299+
296300
headers = {"Authorization": f"Bearer {api_key}"}
297301

298302
response = requests.get(

tests/iotools/test_meteonorm.py

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import pandas as pd
2+
import numpy as np
23
import pytest
34
import pvlib
45
from tests.conftest import RERUNS, RERUNS_DELAY
6+
from requests.exceptions import HTTPError
57

68

79
@pytest.fixture
@@ -29,11 +31,13 @@ def expected_meta():
2931
{'aggregation_method': 'average',
3032
'description': 'Global horizontal irradiance',
3133
'name': 'global_horizontal_irradiance',
32-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
34+
'unit': {
35+
'description': 'Watt per square meter', 'name': 'W/m**2'}},
3336
{'aggregation_method': 'average',
34-
'description': 'Global horizontal irradiance with shading taken into account',
37+
'description': 'Global horizontal irradiance with shading taken into account', # noqa: E501
3538
'name': 'global_horizontal_irradiance_with_shading',
36-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
39+
'unit': {'description': 'Watt per square meter',
40+
'name': 'W/m**2'}},
3741
],
3842
'surface_azimuth': 180,
3943
'surface_tilt': 0,
@@ -186,3 +190,115 @@ def test_get_meteonorm_forecast_precision(demo_api_key, demo_url):
186190
assert data.index[1] - data.index[0] == pd.Timedelta(minutes=15)
187191
assert data.shape == (5, 1)
188192
assert meta['frequency'] == '15_minutes'
193+
194+
195+
@pytest.mark.remote_data
196+
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
197+
def test_get_meteonorm_custom_horizon(demo_api_key, demo_url):
198+
data, meta = pvlib.iotools.get_meteonorm(
199+
latitude=50, longitude=10,
200+
start=pd.Timestamp.now(tz='UTC'),
201+
end=pd.Timestamp.now(tz='UTC') + pd.Timedelta(hours=5),
202+
api_key=demo_api_key,
203+
parameters='ghi',
204+
endpoint='forecast/basic',
205+
horizon=list(np.ones(360).astype(int)*80),
206+
url=demo_url)
207+
208+
209+
@pytest.mark.remote_data
210+
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
211+
def test_get_meteonorm_HTTPError(demo_api_key, demo_url):
212+
with pytest.raises(
213+
HTTPError, match="unknown parameter: not_a_real_parameter'"):
214+
_ = pvlib.iotools.get_meteonorm(
215+
latitude=50, longitude=10,
216+
start=pd.Timestamp.now(tz='UTC'),
217+
end=pd.Timestamp.now(tz='UTC') + pd.Timedelta(hours=5),
218+
api_key=demo_api_key,
219+
parameters='not_a_real_parameter',
220+
endpoint='forecast/basic',
221+
url=demo_url)
222+
223+
224+
@pytest.fixture
225+
def expected_meteonorm_tmy_meta():
226+
meta = {
227+
'altitude': 290,
228+
'frequency': '1_hour',
229+
'parameters': [{
230+
'aggregation_method': 'average',
231+
'description': 'Diffuse horizontal irradiance',
232+
'name': 'diffuse_horizontal_irradiance',
233+
'unit': {'description': 'Watt per square meter',
234+
'name': 'W/m**2'},
235+
}],
236+
'surface_azimuth': 90,
237+
'surface_tilt': 20,
238+
'time_zone': 1,
239+
'latitude': 50,
240+
'longitude': 10,
241+
}
242+
return meta
243+
244+
245+
@pytest.fixture
246+
def expected_meteonorm_tmy_index():
247+
index = pd.date_range(
248+
'2005-01-01', periods=8760, freq='1h', tz=3600)
249+
index.freq = None
250+
return index
251+
252+
253+
@pytest.fixture
254+
def expected_metenorm_tmy_data():
255+
# The first 12 rows of data
256+
columns = ['diffuse_horizontal_irradiance']
257+
expected = [
258+
[0.],
259+
[0.],
260+
[0.],
261+
[0.],
262+
[0.],
263+
[0.],
264+
[0.],
265+
[0.],
266+
[9.],
267+
[8.4],
268+
[86.6],
269+
[110.5],
270+
]
271+
index = pd.date_range(
272+
'2005-01-01', periods=12, freq='1h', tz=3600)
273+
index.freq = None
274+
expected = pd.DataFrame(expected, index=index, columns=columns)
275+
return expected
276+
277+
278+
# @pytest.mark.remote_data
279+
# @pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
280+
def test_get_meteonorm_tmy(
281+
demo_api_key, demo_url, expected_meteonorm_tmy_meta,
282+
expected_metenorm_tmy_data, expected_meteonorm_tmy_index):
283+
data, meta = pvlib.iotools.get_meteonorm_tmy(
284+
latitude=50, longitude=10,
285+
api_key=demo_api_key,
286+
parameters='dhi',
287+
surface_tilt=20,
288+
surface_azimuth=90,
289+
time_step='1h',
290+
horizon=list(np.ones(360).astype(int)*2),
291+
terrain='open',
292+
albedo=0.5,
293+
turbidity='auto',
294+
random_seed=100,
295+
clear_sky_radiation_model='solis',
296+
data_version='v9.0', # fix version
297+
future_scenario='ssp1_26',
298+
future_year=2030,
299+
interval_index=True,
300+
map_variables=False,
301+
url=demo_url)
302+
assert meta == expected_meteonorm_tmy_meta
303+
pd.testing.assert_frame_equal(data.iloc[:12], expected_metenorm_tmy_data)
304+
pd.testing.assert_index_equal(data.index, expected_meteonorm_tmy_index)

0 commit comments

Comments
 (0)