def get_wind_energy_output(self):
     ssc = pssc.PySSC()
     f = open(self.sam_export_json)
     self.dic = json.load(f)
     self.dic['wind_resource_filename'] = self.fp_srw
     wp_dat = pssc.dict_to_ssc_table(self.dic, "windpower")
     grid_dat = pssc.dict_to_ssc_table(self.dic, "grid")
     f.close()
     wp = Windpower.wrap(wp_dat)
     grid = Grid.from_existing(wp)
     grid.assign(Grid.wrap(grid_dat).export())
     wp.execute()
     grid.execute()
     self.json_dict = wp.Outputs.export()
     # print(self.json_dict.keys())
     # print (self.json_dict['gen'])
     self.df_output = pd.DataFrame()
     self.df_output[self.year] = self.json_dict['gen']
     for col in self.df_output.columns:
         self.df_output[col] = preprocessing.minmax_scale(
             self.df_output[col].values.reshape(1, -1),
             feature_range=(0, 1),
             axis=1,
             copy=True).T
     if self.df_all is None:
         self.df_all = self.df_output.copy()
     else:
         self.df_all = pd.concat([self.df_all, self.df_output], axis=1)
    def get_solar_energy_output(self):
        ssc = pssc.PySSC()
        f = open(self.sam_export_json)
        self.dic = json.load(f)
        self.dic['solar_resource_file'] = self.fp_srw

        ### uncomment if you want to change any model input parameters
        #         self.dic['system_capacity'] = 20000
        #         self.dic['module_type'] = 0
        #         self.dic['dc_ac_ratio'] = 1.3
        #         self.dic['array_type'] =  2
        #         self.dic['tilt'] =  35
        #         self.dic['azimuth'] = 180
        #         self.dic['gcr'] = 0.40
        #         self.dic['losses'] = 14
        #         self.dic['en_snowloss'] =  0
        #         self.dic['inv_eff'] = 95

        pv_dat = pssc.dict_to_ssc_table(self.dic, "pvwattsv7")
        grid_dat = pssc.dict_to_ssc_table(self.dic, "grid")
        f.close()
        pv = PVWatts.wrap(pv_dat)
        grid = Grid.from_existing(pv)
        grid.assign(Grid.wrap(grid_dat).export())
        pv.execute()
        grid.execute()
        self.json_dict = pv.Outputs.export()
        #         print(self.json_dict.keys())
        self.df_output = pd.DataFrame()
        self.df_output[self.year] = self.json_dict['gen']
        for col in self.df_output.columns:
            self.df_output[col] = preprocessing.minmax_scale(
                self.df_output[col].values.reshape(1, -1),
                feature_range=(0, 1),
                axis=1,
                copy=True).T

        if self.df_all is None:
            self.df_all = self.df_output.copy()
        else:
            self.df_all = pd.concat([self.df_all, self.df_output], axis=1)
Exemplo n.º 3
0
def calculate_power(solar_data, pv_dict):
    """Use PVWatts to translate weather data into power.

    :param dict solar_data: weather data as returned by :meth:`Psm3Data.to_dict`.
    :param dict pv_dict: solar plant attributes.
    :return: (*numpy.array*) hourly power output.
    """
    pv_dat = pssc.dict_to_ssc_table(pv_dict, "pvwattsv7")
    pv = PVWatts.wrap(pv_dat)
    pv.SolarResource.assign({"solar_resource_data": solar_data})
    pv.execute()
    return np.array(pv.Outputs.gen)
Exemplo n.º 4
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Mar  4 13:47:58 2020

Most recently tested against PySAM 2.2.3

@author: frohro
"""
import json
import PySAM.GenericSystem as GenericSystem
import PySAM.Grid as Grid
import PySAM.Singleowner as Singleowner
import PySAM.PySSC as pssc

ssc = pssc.PySSC()
with open("Examples/100mW_Generic.json") as f:
    dic = json.load(f)
    gs_dat = pssc.dict_to_ssc_table(dic, "generic_system")
    grid_dat = pssc.dict_to_ssc_table(dic, "grid")
    so_dat = pssc.dict_to_ssc_table(dic, "singleowner")

    gs = GenericSystem.wrap(gs_dat)
    grid = Grid.from_existing(gs)
    grid.assign(Grid.wrap(grid_dat).export())

    # to create GenericSystem and Singleowner combined simulation, sharing the same data
    so = Singleowner.from_existing(gs)
    so.assign(Singleowner.wrap(so_dat).export())

gs.execute()
Exemplo n.º 5
0
def retrieve_data(solar_plant, email, api_key, year="2016", rate_limit=0.5):
    """Retrieves irradiance data from NSRDB and calculate the power output using
    the System Adviser Model (SAM).

    :param pandas.DataFrame solar_plant: plant data frame.
    :param str email: email used to`sign up <https://developer.nrel.gov/signup/>`_.
    :param str api_key: API key.
    :param str year: year.
    :param int/float rate_limit: minimum seconds to wait between requests to NREL
    :return: (*pandas.DataFrame*) -- data frame with *'Pout'*, *'plant_id'*,
        *'ts'* and *'ts_id'* as columns. Values are power output for a 1MW generator.
    """

    # SAM only takes 365 days.
    try:
        leap_day = (pd.Timestamp("%s-02-29-00" % year).dayofyear - 1) * 24
        is_leap_year = True
        dates = pd.date_range(start="%s-01-01-00" % 2015,
                              freq="H",
                              periods=365 * 24)
        dates = dates.map(lambda t: t.replace(year=int(year)))
    except ValueError:
        leap_day = None
        is_leap_year = False
        dates = pd.date_range(start="%s-01-01-00" % year,
                              freq="H",
                              periods=365 * 24)

    # Identify unique location
    coord = get_plant_id_unique_location(solar_plant)

    data = pd.DataFrame({"Pout": [], "plant_id": [], "ts": [], "ts_id": []})

    # PV tracking ratios
    # By state and by interconnect when EIA data do not have any solar PV in
    # the state
    pv_info = get_pv_tracking_data()
    zone_id = solar_plant.zone_id.unique()
    frac = {}
    for i in zone_id:
        state = id2abv[i]
        frac[i] = get_pv_tracking_ratio_state(pv_info, [state])
        if frac[i] is None:
            frac[i] = get_pv_tracking_ratio_state(
                pv_info, list(interconnect2abv[abv2interconnect[state]]))

    # Inverter Loading Ratio
    ilr = 1.25
    api = NrelApi(email, api_key, rate_limit)

    for key in tqdm(coord.keys(), total=len(coord)):
        lat, lon = key[1], key[0]
        solar_data = api.get_psm3_at(
            lat,
            lon,
            attributes="dhi,dni,wind_speed,air_temperature",
            year=year,
            leap_day=False,
            dates=dates,
        ).to_dict()

        for i in coord[key]:
            data_site = pd.DataFrame({
                "ts":
                pd.date_range(start="%s-01-01-00" % year,
                              end="%s-12-31-23" % year,
                              freq="H")
            })
            data_site["ts_id"] = range(1, len(data_site) + 1)
            data_site["plant_id"] = i

            power = 0
            for j, axis in enumerate([0, 2, 4]):
                pv_dict = {
                    "system_capacity": ilr,
                    "dc_ac_ratio": ilr,
                    "tilt": 30,
                    "azimuth": 180,
                    "inv_eff": 94,
                    "losses": 14,
                    "array_type": axis,
                    "gcr": 0.4,
                    "adjust:constant": 0,
                }

                pv_dat = pssc.dict_to_ssc_table(pv_dict, "pvwattsv7")
                pv = PVWatts.wrap(pv_dat)
                pv.SolarResource.assign({"solar_resource_data": solar_data})
                pv.execute()

                ratio = frac[solar_plant.loc[i].zone_id][j]
                power += ratio * np.array(pv.Outputs.gen)

            if is_leap_year is True:
                data_site["Pout"] = np.insert(power, leap_day,
                                              power[leap_day - 24:leap_day])
            else:
                data_site["Pout"] = power

            data = data.append(data_site, ignore_index=True, sort=False)

    data["plant_id"] = data["plant_id"].astype(np.int32)
    data["ts_id"] = data["ts_id"].astype(np.int32)

    data.sort_values(by=["ts_id", "plant_id"], inplace=True)
    data.reset_index(inplace=True, drop=True)

    return data
    Load json file with inputs from SAM GUI.
    Load all needed PySAM module's data structures with the json input data.
    Run the simulations.
    Print the results.

@author: frohro
"""

