Beispiel #1
0
    def single_axis_irr(self, include_track_angles=False):
        """
        Calculate the irradiances incident on a surface that mounted on an ideal single-axis tracker

        :param include_track_angles: whether to include the tracker angles into the returned dataframe.
        :return: a dataframe of sun irradiances on the single-axis tracked surface.
        """

        tracker = SingleAxisTracker(axis_tilt=0,
                                    axis_azimuth=0,
                                    max_angle=180,
                                    backtrack=False)

        ngo = Location(latitude=self.latitude,
                       longitude=self.longitude,
                       altitude=0,
                       tz='Japan')
        solar_pos = ngo.get_solarposition(
            pd.DatetimeIndex(self.hour_df['avg_time']))

        tracker_angle = tracker.singleaxis(
            apparent_azimuth=solar_pos['azimuth'],
            apparent_zenith=solar_pos['apparent_zenith'])

        dni_arr = self.get_DNI()

        irr = tracker.get_irradiance(
            dni=dni_arr,
            ghi=self.hour_df['GHI'],
            dhi=self.hour_df['dHI'],
            solar_zenith=solar_pos['apparent_zenith'],
            solar_azimuth=solar_pos['azimuth'],
            surface_tilt=tracker_angle['surface_tilt'],
            surface_azimuth=tracker_angle['surface_azimuth'])

        irr['DNI'] = dni_arr

        n_df = pd.concat([self.hour_df, irr], axis=1)

        if include_track_angles == True:
            n_df = pd.concat([n_df, tracker_angle], axis=1)

        return n_df
Beispiel #2
0
def test_run_model_tracker(system, location, weather, mocker):
    system = SingleAxisTracker(module_parameters=system.module_parameters,
                               inverter_parameters=system.inverter_parameters)
    mocker.spy(system, 'singleaxis')
    mc = ModelChain(system, location)
    mc.run_model(weather.index, weather=weather)
    assert system.singleaxis.call_count == 1
    assert (mc.tracking.columns == ['tracker_theta', 'aoi', 'surface_azimuth',
                                    'surface_tilt']).all()
    assert mc.ac[0] > 0
    assert np.isnan(mc.ac[1])
Beispiel #3
0
def download_forecasts(request):
    modules_per_string = request.session['modules_per_string']
    strings_per_inverter = request.session['strings_per_inverter']
    module = request.session['module']
    inverter = request.session['inverter']
    latitude = request.session['latitude']
    longitude = request.session['longitude']
    tz = request.session['timezone']

    sandia_modules = retrieve_sam('SandiaMod')
    cec_inverters = retrieve_sam('SandiaInverter')

    # Parametros de la granja solar
    surface_tilt = 30
    surface_azimuth = 180  # pvlib uses 0=North, 90=East, 180=South, 270=West convention
    albedo = 0.2
    # Rango de tiempo
    start = pd.Timestamp(date.today(), tz=tz)
    # Pronostico a 3 días en adelante
    end = start + pd.Timedelta(days=3)

    module = pd.Series(sandia_modules[module])
    inverter = cec_inverters[inverter]

    # model a big tracker for more fun
    system = SingleAxisTracker(module_parameters=module,
                               inverter_parameters=inverter,
                               modules_per_string=modules_per_string,
                               strings_per_inverter=strings_per_inverter)

    # fx is a common abbreviation for forecast
    fx_model = GFS()

    fx_data = fx_model.get_processed_data(latitude, longitude, start, end)

    # use a ModelChain object to calculate modeling intermediates
    mc = ModelChain(system, fx_model.location)

    # extract relevant data for model chain
    mc.run_model(fx_data.index, weather=fx_data)

    AC = mc.ac.fillna(0)

    response = HttpResponse(content_type='text/csv')
    response[
        'Content-Disposition'] = 'attachment; filename=AC_5days_forecasts.csv'

    AC.to_csv(path_or_buf=response,
              sep=';',
              float_format='%.2f',
              index=True,
              decimal=",")
    return response
Beispiel #4
0
def test_run_model_tracker(system, location):
    system = SingleAxisTracker(module_parameters=system.module_parameters,
                               inverter_parameters=system.inverter_parameters)
    mc = ModelChain(system, location)
    times = pd.date_range('20160101 1200-0700', periods=2, freq='6H')
    ac = mc.run_model(times).ac

    expected = pd.Series(np.array([119.067713606, nan]), index=times)
    assert_series_equal(ac, expected, check_less_precise=2)

    expected = pd.DataFrame(
        np.array([[54.82513187, 90., 11.0039221, 11.0039221],
                  [nan, 0., 0., nan]]),
        columns=['aoi', 'surface_azimuth', 'surface_tilt', 'tracker_theta'],
        index=times)
    assert_frame_equal(mc.tracking, expected, check_less_precise=2)
Beispiel #5
0
def test_run_model_from_poa_tracking(sapm_dc_snl_ac_system, location,
                                     total_irrad):
    system = SingleAxisTracker(
        module_parameters=sapm_dc_snl_ac_system.module_parameters,
        temperature_model_parameters=(
            sapm_dc_snl_ac_system.temperature_model_parameters
        ),
        inverter_parameters=sapm_dc_snl_ac_system.inverter_parameters)
    mc = ModelChain(system, location, aoi_model='no_loss',
                    spectral_model='no_loss')
    ac = mc.run_model_from_poa(total_irrad).ac
    assert (mc.tracking.columns == ['tracker_theta', 'aoi', 'surface_azimuth',
                                    'surface_tilt']).all()
    expected = pd.Series(np.array([149.280238, 96.678385]),
                         index=total_irrad.index)
    assert_series_equal(ac, expected)
Beispiel #6
0
def get_cast(start_date, end_date):
    from pvlib.pvsystem import PVSystem, retrieve_sam

    from pvlib.temperature import TEMPERATURE_MODEL_PARAMETERS

    from pvlib.tracking import SingleAxisTracker

    from pvlib.modelchain import ModelChain

    sandia_modules = retrieve_sam('sandiamod')

    cec_inverters = retrieve_sam('cecinverter')

    module = sandia_modules['SolarWorld_Sunmodule_250_Poly__2013_']

    inverter = cec_inverters['ABB__TRIO_20_0_TL_OUTD_S1_US_480__480V_']

    temperature_model_parameters = TEMPERATURE_MODEL_PARAMETERS['sapm'][
        'open_rack_glass_glass']

    # model a single axis tracker
    system = SingleAxisTracker(
        module_parameters=module,
        inverter_parameters=inverter,
        temperature_model_parameters=temperature_model_parameters,
        modules_per_string=15,
        strings_per_inverter=4)

    # fx is a common abbreviation for forecast
    fx_model = GFS()

    forecast_mod = fx_model.get_processed_data(latitude, longitude, start_date,
                                               end_date)

    # use a ModelChain object to calculate modeling intermediates
    mchain = ModelChain(system, fx_model.location)

    # extract relevant data for model chain
    mchain.run_model(forecast_mod)
    acp = mchain.ac.fillna(0)
    return acp
Beispiel #7
0
def get_system(racking,
               axis_height,
               collector_width,
               axis_azimuth,
               gcr,
               module_parameters,
               temperature_model_parameters,
               axis_tilt=0,
               max_angle=0,
               backtrack=False,
               surface_tilt=0,
               surface_azimuth=0,
               albedo=0):
    '''
  Creates a PVSystem instance from PVLib (an input to ModelChain which defines a
  standard set of PV system attributes and modeling functions).
  
  Parameters:
  racking: string.
    mounting structure used for PV system
    either (tracker, ground-mount, rooftop, or canopy)
  axis_height: float.
    meters of racking tilt axis above ground
  collector_width: float.
    meter width of PV module perpendicular to axis of tilt
  axis_azimuth: float.
    compass direction along which the axis of rotation lies
    measured in decimal degrees East of North
  gcr: float.
    ratio of ground covered by PV modules within array to spacing betweeen
    modules
    used as common metric to refer to module spacing
  module_parameters: dict.
    module-specific parameters used to model dc output given irradiance
  temperature_model_parameters: dict.
    parameters used to convert ambient temperature to PV cell temperature
  axis_tilt: float.
    tracker requirement. The tilt of the axis of rotation in decimal degrees(DD)
  max_angle: float.
    tracker requirement. The max tilt allowed of a single-axis tracker in DD
  backtrack: boolean.
    tracker requirement. Whether or not the tracking system uses a backtracking
    algorithm
  surface_tilt: float.
    non-tracker requirement. Tilt of a fixed-tilt racking system in DD
  surface_azimuth: float.
    non-tracker requirement. Azimuth angle of the module surface East of North
  albedo: float.
    non-tracker requirement. The percent of light reflected from the ground
    
  Returns:
  pvlib.PVSystem
  
  Note: Would have used a kwargs parameter to but doesnt work with reticulate
  '''

    # Single-Axis Tracker
    if racking == 'tracker':
        system = SingleAxisTracker(axis_tilt=axis_tilt,
                                   axis_azimuth=axis_azimuth,
                                   max_angle=max_angle,
                                   backtrack=backtrack,
                                   gcr=gcr,
                                   module_parameters=module_parameters)
    # Fixed-tilt System
    else:
        system = PVSystem(surface_tilt=surface_tilt,
                          surface_azimuth=surface_azimuth,
                          module_parameters=module_parameters)

        # These attributes get declared as part of SingleAxisTracker but not in
        # PVSystem
        system.axis_azimuth = axis_azimuth
        system.gcr = gcr
        system.backtrack = False

        # If racking is canopy or rooftop
        if racking != 'ground-mount':
            # Override system albedo for canopy and rooftop systems since time
            # series albedo calculations assume typical ground coverage (grass)
            system.albedo = albedo

        if racking == 'rooftop':
            system.module_parameters['bifaciality'] = 0

    # Adding Attributes allows ModelChain to self-contain all project inputs
    system.axis_height = axis_height
    system.collector_width = collector_width
    system.temperature_model_parameters = temperature_model_parameters

    return system
Beispiel #8
0
def construct_pvsystem(
        inverter: models.Inverter) -> Union[PVSystem, SingleAxisTracker]:
    """Construct a pvlib.pvsystem.PVSystem (or SingleAxisTracker) from an
    Inverter object"""
    system_kwargs = dict(
        inverter=inverter.make_model,
        inverter_parameters=inverter.inverter_parameters.dict(),
        name=inverter.name,
    )
    if inverter.losses is not None:
        system_kwargs["losses_parameters"] = inverter.losses.dict()

    array_params = []
    tracking_params = []
    is_single_axis = False
    for array in inverter.arrays:
        array_params.append(
            dict(
                albedo=array.albedo,
                module=array.make_model,
                module_parameters=array.module_parameters.pvlib_dict(),
                temperature_model_parameters=array.
                temperature_model_parameters.dict(),
                modules_per_string=array.modules_per_string,
                strings=array.strings,
                name=array.name,
            ))
        if isinstance(array.tracking, models.SingleAxisTracking):
            tracking_params.append(
                dict(
                    axis_tilt=array.tracking.axis_tilt,
                    axis_azimuth=array.tracking.axis_azimuth,
                    gcr=array.tracking.gcr,
                    backtrack=array.tracking.backtracking,
                ))
            is_single_axis = True
            # later might also need to keep track of the array class to use
        else:
            tracking_params.append(
                dict(
                    surface_tilt=array.tracking.tilt,
                    surface_azimuth=array.tracking.azimuth,
                ))

    if is_single_axis:
        if len(tracking_params) > 1:  # pragma: no cover
            # until pvlib/pvlib-python#1109 is resolved
            raise ValueError(
                "Single axis tracking with multiple arrays not supported")
        else:
            return SingleAxisTracker(arrays=[
                Array(**array_params[0],
                      surface_tilt=None,
                      surface_azimuth=None)
            ],
                                     **tracking_params[0],
                                     **system_kwargs)
    else:
        system_kwargs["arrays"] = [
            Array(**atp[0], **atp[1])
            for atp in zip(array_params, tracking_params)
        ]
        return PVSystem(**system_kwargs)
Beispiel #9
0
def pvlib_location(request):
    if request.method == 'POST':
        formulario = location_pv(request.POST)
        if formulario.is_valid():
            params = formulario.cleaned_data

            #Creación del diccionario para las caracteristicas del modulo PV utilizado en Cutonalá
            #Canadian_Solar_CS6X_320P___2016_ = {"Vintage": 2016, "Area":1.91 , "Material": "Poly-crystalline", "Cells_in_Series": 72, "Parallel_Strings": 1,
            #       "Isco":9.26, "Voco":45.3, "Impo":8.69, "Vmpo":36.8, "Aisc":0.000397, "Aimp":0.000181, "C0":1.01284, "C1":-0.0128398, "Bvoco":-0.21696,
            #      "Mbvoc":0, "Bvmpo":-0.235488, "Mbvmp":0, "N":1.4032, "C2":0.279317, "C3":-7.24463, "A0":0.928385, "A1":0.068093, "A2":-0.0157738, "A3":0.0016605999999999997,
            #     "A4":-6.929999999999999e-05, "B0":1, "B1":-0.002438, "B2":0.0003103, "B3":-1.246e-05, "B4":2.1100000000000002e-07, "B5":-1.36e-09, "DTC":3.0, "FD":1, "A":-3.4064099999999997, "B":-0.0842075, "C4":0.9964459999999999,
            #    "C5":0.003554, "IXO":4.97599, "IXXO":3.18803, "C6":1.15535, "C7":-0.155353, "Notes":"caracteristicas del modulo instalado en CUT"}

            #module = pd.Series(Canadian_Solar_CS6X_320P___2016_, name="Canadian_Solar_CS6X_320P___2016_")

            #Modulo desde la librería de Sandia labs
            #cec_inverters = retrieve_sam('cecinverter')
            #inverter = cec_inverters['SMA_America__SC630CP_US_315V__CEC_2012_']

            modules_per_string = params['modules_per_string']
            strings_per_inverter = params['strings_per_inverter']
            module = params['module']
            inverter = params['inverter']

            request.session['modules_per_string'] = modules_per_string
            request.session['strings_per_inverter'] = strings_per_inverter
            request.session['module'] = module
            request.session['inverter'] = inverter

            #Calcular la potencia CD, aqui debemos tener el diccionario para el tipo de Modulo en CUTonalá
            sandia_modules = retrieve_sam('SandiaMod')

            #### Modulo desde la librería de Sandia labs
            cec_inverters = retrieve_sam('cecinverter')

            # Lugar Tonalá
            latitude, longitude = params['latitude'], params['longitude']

            request.session['latitude'] = latitude
            request.session['longitude'] = longitude

            tz = tzwhere.tzwhere().tzNameAt(latitude, longitude)

            request.session['timezone'] = tz

            # Parametros de la granja solar
            surface_tilt = 30
            surface_azimuth = 180  # pvlib uses 0=North, 90=East, 180=South, 270=West convention
            albedo = 0.2
            # Rango de tiempo
            start = pd.Timestamp(date.today(), tz=tz)
            # Pronostico a 3 días en adelante
            end = start + pd.Timedelta(days=5)

            module = pd.Series(sandia_modules[module])

            inverter = cec_inverters[inverter]

            # model a big tracker for more fun
            system = SingleAxisTracker(
                module_parameters=module,
                inverter_parameters=inverter,
                modules_per_string=modules_per_string,
                strings_per_inverter=strings_per_inverter)

            # fx is a common abbreviation for forecast
            fx_model = GFS()

            fx_data = fx_model.get_processed_data(latitude, longitude, start,
                                                  end)

            # use a ModelChain object to calculate modeling intermediates
            mc = ModelChain(system, fx_model.location)

            # extract relevant data for model chain
            mc.run_model(fx_data.index, weather=fx_data)
            #mc.run_model(fx_data)

            AC = mc.ac.fillna(0)
            #AC = pd.DataFrame(AC)

            #labeles = AC.keys()

            #valores = AC.values()

            #data = {
            #    "Dates": labeles,
            #    "Power (W)": valores,
            #}
            #here we print the data the correct thing would be to use them to graph them
            #print(AC.head())

            #return render(request, 'chart.html', {'forma': formulario})

            template = 'chart.html'
            #columns = [{'field': 'date', 'title': 'Date'}, {'field': 'value', 'title': 'Value'}]
            #Write the DataFrame to JSON (as easy as can be)
            #json = AC.to_json(orient='records')  # output just the records (no fieldnames) as a collection of tuples
            #Proceed to create your context object containing the columns and the data
            #context = {
            #          'data': json,
            #         'columns': columns
            #       }
            #And render it!
            #return render(request, template, context)
            AC = AC.reset_index()
            AC.rename(columns={
                'index': 'Time',
                0: 'AC Power (W)'
            },
                      inplace=True)
            figure = px.line(AC, x='Time', y='AC Power (W)')
            #figure.update_layout(title="Your 5 days AC power output forecast (W)", font=dict(size=20, color='black'))
            #figure.update_xaxes(title_font=dict(size=16, color='black'))
            #figure.update_yaxes(title_font=dict(size=16, color='black'))
            figure.update_xaxes(dtick=10800000)

            plot_div = plot(figure,
                            image_height='100%',
                            output_type='div',
                            include_plotlyjs=False)

            context = {'linechart': plot_div}

            return render(request, template, context)
    else:
        formulario = location_pv()

    return render(request, 'forecast_data.html', {'form': formulario})
