Skip to content

Instantly share code, notes, and snippets.

@mikofski
Last active October 23, 2020 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikofski/a71d047725865a843f7760156a46d534 to your computer and use it in GitHub Desktop.
Save mikofski/a71d047725865a843f7760156a46d534 to your computer and use it in GitHub Desktop.
"""
An open PV system specification
"""
import json
import pathlib
import yaml
def get_pv_spec(pv_spec_pathlib_file_or_buffer):
try:
f = pathlib.Path(pv_spec_pathlib_file_or_buffer)
except TypeError:
f = pv_spec_pathlib_file_or_buffer
try:
g = f.open()
except AttributeError:
g = f
return yaml.load(g)
def test_pv_spec():
x = get_pv_spec('pv_system.yaml')
y = get_pv_spec(pathlib.Path('pv_system.yaml'))
assert x == y
with pathlib.Path('pv_system.yaml').open() as f0:
z = get_pv_spec(f0)
assert x == z
assert y == z
with pathlib.Path('test_pv_system.json').open() as f1:
w = json.load(f1)
assert x == w
assert y == w
assert z == w
if __name__ == '__main__':
x = get_pv_spec('pv_system.yaml')
with pathlib.Path('test_pv_system.json').open('w') as f2:
json.dump(x, f2, indent=2)
# Open PV system specification
# component specifications
PV module specs:
<PV module ID>: <ModuleSpec>
etc: <...>
inverter specs:
<inverter ID>: <InverterSpec>
etc: <...>
mounting type specs:
<mounting type ID>: <RackSpec|TrackerSpec|...>
etc: <...>
transformer specs:
<transformer ID>: <TransformerSpec>
etc: <...>
# site parameters
latitude: <float(degrees)>
longitude: <float(degrees)>
elevation: <float(meters)>
GIS shapefile path: <filepath>|<null> # if null assume horizontal
HOR file path: <filepath>|<null> # if null assume horizon incl. in weather
irradiance weather file path: <filepath(s)>
weather file formats: <enum>|<newspec> # should be list if more than one weather file
albedo per month: <float|floats[12]> # constant or monthly
soiling per month: <float|floats[12]> # constant or monthly
etc: <...>
# layout parameters
transformers:
- transformer name: <str>
transformer spec ID: <enum> # transformer specs are enumerated by ID at top level
transformer count: <int> # identical transformers are scaled linearly
etc: <...>
inverters:
- inverter name: <str>
inverter spec ID: <enum> # inverter specs are enumerated by ID at top level
inverter count: <int> # identical inverters are scaled linearly
AC collection loss: <float(%)>
etc: <..>
layouts:
- layout name: <str> # identical layouts are scale linearly
layout coordinates: <point> # (easting, northing) from (lat, lon)
layout count: <int> # use list to assign to different inverter inputs
inverter input: <int|int[ct]> # 0-based, must be less than number of inverter MPPTs
PV module spec ID: <enum> # PV module specs are enumerated by ID at top level
mounting type ID: <enum> # mounting system specs are enumerated by ID at top level
system azimuth: <float(degrees)> # fixed tilt: normal to surface, trackers: axes
module tilt: <float(degrees)>
gcr: <float>
PV modules per string: <int>
number of strings: <int> # must be a multiple of strings per row
row in front of PV system: <bool> # is this in the middle of the system or not
row in back of PV system: <bool> # useful for bifacial
number strings per row: <int> # number of strings must be a multiple of this
thermal parameters: '<thermal model: {Uc: <float>, Uv: <float>}>'
DC collection loss: <float(%)>
etc: <...>
- layout name: <str> # next layout
etc: <...>
- inverter name: <str> # next inverter
etc: <...>
- transformer name: <str> # next transformer
etc: <...>
# shade objects
shade objects: <shade object spec> # buildings, trees, poles, overhead wires, etc.
# settings & options to toggle different calculations
calcultion settings:
- include thermal: <bool>
- include spectral: <bool>
- include bifacial: <bool>
- include IAM: <bool>
- include diffuse IAM: <bool> # use interate IAM over diffuse
- include ground diffuse: <bool>
- include panel surface VF: <bool> # can the panel surface see all ground & sky?
- include ground-sky VF: <bool> # can the ground see all of the sky?
- always decompose GHI: <bool> # ignore given DNI & DHI, and calculate from GHI
- use Erbs decomposition: <bool> # if false then use DIRINT, may require more inputs
- use Hay-Davies transposition: <bool> # if false then use Perez-Ineichen, may require more inputs
- use POA GTI-DIRINT: <bool> # if true and POA is given, then ignore GHI and other inputs
- include shade objects: <bool>
- etc: <...>
{
"PV module specs": {
"<PV module ID>": "<ModuleSpec>",
"etc": "<...>"
},
"inverter specs": {
"<inverter ID>": "<InverterSpec>",
"etc": "<...>"
},
"mounting type specs": {
"<mounting type ID>": "<RackSpec|TrackerSpec|...>",
"etc": "<...>"
},
"transformer specs": {
"<transformer ID>": "<TransformerSpec>",
"etc": "<...>"
},
"latitude": "<float(degrees)>",
"longitude": "<float(degrees)>",
"elevation": "<float(meters)>",
"GIS shapefile path": "<filepath>|<null>",
"HOR file path": "<filepath>|<null>",
"irradiance weather file path": "<filepath(s)>",
"weather file formats": "<enum>|<newspec>",
"albedo per month": "<float|floats[12]>",
"soiling per month": "<float|floats[12]>",
"etc": "<...>",
"transformers": [
{
"transformer name": "<str>",
"transformer spec ID": "<enum>",
"transformer count": "<int>",
"etc": "<...>",
"inverters": [
{
"inverter name": "<str>",
"inverter spec ID": "<enum>",
"inverter count": "<int>",
"AC collection loss": "<float(%)>",
"etc": "<..>",
"layouts": [
{
"layout name": "<str>",
"layout coordinates": "<point>",
"layout count": "<int>",
"inverter input": "<int|int[ct]>",
"PV module spec ID": "<enum>",
"mounting type ID": "<enum>",
"system azimuth": "<float(degrees)>",
"module tilt": "<float(degrees)>",
"gcr": "<float>",
"PV modules per string": "<int>",
"number of strings": "<int>",
"row in front of PV system": "<bool>",
"row in back of PV system": "<bool>",
"number strings per row": "<int>",
"thermal parameters": "<thermal model: {Uc: <float>, Uv: <float>}>",
"DC collection loss": "<float(%)>",
"etc": "<...>"
},
{
"layout name": "<str>",
"etc": "<...>"
}
]
},
{
"inverter name": "<str>",
"etc": "<...>"
}
]
},
{
"transformer name": "<str>",
"etc": "<...>"
}
],
"shade objects": "<shade object spec>",
"calcultion settings": [
{
"include thermal": "<bool>"
},
{
"include spectral": "<bool>"
},
{
"include bifacial": "<bool>"
},
{
"include IAM": "<bool>"
},
{
"include diffuse IAM": "<bool>"
},
{
"include ground diffuse": "<bool>"
},
{
"include panel surface VF": "<bool>"
},
{
"include ground-sky VF": "<bool>"
},
{
"always decompose GHI": "<bool>"
},
{
"use Erbs decomposition": "<bool>"
},
{
"use Hay-Davies transposition": "<bool>"
},
{
"use POA GTI-DIRINT": "<bool>"
},
{
"include shade objects": "<bool>"
},
{
"etc": "<...>"
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment