battery_optimizer.result#

Classes

CapacityMarketPositions(*, time_from, ...[, ...])

EnergyMarketAuctionedPositions(*, time_from, ...)

EnergyMarketContinuousPositions(*, ...[, ...])

Error(*, request_id, errors)

Imbalance(*, time_from, time_to, ...[, ...])

IntradayBucket(*, max_volume_MW, ...[, ...])

IntradayBuckets(*, intraday_sell, intraday_buy)

MarketPositions(*, intraday, imbalance)

Result(*, asset_id, request_id, ...[, ...])

SoE(*, time_from, time_to, soe_target, ...)

class battery_optimizer.result.CapacityMarketPositions(*, time_from, time_to, volume_MW, capacity_price_per_MWh=None)#

Bases: BaseModel

Parameters:
capacity_price_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].

time_from: datetime#
time_to: datetime#
volume_MW: float#
class battery_optimizer.result.EnergyMarketAuctionedPositions(*, time_from, time_to, volume_sold_MW=None, volume_bought_MW=None, energy_price_per_MWh=None)#

Bases: BaseModel

Parameters:
energy_price_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].

classmethod round_bought_MW_to_nearest_kW(volume_bought_MW)#
classmethod round_sold_MW_to_nearest_kW(volume_sold_MW)#
time_from: datetime#
time_to: datetime#
volume_bought_MW: float | None#
volume_sold_MW: float | None#
class battery_optimizer.result.EnergyMarketContinuousPositions(*, time_from, time_to, volume_sold_MW=None, volume_bought_MW=None, energy_sell_price_per_MWh=None, energy_buy_price_per_MWh=None)#

Bases: BaseModel

Parameters:
  • time_from (datetime)

  • time_to (datetime)

  • volume_sold_MW (float | None)

  • volume_bought_MW (float | None)

  • energy_sell_price_per_MWh (float | None)

  • energy_buy_price_per_MWh (float | None)

energy_buy_price_per_MWh: float | None#
energy_sell_price_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].

classmethod round_bought_MW_to_nearest_kW(volume_bought_MW)#
classmethod round_sold_MW_to_nearest_kW(volume_sold_MW)#
time_from: datetime#
time_to: datetime#
volume_bought_MW: float | None#
volume_sold_MW: float | None#
class battery_optimizer.result.Error(*, request_id, errors)#

Bases: BaseModel

Parameters:
errors: list[str]#
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].

request_id: str#
class battery_optimizer.result.Imbalance(*, time_from, time_to, volume_sold_MW, volume_bought_MW, energy_price_per_MWh=999.0)#

Bases: BaseModel

Parameters:
energy_price_per_MWh: float#
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].

classmethod round_bought_MW_to_nearest_kW(volume_bought_MW)#
classmethod round_sold_MW_to_nearest_kW(volume_sold_MW)#
time_from: datetime#
time_to: datetime#
volume_bought_MW: float#
volume_sold_MW: float#
class battery_optimizer.result.IntradayBucket(*, max_volume_MW, price_per_MWh, volume_MW, to_market=True)#

Bases: BaseModel

Parameters:
max_volume_MW: float#
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].

price_per_MWh: float#
classmethod round_max_volume_MW_to_nearest_kW(max_volume_MW)#
classmethod round_price_per_MWh(price_per_MWh)#
classmethod round_volume_MW_to_nearest_kW(volume_MW)#
to_market: bool#
volume_MW: float#
class battery_optimizer.result.IntradayBuckets(*, intraday_sell, intraday_buy)#

Bases: BaseModel

Parameters:
intraday_buy: list[IntradayBucket]#
intraday_sell: list[IntradayBucket]#
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].

class battery_optimizer.result.MarketPositions(*, intraday, imbalance)#

Bases: BaseModel

Parameters:
imbalance: list[Imbalance] | DataFrame#
intraday: list[EnergyMarketContinuousPositions] | 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].

class battery_optimizer.result.Result(*, asset_id, request_id, battery_optimizer_commit_sha, user_id, request_creation_time, result_creation_time, request, market_positions, markets_optimized, markets_already_auctioned, soe, discharge_over_daily_cycle_limit_kWh=None, discharge_over_daily_cycle_limit_count=None, intraday_buckets=None, aggregated_intraday_buckets=None, trace=None, pulp_solver_variables_values_delta_false=None, pulp_solver_variables_values_delta_true=None, optimizer_object=None)#

Bases: BaseModel

Parameters:
classmethod add_use_case_specific_soe_fields(solved_problem, soe, result)#

Hook method to add use-case specific SoE fields to the SoE DataFrame.

Args:

solved_problem (BatteryOptimizer): The solved optimization problem. soe (pd.DataFrame): The SoE DataFrame. result (pd.DataFrame): The result DataFrame of the solved problem.

Returns:

pd.DataFrame: The amended SoE DataFrame.

Parameters:
Return type:

DataFrame

static aggregate_intraday_buckets(buckets, direction)#

The function returns an aggregate of the passed intraday buckets for one delivery timestamp and one delivery direction. It checks if for a given price any volume needs to be traded. It returns for direction: ‘intraday_buy’: max price of all prices that need to be traded, else max of all passed prices ‘intraday_sell’: min price of all prices that need to be traded, else min of all passed prices

