Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.32.4 #241

Merged
merged 44 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ef343a9
update NSRDB bounds
adfarth Jun 21, 2023
0be383a
add descriptions to PV inputs
adfarth Jun 21, 2023
42b8ca5
update to PVWatts v8
adfarth Jun 21, 2023
38527b9
Update runtests.jl
adfarth Jun 21, 2023
8e65999
update to v8 in utils.jl
adfarth Jun 21, 2023
9a3a421
update other pvwatts calls and some tests
adfarth Jun 21, 2023
cd90bbf
update tests
adfarth Jun 21, 2023
825b277
Update Tests
adfarth Jun 22, 2023
f5e80b7
Update urdb.jl
adfarth Jun 29, 2023
b121d8f
Update CHANGELOG.md
adfarth Jun 30, 2023
01860ed
Update single PVWatts API function
Bill-Becker Jul 2, 2023
3bb505c
Use call_pvwatts_api() for get_production_factor(PV)
Bill-Becker Jul 2, 2023
a5967e3
Use call_pvwatts_api for GHP ambient temp, and assign PV production_f…
Bill-Becker Jul 2, 2023
e4f35c7
Make PV struct mutable
Bill-Becker Jul 2, 2023
da4e224
Update function call to call_pvwatts_api()
Bill-Becker Jul 2, 2023
bb6956c
update generator capx default
hdunham Jul 3, 2023
697736f
update changelog, module_type=0, remove todo
adfarth Jul 5, 2023
53c3a13
Fix leap year issue when using URDB rate
Bill-Becker Jul 5, 2023
f4cc981
Merge branches 'update-pvwatts' and 'update-pvwatts' of https://githu…
Bill-Becker Jul 5, 2023
7105221
Add bug fix to CHANGELOG.md
Bill-Becker Jul 5, 2023
9f15009
Merge pull request #233 from NREL/update-pvwatts
adfarth Jul 5, 2023
29ac5d3
depend gen installed_cost_per_kw on only_runs_during_grid_outage
hdunham Jul 7, 2023
9618744
provide installed_cost_per_kw in tests b/c default changed
hdunham Jul 11, 2023
9b5d494
Merge branch 'develop' into gen-defaults
hdunham Jul 11, 2023
7cf85b4
Update CHANGELOG.md
hdunham Jul 11, 2023
1869b41
remove installed_cost_per_kw from MPC test post
hdunham Jul 11, 2023
cab786b
Merge branch 'develop' into rate-bug-fix
adfarth Jul 13, 2023
65a36ad
Merge pull request #236 from NREL/rate-bug-fix
adfarth Jul 17, 2023
a96a5e7
Update CHANGELOG.md
adfarth Jul 17, 2023
0889c91
Update Project.toml
adfarth Jul 17, 2023
a91e83f
Merge branch 'develop' into gen-defaults
hdunham Jul 20, 2023
88fcdb9
update fuel_avail_gal default to always 1e9
hdunham Jul 21, 2023
58b1060
fix fuel_avail_gal in tests
hdunham Jul 21, 2023
3ff80a1
trigger tests
hdunham Jul 21, 2023
ea8ea27
update unit test values
adfarth Jul 21, 2023
9f2d39e
Update runtests.jl
adfarth Jul 21, 2023
c4df205
Update CHANGELOG.md
adfarth Jul 21, 2023
e31d70d
Update runtests.jl
adfarth Jul 21, 2023
4b38b6a
Merge pull request #242 from NREL/updatetests
adfarth Jul 21, 2023
6ebe348
Merge branch 'develop' into gen-defaults
hdunham Jul 24, 2023
d8b4f47
Update CHANGELOG.md
hdunham Jul 26, 2023
048a85d
Merge pull request #238 from NREL/gen-defaults
hdunham Jul 26, 2023
8cd7974
Update CHANGELOG.md
hdunham Jul 26, 2023
f82349a
readability
hdunham Jul 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,23 @@ Classify the change according to the following categories:
### Deprecated
### Removed

## Develop
### Changed
- Changed unit test expected values due to update to PVWatts v8, which slightly changed expected PV production factors.
- Changed **fuel_avail_gal** default to 1e9 for on-grid scenarios (same as off-grid)
### Fixed
- Corrected `Generator` **installed_cost_per_kw** from 500 to 650 if **only_runs_during_grid_outage** is _true_ or 800 if _false_

