Main Parameters


storage_coupling object

The point at which the storage system is connected to the generation source. DC-Coupled systems are connected on the array side of the inverter. AC-Coupled systems are connected at the medium voltage bus, downstream of the solar inverter and medium voltage transformer. High voltage (HV) AC-Coupled systems are connected downstream of the high voltage transformer, but upstream of the gen-tie. Choose one of these options via the StorageCoupling enum:

pv_inputs object

A sub-model to allow for either a simple or detailed specification of the PV model inputs. See below.

Note: If using a non-Tyba generation profile, reference this.

storage_inputs object

A sub-model to handle the specification of storage model inputs. See below.

energy_prices object or list of floats

The energy prices used for storage dispatch optimization. This can either be a single energy timeseries or two energy timeseries (i.e corresponding to DA & RT markets).

Single energy timeseries

Input a list of prices. The prices should be ordered to align with the total term of all the batteries at the time interval.

Two energy timeseries

AncillaryEnergyPrices object

enable_grid_charge_year int

Optional

The start year to enable grid charging. This value is 1-indexed, which means to have grid charging start in year 1 (i.e immediately), enter 1. To start in year 2, enter 2. And so on.

ancillary_markets object

Optional

A sub-model to handle the specification of Ancillary Services market assumption inputs. See below.

import_limit list

Optional

The kW limit at the POI that the system can import from the grid. Sign convention is from the perspective of the system, so negative values should be used to represent an import limit. For example:

export_limit list

The kW limit at the POI that the system can export to the grid. Sign convention is from the perspective of the system, so positive values should be used to represent an export limit. For example:

class PVStorageModel(object):
    storage_coupling: StorageCoupling = field(metadata=StorageCoupling.__metadata__)
    pv_inputs: PVModel
    storage_inputs: StorageInputs
    energy_prices: t.Union[AncillaryEnergyPrices, t.List[float]]
    enable_grid_charge_year: t.Optional[int] = opt_field()
    ancillary_markets: t.Optional[AncillaryMarkets] = opt_field()
		import_limit: t.Optional[t.List[float]] = opt_field()
    export_limit: t.Optional[t.List[float]] = opt_field()

Sub-models

StorageCoupling

See above.

ac for AC-coupling

dc for DC-coupling

hv_ac for HV AC-coupling

class StorageCoupling(Enum):
    ac = 'ac'
    dc = 'dc'
		hv_ac = 'hv_ac'

StorageInputs

batteries list of objects

A sub-model to handle the specification of battery-specific model inputs. See below.

cycling_cost_adder float

Optional

A hurdle rate to add costs in the optimization framework to reduce cycling. This value is often set at around the Variable O&M cost or the expected cost of degradation.

annual_cycle_limit float

Optional

The maximum number of complete cycles per year. A cycle is measured as the throughput equivalent of the energy capacity fully charging and discharging.

window int

Optional

The number of intervals that the optimization framework has knowledge of constraints. The optimization is rolling and optimizes for each step with the benefit of foresight into the broader window.

step int

Optional

The number of intervals of a single optimization period.

flexible_solar bool

Optional - Only applicable to PV + Storage project. Included here for completeness

Whether or not to include Solar curtailment in Ancillary Services offers:

dart bool

Optional

Whether or not to include DA/RT co-optimization in the Energy Markets

duration_requirement_on_discharge bool

Optional

Whether ReserveMarket.duration_requirement applies to the entire reserve offer, or just the discharge side of the offer. ERCOT currently only constrains the discharge side. This means that if a BESS is offering to reduce the amount it is charging (rather than increasing the amount it is discharging) the offer will not be subject to the duration requirement.

class StorageInputs(object):
    batteries: t.List[Battery]
    cycling_cost_adder: t.Optional[float] = 0
    annual_cycle_limit: t.Optional[float] = opt_field()
    window: t.Optional[int] = opt_field()
    step: t.Optional[int] = opt_field()
    flexible_solar: t.Optional[bool] = opt_field()
    dart: t.Optional[bool] = opt_field()
		dam_annual_cycle_limit: t.Optional[float] = opt_field()
    no_virtual_trades: t.Optional[bool] = opt_field()
    initial_soe: t.Optional[float] = 0
    symmetric_reg: t.Optional[bool] = False
		duration_requirement_on_discharge: t.Optional[bool] = opt_field()

Battery

power_capacity float

The maximum usable capacity of the battery to draw power to charge (kW).

energy_capacity float

The maximum usable capacity of the battery to store energy (kWh).

charge_efficiency float

The percentage of energy stored for every kW of power drawn to charge.

discharge_efficiency float

The percentage of energy discharged for every kW of power drawn to discharge.

degradation_rate float