mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-04-19 08:55:15 +00:00
[BUG]: class_ems nd_array not JSON serializable
Big Bugfix - not sure if everything works
This commit is contained in:
parent
e72008471f
commit
004e1f3dc7
@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
from pprint import pprint
|
import json
|
||||||
|
|
||||||
# Import necessary modules from the project
|
# Import necessary modules from the project
|
||||||
from modules.class_optimize import optimization_problem
|
from akkudoktoreos.class_optimize import optimization_problem
|
||||||
|
|
||||||
start_hour = 10
|
start_hour = 10
|
||||||
|
|
||||||
@ -216,107 +216,7 @@ gesamtlast = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Start Solution (binary)
|
# Start Solution (binary)
|
||||||
start_solution = [
|
start_solution = None
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
]
|
|
||||||
|
|
||||||
# Define parameters for the optimization problem
|
# Define parameters for the optimization problem
|
||||||
parameter = {
|
parameter = {
|
||||||
@ -341,7 +241,7 @@ parameter = {
|
|||||||
# Electricity price forecast (48 hours)
|
# Electricity price forecast (48 hours)
|
||||||
"strompreis_euro_pro_wh": strompreis_euro_pro_wh,
|
"strompreis_euro_pro_wh": strompreis_euro_pro_wh,
|
||||||
# Minimum SOC for electric car
|
# Minimum SOC for electric car
|
||||||
"eauto_min_soc": 1000,
|
"eauto_min_soc": 80,
|
||||||
# Electric car battery capacity (Wh)
|
# Electric car battery capacity (Wh)
|
||||||
"eauto_cap": 60000,
|
"eauto_cap": 60000,
|
||||||
# Charging efficiency of the electric car
|
# Charging efficiency of the electric car
|
||||||
@ -371,4 +271,7 @@ opt_class = optimization_problem(
|
|||||||
ergebnis = opt_class.optimierung_ems(parameter=parameter, start_hour=start_hour)
|
ergebnis = opt_class.optimierung_ems(parameter=parameter, start_hour=start_hour)
|
||||||
|
|
||||||
# Print or visualize the result
|
# Print or visualize the result
|
||||||
pprint(ergebnis)
|
# pprint(ergebnis)
|
||||||
|
|
||||||
|
json_data = json.dumps(ergebnis)
|
||||||
|
print(json_data)
|
||||||
|
@ -58,15 +58,15 @@ class EnergieManagementSystem:
|
|||||||
total_hours = ende - start_stunde
|
total_hours = ende - start_stunde
|
||||||
|
|
||||||
# Pre-allocate arrays for the results, optimized for speed
|
# Pre-allocate arrays for the results, optimized for speed
|
||||||
last_wh_pro_stunde = np.zeros(total_hours)
|
last_wh_pro_stunde = np.full((total_hours), np.nan)
|
||||||
netzeinspeisung_wh_pro_stunde = np.zeros(total_hours)
|
netzeinspeisung_wh_pro_stunde = np.full((total_hours), np.nan)
|
||||||
netzbezug_wh_pro_stunde = np.zeros(total_hours)
|
netzbezug_wh_pro_stunde = np.full((total_hours), np.nan)
|
||||||
kosten_euro_pro_stunde = np.zeros(total_hours)
|
kosten_euro_pro_stunde = np.full((total_hours), np.nan)
|
||||||
einnahmen_euro_pro_stunde = np.zeros(total_hours)
|
einnahmen_euro_pro_stunde = np.full((total_hours), np.nan)
|
||||||
akku_soc_pro_stunde = np.zeros(total_hours)
|
akku_soc_pro_stunde = np.full((total_hours), np.nan)
|
||||||
eauto_soc_pro_stunde = np.zeros(total_hours)
|
eauto_soc_pro_stunde = np.full((total_hours), np.nan)
|
||||||
verluste_wh_pro_stunde = np.zeros(total_hours)
|
verluste_wh_pro_stunde = np.full((total_hours), np.nan)
|
||||||
haushaltsgeraet_wh_pro_stunde = np.zeros(total_hours)
|
haushaltsgeraet_wh_pro_stunde = np.full((total_hours), np.nan)
|
||||||
|
|
||||||
# Set initial state
|
# Set initial state
|
||||||
akku_soc_pro_stunde[0] = self.akku.ladezustand_in_prozent()
|
akku_soc_pro_stunde[0] = self.akku.ladezustand_in_prozent()
|
||||||
@ -78,7 +78,7 @@ class EnergieManagementSystem:
|
|||||||
|
|
||||||
# Accumulate loads and PV generation
|
# Accumulate loads and PV generation
|
||||||
verbrauch = self.gesamtlast[stunde]
|
verbrauch = self.gesamtlast[stunde]
|
||||||
|
verluste_wh_pro_stunde[stunde_since_now] = 0.0
|
||||||
if self.haushaltsgeraet:
|
if self.haushaltsgeraet:
|
||||||
ha_load = self.haushaltsgeraet.get_last_fuer_stunde(stunde)
|
ha_load = self.haushaltsgeraet.get_last_fuer_stunde(stunde)
|
||||||
verbrauch += ha_load
|
verbrauch += ha_load
|
||||||
@ -117,7 +117,7 @@ class EnergieManagementSystem:
|
|||||||
akku_soc_pro_stunde[stunde_since_now] = self.akku.ladezustand_in_prozent()
|
akku_soc_pro_stunde[stunde_since_now] = self.akku.ladezustand_in_prozent()
|
||||||
|
|
||||||
# Total cost and return
|
# Total cost and return
|
||||||
gesamtkosten_euro = np.sum(kosten_euro_pro_stunde) - np.sum(
|
gesamtkosten_euro = np.nansum(kosten_euro_pro_stunde) - np.nansum(
|
||||||
einnahmen_euro_pro_stunde
|
einnahmen_euro_pro_stunde
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -131,35 +131,10 @@ class EnergieManagementSystem:
|
|||||||
"Einnahmen_Euro_pro_Stunde": einnahmen_euro_pro_stunde,
|
"Einnahmen_Euro_pro_Stunde": einnahmen_euro_pro_stunde,
|
||||||
"Gesamtbilanz_Euro": gesamtkosten_euro,
|
"Gesamtbilanz_Euro": gesamtkosten_euro,
|
||||||
"E-Auto_SoC_pro_Stunde": eauto_soc_pro_stunde,
|
"E-Auto_SoC_pro_Stunde": eauto_soc_pro_stunde,
|
||||||
"Gesamteinnahmen_Euro": np.sum(einnahmen_euro_pro_stunde),
|
"Gesamteinnahmen_Euro": np.nansum(einnahmen_euro_pro_stunde),
|
||||||
"Gesamtkosten_Euro": np.sum(kosten_euro_pro_stunde),
|
"Gesamtkosten_Euro": np.nansum(kosten_euro_pro_stunde),
|
||||||
"Verluste_Pro_Stunde": verluste_wh_pro_stunde,
|
"Verluste_Pro_Stunde": verluste_wh_pro_stunde,
|
||||||
"Gesamt_Verluste": np.sum(verluste_wh_pro_stunde),
|
"Gesamt_Verluste": np.nansum(verluste_wh_pro_stunde),
|
||||||
"Haushaltsgeraet_wh_pro_stunde": haushaltsgeraet_wh_pro_stunde,
|
"Haushaltsgeraet_wh_pro_stunde": haushaltsgeraet_wh_pro_stunde,
|
||||||
}
|
}
|
||||||
|
|
||||||
# List output keys where the first element needs to be changed to None
|
|
||||||
keys_to_modify = [
|
|
||||||
"Last_Wh_pro_Stunde",
|
|
||||||
"Netzeinspeisung_Wh_pro_Stunde",
|
|
||||||
"akku_soc_pro_stunde",
|
|
||||||
"Netzbezug_Wh_pro_Stunde",
|
|
||||||
"Kosten_Euro_pro_Stunde",
|
|
||||||
"Einnahmen_Euro_pro_Stunde",
|
|
||||||
"E-Auto_SoC_pro_Stunde",
|
|
||||||
"Verluste_Pro_Stunde",
|
|
||||||
"Haushaltsgeraet_wh_pro_stunde"
|
|
||||||
]
|
|
||||||
|
|
||||||
# Loop through each key in the list
|
|
||||||
for key in keys_to_modify:
|
|
||||||
# Convert the NumPy array to a list
|
|
||||||
element_list = out[key].tolist()
|
|
||||||
|
|
||||||
# Change the first value to None
|
|
||||||
element_list[0] = None
|
|
||||||
|
|
||||||
# Assign the modified list back to the dictionary
|
|
||||||
out[key] = element_list
|
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
@ -16,7 +16,6 @@ class Haushaltsgeraet:
|
|||||||
:param start_hour: The hour at which the device should start.
|
:param start_hour: The hour at which the device should start.
|
||||||
"""
|
"""
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
# Check if the duration of use is within the available time frame
|
# Check if the duration of use is within the available time frame
|
||||||
if start_hour + self.dauer_h > self.hours:
|
if start_hour + self.dauer_h > self.hours:
|
||||||
raise ValueError("The duration of use exceeds the available time frame.")
|
raise ValueError("The duration of use exceeds the available time frame.")
|
||||||
|
@ -15,7 +15,7 @@ from akkudoktoreos.visualize import visualisiere_ergebnisse
|
|||||||
class optimization_problem:
|
class optimization_problem:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
prediction_hours: int = 24,
|
prediction_hours: int = 48,
|
||||||
strafe: float = 10,
|
strafe: float = 10,
|
||||||
optimization_hours: int = 24,
|
optimization_hours: int = 24,
|
||||||
verbose: bool = False,
|
verbose: bool = False,
|
||||||
@ -138,7 +138,7 @@ class optimization_problem:
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
o = self.evaluate_inner(individual, ems, start_hour)
|
o = self.evaluate_inner(individual, ems, start_hour)
|
||||||
except Exception:
|
except Exception as e:
|
||||||
return (100000.0,) # Return a high penalty in case of an exception
|
return (100000.0,) # Return a high penalty in case of an exception
|
||||||
|
|
||||||
gesamtbilanz = o["Gesamtbilanz_Euro"] * (-1.0 if worst_case else 1.0)
|
gesamtbilanz = o["Gesamtbilanz_Euro"] * (-1.0 if worst_case else 1.0)
|
||||||
@ -326,6 +326,35 @@ class optimization_problem:
|
|||||||
extra_data=extra_data,
|
extra_data=extra_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# List output keys where the first element needs to be changed to None
|
||||||
|
keys_to_modify = [
|
||||||
|
"Last_Wh_pro_Stunde",
|
||||||
|
"Netzeinspeisung_Wh_pro_Stunde",
|
||||||
|
"akku_soc_pro_stunde",
|
||||||
|
"Netzbezug_Wh_pro_Stunde",
|
||||||
|
"Kosten_Euro_pro_Stunde",
|
||||||
|
"Einnahmen_Euro_pro_Stunde",
|
||||||
|
"E-Auto_SoC_pro_Stunde",
|
||||||
|
"Verluste_Pro_Stunde",
|
||||||
|
"Haushaltsgeraet_wh_pro_stunde",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Loop through each key in the list
|
||||||
|
for key in keys_to_modify:
|
||||||
|
# Convert the NumPy array to a list
|
||||||
|
element_list = o[key].tolist()
|
||||||
|
|
||||||
|
# Change the first value to None
|
||||||
|
element_list[0] = None
|
||||||
|
# Change the NaN to None (JSON)
|
||||||
|
element_list = [
|
||||||
|
None if isinstance(x, (int, float)) and np.isnan(x) else x
|
||||||
|
for x in element_list
|
||||||
|
]
|
||||||
|
|
||||||
|
# Assign the modified list back to the dictionary
|
||||||
|
o[key] = element_list
|
||||||
|
|
||||||
# Return final results as a dictionary
|
# Return final results as a dictionary
|
||||||
return {
|
return {
|
||||||
"discharge_hours_bin": discharge_hours_bin,
|
"discharge_hours_bin": discharge_hours_bin,
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any, TypeGuard
|
from typing import Any, TypeGuard
|
||||||
import json
|
|
||||||
import matplotlib
|
import matplotlib
|
||||||
|
|
||||||
# Sets the Matplotlib backend to 'Agg' for rendering plots in environments without a display
|
# Sets the Matplotlib backend to 'Agg' for rendering plots in environments without a display
|
||||||
matplotlib.use("Agg")
|
matplotlib.use("Agg")
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from flask import Flask, jsonify, redirect, request, send_from_directory, url_for, Response
|
from flask import Flask, jsonify, redirect, request, send_from_directory, url_for
|
||||||
|
|
||||||
from akkudoktoreos.class_load import LoadForecast
|
from akkudoktoreos.class_load import LoadForecast
|
||||||
from akkudoktoreos.class_load_container import Gesamtlast
|
from akkudoktoreos.class_load_container import Gesamtlast
|
||||||
@ -211,6 +211,12 @@ def flask_pvprognose():
|
|||||||
|
|
||||||
@app.route("/optimize", methods=["POST"])
|
@app.route("/optimize", methods=["POST"])
|
||||||
def flask_optimize():
|
def flask_optimize():
|
||||||
|
with open(
|
||||||
|
"C:\\Users\\drbac\\OneDrive\\Dokumente\\PythonPojects\\EOS\\debug_output.txt",
|
||||||
|
"a",
|
||||||
|
) as f:
|
||||||
|
f.write("Test\n")
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
@ -243,18 +249,17 @@ def flask_optimize():
|
|||||||
{"error": f"Missing parameter: {', '.join(missing_params)}"}
|
{"error": f"Missing parameter: {', '.join(missing_params)}"}
|
||||||
), 400 # Return error for missing parameters
|
), 400 # Return error for missing parameters
|
||||||
|
|
||||||
# Perform optimization simulation
|
|
||||||
result = opt_class.optimierung_ems(
|
|
||||||
parameter=parameter, start_hour=datetime.now().hour
|
|
||||||
)
|
|
||||||
|
|
||||||
# Optional min SoC PV Battery
|
# Optional min SoC PV Battery
|
||||||
if "min_soc_prozent" not in parameter:
|
if "min_soc_prozent" not in parameter:
|
||||||
parameter["min_soc_prozent"] = None
|
parameter["min_soc_prozent"] = None
|
||||||
|
|
||||||
|
# Perform optimization simulation
|
||||||
|
result = opt_class.optimierung_ems(
|
||||||
|
parameter=parameter, start_hour=datetime.now().hour
|
||||||
|
)
|
||||||
|
print(result)
|
||||||
# convert to JSON (None accepted by dumps)
|
# convert to JSON (None accepted by dumps)
|
||||||
json_data = json.dumps(result)
|
return jsonify(result)
|
||||||
return Response(json_data, mimetype='application/json')
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/visualisierungsergebnisse.pdf")
|
@app.route("/visualisierungsergebnisse.pdf")
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import numpy as np
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from akkudoktoreos.class_akku import PVAkku
|
from akkudoktoreos.class_akku import PVAkku
|
||||||
@ -279,15 +280,15 @@ def test_simulation(create_ems_instance):
|
|||||||
|
|
||||||
# Verify that the value at index 0 is 'None'
|
# Verify that the value at index 0 is 'None'
|
||||||
assert (
|
assert (
|
||||||
result["Last_Wh_pro_Stunde"][0] is None
|
np.isnan(result["Last_Wh_pro_Stunde"][0])
|
||||||
), "The value at index 0 of 'Last_Wh_pro_Stunde' should be None."
|
), "The value at index 0 of 'Last_Wh_pro_Stunde' should be None."
|
||||||
|
|
||||||
# Check that 'Netzeinspeisung_Wh_pro_Stunde' and 'Netzbezug_Wh_pro_Stunde' are consistent
|
# Check that 'Netzeinspeisung_Wh_pro_Stunde' and 'Netzbezug_Wh_pro_Stunde' are consistent
|
||||||
assert (
|
assert (
|
||||||
result["Netzeinspeisung_Wh_pro_Stunde"][0] is None
|
np.isnan(result["Netzeinspeisung_Wh_pro_Stunde"][0])
|
||||||
), "The value at index 0 of 'Netzeinspeisung_Wh_pro_Stunde' should be None."
|
), "The value at index 0 of 'Netzeinspeisung_Wh_pro_Stunde' should be None."
|
||||||
assert (
|
assert (
|
||||||
result["Netzbezug_Wh_pro_Stunde"][0] is None
|
np.isnan(result["Netzbezug_Wh_pro_Stunde"][0])
|
||||||
), "The value at index 0 of 'Netzbezug_Wh_pro_Stunde' should be None."
|
), "The value at index 0 of 'Netzbezug_Wh_pro_Stunde' should be None."
|
||||||
assert (
|
assert (
|
||||||
result["Netzbezug_Wh_pro_Stunde"][1] == 21679.13
|
result["Netzbezug_Wh_pro_Stunde"][1] == 21679.13
|
||||||
@ -325,7 +326,14 @@ def test_simulation(create_ems_instance):
|
|||||||
), "The sum of 'ems.haushaltsgeraet.get_lastkurve()' should be 2000."
|
), "The sum of 'ems.haushaltsgeraet.get_lastkurve()' should be 2000."
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
sum(result["Haushaltsgeraet_wh_pro_stunde"]) == 2000
|
np.nansum(
|
||||||
|
np.where(
|
||||||
|
np.equal(result["Haushaltsgeraet_wh_pro_stunde"], None),
|
||||||
|
np.nan,
|
||||||
|
np.array(result["Haushaltsgeraet_wh_pro_stunde"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
== 2000
|
||||||
), "The sum of 'Haushaltsgeraet_wh_pro_stunde' should be 2000."
|
), "The sum of 'Haushaltsgeraet_wh_pro_stunde' should be 2000."
|
||||||
|
|
||||||
print("All tests passed successfully.")
|
print("All tests passed successfully.")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user