import json
import PySAM.Pvwattsv7 as PVWatts
import PySAM.Grid as Grid
import PySAM.Utilityrate5 as UtilityRate
import PySAM.Cashloan as Cashloan
import PySAM.PySSC as pssc

ssc = pssc.PySSC()

verbose = True  # Make False if you don't want all the debugging info.

# Get the SAM json file, make the simulations we need for the commercial
# PVWatts simulation.

# The json file is generated from SAM using the "Generate Code" menu item
# in the added simulation case.  Choose "JSON for inputs" and a .json file
# with the title of your simulation case will be created where you select with
# the "Open" button on the file dialog.
json_file_path = 'Examples/100kW_PVWatts.json'  # Change this file name to yours!
with open(json_file_path) as f:
    dic = json.load(f)
# The next seven lines are needed to load the PySAM data structures with the
# inputs from the json file.
Exemplo n.º 7
0
def fit_sdm_cec_sam(celltype, v_mp, i_mp, v_oc, i_sc, alpha_sc, beta_voc,
                    gamma_pmp, cells_in_series, temp_ref=25):
    """
    Estimates parameters for the CEC single diode model (SDM) using the SAM
    SDK.

    Parameters
    ----------
    celltype : str
        Value is one of 'monoSi', 'multiSi', 'polySi', 'cis', 'cigs', 'cdte',
        'amorphous'
    v_mp : float
        Voltage at maximum power point [V]
    i_mp : float
        Current at maximum power point [A]
    v_oc : float
        Open circuit voltage [V]
    i_sc : float
        Short circuit current [A]
    alpha_sc : float
        Temperature coefficient of short circuit current [A/C]
    beta_voc : float
        Temperature coefficient of open circuit voltage [V/C]
    gamma_pmp : float
        Temperature coefficient of power at maximum point point [%/C]
    cells_in_series : int
        Number of cells in series
    temp_ref : float, default 25
        Reference temperature condition [C]

    Returns
    -------
    I_L_ref : float
        The light-generated current (or photocurrent) at reference
        conditions [A]

    I_o_ref : float
        The dark or diode reverse saturation current at reference
        conditions [A]

    R_sh_ref : float
        The shunt resistance at reference conditions, in ohms.

    R_s : float
        The series resistance at reference conditions, in ohms.

    a_ref : float
        The product of the usual diode ideality factor ``n`` (unitless),
        number of cells in series ``Ns``, and cell thermal voltage at
        reference conditions [V]

    Adjust : float
        The adjustment to the temperature coefficient for short circuit
        current, in percent.

    Raises
    ------
    ImportError
        If NREL-PySAM is not installed.
    RuntimeError
        If parameter extraction is not successful.

    Notes
    -----
    Inputs ``v_mp``, ``v_oc``, ``i_mp`` and ``i_sc`` are assumed to be from a
    single IV curve at constant irradiance and cell temperature. Irradiance is
    not explicitly used by the fitting procedure. The irradiance level at which
    the input IV curve is determined and the specified cell temperature
    ``temp_ref`` are the reference conditions for the output parameters
    ``I_L_ref``, ``I_o_ref``, ``R_sh_ref``, ``R_s``, ``a_ref`` and ``Adjust``.

    References
    ----------
    .. [1] A. Dobos, "An Improved Coefficient Calculator for the California
       Energy Commission 6 Parameter Photovoltaic Module Model", Journal of
       Solar Energy Engineering, vol 134, 2012.
    """

    try:
        from PySAM import PySSC
    except ImportError:
        raise ImportError("Requires NREL's PySAM package at "
                          "https://pypi.org/project/NREL-PySAM/.")

    datadict = {'tech_model': '6parsolve', 'financial_model': 'none',
                'celltype': celltype, 'Vmp': v_mp,
                'Imp': i_mp, 'Voc': v_oc, 'Isc': i_sc, 'alpha_isc': alpha_sc,
                'beta_voc': beta_voc, 'gamma_pmp': gamma_pmp,
                'Nser': cells_in_series, 'Tref': temp_ref}

    result = PySSC.ssc_sim_from_dict(datadict)
    if result['cmod_success'] == 1:
        return tuple([result[k] for k in ['Il', 'Io', 'Rsh', 'Rs', 'a',
                      'Adj']])
    else:
        raise RuntimeError('Parameter estimation failed')
