lib/measures/add_ev_load/measure.rb in openstudio-common-measures-0.5.0 vs lib/measures/add_ev_load/measure.rb in openstudio-common-measures-0.6.0
- old
+ new
@@ -96,14 +96,20 @@
args << chg_station_type
# Make an argument for the % of vehicles parked at the building that are EVs.
ev_percent = OpenStudio::Measure::OSArgument.makeDoubleArgument('ev_percent', true)
ev_percent.setDisplayName('Percent of Vehicles Parked at Building That Are EVs')
- ev_percent.setDefaultValue(1.0)
+ ev_percent.setDefaultValue(100)
ev_percent.setDescription('Denotes percentage of vehicles between 0 to 100 that are electric on site.')
args << ev_percent
+ # Make an argument for using occupancy from OpenStudio Model.
+ ev_use_model_occupancy = OpenStudio::Measure::OSArgument.makeBoolArgument('ev_use_model_occupancy', true)
+ ev_use_model_occupancy.setDisplayName('Use occupancy from OpenStudio Model to determine number of electric vehicles')
+ ev_use_model_occupancy.setDefaultValue(true)
+ args << ev_use_model_occupancy
+
return args
end
# define what happens when the measure is run
def run(model, runner, user_arguments)
@@ -112,10 +118,11 @@
# Assign the user arguments to variables.
delay_type = runner.getStringArgumentValue('delay_type', user_arguments)
charge_behavior = runner.getStringArgumentValue('charge_behavior', user_arguments)
chg_station_type = runner.getStringArgumentValue('chg_station_type', user_arguments)
ev_percent = runner.getDoubleArgumentValue('ev_percent', user_arguments)
+ ev_use_model_occupancy = runner.getBoolArgumentValue('ev_use_model_occupancy', user_arguments)
# use the built-in error checking
if !runner.validateUserArguments(arguments(model), user_arguments)
return false
end
@@ -153,17 +160,28 @@
file_path = "#{__dir__}/resources/"
# Sets key based on charging station type, for general charging load profiles. Will use this to average columns appropriately.
if chg_station_type == 'Typical Home'
chg_station_key = 1
+ runner.registerInfo("charge station type = #{chg_station_type}")
runner.registerInfo("charge station key = #{chg_station_key}")
+ # Assumed occupancy density is the typical occupancy density for charging station type determined by using a weighted
+ # average of building type and associated occupancy density
+ assumed_occupancy_density = 0.003
+ runner.registerInfo("assumed occupancy = #{assumed_occupancy_density}")
elsif chg_station_type == 'Typical Work'
chg_station_key = 2
+ runner.registerInfo("charge station type = #{chg_station_type}")
runner.registerInfo("charge station key = #{chg_station_key}")
+ assumed_occupancy_density = 0.005
+ runner.registerInfo("assumed occupancy = #{assumed_occupancy_density}")
elsif chg_station_type == 'Typical Public'
chg_station_key = 3
+ runner.registerInfo("charge station type = #{chg_station_type}")
runner.registerInfo("charge station key = #{chg_station_key}")
+ assumed_occupancy_density = 0.0226
+ runner.registerInfo("assumed occupancy = #{assumed_occupancy_density}")
end
# Creating a schedule:ruleset
ev_sch = OpenStudio::Model::ScheduleRuleset.new(model)
ev_sch.setName('EV Charging Power Draw')
@@ -208,36 +226,61 @@
indices = work_indices
elsif chg_station_key == 3
indices = public_indices
end
- # Popualte the average weekday load for non PSN case. The load profiles used in this case are averaged based on the selected charging station type,(given the selected charging flexibility option and charging behavior option), and scaled for the percent of vehicles that are EVs.
+ space_type = model.getSpaceTypes[0]
+ model_occupancy = space_type.people.size
+ floor_area = space_type.floorArea
+ model_occupancy_density = space_type.getPeoplePerFloorArea(floor_area)
+ model_occupancy_density = model_occupancy_density/10.76 # Convert to people per ft2
+
+ # Populate the average weekday load for non PSN case. The load profiles used in this case are averaged based on the selected charging station type,(given the selected charging flexibility option and charging behavior option), and scaled for the percent of vehicles that are EVs.
if chg_station_type != 'Pena Station Next Analysis' && chg_station_type != 'Pena Station Next Analysis--DC Fast Charger'
wkday_load_sel = wkday_load.values_at(*indices)
avg_load_wkday = []
wkday_load_sel = wkday_load_sel.transpose
- for i in 0..wkday_load[0].length - 1
- avg_load_wkday[i] = (wkday_load_sel[i].reduce(0, :+) / wkday_load_sel[i].length) * ev_percent / assumed_percent # Scale profiles generated from 50% EV scenario by % of vehicles that are EVs.
+ if ev_use_model_occupancy
+ runner.registerInfo("model occupancy density = #{model_occupancy_density}")
+ for i in 0..wkday_load[0].length - 1
+ avg_load_wkday[i] = ((wkday_load_sel[i].reduce(0, :+) / wkday_load_sel[i].length) * ev_percent/assumed_percent) * (model_occupancy_density/assumed_occupancy_density) # Scale profiles generated from 50% EV scenario by occupancy of OpenStudio model (number of vehicles is assumed to be the same as occupancy of the building).
+ end
+ else
+ for i in 0..wkday_load[0].length - 1
+ avg_load_wkday[i] = (wkday_load_sel[i].reduce(0, :+) / wkday_load_sel[i].length) * ev_percent / assumed_percent # Scale profiles generated from 50% EV scenario by % of vehicles that are EVs.
+ end
end
wkday_max_load = avg_load_wkday.max
# Populate the average Saturday load.
sat_load_sel = sat_load.values_at(*indices)
avg_load_sat = []
sat_load_sel = sat_load_sel.transpose
- for i in 0..sat_load[0].length - 1
- avg_load_sat[i] = (sat_load_sel[i].reduce(0, :+) / sat_load_sel[i].length) * ev_percent / assumed_percent # Scale profiles generated from 50% EV scenario by % of vehicles that are EVs.
+ if ev_use_model_occupancy
+ for i in 0..sat_load[0].length - 1
+ avg_load_sat[i] = ((sat_load_sel[i].reduce(0, :+) / sat_load_sel[i].length) * ev_percent / assumed_percent) * (model_occupancy_density/assumed_occupancy_density) # Scale profiles generated from 50% EV scenario by occupancy of OpenStudio model and apply ev_percent (number of vehicles is assumed to be the same as occupancy of the building).
+ end
+ else
+ for i in 0..sat_load[0].length - 1
+ avg_load_sat[i] = (sat_load_sel[i].reduce(0, :+) / sat_load_sel[i].length) * ev_percent / assumed_percent # Scale profiles generated from 50% EV scenario by % of vehicles that are EVs.
+ end
end
sat_max_load = avg_load_sat.max
# Populate the average Sunday load.
sun_load_sel = sun_load.values_at(*indices)
avg_load_sun = []
sun_load_sel = sun_load_sel.transpose
- for i in 0..sun_load[0].length - 1
- avg_load_sun[i] = (sun_load_sel[i].reduce(0, :+) / sun_load_sel[i].length) * ev_percent / assumed_percent # Scale profiles generated from 50% EV scenario by % of vehicles that are EVs.
+ if ev_use_model_occupancy
+ for i in 0..sun_load[0].length - 1
+ avg_load_sun[i] = ((sun_load_sel[i].reduce(0, :+) / sun_load_sel[i].length) * ev_percent / assumed_percent) * (model_occupancy_density/assumed_occupancy_density) # Scale profiles generated from 50% EV scenario by occupancy of OpenStudio model and apply ev_percent (number of vehicles is assumed to be the same as occupancy of the building).
+ end
+ else
+ for i in 0..sun_load[0].length - 1
+ avg_load_sun[i] = (sun_load_sel[i].reduce(0, :+) / sun_load_sel[i].length) * ev_percent / assumed_percent # Scale profiles generated from 50% EV scenario by % of vehicles that are EVs.
+ end
end
sun_max_load = avg_load_sun.max
# Calculate the overall maximum load