Source code for optihood.sources

import oemof.solph as solph
import numpy as np
import pandas as pd
import pvlib


[docs]class PV(solph.Source): def __init__(self, label, buildingLabel, outputs, peripheral_losses, latitude, longitude, pv_tilt, pv_efficiency, roof_area, zenith_angle, pv_azimuth, irradiance_global, irradiance_diffuse, temp_amb_pv, capacityMin, capacityMax, epc, base, env_capa, env_flow, varc): # Creation of a df with 3 columns data = self.computePvSolarPosition(irradiance_diffuse, irradiance_global, latitude, longitude, pv_azimuth, pv_tilt, temp_amb_pv) self.pv_electricity = np.minimum(self.pv_precalc(temp_amb_pv, data['pv_ira']/1000), capacityMax + base) if not (np.isnan(roof_area) or np.isnan(zenith_angle) or np.isnan(pv_efficiency)): self.surface_used = self._calculateArea(zenith_angle, pv_tilt, pv_azimuth, pv_efficiency) else: self.surface_used = np.nan super(PV, self).__init__(label=label + '__' + buildingLabel, outputs={outputs: solph.Flow( investment=solph.Investment( ep_costs=epc, minimum=capacityMin, maximum=capacityMax, nonconvex=True, space=self.surface_used, roof_area=roof_area, offset=base, env_per_capa=env_capa, ), variable_costs=varc, env_per_flow=env_flow, max=self.pv_electricity )} )
[docs] def computePvSolarPosition(self, irradiance_diffuse, irradiance_global, latitude, longitude, pv_azimuth, pv_tilt, temp_amb_pv): data = pd.DataFrame( { 'ghi': irradiance_global, 'dhi': irradiance_diffuse, 'temp_amb': temp_amb_pv } ) solposition = pvlib.solarposition.get_solarposition( time=data.index, latitude=latitude, longitude=longitude ) dni = pvlib.irradiance.dni( ghi=data['ghi'], dhi=data['dhi'], zenith=solposition['apparent_zenith'] ) total_irradiation = pvlib.irradiance.get_total_irradiance( surface_tilt=pv_tilt, surface_azimuth=pv_azimuth, solar_zenith=solposition['apparent_zenith'], solar_azimuth=solposition['azimuth'], dni=dni.fillna(0), # fill NaN values with '0' ghi=data['ghi'], dhi=data['dhi'], ) data['pv_ira'] = total_irradiation['poa_global'] return data
# model according to Energy management algorithms description. D6.2 v1.0 # nominal power is 1 KW due to the normed optimizer
[docs] def pv_precalc(self, temp_amb, i_H_t, a1=17.23292, a2=0.451708, a3=22.706, a4=-0.062059, a5=0.04277774, a6=9.692792, a7=-1.885868, a8=6.6): temp_cell = a1 + a2 * temp_amb + a3 * i_H_t pvPower = np.maximum(0, (a4*i_H_t + a5)*temp_cell+a6 * i_H_t+a7) / a8 return pvPower
[docs] def getPV(self): return self.__pv
def _calculateArea(self, zenith_angle, pv_tilt, pv_azimuth, pv_efficiency): coeff = -np.sin((zenith_angle+pv_tilt)*np.pi/180)*np.cos(pv_azimuth*np.pi/180)/np.sin(zenith_angle*np.pi/180)/pv_efficiency return coeff