mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-10-20 21:01:57 +00:00
feat: rename genetic optimization API fields to English (#675)
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
pre-commit / pre-commit (push) Has been cancelled
Run Pytest on Pull Request / test (push) Has been cancelled
docker-build / build (push) Has been cancelled
docker-build / merge (push) Has been cancelled
Close stale pull requests/issues / Find Stale issues and PRs (push) Has been cancelled
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
pre-commit / pre-commit (push) Has been cancelled
Run Pytest on Pull Request / test (push) Has been cancelled
docker-build / build (push) Has been cancelled
docker-build / merge (push) Has been cancelled
Close stale pull requests/issues / Find Stale issues and PRs (push) Has been cancelled
Rename the German field names of the genetic optimization API to English with full backward compatibility: - English names are canonical and documented in the OpenAPI schema; the German names are still accepted on input via validation aliases and re-emitted in responses as deprecated computed fields - fix visualization receiving the raw German-keyed simulation dict (KeyError: load_wh_per_hour) - rename internal German identifiers (optimize_ems, total_balance, battery_residual_value, self_consumption, extra_data keys) - use amount instead of currency/euro in chart labels and schema descriptions; document currency handling (whole currency units, never cents) in the API description - regenerate openapi.json and generated docs Co-authored-by: Tobias Welz <tobias.wizneteu@gmail.com>
This commit is contained in:
@@ -11,7 +11,14 @@ forecasts, and fallback defaults, preparing them for optimization runs.
|
||||
from typing import Optional, Union
|
||||
|
||||
from loguru import logger
|
||||
from pydantic import Field, field_validator, model_validator
|
||||
from pydantic import (
|
||||
AliasChoices,
|
||||
ConfigDict,
|
||||
Field,
|
||||
computed_field,
|
||||
field_validator,
|
||||
model_validator,
|
||||
)
|
||||
from typing_extensions import Self
|
||||
|
||||
from akkudoktoreos.core.coreabc import (
|
||||
@@ -37,32 +44,65 @@ from akkudoktoreos.utils.datetimeutil import to_duration
|
||||
class GeneticEnergyManagementParameters(GeneticParametersBaseModel):
|
||||
"""Encapsulates energy-related forecasts and costs used in GENETIC optimization."""
|
||||
|
||||
pv_prognose_wh: list[float] = Field(
|
||||
model_config = ConfigDict(populate_by_name=True, extra="ignore")
|
||||
|
||||
pv_forecast_wh: list[float] = Field(
|
||||
validation_alias=AliasChoices("pv_forecast_wh", "pv_prognose_wh"),
|
||||
json_schema_extra={
|
||||
"description": "An array of floats representing the forecasted photovoltaic output in watts for different time intervals."
|
||||
}
|
||||
},
|
||||
)
|
||||
strompreis_euro_pro_wh: list[float] = Field(
|
||||
electricity_price_per_wh: list[float] = Field(
|
||||
validation_alias=AliasChoices("electricity_price_per_wh", "strompreis_euro_pro_wh"),
|
||||
json_schema_extra={
|
||||
"description": "An array of floats representing the electricity price in euros per watt-hour for different time intervals."
|
||||
}
|
||||
"description": "An array of floats representing the electricity price per watt-hour for different time intervals."
|
||||
},
|
||||
)
|
||||
einspeiseverguetung_euro_pro_wh: Union[list[float], float] = Field(
|
||||
feed_in_tariff_per_wh: Union[list[float], float] = Field(
|
||||
validation_alias=AliasChoices("feed_in_tariff_per_wh", "einspeiseverguetung_euro_pro_wh"),
|
||||
json_schema_extra={
|
||||
"description": "A float or array of floats representing the feed-in compensation in euros per watt-hour."
|
||||
}
|
||||
"description": "A float or array of floats representing the feed-in compensation per watt-hour."
|
||||
},
|
||||
)
|
||||
preis_euro_pro_wh_akku: float = Field(
|
||||
price_per_wh_battery: float = Field(
|
||||
validation_alias=AliasChoices("price_per_wh_battery", "preis_euro_pro_wh_akku"),
|
||||
json_schema_extra={
|
||||
"description": "A float representing the cost of battery energy per watt-hour."
|
||||
}
|
||||
},
|
||||
)
|
||||
gesamtlast: list[float] = Field(
|
||||
total_load: list[float] = Field(
|
||||
validation_alias=AliasChoices("total_load", "gesamtlast"),
|
||||
json_schema_extra={
|
||||
"description": "An array of floats representing the total load (consumption) in watts for different time intervals."
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# Computed fields for backward compatibility (deprecated German names)
|
||||
@computed_field(json_schema_extra={"deprecated": True})
|
||||
def pv_prognose_wh(self) -> list[float]:
|
||||
"""Deprecated: Use pv_forecast_wh instead."""
|
||||
return self.pv_forecast_wh
|
||||
|
||||
@computed_field(json_schema_extra={"deprecated": True})
|
||||
def strompreis_euro_pro_wh(self) -> list[float]:
|
||||
"""Deprecated: Use electricity_price_per_wh instead."""
|
||||
return self.electricity_price_per_wh
|
||||
|
||||
@computed_field(json_schema_extra={"deprecated": True})
|
||||
def einspeiseverguetung_euro_pro_wh(self) -> Union[list[float], float]:
|
||||
"""Deprecated: Use feed_in_tariff_per_wh instead."""
|
||||
return self.feed_in_tariff_per_wh
|
||||
|
||||
@computed_field(json_schema_extra={"deprecated": True})
|
||||
def preis_euro_pro_wh_akku(self) -> float:
|
||||
"""Deprecated: Use price_per_wh_battery instead."""
|
||||
return self.price_per_wh_battery
|
||||
|
||||
@computed_field(json_schema_extra={"deprecated": True})
|
||||
def gesamtlast(self) -> list[float]:
|
||||
"""Deprecated: Use total_load instead."""
|
||||
return self.total_load
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_list_length(self) -> Self:
|
||||
"""Validate that all input lists are of the same length.
|
||||
@@ -70,13 +110,13 @@ class GeneticEnergyManagementParameters(GeneticParametersBaseModel):
|
||||
Raises:
|
||||
ValueError: If input list lengths differ.
|
||||
"""
|
||||
pv_prognose_length = len(self.pv_prognose_wh)
|
||||
pv_forecast_length = len(self.pv_forecast_wh)
|
||||
if (
|
||||
pv_prognose_length != len(self.strompreis_euro_pro_wh)
|
||||
or pv_prognose_length != len(self.gesamtlast)
|
||||
pv_forecast_length != len(self.electricity_price_per_wh)
|
||||
or pv_forecast_length != len(self.total_load)
|
||||
or (
|
||||
isinstance(self.einspeiseverguetung_euro_pro_wh, list)
|
||||
and pv_prognose_length != len(self.einspeiseverguetung_euro_pro_wh)
|
||||
isinstance(self.feed_in_tariff_per_wh, list)
|
||||
and pv_forecast_length != len(self.feed_in_tariff_per_wh)
|
||||
)
|
||||
):
|
||||
raise ValueError("Input lists have different lengths")
|
||||
@@ -122,7 +162,7 @@ class GeneticOptimizationParameters(
|
||||
Raises:
|
||||
ValueError: If list lengths mismatch.
|
||||
"""
|
||||
arr_length = len(self.ems.pv_prognose_wh)
|
||||
arr_length = len(self.ems.pv_forecast_wh)
|
||||
if self.temperature_forecast is not None and arr_length != len(self.temperature_forecast):
|
||||
raise ValueError("Input lists have different lengths")
|
||||
return self
|
||||
@@ -615,11 +655,11 @@ class GeneticOptimizationParameters(
|
||||
try:
|
||||
oparams = GeneticOptimizationParameters(
|
||||
ems=GeneticEnergyManagementParameters(
|
||||
pv_prognose_wh=pvforecast_ac_power,
|
||||
strompreis_euro_pro_wh=elecprice_marketprice_wh,
|
||||
einspeiseverguetung_euro_pro_wh=feed_in_tariff_wh,
|
||||
gesamtlast=loadforecast_power_w,
|
||||
preis_euro_pro_wh_akku=battery_lcos_kwh / 1000,
|
||||
pv_forecast_wh=pvforecast_ac_power,
|
||||
electricity_price_per_wh=elecprice_marketprice_wh,
|
||||
feed_in_tariff_per_wh=feed_in_tariff_wh,
|
||||
total_load=loadforecast_power_w,
|
||||
price_per_wh_battery=battery_lcos_kwh / 1000,
|
||||
),
|
||||
temperature_forecast=weather_temp_air,
|
||||
pv_akku=battery_params,
|
||||
|
||||
Reference in New Issue
Block a user