Beispiel #10
0
def PVlibwrapper(PV_instance, tmy, return_model_object=False):
    PV = PV_instance

    tmy.site = Location(tmy.lat, tmy.lon)

    cec_inverters = pvlib.pvsystem.retrieve_sam("cecinverter")
    cec_modules = pvlib.pvsystem.retrieve_sam("CECMod")

    # default: Jinko Solar Co Ltd JKM350M 72 V
    module = cec_modules[PV.module]

    # default: Huawei Technologies Co Ltd SUN2000 100KTL USH0 800V
    cec_inverter = cec_inverters[PV.inverter]

    temperature_model_parameters = TEMPERATURE_MODEL_PARAMETERS["sapm"][
        "open_rack_glass_glass"]

    if PV.tracking:
        system = SingleAxisTracker(
            axis_tilt=0,
            axis_azimuth=PV.azimuth,
            module_parameters=module,
            inverter_parameters=cec_inverter,
            temperature_model_parameters=temperature_model_parameters,
            strings_per_inverter=PV.strings_per_inverter,
            modules_per_string=PV.modules_per_string,
        )
        losses_model = "no_loss"
    else:
        system = PVSystem(
            surface_tilt=PV.tilt,
            surface_azimuth=PV.azimuth,
            module_parameters=module,
            inverter_parameters=cec_inverter,
            temperature_model_parameters=temperature_model_parameters,
            strings_per_inverter=PV.strings_per_inverter,
            modules_per_string=PV.modules_per_string,
        )
        losses_model = "pvwatts"

    total_module_power = PV.strings_per_inverter * PV.modules_per_string * module[
        "STC"]

    mc = ModelChain(
        system,
        tmy.site,
        aoi_model="ashrae",
        spectral_model="no_loss",
        losses_model=losses_model,
        transposition_model="perez",
    )

    if hasattr(PV, "bifacial_irradiance"):
        mc.run_model_from_effective_irradiance(PV.bifacial_irradiance)
        print()
        print()
        print(f"{PV.name} triggered run_from")
        print()
        print()
    else:
        mc.run_model(PVlibweather(tmy))
        print()
        print()
        print(f"{PV.name} triggered run_model")
        print()
        print()

    normalized_power = mc.ac / total_module_power
    scaled_power = normalized_power * PV.installed
    # reset index
    scaled_power.index = PV.state.index

    if return_model_object:
        return mc, scaled_power
    else:
        return scaled_power