Beispiel #1
0
def _get_poa(data, solar_position):
    """
    Return the radiation adjusted to 
    Plane of Array (SkyDiffuse, GroundDiffuse, Total).
    """

    extra_radiation = get_extra_radiation(data.data.index)

    # Best orientation for pv system
    surface_tilt = _surface_tilt(data.latitude)
    surface_azimuth = _surface_azimuth(data.latitude)

    # Sky Diffuse radiation (From PvLib)
    poa_diffuse = haydavies(surface_tilt=surface_tilt,
                            surface_azimuth=surface_azimuth,
                            dhi=data.data['Gd(h)'],
                            dni=data.data['Gb(n)'],
                            dni_extra=extra_radiation,
                            solar_zenith=solar_position.apparent_zenith,
                            solar_azimuth=solar_position.azimuth)

    # Ground Diffuse radiation (From PvLib)
    poa_ground = get_ground_diffuse(data.latitude,
                                    data.data['G(h)'],
                                    surface_type='urban')

    # Angle of incidence at best orientation
    _aoi = aoi(surface_tilt=surface_tilt,
               surface_azimuth=surface_azimuth,
               solar_zenith=solar_position.apparent_zenith,
               solar_azimuth=solar_position.apparent_zenith)

    # Total radiation at plane of the pv array.
    poa_total = poa_components(aoi=_aoi,
                               dni=data.data['Gb(n)'],
                               poa_sky_diffuse=poa_diffuse,
                               poa_ground_diffuse=poa_ground)

    return poa_total, _aoi
Beispiel #2
0
def test_poa_components(irrad_data, ephem_data, dni_et, relative_airmass):
    aoi = irradiance.aoi(40, 180, ephem_data['apparent_zenith'],
                         ephem_data['azimuth'])
    gr_sand = irradiance.get_ground_diffuse(40,
                                            irrad_data['ghi'],
                                            surface_type='sand')
    diff_perez = irradiance.perez(40, 180, irrad_data['dhi'],
                                  irrad_data['dni'], dni_et,
                                  ephem_data['apparent_zenith'],
                                  ephem_data['azimuth'], relative_airmass)
    out = irradiance.poa_components(aoi, irrad_data['dni'], diff_perez,
                                    gr_sand)
    expected = pd.DataFrame(np.array(
        [[0., -0., 0., 0., 0.],
         [35.19456561, 0., 35.19456561, 31.4635077, 3.73105791],
         [956.18253696, 798.31939281, 157.86314414, 109.08433162, 48.77881252],
         [90.99624896, 33.50143401, 57.49481495, 45.45978964, 12.03502531]]),
                            columns=[
                                'poa_global', 'poa_direct', 'poa_diffuse',
                                'poa_sky_diffuse', 'poa_ground_diffuse'
                            ],
                            index=irrad_data.index)
    assert_frame_equal(out, expected)
Beispiel #3
0
def test_poa_components(irrad_data, ephem_data, dni_et, relative_airmass):
    aoi = irradiance.aoi(40, 180, ephem_data['apparent_zenith'],
                         ephem_data['azimuth'])
    gr_sand = irradiance.get_ground_diffuse(40, irrad_data['ghi'],
                                            surface_type='sand')
    diff_perez = irradiance.perez(
        40, 180, irrad_data['dhi'], irrad_data['dni'], dni_et,
        ephem_data['apparent_zenith'], ephem_data['azimuth'], relative_airmass)
    out = irradiance.poa_components(
        aoi, irrad_data['dni'], diff_perez, gr_sand)
    expected = pd.DataFrame(np.array(
        [[  0.        ,  -0.        ,   0.        ,   0.        ,
            0.        ],
         [ 35.19456561,   0.        ,  35.19456561,  31.4635077 ,
            3.73105791],
         [956.18253696, 798.31939281, 157.86314414, 109.08433162,
           48.77881252],
         [ 90.99624896,  33.50143401,  57.49481495,  45.45978964,
           12.03502531]]),
        columns=['poa_global', 'poa_direct', 'poa_diffuse', 'poa_sky_diffuse',
                 'poa_ground_diffuse'],
        index=irrad_data.index)
    assert_frame_equal(out, expected)
Beispiel #4
0
def test_grounddiffuse_albedo_invalid_surface(irrad_data):
    with pytest.raises(KeyError):
        irradiance.get_ground_diffuse(40, irrad_data['ghi'], surface_type='invalid')
Beispiel #5
0
def test_grounddiffuse_albedo_0(irrad_data):
    ground_irrad = irradiance.get_ground_diffuse(40, irrad_data['ghi'], albedo=0)
    assert 0 == ground_irrad.all()
Beispiel #6
0
def test_grounddiffuse_simple_series(irrad_data):
    ground_irrad = irradiance.get_ground_diffuse(40, irrad_data['ghi'])
    assert ground_irrad.name == 'diffuse_ground'
Beispiel #7
0
def test_grounddiffuse_simple_float():
    result = irradiance.get_ground_diffuse(40, 900)
    assert_allclose(result, 26.32000014911496)
Beispiel #8
0
def test_grounddiffuse_albedo_surface(irrad_data):
    result = irradiance.get_ground_diffuse(40,
                                           irrad_data['ghi'],
                                           surface_type='sand')
    assert_allclose(result, [0, 3.731058, 48.778813, 12.035025], atol=1e-4)
Beispiel #9
0
def get_poa_ground_diffuse(surface_tilt, forecast_data, albedo):
    # Calculate ground diffuse. We specified the albedo above. You could have also provided a string to the ``surface_type`` keyword argument.
    poa_ground_diffuse = irradiance.get_ground_diffuse(surface_tilt, forecast_data['ghi'], albedo=albedo)
    return poa_ground_diffuse
Beispiel #10
0
def test_grounddiffuse_albedo_0(irrad_data):
    ground_irrad = irradiance.get_ground_diffuse(40,
                                                 irrad_data['ghi'],
                                                 albedo=0)
    assert 0 == ground_irrad.all()
Beispiel #11
0
def test_grounddiffuse_simple_series(irrad_data):
    ground_irrad = irradiance.get_ground_diffuse(40, irrad_data['ghi'])
    assert ground_irrad.name == 'diffuse_ground'
Beispiel #12
0
def test_grounddiffuse_simple_float():
    result = irradiance.get_ground_diffuse(40, 900)
    assert_allclose(result, 26.32000014911496)
def simulate_power_by_station(station_index, surface_tilt, surface_azimuth,
                              pv_module, tcell_model_parameters, ghi, tamb,
                              wspd, albedo, days, lead_times, air_mass,
                              dni_extra, zenith, apparent_zenith, azimuth):
    """
    This is the worker function for simulating power at a specified location. This function should be used inside
    of `simulate_power` and direct usage is discouraged.

    :param station_index: A station index
    :param ghi: See `simulate_power`
    :param tamb: See `simulate_power`
    :param wspd: See `simulate_power`
    :param albedo: See `simulate_power`
    :param days: See `simulate_power`
    :param lead_times: See `simulate_power`
    :param air_mass: See `simulate_power`
    :param dni_extra: See `simulate_power`
    :param zenith: See `simulate_power`
    :param apparent_zenith: See `simulate_power`
    :param azimuth: See `simulate_power`
    :param surface_tilt: See `simulate_power`
    :param surface_azimuth: See `simulate_power`
    :param pv_module: A PV module name
    :param tcell_model_parameters: A cell module name
    :return: A list with power, cell temperature, and the effective irradiance
    """

    # Sanity check
    assert 0 <= station_index < ghi.shape[3], 'Invalid station index'

    # Determine the dimensions
    num_analogs = ghi.shape[0]
    num_lead_times = ghi.shape[1]
    num_days = ghi.shape[2]

    # Initialization
    p_mp = np.zeros((num_analogs, num_lead_times, num_days))
    tcell = np.zeros((num_analogs, num_lead_times, num_days))
    effective_irradiance = np.zeros((num_analogs, num_lead_times, num_days))
    pv_module = pvsystem.retrieve_sam("SandiaMod")[pv_module]
    tcell_model_parameters = temperature.TEMPERATURE_MODEL_PARAMETERS["sapm"][
        tcell_model_parameters]

    for day_index in range(num_days):
        for lead_time_index in range(num_lead_times):

            # Determine the current time
            current_posix = days[day_index] + lead_times[lead_time_index]
            current_time = pd.Timestamp(current_posix, tz="UTC", unit='s')

            for analog_index in range(num_analogs):
                ghi_ = ghi[analog_index, lead_time_index, day_index,
                           station_index]

                if ghi_ == 0:
                    continue

                albedo_ = albedo[analog_index, lead_time_index, day_index,
                                 station_index]
                wspd_ = wspd[analog_index, lead_time_index, day_index,
                             station_index]
                tamb_ = tamb[analog_index, lead_time_index, day_index,
                             station_index]
                air_mass_ = air_mass[lead_time_index, day_index, station_index]
                dni_extra_ = dni_extra[lead_time_index, day_index,
                                       station_index]
                zenith_ = zenith[lead_time_index, day_index, station_index]
                apparent_zenith_ = apparent_zenith[lead_time_index, day_index,
                                                   station_index]
                azimuth_ = azimuth[lead_time_index, day_index, station_index]

                ##########################################################################################
                #                                                                                        #
                #                     Core procedures of simulating power at one location                #
                #                                                                                        #
                ##########################################################################################

                # Decompose DNI from GHI
                dni_dict = irradiance.disc(ghi_, zenith_, current_time)

                # Calculate POA sky diffuse
                poa_sky_diffuse = irradiance.haydavies(
                    surface_tilt, surface_azimuth, ghi_, dni_dict["dni"],
                    dni_extra_, apparent_zenith_, azimuth_)

                # Calculate POA ground diffuse
                poa_ground_diffuse = irradiance.get_ground_diffuse(
                    surface_tilt, ghi_, albedo_)

                # Calculate angle of incidence
                aoi = irradiance.aoi(surface_tilt, surface_azimuth,
                                     apparent_zenith_, azimuth_)

                # Calculate POA total
                poa_irradiance = irradiance.poa_components(
                    aoi, dni_dict["dni"], poa_sky_diffuse, poa_ground_diffuse)

                # Calculate cell temperature
                tcell[analog_index, lead_time_index,
                      day_index] = pvsystem.temperature.sapm_cell(
                          poa_irradiance['poa_global'], tamb_, wspd_,
                          tcell_model_parameters['a'],
                          tcell_model_parameters['b'],
                          tcell_model_parameters["deltaT"])

                # Calculate effective irradiance
                effective_irradiance[
                    analog_index, lead_time_index,
                    day_index] = pvsystem.sapm_effective_irradiance(
                        poa_irradiance['poa_direct'],
                        poa_irradiance['poa_diffuse'], air_mass_, aoi,
                        pv_module)

                # Calculate power
                sapm_out = pvsystem.sapm(
                    effective_irradiance[analog_index, lead_time_index,
                                         day_index],
                    tcell[analog_index, lead_time_index, day_index], pv_module)

                # Save output to numpy
                p_mp[analog_index, lead_time_index,
                     day_index] = sapm_out["p_mp"]

    return [p_mp, tcell, effective_irradiance]