## v0.32.4
adfarth marked this conversation as resolved.
Show resolved Hide resolved
### Changed
- Consolidated PVWatts API calls to 1 call (previously 3 separate calls existed). API call occurs in `src/core/utils.jl/call_pvwatts_api()`. This function is called for PV in `src/core/production_factor.jl/get_production_factor(PV)` and for GHP in `src/core/scenario.jl`. If GHP and PV are evaluated together, the GHP PVWatts call for ambient temperature is also used to assign the pv.production_factor_series in Scenario.jl so that the PVWatts API does not get called again downstream in `get_production_factor(PV)`.
- In `src/core/utils.jl/call_pvwatts_api()`, updated NSRDB bounds used in PVWatts query (now includes southern New Zealand)
- Updated PV Watts version from v6 to v8. PVWatts V8 updates the weather data to 2020 TMY data from the NREL NSRDB for locations covered by the database. (The NSRDB weather data used in PVWatts V6 is from around 2015.) See other differences at https://developer.nrel.gov/docs/solar/pvwatts/.
- Made PV struct mutable: This allows for assigning pv.production_factor_series when calling PVWatts for GHP, to avoid a extra PVWatts calls later.
### Fixed
- Issue with using a leap year with a URDB rate - the URDB rate was creating energy_rate of length 8784 instead of intended 8760
- Don't double add adjustments to urdb rates with non-standard units

## v0.32.3
### Fixed
- Calculate **num_battery_bins** default in `backup_reliability.jl` based on battery duration to prevent significant discretization error (and add test)
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "REopt"
uuid = "d36ad4e8-d74a-4f7a-ace1-eaea049febf6"
authors = ["Nick Laws", "Hallie Dunham <[email protected]>", "Bill Becker <[email protected]>", "Bhavesh Rathod <[email protected]>", "Alex Zolan <[email protected]>", "Amanda Farthing <[email protected]>"]
version = "0.32.3"
version = "0.32.4"

