pvlib / pvlib-python

A set of documented functions for simulating the performance of photovoltaic energy systems.
https://pvlib-python.readthedocs.io
BSD 3-Clause "New" or "Revised" License
1.19k stars 998 forks source link

how to use CECMod Modules to predict energy output #1090

Closed caseymcgon closed 3 years ago

caseymcgon commented 3 years ago

I'm trying to reproduce the code here using a 'CECMod' instead of a 'SandiaMod'

So, instead of instantiating sandia_modules = pvlib.pvsystem.retrieve_sam('SandiaMod'), I do sandia_modules = pvlib.pvsystem.retrieve_sam('CECMod').

However, the CECMod DataFrame has fewer rows than the SandiaMod DataFrame. As such, there are some rows in SandiaMod (like A[0], A[1], A[2], A[3], A[4], B[0], etc.) that don't occur in CECMod. Unfortunately, those rows are utilized to calculate the effective irradiance, and thus the ultimate energy output of our system. Since CECMod has incomplete information, the energy output cannot be calculated. That means none of the modules in CECMod can be used to calculate the energy output of the system using this method.

Can someone direct me toward a way to calculate energy output that is compatible with modules in the CECMod DataFrame?

mikofski commented 3 years ago

@caseymcgon CEC modules are different than Sandia modules, and use different energy conversion functions, the first called calcparams_cec followed by max_power_point

Look for where it says: # this is the magic

import os
import pvlib
import pandas as pd

YEAR = 1990
STARTDATE = '%d-01-01T00:00:00' % YEAR
ENDDATE = '%d-12-31T23:59:59' % YEAR
TIMES = pd.date_range(start=STARTDATE, end=ENDDATE, freq='H')
INVERTERS = pvlib.pvsystem.retrieve_sam('CECInverter')
INVERTER_10K = INVERTERS['SMA_America__SB10000TL_US__240V_']
CECMODS = pvlib.pvsystem.retrieve_sam('CECMod')
CECMOD_POLY = CECMODS['Canadian_Solar_Inc__CS6X_300P']
CECMOD_MONO = CECMODS['Canadian_Solar_Inc__CS6X_300M']
LATITUDE, LONGITUDE = 40.5137, -108.5449
NREL_API_KEY = os.getenv('NREL_API_KEY', 'DEMO_KEY')
EMAIL = os.getenv('EMAIL', 'bwana.marko@yahoo.com')

header, data = pvlib.iotools.get_psm3(LATITUDE, LONGITUDE, NREL_API_KEY, EMAIL)
# get solar position
data.index = TIMES
sp = pvlib.solarposition.get_solarposition(
        TIMES, LATITUDE, LONGITUDE)
solar_zenith = sp.apparent_zenith.values
solar_azimuth = sp.azimuth.values
dni = data.DNI.values
ghi = data.GHI.values
dhi = data.DHI.values
surface_albedo = data['Surface Albedo'].values
temp_air = data.Temperature.values
dni_extra = pvlib.irradiance.get_extra_radiation(TIMES).values

tracker = pvlib.tracking.singleaxis(solar_zenith, solar_azimuth)
surface_tilt = tracker['surface_tilt']
surface_azimuth = tracker['surface_azimuth']
poa_sky_diffuse = pvlib.irradiance.get_sky_diffuse(
        surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
        dni, ghi, dhi, dni_extra=dni_extra, model='haydavies')
aoi = tracker['aoi']
poa_ground_diffuse = pvlib.irradiance.get_ground_diffuse(
        surface_tilt, ghi, albedo=surface_albedo)
poa = pvlib.irradiance.poa_components(
        aoi, dni, poa_sky_diffuse, poa_ground_diffuse)
poa_direct = poa['poa_direct']
poa_diffuse = poa['poa_diffuse']
poa_global = poa['poa_global']
iam = pvlib.iam.ashrae(aoi)
effective_irradiance = poa_direct*iam + poa_diffuse
temp_cell = pvlib.temperature.pvsyst_cell(poa_global, temp_air)

# this is the magic
cecparams = pvlib.pvsystem.calcparams_cec(
        effective_irradiance, temp_cell,
        CECMOD_MONO.alpha_sc, CECMOD_MONO.a_ref,
        CECMOD_MONO.I_L_ref, CECMOD_MONO.I_o_ref,
        CECMOD_MONO.R_sh_ref, CECMOD_MONO.R_s, CECMOD_MONO.Adjust)
mpp = pvlib.pvsystem.max_power_point(*cecparams, method='newton')
mpp = pd.DataFrame(mpp, index=TIMES)
Edaily = mpp.p_mp.resample('D').sum()
cwhanse commented 3 years ago

@caseymcgon can you repost your question to the pvlib googlegroup or the pvlib stackoverflow channel? This is a question about usage and there are likely other users who would benefit from the discussion. Here, the responses will be lost with time.

mikofski commented 3 years ago

Hi @caseymcgon , I've fixed the typos in the code. It works now, here's the output I get CECMOD_Edaily

Sorry for the typos, I was adapting this from some other code, and I did this on my phone. Next time I'll be more careful.