Storage Level Output
Contents
Overview | Columns | Configuration | Assumptions | Examples | See Also
Overview
File: storage_level.csv
storage_level.csv records the state of charge (energy or mass stored) of every storage component in the system at the end of each representative time step. Only assets that contain a Storage component (e.g., Battery, GasStorage, HydroReservoir) produce rows in this file.
The storage level represents how much commodity is held inside the storage at a given moment. Tracking this over time reveals charging and discharging patterns, how often storage reaches its capacity limits, and whether inter-period energy carry-over occurs.
storage_level.csv contains only the representative time steps used in the optimization. If time-domain reduction (TDR) is active, this is a subset of the full year. Enable WriteFullTimeseries = true in case_settings.json to also write full-year storage levels. See Full Time Series Output.
Columns
| Column | Type | Description |
|---|---|---|
commodity | String | Commodity type stored (e.g., Electricity, NaturalGas, Hydrogen) |
zone | String | Zone (location) where the storage asset is installed |
resource_id | String | Unique identifier of the parent asset (e.g., battery_SE) |
component_id | String | Unique identifier of the storage component (e.g., battery_SE_storage) |
resource_type | String | Asset type of the parent asset (e.g., Battery, GasStorage, HydroReservoir) |
component_type | String | Type of the storage component (e.g., Storage{Electricity}, Storage{NaturalGas}) |
variable | String | Always "storage_level" |
time | Int | Representative time step index (1-based integer, matches time in other output files) |
value | Float64 | Amount of commodity currently stored, in the commodity's native units (MWh for electricity, tonnes for mass-based commodities) |
Configuration
| Setting | File | Default | Effect |
|---|---|---|---|
OutputLayout (or OutputLayout.StorageLevel) | macro_settings.json | "long" | Set to "wide" to pivot time steps into columns. |
WriteFullTimeseries | case_settings.json | false | When true and TDR is active, also write full-year storage levels to full_time_series/storage_level.csv. |
Assumptions
- End-of-timestep values. The
valueat time steptis the state of charge at the end of that time step, after all flows (charging and discharging) at stepthave been processed. - Units. Storage level is reported in the native units of the stored commodity. For electricity, this is MWh. For gas or biomass, this is tonnes. Ensure your capacity and rate inputs use consistent units.
- Cyclic storage constraint. By default, Macro enforces a cyclic storage constraint within each representative period: the state of charge at the end of the last time step in a representative period must equal the state of charge at the start of the first time step of that period. This is sometimes called the "wrap-around" or "periodic boundary" condition.
- Long-Duration Storage. Assets modeled as
LongDurationStoragerelax the within-period cyclic constraint and allow energy carry-over between representative periods. See Storage for details. - Capacity limit. The storage level is bounded above by the
storage_capacityof the storage component. The level will never exceed the installed storage capacity. - Multi-period models. In multi-period (planning) models, each
results_period_N/directory contains storage levels for the representative time steps of period N. Between-period carry-over (for Long-Duration Storage) is handled internally by the model.
Examples
Default Long Format (example rows)
| commodity | zone | resource_id | component_id | resource_type | component_type | variable | time | value |
|---|---|---|---|---|---|---|---|---|
| Electricity | SE | battery_SE | battery_SE_storage | Battery | Storage{Electricity} | storage_level | 1 | 0.0 |
| Electricity | SE | battery_SE | battery_SE_storage | Battery | Storage{Electricity} | storage_level | 2 | 85.3 |
| Electricity | SE | battery_SE | battery_SE_storage | Battery | Storage{Electricity} | storage_level | 3 | 200.0 |
| Electricity | SE | battery_SE | battery_SE_storage | Battery | Storage{Electricity} | storage_level | 4 | 112.7 |
Wide Format (OutputLayout.StorageLevel = "wide")
| commodity | zone | resource_id | component_id | resource_type | component_type | variable | 1 | 2 | 3 | 4 | … |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Electricity | SE | battery_SE | battery_SE_storage | Battery | Storage{Electricity} | storage_level | 0.0 | 85.3 | 200.0 | 112.7 | … |
Reading and Plotting Storage Levels
using CSV, DataFrames, Plots
storage = CSV.read("results/storage_level.csv", DataFrame)
# Filter to a specific asset
battery_SE = filter(r -> r.resource_id == "battery_SE", storage)
# Plot state of charge over representative time steps
plot(battery_SE.time, battery_SE.value,
xlabel="Time Step", ylabel="Storage Level (MWh)",
title="Battery SE State of Charge", legend=false)See Also
- Outputs Overview — overview of all output files and settings
- Flows Output — charge and discharge flows associated with storage
- Full Time Series Output — 8760-hour expanded storage levels
- Time Weights Output — weights for interpreting representative time steps
- Storage — storage component parameters and types (including Long-Duration Storage)
- Time Data — representative periods and cyclic storage constraint