[deps]
ArchGDAL = "c9ce4bd3-c3d5-55b8-8973-c0e20141b8c3"
Expand Down
12 changes: 6 additions & 6 deletions src/core/generator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@
"""
`Generator` is an optional REopt input with the following keys and default values:
```julia
only_runs_during_grid_outage::Bool = true,
existing_kw::Real = 0,
min_kw::Real = 0,
max_kw::Real = 1.0e6,
installed_cost_per_kw::Real = 500.0,
installed_cost_per_kw::Real = only_runs_during_grid_outage ? 650.0 : 800.0,
om_cost_per_kw::Real = off_grid_flag ? 20.0 : 10.0,
om_cost_per_kwh::Real = 0.0,
fuel_cost_per_gallon::Real = 3.0,
electric_efficiency_full_load::Real = 0.3233,
electric_efficiency_half_load::Real = electric_efficiency_full_load,
fuel_avail_gal::Real = off_grid_flag ? 1.0e9 : 660.0,
fuel_avail_gal::Real = 1.0e9,
fuel_higher_heating_value_kwh_per_gal::Real = 40.7,
min_turn_down_fraction::Real = off_grid_flag ? 0.15 : 0.0,
only_runs_during_grid_outage::Bool = true,
sells_energy_back_to_grid::Bool = false,
can_net_meter::Bool = false,
can_wholesale::Bool = false,
Expand Down Expand Up @@ -125,19 +125,19 @@ struct Generator <: AbstractGenerator
function Generator(;
off_grid_flag::Bool = false,
analysis_years::Int = 25,
only_runs_during_grid_outage::Bool = true,
existing_kw::Real = 0,
min_kw::Real = 0,
max_kw::Real = 1.0e6,
installed_cost_per_kw::Real = 500.0,
installed_cost_per_kw::Real = only_runs_during_grid_outage ? 650.0 : 800.0,
om_cost_per_kw::Real= off_grid_flag ? 20.0 : 10.0,
om_cost_per_kwh::Real = 0.0,
fuel_cost_per_gallon::Real = 3.0,
electric_efficiency_full_load::Real = 0.3233,
electric_efficiency_half_load::Real = electric_efficiency_full_load,
fuel_avail_gal::Real = off_grid_flag ? 1.0e9 : 660.0,
fuel_avail_gal::Real = 1.0e9,
fuel_higher_heating_value_kwh_per_gal::Real = KWH_PER_GAL_DIESEL,
min_turn_down_fraction::Real = off_grid_flag ? 0.15 : 0.0,
only_runs_during_grid_outage::Bool = true,
sells_energy_back_to_grid::Bool = false,
can_net_meter::Bool = false,
can_wholesale::Bool = false,
Expand Down
41 changes: 5 additions & 36 deletions src/core/production_factor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,44 +35,13 @@ function get_production_factor(pv::PV, latitude::Real, longitude::Real; timefram
return pv.production_factor_series
end

# Check if site is beyond the bounds of the NRSDB dataset. If so, use the international dataset.
dataset = "nsrdb"
if longitude < -179.5 || longitude > -21.0 || latitude < -21.5 || latitude > 60.0
if longitude < 81.5 || longitude > 179.5 || latitude < -43.8 || latitude > 60.0
if longitude < 67.0 || longitude > 81.5 || latitude < -43.8 || latitude > 38.0
dataset = "intl"
end
end
end
watts, ambient_temp_celcius = call_pvwatts_api(latitude, longitude; tilt=pv.tilt, azimuth=pv.azimuth, module_type=pv.module_type,
array_type=pv.array_type, losses=round(pv.losses*100, digits=3), dc_ac_ratio=pv.dc_ac_ratio,
gcr=pv.gcr, inv_eff=pv.inv_eff*100, timeframe=timeframe, radius=pv.radius,
time_steps_per_hour=time_steps_per_hour)

url = string("https://developer.nrel.gov/api/pvwatts/v6.json", "?api_key=", nrel_developer_key,
"&lat=", latitude , "&lon=", longitude, "&tilt=", pv.tilt,
"&system_capacity=1", "&azimuth=", pv.azimuth, "&module_type=", pv.module_type,
"&array_type=", pv.array_type, "&losses=", round(pv.losses*100, digits=3), "&dc_ac_ratio=", pv.dc_ac_ratio,
"&gcr=", pv.gcr, "&inv_eff=", pv.inv_eff*100, "&timeframe=", timeframe, "&dataset=", dataset,
"&radius=", pv.radius
)
return watts

try
@info "Querying PVWatts for production_factor with " pv.name
r = HTTP.get(url, keepalive=true, readtimeout=10)
@info "Response received from PVWatts"
response = JSON.parse(String(r.body))
if r.status != 200
throw(@error("Bad response from PVWatts: $(response["errors"])"))
end
@info "PVWatts success."
watts = collect(get(response["outputs"], "ac", []) / 1000) # scale to 1 kW system (* 1 kW / 1000 W)
if length(watts) != 8760
throw(@error("PVWatts did not return a valid production factor. Got $watts"))
end
if time_steps_per_hour > 1
watts = repeat(watts, inner=time_steps_per_hour)
end
return watts
catch e
throw(@error("Error occurred when calling PVWatts: $e"))
end
end


Expand Down
14 changes: 7 additions & 7 deletions src/core/pv.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
array_type::Int=1, # PV Watts array type (0: Ground Mount Fixed (Open Rack); 1: Rooftop, Fixed; 2: Ground Mount 1-Axis Tracking; 3 : 1-Axis Backtracking; 4: Ground Mount, 2-Axis Tracking)
tilt::Real= array_type == 1 ? 10 : abs(latitude), # tilt = 10 deg for rooftop systems, abs(lat) for ground-mount
module_type::Int=0, # PV module type (0: Standard; 1: Premium; 2: Thin Film)
losses::Real=0.14,
losses::Real=0.14, # System losses
azimuth::Real = latitude≥0 ? 180 : 0, # set azimuth to zero for southern hemisphere
gcr::Real=0.4,
radius::Int=0,
name::String="PV",
location::String="both",
gcr::Real=0.4, # Ground coverage ratio
radius::Int=0, # Radius, in miles, to use when searching for the closest climate data station. Use zero to use the closest station regardless of the distance
name::String="PV", # for use with multiple pvs
location::String="both", # one of ["roof", "ground", "both"]
existing_kw::Real=0,
min_kw::Real=0,
max_kw::Real=1.0e9,
Expand Down Expand Up @@ -82,7 +82,7 @@
If `azimuth` is not provided, then it is set to 180 if the site is in the northern hemisphere and 0 if in the southern hemisphere.

"""
struct PV <: AbstractTech
mutable struct PV <: AbstractTech
Copy link
Collaborator

@hdunham hdunham Jul 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fine for now but for performance we should be trying to avoid making structs mutable