Exemplo n.º 8
0
    def generate_solar_power_from_nsrdb(self,
                                        clearsky,
                                        capacity,
                                        DC_AC_ratio,
                                        tilt,
                                        azimuth,
                                        inv_eff,
                                        losses,
                                        array_type,
                                        year=None,
                                        leap_year=None,
                                        interval=None,
                                        utc=None):
        """ Generate PV power time series.
        Parameters
        ----------
        clearsky : bool
            True returns clearsky power, false returns "simulated" output
        capacity : float
            System capacity in MW
        DC_AC_ratio : float
            DC/AC ratio (or power ratio). See https://sam.nrel.gov/sites/default/files/content/virtual_conf_july_2013/07-sam-virtual-conference-2013-woodcock.pdf
        tilt : float
           Tilt of system in degrees
        azimuth : float
            Azimuth angle (in degrees) from north (0 degrees)
        inv_eff : float
            Inverter efficiency (in %)
        losses : float
            Total system losses (in %)
        array_type : int
            # Specify PV configuration (0=Fixed, 1=Fixed Roof, 2=1 Axis Tracker, 3=Backtracted, 4=2 Axis Tracker)
        year : int
            Year of data. May take any value in the interval [1998,2018]
        leap_year : bool
            Leap year to true or false. True will return leap day data if present, false will not.
        interval: string
            Time interval in minutes, i.e., '30' is half hour intervals. Valid intervals are 30 & 60.
        utc : bool
            Specify Coordinated Universal Time (UTC), 'true' will use UTC, 'false' will use the local time zone of the data.
            NOTE: In order to use the NSRDB data in SAM, you must specify UTC as 'false'. SAM requires the data to be in the
            local time zone.

        """
        if not hasattr(self, "resource_data"):
            args = [arg == None for arg in [year, leap_year, interval, utc]]
            if any(args):
                raise NameError("Missing input: year,leap_year,interval,utc")
            else:
                self.year = year
                self.leap_year = leap_year
                self.interval = interval
                self.utc = utc
                self.get_nsrdb_data(self)

        if clearsky == True:
            clearsky_str = "Clearsky "
        else:
            clearsky_str = ""

        ssc = PySSC()

        # Resource inputs for SAM model:
        wfd = ssc.data_create()
        ssc.data_set_number(wfd, 'lat'.encode('utf-8'), self.lat)
        ssc.data_set_number(wfd, 'lon'.encode('utf-8'), self.lon)
        ssc.data_set_number(wfd, 'tz'.encode('utf-8'),
                            self.meta_resource_data["Time Zone"])
        ssc.data_set_number(wfd, 'elev'.encode('utf-8'),
                            self.meta_resource_data["Elevation"])
        ssc.data_set_array(wfd, 'year'.encode('utf-8'),
                           self.resource_data.Year)
        ssc.data_set_array(wfd, 'month'.encode('utf-8'),
                           self.resource_data.Month)
        ssc.data_set_array(wfd, 'day'.encode('utf-8'), self.resource_data.Day)
        ssc.data_set_array(wfd, 'hour'.encode('utf-8'),
                           self.resource_data.Hour)
        ssc.data_set_array(wfd, 'minute'.encode('utf-8'),
                           self.resource_data.Minute)
        ssc.data_set_array(wfd, 'dn'.encode('utf-8'),
                           self.resource_data["{}DNI".format(clearsky_str)])
        ssc.data_set_array(wfd, 'df'.encode('utf-8'),
                           self.resource_data["{}DHI".format(clearsky_str)])
        ssc.data_set_array(wfd, 'wspd'.encode('utf-8'),
                           self.resource_data['Wind Speed'])
        ssc.data_set_array(wfd, 'tdry'.encode('utf-8'),
                           self.resource_data.Temperature)

        # Create SAM compliant object
        dat = ssc.data_create()
        ssc.data_set_table(dat, 'solar_resource_data'.encode('utf-8'), wfd)
        ssc.data_free(wfd)

        # Specify the system Configuration

        ssc.data_set_number(dat, 'system_capacity'.encode('utf-8'), capacity)
        ssc.data_set_number(dat, 'dc_ac_ratio'.encode('utf-8'), DC_AC_ratio)
        ssc.data_set_number(dat, 'tilt'.encode('utf-8'), tilt)
        ssc.data_set_number(dat, 'azimuth'.encode('utf-8'), azimuth)
        ssc.data_set_number(dat, 'inv_eff'.encode('utf-8'), inv_eff)
        ssc.data_set_number(dat, 'losses'.encode('utf-8'), losses)
        ssc.data_set_number(dat, 'array_type'.encode('utf-8'), array_type)
        ssc.data_set_number(dat, 'gcr'.encode('utf-8'),
                            0.4)  # Set ground coverage ratio
        ssc.data_set_number(dat, 'adjust:constant'.encode('utf-8'),
                            0)  # Set constant loss adjustment

        # execute and put generation results back into dataframe
        mod = ssc.module_create('pvwattsv5'.encode('utf-8'))
        ssc.module_exec(mod, dat)
        df = pd.DataFrame()
        df['generation'] = np.array(
            ssc.data_get_array(dat, 'gen'.encode('utf-8')))
        df.index = self.resource_data.index

        # free the memory
        ssc.data_free(dat)
        ssc.module_free(mod)

        self.cloud_type = self.resource_data['Cloud Type']
        self.solar_power_from_nsrdb = df
        self.capacity = capacity

        return df
