Skip to content

Commit ef4f838

Browse files
committed
Update tests
1 parent acbdafa commit ef4f838

File tree

2 files changed

+96
-109
lines changed

2 files changed

+96
-109
lines changed

pvlib/iotools/meteonorm.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,14 @@ def get_meteonorm(latitude, longitude, start, end, api_key, endpoint,
129129
'horizon': horizon,
130130
}
131131

132+
# Allow specifying single parameters as string
133+
if isinstance(parameters, str):
134+
parameter_list = list(VARIABLE_MAP.keys()) + list(VARIABLE_MAP.values())
135+
if parameters in parameter_list:
136+
parameters = [parameters]
137+
132138
# convert list to string with values separated by commas
133-
if not isinstance(params['parameters'], (str, type(None))):
139+
if not isinstance(parameters, (str, type(None))):
134140
# allow the use of pvlib parameter names
135141
parameter_dict = {v: k for k, v in VARIABLE_MAP.items()}
136142
parameters = [parameter_dict.get(p, p) for p in parameters]
@@ -268,8 +274,14 @@ def get_meteonorm_tmy(latitude, longitude, api_key,
268274
'future_year': future_year,
269275
}
270276

277+
# Allow specifying single parameters as string
278+
if isinstance(parameters, str):
279+
parameter_list = list(VARIABLE_MAP.keys()) + list(VARIABLE_MAP.values())
280+
if parameters in parameter_list:
281+
parameters = [parameters]
282+
271283
# convert list to string with values separated by commas
272-
if not isinstance(params['parameters'], (str, type(None))):
284+
if not isinstance(parameters, (str, type(None))):
273285
# allow the use of pvlib parameter names
274286
parameter_dict = {v: k for k, v in VARIABLE_MAP.items()}
275287
parameters = [parameter_dict.get(p, p) for p in parameters]

tests/iotools/test_meteonorm.py