Copy link
Collaborator Author

@adfarth adfarth Jul 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hdunham do you want to make an issue for this? This was a change Bill made in order to allow for assigning pv.production_factor_series when calling PVWatts for GHP, to avoid a extra PVWatts calls later.

tilt
array_type
module_type
Expand Down Expand Up @@ -151,7 +151,7 @@ struct PV <: AbstractTech
acres_per_kw::Real=6e-3,
inv_eff::Real=0.96,
dc_ac_ratio::Real=1.2,
production_factor_series::Union{Nothing, Array{Real,1}} = nothing,
production_factor_series::Union{Nothing, Array{<:Real,1}} = nothing,
federal_itc_fraction::Real = 0.3,
federal_rebate_per_kw::Real = 0.0,
state_ibi_fraction::Real = 0.0,
Expand Down
36 changes: 13 additions & 23 deletions src/core/scenario.jl
Original file line number Diff line number Diff line change
Expand Up @@ -454,37 +454,27 @@ function Scenario(d::Dict; flex_hvac_from_json=false)
number_of_ghpghx = length(d["GHP"]["ghpghx_inputs"])
end
# Call PVWatts for hourly dry-bulb outdoor air temperature
ambient_temperature_f = []
ambient_temp_degF = []
if !haskey(d["GHP"]["ghpghx_inputs"][1], "ambient_temperature_f") || isempty(d["GHP"]["ghpghx_inputs"][1]["ambient_temperature_f"])
url = string("https://developer.nrel.gov/api/pvwatts/v6.json", "?api_key=", nrel_developer_key,
"&lat=", d["Site"]["latitude"] , "&lon=", d["Site"]["longitude"], "&tilt=", d["Site"]["latitude"],
"&system_capacity=1", "&azimuth=", 180, "&module_type=", 0,
"&array_type=", 0, "&losses=", 0.14, "&dc_ac_ratio=", 1.1,
"&gcr=", 0.4, "&inv_eff=", 99, "&timeframe=", "hourly", "&dataset=nsrdb",
"&radius=", 100)
try
@info "Querying PVWatts for ambient temperature"
r = HTTP.get(url)
response = JSON.parse(String(r.body))
if r.status != 200
throw(@error("Bad response from PVWatts: $(response["errors"])"))
# If PV is evaluated and we need to call PVWatts for ambient temperature, assign PV production factor here too with the same call
# By assigning pv.production_factor_series here, it will skip the PVWatts call in get_production_factor(PV) call from reopt_input.jl
if !isempty(pvs)
for pv in pvs
pv.production_factor_series, ambient_temp_celcius = call_pvwatts_api(site.latitude, site.longitude; tilt=pv.tilt, azimuth=pv.azimuth, module_type=pv.module_type,
array_type=pv.array_type, losses=round(pv.losses*100, digits=3), dc_ac_ratio=pv.dc_ac_ratio,
gcr=pv.gcr, inv_eff=pv.inv_eff*100, timeframe="hourly", radius=pv.radius, time_steps_per_hour=settings.time_steps_per_hour)
end
@info "PVWatts success."
temp_c = get(response["outputs"], "tamb", [])
if length(temp_c) != 8760 || isempty(temp_c)
throw(@error("PVWatts did not return a valid temperature profile. Got $temp_c"))
end
ambient_temperature_f = temp_c * 1.8 .+ 32.0
catch e
throw(@error("Error occurred when calling PVWatts: $e"))
else
pv_prodfactor, ambient_temp_celcius = call_pvwatts_api(site.latitude, site.longitude; time_steps_per_hour=settings.time_steps_per_hour)
end
ambient_temp_degF = ambient_temp_celcius * 1.8 .+ 32.0
else
ambient_temperature_f = d["GHP"]["ghpghx_inputs"][1]["ambient_temperature_f"]
ambient_temp_degF = d["GHP"]["ghpghx_inputs"][1]["ambient_temperature_f"]
end

