Files
EOS/tests/test_genetic0translations.py
T
Bobby NoelteandGitHub e23bb7b497
Bump Version / Bump Version Workflow (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
docker-build / platform-excludes (push) Has been cancelled
docker-build / build (push) Has been cancelled
docker-build / merge (push) Has been cancelled
pre-commit / pre-commit (push) Has been cancelled
Run Pytest on Pull Request / test (push) Has been cancelled
chore: prepare for update of genetic algorithm (#1190)
Andreas will update the genetic algorithm for 15-minutes optimization
intervals.

Copy the current GENETIC optimization algorithm to GENETIC0 to enable
to keep the algorithm with the current functionality. Also copy resources
like the load interpolator to the GENETIC0 algorithm to keep them despite
possible later changes to the interpolator.

Make the deprecated legacy /optimize endpoint use the GENETIC0 optimization
algorithm to in-fact behave the same way even if there will later be changes
to the GENETIC algorithm by Andreas. Add a new REST endpoint to provide
the unprocessed optimisation results of the GENETIC and GENETIC0 algorithm
in case one wants to use them as done with the deprecated /optimize endpoint.

Adapt the optimization configuration to have distinct configurations for the
GENETIC and the GENETIC0 algorithm.

Create a copy of the current tests for the GENETIC algorithm to be used
for the GENETIC0 algorithm. This avoids the tests for the GENETIC0
algorithm to be influenced by later changes by Andreas.

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
2026-07-29 12:56:08 +02:00

171 lines
6.6 KiB
Python

#!/usr/bin/env python3
"""Quick test to verify API field name translations work correctly."""
import json
from akkudoktoreos.optimization.genetic0.genetic0 import Genetic0SimulationResult
from akkudoktoreos.optimization.genetic0.genetic0params import (
Genetic0EnergyManagementParameters,
)
def test_genetic0_params_german_input():
"""Test that German field names are accepted as input."""
data_de = {
"pv_prognose_wh": [100.0, 200.0],
"strompreis_euro_pro_wh": [0.0003, 0.0003],
"einspeiseverguetung_euro_pro_wh": 0.00007,
"preis_euro_pro_wh_akku": 0.0001,
"gesamtlast": [500.0, 600.0],
}
params = Genetic0EnergyManagementParameters(**data_de)
assert params.pv_forecast_wh == [100.0, 200.0]
print("✅ German input accepted")
def test_genetic0_params_english_input():
"""Test that English field names are accepted as input."""
data_en = {
"pv_forecast_wh": [100.0, 200.0],
"electricity_price_per_wh": [0.0003, 0.0003],
"feed_in_tariff_per_wh": 0.00007,
"price_per_wh_battery": 0.0001,
"total_load": [500.0, 600.0],
}
params = Genetic0EnergyManagementParameters(**data_en)
assert params.pv_forecast_wh == [100.0, 200.0]
print("✅ English input accepted")
def test_genetic0_params_english_output():
"""Test that both English and German field names are in JSON output (backward compatibility)."""
data_de = {
"pv_prognose_wh": [100.0, 200.0],
"strompreis_euro_pro_wh": [0.0003, 0.0003],
"einspeiseverguetung_euro_pro_wh": 0.00007,
"preis_euro_pro_wh_akku": 0.0001,
"gesamtlast": [500.0, 600.0],
}
params = Genetic0EnergyManagementParameters(**data_de)
json_output = json.loads(params.model_dump_json(by_alias=True))
# English names should be in output
assert "pv_forecast_wh" in json_output
assert "electricity_price_per_wh" in json_output
assert "feed_in_tariff_per_wh" in json_output
assert "price_per_wh_battery" in json_output
assert "total_load" in json_output
# German names should ALSO be in output (backward compatibility)
assert "pv_prognose_wh" in json_output
assert "strompreis_euro_pro_wh" in json_output
assert "einspeiseverguetung_euro_pro_wh" in json_output
assert "preis_euro_pro_wh_akku" in json_output
assert "gesamtlast" in json_output
# Both should have same values
assert json_output["pv_forecast_wh"] == json_output["pv_prognose_wh"]
assert json_output["electricity_price_per_wh"] == json_output["strompreis_euro_pro_wh"]
print("✅ Both English and German output generated")
def test_genetic0_simulation_result_translations():
"""Test simulation result field translations."""
data_de = {
"Last_Wh_pro_Stunde": [100.0, 200.0],
"EAuto_SoC_pro_Stunde": [50.0, 60.0],
"Einnahmen_Euro_pro_Stunde": [0.1, 0.2],
"Gesamt_Verluste": 50.0,
"Gesamtbilanz_Euro": -10.0,
"Gesamteinnahmen_Euro": 5.0,
"Gesamtkosten_Euro": 15.0,
"Home_appliance_wh_per_hour": [0.0, 100.0],
"Kosten_Euro_pro_Stunde": [0.2, 0.3],
"Netzbezug_Wh_pro_Stunde": [50.0, 60.0],
"Netzeinspeisung_Wh_pro_Stunde": [10.0, 20.0],
"Verluste_Pro_Stunde": [5.0, 10.0],
"akku_soc_pro_stunde": [80.0, 90.0],
"Electricity_price": [0.0003, 0.0003],
}
result = Genetic0SimulationResult(**data_de)
json_output = json.loads(result.model_dump_json(by_alias=True))
# Check English field names in output
english_names = [
"load_wh_per_hour",
"ev_soc_per_hour",
"revenue_per_hour",
"total_losses",
"total_balance",
"total_revenue",
"total_costs",
"home_appliance_wh_per_hour",
"costs_per_hour",
"grid_consumption_wh_per_hour",
"grid_feed_in_wh_per_hour",
"losses_per_hour",
"battery_soc_per_hour",
"electricity_price",
]
for name in english_names:
assert name in json_output, f"English field {name} missing in output"
# Check ALL deprecated German field names are still in output (backward compatibility)
for name in data_de:
assert name in json_output, f"Deprecated field {name} missing in output"
# Deprecated fields must mirror the values of the renamed fields
assert json_output["Last_Wh_pro_Stunde"] == json_output["load_wh_per_hour"]
assert json_output["Home_appliance_wh_per_hour"] == json_output["home_appliance_wh_per_hour"]
assert json_output["Gesamtbilanz_Euro"] == json_output["total_balance"]
assert json_output["akku_soc_pro_stunde"] == json_output["battery_soc_per_hour"]
assert json_output["Electricity_price"] == json_output["electricity_price"]
print("✅ Simulation result translations work")
if __name__ == "__main__":
test_genetic0_params_german_input()
test_genetic0_params_english_input()
test_genetic0_params_english_output()
test_genetic0_simulation_result_translations()
print("\n✅✅✅ All translation tests passed! ✅✅✅")
def test_genetic0_optimization_parameters_device_translations():
"""Test that German device field names are accepted and re-emitted."""
from akkudoktoreos.optimization.genetic0.genetic0params import (
Genetic0OptimizationParameters,
)
ems_de = {
"pv_prognose_wh": [100.0, 200.0],
"strompreis_euro_pro_wh": [0.0003, 0.0003],
"einspeiseverguetung_euro_pro_wh": 0.00007,
"preis_euro_pro_wh_akku": 0.0001,
"gesamtlast": [500.0, 600.0],
}
params = Genetic0OptimizationParameters(
ems=ems_de,
pv_akku={"device_id": "battery1", "capacity_wh": 8000},
inverter=None,
eauto={"device_id": "ev1", "capacity_wh": 60000},
)
# English attributes are populated from the German input names
assert params.pv_battery is not None
assert params.pv_battery.capacity_wh == 8000
assert params.ev is not None
assert params.ev.capacity_wh == 60000
# English input names work as well
params_en = Genetic0OptimizationParameters(
ems=ems_de,
pv_battery={"device_id": "battery1", "capacity_wh": 8000},
inverter=None,
ev={"device_id": "ev1", "capacity_wh": 60000},
)
assert params_en.pv_battery is not None
assert params_en.ev is not None
# Both names are present in the output (backward compatibility)
dumped = params.model_dump()
for name in ("pv_battery", "pv_akku", "ev", "eauto"):
assert name in dumped, f"{name} missing in output"
assert dumped["pv_akku"] == dumped["pv_battery"]
assert dumped["eauto"] == dumped["ev"]