Modell funktioniert, Jahr 2019 eingestellt
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
|
production_profile.csv
|
||||||
17522
Lastprofil_final_H0.csv
17522
Lastprofil_final_H0.csv
File diff suppressed because it is too large
Load Diff
11
main.py
11
main.py
@@ -1,16 +1,15 @@
|
|||||||
from neighborhood import Producer, Consumer, Neighborhood
|
from neighborhood import Producer, Consumer, Neighborhood
|
||||||
|
|
||||||
# Anzahl Haushalte ohne PV-Anlagen
|
# Anzahl Haushalte ohne PV-Anlagen
|
||||||
num_consumer = 50
|
num_consumer = 5
|
||||||
avg_consumption_per_consumer = 10
|
|
||||||
|
|
||||||
# Anzahl Haushalte mit PV-Anlagen
|
# Anzahl Haushalte mit PV-Anlagen
|
||||||
num_producer = 10
|
num_producer = 5
|
||||||
avg_production_per_producer = 20
|
|
||||||
|
|
||||||
# Instanzen für Erzeuger und Verbraucher anlegen
|
# Instanzen für Erzeuger und Verbraucher anlegen
|
||||||
consumer = Consumer(num_consumer, avg_consumption_per_consumer)
|
producer = Producer(num_producer)
|
||||||
producer = Producer(num_producer, avg_consumption_per_consumer, avg_production_per_producer)
|
consumer = Consumer(num_consumer)
|
||||||
|
|
||||||
# Instanz für Nachbarschaft anlegen und Ergebnis plotten
|
# Instanz für Nachbarschaft anlegen und Ergebnis plotten
|
||||||
neighborhood = Neighborhood(producer, consumer)
|
neighborhood = Neighborhood(producer, consumer)
|
||||||
|
|||||||
105
neighborhood.py
105
neighborhood.py
@@ -1,85 +1,88 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
import pv_input as pv
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
class Consumer:
|
|
||||||
def __init__(self, quantity, average_consumption):
|
|
||||||
self.quantity = quantity
|
|
||||||
self.consumption_profile = self.create_consumption_profile()
|
|
||||||
self.average_consumption = average_consumption
|
|
||||||
|
|
||||||
def create_consumption_profile(self):
|
|
||||||
profile = np.zeros(24)
|
|
||||||
peak_hours = [12]
|
|
||||||
for hour in peak_hours:
|
|
||||||
profile[hour] = 1.5
|
|
||||||
for hour in range(24):
|
|
||||||
if hour not in peak_hours:
|
|
||||||
profile[hour] = 0.8
|
|
||||||
return profile
|
|
||||||
|
|
||||||
def calculate_daily_consumption(self):
|
|
||||||
daily_consumption = self.quantity * self.average_consumption * self.consumption_profile
|
|
||||||
return daily_consumption
|
|
||||||
|
|
||||||
class Producer:
|
class Producer:
|
||||||
def __init__(self, quantity, average_consumption, average_production):
|
def __init__(self, quantity):
|
||||||
self.quantity = quantity
|
self.quantity = quantity
|
||||||
self.consumption_profile = self.create_consumption_profile()
|
self.consumption_profile = self.create_consumption_profile()
|
||||||
self.average_consumption = average_consumption
|
|
||||||
self.production_profile = self.create_production_profile()
|
self.production_profile = self.create_production_profile()
|
||||||
self.average_production = average_production
|
self.final_consumption = self.calculate_final_consumption()
|
||||||
|
self.final_production = self.calculate_final_production()
|
||||||
|
|
||||||
|
# Vebrauchsprofil aus CSV-Datei in Dataframe einlesen und die Leistungs-Series extrahieren
|
||||||
def create_consumption_profile(self):
|
def create_consumption_profile(self):
|
||||||
profile = np.zeros(24)
|
consumption_profile = pd.read_csv('Lastprofil_final_H0.csv',delimiter=';')
|
||||||
peak_hours = [8,12,13,18,19,20,21]
|
return consumption_profile['Leistung']
|
||||||
for hour in peak_hours:
|
|
||||||
profile[hour] = 1.5
|
|
||||||
for hour in range(24):
|
|
||||||
if hour not in peak_hours:
|
|
||||||
profile[hour] = 0.5
|
|
||||||
return profile
|
|
||||||
|
|
||||||
|
# Verbrauchsprofil mit der Anzahl der Haushalte multiplizieren
|
||||||
|
def calculate_final_consumption(self):
|
||||||
|
final_consumption = self.consumption_profile.mul(self.quantity)
|
||||||
|
return final_consumption
|
||||||
|
|
||||||
|
# Erzegungsprofil über PV_Input.py erstelln, in .csv schreiben und von dort dann die Leistungs-Series extrahieren
|
||||||
def create_production_profile(self):
|
def create_production_profile(self):
|
||||||
profile = np.zeros(24)
|
production_profile = pv.create_production_profile()
|
||||||
peak_hours = [8,9,10,11,12,13,14,15,16,17,18,19]
|
production_profile.to_csv('production_profile.csv', sep=';',header=['Leistung'])
|
||||||
for hour in peak_hours:
|
production_profile = pd.read_csv('production_profile.csv',delimiter=';')
|
||||||
profile[hour] = 1.5
|
return production_profile['Leistung']
|
||||||
for hour in range(24):
|
|
||||||
if hour not in peak_hours:
|
# Erzeugungsprofil mit der Anzahl der Haushalte multiplizieren
|
||||||
profile[hour] = 0
|
def calculate_final_production(self):
|
||||||
return profile
|
final_production = self.production_profile.mul(self.quantity)
|
||||||
|
return final_production
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Consumer:
|
||||||
|
def __init__(self, quantity):
|
||||||
|
self.quantity = quantity
|
||||||
|
self.consumption_profile = self.create_consumption_profile()
|
||||||
|
self.final_consumption = self.calculate_final_consumption()
|
||||||
|
|
||||||
|
# Vebrauchsprofil aus CSV-Datei in Dataframe einlesen und die Leistungs-Series extrahieren, Werte in Watt umrechnen und mit 4 multiplizieren, da Originalwerte 15-minütlich waren
|
||||||
|
def create_consumption_profile(self):
|
||||||
|
consumption_profile = pd.read_csv('Lastprofil_final_H0.csv',delimiter=';')
|
||||||
|
return consumption_profile['Leistung']*1000*4
|
||||||
|
|
||||||
|
# Verbrauchsprofil mit der Anzahl der Haushalte multiplizieren
|
||||||
|
def calculate_final_consumption(self):
|
||||||
|
final_consumption = self.consumption_profile.mul(self.quantity)
|
||||||
|
return final_consumption
|
||||||
|
|
||||||
def calculate_daily_consumption(self):
|
|
||||||
daily_consumption = self.quantity * self.average_consumption * self.consumption_profile
|
|
||||||
return daily_consumption
|
|
||||||
|
|
||||||
def calculate_daily_production(self):
|
|
||||||
daily_production = self.quantity * self.average_production * self.production_profile
|
|
||||||
return daily_production
|
|
||||||
|
|
||||||
class Neighborhood:
|
class Neighborhood:
|
||||||
def __init__(self, producer, consumer):
|
def __init__(self, producer, consumer):
|
||||||
self.producer = producer
|
self.producer = producer
|
||||||
self.consumer = consumer
|
self.consumer = consumer
|
||||||
|
|
||||||
|
# Gesamterzeugung, Gesamtverbrauch und Nettoverbrauch plotten
|
||||||
def plot_consumption(self):
|
def plot_consumption(self):
|
||||||
total_consumption = -1*(self.consumer.calculate_daily_consumption() + self.producer.calculate_daily_consumption())
|
total_consumption = -1*(self.consumer.final_consumption + self.producer.final_consumption)
|
||||||
total_production = self.producer.calculate_daily_production()
|
total_production = self.producer.final_production
|
||||||
net_value = total_consumption + total_production
|
net_value = total_consumption + total_production
|
||||||
|
|
||||||
# X-Werte anlegen
|
# X-Werte anlegen, einen Wert löschen da 8761 Werte vorhanden sind, aber nur 8760 benötigt werden
|
||||||
x = range(24)
|
x = pd.date_range(start='2018-12-31', end ='2019-12-31', freq='1h')
|
||||||
x_labels = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24']
|
x = x[:-1]
|
||||||
# Plot dimensionieren
|
# Plot dimensionieren
|
||||||
plt.figure(figsize=(10, 6))
|
plt.figure(figsize=(10, 6))
|
||||||
# y-Werte den x-Werten zuordnen
|
# y-Werte den x-Werten zuordnen
|
||||||
plt.plot(x, total_consumption, '--', x, total_production, '--', x, net_value, '-')
|
plt.bar(x, total_consumption)
|
||||||
|
plt.bar(x, total_production)
|
||||||
|
plt.bar(x, net_value)
|
||||||
|
#plt.plot(x, net_value, '-')
|
||||||
# Titel und Achsenbeschriftungen anlegen
|
# Titel und Achsenbeschriftungen anlegen
|
||||||
plt.xlabel('Stunde')
|
plt.xlabel('Stunde')
|
||||||
plt.ylabel('Strom (kWh)')
|
plt.ylabel('Strom (kWh)')
|
||||||
plt.title('Produktion/Verbrauch Nachbarschaft')
|
plt.title('Produktion/Verbrauch Nachbarschaft')
|
||||||
# X-Werten die Labels zuordnen
|
# X-Ticks nur monatlich plotten
|
||||||
plt.xticks(x, x_labels)
|
monthly_ticks = pd.date_range(start='2018-12-31', end ='2019-12-31', freq='1MS')
|
||||||
|
plt.xticks(monthly_ticks)
|
||||||
# Legende anlegen
|
# Legende anlegen
|
||||||
plt.legend(['Verbrauch', 'Produktion', 'Netto-Wert'], loc='upper right')
|
plt.legend(['Verbrauch', 'Produktion', 'Netto-Wert'], loc='upper right')
|
||||||
# X-Labels rotieren
|
# X-Labels rotieren
|
||||||
|
|||||||
64
pv_input.py
64
pv_input.py
@@ -39,44 +39,48 @@ surface_azimuth = 180
|
|||||||
# Temperaturparameter definieren
|
# Temperaturparameter definieren
|
||||||
temperature_parameters = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_glass']
|
temperature_parameters = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_glass']
|
||||||
|
|
||||||
# Location + PVSystem-Objekte anlegen und Modelchain damit füttern
|
def create_production_profile():
|
||||||
location = Location(latitude, longitude, tz)
|
# Location + PVSystem-Objekte anlegen und Modelchain damit füttern
|
||||||
system = PVSystem(surface_tilt=surface_tilt, surface_azimuth=surface_azimuth, module_parameters=module,
|
location = Location(latitude, longitude, tz)
|
||||||
inverter_parameters=inverter, temperature_model_parameters=temperature_parameters,
|
system = PVSystem(surface_tilt=surface_tilt, surface_azimuth=surface_azimuth, module_parameters=module,
|
||||||
modules_per_string=modules_per_string, strings_per_inverter=strings_per_inverter)
|
inverter_parameters=inverter, temperature_model_parameters=temperature_parameters,
|
||||||
|
modules_per_string=modules_per_string, strings_per_inverter=strings_per_inverter)
|
||||||
|
|
||||||
modelchain = ModelChain(system, location)
|
modelchain = ModelChain(system, location)
|
||||||
|
|
||||||
# Ertragssimulation mit Clear-Sky Modell
|
# Ertragssimulation mit Clear-Sky Modell
|
||||||
|
|
||||||
# Index-Spalte mit Zeiten für clear-sky Dataset anlegen
|
# Index-Spalte mit Zeiten für clear-sky Dataset anlegen
|
||||||
# times = pd.date_range(start='2020-01-01', end ='2020-12-31', freq='1h', tz=location.tz)
|
# times = pd.date_range(start='2020-01-01', end ='2020-12-31', freq='1h', tz=location.tz)
|
||||||
|
|
||||||
# clear_sky = location.get_clearsky(times)
|
# clear_sky = location.get_clearsky(times)
|
||||||
# #clear_sky.plot(figsize=(16,9))
|
# #clear_sky.plot(figsize=(16,9))
|
||||||
|
|
||||||
# modelchain.run_model(clear_sky)
|
# modelchain.run_model(clear_sky)
|
||||||
|
|
||||||
# Ertragssimulation mit realen Strahlungsdaten aus Wetterjahr
|
# Ertragssimulation mit realen Strahlungsdaten aus Wetterjahr
|
||||||
|
|
||||||
# Hier ist Süden Azimuth = 0°, bei PVLib ist es 180°
|
# Hier ist Süden Azimuth = 0°, bei PVLib ist es 180°
|
||||||
poa_data, meta, inputs = pvlib.iotools.get_pvgis_hourly(latitude=latitude, longitude=longitude, start=year, end=year, raddatabase='PVGIS-SARAH3', components=True, surface_tilt=surface_tilt,
|
poa_data, meta, inputs = pvlib.iotools.get_pvgis_hourly(latitude=latitude, longitude=longitude, start=year, end=year, raddatabase='PVGIS-SARAH3', components=True, surface_tilt=surface_tilt,
|
||||||
surface_azimuth=surface_azimuth-180, outputformat='json', usehorizon=True, userhorizon=None, pvcalculation=False, peakpower=None,
|
surface_azimuth=surface_azimuth-180, outputformat='json', usehorizon=True, userhorizon=None, pvcalculation=False, peakpower=None,
|
||||||
pvtechchoice='crystSi', mountingplace='free', loss=0, trackingtype=0, optimal_surface_tilt=False, optimalangles=False,
|
pvtechchoice='crystSi', mountingplace='free', loss=0, trackingtype=0, optimal_surface_tilt=False, optimalangles=False,
|
||||||
url='https://re.jrc.ec.europa.eu/api/', map_variables=True, timeout=30)
|
url='https://re.jrc.ec.europa.eu/api/', map_variables=True, timeout=30)
|
||||||
|
|
||||||
# Notwendige Spalten ausrechnen und hinzufügen, sodass Modelchain sie verwenden kann
|
# Notwendige Spalten ausrechnen und hinzufügen, sodass Modelchain sie verwenden kann
|
||||||
poa_data['poa_diffuse'] = poa_data['poa_sky_diffuse'] + poa_data['poa_ground_diffuse']
|
poa_data['poa_diffuse'] = poa_data['poa_sky_diffuse'] + poa_data['poa_ground_diffuse']
|
||||||
poa_data['poa_global'] = poa_data['poa_diffuse'] + poa_data['poa_direct']
|
poa_data['poa_global'] = poa_data['poa_diffuse'] + poa_data['poa_direct']
|
||||||
|
|
||||||
# Daten in csv exportieren
|
# Daten in csv exportieren
|
||||||
#poa_data.to_csv('poa_data.csv')
|
#poa_data.to_csv('poa_data.csv')
|
||||||
|
|
||||||
# Index des Dataframe mit datetime-Index von Pandas überschreiben
|
# Index des Dataframe mit datetime-Index von Pandas überschreiben
|
||||||
poa_data.index = pd.to_datetime((poa_data.index))
|
poa_data.index = pd.to_datetime((poa_data.index))
|
||||||
# Diese Funktion benötigt POA-Daten anstatt g(i)-Daten -> DOKU
|
# Diese Funktion benötigt POA-Daten anstatt g(i)-Daten -> DOKU
|
||||||
modelchain.run_model_from_poa(poa_data)
|
modelchain.run_model_from_poa(poa_data)
|
||||||
|
|
||||||
# Ergebnis plotten
|
# Ergebnis plotten
|
||||||
modelchain.results.ac.plot(figsize=(16,9))
|
#modelchain.results.ac.plot(figsize=(16,9))
|
||||||
plt.show()
|
#plt.show()
|
||||||
|
|
||||||
|
# Rückgabewert
|
||||||
|
return modelchain.results.ac
|
||||||
Reference in New Issue
Block a user