From 130d76c8a125a05f7a1b25d55c4f4bd80de0ed23 Mon Sep 17 00:00:00 2001 From: Theo Pascoli Date: Tue, 17 Sep 2024 12:00:37 +0200 Subject: [PATCH] WIP : first commit --- antarest/study/business/link_management.py | 58 +++++++++- .../rawstudy/model/filesystem/config/links.py | 35 ++++++ tests/integration/test_integration.py | 8 ++ .../storage/business/test_arealink_manager.py | 106 +++++++++++++++++- 4 files changed, 196 insertions(+), 11 deletions(-) diff --git a/antarest/study/business/link_management.py b/antarest/study/business/link_management.py index 6f696d2a5e..fdaff6f651 100644 --- a/antarest/study/business/link_management.py +++ b/antarest/study/business/link_management.py @@ -19,8 +19,10 @@ from antarest.study.business.all_optional_meta import all_optional_model, camel_case_model from antarest.study.business.utils import execute_or_add_commands from antarest.study.model import RawStudy -from antarest.study.storage.rawstudy.model.filesystem.config.links import LinkProperties +from antarest.study.storage.rawstudy.model.filesystem.config.links import LinkProperties, LinkStyle, \ + TransmissionCapacity, AssetType from antarest.study.storage.storage_service import StudyStorageService +from antarest.study.storage.variantstudy.model.command.common import FilteringOptions from antarest.study.storage.variantstudy.model.command.create_link import CreateLink from antarest.study.storage.variantstudy.model.command.remove_link import RemoveLink from antarest.study.storage.variantstudy.model.command.update_config import UpdateConfig @@ -31,12 +33,20 @@ class LinkUIDTO(BaseModel): color: str width: float - style: str + style: LinkStyle class LinkInfoDTO(BaseModel): area1: str area2: str + hurdles_cost: t.Optional[bool] = False + loop_flow: t.Optional[bool] = False + use_phase_shifter: t.Optional[bool] = False + transmission_capacities: t.Optional[TransmissionCapacity] = "enabled" + asset_type: t.Optional[AssetType] = "ac" + display_comments: t.Optional[bool] = True + filter_synthesis: t.Optional[str] = FilteringOptions.FILTER_SYNTHESIS + filter_year_by_year: t.Optional[str] = FilteringOptions.FILTER_YEAR_BY_YEAR ui: t.Optional[LinkUIDTO] = None @@ -56,9 +66,7 @@ def get_all_links(self, study: RawStudy, with_ui: bool = False) -> t.List[LinkIn file_study = self.storage_service.get_storage(study).get_raw(study) result = [] for area_id, area in file_study.config.areas.items(): - links_config: t.Optional[t.Dict[str, t.Any]] = None - if with_ui: - links_config = file_study.tree.get(["input", "links", area_id, "properties"]) + links_config = file_study.tree.get(["input", "links", area_id, "properties"]) for link in area.links: ui_info: t.Optional[LinkUIDTO] = None if with_ui and links_config and link in links_config: @@ -67,7 +75,21 @@ def get_all_links(self, study: RawStudy, with_ui: bool = False) -> t.List[LinkIn width=links_config[link].get("link-width", 1), style=links_config[link].get("link-style", "plain"), ) - result.append(LinkInfoDTO(area1=area_id, area2=link, ui=ui_info)) + result.append( + LinkInfoDTO( + area1=area_id, + area2=link, + hurdles_cost=links_config[link].get("hurdles-cost"), + loop_flow=links_config[link].get("loop-flow"), + use_phase_shifter=links_config[link].get("use-phase-shifter"), + transmission_capacities=links_config[link].get("transmission-capacities"), + asset_type=links_config[link].get("asset-type"), + display_comments=links_config[link].get("display-comments"), + filter_synthesis=links_config[link].get("filter-synthesis"), + filter_year_by_year=links_config[link].get("filter-year-by-year"), + ui=ui_info + ) + ) return result @@ -77,12 +99,21 @@ def create_link(self, study: RawStudy, link_creation_info: LinkInfoDTO) -> LinkI command = CreateLink( area1=link_creation_info.area1, area2=link_creation_info.area2, + parameters=self.create_parameters(link_creation_info), command_context=self.storage_service.variant_study_service.command_factory.command_context, ) execute_or_add_commands(study, file_study, [command], self.storage_service) return LinkInfoDTO( area1=link_creation_info.area1, area2=link_creation_info.area2, + hurdles_cost=link_creation_info.hurdles_cost, + loop_flow=link_creation_info.loop_flow, + use_phase_shifter=link_creation_info.use_phase_shifter, + transmission_capacities=link_creation_info.transmission_capacities, + asset_type=link_creation_info.asset_type, + display_comments=link_creation_info.display_comments, + filter_synthesis=link_creation_info.filter_synthesis, + filter_year_by_year=link_creation_info.filter_year_by_year ) def delete_link(self, study: RawStudy, area1_id: str, area2_id: str) -> None: @@ -157,3 +188,18 @@ def update_links_props( @staticmethod def get_table_schema() -> JSON: return LinkOutput.schema() + + @staticmethod + def create_parameters(link_creation_info: LinkInfoDTO) -> dict[str, str]: + parameters = { + "hurdles-cost": link_creation_info.hurdles_cost, + "loop-flow": link_creation_info.loop_flow, + "use-phase-shifter": link_creation_info.use_phase_shifter, + "transmission-capacities": link_creation_info.transmission_capacities, + "asset-type": link_creation_info.asset_type, + "display-comments": link_creation_info.display_comments, + "filter-synthesis": link_creation_info.filter_synthesis, + "filter-year-by-year": link_creation_info.filter_year_by_year + } + + return parameters \ No newline at end of file diff --git a/antarest/study/storage/rawstudy/model/filesystem/config/links.py b/antarest/study/storage/rawstudy/model/filesystem/config/links.py index 88059ef50e..b9fd25ccac 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/config/links.py +++ b/antarest/study/storage/rawstudy/model/filesystem/config/links.py @@ -65,6 +65,41 @@ class TransmissionCapacity(EnumIgnoreCase): IGNORE = "ignore" ENABLED = "enabled" +class LinkStyle(EnumIgnoreCase): + """ + Enum representing the style of a link in a network visualization. + + Attributes: + DOT: Represents a dotted line style. + PLAIN: Represents a solid line style. + DASH: Represents a dashed line style. + DOT_DASH: Represents a line style with alternating dots and dashes. + """ + + DOT = "dot" + PLAIN = "plain" + DASH = "dash" + DOT_DASH = "dotdash" + + +class FilterOption(EnumIgnoreCase): + """ + Enum representing the time filter options for data visualization or analysis in Antares Web. + + Attributes: + HOURLY: Represents filtering data by the hour. + DAILY: Represents filtering data by the day. + WEEKLY: Represents filtering data by the week. + MONTHLY: Represents filtering data by the month. + ANNUAL: Represents filtering data by the year. + """ + + HOURLY = "hourly" + DAILY = "daily" + WEEKLY = "weekly" + MONTHLY = "monthly" + ANNUAL = "annual" + class LinkProperties(IniProperties): """ diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index a136184969..e60b9a2a37 100644 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -620,6 +620,14 @@ def test_area_management(client: TestClient, admin_access_token: str) -> None: { "area1": "area 1", "area2": "area 2", + "asset_type": 'ac', + "display_comments": True, + "filter_synthesis": 'hourly, daily, weekly, monthly, annual', + "filter_year_by_year": 'hourly, daily, weekly, monthly, annual', + "hurdles_cost": False, + "loop_flow": False, + "transmission_capacities": 'enabled', + "use_phase_shifter": False, "ui": {"color": "112,112,112", "style": "plain", "width": 1.0}, } ] diff --git a/tests/storage/business/test_arealink_manager.py b/tests/storage/business/test_arealink_manager.py index cb1d29c971..ac7f2261e7 100644 --- a/tests/storage/business/test_arealink_manager.py +++ b/tests/storage/business/test_arealink_manager.py @@ -29,6 +29,7 @@ from antarest.study.repository import StudyMetadataRepository from antarest.study.storage.patch_service import PatchService from antarest.study.storage.rawstudy.model.filesystem.config.files import build +from antarest.study.storage.rawstudy.model.filesystem.config.links import TransmissionCapacity, AssetType from antarest.study.storage.rawstudy.model.filesystem.config.model import Area, DistrictSet, FileStudyTreeConfig, Link from antarest.study.storage.rawstudy.model.filesystem.config.thermal import ThermalConfig from antarest.study.storage.rawstudy.model.filesystem.factory import FileStudy @@ -37,10 +38,11 @@ from antarest.study.storage.storage_service import StudyStorageService from antarest.study.storage.variantstudy.business.matrix_constants_generator import GeneratorMatrixConstants from antarest.study.storage.variantstudy.command_factory import CommandFactory -from antarest.study.storage.variantstudy.model.command.common import CommandName +from antarest.study.storage.variantstudy.model.command.common import CommandName, FilteringOptions from antarest.study.storage.variantstudy.model.dbmodel import VariantStudy from antarest.study.storage.variantstudy.model.model import CommandDTO from antarest.study.storage.variantstudy.variant_study_service import VariantStudyService +from tests.conftest_services import study_storage_service_fixture from tests.helpers import with_db_context from tests.storage.business.assets import ASSETS_DIR @@ -225,7 +227,16 @@ def test_area_crud(empty_study: FileStudy, matrix_service: SimpleMatrixService): args={ "area1": "test", "area2": "test2", - "parameters": None, + "parameters": { + "hurdles-cost": False, + "loop-flow": False, + "use-phase-shifter": False, + "transmission-capacities": TransmissionCapacity.ENABLED, + "asset-type": AssetType.AC, + "display-comments": True, + 'filter-synthesis': 'hourly, daily, weekly, monthly, annual', + 'filter-year-by-year': 'hourly, daily, weekly, monthly, annual' + }, }, ), ], @@ -416,11 +427,96 @@ def test_get_all_area(): all_areas = area_manager.get_all_areas(study) assert expected_all == [area.model_dump() for area in all_areas] + file_tree_mock.get.side_effect = [ + { + 'a2': { + 'hurdles-cost': True, + 'loop-flow': True, + 'use-phase-shifter': False, + 'transmission-capacities': TransmissionCapacity.ENABLED, + 'asset-type': AssetType.DC, + 'display-comments': False, + 'filter-synthesis': FilteringOptions.FILTER_SYNTHESIS, + 'filter-year-by-year': FilteringOptions.FILTER_YEAR_BY_YEAR, + }, + 'a3': { + 'hurdles-cost': True, + 'loop-flow': False, + 'use-phase-shifter': True, + 'transmission-capacities': TransmissionCapacity.ENABLED, + 'asset-type': AssetType.AC, + 'display-comments': True, + 'filter-synthesis': FilteringOptions.FILTER_SYNTHESIS, + 'filter-year-by-year': FilteringOptions.FILTER_YEAR_BY_YEAR, + }, + }, + { + 'a3': { + 'hurdles-cost': True, + 'loop-flow': False, + 'use-phase-shifter': True, + 'transmission-capacities': TransmissionCapacity.ENABLED, + 'asset-type': AssetType.AC, + 'display-comments': True, + 'filter-synthesis': FilteringOptions.FILTER_SYNTHESIS, + 'filter-year-by-year': FilteringOptions.FILTER_YEAR_BY_YEAR, + } + }, + { + 'a3': { + 'hurdles-cost': False, + 'loop-flow': False, + 'use-phase-shifter': True, + 'transmission-capacities': TransmissionCapacity.ENABLED, + 'asset-type': AssetType.AC, + 'display-comments': True, + 'filter-synthesis': FilteringOptions.FILTER_SYNTHESIS, + 'filter-year-by-year': FilteringOptions.FILTER_YEAR_BY_YEAR, + } + } + ] + links = link_manager.get_all_links(study) assert [ - {"area1": "a1", "area2": "a2", "ui": None}, - {"area1": "a1", "area2": "a3", "ui": None}, - {"area1": "a2", "area2": "a3", "ui": None}, + { + "area1": "a1", + "area2": "a2", + "asset_type": AssetType.DC, + "display_comments": False, + "filter_synthesis": "hourly, daily, weekly, monthly, annual", + "filter_year_by_year": "hourly, daily, weekly, monthly, annual", + "hurdles_cost": True, + "loop_flow": True, + "transmission_capacities": TransmissionCapacity.ENABLED, + "ui": None, + "use_phase_shifter": False + }, + { + "area1": "a1", + "area2": "a3", + "asset_type": AssetType.AC, + "display_comments": True, + "filter_synthesis": "hourly, daily, weekly, monthly, annual", + "filter_year_by_year": "hourly, daily, weekly, monthly, annual", + "hurdles_cost": True, + "loop_flow": False, + "transmission_capacities": TransmissionCapacity.ENABLED, + "ui": None, + "use_phase_shifter": True + }, + { + "area1": "a2", + "area2": "a3", + "asset_type": AssetType.AC, + "display_comments": True, + "filter_synthesis": "hourly, daily, weekly, monthly, annual", + "filter_year_by_year": "hourly, daily, weekly, monthly, annual", + "hurdles_cost": True, + "loop_flow": False, + "transmission_capacities": TransmissionCapacity.ENABLED, + "ui": None, + "use_phase_shifter": True + } ] == [link.model_dump() for link in links]