Skip to content

Commit

Permalink
feat(st-storage): allow all parameters in endpoint for short term sto…
Browse files Browse the repository at this point in the history
…rage creation (#1736)

Co-authored-by: Laurent LAPORTE <[email protected]>
(cherry picked from commit bb6d5c6)
  • Loading branch information
laurent-laporte-pro committed Oct 11, 2023
1 parent 789c2ad commit 853cf6b
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 217 deletions.
113 changes: 35 additions & 78 deletions antarest/study/business/st_storage_manager.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import functools
import json
import operator
from typing import Any, Dict, List, Mapping, MutableMapping, Sequence
from typing import Any, Dict, List, Mapping, MutableMapping, Optional, Sequence

import numpy as np
from pydantic import BaseModel, Extra, Field, root_validator, validator
from pydantic import BaseModel, Extra, root_validator, validator
from typing_extensions import Literal

from antarest.core.exceptions import (
STStorageConfigNotFoundError,
STStorageFieldsNotFoundError,
STStorageMatrixNotFoundError,
)
from antarest.study.business.utils import AllOptionalMetaclass, FormFieldsBaseModel, execute_or_add_commands
from antarest.study.business.utils import AllOptionalMetaclass, camel_case_model, execute_or_add_commands
from antarest.study.model import Study
from antarest.study.storage.rawstudy.model.filesystem.config.st_storage import STStorageConfig, STStorageGroup
from antarest.study.storage.rawstudy.model.filesystem.config.st_storage import (
STStorageConfig,
STStorageGroup,
STStorageProperties,
)
from antarest.study.storage.storage_service import StudyStorageService
from antarest.study.storage.variantstudy.model.command.create_st_storage import CreateSTStorage
from antarest.study.storage.variantstudy.model.command.remove_st_storage import RemoveSTStorage
Expand All @@ -23,77 +27,12 @@
_HOURS_IN_YEAR = 8760


class FormBaseModel(FormFieldsBaseModel):
"""
A foundational model for all form-based models, providing common configurations.
"""

class Config:
validate_assignment = True
allow_population_by_field_name = True


class StorageCreation(FormBaseModel):
@camel_case_model
class StorageInput(STStorageProperties, metaclass=AllOptionalMetaclass):
"""
Model representing the form used to create a new short-term storage entry.
Model representing the form used to EDIT an existing short-term storage.
"""

name: str = Field(
description="Name of the storage.",
regex=r"[a-zA-Z0-9_(),& -]+",
)
group: STStorageGroup = Field(
description="Energy storage system group.",
)

class Config:
@staticmethod
def schema_extra(schema: MutableMapping[str, Any]) -> None:
schema["example"] = StorageCreation(
name="Siemens Battery",
group=STStorageGroup.BATTERY,
)

@property
def to_config(self) -> STStorageConfig:
values = self.dict(by_alias=False)
return STStorageConfig(**values)


class StorageUpdate(StorageCreation, metaclass=AllOptionalMetaclass):
"""set name, group as optional fields"""


class StorageInput(StorageUpdate):
"""
Model representing the form used to edit existing short-term storage details.
"""

injection_nominal_capacity: float = Field(
description="Injection nominal capacity (MW)",
ge=0,
)
withdrawal_nominal_capacity: float = Field(
description="Withdrawal nominal capacity (MW)",
ge=0,
)
reservoir_capacity: float = Field(
description="Reservoir capacity (MWh)",
ge=0,
)
efficiency: float = Field(
description="Efficiency of the storage system",
ge=0,
le=1,
)
initial_level: float = Field(
description="Initial level of the storage system",
ge=0,
)
initial_level_optim: bool = Field(
description="Flag indicating if the initial level is optimized",
)

class Config:
@staticmethod
def schema_extra(schema: MutableMapping[str, Any]) -> None:
Expand All @@ -104,19 +43,37 @@ def schema_extra(schema: MutableMapping[str, Any]) -> None:
withdrawal_nominal_capacity=150,
reservoir_capacity=600,
efficiency=0.94,
initial_level=0.5,
initial_level_optim=True,
)


