Skip to content

Commit

Permalink
Merge pull request #1317 from NREL/ll/test_breaker_space
Browse files Browse the repository at this point in the history
Ll/test breaker space
  • Loading branch information
yingli-NREL authored Nov 5, 2024
2 parents c710d4a + 868e9de commit d608113
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 5 deletions.
5 changes: 3 additions & 2 deletions measures/ResStockArguments/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -845,8 +845,9 @@ def run(model, runner, user_arguments)
args[:electric_panel_service_rating] = cap_val

# FIXME: uncomment these once we pull in OS-HPXML's electric_panel branch
# args[:electric_panel_breaker_spaces_type] = 'headroom'
# args[:electric_panel_breaker_spaces] = breaker_spaces # Yingli
breaker_spaces_headroom = capacity_sampler.assign_breaker_spaces_headroom(args: args)
args[:electric_panel_breaker_spaces_type] = 'headroom'
args[:electric_panel_breaker_spaces] = breaker_spaces_headroom

# Register values to runner
args.each do |arg_name, arg_value|
Expand Down
8 changes: 6 additions & 2 deletions measures/ResStockArguments/resources/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,15 @@ module Constants
ArgumentsToRegister = ['heating_unavailable_period',
'cooling_unavailable_period',
'electric_panel_service_rating_bin',
'electric_panel_service_rating']
'electric_panel_service_rating',
'electric_panel_breaker_spaces_type',
'electric_panel_breaker_spaces']

# List of ResStockArguments arguments; will not be passed into BuildResidentialHPXML
ArgumentsToExclude = ['heating_unavailable_period',
'cooling_unavailable_period',
'electric_panel_service_rating_bin',
'electric_panel_service_rating'] # FIXME: temporarily exclude this last one until we pull in OS-HPXML's electric_panel branch
'electric_panel_service_rating',
'electric_panel_breaker_spaces_type',
'electric_panel_breaker_spaces'] # FIXME: temporarily exclude this last one until we pull in OS-HPXML's electric_panel branch
end
150 changes: 149 additions & 1 deletion measures/ResStockArguments/resources/electrical_panel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ def assign_rated_capacity(args:)
return capacity_bin, capacity_value
end

def assign_breaker_spaces_headroom(args:)
# initialize a random number generator
prng = Random.new(args[:building_id])

# load probability distribution csv
breaker_spaces_headroom_prob_map = read_breaker_spaces_headroom_probs()

# assign breaker space headroom number
breaker_spaces_headroom = sample_breaker_spaces_headroom(prng, breaker_spaces_headroom_prob_map, args)

return breaker_spaces_headroom
end

def sample_rated_capacity_bin(prng, rated_capacity_map, args)
# emulate Geometry Building Type RECS
geometry_building_type_recs = convert_building_type(args[:geometry_unit_type], args[:geometry_building_num_units])
Expand Down Expand Up @@ -65,6 +78,23 @@ def sample_rated_capacity_bin(prng, rated_capacity_map, args)
return capacity_bins[index]
end

def sample_breaker_spaces_headroom(prng, breaker_spaces_headroom_prob_map, args)
# calculate number of major electric load
major_elec_load_count = get_major_elec_load_count(args)
# get panel capacity bin
capacity_bin = args[:electric_panel_service_rating_bin]

lookup_array = [
major_elec_load_count.to_s,
capacity_bin.to_s,
]

breaker_spaces_headroom = get_row_headers_breaker_spaces_headroom(breaker_spaces_headroom_prob_map, lookup_array)
row_probability = get_row_probability_breaker_spaces_headroom(breaker_spaces_headroom_prob_map, lookup_array)
index = weighted_random(prng, row_probability)
return breaker_spaces_headroom[index]
end

def convert_capacity_bin_to_value(capacity_bin, heating_system_fuel, geometry_unit_cfa_bin)
if capacity_bin == '<100'
if heating_system_fuel == HPXML::FuelTypeElectricity
Expand Down Expand Up @@ -100,12 +130,25 @@ def read_rated_capacity_probs(heating_system_fuel)
return prob_table
end

def read_breaker_spaces_headroom_probs()
filename = 'electrical_panel_breaker_space.csv'
file = File.absolute_path(File.join(File.dirname(__FILE__), 'electrical_panel_resources', filename))
prob_table = CSV.read(file)
return prob_table
end

