diff --git a/Project.toml b/Project.toml index a3cb3d5..3a5ffef 100644 --- a/Project.toml +++ b/Project.toml @@ -18,10 +18,10 @@ YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" Dates = "1" DataFrames = "1" DataStructures = "0.18" -InfrastructureSystems = "1" +InfrastructureSystems = "2" InteractiveUtils = "1" -PowerSimulations = "^0.27.1" -PowerSystems = "3" -TimeSeries = "0.23" +PowerSimulations = "^0.28" +PowerSystems = "4" +TimeSeries = "0.24" YAML = "0.4" julia = "1.6" diff --git a/src/get_data.jl b/src/get_data.jl index 2c0dc49..dab9b66 100644 --- a/src/get_data.jl +++ b/src/get_data.jl @@ -419,8 +419,7 @@ function _get_loads(system::PSY.System, sys::PSY.System) end get_base_power(system::PSY.System) = PSY.get_base_power(system) -get_base_power(results::PSI.SimulationProblemResults) = IS.get_base_power(results) -get_base_power(results::PSI.ProblemResults) = results.base_power +get_base_power(results::IS.Results) = IS.get_base_power(results) function get_load_data( system::PSY.System; @@ -441,30 +440,53 @@ function get_load_data( initial_time = get(kwargs, :initial_time, PSY.get_forecast_initial_timestamp(system)) parameters = Dict{Symbol, DataFrames.DataFrame}() PSY.set_units_base_system!(system, "SYSTEM_BASE") + resolution = nothing + len = nothing for agg in aggregation_components loads = _get_loads(system, agg) length(loads) == 0 && continue colname = aggregation == PSY.System ? "System" : PSY.get_name(agg) load_values = DataFrames.DataFrame() for load in loads + # TODO awaiting methods in PSY to make this simpler + keys = filter( + key -> + PSY.get_time_series_type(key) == PSY.Deterministic && + PSY.get_name(key) == "max_active_power", + PSY.get_time_series_keys(load), + ) + @assert length(keys) == 1 + my_resolution = first(keys).resolution + if isnothing(resolution) + resolution = my_resolution + len = (horizon isa Dates.Period) ? Int64(horizon / resolution) : horizon + else + (resolution != my_resolution) && + throw(error("Load time series have mismatched resolutions")) + end + f = PSY.get_time_series_values( # TODO: this isn't applying the scaling factors PSY.Deterministic, load, "max_active_power"; start_time = initial_time, - len = horizon, + len = len, ) load_values[:, PSY.get_name(load)] = f end parameters[Symbol(colname)] = load_values end - time_range = collect( - range( - initial_time; - step = PSY.get_time_series_resolution(system), - length = horizon, - ), - ) + time_range = if isnothing(len) + Dates.DateTime[] + else + collect( + range( + initial_time; + step = resolution, + length = len, + ), + ) + end return PowerData(parameters, time_range) end diff --git a/test/test_data/results_data.jl b/test/test_data/results_data.jl index d4c0245..ead0446 100644 --- a/test/test_data/results_data.jl +++ b/test/test_data/results_data.jl @@ -1,3 +1,15 @@ +# Will be superseded by https://github.com/NREL-Sienna/PowerSystems.jl/issues/1143 +function linear_fuel_to_linear_cost(fc::FuelCurve{LinearCurve}) + fuel_cost = get_fuel_cost(fc) + !(fuel_cost isa Float64) && throw(ArgumentError("fuel_cost must be a scalar")) + old_vc = get_value_curve(fc) + new_vc = LinearCurve( + get_proportional_term(old_vc) * fuel_cost, + get_constant_term(old_vc) * fuel_cost, + ) + return CostCurve(new_vc, get_power_units(fc), get_vom_cost(fc)) +end + function add_re!(sys) re = RenewableDispatch( "WindBusA", @@ -9,13 +21,13 @@ function add_re!(sys) PrimeMovers.WT, (min = 0.0, max = 0.0), 1.0, - TwoPartCost(0.220, 0.0), + RenewableGenerationCost(CostCurve(LinearCurve(0.220))), 100.0, ) add_component!(sys, re) copy_time_series!(re, get_component(PowerLoad, sys, "bus2")) - fx = RenewableFix( + fx = RenewableNonDispatch( "RoofTopSolar", true, get_component(ACBus, sys, "bus5"), @@ -31,9 +43,12 @@ function add_re!(sys) for g in get_components(HydroEnergyReservoir, sys) tpc = get_operation_cost(g) - smc = StorageManagementCost(; - variable = get_variable(tpc), - fixed = get_fixed(tpc), + cc = get_variable(tpc) + (cc isa FuelCurve) && (cc = linear_fuel_to_linear_cost(cc)) + smc = StorageCost(; + charge_variable_cost = cc, + discharge_variable_cost = cc, + fixed = PSY.get_fixed(tpc), start_up = 0.0, shut_down = 0.0, energy_shortage_cost = 10.0, @@ -42,21 +57,23 @@ function add_re!(sys) set_operation_cost!(g, smc) end - batt = GenericBattery( - "test_batt", - true, - get_component(ACBus, sys, "bus4"), - PrimeMovers.BA, - 0.0, - (min = 0.0, max = 1.0), - 1.0, - 0.0, - (min = 0.0, max = 1.0), - (min = 0.0, max = 1.0), - (in = 1.0, out = 1.0), - 0.0, - nothing, - 10.0, + batt = EnergyReservoirStorage(; + name = "test_batt", + available = true, + bus = get_component(ACBus, sys, "bus4"), + prime_mover_type = PrimeMovers.BA, + storage_technology_type = StorageTech.OTHER_CHEM, + storage_capacity = 1.0, + storage_level_limits = (min = 0.0, max = 1.0), + initial_storage_capacity_level = 0.0, + rating = 1.0, + active_power = 0.0, + input_active_power_limits = (min = 0.0, max = 1.0), + output_active_power_limits = (min = 0.0, max = 1.0), + efficiency = (in = 1.0, out = 1.0), + reactive_power = 0.0, + reactive_power_limits = nothing, + base_power = 10.0, ) add_component!(sys, batt) end @@ -97,10 +114,14 @@ function _execute_simulation(base_path, sim_name) ProblemTemplate(NetworkModel(CopperPlatePowerModel; use_slacks = false)) set_device_model!(template_hydro_st_uc, ThermalStandard, ThermalBasicUnitCommitment) set_device_model!(template_hydro_st_uc, PowerLoad, StaticPowerLoad) - set_device_model!(template_hydro_st_uc, RenewableFix, FixedOutput) + set_device_model!(template_hydro_st_uc, RenewableNonDispatch, FixedOutput) set_device_model!(template_hydro_st_uc, RenewableDispatch, RenewableFullDispatch) set_device_model!(template_hydro_st_uc, HydroDispatch, FixedOutput) - set_device_model!(template_hydro_st_uc, GenericBattery, StorageDispatchWithReserves) + set_device_model!( + template_hydro_st_uc, + EnergyReservoirStorage, + StorageDispatchWithReserves, + ) set_device_model!( template_hydro_st_uc, HydroEnergyReservoir, @@ -117,16 +138,19 @@ function _execute_simulation(base_path, sim_name) ) set_device_model!(template_hydro_st_ed, ThermalStandard, ThermalBasicDispatch) set_device_model!(template_hydro_st_ed, PowerLoad, StaticPowerLoad) - set_device_model!(template_hydro_st_ed, RenewableFix, FixedOutput) + set_device_model!(template_hydro_st_ed, RenewableNonDispatch, FixedOutput) set_device_model!(template_hydro_st_ed, RenewableDispatch, RenewableFullDispatch) set_device_model!(template_hydro_st_ed, HydroDispatch, FixedOutput) - set_device_model!(template_hydro_st_ed, GenericBattery, StorageDispatchWithReserves) + set_device_model!( + template_hydro_st_ed, + EnergyReservoirStorage, + StorageDispatchWithReserves, + ) set_device_model!( template_hydro_st_ed, HydroEnergyReservoir, HydroDispatchReservoirStorage, ) - models = SimulationModels(; decision_models = [ DecisionModel( @@ -233,10 +257,10 @@ function run_test_prob() template_hydro_st_uc, c_sys5_hy_uc; optimizer = GLPK_optimizer, - horizon = 12, + horizon = Hour(12), ) build!(prob; output_dir = mktempdir()) solve!(prob) - res = ProblemResults(prob) + res = OptimizationProblemResults(prob) return res end