diff --git a/modules/class_inverter.py b/modules/class_inverter.py index 514b4d3..becaca7 100644 --- a/modules/class_inverter.py +++ b/modules/class_inverter.py @@ -30,7 +30,7 @@ class Wechselrichter: # Akku geladene_energie, verluste_laden_akku = self.akku.energie_laden(restleistung_nach_verbrauch, hour) rest_überschuss = restleistung_nach_verbrauch - (geladene_energie+verluste_laden_akku) - # if hour == 12: + # if hour == 1: # print("Erzeugung:",erzeugung) # print("Last:",verbrauch) # print("Akku:",geladene_energie) @@ -44,8 +44,8 @@ class Wechselrichter: verluste += rest_überschuss - netzeinspeisung else: netzeinspeisung = rest_überschuss - #if hour ==10: - # print(rest_überschuss," ",restleistung_nach_verbrauch, " Gela:",geladene_energie," Ver:",verluste_laden_akku) + #if hour ==14: + # print("Erz:",erzeugung," Last:",verbrauch, " RestPV:",rest_überschuss," ",restleistung_nach_verbrauch, " Gela:",geladene_energie," Ver:",verluste_laden_akku," Einsp:",netzeinspeisung) verluste += verluste_laden_akku @@ -71,73 +71,4 @@ class Wechselrichter: 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 7a51448..c780403 100644 --- a/modules/class_optimize.py +++ b/modules/class_optimize.py @@ -23,7 +23,8 @@ from deap import base, creator, tools, algorithms import numpy as np import random import os - +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from config import * def isfloat(num): try: @@ -38,7 +39,7 @@ class optimization_problem: self.strafe = strafe self.opti_param = None self.fixed_eauto_hours = prediction_hours-optimization_hours - + self.possible_charge_values = moegliche_ladestroeme_in_prozent def split_individual(self, individual): @@ -74,7 +75,9 @@ class optimization_problem: # PARAMETER self.toolbox = base.Toolbox() self.toolbox.register("attr_bool", random.randint, 0, 1) - self.toolbox.register("attr_float", random.uniform, 0, 1) # Für kontinuierliche Werte zwischen 0 und 1 (z.B. für E-Auto-Ladeleistung) + #self.toolbox.register("attr_float", random.uniform, 0, 1) # Für kontinuierliche Werte zwischen 0 und 1 (z.B. für E-Auto-Ladeleistung) + self.toolbox.register("attr_choice", random.choice, self.possible_charge_values) # Für diskrete Ladeströme + self.toolbox.register("attr_int", random.randint, start_hour, 23) ################### @@ -83,14 +86,14 @@ class optimization_problem: if opti_param["haushaltsgeraete"]>0: def create_individual(): attrs = [self.toolbox.attr_bool() for _ in range(self.prediction_hours)] # 24 Bool-Werte für Entladen - attrs += [self.toolbox.attr_float() for _ in range(self.prediction_hours)] # 24 Float-Werte für Laden + attrs += [self.toolbox.attr_choice() for _ in range(self.prediction_hours)] # 24 Float-Werte für Laden attrs.append(self.toolbox.attr_int()) # Haushaltsgerät-Startzeit return creator.Individual(attrs) else: def create_individual(): attrs = [self.toolbox.attr_bool() for _ in range(self.prediction_hours)] # 24 Bool-Werte für Entladen - attrs += [self.toolbox.attr_float() for _ in range(self.prediction_hours)] # 24 Float-Werte für Laden + attrs += [self.toolbox.attr_choice() for _ in range(self.prediction_hours)] # 24 Float-Werte für Laden return creator.Individual(attrs) @@ -113,14 +116,14 @@ class optimization_problem: - + #discharge_hours_bin = np.full(self.prediction_hours,0) ems.set_akku_discharge_hours(discharge_hours_bin) # Setze die festen Werte für die letzten x Stunden for i in range(self.prediction_hours - self.fixed_eauto_hours, self.prediction_hours): eautocharge_hours_float[i] = 0.0 # Setze die letzten x Stunden auf einen festen Wert (oder vorgegebenen Wert) - + #print(eautocharge_hours_float) ems.set_eauto_charge_hours(eautocharge_hours_float) @@ -141,9 +144,15 @@ class optimization_problem: if worst_case: gesamtbilanz = gesamtbilanz * -1.0 + discharge_hours_bin, eautocharge_hours_float, spuelstart_int = self.split_individual(individual) + + # Für jeden Discharge 0, eine kleine Strafe von 1 Cent, da die Lastvertelung noch fehlt. Also wenn es egal ist, soll er den Akku entladen lassen + for i in range(0, self.prediction_hours): + if discharge_hours_bin[i] == 0.0: # Wenn die letzten x Stunden von einem festen Wert abweichen + gesamtbilanz += 0.01 # Bestrafe den Optimierer + # E-Auto nur die ersten self.fixed_eauto_hours - eautocharge_hours_float = individual[self.prediction_hours:self.prediction_hours * 2] for i in range(self.prediction_hours - self.fixed_eauto_hours, self.prediction_hours): if eautocharge_hours_float[i] != 0.0: # Wenn die letzten x Stunden von einem festen Wert abweichen gesamtbilanz += self.strafe # Bestrafe den Optimierer @@ -186,7 +195,7 @@ class optimization_problem: # Genetischer Algorithmus def optimize(self,start_solution=None): - population = self.toolbox.population(n=400) + population = self.toolbox.population(n=600) hof = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: ind.fitness.values) @@ -199,7 +208,7 @@ 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, mu=200, lambda_=300, cxpb=0.3, mutpb=0.4, ngen=500, stats=stats, halloffame=hof, verbose=True) + algorithms.eaMuPlusLambda(population, self.toolbox, mu=200, lambda_=300, cxpb=0.3, mutpb=0.4, ngen=300, stats=stats, halloffame=hof, verbose=True) #algorithms.eaSimple(population, self.toolbox, cxpb=0.2, mutpb=0.2, ngen=1000, stats=stats, halloffame=hof, verbose=True) member = {"bilanz":[],"verluste":[],"nebenbedingung":[]} @@ -231,12 +240,12 @@ class optimization_problem: akku_size = parameter['pv_akku_cap'] # Wh einspeiseverguetung_euro_pro_wh = np.full(self.prediction_hours, parameter["einspeiseverguetung_euro_pro_wh"]) #= # € / Wh 7/(1000.0*100.0) - + discharge_array = np.full(self.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(kapazitaet_wh=akku_size,hours=self.prediction_hours,start_soc_prozent=parameter["pv_soc"], max_ladeleistung_w=5000) - discharge_array = np.full(self.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.set_charge_per_hour(discharge_array) + + laden_moeglich = np.full(self.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]) - - eauto = PVAkku(kapazitaet_wh=parameter["eauto_cap"], hours=self.prediction_hours, lade_effizienz=parameter["eauto_charge_efficiency"], entlade_effizienz=1.0, max_ladeleistung_w=parameter["eauto_charge_power"] ,start_soc_prozent=parameter["eauto_soc"]) eauto.set_charge_per_hour(laden_moeglich) min_soc_eauto = parameter['eauto_min_soc'] diff --git a/test.py b/test.py index b6cb077..922abb2 100644 --- a/test.py +++ b/test.py @@ -23,7 +23,7 @@ import os -start_hour = 13 +start_hour = 10 pv_forecast= [ 0, @@ -33,45 +33,45 @@ pv_forecast= [ 0, 0, 0, - 35.4104640357043, - 436.191574979506, - 734.585613834398, - 914.346108603927, - 1019.5228214119, - 1766.84136350058, - 5980.60975052259, - 6236.00681862336, - 5893.38154543782, - 4309.88538120413, - 3338.29004915145, - 2177.55660706753, - 1091.00542545193, - 437.819525591319, - 44.2226537829726, + 8.05499380056326, + 352.906710152794, + 728.510230116837, + 930.282113186742, + 1043.25445504815, + 1106.74498341506, + 1161.69140358941, + 6018.82237954771, + 5519.06508185542, + 3969.87633262384, + 3017.96293205546, + 1943.06957539177, + 1007.17065928121, + 319.672404988219, + 7.87634136648885, 0, 0, 0, 0, - -0.0269415125679914, 0, 0, 0, 0, - 25.5745140893473, - 494.188146846569, - 943.821134036728, - 1458.66413119635, - 1819.46147983229, - 2127.45430524539, - 2267.78128099068, - 5944.86706099518, - 5337.1322153025, - 4376.56125932204, - 3020.00212091936, - 2414.53994231359, - 1373.626161377, - 517.764497317134, - 35.619750070296, + 0, + 5.04340865393592, + 335.585179721385, + 705.32093965119, + 1121.11845108965, + 1604.78796905453, + 2157.38417470292, + 1433.25331647539, + 5718.48693381975, + 4553.95522042393, + 3027.5471975751, + 2574.46499468404, + 1720.39712914078, + 963.402827741714, + 383.299960578605, + 0, 0, 0 ] @@ -177,60 +177,60 @@ strompreis_euro_pro_wh = [ 0.00027800228 ] gesamtlast= [ - 546.16318964697, - 893.072526185525, - 448.7325491406, - 460.696954446666, - 497.688171532182, - 468.186120420737, - 424.440426628658, - 454.341890696582, - 1070.45287392313, - 1096.46234344204, - 1199.71317588613, - 1294.39989535284, - 1459.42631059004, - 1295.23757474948, - 1304.65748778424, - 1187.47511606455, - 1309.49984671163, - 1106.60773651081, - 1098.98136451936, - 2112.82264661039, - 1143.37118921705, - 858.863135790621, - 787.018517493612, - 693.683533270357, - 545.860858342826, - 892.702692835489, - 448.372058076642, - 460.284228901714, - 498.457870099476, - 469.01826331988, - 424.293997897019, - 454.660942633609, - 1070.71990586461, - 1096.44557410693, - 1199.72027861112, - 1294.75410706442, - 1459.61174223338, - 1295.77661554687, - 1304.95591385395, - 1188.62778631227, - 1310.43099742786, - 1108.58589249073, - 1101.73849714744, - 2114.05576978017, - 1143.68031998738, - 858.607350786608, - 786.574111043611, - 693.463415886943 + 676.712691350422, + 876.187995931743, + 527.13496018672, + 468.8832716908, + 531.379343927472, + 517.948592590007, + 483.146247717859, + 472.284832630916, + 1011.67951144825, + 995.004317471209, + 1053.06955100748, + 1063.9080395892, + 1320.56143113193, + 1132.02504127723, + 1163.67246837107, + 1176.81613875329, + 1216.21914051274, + 1103.77675478374, + 1129.12158352941, + 1178.70748410006, + 1050.97894301995, + 988.55813665172, + 912.383030600675, + 704.613809064162, + 516.371536532904, + 868.049462163551, + 694.342395302237, + 608.791374542592, + 556.310160150771, + 488.88509383088, + 506.910948217211, + 804.891484351704, + 1141.97850300923, + 1056.97012155463, + 992.46421110044, + 1155.98941936038, + 827.012550864246, + 1257.97979633947, + 1232.66876472966, + 871.261677859026, + 860.884647456424, + 1158.02879027548, + 1222.71811626233, + 1221.03860924522, + 949.989048056282, + 987.007654562746, + 733.993140774617, + 592.972573276025 ] start_solution= [ - 0, 1, - 0, + 1, + 1, 1, 0, 1, @@ -325,11 +325,11 @@ start_solution= [ 1, 1 ] -parameter= {"preis_euro_pro_wh_akku": 30e-05,'pv_soc': 95.00, 'pv_akku_cap': 30000, 'year_energy': 4100000, 'einspeiseverguetung_euro_pro_wh': 7e-05, 'max_heizleistung': 1000,"gesamtlast":gesamtlast, 'pv_forecast': pv_forecast, "temperature_forecast":temperature_forecast, "strompreis_euro_pro_wh":strompreis_euro_pro_wh, 'eauto_min_soc': 0, 'eauto_cap': 60000, 'eauto_charge_efficiency': 0.95, 'eauto_charge_power': 7590, 'eauto_soc': 53, 'pvpowernow': 211.137503624, 'start_solution': start_solution, 'haushaltsgeraet_wh': 937, 'haushaltsgeraet_dauer': 0} +parameter= {"preis_euro_pro_wh_akku": 10e-05,'pv_soc': 80, 'pv_akku_cap': 26400, 'year_energy': 4100000, 'einspeiseverguetung_euro_pro_wh': 7e-05, 'max_heizleistung': 1000,"gesamtlast":gesamtlast, 'pv_forecast': pv_forecast, "temperature_forecast":temperature_forecast, "strompreis_euro_pro_wh":strompreis_euro_pro_wh, 'eauto_min_soc': 0, 'eauto_cap': 60000, 'eauto_charge_efficiency': 0.95, 'eauto_charge_power': 11040, 'eauto_soc': 54, 'pvpowernow': 211.137503624, 'start_solution': start_solution, 'haushaltsgeraet_wh': 937, 'haushaltsgeraet_dauer': 0} opt_class = optimization_problem(prediction_hours=48, strafe=10,optimization_hours=24) ergebnis = opt_class.optimierung_ems(parameter=parameter, start_hour=start_hour) -print(ergebnis) -print(jsonify(ergebnis)) \ No newline at end of file +#print(ergebnis) +#print(jsonify(ergebnis)) \ No newline at end of file