EOS/tests/test_class_ems.py

356 lines
9.3 KiB
Python
Raw Normal View History

from pathlib import Path
import numpy as np
2024-10-04 10:57:01 +02:00
import pytest
2024-10-04 11:46:52 +02:00
from akkudoktoreos.config import AppConfig
from akkudoktoreos.devices.battery import EAutoParameters, PVAkku, PVAkkuParameters
from akkudoktoreos.devices.generic import HomeAppliance, HomeApplianceParameters
from akkudoktoreos.devices.inverter import Wechselrichter, WechselrichterParameters
from akkudoktoreos.prediction.ems import (
EnergieManagementSystem,
EnergieManagementSystemParameters,
SimulationResult,
)
from akkudoktoreos.prediction.self_consumption_probability import (
self_consumption_probability_interpolator,
)
2024-10-06 14:32:49 +02:00
2024-10-04 10:57:01 +02:00
prediction_hours = 48
optimization_hours = 24
start_hour = 1
2024-10-04 11:46:52 +02:00
2024-10-06 14:32:49 +02:00
2024-10-04 10:57:51 +02:00
# Example initialization of necessary components
2024-10-04 10:57:01 +02:00
@pytest.fixture
def create_ems_instance(tmp_config: AppConfig) -> EnergieManagementSystem:
"""Fixture to create an EnergieManagementSystem instance with given test parameters."""
2024-10-04 10:57:51 +02:00
# Initialize the battery and the inverter
akku = PVAkku(
PVAkkuParameters(kapazitaet_wh=5000, start_soc_prozent=80, min_soc_prozent=10),
hours=prediction_hours,
)
# 1h Load to Sub 1h Load Distribution -> SelfConsumptionRate
sc = self_consumption_probability_interpolator(
2024-12-21 13:30:51 +01:00
Path(__file__).parent.resolve()
/ ".."
/ "src"
/ "akkudoktoreos"
/ "data"
/ "regular_grid_interpolator.pkl"
)
2024-10-04 10:57:01 +02:00
akku.reset()
wechselrichter = Wechselrichter(
WechselrichterParameters(max_leistung_wh=10000), akku, self_consumption_predictor=sc
)
2024-10-04 10:57:51 +02:00
# Household device (currently not used, set to None)
home_appliance = HomeAppliance(
HomeApplianceParameters(
consumption_wh=2000,
duration_h=2,
),
2024-10-06 14:32:49 +02:00
hours=prediction_hours,
)
home_appliance.set_starting_time(2)
2024-10-06 14:32:49 +02:00
2024-10-04 10:57:51 +02:00
# Example initialization of electric car battery
eauto = PVAkku(
EAutoParameters(kapazitaet_wh=26400, start_soc_prozent=10, min_soc_prozent=10),
hours=prediction_hours,
)
eauto.set_charge_per_hour(np.full(prediction_hours, 1))
2024-10-04 10:57:51 +02:00
# Parameters based on previous example data
2024-10-04 10:57:01 +02:00
pv_prognose_wh = [
2024-10-04 11:46:52 +02:00
0,
0,
0,
0,
0,
0,
0,
8.05,
352.91,
728.51,
930.28,
1043.25,
1106.74,
1161.69,
6018.82,
5519.07,
3969.88,
3017.96,
1943.07,
1007.17,
319.67,
7.88,
0,
0,
0,
0,
0,
0,
0,
0,
0,
5.04,
335.59,
705.32,
1121.12,
1604.79,
2157.38,
1433.25,
5718.49,
4553.96,
3027.55,
2574.46,
1720.4,
963.4,
383.3,
0,
0,
0,
2024-10-04 10:57:01 +02:00
]
2024-10-04 10:57:51 +02:00
2024-10-04 10:57:01 +02:00
strompreis_euro_pro_wh = [
2024-10-04 11:46:52 +02:00
0.0003384,
0.0003318,
0.0003284,
0.0003283,
0.0003289,
0.0003334,
0.0003290,
0.0003302,
0.0003042,
0.0002430,
0.0002280,
0.0002212,
0.0002093,
0.0001879,
0.0001838,
0.0002004,
0.0002198,
0.0002270,
0.0002997,
0.0003195,
0.0003081,
0.0002969,
0.0002921,
0.0002780,
0.0003384,
0.0003318,
0.0003284,
0.0003283,
0.0003289,
0.0003334,
0.0003290,
0.0003302,
0.0003042,
0.0002430,
0.0002280,
0.0002212,
0.0002093,
0.0001879,
0.0001838,
0.0002004,
0.0002198,
0.0002270,
0.0002997,
0.0003195,
0.0003081,
0.0002969,
0.0002921,
0.0002780,
2024-10-04 10:57:01 +02:00
]
2024-10-04 10:57:51 +02:00
einspeiseverguetung_euro_pro_wh = 0.00007
preis_euro_pro_wh_akku = 0.0001
2024-10-04 10:57:01 +02:00
gesamtlast = [
2024-10-04 11:46:52 +02:00
676.71,
876.19,
527.13,
468.88,
531.38,
517.95,
483.15,
472.28,
1011.68,
995.00,
1053.07,
1063.91,
1320.56,
1132.03,
1163.67,
1176.82,
1216.22,
1103.78,
1129.12,
1178.71,
1050.98,
988.56,
912.38,
704.61,
516.37,
868.05,
694.34,
608.79,
556.31,
488.89,
506.91,
804.89,
1141.98,
1056.97,
992.46,
1155.99,
827.01,
1257.98,
1232.67,
871.26,
860.88,
1158.03,
1222.72,
1221.04,
949.99,
987.01,
733.99,
592.97,
2024-10-04 10:57:01 +02:00
]
2024-10-04 10:57:51 +02:00
# Initialize the energy management system with the respective parameters
2024-10-04 10:57:01 +02:00
ems = EnergieManagementSystem(
tmp_config.eos,
EnergieManagementSystemParameters(
pv_prognose_wh=pv_prognose_wh,
strompreis_euro_pro_wh=strompreis_euro_pro_wh,
einspeiseverguetung_euro_pro_wh=einspeiseverguetung_euro_pro_wh,
preis_euro_pro_wh_akku=preis_euro_pro_wh_akku,
gesamtlast=gesamtlast,
),
wechselrichter=wechselrichter,
2024-10-04 10:57:01 +02:00
eauto=eauto,
home_appliance=home_appliance,
2024-10-04 10:57:01 +02:00
)
2024-10-04 10:57:01 +02:00
return ems
def test_simulation(create_ems_instance):
"""Test the EnergieManagementSystem simulation method."""
2024-10-04 10:57:01 +02:00
ems = create_ems_instance
2024-10-04 10:57:51 +02:00
# Simulate starting from hour 1 (this value can be adjusted)
2024-10-06 14:32:49 +02:00
result = ems.simuliere(start_hour=start_hour)
2024-10-06 14:32:49 +02:00
2024-10-22 10:22:50 +02:00
# visualisiere_ergebnisse(
# ems.gesamtlast,
# ems.pv_prognose_wh,
# ems.strompreis_euro_pro_wh,
# result,
# ems.akku.discharge_array+ems.akku.charge_array,
# None,
# ems.pv_prognose_wh,
# start_hour,
# 48,
# np.full(48, 0.0),
# filename="visualization_results.pdf",
# extra_data=None,
# )
2024-10-04 10:57:01 +02:00
# Assertions to validate results
2024-10-04 10:57:51 +02:00
assert result is not None, "Result should not be None"
assert isinstance(result, dict), "Result should be a dictionary"
assert "Last_Wh_pro_Stunde" in result, "Result should contain 'Last_Wh_pro_Stunde'"
2024-10-04 10:57:01 +02:00
"""
2024-10-04 10:57:51 +02:00
Check the result of the simulation based on expected values.
2024-10-04 10:57:01 +02:00
"""
2024-10-04 10:57:51 +02:00
# Example result returned from the simulation (used for assertions)
assert result is not None, "Result should not be None."
# Check that the result is a dictionary
assert isinstance(result, dict), "Result should be a dictionary."
assert SimulationResult(**result) is not None
2024-10-04 10:57:51 +02:00
# Check the length of the main arrays
2024-10-04 11:46:52 +02:00
assert (
len(result["Last_Wh_pro_Stunde"]) == 47
), "The length of 'Last_Wh_pro_Stunde' should be 48."
assert (
len(result["Netzeinspeisung_Wh_pro_Stunde"]) == 47
), "The length of 'Netzeinspeisung_Wh_pro_Stunde' should be 48."
assert (
len(result["Netzbezug_Wh_pro_Stunde"]) == 47
), "The length of 'Netzbezug_Wh_pro_Stunde' should be 48."
assert (
len(result["Kosten_Euro_pro_Stunde"]) == 47
), "The length of 'Kosten_Euro_pro_Stunde' should be 48."
assert (
len(result["akku_soc_pro_stunde"]) == 47
), "The length of 'akku_soc_pro_stunde' should be 48."
2024-10-04 10:57:51 +02:00
# Verify specific values in the 'Last_Wh_pro_Stunde' array
2024-10-04 11:46:52 +02:00
assert (
2024-10-22 10:22:50 +02:00
result["Last_Wh_pro_Stunde"][1] == 1527.13
), "The value at index 1 of 'Last_Wh_pro_Stunde' should be 1527.13."
2024-10-04 11:46:52 +02:00
assert (
2024-10-22 10:22:50 +02:00
result["Last_Wh_pro_Stunde"][2] == 1468.88
), "The value at index 2 of 'Last_Wh_pro_Stunde' should be 1468.88."
2024-10-04 11:46:52 +02:00
assert (
result["Last_Wh_pro_Stunde"][12] == 1132.03
), "The value at index 12 of 'Last_Wh_pro_Stunde' should be 1132.03."
2024-10-04 10:57:51 +02:00
# Verify that the value at index 0 is 'None'
# Check that 'Netzeinspeisung_Wh_pro_Stunde' and 'Netzbezug_Wh_pro_Stunde' are consistent
2024-10-04 11:46:52 +02:00
assert (
2024-10-22 10:22:50 +02:00
result["Netzbezug_Wh_pro_Stunde"][1] == 0
), "The value at index 1 of 'Netzbezug_Wh_pro_Stunde' should be 0."
2024-10-04 10:57:51 +02:00
# Verify the total balance
2024-10-04 11:46:52 +02:00
assert (
2024-12-21 14:39:57 +01:00
abs(result["Gesamtbilanz_Euro"] - 1.958185274567674) < 1e-5
), "Total balance should be 1.958185274567674."
2024-10-04 10:57:51 +02:00
# Check total revenue and total costs
2024-10-04 11:46:52 +02:00
assert (
2024-12-21 14:39:57 +01:00
abs(result["Gesamteinnahmen_Euro"] - 1.168863124510214) < 1e-5
), "Total revenue should be 1.168863124510214."
2024-10-04 11:46:52 +02:00
assert (
2024-12-21 14:39:57 +01:00
abs(result["Gesamtkosten_Euro"] - 3.127048399077888) < 1e-5
), "Total costs should be 3.127048399077888 ."
2024-10-04 10:57:51 +02:00
# Check the losses
2024-10-04 11:46:52 +02:00
assert (
2024-12-21 14:39:57 +01:00
abs(result["Gesamt_Verluste"] - 2871.5330639359036) < 1e-5
), "Total losses should be 2871.5330639359036 ."
2024-10-04 10:57:51 +02:00
# Check the values in 'akku_soc_pro_stunde'
2024-10-04 11:46:52 +02:00
assert (
result["akku_soc_pro_stunde"][-1] == 42.151590909090906
), "The value at index -1 of 'akku_soc_pro_stunde' should be 42.151590909090906."
2024-10-04 11:46:52 +02:00
assert (
result["akku_soc_pro_stunde"][1] == 60.08659090909091
), "The value at index 1 of 'akku_soc_pro_stunde' should be 60.08659090909091."
2024-10-04 10:57:51 +02:00
2024-10-06 14:04:26 +02:00
# Check home appliances
assert (
sum(ems.home_appliance.get_load_curve()) == 2000
), "The sum of 'ems.home_appliance.get_load_curve()' should be 2000."
2024-10-06 14:04:26 +02:00
assert (
np.nansum(
np.where(
result["Home_appliance_wh_per_hour"] is None,
np.nan,
np.array(result["Home_appliance_wh_per_hour"]),
)
)
== 2000
), "The sum of 'Home_appliance_wh_per_hour' should be 2000."
2024-10-06 14:04:26 +02:00
2024-10-04 10:57:51 +02:00
print("All tests passed successfully.")