Beispiel #14
0
 def time_get_ground_diffuse(self):
     irradiance.get_ground_diffuse(self.tilt, self.clearsky_irradiance.ghi)
Beispiel #15
0
sandia_module = sandia_modules.Canadian_Solar_CS5P_220M___2009_



# retrieve time and location parameters
time = forecast_data.index
a_point = fm.location

solpos = a_point.get_solarposition(time)
dni_extra = irradiance.get_extra_radiation(fm.time)
airmass = atmosphere.get_relative_airmass(solpos['apparent_zenith'])
poa_sky_diffuse = irradiance.haydavies(surface_tilt, surface_azimuth,
                           forecast_data['dhi'], forecast_data['dni'], dni_extra,
                           solpos['apparent_zenith'], solpos['azimuth'])

poa_ground_diffuse = irradiance.get_ground_diffuse(surface_tilt, ghi, albedo=albedo)
aoi = irradiance.aoi(surface_tilt, surface_azimuth, solpos['apparent_zenith'], solpos['azimuth'])

poa_irrad = irradiance.poa_components(aoi, forecast_data['dni'], poa_sky_diffuse,
                                        poa_ground_diffuse)

temperature = forecast_data['temp_air']
wnd_spd = forecast_data['wind_speed']
pvtemps = pvsystem.sapm_celltemp(poa_irrad['poa_global'], wnd_spd, temperature)

effective_irradiance = pvsystem.sapm_effective_irradiance(poa_irrad.poa_direct,
                            poa_irrad.poa_diffuse, airmass, aoi, sandia_module)
sapm_out = pvsystem.sapm(effective_irradiance, pvtemps['temp_cell'], sandia_module)
# print(sapm_out.head())
print(sapm_out['p_mp'])
plot = "pop"
Beispiel #16
0
def test_grounddiffuse_albedo_surface(irrad_data):
    result = irradiance.get_ground_diffuse(40, irrad_data['ghi'],
                                           surface_type='sand')
    assert_allclose(result, [0, 3.731058, 48.778813, 12.035025], atol=1e-4)