Exemplo n.º 9
0
# https://nrel-pysam.readthedocs.io/en/latest/
# https://nrel-pysam.readthedocs.io/en/latest/#importing-a-sam-gui-case
# https://nrel-pysam.readthedocs.io/en/latest/Models.html

import json
import os
import PySAM.Pvwattsv5 as pvwatts
import PySAM.StandAloneBattery as battery
import PySAM.Utilityrate5 as utility
import PySAM.CashloanModel as cashloan
from PySAM.PySSC import *

ssc = PySSC()

# I generated json files using "Generate Code" option in example.sam in pysam-examples and exporting as json.
# Battery data is captured through detailed PV model, but will be used with PVWatts here
with open(os.path.join('pysam_inputs', "pvwatts.json")) as f:
    dic = json.load(f)
    pvwatts_dat = dict_to_ssc_table(dic, "pvwattsv5")
    pv = pvwatts.wrap(pvwatts_dat)

with open(os.path.join('pysam_inputs', "pvsamv1.json")) as f:
    dic = json.load(f)
    batt_dat = dict_to_ssc_table(dic, "battery")
    batt = battery.wrap(batt_dat)
    utility_dat = dict_to_ssc_table(dic, "utilityrate5")
    utilityrate = utility.wrap(utility_dat)
    loan_dat = dict_to_ssc_table(dic, "cashloan")
    loan = cashloan.wrap(loan_dat)

# run PV model