mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-10-21 21:31:57 +00:00
test(integration): validate optimizer economics and document measurement settings
This commit is contained in:
@@ -91,7 +91,10 @@ class MeasurementCommonSettings(SettingsBaseModel):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
household: Optional[HouseholdSettings] = None
|
household: Optional[HouseholdSettings] = Field(
|
||||||
|
default=None,
|
||||||
|
json_schema_extra={"description": "Optional household energy balance definition.", "examples": [None]},
|
||||||
|
)
|
||||||
energy_context_seconds: int = Field(default=86400, gt=0, le=604800, strict=True)
|
energy_context_seconds: int = Field(default=86400, gt=0, le=604800, strict=True)
|
||||||
|
|
||||||
@model_validator(mode="after")
|
@model_validator(mode="after")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from pathlib import Path
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
import pytest
|
import pytest
|
||||||
from pydantic import ValidationError
|
from pydantic import ValidationError
|
||||||
from pypdf import PdfReader
|
from pypdf import PdfReader
|
||||||
@@ -140,14 +141,29 @@ async def test_optimize(
|
|||||||
f"cp {TESTDATA_FILE} {solution_file}\n"
|
f"cp {TESTDATA_FILE} {solution_file}\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
assert genetic_solution.result.Gesamtbilanz_Euro == pytest.approx(
|
# Keep the output contract, but do not demand an identical stochastic
|
||||||
expected_result.result.Gesamtbilanz_Euro
|
# schedule or monetary golden from the previous direct-consumption model.
|
||||||
)
|
assert set(genetic_solution.model_dump()) == set(expected_result.model_dump())
|
||||||
|
result = genetic_solution.result
|
||||||
# Assert that the output contains all expected entries.
|
expected_slots = len(input_data.ems.pv_forecast_wh) - fixed_start_hour
|
||||||
# This does not assert that the optimization always gives the same result!
|
assert len(result.grid_consumption_wh_per_hour) == expected_slots
|
||||||
# Reproducibility and mathematical accuracy should be tested on the level of individual components.
|
assert len(result.grid_feed_in_wh_per_hour) == expected_slots
|
||||||
compare_dict(genetic_solution.model_dump(), expected_result.model_dump())
|
prices = np.asarray(genetic_solution.parameters.ems.electricity_price_per_wh)[fixed_start_hour:]
|
||||||
|
tariffs = genetic_solution.parameters.ems.feed_in_tariff_per_wh
|
||||||
|
if isinstance(tariffs, list):
|
||||||
|
tariffs = np.asarray(tariffs)[fixed_start_hour:]
|
||||||
|
expected_costs = np.asarray(result.grid_consumption_wh_per_hour) * prices
|
||||||
|
expected_revenues = np.asarray(result.grid_feed_in_wh_per_hour) * tariffs
|
||||||
|
np.testing.assert_allclose(result.costs_per_hour, expected_costs)
|
||||||
|
np.testing.assert_allclose(result.revenue_per_hour, expected_revenues)
|
||||||
|
assert result.total_costs == pytest.approx(sum(expected_costs))
|
||||||
|
assert result.total_revenue == pytest.approx(sum(expected_revenues))
|
||||||
|
assert result.total_balance == pytest.approx(sum(expected_costs) - sum(expected_revenues))
|
||||||
|
assert result.total_losses == pytest.approx(sum(result.losses_per_hour))
|
||||||
|
assert all(value >= 0 for value in result.grid_consumption_wh_per_hour)
|
||||||
|
assert all(value >= 0 for value in result.grid_feed_in_wh_per_hour)
|
||||||
|
assert all(0 <= value <= 100 for value in result.battery_soc_per_hour)
|
||||||
|
assert all(0 <= value <= 100 for value in result.ev_soc_per_hour)
|
||||||
|
|
||||||
# Check the correct generic optimization solution is created
|
# Check the correct generic optimization solution is created
|
||||||
optimization_solution = await genetic_solution.optimization_solution()
|
optimization_solution = await genetic_solution.optimization_solution()
|
||||||
|
|||||||
Reference in New Issue
Block a user