Add Time Series Fuel Cost Data
This how-to guide demonstrates how to add time-varying fuel costs to a thermal generator that uses a ThermalGenerationCost with a FuelCurve. This is useful when fuel prices vary over time, such as with natural gas prices that change throughout the day or across seasons.
Overview
This guide assumes you have already defined a System with a thermal generator (e.g., ThermalStandard) that has a ThermalGenerationCost containing a FuelCurve. The generator's FuelCurve must specify a heat rate curve (fuel consumption at different power outputs) and an initial scalar fuel cost value, which will be replaced with time series data.
To add time-varying fuel costs, you need to:
Create time series fuel cost data: Prepare your fuel price data as either
SingleTimeSeries(for simple time-varying data like historical prices) orDeterministic(for forecast windows used in day-ahead scheduling with rolling horizons).Attach the time series to the generator: Use the
set_fuel_cost!function to attach the time series data to the generator component. The component must already be added to the system before attaching time series.Verify and retrieve the data: Use
get_fuel_costto retrieve the time series data and verify it was attached correctly.
Key requirements:
- The generator must use a 
FuelCurve(not aCostCurve) in itsThermalGenerationCostto enable time series fuel costs - Time series resolution should match your simulation resolution (e.g., Hour(1) for hourly simulations)
 - Fuel cost units should be in $/GJ (or $/MBtu, etc.) and heat rate in GJ/MWh (or MBtu/MWh); their product gives the effective cost in $/MWh
 
