pvlib 0.11.2__py3-none-any.whl → 0.12.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pvlib/__init__.py +1 -0
- pvlib/atmosphere.py +0 -9
- pvlib/bifacial/infinite_sheds.py +4 -3
- pvlib/bifacial/utils.py +2 -1
- pvlib/iotools/psm3.py +1 -1
- pvlib/iotools/pvgis.py +10 -2
- pvlib/iotools/tmy.py +3 -69
- pvlib/irradiance.py +14 -0
- pvlib/location.py +73 -33
- pvlib/modelchain.py +18 -35
- pvlib/pvsystem.py +7 -10
- pvlib/snow.py +64 -28
- pvlib/spectrum/__init__.py +0 -1
- pvlib/spectrum/irradiance.py +0 -63
- pvlib/spectrum/mismatch.py +3 -3
- pvlib/tools.py +6 -5
- {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/METADATA +5 -3
- pvlib-0.12.0.dist-info/RECORD +75 -0
- {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/WHEEL +1 -1
- pvlib/data/BIRD_08_16_2012.csv +0 -8761
- pvlib/data/BIRD_08_16_2012_patm.csv +0 -8761
- pvlib/data/Burlington, United States SolarAnywhere Time Series 2021 Lat_44_465 Lon_-73_205 TMY3 format.csv +0 -8762
- pvlib/data/Burlington, United States SolarAnywhere Time Series 20210101 to 20210103 Lat_44_4675 Lon_-73_2075 SA format.csv +0 -578
- pvlib/data/Burlington, United States SolarAnywhere Typical GHI Year Lat_44_465 Lon_-73_205 SA format.csv +0 -74
- pvlib/data/CPS SCH275KTL-DO-US-800-250kW_275kVA_1.OND +0 -146
- pvlib/data/CRNS0101-05-2019-AZ_Tucson_11_W.txt +0 -4
- pvlib/data/CRN_with_problems.txt +0 -3
- pvlib/data/ET-M772BH550GL.PAN +0 -75
- pvlib/data/NLD_Amsterdam062400_IWEC.epw +0 -8768
- pvlib/data/PVsyst_demo.csv +0 -10757
- pvlib/data/PVsyst_demo_model.csv +0 -3588
- pvlib/data/SRML-day-EUPO1801.txt +0 -1441
- pvlib/data/abq19056.dat +0 -6
- pvlib/data/bishop88_numerical_precision.csv +0 -101
- pvlib/data/bsrn-lr0100-pay0616.dat +0 -86901
- pvlib/data/bsrn-pay0616.dat.gz +0 -0
- pvlib/data/cams_mcclear_1min_verbose.csv +0 -60
- pvlib/data/cams_mcclear_monthly.csv +0 -42
- pvlib/data/cams_radiation_1min_verbose.csv +0 -72
- pvlib/data/cams_radiation_monthly.csv +0 -47
- pvlib/data/detect_clearsky_data.csv +0 -35
- pvlib/data/detect_clearsky_threshold_data.csv +0 -126
- pvlib/data/greensboro_kimber_soil_manwash.dat +0 -8761
- pvlib/data/greensboro_kimber_soil_nowash.dat +0 -8761
- pvlib/data/inverter_fit_snl_meas.csv +0 -127
- pvlib/data/inverter_fit_snl_sim.csv +0 -19
- pvlib/data/ivtools_numdiff.csv +0 -52
- pvlib/data/midc_20181014.txt +0 -1441
- pvlib/data/midc_raw_20181018.txt +0 -1441
- pvlib/data/midc_raw_short_header_20191115.txt +0 -1441
- pvlib/data/msn19056.dat +0 -6
- pvlib/data/precise_iv_curves1.json +0 -10251
- pvlib/data/precise_iv_curves2.json +0 -10251
- pvlib/data/precise_iv_curves_parameter_sets1.csv +0 -33
- pvlib/data/precise_iv_curves_parameter_sets2.csv +0 -33
- pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA2_10kWp_CIS_5_2a_2013_2014.json +0 -1
- pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA_30deg_0deg_2016_2016.csv +0 -35
- pvlib/data/pvgis_tmy_meta.json +0 -32
- pvlib/data/pvgis_tmy_test.csv +0 -8761
- pvlib/data/pvwatts_8760_rackmount.csv +0 -8779
- pvlib/data/pvwatts_8760_roofmount.csv +0 -8779
- pvlib/data/singleaxis_tracker_wslope.csv +0 -8761
- pvlib/data/spectrl2_example_spectra.csv +0 -123
- pvlib/data/surfrad-slv16001.dat +0 -1442
- pvlib/data/test_psm3_2017.csv +0 -17521
- pvlib/data/test_psm3_2019_5min.csv +0 -289
- pvlib/data/test_psm3_tmy-2017.csv +0 -8761
- pvlib/data/test_read_psm3.csv +0 -17523
- pvlib/data/test_read_pvgis_horizon.csv +0 -49
- pvlib/data/tmy_45.000_8.000_2005_2023.csv +0 -8789
- pvlib/data/tmy_45.000_8.000_2005_2023.epw +0 -8768
- pvlib/data/tmy_45.000_8.000_2005_2023.json +0 -1
- pvlib/data/tmy_45.000_8.000_2005_2023.txt +0 -8761
- pvlib/data/tmy_45.000_8.000_userhorizon.json +0 -1
- pvlib/spa_c_files/README.md +0 -81
- pvlib/spa_c_files/cspa_py.pxd +0 -43
- pvlib/spa_c_files/spa_py.pyx +0 -30
- pvlib/tests/__init__.py +0 -0
- pvlib/tests/bifacial/__init__.py +0 -0
- pvlib/tests/bifacial/test_infinite_sheds.py +0 -317
- pvlib/tests/bifacial/test_losses_models.py +0 -54
- pvlib/tests/bifacial/test_pvfactors.py +0 -82
- pvlib/tests/bifacial/test_utils.py +0 -192
- pvlib/tests/conftest.py +0 -476
- pvlib/tests/iotools/__init__.py +0 -0
- pvlib/tests/iotools/test_acis.py +0 -213
- pvlib/tests/iotools/test_bsrn.py +0 -131
- pvlib/tests/iotools/test_crn.py +0 -95
- pvlib/tests/iotools/test_epw.py +0 -23
- pvlib/tests/iotools/test_midc.py +0 -89
- pvlib/tests/iotools/test_panond.py +0 -32
- pvlib/tests/iotools/test_psm3.py +0 -198
- pvlib/tests/iotools/test_pvgis.py +0 -644
- pvlib/tests/iotools/test_sodapro.py +0 -298
- pvlib/tests/iotools/test_solaranywhere.py +0 -287
- pvlib/tests/iotools/test_solargis.py +0 -68
- pvlib/tests/iotools/test_solcast.py +0 -324
- pvlib/tests/iotools/test_solrad.py +0 -152
- pvlib/tests/iotools/test_srml.py +0 -124
- pvlib/tests/iotools/test_surfrad.py +0 -75
- pvlib/tests/iotools/test_tmy.py +0 -133
- pvlib/tests/ivtools/__init__.py +0 -0
- pvlib/tests/ivtools/test_sde.py +0 -230
- pvlib/tests/ivtools/test_sdm.py +0 -429
- pvlib/tests/ivtools/test_utils.py +0 -173
- pvlib/tests/spectrum/__init__.py +0 -0
- pvlib/tests/spectrum/conftest.py +0 -40
- pvlib/tests/spectrum/test_irradiance.py +0 -138
- pvlib/tests/spectrum/test_mismatch.py +0 -304
- pvlib/tests/spectrum/test_response.py +0 -124
- pvlib/tests/spectrum/test_spectrl2.py +0 -72
- pvlib/tests/test__deprecation.py +0 -97
- pvlib/tests/test_albedo.py +0 -84
- pvlib/tests/test_atmosphere.py +0 -351
- pvlib/tests/test_clearsky.py +0 -884
- pvlib/tests/test_conftest.py +0 -37
- pvlib/tests/test_iam.py +0 -555
- pvlib/tests/test_inverter.py +0 -213
- pvlib/tests/test_irradiance.py +0 -1487
- pvlib/tests/test_location.py +0 -356
- pvlib/tests/test_modelchain.py +0 -2020
- pvlib/tests/test_numerical_precision.py +0 -124
- pvlib/tests/test_pvarray.py +0 -71
- pvlib/tests/test_pvsystem.py +0 -2511
- pvlib/tests/test_scaling.py +0 -207
- pvlib/tests/test_shading.py +0 -391
- pvlib/tests/test_singlediode.py +0 -608
- pvlib/tests/test_snow.py +0 -212
- pvlib/tests/test_soiling.py +0 -230
- pvlib/tests/test_solarposition.py +0 -966
- pvlib/tests/test_spa.py +0 -454
- pvlib/tests/test_temperature.py +0 -470
- pvlib/tests/test_tools.py +0 -146
- pvlib/tests/test_tracking.py +0 -474
- pvlib/tests/test_transformer.py +0 -60
- pvlib-0.11.2.dist-info/RECORD +0 -191
- {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info/licenses}/AUTHORS.md +0 -0
- {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info/licenses}/LICENSE +0 -0
- {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/top_level.txt +0 -0
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
test iotools for sodapro
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import pandas as pd
|
|
6
|
-
import numpy as np
|
|
7
|
-
import requests
|
|
8
|
-
import pytest
|
|
9
|
-
|
|
10
|
-
from pvlib.iotools import sodapro
|
|
11
|
-
from ..conftest import DATA_DIR, assert_frame_equal
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
testfile_mcclear_verbose = DATA_DIR / 'cams_mcclear_1min_verbose.csv'
|
|
15
|
-
testfile_mcclear_monthly = DATA_DIR / 'cams_mcclear_monthly.csv'
|
|
16
|
-
testfile_radiation_verbose = DATA_DIR / 'cams_radiation_1min_verbose.csv'
|
|
17
|
-
testfile_radiation_monthly = DATA_DIR / 'cams_radiation_monthly.csv'
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
index_verbose = pd.date_range('2020-06-01 12', periods=4, freq='1min',
|
|
21
|
-
tz='UTC')
|
|
22
|
-
index_monthly = pd.date_range('2020-01-01', periods=4, freq='1M')
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
dtypes_mcclear_verbose = [
|
|
26
|
-
'object', 'float64', 'float64', 'float64', 'float64', 'float64', 'float64',
|
|
27
|
-
'float64', 'float64', 'float64', 'float64', 'float64', 'float64',
|
|
28
|
-
'float64', 'float64', 'float64', 'float64', 'float64', 'int64', 'float64',
|
|
29
|
-
'float64', 'float64', 'float64']
|
|
30
|
-
|
|
31
|
-
dtypes_mcclear = [
|
|
32
|
-
'object', 'float64', 'float64', 'float64', 'float64', 'float64']
|
|
33
|
-
|
|
34
|
-
dtypes_radiation_verbose = [
|
|
35
|
-
'object', 'float64', 'float64', 'float64', 'float64', 'float64', 'float64',
|
|
36
|
-
'float64', 'float64', 'float64', 'float64', 'float64', 'float64',
|
|
37
|
-
'float64', 'float64', 'float64', 'float64', 'float64', 'float64',
|
|
38
|
-
'float64', 'float64', 'float64', 'float64', 'int64', 'float64', 'float64',
|
|
39
|
-
'float64', 'float64', 'float64', 'int64', 'int64', 'float64', 'float64',
|
|
40
|
-
'float64', 'float64']
|
|
41
|
-
|
|
42
|
-
dtypes_radiation = [
|
|
43
|
-
'object', 'float64', 'float64', 'float64', 'float64', 'float64', 'float64',
|
|
44
|
-
'float64', 'float64', 'float64', 'float64']
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
columns_mcclear_verbose = [
|
|
48
|
-
'Observation period', 'ghi_extra', 'ghi_clear', 'bhi_clear',
|
|
49
|
-
'dhi_clear', 'dni_clear', 'solar_zenith', 'summer/winter split', 'tco3',
|
|
50
|
-
'tcwv', 'AOD BC', 'AOD DU', 'AOD SS', 'AOD OR', 'AOD SU', 'AOD NI',
|
|
51
|
-
'AOD AM', 'alpha', 'Aerosol type', 'fiso', 'fvol', 'fgeo', 'albedo']
|
|
52
|
-
|
|
53
|
-
columns_mcclear = [
|
|
54
|
-
'Observation period', 'ghi_extra', 'ghi_clear', 'bhi_clear', 'dhi_clear',
|
|
55
|
-
'dni_clear']
|
|
56
|
-
|
|
57
|
-
columns_radiation_verbose = [
|
|
58
|
-
'Observation period', 'ghi_extra', 'ghi_clear', 'bhi_clear', 'dhi_clear',
|
|
59
|
-
'dni_clear', 'ghi', 'bhi', 'dhi', 'dni', 'Reliability', 'solar_zenith',
|
|
60
|
-
'summer/winter split', 'tco3', 'tcwv', 'AOD BC', 'AOD DU', 'AOD SS',
|
|
61
|
-
'AOD OR', 'AOD SU', 'AOD NI', 'AOD AM', 'alpha', 'Aerosol type', 'fiso',
|
|
62
|
-
'fvol', 'fgeo', 'albedo', 'Cloud optical depth', 'Cloud coverage',
|
|
63
|
-
'Cloud type', 'GHI no corr', 'BHI no corr', 'DHI no corr', 'BNI no corr']
|
|
64
|
-
|
|
65
|
-
columns_radiation_verbose_unmapped = [
|
|
66
|
-
'Observation period', 'TOA', 'Clear sky GHI', 'Clear sky BHI',
|
|
67
|
-
'Clear sky DHI', 'Clear sky BNI', 'GHI', 'BHI', 'DHI', 'BNI',
|
|
68
|
-
'Reliability', 'sza', 'summer/winter split', 'tco3', 'tcwv', 'AOD BC',
|
|
69
|
-
'AOD DU', 'AOD SS', 'AOD OR', 'AOD SU', 'AOD NI', 'AOD AM', 'alpha',
|
|
70
|
-
'Aerosol type', 'fiso', 'fvol', 'fgeo', 'albedo', 'Cloud optical depth',
|
|
71
|
-
'Cloud coverage', 'Cloud type', 'GHI no corr', 'BHI no corr',
|
|
72
|
-
'DHI no corr', 'BNI no corr']
|
|
73
|
-
|
|
74
|
-
columns_radiation = [
|
|
75
|
-
'Observation period', 'ghi_extra', 'ghi_clear', 'bhi_clear', 'dhi_clear',
|
|
76
|
-
'dni_clear', 'ghi', 'bhi', 'dhi', 'dni', 'Reliability']
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
values_mcclear_verbose = np.array([
|
|
80
|
-
['2020-06-01T12:00:00.0/2020-06-01T12:01:00.0', 1084.194, 848.5020,
|
|
81
|
-
753.564, 94.938, 920.28, 35.0308, 0.9723, 341.0221, 17.7962, 0.0065,
|
|
82
|
-
0.0067, 0.0008, 0.0215, 0.0252, 0.0087, 0.0022, np.nan, -1, 0.1668,
|
|
83
|
-
0.0912, 0.0267, 0.1359],
|
|
84
|
-
['2020-06-01T12:01:00.0/2020-06-01T12:02:00.0', 1083.504, 847.866, 752.904,
|
|
85
|
-
94.962, 920.058, 35.0828, 0.9723, 341.0223, 17.802, 0.0065, 0.0067,
|
|
86
|
-
0.0008, 0.0215, 0.0253, 0.0087, 0.0022, np.nan, -1, 0.1668, 0.0912,
|
|
87
|
-
0.0267, 0.1359],
|
|
88
|
-
['2020-06-01T12:02:00.0/2020-06-01T12:03:00.0', 1082.802, 847.224, 752.232,
|
|
89
|
-
94.986, 919.836, 35.1357, 0.9723, 341.0224, 17.8079, 0.0065, 0.0067,
|
|
90
|
-
0.0008, 0.0216, 0.0253, 0.0087, 0.0022, np.nan, -1, 0.1668, 0.0912,
|
|
91
|
-
0.0267, 0.1359],
|
|
92
|
-
['2020-06-01T12:03:00.0/2020-06-01T12:04:00.0', 1082.088, 846.564, 751.554,
|
|
93
|
-
95.01, 919.614, 35.1896, 0.9723, 341.0226, 17.8137, 0.0065, 0.0067,
|
|
94
|
-
0.0008, 0.0217, 0.0253, 0.0087, 0.0022, np.nan, -1, 0.1668, 0.0912,
|
|
95
|
-
0.0267, 0.1359]])
|
|
96
|
-
|
|
97
|
-
values_mcclear_monthly = np.array([
|
|
98
|
-
['2020-01-01T00:00:00.0/2020-02-01T00:00:00.0', 67.4314, 39.5494,
|
|
99
|
-
26.1998, 13.3496, 142.1562],
|
|
100
|
-
['2020-02-01T00:00:00.0/2020-03-01T00:00:00.0', 131.2335, 84.7849,
|
|
101
|
-
58.3855, 26.3994, 202.4865],
|
|
102
|
-
['2020-03-01T00:00:00.0/2020-04-01T00:00:00.0', 232.3323, 163.176,
|
|
103
|
-
125.1675, 38.0085, 307.5254],
|
|
104
|
-
['2020-04-01T00:00:00.0/2020-05-01T00:00:00.0', 344.7431, 250.7585,
|
|
105
|
-
197.8757, 52.8829, 387.6707]])
|
|
106
|
-
|
|
107
|
-
values_radiation_verbose = np.array([
|
|
108
|
-
['2020-06-01T12:00:00.0/2020-06-01T12:01:00.0', 1084.194, 848.502, 753.564,
|
|
109
|
-
94.938, 920.28, 815.358, 702.342, 113.022, 857.724, 1.0, 35.0308, 0.9723,
|
|
110
|
-
341.0221, 17.7962, 0.0065, 0.0067, 0.0008, 0.0215, 0.0252, 0.0087, 0.0022,
|
|
111
|
-
np.nan, -1, 0.1668, 0.0912, 0.0267, 0.1359, 0.0, 0, 5, 848.502, 753.564,
|
|
112
|
-
94.938, 920.28],
|
|
113
|
-
['2020-06-01T12:01:00.0/2020-06-01T12:02:00.0', 1083.504, 847.866, 752.904,
|
|
114
|
-
94.962, 920.058, 814.806, 701.73, 113.076, 857.52, 1.0, 35.0828, 0.9723,
|
|
115
|
-
341.0223, 17.802, 0.0065, 0.0067, 0.0008, 0.0215, 0.0253, 0.0087, 0.0022,
|
|
116
|
-
np.nan, -1, 0.1668, 0.0912, 0.0267, 0.1359, 0.0, 0, 5, 847.866, 752.904,
|
|
117
|
-
94.962, 920.058],
|
|
118
|
-
['2020-06-01T12:02:00.0/2020-06-01T12:03:00.0', 1082.802, 847.224, 752.232,
|
|
119
|
-
94.986, 919.836, 814.182, 701.094, 113.088, 857.298, 1.0, 35.1357, 0.9723,
|
|
120
|
-
341.0224, 17.8079, 0.0065, 0.0067, 0.0008, 0.0216, 0.0253, 0.0087, 0.0022,
|
|
121
|
-
np.nan, -1, 0.1668, 0.0912, 0.0267, 0.1359, 0.0, 0, 5, 847.224, 752.232,
|
|
122
|
-
94.986, 919.836],
|
|
123
|
-
['2020-06-01T12:03:00.0/2020-06-01T12:04:00.0', 1082.088, 846.564, 751.554,
|
|
124
|
-
95.01, 919.614, 813.612, 700.464, 113.148, 857.094, 1.0, 35.1896, 0.9723,
|
|
125
|
-
341.0226, 17.8137, 0.0065, 0.0067, 0.0008, 0.0217, 0.0253, 0.0087, 0.0022,
|
|
126
|
-
np.nan, -1, 0.1668, 0.0912, 0.0267, 0.1359, 0.0, 0, 5, 846.564, 751.554,
|
|
127
|
-
95.01, 919.614]])
|
|
128
|
-
|
|
129
|
-
values_radiation_verbose_integrated = np.copy(values_radiation_verbose)
|
|
130
|
-
values_radiation_verbose_integrated[:, 1:10] = \
|
|
131
|
-
values_radiation_verbose_integrated[:, 1:10].astype(float)/60
|
|
132
|
-
values_radiation_verbose_integrated[:, 31:35] = \
|
|
133
|
-
values_radiation_verbose_integrated[:, 31:35].astype(float)/60
|
|
134
|
-
|
|
135
|
-
values_radiation_monthly = np.array([
|
|
136
|
-
['2020-01-01T00:00:00.0/2020-02-01T00:00:00.0', 67.4317, 39.5496,
|
|
137
|
-
26.2, 13.3496, 142.1567, 20.8763, 3.4526, 17.4357, 16.7595, 0.997],
|
|
138
|
-
['2020-02-01T00:00:00.0/2020-03-01T00:00:00.0', 131.2338, 84.7852,
|
|
139
|
-
58.3858, 26.3994, 202.4871, 47.5197, 13.984, 33.5512, 47.8541, 0.9956],
|
|
140
|
-
['2020-03-01T00:00:00.0/2020-04-01T00:00:00.0', 232.3325, 163.1762,
|
|
141
|
-
125.1677, 38.0085, 307.5256, 120.1659, 69.6217, 50.5653, 159.576, 0.9949],
|
|
142
|
-
['2020-04-01T00:00:00.0/2020-05-01T00:00:00.0', 344.7433, 250.7587,
|
|
143
|
-
197.8758, 52.8829, 387.6709, 196.7015, 123.2593, 73.5152, 233.9675,
|
|
144
|
-
0.9897]])
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
# @pytest.fixture
|
|
148
|
-
def generate_expected_dataframe(values, columns, index, dtypes):
|
|
149
|
-
"""Create dataframe from arrays of values, columns and index, in order to
|
|
150
|
-
use this dataframe to compare to.
|
|
151
|
-
"""
|
|
152
|
-
expected = pd.DataFrame(values, columns=columns, index=index)
|
|
153
|
-
expected.index.freq = None
|
|
154
|
-
for (col, _dtype) in zip(expected.columns, dtypes):
|
|
155
|
-
expected[col] = expected[col].astype(_dtype)
|
|
156
|
-
return expected
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
@pytest.mark.parametrize('testfile,index,columns,values,dtypes', [
|
|
160
|
-
(testfile_mcclear_verbose, index_verbose, columns_mcclear_verbose,
|
|
161
|
-
values_mcclear_verbose, dtypes_mcclear_verbose),
|
|
162
|
-
(testfile_mcclear_monthly, index_monthly, columns_mcclear,
|
|
163
|
-
values_mcclear_monthly, dtypes_mcclear),
|
|
164
|
-
(testfile_radiation_verbose, index_verbose, columns_radiation_verbose,
|
|
165
|
-
values_radiation_verbose, dtypes_radiation_verbose),
|
|
166
|
-
(testfile_radiation_monthly, index_monthly, columns_radiation,
|
|
167
|
-
values_radiation_monthly, dtypes_radiation)])
|
|
168
|
-
def test_read_cams(testfile, index, columns, values, dtypes):
|
|
169
|
-
expected = generate_expected_dataframe(values, columns, index, dtypes)
|
|
170
|
-
out, metadata = sodapro.read_cams(testfile, integrated=False,
|
|
171
|
-
map_variables=True)
|
|
172
|
-
assert_frame_equal(out, expected, check_less_precise=True)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
def test_read_cams_integrated_unmapped_label():
|
|
176
|
-
# Default label is 'left' for 1 minute time resolution, hence 1 minute is
|
|
177
|
-
# added for label='right'
|
|
178
|
-
expected = generate_expected_dataframe(
|
|
179
|
-
values_radiation_verbose_integrated,
|
|
180
|
-
columns_radiation_verbose_unmapped,
|
|
181
|
-
index_verbose+pd.Timedelta(minutes=1), dtypes=dtypes_radiation_verbose)
|
|
182
|
-
out, metadata = sodapro.read_cams(testfile_radiation_verbose,
|
|
183
|
-
integrated=True, label='right',
|
|
184
|
-
map_variables=False)
|
|
185
|
-
assert_frame_equal(out, expected, check_less_precise=True)
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def test_read_cams_metadata():
|
|
189
|
-
_, metadata = sodapro.read_cams(testfile_mcclear_monthly, integrated=False)
|
|
190
|
-
assert metadata['Time reference'] == 'Universal time (UT)'
|
|
191
|
-
assert metadata['noValue'] == 'nan'
|
|
192
|
-
assert metadata['latitude'] == 55.7906
|
|
193
|
-
assert metadata['longitude'] == 12.5251
|
|
194
|
-
assert metadata['altitude'] == 39.0
|
|
195
|
-
assert metadata['radiation_unit'] == 'W/m^2'
|
|
196
|
-
assert metadata['time_step'] == '1M'
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
@pytest.mark.parametrize('testfile,index,columns,values,dtypes,identifier', [
|
|
200
|
-
(testfile_mcclear_monthly, index_monthly, columns_mcclear,
|
|
201
|
-
values_mcclear_monthly, dtypes_mcclear, 'mcclear'),
|
|
202
|
-
(testfile_radiation_monthly, index_monthly, columns_radiation,
|
|
203
|
-
values_radiation_monthly, dtypes_radiation, 'cams_radiation')])
|
|
204
|
-
def test_get_cams(requests_mock, testfile, index, columns, values, dtypes,
|
|
205
|
-
identifier):
|
|
206
|
-
"""Test that get_cams generates the correct URI request and that parse_cams
|
|
207
|
-
is being called correctly"""
|
|
208
|
-
# Open local test file containing McClear mothly data
|
|
209
|
-
with open(testfile, 'r') as test_file:
|
|
210
|
-
mock_response = test_file.read()
|
|
211
|
-
# Specify the full URI of a specific example, this ensures that all of the
|
|
212
|
-
# inputs are passing on correctly
|
|
213
|
-
url_test_cams = f'https://api.soda-solardata.com/service/wps?DataInputs=latitude=55.7906;longitude=12.5251;altitude=80;date_begin=2020-01-01;date_end=2020-05-04;time_ref=UT;summarization=P01M;username=pvlib-admin%2540googlegroups.com;verbose=false&Service=WPS&Request=Execute&Identifier=get_{identifier}&version=1.0.0&RawDataOutput=irradiation' # noqa: E501
|
|
214
|
-
|
|
215
|
-
requests_mock.get(url_test_cams, text=mock_response,
|
|
216
|
-
headers={'Content-Type': 'application/csv'})
|
|
217
|
-
|
|
218
|
-
# Make API call - an error is raised if requested URI does not match
|
|
219
|
-
out, metadata = sodapro.get_cams(
|
|
220
|
-
start=pd.Timestamp('2020-01-01'),
|
|
221
|
-
end=pd.Timestamp('2020-05-04'),
|
|
222
|
-
latitude=55.7906,
|
|
223
|
-
longitude=12.5251,
|
|
224
|
-
email='pvlib-admin@googlegroups.com',
|
|
225
|
-
identifier=identifier,
|
|
226
|
-
altitude=80,
|
|
227
|
-
time_step='1M',
|
|
228
|
-
verbose=False,
|
|
229
|
-
integrated=False)
|
|
230
|
-
expected = generate_expected_dataframe(values, columns, index, dtypes)
|
|
231
|
-
assert_frame_equal(out, expected, check_less_precise=True)
|
|
232
|
-
|
|
233
|
-
# Test if Warning is raised if verbose mode is True and time_step != '1min'
|
|
234
|
-
with pytest.warns(UserWarning, match='Verbose mode only supports'):
|
|
235
|
-
_ = sodapro.get_cams(
|
|
236
|
-
start=pd.Timestamp('2020-01-01'),
|
|
237
|
-
end=pd.Timestamp('2020-05-04'),
|
|
238
|
-
latitude=55.7906,
|
|
239
|
-
longitude=12.5251,
|
|
240
|
-
email='pvlib-admin@googlegroups.com',
|
|
241
|
-
identifier=identifier,
|
|
242
|
-
altitude=80,
|
|
243
|
-
time_step='1M',
|
|
244
|
-
verbose=True)
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
def test_get_cams_bad_request(requests_mock):
|
|
248
|
-
"""Test that a the correct errors/warnings ares raised for invalid
|
|
249
|
-
requests inputs. Also tests if the specified server url gets used"""
|
|
250
|
-
|
|
251
|
-
# Subset of an xml file returned for errornous requests
|
|
252
|
-
mock_response_bad_text = """<?xml version="1.0" encoding="utf-8"?>
|
|
253
|
-
<ows:Exception exceptionCode="NoApplicableCode" locator="None">
|
|
254
|
-
<ows:ExceptionText>Failed to execute WPS process [get_mcclear]:
|
|
255
|
-
Please, register yourself at www.soda-pro.com
|
|
256
|
-
</ows:ExceptionText>"""
|
|
257
|
-
|
|
258
|
-
url_cams_bad_request = 'https://pro.soda-is.com/service/wps?DataInputs=latitude=55.7906;longitude=12.5251;altitude=-999;date_begin=2020-01-01;date_end=2020-05-04;time_ref=TST;summarization=PT01H;username=test%2540test.com;verbose=false&Service=WPS&Request=Execute&Identifier=get_mcclear&version=1.0.0&RawDataOutput=irradiation' # noqa: E501
|
|
259
|
-
|
|
260
|
-
requests_mock.get(url_cams_bad_request, status_code=400,
|
|
261
|
-
text=mock_response_bad_text)
|
|
262
|
-
|
|
263
|
-
# Test if HTTPError is raised if incorrect input is specified
|
|
264
|
-
# In the below example a non-registrered email is specified
|
|
265
|
-
with pytest.raises(requests.exceptions.HTTPError,
|
|
266
|
-
match='Failed to execute WPS process'):
|
|
267
|
-
_ = sodapro.get_cams(
|
|
268
|
-
start=pd.Timestamp('2020-01-01'),
|
|
269
|
-
end=pd.Timestamp('2020-05-04'),
|
|
270
|
-
latitude=55.7906,
|
|
271
|
-
longitude=12.5251,
|
|
272
|
-
email='test@test.com', # a non-registrered email
|
|
273
|
-
identifier='mcclear',
|
|
274
|
-
time_ref='TST',
|
|
275
|
-
verbose=False,
|
|
276
|
-
time_step='1h',
|
|
277
|
-
server='pro.soda-is.com')
|
|
278
|
-
# Test if value error is raised if incorrect identifier is specified
|
|
279
|
-
with pytest.raises(ValueError, match='Identifier must be either'):
|
|
280
|
-
_ = sodapro.get_cams(
|
|
281
|
-
start=pd.Timestamp('2020-01-01'),
|
|
282
|
-
end=pd.Timestamp('2020-05-04'),
|
|
283
|
-
latitude=55.7906,
|
|
284
|
-
longitude=12.5251,
|
|
285
|
-
email='test@test.com',
|
|
286
|
-
identifier='test', # incorrect identifier
|
|
287
|
-
server='pro.soda-is.com')
|
|
288
|
-
# Test if value error is raised if incorrect time step is specified
|
|
289
|
-
with pytest.raises(ValueError, match='Time step not recognized'):
|
|
290
|
-
_ = sodapro.get_cams(
|
|
291
|
-
start=pd.Timestamp('2020-01-01'),
|
|
292
|
-
end=pd.Timestamp('2020-05-04'),
|
|
293
|
-
latitude=55.7906,
|
|
294
|
-
longitude=12.5251,
|
|
295
|
-
email='test@test.com',
|
|
296
|
-
identifier='mcclear',
|
|
297
|
-
time_step='test', # incorrect time step
|
|
298
|
-
server='pro.soda-is.com')
|
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import pandas as pd
|
|
2
|
-
import pytest
|
|
3
|
-
import pvlib
|
|
4
|
-
import os
|
|
5
|
-
from ..conftest import (DATA_DIR, RERUNS, RERUNS_DELAY,
|
|
6
|
-
requires_solaranywhere_credentials)
|
|
7
|
-
|
|
8
|
-
# High spatial resolution and 5-min data, true dynamics enabled
|
|
9
|
-
TESTFILE_HIGH_RESOLUTION = DATA_DIR / 'Burlington, United States SolarAnywhere Time Series 20210101 to 20210103 Lat_44_4675 Lon_-73_2075 SA format.csv' # noqa: E501
|
|
10
|
-
# TGY test file (v3.6) containing GHI/DHI and temperature.
|
|
11
|
-
# Note, the test file only contains the first three days.
|
|
12
|
-
TESTFILE_TMY = DATA_DIR / 'Burlington, United States SolarAnywhere Typical GHI Year Lat_44_465 Lon_-73_205 SA format.csv' # noqa: E501
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@pytest.fixture(scope="module")
|
|
16
|
-
def solaranywhere_api_key():
|
|
17
|
-
"""Supplies the pvlib's SolarAnywhere API key for testing purposes.
|
|
18
|
-
Users can freely register for an API key."""
|
|
19
|
-
solaranywhere_api_key = os.environ["SOLARANYWHERE_API_KEY"]
|
|
20
|
-
return solaranywhere_api_key
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@pytest.fixture
|
|
24
|
-
def high_resolution_index():
|
|
25
|
-
index = pd.date_range(start='2021-01-01 00:05-0500',
|
|
26
|
-
end='2021-01-03 00:00-0500', freq='5min')
|
|
27
|
-
index.name = 'ObservationTime'
|
|
28
|
-
return index
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@pytest.fixture
|
|
32
|
-
def tmy_index():
|
|
33
|
-
index = pd.date_range(
|
|
34
|
-
start='2000-01-01 01:00-0500', periods=3*24, freq='1h')
|
|
35
|
-
index.name = 'ObservationTime'
|
|
36
|
-
index.freq = None
|
|
37
|
-
return index
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@pytest.fixture
|
|
41
|
-
def tmy_ghi_series(tmy_index):
|
|
42
|
-
ghi = [
|
|
43
|
-
0, 0, 0, 0, 0, 0, 0, 3, 50, 171, 234, 220, 202, 122, 141, 65, 2, 0, 0,
|
|
44
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 48, 105, 161, 135, 108, 72, 58,
|
|
45
|
-
33, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 47, 124, 99, 116,
|
|
46
|
-
130, 165, 110, 36, 1, 0, 0, 0, 0, 0, 0, 0
|
|
47
|
-
]
|
|
48
|
-
return pd.Series(data=ghi, index=tmy_index, name='ghi')
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def test_read_solaranywhere_high_resolution(high_resolution_index):
|
|
52
|
-
data, meta = pvlib.iotools.read_solaranywhere(TESTFILE_HIGH_RESOLUTION,
|
|
53
|
-
map_variables=False)
|
|
54
|
-
# Check that metadata is parsed correctly
|
|
55
|
-
assert meta['latitude'] == 44.4675
|
|
56
|
-
assert meta['longitude'] == -73.2075
|
|
57
|
-
assert meta['altitude'] == 41.0
|
|
58
|
-
assert meta['name'] == 'Burlington United States'
|
|
59
|
-
assert meta['TZ'] == -5.0
|
|
60
|
-
assert meta['Data Version'] == '3.6'
|
|
61
|
-
assert meta['LatLon Resolution'] == 0.005
|
|
62
|
-
# Check that columns are parsed correctly
|
|
63
|
-
assert 'Albedo' in data.columns
|
|
64
|
-
assert 'Global Horizontal Irradiance (GHI) W/m2' in data.columns
|
|
65
|
-
assert 'Direct Normal Irradiance (DNI) W/m2' in data.columns
|
|
66
|
-
assert 'WindSpeed (m/s)' in data.columns
|
|
67
|
-
assert 'WindSpeedObservationType' in data.columns
|
|
68
|
-
assert 'Particulate Matter 10 (µg/m3)' in data.columns
|
|
69
|
-
# Check that data is parsed correctly
|
|
70
|
-
assert data.loc['2021-01-01 07:00:00-05:00', 'Albedo'] == 0.6
|
|
71
|
-
assert data.loc['2021-01-01 07:00:00-05:00', 'WindSpeed (m/s)'] == 0
|
|
72
|
-
# Assert that the index is parsed correctly
|
|
73
|
-
pd.testing.assert_index_equal(data.index, high_resolution_index)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def test_read_solaranywhere_map_variables():
|
|
77
|
-
# Check that variables are mapped by default to pvlib names
|
|
78
|
-
data, meta = pvlib.iotools.read_solaranywhere(TESTFILE_HIGH_RESOLUTION)
|
|
79
|
-
mapped_column_names = ['ghi', 'dni', 'dhi', 'temp_air', 'wind_speed',
|
|
80
|
-
'relative_humidity', 'ghi_clear', 'dni_clear',
|
|
81
|
-
'dhi_clear', 'albedo']
|
|
82
|
-
for c in mapped_column_names:
|
|
83
|
-
assert c in data.columns
|
|
84
|
-
assert meta['latitude'] == 44.4675
|
|
85
|
-
assert meta['longitude'] == -73.2075
|
|
86
|
-
assert meta['altitude'] == 41.0
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def test_read_solaranywhere_tmy(tmy_index, tmy_ghi_series):
|
|
90
|
-
# Check that TMY files are correctly parsed
|
|
91
|
-
data, meta = pvlib.iotools.read_solaranywhere(TESTFILE_TMY)
|
|
92
|
-
# Check that columns names are correct and mapped to pvlib names
|
|
93
|
-
assert 'ghi' in data.columns
|
|
94
|
-
assert 'dni' in data.columns
|
|
95
|
-
assert 'dhi' in data.columns
|
|
96
|
-
assert 'temp_air' in data.columns
|
|
97
|
-
# Check that metadata is parsed correctly
|
|
98
|
-
assert meta['latitude'] == 44.465
|
|
99
|
-
assert meta['longitude'] == -73.205
|
|
100
|
-
assert meta['altitude'] == 41.0
|
|
101
|
-
assert meta['name'] == 'Burlington United States'
|
|
102
|
-
assert meta['TZ'] == -5.0
|
|
103
|
-
assert meta['Data Version'] == '3.6'
|
|
104
|
-
assert meta['LatLon Resolution'] == 0.010
|
|
105
|
-
assert meta['Time Resolution'] == '60 minutes'
|
|
106
|
-
# Assert that the index is parsed correctly
|
|
107
|
-
pd.testing.assert_index_equal(data.index, tmy_index)
|
|
108
|
-
# Test one column
|
|
109
|
-
pd.testing.assert_series_equal(data['ghi'], tmy_ghi_series)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
@pytest.mark.remote_data
|
|
113
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
114
|
-
def test_get_solaranywhere_bad_probability_of_exceedance():
|
|
115
|
-
# Test if ValueError is raised if probability_of_exceedance is not integer
|
|
116
|
-
with pytest.raises(ValueError, match="must be an integer"):
|
|
117
|
-
pvlib.iotools.get_solaranywhere(
|
|
118
|
-
latitude=44, longitude=-73, api_key='empty',
|
|
119
|
-
source='SolarAnywherePOELatest', probability_of_exceedance=0.5)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
@pytest.mark.remote_data
|
|
123
|
-
@requires_solaranywhere_credentials
|
|
124
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
125
|
-
def test_get_solaranywhere_missing_start_end(solaranywhere_api_key):
|
|
126
|
-
# Test if ValueError is raised if start/end is missing for non-TMY request
|
|
127
|
-
with pytest.raises(ValueError, match="simulation start and end time"):
|
|
128
|
-
pvlib.iotools.get_solaranywhere(
|
|
129
|
-
latitude=44, longitude=-73, api_key=solaranywhere_api_key,
|
|
130
|
-
source='SolarAnywhereLatest')
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
@pytest.fixture
|
|
134
|
-
def time_series_index():
|
|
135
|
-
index = pd.date_range(start='2019-12-31 19:02:30-05:00', periods=288,
|
|
136
|
-
freq='5min')
|
|
137
|
-
index.name = 'ObservationTime'
|
|
138
|
-
index.freq = None
|
|
139
|
-
return index
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
@pytest.fixture
|
|
143
|
-
def timeseries_temp_air(time_series_index):
|
|
144
|
-
temp_air = [
|
|
145
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
146
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
147
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
148
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
149
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
|
|
150
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
151
|
-
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
|
|
152
|
-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
|
|
153
|
-
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
154
|
-
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
155
|
-
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
156
|
-
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
|
|
157
|
-
]
|
|
158
|
-
return pd.Series(data=temp_air, index=time_series_index, name='temp_air')
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
@requires_solaranywhere_credentials
|
|
162
|
-
@pytest.mark.remote_data
|
|
163
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
164
|
-
def test_get_solaranywhere_no_timezone(
|
|
165
|
-
solaranywhere_api_key, time_series_index, timeseries_temp_air):
|
|
166
|
-
# Test if data can be retrieved. This test only retrieves one day of data
|
|
167
|
-
# to minimize the request time.
|
|
168
|
-
data, meta = pvlib.iotools.get_solaranywhere(
|
|
169
|
-
latitude=44.4675, longitude=-73.2075, api_key=solaranywhere_api_key,
|
|
170
|
-
# specify start/end without timezone information
|
|
171
|
-
start=pd.Timestamp(2020, 1, 1), end=pd.Timestamp(2020, 1, 2),
|
|
172
|
-
# test specific version of SolarAnywhere
|
|
173
|
-
source='SolarAnywhere3_6',
|
|
174
|
-
spatial_resolution=0.005, time_resolution=5, true_dynamics=True)
|
|
175
|
-
|
|
176
|
-
# Check metadata, including that true-dynamics is set
|
|
177
|
-
assert meta['WeatherSiteName'] == 'SolarAnywhere3_6'
|
|
178
|
-
assert meta['ApplyTrueDynamics'] is True
|
|
179
|
-
assert meta['time_resolution'] == 5
|
|
180
|
-
assert meta['spatial_resolution'] == 0.005
|
|
181
|
-
assert meta['latitude'] == 44.4675
|
|
182
|
-
assert meta['longitude'] == -73.2075
|
|
183
|
-
assert meta['altitude'] == 41.0
|
|
184
|
-
|
|
185
|
-
# Check that variables have been mapped (default convention)
|
|
186
|
-
assert 'StartTime' in data.columns
|
|
187
|
-
assert 'ObservationTime' in data.columns
|
|
188
|
-
assert 'EndTime' in data.columns
|
|
189
|
-
assert 'ghi' in data.columns
|
|
190
|
-
assert 'dni' in data.columns
|
|
191
|
-
assert 'dhi' in data.columns
|
|
192
|
-
assert 'temp_air' in data.columns
|
|
193
|
-
assert 'wind_speed' in data.columns
|
|
194
|
-
assert 'albedo' in data.columns
|
|
195
|
-
assert 'DataVersion' in data.columns
|
|
196
|
-
|
|
197
|
-
# Assert index (checks that time resolution is 5 min)
|
|
198
|
-
pd.testing.assert_index_equal(data.index, time_series_index)
|
|
199
|
-
# Test one column
|
|
200
|
-
pd.testing.assert_series_equal(data['temp_air'], timeseries_temp_air)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
@requires_solaranywhere_credentials
|
|
204
|
-
@pytest.mark.remote_data
|
|
205
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
206
|
-
def test_get_solaranywhere_other_options(
|
|
207
|
-
solaranywhere_api_key, time_series_index, timeseries_temp_air):
|
|
208
|
-
# Test if data can be retrieved. This test only retrieves one day of data
|
|
209
|
-
# to minimize the request time.
|
|
210
|
-
data, meta = pvlib.iotools.get_solaranywhere(
|
|
211
|
-
latitude=44.4675, longitude=-73.2075, api_key=solaranywhere_api_key,
|
|
212
|
-
# specify start/end as str with timezone information
|
|
213
|
-
start='2020-01-01 00:00:00+0000',
|
|
214
|
-
end='2020-01-02 00:00:00+0000',
|
|
215
|
-
# test specific version of SolarAnywhere
|
|
216
|
-
source='SolarAnywhere3_7',
|
|
217
|
-
# test fewer variables
|
|
218
|
-
variables=[
|
|
219
|
-
'ObservationTime',
|
|
220
|
-
'GlobalHorizontalIrradiance_WattsPerMeterSquared',
|
|
221
|
-
],
|
|
222
|
-
map_variables=False)
|
|
223
|
-
|
|
224
|
-
# Check metadata
|
|
225
|
-
assert meta['WeatherSiteName'] == 'SolarAnywhere3_7'
|
|
226
|
-
assert meta['ApplyTrueDynamics'] is False # default setting
|
|
227
|
-
assert meta['time_resolution'] == 60 # default resolution
|
|
228
|
-
assert meta['spatial_resolution'] == 0.01 # default resolution
|
|
229
|
-
assert meta['latitude'] == 44.4675
|
|
230
|
-
assert meta['longitude'] == -73.2075
|
|
231
|
-
assert meta['altitude'] == 41.0
|
|
232
|
-
|
|
233
|
-
# Check that variables have been mapped (default convention)
|
|
234
|
-
assert 'StartTime' not in data.columns
|
|
235
|
-
assert 'ObservationTime' in data.columns
|
|
236
|
-
assert 'EndTime' not in data.columns
|
|
237
|
-
# Check that ghi is not mapped
|
|
238
|
-
assert 'ghi' not in data.columns
|
|
239
|
-
assert 'GlobalHorizontalIrradiance_WattsPerMeterSquared' in data.columns
|
|
240
|
-
assert 'dni' not in data.columns
|
|
241
|
-
assert 'dhi' not in data.columns
|
|
242
|
-
assert 'temp_air' not in data.columns
|
|
243
|
-
assert 'wind_speed' not in data.columns
|
|
244
|
-
assert 'albedo' not in data.columns
|
|
245
|
-
assert 'DataVersion' not in data.columns
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
@requires_solaranywhere_credentials
|
|
249
|
-
@pytest.mark.remote_data
|
|
250
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
251
|
-
def test_get_solaranywhere_probability_exceedance_error(solaranywhere_api_key):
|
|
252
|
-
# Test if ValueError is raised when passing start/end to typical year
|
|
253
|
-
with pytest.raises(ValueError, match="start and end time must be null"):
|
|
254
|
-
data, meta = pvlib.iotools.get_solaranywhere(
|
|
255
|
-
latitude=44.4675, longitude=-73.2075,
|
|
256
|
-
api_key=solaranywhere_api_key,
|
|
257
|
-
# Probabiliy of exceedance year should not have start/end specified
|
|
258
|
-
start=pd.Timestamp('2020-01-01 00:00:00+0000'),
|
|
259
|
-
end=pd.Timestamp('2020-01-05 12:00:00+0000'),
|
|
260
|
-
source='SolarAnywherePOELatest',
|
|
261
|
-
probability_of_exceedance=20)
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
@requires_solaranywhere_credentials
|
|
265
|
-
@pytest.mark.remote_data
|
|
266
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
267
|
-
def test_get_solaranywhere_timeout_tgy(solaranywhere_api_key):
|
|
268
|
-
# Test if the service times out when the timeout parameter is close to zero
|
|
269
|
-
with pytest.raises(TimeoutError, match="Time exceeded"):
|
|
270
|
-
pvlib.iotools.get_solaranywhere(
|
|
271
|
-
latitude=44.4675, longitude=-73.2075,
|
|
272
|
-
api_key=solaranywhere_api_key,
|
|
273
|
-
source='SolarAnywhereTGYLatest',
|
|
274
|
-
timeout=0.00001)
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
@requires_solaranywhere_credentials
|
|
278
|
-
@pytest.mark.remote_data
|
|
279
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
280
|
-
def test_get_solaranywhere_not_available(solaranywhere_api_key):
|
|
281
|
-
# Test if RuntimeError is raised if location in the ocean is requested
|
|
282
|
-
with pytest.raises(RuntimeError, match="Tile is outside of our coverage"):
|
|
283
|
-
pvlib.iotools.get_solaranywhere(
|
|
284
|
-
latitude=40, longitude=-70,
|
|
285
|
-
api_key=solaranywhere_api_key,
|
|
286
|
-
start=pd.Timestamp('2020-01-01 00:00:00+0000'),
|
|
287
|
-
end=pd.Timestamp('2020-01-05 12:00:00+0000'))
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import pandas as pd
|
|
2
|
-
import pytest
|
|
3
|
-
import pvlib
|
|
4
|
-
import requests
|
|
5
|
-
from ..conftest import (RERUNS, RERUNS_DELAY, assert_frame_equal,
|
|
6
|
-
assert_index_equal)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@pytest.fixture
|
|
10
|
-
def hourly_index():
|
|
11
|
-
hourly_index = pd.date_range(start='2022-01-01 00:30+01:00', freq='60min',
|
|
12
|
-
periods=24, name='dateTime')
|
|
13
|
-
hourly_index.freq = None
|
|
14
|
-
return hourly_index
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@pytest.fixture
|
|
18
|
-
def hourly_index_start_utc():
|
|
19
|
-
hourly_index_left_utc = pd.date_range(
|
|
20
|
-
start='2023-01-01 00:00+00:00', freq='30min', periods=24*2,
|
|
21
|
-
name='dateTime')
|
|
22
|
-
hourly_index_left_utc.freq = None
|
|
23
|
-
return hourly_index_left_utc
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@pytest.fixture
|
|
27
|
-
def hourly_dataframe(hourly_index):
|
|
28
|
-
ghi = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 73.0, 152.0, 141.0, 105.0,
|
|
29
|
-
62.0, 65.0, 62.0, 11.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
|
30
|
-
dni = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 30.0, 233.0, 301.0, 136.0, 32.0,
|
|
31
|
-
0.0, 3.0, 77.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
|
32
|
-
return pd.DataFrame(data={'ghi': ghi, 'dni': dni}, index=hourly_index)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@pytest.mark.remote_data
|
|
36
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
37
|
-
def test_get_solargis(hourly_dataframe):
|
|
38
|
-
data, meta = pvlib.iotools.get_solargis(
|
|
39
|
-
latitude=48.61259, longitude=20.827079,
|
|
40
|
-
start='2022-01-01', end='2022-01-01',
|
|
41
|
-
tz='GMT+01', variables=['GHI', 'DNI'],
|
|
42
|
-
time_resolution='HOURLY', api_key='demo')
|
|
43
|
-
assert_frame_equal(data, hourly_dataframe)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@pytest.mark.remote_data
|
|
47
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
48
|
-
def test_get_solargis_utc_start_timestamp(hourly_index_start_utc):
|
|
49
|
-
data, meta = pvlib.iotools.get_solargis(
|
|
50
|
-
latitude=48.61259, longitude=20.827079,
|
|
51
|
-
start='2023-01-01', end='2023-01-01',
|
|
52
|
-
variables=['GTI'],
|
|
53
|
-
timestamp_type='start',
|
|
54
|
-
time_resolution='MIN_30',
|
|
55
|
-
map_variables=False, api_key='demo')
|
|
56
|
-
assert 'GTI' in data.columns # assert that variables aren't mapped
|
|
57
|
-
assert_index_equal(data.index, hourly_index_start_utc)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
@pytest.mark.remote_data
|
|
61
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
62
|
-
def test_get_solargis_http_error():
|
|
63
|
-
# Test if HTTPError is raised if date outside range is specified
|
|
64
|
-
with pytest.raises(requests.HTTPError, match="data coverage"):
|
|
65
|
-
_, _ = pvlib.iotools.get_solargis(
|
|
66
|
-
latitude=48.61259, longitude=20.827079,
|
|
67
|
-
start='1920-01-01', end='1920-01-01', # date outside range
|
|
68
|
-
variables=['GHI', 'DNI'], time_resolution='HOURLY', api_key='demo')
|