for i in 1:number_of_ghpghx
ghpghx_inputs = d["GHP"]["ghpghx_inputs"][i]
d["GHP"]["ghpghx_inputs"][i]["ambient_temperature_f"] = ambient_temperature_f
d["GHP"]["ghpghx_inputs"][i]["ambient_temperature_f"] = ambient_temp_degF
# Only SpaceHeating portion of Heating Load gets served by GHP, unless allowed by can_serve_dhw
if get(ghpghx_inputs, "heating_thermal_load_mmbtu_per_hr", []) in [nothing, []]
if haskey(d["GHP"], "can_serve_dhw") && d["GHP"]["can_serve_dhw"]
Expand Down
2 changes: 1 addition & 1 deletion src/core/site.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Inputs related to the physical location:
longitude::Real,
land_acres::Union{Real, Nothing} = nothing, # acres of land available for PV panels and/or Wind turbines. Constraint applied separately to PV and Wind, meaning the two technologies are assumed to be able to be co-located.
roof_squarefeet::Union{Real, Nothing} = nothing,
min_resil_time_steps::Int=0,
min_resil_time_steps::Int=0, # The minimum number consecutive timesteps that load must be fully met once an outage begins. Only applies to multiple outage modeling using inputs outage_start_time_steps and outage_durations.
mg_tech_sizes_equal_grid_sizes::Bool = true,
node::Int = 1,
CO2_emissions_reduction_min_fraction::Union{Float64, Nothing} = nothing,
Expand Down
9 changes: 7 additions & 2 deletions src/core/urdb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ function URDBrate(urdb_response::Dict, year::Int; time_steps_per_hour=1)
n_monthly_demand_tiers, monthly_demand_tier_limits, monthly_demand_rates,
n_tou_demand_tiers, tou_demand_tier_limits, tou_demand_rates, tou_demand_ratchet_time_steps =
parse_demand_rates(urdb_response, year, time_steps_per_hour=time_steps_per_hour)

energy_rates, energy_tier_limits, n_energy_tiers, sell_rates =
parse_urdb_energy_costs(urdb_response, year; time_steps_per_hour=time_steps_per_hour)

