EOS/tests/test_class_ems_2.py
Normann a7d58eed9a
pre-commit update and ignore changes (#461)
* pre-commit autoupdate
* type: ignore changes
* [attr-defined,unused-ignore] usage
2025-02-24 10:00:09 +01:00

326 lines
10 KiB
Python

import numpy as np
import pytest
from akkudoktoreos.core.ems import (
EnergyManagement,
EnergyManagementParameters,
SimulationResult,
get_ems,
)
from akkudoktoreos.devices.battery import (
Battery,
ElectricVehicleParameters,
SolarPanelBatteryParameters,
)
from akkudoktoreos.devices.generic import HomeAppliance, HomeApplianceParameters
from akkudoktoreos.devices.inverter import Inverter, InverterParameters
start_hour = 0
# Example initialization of necessary components
@pytest.fixture
def create_ems_instance(devices_eos, config_eos) -> EnergyManagement:
"""Fixture to create an EnergyManagement instance with given test parameters."""
# Assure configuration holds the correct values
config_eos.merge_settings_from_dict(
{"prediction": {"hours": 48}, "optimization": {"hours": 24}}
)
assert config_eos.prediction.hours == 48
# Initialize the battery and the inverter
akku = Battery(
SolarPanelBatteryParameters(
device_id="pv1", capacity_wh=5000, initial_soc_percentage=80, min_soc_percentage=10
)
)
akku.reset()
devices_eos.add_device(akku)
inverter = Inverter(
InverterParameters(device_id="iv1", max_power_wh=10000, battery_id=akku.device_id)
)
devices_eos.add_device(inverter)
# Household device (currently not used, set to None)
home_appliance = HomeAppliance(
HomeApplianceParameters(
device_id="dishwasher1",
consumption_wh=2000,
duration_h=2,
)
)
home_appliance.set_starting_time(2)
devices_eos.add_device(home_appliance)
# Example initialization of electric car battery
eauto = Battery(
ElectricVehicleParameters(
device_id="ev1", capacity_wh=26400, initial_soc_percentage=100, min_soc_percentage=100
),
)
devices_eos.add_device(eauto)
devices_eos.post_setup()
# Parameters based on previous example data
pv_prognose_wh = [0.0] * config_eos.prediction.hours
pv_prognose_wh[10] = 5000.0
pv_prognose_wh[11] = 5000.0
strompreis_euro_pro_wh = [0.001] * config_eos.prediction.hours
strompreis_euro_pro_wh[0:10] = [0.00001] * 10
strompreis_euro_pro_wh[11:15] = [0.00005] * 4
strompreis_euro_pro_wh[20] = 0.00001
einspeiseverguetung_euro_pro_wh = [0.00007] * len(strompreis_euro_pro_wh)
preis_euro_pro_wh_akku = 0.0001
gesamtlast = [
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,
]
# Initialize the energy management system with the respective parameters
ems = get_ems()
ems.set_parameters(
EnergyManagementParameters(
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,
),
inverter=inverter,
ev=eauto,
home_appliance=home_appliance,
)
ac = np.full(config_eos.prediction.hours, 0.0)
ac[20] = 1
ems.set_akku_ac_charge_hours(ac)
dc = np.full(config_eos.prediction.hours, 0.0)
dc[11] = 1
ems.set_akku_dc_charge_hours(dc)
return ems
def test_simulation(create_ems_instance):
"""Test the EnergyManagement simulation method."""
ems = create_ems_instance
# Simulate starting from hour 0 (this value can be adjusted)
result = ems.simulate(start_hour=start_hour)
# --- Pls do not remove! ---
# 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,
# )
# Assertions to validate results
assert result is not None, "Result should not be None"
assert isinstance(result, dict), "Result should be a dictionary"
assert SimulationResult(**result) is not None
assert "Last_Wh_pro_Stunde" in result, "Result should contain 'Last_Wh_pro_Stunde'"
"""
Check the result of the simulation based on expected values.
"""
# 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."
# Verify that the expected keys are present in the result
expected_keys = [
"Last_Wh_pro_Stunde",
"Netzeinspeisung_Wh_pro_Stunde",
"Netzbezug_Wh_pro_Stunde",
"Kosten_Euro_pro_Stunde",
"akku_soc_pro_stunde",
"Einnahmen_Euro_pro_Stunde",
"Gesamtbilanz_Euro",
"EAuto_SoC_pro_Stunde",
"Gesamteinnahmen_Euro",
"Gesamtkosten_Euro",
"Verluste_Pro_Stunde",
"Gesamt_Verluste",
"Home_appliance_wh_per_hour",
]
for key in expected_keys:
assert key in result, f"The key '{key}' should be present in the result."
# Check the length of the main arrays
assert len(result["Last_Wh_pro_Stunde"]) == 48, (
"The length of 'Last_Wh_pro_Stunde' should be 48."
)
assert len(result["Netzeinspeisung_Wh_pro_Stunde"]) == 48, (
"The length of 'Netzeinspeisung_Wh_pro_Stunde' should be 48."
)
assert len(result["Netzbezug_Wh_pro_Stunde"]) == 48, (
"The length of 'Netzbezug_Wh_pro_Stunde' should be 48."
)
assert len(result["Kosten_Euro_pro_Stunde"]) == 48, (
"The length of 'Kosten_Euro_pro_Stunde' should be 48."
)
assert len(result["akku_soc_pro_stunde"]) == 48, (
"The length of 'akku_soc_pro_stunde' should be 48."
)
# Verfify DC and AC Charge Bins
assert abs(result["akku_soc_pro_stunde"][2] - 44.70681818181818) < 1e-5, (
"'akku_soc_pro_stunde[2]' should be 44.70681818181818."
)
assert abs(result["akku_soc_pro_stunde"][10] - 10.0) < 1e-5, (
"'akku_soc_pro_stunde[10]' should be 10."
)
assert abs(result["Netzeinspeisung_Wh_pro_Stunde"][10] - 3946.93) < 1e-3, (
"'Netzeinspeisung_Wh_pro_Stunde[11]' should be 3946.93."
)
assert abs(result["Netzeinspeisung_Wh_pro_Stunde"][11] - 0.0) < 1e-3, (
"'Netzeinspeisung_Wh_pro_Stunde[11]' should be 0.0."
)
assert abs(result["akku_soc_pro_stunde"][20] - 10) < 1e-5, (
"'akku_soc_pro_stunde[20]' should be 10."
)
assert abs(result["Last_Wh_pro_Stunde"][20] - 6050.98) < 1e-3, (
"'Last_Wh_pro_Stunde[20]' should be 6050.98."
)
print("All tests passed successfully.")
def test_set_parameters(create_ems_instance):
"""Test the set_parameters method of EnergyManagement."""
ems = create_ems_instance
# Check if parameters are set correctly
assert ems.load_energy_array is not None, "load_energy_array should not be None"
assert ems.pv_prediction_wh is not None, "pv_prediction_wh should not be None"
assert ems.elect_price_hourly is not None, "elect_price_hourly should not be None"
assert ems.elect_revenue_per_hour_arr is not None, (
"elect_revenue_per_hour_arr should not be None"
)
def test_set_akku_discharge_hours(create_ems_instance):
"""Test the set_akku_discharge_hours method of EnergyManagement."""
ems = create_ems_instance
discharge_hours = np.full(ems.config.prediction.hours, 1.0)
ems.set_akku_discharge_hours(discharge_hours)
assert np.array_equal(ems.battery.discharge_array, discharge_hours), (
"Discharge hours should be set correctly"
)
def test_set_akku_ac_charge_hours(create_ems_instance):
"""Test the set_akku_ac_charge_hours method of EnergyManagement."""
ems = create_ems_instance
ac_charge_hours = np.full(ems.config.prediction.hours, 1.0)
ems.set_akku_ac_charge_hours(ac_charge_hours)
assert np.array_equal(ems.ac_charge_hours, ac_charge_hours), (
"AC charge hours should be set correctly"
)
def test_set_akku_dc_charge_hours(create_ems_instance):
"""Test the set_akku_dc_charge_hours method of EnergyManagement."""
ems = create_ems_instance
dc_charge_hours = np.full(ems.config.prediction.hours, 1.0)
ems.set_akku_dc_charge_hours(dc_charge_hours)
assert np.array_equal(ems.dc_charge_hours, dc_charge_hours), (
"DC charge hours should be set correctly"
)
def test_set_ev_charge_hours(create_ems_instance):
"""Test the set_ev_charge_hours method of EnergyManagement."""
ems = create_ems_instance
ev_charge_hours = np.full(ems.config.prediction.hours, 1.0)
ems.set_ev_charge_hours(ev_charge_hours)
assert np.array_equal(ems.ev_charge_hours, ev_charge_hours), (
"EV charge hours should be set correctly"
)
def test_reset(create_ems_instance):
"""Test the reset method of EnergyManagement."""
ems = create_ems_instance
ems.reset()
assert ems.ev.current_soc_percentage() == 100, "EV SOC should be reset to initial value"
assert ems.battery.current_soc_percentage() == 80, (
"Battery SOC should be reset to initial value"
)
def test_simulate_start_now(create_ems_instance):
"""Test the simulate_start_now method of EnergyManagement."""
ems = create_ems_instance
result = ems.simulate_start_now()
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'"