E-Auto/Wallbox wird jetzt mit diskreten Ladezuständen versehen, in der

config.py einstellbar
Jeder DisCharge = 0 (Akkus nicht benutzen) wird mit 1Cent Strafe belegt,
da die Lastverteilung fehlt. Also wenn es egal ist, soll er den Akku
anschalten.
This commit is contained in:
Bla Bla 2024-09-04 08:23:17 +02:00
parent c03d5f386a
commit 8f1d23fe9d
3 changed files with 111 additions and 171 deletions

View File

@ -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

View File

@ -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']

170
test.py
View File

@ -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))
#print(ergebnis)
#print(jsonify(ergebnis))