예제 #1
0
    def _setup_irradiance(self):
        """
        Compute solar azimuth and elevation degrees;
        Compute plane-of-array irradiance for a single-axis tracking PVwatts system
        :return:
        """
        pv_model = pv.default("PVWattsNone")
        pv_model.SystemDesign.array_type = 2
        pv_model.SystemDesign.gcr = .1
        if self.solar_resource_data is None:
            filename = str(self.lat) + "_" + str(
                self.lon) + "_psmv3_60_2012.csv"
            weather_path = Path(
                __file__
            ).parent.parent.parent / "resource_files" / "solar" / filename
            if not weather_path.is_file():
                SolarResource(self.lat, self.lon, year=2012)
                if not weather_path.is_file():
                    raise ValueError("resource file does not exist")
            pv_model.SolarResource.solar_resource_file = str(weather_path)
        else:
            pv_model.SolarResource.solar_resource_data = self.solar_resource_data
        pv_model.execute(0)
        self.poa = np.array(pv_model.Outputs.poa)

        logger.info("get_irradiance success")
예제 #2
0
 def __init__(self, data, solar_resource_file="", wind_resource_file=""):
     self.data = data
     self.vertices = np.array(
         [np.array(v) for v in data['site_boundaries']['verts']])
     self.polygon: Polygon = Polygon(self.vertices)
     self.valid_region = self.polygon.buffer(1e-8)
     if 'lat' not in data or 'lon' not in data:
         raise ValueError("SiteInfo requires lat and lon")
     self.lat = data['lat']
     self.lon = data['lon']
     if 'year' not in data:
         data['year'] = 2012
     self.solar_resource = SolarResource(data['lat'],
                                         data['lon'],
                                         data['year'],
                                         filepath=solar_resource_file)
     # TODO: allow hub height to be used as an optimization variable
     self.wind_resource = WindResource(data['lat'],
                                       data['lon'],
                                       data['year'],
                                       wind_turbine_hub_ht=80,
                                       filepath=wind_resource_file)
     self.n_timesteps = len(self.solar_resource.data['gh']) // 8760 * 8760
     self.urdb_label = data['urdb_label'] if 'urdb_label' in data.keys(
     ) else None
     logging.info(
         "Set up SiteInfo with solar and wind resource files: {}, {}".
         format(self.solar_resource.filename, self.wind_resource.filename))
예제 #3
0
def test_from_file():
    windfile = Path(
        __file__
    ).parent.parent / "resource_files" / "wind" / "35.2018863_-101.945027_windtoolkit_2012_60min_80.0m.srw"
    wind_resource = WindResource(lat=lat,
                                 lon=lon,
                                 year=year,
                                 wind_turbine_hub_ht=70,
                                 filepath=windfile)
    assert (len(wind_resource.data['data']) > 0)

    solarfile = Path(
        __file__
    ).parent.parent / "resource_files" / "solar" / "35.2018863_-101.945027_psmv3_60.csv"
    solar_resource = SolarResource(lat=lat,
                                   lon=lon,
                                   year=year,
                                   filepath=solarfile)
    assert (len(solar_resource.data['gh']) > 0)
예제 #4
0
from dotenv import load_dotenv
from hybrid.keys import set_developer_nrel_gov_key

# California Site
# lat = 33.907295
# lon = -116.555588
# year = 2012
# hubheight = 80

# Texas Site
# lat = 34.212257
# lon = -101.361160
# year = 2012
# hubheight = 91.5

# Maine Site
lat = 44.766171
lon = -68.157669
year = 2012
hubheight = 116.5

load_dotenv()
NREL_API_KEY = os.getenv("NREL_API_KEY")
set_developer_nrel_gov_key(
    NREL_API_KEY
)  # Set this key manually here if you are not setting it using the .env

WindResource(lat=lat, lon=lon, year=year, wind_turbine_hub_ht=hubheight)

SolarResource(lat=lat, lon=lon, year=year)
예제 #5
0
def solar_resource():
    return SolarResource(lat=lat, lon=lon, year=year)
