Storage Unit
Use the StorageUnit class to represent a storage unit with a given active power capacity (p_nom), in order to optimize its active power over time (StorageUnitOptimizationDynamicResults.p). The storage unit's energy capacity is determined by its max_hours in conjunction with p_nom.
Use the ExtendableStorageUnit class to represent a hypothetical storage unit with an active power capacity that is flexible, in order to also optimize the active power capacity (ExtendableStorageUnitOptimizationStaticResults.p_nom_opt).
API Reference
StorageUnit and ExtendableStorageUnit both inherit from the BaseStorageUnit parent class.
BaseStorageUnit
Bases: PNomExtendableComponent[T]
Storage units enable inter-temporal energy shifting with fixed nominal-energy-to-nominal-power ratio.
PyPSA user guide for this component.
bus: str = Field(min_length=1)
Name of bus to which storage unit is attached.
control: ControlType = 'PQ'
P,Q,V control strategy for PF, must be "PQ", "PV" or "Slack".
p_nom_extendable: bool
Switch to allow capacity p_nom to be extended in optimisation.
p_min_pu: float | Series[T] = Field(default=(-1.0), ge=(-1.0), le=1.0)
The minimum output for each snapshot per unit of p_nom for the optimisation. Negative sign implies storing mode withdrawing power from bus.
p_max_pu: float | Series[T] = Field(default=1.0, ge=(-1.0), le=1.0)
The maximum output for each snapshot per unit of p_nom for the optimisation. Positive sign implies discharging mode injecting power into bus.
p_set: float | Series[T] | None = None
Active power set point (for power flow only)
q_set: float | Series[T] = 0.0
Reactive power set point (for power flow only)
p_dispatch_set: float | Series[T] | None = None
Active power dispatch set point (for optimisation only)
p_store_set: float | Series[T] | None = None
Active power charging set point (for optimisation only)
sign: SignType = +1
Sign denoting the orientation of the dispatch variable.
carrier: str | None = Field(default=None, min_length=1)
Prime mover energy carrier (e.g. coal, gas, wind, solar); required for global constraints on primary energy in optimisation
spill_cost: float | Series[T] = 0.0
Cost of spilling 1 MWh
marginal_cost: float | Series[T] = Field(default=0.0, ge=0.0)
Marginal cost of production (discharge) of 1 MWh.
marginal_cost_quadratic: float | Series[T] = Field(default=0.0, ge=0.0)
Quadratic marginal cost of production (discharge) of 1 MWh.
marginal_cost_storage: float | Series[T] = Field(default=0.0, ge=0.0)
Marginal cost of energy storage of 1 MWh for one hour.
active: bool = True
Whether to consider the component in optimisation or not.
build_year: int | None = None
Build year.
lifetime: float | None = Field(default=None, gt=0.0)
Lifetime.
state_of_charge_initial: float = Field(default=0.0, ge=0.0, le=1.0)
State of charge before the snapshots in the optimisation.
state_of_charge_initial_per_period: bool = False
Switch: if True, the state of charge at the beginning of an investment period is set to state_of_charge_initial.
state_of_charge_set: float | Series[T] | None = Field(default=None, ge=0.0, le=1.0)
State of charge set points for snapshots in the optimisation.
cyclic_state_of_charge: bool = False
Switch: if True, then state_of_charge_initial is ignored and the initial state of charge is set to the final state of charge for the group of snapshots in the optimisation (soc[-1] = soc[len(snapshots)-1]).
cyclic_state_of_charge_per_period: bool = False
Switch: if True, the cyclic constraints are applied to each investment period separately.
max_hours: float = Field(gt=0.0)
Maximum state of charge capacity in terms of hours at full output power capacity p_nom.
efficiency_store: float | Series[T] = Field(default=1.0, gt=0.0, le=1.0)
Efficiency of storage on the way into the storage.
efficiency_dispatch: float | Series[T] = Field(default=1.0, gt=0.0, le=1.0)
Efficiency of storage on the way out of the storage.
standing_loss: float | Series[T] = Field(default=0.0, ge=0.0)
Losses per hour to state of charge.
inflow: float | Series[T] = Field(default=0.0, ge=0.0)
Inflow to the state of charge (e.g. due to river inflow in hydro reservoir).
StorageUnit
Bases: BaseStorageUnit[T]
p_nom: float | None = Field(default=None, gt=0.0)
Nominal power for limits on p in optimisation.
ExtendableStorageUnit
Bases: BaseStorageUnit[T]
p_nom_mod: float = Field(default=0.0, ge=0.0)
Nominal power of the storage unit module. Introduces integer variables if set.
p_nom_min: float = Field(default=0.0, ge=0.0)
Minimum value of p_nom_opt.
p_nom_max: float | None = Field(default=None, gt=0.0)
Maximum value of p_nom_opt.
p_nom_set: float | None = Field(default=None, ge=0.0)
Set value of p_nom_opt.
capital_cost: float = Field(default=0.0, ge=0.0)
Fixed period costs of extending p_nom by 1 MW, including periodized investment costs and periodic fixed O&M costs (e.g. annuitized investment costs).
StorageUnitBaseDynamicResults
Bases: BaseDynamicResults
p: pandas.DataFrame
Active power at bus (positive if net generation).
StorageUnitOptimizationDynamicResults
Bases: StorageUnitBaseDynamicResults
p_dispatch: pandas.DataFrame
Active power dispatch at bus.
p_store: pandas.DataFrame
Active power charging at bus.
state_of_charge: pandas.DataFrame
State of charge as calculated by the optimisation.
spill: pandas.DataFrame
Spillage for each snapshot (e.g. hydro-dam letting water flow over the spillway without generating electricity).
mu_upper: pandas.DataFrame
Shadow price of upper p_nom limit.
mu_lower: pandas.DataFrame
Shadow price of lower p_nom limit.
mu_state_of_charge_set: pandas.DataFrame
Shadow price of fixed state of charge state_of_charge_set.
mu_energy_balance: pandas.DataFrame
Shadow price of storage consistency equations.
StorageUnitPfDynamicResults
StorageUnitNonlinearPfDynamicResults
Bases: StorageUnitPfDynamicResults
q: pandas.DataFrame
Reactive power (positive if net generation).