class StorageOutput(StorageInput):
class StorageCreation(StorageInput):
"""
Model representing the form used to display the details of a short-term storage entry.
Model representing the form used to CREATE a new short-term storage.
"""

id: str = Field(
description="Short-term storage ID",
regex=r"[a-zA-Z0-9_(),& -]+",
)
# noinspection Pydantic
@validator("name", pre=True)
def validate_name(cls, name: Optional[str]) -> str:
"""
Validator to check if the name is not empty.
"""
if not name:
raise ValueError("'name' must not be empty")
return name

@property
def to_config(self) -> STStorageConfig:
values = self.dict(by_alias=False, exclude_none=True)
return STStorageConfig(**values)


@camel_case_model
class StorageOutput(STStorageConfig):
"""
Model representing the form used to display the details of a short-term storage entry.
"""

class Config:
@staticmethod
Expand Down
16 changes: 16 additions & 0 deletions antarest/study/business/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,19 @@ def __new__(
annotations[field] = Optional[annotations[field]]
namespaces["__annotations__"] = annotations
return super().__new__(cls, name, bases, namespaces)


def camel_case_model(model: Type[BaseModel]) -> Type[BaseModel]:
"""
This decorator can be used to modify a model to use camel case aliases.
Args:
model: The pydantic model to modify.
Returns:
The modified model.
"""
model.__config__.alias_generator = to_camel_case
for field_name, field in model.__fields__.items():
field.alias = to_camel_case(field_name)
return model
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,18 @@ class STStorageGroup(EnumIgnoreCase):


# noinspection SpellCheckingInspection
class STStorageConfig(BaseModel):
"""
Manage the configuration files in the context of Short-Term Storage.
It provides a convenient way to read and write configuration data from/to an INI file format.
class STStorageProperties(
BaseModel,
extra=Extra.forbid,
validate_assignment=True,
allow_population_by_field_name=True,
):
"""
Properties of a short-term storage system read from the configuration files.
class Config:
extra = Extra.forbid
allow_population_by_field_name = True
All aliases match the name of the corresponding field in the INI files.
"""

# The `id` field is a calculated from the `name` if not provided.
# This value must be stored in the config cache.
id: str = Field(
description="Short-term storage ID",
regex=r"[a-zA-Z0-9_(),& -]+",
)
name: str = Field(
description="Short-term storage name",
regex=r"[a-zA-Z0-9_(),& -]+",
Expand Down Expand Up @@ -90,6 +86,21 @@ class Config:
alias="initialleveloptim",
)


# noinspection SpellCheckingInspection
class STStorageConfig(STStorageProperties):
"""
Manage the configuration files in the context of Short-Term Storage.
It provides a convenient way to read and write configuration data from/to an INI file format.
"""

# The `id` field is a calculated from the `name` if not provided.
# This value must be stored in the config cache.
id: str = Field(
description="Short-term storage ID",
regex=r"[a-zA-Z0-9_(),& -]+",
)

@root_validator(pre=True)
def calculate_storage_id(cls, values: Dict[str, Any]) -> Dict[str, Any]:
"""
Expand Down
11 changes: 9 additions & 2 deletions antarest/study/web/study_data_blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -1577,8 +1577,15 @@ def create_st_storage(
Args:
- `uuid`: The UUID of the study.
- `area_id`: The area ID.
- `form`: The name and the group(PSP_open, PSP_closed, Pondage, Battery, Other1, Other2, Other3, Other4, Other5)
of the storage that we want to create.
- `form`: The characteristic of the storage that we can update:
- `name`: The name of the updated storage.
- `group`: The group of the updated storage.
- `injectionNominalCapacity`: The injection Nominal Capacity of the updated storage.
- `withdrawalNominalCapacity`: The withdrawal Nominal Capacity of the updated storage.
- `reservoirCapacity`: The reservoir capacity of the updated storage.
- `efficiency`: The efficiency of the updated storage
- `initialLevel`: The initial Level of the updated storage
- `initialLevelOptim`: The initial Level Optim of the updated storage
Returns: New storage with the following attributes:
- `id`: The storage ID of the study.
Expand Down
Loading

0 comments on commit 853cf6b

Please sign in to comment.