Lines changed: 82 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import pandas as pd
2-
import numpy as np
32
import pytest
43
import pvlib
54
from tests.conftest import RERUNS, RERUNS_DELAY
@@ -27,50 +26,6 @@ def expected_meta():
2726
'altitude': 290,
2827
'frequency': '1_hour',
2928
'parameters': [
30-
{'aggregation_method': 'average',
31-
'description': 'Diffuse horizontal irradiance',
32-
'name': 'diffuse_horizontal_irradiance',
33-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
34-
{'aggregation_method': 'average',
35-
'description': 'Diffuse horizontal irradiance with shading taken into account',
36-
'name': 'diffuse_horizontal_irradiance_with_shading',
37-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
38-
{'aggregation_method': 'average',
39-
'description': 'Diffuse tilted irradiance',
40-
'name': 'diffuse_tilted_irradiance',
41-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
42-
{'aggregation_method': 'average',
43-
'description': 'Diffuse tilted irradiance with shading taken into account',
44-
'name': 'diffuse_tilted_irradiance_with_shading',
45-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
46-
{'aggregation_method': 'average',
47-
'description': 'Direct horizontal irradiance',
48-
'name': 'direct_horizontal_irradiance',
49-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
50-
{'aggregation_method': 'average',
51-
'description': 'Direct horizontal irradiance with shading taken into account',
52-
'name': 'direct_horizontal_irradiance_with_shading',
53-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
54-
{'aggregation_method': 'average',
55-
'description': 'Direct normal irradiance',
56-
'name': 'direct_normal_irradiance',
57-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
58-
{'aggregation_method': 'average',
59-
'description': 'Direct normal irradiance with shading taken into account',
60-
'name': 'direct_normal_irradiance_with_shading',
61-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
62-
{'aggregation_method': 'average',
63-
'description': 'Direct tilted irradiance',
64-
'name': 'direct_tilted_irradiance',
65-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
66-
{'aggregation_method': 'average',
67-
'description': 'Direct tilted irradiance with shading taken into account',
68-
'name': 'direct_tilted_irradiance_with_shading',
69-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
70-
{'aggregation_method': 'average',
71-
'description': 'Global horizontal clear sky irradiance',
72-
'name': 'global_clear_sky_irradiance',
73-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
7429
{'aggregation_method': 'average',
7530
'description': 'Global horizontal irradiance',
7631
'name': 'global_horizontal_irradiance',
@@ -79,30 +34,7 @@ def expected_meta():
7934
'description': 'Global horizontal irradiance with shading taken into account',
8035
'name': 'global_horizontal_irradiance_with_shading',
8136
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
82-
{'aggregation_method': 'average',
83-
'description': 'Global tilted irradiance',
84-
'name': 'global_tilted_irradiance',
85-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
86-
{'aggregation_method': 'average',
87-
'description': 'Global tilted irradiance with shading taken into account',
88-
'name': 'global_tilted_irradiance_with_shading',
89-
'unit': {'description': 'Watt per square meter', 'name': 'W/m**2'}},
90-
{'aggregation_method': 'average',
91-
'description': 'Power output per kWp installed',
92-
'name': 'pv_production',
93-
'unit': {'description': 'Watts per kilowatt peak', 'name': 'W/kWp'}},
94-
{'aggregation_method': 'average',
95-
'description': 'Power output per kWp installed, with shading taken into account',
96-
'name': 'pv_production_with_shading',
97-
'unit': {'description': 'Watts per kilowatt peak', 'name': 'W/kWp'}},
98-
{'aggregation_method': 'average',
99-
'description': 'Snow depth',
100-
'name': 'snow_depth',
101-
'unit': {'description': 'millimeters', 'name': 'mm'}},
102-
{'aggregation_method': 'average',
103-
'description': 'Air temperature, 2 m above ground.',
104-
'name': 'temperature',
105-
'unit': {'description': 'degrees Celsius', 'name': '°C'}}],
37+
],
10638
'surface_azimuth': 180,
10739
'surface_tilt': 0,
10840
'time_zone': 0,
@@ -123,44 +55,53 @@ def expected_meteonorm_index():
12355
@pytest.fixture
12456
def expected_metenorm_data():
12557
# The first 12 rows of data
126-
columns = ['dhi', 'diffuse_horizontal_irradiance_with_shading', 'poa_diffuse',
127-
'diffuse_tilted_irradiance_with_shading', 'bhi',
128-
'direct_horizontal_irradiance_with_shading', 'dni',
129-
'direct_normal_irradiance_with_shading', 'poa_direct',
130-
'direct_tilted_irradiance_with_shading', 'ghi_clear', 'ghi',
131-
'global_horizontal_irradiance_with_shading', 'poa',
132-
'global_tilted_irradiance_with_shading', 'pv_production',
133-
'pv_production_with_shading', 'snow_depth', 'temp_air']
58+
columns = ['ghi', 'global_horizontal_irradiance_with_shading']
13459
expected = [
135-
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 12.25],
136-
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 11.75],
137-
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 11.75],
138-
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 11.5],
139-
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 11.25],
140-
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 11.],
141-
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 11.],
142-
[2.5, 2.68309898, 2.67538201, 2.68309898, 0., 0., 0., 0., 0., 0., 0., 2.5,
143-
2.68309898, 2.67538201, 2.68309898, 2.34649978, 2.35326557, 0., 11.],
144-
[40.43632435, 40.41304027, 40.43632435, 40.41304027, 37.06367565, 37.06367565,
145-
288.7781947, 288.7781947, 37.06367565, 37.06367565, 98.10113439, 77.5,
146-
77.47671591, 77.5, 77.47671591, 67.02141875, 67.00150474, 0., 11.75],
147-
[60.52591348, 60.51498257, 60.52591348, 60.51498257, 104.47408652, 104.47408652,
148-
478.10101591, 478.10101591, 104.47408652, 104.47408652, 191.27910925, 165.,
149-
164.98906908, 165., 164.98906908, 140.23845, 140.22938131, 0., 12.75],
150-
[71.90169306, 71.89757085, 71.90169306, 71.89757085, 138.84830694, 138.84830694,
151-
508.02986044, 508.02986044, 138.84830694, 138.84830694, 253.85597777, 210.75,
152-
210.7458778, 210.75, 210.7458778, 177.07272956, 177.06937293, 0., 13.75],
153-
[78.20403711, 78.19681926, 78.20403711, 78.19681926, 142.79596289, 142.79596289,
154-
494.06576548, 494.06576548, 142.79596289, 142.79596289, 272.34275335, 221.,
155-
220.99278214, 221., 220.99278214, 185.179657, 185.17380523, 0., 14.],
60+
[0.0, 0.0],
61+
[0.0, 0.0],
62+
[0.0, 0.0],
63+
[0.0, 0.0],
64+
[0.0, 0.0],
65+
[0.0, 0.0],
66+
[0.0, 0.0],
67+
[2.5, 2.68309898],
68+
[77.5, 77.47671591],
69+
[165.0, 164.98906908],
70+
[210.75, 210.7458778],
71+
[221.0, 220.99278214],
15672
]
15773
index = pd.date_range('2023-01-01', periods=12, freq='1h', tz='UTC')
15874
index.freq = None
15975
expected = pd.DataFrame(expected, index=index, columns=columns)
160-
expected['snow_depth'] = expected['snow_depth'].astype(np.int64)
16176
return expected
16277

16378

79+
@pytest.fixture
80+
def expected_columns_all():
81+
columns = [
82+
'diffuse_horizontal_irradiance',
83+
'diffuse_horizontal_irradiance_with_shading',
84+
'diffuse_tilted_irradiance',
85+
'diffuse_tilted_irradiance_with_shading',
86+
'direct_horizontal_irradiance',
87+
'direct_horizontal_irradiance_with_shading',
88+
'direct_normal_irradiance',
89+
'direct_normal_irradiance_with_shading',
90+
'direct_tilted_irradiance',
91+
'direct_tilted_irradiance_with_shading',
92+
'global_clear_sky_irradiance',
93+
'global_horizontal_irradiance',
94+
'global_horizontal_irradiance_with_shading',
95+
'global_tilted_irradiance',
96+
'global_tilted_irradiance_with_shading',
97+
'pv_production',
98+
'pv_production_with_shading',
99+
'snow_depth',
100+
'temperature',
101+
]
102+
return columns
103+
104+
164105
@pytest.mark.remote_data
165106
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
166107
def test_get_meteonorm_training(
@@ -170,6 +111,7 @@ def test_get_meteonorm_training(
170111
latitude=50, longitude=10,
171112
start='2023-01-01', end='2025-01-01',
172113
api_key=demo_api_key,
114+
parameters=['ghi', 'global_horizontal_irradiance_with_shading'],
173115
endpoint='observation/training',
174116
time_step='1h',
175117
url=demo_url)
@@ -181,15 +123,13 @@ def test_get_meteonorm_training(
181123

182124
@pytest.mark.remote_data
183125
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
184-
def test_get_meteonorm_realtime(
185-
demo_api_key, demo_url, expected_meta, expected_meteonorm_index,
186-
expected_metenorm_data):
126+
def test_get_meteonorm_realtime(demo_api_key, demo_url, expected_columns_all):
187127
data, meta = pvlib.iotools.get_meteonorm(
188128
latitude=21, longitude=79,
189129
start=pd.Timestamp.now(tz='UTC') - pd.Timedelta(hours=5),
190130
end=pd.Timestamp.now(tz='UTC') - pd.Timedelta(hours=1),
191131
surface_tilt=20, surface_azimuth=10,
192-
parameters=['ghi', 'global_horizontal_irradiance_with_shading'],
132+
parameters=['all'],
193133
api_key=demo_api_key,
194134
endpoint='/observation/realtime',
195135
time_step='1min',
@@ -204,10 +144,45 @@ def test_get_meteonorm_realtime(
204144
assert meta['surface_tilt'] == 20
205145
assert meta['surface_azimuth'] == 10
206146

207-
assert all(data.columns == pd.Index([
208-
'global_horizontal_irradiance',
209-
'global_horizontal_irradiance_with_shading']))
210-
assert data.shape == (241, 2)
147+
assert list(data.columns) == expected_columns_all
148+
assert data.shape == (241, 19)
211149
# can't test the specific index as it varies due to the
212150
# use of pd.Timestamp.now
213151
assert type(data.index) is pd.core.indexes.interval.IntervalIndex
152+
153+
154+
@pytest.mark.remote_data
155+
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
156+
def test_get_meteonorm_forecast_basic(demo_api_key, demo_url):
157+
data, meta = pvlib.iotools.get_meteonorm(
158+
latitude=50, longitude=10,
159+
start=pd.Timestamp.now(tz='UTC'),
160+
end=pd.Timestamp.now(tz='UTC') + pd.Timedelta(hours=5),
161+
api_key=demo_api_key,
162+
parameters='ghi',
163+
endpoint='forecast/basic',
164+
url=demo_url)
165+
166+
assert data.shape == (6, 1)
167+
assert data.columns == pd.Index(['ghi'])
168+
assert data.index[1] - data.index[0] == pd.Timedelta(hours=1)
169+
assert meta['frequency'] == '1_hour'
170+
171+
172+
@pytest.mark.remote_data
173+
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
174+
def test_get_meteonorm_forecast_precision(demo_api_key, demo_url):
175+
data, meta = pvlib.iotools.get_meteonorm(
176+
latitude=50, longitude=10,
177+
start=pd.Timestamp.now(tz='UTC') + pd.Timedelta(hours=5),
178+
end=pd.Timestamp.now(tz='UTC') + pd.Timedelta(hours=6),
179+
api_key=demo_api_key,
180+
parameters='ghi',
181+
endpoint='forecast/precision',
182+
# test that the time_step parameter is ignored
183+
time_step='1h',
184+
url=demo_url)
185+
186+
assert data.index[1] - data.index[0] == pd.Timedelta(minutes=15)
187+
assert data.shape == (5, 1)
188+
assert meta['frequency'] == '15_minutes'

0 commit comments

Comments
 (0)