pvlib 0.12.1a1__py3-none-any.whl → 0.13.0a1__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/bifacial/infinite_sheds.py +11 -16
- pvlib/iotools/__init__.py +0 -1
- pvlib/iotools/bsrn.py +16 -10
- pvlib/iotools/epw.py +14 -11
- pvlib/iotools/psm3.py +37 -71
- pvlib/iotools/psm4.py +62 -115
- pvlib/iotools/pvgis.py +116 -101
- pvlib/iotools/sodapro.py +54 -69
- pvlib/iotools/srml.py +1 -2
- pvlib/ivtools/sdm/_fit_desoto_pvsyst_sandia.py +1 -1
- pvlib/pvsystem.py +21 -12
- pvlib/solarposition.py +1 -1
- pvlib/temperature.py +13 -10
- pvlib/tools.py +27 -0
- {pvlib-0.12.1a1.dist-info → pvlib-0.13.0a1.dist-info}/METADATA +1 -1
- {pvlib-0.12.1a1.dist-info → pvlib-0.13.0a1.dist-info}/RECORD +20 -20
- {pvlib-0.12.1a1.dist-info → pvlib-0.13.0a1.dist-info}/WHEEL +1 -1
- {pvlib-0.12.1a1.dist-info → pvlib-0.13.0a1.dist-info}/licenses/AUTHORS.md +0 -0
- {pvlib-0.12.1a1.dist-info → pvlib-0.13.0a1.dist-info}/licenses/LICENSE +0 -0
- {pvlib-0.12.1a1.dist-info → pvlib-0.13.0a1.dist-info}/top_level.txt +0 -0
pvlib/iotools/pvgis.py
CHANGED
|
@@ -21,7 +21,7 @@ import requests
|
|
|
21
21
|
import numpy as np
|
|
22
22
|
import pandas as pd
|
|
23
23
|
import pytz
|
|
24
|
-
from pvlib.iotools import read_epw
|
|
24
|
+
from pvlib.iotools import read_epw
|
|
25
25
|
|
|
26
26
|
URL = 'https://re.jrc.ec.europa.eu/api/'
|
|
27
27
|
|
|
@@ -57,6 +57,12 @@ def get_pvgis_hourly(latitude, longitude, start=None, end=None,
|
|
|
57
57
|
|
|
58
58
|
PVGIS data is freely available at [1]_.
|
|
59
59
|
|
|
60
|
+
.. versionchanged:: 0.13.0
|
|
61
|
+
The function now returns two items ``(data,meta)``. Previous
|
|
62
|
+
versions of this function returned three elements
|
|
63
|
+
``(data,inputs,meta)``. The ``inputs`` dictionary is now included in
|
|
64
|
+
``meta``, which has changed structure to accommodate it.
|
|
65
|
+
|
|
60
66
|
Parameters
|
|
61
67
|
----------
|
|
62
68
|
latitude: float
|
|
@@ -130,8 +136,6 @@ def get_pvgis_hourly(latitude, longitude, start=None, end=None,
|
|
|
130
136
|
-------
|
|
131
137
|
data : pandas.DataFrame
|
|
132
138
|
Time-series of hourly data, see Notes for fields
|
|
133
|
-
inputs : dict
|
|
134
|
-
Dictionary of the request input parameters
|
|
135
139
|
metadata : dict
|
|
136
140
|
Dictionary containing metadata
|
|
137
141
|
|
|
@@ -189,7 +193,7 @@ def get_pvgis_hourly(latitude, longitude, start=None, end=None,
|
|
|
189
193
|
Examples
|
|
190
194
|
--------
|
|
191
195
|
>>> # Retrieve two years of irradiance data from PVGIS:
|
|
192
|
-
>>> data, meta
|
|
196
|
+
>>> data, meta = pvlib.iotools.get_pvgis_hourly( # doctest: +SKIP
|
|
193
197
|
>>> latitude=45, longitude=8, start=2015, end=2016) # doctest: +SKIP
|
|
194
198
|
|
|
195
199
|
References
|
|
@@ -241,28 +245,33 @@ def get_pvgis_hourly(latitude, longitude, start=None, end=None,
|
|
|
241
245
|
|
|
242
246
|
|
|
243
247
|
def _parse_pvgis_hourly_json(src, map_variables):
|
|
244
|
-
|
|
245
|
-
|
|
248
|
+
metadata = src['meta'].copy()
|
|
249
|
+
# Override the "inputs" in metadata
|
|
250
|
+
metadata['inputs'] = src['inputs']
|
|
251
|
+
# Re-add the inputs in metadata one-layer down
|
|
252
|
+
metadata['inputs']['descriptions'] = src['meta']['inputs']
|
|
246
253
|
data = pd.DataFrame(src['outputs']['hourly'])
|
|
247
254
|
data.index = pd.to_datetime(data['time'], format='%Y%m%d:%H%M', utc=True)
|
|
248
255
|
data = data.drop('time', axis=1)
|
|
249
256
|
data = data.astype(dtype={'Int': 'int'}) # The 'Int' column to be integer
|
|
250
257
|
if map_variables:
|
|
251
258
|
data = data.rename(columns=VARIABLE_MAP)
|
|
252
|
-
return data,
|
|
259
|
+
return data, metadata
|
|
253
260
|
|
|
254
261
|
|
|
255
262
|
def _parse_pvgis_hourly_csv(src, map_variables):
|
|
256
263
|
# The first 4 rows are latitude, longitude, elevation, radiation database
|
|
257
|
-
|
|
264
|
+
metadata = {'inputs': {}, 'descriptions': {}}
|
|
265
|
+
# 'location' metadata
|
|
258
266
|
# 'Latitude (decimal degrees): 45.000\r\n'
|
|
259
|
-
inputs['latitude'] = float(src.readline().split(':')[1])
|
|
267
|
+
metadata['inputs']['latitude'] = float(src.readline().split(':')[1])
|
|
260
268
|
# 'Longitude (decimal degrees): 8.000\r\n'
|
|
261
|
-
inputs['longitude'] = float(src.readline().split(':')[1])
|
|
269
|
+
metadata['inputs']['longitude'] = float(src.readline().split(':')[1])
|
|
262
270
|
# Elevation (m): 1389.0\r\n
|
|
263
|
-
inputs['elevation'] = float(src.readline().split(':')[1])
|
|
271
|
+
metadata['inputs']['elevation'] = float(src.readline().split(':')[1])
|
|
264
272
|
# 'Radiation database: \tPVGIS-SARAH\r\n'
|
|
265
|
-
inputs['radiation_database'] =
|
|
273
|
+
metadata['inputs']['radiation_database'] = \
|
|
274
|
+
src.readline().split(':')[1].strip()
|
|
266
275
|
# Parse through the remaining metadata section (the number of lines for
|
|
267
276
|
# this section depends on the requested parameters)
|
|
268
277
|
while True:
|
|
@@ -273,7 +282,7 @@ def _parse_pvgis_hourly_csv(src, map_variables):
|
|
|
273
282
|
break
|
|
274
283
|
# Only retrieve metadata from non-empty lines
|
|
275
284
|
elif line.strip() != '':
|
|
276
|
-
inputs[line.split(':')[0]] = line.split(':')[1].strip()
|
|
285
|
+
metadata['inputs'][line.split(':')[0]] = line.split(':')[1].strip()
|
|
277
286
|
elif line == '': # If end of file is reached
|
|
278
287
|
raise ValueError('No data section was detected. File has probably '
|
|
279
288
|
'been modified since being downloaded from PVGIS')
|
|
@@ -295,16 +304,23 @@ def _parse_pvgis_hourly_csv(src, map_variables):
|
|
|
295
304
|
# integer. It is necessary to convert to float, before converting to int
|
|
296
305
|
data = data.astype(float).astype(dtype={'Int': 'int'})
|
|
297
306
|
# Generate metadata dictionary containing description of parameters
|
|
298
|
-
metadata = {}
|
|
307
|
+
metadata['descriptions'] = {}
|
|
299
308
|
for line in src.readlines():
|
|
300
309
|
if ':' in line:
|
|
301
|
-
metadata[line.split(':')[0]] =
|
|
302
|
-
|
|
310
|
+
metadata['descriptions'][line.split(':')[0]] = \
|
|
311
|
+
line.split(':')[1].strip()
|
|
312
|
+
return data, metadata
|
|
303
313
|
|
|
304
314
|
|
|
305
315
|
def read_pvgis_hourly(filename, pvgis_format=None, map_variables=True):
|
|
306
316
|
"""Read a PVGIS hourly file.
|
|
307
317
|
|
|
318
|
+
.. versionchanged:: 0.13.0
|
|
319
|
+
The function now returns two items ``(data,meta)``. Previous
|
|
320
|
+
versions of this function returned three elements
|
|
321
|
+
``(data,inputs,meta)``. The ``inputs`` dictionary is now included in
|
|
322
|
+
``meta``, which has changed structure to accommodate it.
|
|
323
|
+
|
|
308
324
|
Parameters
|
|
309
325
|
----------
|
|
310
326
|
filename : str, pathlib.Path, or file-like buffer
|
|
@@ -323,8 +339,6 @@ def read_pvgis_hourly(filename, pvgis_format=None, map_variables=True):
|
|
|
323
339
|
-------
|
|
324
340
|
data : pandas.DataFrame
|
|
325
341
|
the time series data
|
|
326
|
-
inputs : dict
|
|
327
|
-
the inputs
|
|
328
342
|
metadata : dict
|
|
329
343
|
metadata
|
|
330
344
|
|
|
@@ -373,7 +387,7 @@ def read_pvgis_hourly(filename, pvgis_format=None, map_variables=True):
|
|
|
373
387
|
return _parse_pvgis_hourly_json(src, map_variables=map_variables)
|
|
374
388
|
|
|
375
389
|
# CSV: use _parse_pvgis_hourly_csv()
|
|
376
|
-
|
|
390
|
+
elif outputformat == 'csv':
|
|
377
391
|
try:
|
|
378
392
|
pvgis_data = _parse_pvgis_hourly_csv(
|
|
379
393
|
filename, map_variables=map_variables)
|
|
@@ -383,11 +397,12 @@ def read_pvgis_hourly(filename, pvgis_format=None, map_variables=True):
|
|
|
383
397
|
fbuf, map_variables=map_variables)
|
|
384
398
|
return pvgis_data
|
|
385
399
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
400
|
+
else:
|
|
401
|
+
# raise exception if pvgis format isn't in ['csv', 'json']
|
|
402
|
+
err_msg = (
|
|
403
|
+
"pvgis format '{:s}' was unknown, must be either 'json' or 'csv'")\
|
|
404
|
+
.format(outputformat)
|
|
405
|
+
raise ValueError(err_msg)
|
|
391
406
|
|
|
392
407
|
|
|
393
408
|
def _coerce_and_roll_tmy(tmy_data, tz, year):
|
|
@@ -410,18 +425,28 @@ def _coerce_and_roll_tmy(tmy_data, tz, year):
|
|
|
410
425
|
np.roll(tmy_data, tz, axis=0),
|
|
411
426
|
columns=tmy_data.columns,
|
|
412
427
|
index=new_index)
|
|
428
|
+
# GH 2399
|
|
429
|
+
new_tmy_data = \
|
|
430
|
+
new_tmy_data.astype(dtype=dict(zip(tmy_data.columns, tmy_data.dtypes)))
|
|
413
431
|
return new_tmy_data
|
|
414
432
|
|
|
415
433
|
|
|
416
434
|
def get_pvgis_tmy(latitude, longitude, outputformat='json', usehorizon=True,
|
|
417
435
|
userhorizon=None, startyear=None, endyear=None,
|
|
418
436
|
map_variables=True, url=URL, timeout=30,
|
|
419
|
-
roll_utc_offset=None, coerce_year=
|
|
437
|
+
roll_utc_offset=None, coerce_year=1990):
|
|
420
438
|
"""
|
|
421
439
|
Get TMY data from PVGIS.
|
|
422
440
|
|
|
423
441
|
For more information see the PVGIS [1]_ TMY tool documentation [2]_.
|
|
424
442
|
|
|
443
|
+
.. versionchanged:: 0.13.0
|
|
444
|
+
The function now returns two items ``(data,meta)``. Previous
|
|
445
|
+
versions of this function returned four elements
|
|
446
|
+
``(data,months_selected,inputs,meta)``. The ``inputs`` dictionary
|
|
447
|
+
and ``months_selected`` are now included in ``meta``, which has
|
|
448
|
+
changed structure to accommodate it.
|
|
449
|
+
|
|
425
450
|
Parameters
|
|
426
451
|
----------
|
|
427
452
|
latitude : float
|
|
@@ -429,7 +454,7 @@ def get_pvgis_tmy(latitude, longitude, outputformat='json', usehorizon=True,
|
|
|
429
454
|
longitude : float
|
|
430
455
|
Longitude in degrees east
|
|
431
456
|
outputformat : str, default 'json'
|
|
432
|
-
Must be in ``['csv', '
|
|
457
|
+
Must be in ``['csv', 'epw', 'json']``. See PVGIS TMY tool
|
|
433
458
|
documentation [2]_ for more info.
|
|
434
459
|
usehorizon : bool, default True
|
|
435
460
|
include effects of horizon
|
|
@@ -452,20 +477,18 @@ def get_pvgis_tmy(latitude, longitude, outputformat='json', usehorizon=True,
|
|
|
452
477
|
Use to specify a time zone other than the default UTC zero and roll
|
|
453
478
|
dataframe by ``roll_utc_offset`` so it starts at midnight on January
|
|
454
479
|
1st. Ignored if ``None``, otherwise will force year to ``coerce_year``.
|
|
455
|
-
coerce_year: int,
|
|
456
|
-
Use to force indices to desired year.
|
|
457
|
-
``
|
|
480
|
+
coerce_year: int, default 1990
|
|
481
|
+
Use to force indices to desired year. Defaults to 1990. Specify
|
|
482
|
+
``None`` to return the actual indices used for the TMY. If
|
|
483
|
+
``coerce_year`` is ``None``, but ``roll_utc_offset`` is specified,
|
|
484
|
+
then ``coerce_year`` will be set to the default.
|
|
458
485
|
|
|
459
486
|
Returns
|
|
460
487
|
-------
|
|
461
488
|
data : pandas.DataFrame
|
|
462
489
|
the weather data
|
|
463
|
-
months_selected : list
|
|
464
|
-
TMY year for each month, ``None`` for basic and EPW
|
|
465
|
-
inputs : dict
|
|
466
|
-
the inputs, ``None`` for basic and EPW
|
|
467
490
|
metadata : list or dict
|
|
468
|
-
file metadata
|
|
491
|
+
file metadata
|
|
469
492
|
|
|
470
493
|
Raises
|
|
471
494
|
------
|
|
@@ -509,24 +532,20 @@ def get_pvgis_tmy(latitude, longitude, outputformat='json', usehorizon=True,
|
|
|
509
532
|
else:
|
|
510
533
|
raise requests.HTTPError(err_msg['message'])
|
|
511
534
|
# initialize data to None in case API fails to respond to bad outputformat
|
|
512
|
-
data = None, None
|
|
535
|
+
data = None, None
|
|
513
536
|
if outputformat == 'json':
|
|
514
537
|
src = res.json()
|
|
515
|
-
data,
|
|
538
|
+
data, meta = _parse_pvgis_tmy_json(src)
|
|
516
539
|
elif outputformat == 'csv':
|
|
517
540
|
with io.BytesIO(res.content) as src:
|
|
518
|
-
data,
|
|
519
|
-
elif outputformat == 'basic':
|
|
520
|
-
with io.BytesIO(res.content) as src:
|
|
521
|
-
data, months_selected, inputs, meta = _parse_pvgis_tmy_basic(src)
|
|
541
|
+
data, meta = _parse_pvgis_tmy_csv(src)
|
|
522
542
|
elif outputformat == 'epw':
|
|
523
543
|
with io.StringIO(res.content.decode('utf-8')) as src:
|
|
524
|
-
data, meta =
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
pass
|
|
544
|
+
data, meta = read_epw(src)
|
|
545
|
+
elif outputformat == 'basic':
|
|
546
|
+
err_msg = ("outputformat='basic' is no longer supported by pvlib, "
|
|
547
|
+
"please use outputformat='csv' instead.")
|
|
548
|
+
raise ValueError(err_msg)
|
|
530
549
|
|
|
531
550
|
if map_variables:
|
|
532
551
|
data = data.rename(columns=VARIABLE_MAP)
|
|
@@ -536,34 +555,37 @@ def get_pvgis_tmy(latitude, longitude, outputformat='json', usehorizon=True,
|
|
|
536
555
|
coerce_year = coerce_year or 1990
|
|
537
556
|
data = _coerce_and_roll_tmy(data, roll_utc_offset, coerce_year)
|
|
538
557
|
|
|
539
|
-
return data,
|
|
558
|
+
return data, meta
|
|
540
559
|
|
|
541
560
|
|
|
542
561
|
def _parse_pvgis_tmy_json(src):
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
562
|
+
meta = src['meta'].copy()
|
|
563
|
+
# Override the "inputs" in metadata
|
|
564
|
+
meta['inputs'] = src['inputs']
|
|
565
|
+
# Re-add the inputs in metadata one-layer down
|
|
566
|
+
meta['inputs']['descriptions'] = src['meta']['inputs']
|
|
567
|
+
meta['months_selected'] = src['outputs']['months_selected']
|
|
546
568
|
data = pd.DataFrame(src['outputs']['tmy_hourly'])
|
|
547
569
|
data.index = pd.to_datetime(
|
|
548
570
|
data['time(UTC)'], format='%Y%m%d:%H%M', utc=True)
|
|
549
571
|
data = data.drop('time(UTC)', axis=1)
|
|
550
|
-
return data,
|
|
572
|
+
return data, meta
|
|
551
573
|
|
|
552
574
|
|
|
553
575
|
def _parse_pvgis_tmy_csv(src):
|
|
554
576
|
# the first 3 rows are latitude, longitude, elevation
|
|
555
|
-
|
|
577
|
+
meta = {'inputs': {}, 'descriptions': {}}
|
|
556
578
|
# 'Latitude (decimal degrees): 45.000\r\n'
|
|
557
|
-
inputs['latitude'] = float(src.readline().split(b':')[1])
|
|
579
|
+
meta['inputs']['latitude'] = float(src.readline().split(b':')[1])
|
|
558
580
|
# 'Longitude (decimal degrees): 8.000\r\n'
|
|
559
|
-
inputs['longitude'] = float(src.readline().split(b':')[1])
|
|
581
|
+
meta['inputs']['longitude'] = float(src.readline().split(b':')[1])
|
|
560
582
|
# Elevation (m): 1389.0\r\n
|
|
561
|
-
inputs['elevation'] = float(src.readline().split(b':')[1])
|
|
583
|
+
meta['inputs']['elevation'] = float(src.readline().split(b':')[1])
|
|
562
584
|
|
|
563
585
|
# TMY has an extra line here: Irradiance Time Offset (h): 0.1761\r\n
|
|
564
586
|
line = src.readline()
|
|
565
587
|
if line.startswith(b'Irradiance Time Offset'):
|
|
566
|
-
inputs['irradiance time offset'] = float(line.split(b':')[1])
|
|
588
|
+
meta['inputs']['irradiance time offset'] = float(line.split(b':')[1])
|
|
567
589
|
src.readline() # skip over the "month,year\r\n"
|
|
568
590
|
else:
|
|
569
591
|
# `line` is already the "month,year\r\n" line, so nothing to do
|
|
@@ -574,6 +596,7 @@ def _parse_pvgis_tmy_csv(src):
|
|
|
574
596
|
for month in range(12):
|
|
575
597
|
months_selected.append(
|
|
576
598
|
{'month': month+1, 'year': int(src.readline().split(b',')[1])})
|
|
599
|
+
meta['months_selected'] = months_selected
|
|
577
600
|
# then there's the TMY (typical meteorological year) data
|
|
578
601
|
# first there's a header row:
|
|
579
602
|
# time(UTC),T2m,RH,G(h),Gb(n),Gd(h),IR(h),WS10m,WD10m,SP
|
|
@@ -586,21 +609,25 @@ def _parse_pvgis_tmy_csv(src):
|
|
|
586
609
|
data = pd.DataFrame(data, dtype=float)
|
|
587
610
|
data.index = dtidx
|
|
588
611
|
# finally there's some meta data
|
|
589
|
-
meta
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
data
|
|
596
|
-
data['time(UTC)'], format='%Y%m%d:%H%M', utc=True)
|
|
597
|
-
data = data.drop('time(UTC)', axis=1)
|
|
598
|
-
return data, None, None, None
|
|
612
|
+
meta['descriptions'] = {}
|
|
613
|
+
for line in src.readlines():
|
|
614
|
+
line = line.decode('utf-8').strip()
|
|
615
|
+
if ':' in line:
|
|
616
|
+
meta['descriptions'][line.split(':')[0]] = \
|
|
617
|
+
line.split(':')[1].strip()
|
|
618
|
+
return data, meta
|
|
599
619
|
|
|
600
620
|
|
|
601
621
|
def read_pvgis_tmy(filename, pvgis_format=None, map_variables=True):
|
|
602
622
|
"""
|
|
603
|
-
Read a file downloaded from PVGIS.
|
|
623
|
+
Read a TMY file downloaded from PVGIS.
|
|
624
|
+
|
|
625
|
+
.. versionchanged:: 0.13.0
|
|
626
|
+
The function now returns two items ``(data,meta)``. Previous
|
|
627
|
+
versions of this function returned four elements
|
|
628
|
+
``(data,months_selected,inputs,meta)``. The ``inputs`` dictionary
|
|
629
|
+
and ``months_selected`` are now included in ``meta``, which has
|
|
630
|
+
changed structure to accommodate it.
|
|
604
631
|
|
|
605
632
|
Parameters
|
|
606
633
|
----------
|
|
@@ -610,11 +637,9 @@ def read_pvgis_tmy(filename, pvgis_format=None, map_variables=True):
|
|
|
610
637
|
Format of PVGIS file or buffer. Equivalent to the ``outputformat``
|
|
611
638
|
parameter in the PVGIS TMY API. If ``filename`` is a file and
|
|
612
639
|
``pvgis_format`` is not specified then the file extension will be used
|
|
613
|
-
to determine the PVGIS format to parse.
|
|
614
|
-
with ``outputformat='basic'``, please set ``pvgis_format`` to
|
|
615
|
-
``'basic'``.
|
|
640
|
+
to determine the PVGIS format to parse.
|
|
616
641
|
If ``filename`` is a buffer, then ``pvgis_format`` is required and must
|
|
617
|
-
be in ``['csv', 'epw', 'json'
|
|
642
|
+
be in ``['csv', 'epw', 'json']``.
|
|
618
643
|
map_variables: bool, default True
|
|
619
644
|
When true, renames columns of the Dataframe to pvlib variable names
|
|
620
645
|
where applicable. See variable :const:`VARIABLE_MAP`.
|
|
@@ -624,19 +649,15 @@ def read_pvgis_tmy(filename, pvgis_format=None, map_variables=True):
|
|
|
624
649
|
-------
|
|
625
650
|
data : pandas.DataFrame
|
|
626
651
|
the weather data
|
|
627
|
-
months_selected : list
|
|
628
|
-
TMY year for each month, ``None`` for basic and EPW
|
|
629
|
-
inputs : dict
|
|
630
|
-
the inputs, ``None`` for basic and EPW
|
|
631
652
|
metadata : list or dict
|
|
632
|
-
file metadata
|
|
653
|
+
file metadata
|
|
633
654
|
|
|
634
655
|
Raises
|
|
635
656
|
------
|
|
636
657
|
ValueError
|
|
637
658
|
if ``pvgis_format`` is not specified and the file extension is neither
|
|
638
659
|
``.csv``, ``.json``, nor ``.epw``, or if ``pvgis_format`` is provided
|
|
639
|
-
as input but isn't in ``['csv', 'epw', 'json'
|
|
660
|
+
as input but isn't in ``['csv', 'epw', 'json']``
|
|
640
661
|
TypeError
|
|
641
662
|
if ``pvgis_format`` is not specified and ``filename`` is a buffer
|
|
642
663
|
|
|
@@ -652,18 +673,13 @@ def read_pvgis_tmy(filename, pvgis_format=None, map_variables=True):
|
|
|
652
673
|
outputformat = Path(filename).suffix[1:].lower()
|
|
653
674
|
else:
|
|
654
675
|
outputformat = pvgis_format
|
|
655
|
-
# parse
|
|
656
|
-
# 'csv', or 'basic'
|
|
676
|
+
# parse pvgis file based on outputformat, either 'epw', 'json', or 'csv'
|
|
657
677
|
|
|
658
678
|
# EPW: use the EPW parser from the pvlib.iotools epw.py module
|
|
659
679
|
if outputformat == 'epw':
|
|
660
|
-
|
|
661
|
-
data, meta = parse_epw(filename)
|
|
662
|
-
except AttributeError: # str/path has no .read() attribute
|
|
663
|
-
data, meta = read_epw(filename)
|
|
664
|
-
months_selected, inputs = None, None
|
|
680
|
+
data, meta = read_epw(filename)
|
|
665
681
|
|
|
666
|
-
# NOTE: json
|
|
682
|
+
# NOTE: json and csv output formats have parsers defined as private
|
|
667
683
|
# functions in this module
|
|
668
684
|
|
|
669
685
|
# JSON: use Python built-in json module to convert file contents to a
|
|
@@ -675,32 +691,31 @@ def read_pvgis_tmy(filename, pvgis_format=None, map_variables=True):
|
|
|
675
691
|
except AttributeError: # str/path has no .read() attribute
|
|
676
692
|
with open(str(filename), 'r') as fbuf:
|
|
677
693
|
src = json.load(fbuf)
|
|
678
|
-
data,
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
# eg: _parse_pvgis_tmy_csv() or _parse_pvgist_tmy_basic()
|
|
682
|
-
elif outputformat in ['csv', 'basic']:
|
|
683
|
-
# get the correct parser function for this output format from globals()
|
|
684
|
-
pvgis_parser = globals()['_parse_pvgis_tmy_{:s}'.format(outputformat)]
|
|
685
|
-
# NOTE: pvgis_parse() is a pvgis parser function from this module,
|
|
686
|
-
# either _parse_pvgis_tmy_csv() or _parse_pvgist_tmy_basic()
|
|
694
|
+
data, meta = _parse_pvgis_tmy_json(src)
|
|
695
|
+
|
|
696
|
+
elif outputformat == 'csv':
|
|
687
697
|
try:
|
|
688
|
-
data,
|
|
698
|
+
data, meta = _parse_pvgis_tmy_csv(filename)
|
|
689
699
|
except AttributeError: # str/path has no .read() attribute
|
|
690
700
|
with open(str(filename), 'rb') as fbuf:
|
|
691
|
-
data,
|
|
701
|
+
data, meta = _parse_pvgis_tmy_csv(fbuf)
|
|
702
|
+
|
|
703
|
+
elif outputformat == 'basic':
|
|
704
|
+
err_msg = "outputformat='basic' is no longer supported, please use " \
|
|
705
|
+
"outputformat='csv' instead."
|
|
706
|
+
raise ValueError(err_msg)
|
|
692
707
|
|
|
693
708
|
else:
|
|
694
|
-
# raise exception if pvgis format isn't in ['csv','
|
|
709
|
+
# raise exception if pvgis format isn't in ['csv','epw','json']
|
|
695
710
|
err_msg = (
|
|
696
|
-
"pvgis format '{:s}' was unknown, must be either '
|
|
697
|
-
"
|
|
711
|
+
"pvgis format '{:s}' was unknown, must be either 'json', 'csv',"
|
|
712
|
+
"or 'epw'").format(outputformat)
|
|
698
713
|
raise ValueError(err_msg)
|
|
699
714
|
|
|
700
715
|
if map_variables:
|
|
701
716
|
data = data.rename(columns=VARIABLE_MAP)
|
|
702
717
|
|
|
703
|
-
return data,
|
|
718
|
+
return data, meta
|
|
704
719
|
|
|
705
720
|
|
|
706
721
|
def get_pvgis_horizon(latitude, longitude, url=URL, **kwargs):
|
|
@@ -720,7 +735,7 @@ def get_pvgis_horizon(latitude, longitude, url=URL, **kwargs):
|
|
|
720
735
|
Returns
|
|
721
736
|
-------
|
|
722
737
|
data : pd.Series
|
|
723
|
-
Pandas Series of the
|
|
738
|
+
Pandas Series of the retrieved horizon elevation angles. Index is the
|
|
724
739
|
corresponding horizon azimuth angles.
|
|
725
740
|
metadata : dict
|
|
726
741
|
Metadata returned by PVGIS.
|