Flask Server

This commit is contained in:
Bla Bla 2024-03-29 08:27:39 +01:00
parent 74c9d349d1
commit 0dd766e8a6
5 changed files with 205 additions and 135 deletions

View File

@ -3,7 +3,6 @@
Dieses Projekt bietet eine umfassende Lösung zur Simulation und Optimierung eines Energiesystems, das auf erneuerbaren Energiequellen basiert. Mit Fokus auf Photovoltaik (PV)-Anlagen, Batteriespeichern (Akkus), Lastmanagement (Verbraucheranforderungen), Wärmepumpen, Elektrofahrzeugen und der Berücksichtigung von Strompreisdaten ermöglicht dieses System die Vorhersage und Optimierung des Energieflusses und der Kosten über einen bestimmten Zeitraum. Dieses Projekt bietet eine umfassende Lösung zur Simulation und Optimierung eines Energiesystems, das auf erneuerbaren Energiequellen basiert. Mit Fokus auf Photovoltaik (PV)-Anlagen, Batteriespeichern (Akkus), Lastmanagement (Verbraucheranforderungen), Wärmepumpen, Elektrofahrzeugen und der Berücksichtigung von Strompreisdaten ermöglicht dieses System die Vorhersage und Optimierung des Energieflusses und der Kosten über einen bestimmten Zeitraum.
## Todo ## Todo
- `Backend:` Flask Server
- `Backend:` Mehr Optimierungsparameter - `Backend:` Mehr Optimierungsparameter
- `Frontend:` User Management - `Frontend:` User Management
- `Frontend:` Grafische Ausgabe - `Frontend:` Grafische Ausgabe
@ -11,7 +10,7 @@ Dieses Projekt bietet eine umfassende Lösung zur Simulation und Optimierung ein
- `Frontend:` Festeingestellte E-Autos / Wärmepumpen in DB - `Frontend:` Festeingestellte E-Autos / Wärmepumpen in DB
- `Simulation:` Wärmepumpe allgemeineren Ansatz - `Simulation:` Wärmepumpe allgemeineren Ansatz
- `Simulation:` Strompreisvorhersage > 1D (Timeseries Forecast) - `Simulation:` Strompreisvorhersage > 1D (Timeseries Forecast)
- - `Dynamische Lasten:` z.B. eine Spülmaschine, welche gesteuert werdeb jabb,
## Installation ## Installation
@ -42,8 +41,6 @@ In diesem Projekt werden verschiedene Klassen verwendet, um die Komponenten eine
- `HeatPump`: Simuliert eine Wärmepumpe, einschließlich ihres Energieverbrauchs und ihrer Effizienz unter verschiedenen Betriebsbedingungen. - `HeatPump`: Simuliert eine Wärmepumpe, einschließlich ihres Energieverbrauchs und ihrer Effizienz unter verschiedenen Betriebsbedingungen.
- `EAuto`: Repräsentiert ein Elektrofahrzeug mit spezifischen Ladeanforderungen und -zeiten, optimiert die Ladevorgänge basierend auf Energieverfügbarkeit und -kosten.
- `Strompreis`: Bietet Informationen zu den Strompreisen, ermöglicht die Optimierung des Energieverbrauchs und der -erzeugung basierend auf Tarifinformationen. - `Strompreis`: Bietet Informationen zu den Strompreisen, ermöglicht die Optimierung des Energieverbrauchs und der -erzeugung basierend auf Tarifinformationen.
- `EMS`: Das Energiemanagementsystem (EMS) koordiniert die Interaktion zwischen den verschiedenen Komponenten, führt die Optimierung durch und simuliert den Betrieb des gesamten Energiesystems. - `EMS`: Das Energiemanagementsystem (EMS) koordiniert die Interaktion zwischen den verschiedenen Komponenten, führt die Optimierung durch und simuliert den Betrieb des gesamten Energiesystems.

View File

