battery_optimizer.uk.legacy.basic_problem#

Classes

BasicProblem(optimization_description, data, ...)

class battery_optimizer.uk.legacy.basic_problem.BasicProblem(optimization_description, data, soc, battery_parameters, strategy, kwargs)#

Bases: object

add_PV_goes_either_to_batt_or_grid(problem, variables, PV_to_batt, PV_to_grid, period_in_h)#

Adds the constraint that the PV goes either in charging the battery or exported to the grid PV can also export to the grid and charge the battery at the same time

add_SOC_target_EV(problem, soc_df)#

Ensuring the battery reaches SOC target at the end of each charging session

add_all_PV_goes_to_the_grid_unconstrained_constraint(problem, variables)#

All PV production is exported to the grid unconstrained

add_battery_charges_either_via_PV_or_grid_constraint(problem, variables, PV_to_batt='PV_to_batt', grid_to_batt='grid_to_batt')#

Adds the constraint that at a given time, battery can charge either via PV or the grid but not from both at the same time

add_charge_bound_from_PRL_capacity_constraint(problem, variables)#
add_constant_PRL_capacity_during_PRL_Period_for_EV(problem, variables, data)#

During the PRL period, the PRL capacity must be constant. Remark: data is updated for each optimization.

For instance, if the optimization is run day-by-day, only data for one day is included here. More specifically, only the period when EV is available is taken into consideration, i.e., from arrival_time to departure_time

add_constant_power_per_block(problem, variables, data, col_block_indicator, col_const_power)#

During each block, provided power must be constant. The provided data should include UNIQUE block indicator for each block. Example: for a 4h-block product, the overall optimization is run for 720h, there must be 720/4 = 180 unique indicators.

Remark: data is updated for each optimization.

For instance, if the optimization is run day-by-day, only data for one day is included here. More specifically, only the period when EV is available is taken into consideration, i.e., from arrival_time to departure_time

add_constraint_to_bool_decision_variable(problem, variables, bool_var, decision_var, var_name_iter_str='')#

decision_var can only be positive, if the bool_var is 1.

add_constraint_to_decision_variable(problem, variables, var_name, var_value=0, var_name_iter_str='', var_filter=None)#

general function to add constraints to power decision variables

TODO: Simpplify and improve constraint name, e.g. additional argument for constraint name and iterate across index + variable name in here

add_constraint_via_expression_series_to_problem(problem, variables, name_str, expression_series, relation_symbol, const_value=0)#

this is an alternative method to add constraints to problem. This method offers a convienient/standard way to add some complicated constraints to a problem.

This applys to situations, when you need to add some equations with one side a constant value and the other side as a pd.Series For instance, it can be commonly used for power/energy balance equation.

add_continuous_discharge_during_triad_constraint(problem, variables)#

During the Triad time the discharge must be as constant as possible over the different settlement periods.

add_grid_export_constraint(problem, variables)#

Adds the constraint that the total power exported to the grid is smaller then a certain threshold

add_grid_import_constraint(problem, variables)#

Adds the constraint that the total power imported from the grid is smaller then a certain threshold

add_imbalance_marketing_when_portfolio_is_too_long_or_too_short_constraint(problem, variables, portfolio_is_long, portfolio_is_short)#

The residual shape is marketed to the imbalance market outside the threshold (too long or short)

add_intraday_marketing_when_portfolio_is_not_too_long_or_too_short_constraint(problem, variables, portfolio_is_long, portfolio_is_short)#

The residual shape is marketed to the intraday market withing the threshold (not too long or short)

add_limit_cycles_constraint(problem, variables, period_in_h, num_cycles)#

Don’t cycle more than ‘num_cycles’ times over the optimization horizon.

add_market_minimum_over_4h_uk_block_constraint(problem, variables, soc_df, t_, idx, var)#
add_maximum_soc_during_dc_high_constraint(problem, soc_df)#

Only dc high considered

add_minimum_dc_charge_energy(problem, variables, soc_df)#

During dc low, the energy stored in the battery must at least enable a discharge during 15min of the contracted quantity.

add_minimum_soc_during_dc_low_constraint(problem, soc_df)#

Only dc low considered

add_minimum_soc_sp_before_dc_and_during_dc_constraint(problem, variables, soc_df)#

Only dc low considered TODO: generalize to dc high and low

add_no_charge_and_discharge_simultaneously_constraint(problem, variables, charge_name=('isCharging', 'charge'), discharge_name=('isDischarging', 'discharge'))#

despite the method name, this is used to constraint that two boolean variables cannot be non-zero at the same time

add_soc_physical_constraint(problem, variables, soc_df)#

At any time, soc_min <= soc <= soc_max must be respected.

add_soc_physical_limit_only_when_action_is_taken_constraint(problem, variables, soc_df)#
  1. when deciding to charge or discharge the action taken should keep the soc between the min and max physically allowed

  2. when we don’t charge or discharge we don’t impose any min/max to avoid taking the risk that the algo compensate

when the initial soc is out of the min max allowed (the soc level measured varies also when nobody does something and can be for short times out of the min max)

evaluate_problem_variables()#

Computes the soc per timestamp from the problem variables after the problem was solved.

get_name_iter(variables, var_name_iter_str='')#

Get the name iteration label for the constraints/variables

get_soc(variables)#

This is a general method to get the SoC of each problem, self.soc is the initial SoC (the SoC at the first timestamp) The energy delta is calculated based on the energy transferred into/out of the battery. Depends on the specific use cases, some parameters might be 0, hence, irrelavant.

get_variables()#

Input: pandas datetimeindex timestamps. Output: pandas dataframe of the decision variables with index timestamps, columns ‘charge’, ‘dicharge’, ‘isCharging’, ‘isDischarging’.

solve_opt()#

Solve the given problem and raise an exception in case of a non optimal solution.