예제 #6
0
파일: site_info.py 프로젝트: NREL/HOPP
    def __init__(self, data,
                 solar_resource_file="",
                 wind_resource_file="", 
                 grid_resource_file="",
                 hub_height=97,
                 capacity_hours=[],
                 desired_schedule=[]):
        """
        Site specific information required by the hybrid simulation class and layout optimization.

        :param data: dict, containing the following keys:

            #. ``lat``: float, latitude [decimal degrees]
            #. ``lon``: float, longitude [decimal degrees]
            #. ``year``: int, year used to pull solar and/or wind resource data. If not provided, default is 2012 [-]
            #. ``elev``: float (optional), elevation (metadata purposes only) [m] 
            #. ``tz``: int (optional), timezone code (metadata purposes only) [-]
            #. ``no_solar``: bool (optional), if ``True`` solar data download for site is skipped, otherwise solar resource is downloaded from NSRDB
            #. ``no_wind``: bool (optional), if ``True`` wind data download for site is skipped, otherwise wind resource is downloaded from wind-toolkit
            #. ``site_boundaries``: dict (optional), with the following keys:

                * ``verts``: list of list [x,y], site boundary vertices [m]
                * ``verts_simple``: list of list [x,y], simple site boundary vertices [m]

            #. ``urdb_label``: string (optional), `Link Utility Rate DataBase <https://openei.org/wiki/Utility_Rate_Database>`_ label for REopt runs

            .. TODO: Can we get rid of verts_simple and simplify site_boundaries

        :param solar_resource_file: string, location (path) and filename of solar resource file (if not downloading from NSRDB)
        :param wind_resource_file: string, location (path) and filename of wind resource file (if not downloading from wind-toolkit)
        :param grid_resource_file: string, location (path) and filename of grid pricing data 
        :param hub_height: int (default = 97), turbine hub height for resource download [m]
        :param capacity_hours: list of booleans, (8760 length) ``True`` if the hour counts for capacity payments, ``False`` otherwise
        :param desired_schedule: list of floats, (8760 length) absolute desired load profile [MWe]
        """
        set_nrel_key_dot_env()
        self.data = data
        if 'site_boundaries' in data:
            self.vertices = np.array([np.array(v) for v in data['site_boundaries']['verts']])
            self.polygon: Polygon = Polygon(self.vertices)
            self.valid_region = self.polygon.buffer(1e-8)
        if 'lat' not in data or 'lon' not in data:
            raise ValueError("SiteInfo requires lat and lon")
        self.lat = data['lat']
        self.lon = data['lon']
        if 'year' not in data:
            data['year'] = 2012
        
        if 'no_solar' not in data:
            data['no_solar'] = False

        if not data['no_solar']:
            self.solar_resource = SolarResource(data['lat'], data['lon'], data['year'], filepath=solar_resource_file)

        if 'no_wind' not in data:
            data['no_wind'] = False

        if not data['no_wind']:
            # TODO: allow hub height to be used as an optimization variable
            self.wind_resource = WindResource(data['lat'], data['lon'], data['year'], wind_turbine_hub_ht=hub_height,
                                            filepath=wind_resource_file)

        self.elec_prices = ElectricityPrices(data['lat'], data['lon'], data['year'], filepath=grid_resource_file)
        self.n_timesteps = len(self.solar_resource.data['gh']) // 8760 * 8760
        self.n_periods_per_day = self.n_timesteps // 365  # TODO: Does not handle leap years well
        self.interval = int((60*24)/self.n_periods_per_day)
        self.urdb_label = data['urdb_label'] if 'urdb_label' in data.keys() else None

        if len(capacity_hours) == self.n_timesteps:
            self.capacity_hours = capacity_hours
        else:
            self.capacity_hours = [False] * self.n_timesteps

        # Desired load schedule for the system to dispatch against
        self.desired_schedule = desired_schedule
        self.follow_desired_schedule = len(desired_schedule) == self.n_timesteps
        if len(desired_schedule) > 0 and len(desired_schedule) != self.n_timesteps:
            raise ValueError('The provided desired schedule does not match length of the simulation horizon.')

            # FIXME: this a hack
        if 'no_wind' in data:
            logger.info("Set up SiteInfo with solar resource files: {}".format(self.solar_resource.filename))
        else:
            logger.info(
                "Set up SiteInfo with solar and wind resource files: {}, {}".format(self.solar_resource.filename,
                                                                                    self.wind_resource.filename))