@ -11,6 +11,8 @@ from modules.class_load_container import *
from modules.class_eauto import * from modules.class_eauto import *
from pprint import pprint from pprint import pprint
import matplotlib
matplotlib.use('Agg') # Setzt das Backend auf Agg
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from modules.visualize import * from modules.visualize import *
from deap import base, creator, tools, algorithms from deap import base, creator, tools, algorithms
@ -83,7 +85,7 @@ def optimize():
stats.register("min", np.min) stats.register("min", np.min)
stats.register("max", np.max) stats.register("max", np.max)
algorithms.eaMuPlusLambda(population, toolbox, 50, 100, cxpb=0.5, mutpb=0.5, ngen=500, stats=stats, halloffame=hof, verbose=True) algorithms.eaMuPlusLambda(population, toolbox, 100, 200, cxpb=0.3, mutpb=0.3, ngen=500, stats=stats, halloffame=hof, verbose=True)
#algorithms.eaSimple(population, toolbox, cxpb=0.2, mutpb=0.2, ngen=1000, stats=stats, halloffame=hof, verbose=True) #algorithms.eaSimple(population, toolbox, cxpb=0.2, mutpb=0.2, ngen=1000, stats=stats, halloffame=hof, verbose=True)
return hof[0] return hof[0]
@ -180,7 +182,7 @@ def durchfuehre_simulation(parameter):
#print(o) #print(o)
#visualisiere_ergebnisse(gesamtlast, pv_forecast, specific_date_prices, o,best_solution[0::2],best_solution[1::2] , temperature_forecast, start_hour, prediction_hours) visualisiere_ergebnisse(gesamtlast, pv_forecast, specific_date_prices, o,best_solution[0::2],best_solution[1::2] , temperature_forecast, start_hour, prediction_hours)
#print(eauto) #print(eauto)
return {"discharge_hours_bin":discharge_hours_bin, "eautocharge_hours_float":eautocharge_hours_float ,"result":o ,"eauto_obj":eauto} return {"discharge_hours_bin":discharge_hours_bin, "eautocharge_hours_float":eautocharge_hours_float ,"result":o ,"eauto_obj":eauto}

View File

@ -4,6 +4,17 @@ import numpy as np
import json, os import json, os
from datetime import datetime from datetime import datetime
import hashlib, requests import hashlib, requests
import pytz
# Beispiel: Umwandlung eines UTC-Zeitstempels in lokale Zeit
utc_time = datetime.strptime('2024-03-28T01:00:00.000Z', '%Y-%m-%dT%H:%M:%S.%fZ')
utc_time = utc_time.replace(tzinfo=pytz.utc)
# Ersetzen Sie 'Europe/Berlin' mit Ihrer eigenen Zeitzone
local_time = utc_time.astimezone(pytz.timezone('Europe/Berlin'))
print(local_time)
class HourlyElectricityPriceForecast: class HourlyElectricityPriceForecast:
def __init__(self, source, cache_dir='cache', abgaben=0.00019): def __init__(self, source, cache_dir='cache', abgaben=0.00019):
@ -48,8 +59,12 @@ class HourlyElectricityPriceForecast:
def get_price_for_daterange(self, start_date_str, end_date_str): def get_price_for_daterange(self, start_date_str, end_date_str):
"""Gibt alle Preise zwischen dem Start- und Enddatum zurück.""" """Gibt alle Preise zwischen dem Start- und Enddatum zurück."""
start_date = datetime.strptime(start_date_str, "%Y-%m-%d") start_date_utc = datetime.strptime(start_date_str, "%Y-%m-%d").replace(tzinfo=pytz.utc)
end_date = datetime.strptime(end_date_str, "%Y-%m-%d") end_date_utc = datetime.strptime(end_date_str, "%Y-%m-%d").replace(tzinfo=pytz.utc)
start_date = start_date_utc.astimezone(pytz.timezone('Europe/Berlin'))
end_date = end_date_utc.astimezone(pytz.timezone('Europe/Berlin'))
price_list = [] price_list = []
while start_date <= end_date: while start_date <= end_date:

