@@ -61,30 +61,6 @@ def expected_meteonorm_index():
6161 return expected_meteonorm_index
6262
6363
64- @pytest .fixture
65- def expected_meteonorm_data ():
66- # The first 12 rows of data
67- columns = ['ghi' , 'global_horizontal_irradiance_with_shading' ]
68- expected = [
69- [0.0 , 0.0 ],
70- [0.0 , 0.0 ],
71- [0.0 , 0.0 ],
72- [0.0 , 0.0 ],
73- [0.0 , 0.0 ],
74- [0.0 , 0.0 ],
75- [0.0 , 0.0 ],
76- [3.75 , 3.74 ],
77- [57.25 , 57.20 ],
78- [149.0 , 148.96 ],
79- [242.25 , 242.24 ],
80- [228.0 , 227.98 ],
81- ]
82- index = pd .date_range ('2025-01-01 00:30' , periods = 12 , freq = '1h' , tz = 'UTC' )
83- index .freq = None
84- expected = pd .DataFrame (expected , index = index , columns = columns )
85- return expected
86-
87-
8864@pytest .fixture
8965def expected_columns_all ():
9066 columns = [
@@ -114,8 +90,7 @@ def expected_columns_all():
11490@pytest .mark .remote_data
11591@pytest .mark .flaky (reruns = RERUNS , reruns_delay = RERUNS_DELAY )
11692def test_get_meteonorm_training (
117- demo_api_key , demo_url , expected_meta , expected_meteonorm_index ,
118- expected_meteonorm_data ):
93+ demo_api_key , demo_url , expected_meta , expected_meteonorm_index ):
11994 data , meta = pvlib .iotools .get_meteonorm_observation_training (
12095 latitude = 50 , longitude = 10 ,
12196 start = '2025-01-01' , end = '2026-01-01' ,
@@ -128,10 +103,12 @@ def test_get_meteonorm_training(
128103 for key in ['version' , 'commit' ]:
129104 assert key in meta # value changes, so only check presence
130105 pd .testing .assert_index_equal (data .index , expected_meteonorm_index )
131- # meteonorm API only guarantees similar, not identical, results between
132- # calls. so we allow a small amount of variation with atol.
133- pd .testing .assert_frame_equal (data .iloc [:12 ], expected_meteonorm_data ,
134- check_exact = False , atol = 1 )
106+ # don't pin values: meteonorm may update the dataset without it being a
107+ # breaking change. check parsing instead.
108+ assert list (data .columns ) == \
109+ ['ghi' , 'global_horizontal_irradiance_with_shading' ]
110+ assert data .dtypes .map (pd .api .types .is_numeric_dtype ).all ()
111+ assert (data .isna ().mean () <= 0.2 ).all () # meteonorm guarantees <=20% NaN
135112
136113
137114@pytest .mark .remote_data
@@ -156,8 +133,11 @@ def test_get_meteonorm_realtime(demo_api_key, demo_url, expected_columns_all):
156133 assert meta ['surface_tilt' ] == 20
157134 assert meta ['surface_azimuth' ] == 10
158135
159- assert list (data .columns ) == expected_columns_all
160- assert data .shape == (241 , 19 )
136+ # meteonorm may add parameters to 'all' at any time, so only check that
137+ # the columns we know about are present, not that the set matches exactly.
138+ assert set (expected_columns_all ).issubset (data .columns )
139+ assert data .shape [0 ] == 241 # row count is determined by the time range
140+ assert data .shape [1 ] >= len (expected_columns_all )
161141 # can't test the specific index as it varies due to the
162142 # use of pd.Timestamp.now
163143 assert type (data .index ) is pd .core .indexes .interval .IntervalIndex
@@ -259,38 +239,10 @@ def expected_meteonorm_tmy_meta():
259239 return meta
260240
261241
262- @pytest .fixture
263- def expected_meteonorm_tmy_data ():
264- # The first 12 rows of data
265- columns = ['diffuse_horizontal_irradiance' ]
266- expected = [
267- [0. ],
268- [0. ],
269- [0. ],
270- [0. ],
271- [0. ],
272- [0. ],
273- [0. ],
274- [0. ],
275- [9.07 ],
276- [8.44 ],
277- [86.64 ],
278- [110.44 ],
279- ]
280- index = pd .date_range (
281- '2030-01-01' , periods = 12 , freq = '1h' , tz = 3600 )
282- index .freq = None
283- interval_index = pd .IntervalIndex .from_arrays (
284- index , index + pd .Timedelta (hours = 1 ), closed = 'left' )
285- expected = pd .DataFrame (expected , index = interval_index , columns = columns )
286- return expected
287-
288-
289242@pytest .mark .remote_data
290243@pytest .mark .flaky (reruns = RERUNS , reruns_delay = RERUNS_DELAY )
291244def test_get_meteonorm_tmy (
292- demo_api_key , demo_url , expected_meteonorm_tmy_meta ,
293- expected_meteonorm_tmy_data ):
245+ demo_api_key , demo_url , expected_meteonorm_tmy_meta ):
294246 data , meta = pvlib .iotools .get_meteonorm_tmy (
295247 latitude = 50 , longitude = 10 ,
296248 api_key = demo_api_key ,
@@ -312,10 +264,11 @@ def test_get_meteonorm_tmy(
312264 assert meta .items () >= expected_meteonorm_tmy_meta .items ()
313265 for key in ['version' , 'commit' ]:
314266 assert key in meta # value changes, so only check presence
315- # meteonorm API only guarantees similar, not identical, results between
316- # calls. so we allow a small amount of variation with atol.
317- pd .testing .assert_frame_equal (data .iloc [:12 ], expected_meteonorm_tmy_data ,
318- check_exact = False , atol = 1 )
267+ # don't pin values: meteonorm may update the dataset without it being a
268+ # breaking change. check parsing instead.
269+ assert list (data .columns ) == ['diffuse_horizontal_irradiance' ]
270+ assert data .dtypes .map (pd .api .types .is_numeric_dtype ).all ()
271+ assert (data .isna ().mean () <= 0.2 ).all () # meteonorm guarantees <=20% NaN
319272
320273
321274@fail_on_pvlib_version ('0.16.0' )
0 commit comments