Args:

buckets (list[dict]): list of intraday buckets in dict direction (str): one of [‘intraday_buy’, ‘intraday_sell’]

Raises:

NotImplementedError: if direction isn’t one of [‘intraday_buy’, ‘intraday_sell’]

Returns:

IntradayBucket: _description_

Parameters:
Return type:

IntradayBucket

aggregated_intraday_buckets: Dict[datetime, IntradayBuckets] | None#
classmethod amend_result_dict(result_dict, solved_problem, delta=False)#

Amend the result dictionary with additional information.

Parameters:
  • result_dict: The result dictionary to amend.

  • solved_problem: The solved optimization problem.

  • delta: Whether to use delta values.

Returns:
  • The amended result dictionary.

Parameters:
Return type:

dict

asset_id: str | int#
battery_optimizer_commit_sha: str | None#
check_markets_already_auctioned()#
static compute_vwap_for_bucketed_prices_per_sp_and_price_side(buckets, price_col, energy_col)#
Parameters:
Return type:

float

classmethod create_dataframe_from_solved_problem(solved_problem, delta=False)#
Parameters:

solved_problem (BatteryOptimizer)

classmethod create_result_from_solved_problem(solved_problem, delta=False)#

Create Result object from solved BatteryOptimizer problem.

Parameters:
  • solved_problem: The solved optimization problem.

  • markets: Markets that we want to compute the objective for, especially for the commercial results.

Parameters:

solved_problem (BatteryOptimizer)

discharge_over_daily_cycle_limit_count: dict | None#
discharge_over_daily_cycle_limit_kWh: dict | None#
ensure_requested_markets_are_sensible()#
ensure_soe_target_within_bounds()#
classmethod get_base_result_dict(solved_problem)#

Create a dictionary with the base result data.

Parameters:
  • solved_problem: The solved optimization problem.

Parameters:

solved_problem (BatteryOptimizer)

Return type:

dict

classmethod get_capacity_market_positions(solved_problem, result, capacity_product)#
Parameters:
Return type:

list[CapacityMarketPositions]

classmethod get_imbalance_market_positions(solved_problem, result)#
Parameters:
Return type:

list[Imbalance]

classmethod get_intraday_buckets(solved_problem)#
Parameters:

solved_problem (BatteryOptimizer)

Return type:

tuple[Dict[datetime, IntradayBuckets], Dict[datetime, IntradayBuckets]]

classmethod get_intraday_market_positions(solved_problem, result, intraday_buckets)#

Create a list of intraday market positions.

Parameters:
  • solved_problem: The solved optimization problem.

  • result: The result DataFrame.

Parameters:
Return type:

list[EnergyMarketContinuousPositions]

classmethod get_intraday_position_model()#

Hook method to return the class used for intraday market positions.

Return type:

type[EnergyMarketContinuousPositions]

classmethod get_market_positions(solved_problem, result, intraday_buckets)#

Create a dictionary with the market positions.

Parameters:
  • solved_problem: The solved optimization problem.

Parameters:
Return type:

MarketPositions

classmethod get_market_positions_for_day_ahead_product(solved_problem, result, day_ahead_product)#

Create a list of market positions for a specific day-ahead product.

Parameters:
  • solved_problem: The solved optimization problem.

  • result: The result DataFrame.

  • day_ahead_product: The day-ahead product to create market positions for.

Parameters:
Return type:

list[EnergyMarketAuctionedPositions]

static get_markets_optimized(solved_problem)#
Parameters:

solved_problem (BatteryOptimizer)

classmethod get_result_dict(solved_problem, delta=False)#
Parameters:

solved_problem (BatteryOptimizer)

classmethod get_soe(solved_problem, result)#
Parameters:

solved_problem (BatteryOptimizer)

Return type:

list[SoE]

classmethod get_soe_model()#

Hook method to return the class used for SoE records.

Return type:

type[SoE]

classmethod get_solved_problem_dataframe_additional_columns()#
intraday_buckets: Dict[datetime, IntradayBuckets] | None#
market_positions: MarketPositions#
markets_already_auctioned: Dict[datetime, set[str]]#
markets_optimized: set[str] | Dict[datetime, set[str]]#
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].

optimizer_object: str | None#
pulp_solver_variables_values_delta_false: list[dict] | None#
pulp_solver_variables_values_delta_true: list[dict] | None#
request: Request#
request_creation_time: datetime#
request_id: str#
result_creation_time: datetime#
soe: list[SoE] | DataFrame#
trace: Any#
user_id: str | int#
class battery_optimizer.result.SoE(*, time_from, time_to, soe_target, soe_target_kwh, max_charge_kW, max_discharge_kW, charge_power_kW, discharge_power_kW)#

Bases: BaseModel

Parameters:
charge_power_kW: float#
discharge_power_kW: float#
max_charge_kW: float#
max_discharge_kW: float#
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].

classmethod round_soe_target(soe_target)#
classmethod round_soe_target_kwh(soe_target_kwh)#
soe_target: float#
soe_target_kwh: float#
time_from: datetime#
time_to: datetime#
classmethod validate_charge_power_kW(charge_power_kW, values)#
classmethod validate_discharge_power_kW(discharge_power_kW, values)#