battery_optimizer_app.models#

Functions

get_battery_optimizer_discriminator(request)

Composite discriminator combining country and use_case.

Classes

APIWrappedAFRREnergyRequest(*, request_id[, ...])

APIWrappedBatteryOptimizer(*, request_id[, ...])

APIWrappedBodRequest(*, request_id[, ...])

APIWrappedMelMilBoaRequest(*, request_id[, ...])

APIWrappedMelMilNowRequest(*, request_id[, ...])

APIWrappedMelMilRequest(*, request_id[, ...])

aFRREnergyPosition(*, start, volume_MW, ...)

aFRREnergyPositionMetadata(*, result)

aFRREnergyPositions(*, start, afrr_positive, ...)

aFRREnergyPremium(*, start[, ...])

aFRREnergyResult(*, request, positions)

class battery_optimizer_app.models.APIWrappedAFRREnergyRequest(*, request_id, problem_type=ProblemType.AFRR_ENERGY, payload, orderbook=None, bucketing_approach=BucketingApproach.whole, blocked_capacities=[], timestamps, premiums=[], premium_lower_bound_per_MWh=10.0, premium_upper_bound_per_MWh=9999.0, premium_multiplier=3.0)#

Bases: APIWrappedBatteryOptimizer

Parameters:
ensure_premiums_are_not_null()#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

payload: DERequest#
premium_lower_bound_per_MWh: float#
premium_multiplier: float#
premium_upper_bound_per_MWh: float#
premiums: list[aFRREnergyPremium]#
problem_type: ProblemType#
timestamps: list[datetime]#
class battery_optimizer_app.models.APIWrappedBatteryOptimizer(*, request_id, problem_type=ProblemType.PNL, payload, orderbook=None, bucketing_approach=BucketingApproach.whole, blocked_capacities=[])#

Bases: BaseModel

Parameters:
aggregate_blocked_capacities()#

Generally, we may be sent blocked capacities with overlapping time ranges, i.e. multuple entries for the same time_from and time_to. Here, we aggregate such entries by summing their volumes.

classmethod avoid_premature_intraday_buckets_check(data)#
blocked_capacities: list[EnergyMarketContinuousPositions]#
bucketing_approach: BucketingApproach#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

orderbook: str | None#
payload: get_battery_optimizer_discriminator, custom_error_type=None, custom_error_message=None, custom_error_context=None)]#
problem_type: ProblemType#
reinstate_buckets_check()#
request_id: str#
validate_blocked_capacities_timestamps()#

Validate that blocked_capacities timestamps align with optimization_time_range. Both time_from and time_to must be within the optimization bounds.

class battery_optimizer_app.models.APIWrappedBodRequest(*, request_id, problem_type=ProblemType.BOD, payload)#

Bases: BaseModel

Parameters:
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

payload: BodRequest#
problem_type: ProblemType#
request_id: str#
class battery_optimizer_app.models.APIWrappedMelMilBoaRequest(*, request_id, problem_type=ProblemType.MELMILBOA, payload, boas=None, start=None, baseline)#

Bases: APIWrappedMelMilRequest

Parameters:
baseline: list[BaselinePoint]#
boas: list[BOA] | None#
ensure_soc_level_after_boa_is_given()#
ensure_soc_level_of_boa_is_given()#
property latest_boa_timestamp: datetime#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

problem_type: ProblemType#
property soc_fraction_after_boa: float#
start: datetime | None#
class battery_optimizer_app.models.APIWrappedMelMilNowRequest(*, request_id, problem_type=ProblemType.MELMILNOW, payload)#

Bases: APIWrappedMelMilRequest

Parameters:
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

payload: UKMelMilNowRequest#
problem_type: ProblemType#
class battery_optimizer_app.models.APIWrappedMelMilRequest(*, request_id, problem_type=ProblemType.MELMIL, payload)#

Bases: BaseModel

Parameters:
ensure_asset_strategy_optimization_markets_is_empty()#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

payload: UKRequest#
problem_type: ProblemType#
request_id: str#
class battery_optimizer_app.models.aFRREnergyPosition(*, start, volume_MW, base_price_per_MWh, premium_per_MWh, price_per_MWh, market, metadata, blocked_capacities=[])#

Bases: BaseModel

Parameters:
base_price_per_MWh: float#
blocked_capacities: list[EnergyMarketContinuousPositions]#
market: MarketType#
metadata: aFRREnergyPositionMetadata | None#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

premium_per_MWh: float#
price_per_MWh: float#
start: datetime#
volume_MW: float#
class battery_optimizer_app.models.aFRREnergyPositionMetadata(*, result)#

Bases: BaseModel

Parameters:

result (DataFrame)

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

result: DataFrame#
class battery_optimizer_app.models.aFRREnergyPositions(*, start, afrr_positive, afrr_negative)#

Bases: BaseModel

Parameters:
afrr_negative: aFRREnergyPosition#
afrr_positive: aFRREnergyPosition#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

start: datetime#
class battery_optimizer_app.models.aFRREnergyPremium(*, start, afrr_positive_premium_per_MWh=None, afrr_negative_premium_per_MWh=None)#

Bases: BaseModel

Parameters:
  • start (datetime)

  • afrr_positive_premium_per_MWh (Annotated[float | None, Ge(ge=-4999.0), Le(le=4999.0)])

  • afrr_negative_premium_per_MWh (Annotated[float | None, Ge(ge=-4999.0), Le(le=4999.0)])

afrr_negative_premium_per_MWh: float | None#
afrr_positive_premium_per_MWh: float | None#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

start: datetime#
class battery_optimizer_app.models.aFRREnergyResult(*, request, positions)#

Bases: BaseModel

Parameters:
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'frozen': False, 'json_encoders': {<class 'datetime.datetime'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>: <function BaseModel.<lambda>>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>: <function BaseModel.<lambda>>, <class 'pandas.core.frame.DataFrame'>: <function BaseModel.<lambda>>, <class 'pandas.core.series.Series'>: <function BaseModel.<lambda>>}, 'validate_default': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

positions: list[aFRREnergyPositions]#
request: APIWrappedAFRREnergyRequest#
battery_optimizer_app.models.get_battery_optimizer_discriminator(request)#

Composite discriminator combining country and use_case. Backward compatible: missing use_case -> BESS.

Parameters:

request (dict)

Return type:

tuple[str, str]