Skip to content

Commit

Permalink
Merge pull request #22 from NREL-Sienna/accommodate-refactors
Browse files Browse the repository at this point in the history
Make (old) PowerAnalytics work with PSY4
  • Loading branch information
GabrielKS authored Jun 25, 2024
2 parents eca7764 + aa05484 commit 6520599
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 36 deletions.
42 changes: 32 additions & 10 deletions src/get_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
63 changes: 39 additions & 24 deletions test/test_data/results_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ 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)
Expand All @@ -31,9 +31,10 @@ 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),
smc = StorageCost(;
charge_variable_cost = PSY.get_variable(tpc),
discharge_variable_cost = PSY.get_variable(tpc),
fixed = PSY.get_fixed(tpc),
start_up = 0.0,
shut_down = 0.0,
energy_shortage_cost = 10.0,
Expand All @@ -42,21 +43,22 @@ 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,
initial_energy = 0.0,
state_of_charge_limits = (min = 0.0, max = 1.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
Expand Down Expand Up @@ -100,12 +102,19 @@ function _execute_simulation(base_path, sim_name)
set_device_model!(template_hydro_st_uc, RenewableFix, 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)
# TODO uncomment when PSI is fixed
set_device_model!(
template_hydro_st_uc,
EnergyReservoirStorage,
StorageDispatchWithReserves,
)
#=
set_device_model!(
template_hydro_st_uc,
HydroEnergyReservoir,
HydroDispatchReservoirStorage,
)
=#
set_service_model!(template_hydro_st_uc, VariableReserve{ReserveUp}, RangeReserve)

template_hydro_st_ed = ProblemTemplate(
Expand All @@ -120,13 +129,19 @@ function _execute_simulation(base_path, sim_name)
set_device_model!(template_hydro_st_ed, RenewableFix, 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)
# TODO uncomment when PSI is fixed
set_device_model!(
template_hydro_st_ed,
EnergyReservoirStorage,
StorageDispatchWithReserves,
)
#=
set_device_model!(
template_hydro_st_ed,
HydroEnergyReservoir,
HydroDispatchReservoirStorage,
)

=#
models = SimulationModels(;
decision_models = [
DecisionModel(
Expand Down Expand Up @@ -233,10 +248,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
4 changes: 2 additions & 2 deletions test/test_result_sorting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ problem_results = run_test_prob()

@testset "test filter results" begin
gen = PA.get_generation_data(results_uc; curtailment = false)
@test length(gen.data) == 7
@test length(gen.data) == 6 # TODO will be 7 when storage and hydro are reenabled
@test length(gen.time) == 48

gen = PA.get_generation_data(
Expand Down Expand Up @@ -65,7 +65,7 @@ problem_results = run_test_prob()
# TODO: make tests for subsetting data
sub_gen =
get_generation_data(results_uc; filter_func = x -> get_name(get_bus(x)) == "bus1")
@test length(sub_gen.data) == 8
@test length(sub_gen.data) == 7 # TODO will be 8 when storage and hydro are reenabled
end

@testset "test curtailment calculations" begin
Expand Down

0 comments on commit 6520599

Please sign in to comment.