I have been researching Pvlib and was wondering if I am missing something.
My dataset contains power values, GHI, DHI, tilted global irradiance and tilted diffuse irradiance values for 5 minutes recording intervals for 7 years dataset. I have been trying to calculate POA for each record using
poa_irradiance = pvlib.irradiance.get_total_irradiance(
surface_tilt=tilt_angle, surface_azimuth=0,
dni=dni_effective, ghi=tilted_ghi, dhi=tilted_diffuse,
solar_zenith=solar_position['apparent_zenith'],
solar_azimuth=solar_position['azimuth'],
model='haydavies',
albedo=0.2,
surface_type='urban')
since I don't have the DNI, I tried to calculate it using perez model as follows:
dni_perez = pvlib.irradiance.perez(ghi, dhi, location.latitude, solar_position['apparent_zenith'], solar_position['azimuth'], airmass)
I have some concerns:
1- GHI and DHI are used to calculate DNI. No tilted values are used here as since DNI is mainly calculated using horizontal values
2- For POA, we use tilted global and diffuse values as we care about out system.
3- I am not sure if Perez model is used to calculate DNI. The documentation says that it is used to calculate diffuse irradiance and DNI is used as an input.
4- I have included my full code below for your reference.
import pandas as pd
import pvlib
# Load the solar irradiance data from the CSV file
data = pd.read_csv(r"C:\Users\test\Downloads\70-Site_3-BP-Solar.csv")
# Set up the location information for the site
latitude = -23.761683875154326
longitude = 133.87495009067854
altitude = 560
tz = 'Australia/Darwin'
location = pvlib.location.Location(latitude=latitude, longitude=longitude, altitude=altitude, tz=tz)
# Calculate the solar position and air mass for each timestamp in the data
times = pd.to_datetime(data['timestamp']).dt.tz_localize(tz)
solar_position = location.get_solarposition(times)
airmass = location.get_airmass(times)['airmass_absolute']
# Calculate the DNI for each timestamp using the Perez model
ghi = data['Global_Horizontal_Radiation']
dhi = data['Diffuse_Horizontal_Radiation']
dni_perez = pvlib.irradiance.perez(ghi, dhi, location.latitude, solar_position['apparent_zenith'], solar_position['azimuth'], airmass)
# Calculate the POA irradiance for each timestamp using the estimated DNI and the tilted global and diffuse components
tilt_angle = 20.0
tilted_ghi = data['Radiation_Global_Tilted']
tilted_dhi = data['Radiation_Diffuse_Tilted'] / (5 * 60) # convert to W/m2
tilted_diffuse = pvlib.irradiance.isotropic(tilted_dhi, tilt_angle)
poa_irradiance = pvlib.irradiance.get_total_irradiance(
surface_tilt=tilt_angle, surface_azimuth=0,
dni=dni_perez, ghi=tilted_ghi, dhi=tilted_diffuse,
solar_zenith=solar_position['apparent_zenith'],
solar_azimuth=solar_position['azimuth'],
model='haydavies',
albedo=0.2,
surface_type='urban')
# Add the POA data to the DataFrame
data['POA'] = poa_irradiance['poa_global']
data.to_csv(r"C:\Users\test\Downloads\POA.csv")
Thanks,
Global horizontal irradiance (GHI) consists of diffuse horizontal irradiance (DHI), and direct normal irradiance (DNI) projected onto the horizontal. This can be expressed mathematically as:
GHI = DHI + DNI * cos(solar_zenith)
Thus, if you have two of the three components you can easily calculate the third. The calculated DNI can be rather spiky at low solar elevation (as cos(solar_zenith) approaches zero). Therefore, you might want to check out the pvlib.irradiance.complete_irradiance function which uses the above equation but imposes some limitations on the returned values to avoid unrealistic results.
Once you have the three irradiance components, you can use a transposition model (e.g., Perez) to calculate the irradiance on a tilted plane. Transposition models typically require knowledge of DNI and DHI and return POA.
Last, you write that you want to calculate POA (plane-of-array), this is just a different terminology for global tilted irradiance (GTI), which you mention you already have.