From c5e59f7b3a418122092126fc4ef936be50ff7ebd Mon Sep 17 00:00:00 2001 From: Bla Bla Date: Thu, 2 May 2024 10:27:33 +0200 Subject: [PATCH] =?UTF-8?q?Inverter=20Klasse=20hinzugef=C3=BCgt=20Kleinere?= =?UTF-8?q?=20Bugs=20bei=20max=5FWR=20Leistung=20behoben?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/class_akku.py | 5 +- modules/class_inverter.py | 140 ++++++++++++ modules/class_optimize.py | 16 +- modules/visualize.py | 78 +++---- test.py | 446 ++++++++++++++++++++------------------ 5 files changed, 425 insertions(+), 260 deletions(-) create mode 100644 modules/class_inverter.py diff --git a/modules/class_akku.py b/modules/class_akku.py index f89c9ce..98590bb 100644 --- a/modules/class_akku.py +++ b/modules/class_akku.py @@ -105,13 +105,16 @@ class PVAkku: # Aktualisierung des Ladezustands ohne die Kapazität zu überschreiten geladene_menge_ohne_verlust = min(self.kapazitaet_wh - self.soc_wh, effektive_lademenge) - + geladene_menge = geladene_menge_ohne_verlust * self.lade_effizienz + self.soc_wh += geladene_menge verluste_wh = geladene_menge_ohne_verlust* (1.0-self.lade_effizienz) + + # Zusätzliche Verluste, wenn die Energiezufuhr die Kapazitätsgrenze überschreitet # zusatz_verluste_wh = 0 # if effektive_lademenge > geladene_menge_ohne_verlust: diff --git a/modules/class_inverter.py b/modules/class_inverter.py new file mode 100644 index 0000000..202efe4 --- /dev/null +++ b/modules/class_inverter.py @@ -0,0 +1,140 @@ +class Wechselrichter: + def __init__(self, max_leistung_wh, akku): + self.max_leistung_wh = max_leistung_wh # Maximale Leistung, die der Wechselrichter verarbeiten kann + self.akku = akku # Verbindung zu einem Akku-Objekt + + def energie_verarbeiten(self, erzeugung, verbrauch, hour): + verluste = 0 + netzeinspeisung = 0 + netzbezug = 0.0 + eigenverbrauch = 0.0 + #eigenverbrauch = min(erzeugung, verbrauch) # Direkt verbrauchte Energie + + if erzeugung > verbrauch: + if verbrauch > self.max_leistung_wh: + + verluste += erzeugung - self.max_leistung_wh + restleistung_nach_verbrauch = self.max_leistung_wh - verbrauch + netzbezug = -restleistung_nach_verbrauch + eigenverbrauch = self.max_leistung_wh + + else: + # if hour==10: + # print("PV:",erzeugung) + # print("Load:",verbrauch) + # print("Max Leist:",self.max_leistung_wh) + # PV > WR Leistung dann Verlust + + # Load + restleistung_nach_verbrauch = erzeugung-verbrauch #min(self.max_leistung_wh - verbrauch, erzeugung-verbrauch) + # Akku + geladene_energie, verluste_laden_akku = self.akku.energie_laden(restleistung_nach_verbrauch, hour) + rest_überschuss = restleistung_nach_verbrauch - geladene_energie + # if hour == 12: + # print("Erzeugung:",erzeugung) + # print("Last:",verbrauch) + # print("Akku:",geladene_energie) + # print("Akku:",self.akku.ladezustand_in_prozent()) + # print("RestÜberschuss"," - ",rest_überschuss) + # print("RestLesitung WR:",self.max_leistung_wh - verbrauch) + # Einspeisung, restliche WR Kapazität + if rest_überschuss > self.max_leistung_wh - verbrauch: + netzeinspeisung = self.max_leistung_wh - verbrauch + verluste += rest_überschuss - netzeinspeisung + else: + netzeinspeisung = rest_überschuss + + verluste += verluste_laden_akku + + + + eigenverbrauch = verbrauch + + else: + benötigte_energie = verbrauch - erzeugung + max_akku_leistung = self.akku.max_ladeleistung_w + + rest_ac_leistung = max(max_akku_leistung - erzeugung,0) + + if benötigte_energie < rest_ac_leistung: + aus_akku, akku_entladeverluste = self.akku.energie_abgeben(benötigte_energie, hour) + else: + aus_akku, akku_entladeverluste = self.akku.energie_abgeben(rest_ac_leistung, hour) + + + verluste += akku_entladeverluste + + netzbezug = benötigte_energie - aus_akku + eigenverbrauch = erzeugung + aus_akku + + + # if erzeugung > verbrauch: + # if verbrauch > self.max_leistung_wh: + + # else: + + + # überschuss = self.max_leistung_wh - verbrauch + + # geladene_energie, verluste_laden_akku = self.akku.energie_laden(überschuss, hour) + # rest_überschuss = überschuss - geladene_energie + # verluste += verluste_laden_akku + + # if (rest_überschuss > self.max_leistung_wh): + # netzeinspeisung = self.max_leistung_wh + # verluste += rest_überschuss - self.max_leistung_wh + # else: + # netzeinspeisung = rest_überschuss + + # eigenverbrauch = verbrauch + + # else: + # benötigte_energie = verbrauch - erzeugung + # max_akku_leistung = self.akku.max_ladeleistung_w + + # rest_ac_leistung = max(max_akku_leistung - erzeugung,0) + + # if benötigte_energie < rest_ac_leistung: + # aus_akku, akku_entladeverluste = self.akku.energie_abgeben(benötigte_energie, hour) + # else: + # aus_akku, akku_entladeverluste = self.akku.energie_abgeben(rest_ac_leistung, hour) + + + # verluste += akku_entladeverluste + + # netzbezug = benötigte_energie - aus_akku + # eigenverbrauch = erzeugung + aus_akku + + # # Berechnung der gesamten verarbeiteten Energie + # total_verarbeitet = eigenverbrauch + # if total_verarbeitet > self.max_leistung_wh: + # verluste += total_verarbeitet - self.max_leistung_wh + + return netzeinspeisung, netzbezug, verluste, eigenverbrauch + + + # def energie_verarbeiten(self, erzeugung, verbrauch, hour): + + # verluste = 0 + # netzeinspeisung = 0 + # netzbezug = 0.0 + # eigenverbrauch = 0.0 + + # if erzeugung > verbrauch: + # überschuss = erzeugung - verbrauch + # geladene_energie, verluste_laden_akku = self.akku.energie_laden(überschuss, hour) + # verluste += verluste_laden_akku + + # netzeinspeisung = überschuss - geladene_energie-verluste_laden_akku + # eigenverbrauch = verbrauch + # netzbezug = 0.0 + # # Noch Netzbezug nötig + # else: + # netzeinspeisung = 0.0 + # benötigte_energie = verbrauch - erzeugung + # aus_akku, akku_entladeverluste = self.akku.energie_abgeben(benötigte_energie, hour) + # verluste += akku_entladeverluste + # netzbezug = benötigte_energie - aus_akku + # eigenverbrauch = erzeugung+aus_akku + + # return netzeinspeisung, netzbezug, verluste, eigenverbrauch # Keine Einspeisung, Netzbezug, aus Akku, Verluste, Eigenverbrauch diff --git a/modules/class_optimize.py b/modules/class_optimize.py index b7e056c..596a2d0 100644 --- a/modules/class_optimize.py +++ b/modules/class_optimize.py @@ -99,6 +99,7 @@ class optimization_problem: # Fitness-Funktion (muss Ihre EnergieManagementSystem-Logik integrieren) def evaluate(self,individual,ems,parameter,start_hour,worst_case): + try: o = self.evaluate_inner(individual,ems,start_hour) except: @@ -121,7 +122,7 @@ class optimization_problem: strafe = 0.0 strafe = max(0,(parameter['eauto_min_soc']-ems.eauto.ladezustand_in_prozent()) * self.strafe ) gesamtbilanz += strafe - gesamtbilanz += o["Gesamt_Verluste"]/1000.0 + gesamtbilanz += o["Gesamt_Verluste"]/10000.0 return (gesamtbilanz,) @@ -131,7 +132,7 @@ class optimization_problem: # Genetischer Algorithmus def optimize(self,start_solution=None): - population = self.toolbox.population(n=200) + population = self.toolbox.population(n=1000) hof = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: ind.fitness.values) @@ -144,8 +145,8 @@ class optimization_problem: if start_solution is not None and start_solution != -1: population.insert(0, creator.Individual(start_solution)) - #algorithms.eaMuPlusLambda(population, self.toolbox, 100, 200, cxpb=0.4, mutpb=0.5, ngen=500, stats=stats, halloffame=hof, verbose=True) - algorithms.eaSimple(population, self.toolbox, cxpb=0.4, mutpb=0.4, ngen=100, stats=stats, halloffame=hof, verbose=True) + #algorithms.eaMuPlusLambda(population, self.toolbox, 100, 200, cxpb=0.2, mutpb=0.2, ngen=500, stats=stats, halloffame=hof, verbose=True) + algorithms.eaSimple(population, self.toolbox, cxpb=0.2, mutpb=0.2, ngen=200, stats=stats, halloffame=hof, verbose=True) member = {"bilanz":[],"verluste":[],"nebenbedingung":[]} for ind in population: @@ -161,6 +162,7 @@ class optimization_problem: def optimierung_ems(self,parameter=None, start_hour=None,worst_case=False): + ############ # Parameter ############ @@ -256,7 +258,7 @@ class optimization_problem: self.toolbox.register("evaluate", evaluate_wrapper) start_solution, extra_data = self.optimize(start_params) - best_solution = start_solution + best_solution = start_params o = self.evaluate_inner(best_solution, ems,start_hour) eauto = ems.eauto.to_dict() spuelstart_int = None @@ -269,8 +271,8 @@ class optimization_problem: - - print(o) + print(parameter) + print(best_solution) visualisiere_ergebnisse(gesamtlast, pv_forecast, specific_date_prices, o,best_solution[0::2],best_solution[1::2] , temperature_forecast, start_hour, self.prediction_hours,einspeiseverguetung_euro_pro_wh,extra_data=extra_data) os.system("cp visualisierungsergebnisse.pdf ~/") diff --git a/modules/visualize.py b/modules/visualize.py index 3f88a40..8a58a1f 100644 --- a/modules/visualize.py +++ b/modules/visualize.py @@ -170,52 +170,52 @@ def visualisiere_ergebnisse(gesamtlast, pv_forecast, strompreise, ergebnisse, d + if extra_data != None: + plt.figure(figsize=(14, 10)) + plt.subplot(1, 2, 1) + f1 = np.array(extra_data["verluste"]) + f2 = np.array(extra_data["bilanz"]) + n1 = np.array(extra_data["nebenbedingung"]) + scatter = plt.scatter(f1, f2, c=n1, cmap='viridis') - plt.figure(figsize=(14, 10)) - plt.subplot(1, 2, 1) - f1 = np.array(extra_data["verluste"]) - f2 = np.array(extra_data["bilanz"]) - n1 = np.array(extra_data["nebenbedingung"]) - scatter = plt.scatter(f1, f2, c=n1, cmap='viridis') + # Farblegende hinzufügen + plt.colorbar(scatter, label='Nebenbedingung') - # Farblegende hinzufügen - plt.colorbar(scatter, label='Nebenbedingung') + pdf.savefig() # Speichert die komplette Figure im PDF + plt.close() # Schließt die Figure - pdf.savefig() # Speichert die komplette Figure im PDF - plt.close() # Schließt die Figure + + plt.figure(figsize=(14, 10)) + filtered_verluste = np.array([v for v, n in zip(extra_data["verluste"], extra_data["nebenbedingung"]) if n < 0.01]) + filtered_bilanz = np.array([b for b, n in zip(extra_data["bilanz"], extra_data["nebenbedingung"]) if n< 0.01]) + + beste_verluste = min(filtered_verluste) + schlechteste_verluste = max(filtered_verluste) + beste_bilanz = min(filtered_bilanz) + schlechteste_bilanz = max(filtered_bilanz) - - plt.figure(figsize=(14, 10)) - filtered_verluste = np.array([v for v, n in zip(extra_data["verluste"], extra_data["nebenbedingung"]) if n < 0.01]) - filtered_bilanz = np.array([b for b, n in zip(extra_data["bilanz"], extra_data["nebenbedingung"]) if n< 0.01]) - - beste_verluste = min(filtered_verluste) - schlechteste_verluste = max(filtered_verluste) - beste_bilanz = min(filtered_bilanz) - schlechteste_bilanz = max(filtered_bilanz) + data = [filtered_verluste, filtered_bilanz] + labels = ['Verluste', 'Bilanz'] + # Plot-Erstellung + fig, axs = plt.subplots(1, 2, figsize=(10, 6), sharey=False) # Zwei Subplots, getrennte y-Achsen - data = [filtered_verluste, filtered_bilanz] - labels = ['Verluste', 'Bilanz'] - # Plot-Erstellung - fig, axs = plt.subplots(1, 2, figsize=(10, 6), sharey=False) # Zwei Subplots, getrennte y-Achsen + # Erster Boxplot für Verluste + #axs[0].boxplot(data[0]) + axs[0].violinplot(data[0], + showmeans=True, + showmedians=True) + axs[0].set_title('Verluste') + axs[0].set_xticklabels(['Verluste']) - # Erster Boxplot für Verluste - #axs[0].boxplot(data[0]) - axs[0].violinplot(data[0], - showmeans=True, - showmedians=True) - axs[0].set_title('Verluste') - axs[0].set_xticklabels(['Verluste']) + # Zweiter Boxplot für Bilanz + axs[1].violinplot(data[1], + showmeans=True, + showmedians=True) + axs[1].set_title('Bilanz') + axs[1].set_xticklabels(['Bilanz']) - # Zweiter Boxplot für Bilanz - axs[1].violinplot(data[1], - showmeans=True, - showmedians=True) - axs[1].set_title('Bilanz') - axs[1].set_xticklabels(['Bilanz']) - - # Feinabstimmung - plt.tight_layout() + # Feinabstimmung + plt.tight_layout() pdf.savefig() # Speichert den aktuellen Figure-State im PDF diff --git a/test.py b/test.py index 01c6375..4dccff5 100644 --- a/test.py +++ b/test.py @@ -1,14 +1,16 @@ from flask import Flask, jsonify, request import numpy as np from datetime import datetime -from modules.class_load import * -from modules.class_ems import * -from modules.class_pv_forecast import * -from modules.class_akku import * -from modules.class_strompreis import * -from modules.class_heatpump import * -from modules.class_load_container import * -from modules.class_eauto import * +from modules.class_optimize import * +# from modules.class_load import * +# from modules.class_ems import * +# from modules.class_pv_forecast import * +# from modules.class_akku import * +# from modules.class_strompreis import * +# from modules.class_heatpump import * +# from modules.class_load_container import * +# from modules.class_eauto import * +from modules.class_optimize import * from pprint import pprint import matplotlib.pyplot as plt @@ -19,193 +21,165 @@ import random import os -start_hour = 11 -prediction_hours = 24 -date = (datetime.now().date() + timedelta(hours = prediction_hours)).strftime("%Y-%m-%d") -date_now = datetime.now().strftime("%Y-%m-%d") +start_hour = 8 +# prediction_hours = 24 +# date = (datetime.now().date() + timedelta(hours = prediction_hours)).strftime("%Y-%m-%d") +# date_now = datetime.now().strftime("%Y-%m-%d") -akku_size = 30000 # Wh -year_energy = 2000*1000 #Wh -einspeiseverguetung_cent_pro_wh = np.full(prediction_hours, 7/(1000.0*100.0)) # € / Wh +# akku_size = 30000 # Wh +# year_energy = 2000*1000 #Wh +# einspeiseverguetung_cent_pro_wh = np.full(prediction_hours, 7/(1000.0*100.0)) # € / Wh -max_heizleistung = 1000 # 5 kW Heizleistung -wp = Waermepumpe(max_heizleistung,prediction_hours) +# max_heizleistung = 1000 # 5 kW Heizleistung +# wp = Waermepumpe(max_heizleistung,prediction_hours) -akku = PVAkku(akku_size,prediction_hours) -discharge_array = np.full(prediction_hours,1) #np.array([1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]) # +# akku = PVAkku(akku_size,prediction_hours) +# discharge_array = np.full(prediction_hours,1) #np.array([1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]) # -laden_moeglich = np.full(prediction_hours,1) # np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0]) -#np.full(prediction_hours,1) -eauto = PVAkku(kapazitaet_wh=60000, hours=prediction_hours, lade_effizienz=0.95, entlade_effizienz=1.0, max_ladeleistung_w=10000 ,start_soc_prozent=10) -eauto.set_charge_per_hour(laden_moeglich) -min_soc_eauto = 80 -hohe_strafe = 10.0 +# laden_moeglich = np.full(prediction_hours,1) # np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0]) +# #np.full(prediction_hours,1) +# eauto = PVAkku(kapazitaet_wh=60000, hours=prediction_hours, lade_effizienz=0.95, entlade_effizienz=1.0, max_ladeleistung_w=10000 ,start_soc_prozent=10) +# eauto.set_charge_per_hour(laden_moeglich) +# min_soc_eauto = 80 +# hohe_strafe = 10.0 +#[1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1] +individual = [1, 1, # 0 + 0, 1, # 1 + 0, 0, # 2 + 0, 1, # 3 + 0, 0, # 4 + 1, 0, # 5 + 0, 1, # 6 + 0, 0, # 7 + 0, 0, # 8 + 1, 0, + 0, 0, + 1, 0, + 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1] +parameter= {'pv_soc': 92.4052, 'pv_akku_cap': 30000, 'year_energy': 4100000, 'einspeiseverguetung_euro_pro_wh': 7e-05, 'max_heizleistung': 1000, 'pv_forecast_url': 'https://api.akkudoktor.net/forecast?lat=52.52&lon=13.405&power=5000&azimuth=-10&tilt=7&powerInvertor=10000&horizont=20,27,22,20&power=4800&azimuth=-90&tilt=7&powerInvertor=10000&horizont=30,30,30,50&power=1400&azimuth=-40&tilt=60&powerInvertor=2000&horizont=60,30,0,30&power=1600&azimuth=5&tilt=45&powerInvertor=1400&horizont=45,25,30,60&past_days=5&cellCoEff=-0.36&inverterEfficiency=0.8&albedo=0.25&timezone=Europe%2FBerlin&hourly=relativehumidity_2m%2Cwindspeed_10m', 'eauto_min_soc': 100, 'eauto_cap': 60000, 'eauto_charge_efficiency': 0.95, 'eauto_charge_power': 5500, 'eauto_soc': 77, 'pvpowernow': 211.137503624, 'start_solution': individual, 'haushaltsgeraet_wh': 937, 'haushaltsgeraet_dauer': 0} - -#Gesamtlast -############# -gesamtlast = Gesamtlast() +opt_class = optimization_problem(prediction_hours=24, strafe=10) +ergebnis = opt_class.optimierung_ems(parameter=parameter, start_hour=start_hour) -# Load Forecast -############### -lf = LoadForecast(filepath=r'load_profiles.npz', year_energy=year_energy) -#leistung_haushalt = lf.get_daily_stats(date)[0,...] # Datum anpassen -leistung_haushalt = lf.get_stats_for_date_range(date_now,date)[0,...].flatten() -# print(date_now," ",date) -# print(leistung_haushalt.shape) -gesamtlast.hinzufuegen("Haushalt", leistung_haushalt) +# #Gesamtlast +# ############# +# gesamtlast = Gesamtlast() -# PV Forecast -############### -#PVforecast = PVForecast(filepath=os.path.join(r'test_data', r'pvprognose.json')) -PVforecast = PVForecast(prediction_hours = prediction_hours, url="https://api.akkudoktor.net/forecast?lat=52.52&lon=13.405&power=5000&azimuth=-10&tilt=7&powerInvertor=10000&horizont=20,27,22,20&power=4800&azimuth=-90&tilt=7&powerInvertor=10000&horizont=30,30,30,50&power=1400&azimuth=-40&tilt=60&powerInvertor=2000&horizont=60,30,0,30&power=1600&azimuth=5&tilt=45&powerInvertor=1400&horizont=45,25,30,60&past_days=5&cellCoEff=-0.36&inverterEfficiency=0.8&albedo=0.25&timezone=Europe%2FBerlin&hourly=relativehumidity_2m%2Cwindspeed_10m") -pv_forecast = PVforecast.get_pv_forecast_for_date_range(date_now,date) #get_forecast_for_date(date) -temperature_forecast = PVforecast.get_temperature_for_date_range(date_now,date) +# # Load Forecast +# ############### +# lf = LoadForecast(filepath=r'load_profiles.npz', year_energy=year_energy) +# #leistung_haushalt = lf.get_daily_stats(date)[0,...] # Datum anpassen +# leistung_haushalt = lf.get_stats_for_date_range(date_now,date)[0,...].flatten() +# # print(date_now," ",date) +# # print(leistung_haushalt.shape) +# gesamtlast.hinzufuegen("Haushalt", leistung_haushalt) + +# # PV Forecast +# ############### +# #PVforecast = PVForecast(filepath=os.path.join(r'test_data', r'pvprognose.json')) +# PVforecast = PVForecast(prediction_hours = prediction_hours, url="https://api.akkudoktor.net/forecast?lat=52.52&lon=13.405&power=5000&azimuth=-10&tilt=7&powerInvertor=10000&horizont=20,27,22,20&power=4800&azimuth=-90&tilt=7&powerInvertor=10000&horizont=30,30,30,50&power=1400&azimuth=-40&tilt=60&powerInvertor=2000&horizont=60,30,0,30&power=1600&azimuth=5&tilt=45&powerInvertor=1400&horizont=45,25,30,60&past_days=5&cellCoEff=-0.36&inverterEfficiency=0.8&albedo=0.25&timezone=Europe%2FBerlin&hourly=relativehumidity_2m%2Cwindspeed_10m") +# pv_forecast = PVforecast.get_pv_forecast_for_date_range(date_now,date) #get_forecast_for_date(date) + +# temperature_forecast = PVforecast.get_temperature_for_date_range(date_now,date) -# Strompreise -############### -filepath = os.path.join (r'test_data', r'strompreise_akkudokAPI.json') # Pfad zur JSON-Datei anpassen -#price_forecast = HourlyElectricityPriceForecast(source=filepath) -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) -# print("13:",specific_date_prices[13]) -# print("14:",specific_date_prices[14]) -# print("15:",specific_date_prices[15]) -# sys.exit() -# WP -############## -leistung_wp = wp.simulate_24h(temperature_forecast) -gesamtlast.hinzufuegen("Heatpump", leistung_wp) +# # Strompreise +# ############### +# filepath = os.path.join (r'test_data', r'strompreise_akkudokAPI.json') # Pfad zur JSON-Datei anpassen +# #price_forecast = HourlyElectricityPriceForecast(source=filepath) +# 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) +# # print("13:",specific_date_prices[13]) +# # print("14:",specific_date_prices[14]) +# # print("15:",specific_date_prices[15]) +# # sys.exit() +# # WP +# ############## +# leistung_wp = wp.simulate_24h(temperature_forecast) +# gesamtlast.hinzufuegen("Heatpump", leistung_wp) -# EAuto -###################### -# leistung_eauto = eauto.get_stuendliche_last() -# soc_eauto = eauto.get_stuendlicher_soc() -# gesamtlast.hinzufuegen("eauto", leistung_eauto) +# # EAuto +# ###################### +# # leistung_eauto = eauto.get_stuendliche_last() +# # soc_eauto = eauto.get_stuendlicher_soc() +# # gesamtlast.hinzufuegen("eauto", leistung_eauto) -# print(gesamtlast.gesamtlast_berechnen()) +# # print(gesamtlast.gesamtlast_berechnen()) -# EMS / Stromzähler Bilanz -#akku=None, pv_prognose_wh=None, strompreis_cent_pro_wh=None, einspeiseverguetung_cent_pro_wh=None, eauto=None, gesamtlast=None +# # EMS / Stromzähler Bilanz +# #akku=None, pv_prognose_wh=None, strompreis_cent_pro_wh=None, einspeiseverguetung_cent_pro_wh=None, eauto=None, gesamtlast=None -ems = EnergieManagementSystem(akku=akku, gesamtlast = gesamtlast, pv_prognose_wh=pv_forecast, strompreis_cent_pro_wh=specific_date_prices, einspeiseverguetung_cent_pro_wh=einspeiseverguetung_cent_pro_wh, eauto=eauto) +# ems = EnergieManagementSystem(akku=akku, gesamtlast = gesamtlast, pv_prognose_wh=pv_forecast, strompreis_cent_pro_wh=specific_date_prices, einspeiseverguetung_cent_pro_wh=einspeiseverguetung_cent_pro_wh, eauto=eauto) -o = ems.simuliere(start_hour)#ems.simuliere_ab_jetzt() -#pprint(o) -#pprint(o["Gesamtbilanz_Euro"]) +# o = ems.simuliere(start_hour)#ems.simuliere_ab_jetzt() +# #pprint(o) +# #pprint(o["Gesamtbilanz_Euro"]) -#visualisiere_ergebnisse(gesamtlast, pv_forecast, specific_date_prices, o,discharge_array,laden_moeglich, temperature_forecast, start_hour, prediction_hours) +# #visualisiere_ergebnisse(gesamtlast, pv_forecast, specific_date_prices, o,discharge_array,laden_moeglich, temperature_forecast, start_hour, prediction_hours) -# Optimierung +# # Optimierung -def evaluate_inner(individual): - #print(individual) - discharge_hours_bin = individual[0::2] - eautocharge_hours_float = individual[1::2] +# def evaluate_inner(individual): + # #print(individual) + # discharge_hours_bin = individual[0::2] + # eautocharge_hours_float = individual[1::2] - #print(discharge_hours_bin) - #print(len(eautocharge_hours_float)) - ems.reset() - #eauto.reset() - ems.set_akku_discharge_hours(discharge_hours_bin) - ems.set_eauto_charge_hours(eautocharge_hours_float) + # #print(discharge_hours_bin) + # #print(len(eautocharge_hours_float)) + # ems.reset() + # #eauto.reset() + # ems.set_akku_discharge_hours(discharge_hours_bin) + # ems.set_eauto_charge_hours(eautocharge_hours_float) - #eauto.set_laden_moeglich(eautocharge_hours_float) - #eauto.berechne_ladevorgang() - #leistung_eauto = eauto.get_stuendliche_last() - #gesamtlast.hinzufuegen("eauto", leistung_eauto) + # #eauto.set_laden_moeglich(eautocharge_hours_float) + # #eauto.berechne_ladevorgang() + # #leistung_eauto = eauto.get_stuendliche_last() + # #gesamtlast.hinzufuegen("eauto", leistung_eauto) - #ems.set_gesamtlast(gesamtlast.gesamtlast_berechnen()) + # #ems.set_gesamtlast(gesamtlast.gesamtlast_berechnen()) - o = ems.simuliere(start_hour) - return o, eauto + # o = ems.simuliere(start_hour) + # return o, eauto -# Fitness-Funktion (muss Ihre EnergieManagementSystem-Logik integrieren) -def evaluate(individual): - o,eauto = evaluate_inner(individual) - gesamtbilanz = o["Gesamtbilanz_Euro"] +# # Fitness-Funktion (muss Ihre EnergieManagementSystem-Logik integrieren) +# def evaluate(individual): + # o,eauto = evaluate_inner(individual) + # gesamtbilanz = o["Gesamtbilanz_Euro"] - # Überprüfung, ob der Mindest-SoC erreicht wird - final_soc = eauto.ladezustand_in_prozent() # Nimmt den SoC am Ende des Optimierungszeitraums - strafe = 0.0 - #if final_soc < min_soc_eauto: - # Fügt eine Strafe hinzu, wenn der Mindest-SoC nicht erreicht wird - strafe = max(0,(min_soc_eauto - final_soc) * hohe_strafe ) # `hohe_strafe` ist ein vorher festgelegter Strafwert - gesamtbilanz += strafe - gesamtbilanz += o["Gesamt_Verluste"]/1000.0 - return (gesamtbilanz,) + # # Überprüfung, ob der Mindest-SoC erreicht wird + # final_soc = eauto.ladezustand_in_prozent() # Nimmt den SoC am Ende des Optimierungszeitraums + # strafe = 0.0 + # #if final_soc < min_soc_eauto: + # # Fügt eine Strafe hinzu, wenn der Mindest-SoC nicht erreicht wird + # strafe = max(0,(min_soc_eauto - final_soc) * hohe_strafe ) # `hohe_strafe` ist ein vorher festgelegter Strafwert + # gesamtbilanz += strafe + # gesamtbilanz += o["Gesamt_Verluste"]/1000.0 + # return (gesamtbilanz,) -# Werkzeug-Setup -creator.create("FitnessMin", base.Fitness, weights=(-1.0,)) -creator.create("Individual", list, fitness=creator.FitnessMin) - -toolbox = base.Toolbox() - -toolbox.register("attr_bool", random.randint, 0, 1) -toolbox.register("attr_bool", random.randint, 0, 1) -toolbox.register("individual", tools.initCycle, creator.Individual, (toolbox.attr_bool,toolbox.attr_bool), n=prediction_hours) - - - -toolbox.register("population", tools.initRepeat, list, toolbox.individual) - -toolbox.register("evaluate", evaluate) -toolbox.register("mate", tools.cxTwoPoint) -toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) -toolbox.register("select", tools.selTournament, tournsize=3) - -# Genetischer Algorithmus -def optimize(): - population = toolbox.population(n=500) - hof = tools.HallOfFame(1) - - stats = tools.Statistics(lambda ind: ind.fitness.values) - stats.register("avg", np.mean) - stats.register("min", np.min) - 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.eaSimple(population, toolbox, cxpb=0.2, mutpb=0.2, ngen=1000, stats=stats, halloffame=hof, verbose=True) - return hof[0] - - -start_solution = optimize() - - -print("Start Lösung:", start_solution) - - - - # # Werkzeug-Setup # creator.create("FitnessMin", base.Fitness, weights=(-1.0,)) # creator.create("Individual", list, fitness=creator.FitnessMin) # toolbox = base.Toolbox() - - - # toolbox.register("attr_bool", random.randint, 0, 1) -# toolbox.register("attr_float", random.uniform, 0.0, 1.0) -# toolbox.register("individual", tools.initCycle, creator.Individual, (toolbox.attr_bool,toolbox.attr_float), n=prediction_hours) +# toolbox.register("attr_bool", random.randint, 0, 1) +# toolbox.register("individual", tools.initCycle, creator.Individual, (toolbox.attr_bool,toolbox.attr_bool), n=prediction_hours) + -# start_individual = toolbox.individual() -# start_individual[:] = start_solution # toolbox.register("population", tools.initRepeat, list, toolbox.individual) @@ -216,8 +190,7 @@ print("Start Lösung:", start_solution) # # Genetischer Algorithmus # def optimize(): - # population = toolbox.population(n=1000) - # population[0] = start_individual + # population = toolbox.population(n=500) # hof = tools.HallOfFame(1) # stats = tools.Statistics(lambda ind: ind.fitness.values) @@ -225,73 +198,120 @@ print("Start Lösung:", start_solution) # stats.register("min", np.min) # stats.register("max", np.max) - # algorithms.eaMuPlusLambda(population, toolbox, 100, 200, cxpb=0.5, mutpb=0.2, ngen=1000, stats=stats, halloffame=hof, verbose=True) + # algorithms.eaMuPlusLambda(population, toolbox, 50, 100, cxpb=0.5, mutpb=0.5, 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) # return hof[0] - -# best_solution = optimize() -best_solution = start_solution -print("Beste Lösung:", best_solution) - -#ems.set_akku_discharge_hours(best_solution) -o,eauto = evaluate_inner(best_solution) - -# soc_eauto = eauto.get_stuendlicher_soc() -# print(soc_eauto) -# pprint(o) -# pprint(eauto.get_stuendlicher_soc()) - - -#visualisiere_ergebnisse(gesamtlast,leistung_haushalt,leistung_wp, pv_forecast, specific_date_prices, o,soc_eauto,best_solution[0::2],best_solution[1::2] , temperature_forecast) -visualisiere_ergebnisse(gesamtlast, pv_forecast, specific_date_prices, o,best_solution[0::2],best_solution[1::2] , temperature_forecast, start_hour, prediction_hours) - - -# for data in forecast.get_forecast_data(): - # print(data.get_date_time(), data.get_dc_power(), data.get_ac_power(), data.get_windspeed_10m(), data.get_temperature())for data in forecast.get_forecast_data(): - - - - -# app = Flask(__name__) - - - -# @app.route('/getdata', methods=['GET']) -# def get_data(): - # # Hole das Datum aus den Query-Parametern - # date_str = request.args.get('date') - # year_energy = request.args.get('year_energy') - # try: - # # Konvertiere das Datum in ein datetime-Objekt - # date_obj = datetime.strptime(date_str, '%Y-%m-%d') - # filepath = r'.\load_profiles.npz' # Pfad zur JSON-Datei anpassen - # lf = cl.LoadForecast(filepath=filepath, year_energy=float(year_energy)) - # specific_date_prices = lf.get_daily_stats('2024-02-16') + +# start_solution = optimize() + + +# print("Start Lösung:", start_solution) + + + + +# # # Werkzeug-Setup +# # creator.create("FitnessMin", base.Fitness, weights=(-1.0,)) +# # creator.create("Individual", list, fitness=creator.FitnessMin) + +# # toolbox = base.Toolbox() + + + + +# # toolbox.register("attr_bool", random.randint, 0, 1) +# # toolbox.register("attr_float", random.uniform, 0.0, 1.0) +# # toolbox.register("individual", tools.initCycle, creator.Individual, (toolbox.attr_bool,toolbox.attr_float), n=prediction_hours) + +# # start_individual = toolbox.individual() +# # start_individual[:] = start_solution + +# # toolbox.register("population", tools.initRepeat, list, toolbox.individual) + +# # toolbox.register("evaluate", evaluate) +# # toolbox.register("mate", tools.cxTwoPoint) +# # toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) +# # toolbox.register("select", tools.selTournament, tournsize=3) + +# # # Genetischer Algorithmus +# # def optimize(): + # # population = toolbox.population(n=1000) + # # population[0] = start_individual + # # hof = tools.HallOfFame(1) + + # # stats = tools.Statistics(lambda ind: ind.fitness.values) + # # stats.register("avg", np.mean) + # # stats.register("min", np.min) + # # stats.register("max", np.max) + + # # algorithms.eaMuPlusLambda(population, toolbox, 100, 200, cxpb=0.5, 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] + +# # best_solution = optimize() +# best_solution = start_solution +# print("Beste Lösung:", best_solution) + +# #ems.set_akku_discharge_hours(best_solution) +# o,eauto = evaluate_inner(best_solution) + +# # soc_eauto = eauto.get_stuendlicher_soc() +# # print(soc_eauto) +# # pprint(o) +# # pprint(eauto.get_stuendlicher_soc()) + + +# #visualisiere_ergebnisse(gesamtlast,leistung_haushalt,leistung_wp, pv_forecast, specific_date_prices, o,soc_eauto,best_solution[0::2],best_solution[1::2] , temperature_forecast) +# visualisiere_ergebnisse(gesamtlast, pv_forecast, specific_date_prices, o,best_solution[0::2],best_solution[1::2] , temperature_forecast, start_hour, prediction_hours) + + +# # for data in forecast.get_forecast_data(): + # # print(data.get_date_time(), data.get_dc_power(), data.get_ac_power(), data.get_windspeed_10m(), data.get_temperature())for data in forecast.get_forecast_data(): + + + + +# # app = Flask(__name__) + + + +# # @app.route('/getdata', methods=['GET']) +# # def get_data(): + # # # Hole das Datum aus den Query-Parametern + # # date_str = request.args.get('date') + # # year_energy = request.args.get('year_energy') + + # # try: + # # # Konvertiere das Datum in ein datetime-Objekt + # # date_obj = datetime.strptime(date_str, '%Y-%m-%d') + # # filepath = r'.\load_profiles.npz' # Pfad zur JSON-Datei anpassen + # # lf = cl.LoadForecast(filepath=filepath, year_energy=float(year_energy)) + # # specific_date_prices = lf.get_daily_stats('2024-02-16') - # # Berechne den Tag des Jahres - # #day_of_year = date_obj.timetuple().tm_yday + # # # Berechne den Tag des Jahres + # # #day_of_year = date_obj.timetuple().tm_yday - # # Konvertiere den Tag des Jahres in einen String, falls die Schlüssel als Strings gespeichert sind - # #day_key = int(day_of_year) - # #print(day_key) - # # Überprüfe, ob der Tag im Jahr in den Daten vorhanden ist - # array_list = lf.get_daily_stats(date_str) - # pprint(array_list) - # pprint(array_list.shape) - # if array_list.shape == (2,24): - # #if day_key < len(load_profiles_exp): - # # Konvertiere das Array in eine Liste für die JSON-Antwort - # #((load_profiles_exp_l[day_key]).tolist(),(load_profiles_std_l)[day_key].tolist()) + # # # Konvertiere den Tag des Jahres in einen String, falls die Schlüssel als Strings gespeichert sind + # # #day_key = int(day_of_year) + # # #print(day_key) + # # # Überprüfe, ob der Tag im Jahr in den Daten vorhanden ist + # # array_list = lf.get_daily_stats(date_str) + # # pprint(array_list) + # # pprint(array_list.shape) + # # if array_list.shape == (2,24): + # # #if day_key < len(load_profiles_exp): + # # # Konvertiere das Array in eine Liste für die JSON-Antwort + # # #((load_profiles_exp_l[day_key]).tolist(),(load_profiles_std_l)[day_key].tolist()) - # return jsonify({date_str: array_list.tolist()}) - # else: - # return jsonify({"error": "Datum nicht gefunden"}), 404 - # except ValueError: - # # Wenn das Datum nicht im richtigen Format ist oder ungültig ist - # return jsonify({"error": "Ungültiges Datum"}), 400 + # # return jsonify({date_str: array_list.tolist()}) + # # else: + # # return jsonify({"error": "Datum nicht gefunden"}), 404 + # # except ValueError: + # # # Wenn das Datum nicht im richtigen Format ist oder ungültig ist + # # return jsonify({"error": "Ungültiges Datum"}), 400 -# if __name__ == '__main__': - # app.run(debug=True) +# # if __name__ == '__main__': + # # app.run(debug=True)