Beispiel #17
0
def test_grounddiffuse_albedo_invalid_surface(irrad_data):
    with pytest.raises(KeyError):
        irradiance.get_ground_diffuse(40,
                                      irrad_data['ghi'],
                                      surface_type='invalid')
Beispiel #18
0
    def __init__(self, panel=None, forecast_length=7, forecast_model=None):
        self.forecast_length = forecast_length
        if panel == None:
            self.panel = Panel()
        else:
            self.panel = panel

        if forecast_model == None:
            self.fm = GFS()
        else:
            self.fm = forecast_model

        self.start = pd.Timestamp(datetime.date.today(),
                                  tz=self.panel.tz)  # today's date
        self.end = self.start + pd.Timedelta(
            days=forecast_length)  # days from today

        print(
            "getting processed data with lat: %s, lng: %s, start:%s, end:%s" %
            (self.panel.latitude, self.panel.longitude, self.start, self.end))
        # get forecast data
        forecast_data = self.fm.get_processed_data(self.panel.latitude,
                                                   self.panel.longitude,
                                                   self.start, self.end)
        ghi = forecast_data['ghi']

        # get solar position
        time = forecast_data.index
        a_point = self.fm.location
        solpos = a_point.get_solarposition(time)

        # get PV(photovoltaic device) modules
        sandia_modules = pvsystem.retrieve_sam('SandiaMod')
        sandia_module = sandia_modules.Canadian_Solar_CS5P_220M___2009_

        dni_extra = irradiance.get_extra_radiation(
            self.fm.time)  # extra terrestrial radiation
        airmass = atmosphere.get_relative_airmass(solpos['apparent_zenith'])
        # POA: Plane Of Array: an image sensing device consisting of an array
        # (typically rectangular) of light-sensing pixels at the focal plane of a lens.
        # https://en.wikipedia.org/wiki/Staring_array

        # Diffuse sky radiation is solar radiation reaching the Earth's surface after
        # having been scattered from the direct solar beam by molecules or particulates
        # in the atmosphere.
        # https://en.wikipedia.org/wiki/Diffuse_sky_radiation
        poa_sky_diffuse = irradiance.haydavies(self.panel.surface_tilt,
                                               self.panel.surface_azimuth,
                                               forecast_data['dhi'],
                                               forecast_data['dni'], dni_extra,
                                               solpos['apparent_zenith'],
                                               solpos['azimuth'])

        # Diffuse reflection is the reflection of light or other waves or particles
        # from a surface such that a ray incident on the surface is scattered at many
        # angles rather than at just one angle as in the case of specular reflection.
        poa_ground_diffuse = irradiance.get_ground_diffuse(
            self.panel.surface_tilt, ghi, albedo=self.panel.albedo)

        # AOI: Angle Of Incidence
        aoi = irradiance.aoi(self.panel.surface_tilt,
                             self.panel.surface_azimuth,
                             solpos['apparent_zenith'], solpos['azimuth'])

        #  irradiance is the radiant flux (power) received by a surface per unit area
        # https://en.wikipedia.org/wiki/Irradiance
        poa_irrad = irradiance.poa_components(aoi, forecast_data['dni'],
                                              poa_sky_diffuse,
                                              poa_ground_diffuse)

        temperature = forecast_data['temp_air']
        wnd_spd = forecast_data['wind_speed']

        # pvtemps: pv temperature
        pvtemps = pvsystem.sapm_celltemp(poa_irrad['poa_global'], wnd_spd,
                                         temperature)

        # irradiance actually used by PV
        effective_irradiance = pvsystem.sapm_effective_irradiance(
            poa_irrad.poa_direct, poa_irrad.poa_diffuse, airmass, aoi,
            sandia_module)

        # SAPM: Sandia PV Array Performance Model
        # https://pvpmc.sandia.gov/modeling-steps/2-dc-module-iv/point-value-models/sandia-pv-array-performance-model/

        self.sapm_out = pvsystem.sapm(effective_irradiance,
                                      pvtemps['temp_cell'], sandia_module)

        sapm_inverters = pvsystem.retrieve_sam('sandiainverter')
        sapm_inverter = sapm_inverters[
            'ABB__MICRO_0_25_I_OUTD_US_208_208V__CEC_2014_']
        self.ac_power = pvsystem.snlinverter(self.sapm_out.v_mp,
                                             self.sapm_out.p_mp, sapm_inverter)