Revert "restructure and optimization of class_optimize.py"

This reverts commit e7f6853f7f64214da98701fc049e33a76b780ff7.
This commit is contained in:
drbacke 2024-09-30 08:23:38 +02:00
parent 3cc4ae58b4
commit 1131887ae7

View File

@ -1,165 +1,264 @@
import os from flask import Flask, jsonify, request
import sys
import random
from datetime import datetime, timedelta
import numpy as np import numpy as np
from modules.class_load import *
from modules.class_ems import *
from modules.class_pv_forecast import *
from modules.class_akku import *
from modules.class_heatpump import *
from modules.class_load_container import *
from modules.class_inverter import *
from modules.class_sommerzeit import *
from modules.visualize import *
from modules.class_haushaltsgeraet import *
import os
from flask import Flask, send_from_directory
from pprint import pprint
import matplotlib
matplotlib.use('Agg') # Setzt das Backend auf Agg
import matplotlib.pyplot as plt
import string
from datetime import datetime
from deap import base, creator, tools, algorithms from deap import base, creator, tools, algorithms
import numpy as np
from modules.class_akku import PVAkku import random
from modules.class_ems import EnergieManagementSystem import os
from modules.class_haushaltsgeraet import Haushaltsgeraet
from modules.class_inverter import Wechselrichter
from config import moegliche_ladestroeme_in_prozent
from modules.visualize import visualisiere_ergebnisse
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from config import *
def isfloat(num):
try:
float(num)
return True
except:
return False
def differential_evolution(population, toolbox, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=__debug__):
"""Differential Evolution Algorithm"""
# Evaluate the entire population
fitnesses = list(map(toolbox.evaluate, population))
for ind, fit in zip(population, fitnesses):
ind.fitness.values = fit
if halloffame is not None:
halloffame.update(population)
logbook = tools.Logbook()
logbook.header = ['gen', 'nevals'] + (stats.fields if stats else [])
for gen in range(ngen):
# Generate the next generation by mutation and recombination
for i, target in enumerate(population):
a, b, c = random.sample([ind for ind in population if ind != target], 3)
mutant = toolbox.clone(a)
for k in range(len(mutant)):
mutant[k] = c[k] + mutpb * (a[k] - b[k]) # Mutation step
if random.random() < cxpb: # Recombination step
mutant[k] = target[k]
# Evaluate the mutant
mutant.fitness.values = toolbox.evaluate(mutant)
# Replace if mutant is better
if mutant.fitness > target.fitness:
population[i] = mutant
# Update hall of fame
if halloffame is not None:
halloffame.update(population)
# Gather all the fitnesses in one list and print the stats
record = stats.compile(population) if stats else {}
logbook.record(gen=gen, nevals=len(population), **record)
if verbose:
print(logbook.stream)
return population, logbook
class optimization_problem: class optimization_problem:
def __init__(self, prediction_hours=48, strafe=10, optimization_hours=24, verbose=False, fixed_seed=None): def __init__(self, prediction_hours=24, strafe = 10, optimization_hours= 24):
self.prediction_hours = prediction_hours self.prediction_hours = prediction_hours#
self.strafe = strafe self.strafe = strafe
self.opti_param = None self.opti_param = None
self.fixed_eauto_hours = prediction_hours - optimization_hours self.fixed_eauto_hours = prediction_hours-optimization_hours
self.possible_charge_values = moegliche_ladestroeme_in_prozent self.possible_charge_values = moegliche_ladestroeme_in_prozent
self.verbose = verbose
if fixed_seed is not None:
random.seed(fixed_seed)
def split_individual(self, individual): def split_individual(self, individual):
"""Splits an individual into its components: discharge hours, EV charge hours, and appliance start.""" """
discharge_hours_bin = individual[:self.prediction_hours] Teilt das gegebene Individuum in die verschiedenen Parameter auf:
eautocharge_hours_float = individual[self.prediction_hours:self.prediction_hours * 2] - Entladeparameter (discharge_hours_bin)
- Ladeparameter (eautocharge_hours_float)
- Haushaltsgeräte (spuelstart_int, falls vorhanden)
"""
# Extrahiere die Entlade- und Ladeparameter direkt aus dem Individuum
discharge_hours_bin = individual[:self.prediction_hours] # Erste 24 Werte sind Bool (Entladen)
eautocharge_hours_float = individual[self.prediction_hours:self.prediction_hours * 2] # Nächste 24 Werte sind Float (Laden)
spuelstart_int = individual[-1] if self.opti_param.get("haushaltsgeraete", 0) > 0 else None spuelstart_int = None
if self.opti_param and self.opti_param.get("haushaltsgeraete", 0) > 0:
spuelstart_int = individual[-1] # Letzter Wert ist Startzeit für Haushaltsgerät
return discharge_hours_bin, eautocharge_hours_float, spuelstart_int return discharge_hours_bin, eautocharge_hours_float, spuelstart_int
def setup_deap_environment(self, opti_param, start_hour):
"""Sets up the DEAP environment with the given optimization parameters.""" def setup_deap_environment(self,opti_param, start_hour):
self.opti_param = opti_param self.opti_param = opti_param
if "FitnessMin" in creator.__dict__: if "FitnessMin" in creator.__dict__:
del creator.FitnessMin del creator.FitnessMin
if "Individual" in creator.__dict__: if "Individual" in creator.__dict__:
del creator.Individual del creator.Individual
# Clear any previous fitness and individual definitions
creator.create("FitnessMin", base.Fitness, weights=(-1.0,)) creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMin) creator.create("Individual", list, fitness=creator.FitnessMin)
# PARAMETER
self.toolbox = base.Toolbox() self.toolbox = base.Toolbox()
self.toolbox.register("attr_bool", random.randint, 0, 1) self.toolbox.register("attr_bool", random.randint, 0, 1)
self.toolbox.register("attr_float", random.uniform, 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_choice", random.choice, self.possible_charge_values) # Für diskrete Ladeströme
self.toolbox.register("attr_int", random.randint, start_hour, 23) self.toolbox.register("attr_int", random.randint, start_hour, 23)
###################
# Haushaltsgeraete
#print("Haushalt:",opti_param["haushaltsgeraete"])
if opti_param["haushaltsgeraete"]>0:
def create_individual(): def create_individual():
"""Creates an individual based on the prediction hours and appliance start time.""" attrs = [self.toolbox.attr_bool() for _ in range(self.prediction_hours)] # 24 Bool-Werte für Entladen
attrs = [self.toolbox.attr_bool() for _ in range(self.prediction_hours)] attrs += [self.toolbox.attr_float() for _ in range(self.prediction_hours)] # 24 Float-Werte für Laden
attrs += [self.toolbox.attr_float() for _ in range(self.prediction_hours)] attrs.append(self.toolbox.attr_int()) # Haushaltsgerät-Startzeit
if opti_param["haushaltsgeraete"] > 0:
attrs.append(self.toolbox.attr_int())
return creator.Individual(attrs) return creator.Individual(attrs)
self.toolbox.register("individual", create_individual) 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
return creator.Individual(attrs)
self.toolbox.register("individual", create_individual)#tools.initCycle, creator.Individual, (self.toolbox.attr_bool,self.toolbox.attr_bool), n=self.prediction_hours+1)
self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual) self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual)
self.toolbox.register("mate", tools.cxTwoPoint) self.toolbox.register("mate", tools.cxTwoPoint)
self.toolbox.register("mutate", tools.mutFlipBit, indpb=0.1) self.toolbox.register("mutate", tools.mutFlipBit, indpb=0.1)
#self.toolbox.register("mutate", mutate_choice, self.possible_charge_values, indpb=0.1)
#self.toolbox.register("mutate", tools.mutUniformInt, low=0, up=len(self.possible_charge_values)-1, indpb=0.1)
self.toolbox.register("select", tools.selTournament, tournsize=3) self.toolbox.register("select", tools.selTournament, tournsize=3)
def evaluate_inner(self, individual, ems, start_hour): def evaluate_inner(self,individual, ems,start_hour):
"""Performs inner evaluation of an individual's performance."""
ems.reset() ems.reset()
#print("Spuel:",self.opti_param)
discharge_hours_bin, eautocharge_hours_float, spuelstart_int = self.split_individual(individual) discharge_hours_bin, eautocharge_hours_float, spuelstart_int = self.split_individual(individual)
if self.opti_param["haushaltsgeraete"] > 0: # Haushaltsgeraete
ems.set_haushaltsgeraet_start(spuelstart_int, global_start_hour=start_hour) if self.opti_param["haushaltsgeraete"]>0:
ems.set_haushaltsgeraet_start(spuelstart_int,global_start_hour=start_hour)
#discharge_hours_bin = np.full(self.prediction_hours,0)
ems.set_akku_discharge_hours(discharge_hours_bin) ems.set_akku_discharge_hours(discharge_hours_bin)
# Ensure fixed EV charging hours are set to 0.0 # Setze die festen Werte für die letzten x Stunden
eautocharge_hours_float[self.prediction_hours - self.fixed_eauto_hours:] = [0.0] * self.fixed_eauto_hours 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) ems.set_eauto_charge_hours(eautocharge_hours_float)
return ems.simuliere(start_hour)
def evaluate(self, individual, ems, parameter, start_hour, worst_case): o = ems.simuliere(start_hour)
"""
Fitness function that evaluates the given individual by applying it to the EMS and calculating penalties and rewards. return o
"""
# Fitness-Funktion (muss Ihre EnergieManagementSystem-Logik integrieren)
def evaluate(self,individual,ems,parameter,start_hour,worst_case):
try: try:
evaluation_results = self.evaluate_inner(individual, ems, start_hour) o = self.evaluate_inner(individual,ems,start_hour)
except Exception: except:
return (100000.0,) return (100000.0,)
# Calculate total balance in euros gesamtbilanz = o["Gesamtbilanz_Euro"]
gesamtbilanz = evaluation_results["Gesamtbilanz_Euro"]
if worst_case: if worst_case:
gesamtbilanz *= -1.0 gesamtbilanz = gesamtbilanz * -1.0
discharge_hours_bin, eautocharge_hours_float, spuelstart_int = self.split_individual(individual) discharge_hours_bin, eautocharge_hours_float, spuelstart_int = self.split_individual(individual)
max_ladeleistung = np.max(self.possible_charge_values) max_ladeleistung = np.max(moegliche_ladestroeme_in_prozent)
# Calculate penalties strafe_überschreitung = 0.0
strafe_ueberschreitung = self.calculate_exceeding_penalty(eautocharge_hours_float, max_ladeleistung)
gesamtbilanz += self.calculate_unused_discharge_penalty(discharge_hours_bin)
gesamtbilanz += self.calculate_restricted_charging_penalty(eautocharge_hours_float, parameter)
# Check minimum state of charge (SoC) for the EV # Ladeleistung überschritten?
final_soc = ems.eauto.ladezustand_in_prozent()
if (parameter['eauto_min_soc'] - final_soc) > 0.0:
gesamtbilanz += self.calculate_min_soc_penalty(eautocharge_hours_float, parameter, final_soc)
# Record extra data for the individual
eauto_roi = parameter['eauto_min_soc'] - final_soc
individual.extra_data = (evaluation_results["Gesamtbilanz_Euro"], evaluation_results["Gesamt_Verluste"], eauto_roi)
# Calculate residual energy in the battery
restenergie_akku = ems.akku.aktueller_energieinhalt()
restwert_akku = restenergie_akku * parameter["preis_euro_pro_wh_akku"]
# Final penalties and fitness calculation
strafe = max(0, (parameter['eauto_min_soc'] - final_soc) * self.strafe)
gesamtbilanz += strafe - restwert_akku + strafe_ueberschreitung
return (gesamtbilanz,)
def calculate_exceeding_penalty(self, eautocharge_hours_float, max_ladeleistung):
"""Calculate penalties for exceeding charging power limits."""
penalty = 0.0
for ladeleistung in eautocharge_hours_float: for ladeleistung in eautocharge_hours_float:
if ladeleistung > max_ladeleistung: if ladeleistung > max_ladeleistung:
penalty += self.strafe * 10 # Penalty is proportional to the violation # Berechne die Überschreitung
return penalty überschreitung = ladeleistung - max_ladeleistung
# Füge eine Strafe hinzu (z.B. 10 Einheiten Strafe pro Prozentpunkt Überschreitung)
strafe_überschreitung += self.strafe * 10 # Hier ist die Strafe proportional zur Überschreitung
def calculate_unused_discharge_penalty(self, discharge_hours_bin):
"""Calculate penalty for unused discharge hours."""
penalty = 0.0
for hour in discharge_hours_bin:
if hour == 0.0:
penalty += 0.01 # Small penalty for each unused discharge hour
return penalty
def calculate_restricted_charging_penalty(self, eautocharge_hours_float, parameter): # 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
"""Calculate penalty for charging the EV during restricted hours.""" for i in range(0, self.prediction_hours):
penalty = 0.0 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
for i in range(self.prediction_hours - self.fixed_eauto_hours, self.prediction_hours): for i in range(self.prediction_hours - self.fixed_eauto_hours, self.prediction_hours):
if eautocharge_hours_float[i] != 0.0: if eautocharge_hours_float[i] != 0.0: # Wenn die letzten x Stunden von einem festen Wert abweichen
penalty += self.strafe # Penalty for charging during fixed hours gesamtbilanz += self.strafe # Bestrafe den Optimierer
return penalty
def calculate_min_soc_penalty(self, eautocharge_hours_float, parameter, final_soc):
"""Calculate penalty for not meeting the minimum state of charge (SoC).""" # Überprüfung, ob der Mindest-SoC erreicht wird
penalty = 0.0 final_soc = ems.eauto.ladezustand_in_prozent() # Nimmt den SoC am Ende des Optimierungszeitraums
for hour in eautocharge_hours_float:
if hour != 0.0: if (parameter['eauto_min_soc']-ems.eauto.ladezustand_in_prozent()) <= 0.0:
penalty += self.strafe # Penalty for not meeting minimum SoC #print (parameter['eauto_min_soc']," " ,ems.eauto.ladezustand_in_prozent()," ",(parameter['eauto_min_soc']-ems.eauto.ladezustand_in_prozent()))
return penalty for i in range(0, self.prediction_hours):
# Genetic Algorithm for Optimization if eautocharge_hours_float[i] != 0.0: # Wenn die letzten x Stunden von einem festen Wert abweichen
gesamtbilanz += self.strafe # Bestrafe den Optimierer
eauto_roi = (parameter['eauto_min_soc']-ems.eauto.ladezustand_in_prozent())
individual.extra_data = (o["Gesamtbilanz_Euro"],o["Gesamt_Verluste"], eauto_roi )
restenergie_akku = ems.akku.aktueller_energieinhalt()
restwert_akku = restenergie_akku*parameter["preis_euro_pro_wh_akku"]
# print(restenergie_akku)
# print(parameter["preis_euro_pro_wh_akku"])
# print(restwert_akku)
# print()
strafe = 0.0
strafe = max(0,(parameter['eauto_min_soc']-ems.eauto.ladezustand_in_prozent()) * self.strafe )
gesamtbilanz += strafe - restwert_akku + strafe_überschreitung
#gesamtbilanz += o["Gesamt_Verluste"]/10000.0
return (gesamtbilanz,)
# Example of how to use the callback in your optimization
def optimize(self, start_solution=None, generations_no_improvement=20):
# Genetischer Algorithmus
def optimize(self,start_solution=None):
population = self.toolbox.population(n=300) population = self.toolbox.population(n=300)
hof = tools.HallOfFame(1) hof = tools.HallOfFame(1)
@ -168,118 +267,151 @@ class optimization_problem:
stats.register("min", np.min) stats.register("min", np.min)
stats.register("max", np.max) stats.register("max", np.max)
if self.verbose: print("Start:",start_solution)
print("Start solution:", start_solution)
if start_solution is not None and start_solution != -1: if start_solution is not None and start_solution != -1:
starting_individual = creator.Individual(start_solution) population.insert(0, creator.Individual(start_solution))
population = [starting_individual] * 3 + population population.insert(1, creator.Individual(start_solution))
population.insert(2, creator.Individual(start_solution))
# Register the convergence callback algorithms.eaMuPlusLambda(population, self.toolbox, mu=100, lambda_=200, cxpb=0.5, mutpb=0.3, ngen=400, stats=stats, halloffame=hof, verbose=True)
convergence_count = 0 #algorithms.eaSimple(population, self.toolbox, cxpb=0.3, mutpb=0.3, ngen=200, stats=stats, halloffame=hof, verbose=True)
convergence_last = float('inf') #algorithms.eaMuCommaLambda(population, self.toolbox, mu=100, lambda_=200, cxpb=0.2, mutpb=0.4, ngen=300, stats=stats, halloffame=hof, verbose=True)
generations_no_improvement = 20 #population, log = differential_evolution(population, self.toolbox, cxpb=0.2, mutpb=0.5, ngen=200, stats=stats, halloffame=hof, verbose=True)
# Run the genetic algorithm with 3 additional callback per generation
for gen in range(1000): # Define the number of generations
population, logbook = algorithms.eaMuPlusLambda(
population, self.toolbox,
mu=100, lambda_=200,
cxpb=0.5, mutpb=0.3,
ngen=2, stats=stats, # Run for 1 generation at a time
halloffame=hof, verbose=False
)
# Retrieve statistics from the logbook (only one generation per loop)
if len(logbook) > 0:
gen_stats = logbook[-1]
# Print generation stats if self.verbose is True
if self.verbose:
print(f"Generation {gen}: {gen_stats}")
# Call the convergence check after each generation
best_fitness = max(ind.fitness.values[0] for ind in population)
if best_fitness >= convergence_last:
convergence_count += 1 member = {"bilanz":[],"verluste":[],"nebenbedingung":[]}
if convergence_count >= generations_no_improvement:
if self.verbose:
print(f"Convergence detected at generation {gen}. No improvement in the last {generations_no_improvement} generations.")
break
else:
convergence_count = 0
convergence_last = best_fitness
# Collect extra data (if exists) from the individuals in the population
member = {"bilanz": [], "verluste": [], "nebenbedingung": []}
for ind in population: for ind in population:
if hasattr(ind, 'extra_data'): if hasattr(ind, 'extra_data'):
member["bilanz"].append(ind.extra_data[0]) extra_value1, extra_value2,extra_value3 = ind.extra_data
member["verluste"].append(ind.extra_data[1]) member["bilanz"].append(extra_value1)
member["nebenbedingung"].append(ind.extra_data[2]) member["verluste"].append(extra_value2)
print(max(ind.fitness.values[0] for ind in population)) member["nebenbedingung"].append(extra_value3)
# Return the best solution
return hof[0], member return hof[0], member
def optimierung_ems(self, parameter=None, start_hour=None, worst_case=False, startdate=None):
"""Orchestrates the entire EMS optimization.""" def optimierung_ems(self,parameter=None, start_hour=None,worst_case=False, startdate=None):
current_date = datetime.now()
if startdate is None:
date = (current_date + timedelta(hours=self.prediction_hours)).strftime("%Y-%m-%d") ############
date_now = current_date.strftime("%Y-%m-%d") # Parameter
############
if startdate == None:
date = (datetime.now().date() + timedelta(hours = self.prediction_hours)).strftime("%Y-%m-%d")
date_now = datetime.now().strftime("%Y-%m-%d")
else: else:
date = (startdate + timedelta(hours=self.prediction_hours)).strftime("%Y-%m-%d") date = (startdate + timedelta(hours = self.prediction_hours)).strftime("%Y-%m-%d")
date_now = startdate.strftime("%Y-%m-%d") date_now = startdate.strftime("%Y-%m-%d")
#print("Start_date:",date_now)
# Initialize battery and EV objects akku_size = parameter['pv_akku_cap'] # Wh
akku = PVAkku(kapazitaet_wh=parameter['pv_akku_cap'], hours=self.prediction_hours,
start_soc_prozent=parameter["pv_soc"], max_ladeleistung_w=5000)
akku.set_charge_per_hour(np.ones(self.prediction_hours))
eauto = PVAkku(kapazitaet_wh=parameter["eauto_cap"], hours=self.prediction_hours, einspeiseverguetung_euro_pro_wh = np.full(self.prediction_hours, parameter["einspeiseverguetung_euro_pro_wh"]) #= # € / Wh 7/(1000.0*100.0)
lade_effizienz=parameter["eauto_charge_efficiency"], max_ladeleistung_w=parameter["eauto_charge_power"], 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]) #
start_soc_prozent=parameter["eauto_soc"]) akku = PVAkku(kapazitaet_wh=akku_size,hours=self.prediction_hours,start_soc_prozent=parameter["pv_soc"], max_ladeleistung_w=5000)
eauto.set_charge_per_hour(np.ones(self.prediction_hours)) akku.set_charge_per_hour(discharge_array)
# Household appliance initialization
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']
start_params = parameter['start_solution']
###############
# spuelmaschine
##############
print(parameter)
if parameter["haushaltsgeraet_dauer"] >0:
spuelmaschine = Haushaltsgeraet(hours=self.prediction_hours, verbrauch_kwh=parameter["haushaltsgeraet_wh"], dauer_h=parameter["haushaltsgeraet_dauer"])
spuelmaschine.set_startzeitpunkt(start_hour) # Startet jetzt
else:
spuelmaschine = None spuelmaschine = None
if parameter["haushaltsgeraet_dauer"] > 0:
spuelmaschine = Haushaltsgeraet(hours=self.prediction_hours,
verbrauch_kwh=parameter["haushaltsgeraet_wh"],
dauer_h=parameter["haushaltsgeraet_dauer"])
spuelmaschine.set_startzeitpunkt(start_hour)
ems = EnergieManagementSystem(
gesamtlast=parameter["gesamtlast"],
pv_prognose_wh=parameter['pv_forecast'],
strompreis_euro_pro_wh=parameter["strompreis_euro_pro_wh"],
einspeiseverguetung_euro_pro_wh=np.full(self.prediction_hours, parameter["einspeiseverguetung_euro_pro_wh"]),
eauto=eauto,
haushaltsgeraet=spuelmaschine,
wechselrichter=Wechselrichter(10000, akku)
)
self.setup_deap_environment({"haushaltsgeraete": int(spuelmaschine is not None)}, start_hour)
self.toolbox.register("evaluate", lambda ind: self.evaluate(ind, ems, parameter, start_hour, worst_case))
start_solution, extra_data = self.optimize(parameter['start_solution'])
###############
# PV Forecast
###############
#PVforecast = PVForecast(filepath=os.path.join(r'test_data', r'pvprognose.json'))
# PVforecast = PVForecast(prediction_hours = self.prediction_hours, url=pv_forecast_url)
# #print("PVPOWER",parameter['pvpowernow'])
# if isfloat(parameter['pvpowernow']):
# PVforecast.update_ac_power_measurement(date_time=datetime.now(), ac_power_measurement=float(parameter['pvpowernow']))
# #PVforecast.print_ac_power_and_measurement()
pv_forecast = parameter['pv_forecast'] #PVforecast.get_pv_forecast_for_date_range(date_now,date) #get_forecast_for_date(date)
temperature_forecast = parameter['temperature_forecast'] #PVforecast.get_temperature_for_date_range(date_now,date)
###############
# Strompreise
###############
specific_date_prices = parameter["strompreis_euro_pro_wh"]
print(specific_date_prices)
#print("https://api.akkudoktor.net/prices?start="+date_now+"&end="+date)
wr = Wechselrichter(10000, akku)
ems = EnergieManagementSystem(gesamtlast = parameter["gesamtlast"], pv_prognose_wh=pv_forecast, strompreis_euro_pro_wh=specific_date_prices, einspeiseverguetung_euro_pro_wh=einspeiseverguetung_euro_pro_wh, eauto=eauto, haushaltsgeraet=spuelmaschine,wechselrichter=wr)
o = ems.simuliere(start_hour)
###############
# Optimizer Init
##############
opti_param = {}
opti_param["haushaltsgeraete"] = 0
if spuelmaschine != None:
opti_param["haushaltsgeraete"] = 1
self.setup_deap_environment(opti_param, start_hour)
def evaluate_wrapper(individual):
return self.evaluate(individual, ems, parameter,start_hour,worst_case)
self.toolbox.register("evaluate", evaluate_wrapper)
start_solution, extra_data = self.optimize(start_params)
best_solution = start_solution best_solution = start_solution
o = self.evaluate_inner(best_solution, ems,start_hour)
# Perform final evaluation and visualize results eauto = ems.eauto.to_dict()
o = self.evaluate_inner(best_solution, ems, start_hour) spuelstart_int = None
discharge_hours_bin, eautocharge_hours_float, spuelstart_int = self.split_individual(best_solution) discharge_hours_bin, eautocharge_hours_float, spuelstart_int = self.split_individual(best_solution)
visualisiere_ergebnisse(parameter["gesamtlast"], parameter['pv_forecast'], parameter["strompreis_euro_pro_wh"], o,
discharge_hours_bin, eautocharge_hours_float,
parameter['temperature_forecast'], start_hour, self.prediction_hours,
parameter["strompreis_euro_pro_wh"], extra_data=extra_data)
return { print(parameter)
"discharge_hours_bin": discharge_hours_bin, print(best_solution)
"eautocharge_hours_float": eautocharge_hours_float, visualisiere_ergebnisse(parameter["gesamtlast"], pv_forecast, specific_date_prices, o,discharge_hours_bin,eautocharge_hours_float , temperature_forecast, start_hour, self.prediction_hours,einspeiseverguetung_euro_pro_wh,extra_data=extra_data)
"result": o, os.system("cp visualisierungsergebnisse.pdf ~/")
"eauto_obj": ems.eauto.to_dict(),
"start_solution": best_solution, # 'Eigenverbrauch_Wh_pro_Stunde': eigenverbrauch_wh_pro_stunde,
"spuelstart": spuelstart_int, # 'Netzeinspeisung_Wh_pro_Stunde': netzeinspeisung_wh_pro_stunde,
"simulation_data": o # 'Netzbezug_Wh_pro_Stunde': netzbezug_wh_pro_stunde,
} # 'Kosten_Euro_pro_Stunde': kosten_euro_pro_stunde,
# 'akku_soc_pro_stunde': akku_soc_pro_stunde,
# 'Einnahmen_Euro_pro_Stunde': einnahmen_euro_pro_stunde,
# 'Gesamtbilanz_Euro': gesamtkosten_euro,
# 'E-Auto_SoC_pro_Stunde':eauto_soc_pro_stunde,
# 'Gesamteinnahmen_Euro': sum(einnahmen_euro_pro_stunde),
# 'Gesamtkosten_Euro': sum(kosten_euro_pro_stunde),
# "Verluste_Pro_Stunde":verluste_wh_pro_stunde,
# "Gesamt_Verluste":sum(verluste_wh_pro_stunde),
# "Haushaltsgeraet_wh_pro_stunde":haushaltsgeraet_wh_pro_stunde
#print(eauto)
return {"discharge_hours_bin":discharge_hours_bin, "eautocharge_hours_float":eautocharge_hours_float ,"result":o ,"eauto_obj":eauto,"start_solution":best_solution,"spuelstart":spuelstart_int,"simulation_data":o}