From 3864f141af3e704eeb1ca231015fef08763f3882 Mon Sep 17 00:00:00 2001 From: MartinBelthle Date: Wed, 12 Feb 2025 18:14:28 +0100 Subject: [PATCH] refactor(st-storage): create user class (#83) --- src/antares/craft/model/st_storage.py | 56 ++++---------- .../craft/service/api_services/area_api.py | 13 ++-- .../service/api_services/models/st_storage.py | 48 ++++++++++++ .../st_storage.py} | 19 +++-- src/antares/craft/service/base_services.py | 9 ++- .../service/local_services/area_local.py | 11 +-- .../local_services/models/st_storage.py | 52 +++++++++++++ .../st_storage.py} | 9 ++- src/antares/craft/service/service_factory.py | 4 +- tests/antares/delete/test_delete_api.py | 2 +- .../services/api_services/test_area_api.py | 7 +- .../api_services/test_st_storage_api.py | 10 ++- .../services/local_services/test_area.py | 75 +++++++------------ .../test_create_thermal_cluster.py | 13 +--- tests/integration/test_web_client.py | 11 ++- 15 files changed, 205 insertions(+), 134 deletions(-) create mode 100644 src/antares/craft/service/api_services/models/st_storage.py rename src/antares/craft/service/api_services/{st_storage_api.py => services/st_storage.py} (84%) create mode 100644 src/antares/craft/service/local_services/models/st_storage.py rename src/antares/craft/service/local_services/{st_storage_local.py => services/st_storage.py} (90%) diff --git a/src/antares/craft/model/st_storage.py b/src/antares/craft/model/st_storage.py index 4466774e..f0796a1d 100644 --- a/src/antares/craft/model/st_storage.py +++ b/src/antares/craft/model/st_storage.py @@ -9,17 +9,14 @@ # SPDX-License-Identifier: MPL-2.0 # # This file is part of the Antares project. - +from dataclasses import dataclass from enum import Enum from typing import Optional import pandas as pd from antares.craft.service.base_services import BaseShortTermStorageService -from antares.craft.tools.all_optional_meta import all_optional_model from antares.craft.tools.contents_tool import transform_name_to_id -from pydantic import BaseModel -from pydantic.alias_generators import to_camel class STStorageGroup(Enum): @@ -43,13 +40,20 @@ class STStorageMatrixName(Enum): INFLOWS = "inflows" -class DefaultSTStorageProperties(BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel): - """ - Properties of a short-term storage system read from the configuration files. +@dataclass +class STStoragePropertiesUpdate: + group: Optional[STStorageGroup] = None + injection_nominal_capacity: Optional[float] = None + withdrawal_nominal_capacity: Optional[float] = None + reservoir_capacity: Optional[float] = None + efficiency: Optional[float] = None + initial_level: Optional[float] = None + initial_level_optim: Optional[bool] = None + enabled: Optional[bool] = None - All aliases match the name of the corresponding field in the INI files. - """ +@dataclass +class STStorageProperties: group: STStorageGroup = STStorageGroup.OTHER1 injection_nominal_capacity: float = 0 withdrawal_nominal_capacity: float = 0 @@ -57,39 +61,9 @@ class DefaultSTStorageProperties(BaseModel, extra="forbid", populate_by_name=Tru efficiency: float = 1 initial_level: float = 0.5 initial_level_optim: bool = False - # v880 enabled: bool = True -@all_optional_model -class STStorageProperties(DefaultSTStorageProperties): - pass - - -class STStoragePropertiesLocal(DefaultSTStorageProperties): - st_storage_name: str - - @property - def list_ini_fields(self) -> dict[str, dict[str, str]]: - return { - f"{self.st_storage_name}": { - "name": self.st_storage_name, - "group": self.group.value, - "injectionnominalcapacity": f"{self.injection_nominal_capacity:.6f}", - "withdrawalnominalcapacity": f"{self.withdrawal_nominal_capacity:.6f}", - "reservoircapacity": f"{self.reservoir_capacity:.6f}", - "efficiency": f"{self.efficiency:.6f}", - "initiallevel": f"{self.initial_level:.6f}", - "initialleveloptim": f"{self.initial_level_optim}".lower(), - "enabled": f"{self.enabled}".lower(), - } - } - - def yield_st_storage_properties(self) -> STStorageProperties: - excludes = {"st_storage_name", "list_ini_fields"} - return STStorageProperties.model_validate(self.model_dump(mode="json", exclude=excludes)) - - class STStorage: def __init__( self, @@ -104,8 +78,6 @@ def __init__( self._id: str = transform_name_to_id(name) self._properties: STStorageProperties = properties or STStorageProperties() - # TODO: Add matrices. - @property def area_id(self) -> str: return self._area_id @@ -122,7 +94,7 @@ def id(self) -> str: def properties(self) -> STStorageProperties: return self._properties - def update_properties(self, properties: STStorageProperties) -> None: + def update_properties(self, properties: STStoragePropertiesUpdate) -> None: new_properties = self._storage_service.update_st_storage_properties(self, properties) self._properties = new_properties diff --git a/src/antares/craft/service/api_services/area_api.py b/src/antares/craft/service/api_services/area_api.py index c63322d3..c1b3d526 100644 --- a/src/antares/craft/service/api_services/area_api.py +++ b/src/antares/craft/service/api_services/area_api.py @@ -38,6 +38,7 @@ from antares.craft.model.st_storage import STStorage, STStorageProperties from antares.craft.model.thermal import ThermalCluster, ThermalClusterProperties from antares.craft.service.api_services.models.renewable import RenewableClusterPropertiesAPI +from antares.craft.service.api_services.models.st_storage import STStoragePropertiesAPI from antares.craft.service.api_services.models.thermal import ThermalClusterPropertiesAPI from antares.craft.service.api_services.utils import get_matrix, upload_series from antares.craft.service.base_services import ( @@ -257,8 +258,7 @@ def create_renewable_cluster( body = {**body, **camel_properties} response = self._wrapper.post(url, json=body) json_response = response.json() - name = json_response["name"] - del json_response["name"] + name = json_response.pop("name") del json_response["id"] api_properties = RenewableClusterPropertiesAPI.model_validate(json_response) properties = api_properties.to_user_model() @@ -294,14 +294,15 @@ def create_st_storage( url = f"{self._base_url}/studies/{self.study_id}/areas/{area_id}/storages" body = {"name": st_storage_name} if properties: - camel_properties = properties.model_dump(mode="json", by_alias=True, exclude_none=True) + api_model = STStoragePropertiesAPI.from_user_model(properties) + camel_properties = api_model.model_dump(mode="json", by_alias=True, exclude_none=True) body = {**body, **camel_properties} response = self._wrapper.post(url, json=body) json_response = response.json() - name = json_response["name"] - del json_response["name"] + name = json_response.pop("name") del json_response["id"] - properties = STStorageProperties.model_validate(json_response) + api_properties = STStoragePropertiesAPI.model_validate(json_response) + properties = api_properties.to_user_model() except APIError as e: raise STStorageCreationError(st_storage_name, area_id, e.message) from e diff --git a/src/antares/craft/service/api_services/models/st_storage.py b/src/antares/craft/service/api_services/models/st_storage.py new file mode 100644 index 00000000..3bfc7ed9 --- /dev/null +++ b/src/antares/craft/service/api_services/models/st_storage.py @@ -0,0 +1,48 @@ +# Copyright (c) 2024, RTE (https://www.rte-france.com) +# +# See AUTHORS.txt +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# SPDX-License-Identifier: MPL-2.0 +# +# This file is part of the Antares project. +from dataclasses import asdict +from typing import Union + +from antares.craft.model.st_storage import STStorageGroup, STStorageProperties, STStoragePropertiesUpdate +from antares.craft.service.api_services.models.base_model import APIBaseModel +from antares.craft.tools.all_optional_meta import all_optional_model + +STStoragePropertiesType = Union[STStorageProperties, STStoragePropertiesUpdate] + + +@all_optional_model +class STStoragePropertiesAPI(APIBaseModel): + group: STStorageGroup + injection_nominal_capacity: float + withdrawal_nominal_capacity: float + reservoir_capacity: float + efficiency: float + initial_level: float + initial_level_optim: bool + enabled: bool + + @staticmethod + def from_user_model(user_class: STStoragePropertiesType) -> "STStoragePropertiesAPI": + user_dict = asdict(user_class) + return STStoragePropertiesAPI.model_validate(user_dict) + + def to_user_model(self) -> STStorageProperties: + return STStorageProperties( + enabled=self.enabled, + group=self.group, + injection_nominal_capacity=self.injection_nominal_capacity, + withdrawal_nominal_capacity=self.withdrawal_nominal_capacity, + reservoir_capacity=self.reservoir_capacity, + efficiency=self.efficiency, + initial_level=self.initial_level, + initial_level_optim=self.initial_level_optim, + ) diff --git a/src/antares/craft/service/api_services/st_storage_api.py b/src/antares/craft/service/api_services/services/st_storage.py similarity index 84% rename from src/antares/craft/service/api_services/st_storage_api.py rename to src/antares/craft/service/api_services/services/st_storage.py index 97ec3791..ce665e24 100644 --- a/src/antares/craft/service/api_services/st_storage_api.py +++ b/src/antares/craft/service/api_services/services/st_storage.py @@ -21,7 +21,13 @@ STStorageMatrixUploadError, STStoragePropertiesUpdateError, ) -from antares.craft.model.st_storage import STStorage, STStorageMatrixName, STStorageProperties +from antares.craft.model.st_storage import ( + STStorage, + STStorageMatrixName, + STStorageProperties, + STStoragePropertiesUpdate, +) +from antares.craft.service.api_services.models.st_storage import STStoragePropertiesAPI from antares.craft.service.base_services import BaseShortTermStorageService from typing_extensions import override @@ -36,11 +42,12 @@ def __init__(self, config: APIconf, study_id: str): @override def update_st_storage_properties( - self, st_storage: STStorage, properties: STStorageProperties + self, st_storage: STStorage, properties: STStoragePropertiesUpdate ) -> STStorageProperties: url = f"{self._base_url}/studies/{self.study_id}/areas/{st_storage.area_id}/storages/{st_storage.id}" try: - body = properties.model_dump(mode="json", by_alias=True, exclude_none=True) + api_model = STStoragePropertiesAPI.from_user_model(properties) + body = api_model.model_dump(mode="json", by_alias=True, exclude_none=True) if not body: return st_storage.properties @@ -48,7 +55,8 @@ def update_st_storage_properties( json_response = response.json() del json_response["id"] del json_response["name"] - new_properties = STStorageProperties.model_validate(json_response) + new_api_properties = STStoragePropertiesAPI.model_validate(json_response) + new_properties = new_api_properties.to_user_model() except APIError as e: raise STStoragePropertiesUpdateError(st_storage.id, st_storage.area_id, e.message) from e @@ -89,7 +97,8 @@ def read_st_storages(self, area_id: str) -> List[STStorage]: storage_id = storage.pop("id") storage_name = storage.pop("name") - storage_properties = STStorageProperties(**storage) + api_props = STStoragePropertiesAPI.model_validate(storage) + storage_properties = api_props.to_user_model() st_storage = STStorage(self, storage_id, storage_name, storage_properties) storages.append(st_storage) diff --git a/src/antares/craft/service/base_services.py b/src/antares/craft/service/base_services.py index 75603489..d6e8ee4b 100644 --- a/src/antares/craft/service/base_services.py +++ b/src/antares/craft/service/base_services.py @@ -36,7 +36,12 @@ RenewableClusterProperties, RenewableClusterPropertiesUpdate, ) - from antares.craft.model.st_storage import STStorage, STStorageMatrixName, STStorageProperties + from antares.craft.model.st_storage import ( + STStorage, + STStorageMatrixName, + STStorageProperties, + STStoragePropertiesUpdate, + ) from antares.craft.model.study import Study from antares.craft.model.thermal import ( ThermalCluster, @@ -701,7 +706,7 @@ def read_renewables(self, area_id: str) -> list["RenewableCluster"]: class BaseShortTermStorageService(ABC): @abstractmethod def update_st_storage_properties( - self, st_storage: "STStorage", properties: "STStorageProperties" + self, st_storage: "STStorage", properties: "STStoragePropertiesUpdate" ) -> "STStorageProperties": """ Args: diff --git a/src/antares/craft/service/local_services/area_local.py b/src/antares/craft/service/local_services/area_local.py index f76b4d31..6e73ef98 100644 --- a/src/antares/craft/service/local_services/area_local.py +++ b/src/antares/craft/service/local_services/area_local.py @@ -29,7 +29,7 @@ ) from antares.craft.model.hydro import Hydro, HydroProperties from antares.craft.model.renewable import RenewableCluster, RenewableClusterProperties -from antares.craft.model.st_storage import STStorage, STStorageProperties, STStoragePropertiesLocal +from antares.craft.model.st_storage import STStorage, STStorageProperties from antares.craft.model.thermal import ThermalCluster, ThermalClusterProperties from antares.craft.service.base_services import ( BaseAreaService, @@ -39,6 +39,7 @@ BaseThermalService, ) from antares.craft.service.local_services.models.renewable import RenewableClusterPropertiesLocal +from antares.craft.service.local_services.models.st_storage import STStoragePropertiesLocal from antares.craft.service.local_services.models.thermal import ThermalClusterPropertiesLocal from antares.craft.service.local_services.services.hydro import edit_hydro_properties from antares.craft.tools.contents_tool import transform_name_to_id @@ -169,18 +170,18 @@ def create_st_storage( self, area_id: str, st_storage_name: str, properties: Optional[STStorageProperties] = None ) -> STStorage: properties = properties or STStorageProperties() - args = {"st_storage_name": st_storage_name, **properties.model_dump(mode="json", exclude_none=True)} - local_st_storage_properties = STStoragePropertiesLocal.model_validate(args) + local_properties = STStoragePropertiesLocal.from_user_model(properties) + new_section_content = {"name": st_storage_name, **local_properties.model_dump(mode="json", by_alias=True)} list_ini = IniFile(self.config.study_path, InitializationFilesTypes.ST_STORAGE_LIST_INI, area_id=area_id) - list_ini.add_section(local_st_storage_properties.list_ini_fields) + list_ini.add_section({st_storage_name: new_section_content}) list_ini.write_ini_file(sort_sections=True) return STStorage( self.storage_service, area_id, st_storage_name, - local_st_storage_properties.yield_st_storage_properties(), + properties, ) @override diff --git a/src/antares/craft/service/local_services/models/st_storage.py b/src/antares/craft/service/local_services/models/st_storage.py new file mode 100644 index 00000000..21b55ee3 --- /dev/null +++ b/src/antares/craft/service/local_services/models/st_storage.py @@ -0,0 +1,52 @@ +# Copyright (c) 2024, RTE (https://www.rte-france.com) +# +# See AUTHORS.txt +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# SPDX-License-Identifier: MPL-2.0 +# +# This file is part of the Antares project. +from dataclasses import asdict +from typing import Union + +from antares.craft.model.st_storage import STStorageGroup, STStorageProperties, STStoragePropertiesUpdate +from antares.craft.service.local_services.models.base_model import LocalBaseModel +from antares.craft.tools.all_optional_meta import all_optional_model + +STStoragePropertiesType = Union[STStorageProperties, STStoragePropertiesUpdate] + + +def _sts_alias_generator(input: str) -> str: + return input.replace("_", "") + + +@all_optional_model +class STStoragePropertiesLocal(LocalBaseModel, alias_generator=_sts_alias_generator): + group: STStorageGroup = STStorageGroup.OTHER1 + injection_nominal_capacity: float = 0 + withdrawal_nominal_capacity: float = 0 + reservoir_capacity: float = 0 + efficiency: float = 1 + initial_level: float = 0.5 + initial_level_optim: bool = False + enabled: bool = True + + @staticmethod + def from_user_model(user_class: STStoragePropertiesType) -> "STStoragePropertiesLocal": + user_dict = asdict(user_class) + return STStoragePropertiesLocal.model_validate(user_dict) + + def to_user_model(self) -> STStorageProperties: + return STStorageProperties( + enabled=self.enabled, + group=self.group, + injection_nominal_capacity=self.injection_nominal_capacity, + withdrawal_nominal_capacity=self.withdrawal_nominal_capacity, + reservoir_capacity=self.reservoir_capacity, + efficiency=self.efficiency, + initial_level=self.initial_level, + initial_level_optim=self.initial_level_optim, + ) diff --git a/src/antares/craft/service/local_services/st_storage_local.py b/src/antares/craft/service/local_services/services/st_storage.py similarity index 90% rename from src/antares/craft/service/local_services/st_storage_local.py rename to src/antares/craft/service/local_services/services/st_storage.py index 88768704..93777914 100644 --- a/src/antares/craft/service/local_services/st_storage_local.py +++ b/src/antares/craft/service/local_services/services/st_storage.py @@ -15,7 +15,12 @@ import pandas as pd from antares.craft.config.local_configuration import LocalConfiguration -from antares.craft.model.st_storage import STStorage, STStorageMatrixName, STStorageProperties +from antares.craft.model.st_storage import ( + STStorage, + STStorageMatrixName, + STStorageProperties, + STStoragePropertiesUpdate, +) from antares.craft.service.base_services import BaseShortTermStorageService from typing_extensions import override @@ -28,7 +33,7 @@ def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) - @override def update_st_storage_properties( - self, st_storage: STStorage, properties: STStorageProperties + self, st_storage: STStorage, properties: STStoragePropertiesUpdate ) -> STStorageProperties: raise NotImplementedError diff --git a/src/antares/craft/service/service_factory.py b/src/antares/craft/service/service_factory.py index 424575bc..0aa8a7c7 100644 --- a/src/antares/craft/service/service_factory.py +++ b/src/antares/craft/service/service_factory.py @@ -21,8 +21,8 @@ from antares.craft.service.api_services.services.renewable import RenewableApiService from antares.craft.service.api_services.services.run import RunApiService from antares.craft.service.api_services.services.settings import StudySettingsAPIService +from antares.craft.service.api_services.services.st_storage import ShortTermStorageApiService from antares.craft.service.api_services.services.thermal import ThermalApiService -from antares.craft.service.api_services.st_storage_api import ShortTermStorageApiService from antares.craft.service.api_services.study_api import StudyApiService from antares.craft.service.base_services import ( BaseAreaService, @@ -45,8 +45,8 @@ from antares.craft.service.local_services.services.renewable import RenewableLocalService from antares.craft.service.local_services.services.run import RunLocalService from antares.craft.service.local_services.services.settings import StudySettingsLocalService +from antares.craft.service.local_services.services.st_storage import ShortTermStorageLocalService from antares.craft.service.local_services.services.thermal import ThermalLocalService -from antares.craft.service.local_services.st_storage_local import ShortTermStorageLocalService from antares.craft.service.local_services.study_local import StudyLocalService ERROR_MESSAGE = "Unsupported configuration type: " diff --git a/tests/antares/delete/test_delete_api.py b/tests/antares/delete/test_delete_api.py index 51c23357..1887b9a0 100644 --- a/tests/antares/delete/test_delete_api.py +++ b/tests/antares/delete/test_delete_api.py @@ -35,8 +35,8 @@ from antares.craft.service.api_services.services.hydro import HydroApiService from antares.craft.service.api_services.services.output import OutputApiService from antares.craft.service.api_services.services.renewable import RenewableApiService +from antares.craft.service.api_services.services.st_storage import ShortTermStorageApiService from antares.craft.service.api_services.services.thermal import ThermalApiService -from antares.craft.service.api_services.st_storage_api import ShortTermStorageApiService from antares.craft.service.api_services.study_api import StudyApiService diff --git a/tests/antares/services/api_services/test_area_api.py b/tests/antares/services/api_services/test_area_api.py index 3c2925a5..127189f3 100644 --- a/tests/antares/services/api_services/test_area_api.py +++ b/tests/antares/services/api_services/test_area_api.py @@ -27,12 +27,13 @@ from antares.craft.model.area import Area, AreaProperties, AreaUi from antares.craft.model.hydro import Hydro, HydroProperties, HydroPropertiesUpdate from antares.craft.model.renewable import RenewableCluster, RenewableClusterProperties -from antares.craft.model.st_storage import STStorage, STStorageProperties +from antares.craft.model.st_storage import STStorage from antares.craft.model.study import Study from antares.craft.model.thermal import ThermalCluster, ThermalClusterProperties from antares.craft.service.api_services.area_api import AreaApiService from antares.craft.service.api_services.models.hydro import HydroPropertiesAPI from antares.craft.service.api_services.models.renewable import RenewableClusterPropertiesAPI +from antares.craft.service.api_services.models.st_storage import STStoragePropertiesAPI from antares.craft.service.api_services.models.thermal import ThermalClusterPropertiesAPI from antares.craft.service.service_factory import ServiceFactory @@ -159,7 +160,7 @@ def test_create_renewable_fails(self): def test_create_st_storage_success(self): with requests_mock.Mocker() as mocker: url = f"https://antares.com/api/v1/studies/{self.study_id}/areas/{self.area.id}/storages" - json_response = STStorageProperties().model_dump(mode="json", by_alias=True) + json_response = STStoragePropertiesAPI().model_dump(mode="json", by_alias=True) st_storage_name = "short_term_storage" mocker.post(url, json={"name": st_storage_name, "id": st_storage_name, **json_response}, status_code=201) @@ -306,7 +307,7 @@ def test_read_areas_success(self): renewable_cluster = RenewableCluster( self.area_api.renewable_service, renewable_id, renewable_name, renewable_props ) - storage_props = STStorageProperties(**storage_) + storage_props = STStoragePropertiesAPI(**storage_).to_user_model() st_storage = STStorage(self.area_api.storage_service, storage_id, storage_name, storage_props) hydro = Hydro(self.area_api.hydro_service, area_id, hydro_properties) diff --git a/tests/antares/services/api_services/test_st_storage_api.py b/tests/antares/services/api_services/test_st_storage_api.py index 0ad79538..ba6bce8f 100644 --- a/tests/antares/services/api_services/test_st_storage_api.py +++ b/tests/antares/services/api_services/test_st_storage_api.py @@ -25,7 +25,8 @@ from antares.craft.model.area import Area from antares.craft.model.st_storage import STStorage, STStorageProperties from antares.craft.service.api_services.area_api import AreaApiService -from antares.craft.service.api_services.st_storage_api import ShortTermStorageApiService +from antares.craft.service.api_services.models.st_storage import STStoragePropertiesAPI +from antares.craft.service.api_services.services.st_storage import ShortTermStorageApiService from antares.craft.service.service_factory import ServiceFactory @@ -47,11 +48,14 @@ class TestCreateAPI: def test_update_st_storage_properties_success(self): with requests_mock.Mocker() as mocker: properties = STStorageProperties(enabled=False) + api_properties = STStoragePropertiesAPI.from_user_model(properties) url = ( f"https://antares.com/api/v1/studies/{self.study_id}/" f"areas/{self.storage.area_id}/storages/{self.storage.id}" ) - mocker.patch(url, json={"id": "id", "name": "name", **properties.model_dump()}, status_code=200) + mocker.patch( + url, json={"id": "id", "name": "name", **api_properties.model_dump(mode="json")}, status_code=200 + ) self.storage.update_properties(properties=properties) def test_update_st_storage_properties_fails(self): @@ -153,7 +157,7 @@ def test_read_st_storages(self): storage_id = json_storage[0].pop("id") storage_name = json_storage[0].pop("name") - storage_props = STStorageProperties(**json_storage[0]) + storage_props = STStoragePropertiesAPI(**json_storage[0]).to_user_model() expected_st_storage = STStorage(area_api.storage_service, storage_id, storage_name, storage_props) assert len(actual_storage_list) == 1 diff --git a/tests/antares/services/local_services/test_area.py b/tests/antares/services/local_services/test_area.py index 529ec662..723dcbcb 100644 --- a/tests/antares/services/local_services/test_area.py +++ b/tests/antares/services/local_services/test_area.py @@ -29,7 +29,7 @@ RenewableClusterProperties, TimeSeriesInterpretation, ) -from antares.craft.model.st_storage import STStorage, STStorageGroup, STStorageProperties, STStoragePropertiesLocal +from antares.craft.model.st_storage import STStorage, STStorageGroup, STStorageProperties from antares.craft.model.study import read_study_local from antares.craft.model.thermal import ThermalCluster from antares.craft.tools.ini_tool import IniFile, InitializationFilesTypes @@ -51,18 +51,10 @@ def test_can_create_renewables_cluster(self, local_study_w_thermal): local_study_w_thermal.get_areas()["fr"].get_renewables()[renewable_cluster_name], RenewableCluster ) - def test_renewable_cluster_has_properties(self, local_study_with_renewable): + def test_renewable_cluster_has_correct_default_properties(self, local_study_with_renewable): renewable_cluster = local_study_with_renewable.get_areas()["fr"].get_renewables()["renewable cluster"] assert renewable_cluster.properties == RenewableClusterProperties() - def test_renewable_cluster_has_correct_default_properties( - self, local_study_with_renewable, default_renewable_cluster_properties - ): - assert ( - local_study_with_renewable.get_areas()["fr"].get_renewables()["renewable cluster"].properties - == default_renewable_cluster_properties - ) - def test_renewables_list_ini_exists(self, local_study_with_renewable): renewables_list_ini = ( local_study_with_renewable.service.config.study_path @@ -135,18 +127,9 @@ def test_can_create_st_storage(self, local_study_with_renewable): assert local_study_with_renewable.get_areas()["fr"].get_st_storages() assert isinstance(local_study_with_renewable.get_areas()["fr"].get_st_storages()[storage_name], STStorage) - def test_storage_has_properties(self, local_study_with_st_storage): - assert ( - local_study_with_st_storage.get_areas()["fr"] - .get_st_storages()["short term storage"] - .properties.model_dump(exclude_none=True) - ) - - def test_storage_has_correct_default_properties(self, local_study_with_st_storage, default_st_storage_properties): - assert ( - local_study_with_st_storage.get_areas()["fr"].get_st_storages()["short term storage"].properties - == default_st_storage_properties - ) + def test_storage_has_correct_default_properties(self, local_study_with_st_storage): + st_storage = local_study_with_st_storage.get_areas()["fr"].get_st_storages()["short term storage"] + assert st_storage.properties == STStorageProperties() def test_st_storage_list_ini_exists(self, local_study_with_st_storage): st_storage_list_ini = ( @@ -162,13 +145,13 @@ def test_st_storage_list_ini_has_correct_default_values( expected_st_storage_list_ini_content = """[short term storage] name = short term storage group = Other1 -injectionnominalcapacity = 0.000000 -withdrawalnominalcapacity = 0.000000 -reservoircapacity = 0.000000 -efficiency = 1.000000 -initiallevel = 0.500000 -initialleveloptim = false -enabled = true +injectionnominalcapacity = 0.0 +withdrawalnominalcapacity = 0.0 +reservoircapacity = 0.0 +efficiency = 1.0 +initiallevel = 0.5 +initialleveloptim = False +enabled = True """ expected_st_storage_list_ini = ConfigParser() @@ -184,37 +167,33 @@ def test_st_storage_list_ini_has_correct_default_values( def test_st_storage_and_ini_have_custom_properties(self, local_study_w_areas): # Given - props = STStorageProperties(group=STStorageGroup.BATTERY, reservoir_capacity=12.345) - args = {"st_storage_name": "short term storage", **props.model_dump(mode="json", exclude_none=True)} - custom_properties = STStoragePropertiesLocal.model_validate(args) + properties = STStorageProperties(group=STStorageGroup.BATTERY, reservoir_capacity=12.345) + st_storage_name = "short term storage" + + # When + created_storage = local_study_w_areas.get_areas()["fr"].create_st_storage(st_storage_name, properties) + + # Then expected_st_storage_list_ini_content = """[short term storage] name = short term storage group = Battery -injectionnominalcapacity = 0.000000 -withdrawalnominalcapacity = 0.000000 -reservoircapacity = 12.345000 -efficiency = 1.000000 -initiallevel = 0.500000 -initialleveloptim = false -enabled = true +injectionnominalcapacity = 0.0 +withdrawalnominalcapacity = 0.0 +reservoircapacity = 12.345 +efficiency = 1.0 +initiallevel = 0.5 +initialleveloptim = False +enabled = True """ actual_st_storage_list_ini = IniFile( local_study_w_areas.service.config.study_path, InitializationFilesTypes.ST_STORAGE_LIST_INI, area_id="fr" ) - # When - local_study_w_areas.get_areas()["fr"].create_st_storage( - st_storage_name=custom_properties.st_storage_name, - properties=custom_properties.yield_st_storage_properties(), - ) with actual_st_storage_list_ini.ini_path.open() as st_storage_list_ini_file: actual_st_storage_list_ini_content = st_storage_list_ini_file.read() - assert ( - local_study_w_areas.get_areas()["fr"].get_st_storages()["short term storage"].properties - == custom_properties.yield_st_storage_properties() - ) + assert created_storage.properties == properties assert actual_st_storage_list_ini_content == expected_st_storage_list_ini_content diff --git a/tests/antares/services/local_services/test_create_thermal_cluster.py b/tests/antares/services/local_services/test_create_thermal_cluster.py index c87a81b8..2813489e 100644 --- a/tests/antares/services/local_services/test_create_thermal_cluster.py +++ b/tests/antares/services/local_services/test_create_thermal_cluster.py @@ -49,21 +49,10 @@ def test_duplicate_name_errors(self, local_study_w_thermal): ): local_study_w_thermal.get_areas()[area_name].create_thermal_cluster(thermal_name) - def test_has_default_properties(self, local_study_w_thermal): + def test_has_correct_default_properties(self, local_study_w_thermal): thermal_cluster = local_study_w_thermal.get_areas()["fr"].get_thermals()["test thermal cluster"] assert thermal_cluster.properties == ThermalClusterProperties() - def test_has_correct_default_properties(self, local_study_w_thermal, default_thermal_cluster_properties): - # Given - expected_thermal_cluster_properties = default_thermal_cluster_properties - - # When - actual_thermal_cluster_properties = ( - local_study_w_thermal.get_areas()["fr"].get_thermals()["test thermal cluster"].properties - ) - - assert expected_thermal_cluster_properties == actual_thermal_cluster_properties - def test_required_ini_files_exist(self, tmp_path, local_study_w_thermal): # Given expected_list_ini_path = ( diff --git a/tests/integration/test_web_client.py b/tests/integration/test_web_client.py index 82ce1c27..3dd47474 100644 --- a/tests/integration/test_web_client.py +++ b/tests/integration/test_web_client.py @@ -53,7 +53,12 @@ from antares.craft.model.settings.optimization import ExportMPS, OptimizationParametersUpdate from antares.craft.model.settings.study_settings import PlaylistParameters, StudySettings, StudySettingsUpdate from antares.craft.model.simulation import AntaresSimulationParameters, Job, JobStatus -from antares.craft.model.st_storage import STStorageGroup, STStorageMatrixName, STStorageProperties +from antares.craft.model.st_storage import ( + STStorageGroup, + STStorageMatrixName, + STStorageProperties, + STStoragePropertiesUpdate, +) from antares.craft.model.study import create_study_api, create_variant_api, import_study_api, read_study_api from antares.craft.model.thermal import ThermalClusterGroup, ThermalClusterProperties, ThermalClusterPropertiesUpdate @@ -451,10 +456,10 @@ def test_creation_lifecycle(self, antares_web: AntaresWebDesktop, tmp_path): assert renewable_onshore.properties.ts_interpretation == TimeSeriesInterpretation.POWER_GENERATION # tests short term storage properties update - new_props = STStorageProperties() - new_props.group = STStorageGroup.PONDAGE + new_props = STStoragePropertiesUpdate(group=STStorageGroup.PONDAGE) battery_fr.update_properties(new_props) assert battery_fr.properties.group == STStorageGroup.PONDAGE + assert battery_fr.properties.reservoir_capacity == 0.5 # Checks old value wasn't modified # tests constraint properties update new_props = BindingConstraintProperties()