View File

@ -1,6 +1,11 @@
import numpy as np import numpy as np
from modules.class_load_container import Gesamtlast # Stellen Sie sicher, dass dies dem tatsächlichen Importpfad entspricht from modules.class_load_container import Gesamtlast # Stellen Sie sicher, dass dies dem tatsächlichen Importpfad entspricht
import matplotlib
matplotlib.use('Agg') # Setzt das Backend auf Agg
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
def visualisiere_ergebnisse(gesamtlast, pv_forecast, strompreise, ergebnisse, discharge_hours, laden_moeglich, temperature, start_hour, prediction_hours): def visualisiere_ergebnisse(gesamtlast, pv_forecast, strompreise, ergebnisse, discharge_hours, laden_moeglich, temperature, start_hour, prediction_hours):
@ -8,140 +13,188 @@ def visualisiere_ergebnisse(gesamtlast, pv_forecast, strompreise, ergebnisse, d
##################### #####################
# 24h # 24h
##################### #####################
with PdfPages('visualisierungsergebnisse.pdf') as pdf:
# Last und PV-Erzeugung
plt.figure(figsize=(14, 14))
plt.subplot(3, 2, 1) # Last und PV-Erzeugung
stunden = np.arange(0, prediction_hours) plt.figure(figsize=(14, 14))
plt.subplot(3, 2, 1)
stunden = np.arange(0, prediction_hours)
# Einzellasten plotten
for name, last_array in gesamtlast.lasten.items():
plt.plot(stunden, last_array, label=f'{name} (Wh)', marker='o') # Einzellasten plotten
for name, last_array in gesamtlast.lasten.items():
# Gesamtlast berechnen und plotten plt.plot(stunden, last_array, label=f'{name} (Wh)', marker='o')
gesamtlast_array = gesamtlast.gesamtlast_berechnen()
plt.plot(stunden, gesamtlast_array, label='Gesamtlast (Wh)', marker='o', linewidth=2, linestyle='--') # Gesamtlast berechnen und plotten
plt.xlabel('Stunde') gesamtlast_array = gesamtlast.gesamtlast_berechnen()
plt.ylabel('Last (Wh)') plt.plot(stunden, gesamtlast_array, label='Gesamtlast (Wh)', marker='o', linewidth=2, linestyle='--')
plt.title('Lastprofile') plt.xlabel('Stunde')
plt.grid(True) plt.ylabel('Last (Wh)')
plt.legend() plt.title('Lastprofile')
plt.grid(True)
plt.legend()
# Strompreise # Strompreise
stundenp = np.arange(1, len(strompreise)+1) stundenp = np.arange(0, len(strompreise))
plt.subplot(3, 2, 2) plt.subplot(3, 2, 2)
plt.plot(stundenp, strompreise, label='Strompreis (€/Wh)', color='purple', marker='s') plt.plot(stundenp, strompreise, label='Strompreis (€/Wh)', color='purple', marker='s')
plt.title('Strompreise') plt.title('Strompreise')
plt.xlabel('Stunde des Tages') plt.xlabel('Stunde des Tages')
plt.ylabel('Preis (€/Wh)') plt.ylabel('Preis (€/Wh)')
plt.legend() plt.legend()
plt.grid(True) plt.grid(True)
# Strompreise # Strompreise
stundenp = np.arange(1, len(strompreise)+1) stundenp = np.arange(1, len(strompreise)+1)
plt.subplot(3, 2, 3) plt.subplot(3, 2, 3)
plt.plot(stunden, pv_forecast, label='PV-Erzeugung (Wh)', marker='x') plt.plot(stunden, pv_forecast, label='PV-Erzeugung (Wh)', marker='x')
plt.title('PV Forecast') plt.title('PV Forecast')
plt.xlabel('Stunde des Tages') plt.xlabel('Stunde des Tages')
plt.ylabel('Wh') plt.ylabel('Wh')
plt.legend() plt.legend()
plt.grid(True) plt.grid(True)
# Temperatur Forecast # Temperatur Forecast
plt.subplot(3, 2, 4) plt.subplot(3, 2, 4)
plt.title('Temperatur Forecast °C') plt.title('Temperatur Forecast °C')
plt.plot(stunden, temperature, label='Temperatur °C', marker='x') plt.plot(stunden, temperature, label='Temperatur °C', marker='x')
plt.xlabel('Stunde des Tages') plt.xlabel('Stunde des Tages')
plt.ylabel('°C') plt.ylabel('°C')
plt.legend() plt.legend()
plt.grid(True) plt.grid(True)
pdf.savefig() # Speichert den aktuellen Figure-State im PDF
plt.close() # Schließt die aktuelle Figure, um Speicher freizugeben
##################### #####################
# Start_Hour # Start_Hour
##################### #####################
plt.figure(figsize=(14, 10)) plt.figure(figsize=(14, 10))
stunden = np.arange(start_hour, prediction_hours) stunden = np.arange(start_hour, prediction_hours)
# Eigenverbrauch, Netzeinspeisung und Netzbezug # Eigenverbrauch, Netzeinspeisung und Netzbezug
plt.subplot(3, 2, 1) plt.subplot(3, 2, 1)
plt.plot(stunden, ergebnisse['Eigenverbrauch_Wh_pro_Stunde'], label='Eigenverbrauch (Wh)', marker='o') plt.plot(stunden, ergebnisse['Eigenverbrauch_Wh_pro_Stunde'], label='Eigenverbrauch (Wh)', marker='o')
plt.plot(stunden, ergebnisse['Netzeinspeisung_Wh_pro_Stunde'], label='Netzeinspeisung (Wh)', marker='x') plt.plot(stunden, ergebnisse['Netzeinspeisung_Wh_pro_Stunde'], label='Netzeinspeisung (Wh)', marker='x')
plt.plot(stunden, ergebnisse['Netzbezug_Wh_pro_Stunde'], label='Netzbezug (Wh)', marker='^') plt.plot(stunden, ergebnisse['Netzbezug_Wh_pro_Stunde'], label='Netzbezug (Wh)', marker='^')
plt.plot(stunden, ergebnisse['Verluste_Pro_Stunde'], label='Verluste (Wh)', marker='^') plt.plot(stunden, ergebnisse['Verluste_Pro_Stunde'], label='Verluste (Wh)', marker='^')
plt.title('Energiefluss pro Stunde') plt.title('Energiefluss pro Stunde')
plt.xlabel('Stunde') plt.xlabel('Stunde')
plt.ylabel('Energie (Wh)') plt.ylabel('Energie (Wh)')
plt.legend() plt.legend()
plt.subplot(3, 2, 2) plt.subplot(3, 2, 2)
plt.plot(stunden, ergebnisse['akku_soc_pro_stunde'], label='PV Akku (%)', marker='x') plt.plot(stunden, ergebnisse['akku_soc_pro_stunde'], label='PV Akku (%)', marker='x')
plt.plot(stunden, ergebnisse['E-Auto_SoC_pro_Stunde'], label='E-Auto Akku (%)', marker='x') plt.plot(stunden, ergebnisse['E-Auto_SoC_pro_Stunde'], label='E-Auto Akku (%)', marker='x')
plt.legend(loc='upper left') plt.legend(loc='upper left')
ax1 = plt.subplot(3, 2, 3) ax1 = plt.subplot(3, 2, 3)
for hour, value in enumerate(discharge_hours): for hour, value in enumerate(discharge_hours):
#if value == 1: #if value == 1:
ax1.axvspan(hour, hour+1, color='red',ymax=value, alpha=0.3, label='Entlademöglichkeit' if hour == 0 else "") ax1.axvspan(hour, hour+1, color='red',ymax=value, alpha=0.3, label='Entlademöglichkeit' if hour == 0 else "")
for hour, value in enumerate(laden_moeglich): for hour, value in enumerate(laden_moeglich):
#if value == 1: #if value == 1:
ax1.axvspan(hour, hour+1, color='green',ymax=value, alpha=0.3, label='Lademöglichkeit' if hour == 0 else "") ax1.axvspan(hour, hour+1, color='green',ymax=value, alpha=0.3, label='Lademöglichkeit' if hour == 0 else "")
ax1.legend(loc='upper left') ax1.legend(loc='upper left')
pdf.savefig() # Speichert den aktuellen Figure-State im PDF
plt.close() # Schließt die aktuelle Figure, um Speicher freizugeben
plt.grid(True)
fig, axs = plt.subplots(1, 2, figsize=(14, 10)) # Erstellt 1x2 Raster von Subplots
gesamtkosten = ergebnisse['Gesamtkosten_Euro']
gesamteinnahmen = ergebnisse['Gesamteinnahmen_Euro']
gesamtbilanz = ergebnisse['Gesamtbilanz_Euro']
verluste = ergebnisse['Gesamt_Verluste']
# Kosten und Einnahmen pro Stunde auf der ersten Achse (axs[0])
axs[0].plot(stunden, ergebnisse['Kosten_Euro_pro_Stunde'], label='Kosten (Euro)', marker='o', color='red')
axs[0].plot(stunden, ergebnisse['Einnahmen_Euro_pro_Stunde'], label='Einnahmen (Euro)', marker='x', color='green')
axs[0].set_title('Finanzielle Bilanz pro Stunde')
axs[0].set_xlabel('Stunde')
axs[0].set_ylabel('Euro')
axs[0].legend()
axs[0].grid(True)
# Zusammenfassende Finanzen auf der zweiten Achse (axs[1])
labels = ['GesamtKosten [€]', 'GesamtEinnahmen [€]', 'GesamtBilanz [€]']
werte = [gesamtkosten, gesamteinnahmen, gesamtbilanz]
colors = ['red' if wert > 0 else 'green' for wert in werte]
axs[1].bar(labels, werte, color=colors)
axs[1].set_title('Finanzübersicht')
axs[1].set_ylabel('Euro')
# Zweite Achse (ax2) für die Verluste, geteilt mit axs[1]
ax2 = axs[1].twinx()
ax2.bar('GesamtVerluste', verluste, color='blue')
ax2.set_ylabel('Verluste [Wh]', color='blue')
ax2.tick_params(axis='y', labelcolor='blue')
pdf.savefig() # Speichert die komplette Figure im PDF
plt.close() # Schließt die Figure
# plt.figure(figsize=(14, 10))
# # Kosten und Einnahmen pro Stunde
# plt.subplot(1, 2, 1)
# plt.plot(stunden, ergebnisse['Kosten_Euro_pro_Stunde'], label='Kosten (Euro)', marker='o', color='red')
# plt.plot(stunden, ergebnisse['Einnahmen_Euro_pro_Stunde'], label='Einnahmen (Euro)', marker='x', color='green')
# plt.title('Finanzielle Bilanz pro Stunde')
# plt.xlabel('Stunde')
# plt.ylabel('Euro')
# plt.legend()
# plt.grid(True)
# #plt.figure(figsize=(14, 10))
# # Zusammenfassende Finanzen
# #fig, ax1 = plt.subplot(1, 2, 2)
# fig, ax1 = plt.subplots()
# gesamtkosten = ergebnisse['Gesamtkosten_Euro']
# gesamteinnahmen = ergebnisse['Gesamteinnahmen_Euro']
# gesamtbilanz = ergebnisse['Gesamtbilanz_Euro']
# labels = ['GesamtKosten [€]', 'GesamtEinnahmen [€]', 'GesamtBilanz [€]']
# werte = [gesamtkosten, gesamteinnahmen, gesamtbilanz]
# colors = ['red' if wert > 0 else 'green' for wert in werte]
# ax1.bar(labels, werte, color=colors)
# ax1.set_ylabel('Euro')
# ax1.set_title('Finanzübersicht')
# # Zweite Achse (ax2) für die Verluste, geteilt mit ax1
# ax2 = ax1.twinx()
# verluste = ergebnisse['Gesamt_Verluste']
# ax2.bar('GesamtVerluste', verluste, color='blue')
# ax2.set_ylabel('Verluste [Wh]', color='blue')
# # Stellt sicher, dass die Achsenbeschriftungen der zweiten Achse in der gleichen Farbe angezeigt werden
# ax2.tick_params(axis='y', labelcolor='blue')
# pdf.savefig() # Speichert den aktuellen Figure-State im PDF
# plt.close() # Schließt die aktuelle Figure, um Speicher freizugeben
# plt.title('Gesamtkosten')
# plt.ylabel('Euro')
# plt.legend()
# plt.grid(True)
# plt.tight_layout()
#plt.show()
plt.grid(True)
plt.figure(figsize=(14, 10))
# Kosten und Einnahmen pro Stunde
plt.subplot(1, 2, 1)
plt.plot(stunden, ergebnisse['Kosten_Euro_pro_Stunde'], label='Kosten (Euro)', marker='o', color='red')
plt.plot(stunden, ergebnisse['Einnahmen_Euro_pro_Stunde'], label='Einnahmen (Euro)', marker='x', color='green')
plt.title('Finanzielle Bilanz pro Stunde')
plt.xlabel('Stunde')
plt.ylabel('Euro')
plt.legend()
# Zusammenfassende Finanzen
fig, ax1 = plt.subplots()
gesamtkosten = ergebnisse['Gesamtkosten_Euro']
gesamteinnahmen = ergebnisse['Gesamteinnahmen_Euro']
gesamtbilanz = ergebnisse['Gesamtbilanz_Euro']
labels = ['GesamtKosten [€]', 'GesamtEinnahmen [€]', 'GesamtBilanz [€]']
werte = [gesamtkosten, gesamteinnahmen, gesamtbilanz]
colors = ['red' if wert > 0 else 'green' for wert in werte]
ax1.bar(labels, werte, color=colors)
ax1.set_ylabel('Euro')
ax1.set_title('Finanzübersicht')
# Zweite Achse (ax2) für die Verluste, geteilt mit ax1
ax2 = ax1.twinx()
verluste = ergebnisse['Gesamt_Verluste']
ax2.bar('GesamtVerluste', verluste, color='blue')
ax2.set_ylabel('Verluste [Wh]', color='blue')
# Stellt sicher, dass die Achsenbeschriftungen der zweiten Achse in der gleichen Farbe angezeigt werden
ax2.tick_params(axis='y', labelcolor='blue')
# plt.title('Gesamtkosten')
# plt.ylabel('Euro')
# plt.legend()
# plt.grid(True)
# plt.tight_layout()
plt.show()

View File

@ -74,7 +74,10 @@ filepath = os.path.join (r'test_data', r'strompreise_akkudokAPI.json') # Pfad z
#price_forecast = HourlyElectricityPriceForecast(source=filepath) #price_forecast = HourlyElectricityPriceForecast(source=filepath)
price_forecast = HourlyElectricityPriceForecast(source="https://api.akkudoktor.net/prices?start="+date_now+"&end="+date+"") price_forecast = HourlyElectricityPriceForecast(source="https://api.akkudoktor.net/prices?start="+date_now+"&end="+date+"")
specific_date_prices = price_forecast.get_price_for_daterange(date_now,date) specific_date_prices = price_forecast.get_price_for_daterange(date_now,date)
# print("13:",specific_date_prices[13])
# print("14:",specific_date_prices[14])
# print("15:",specific_date_prices[15])
# sys.exit()
# WP # WP
############## ##############
leistung_wp = wp.simulate_24h(temperature_forecast) leistung_wp = wp.simulate_24h(temperature_forecast)