Source code for energydatamodel.solar

"""Solar assets."""

import json
from dataclasses import dataclass

import pandas as pd
import pvlib

from energydatamodel.bases import NodeAsset

__all__ = [
    "FixedMount",
    "SingleAxisTrackerMount",
    "PVArray",
    "PVSystem",
    "SolarPowerArea",
]


[docs] @dataclass class FixedMount: surface_tilt: float = 0.0 surface_azimuth: float = 0.0
[docs] @dataclass class SingleAxisTrackerMount: axis_tilt: float = 0.0 axis_azimuth: float = 0.0 max_angle: float | tuple = 90.0 backtrack: bool = True gcr: float = 0.2857142857142857 cross_axis_tilt: float = 0.0 racking_model: str | None = None module_height: float | None = None
[docs] @dataclass(repr=False, kw_only=True) class PVArray(NodeAsset): capacity: float | None = None surface_azimuth: float | None = None surface_tilt: float | None = None surface_area: float | None = None efficiency: float | None = None module: str | None = None module_type: str = "glass_polymer" module_parameters: dict | pd.Series | None = None temperature_model_parameters: dict | pd.Series | None = None
[docs] @dataclass(repr=False, kw_only=True) class PVSystem(NodeAsset): """A PV system — an Asset that contains :class:`PVArray` members. Stored in the inherited ``members`` list. Attach arrays explicitly with ``pv_system.members.append(PVArray(...))`` or via ``add_child(...)`` — no auto-creation. """ capacity: float | None = None surface_azimuth: float | None = None surface_tilt: float | None = None albedo: float | None = None surface_type: str | None = None module_parameters: dict | None = None inverter_parameters: dict | None = None module_type: str = "glass_polymer" racking_model: str = "open_rack"
[docs] def to_pvlib(self, **kwargs): if self.module_parameters is None: self.module_parameters = {"pdc0": self.capacity} if "pdc0" not in self.module_parameters: self.module_parameters["pdc0"] = self.capacity if self.inverter_parameters is None: self.inverter_parameters = {"pdc0": self.capacity} if "pdc0" not in self.inverter_parameters: self.inverter_parameters["pdc0"] = self.capacity return pvlib.pvsystem.PVSystem( name=self.name, surface_tilt=self.surface_tilt, surface_azimuth=self.surface_azimuth, albedo=self.albedo, surface_type=self.surface_type, module_parameters=self.module_parameters, inverter_parameters=self.inverter_parameters, module_type=self.module_type, racking_model=self.racking_model, **kwargs, )
[docs] @dataclass(repr=False, kw_only=True) class SolarPowerArea(NodeAsset): """A solar-power-potential area. The area's polygon lives in the inherited ``geometry`` field. """ capacity: float | pd.DataFrame | None = None
[docs] def to_geojson(self, exclude_none: bool = True): if self.geometry is None: raise ValueError("SolarPowerArea has no geometry to serialize") return json.loads(json.dumps(self.geometry.__geo_interface__))
@property def geojson(self): return self.to_geojson()