Expand Down Expand Up @@ -270,6 +270,9 @@ function parse_urdb_energy_costs(d::Dict, year::Int; time_steps_per_hour=1, bigM

for month in range(1, stop=12)
n_days = daysinmonth(Date(string(year) * "-" * string(month)))
if month == 2 && isleapyear(year)
hdunham marked this conversation as resolved.
Show resolved Hide resolved
n_days -= 1
end

for day in range(1, stop=n_days)

Expand All @@ -292,10 +295,12 @@ function parse_urdb_energy_costs(d::Dict, year::Int; time_steps_per_hour=1, bigM
end
if non_kwh_units
rate = rate_average
adfarth marked this conversation as resolved.
Show resolved Hide resolved
total_rate = rate
else
rate = get(d["energyratestructure"][period][tier_use], "rate", 0)
total_rate = rate + get(d["energyratestructure"][period][tier_use], "adj", 0)
end
total_rate = rate + get(d["energyratestructure"][period][tier_use], "adj", 0)

sell = get(d["energyratestructure"][period][tier_use], "sell", 0)

for step in range(1, stop=time_steps_per_hour) # repeat hourly rates intrahour
Expand Down
73 changes: 38 additions & 35 deletions src/core/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -377,54 +377,57 @@ function generate_year_profile_hourly(year::Int64, consecutive_periods::Abstract
end


function get_ambient_temperature(latitude::Real, longitude::Real; timeframe="hourly")
url = string("https://developer.nrel.gov/api/pvwatts/v6.json", "?api_key=", nrel_developer_key,
"&lat=", latitude , "&lon=", longitude, "&tilt=", latitude,
"&system_capacity=1", "&azimuth=", 180, "&module_type=", 0,
"&array_type=", 0, "&losses=", 14,
"&timeframe=", timeframe, "&dataset=nsrdb"
)

try
@info "Querying PVWatts for ambient temperature... "
r = HTTP.get(url)
response = JSON.parse(String(r.body))
if r.status != 200
throw(@error("Bad response from PVWatts: $(response["errors"])"))
end
@info "PVWatts success."
tamb = collect(get(response["outputs"], "tamb", [])) # Celcius
if length(tamb) != 8760
throw(@error("PVWatts did not return a valid temperature. Got $tamb"))
"""
call_pvwatts_api(latitude::Real, longitude::Real; tilt=latitude, azimuth=180, module_type=0, array_type=1,
losses=14, dc_ac_ratio=1.2, gcr=0.4, inv_eff=96, timeframe="hourly", radius=0, time_steps_per_hour=1)
This calls the PVWatts API and returns both:
- PV production factor
- Ambient outdoor air dry bulb temperature profile [Celcius]
"""
function call_pvwatts_api(latitude::Real, longitude::Real; tilt=latitude, azimuth=180, module_type=0, array_type=1,
losses=14, dc_ac_ratio=1.2, gcr=0.4, inv_eff=96, timeframe="hourly", radius=0, time_steps_per_hour=1)
# Check if site is beyond the bounds of the NRSDB TMY dataset. If so, use the international dataset.
dataset = "nsrdb"
if longitude < -179.5 || longitude > -21.0 || latitude < -21.5 || latitude > 60.0
if longitude < 81.5 || longitude > 179.5 || latitude < -60.0 || latitude > 60.0
if longitude < 67.0 || latitude < -40.0 || latitude > 38.0
dataset = "intl"
end
end
return tamb
catch e
throw(@error("Error occurred when calling PVWatts: $e"))
end
end


function get_pvwatts_prodfactor(latitude::Real, longitude::Real; timeframe="hourly")
url = string("https://developer.nrel.gov/api/pvwatts/v6.json", "?api_key=", nrel_developer_key,
"&lat=", latitude , "&lon=", longitude, "&tilt=", latitude,
"&system_capacity=1", "&azimuth=", 180, "&module_type=", 0,
"&array_type=", 0, "&losses=", 14,
"&timeframe=", timeframe, "&dataset=nsrdb"
)
url = string("https://developer.nrel.gov/api/pvwatts/v8.json", "?api_key=", nrel_developer_key,
"&lat=", latitude , "&lon=", longitude, "&tilt=", tilt,
"&system_capacity=1", "&azimuth=", azimuth, "&module_type=", module_type,
"&array_type=", array_type, "&losses=", losses, "&dc_ac_ratio=", dc_ac_ratio,
"&gcr=", gcr, "&inv_eff=", inv_eff, "&timeframe=", timeframe, "&dataset=", dataset,
"&radius=", radius
)

try
@info "Querying PVWatts for production factor of 1 kW system with tilt set to latitude... "
r = HTTP.get(url)
@info "Querying PVWatts for production factor and ambient air temperature... "
r = HTTP.get(url, keepalive=true, readtimeout=10)
response = JSON.parse(String(r.body))
if r.status != 200
throw(@error("Bad response from PVWatts: $(response["errors"])"))
end
@info "PVWatts success."
# Get both possible data of interest
watts = collect(get(response["outputs"], "ac", []) / 1000) # scale to 1 kW system (* 1 kW / 1000 W)
tamb_celcius = collect(get(response["outputs"], "tamb", [])) # Celcius
# Validate outputs
if length(watts) != 8760
throw(@error("PVWatts did not return a valid prodfactor. Got $watts"))
end
return watts
# Validate tamb_celcius
if length(tamb_celcius) != 8760
throw(@error("PVWatts did not return a valid temperature. Got $tamb_celcius"))
end
# Upsample or downsample based on model time_steps_per_hour
if time_steps_per_hour > 1
watts = repeat(watts, inner=time_steps_per_hour)
tamb_celcius = repeat(tamb_celcius, inner=time_steps_per_hour)
end
return watts, tamb_celcius
catch e
throw(@error("Error occurred when calling PVWatts: $e"))
end
Expand Down
4 changes: 2 additions & 2 deletions src/mpc/structs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ function MPCGenerator(;
fuel_cost_per_gallon::Real = 3.0,
electric_efficiency_full_load::Real = 0.3233,
electric_efficiency_half_load::Real = electric_efficiency_full_load,
fuel_avail_gal::Real = 660.0,
fuel_avail_gal::Real = 1.0e9,
fuel_higher_heating_value_kwh_per_gal::Real = KWH_PER_GAL_DIESEL,
min_turn_down_fraction::Real = 0.0, # TODO change this to non-zero value
only_runs_during_grid_outage::Bool = true,
Expand All @@ -310,7 +310,7 @@ struct MPCGenerator <: AbstractGenerator
fuel_cost_per_gallon::Real = 3.0,
electric_efficiency_full_load::Real = 0.3233,
electric_efficiency_half_load::Real = electric_efficiency_full_load,
fuel_avail_gal::Real = 660.0,
fuel_avail_gal::Real = 1.0e9,
fuel_higher_heating_value_kwh_per_gal::Real = KWH_PER_GAL_DIESEL,
min_turn_down_fraction::Real = 0.0, # TODO change this to non-zero value
only_runs_during_grid_outage::Bool = true,
Expand Down
Loading
Loading