diff --git a/src/ElectricityMarketData.jl b/src/ElectricityMarketData.jl index 31d3d94..e474c84 100644 --- a/src/ElectricityMarketData.jl +++ b/src/ElectricityMarketData.jl @@ -21,7 +21,15 @@ export ElectricityMarket, get_day_ahead_lmp_raw_data, get_day_ahead_lmp, get_timezone, - ZonedDateTime + ZonedDateTime, + get_load_forecast_raw_data, + get_load_forecast, + get_load_raw_data, + get_load, + load_data_types, + real_time_lmp_data_types, + real_time_lmp_frequency, + load_forecast_data_types # general include("helpers/http_helper.jl") diff --git a/src/electricity_market.jl b/src/electricity_market.jl index aca71f0..5bcc913 100644 --- a/src/electricity_market.jl +++ b/src/electricity_market.jl @@ -12,7 +12,7 @@ abstract type ElectricityMarket end Return a vector of all available electricity markets. """ function list_markets()::Vector{Symbol} - return [:MisoMarket] + return [:MisoMarket, :PjmMarket] end """ @@ -29,7 +29,7 @@ Ex: ``` """ function available_time_series(market::ElectricityMarket)::Vector{NamedTuple} - @warn "No time series registered for $(market)" + @info "No time series registered for $(market)" return Vector{NamedTuple}() end @@ -52,7 +52,14 @@ function ZonedDateTime(date::DateTime, market::ElectricityMarket)::ZonedDateTime end """ - get_real_time_lmp_raw_data(market::ElectricityMarket, start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString=tempdir()) + get_real_time_lmp_raw_data(market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString=tempdir(), + locations::Vector{T} = [], + data_type::Symbol=:verified, # :verified, :unverified + frequency::Symbol=:hourly, # :hourly, :fivemin + ) Download raw data for Real-Time (RT) Locational Marginal Price (LMP) for the given `market` and `start_date` to `end_date` and save it in `folder`. """ @@ -61,7 +68,10 @@ function get_real_time_lmp_raw_data( start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString = tempdir(), -)::Nothing + locations::Vector{T} = [], + data_type::Symbol = :verified, + frequency::Symbol = :hourly, +)::Nothing where {T} throw(MethodError(get_real_time_lmp_raw_data, (market, start_date, end_date))) end @@ -70,18 +80,31 @@ function get_real_time_lmp_raw_data( start_date::DateTime, end_date::DateTime; folder::AbstractString = tempdir(), -)::Nothing - @warn "Converting DateTime to ZonedDateTime using the timezone of $(market)" + locations::Vector{T} = [], + data_type::Symbol = :verified, + frequency::Symbol = :hourly, +)::Nothing where {T} + @info "Converting DateTime to ZonedDateTime using the timezone of $(market)" get_real_time_lmp_raw_data( market, ZonedDateTime(start_date, get_timezone(market)), ZonedDateTime(end_date, get_timezone(market)); folder = folder, + locations = locations, + data_type = data_type, + frequency = frequency, ) end """ - get_real_time_lmp(market::ElectricityMarket, start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString=tempdir()) :: Tables.table + get_real_time_lmp(market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString=tempdir(), + locations::Vector{T} = [], + data_type::Symbol=:verified, # :verified, :unverified + frequency::Symbol=:hourly, # :hourly, :fivemin + ) :: Tables.table Return a table with Real-Time (RT) Locational Marginal Price (LMP) data for the given `market` and `start_date` to `end_date`. If the data is not available, download it and save it in `folder`. @@ -91,7 +114,10 @@ function get_real_time_lmp( start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString = tempdir(), -) + locations::Vector{T} = [], + data_type::Symbol = :verified, + frequency::Symbol = :hourly, +) where {T} throw(MethodError(get_real_time_lmp, (market, start_date, end_date))) end @@ -100,18 +126,62 @@ function get_real_time_lmp( start_date::DateTime, end_date::DateTime; folder::AbstractString = tempdir(), -) - @warn "Converting DateTime to ZonedDateTime using the timezone of $(market)" + locations::Vector{T} = [], + data_type::Symbol = :verified, + frequency::Symbol = :hourly, +) where {T} + @info "Converting DateTime to ZonedDateTime using the timezone of $(market)" get_real_time_lmp( market, ZonedDateTime(start_date, get_timezone(market)), ZonedDateTime(end_date, get_timezone(market)); folder = folder, + locations = locations, + data_type = data_type, ) end """ - get_day_ahead_lmp_raw_data(market::ElectricityMarket, start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString=tempdir()) + real_time_lmp_data_types(market::ElectricityMarket) :: Vector{Symbol} + +Return a vector of available Real-Time (RT) Locational Marginal Price (LMP) data types for the given `market`. + +Ex: +``` +[ + :verified, + :unverified, +] +``` +""" +function real_time_lmp_data_types(market::ElectricityMarket)::Vector{Symbol} + throw(MethodError(real_time_lmp_data_types, (market,))) +end + +""" + real_time_lmp_frequency(market::ElectricityMarket) :: Vector{Symbol} + +Return a vector of available Real-Time (RT) Locational Marginal Price (LMP) frequencies for the given `market`. + +Ex: +``` +[ + :hourly, + :fivemin, +] +``` +""" +function real_time_lmp_frequency(market::ElectricityMarket)::Vector{Symbol} + throw(MethodError(real_time_lmp_frequency, (market,))) +end + +""" + get_day_ahead_lmp_raw_data(market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString=tempdir(), + locations::Vector{T} = [], + ) Download raw data for Day-Ahead (DA) Locational Marginal Price (LMP) for the given `market` and `start_date` to `end_date` and save it in `folder`. """ @@ -120,7 +190,8 @@ function get_day_ahead_lmp_raw_data( start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString = tempdir(), -)::Nothing + locations::Vector{T} = [], +)::Nothing where {T} throw(MethodError(get_day_ahead_lmp_raw_data, (market, start_date, end_date))) end @@ -129,18 +200,25 @@ function get_day_ahead_lmp_raw_data( start_date::DateTime, end_date::DateTime; folder::AbstractString = tempdir(), -)::Nothing - @warn "Converting DateTime to ZonedDateTime using the timezone of $(market)" + locations::Vector{T} = [], +)::Nothing where {T} + @info "Converting DateTime to ZonedDateTime using the timezone of $(market)" get_day_ahead_lmp_raw_data( market, ZonedDateTime(start_date, get_timezone(market)), ZonedDateTime(end_date, get_timezone(market)); folder = folder, + locations = locations, ) end """ - get_day_ahead_lmp(market::ElectricityMarket, start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString=tempdir()) :: Tables.table + get_day_ahead_lmp(market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString=tempdir(), + locations::Vector{T} = [], + ) :: Tables.table Return a table with Day-Ahead (DA) Locational Marginal Price (LMP) data for the given `market` and `start_date` to `end_date`. If the data is not available, download it and save it in `folder`. @@ -150,7 +228,8 @@ function get_day_ahead_lmp( start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString = tempdir(), -) + locations::Vector{T} = [], +) where {T} throw(MethodError(get_day_ahead_lmp, (market, start_date, end_date))) end @@ -159,12 +238,215 @@ function get_day_ahead_lmp( start_date::DateTime, end_date::DateTime; folder::AbstractString = tempdir(), -) - @warn "Converting DateTime to ZonedDateTime using the timezone of $(market)" + locations::Vector{T} = [], +) where {T} + @info "Converting DateTime to ZonedDateTime using the timezone of $(market)" get_day_ahead_lmp( market, ZonedDateTime(start_date, get_timezone(market)), ZonedDateTime(end_date, get_timezone(market)); folder = folder, + locations = locations, + ) +end + +""" + get_load_raw_data(market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString=tempdir(), + locations::Vector{T} = [], + data_type::Symbol=:metered, # :metered, :preliminary, :estimated + ) + +Download raw Load data for the given `market` and `start_date` to `end_date` and save it in `folder`. +""" +function get_load_raw_data( + market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString = tempdir(), + locations::Vector{T} = [], + data_type::Symbol = :metered, +)::Nothing where {T} + throw(MethodError(get_load_raw_data, (market, start_date, end_date))) +end + +function get_load_raw_data( + market::ElectricityMarket, + start_date::DateTime, + end_date::DateTime; + folder::AbstractString = tempdir(), + locations::Vector{T} = [], + data_type::Symbol = :metered, +)::Nothing where {T} + @info "Converting DateTime to ZonedDateTime using the timezone of $(market)" + get_load_raw_data( + market, + ZonedDateTime(start_date, get_timezone(market)), + ZonedDateTime(end_date, get_timezone(market)); + folder = folder, + locations = locations, + data_type = data_type, + ) +end + +""" + get_load(market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString=tempdir(), + locations::Vector{T} = [], + data_type::Symbol=:metered, # :metered, :preliminary, :estimated + ) :: Tables.table + +Return a table with Load data for the given `market` and `start_date` to `end_date`. +If the data is not available, download it and save it in `folder`. +""" +function get_load( + market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString = tempdir(), + locations::Vector{T} = [], + data_type::Symbol = :metered, +) where {T} + throw(MethodError(get_load, (market, start_date, end_date))) +end + +function get_load( + market::ElectricityMarket, + start_date::DateTime, + end_date::DateTime; + folder::AbstractString = tempdir(), + locations::Vector{T} = [], + data_type::Symbol = :metered, +) where {T} + @info "Converting DateTime to ZonedDateTime using the timezone of $(market)" + get_load( + market, + ZonedDateTime(start_date, get_timezone(market)), + ZonedDateTime(end_date, get_timezone(market)); + folder = folder, + locations = locations, + data_type = data_type, + ) +end + +""" + load_data_types(market::ElectricityMarket) :: Vector{Symbol} + +Return a vector of available Load data types for the given `market`. + +Ex: +``` +[ + :metered, + :preliminary, + :estimated, +] +``` +""" +function load_data_types(market::ElectricityMarket)::Vector{Symbol} + throw(MethodError(load_data_types, (market,))) +end + +""" + get_load_forecast_raw_data(market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString=tempdir(), + locations::Vector{T} = [], + data_type::Symbol=:fivemin # :fivemin, :7days + ) + +Download raw Load Forecast data for the given `market` and `start_date` to `end_date` and save it in `folder`. +""" +function get_load_forecast_raw_data( + market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString = tempdir(), + locations::Vector{T} = [], + data_type::Symbol = :fivemin, +)::Nothing where {T} + throw(MethodError(get_load_forecast_raw_data, (market, start_date, end_date))) +end + +function get_load_forecast_raw_data( + market::ElectricityMarket, + start_date::DateTime, + end_date::DateTime; + folder::AbstractString = tempdir(), + locations::Vector{T} = [], + data_type::Symbol = :fivemin, +)::Nothing where {T} + @info "Converting DateTime to ZonedDateTime using the timezone of $(market)" + get_load_forecast_raw_data( + market, + ZonedDateTime(start_date, get_timezone(market)), + ZonedDateTime(end_date, get_timezone(market)); + folder = folder, + locations = locations, + data_type = data_type, ) end + +""" + get_load_forecast(market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString=tempdir(), + locations::Vector{T} = [], + data_type::Symbol=:fivemin # :fivemin, :7days + ) :: Tables.table + +Return a table with Load Forecast data for the given `market` and `start_date` to `end_date`. +If the data is not available, download it and save it in `folder`. +""" +function get_load_forecast( + market::ElectricityMarket, + start_date::ZonedDateTime, + end_date::ZonedDateTime; + folder::AbstractString = tempdir(), + locations::Vector{T} = [], + data_type::Symbol = :fivemin, +) where {T} + throw(MethodError(get_load_forecast, (market, start_date, end_date))) +end + +function get_load_forecast( + market::ElectricityMarket, + start_date::DateTime, + end_date::DateTime; + folder::AbstractString = tempdir(), + locations::Vector{T} = [], + data_type::Symbol = :fivemin, +) where {T} + @info "Converting DateTime to ZonedDateTime using the timezone of $(market)" + get_load_forecast( + market, + ZonedDateTime(start_date, get_timezone(market)), + ZonedDateTime(end_date, get_timezone(market)); + folder = folder, + locations = locations, + data_type = data_type, + ) +end + +""" + load_forecast_data_types(market::ElectricityMarket) :: Vector{Symbol} + +Return a vector of available Load Forecast data types for the given `market`. + +Ex: +``` +[ + :fivemin, + :7days, +] +``` +""" +function load_forecast_data_types(market::ElectricityMarket)::Vector{Symbol} + throw(MethodError(load_forecast_data_types, (market,))) +end diff --git a/src/miso/miso_market.jl b/src/miso/miso_market.jl index 79d95d5..bf18421 100644 --- a/src/miso/miso_market.jl +++ b/src/miso/miso_market.jl @@ -63,6 +63,7 @@ function get_real_time_lmp_raw_data( start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString = tempdir(), + kwargs..., # additional keyword arguments - to be extended in the future )::Nothing _get_raw_data( market, @@ -86,6 +87,7 @@ function get_day_ahead_lmp_raw_data( start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString = tempdir(), + kwargs..., # additional keyword arguments - to be extended in the future )::Nothing _get_raw_data( market, @@ -110,6 +112,7 @@ function get_real_time_lmp( start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString = tempdir(), + kwargs..., # additional keyword arguments - to be extended in the future ) return _get_data( market, @@ -134,6 +137,7 @@ function get_day_ahead_lmp( start_date::ZonedDateTime, end_date::ZonedDateTime; folder::AbstractString = tempdir(), + kwargs..., # additional keyword arguments - to be extended in the future ) return _get_data( market, diff --git a/src/pjm/pjm_market.jl b/src/pjm/pjm_market.jl index 4a7e2cd..228ca1b 100644 --- a/src/pjm/pjm_market.jl +++ b/src/pjm/pjm_market.jl @@ -66,6 +66,7 @@ function get_pjm_lmp_raw_data( end_date::ZonedDateTime; folder::AbstractString = tempdir(), download::Bool = true, + kwargs..., # additional keyword arguments - to be extended in the future ) url_function = get_url_function(market, series_name) @@ -114,6 +115,7 @@ function get_real_time_lmp( end_date::ZonedDateTime; folder::AbstractString = tempdir(), download::Bool = false, + kwargs..., # additional keyword arguments - to be extended in the future ) return get_pjm_lmp_raw_data( market, @@ -122,6 +124,7 @@ function get_real_time_lmp( end_date; folder = folder, download = download, + kwargs..., ) end @@ -137,6 +140,7 @@ function get_day_ahead_lmp( end_date::ZonedDateTime; folder::AbstractString = tempdir(), download::Bool = false, + kwargs..., # additional keyword arguments - to be extended in the future ) return get_pjm_lmp_raw_data( market, @@ -145,5 +149,6 @@ function get_day_ahead_lmp( end_date; folder = folder, download = download, + kwargs..., ) end diff --git a/test/electricity_market.jl b/test/electricity_market.jl index 4b22c6d..4cb84e5 100644 --- a/test/electricity_market.jl +++ b/test/electricity_market.jl @@ -86,5 +86,77 @@ ZonedDateTime(DateTime("2021-01-01T00:00:00"), tz"UTC"), ) end + + @testset "get_load_raw_data" begin + @test_throws MethodError get_load_raw_data( + market, + DateTime("2021-01-01T00:00:00"), + DateTime("2021-01-01T00:00:00"), + ) + + @test_throws MethodError get_load_raw_data( + market, + ZonedDateTime(DateTime("2021-01-01T00:00:00"), tz"UTC"), + ZonedDateTime(DateTime("2021-01-01T00:00:00"), tz"UTC"), + ) + end + + @testset "get_load" begin + @test_throws MethodError get_load( + market, + DateTime("2021-01-01T00:00:00"), + DateTime("2021-01-01T00:00:00"), + ) + + @test_throws MethodError get_load( + market, + ZonedDateTime(DateTime("2021-01-01T00:00:00"), tz"UTC"), + ZonedDateTime(DateTime("2021-01-01T00:00:00"), tz"UTC"), + ) + end + + @testset "get_load_forecast_raw_data" begin + @test_throws MethodError get_load_forecast_raw_data( + market, + DateTime("2021-01-01T00:00:00"), + DateTime("2021-01-01T00:00:00"), + ) + + @test_throws MethodError get_load_forecast_raw_data( + market, + ZonedDateTime(DateTime("2021-01-01T00:00:00"), tz"UTC"), + ZonedDateTime(DateTime("2021-01-01T00:00:00"), tz"UTC"), + ) + end + + @testset "get_load_forecast" begin + @test_throws MethodError get_load_forecast( + market, + DateTime("2021-01-01T00:00:00"), + DateTime("2021-01-01T00:00:00"), + ) + + @test_throws MethodError get_load_forecast( + market, + ZonedDateTime(DateTime("2021-01-01T00:00:00"), tz"UTC"), + ZonedDateTime(DateTime("2021-01-01T00:00:00"), tz"UTC"), + ) + end + + @testset "real_time_lmp_data_types" begin + @test_throws MethodError real_time_lmp_data_types(market) + end + + @testset "real_time_lmp_frequency" begin + @test_throws MethodError real_time_lmp_frequency(market) + end + + @testset "load_data_types" begin + @test_throws MethodError load_data_types(market) + end + + @testset "load_forecast_data_types" begin + @test_throws MethodError load_forecast_data_types(market) + end end end