Step 1: Create Time Series Fuel Cost Data
Create time series data representing fuel costs that vary throughout the day. This example uses hourly natural gas prices with SingleTimeSeries:
julia> # Define the initial time and resolution initial_time = DateTime("2024-01-01T00:00:00")2024-01-01T00:00:00julia> resolution = Hour(1)1 hourjulia> # Create hourly fuel cost data for 24 hours # Prices are higher during peak hours (midday to early evening) and lower at night fuel_cost_data = [ 4.5, 4.3, 4.2, 4.1, 4.2, 4.5, # 00:00 - 05:00 (low overnight prices) 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, # 06:00 - 11:00 (morning ramp) 8.0, 8.0, 7.8, 7.8, 7.5, 7.0, # 12:00 - 17:00 (afternoon peak) 6.5, 6.0, 5.5, 5.0, 4.8, 4.6, # 18:00 - 23:00 (evening decline) ]24-element Vector{Float64}: 4.5 4.3 4.2 4.1 4.2 4.5 5.0 5.5 6.0 6.5 ⋮ 7.8 7.5 7.0 6.5 6.0 5.5 5.0 4.8 4.6julia> # Create timestamps for each data point timestamps = collect(initial_time:resolution:(initial_time + Hour(length(fuel_cost_data) - 1)))24-element Vector{Dates.DateTime}: 2024-01-01T00:00:00 2024-01-01T01:00:00 2024-01-01T02:00:00 2024-01-01T03:00:00 2024-01-01T04:00:00 2024-01-01T05:00:00 2024-01-01T06:00:00 2024-01-01T07:00:00 2024-01-01T08:00:00 2024-01-01T09:00:00 ⋮ 2024-01-01T15:00:00 2024-01-01T16:00:00 2024-01-01T17:00:00 2024-01-01T18:00:00 2024-01-01T19:00:00 2024-01-01T20:00:00 2024-01-01T21:00:00 2024-01-01T22:00:00 2024-01-01T23:00:00julia> # Create a TimeArray with timestamps and data time_array = TimeArray(timestamps, fuel_cost_data)24×1 TimeSeries.TimeArray{Float64, 1, Dates.DateTime, Vector{Float64}} 2024-01-01T00:00:00 to 2024-01-01T23:00:00 ┌─────────────────────┬─────┐ │ │ A │ ├─────────────────────┼─────┤ │ 2024-01-01T00:00:00 │ 4.5 │ │ 2024-01-01T01:00:00 │ 4.3 │ │ 2024-01-01T02:00:00 │ 4.2 │ │ 2024-01-01T03:00:00 │ 4.1 │ │ 2024-01-01T04:00:00 │ 4.2 │ │ 2024-01-01T05:00:00 │ 4.5 │ │ 2024-01-01T06:00:00 │ 5.0 │ │ 2024-01-01T07:00:00 │ 5.5 │ │ ⋮ │ ⋮ │ │ 2024-01-01T17:00:00 │ 7.0 │ │ 2024-01-01T18:00:00 │ 6.5 │ │ 2024-01-01T19:00:00 │ 6.0 │ │ 2024-01-01T20:00:00 │ 5.5 │ │ 2024-01-01T21:00:00 │ 5.0 │ │ 2024-01-01T22:00:00 │ 4.8 │ │ 2024-01-01T23:00:00 │ 4.6 │ └─────────────────────┴─────┘ 9 rows omittedjulia> # Create a SingleTimeSeries from the TimeArray fuel_cost_timeseries = SingleTimeSeries(; name = "fuel_cost", data = time_array, )SingleTimeSeries("fuel_cost", 24×1 TimeSeries.TimeArray{Float64, 1, Dates.DateTime, Vector{Float64}} 2024-01-01T00:00:00 to 2024-01-01T23:00:00, Dates.Millisecond(3600000), nothing, InfrastructureSystems.InfrastructureSystemsInternal(Base.UUID("a4a8b398-c728-4710-8649-e5370ea22805"), nothing, nothing, nothing))
Step 2: Attach Time Series to the Generator
Use the set_fuel_cost! function to attach the time series data to your previously defined System and generator (e.g., ThermalStandard):
julia> # Add the time series fuel cost to the generator set_fuel_cost!(sys, generator, fuel_cost_timeseries)FuelCurve: value_curve: PiecewisePointCurve (a type of InputOutputCurve) where function is: piecewise linear y = f(x) connecting points: (x = 100.0, y = 7.0) (x = 200.0, y = 8.0) (x = 300.0, y = 9.5) power_units: UnitSystem.NATURAL_UNITS = 2 fuel_cost: StaticTimeSeriesKey(SingleTimeSeries, "fuel_cost", Dates.DateTime("2024-01-01T00:00:00"), Dates.Millisecond(3600000), 24, Dict{String, Any}()) startup_fuel_offtake: LinearCurve (a type of InputOutputCurve) where function is: f(x) = 0.0 x + 0.0 vom_cost: LinearCurve (a type of InputOutputCurve) where function is: f(x) = 0.0 x + 0.0
Step 3: Verify and Retrieve Time Series Data
Now the generator has time-varying fuel costs. You can retrieve the time series data:
julia> # Get the fuel cost time series starting at the initial time fuel_forecast = get_fuel_cost(generator; start_time = initial_time)24×1 TimeSeries.TimeArray{Float64, 1, Dates.DateTime, Vector{Float64}} 2024-01-01T00:00:00 to 2024-01-01T23:00:00 ┌─────────────────────┬─────┐ │ │ A │ ├─────────────────────┼─────┤ │ 2024-01-01T00:00:00 │ 4.5 │ │ 2024-01-01T01:00:00 │ 4.3 │ │ 2024-01-01T02:00:00 │ 4.2 │ │ 2024-01-01T03:00:00 │ 4.1 │ │ 2024-01-01T04:00:00 │ 4.2 │ │ 2024-01-01T05:00:00 │ 4.5 │ │ 2024-01-01T06:00:00 │ 5.0 │ │ 2024-01-01T07:00:00 │ 5.5 │ │ ⋮ │ ⋮ │ │ 2024-01-01T17:00:00 │ 7.0 │ │ 2024-01-01T18:00:00 │ 6.5 │ │ 2024-01-01T19:00:00 │ 6.0 │ │ 2024-01-01T20:00:00 │ 5.5 │ │ 2024-01-01T21:00:00 │ 5.0 │ │ 2024-01-01T22:00:00 │ 4.8 │ │ 2024-01-01T23:00:00 │ 4.6 │ └─────────────────────┴─────┘ 9 rows omittedjulia> # Display the first few values first(TimeSeries.values(fuel_forecast), 6)6-element Vector{Float64}: 4.5 4.3 4.2 4.1 4.2 4.5
You can also query for a specific time window:
julia> # Get fuel costs for a specific 12-hour period starting at 6 AM morning_time = DateTime("2024-01-01T06:00:00")2024-01-01T06:00:00julia> fuel_forecast_morning = get_fuel_cost(generator; start_time = morning_time, len = 12)12×1 TimeSeries.TimeArray{Float64, 1, Dates.DateTime, Vector{Float64}} 2024-01-01T06:00:00 to 2024-01-01T17:00:00 ┌─────────────────────┬─────┐ │ │ A │ ├─────────────────────┼─────┤ │ 2024-01-01T06:00:00 │ 5.0 │ │ 2024-01-01T07:00:00 │ 5.5 │ │ 2024-01-01T08:00:00 │ 6.0 │ │ 2024-01-01T09:00:00 │ 6.5 │ │ 2024-01-01T10:00:00 │ 7.0 │ │ 2024-01-01T11:00:00 │ 7.5 │ │ 2024-01-01T12:00:00 │ 8.0 │ │ 2024-01-01T13:00:00 │ 8.0 │ │ 2024-01-01T14:00:00 │ 7.8 │ │ 2024-01-01T15:00:00 │ 7.8 │ │ 2024-01-01T16:00:00 │ 7.5 │ │ 2024-01-01T17:00:00 │ 7.0 │ └─────────────────────┴─────┘julia> # Display these values TimeSeries.values(fuel_forecast_morning)12-element Vector{Float64}: 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.0 7.8 7.8 7.5 7.0
See Also
- Add an Operating Cost - General guide for adding operational costs
 - Parse Time Series Data from .csv files - How to load time series from CSV files
 - Working with Time Series Data - Tutorial on time series data in PowerSystems
 ThermalGenerationCost- API reference for thermal generation costsFuelCurve- API reference for fuel curves