def get_row_headers(prob_table, lookup_array)
len = lookup_array.length()
row_headers = prob_table[0][len..len + 7]
return row_headers
end

def get_row_headers_breaker_spaces_headroom(prob_table, lookup_array)
len = lookup_array.length()
row_headers = prob_table[0][len..len + 32]
return row_headers
end

def get_row_probability(prob_table, lookup_array)
len = lookup_array.length()
row_probability = []
Expand All @@ -121,6 +164,21 @@ def get_row_probability(prob_table, lookup_array)
return row_probability
end

def get_row_probability_breaker_spaces_headroom(prob_table, lookup_array)
len = lookup_array.length()
row_probability = []
prob_table.each do |row|
next if row[0..len - 1] != lookup_array

row_probability = row[len..len + 32].map(&:to_f)
end

if row_probability.length() != 32
@runner.registerError("BreakerSpacesHeadroomGenerator cannot find row_probability for keys: #{lookup_array}")
end
return row_probability
end

def weighted_random(prng, weights)
n = prng.rand
cum_weights = 0
Expand Down Expand Up @@ -164,8 +222,24 @@ def convert_cooling_type(cooling_system_type, heat_pump_type)
end
end

def has_cooling(hvac_cooling_type)
if hvac_cooling_type != 'none'
return 1
else
return 0
end
end

def is_ducted_heat_pump_heating(heat_pump_type)
if [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpGroundToAir].include?(heat_pump_type)
return true
else
return false
end
end

def convert_fuel_and_presence(equipment_present, fuel_type)
if equipment_present == 'false'
if equipment_present == false
return 'none'
else
return simplify_fuel_type(fuel_type)
Expand All @@ -179,4 +253,78 @@ def simplify_fuel_type(fuel_type)
return 'non-electricity'
end
end

def get_major_elec_load_count(args)
# has electric primary heating
has_elec_heating_primary = is_electric_fuel(args[:heating_system_fuel])
# has electric water heater
has_elec_water_heater = is_electric_fuel(args[:water_heater_fuel_type])
# has cooling
hvac_cooling_type = convert_cooling_type(args[:cooling_system_type], args[:heat_pump_type])
has_cooling = has_cooling(hvac_cooling_type)
# appliance presence and electric fuel
has_elec_drying = electric_fuel_and_presence(args[:clothes_dryer_present], args[:clothes_dryer_fuel_type])
has_elec_cooking = electric_fuel_and_presence(args[:cooking_range_oven_present], args[:cooking_range_fuel_type])
# has pv
has_pv = has_pv(args[:pv_system_present])
# has ev charging
has_ev_charging = 0 #TODO: connect with args[:ev_charger_present] when PR 1299 is merged

load_vars = [
has_elec_heating_primary,
has_elec_water_heater,
has_elec_drying,
has_elec_cooking,
has_cooling,
has_ev_charging,
has_pv
]
# The maximum load_count is 7.
# The calculation of load_count is based on the available information of training data, not the real load count in the model.
load_count = load_vars.sum

load_count = load_count_hvac_adjustment(load_count, args)
return load_count
end

def electric_fuel_and_presence(equipment_present, fuel_type)
if equipment_present == false
return 0
else
return is_electric_fuel(fuel_type)
end
end

def is_electric_fuel(fuel_type)
if fuel_type == HPXML::FuelTypeElectricity
return 1
else
return 0
end
end

def has_pv(pv_system_present)
if pv_system_present
return 1
else
return 0
end
end

def load_count_hvac_adjustment(load_count, args)
# emulate HVAC Heating Type
is_ducted_heat_pump_heating = is_ducted_heat_pump_heating(args[:heat_pump_type]) # ASHP or GHP
# emulate HVAC Cooling Type
hvac_cooling_type = convert_cooling_type(args[:cooling_system_type], args[:heat_pump_type])

#Count ducted heat pump only once if it provides heating and cooling
if hvac_cooling_type == "heat pump" and is_ducted_heat_pump_heating == true
load_count = load_count - 1 #Assuming a single ducted heat pump provides heating and cooling
#Don't count plug-in Room ACs as major loads
elsif hvac_cooling_type == HPXML::HVACTypeRoomAirConditioner
load_count = load_count - 1
end
return load_count
end

end
Loading

0 comments on commit d608113

Please sign in to comment.