diff --git a/BuildResidentialHPXML/README.md b/BuildResidentialHPXML/README.md index 75ac79c0cb..c6934a484c 100644 --- a/BuildResidentialHPXML/README.md +++ b/BuildResidentialHPXML/README.md @@ -2777,7 +2777,7 @@ Pipe diameter of the geothermal loop. Only applies to ground-to-air heat pump ty **Heating System 2: Type** -The type of the second heating system. +The type of the second heating system. If a heat pump is specified and the backup type is 'separate', this heating system represents 'separate' backup heating. For ducted heat pumps where the backup heating system is a 'Furnace', the backup would typically be characterized as 'integrated' in that the furnace and heat pump share the same distribution system and blower fan; a 'Furnace' as 'separate' backup to a ducted heat pump is not supported. - **Name:** ``heating_system_2_type`` - **Type:** ``Choice`` diff --git a/BuildResidentialHPXML/measure.rb b/BuildResidentialHPXML/measure.rb index 5e0a8d19e1..782fbaad2f 100644 --- a/BuildResidentialHPXML/measure.rb +++ b/BuildResidentialHPXML/measure.rb @@ -1674,7 +1674,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heating_system_2_type', heating_system_2_type_choices, true) arg.setDisplayName('Heating System 2: Type') - arg.setDescription('The type of the second heating system.') + arg.setDescription("The type of the second heating system. If a heat pump is specified and the backup type is '#{HPXML::HeatPumpBackupTypeSeparate}', this heating system represents '#{HPXML::HeatPumpBackupTypeSeparate}' backup heating. For ducted heat pumps where the backup heating system is a '#{HPXML::HVACTypeFurnace}', the backup would typically be characterized as '#{HPXML::HeatPumpBackupTypeIntegrated}' in that the furnace and heat pump share the same distribution system and blower fan; a '#{HPXML::HVACTypeFurnace}' as '#{HPXML::HeatPumpBackupTypeSeparate}' backup to a ducted heat pump is not supported.") arg.setDefaultValue('none') args << arg @@ -3798,8 +3798,8 @@ module HPXMLFile # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param args [Hash] Map of :argument_name => value # @param epw_path [String] Path to the EPW weather file - # @param hpxml_path [TODO] TODO - # @param existing_hpxml_path [TODO] TODO + # @param hpxml_path [String] Path to the created HPXML file + # @param existing_hpxml_path [String] Path to the existing HPXML file # @return [Oga::XML::Element] Root XML element of the updated HPXML document def self.create(runner, model, args, epw_path, hpxml_path, existing_hpxml_path) if need_weather_based_on_args(args) @@ -3926,7 +3926,7 @@ def self.need_weather_based_on_args(args) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param hpxml [HPXML] HPXML object # @param hpxml_doc [Oga::XML::Element] Root XML element of the HPXML document - # @param hpxml_path [TODO] TODO + # @param hpxml_path [String] Path to the created HPXML file # @return [Boolean] True if the HPXML is valid def self.validate_hpxml(runner, hpxml, hpxml_doc, hpxml_path) # Check for errors in the HPXML object @@ -4517,7 +4517,7 @@ def self.add_building(hpxml, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_site(hpxml_bldg, args) hpxml_bldg.site.shielding_of_home = args[:site_shielding_of_home] hpxml_bldg.site.ground_conductivity = args[:site_ground_conductivity] @@ -4572,7 +4572,7 @@ def self.set_site(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_neighbor_buildings(hpxml_bldg, args) nbr_map = { Constants.FacadeFront => [args[:neighbor_front_distance], args[:neighbor_front_height]], Constants.FacadeBack => [args[:neighbor_back_distance], args[:neighbor_back_height]], @@ -4601,7 +4601,7 @@ def self.set_neighbor_buildings(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_building_occupancy(hpxml_bldg, args) hpxml_bldg.building_occupancy.number_of_residents = args[:geometry_unit_num_occupants] hpxml_bldg.building_occupancy.general_water_use_usage_multiplier = args[:general_water_use_usage_multiplier] @@ -4619,7 +4619,7 @@ def self.set_building_occupancy(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_building_construction(hpxml_bldg, args) if args[:geometry_unit_type] == HPXML::ResidentialTypeApartment args[:geometry_unit_num_floors_above_grade] = 1 @@ -4652,7 +4652,7 @@ def self.set_building_construction(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_building_header(hpxml_bldg, args) if not args[:schedules_filepaths].nil? hpxml_bldg.header.schedules_filepaths = args[:schedules_filepaths].split(',').map(&:strip) @@ -4685,7 +4685,7 @@ def self.set_building_header(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_climate_and_risk_zones(hpxml_bldg, args) hpxml_bldg.climate_and_risk_zones.weather_station_id = 'WeatherStation' @@ -4707,7 +4707,7 @@ def self.set_climate_and_risk_zones(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_air_infiltration_measurements(hpxml_bldg, args) if args[:air_leakage_value] if args[:air_leakage_units] == HPXML::UnitsELA @@ -4753,7 +4753,7 @@ def self.set_air_infiltration_measurements(hpxml_bldg, args) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value # @param sorted_surfaces [Array] surfaces sorted by deterministically assigned Index - # @return [void] + # @return [nil] def self.set_roofs(hpxml_bldg, args, sorted_surfaces) args[:geometry_roof_pitch] *= 12.0 if (args[:geometry_attic_type] == HPXML::AtticTypeFlatRoof) || (args[:geometry_attic_type] == HPXML::AtticTypeBelowApartment) @@ -4802,7 +4802,7 @@ def self.set_roofs(hpxml_bldg, args, sorted_surfaces) # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param args [Hash] Map of :argument_name => value # @param sorted_surfaces [Array] surfaces sorted by deterministically assigned Index - # @return [void] + # @return [nil] def self.set_rim_joists(hpxml_bldg, model, args, sorted_surfaces) sorted_surfaces.each do |surface| next if surface.surfaceType != 'Wall' @@ -4865,7 +4865,7 @@ def self.set_rim_joists(hpxml_bldg, model, args, sorted_surfaces) # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param args [Hash] Map of :argument_name => value # @param sorted_surfaces [Array] surfaces sorted by deterministically assigned Index - # @return [void] + # @return [nil] def self.set_walls(hpxml_bldg, model, args, sorted_surfaces) sorted_surfaces.each do |surface| next if surface.surfaceType != 'Wall' @@ -4959,7 +4959,7 @@ def self.set_walls(hpxml_bldg, model, args, sorted_surfaces) # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param args [Hash] Map of :argument_name => value # @param sorted_surfaces [Array] surfaces sorted by deterministically assigned Index - # @return [void] + # @return [nil] def self.set_foundation_walls(hpxml_bldg, model, args, sorted_surfaces) sorted_surfaces.each do |surface| next if surface.surfaceType != 'Wall' @@ -5046,7 +5046,7 @@ def self.set_foundation_walls(hpxml_bldg, model, args, sorted_surfaces) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value # @param sorted_surfaces [Array] surfaces sorted by deterministically assigned Index - # @return [void] + # @return [nil] def self.set_floors(hpxml_bldg, args, sorted_surfaces) if [HPXML::FoundationTypeBasementConditioned, HPXML::FoundationTypeCrawlspaceConditioned].include?(args[:geometry_foundation_type]) && (args[:floor_over_foundation_assembly_r] > 2.1) @@ -5129,7 +5129,7 @@ def self.set_floors(hpxml_bldg, args, sorted_surfaces) # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param args [Hash] Map of :argument_name => value # @param sorted_surfaces [Array] surfaces sorted by deterministically assigned Index - # @return [void] + # @return [nil] def self.set_slabs(hpxml_bldg, model, args, sorted_surfaces) sorted_surfaces.each do |surface| next unless ['Foundation'].include? surface.outsideBoundaryCondition @@ -5200,7 +5200,7 @@ def self.set_slabs(hpxml_bldg, model, args, sorted_surfaces) # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param args [Hash] Map of :argument_name => value # @param sorted_subsurfaces [Array] subsurfaces sorted by deterministically assigned Index - # @return [void] + # @return [nil] def self.set_windows(hpxml_bldg, model, args, sorted_subsurfaces) sorted_subsurfaces.each do |sub_surface| next if sub_surface.subSurfaceType != 'FixedWindow' @@ -5277,7 +5277,7 @@ def self.set_windows(hpxml_bldg, model, args, sorted_subsurfaces) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value # @param sorted_subsurfaces [Array] subsurfaces sorted by deterministically assigned Index - # @return [void] + # @return [nil] def self.set_skylights(hpxml_bldg, args, sorted_subsurfaces) sorted_subsurfaces.each do |sub_surface| next if sub_surface.subSurfaceType != 'Skylight' @@ -5318,7 +5318,7 @@ def self.set_skylights(hpxml_bldg, args, sorted_subsurfaces) # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param args [Hash] Map of :argument_name => value # @param sorted_subsurfaces [Array] subsurfaces sorted by deterministically assigned Index - # @return [void] + # @return [nil] def self.set_doors(hpxml_bldg, model, args, sorted_subsurfaces) sorted_subsurfaces.each do |sub_surface| next if sub_surface.subSurfaceType != 'Door' @@ -5349,7 +5349,7 @@ def self.set_doors(hpxml_bldg, model, args, sorted_subsurfaces) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_attics(hpxml_bldg, args) surf_ids = { 'roofs' => { 'surfaces' => hpxml_bldg.roofs, 'ids' => [] }, 'walls' => { 'surfaces' => hpxml_bldg.walls, 'ids' => [] }, @@ -5387,7 +5387,7 @@ def self.set_attics(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_foundations(hpxml_bldg, args) surf_ids = { 'slabs' => { 'surfaces' => hpxml_bldg.slabs, 'ids' => [] }, 'floors' => { 'surfaces' => hpxml_bldg.floors, 'ids' => [] }, @@ -5446,7 +5446,7 @@ def self.set_foundations(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_heating_systems(hpxml_bldg, args) heating_system_type = args[:heating_system_type] @@ -5520,7 +5520,7 @@ def self.set_heating_systems(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_cooling_systems(hpxml_bldg, args) cooling_system_type = args[:cooling_system_type] @@ -5639,7 +5639,7 @@ def self.set_cooling_systems(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_heat_pumps(hpxml_bldg, args) heat_pump_type = args[:heat_pump_type] @@ -5828,7 +5828,7 @@ def self.set_heat_pumps(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_geothermal_loop(hpxml_bldg, args) return if hpxml_bldg.heat_pumps.select { |hp| hp.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir }.size == 0 return if args[:geothermal_loop_configuration].nil? || args[:geothermal_loop_configuration] == 'none' @@ -5867,7 +5867,7 @@ def self.set_geothermal_loop(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_secondary_heating_systems(hpxml_bldg, args) heating_system_type = args[:heating_system_2_type] heating_system_is_heatpump_backup = (args[:heat_pump_type] != 'none' && args[:heat_pump_backup_type] == HPXML::HeatPumpBackupTypeSeparate) @@ -5910,7 +5910,7 @@ def self.set_secondary_heating_systems(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_hvac_distribution(hpxml_bldg, args) # HydronicDistribution? hpxml_bldg.heating_systems.each do |heating_system| @@ -5993,7 +5993,7 @@ def self.set_hvac_distribution(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_hvac_blower(hpxml_bldg, args) # Blower fan W/cfm hpxml_bldg.hvac_systems.each do |hvac_system| @@ -6023,7 +6023,7 @@ def self.set_hvac_blower(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_duct_leakages(args, hvac_distribution) hvac_distribution.duct_leakage_measurements.add(duct_type: HPXML::DuctTypeSupply, duct_leakage_units: args[:ducts_leakage_units], @@ -6041,7 +6041,7 @@ def self.set_duct_leakages(args, hvac_distribution) # @param location [String] the general HPXML location (crawlspace or attic) # @param foundation_type [String] the specific HPXML foundation type (unvented crawlspace, vented crawlspace, conditioned crawlspace) # @param attic_type [String] the specific HPXML attic type (unvented attic, vented attic, conditioned attic) - # @return [void] + # @return [nil] def self.get_location(location, foundation_type, attic_type) return if location.nil? @@ -6078,7 +6078,7 @@ def self.get_location(location, foundation_type, attic_type) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value # @param hvac_distribution [HPXML::HVACDistribution] HPXML HVAC Distribution object - # @return [void] + # @return [nil] def self.set_ducts(hpxml_bldg, args, hvac_distribution) ducts_supply_location = get_location(args[:ducts_supply_location], hpxml_bldg.foundations[-1].foundation_type, hpxml_bldg.attics[-1].attic_type) ducts_return_location = get_location(args[:ducts_return_location], hpxml_bldg.foundations[-1].foundation_type, hpxml_bldg.attics[-1].attic_type) @@ -6196,7 +6196,7 @@ def self.set_ducts(hpxml_bldg, args, hvac_distribution) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value # @param weather [WeatherFile] Weather object containing EPW information - # @return [void] + # @return [nil] def self.set_hvac_control(hpxml, hpxml_bldg, args, weather) return if (args[:heating_system_type] == 'none') && (args[:cooling_system_type] == 'none') && (args[:heat_pump_type] == 'none') @@ -6297,7 +6297,7 @@ def self.set_hvac_control(hpxml, hpxml_bldg, args, weather) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_ventilation_fans(hpxml_bldg, args) if args[:mech_vent_fan_type] != 'none' @@ -6439,7 +6439,7 @@ def self.set_ventilation_fans(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_water_heating_systems(hpxml_bldg, args) water_heater_type = args[:water_heater_type] return if water_heater_type == 'none' @@ -6557,7 +6557,7 @@ def self.set_water_heating_systems(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_hot_water_distribution(hpxml_bldg, args) return if args[:water_heater_type] == 'none' @@ -6595,7 +6595,7 @@ def self.set_hot_water_distribution(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_water_fixtures(hpxml_bldg, args) return if args[:water_heater_type] == 'none' @@ -6619,7 +6619,7 @@ def self.set_water_fixtures(hpxml_bldg, args) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value # @param weather [WeatherFile] Weather object containing EPW information - # @return [void] + # @return [nil] def self.set_solar_thermal(hpxml_bldg, args, weather) return if args[:solar_thermal_system_type] == 'none' @@ -6669,7 +6669,7 @@ def self.set_solar_thermal(hpxml_bldg, args, weather) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value # @param weather [WeatherFile] Weather object containing EPW information - # @return [void] + # @return [nil] def self.set_pv_systems(hpxml_bldg, args, weather) return unless args[:pv_system_present] @@ -6723,7 +6723,7 @@ def self.set_pv_systems(hpxml_bldg, args, weather) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_battery(hpxml_bldg, args) return unless args[:battery_present] @@ -6754,7 +6754,7 @@ def self.set_battery(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_lighting(hpxml_bldg, args) if args[:lighting_present] has_garage = (args[:geometry_garage_width] * args[:geometry_garage_depth] > 0) @@ -6839,7 +6839,7 @@ def self.set_lighting(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_dehumidifier(hpxml_bldg, args) return if args[:dehumidifier_type] == 'none' @@ -6870,7 +6870,7 @@ def self.set_dehumidifier(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_clothes_washer(hpxml_bldg, args) return if args[:water_heater_type] == 'none' return unless args[:clothes_washer_present] @@ -6903,7 +6903,7 @@ def self.set_clothes_washer(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_clothes_dryer(hpxml_bldg, args) return if args[:water_heater_type] == 'none' return unless args[:clothes_washer_present] @@ -6944,7 +6944,7 @@ def self.set_clothes_dryer(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_dishwasher(hpxml_bldg, args) return if args[:water_heater_type] == 'none' return unless args[:dishwasher_present] @@ -6974,7 +6974,7 @@ def self.set_dishwasher(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_refrigerator(hpxml_bldg, args) return unless args[:refrigerator_present] @@ -6991,7 +6991,7 @@ def self.set_refrigerator(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_extra_refrigerator(hpxml_bldg, args) return unless args[:extra_refrigerator_present] @@ -7010,7 +7010,7 @@ def self.set_extra_refrigerator(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_freezer(hpxml_bldg, args) return unless args[:freezer_present] @@ -7027,7 +7027,7 @@ def self.set_freezer(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_cooking_range_oven(hpxml_bldg, args) return unless args[:cooking_range_oven_present] @@ -7048,7 +7048,7 @@ def self.set_cooking_range_oven(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_ceiling_fans(hpxml_bldg, args) return unless args[:ceiling_fan_present] @@ -7064,7 +7064,7 @@ def self.set_ceiling_fans(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_misc_plug_loads_television(hpxml_bldg, args) return unless args[:misc_plug_loads_television_present] @@ -7081,7 +7081,7 @@ def self.set_misc_plug_loads_television(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_misc_plug_loads_other(hpxml_bldg, args) hpxml_bldg.plug_loads.add(id: "PlugLoad#{hpxml_bldg.plug_loads.size + 1}", plug_load_type: HPXML::PlugLoadTypeOther, @@ -7097,7 +7097,7 @@ def self.set_misc_plug_loads_other(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_misc_plug_loads_well_pump(hpxml_bldg, args) return unless args[:misc_plug_loads_well_pump_present] @@ -7113,7 +7113,7 @@ def self.set_misc_plug_loads_well_pump(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_misc_plug_loads_vehicle(hpxml_bldg, args) return unless args[:misc_plug_loads_vehicle_present] @@ -7130,7 +7130,7 @@ def self.set_misc_plug_loads_vehicle(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_misc_fuel_loads_grill(hpxml_bldg, args) return unless args[:misc_fuel_loads_grill_present] @@ -7148,7 +7148,7 @@ def self.set_misc_fuel_loads_grill(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_misc_fuel_loads_lighting(hpxml_bldg, args) return unless args[:misc_fuel_loads_lighting_present] @@ -7167,7 +7167,7 @@ def self.set_misc_fuel_loads_lighting(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_misc_fuel_loads_fireplace(hpxml_bldg, args) return unless args[:misc_fuel_loads_fireplace_present] @@ -7189,7 +7189,7 @@ def self.set_misc_fuel_loads_fireplace(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_pool(hpxml_bldg, args) return unless args[:pool_present] @@ -7227,7 +7227,7 @@ def self.set_pool(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.set_permanent_spa(hpxml_bldg, args) return unless args[:permanent_spa_present] @@ -7260,7 +7260,7 @@ def self.set_permanent_spa(hpxml_bldg, args) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param args [Hash] Map of :argument_name => value - # @return [void] + # @return [nil] def self.collapse_surfaces(hpxml_bldg, args) if args[:combine_like_surfaces] # Collapse some surfaces whose azimuth is a minor effect to simplify HPXMLs. @@ -7285,7 +7285,7 @@ def self.collapse_surfaces(hpxml_bldg, args) # After having collapsed some surfaces, renumber SystemIdentifier ids and AttachedToXXX idrefs. # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.renumber_hpxml_ids(hpxml_bldg) # Renumber surfaces indexes = {} diff --git a/BuildResidentialHPXML/measure.xml b/BuildResidentialHPXML/measure.xml index 3b50b11bf5..595f7f30f0 100644 --- a/BuildResidentialHPXML/measure.xml +++ b/BuildResidentialHPXML/measure.xml @@ -3,8 +3,8 @@ 3.1 build_residential_hpxml a13a8983-2b01-4930-8af2-42030b6e4233 - 8d558b94-90a7-4f68-86a0-8f80b41ddbb5 - 2024-08-06T22:34:22Z + ffacf8b9-4562-4319-ab8a-f4a63fc0126f + 2024-08-16T19:31:29Z 2C38F48B BuildResidentialHPXML HPXML Builder @@ -3359,7 +3359,7 @@ heating_system_2_type Heating System 2: Type - The type of the second heating system. + The type of the second heating system. If a heat pump is specified and the backup type is 'separate', this heating system represents 'separate' backup heating. For ducted heat pumps where the backup heating system is a 'Furnace', the backup would typically be characterized as 'integrated' in that the furnace and heat pump share the same distribution system and blower fan; a 'Furnace' as 'separate' backup to a ducted heat pump is not supported. Choice true false @@ -7389,7 +7389,7 @@ README.md md readme - B702F428 + FCAE28E2 README.md.erb @@ -7406,13 +7406,13 @@ measure.rb rb script - 0472491B + 3E87E8F5 geometry.rb rb resource - 2764D675 + 523DF705 test_build_residential_hpxml.rb diff --git a/BuildResidentialHPXML/resources/geometry.rb b/BuildResidentialHPXML/resources/geometry.rb index b095a2e627..313889fb05 100644 --- a/BuildResidentialHPXML/resources/geometry.rb +++ b/BuildResidentialHPXML/resources/geometry.rb @@ -1919,7 +1919,7 @@ def self.get_abs_azimuth(relative_azimuth:, # @param space [OpenStudio::Model::Space] the foundation space adjacent to the rim joist # @param rim_joist_height [Double] height of the rim joists (ft) # @param z [Double] z coordinate of the bottom of the rim joists - # @return [void] + # @return [nil] def self.add_rim_joist(model:, polygon:, space:, @@ -1963,7 +1963,7 @@ def self.add_rim_joist(model:, # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param footprint_polygon [OpenStudio::Point3dVector] an OpenStudio::Point3dVector object # @param space [OpenStudio::Model::Space] an OpenStudio::Model::Space object - # @return [void] + # @return [nil] def self.assign_indexes(model:, footprint_polygon:, space:) @@ -2010,7 +2010,7 @@ def self.assign_indexes(model:, # We can't deterministically assign indexes to these surfaces. # # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @return [void] + # @return [nil] def self.assign_remaining_surface_indexes(model:) model.getSurfaces.each do |surface| next if surface.additionalProperties.getFeatureAsInteger('Index').is_initialized @@ -2273,7 +2273,7 @@ def self.add_windows_to_wall(surface:, # @param win_num [Integer] The window number for the current surface # @param facade [String] front, back, left, or right # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @return [void] + # @return [nil] def self.add_window_to_wall(surface:, win_width:, win_height:, @@ -2535,7 +2535,7 @@ def self.get_attic_space(model:, # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param foundation_type [String] HPXML location for foundation type # @param foundation_height [Double] height of the foundation (m) - # @return [void] + # @return [nil] def self.apply_ambient_foundation_shift(model:, foundation_type:, foundation_height:) diff --git a/BuildResidentialScheduleFile/measure.rb b/BuildResidentialScheduleFile/measure.rb index da1fd23a86..b800842228 100644 --- a/BuildResidentialScheduleFile/measure.rb +++ b/BuildResidentialScheduleFile/measure.rb @@ -178,8 +178,8 @@ def run(model, runner, user_arguments) # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param doc [Oga::XML::Document] Oga XML Document object - # @param hpxml_path [String] path of the input HPXML file - # @param hpxml_output_path [String] path of the output HPXML file + # @param hpxml_path [String] Path to the HPXML file + # @param hpxml_output_path [String] Path to the output HPXML file # @param schedules_filepaths [Array] array of SchedulesFilePath strings in the input HPXML file # @param args [Hash] Map of :argument_name => value def write_modified_hpxml(runner, doc, hpxml_path, hpxml_output_path, schedules_filepaths, args) diff --git a/BuildResidentialScheduleFile/measure.xml b/BuildResidentialScheduleFile/measure.xml index 4e420e58e0..23e77c34e2 100644 --- a/BuildResidentialScheduleFile/measure.xml +++ b/BuildResidentialScheduleFile/measure.xml @@ -3,8 +3,8 @@ 3.1 build_residential_schedule_file f770b2db-1a9f-4e99-99a7-7f3161a594b1 - 82cc5cf7-51fc-435c-9ea1-429bf4b72080 - 2024-07-15T21:48:21Z + c82306e3-de8f-4659-b356-4e9cd05205e1 + 2024-08-16T19:20:19Z 03F02484 BuildResidentialScheduleFile Schedule File Builder @@ -133,13 +133,13 @@ measure.rb rb script - D2B0EB5F + 038D2D11 README.md md resource - 08194138 + 7060BE69 clothes_dryer_consumption_dist.csv @@ -169,7 +169,7 @@ constants.rb rb resource - B2B70AD9 + 962DC751 cooking_consumption_dist.csv @@ -220,16 +220,16 @@ 419E598E - schedules.rb - rb + schedules.csv + csv resource - A0CC250C + 7B6640FE - schedules_config.md - md + schedules.rb + rb resource - 916BF4C3 + 25A966F4 shower_cluster_size_probability.csv diff --git a/BuildResidentialScheduleFile/resources/README.md b/BuildResidentialScheduleFile/resources/README.md index 08326521c9..2561418635 100644 --- a/BuildResidentialScheduleFile/resources/README.md +++ b/BuildResidentialScheduleFile/resources/README.md @@ -1,9 +1,16 @@ -Stochastic Occupancy Modeling introduces major changes to most occupant-related schedules. -Occupant activities are now generated on-the-fly and saved to CSV files used by `OpenStudio` Schedule:File objects. +# Stochastic Occupancy Modeling + +The `BuildResidentialScheduleFile` measure introduces major changes to most occupant-related schedules. + +## Overview + +Occupant activities are now generated on-the-fly and saved to CSV files used by OpenStudio/EnergyPlus `Schedule:File` objects. Schedules are generated using time-inhomogenous Markov chains derived from American Time Use Survey data, supplemented with sampling duration and power level from NEEA RBSA data, as well as DHW draw duration and flow rate data from Aquacraft/AWWA data. See [Stochastic simulation of occupant-driven energy use in a bottom-up residential building stock model](https://www.sciencedirect.com/science/article/pii/S0306261922011540) for a more complete description of the methodology. -The `BuildResidentialScheduleFile` measure outputs a schedule CSV file (available inside the `run` folder of each building simulation output). +## Outputs + +The `BuildResidentialScheduleFile` measure outputs schedule CSV files (available inside the `run` folder of each building simulation output). The schedule CSV file contains the following columns: * `occupants` * `lighting_interior` @@ -27,42 +34,108 @@ The `sleeping` column represents the fractional percent of the total number of o There are the same number of rows as the total simulation time-step (e.g., 35040 if 15-min, 8760 if hourly [8784, if leap year]). -The `ScheduleGenerator` class uses Markov chain based simulation to generate the schedule.csv. +## The `ScheduleGenerator` + +This class uses Markov chain based simulation to generate the schedule CSV files. To support that, several pre-generated set of files are used, contained in the following folders: * `weekday` * `weekend` -These two folders contain the Markov chain initial probability, Markov chain transition and also appliance duration probabilities csv files. +These two folders contain the Markov chain initial probability, Markov chain transition and also appliance duration probabilities CSV files. The appliance duration probabilities here are used during the Markov chain simulation to determine duration of various appliances. The files are divided into four clusters (cluster0 to cluster3), for 4 occupant behavior types. -`_consumption_dist.csv` +The following sections describe the remaining files found in the schedule generator resources folder. + +### `_consumption_dist.csv` These files contain the 15-min power consumption kWh samples for the given end use, obtained from RBSA (average 15-min end use kWh for each submetered home; N=number of homes with that end use). The schedule generator randomly picks one of these values to determine the power level of the appliance schedule. -`_duration_dist.csv` +Here, `` may be: +* `clothes_dryer` +* `clothes_washer` +* `cooking` +* `dishwasher` + +### `_duration_dist.csv` These files contain the samples of runtime duration of different end uses, in 15-min increments, generated from the RBSA dataset. So, a value of 3 means 45 minutes. Each row is for one household, and each column is the duration of one instance of the appliance running. -For the above `_consumption_dist.csv` and `_duration_dist.csv` files, `` may be: +Again, `` may be: * `clothes_dryer` * `clothes_washer` * `cooking` * `dishwasher` -`_cluster_size_probability.csv` +### `_cluster_size_probability.csv` These files contain the probability distribution of the event cluster size for different domestic hot water end uses, obtained from the HotWaterEventScheduleGenerator Excel file. The first row is the probability of a cluster size of 1 event, second row for probability of cluster size of 2 events and so on. -For the above `_cluster_size_probability.csv` files, `` may be: +Here, `` may be: * `hot_water_clothes_washer` * `hot_water_dishwasher` * `shower` -`constants.rb` +### `_event_duration_probability.csv` + +TODO + +Again, `` may be: +* `hot_water_clothes_washer` +* `hot_water_dishwasher` +* `shower` + +### `constants.rb` and `schedules.csv` + +These files contain various miscellaneous configurations for the schedule generator. +Their meanings and sources are defined below. + +#### Occupancy Types + +Occupancy cluster types: Mostly Home, Early Regular Worker, Mostly Away, Regular Worker. +Probabilities are derived from ATUS using the k-modes algorithm. + +#### Plug Loads + +This is the baseline schedule for misc plugload, lighting and ceiling fan. +It will be modified based on occupancy. +Television plugload uses the same schedule as misc plugload. + +#### Lighting + +Indoor lighting schedule is generated on the fly. +Garage lighting uses the same schedule as indoor lighting. + +#### Cooking + +Monthly energy use multipliers for cooking stove/oven/range from average of multiple end-use submetering datasets (HEMS, RBSAM, ELCAP, Mass Res 1, Pecan St.). +Power draw distribution is based on csv files. + +#### Clothes Dryer + +Monthly energy use multipliers for clothes dryer from average of multiple end-use submetering datasets (HEMS, RBSAM, ELCAP, Mass Res 1, Pecan St., FSEC). +Power draw distribution is based on csv files. + +#### Clothes Washer + +Monthly energy use multipliers for clothes washer and dishwasher from average of multiple end-use submetering datasets (generally HEMS, RBSAM, ELCAP, Mass Res 1, and Pecan St.). +Power draw distribution is based on csv files. + +#### Dishwasher + +Monthly energy use multipliers for clothes washer and dishwasher from average of multiple end-use submetering datasets (generally HEMS, RBSAM, ELCAP, Mass Res 1, Pecan St., and FSEC). +Power draw distribution is based on csv files. + +#### Water Draw Events + +Probabilities for all water draw events are extracted from DHW event generators. +The onset, duration, events_per_cluster_probs, flow rate mean and std could all refer to the DHW event generator excel sheet ('event characteristics' and 'Start Times' sheet). + +#### Sink -This file contains various miscellaneous configurations for the schedule generator, and their meanings and sources are defined within the file. +avg_sink_clusters_per_hh -> Average sink cluster per house hold. Set to 6657 for U.S. average of 2.53 occupants per household, based on relationship of 6885 clusters for 25 gpd, from Building America DHW Event Schedule Generator, +Set to 6657 for U.S. average of 2.53 occupants per household, based on relationship of 6885 clusters for 25 gpd, from Building America DHW Event Schedule Generator. diff --git a/BuildResidentialScheduleFile/resources/constants.rb b/BuildResidentialScheduleFile/resources/constants.rb index e506c0d02e..2df36a4768 100644 --- a/BuildResidentialScheduleFile/resources/constants.rb +++ b/BuildResidentialScheduleFile/resources/constants.rb @@ -4,225 +4,162 @@ module Constants # TODO # - # @return [TODO] TODO + # @return [String] TODO def self.OccupancyTypesProbabilities return '0.381, 0.297, 0.165, 0.157' end # TODO # - # @return [TODO] TODO - def self.LightingInteriorMonthlyMultipliers - return '1.075, 1.064951905, 1.0375, 1.0, 0.9625, 0.935048095, 0.925, 0.935048095, 0.9625, 1.0, 1.0375, 1.064951905' - end - - # TODO - # - # @return [TODO] TODO + # @return [String] TODO def self.SinkDurationProbability return '0.901242, 0.076572, 0.01722, 0.003798, 0.000944, 0.000154, 4.6e-05, 2.2e-05, 2.0e-06' end # TODO # - # @return [TODO] TODO + # @return [String] TODO def self.SinkEventsPerClusterProbs return '0.62458, 0.18693, 0.08011, 0.0433, 0.02178, 0.01504, 0.0083, 0.00467, 0.0057, 0.00285, 0.00181, 0.00233, 0.0013, 0.00104, 0.00026' end # TODO # - # @return [TODO] TODO + # @return [String] TODO def self.SinkHourlyOnsetProb return '0.007, 0.018, 0.042, 0.062, 0.066, 0.062, 0.054, 0.05, 0.049, 0.045, 0.041, 0.043, 0.048, 0.065, 0.075, 0.069, 0.057, 0.048, 0.04, 0.027, 0.014, 0.007, 0.005, 0.005' end # TODO # - # @return [TODO] TODO + # @return [Integer] TODO def self.SinkAvgSinkClustersPerHH return 6657 end # TODO # - # @return [TODO] TODO + # @return [Integer] TODO def self.SinkMinutesBetweenEventGap return 2 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.SinkFlowRateMean return 1.14 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.SinkFlowRateStd return 0.61 end # TODO # - # @return [TODO] TODO + # @return [Integer] TODO def self.ShowerMinutesBetweenEventGap return 30 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.ShowerFlowRateMean return 2.25 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.ShowerFlowRateStd return 0.68 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.BathBathToShowerRatio return 0.078843 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.BathDurationMean return 5.65 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.BathDurationStd return 2.09 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.BathFlowRateMean return 4.4 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.BathFlowRateStd return 1.17 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.HotWaterDishwasherFlowRateMean return 1.39 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.HotWaterDishwasherFlowRateStd return 0.2 end # TODO # - # @return [TODO] TODO + # @return [Integer] TODO def self.HotWaterDishwasherMinutesBetweenEventGap return 10 end # TODO # - # @return [TODO] TODO - def self.HotWaterDishwasherMonthlyMultiplier - return '1.083, 1.056, 1.023, 0.999, 0.975, 0.944, 0.918, 0.928, 0.938, 0.984, 1.059, 1.094' - end - - # TODO - # - # @return [TODO] TODO + # @return [Double] TODO def self.HotWaterClothesWasherFlowRateMean return 2.2 end # TODO # - # @return [TODO] TODO + # @return [Double] TODO def self.HotWaterClothesWasherFlowRateStd return 0.62 end # TODO # - # @return [TODO] TODO + # @return [Integer] TODO def self.HotWaterClothesWasherMinutesBetweenEventGap return 4 end # TODO # - # @return [TODO] TODO + # @return [String] TODO def self.HotWaterClothesWasherLoadSizeProbability return '0.682926829, 0.227642276, 0.056910569, 0.032520325' end - - # TODO - # - # @return [TODO] TODO - def self.HotWaterClothesWasherMonthlyMultiplier - return '0.968, 1.013, 0.99, 1.034, 1.019, 1.015, 1.048, 1, 1.021, 0.949, 0.945, 0.999' - end - - # TODO - # - # @return [TODO] TODO - def self.ClothesDryerMonthlyMultiplier - return '1.09, 1.054, 1.044, 0.996, 0.992, 0.967, 0.931, 0.906, 0.923, 0.955, 1.035, 1.108' - end - - # TODO - # - # @return [TODO] TODO - def self.CookingMonthlyMultiplier - return '1.038, 1.026, 0.976, 0.945, 0.965, 0.947, 0.939, 0.965, 0.967, 1.006, 1.098, 1.129' - end - - # TODO - # - # @return [TODO] TODO - def self.PlugLoadsOtherMonthlyMultipliers - return '1.248, 1.257, 0.993, 0.989, 0.993, 0.827, 0.821, 0.821, 0.827, 0.99, 0.987, 1.248' - end - - # TODO - # - # @return [TODO] TODO - def self.PlugLoadsTVWeekdayFractions - return '0.037, 0.018, 0.009, 0.007, 0.011, 0.018, 0.029, 0.040, 0.049, 0.058, 0.065, 0.072, 0.076, 0.086, 0.091, 0.102, 0.127, 0.156, 0.210, 0.294, 0.363, 0.344, 0.208, 0.090' - end - - # TODO - # - # @return [TODO] TODO - def self.PlugLoadsTVWeekendFractions - return '0.044, 0.022, 0.012, 0.008, 0.011, 0.014, 0.024, 0.043, 0.071, 0.094, 0.112, 0.123, 0.132, 0.156, 0.178, 0.196, 0.206, 0.213, 0.251, 0.330, 0.388, 0.358, 0.226, 0.103' - end - - # TODO - # - # @return [TODO] TODO - def self.PlugLoadsTVMonthlyMultipliers - return '1.137, 1.129, 0.961, 0.969, 0.961, 0.993, 0.996, 0.96, 0.993, 0.867, 0.86, 1.137' - end end diff --git a/BuildResidentialScheduleFile/resources/schedules.csv b/BuildResidentialScheduleFile/resources/schedules.csv new file mode 100644 index 0000000000..b08935dcd5 --- /dev/null +++ b/BuildResidentialScheduleFile/resources/schedules.csv @@ -0,0 +1,10 @@ +Schedule Name,Element,Values,Data Source +lighting_interior,LightingInteriorMonthlyMultipliers,"1.075, 1.064951905, 1.0375, 1.0, 0.9625, 0.935048095, 0.925, 0.935048095, 0.9625, 1.0, 1.0375, 1.064951905", +dishwasher,HotWaterDishwasherMonthlyMultiplier,"1.083, 1.056, 1.023, 0.999, 0.975, 0.944, 0.918, 0.928, 0.938, 0.984, 1.059, 1.094", +clothes_washer,HotWaterClothesWasherMonthlyMultiplier,"0.968, 1.013, 0.99, 1.034, 1.019, 1.015, 1.048, 1, 1.021, 0.949, 0.945, 0.999", +clothes_dryer,ClothesDryerMonthlyMultiplier,"1.09, 1.054, 1.044, 0.996, 0.992, 0.967, 0.931, 0.906, 0.923, 0.955, 1.035, 1.108", +cooking_range,CookingMonthlyMultiplier,"1.038, 1.026, 0.976, 0.945, 0.965, 0.947, 0.939, 0.965, 0.967, 1.006, 1.098, 1.129", +plug_loads_other,PlugLoadsOtherMonthlyMultipliers,"1.248, 1.257, 0.993, 0.989, 0.993, 0.827, 0.821, 0.821, 0.827, 0.99, 0.987, 1.248",Figure 24 of the `2010 BAHSP `_ +plug_loads_tv,PlugLoadsTVWeekdayFractions,"0.037, 0.018, 0.009, 0.007, 0.011, 0.018, 0.029, 0.040, 0.049, 0.058, 0.065, 0.072, 0.076, 0.086, 0.091, 0.102, 0.127, 0.156, 0.210, 0.294, 0.363, 0.344, 0.208, 0.090",`American Time Use Survey `_ +plug_loads_tv,PlugLoadsTVWeekendFractions,"0.044, 0.022, 0.012, 0.008, 0.011, 0.014, 0.024, 0.043, 0.071, 0.094, 0.112, 0.123, 0.132, 0.156, 0.178, 0.196, 0.206, 0.213, 0.251, 0.330, 0.388, 0.358, 0.226, 0.103",`American Time Use Survey `_ +plug_loads_tv,PlugLoadsTVMonthlyMultipliers,"1.137, 1.129, 0.961, 0.969, 0.961, 0.993, 0.996, 0.96, 0.993, 0.867, 0.86, 1.137",`American Time Use Survey `_ diff --git a/BuildResidentialScheduleFile/resources/schedules.rb b/BuildResidentialScheduleFile/resources/schedules.rb index 935b267ffd..6f937d8648 100644 --- a/BuildResidentialScheduleFile/resources/schedules.rb +++ b/BuildResidentialScheduleFile/resources/schedules.rb @@ -92,6 +92,9 @@ def create(args:, # @return [Boolean] true if successful def create_stochastic_schedules(args:, weather:) + default_schedules_csv_data = HPXMLDefaults.get_default_schedules_csv_data() + schedules_csv_data = get_schedules_csv_data() + # initialize a random number generator prng = Random.new(@random_seed) @@ -165,17 +168,17 @@ def create_stochastic_schedules(args:, all_simulated_values << Matrix[*simulated_values] end # shape of all_simulated_values is [2, 35040, 7] i.e. (geometry_num_occupants, period_in_a_year, number_of_states) - plugload_other_weekday_sch = Schedule.validate_values(Schedule.PlugLoadsOtherWeekdayFractions, 24, 'weekday') # Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C - plugload_other_weekend_sch = Schedule.validate_values(Schedule.PlugLoadsOtherWeekendFractions, 24, 'weekend') # Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C - plugload_other_monthly_multiplier = Schedule.validate_values(Constants.PlugLoadsOtherMonthlyMultipliers, 12, 'monthly') # Figure 24 of the 2010 BAHSP - plugload_tv_weekday_sch = Schedule.validate_values(Constants.PlugLoadsTVWeekdayFractions, 24, 'weekday') # American Time Use Survey - plugload_tv_weekend_sch = Schedule.validate_values(Constants.PlugLoadsTVWeekendFractions, 24, 'weekend') # American Time Use Survey - plugload_tv_monthly_multiplier = Schedule.validate_values(Constants.PlugLoadsTVMonthlyMultipliers, 12, 'monthly') # American Time Use Survey - ceiling_fan_weekday_sch = Schedule.validate_values(Schedule.CeilingFanWeekdayFractions, 24, 'weekday') # Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C - ceiling_fan_weekend_sch = Schedule.validate_values(Schedule.CeilingFanWeekendFractions, 24, 'weekend') # Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C + plugload_other_weekday_sch = Schedule.validate_values(default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['WeekdayScheduleFractions'], 24, 'weekday') # Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C + plugload_other_weekend_sch = Schedule.validate_values(default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['WeekendScheduleFractions'], 24, 'weekend') # Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C + plugload_other_monthly_multiplier = Schedule.validate_values(schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['PlugLoadsOtherMonthlyMultipliers'], 12, 'monthly') # Figure 24 of the 2010 BAHSP + plugload_tv_weekday_sch = Schedule.validate_values(schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['PlugLoadsTVWeekdayFractions'], 24, 'weekday') # American Time Use Survey + plugload_tv_weekend_sch = Schedule.validate_values(schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['PlugLoadsTVWeekendFractions'], 24, 'weekend') # American Time Use Survey + plugload_tv_monthly_multiplier = Schedule.validate_values(schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['PlugLoadsTVMonthlyMultipliers'], 12, 'monthly') # American Time Use Survey + ceiling_fan_weekday_sch = Schedule.validate_values(default_schedules_csv_data[SchedulesFile::Columns[:CeilingFan].name]['WeekdayScheduleFractions'], 24, 'weekday') # Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C + ceiling_fan_weekend_sch = Schedule.validate_values(default_schedules_csv_data[SchedulesFile::Columns[:CeilingFan].name]['WeekendScheduleFractions'], 24, 'weekend') # Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C ceiling_fan_monthly_multiplier = Schedule.validate_values(Schedule.CeilingFanMonthlyMultipliers(weather: weather), 12, 'monthly') # based on monthly average outdoor temperatures per ANSI/RESNET/ICC 301-2019 - sch = get_building_america_lighting_schedule(args[:time_zone_utc_offset], args[:latitude], args[:longitude]) + sch = get_building_america_lighting_schedule(args[:time_zone_utc_offset], args[:latitude], args[:longitude], schedules_csv_data) interior_lighting_schedule = [] num_days_in_months = Constants.NumDaysInMonths(@sim_year) for month in 0..11 @@ -458,7 +461,7 @@ def create_stochastic_schedules(args:, step = 0 last_state = 0 start_time = Time.new(@sim_year, 1, 1) - hot_water_dishwasher_monthly_multiplier = Schedule.validate_values(Constants.HotWaterDishwasherMonthlyMultiplier, 12, 'hot_water_dishwasher_monthly_multiplier') + hot_water_dishwasher_monthly_multiplier = Schedule.validate_values(schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['HotWaterDishwasherMonthlyMultiplier'], 12, 'hot_water_dishwasher_monthly_multiplier') while step < mkc_steps_in_a_year dish_state = sum_across_occupants(all_simulated_values, 4, step, max_clip: 1) step_jump = 1 @@ -483,8 +486,8 @@ def create_stochastic_schedules(args:, step = 0 last_state = 0 start_time = Time.new(@sim_year, 1, 1) - clothes_dryer_monthly_multiplier = Schedule.validate_values(Constants.ClothesDryerMonthlyMultiplier, 12, 'clothes_dryer_monthly_multiplier') - hot_water_clothes_washer_monthly_multiplier = Schedule.validate_values(Constants.HotWaterClothesWasherMonthlyMultiplier, 12, 'hot_water_clothes_washer_monthly_multiplier') + clothes_dryer_monthly_multiplier = Schedule.validate_values(schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['ClothesDryerMonthlyMultiplier'], 12, 'clothes_dryer_monthly_multiplier') + hot_water_clothes_washer_monthly_multiplier = Schedule.validate_values(schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['HotWaterClothesWasherMonthlyMultiplier'], 12, 'hot_water_clothes_washer_monthly_multiplier') while step < mkc_steps_in_a_year clothes_state = sum_across_occupants(all_simulated_values, 2, step, max_clip: 1) step_jump = 1 @@ -513,7 +516,7 @@ def create_stochastic_schedules(args:, step = 0 last_state = 0 start_time = Time.new(@sim_year, 1, 1) - cooking_monthly_multiplier = Schedule.validate_values(Constants.CookingMonthlyMultiplier, 12, 'cooking_monthly_multiplier') + cooking_monthly_multiplier = Schedule.validate_values(schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['CookingMonthlyMultiplier'], 12, 'cooking_monthly_multiplier') while step < mkc_steps_in_a_year cooking_state = sum_across_occupants(all_simulated_values, 3, step, max_clip: 1) step_jump = 1 @@ -958,7 +961,7 @@ def weighted_random(prng, weights) # @param latitude [TODO] TODO # @param longitude [TODO] TODO # @return [TODO] TODO - def get_building_america_lighting_schedule(time_zone_utc_offset, latitude, longitude) + def get_building_america_lighting_schedule(time_zone_utc_offset, latitude, longitude, schedules_csv_data) # Sunrise and sunset hours sunrise_hour = [] sunset_hour = [] @@ -988,7 +991,7 @@ def get_building_america_lighting_schedule(time_zone_utc_offset, latitude, longi end june_kws = [0.060, 0.040, 0.035, 0.025, 0.020, 0.020, 0.020, 0.020, 0.020, 0.020, 0.020, 0.020, 0.020, 0.025, 0.030, 0.030, 0.025, 0.020, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.020, 0.020, 0.020, 0.025, 0.025, 0.030, 0.030, 0.035, 0.045, 0.060, 0.085, 0.125, 0.145, 0.130, 0.105, 0.080] - lighting_seasonal_multiplier = Constants.LightingInteriorMonthlyMultipliers.split(',').map { |v| v.to_f } + lighting_seasonal_multiplier = schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['LightingInteriorMonthlyMultipliers'].split(',').map { |v| v.to_f } amplConst1 = 0.929707907917098 sunsetLag1 = 2.45016230615269 stdDevCons1 = 1.58679810983444 @@ -1067,4 +1070,27 @@ def get_building_america_lighting_schedule(time_zone_utc_offset, latitude, longi return lighting_sch end + + # Get the weekday/weekend schedule fractions for TV plug loads and monthly multipliers for interior lighting, dishwasher, clothes washer/dryer, cooking range, and other/TV plug loads. + # + # @return [Hash] { schedule_name => { element => values, ... }, ... } + def get_schedules_csv_data() + schedules_csv = File.join(File.dirname(__FILE__), 'schedules.csv') + if not File.exist?(schedules_csv) + fail 'Could not find schedules.csv' + end + + require 'csv' + schedules_csv_data = {} + CSV.foreach(schedules_csv, headers: true) do |row| + schedule_name = row['Schedule Name'] + element = row['Element'] + values = row['Values'] + + schedules_csv_data[schedule_name] = {} if !schedules_csv_data.keys.include?(schedule_name) + schedules_csv_data[schedule_name][element] = values + end + + return schedules_csv_data + end end diff --git a/BuildResidentialScheduleFile/resources/schedules_config.md b/BuildResidentialScheduleFile/resources/schedules_config.md deleted file mode 100644 index e590b0344f..0000000000 --- a/BuildResidentialScheduleFile/resources/schedules_config.md +++ /dev/null @@ -1,44 +0,0 @@ -### Occupancy Types - -Occupancy cluster types: Mostly Home, Early Regular Worker, Mostly Away, Regular Worker. -Probabilities are derived from ATUS using the k-modes algorithm. - -### Plug Loads - -This is the baseline schedule for misc plugload, lighting and ceiling fan. -It will be modified based on occupancy. -Television plugload uses the same schedule as misc plugload. - -### Lighting - -Indoor lighting schedule is generated on the fly. -Garage lighting uses the same schedule as indoor lighting. - -### Cooking - -Monthly energy use multipliers for cooking stove/oven/range from average of multiple end-use submetering datasets (HEMS, RBSAM, ELCAP, Mass Res 1, Pecan St.). -Power draw distribution is based on csv files. - -### Clothes Dryer - -Monthly energy use multipliers for clothes dryer from average of multiple end-use submetering datasets (HEMS, RBSAM, ELCAP, Mass Res 1, Pecan St., FSEC). -Power draw distribution is based on csv files. - -### Clothes Washer - -Monthly energy use multipliers for clothes washer and dishwasher from average of multiple end-use submetering datasets (generally HEMS, RBSAM, ELCAP, Mass Res 1, and Pecan St.). -Power draw distribution is based on csv files. - -### Dishwasher - -Monthly energy use multipliers for clothes washer and dishwasher from average of multiple end-use submetering datasets (generally HEMS, RBSAM, ELCAP, Mass Res 1, Pecan St., and FSEC). -Power draw distribution is based on csv files. - -### Water Draw Events - -Probabilities for all water draw events are extracted from DHW event generators. -The onset, duration, events_per_cluster_probs, flow rate mean and std could all refer to the DHW event generator excel sheet ('event characteristics' and 'Start Times' sheet). - -#### Sink - -avg_sink_clusters_per_hh -> Average sink cluster per house hold. Set to 6657 for U.S. average of 2.53 occupants per household, based on relationship of 6885 clusters for 25 gpd, from Building America DHW Event Schedule Generator, diff --git a/HPXMLtoOpenStudio/measure.rb b/HPXMLtoOpenStudio/measure.rb index 1c70c01300..01b41b4d3a 100644 --- a/HPXMLtoOpenStudio/measure.rb +++ b/HPXMLtoOpenStudio/measure.rb @@ -477,7 +477,7 @@ def make_variable_name(obj_name, unit_number) # @param schedules_file [TODO] TODO # @param eri_version [TODO] TODO # @param unit_num [TODO] TODO - # @return [void] + # @return [nil] def create_unit_model(hpxml, hpxml_bldg, runner, model, epw_path, weather, debug, schedules_file, eri_version, unit_num) @hpxml_header = hpxml.header @hpxml_bldg = hpxml_bldg @@ -556,7 +556,7 @@ def create_unit_model(hpxml, hpxml_bldg, runner, model, epw_path, weather, debug # TODO # # @param hpxml_header [HPXML::Header] HPXML Header object (one per HPXML file) - # @param hpxml_path [TODO] TODO + # @param hpxml_path [String] Path to the HPXML file # @return [TODO] TODO def check_emissions_references(hpxml_header, hpxml_path) # Check/update file references @@ -575,7 +575,7 @@ def check_emissions_references(hpxml_header, hpxml_path) # TODO # # @param hpxml_bldg_header [TODO] TODO - # @param hpxml_path [TODO] TODO + # @param hpxml_path [String] Path to the HPXML file # @return [TODO] TODO def check_schedule_references(hpxml_bldg_header, hpxml_path) # Check/update file references @@ -690,7 +690,7 @@ def create_or_get_space(model, spaces, location) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects - # @return [void] + # @return [nil] def add_roofs(runner, model, spaces) @hpxml_bldg.roofs.each do |roof| next if roof.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area @@ -808,7 +808,7 @@ def add_roofs(runner, model, spaces) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects - # @return [void] + # @return [nil] def add_walls(runner, model, spaces) @hpxml_bldg.walls.each do |wall| next if wall.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area @@ -886,7 +886,7 @@ def add_walls(runner, model, spaces) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects - # @return [void] + # @return [nil] def add_rim_joists(runner, model, spaces) @hpxml_bldg.rim_joists.each do |rim_joist| if rim_joist.azimuth.nil? @@ -964,7 +964,7 @@ def add_rim_joists(runner, model, spaces) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects - # @return [void] + # @return [nil] def add_floors(runner, model, spaces) @hpxml_bldg.floors.each do |floor| next if floor.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area @@ -1446,7 +1446,7 @@ def add_thermal_mass(model, spaces) # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects - # @return [void] + # @return [nil] def add_windows(model, spaces) # We already stored @fraction_of_windows_operable, so lets remove the # fraction_operable properties from windows and re-collapse the enclosure @@ -1549,7 +1549,7 @@ def add_windows(model, spaces) # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects - # @return [void] + # @return [nil] def add_skylights(model, spaces) surfaces = [] shading_schedules = {} @@ -1652,7 +1652,7 @@ def add_skylights(model, spaces) # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects - # @return [void] + # @return [nil] def add_doors(model, spaces) surfaces = [] @hpxml_bldg.doors.each do |door| @@ -2006,7 +2006,7 @@ def add_heat_pump(runner, model, weather, spaces, airloop_map) # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects # @param weather [WeatherFile] Weather object containing EPW information - # @return [void] + # @return [nil] def add_ideal_system(model, spaces, weather) conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get @@ -2382,7 +2382,7 @@ def create_ducts(model, hvac_distribution, spaces) # TODO # # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @return [TODO] TODO + # @return [nil] def add_photovoltaics(model) @hpxml_bldg.pv_systems.each do |pv_system| next if pv_system.inverter.inverter_efficiency == @hpxml_bldg.pv_systems[0].inverter.inverter_efficiency @@ -2397,7 +2397,7 @@ def add_photovoltaics(model) # TODO # # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @return [TODO] TODO + # @return [nil] def add_generators(model) @hpxml_bldg.generators.each do |generator| Generator.apply(model, @nbeds, generator, @hpxml_bldg.building_construction.number_of_units) @@ -2409,7 +2409,7 @@ def add_generators(model) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects - # @return [TODO] TODO + # @return [nil] def add_batteries(runner, model, spaces) @hpxml_bldg.batteries.each do |battery| # Assign space @@ -2438,7 +2438,7 @@ def add_building_unit(model, unit_num) # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param hpxml [HPXML] HPXML object # @param hpxml_osm_map [Hash] Map of HPXML::Building objects => OpenStudio Model objects for each dwelling unit - # @param hpxml_path [TODO] TODO + # @param hpxml_path [String] Path to the HPXML file # @param building_id [TODO] TODO # @param hpxml_defaults_path [TODO] TODO # @return [TODO] TODO @@ -3156,7 +3156,7 @@ def add_component_loads_output(model, hpxml_osm_map, loads_data, season_day_nums # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param hpxml_osm_map [Hash] Map of HPXML::Building objects => OpenStudio Model objects for each dwelling unit - # @return [void] + # @return [nil] def add_total_airflows_output(model, hpxml_osm_map) # Retrieve objects infil_vars = [] @@ -3480,7 +3480,7 @@ def get_space_from_location(location, spaces) # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param hpxml_surface [TODO] TODO - # @return [void] + # @return [nil] def set_subsurface_exterior(surface, spaces, model, hpxml_surface) # Set its parent surface outside boundary condition, which will be also applied to subsurfaces through OS # The parent surface is entirely comprised of the subsurface. @@ -3495,7 +3495,7 @@ def set_subsurface_exterior(surface, spaces, model, hpxml_surface) # TODO # - # @return [void] + # @return [nil] def set_foundation_and_walls_top() @foundation_top = 0 @hpxml_bldg.floors.each do |floor| @@ -3511,10 +3511,10 @@ def set_foundation_and_walls_top() @walls_top = @foundation_top + @hpxml_bldg.building_construction.average_ceiling_height * @ncfl_ag end - # TODO + # Set 365 (or 366 for a leap year) heating/cooling day arrays based on heating/cooling season begin/end month/day, respectively. # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings - # @return [void] + # @return [nil] def set_heating_and_cooling_seasons(runner) return if @hpxml_bldg.hvac_controls.size == 0 diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index c6487bec79..b3c7b4fc65 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 750796d0-c072-40f1-ab6a-2ed3d215d130 - 2024-08-12T22:41:49Z + 9745a9eb-eb1d-46d0-9fa6-ae1e0539dc5b + 2024-08-16T21:02:18Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -183,7 +183,7 @@ measure.rb rb script - 91E70775 + E4088E63 airflow.rb @@ -195,7 +195,7 @@ battery.rb rb resource - CE2C1767 + 6434EF2B constants.rb @@ -263,6 +263,12 @@ resource 63C6A1E2 + + data/default_schedules.csv + csv + resource + BF708670 + data/g_functions/C_configurations_5m_v1.0.json json @@ -309,7 +315,7 @@ data/g_functions/util.rb rb resource - 189A11B8 + D00579DD data/unavailable_periods.csv @@ -327,13 +333,13 @@ generator.rb rb resource - 40380F84 + A4B07257 geometry.rb rb resource - E606A192 + BCD7DC91 hotwater_appliances.rb @@ -345,13 +351,13 @@ hpxml.rb rb resource - 9CBC641F + ACE854BB hpxml_defaults.rb rb resource - CCAD07C4 + 76B79520 hpxml_schema/HPXML.xsd @@ -381,13 +387,13 @@ hvac.rb rb resource - 621EB8F8 + 2B371672 hvac_sizing.rb rb resource - 99F4DE93 + FFC7B0E0 lighting.rb @@ -399,7 +405,7 @@ location.rb rb resource - 73069528 + 6D2C21EE materials.rb @@ -447,7 +453,7 @@ pv.rb rb resource - AA60733A + 6ACFD5FF schedule_files/battery.csv @@ -573,13 +579,13 @@ schedules.rb rb resource - 2778CD55 + 6CAB9329 simcontrols.rb rb resource - 24E3F0EE + 25DD5859 unit_conversions.rb @@ -591,7 +597,7 @@ util.rb rb resource - 1F7CD2A3 + D9F271FC utility_bills.rb @@ -603,7 +609,7 @@ version.rb rb resource - B3ECF69F + C8C5DD23 waterheater.rb @@ -615,13 +621,13 @@ weather.rb rb resource - 8A390166 + D15242A9 xmlhelper.rb rb resource - 6E1E1307 + 7CBAECF6 xmlvalidator.rb @@ -629,18 +635,6 @@ resource 93120E27 - - results_annual.json - json - test - 0F850D04 - - - results_design_load_details.json - json - test - 43478902 - test_airflow.rb rb @@ -657,7 +651,7 @@ test_defaults.rb rb test - 132CCC8D + 621257C3 test_enclosure.rb @@ -717,7 +711,7 @@ test_schedules.rb rb test - C6CCF641 + 08E3AAFF test_simcontrols.rb @@ -729,7 +723,7 @@ test_validation.rb rb test - D243A782 + 51E564BC test_water_heater.rb diff --git a/HPXMLtoOpenStudio/resources/battery.rb b/HPXMLtoOpenStudio/resources/battery.rb index f5a5f8465a..625073beee 100644 --- a/HPXMLtoOpenStudio/resources/battery.rb +++ b/HPXMLtoOpenStudio/resources/battery.rb @@ -1,17 +1,21 @@ # frozen_string_literal: true -# TODO +# Collection of methods for adding battery-related OpenStudio objects. module Battery - # TODO + # Apply a home battery to the model using OpenStudio ElectricLoadCenterStorageLiIonNMCBattery, ElectricLoadCenterDistribution, ElectricLoadCenterStorageConverter, OtherEquipment, and EMS objects. + # Battery without PV specified, and no charging/discharging schedule provided; battery is assumed to operate as backup and will not be modeled. + # The system may be shared, in which case nominal/usable capacity (kWh) and usable fraction are apportioned to the dwelling unit by total number of bedrooms served. + # A battery may share an ElectricLoadCenterDistribution object with PV; electric buss type and storage operation scheme are therefore changed. + # Round trip efficiency is (temporarily) applied as an EMS program b/c E+ input is not hooked up. # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @param pv_systems [TODO] TODO - # @param battery [TODO] TODO + # @param pv_systems [HPXML::PVSystems] Object that defines each solar electric photovoltaic (PV) system + # @param battery [HPXML::Battery] Object that defines a single home battery # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @param unit_multiplier [Integer] Number of similar dwelling units - # @return [TODO] TODO + # @return [nil] for unscheduled battery w/out PV; in this case battery is not modeled def self.apply(runner, model, nbeds, pv_systems, battery, schedules_file, unit_multiplier) charging_schedule = nil discharging_schedule = nil @@ -195,10 +199,10 @@ def self.apply(runner, model, nbeds, pv_systems, battery, schedules_file, unit_m elcs.additionalProperties.setFeature('UsableCapacity_kWh', Float(usable_capacity_kwh)) end - # TODO + # Get default location, lifetime model, nominal capacity/voltage, round trip efficiency, and usable fraction for a battery. # - # @param has_garage [TODO] TODO - # @return [TODO] TODO + # @param has_garage [Boolean] whether the HPXML Building object has a garage + # @return [Hash] map of battery properties to default values def self.get_battery_default_values(has_garage = false) if has_garage location = HPXML::LocationGarage @@ -213,33 +217,21 @@ def self.get_battery_default_values(has_garage = false) usable_fraction: 0.9 } # Fraction of usable capacity to nominal capacity end - # TODO + # Get nominal capacity (amp-hours) from nominal capacity (kWh) and voltage (V). # - # @param nominal_capacity_kwh [TODO] TODO - # @param nominal_voltage [TODO] TODO - # @return [TODO] TODO + # @param nominal_capacity_kwh [Double] nominal (total) capacity (kWh) + # @param nominal_voltage [Double] nominal voltage (V) + # @return [Double] nominal (total) capacity (Ah) def self.get_Ah_from_kWh(nominal_capacity_kwh, nominal_voltage) return nominal_capacity_kwh * 1000.0 / nominal_voltage end - # TODO + # Get nominal capacity (kWh) from nominal capacity (amp-hours) and voltage (V). # - # @param nominal_capacity_ah [TODO] TODO - # @param nominal_voltage [TODO] TODO - # @return [TODO] TODO + # @param nominal_capacity_ah [Double] nominal (total) capacity (Ah) + # @param nominal_voltage [Double] nominal voltage (V) + # @return [Double] nominal (total) capacity (kWh) def self.get_kWh_from_Ah(nominal_capacity_ah, nominal_voltage) return nominal_capacity_ah * nominal_voltage / 1000.0 end - - # TODO - # - # @param battery [TODO] TODO - # @return [TODO] TODO - def self.get_usable_capacity_kWh(battery) - usable_capacity_kwh = battery.usable_capacity_kwh - if usable_capacity_kwh.nil? - usable_capacity_kwh = get_kWh_from_Ah(battery.usable_capacity_ah, battery.nominal_voltage) # kWh - end - return usable_capacity_kwh - end end diff --git a/HPXMLtoOpenStudio/resources/data/default_schedules.csv b/HPXMLtoOpenStudio/resources/data/default_schedules.csv new file mode 100644 index 0000000000..e08c04f96b --- /dev/null +++ b/HPXMLtoOpenStudio/resources/data/default_schedules.csv @@ -0,0 +1,88 @@ +Schedule Name,Element,Values,Data Source +occupants,WeekdayScheduleFractions,"0.035, 0.035, 0.035, 0.035, 0.035, 0.059, 0.082, 0.055, 0.027, 0.014, 0.014, 0.014, 0.014, 0.014, 0.019, 0.027, 0.041, 0.055, 0.068, 0.082, 0.082, 0.070, 0.053, 0.035",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +occupants,WeekendScheduleFractions,"0.035, 0.035, 0.035, 0.035, 0.035, 0.059, 0.082, 0.055, 0.027, 0.014, 0.014, 0.014, 0.014, 0.014, 0.019, 0.027, 0.041, 0.055, 0.068, 0.082, 0.082, 0.070, 0.053, 0.035",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +occupants,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +general_water_use,GeneralWaterUseWeekdayScheduleFractions,"0.023, 0.021, 0.021, 0.025, 0.027, 0.038, 0.044, 0.039, 0.037, 0.037, 0.034, 0.035, 0.035, 0.035, 0.039, 0.043, 0.051, 0.064, 0.065, 0.072, 0.073, 0.063, 0.045, 0.034",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +general_water_use,GeneralWaterUseWeekendScheduleFractions,"0.023, 0.021, 0.021, 0.025, 0.027, 0.038, 0.044, 0.039, 0.037, 0.037, 0.034, 0.035, 0.035, 0.035, 0.039, 0.043, 0.051, 0.064, 0.065, 0.072, 0.073, 0.063, 0.045, 0.034",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +general_water_use,GeneralWaterUseMonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +lighting_interior,InteriorWeekdayScheduleFractions,"0.012, 0.010, 0.010, 0.010, 0.011, 0.018, 0.030, 0.038, 0.041, 0.041, 0.039, 0.037, 0.036, 0.035, 0.037, 0.041, 0.050, 0.065, 0.086, 0.106, 0.110, 0.079, 0.040, 0.018",Table C.3(3) of ANSI/RESNET/ICC 301-2022 Addendum C +lighting_interior,InteriorWeekendScheduleFractions,"0.012, 0.010, 0.010, 0.010, 0.011, 0.018, 0.030, 0.038, 0.041, 0.041, 0.039, 0.037, 0.036, 0.035, 0.037, 0.041, 0.050, 0.065, 0.086, 0.106, 0.110, 0.079, 0.040, 0.018",Table C.3(3) of ANSI/RESNET/ICC 301-2022 Addendum C +lighting_interior,InteriorMonthlyScheduleMultipliers,"1.19, 1.11, 1.02, 0.93, 0.84, 0.80, 0.82, 0.88, 0.98, 1.07, 1.16, 1.20",Table C.3(4) of ANSI/RESNET/ICC 301-2022 Addendum C +lighting_exterior,ExteriorWeekdayScheduleFractions,"0.040, 0.037, 0.037, 0.035, 0.035, 0.039, 0.044, 0.041, 0.031, 0.025, 0.024, 0.024, 0.025, 0.028, 0.030, 0.035, 0.044, 0.056, 0.064, 0.068, 0.070, 0.065, 0.056, 0.047",Table C.3(3) of ANSI/RESNET/ICC 301-2022 Addendum C +lighting_exterior,ExteriorWeekendScheduleFractions,"0.040, 0.037, 0.037, 0.035, 0.035, 0.039, 0.044, 0.041, 0.031, 0.025, 0.024, 0.024, 0.025, 0.028, 0.030, 0.035, 0.044, 0.056, 0.064, 0.068, 0.070, 0.065, 0.056, 0.047",Table C.3(3) of ANSI/RESNET/ICC 301-2022 Addendum C +lighting_exterior,ExteriorMonthlyScheduleMultipliers,"1.19, 1.11, 1.02, 0.93, 0.84, 0.80, 0.82, 0.88, 0.98, 1.07, 1.16, 1.20",Table C.3(4) of ANSI/RESNET/ICC 301-2022 Addendum C +lighting_garage,GarageWeekdayScheduleFractions,"0.023, 0.019, 0.015, 0.017, 0.021, 0.031, 0.042, 0.041, 0.034, 0.029, 0.027, 0.025, 0.021, 0.021, 0.021, 0.026, 0.031, 0.044, 0.084, 0.117, 0.113, 0.096, 0.063, 0.039",Table C.3(3) of ANSI/RESNET/ICC 301-2022 Addendum C +lighting_garage,GarageWeekendScheduleFractions,"0.023, 0.019, 0.015, 0.017, 0.021, 0.031, 0.042, 0.041, 0.034, 0.029, 0.027, 0.025, 0.021, 0.021, 0.021, 0.026, 0.031, 0.044, 0.084, 0.117, 0.113, 0.096, 0.063, 0.039",Table C.3(3) of ANSI/RESNET/ICC 301-2022 Addendum C +lighting_garage,GarageMonthlyScheduleMultipliers,"1.19, 1.11, 1.02, 0.93, 0.84, 0.80, 0.82, 0.88, 0.98, 1.07, 1.16, 1.20",Table C.3(4) of ANSI/RESNET/ICC 301-2022 Addendum C +lighting_exterior_holiday,WeekdayScheduleFractions,"0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.008, 0.098, 0.168, 0.194, 0.284, 0.192, 0.037, 0.019", +lighting_exterior_holiday,WeekendScheduleFractions,"0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.008, 0.098, 0.168, 0.194, 0.284, 0.192, 0.037, 0.019", +cooking_range,WeekdayScheduleFractions,"0.008, 0.008, 0.008, 0.008, 0.008, 0.015, 0.023, 0.039, 0.046, 0.046, 0.046, 0.054, 0.062, 0.046, 0.039, 0.054, 0.076, 0.134, 0.114, 0.058, 0.039, 0.031, 0.023, 0.015",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +cooking_range,WeekendScheduleFractions,"0.008, 0.008, 0.008, 0.008, 0.008, 0.015, 0.023, 0.039, 0.046, 0.046, 0.046, 0.054, 0.062, 0.046, 0.039, 0.054, 0.076, 0.134, 0.114, 0.058, 0.039, 0.031, 0.023, 0.015",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +cooking_range,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +refrigerator,WeekdayScheduleFractions,"0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041",Figure 16 of the `2010 BAHSP `_ +refrigerator,WeekendScheduleFractions,"0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041",Figure 16 of the `2010 BAHSP `_ +refrigerator,MonthlyScheduleMultipliers,"0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837",Figure 24 of the `2010 BAHSP `_ +refrigerator,ConstantScheduleCoefficients,"-0.487, -0.340, -0.370, -0.361, -0.515, -0.684, -0.471, -0.159, -0.079, -0.417, -0.411, -0.386, -0.240, -0.314, -0.160, -0.121, -0.469, -0.412, -0.091, 0.077, -0.118, -0.247, -0.445, -0.544",Table C.3(2) of ANSI/RESNET/ICC 301-2022 Addendum C +refrigerator,TemperatureScheduleCoefficients,"0.019, 0.016, 0.017, 0.016, 0.018, 0.021, 0.019, 0.015, 0.015, 0.019, 0.018, 0.018, 0.016, 0.017, 0.015, 0.015, 0.020, 0.020, 0.017, 0.014, 0.016, 0.017, 0.019, 0.020",Table C.3(2) of ANSI/RESNET/ICC 301-2022 Addendum C +extra_refrigerator,WeekdayScheduleFractions,"0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041",Figure 16 of the `2010 BAHSP `_ +extra_refrigerator,WeekendScheduleFractions,"0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041",Figure 16 of the `2010 BAHSP `_ +extra_refrigerator,MonthlyScheduleMultipliers,"0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837",Figure 24 of the `2010 BAHSP `_ +extra_refrigerator,ConstantScheduleCoefficients,"-0.487, -0.340, -0.370, -0.361, -0.515, -0.684, -0.471, -0.159, -0.079, -0.417, -0.411, -0.386, -0.240, -0.314, -0.160, -0.121, -0.469, -0.412, -0.091, -0.077, -0.118, -0.247, -0.445, -0.544",Table C.3(2) of ANSI/RESNET/ICC 301-2022 Addendum C +extra_refrigerator,TemperatureScheduleCoefficients,"0.019, 0.016, 0.017, 0.016, 0.018, 0.021, 0.019, 0.015, 0.015, 0.019, 0.018, 0.018, 0.016, 0.017, 0.015, 0.015, 0.020, 0.020, 0.017, 0.014, 0.016, 0.017, 0.019, 0.020",Table C.3(2) of ANSI/RESNET/ICC 301-2022 Addendum C +freezer,WeekdayScheduleFractions,"0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041",Figure 16 of the `2010 BAHSP `_ +freezer,WeekendScheduleFractions,"0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041",Figure 16 of the `2010 BAHSP `_ +freezer,MonthlyScheduleMultipliers,"0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837",Figure 24 of the `2010 BAHSP `_ +dishwasher,WeekdayScheduleFractions,"0.015, 0.007, 0.005, 0.003, 0.003, 0.010, 0.020, 0.031, 0.058, 0.065, 0.056, 0.048, 0.042, 0.046, 0.036, 0.038, 0.038, 0.049, 0.087, 0.111, 0.090, 0.067, 0.044, 0.031",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +dishwasher,WeekendScheduleFractions,"0.015, 0.007, 0.005, 0.003, 0.003, 0.010, 0.020, 0.031, 0.058, 0.065, 0.056, 0.048, 0.042, 0.046, 0.036, 0.038, 0.038, 0.049, 0.087, 0.111, 0.090, 0.067, 0.044, 0.031",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +dishwasher,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +clothes_washer,WeekdayScheduleFractions,"0.009, 0.007, 0.004, 0.004, 0.007, 0.011, 0.022, 0.049, 0.073, 0.086, 0.084, 0.075, 0.067, 0.060, 0.049, 0.051, 0.050, 0.049, 0.049, 0.049, 0.049, 0.047, 0.032, 0.017",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +clothes_washer,WeekendScheduleFractions,"0.009, 0.007, 0.004, 0.004, 0.007, 0.011, 0.022, 0.049, 0.073, 0.086, 0.084, 0.075, 0.067, 0.060, 0.049, 0.051, 0.050, 0.049, 0.049, 0.049, 0.049, 0.047, 0.032, 0.017",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +clothes_washer,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +clothes_dryer,WeekdayScheduleFractions,"0.010, 0.006, 0.004, 0.002, 0.004, 0.006, 0.016, 0.032, 0.048, 0.068, 0.078, 0.081, 0.074, 0.067, 0.058, 0.061, 0.055, 0.054, 0.051, 0.051, 0.052, 0.054, 0.044, 0.024",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +clothes_dryer,WeekendScheduleFractions,"0.010, 0.006, 0.004, 0.002, 0.004, 0.006, 0.016, 0.032, 0.048, 0.068, 0.078, 0.081, 0.074, 0.067, 0.058, 0.061, 0.055, 0.054, 0.051, 0.051, 0.052, 0.054, 0.044, 0.024",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +clothes_dryer,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +ceiling_fan,WeekdayScheduleFractions,"0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.052, 0.057, 0.057, 0.057, 0.057, 0.057",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +ceiling_fan,WeekendScheduleFractions,"0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.052, 0.057, 0.057, 0.057, 0.057, 0.057",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +plug_loads_other,WeekdayScheduleFractions,"0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.038, 0.041, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.044, 0.047, 0.050, 0.051, 0.050, 0.048, 0.044, 0.040, 0.037",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +plug_loads_other,WeekendScheduleFractions,"0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.038, 0.041, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.044, 0.047, 0.050, 0.051, 0.050, 0.048, 0.044, 0.040, 0.037",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +plug_loads_other,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +plug_loads_tv,WeekdayScheduleFractions,"0.014, 0.007, 0.004, 0.003, 0.004, 0.006, 0.010, 0.015, 0.020, 0.025, 0.028, 0.031, 0.033, 0.038, 0.042, 0.046, 0.054, 0.062, 0.080, 0.110, 0.132, 0.125, 0.077, 0.034",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +plug_loads_tv,WeekendScheduleFractions,"0.014, 0.007, 0.004, 0.003, 0.004, 0.006, 0.010, 0.015, 0.020, 0.025, 0.028, 0.031, 0.033, 0.038, 0.042, 0.046, 0.054, 0.062, 0.080, 0.110, 0.132, 0.125, 0.077, 0.034",Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C +plug_loads_tv,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +plug_loads_vehicle,WeekdayScheduleFractions,"0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042", +plug_loads_vehicle,WeekendScheduleFractions,"0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042", +plug_loads_vehicle,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +plug_loads_well_pump,WeekdayScheduleFractions,"0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065",Figure 23 of the `2010 BAHSP `_ +plug_loads_well_pump,WeekendScheduleFractions,"0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065",Figure 23 of the `2010 BAHSP `_ +plug_loads_well_pump,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +fuel_loads_grill,WeekdayScheduleFractions,"0.004, 0.001, 0.001, 0.002, 0.007, 0.012, 0.029, 0.046, 0.044, 0.041, 0.044, 0.046, 0.042, 0.038, 0.049, 0.059, 0.110, 0.161, 0.115, 0.070, 0.044, 0.019, 0.013, 0.007",Figure 23 of the `2010 BAHSP `_ +fuel_loads_grill,WeekendScheduleFractions,"0.004, 0.001, 0.001, 0.002, 0.007, 0.012, 0.029, 0.046, 0.044, 0.041, 0.044, 0.046, 0.042, 0.038, 0.049, 0.059, 0.110, 0.161, 0.115, 0.070, 0.044, 0.019, 0.013, 0.007",Figure 23 of the `2010 BAHSP `_ +fuel_loads_grill,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +fuel_loads_lighting,WeekdayScheduleFractions,"0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065",Figure 23 of the `2010 BAHSP `_ +fuel_loads_lighting,WeekendScheduleFractions,"0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065",Figure 23 of the `2010 BAHSP `_ +fuel_loads_lighting,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +fuel_loads_fireplace,WeekdayScheduleFractions,"0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065",Figure 23 of the `2010 BAHSP `_ +fuel_loads_fireplace,WeekendScheduleFractions,"0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065",Figure 23 of the `2010 BAHSP `_ +fuel_loads_fireplace,MonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +pool_pump,WeekdayScheduleFractions,"0.003, 0.003, 0.003, 0.004, 0.008, 0.015, 0.026, 0.044, 0.084, 0.121, 0.127, 0.121, 0.120, 0.090, 0.075, 0.061, 0.037, 0.023, 0.013, 0.008, 0.004, 0.003, 0.003, 0.003",Figure 23 of the `2010 BAHSP `_ +pool_pump,WeekendScheduleFractions,"0.003, 0.003, 0.003, 0.004, 0.008, 0.015, 0.026, 0.044, 0.084, 0.121, 0.127, 0.121, 0.120, 0.090, 0.075, 0.061, 0.037, 0.023, 0.013, 0.008, 0.004, 0.003, 0.003, 0.003",Figure 23 of the `2010 BAHSP `_ +pool_pump,MonthlyScheduleMultipliers,"1.154, 1.161, 1.013, 1.010, 1.013, 0.888, 0.883, 0.883, 0.888, 0.978, 0.974, 1.154",Figure 24 of the `2010 BAHSP `_ +pool_heater,WeekdayScheduleFractions,"0.003, 0.003, 0.003, 0.004, 0.008, 0.015, 0.026, 0.044, 0.084, 0.121, 0.127, 0.121, 0.120, 0.090, 0.075, 0.061, 0.037, 0.023, 0.013, 0.008, 0.004, 0.003, 0.003, 0.003",Figure 23 of the `2010 BAHSP `_ +pool_heater,WeekendScheduleFractions,"0.003, 0.003, 0.003, 0.004, 0.008, 0.015, 0.026, 0.044, 0.084, 0.121, 0.127, 0.121, 0.120, 0.090, 0.075, 0.061, 0.037, 0.023, 0.013, 0.008, 0.004, 0.003, 0.003, 0.003",Figure 23 of the `2010 BAHSP `_ +pool_heater,MonthlyScheduleMultipliers,"1.154, 1.161, 1.013, 1.010, 1.013, 0.888, 0.883, 0.883, 0.888, 0.978, 0.974, 1.154",Figure 24 of the `2010 BAHSP `_ +permanent_spa_pump,WeekdayScheduleFractions,"0.024, 0.029, 0.024, 0.029, 0.047, 0.067, 0.057, 0.024, 0.024, 0.019, 0.015, 0.014, 0.014, 0.014, 0.024, 0.058, 0.126, 0.122, 0.068, 0.061, 0.051, 0.043, 0.024, 0.024",Figure 23 of the `2010 BAHSP `_ +permanent_spa_pump,WeekendScheduleFractions,"0.024, 0.029, 0.024, 0.029, 0.047, 0.067, 0.057, 0.024, 0.024, 0.019, 0.015, 0.014, 0.014, 0.014, 0.024, 0.058, 0.126, 0.122, 0.068, 0.061, 0.051, 0.043, 0.024, 0.024",Figure 23 of the `2010 BAHSP `_ +permanent_spa_pump,MonthlyScheduleMultipliers,"0.921, 0.928, 0.921, 0.915, 0.921, 1.160, 1.158, 1.158, 1.160, 0.921, 0.915, 0.921",Figure 24 of the `2010 BAHSP `_ +permanent_spa_heater,WeekdayScheduleFractions,"0.024, 0.029, 0.024, 0.029, 0.047, 0.067, 0.057, 0.024, 0.024, 0.019, 0.015, 0.014, 0.014, 0.014, 0.024, 0.058, 0.126, 0.122, 0.068, 0.061, 0.051, 0.043, 0.024, 0.024",Figure 23 of the `2010 BAHSP `_ +permanent_spa_heater,WeekendScheduleFractions,"0.024, 0.029, 0.024, 0.029, 0.047, 0.067, 0.057, 0.024, 0.024, 0.019, 0.015, 0.014, 0.014, 0.014, 0.024, 0.058, 0.126, 0.122, 0.068, 0.061, 0.051, 0.043, 0.024, 0.024",Figure 23 of the `2010 BAHSP `_ +permanent_spa_heater,MonthlyScheduleMultipliers,"0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837",Figure 24 of the `2010 BAHSP `_ +hot_water_fixtures,WaterFixturesWeekdayScheduleFractions,"0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +hot_water_fixtures,WaterFixturesWeekendScheduleFractions,"0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +hot_water_fixtures,WaterFixturesMonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", +hot_water_recirculation_pump_no_control,RecirculationPumpWeekdayScheduleFractions,"0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042",Equation 4.2-43a of ANSI/RESNET/ICC 301-2022 Addendum C +hot_water_recirculation_pump_no_control,RecirculationPumpWeekendScheduleFractions,"0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042",Equation 4.2-43a of ANSI/RESNET/ICC 301-2022 Addendum C +hot_water_recirculation_pump_demand_control,RecirculationPumpWeekdayScheduleFractions,"0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +hot_water_recirculation_pump_demand_control,RecirculationPumpWeekendScheduleFractions,"0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +hot_water_recirculation_pump_temperature_control,RecirculationPumpWeekdayScheduleFractions,"0.067, 0.072, 0.074, 0.073, 0.069, 0.048, 0.011, 0.003, 0.009, 0.020, 0.030, 0.037, 0.043, 0.047, 0.050, 0.051, 0.044, 0.034, 0.026, 0.026, 0.030, 0.036, 0.045, 0.055",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +hot_water_recirculation_pump_temperature_control,RecirculationPumpWeekendScheduleFractions,"0.067, 0.072, 0.074, 0.073, 0.069, 0.048, 0.011, 0.003, 0.009, 0.020, 0.030, 0.037, 0.043, 0.047, 0.050, 0.051, 0.044, 0.034, 0.026, 0.026, 0.030, 0.036, 0.045, 0.055",Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C +hot_water_recirculation_pump,RecirculationPumpMonthlyScheduleMultipliers,"1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", diff --git a/HPXMLtoOpenStudio/resources/data/g_functions/util.rb b/HPXMLtoOpenStudio/resources/data/g_functions/util.rb index c70492091a..6d8c362a2e 100644 --- a/HPXMLtoOpenStudio/resources/data/g_functions/util.rb +++ b/HPXMLtoOpenStudio/resources/data/g_functions/util.rb @@ -83,7 +83,7 @@ def process_g_functions(filepath) # @param expected_num_boreholes [Integer] expected number of boreholes for a config/boreholes combo # @param m_n [String] keys from the config files where m is borehole "columns" and n is borehole "rows" # @param key2 [String] additional key some configs use to access specific configurations -# @return [void] +# @return [nil] def add_m_n(json, json2, expected_num_boreholes, m_n, key2 = nil) if key2.nil? actual_num_boreholes = json[m_n]['bore_locations'].size diff --git a/HPXMLtoOpenStudio/resources/generator.rb b/HPXMLtoOpenStudio/resources/generator.rb index c6bcdd36fa..b5be879640 100644 --- a/HPXMLtoOpenStudio/resources/generator.rb +++ b/HPXMLtoOpenStudio/resources/generator.rb @@ -1,14 +1,16 @@ # frozen_string_literal: true -# TODO +# Collection of methods for adding generator-related OpenStudio objects. module Generator - # TODO + # Apply a on-site power generator to the model using OpenStudio GeneratorMicroTurbine and ElectricLoadCenterDistribution objects. + # The system may be shared, in which case annual consumption (kBtu) and output (kWh) are apportioned to the dwelling unit by total number of bedrooms served. + # A new ElectricLoadCenterDistribution object is created for each generator. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @param generator [TODO] TODO + # @param generator [HPXML::Generator] Object that defines a single generator that provides on-site power # @param unit_multiplier [Integer] Number of similar dwelling units - # @return [TODO] TODO + # @return [nil] def self.apply(model, nbeds, generator, unit_multiplier) obj_name = generator.id @@ -57,10 +59,10 @@ def self.apply(model, nbeds, generator, unit_multiplier) elcd.setElectricalBussType('AlternatingCurrent') end - # TODO + # Create a cubic constant curve for electrical efficiency function of temperature and part load ratio. # # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @return [TODO] TODO + # @return [OpenStudio::Model::CurveCubic] OpenStudio CurveCubic object def self.create_curve_cubic_constant(model) constant_cubic = OpenStudio::Model::CurveCubic.new(model) constant_cubic.setName('ConstantCubic') @@ -73,10 +75,10 @@ def self.create_curve_cubic_constant(model) return constant_cubic end - # TODO + # Create a biquadratic constant curve for electrical power function of temperature and elevation. # # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @return [TODO] TODO + # @return [OpenStudio::Model::CurveBiquadratic] OpenStudio CurveBiquadratic object def self.create_curve_biquadratic_constant(model) const_biquadratic = OpenStudio::Model::CurveBiquadratic.new(model) const_biquadratic.setName('ConstantBiquadratic') diff --git a/HPXMLtoOpenStudio/resources/geometry.rb b/HPXMLtoOpenStudio/resources/geometry.rb index 6d767b5e20..867322cdbf 100644 --- a/HPXMLtoOpenStudio/resources/geometry.rb +++ b/HPXMLtoOpenStudio/resources/geometry.rb @@ -6,7 +6,7 @@ module Geometry # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings - # @return [TODO] TODO + # @return [nil] def self.tear_down_model(model:, runner:) handles = OpenStudio::UUIDVector.new @@ -346,7 +346,7 @@ def self.set_zone_volumes(spaces:, # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param walls_top [Double] the total height of the dwelling unit - # @return [void] + # @return [nil] def self.explode_surfaces(model:, hpxml_bldg:, walls_top:) @@ -495,7 +495,7 @@ def self.explode_surfaces(model:, # @param space [OpenStudio::Model::Space] an OpenStudio::Model::Space object # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @param unavailable_periods [HPXML::UnavailablePeriods] Object that defines periods for, e.g., power outages or vacancies - # @return [void] + # @return [nil] def self.apply_occupants(model, runner, hpxml_bldg, num_occ, space, schedules_file, unavailable_periods) occ_gain, _hrs_per_day, sens_frac, _lat_frac = get_occupancy_default_values() activity_per_person = UnitConversions.convert(occ_gain, 'Btu/hr', 'W') @@ -655,7 +655,7 @@ def self.calculate_zone_volume(hpxml_bldg:, # TODO # - # @param location [TODO] TODO + # @param location [String] the general HPXML location # @return [TODO] TODO def self.get_temperature_scheduled_space_values(location:) if location == HPXML::LocationOtherHeatedSpace diff --git a/HPXMLtoOpenStudio/resources/hpxml.rb b/HPXMLtoOpenStudio/resources/hpxml.rb index 2f617bb9ff..8d9ac8f5a0 100644 --- a/HPXMLtoOpenStudio/resources/hpxml.rb +++ b/HPXMLtoOpenStudio/resources/hpxml.rb @@ -615,7 +615,7 @@ def to_doc # Populates the HPXML object(s) from the XML document. # # @param hpxml_element [Oga::XML::Element] Root XML element of the HPXML document - # @return [void] + # @return [nil] def from_doc(hpxml_element) @header = Header.new(self, hpxml_element) @buildings = Buildings.new(self, hpxml_element) @@ -625,7 +625,7 @@ def from_doc(hpxml_element) # # @param hpxml_doc [Oga::XML::Document] HPXML object as an XML document # @param last_building_only [Boolean] Whether to update IDs for all Building elements or only the last Building element - # @return [void] + # @return [nil] def set_unique_hpxml_ids(hpxml_doc, last_building_only = false) buildings = XMLHelper.get_elements(hpxml_doc, '/HPXML/Building') @@ -798,7 +798,7 @@ def check_for_errors # Adds each object in the array to the provided Oga XML element. # # @param xml_element [Oga::XML::Element] XML element - # @return [void] + # @return [nil] def to_doc(xml_element) each do |child| child.to_doc(xml_element) @@ -874,7 +874,7 @@ def check_for_errors # Adds this object to the Oga XML document. # # @param hpxml_doc [Oga::XML::Document] HPXML object as an XML document - # @return [void] + # @return [nil] def to_doc(hpxml_doc) return if nil? @@ -930,7 +930,7 @@ def to_doc(hpxml_doc) # Populates the HPXML object(s) from the XML document. # # @param hpxml [Oga::XML::Element] Root XML element of the HPXML document - # @return [void] + # @return [nil] def from_doc(hpxml) return if hpxml.nil? @@ -967,7 +967,7 @@ def from_doc(hpxml) class EmissionsScenarios < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << EmissionsScenario.new(@parent_object, **kwargs) end @@ -975,7 +975,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param hpxml [Oga::XML::Element] Root XML element of the HPXML document - # @return [void] + # @return [nil] def from_doc(hpxml) return if hpxml.nil? @@ -1015,7 +1015,7 @@ class EmissionsScenario < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.header.emissions_scenarios.delete(self) end @@ -1031,7 +1031,7 @@ def check_for_errors # Adds this object to the Oga XML document. # # @param hpxml [Oga::XML::Element] Root XML element of the HPXML document - # @return [void] + # @return [nil] def to_doc(hpxml) emissions_scenarios = XMLHelper.create_elements_as_needed(hpxml, ['SoftwareInfo', 'extension', 'EmissionsScenarios']) emissions_scenario = XMLHelper.add_element(emissions_scenarios, 'EmissionsScenario') @@ -1072,7 +1072,7 @@ def to_doc(hpxml) # Populates the HPXML object(s) from the XML document. # # @param emissions_scenario [Oga::XML::Element] The current EmissionsScenario XML element - # @return [void] + # @return [nil] def from_doc(emissions_scenario) return if emissions_scenario.nil? @@ -1102,7 +1102,7 @@ def from_doc(emissions_scenario) class UtilityBillScenarios < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << UtilityBillScenario.new(@parent_object, **kwargs) end @@ -1110,7 +1110,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param hpxml [Oga::XML::Element] Root XML element of the HPXML document - # @return [void] + # @return [nil] def from_doc(hpxml) return if hpxml.nil? @@ -1162,7 +1162,7 @@ class UtilityBillScenario < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.header.utility_bill_scenarios.delete(self) end @@ -1178,7 +1178,7 @@ def check_for_errors # Adds this object to the Oga XML document. # # @param hpxml [Oga::XML::Element] Root XML element of the HPXML document - # @return [void] + # @return [nil] def to_doc(hpxml) utility_bill_scenarios = XMLHelper.create_elements_as_needed(hpxml, ['SoftwareInfo', 'extension', 'UtilityBillScenarios']) utility_bill_scenario = XMLHelper.add_element(utility_bill_scenarios, 'UtilityBillScenario') @@ -1227,7 +1227,7 @@ def to_doc(hpxml) # Populates the HPXML object(s) from the XML document. # # @param utility_bill_scenario [Oga::XML::Element] The current UtilityBillScenario XML element - # @return [void] + # @return [nil] def from_doc(utility_bill_scenario) return if utility_bill_scenario.nil? @@ -1265,7 +1265,7 @@ def from_doc(utility_bill_scenario) class UnavailablePeriods < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << UnavailablePeriod.new(@parent_object, **kwargs) end @@ -1273,7 +1273,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param hpxml [Oga::XML::Element] Root XML element of the HPXML document - # @return [void] + # @return [nil] def from_doc(hpxml) return if hpxml.nil? @@ -1297,7 +1297,7 @@ class UnavailablePeriod < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.header.unavailable_periods.delete(self) end @@ -1314,7 +1314,7 @@ def check_for_errors # Adds this object to the Oga XML document. # # @param hpxml [Oga::XML::Element] Root XML element of the HPXML document - # @return [void] + # @return [nil] def to_doc(hpxml) unavailable_periods = XMLHelper.create_elements_as_needed(hpxml, ['SoftwareInfo', 'extension', 'UnavailablePeriods']) unavailable_period = XMLHelper.add_element(unavailable_periods, 'UnavailablePeriod') @@ -1331,7 +1331,7 @@ def to_doc(hpxml) # Populates the HPXML object(s) from the XML document. # # @param unavailable_period [Oga::XML::Element] The current UnavailablePeriod XML element - # @return [void] + # @return [nil] def from_doc(unavailable_period) return if unavailable_period.nil? @@ -1350,7 +1350,7 @@ def from_doc(unavailable_period) class Buildings < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Building.new(@parent_object, **kwargs) end @@ -1358,7 +1358,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param hpxml [Oga::XML::Element] Root XML element of the HPXML document - # @return [void] + # @return [nil] def from_doc(hpxml) return if hpxml.nil? @@ -1457,7 +1457,7 @@ def initialize(*args, **kwargs) # Adds this object to the Oga XML document. # # @param hpxml_doc [Oga::XML::Document] HPXML object as an XML document - # @return [void] + # @return [nil] def to_doc(hpxml_doc) return if nil? @@ -1569,7 +1569,7 @@ def to_doc(hpxml_doc) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) if not building.nil? @building_id = HPXML::get_id(building, 'BuildingID') @@ -1997,7 +1997,7 @@ def inferred_conditioned_crawlspace_volume # Deletes any adiabatic sub-surfaces since EnergyPlus does not allow it. # - # @return [void] + # @return [nil] def delete_adiabatic_subsurfaces @doors.reverse_each do |door| next if door.wall.nil? @@ -2145,7 +2145,7 @@ def check_for_errors # surfaces (e.g., windows). # # @param surf_types_of_interest [Array] Subset of surface types (e.g., :roofs, :walls, etc.) to collapse - # @return [void] + # @return [nil] def collapse_enclosure_surfaces(surf_types_of_interest = nil) surf_types = { roofs: @roofs, walls: @walls, @@ -2267,7 +2267,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -2304,7 +2304,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -2329,7 +2329,7 @@ def from_doc(building) class NeighborBuildings < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << NeighborBuilding.new(@parent_object, **kwargs) end @@ -2337,7 +2337,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -2366,7 +2366,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -2381,7 +2381,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param neighbor_building [Oga::XML::Element] The current NeighborBuilding XML element - # @return [void] + # @return [nil] def from_doc(neighbor_building) return if neighbor_building.nil? @@ -2415,7 +2415,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -2433,7 +2433,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -2479,7 +2479,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -2502,7 +2502,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -2562,7 +2562,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -2611,7 +2611,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -2676,7 +2676,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -2697,7 +2697,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -2720,7 +2720,7 @@ def from_doc(building) class ClimateZoneIECCs < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << ClimateZoneIECC.new(@parent_object, **kwargs) end @@ -2728,7 +2728,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -2746,7 +2746,7 @@ class ClimateZoneIECC < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.climate_and_risk_zones.climate_zone_ieccs.delete(self) end @@ -2762,7 +2762,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param climate_and_risk_zones [Oga::XML::Element] Parent XML element - # @return [void] + # @return [nil] def to_doc(climate_and_risk_zones) climate_zone_iecc = XMLHelper.add_element(climate_and_risk_zones, 'ClimateZoneIECC') XMLHelper.add_element(climate_zone_iecc, 'Year', @year, :integer, @year_isdefaulted) unless @year.nil? @@ -2772,7 +2772,7 @@ def to_doc(climate_and_risk_zones) # Populates the HPXML object(s) from the XML document. # # @param climate_and_risk_zones [Oga::XML::Element] The current ClimateZoneIECC XML element - # @return [void] + # @return [nil] def from_doc(climate_zone_iecc) return if climate_zone_iecc.nil? @@ -2785,7 +2785,7 @@ def from_doc(climate_zone_iecc) class Zones < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Zone.new(@parent_object, **kwargs) end @@ -2793,7 +2793,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -2837,7 +2837,7 @@ def check_for_errors # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete hvac_systems.reverse_each do |hvac_system| hvac_system.attached_to_zone_idref = nil @@ -2967,7 +2967,7 @@ def subsurfaces # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -2985,7 +2985,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param zone [Oga::XML::Element] The current Zone XML element - # @return [void] + # @return [nil] def from_doc(zone) return if zone.nil? @@ -3000,7 +3000,7 @@ def from_doc(zone) class Spaces < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Space.new(@parent_object, **kwargs) end @@ -3008,7 +3008,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param zone [Oga::XML::Element] The current Zone XML element - # @return [void] + # @return [nil] def from_doc(zone) return if zone.nil? @@ -3041,7 +3041,7 @@ def check_for_errors # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete surfaces.reverse_each do |surface| surface.attached_to_space_idref = nil @@ -3136,7 +3136,7 @@ def subsurfaces # Adds this object to the provided Oga XML element. # # @param zone [Oga::XML::Element] Parent XML element - # @return [void] + # @return [nil] def to_doc(zone) return if nil? @@ -3160,7 +3160,7 @@ def to_doc(zone) # Populates the HPXML object(s) from the XML document. # # @param space [Oga::XML::Element] The current Space XML element - # @return [void] + # @return [nil] def from_doc(space) return if space.nil? @@ -3190,7 +3190,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -3201,7 +3201,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -3216,7 +3216,7 @@ def from_doc(building) class AirInfiltrationMeasurements < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << AirInfiltrationMeasurement.new(@parent_object, **kwargs) end @@ -3224,7 +3224,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -3260,7 +3260,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -3286,7 +3286,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param air_infiltration_measurement [Oga::XML::Element] The current AirInfiltrationMeasurement XML element - # @return [void] + # @return [nil] def from_doc(air_infiltration_measurement) return if air_infiltration_measurement.nil? @@ -3308,7 +3308,7 @@ def from_doc(air_infiltration_measurement) class Attics < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Attic.new(@parent_object, **kwargs) end @@ -3316,7 +3316,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -3399,7 +3399,7 @@ def to_location # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.attics.delete(self) end @@ -3419,7 +3419,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -3477,7 +3477,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param attic [Oga::XML::Element] The current Attic XML element - # @return [void] + # @return [nil] def from_doc(attic) return if attic.nil? @@ -3519,7 +3519,7 @@ def from_doc(attic) class Foundations < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Foundation.new(@parent_object, **kwargs) end @@ -3527,7 +3527,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -3668,7 +3668,7 @@ def area # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.foundations.delete(self) end @@ -3690,7 +3690,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -3765,7 +3765,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param foundation [Oga::XML::Element] The current Foundation XML element - # @return [void] + # @return [nil] def from_doc(foundation) return if foundation.nil? @@ -3821,7 +3821,7 @@ def from_doc(foundation) class Roofs < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Roof.new(@parent_object, **kwargs) end @@ -3829,7 +3829,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -3949,7 +3949,7 @@ def is_conditioned # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.roofs.delete(self) skylights.reverse_each do |skylight| @@ -3973,7 +3973,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -4041,7 +4041,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param roof [Oga::XML::Element] The current Roof XML element - # @return [void] + # @return [nil] def from_doc(roof) return if roof.nil? @@ -4091,7 +4091,7 @@ def from_doc(roof) class RimJoists < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << RimJoist.new(@parent_object, **kwargs) end @@ -4099,7 +4099,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -4201,7 +4201,7 @@ def net_area # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.rim_joists.delete(self) @parent_object.foundations.each do |foundation| @@ -4221,7 +4221,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -4279,7 +4279,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param rim_joist [Oga::XML::Element] The current RimJoist XML element - # @return [void] + # @return [nil] def from_doc(rim_joist) return if rim_joist.nil? @@ -4319,7 +4319,7 @@ def from_doc(rim_joist) class Walls < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Wall.new(@parent_object, **kwargs) end @@ -4327,7 +4327,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -4459,7 +4459,7 @@ def is_conditioned # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.walls.delete(self) windows.reverse_each do |window| @@ -4489,7 +4489,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -4565,7 +4565,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param wall [Oga::XML::Element] The current Wall XML element - # @return [void] + # @return [nil] def from_doc(wall) return if wall.nil? @@ -4620,7 +4620,7 @@ def from_doc(wall) class FoundationWalls < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << FoundationWall.new(@parent_object, **kwargs) end @@ -4628,7 +4628,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -4810,7 +4810,7 @@ def is_conditioned # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.foundation_walls.delete(self) windows.reverse_each do |window| @@ -4837,7 +4837,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -4901,7 +4901,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param foundation_wall [Oga::XML::Element] The current FoundationWall XML element - # @return [void] + # @return [nil] def from_doc(foundation_wall) return if foundation_wall.nil? @@ -4950,7 +4950,7 @@ def from_doc(foundation_wall) class Floors < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Floor.new(@parent_object, **kwargs) end @@ -4958,7 +4958,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -5102,7 +5102,7 @@ def is_conditioned # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.floors.delete(self) skylights.reverse_each do |skylight| @@ -5132,7 +5132,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -5199,7 +5199,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param floor [Oga::XML::Element] The current Floor XML element - # @return [void] + # @return [nil] def from_doc(floor) return if floor.nil? @@ -5245,7 +5245,7 @@ def from_doc(floor) class Slabs < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Slab.new(@parent_object, **kwargs) end @@ -5253,7 +5253,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -5356,7 +5356,7 @@ def connected_foundation_walls # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.slabs.delete(self) @parent_object.foundations.each do |foundation| @@ -5376,7 +5376,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -5432,7 +5432,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param slab [Oga::XML::Element] The current Slab XML element - # @return [void] + # @return [nil] def from_doc(slab) return if slab.nil? @@ -5476,7 +5476,7 @@ def from_doc(slab) class Windows < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Window.new(@parent_object, **kwargs) end @@ -5484,7 +5484,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -5577,7 +5577,7 @@ def is_conditioned # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.windows.delete(self) end @@ -5594,7 +5594,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -5664,7 +5664,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param window [Oga::XML::Element] The current Window XML element - # @return [void] + # @return [nil] def from_doc(window) return if window.nil? @@ -5705,7 +5705,7 @@ def from_doc(window) class Skylights < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Skylight.new(@parent_object, **kwargs) end @@ -5713,7 +5713,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -5822,7 +5822,7 @@ def is_conditioned # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.skylights.delete(self) end @@ -5840,7 +5840,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -5908,7 +5908,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param skylight [Oga::XML::Element] The current Skylight XML element - # @return [void] + # @return [nil] def from_doc(skylight) return if skylight.nil? @@ -5947,7 +5947,7 @@ def from_doc(skylight) class Doors < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Door.new(@parent_object, **kwargs) end @@ -5955,7 +5955,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -6028,7 +6028,7 @@ def is_conditioned # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.doors.delete(self) end @@ -6045,7 +6045,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -6066,7 +6066,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param door [Oga::XML::Element] The current Door XML element - # @return [void] + # @return [nil] def from_doc(door) return if door.nil? @@ -6097,7 +6097,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -6113,7 +6113,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -6146,7 +6146,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -6158,7 +6158,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -6174,7 +6174,7 @@ def from_doc(building) class HeatingSystems < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << HeatingSystem.new(@parent_object, **kwargs) end @@ -6182,7 +6182,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -6317,7 +6317,7 @@ def is_heat_pump_backup_system # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.heating_systems.delete(self) @parent_object.water_heating_systems.each do |water_heating_system| @@ -6341,7 +6341,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -6415,7 +6415,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param heating_system [Oga::XML::Element] The current HeatingSystem XML element - # @return [void] + # @return [nil] def from_doc(heating_system) return if heating_system.nil? @@ -6465,7 +6465,7 @@ def from_doc(heating_system) class CoolingSystems < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << CoolingSystem.new(@parent_object, **kwargs) end @@ -6473,7 +6473,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -6598,7 +6598,7 @@ def has_integrated_heating # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.cooling_systems.delete(self) @parent_object.water_heating_systems.each do |water_heating_system| @@ -6622,7 +6622,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -6706,7 +6706,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param cooling_system [Oga::XML::Element] The current CoolingSystem XML element - # @return [void] + # @return [nil] def from_doc(cooling_system) return if cooling_system.nil? @@ -6760,7 +6760,7 @@ def from_doc(cooling_system) class HeatPumps < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << HeatPump.new(@parent_object, **kwargs) end @@ -6768,7 +6768,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -6944,7 +6944,7 @@ def backup_system # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.heat_pumps.delete(self) @parent_object.water_heating_systems.each do |water_heating_system| @@ -6970,7 +6970,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -7097,7 +7097,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param heat_pump [Oga::XML::Element] The current HeatPump XML element - # @return [void] + # @return [nil] def from_doc(heat_pump) return if heat_pump.nil? @@ -7175,7 +7175,7 @@ def from_doc(heat_pump) class GeothermalLoops < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << GeothermalLoop.new(@parent_object, **kwargs) end @@ -7183,7 +7183,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -7232,7 +7232,7 @@ def heat_pump # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.geothermal_loops.delete(self) @parent_object.heat_pumps.each do |heat_pump| @@ -7254,7 +7254,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -7292,7 +7292,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param geothermal_loop [Oga::XML::Element] The current GeothermalLoop XML element - # @return [void] + # @return [nil] def from_doc(geothermal_loop) return if geothermal_loop.nil? @@ -7329,7 +7329,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -7340,7 +7340,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -7355,7 +7355,7 @@ def from_doc(building) class HVACControls < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << HVACControl.new(@parent_object, **kwargs) end @@ -7363,7 +7363,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -7402,7 +7402,7 @@ class HVACControl < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.hvac_controls.delete(self) end @@ -7420,7 +7420,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -7461,7 +7461,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param hvac_control [Oga::XML::Element] The current HVACControl XML element - # @return [void] + # @return [nil] def from_doc(hvac_control) return if hvac_control.nil? @@ -7495,7 +7495,7 @@ def from_doc(hvac_control) class HVACDistributions < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << HVACDistribution.new(@parent_object, **kwargs) end @@ -7503,7 +7503,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -7575,7 +7575,7 @@ def hvac_systems # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.hvac_distributions.delete(self) @parent_object.hvac_systems.each do |hvac_system| @@ -7605,7 +7605,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -7654,7 +7654,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param hvac_distribution [Oga::XML::Element] The current HVACDistribution XML element - # @return [void] + # @return [nil] def from_doc(hvac_distribution) return if hvac_distribution.nil? @@ -7689,7 +7689,7 @@ def from_doc(hvac_distribution) class DuctLeakageMeasurements < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << DuctLeakageMeasurement.new(@parent_object, **kwargs) end @@ -7697,7 +7697,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param hvac_distribution [Oga::XML::Element] The current HVACDistribution XML element - # @return [void] + # @return [nil] def from_doc(hvac_distribution) return if hvac_distribution.nil? @@ -7718,7 +7718,7 @@ class DuctLeakageMeasurement < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.hvac_distributions.each do |hvac_distribution| next unless hvac_distribution.duct_leakage_measurements.include? self @@ -7738,7 +7738,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param air_distribution [Oga::XML::Element] Parent XML element - # @return [void] + # @return [nil] def to_doc(air_distribution) duct_leakage_measurement_el = XMLHelper.add_element(air_distribution, 'DuctLeakageMeasurement') XMLHelper.add_element(duct_leakage_measurement_el, 'DuctType', @duct_type, :string) unless @duct_type.nil? @@ -7754,7 +7754,7 @@ def to_doc(air_distribution) # Populates the HPXML object(s) from the XML document. # # @param duct_leakage_measurement [Oga::XML::Element] The current DuctLeakageMeasurement XML element - # @return [void] + # @return [nil] def from_doc(duct_leakage_measurement) return if duct_leakage_measurement.nil? @@ -7770,7 +7770,7 @@ def from_doc(duct_leakage_measurement) class Ducts < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Duct.new(@parent_object, **kwargs) end @@ -7778,7 +7778,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param hvac_distribution [Oga::XML::Element] The current HVACDistribution XML element - # @return [void] + # @return [nil] def from_doc(hvac_distribution) return if hvac_distribution.nil? @@ -7806,7 +7806,7 @@ class Duct < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.hvac_distributions.each do |hvac_distribution| next unless hvac_distribution.ducts.include? self @@ -7826,7 +7826,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param air_distribution [Oga::XML::Element] Parent XML element - # @return [void] + # @return [nil] def to_doc(air_distribution) ducts_el = XMLHelper.add_element(air_distribution, 'Ducts') sys_id = XMLHelper.add_element(ducts_el, 'SystemIdentifier') @@ -7850,7 +7850,7 @@ def to_doc(air_distribution) # Populates the HPXML object(s) from the XML document. # # @param duct [Oga::XML::Element] The current Duct XML element - # @return [void] + # @return [nil] def from_doc(duct) return if duct.nil? @@ -7873,7 +7873,7 @@ def from_doc(duct) class VentilationFans < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << VentilationFan.new(@parent_object, **kwargs) end @@ -7881,7 +7881,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -8109,7 +8109,7 @@ def is_cfis_supplemental_fan # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.ventilation_fans.delete(self) end @@ -8128,7 +8128,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -8193,7 +8193,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param ventilation_fan [Oga::XML::Element] The current VentilationFan XML element - # @return [void] + # @return [nil] def from_doc(ventilation_fan) return if ventilation_fan.nil? @@ -8238,7 +8238,7 @@ def from_doc(ventilation_fan) class WaterHeatingSystems < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << WaterHeatingSystem.new(@parent_object, **kwargs) end @@ -8246,7 +8246,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -8302,7 +8302,7 @@ def related_hvac_system # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.water_heating_systems.delete(self) @parent_object.solar_thermal_systems.each do |solar_thermal_system| @@ -8334,7 +8334,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -8384,7 +8384,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param water_heating_system [Oga::XML::Element] The current WaterHeatingSystem XML element - # @return [void] + # @return [nil] def from_doc(water_heating_system) return if water_heating_system.nil? @@ -8420,7 +8420,7 @@ def from_doc(water_heating_system) class HotWaterDistributions < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << HotWaterDistribution.new(@parent_object, **kwargs) end @@ -8428,7 +8428,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -8463,7 +8463,7 @@ class HotWaterDistribution < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.hot_water_distributions.delete(self) end @@ -8479,7 +8479,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -8528,7 +8528,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param hot_water_distribution [Oga::XML::Element] The current HotWaterDistribution XML element - # @return [void] + # @return [nil] def from_doc(hot_water_distribution) return if hot_water_distribution.nil? @@ -8563,7 +8563,7 @@ def from_doc(hot_water_distribution) class WaterFixtures < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << WaterFixture.new(@parent_object, **kwargs) end @@ -8571,7 +8571,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -8592,7 +8592,7 @@ class WaterFixture < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.water_fixtures.delete(self) end @@ -8608,7 +8608,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -8625,7 +8625,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param water_fixture [Oga::XML::Element] The current WaterFixture XML element - # @return [void] + # @return [nil] def from_doc(water_fixture) return if water_fixture.nil? @@ -8656,7 +8656,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -8670,7 +8670,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -8688,7 +8688,7 @@ def from_doc(building) class SolarThermalSystems < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << SolarThermalSystem.new(@parent_object, **kwargs) end @@ -8696,7 +8696,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -8739,7 +8739,7 @@ def water_heating_system # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.solar_thermal_systems.delete(self) end @@ -8756,7 +8756,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -8784,7 +8784,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param solar_thermal_system [Oga::XML::Element] The current SolarThermalSystem XML element - # @return [void] + # @return [nil] def from_doc(solar_thermal_system) return if solar_thermal_system.nil? @@ -8808,7 +8808,7 @@ def from_doc(solar_thermal_system) class PVSystems < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << PVSystem.new(@parent_object, **kwargs) end @@ -8816,7 +8816,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -8860,7 +8860,7 @@ def inverter # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.pv_systems.delete(self) end @@ -8877,7 +8877,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -8906,7 +8906,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param pv_system [Oga::XML::Element] The current PVSystem XML element - # @return [void] + # @return [nil] def from_doc(pv_system) return if pv_system.nil? @@ -8931,7 +8931,7 @@ def from_doc(pv_system) class Inverters < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Inverter.new(@parent_object, **kwargs) end @@ -8939,7 +8939,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -8977,7 +8977,7 @@ def pv_systems # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.inverters.delete(self) end @@ -8994,7 +8994,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -9008,7 +9008,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param inverter [Oga::XML::Element] The current Inverter XML element - # @return [void] + # @return [nil] def from_doc(inverter) return if inverter.nil? @@ -9021,7 +9021,7 @@ def from_doc(inverter) class Batteries < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Battery.new(@parent_object, **kwargs) end @@ -9029,7 +9029,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -9058,7 +9058,7 @@ class Battery < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.batteries.delete(self) end @@ -9074,7 +9074,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -9115,7 +9115,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param battery [Oga::XML::Element] The current Battery XML element - # @return [void] + # @return [nil] def from_doc(battery) return if battery.nil? @@ -9139,7 +9139,7 @@ def from_doc(battery) class Generators < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Generator.new(@parent_object, **kwargs) end @@ -9147,7 +9147,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -9169,7 +9169,7 @@ class Generator < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.generators.delete(self) end @@ -9185,7 +9185,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -9203,7 +9203,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param generator [Oga::XML::Element] The current Generator XML element - # @return [void] + # @return [nil] def from_doc(generator) return if generator.nil? @@ -9220,7 +9220,7 @@ def from_doc(generator) class ClothesWashers < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << ClothesWasher.new(@parent_object, **kwargs) end @@ -9228,7 +9228,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -9291,7 +9291,7 @@ def hot_water_distribution # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.clothes_washers.delete(self) end @@ -9309,7 +9309,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -9345,7 +9345,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param clothes_washer [Oga::XML::Element] The current ClothesWasher XML element - # @return [void] + # @return [nil] def from_doc(clothes_washer) return if clothes_washer.nil? @@ -9375,7 +9375,7 @@ def from_doc(clothes_washer) class ClothesDryers < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << ClothesDryer.new(@parent_object, **kwargs) end @@ -9383,7 +9383,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -9414,7 +9414,7 @@ class ClothesDryer < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.clothes_dryers.delete(self) end @@ -9430,7 +9430,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -9457,7 +9457,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param clothes_dryer [Oga::XML::Element] The current ClothesDryer XML element - # @return [void] + # @return [nil] def from_doc(clothes_dryer) return if clothes_dryer.nil? @@ -9483,7 +9483,7 @@ def from_doc(clothes_dryer) class Dishwashers < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Dishwasher.new(@parent_object, **kwargs) end @@ -9491,7 +9491,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -9551,7 +9551,7 @@ def hot_water_distribution # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.dishwashers.delete(self) end @@ -9569,7 +9569,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -9602,7 +9602,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param dishwasher [Oga::XML::Element] The current Dishwasher XML element - # @return [void] + # @return [nil] def from_doc(dishwasher) return if dishwasher.nil? @@ -9629,7 +9629,7 @@ def from_doc(dishwasher) class Refrigerators < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Refrigerator.new(@parent_object, **kwargs) end @@ -9637,7 +9637,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -9663,7 +9663,7 @@ class Refrigerator < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.refrigerators.delete(self) end @@ -9679,7 +9679,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -9701,7 +9701,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param refrigerator [Oga::XML::Element] The current Refrigerator XML element - # @return [void] + # @return [nil] def from_doc(refrigerator) return if refrigerator.nil? @@ -9722,7 +9722,7 @@ def from_doc(refrigerator) class Freezers < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Freezer.new(@parent_object, **kwargs) end @@ -9730,7 +9730,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -9755,7 +9755,7 @@ class Freezer < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.freezers.delete(self) end @@ -9771,7 +9771,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -9792,7 +9792,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param freezer [Oga::XML::Element] The current Freezer XML element - # @return [void] + # @return [nil] def from_doc(freezer) return if freezer.nil? @@ -9812,7 +9812,7 @@ def from_doc(freezer) class Dehumidifiers < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Dehumidifier.new(@parent_object, **kwargs) end @@ -9820,7 +9820,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -9844,7 +9844,7 @@ class Dehumidifier < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.dehumidifiers.delete(self) end @@ -9860,7 +9860,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -9880,7 +9880,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param dehumidifier [Oga::XML::Element] The current Dehumidifier XML element - # @return [void] + # @return [nil] def from_doc(dehumidifier) return if dehumidifier.nil? @@ -9899,7 +9899,7 @@ def from_doc(dehumidifier) class CookingRanges < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << CookingRange.new(@parent_object, **kwargs) end @@ -9907,7 +9907,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -9931,7 +9931,7 @@ class CookingRange < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.cooking_ranges.delete(self) end @@ -9947,7 +9947,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -9967,7 +9967,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param cooking_range [Oga::XML::Element] The current CookingRange XML element - # @return [void] + # @return [nil] def from_doc(cooking_range) return if cooking_range.nil? @@ -9986,7 +9986,7 @@ def from_doc(cooking_range) class Ovens < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Oven.new(@parent_object, **kwargs) end @@ -9994,7 +9994,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -10012,7 +10012,7 @@ class Oven < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.ovens.delete(self) end @@ -10028,7 +10028,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -10042,7 +10042,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param oven [Oga::XML::Element] The current Oven XML element - # @return [void] + # @return [nil] def from_doc(oven) return if oven.nil? @@ -10055,7 +10055,7 @@ def from_doc(oven) class LightingGroups < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << LightingGroup.new(@parent_object, **kwargs) end @@ -10063,7 +10063,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -10084,7 +10084,7 @@ class LightingGroup < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.lighting_groups.delete(self) end @@ -10100,7 +10100,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -10124,7 +10124,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param lighting_group [Oga::XML::Element] The current LightingGroup XML element - # @return [void] + # @return [nil] def from_doc(lighting_group) return if lighting_group.nil? @@ -10140,7 +10140,7 @@ def from_doc(lighting_group) class CeilingFans < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << CeilingFan.new(@parent_object, **kwargs) end @@ -10148,7 +10148,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -10171,7 +10171,7 @@ class CeilingFan < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.ceiling_fans.delete(self) end @@ -10187,7 +10187,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -10210,7 +10210,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param ceiling_fan [Oga::XML::Element] The current CeilingFan XML element - # @return [void] + # @return [nil] def from_doc(ceiling_fan) @id = HPXML::get_id(ceiling_fan) @efficiency = XMLHelper.get_value(ceiling_fan, "Airflow[FanSpeed='medium']/Efficiency", :float) @@ -10258,7 +10258,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -10294,7 +10294,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -10332,7 +10332,7 @@ def from_doc(building) class Pools < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << Pool.new(@parent_object, **kwargs) end @@ -10340,7 +10340,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -10373,7 +10373,7 @@ class Pool < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.pools.delete(self) end @@ -10389,7 +10389,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -10444,7 +10444,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param pool [Oga::XML::Element] The current Pool XML element - # @return [void] + # @return [nil] def from_doc(pool) @id = HPXML::get_id(pool) @type = XMLHelper.get_value(pool, 'Type', :string) @@ -10476,7 +10476,7 @@ def from_doc(pool) class PermanentSpas < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << PermanentSpa.new(@parent_object, **kwargs) end @@ -10484,7 +10484,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -10517,7 +10517,7 @@ class PermanentSpa < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.permanent_spas.delete(self) end @@ -10533,7 +10533,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -10588,7 +10588,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param spa [Oga::XML::Element] The current Spa XML element - # @return [void] + # @return [nil] def from_doc(spa) @id = HPXML::get_id(spa) @type = XMLHelper.get_value(spa, 'Type', :string) @@ -10620,7 +10620,7 @@ def from_doc(spa) class PortableSpas < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << PortableSpa.new(@parent_object, **kwargs) end @@ -10628,7 +10628,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -10645,7 +10645,7 @@ class PortableSpa < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.portable_spas.delete(self) end @@ -10661,7 +10661,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -10674,7 +10674,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param spa [Oga::XML::Element] The current Spa XML element - # @return [void] + # @return [nil] def from_doc(spa) @id = HPXML::get_id(spa) end @@ -10684,7 +10684,7 @@ def from_doc(spa) class PlugLoads < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << PlugLoad.new(@parent_object, **kwargs) end @@ -10692,7 +10692,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -10717,7 +10717,7 @@ class PlugLoad < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.plug_loads.delete(self) end @@ -10733,7 +10733,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -10758,7 +10758,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param plug_load [Oga::XML::Element] The current PlugLoad XML element - # @return [void] + # @return [nil] def from_doc(plug_load) @id = HPXML::get_id(plug_load) @plug_load_type = XMLHelper.get_value(plug_load, 'PlugLoadType', :string) @@ -10776,7 +10776,7 @@ def from_doc(plug_load) class FuelLoads < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << FuelLoad.new(@parent_object, **kwargs) end @@ -10784,7 +10784,7 @@ def add(**kwargs) # Populates the HPXML object(s) from the XML document. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def from_doc(building) return if building.nil? @@ -10810,7 +10810,7 @@ class FuelLoad < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete @parent_object.fuel_loads.delete(self) end @@ -10826,7 +10826,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param building [Oga::XML::Element] The current Building XML element - # @return [void] + # @return [nil] def to_doc(building) return if nil? @@ -10852,7 +10852,7 @@ def to_doc(building) # Populates the HPXML object(s) from the XML document. # # @param fuel_load [Oga::XML::Element] The current FuelLoad XML element - # @return [void] + # @return [nil] def from_doc(fuel_load) @id = HPXML::get_id(fuel_load) @fuel_load_type = XMLHelper.get_value(fuel_load, 'FuelLoadType', :string) @@ -10871,7 +10871,7 @@ def from_doc(fuel_load) class CoolingDetailedPerformanceData < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << CoolingPerformanceDataPoint.new(@parent_object, **kwargs) end @@ -10896,7 +10896,7 @@ def check_for_errors # Populates the HPXML object(s) from the XML document. # # @param hvac_system [Oga::XML::Element] The current HVAC system XML element - # @return [void] + # @return [nil] def from_doc(hvac_system) return if hvac_system.nil? @@ -10922,7 +10922,7 @@ class CoolingPerformanceDataPoint < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete (@parent_object.cooling_systems + @parent_object.heat_pumps).each do |cooling_system| cooling_system.cooling_detailed_performance_data.delete(self) @@ -10940,7 +10940,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param hvac_system [Oga::XML::Element] Parent XML element - # @return [void] + # @return [nil] def to_doc(hvac_system) detailed_performance_data = XMLHelper.create_elements_as_needed(hvac_system, ['CoolingDetailedPerformanceData']) performance_data_point = XMLHelper.add_element(detailed_performance_data, 'PerformanceDataPoint') @@ -10961,7 +10961,7 @@ def to_doc(hvac_system) # Populates the HPXML object(s) from the XML document. # # @param performance_data_point [Oga::XML::Element] The current CoolingPerformanceDataPoint XML element - # @return [void] + # @return [nil] def from_doc(performance_data_point) return if performance_data_point.nil? @@ -10979,7 +10979,7 @@ def from_doc(performance_data_point) class HeatingDetailedPerformanceData < BaseArrayElement # Adds a new object, with the specified keyword arguments, to the array. # - # @return [void] + # @return [nil] def add(**kwargs) self << HeatingPerformanceDataPoint.new(@parent_object, **kwargs) end @@ -11004,7 +11004,7 @@ def check_for_errors # Populates the HPXML object(s) from the XML document. # # @param hvac_system [Oga::XML::Element] The current HVAC system XML element - # @return [void] + # @return [nil] def from_doc(hvac_system) return if hvac_system.nil? @@ -11029,7 +11029,7 @@ class HeatingPerformanceDataPoint < BaseElement # Deletes the current object from the array. # - # @return [void] + # @return [nil] def delete (@parent_object.heating_systems + @parent_object.heat_pumps).each do |heating_system| heating_system.cooling_detailed_performance_data.delete(self) @@ -11047,7 +11047,7 @@ def check_for_errors # Adds this object to the provided Oga XML element. # # @param hvac_system [Oga::XML::Element] Parent XML element - # @return [void] + # @return [nil] def to_doc(hvac_system) detailed_performance_data = XMLHelper.create_elements_as_needed(hvac_system, ['HeatingDetailedPerformanceData']) performance_data_point = XMLHelper.add_element(detailed_performance_data, 'PerformanceDataPoint') @@ -11067,7 +11067,7 @@ def to_doc(hvac_system) # Populates the HPXML object(s) from the XML document. # # @param performance_data_point [Oga::XML::Element] The current HeatingPerformanceDataPoint XML element - # @return [void] + # @return [nil] def from_doc(performance_data_point) return if performance_data_point.nil? @@ -11297,7 +11297,7 @@ def self.check_dates(use_case, begin_month, begin_day, end_month, end_day) # # @param hpxml_object [HPXML::XXX] The Zone/Space/HVACPlant object # @param hpxml_element [Oga::XML::Element] The Zone/Space/HVACPlant XML element - # @return [void] + # @return [nil] def self.design_loads_to_doc(hpxml_object, hpxml_element) { HDL_ATTRS => 'Heating', CDL_SENS_ATTRS => 'CoolingSensible', @@ -11321,7 +11321,7 @@ def self.design_loads_to_doc(hpxml_object, hpxml_element) # # @param hpxml_object [HPXML::XXX] The Zone/Space/HVACPlant object # @param hpxml_element [Oga::XML::Element] The Zone/Space/HVACPlant XML element - # @return [void] + # @return [nil] def self.design_loads_from_doc(hpxml_object, hpxml_element) { HDL_ATTRS => 'Heating', CDL_SENS_ATTRS => 'CoolingSensible', diff --git a/HPXMLtoOpenStudio/resources/hpxml_defaults.rb b/HPXMLtoOpenStudio/resources/hpxml_defaults.rb index ce54c4b729..1a0044e0ed 100644 --- a/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +++ b/HPXMLtoOpenStudio/resources/hpxml_defaults.rb @@ -26,7 +26,7 @@ module HPXMLDefaults # @param convert_shared_systems [Boolean] Whether to convert shared systems to equivalent in-unit systems per ANSI 301 # @param design_load_details_output_file_path [String] Detailed HVAC sizing output file path # @param output_format [String] Detailed HVAC sizing output file format ('csv', 'json', or 'msgpack') - # @return [void] + # @return [nil] def self.apply(runner, hpxml, hpxml_bldg, eri_version, weather, schedules_file: nil, convert_shared_systems: true, design_load_details_output_file_path: nil, output_format: 'csv') cfa = hpxml_bldg.building_construction.conditioned_floor_area @@ -39,6 +39,8 @@ def self.apply(runner, hpxml, hpxml_bldg, eri_version, weather, schedules_file: add_zones_spaces_if_needed(hpxml, hpxml_bldg, cfa) + @default_schedules_csv_data = get_default_schedules_csv_data() + apply_header(hpxml.header, hpxml_bldg, weather) apply_building(hpxml_bldg, weather) apply_emissions_scenarios(hpxml.header, has_fuel) @@ -144,7 +146,7 @@ def self.unspin_azimuth(azimuth) # @param hpxml [HPXML] HPXML object # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) - # @return [void] + # @return [nil] def self.add_zones_spaces_if_needed(hpxml, hpxml_bldg, cfa) bldg_idx = hpxml.buildings.index(hpxml_bldg) if hpxml_bldg.conditioned_zones.empty? @@ -169,7 +171,7 @@ def self.add_zones_spaces_if_needed(hpxml, hpxml_bldg, cfa) # @param hpxml_header [HPXML::Header] HPXML Header object (one per HPXML file) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param weather [WeatherFile] Weather object containing EPW information - # @return [void] + # @return [nil] def self.apply_header(hpxml_header, hpxml_bldg, weather) if hpxml_header.timestep.nil? hpxml_header.timestep = 60 @@ -237,7 +239,7 @@ def self.apply_header(hpxml_header, hpxml_bldg, weather) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param weather [WeatherFile] Weather object containing EPW information # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @return [void] + # @return [nil] def self.apply_building_header_sizing(runner, hpxml_bldg, weather, nbeds) if hpxml_bldg.header.manualj_heating_design_temp.nil? hpxml_bldg.header.manualj_heating_design_temp = weather.design.HeatingDrybulb.round(2) @@ -356,7 +358,7 @@ def self.apply_building_header_sizing(runner, hpxml_bldg, weather, nbeds) # @param hpxml_header [HPXML::Header] HPXML Header object (one per HPXML file) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param weather [WeatherFile] Weather object containing EPW information - # @return [void] + # @return [nil] def self.apply_building_header(hpxml_header, hpxml_bldg, weather) if hpxml_bldg.header.natvent_days_per_week.nil? hpxml_bldg.header.natvent_days_per_week = 3 @@ -401,7 +403,7 @@ def self.apply_building_header(hpxml_header, hpxml_bldg, weather) # # @param hpxml_header [HPXML::Header] HPXML Header object (one per HPXML file) # @param has_fuel [Hash] Map of HPXML fuel type => boolean of whether fuel type is used - # @return [void] + # @return [nil] def self.apply_emissions_scenarios(hpxml_header, has_fuel) hpxml_header.emissions_scenarios.each do |scenario| # Electricity @@ -484,7 +486,7 @@ def self.apply_emissions_scenarios(hpxml_header, has_fuel) # @param hpxml_header [HPXML::Header] HPXML Header object (one per HPXML file) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param has_fuel [Hash] Map of HPXML fuel type => boolean of whether fuel type is used - # @return [void] + # @return [nil] def self.apply_utility_bill_scenarios(runner, hpxml_header, hpxml_bldg, has_fuel) hpxml_header.utility_bill_scenarios.each do |scenario| if scenario.elec_tariff_filepath.nil? @@ -600,7 +602,7 @@ def self.apply_utility_bill_scenarios(runner, hpxml_header, hpxml_bldg, has_fuel # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param weather [WeatherFile] Weather object containing EPW information - # @return [void] + # @return [nil] def self.apply_building(hpxml_bldg, weather) if hpxml_bldg.site.soil_type.nil? && hpxml_bldg.site.ground_conductivity.nil? && hpxml_bldg.site.ground_diffusivity.nil? hpxml_bldg.site.soil_type = HPXML::SiteSoilTypeUnknown @@ -742,7 +744,7 @@ def self.apply_building(hpxml_bldg, weather) # Assigns default values for omitted optional inputs in the HPXML::Site object # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_site(hpxml_bldg) if hpxml_bldg.site.site_type.nil? hpxml_bldg.site.site_type = HPXML::SiteTypeSuburban @@ -769,7 +771,7 @@ def self.apply_site(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::NeighborBuildings objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_neighbor_buildings(hpxml_bldg) hpxml_bldg.neighbor_buildings.each do |neighbor_building| if neighbor_building.azimuth.nil? @@ -787,7 +789,7 @@ def self.apply_neighbor_buildings(hpxml_bldg) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_building_occupancy(hpxml_bldg, schedules_file) if hpxml_bldg.building_occupancy.number_of_residents.nil? hpxml_bldg.building_construction.additional_properties.adjusted_number_of_bedrooms = hpxml_bldg.building_construction.number_of_bedrooms @@ -798,15 +800,15 @@ def self.apply_building_occupancy(hpxml_bldg, schedules_file) end schedules_file_includes_occupants = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:Occupants].name)) if hpxml_bldg.building_occupancy.weekday_fractions.nil? && !schedules_file_includes_occupants - hpxml_bldg.building_occupancy.weekday_fractions = Schedule.OccupantsWeekdayFractions + hpxml_bldg.building_occupancy.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:Occupants].name]['WeekdayScheduleFractions'] hpxml_bldg.building_occupancy.weekday_fractions_isdefaulted = true end if hpxml_bldg.building_occupancy.weekend_fractions.nil? && !schedules_file_includes_occupants - hpxml_bldg.building_occupancy.weekend_fractions = Schedule.OccupantsWeekendFractions + hpxml_bldg.building_occupancy.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:Occupants].name]['WeekendScheduleFractions'] hpxml_bldg.building_occupancy.weekend_fractions_isdefaulted = true end if hpxml_bldg.building_occupancy.monthly_multipliers.nil? && !schedules_file_includes_occupants - hpxml_bldg.building_occupancy.monthly_multipliers = Schedule.OccupantsMonthlyMultipliers + hpxml_bldg.building_occupancy.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:Occupants].name]['MonthlyScheduleMultipliers'] hpxml_bldg.building_occupancy.monthly_multipliers_isdefaulted = true end if hpxml_bldg.building_occupancy.general_water_use_usage_multiplier.nil? @@ -815,15 +817,15 @@ def self.apply_building_occupancy(hpxml_bldg, schedules_file) end schedules_file_includes_water = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:GeneralWaterUse].name)) if hpxml_bldg.building_occupancy.general_water_use_weekday_fractions.nil? && !schedules_file_includes_water - hpxml_bldg.building_occupancy.general_water_use_weekday_fractions = Schedule.GeneralWaterUseWeekdayFractions + hpxml_bldg.building_occupancy.general_water_use_weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:GeneralWaterUse].name]['GeneralWaterUseWeekdayScheduleFractions'] hpxml_bldg.building_occupancy.general_water_use_weekday_fractions_isdefaulted = true end if hpxml_bldg.building_occupancy.general_water_use_weekend_fractions.nil? && !schedules_file_includes_water - hpxml_bldg.building_occupancy.general_water_use_weekend_fractions = Schedule.GeneralWaterUseWeekendFractions + hpxml_bldg.building_occupancy.general_water_use_weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:GeneralWaterUse].name]['GeneralWaterUseWeekendScheduleFractions'] hpxml_bldg.building_occupancy.general_water_use_weekend_fractions_isdefaulted = true end if hpxml_bldg.building_occupancy.general_water_use_monthly_multipliers.nil? && !schedules_file_includes_water - hpxml_bldg.building_occupancy.general_water_use_monthly_multipliers = Schedule.GeneralWaterUseMonthlyMultipliers + hpxml_bldg.building_occupancy.general_water_use_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:GeneralWaterUse].name]['GeneralWaterUseMonthlyScheduleMultipliers'] hpxml_bldg.building_occupancy.general_water_use_monthly_multipliers_isdefaulted = true end end @@ -833,7 +835,7 @@ def self.apply_building_occupancy(hpxml_bldg, schedules_file) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @return [void] + # @return [nil] def self.apply_building_construction(hpxml_bldg, cfa, nbeds) cond_crawl_volume = hpxml_bldg.inferred_conditioned_crawlspace_volume() if hpxml_bldg.building_construction.average_ceiling_height.nil? @@ -858,7 +860,7 @@ def self.apply_building_construction(hpxml_bldg, cfa, nbeds) # Assigns default values for omitted optional inputs in the HPXML::Zones and HPXML::Spaces objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_zone_spaces(hpxml_bldg) hpxml_bldg.conditioned_spaces.each do |space| if space.fenestration_load_procedure.nil? @@ -872,7 +874,7 @@ def self.apply_zone_spaces(hpxml_bldg) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param weather [WeatherFile] Weather object containing EPW information - # @return [void] + # @return [nil] def self.apply_climate_and_risk_zones(hpxml_bldg, weather) if (not weather.nil?) && hpxml_bldg.climate_and_risk_zones.climate_zone_ieccs.empty? zone = Location.get_climate_zone_iecc(weather.header.WMONumber) @@ -888,7 +890,7 @@ def self.apply_climate_and_risk_zones(hpxml_bldg, weather) # Assigns default values for omitted optional inputs in the HPXML::Attic objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_attics(hpxml_bldg) if hpxml_bldg.has_location(HPXML::LocationAtticUnvented) unvented_attics = hpxml_bldg.attics.select { |a| a.attic_type == HPXML::AtticTypeUnvented } @@ -933,7 +935,7 @@ def self.apply_attics(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::Foundation objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_foundations(hpxml_bldg) if hpxml_bldg.has_location(HPXML::LocationCrawlspaceUnvented) unvented_crawls = hpxml_bldg.foundations.select { |f| f.foundation_type == HPXML::FoundationTypeCrawlspaceUnvented } @@ -1013,7 +1015,7 @@ def self.apply_foundations(hpxml_bldg) # Note: This needs to be called after we have applied defaults for ducts. # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_infiltration(hpxml_bldg) infil_measurement = Airflow.get_infiltration_measurement_of_interest(hpxml_bldg) if infil_measurement.infiltration_volume.nil? @@ -1106,7 +1108,7 @@ def self.apply_infiltration(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::Roof objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_roofs(hpxml_bldg) hpxml_bldg.roofs.each do |roof| if roof.azimuth.nil? @@ -1166,7 +1168,7 @@ def self.apply_roofs(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::RimJoist objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_rim_joists(hpxml_bldg) hpxml_bldg.rim_joists.each do |rim_joist| if rim_joist.azimuth.nil? @@ -1205,7 +1207,7 @@ def self.apply_rim_joists(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::Wall objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_walls(hpxml_bldg) hpxml_bldg.walls.each do |wall| if wall.azimuth.nil? @@ -1268,7 +1270,7 @@ def self.apply_walls(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::FoundationWall objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_foundation_walls(hpxml_bldg) hpxml_bldg.foundation_walls.each do |foundation_wall| if foundation_wall.type.nil? @@ -1328,7 +1330,7 @@ def self.apply_foundation_walls(hpxml_bldg) # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_floors(runner, hpxml_bldg) hpxml_bldg.floors.each do |floor| if floor.floor_or_ceiling.nil? @@ -1386,7 +1388,7 @@ def self.apply_floors(runner, hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::Slab objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_slabs(hpxml_bldg) hpxml_bldg.slabs.each do |slab| if slab.thickness.nil? @@ -1424,7 +1426,7 @@ def self.apply_slabs(hpxml_bldg) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions - # @return [void] + # @return [nil] def self.apply_windows(hpxml_bldg, eri_version) hpxml_bldg.windows.each do |window| if window.ufactor.nil? || window.shgc.nil? @@ -1504,7 +1506,7 @@ def self.apply_windows(hpxml_bldg, eri_version) # Assigns default values for omitted optional inputs in the HPXML::Skylight objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_skylights(hpxml_bldg) hpxml_bldg.skylights.each do |skylight| if skylight.azimuth.nil? @@ -1579,7 +1581,7 @@ def self.apply_skylights(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::Door objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_doors(hpxml_bldg) hpxml_bldg.doors.each do |door| if door.azimuth.nil? @@ -1606,7 +1608,7 @@ def self.apply_doors(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::PartitionWallMass object # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_partition_wall_mass(hpxml_bldg) if hpxml_bldg.partition_wall_mass.area_fraction.nil? hpxml_bldg.partition_wall_mass.area_fraction = 1.0 @@ -1625,7 +1627,7 @@ def self.apply_partition_wall_mass(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::FurnitureMass object # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_furniture_mass(hpxml_bldg) if hpxml_bldg.furniture_mass.area_fraction.nil? hpxml_bldg.furniture_mass.area_fraction = 0.4 @@ -1645,7 +1647,7 @@ def self.apply_furniture_mass(hpxml_bldg) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param weather [WeatherFile] Weather object containing EPW information # @param convert_shared_systems [Boolean] Whether to convert shared systems to equivalent in-unit systems per ANSI 301 - # @return [void] + # @return [nil] def self.apply_hvac(runner, hpxml, hpxml_bldg, weather, convert_shared_systems) if convert_shared_systems HVAC.apply_shared_systems(hpxml_bldg) @@ -2169,7 +2171,7 @@ def self.apply_hvac(runner, hpxml, hpxml_bldg, weather, convert_shared_systems) # Currently these objects are only used for variable-speed air source systems. # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_detailed_performance_data_for_var_speed_systems(hpxml_bldg) (hpxml_bldg.cooling_systems + hpxml_bldg.heat_pumps).each do |hvac_system| is_hp = hvac_system.is_a? HPXML::HeatPump @@ -2240,7 +2242,7 @@ def self.apply_detailed_performance_data_for_var_speed_systems(hpxml_bldg) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions - # @return [void] + # @return [nil] def self.apply_hvac_control(hpxml_bldg, schedules_file, eri_version) hpxml_bldg.hvac_controls.each do |hvac_control| schedules_file_includes_heating_setpoint_temp = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:HeatingSetpoint].name)) @@ -2308,7 +2310,7 @@ def self.apply_hvac_control(hpxml_bldg, schedules_file, eri_version) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param ncfl [Double] Total number of conditioned floors in the dwelling unit # @param ncfl_ag [Double] Number of conditioned floors above grade in the dwelling unit - # @return [void] + # @return [nil] def self.apply_hvac_distribution(hpxml_bldg, ncfl, ncfl_ag) hpxml_bldg.hvac_distributions.each do |hvac_distribution| next unless hvac_distribution.distribution_system_type == HPXML::HVACDistributionTypeAir @@ -2459,7 +2461,7 @@ def self.apply_hvac_distribution(hpxml_bldg, ncfl, ncfl_ag) # Note: This needs to be called after we have applied defaults for ducts. # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_hvac_location(hpxml_bldg) hpxml_bldg.hvac_systems.each do |hvac_system| next unless hvac_system.location.nil? @@ -2525,7 +2527,7 @@ def self.apply_hvac_location(hpxml_bldg) # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions - # @return [void] + # @return [nil] def self.apply_ventilation_fans(hpxml_bldg, weather, cfa, nbeds, eri_version) # Default mech vent systems hpxml_bldg.ventilation_fans.each do |vent_fan| @@ -2639,7 +2641,7 @@ def self.apply_ventilation_fans(hpxml_bldg, weather, cfa, nbeds, eri_version) # @param nbeds [Integer] Number of bedrooms in the dwelling unit # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_water_heaters(hpxml_bldg, nbeds, eri_version, schedules_file) hpxml_bldg.water_heating_systems.each do |water_heating_system| if water_heating_system.is_shared_system.nil? @@ -2712,7 +2714,7 @@ def self.apply_water_heaters(hpxml_bldg, nbeds, eri_version, schedules_file) # Note: This needs to be called after we have applied defaults for HVAC/DHW systems. # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_flue_or_chimney(hpxml_bldg) if hpxml_bldg.air_infiltration.has_flue_or_chimney_in_conditioned_space.nil? hpxml_bldg.air_infiltration.has_flue_or_chimney_in_conditioned_space = get_default_flue_or_chimney_in_conditioned_space(hpxml_bldg) @@ -2726,7 +2728,7 @@ def self.apply_flue_or_chimney(hpxml_bldg) # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param ncfl [Double] Total number of conditioned floors in the dwelling unit # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_hot_water_distribution(hpxml_bldg, cfa, ncfl, schedules_file) return if hpxml_bldg.hot_water_distributions.size == 0 @@ -2771,34 +2773,34 @@ def self.apply_hot_water_distribution(hpxml_bldg, cfa, ncfl, schedules_file) recirc_control_type = hot_water_distribution.has_shared_recirculation ? hot_water_distribution.shared_recirculation_control_type : hot_water_distribution.recirculation_control_type if [HPXML::DHWRecircControlTypeNone, HPXML::DHWRecircControlTypeTimer].include?(recirc_control_type) if hot_water_distribution.recirculation_pump_weekday_fractions.nil? && !schedules_file_includes_recirculation_pump - hot_water_distribution.recirculation_pump_weekday_fractions = Schedule.RecirculationPumpWithoutControlWeekdayFractions + hot_water_distribution.recirculation_pump_weekday_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekdayScheduleFractions'] hot_water_distribution.recirculation_pump_weekday_fractions_isdefaulted = true end if hot_water_distribution.recirculation_pump_weekend_fractions.nil? && !schedules_file_includes_recirculation_pump - hot_water_distribution.recirculation_pump_weekend_fractions = Schedule.RecirculationPumpWithoutControlWeekendFractions + hot_water_distribution.recirculation_pump_weekend_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekendScheduleFractions'] hot_water_distribution.recirculation_pump_weekend_fractions_isdefaulted = true end elsif [HPXML::DHWRecircControlTypeSensor, HPXML::DHWRecircControlTypeManual].include?(recirc_control_type) if hot_water_distribution.recirculation_pump_weekday_fractions.nil? && !schedules_file_includes_recirculation_pump - hot_water_distribution.recirculation_pump_weekday_fractions = Schedule.RecirculationPumpDemandControlledWeekdayFractions + hot_water_distribution.recirculation_pump_weekday_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekdayScheduleFractions'] hot_water_distribution.recirculation_pump_weekday_fractions_isdefaulted = true end if hot_water_distribution.recirculation_pump_weekend_fractions.nil? && !schedules_file_includes_recirculation_pump - hot_water_distribution.recirculation_pump_weekend_fractions = Schedule.RecirculationPumpDemandControlledWeekendFractions + hot_water_distribution.recirculation_pump_weekend_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekendScheduleFractions'] hot_water_distribution.recirculation_pump_weekend_fractions_isdefaulted = true end elsif [HPXML::DHWRecircControlTypeTemperature].include?(recirc_control_type) if hot_water_distribution.recirculation_pump_weekday_fractions.nil? && !schedules_file_includes_recirculation_pump - hot_water_distribution.recirculation_pump_weekday_fractions = Schedule.RecirculationPumpTemperatureControlledWeekdayFractions + hot_water_distribution.recirculation_pump_weekday_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_temperature_control"]['RecirculationPumpWeekdayScheduleFractions'] hot_water_distribution.recirculation_pump_weekday_fractions_isdefaulted = true end if hot_water_distribution.recirculation_pump_weekend_fractions.nil? && !schedules_file_includes_recirculation_pump - hot_water_distribution.recirculation_pump_weekend_fractions = Schedule.RecirculationPumpTemperatureControlledWeekendFractions + hot_water_distribution.recirculation_pump_weekend_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_temperature_control"]['RecirculationPumpWeekendScheduleFractions'] hot_water_distribution.recirculation_pump_weekend_fractions_isdefaulted = true end end if hot_water_distribution.recirculation_pump_monthly_multipliers.nil? && !schedules_file_includes_recirculation_pump - hot_water_distribution.recirculation_pump_monthly_multipliers = Schedule.RecirculationPumpMonthlyMultipliers + hot_water_distribution.recirculation_pump_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers'] hot_water_distribution.recirculation_pump_monthly_multipliers_isdefaulted = true end end @@ -2808,7 +2810,7 @@ def self.apply_hot_water_distribution(hpxml_bldg, cfa, ncfl, schedules_file) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_water_fixtures(hpxml_bldg, schedules_file) return if hpxml_bldg.hot_water_distributions.size == 0 @@ -2827,15 +2829,15 @@ def self.apply_water_fixtures(hpxml_bldg, schedules_file) end schedules_file_includes_fixtures = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:HotWaterFixtures].name)) if hpxml_bldg.water_heating.water_fixtures_weekday_fractions.nil? && !schedules_file_includes_fixtures - hpxml_bldg.water_heating.water_fixtures_weekday_fractions = Schedule.FixturesWeekdayFractions + hpxml_bldg.water_heating.water_fixtures_weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterFixtures].name]['WaterFixturesWeekdayScheduleFractions'] hpxml_bldg.water_heating.water_fixtures_weekday_fractions_isdefaulted = true end if hpxml_bldg.water_heating.water_fixtures_weekend_fractions.nil? && !schedules_file_includes_fixtures - hpxml_bldg.water_heating.water_fixtures_weekend_fractions = Schedule.FixturesWeekendFractions + hpxml_bldg.water_heating.water_fixtures_weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterFixtures].name]['WaterFixturesWeekendScheduleFractions'] hpxml_bldg.water_heating.water_fixtures_weekend_fractions_isdefaulted = true end if hpxml_bldg.water_heating.water_fixtures_monthly_multipliers.nil? && !schedules_file_includes_fixtures - hpxml_bldg.water_heating.water_fixtures_monthly_multipliers = Schedule.FixturesMonthlyMultipliers + hpxml_bldg.water_heating.water_fixtures_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterFixtures].name]['WaterFixturesMonthlyScheduleMultipliers'] hpxml_bldg.water_heating.water_fixtures_monthly_multipliers_isdefaulted = true end end @@ -2843,7 +2845,7 @@ def self.apply_water_fixtures(hpxml_bldg, schedules_file) # Assigns default values for omitted optional inputs in the HPXML::SolarThermalSystem objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_solar_thermal_systems(hpxml_bldg) hpxml_bldg.solar_thermal_systems.each do |solar_thermal_system| if solar_thermal_system.collector_azimuth.nil? @@ -2864,7 +2866,7 @@ def self.apply_solar_thermal_systems(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::PVSystem objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_pv_systems(hpxml_bldg) hpxml_bldg.pv_systems.each do |pv_system| if pv_system.array_azimuth.nil? @@ -2907,7 +2909,7 @@ def self.apply_pv_systems(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::Generator objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_generators(hpxml_bldg) hpxml_bldg.generators.each do |generator| if generator.is_shared_system.nil? @@ -2920,7 +2922,7 @@ def self.apply_generators(hpxml_bldg) # Assigns default values for omitted optional inputs in the HPXML::Battery objects # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_batteries(hpxml_bldg) default_values = Battery.get_battery_default_values(hpxml_bldg.has_location(HPXML::LocationGarage)) hpxml_bldg.batteries.each do |battery| @@ -2989,7 +2991,7 @@ def self.apply_batteries(hpxml_bldg) # @param nbeds [Integer] Number of bedrooms in the dwelling unit # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_appliances(hpxml_bldg, nbeds, eri_version, schedules_file) # Default clothes washer if hpxml_bldg.clothes_washers.size > 0 @@ -3025,15 +3027,15 @@ def self.apply_appliances(hpxml_bldg, nbeds, eri_version, schedules_file) end schedules_file_includes_cw = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:ClothesWasher].name)) if clothes_washer.weekday_fractions.nil? && !schedules_file_includes_cw - clothes_washer.weekday_fractions = Schedule.ClothesWasherWeekdayFractions + clothes_washer.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['WeekdayScheduleFractions'] clothes_washer.weekday_fractions_isdefaulted = true end if clothes_washer.weekend_fractions.nil? && !schedules_file_includes_cw - clothes_washer.weekend_fractions = Schedule.ClothesWasherWeekendFractions + clothes_washer.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['WeekendScheduleFractions'] clothes_washer.weekend_fractions_isdefaulted = true end if clothes_washer.monthly_multipliers.nil? && !schedules_file_includes_cw - clothes_washer.monthly_multipliers = Schedule.ClothesWasherMonthlyMultipliers + clothes_washer.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['MonthlyScheduleMultipliers'] clothes_washer.monthly_multipliers_isdefaulted = true end end @@ -3073,15 +3075,15 @@ def self.apply_appliances(hpxml_bldg, nbeds, eri_version, schedules_file) end schedules_file_includes_cd = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:ClothesDryer].name)) if clothes_dryer.weekday_fractions.nil? && !schedules_file_includes_cd - clothes_dryer.weekday_fractions = Schedule.ClothesDryerWeekdayFractions + clothes_dryer.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['WeekdayScheduleFractions'] clothes_dryer.weekday_fractions_isdefaulted = true end if clothes_dryer.weekend_fractions.nil? && !schedules_file_includes_cd - clothes_dryer.weekend_fractions = Schedule.ClothesDryerWeekendFractions + clothes_dryer.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['WeekendScheduleFractions'] clothes_dryer.weekend_fractions_isdefaulted = true end if clothes_dryer.monthly_multipliers.nil? && !schedules_file_includes_cd - clothes_dryer.monthly_multipliers = Schedule.ClothesDryerMonthlyMultipliers + clothes_dryer.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['MonthlyScheduleMultipliers'] clothes_dryer.monthly_multipliers_isdefaulted = true end end @@ -3118,15 +3120,15 @@ def self.apply_appliances(hpxml_bldg, nbeds, eri_version, schedules_file) end schedules_file_includes_dw = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:Dishwasher].name)) if dishwasher.weekday_fractions.nil? && !schedules_file_includes_dw - dishwasher.weekday_fractions = Schedule.DishwasherWeekdayFractions + dishwasher.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['WeekdayScheduleFractions'] dishwasher.weekday_fractions_isdefaulted = true end if dishwasher.weekend_fractions.nil? && !schedules_file_includes_dw - dishwasher.weekend_fractions = Schedule.DishwasherWeekendFractions + dishwasher.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['WeekendScheduleFractions'] dishwasher.weekend_fractions_isdefaulted = true end if dishwasher.monthly_multipliers.nil? && !schedules_file_includes_dw - dishwasher.monthly_multipliers = Schedule.DishwasherMonthlyMultipliers + dishwasher.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['MonthlyScheduleMultipliers'] dishwasher.monthly_multipliers_isdefaulted = true end end @@ -3152,24 +3154,24 @@ def self.apply_appliances(hpxml_bldg, nbeds, eri_version, schedules_file) if !schedules_file_includes_extrafridge if schedules_includes_fractions_multipliers if refrigerator.weekday_fractions.nil? - refrigerator.weekday_fractions = Schedule.ExtraRefrigeratorWeekdayFractions + refrigerator.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:ExtraRefrigerator].name]['WeekdayScheduleFractions'] refrigerator.weekday_fractions_isdefaulted = true end if refrigerator.weekend_fractions.nil? - refrigerator.weekend_fractions = Schedule.ExtraRefrigeratorWeekendFractions + refrigerator.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:ExtraRefrigerator].name]['WeekendScheduleFractions'] refrigerator.weekend_fractions_isdefaulted = true end if refrigerator.monthly_multipliers.nil? - refrigerator.monthly_multipliers = Schedule.ExtraRefrigeratorMonthlyMultipliers + refrigerator.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:ExtraRefrigerator].name]['MonthlyScheduleMultipliers'] refrigerator.monthly_multipliers_isdefaulted = true end else if refrigerator.constant_coefficients.nil? - refrigerator.constant_coefficients = Schedule.ExtraRefrigeratorConstantCoefficients + refrigerator.constant_coefficients = @default_schedules_csv_data[SchedulesFile::Columns[:ExtraRefrigerator].name]['ConstantScheduleCoefficients'] refrigerator.constant_coefficients_isdefaulted = true end if refrigerator.temperature_coefficients.nil? - refrigerator.temperature_coefficients = Schedule.ExtraRefrigeratorTemperatureCoefficients + refrigerator.temperature_coefficients = @default_schedules_csv_data[SchedulesFile::Columns[:ExtraRefrigerator].name]['TemperatureScheduleCoefficients'] refrigerator.temperature_coefficients_isdefaulted = true end end @@ -3188,24 +3190,24 @@ def self.apply_appliances(hpxml_bldg, nbeds, eri_version, schedules_file) if !schedules_file_includes_fridge if schedules_includes_fractions_multipliers if refrigerator.weekday_fractions.nil? - refrigerator.weekday_fractions = Schedule.RefrigeratorWeekdayFractions + refrigerator.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['WeekdayScheduleFractions'] refrigerator.weekday_fractions_isdefaulted = true end if refrigerator.weekend_fractions.nil? - refrigerator.weekend_fractions = Schedule.RefrigeratorWeekendFractions + refrigerator.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['WeekendScheduleFractions'] refrigerator.weekend_fractions_isdefaulted = true end if refrigerator.monthly_multipliers.nil? - refrigerator.monthly_multipliers = Schedule.RefrigeratorMonthlyMultipliers + refrigerator.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['MonthlyScheduleMultipliers'] refrigerator.monthly_multipliers_isdefaulted = true end else if refrigerator.constant_coefficients.nil? - refrigerator.constant_coefficients = Schedule.RefrigeratorConstantCoefficients + refrigerator.constant_coefficients = @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['ConstantScheduleCoefficients'] refrigerator.constant_coefficients_isdefaulted = true end if refrigerator.temperature_coefficients.nil? - refrigerator.temperature_coefficients = Schedule.RefrigeratorTemperatureCoefficients + refrigerator.temperature_coefficients = @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['TemperatureScheduleCoefficients'] refrigerator.temperature_coefficients_isdefaulted = true end end @@ -3237,15 +3239,15 @@ def self.apply_appliances(hpxml_bldg, nbeds, eri_version, schedules_file) next unless !schedules_includes_schedule_coefficients if freezer.weekday_fractions.nil? && !schedules_file_includes_freezer - freezer.weekday_fractions = Schedule.FreezerWeekdayFractions + freezer.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:Freezer].name]['WeekdayScheduleFractions'] freezer.weekday_fractions_isdefaulted = true end if freezer.weekend_fractions.nil? && !schedules_file_includes_freezer - freezer.weekend_fractions = Schedule.FreezerWeekendFractions + freezer.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:Freezer].name]['WeekendScheduleFractions'] freezer.weekend_fractions_isdefaulted = true end if freezer.monthly_multipliers.nil? && !schedules_file_includes_freezer - freezer.monthly_multipliers = Schedule.FreezerMonthlyMultipliers + freezer.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:Freezer].name]['MonthlyScheduleMultipliers'] freezer.monthly_multipliers_isdefaulted = true end end @@ -3268,15 +3270,15 @@ def self.apply_appliances(hpxml_bldg, nbeds, eri_version, schedules_file) end schedules_file_includes_range = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:CookingRange].name)) if cooking_range.weekday_fractions.nil? && !schedules_file_includes_range - cooking_range.weekday_fractions = Schedule.CookingRangeWeekdayFractions + cooking_range.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['WeekdayScheduleFractions'] cooking_range.weekday_fractions_isdefaulted = true end if cooking_range.weekend_fractions.nil? && !schedules_file_includes_range - cooking_range.weekend_fractions = Schedule.CookingRangeWeekendFractions + cooking_range.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['WeekendScheduleFractions'] cooking_range.weekend_fractions_isdefaulted = true end if cooking_range.monthly_multipliers.nil? && !schedules_file_includes_range - cooking_range.monthly_multipliers = Schedule.CookingRangeMonthlyMultipliers + cooking_range.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['MonthlyScheduleMultipliers'] cooking_range.monthly_multipliers_isdefaulted = true end end @@ -3296,7 +3298,7 @@ def self.apply_appliances(hpxml_bldg, nbeds, eri_version, schedules_file) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_lighting(hpxml_bldg, schedules_file) return if hpxml_bldg.lighting_groups.empty? @@ -3312,46 +3314,45 @@ def self.apply_lighting(hpxml_bldg, schedules_file) hpxml_bldg.lighting.exterior_usage_multiplier = 1.0 hpxml_bldg.lighting.exterior_usage_multiplier_isdefaulted = true end - default_lighting_monthly_multipliers = Schedule.LightingMonthlyMultipliers schedules_file_includes_lighting_interior = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:LightingInterior].name)) if hpxml_bldg.lighting.interior_weekday_fractions.nil? && !schedules_file_includes_lighting_interior - hpxml_bldg.lighting.interior_weekday_fractions = Schedule.LightingInteriorWeekdayFractions + hpxml_bldg.lighting.interior_weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorWeekdayScheduleFractions'] hpxml_bldg.lighting.interior_weekday_fractions_isdefaulted = true end if hpxml_bldg.lighting.interior_weekend_fractions.nil? && !schedules_file_includes_lighting_interior - hpxml_bldg.lighting.interior_weekend_fractions = Schedule.LightingInteriorWeekendFractions + hpxml_bldg.lighting.interior_weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorWeekendScheduleFractions'] hpxml_bldg.lighting.interior_weekend_fractions_isdefaulted = true end if hpxml_bldg.lighting.interior_monthly_multipliers.nil? && !schedules_file_includes_lighting_interior - hpxml_bldg.lighting.interior_monthly_multipliers = default_lighting_monthly_multipliers + hpxml_bldg.lighting.interior_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers'] hpxml_bldg.lighting.interior_monthly_multipliers_isdefaulted = true end if hpxml_bldg.has_location(HPXML::LocationGarage) schedules_file_includes_lighting_garage = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:LightingGarage].name)) if hpxml_bldg.lighting.garage_weekday_fractions.nil? && !schedules_file_includes_lighting_garage - hpxml_bldg.lighting.garage_weekday_fractions = Schedule.LightingGarageWeekdayFractions + hpxml_bldg.lighting.garage_weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:LightingGarage].name]['GarageWeekdayScheduleFractions'] hpxml_bldg.lighting.garage_weekday_fractions_isdefaulted = true end if hpxml_bldg.lighting.garage_weekend_fractions.nil? && !schedules_file_includes_lighting_garage - hpxml_bldg.lighting.garage_weekend_fractions = Schedule.LightingGarageWeekendFractions + hpxml_bldg.lighting.garage_weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:LightingGarage].name]['GarageWeekendScheduleFractions'] hpxml_bldg.lighting.garage_weekend_fractions_isdefaulted = true end if hpxml_bldg.lighting.garage_monthly_multipliers.nil? && !schedules_file_includes_lighting_garage - hpxml_bldg.lighting.garage_monthly_multipliers = default_lighting_monthly_multipliers + hpxml_bldg.lighting.garage_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:LightingGarage].name]['GarageMonthlyScheduleMultipliers'] hpxml_bldg.lighting.garage_monthly_multipliers_isdefaulted = true end end schedules_file_includes_lighting_exterior = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:LightingExterior].name)) if hpxml_bldg.lighting.exterior_weekday_fractions.nil? && !schedules_file_includes_lighting_exterior - hpxml_bldg.lighting.exterior_weekday_fractions = Schedule.LightingExteriorWeekdayFractions + hpxml_bldg.lighting.exterior_weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorWeekdayScheduleFractions'] hpxml_bldg.lighting.exterior_weekday_fractions_isdefaulted = true end if hpxml_bldg.lighting.exterior_weekend_fractions.nil? && !schedules_file_includes_lighting_exterior - hpxml_bldg.lighting.exterior_weekend_fractions = Schedule.LightingExteriorWeekendFractions + hpxml_bldg.lighting.exterior_weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorWeekendScheduleFractions'] hpxml_bldg.lighting.exterior_weekend_fractions_isdefaulted = true end if hpxml_bldg.lighting.exterior_monthly_multipliers.nil? && !schedules_file_includes_lighting_exterior - hpxml_bldg.lighting.exterior_monthly_multipliers = default_lighting_monthly_multipliers + hpxml_bldg.lighting.exterior_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorMonthlyScheduleMultipliers'] hpxml_bldg.lighting.exterior_monthly_multipliers_isdefaulted = true end if hpxml_bldg.lighting.holiday_exists @@ -3378,11 +3379,11 @@ def self.apply_lighting(hpxml_bldg, schedules_file) end schedules_file_includes_lighting_holiday_exterior = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:LightingExteriorHoliday].name)) if hpxml_bldg.lighting.holiday_weekday_fractions.nil? && !schedules_file_includes_lighting_holiday_exterior - hpxml_bldg.lighting.holiday_weekday_fractions = Schedule.LightingExteriorHolidayWeekdayFractions + hpxml_bldg.lighting.holiday_weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:LightingExteriorHoliday].name]['WeekdayScheduleFractions'] hpxml_bldg.lighting.holiday_weekday_fractions_isdefaulted = true end if hpxml_bldg.lighting.holiday_weekend_fractions.nil? && !schedules_file_includes_lighting_holiday_exterior - hpxml_bldg.lighting.holiday_weekend_fractions = Schedule.LightingExteriorHolidayWeekendFractions + hpxml_bldg.lighting.holiday_weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:LightingExteriorHoliday].name]['WeekendScheduleFractions'] hpxml_bldg.lighting.holiday_weekend_fractions_isdefaulted = true end end @@ -3394,7 +3395,7 @@ def self.apply_lighting(hpxml_bldg, schedules_file) # @param nbeds [Integer] Number of bedrooms in the dwelling unit # @param weather [WeatherFile] Weather object containing EPW information # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_ceiling_fans(hpxml_bldg, nbeds, weather, schedules_file) return if hpxml_bldg.ceiling_fans.size == 0 @@ -3409,11 +3410,11 @@ def self.apply_ceiling_fans(hpxml_bldg, nbeds, weather, schedules_file) end schedules_file_includes_ceiling_fan = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:CeilingFan].name)) if ceiling_fan.weekday_fractions.nil? && !schedules_file_includes_ceiling_fan - ceiling_fan.weekday_fractions = Schedule.CeilingFanWeekdayFractions + ceiling_fan.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:CeilingFan].name]['WeekdayScheduleFractions'] ceiling_fan.weekday_fractions_isdefaulted = true end if ceiling_fan.weekend_fractions.nil? && !schedules_file_includes_ceiling_fan - ceiling_fan.weekend_fractions = Schedule.CeilingFanWeekendFractions + ceiling_fan.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:CeilingFan].name]['WeekendScheduleFractions'] ceiling_fan.weekend_fractions_isdefaulted = true end if ceiling_fan.monthly_multipliers.nil? && !schedules_file_includes_ceiling_fan @@ -3427,7 +3428,7 @@ def self.apply_ceiling_fans(hpxml_bldg, nbeds, weather, schedules_file) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_pools_and_permanent_spas(hpxml_bldg, cfa, schedules_file) nbeds = hpxml_bldg.building_construction.additional_properties.adjusted_number_of_bedrooms hpxml_bldg.pools.each do |pool| @@ -3445,15 +3446,15 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_pool_pump = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:PoolPump].name)) if pool.pump_weekday_fractions.nil? && !schedules_file_includes_pool_pump - pool.pump_weekday_fractions = Schedule.PoolPumpWeekdayFractions + pool.pump_weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PoolPump].name]['WeekdayScheduleFractions'] pool.pump_weekday_fractions_isdefaulted = true end if pool.pump_weekend_fractions.nil? && !schedules_file_includes_pool_pump - pool.pump_weekend_fractions = Schedule.PoolPumpWeekendFractions + pool.pump_weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PoolPump].name]['WeekendScheduleFractions'] pool.pump_weekend_fractions_isdefaulted = true end if pool.pump_monthly_multipliers.nil? && !schedules_file_includes_pool_pump - pool.pump_monthly_multipliers = Schedule.PoolPumpMonthlyMultipliers + pool.pump_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PoolPump].name]['MonthlyScheduleMultipliers'] pool.pump_monthly_multipliers_isdefaulted = true end end @@ -3473,15 +3474,15 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_pool_heater = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:PoolHeater].name)) if pool.heater_weekday_fractions.nil? && !schedules_file_includes_pool_heater - pool.heater_weekday_fractions = Schedule.PoolHeaterWeekdayFractions + pool.heater_weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PoolHeater].name]['WeekdayScheduleFractions'] pool.heater_weekday_fractions_isdefaulted = true end if pool.heater_weekend_fractions.nil? && !schedules_file_includes_pool_heater - pool.heater_weekend_fractions = Schedule.PoolHeaterWeekendFractions + pool.heater_weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PoolHeater].name]['WeekendScheduleFractions'] pool.heater_weekend_fractions_isdefaulted = true end if pool.heater_monthly_multipliers.nil? && !schedules_file_includes_pool_heater - pool.heater_monthly_multipliers = Schedule.PoolHeaterMonthlyMultipliers + pool.heater_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PoolHeater].name]['MonthlyScheduleMultipliers'] pool.heater_monthly_multipliers_isdefaulted = true end end @@ -3501,15 +3502,15 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_permanent_spa_pump = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:PermanentSpaPump].name)) if spa.pump_weekday_fractions.nil? && !schedules_file_includes_permanent_spa_pump - spa.pump_weekday_fractions = Schedule.PermanentSpaPumpWeekdayFractions + spa.pump_weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaPump].name]['WeekdayScheduleFractions'] spa.pump_weekday_fractions_isdefaulted = true end if spa.pump_weekend_fractions.nil? && !schedules_file_includes_permanent_spa_pump - spa.pump_weekend_fractions = Schedule.PermanentSpaPumpWeekendFractions + spa.pump_weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaPump].name]['WeekendScheduleFractions'] spa.pump_weekend_fractions_isdefaulted = true end if spa.pump_monthly_multipliers.nil? && !schedules_file_includes_permanent_spa_pump - spa.pump_monthly_multipliers = Schedule.PermanentSpaPumpMonthlyMultipliers + spa.pump_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaPump].name]['MonthlyScheduleMultipliers'] spa.pump_monthly_multipliers_isdefaulted = true end end @@ -3529,15 +3530,15 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_permanent_spa_heater = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:PermanentSpaHeater].name)) if spa.heater_weekday_fractions.nil? && !schedules_file_includes_permanent_spa_heater - spa.heater_weekday_fractions = Schedule.PermanentSpaHeaterWeekdayFractions + spa.heater_weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaHeater].name]['WeekdayScheduleFractions'] spa.heater_weekday_fractions_isdefaulted = true end if spa.heater_weekend_fractions.nil? && !schedules_file_includes_permanent_spa_heater - spa.heater_weekend_fractions = Schedule.PermanentSpaHeaterWeekendFractions + spa.heater_weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaHeater].name]['WeekendScheduleFractions'] spa.heater_weekend_fractions_isdefaulted = true end if spa.heater_monthly_multipliers.nil? && !schedules_file_includes_permanent_spa_heater - spa.heater_monthly_multipliers = Schedule.PermanentSpaHeaterMonthlyMultipliers + spa.heater_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaHeater].name]['MonthlyScheduleMultipliers'] spa.heater_monthly_multipliers_isdefaulted = true end end @@ -3548,7 +3549,7 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, cfa, schedules_file) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_plug_loads(hpxml_bldg, cfa, schedules_file) nbeds = hpxml_bldg.building_construction.additional_properties.adjusted_number_of_bedrooms hpxml_bldg.plug_loads.each do |plug_load| @@ -3568,15 +3569,15 @@ def self.apply_plug_loads(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_plug_loads_other = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:PlugLoadsOther].name)) if plug_load.weekday_fractions.nil? && !schedules_file_includes_plug_loads_other - plug_load.weekday_fractions = Schedule.PlugLoadsOtherWeekdayFractions + plug_load.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['WeekdayScheduleFractions'] plug_load.weekday_fractions_isdefaulted = true end if plug_load.weekend_fractions.nil? && !schedules_file_includes_plug_loads_other - plug_load.weekend_fractions = Schedule.PlugLoadsOtherWeekendFractions + plug_load.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['WeekendScheduleFractions'] plug_load.weekend_fractions_isdefaulted = true end if plug_load.monthly_multipliers.nil? && !schedules_file_includes_plug_loads_other - plug_load.monthly_multipliers = Schedule.PlugLoadsOtherMonthlyMultipliers + plug_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['MonthlyScheduleMultipliers'] plug_load.monthly_multipliers_isdefaulted = true end elsif plug_load.plug_load_type == HPXML::PlugLoadTypeTelevision @@ -3595,15 +3596,15 @@ def self.apply_plug_loads(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_plug_loads_tv = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:PlugLoadsTV].name)) if plug_load.weekday_fractions.nil? && !schedules_file_includes_plug_loads_tv - plug_load.weekday_fractions = Schedule.PlugLoadsTVWeekdayFractions + plug_load.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['WeekdayScheduleFractions'] plug_load.weekday_fractions_isdefaulted = true end if plug_load.weekend_fractions.nil? && !schedules_file_includes_plug_loads_tv - plug_load.weekend_fractions = Schedule.PlugLoadsTVWeekendFractions + plug_load.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['WeekendScheduleFractions'] plug_load.weekend_fractions_isdefaulted = true end if plug_load.monthly_multipliers.nil? && !schedules_file_includes_plug_loads_tv - plug_load.monthly_multipliers = Schedule.PlugLoadsTVMonthlyMultipliers + plug_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['MonthlyScheduleMultipliers'] plug_load.monthly_multipliers_isdefaulted = true end elsif plug_load.plug_load_type == HPXML::PlugLoadTypeElectricVehicleCharging @@ -3622,15 +3623,15 @@ def self.apply_plug_loads(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_plug_loads_vehicle = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:PlugLoadsVehicle].name)) if plug_load.weekday_fractions.nil? && !schedules_file_includes_plug_loads_vehicle - plug_load.weekday_fractions = Schedule.PlugLoadsVehicleWeekdayFractions + plug_load.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsVehicle].name]['WeekdayScheduleFractions'] plug_load.weekday_fractions_isdefaulted = true end if plug_load.weekend_fractions.nil? && !schedules_file_includes_plug_loads_vehicle - plug_load.weekend_fractions = Schedule.PlugLoadsVehicleWeekendFractions + plug_load.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsVehicle].name]['WeekdayScheduleFractions'] plug_load.weekend_fractions_isdefaulted = true end if plug_load.monthly_multipliers.nil? && !schedules_file_includes_plug_loads_vehicle - plug_load.monthly_multipliers = Schedule.PlugLoadsVehicleMonthlyMultipliers + plug_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsVehicle].name]['MonthlyScheduleMultipliers'] plug_load.monthly_multipliers_isdefaulted = true end elsif plug_load.plug_load_type == HPXML::PlugLoadTypeWellPump @@ -3649,15 +3650,15 @@ def self.apply_plug_loads(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_plug_loads_well_pump = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:PlugLoadsWellPump].name)) if plug_load.weekday_fractions.nil? && !schedules_file_includes_plug_loads_well_pump - plug_load.weekday_fractions = Schedule.PlugLoadsWellPumpWeekdayFractions + plug_load.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsWellPump].name]['WeekdayScheduleFractions'] plug_load.weekday_fractions_isdefaulted = true end if plug_load.weekend_fractions.nil? && !schedules_file_includes_plug_loads_well_pump - plug_load.weekend_fractions = Schedule.PlugLoadsWellPumpWeekendFractions + plug_load.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsWellPump].name]['WeekdayScheduleFractions'] plug_load.weekend_fractions_isdefaulted = true end if plug_load.monthly_multipliers.nil? && !schedules_file_includes_plug_loads_well_pump - plug_load.monthly_multipliers = Schedule.PlugLoadsWellPumpMonthlyMultipliers + plug_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsWellPump].name]['MonthlyScheduleMultipliers'] plug_load.monthly_multipliers_isdefaulted = true end end @@ -3673,7 +3674,7 @@ def self.apply_plug_loads(hpxml_bldg, cfa, schedules_file) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_fuel_loads(hpxml_bldg, cfa, schedules_file) nbeds = hpxml_bldg.building_construction.additional_properties.adjusted_number_of_bedrooms hpxml_bldg.fuel_loads.each do |fuel_load| @@ -3692,15 +3693,15 @@ def self.apply_fuel_loads(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_fuel_loads_grill = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:FuelLoadsGrill].name)) if fuel_load.weekday_fractions.nil? && !schedules_file_includes_fuel_loads_grill - fuel_load.weekday_fractions = Schedule.FuelLoadsGrillWeekdayFractions + fuel_load.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsGrill].name]['WeekdayScheduleFractions'] fuel_load.weekday_fractions_isdefaulted = true end if fuel_load.weekend_fractions.nil? && !schedules_file_includes_fuel_loads_grill - fuel_load.weekend_fractions = Schedule.FuelLoadsGrillWeekendFractions + fuel_load.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsGrill].name]['WeekendScheduleFractions'] fuel_load.weekend_fractions_isdefaulted = true end if fuel_load.monthly_multipliers.nil? && !schedules_file_includes_fuel_loads_grill - fuel_load.monthly_multipliers = Schedule.FuelLoadsGrillMonthlyMultipliers + fuel_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsGrill].name]['MonthlyScheduleMultipliers'] fuel_load.monthly_multipliers_isdefaulted = true end elsif fuel_load.fuel_load_type == HPXML::FuelLoadTypeLighting @@ -3718,15 +3719,15 @@ def self.apply_fuel_loads(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_fuel_loads_lighting = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:FuelLoadsLighting].name)) if fuel_load.weekday_fractions.nil? && !schedules_file_includes_fuel_loads_lighting - fuel_load.weekday_fractions = Schedule.FuelLoadsLightingWeekdayFractions + fuel_load.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsLighting].name]['WeekdayScheduleFractions'] fuel_load.weekday_fractions_isdefaulted = true end if fuel_load.weekend_fractions.nil? && !schedules_file_includes_fuel_loads_lighting - fuel_load.weekend_fractions = Schedule.FuelLoadsLightingWeekendFractions + fuel_load.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsLighting].name]['WeekendScheduleFractions'] fuel_load.weekend_fractions_isdefaulted = true end if fuel_load.monthly_multipliers.nil? && !schedules_file_includes_fuel_loads_lighting - fuel_load.monthly_multipliers = Schedule.FuelLoadsLightingMonthlyMultipliers + fuel_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsLighting].name]['MonthlyScheduleMultipliers'] fuel_load.monthly_multipliers_isdefaulted = true end elsif fuel_load.fuel_load_type == HPXML::FuelLoadTypeFireplace @@ -3744,15 +3745,15 @@ def self.apply_fuel_loads(hpxml_bldg, cfa, schedules_file) end schedules_file_includes_fuel_loads_fireplace = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:FuelLoadsFireplace].name)) if fuel_load.weekday_fractions.nil? && !schedules_file_includes_fuel_loads_fireplace - fuel_load.weekday_fractions = Schedule.FuelLoadsFireplaceWeekdayFractions + fuel_load.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsFireplace].name]['WeekdayScheduleFractions'] fuel_load.weekday_fractions_isdefaulted = true end if fuel_load.weekend_fractions.nil? && !schedules_file_includes_fuel_loads_fireplace - fuel_load.weekend_fractions = Schedule.FuelLoadsFireplaceWeekendFractions + fuel_load.weekend_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsFireplace].name]['WeekendScheduleFractions'] fuel_load.weekend_fractions_isdefaulted = true end if fuel_load.monthly_multipliers.nil? && !schedules_file_includes_fuel_loads_fireplace - fuel_load.monthly_multipliers = Schedule.FuelLoadsFireplaceMonthlyMultipliers + fuel_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsFireplace].name]['MonthlyScheduleMultipliers'] fuel_load.monthly_multipliers_isdefaulted = true end end @@ -3770,7 +3771,7 @@ def self.apply_fuel_loads(hpxml_bldg, cfa, schedules_file) # @param weather [WeatherFile] Weather object containing EPW information # @param output_format [String] Detailed output file format ('csv', 'json', or 'msgpack') # @param design_load_details_output_file_path [String] Detailed HVAC sizing output file path - # @return [void] + # @return [nil] def self.apply_hvac_sizing(runner, hpxml_bldg, weather, output_format, design_load_details_output_file_path) hvac_systems = HVAC.get_hpxml_hvac_systems(hpxml_bldg) HVACSizing.calculate(runner, weather, hpxml_bldg, hvac_systems, output_format: output_format, output_file_path: design_load_details_output_file_path) @@ -3943,11 +3944,34 @@ def self.get_default_state_code(state_code, weather) # Removes any zones/spaces that were automatically created in the add_zones_spaces_if_needed method. # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.cleanup_zones_spaces(hpxml_bldg) auto_space = hpxml_bldg.conditioned_spaces.find { |space| space.id.start_with? Constants.AutomaticallyAdded } auto_space.delete if not auto_space.nil? auto_zone = hpxml_bldg.conditioned_zones.find { |zone| zone.id.start_with? Constants.AutomaticallyAdded } auto_zone.delete if not auto_zone.nil? end + + # Get the default weekday/weekend schedule fractions and monthly multipliers for each end use. + # + # @return [Hash] { schedule_name => { element => values, ... }, ... } + def self.get_default_schedules_csv_data() + default_schedules_csv = File.join(File.dirname(__FILE__), 'data', 'default_schedules.csv') + if not File.exist?(default_schedules_csv) + fail 'Could not find default_schedules.csv' + end + + require 'csv' + default_schedules_csv_data = {} + CSV.foreach(default_schedules_csv, headers: true) do |row| + schedule_name = row['Schedule Name'] + element = row['Element'] + values = row['Values'] + + default_schedules_csv_data[schedule_name] = {} if !default_schedules_csv_data.keys.include?(schedule_name) + default_schedules_csv_data[schedule_name][element] = values + end + + return default_schedules_csv_data + end end diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index 413b082e1e..7adf1bd5df 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -1810,10 +1810,10 @@ def self.get_default_ceiling_fan_quantity(nbeds) return nbeds + 1 end - # TODO + # Return a 12-element array of 1s and 0s that reflects months for which the average drybulb temperature is greater than 63F. # # @param weather [WeatherFile] Weather object containing EPW information - # @return [TODO] TODO + # @return [Array] monthly array of 1s and 0s def self.get_default_ceiling_fan_months(weather) # Per ANSI/RESNET/ICC 301 months = [0] * 12 @@ -3416,7 +3416,7 @@ def self.get_supp_coil_avail_sch_actuator(model, htg_supp_coil) # @param htg_coil [OpenStudio::Model::CoilHeatingDXSingleSpeed or OpenStudio::Model::CoilHeatingDXMultiSpeed] OpenStudio Heating Coil object # @param is_onoff_thermostat_ddb [Boolean] Whether to apply on off thermostat deadband # @param cooling_system [HPXML::CoolingSystem or HPXML::HeatPump] HPXML Cooling System or HPXML Heat Pump object - # @return [void] + # @return [nil] def self.apply_supp_coil_EMS_for_ddb_thermostat(model, htg_supp_coil, control_zone, htg_coil, is_onoff_thermostat_ddb, cooling_system) return if htg_supp_coil.nil? return unless cooling_system.compressor_type == HPXML::HVACCompressorTypeSingleStage @@ -3509,7 +3509,7 @@ def self.apply_supp_coil_EMS_for_ddb_thermostat(model, htg_supp_coil, control_zo # @param is_cooling [Boolean] True if apply to cooling system # @param cap_fff_curve [OpenStudio::Model::CurveQuadratic] OpenStudio CurveQuadratic object for heat pump capacity function of air flow rates # @param eir_fff_curve [OpenStudio::Model::CurveQuadratic] OpenStudio CurveQuadratic object for heat pump eir function of air flow rates - # @return [void] + # @return [nil] def self.apply_capacity_degradation_EMS(model, system_ap, coil_name, is_cooling, cap_fff_curve, eir_fff_curve) # Note: Currently only available in 1 min time step if is_cooling @@ -3624,7 +3624,7 @@ def self.apply_capacity_degradation_EMS(model, system_ap, coil_name, is_cooling, # @param control_zone [OpenStudio::Model::ThermalZone] Conditioned space thermal zone # @param is_onoff_thermostat_ddb [Boolean] Whether to apply on off thermostat deadband # @param cooling_system [HPXML::CoolingSystem or HPXML::HeatPump] HPXML Cooling System or HPXML Heat Pump object - # @return [void] + # @return [nil] def self.apply_two_speed_realistic_staging_EMS(model, unitary_system, htg_supp_coil, control_zone, is_onoff_thermostat_ddb, cooling_system) # Note: Currently only available in 1 min time step return unless is_onoff_thermostat_ddb @@ -3754,7 +3754,7 @@ def self.apply_two_speed_realistic_staging_EMS(model, unitary_system, htg_supp_c # @param clg_coil [OpenStudio::Model::CoilCoolingDXMultiSpeed] OpenStudio MultiStage Cooling Coil object # @param htg_coil [OpenStudio::Model::CoilHeatingDXMultiSpeed] OpenStudio MultiStage Heating Coil object # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [void] + # @return [nil] def self.apply_max_power_EMS(model, runner, air_loop_unitary, control_zone, heating_system, cooling_system, htg_supp_coil, clg_coil, htg_coil, schedules_file) return if schedules_file.nil? return if clg_coil.nil? && htg_coil.nil? @@ -4010,7 +4010,7 @@ def self.apply_max_power_EMS(model, runner, air_loop_unitary, control_zone, heat # @param htg_supp_coil [OpenStudio::Model::CoilHeatingElectric or CoilHeatingElectricMultiStage] OpenStudio Supplemental Heating Coil object # @param control_zone [OpenStudio::Model::ThermalZone] Conditioned space thermal zone # @param htg_coil [OpenStudio::Model::CoilHeatingDXSingleSpeed or OpenStudio::Model::CoilHeatingDXMultiSpeed] OpenStudio Heating Coil object - # @return [void] + # @return [nil] def self.add_backup_staging_EMS(model, unitary_system, htg_supp_coil, control_zone, htg_coil) return unless htg_supp_coil.is_a? OpenStudio::Model::CoilHeatingElectricMultiStage @@ -4294,14 +4294,13 @@ def self.set_gshp_assumptions(heat_pump, weather) end end - # TODO + # Returns the EnergyPlus sequential load fractions for every day of the year. # # @param load_fraction [TODO] TODO # @param remaining_fraction [TODO] TODO # @param availability_days [TODO] TODO # @return [TODO] TODO def self.calc_sequential_load_fractions(load_fraction, remaining_fraction, availability_days) - # Returns the EnergyPlus sequential load fractions for every day of the year if remaining_fraction > 0 sequential_load_frac = load_fraction / remaining_fraction # Fraction of remaining load served by this system else diff --git a/HPXMLtoOpenStudio/resources/hvac_sizing.rb b/HPXMLtoOpenStudio/resources/hvac_sizing.rb index 7d293fc78a..047b669f5e 100644 --- a/HPXMLtoOpenStudio/resources/hvac_sizing.rb +++ b/HPXMLtoOpenStudio/resources/hvac_sizing.rb @@ -156,7 +156,7 @@ def self.is_system_to_skip(hvac_heating, hvac_cooling, zone) # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param hvac_systems [Array] List of HPXML HVAC (heating and/or cooling) systems - # @return [void] + # @return [nil] def self.check_for_errors(hpxml_bldg, hvac_systems) # Check all surfaces adjacent to conditioned space (and not adiabatic) are # not attached to spaces of unconditioned zones. @@ -189,7 +189,7 @@ def self.check_for_errors(hpxml_bldg, hvac_systems) # @param mj [MJValues] Object with a collection of misc Manual J values # @param weather [WeatherFile] Weather object containing EPW information # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.process_site_calcs_and_design_temps(mj, weather, hpxml_bldg) # CLTD adjustments based on daily temperature range mj.daily_range_temp_adjust = [4, 0, -5] @@ -588,7 +588,7 @@ def self.init_loads(hpxml_bldg) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object - # @return [void] + # @return [nil] def self.process_load_windows_skylights(mj, hpxml_bldg, all_zone_loads, all_space_loads) # Average cooling load factors (CLF) for windows/skylights WITHOUT internal shading (MJ8 Table 3D-3) clf_avg_nois = [0.24, 0.35, 0.38, 0.4, 0.48, 0.4, 0.38, 0.35, 0.24] @@ -959,7 +959,7 @@ def self.calculate_aed_excursion(afl_hr) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object - # @return [void] + # @return [nil] def self.process_load_doors(mj, hpxml_bldg, all_zone_loads, all_space_loads) # CLTD values derived from Table 4A Construction 11 table. if mj.daily_range_num == 0 @@ -1007,7 +1007,7 @@ def self.process_load_doors(mj, hpxml_bldg, all_zone_loads, all_space_loads) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object - # @return [void] + # @return [nil] def self.process_load_walls(mj, hpxml_bldg, all_zone_loads, all_space_loads) # Above-Grade Wall Area (hpxml_bldg.walls + hpxml_bldg.rim_joists + hpxml_bldg.foundation_walls).each do |wall| @@ -1132,7 +1132,7 @@ def self.process_load_walls(mj, hpxml_bldg, all_zone_loads, all_space_loads) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object - # @return [void] + # @return [nil] def self.process_load_roofs(mj, hpxml_bldg, all_zone_loads, all_space_loads) hpxml_bldg.roofs.each do |roof| next unless roof.is_thermal_boundary @@ -1201,7 +1201,7 @@ def self.process_load_roofs(mj, hpxml_bldg, all_zone_loads, all_space_loads) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object - # @return [void] + # @return [nil] def self.process_load_ceilings(mj, hpxml_bldg, all_zone_loads, all_space_loads) hpxml_bldg.floors.each do |floor| next unless floor.is_ceiling @@ -1240,7 +1240,7 @@ def self.process_load_ceilings(mj, hpxml_bldg, all_zone_loads, all_space_loads) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object - # @return [void] + # @return [nil] def self.process_load_floors(mj, hpxml_bldg, all_zone_loads, all_space_loads) hpxml_bldg.floors.each do |floor| next unless floor.is_floor @@ -1335,7 +1335,7 @@ def self.process_load_floors(mj, hpxml_bldg, all_zone_loads, all_space_loads) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object - # @return [void] + # @return [nil] def self.process_load_slabs(mj, hpxml_bldg, all_zone_loads, all_space_loads) hpxml_bldg.slabs.each do |slab| next unless slab.is_thermal_boundary @@ -1421,7 +1421,7 @@ def self.process_load_slabs(mj, hpxml_bldg, all_zone_loads, all_space_loads) # @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object # @param weather [WeatherFile] Weather object containing EPW information - # @return [void] + # @return [nil] def self.process_load_infiltration_ventilation(mj, hpxml_bldg, all_zone_loads, all_space_loads, weather) cfa = hpxml_bldg.building_construction.conditioned_floor_area measurement = Airflow.get_infiltration_measurement_of_interest(hpxml_bldg, manualj_infiltration_method: hpxml_bldg.header.manualj_infiltration_method) @@ -1565,7 +1565,7 @@ def self.process_load_infiltration_ventilation(mj, hpxml_bldg, all_zone_loads, a # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object - # @return [void] + # @return [nil] def self.process_load_internal_gains(hpxml_bldg, all_zone_loads, all_space_loads) hpxml_bldg.conditioned_zones.each do |zone| zone_manualj_num_occupants = zone.spaces.map { |space| space.manualj_num_occupants }.sum @@ -1584,7 +1584,7 @@ def self.process_load_internal_gains(hpxml_bldg, all_zone_loads, all_space_loads # Aggregates component design loads to totals; updates the object that is passed in. # # @param loads [DesignLoadValues] Object with component design loads - # @return [void] + # @return [nil] def self.aggregate_loads_to_totals(loads) # Heating loads.Heat_Tot = loads.Heat_Windows + loads.Heat_Skylights + @@ -1614,7 +1614,7 @@ def self.aggregate_loads_to_totals(loads) # @param zone_loads [DesignLoadValues] Object with design loads for the current HPXML::Zone # @param hvac_heating [HPXML::HeatingSystem or HPXML::HeatPump] The heating portion of the current HPXML HVAC system # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system - # @return [void] + # @return [nil] def self.apply_hvac_air_temperatures(mj, zone_loads, hvac_heating, hvac_cooling) if not hvac_cooling.nil? cooling_type = get_hvac_cooling_type(hvac_cooling) @@ -1661,7 +1661,7 @@ def self.apply_hvac_air_temperatures(mj, zone_loads, hvac_heating, hvac_cooling) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param hvac_systems [Array] List of HPXML HVAC (heating and/or cooling) systems # @param zone [HPXML::Zone] The current zone of interest - # @return [void] + # @return [nil] def self.apply_hvac_fractions_load_served(hvac_loads, hvac_heating, hvac_cooling, hpxml_bldg, hvac_systems, zone) frac_zone_heat_load_served, frac_zone_cool_load_served = get_fractions_load_served(hvac_heating, hvac_cooling, hpxml_bldg, hvac_systems, zone) @@ -1707,7 +1707,7 @@ def self.get_hvac_size_limits(hvac_cooling) # # @param hvac_sizings [HVACSizingValues] Object with sizing values for a given HVAC system # @param zone_loads [DesignLoadValues] Object with design loads for the current HPXML::Zone - # @return [void] + # @return [nil] def self.apply_hvac_loads_to_hvac_sizings(hvac_sizings, hvac_loads) # Note: We subtract the blower heat below because we want to calculate a net capacity, # not a gross capacity. @@ -1804,7 +1804,7 @@ def self.get_duct_regain_factor(duct, hpxml_bldg) # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object # @param hvac_heating [HPXML::HeatingSystem or HPXML::HeatPump] The heating portion of the current HPXML HVAC system # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_hvac_duct_loads_heating(mj, zone, hvac_loads, zone_loads, all_space_loads, hvac_heating, hpxml_bldg) return if hvac_heating.nil? || (hvac_loads.Heat_Tot <= 0) || hvac_heating.distribution_system.nil? || hvac_heating.distribution_system.ducts.empty? @@ -1872,7 +1872,7 @@ def self.apply_hvac_duct_loads_heating(mj, zone, hvac_loads, zone_loads, all_spa # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param weather [WeatherFile] Weather object containing EPW information - # @return [void] + # @return [nil] def self.apply_hvac_duct_loads_cooling(mj, zone, hvac_loads, zone_loads, all_space_loads, hvac_cooling, hpxml_bldg, weather) return if hvac_cooling.nil? || (hvac_loads.Cool_Sens <= 0) || hvac_cooling.distribution_system.nil? || hvac_cooling.distribution_system.ducts.empty? @@ -1951,7 +1951,7 @@ def self.apply_hvac_duct_loads_cooling(mj, zone, hvac_loads, zone_loads, all_spa # @param hvac_heating [HPXML::HeatingSystem or HPXML::HeatPump] The heating portion of the current HPXML HVAC system # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_hvac_cfis_loads(mj, hvac_loads, zone_loads, hvac_heating, hvac_cooling, hpxml_bldg) if (not hvac_heating.nil?) && (not hvac_heating.distribution_system.nil?) hvac_distribution = hvac_heating.distribution_system @@ -1992,7 +1992,7 @@ def self.apply_hvac_cfis_loads(mj, hvac_loads, zone_loads, hvac_heating, hvac_co # @param zone_loads [DesignLoadValues] Object with design loads for the current HPXML::Zone # @param hvac_heating [HPXML::HeatingSystem or HPXML::HeatPump] The heating portion of the current HPXML HVAC system # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system - # @return [void] + # @return [nil] def self.apply_hvac_blower_heat_load(hvac_loads, zone_loads, hvac_heating, hvac_cooling) if not hvac_heating.nil? hvac_distribution = hvac_heating.distribution_system @@ -2018,7 +2018,7 @@ def self.apply_hvac_blower_heat_load(hvac_loads, zone_loads, hvac_heating, hvac_ # @param hvac_loads [DesignLoadValues] Object with design loads for the current HPXML HVAC system # @param zone_loads [DesignLoadValues] Object with design loads for the current HPXML::Zone # @param hvac_heating [HPXML::HeatingSystem or HPXML::HeatPump] The heating portion of the current HPXML HVAC system - # @return [void] + # @return [nil] def self.apply_hvac_piping_load(hvac_loads, zone_loads, hvac_heating) if not hvac_heating.nil? hvac_distribution = hvac_heating.distribution_system @@ -2045,7 +2045,7 @@ def self.apply_hvac_piping_load(hvac_loads, zone_loads, hvac_heating) # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system # @param hvac_system [Hash] HPXML HVAC (heating and/or cooling) system # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_hvac_equipment_adjustments(mj, runner, hvac_sizings, weather, hvac_heating, hvac_cooling, hvac_system, hpxml_bldg) is_heatpump_with_both_htg_and_clg = false if (not hvac_cooling.nil?) && hvac_cooling.is_a?(HPXML::HeatPump) && (hvac_cooling.fraction_heat_load_served > 0) && (hvac_cooling.fraction_cool_load_served > 0) @@ -2492,7 +2492,7 @@ def self.adjust_outdoor_condition_var_speed(outdoor_temp, hvac_sys, mode) # @param hvac_heating [HPXML::HeatingSystem or HPXML::HeatPump] The heating portion of the current HPXML HVAC system # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_hvac_installation_quality(mj, hvac_sizings, hvac_heating, hvac_cooling, hpxml_bldg) cool_charge_defect_ratio = 0.0 cool_airflow_defect_ratio = 0.0 @@ -2650,7 +2650,7 @@ def self.apply_hvac_installation_quality(mj, hvac_sizings, hvac_heating, hvac_co # @param hvac_sizings [HVACSizingValues] Object with sizing values for a given HVAC system # @param hvac_heating [HPXML::HeatingSystem or HPXML::HeatPump] The heating portion of the current HPXML HVAC system # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system - # @return [void] + # @return [nil] def self.apply_hvac_autosizing_factors_and_limits(hvac_sizings, hvac_heating, hvac_cooling) if not hvac_cooling.nil? cooling_autosizing_limit = hvac_cooling.cooling_autosizing_limit @@ -2693,7 +2693,7 @@ def self.apply_hvac_autosizing_factors_and_limits(hvac_sizings, hvac_heating, hv # @param hvac_heating [HPXML::HeatingSystem or HPXML::HeatPump] The heating portion of the current HPXML HVAC system # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_hvac_final_capacities(hvac_sizings, hvac_heating, hvac_cooling, hpxml_bldg) # Cooling if not hvac_cooling.nil? @@ -2749,7 +2749,7 @@ def self.apply_hvac_final_capacities(hvac_sizings, hvac_heating, hvac_cooling, h # @param weather [WeatherFile] Weather object containing EPW information # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.apply_hvac_ground_loop(mj, runner, hvac_sizings, weather, hvac_cooling, hpxml_bldg) cooling_type = get_hvac_cooling_type(hvac_cooling) @@ -3037,7 +3037,7 @@ def self.get_geothermal_loop_valid_num_bores(g_functions_json) # @param hvac_sizings [HVACSizingValues] Object with sizing values for a given HVAC system # @param hvac_heating [HPXML::HeatingSystem or HPXML::HeatPump] The heating portion of the current HPXML HVAC system # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system - # @return [void] + # @return [nil] def self.apply_hvac_final_airflows(hvac_sizings, hvac_heating, hvac_cooling) if (not hvac_heating.nil?) && hvac_heating.respond_to?(:airflow_defect_ratio) if hvac_sizings.Heat_Airflow > 0 @@ -3121,7 +3121,7 @@ def self.calculate_heat_pump_backup_load(mj, hvac_heating, heating_load, hp_nomi # @param oversize_limit [Double] Oversize fraction (frac) # @param oversize_delta [Double] Oversize delta (Btu/hr) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [void] + # @return [nil] def self.process_heat_pump_adjustment(mj, runner, hvac_sizings, weather, hvac_heating, cool_cap_adj_factor, hvac_system, hvac_heating_speed, oversize_limit, oversize_delta, hpxml_bldg) @@ -4489,7 +4489,7 @@ def self.get_has_radiant_floor(zone) # @param hvac_heating [HPXML::HeatingSystem or HPXML::HeatPump] The heating portion of the current HPXML HVAC system # @param hvac_cooling [HPXML::CoolingSystem or HPXML::HeatPump] The cooling portion of the current HPXML HVAC system # @param hvac_sizings [HVACSizingValues] Object with sizing values for a given HVAC system - # @return [void] + # @return [nil] def self.assign_to_hpxml_system(hvac_heating, hvac_cooling, hvac_sizings) if not hvac_heating.nil? @@ -4637,7 +4637,7 @@ def self.aggregate_zone_loads_to_bldg(all_zone_loads) # # @param hpxml_object [HPXML::HVACPlant or HPXML::Zone or HPXML::Space] HPXML object to assign the loads to # @param loads [DesignLoadValues] Design loads for the building, zone, or space - # @return [void] + # @return [nil] def self.assign_to_hpxml_obj(hpxml_object, loads) tol = 10 # Btu/hr @@ -4720,7 +4720,7 @@ def self.assign_to_hpxml_obj(hpxml_object, loads) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object # @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object - # @return [void] + # @return [nil] def self.write_detailed_output(output_format, output_file_path, hpxml_bldg, all_zone_loads, all_space_loads) line_break = nil results_out = [] diff --git a/HPXMLtoOpenStudio/resources/location.rb b/HPXMLtoOpenStudio/resources/location.rb index 3f31500d60..94770b6de1 100644 --- a/HPXMLtoOpenStudio/resources/location.rb +++ b/HPXMLtoOpenStudio/resources/location.rb @@ -1,14 +1,15 @@ # frozen_string_literal: true -# TODO +# Collection of methods for applying site, year, daylight saving time, and ground temperature properties. +# Also includes some helper methods for getting IECC climate zone based on WMO, EPW file path, and simulation calendar year. module Location - # TODO + # This method calls individual methods for applying site, year, daylight saving time, and ground temperature properties on OpenStudio objects. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param weather [WeatherFile] Weather object containing EPW information # @param hpxml_header [HPXML::Header] HPXML Header object (one per HPXML file) # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [TODO] TODO + # @return [nil] def self.apply(model, weather, hpxml_header, hpxml_bldg) apply_year(model, hpxml_header, weather) apply_site(model, hpxml_bldg) @@ -16,11 +17,11 @@ def self.apply(model, weather, hpxml_header, hpxml_bldg) apply_ground_temps(model, weather, hpxml_bldg) end - # TODO + # Set latitude, longitude, time zone, and elevation on the OpenStudio Site object. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [TODO] TODO + # @return [nil] def self.apply_site(model, hpxml_bldg) # Note: None of these affect the model; see https://github.com/NREL/EnergyPlus/issues/10579. site = model.getSite @@ -31,12 +32,12 @@ def self.apply_site(model, hpxml_bldg) site.setElevation(UnitConversions.convert(hpxml_bldg.elevation, 'ft', 'm').round) end - # TODO + # Set calendar year on the OpenStudio YearDescription object. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param hpxml_header [HPXML::Header] HPXML Header object (one per HPXML file) # @param weather [WeatherFile] Weather object containing EPW information - # @return [TODO] TODO + # @return [nil] def self.apply_year(model, hpxml_header, weather) if Date.leap?(hpxml_header.sim_calendar_year) n_hours = weather.header.NumRecords @@ -49,11 +50,11 @@ def self.apply_year(model, hpxml_header, weather) year_description.setCalendarYear(hpxml_header.sim_calendar_year) end - # TODO + # If enabled, set daylight saving time start and end dates on the OpenStudio RunPeriodControlDaylightSavingTime object. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [TODO] TODO + # @return [nil] def self.apply_dst(model, hpxml_bldg) return unless hpxml_bldg.dst_enabled @@ -66,12 +67,12 @@ def self.apply_dst(model, hpxml_bldg) run_period_control_daylight_saving_time.setEndDate(dst_end_date) end - # TODO + # Set monthly shallow (varies by month) and monthly deep (constant) ground temperatures on the OpenStudio SiteGroundTemperatureShallow and SiteGroundTemperatureDeep objects, respectively. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param weather [WeatherFile] Weather object containing EPW information # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [TODO] TODO + # @return [nil] def self.apply_ground_temps(model, weather, hpxml_bldg) # Shallow ground temperatures only currently used for ducts located under slab sgts = model.getSiteGroundTemperatureShallow @@ -86,9 +87,9 @@ def self.apply_ground_temps(model, weather, hpxml_bldg) end end - # TODO + # Get the absolute path to the climate zones CSV lookup file containing WMO, station, county, state, and BA/IECC zone data. # - # @return [TODO] TODO + # @return [String] Path to the climate_zones.csv lookup file def self.get_climate_zones zones_csv = File.join(File.dirname(__FILE__), 'data', 'climate_zones.csv') if not File.exist?(zones_csv) @@ -98,10 +99,10 @@ def self.get_climate_zones return zones_csv end - # TODO + # From the climate zones CSV lookup file, get the IECC zone corresponding to given WMO number. # - # @param wmo [TODO] TODO - # @return [TODO] TODO + # @param wmo [String] Weather station World Meteorological Organization (WMO) number + # @return [String or nil] IECC zone if WMO is found, otherwise nil def self.get_climate_zone_iecc(wmo) zones_csv = get_climate_zones @@ -113,11 +114,11 @@ def self.get_climate_zone_iecc(wmo) return end - # TODO + # Get (find) the absolute path to the EPW file. # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @param hpxml_path [TODO] TODO - # @return [TODO] TODO + # @param hpxml_path [String] Path to the HPXML file + # @return [String] Path to the EnergyPlus weather file (EPW) def self.get_epw_path(hpxml_bldg, hpxml_path) epw_filepath = hpxml_bldg.climate_and_risk_zones.weather_station_epw_filepath abs_epw_path = File.absolute_path(epw_filepath) @@ -149,11 +150,11 @@ def self.get_epw_path(hpxml_bldg, hpxml_path) return abs_epw_path end - # TODO + # Get the simulation calendar year. # - # @param sim_calendar_year [TODO] TODO + # @param sim_calendar_year [Integer] nil if EPW is AMY or using 2007 default # @param weather [WeatherFile] Weather object containing EPW information - # @return [TODO] TODO + # @return [Integer] the simulation calendar year def self.get_sim_calendar_year(sim_calendar_year, weather) if (not weather.nil?) && (not weather.header.ActualYear.nil?) # AMY sim_calendar_year = weather.header.ActualYear @@ -161,6 +162,7 @@ def self.get_sim_calendar_year(sim_calendar_year, weather) if sim_calendar_year.nil? sim_calendar_year = 2007 end + return sim_calendar_year end end diff --git a/HPXMLtoOpenStudio/resources/pv.rb b/HPXMLtoOpenStudio/resources/pv.rb index 75116217d2..0fbf1942af 100644 --- a/HPXMLtoOpenStudio/resources/pv.rb +++ b/HPXMLtoOpenStudio/resources/pv.rb @@ -1,14 +1,16 @@ # frozen_string_literal: true -# TODO +# Collection of methods for adding photovoltaic-related OpenStudio objects. module PV - # TODO + # Apply a photovoltaic system to the model using OpenStudio ElectricLoadCenterDistribution, ElectricLoadCenterInverterPVWatts, and GeneratorPVWatts objects. + # The system may be shared, in which case max power is apportioned to the dwelling unit by total number of bedrooms served. + # In case an ElectricLoadCenterDistribution object does not already exist, a new ElectricLoadCenterInverterPVWatts object is set on a new ElectricLoadCenterDistribution object. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @param pv_system [TODO] TODO + # @param pv_system [HPXML::PVSystem] Object that defines a single solar electric photovoltaic (PV) system # @param unit_multiplier [Integer] Number of similar dwelling units - # @return [TODO] TODO + # @return [nil] def self.apply(model, nbeds, pv_system, unit_multiplier) obj_name = pv_system.id @@ -63,39 +65,37 @@ def self.apply(model, nbeds, pv_system, unit_multiplier) elcd.addGenerator(gpvwatts) end - # TODO + # Calculation from HEScore for module power from year. # - # @param year_modules_manufactured [TODO] TODO - # @return [TODO] TODO + # @param year_modules_manufactured [Integer] year of manufacture of the modules + # @return [Double] the calculated module power from year (W/panel) def self.calc_module_power_from_year(year_modules_manufactured) - # Calculation from HEScore return 13.3 * year_modules_manufactured - 26494.0 # W/panel end - # TODO + # Calculation from HEScore for losses fraction from year. # - # @param year_modules_manufactured [TODO] TODO - # @param default_loss_fraction [TODO] TODO - # @return [TODO] TODO + # @param year_modules_manufactured [Integer] year of manufacture of the modules + # @param default_loss_fraction [Double] the default loss fraction + # @return [Double] the calculated losses fraction from year def self.calc_losses_fraction_from_year(year_modules_manufactured, default_loss_fraction) - # Calculation from HEScore age = Time.new.year - year_modules_manufactured age_losses = 1.0 - 0.995**Float(age) losses_fraction = 1.0 - (1.0 - default_loss_fraction) * (1.0 - age_losses) return losses_fraction end - # TODO + # Get the default inverter efficiency. # - # @return [TODO] TODO + # @return [Double] the default inverter efficiency def self.get_default_inv_eff() return 0.96 # PVWatts default inverter efficiency end - # TODO + # Get the default system losses. # - # @param year_modules_manufactured [TODO] TODO - # @return [TODO] TODO + # @param year_modules_manufactured [Integer] year of manufacture of the modules + # @return [Double] the default system losses def self.get_default_system_losses(year_modules_manufactured = nil) default_loss_fraction = 0.14 # PVWatts default system losses if not year_modules_manufactured.nil? diff --git a/HPXMLtoOpenStudio/resources/schedules.rb b/HPXMLtoOpenStudio/resources/schedules.rb index 0758007155..60678c1c1b 100644 --- a/HPXMLtoOpenStudio/resources/schedules.rb +++ b/HPXMLtoOpenStudio/resources/schedules.rb @@ -413,10 +413,10 @@ class MonthWeekdayWeekendSchedule # @param monthly_values [String or Array] a comma-separated string of 12 numbers or a 12-element array of numbers # @param schedule_type_limits_name [String] data type for the values contained in the schedule # @param normalize_values [Boolean] whether to divide schedule values by the max value - # @param begin_month [Integer] TODO - # @param begin_day [Integer] TODO - # @param end_month [Integer] TODO - # @param end_day [Integer] TODO + # @param begin_month [Integer] the begin month of the year + # @param begin_day [Integer] the begin day of the begin month + # @param end_month [Integer] the end month of the year + # @param end_day [Integer] the end day of the end month # @param unavailable_periods [HPXML::UnavailablePeriods] Object that defines periods for, e.g., power outages or vacancies def initialize(model, sch_name, weekday_hourly_values, weekend_hourly_values, monthly_values, schedule_type_limits_name = nil, normalize_values = true, begin_month = 1, @@ -510,11 +510,10 @@ def calc_max_val() return maxval end - # TODO + # If sum != 1, normalize to get correct max val. # - # @return [TODO] TODO + # @return [Double] the calculated schedule adjustment def calc_sch_adjust() - # if sum != 1, normalize to get correct max val sum_wkdy = 0 sum_wknd = 0 @weekday_hourly_values.each do |v| @@ -535,10 +534,10 @@ def calc_sch_adjust() # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param sch_name [String] name that is assigned to the OpenStudio Schedule object # @param year [Integer] the calendar year - # @param begin_month [TODO] TODO - # @param begin_day [TODO] TODO - # @param end_month [TODO] TODO - # @param end_day [TODO] TODO + # @param begin_month [Integer] the begin month of the year + # @param begin_day [Integer] the begin day of the begin month + # @param end_month [Integer] the end month of the year + # @param end_day [Integer] the end day of the end month # @param schedule_type_limits_name [String] data type for the values contained in the schedule # @param unavailable_periods [HPXML::UnavailablePeriods] Object that defines periods for, e.g., power outages or vacancies # @return [OpenStudio::Model::ScheduleRuleset] the OpenStudio Schedule object with rules @@ -656,23 +655,23 @@ def create_schedule(model, sch_name, year, begin_month, begin_day, end_month, en end end -# TODO +# Collection of helper methods related to schedules. module Schedule - # TODO + # Used to describe a OpenStudio Schedule Rule that applies to both weekdays and weekends. # # @return [String] name for the allday schedule def self.allday_name return 'allday' end - # TODO + # Used to describe a OpenStudio Schedule Rule that applies only to weekdays. # # @return [String] name for the weekday schedule def self.weekday_name return 'weekday' end - # TODO + # Used to describe a OpenStudio Schedule Rule that applies only to weekends. # # @return [String] name for the weekend schedule def self.weekend_name @@ -781,7 +780,7 @@ def self.annual_equivalent_full_load_hrs(modelYear, schedule) # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param schedule [OpenStudio::Model::ScheduleInterval or OpenStudio::Model::ScheduleConstant or OpenStudio::Model::ScheduleRuleset] the OpenStudio Schedule object # @param schedule_type_limits_name [String] data type for the values contained in the schedule - # @return [void] + # @return [nil] def self.set_schedule_type_limits(model, schedule, schedule_type_limits_name) return if schedule_type_limits_name.nil? @@ -808,7 +807,7 @@ def self.set_schedule_type_limits(model, schedule, schedule_type_limits_name) # Apply true for all weekday days of an OpenStudio ScheduleRule object. # # @param rule [OpenStudio::Model::ScheduleRule] an OpenStudio ScheduleRule object - # @return [void] + # @return [nil] def self.set_weekday_rule(rule) rule.setApplyMonday(true) rule.setApplyTuesday(true) @@ -820,29 +819,29 @@ def self.set_weekday_rule(rule) # Apply true for all weekend days of an OpenStudio ScheduleRule object. # # @param rule [OpenStudio::Model::ScheduleRule] an OpenStudio ScheduleRule object - # @return [void] + # @return [nil] def self.set_weekend_rule(rule) rule.setApplySaturday(true) rule.setApplySunday(true) end - # TODO + # Downselect the unavailable periods to only those that apply to the given schedule. # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings - # @param schedule_name [TODO] TODO + # @param schedule_name [String] the column header of the detailed schedule # @param unavailable_periods [HPXML::UnavailablePeriods] Object that defines periods for, e.g., power outages or vacancies - # @return [TODO] TODO + # @return [HPXML::UnavailablePeriods] the subset of unavailable period objects for which the ColumnName applies to the provided schedule name def self.get_unavailable_periods(runner, schedule_name, unavailable_periods) return unavailable_periods.select { |p| Schedule.unavailable_period_applies(runner, schedule_name, p.column_name) } end - # TODO + # Add unavailable period rules to the OpenStudio Schedule object. # - # @param schedule [TODO] TODO + # @param schedule [OpenStudio::Model::ScheduleRuleset] the OpenStudio Schedule object for which to set unavailable period rules # @param sch_name [String] name that is assigned to the OpenStudio Schedule object # @param unavailable_periods [HPXML::UnavailablePeriods] Object that defines periods for, e.g., power outages or vacancies # @param year [Integer] the calendar year - # @return [TODO] TODO + # @return [nil] def self.set_unavailable_periods(schedule, sch_name, unavailable_periods, year) return if unavailable_periods.nil? @@ -924,14 +923,14 @@ def self.set_unavailable_periods(schedule, sch_name, unavailable_periods, year) end end - # TODO + # Create an unavailable period rule from start date to end date. # - # @param schedule [TODO] TODO + # @param schedule [OpenStudio::Model::ScheduleRuleset] the OpenStudio Schedule object for which to set unavailable period rules # @param sch_name [String] name that is assigned to the OpenStudio Schedule object - # @param i [TODO] TODO - # @param date_s [TODO] TODO - # @param date_e [TODO] TODO - # @return [TODO] TODO + # @param i [Integer] the index of the applicable unavailable period + # @param date_s [OpenStudio::Date] unavailable period rule start date + # @param date_e [OpenStudio::Date] unavailable period rule end date + # @return [OpenStudio::Model::ScheduleDay] OpenStudio Schedule Day object connected to the unavailable period rule def self.create_unavailable_period_rule(schedule, sch_name, i, date_s, date_e) out_rule = OpenStudio::Model::ScheduleRule.new(schedule) out_rule.setName(sch_name + " unavailable period ruleset#{i}") @@ -944,14 +943,14 @@ def self.create_unavailable_period_rule(schedule, sch_name, i, date_s, date_e) return out_sch end - # TODO + # Set the unavailable period values for the hours of the day which it applies. # - # @param out [TODO] TODO - # @param day_schedule [TODO] TODO - # @param begin_hour [TODO] TODO - # @param end_hour [TODO] TODO - # @param value [TODO] TODO - # @return [TODO] TODO + # @param out [OpenStudio::Model::ScheduleDay] OpenStudio Schedule Day object connected to the unavailable period rule + # @param day_schedule [OpenStudio::Model::ScheduleDay] the OpenStudio Schedule Day object before applying the unavailable period + # @param begin_hour [Integer] hour of the day that the unavailable period begins + # @param end_hour [Integer] hour of the day that the unavailable period ends + # @param value [Double] the value to set on the day schedule that means unavailable + # @return [nil] def self.set_unavailable_period_values(out, day_schedule, begin_hour, end_hour, value) for h in 0..23 time = OpenStudio::Time.new(0, h + 1, 0, 0) @@ -963,378 +962,7 @@ def self.set_unavailable_period_values(out, day_schedule, begin_hour, end_hour, end end - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.OccupantsWeekdayFractions - return '0.035, 0.035, 0.035, 0.035, 0.035, 0.059, 0.082, 0.055, 0.027, 0.014, 0.014, 0.014, 0.014, 0.014, 0.019, 0.027, 0.041, 0.055, 0.068, 0.082, 0.082, 0.070, 0.053, 0.035' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.OccupantsWeekendFractions - return '0.035, 0.035, 0.035, 0.035, 0.035, 0.059, 0.082, 0.055, 0.027, 0.014, 0.014, 0.014, 0.014, 0.014, 0.019, 0.027, 0.041, 0.055, 0.068, 0.082, 0.082, 0.070, 0.053, 0.035' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.OccupantsMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.LightingInteriorWeekdayFractions - return '0.012, 0.010, 0.010, 0.010, 0.011, 0.018, 0.030, 0.038, 0.041, 0.041, 0.039, 0.037, 0.036, 0.035, 0.037, 0.041, 0.050, 0.065, 0.086, 0.106, 0.110, 0.079, 0.040, 0.018' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.LightingInteriorWeekendFractions - return '0.012, 0.010, 0.010, 0.010, 0.011, 0.018, 0.030, 0.038, 0.041, 0.041, 0.039, 0.037, 0.036, 0.035, 0.037, 0.041, 0.050, 0.065, 0.086, 0.106, 0.110, 0.079, 0.040, 0.018' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.LightingExteriorWeekdayFractions - return '0.040, 0.037, 0.037, 0.035, 0.035, 0.039, 0.044, 0.041, 0.031, 0.025, 0.024, 0.024, 0.025, 0.028, 0.030, 0.035, 0.044, 0.056, 0.064, 0.068, 0.070, 0.065, 0.056, 0.047' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.LightingExteriorWeekendFractions - return '0.040, 0.037, 0.037, 0.035, 0.035, 0.039, 0.044, 0.041, 0.031, 0.025, 0.024, 0.024, 0.025, 0.028, 0.030, 0.035, 0.044, 0.056, 0.064, 0.068, 0.070, 0.065, 0.056, 0.047' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.LightingGarageWeekdayFractions - return '0.023, 0.019, 0.015, 0.017, 0.021, 0.031, 0.042, 0.041, 0.034, 0.029, 0.027, 0.025, 0.021, 0.021, 0.021, 0.026, 0.031, 0.044, 0.084, 0.117, 0.113, 0.096, 0.063, 0.039' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.LightingGarageWeekendFractions - return '0.023, 0.019, 0.015, 0.017, 0.021, 0.031, 0.042, 0.041, 0.034, 0.029, 0.027, 0.025, 0.021, 0.021, 0.021, 0.026, 0.031, 0.044, 0.084, 0.117, 0.113, 0.096, 0.063, 0.039' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.LightingMonthlyMultipliers - return '1.19, 1.11, 1.02, 0.93, 0.84, 0.80, 0.82, 0.88, 0.98, 1.07, 1.16, 1.20' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.LightingExteriorHolidayWeekdayFractions - return '0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.008, 0.098, 0.168, 0.194, 0.284, 0.192, 0.037, 0.019' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.LightingExteriorHolidayWeekendFractions - return '0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.008, 0.098, 0.168, 0.194, 0.284, 0.192, 0.037, 0.019' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.LightingExteriorHolidayMonthlyMultipliers - return '1.248, 1.257, 0.993, 0.989, 0.993, 0.827, 0.821, 0.821, 0.827, 0.99, 0.987, 1.248' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.CookingRangeWeekdayFractions - return '0.008, 0.008, 0.008, 0.008, 0.008, 0.015, 0.023, 0.039, 0.046, 0.046, 0.046, 0.054, 0.062, 0.046, 0.039, 0.054, 0.076, 0.134, 0.114, 0.058, 0.039, 0.031, 0.023, 0.015' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.CookingRangeWeekendFractions - return '0.008, 0.008, 0.008, 0.008, 0.008, 0.015, 0.023, 0.039, 0.046, 0.046, 0.046, 0.054, 0.062, 0.046, 0.039, 0.054, 0.076, 0.134, 0.114, 0.058, 0.039, 0.031, 0.023, 0.015' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.CookingRangeMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.DishwasherWeekdayFractions - return '0.015, 0.007, 0.005, 0.003, 0.003, 0.010, 0.020, 0.031, 0.058, 0.065, 0.056, 0.048, 0.042, 0.046, 0.036, 0.038, 0.038, 0.049, 0.087, 0.111, 0.090, 0.067, 0.044, 0.031' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.DishwasherWeekendFractions - return '0.015, 0.007, 0.005, 0.003, 0.003, 0.010, 0.020, 0.031, 0.058, 0.065, 0.056, 0.048, 0.042, 0.046, 0.036, 0.038, 0.038, 0.049, 0.087, 0.111, 0.090, 0.067, 0.044, 0.031' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.DishwasherMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.ClothesWasherWeekdayFractions - return '0.009, 0.007, 0.004, 0.004, 0.007, 0.011, 0.022, 0.049, 0.073, 0.086, 0.084, 0.075, 0.067, 0.060, 0.049, 0.051, 0.050, 0.049, 0.049, 0.049, 0.049, 0.047, 0.032, 0.017' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.ClothesWasherWeekendFractions - return '0.009, 0.007, 0.004, 0.004, 0.007, 0.011, 0.022, 0.049, 0.073, 0.086, 0.084, 0.075, 0.067, 0.060, 0.049, 0.051, 0.050, 0.049, 0.049, 0.049, 0.049, 0.047, 0.032, 0.017' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.ClothesWasherMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.ClothesDryerWeekdayFractions - return '0.010, 0.006, 0.004, 0.002, 0.004, 0.006, 0.016, 0.032, 0.048, 0.068, 0.078, 0.081, 0.074, 0.067, 0.058, 0.061, 0.055, 0.054, 0.051, 0.051, 0.052, 0.054, 0.044, 0.024' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.ClothesDryerWeekendFractions - return '0.010, 0.006, 0.004, 0.002, 0.004, 0.006, 0.016, 0.032, 0.048, 0.068, 0.078, 0.081, 0.074, 0.067, 0.058, 0.061, 0.055, 0.054, 0.051, 0.051, 0.052, 0.054, 0.044, 0.024' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.ClothesDryerMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.FixturesWeekdayFractions - return '0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.FixturesWeekendFractions - return '0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.FixturesMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.GeneralWaterUseWeekdayFractions - return '0.023, 0.021, 0.021, 0.025, 0.027, 0.038, 0.044, 0.039, 0.037, 0.037, 0.034, 0.035, 0.035, 0.035, 0.039, 0.043, 0.051, 0.064, 0.065, 0.072, 0.073, 0.063, 0.045, 0.034' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.GeneralWaterUseWeekendFractions - return '0.023, 0.021, 0.021, 0.025, 0.027, 0.038, 0.044, 0.039, 0.037, 0.037, 0.034, 0.035, 0.035, 0.035, 0.039, 0.043, 0.051, 0.064, 0.065, 0.072, 0.073, 0.063, 0.045, 0.034' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.GeneralWaterUseMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.RecirculationPumpWithoutControlWeekdayFractions - return '0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.RecirculationPumpWithoutControlWeekendFractions - return '0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.RecirculationPumpDemandControlledWeekdayFractions - return '0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.RecirculationPumpDemandControlledWeekendFractions - return '0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.RecirculationPumpTemperatureControlledWeekdayFractions - return '0.067, 0.072, 0.074, 0.073, 0.069, 0.048, 0.011, 0.003, 0.009, 0.020, 0.030, 0.037, 0.043, 0.047, 0.050, 0.051, 0.044, 0.034, 0.026, 0.026, 0.030, 0.036, 0.045, 0.055' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.RecirculationPumpTemperatureControlledWeekendFractions - return '0.067, 0.072, 0.074, 0.073, 0.069, 0.048, 0.011, 0.003, 0.009, 0.020, 0.030, 0.037, 0.043, 0.047, 0.050, 0.051, 0.044, 0.034, 0.026, 0.026, 0.030, 0.036, 0.045, 0.055' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.RecirculationPumpMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.RefrigeratorWeekdayFractions - return '0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.RefrigeratorWeekendFractions - return '0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.RefrigeratorMonthlyMultipliers - return '0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837' - end - - # TODO - # - # @return [String] 24 comma-separated constant coefficients - def self.RefrigeratorConstantCoefficients - return '-0.487, -0.340, -0.370, -0.361, -0.515, -0.684, -0.471, -0.159, -0.079, -0.417, -0.411, -0.386, -0.240, -0.314, -0.160, -0.121, -0.469, -0.412, -0.091, 0.077, -0.118, -0.247, -0.445, -0.544' # Table C.3(2) Daily Refrigerator Coefficient Schedules - end - - # TODO - # - # @return [String] 24 comma-separated temperature coefficients - def self.RefrigeratorTemperatureCoefficients - return '0.019, 0.016, 0.017, 0.016, 0.018, 0.021, 0.019, 0.015, 0.015, 0.019, 0.018, 0.018, 0.016, 0.017, 0.015, 0.015, 0.020, 0.020, 0.017, 0.014, 0.016, 0.017, 0.019, 0.020' # Table C.3(2) Daily Refrigerator Coefficient Schedules - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.ExtraRefrigeratorWeekdayFractions - return '0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.ExtraRefrigeratorWeekendFractions - return '0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.ExtraRefrigeratorMonthlyMultipliers - return '0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837' - end - - # TODO - # - # @return [TODO] TODO - def self.ExtraRefrigeratorConstantCoefficients - return '-0.487, -0.340, -0.370, -0.361, -0.515, -0.684, -0.471, -0.159, -0.079, -0.417, -0.411, -0.386, -0.240, -0.314, -0.160, -0.121, -0.469, -0.412, -0.091, -0.077, -0.118, -0.247, -0.445, -0.544' - end - - # TODO - # - # @return [TODO] TODO - def self.ExtraRefrigeratorTemperatureCoefficients - return '0.019, 0.016, 0.017, 0.016, 0.018, 0.021, 0.019, 0.015, 0.015, 0.019, 0.018, 0.018, 0.016, 0.017, 0.015, 0.015, 0.020, 0.020, 0.017, 0.014, 0.016, 0.017, 0.019, 0.020' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.FreezerWeekdayFractions - return '0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.FreezerWeekendFractions - return '0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.FreezerMonthlyMultipliers - return '0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.CeilingFanWeekdayFractions - return '0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.052, 0.057, 0.057, 0.057, 0.057, 0.057' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.CeilingFanWeekendFractions - return '0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.052, 0.057, 0.057, 0.057, 0.057, 0.057' - end - - # TODO + # Default ceiling fan monthly multipliers. # # @param weather [WeatherFile] Weather object containing EPW information # @return [String] 12 comma-separated monthly multipliers @@ -1342,246 +970,14 @@ def self.CeilingFanMonthlyMultipliers(weather:) return HVAC.get_default_ceiling_fan_months(weather).join(', ') end - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.PlugLoadsOtherWeekdayFractions - return '0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.038, 0.041, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.044, 0.047, 0.050, 0.051, 0.050, 0.048, 0.044, 0.040, 0.037' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.PlugLoadsOtherWeekendFractions - return '0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.038, 0.041, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.044, 0.047, 0.050, 0.051, 0.050, 0.048, 0.044, 0.040, 0.037' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.PlugLoadsOtherMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.PlugLoadsTVWeekdayFractions - return '0.014, 0.007, 0.004, 0.003, 0.004, 0.006, 0.010, 0.015, 0.020, 0.025, 0.028, 0.031, 0.033, 0.038, 0.042, 0.046, 0.054, 0.062, 0.080, 0.110, 0.132, 0.125, 0.077, 0.034' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.PlugLoadsTVWeekendFractions - return '0.014, 0.007, 0.004, 0.003, 0.004, 0.006, 0.010, 0.015, 0.020, 0.025, 0.028, 0.031, 0.033, 0.038, 0.042, 0.046, 0.054, 0.062, 0.080, 0.110, 0.132, 0.125, 0.077, 0.034' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.PlugLoadsTVMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.PlugLoadsVehicleWeekdayFractions - return '0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.PlugLoadsVehicleWeekendFractions - return '0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.PlugLoadsVehicleMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.PlugLoadsWellPumpWeekdayFractions - return '0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.PlugLoadsWellPumpWeekendFractions - return '0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.PlugLoadsWellPumpMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.FuelLoadsGrillWeekdayFractions - return '0.004, 0.001, 0.001, 0.002, 0.007, 0.012, 0.029, 0.046, 0.044, 0.041, 0.044, 0.046, 0.042, 0.038, 0.049, 0.059, 0.110, 0.161, 0.115, 0.070, 0.044, 0.019, 0.013, 0.007' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.FuelLoadsGrillWeekendFractions - return '0.004, 0.001, 0.001, 0.002, 0.007, 0.012, 0.029, 0.046, 0.044, 0.041, 0.044, 0.046, 0.042, 0.038, 0.049, 0.059, 0.110, 0.161, 0.115, 0.070, 0.044, 0.019, 0.013, 0.007' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.FuelLoadsGrillMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.FuelLoadsLightingWeekdayFractions - return '0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.FuelLoadsLightingWeekendFractions - return '0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.FuelLoadsLightingMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.FuelLoadsFireplaceWeekdayFractions - return '0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.FuelLoadsFireplaceWeekendFractions - return '0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.FuelLoadsFireplaceMonthlyMultipliers - return '1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.PoolPumpWeekdayFractions - return '0.003, 0.003, 0.003, 0.004, 0.008, 0.015, 0.026, 0.044, 0.084, 0.121, 0.127, 0.121, 0.120, 0.090, 0.075, 0.061, 0.037, 0.023, 0.013, 0.008, 0.004, 0.003, 0.003, 0.003' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.PoolPumpWeekendFractions - return '0.003, 0.003, 0.003, 0.004, 0.008, 0.015, 0.026, 0.044, 0.084, 0.121, 0.127, 0.121, 0.120, 0.090, 0.075, 0.061, 0.037, 0.023, 0.013, 0.008, 0.004, 0.003, 0.003, 0.003' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.PoolPumpMonthlyMultipliers - return '1.154, 1.161, 1.013, 1.010, 1.013, 0.888, 0.883, 0.883, 0.888, 0.978, 0.974, 1.154' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.PoolHeaterWeekdayFractions - return '0.003, 0.003, 0.003, 0.004, 0.008, 0.015, 0.026, 0.044, 0.084, 0.121, 0.127, 0.121, 0.120, 0.090, 0.075, 0.061, 0.037, 0.023, 0.013, 0.008, 0.004, 0.003, 0.003, 0.003' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.PoolHeaterWeekendFractions - return '0.003, 0.003, 0.003, 0.004, 0.008, 0.015, 0.026, 0.044, 0.084, 0.121, 0.127, 0.121, 0.120, 0.090, 0.075, 0.061, 0.037, 0.023, 0.013, 0.008, 0.004, 0.003, 0.003, 0.003' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.PoolHeaterMonthlyMultipliers - return '1.154, 1.161, 1.013, 1.010, 1.013, 0.888, 0.883, 0.883, 0.888, 0.978, 0.974, 1.154' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.PermanentSpaPumpWeekdayFractions - return '0.024, 0.029, 0.024, 0.029, 0.047, 0.067, 0.057, 0.024, 0.024, 0.019, 0.015, 0.014, 0.014, 0.014, 0.024, 0.058, 0.126, 0.122, 0.068, 0.061, 0.051, 0.043, 0.024, 0.024' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.PermanentSpaPumpWeekendFractions - return '0.024, 0.029, 0.024, 0.029, 0.047, 0.067, 0.057, 0.024, 0.024, 0.019, 0.015, 0.014, 0.014, 0.014, 0.024, 0.058, 0.126, 0.122, 0.068, 0.061, 0.051, 0.043, 0.024, 0.024' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.PermanentSpaPumpMonthlyMultipliers - return '0.921, 0.928, 0.921, 0.915, 0.921, 1.160, 1.158, 1.158, 1.160, 0.921, 0.915, 0.921' - end - - # TODO - # - # @return [String] 24 comma-separated weekday fractions - def self.PermanentSpaHeaterWeekdayFractions - return '0.024, 0.029, 0.024, 0.029, 0.047, 0.067, 0.057, 0.024, 0.024, 0.019, 0.015, 0.014, 0.014, 0.014, 0.024, 0.058, 0.126, 0.122, 0.068, 0.061, 0.051, 0.043, 0.024, 0.024' - end - - # TODO - # - # @return [String] 24 comma-separated weekend fractions - def self.PermanentSpaHeaterWeekendFractions - return '0.024, 0.029, 0.024, 0.029, 0.047, 0.067, 0.057, 0.024, 0.024, 0.019, 0.015, 0.014, 0.014, 0.014, 0.024, 0.058, 0.126, 0.122, 0.068, 0.061, 0.051, 0.043, 0.024, 0.024' - end - - # TODO - # - # @return [String] 12 comma-separated monthly multipliers - def self.PermanentSpaHeaterMonthlyMultipliers - return '0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837' - end - - # TODO + # Returns a value between 1 and 365 (or 366 for a leap year). + # Returns e.g. 32 for month=2 and day=1 (Feb 1). # # @param year [Integer] the calendar year - # @param month [TODO] TODO - # @param day [TODO] TODO - # @return [TODO] TODO + # @param month [Integer] the month of the year + # @param day [Integer] the day of the month + # @return [Integer] the day number of the year def self.get_day_num_from_month_day(year, month, day) - # Returns a value between 1 and 365 (or 366 for a leap year) - # Returns e.g. 32 for month=2 and day=1 (Feb 1) month_num_days = Constants.NumDaysInMonths(year) day_num = day for m in 0..month - 2 @@ -1590,14 +986,14 @@ def self.get_day_num_from_month_day(year, month, day) return day_num end - # TODO + # Returns an array of 365 (or 366 for a leap year) values of 0s and 1s that define a daily season. # # @param year [Integer] the calendar year - # @param start_month [TODO] TODO - # @param start_day [TODO] TODO - # @param end_month [TODO] TODO - # @param end_day [TODO] TODO - # @return [TODO] TODO + # @param start_month [Integer] the start month of the year + # @param start_day [Integer] the start day of the start month + # @param end_month [Integer] the end month of the year + # @param end_day [Integer] the end day of the end month + # @return [Array] 1s ranging from start month/day to end month/day, and 0s outside of this range def self.get_daily_season(year, start_month, start_day, end_month, end_day) start_day_num = get_day_num_from_month_day(year, start_month, start_day) end_day_num = get_day_num_from_month_day(year, end_month, end_day) @@ -1612,43 +1008,44 @@ def self.get_daily_season(year, start_month, start_day, end_month, end_day) return season end - # TODO + # Convert a 12-element monthly array of 1s and 0s to a 365-element (or 366-element for a leap year) daily array of 1s and 0s. # # @param year [Integer] the calendar year - # @param months [TODO] TODO - # @return [TODO] TODO + # @param months [Array] monthly array of 1s and 0s + # @return [Array] daily array of 1s and 0s def self.months_to_days(year, months) month_num_days = Constants.NumDaysInMonths(year) days = [] for m in 0..11 days.concat([months[m]] * month_num_days[m]) end + return days end - # TODO + # Returns a 12-element array of day numbers of the year corresponding to the first days of each month. # # @param year [Integer] the calendar year - # @return [TODO] TODO + # @return [Array] day number of the year for the first day of each month def self.day_start_months(year) month_num_days = Constants.NumDaysInMonths(year) return month_num_days.each_with_index.map { |_n, i| get_day_num_from_month_day(year, i + 1, 1) } end - # TODO + # Returns a 12-element array of day numbers of the year corresponding to the last days of each month. # # @param year [Integer] the calendar year - # @return [TODO] TODO + # @return [Array] day number of the year for the last day of each month def self.day_end_months(year) month_num_days = Constants.NumDaysInMonths(year) return month_num_days.each_with_index.map { |n, i| get_day_num_from_month_day(year, i + 1, n) } end - # TODO + # Create an OpenStudio Schedule object based on a 365-element (or 366 for a leap year) daily season array. # # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @param values [TODO] TODO - # @return [TODO] TODO + # @param values [Array] array of daily sequential load fractions + # @return [OpenStudio::Model::ScheduleRuleset] the OpenStudio Schedule object with rules def self.create_ruleset_from_daily_season(model, values) s = OpenStudio::Model::ScheduleRuleset.new(model) year = model.getYearDescription.assumedYear @@ -1675,10 +1072,10 @@ def self.create_ruleset_from_daily_season(model, values) return s end - # TODO + # Return begin month/day/hour and end month/day/hour integers based on a string datetime range. # - # @param date_time_range [TODO] TODO - # @return [TODO] TODO + # @param date_time_range [String] a date like 'Jan 1 - Dec 31' (optionally can enter hour like 'Dec 15 2 - Jan 15 20') + # @return [Array] begin/end month/day/hour def self.parse_date_time_range(date_time_range) begin_end_dates = date_time_range.split('-').map { |v| v.strip } if begin_end_dates.size != 2 @@ -1710,11 +1107,11 @@ def self.parse_date_time_range(date_time_range) return begin_month, begin_day, begin_hour, end_month, end_day, end_hour end - # TODO + # Return begin month/day and end month/day based on a provided monthly availability array. # - # @param months [TODO] TODO + # @param months [Array] monthly array of 1s and 0s # @param year [Integer] the calendar year - # @return [TODO] TODO + # @return [Array] begin month/day and end month/day def self.get_begin_and_end_dates_from_monthly_array(months, year) num_days_in_month = Constants.NumDaysInMonths(year) @@ -1736,9 +1133,9 @@ def self.get_begin_and_end_dates_from_monthly_array(months, year) return begin_month, begin_day, end_month, end_day end - # TODO + # Return a array of maps that reflect the contents of the unavailable_periods.csv file. # - # @return [TODO] TODO + # @return [Array] array with maps for components that are affected by unavailable period types def self.get_unavailable_periods_csv_data unavailable_periods_csv = File.join(File.dirname(__FILE__), 'data', 'unavailable_periods.csv') if not File.exist?(unavailable_periods_csv) @@ -1751,12 +1148,12 @@ def self.get_unavailable_periods_csv_data return unavailable_periods_csv_data end - # TODO + # Determine whether an unavailable period applies to a given detailed schedule. # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings - # @param schedule_name [TODO] TODO - # @param col_name [TODO] TODO - # @return [TODO] TODO + # @param schedule_name [String] the column header of the detailed schedule + # @param col_name [String] the unavailable period type + # @return [Boolean] true if the unavailable period type applies to the detailed schedule def self.unavailable_period_applies(runner, schedule_name, col_name) if @unavailable_periods_csv_data.nil? @unavailable_periods_csv_data = get_unavailable_periods_csv_data @@ -1960,7 +1357,7 @@ def includes_col_name(col_name) # Assemble schedules from all detailed schedule CSVs into a hash. # # @param schedules_paths [Array] array of file paths pointing to detailed schedule CSVs - # @return [void] + # @return [nil] def import(schedules_paths) num_hrs_in_year = Constants.NumHoursInYear(@year) @schedules = {} @@ -2092,9 +1489,9 @@ def create_schedule_file(model, col_name:, rows_to_skip: 1, # The equivalent number of hours in the year, if the schedule was at full load (1.0). # - # @param col_name [TODO] TODO - # @param schedules [TODO] TODO - # @return [TODO] TODO + # @param col_name [String] the column header of the detailed schedule + # @param schedules [Hash] schedules from all detailed schedule CSVs + # @return [Double] total number of full load hours for the year def annual_equivalent_full_load_hrs(col_name:, schedules: nil) @@ -2105,10 +1502,10 @@ def annual_equivalent_full_load_hrs(col_name:, # The equivalent number of hours in the period, if the schedule was at full load (1.0). # - # @param col_name [TODO] TODO - # @param schedules [TODO] TODO - # @param period [TODO] TODO - # @return [TODO] TODO + # @param col_name [String] the column header of the detailed schedule + # @param schedules [Hash] schedules from all detailed schedule CSVs + # @param period [HPXM::UnavailablePeriod] Object that defines begin/end month/day/hour for, e.g., a power outage or vacancy + # @return [Double] total number of full load hours for the period def period_equivalent_full_load_hrs(col_name:, schedules: nil, period: nil) @@ -2164,9 +1561,9 @@ def period_equivalent_full_load_hrs(col_name:, # it would consume the annual_kwh energy in the year. Essentially, returns the watts for the equipment when schedule # is at 1.0, so that, for the given schedule values, the equipment will consume annual_kwh energy in a year. # - # @param col_name [TODO] TODO - # @param annual_kwh [TODO] TODO - # @return [TODO] TODO + # @param col_name [String] the column header of the detailed schedule + # @param annual_kwh [Double] annual consumption in a year (kWh) + # @return [Double] design level used to represent maximum input (W) def calc_design_level_from_annual_kwh(col_name:, annual_kwh:) if @schedules[col_name].nil? @@ -2183,9 +1580,9 @@ def calc_design_level_from_annual_kwh(col_name:, # Similar to ann_equiv_full_load_hrs, but for thermal energy. # - # @param col_name [TODO] TODO - # @param annual_therm [TODO] TODO - # @return [TODO] TODO + # @param col_name [String] the column header of the detailed schedule + # @param annual_therm [Double] annual consumption in a year (therm) + # @return [Double] design level used to represent maximum input (W) def calc_design_level_from_annual_therm(col_name:, annual_therm:) if @schedules[col_name].nil? @@ -2200,9 +1597,9 @@ def calc_design_level_from_annual_therm(col_name:, # Similar to the calc_design_level_from_annual_kwh, but use daily_kwh instead of annual_kwh to calculate the design level. # - # @param col_name [TODO] TODO - # @param daily_kwh [TODO] TODO - # @return [TODO] TODO + # @param col_name [String] the column header of the detailed schedule + # @param daily_kwh [Double] daily energy use (kWh) + # @return [Double] design level used to represent maximum input (W) def calc_design_level_from_daily_kwh(col_name:, daily_kwh:) if @schedules[col_name].nil? @@ -2221,9 +1618,9 @@ def calc_design_level_from_daily_kwh(col_name:, # Similar to calc_design_level_from_daily_kwh but for water usage. # - # @param col_name [TODO] TODO - # @param daily_water [TODO] TODO - # @return [TODO] TODO + # @param col_name [String] the column header of the detailed schedule + # @param daily_water [Double] daily water use (gal/day) + # @return [Double] peak flow used to represent maximum input (m^3/s) def calc_peak_flow_from_daily_gpm(col_name:, daily_water:) if @schedules[col_name].nil? @@ -2243,9 +1640,9 @@ def calc_peak_flow_from_daily_gpm(col_name:, # Create a column of zeroes or ones for, e.g., vacancy periods or power outage periods. # - # @param col_name [TODO] TODO - # @param periods [TODO] TODO - # @return [void] + # @param col_name [String] the column header of the detailed schedule + # @param periods [HPXML::UnavailablePeriods] Object that defines periods for, e.g., power outages or vacancies + # @return [nil] def create_column_values_from_periods(col_name, periods) n_steps = @tmp_schedules[@tmp_schedules.keys[0]].length num_days_in_year = Constants.NumDaysInYear(@year) @@ -2277,7 +1674,7 @@ def create_column_values_from_periods(col_name, periods) # Expand schedules with fewer elements such that all the schedules have the same number of elements. # - # @return [void] + # @return [nil] def expand_schedules max_size = @schedules.map { |_k, v| v.size }.uniq.max @schedules.each do |col, values| @@ -2287,11 +1684,11 @@ def expand_schedules end end - # TODO + # Modify the detailed schedules hash referenced by EnergyPlus with appropriate unavailable period values. # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param unavailable_periods [HPXML::UnavailablePeriods] Object that defines periods for, e.g., power outages or vacancies - # @return [void] + # @return [nil] def set_unavailable_periods(runner, unavailable_periods) if @unavailable_periods_csv_data.nil? @unavailable_periods_csv_data = Schedule.get_unavailable_periods_csv_data @@ -2330,10 +1727,10 @@ def set_unavailable_periods(runner, unavailable_periods) end end - # TODO + # Convert detailed setpoint schedule values from F to C. # # @param offset_db [Float] On-off thermostat deadband - # @return [void] + # @return [nil] def convert_setpoints(offset_db) setpoint_col_names = Columns.values.select { |c| c.type == :setpoint }.map { |c| c.name } return if @tmp_schedules.keys.none? { |k| setpoint_col_names.include?(k) } @@ -2354,9 +1751,9 @@ def convert_setpoints(offset_db) end end - # TODO + # Create separate charging (positive) and discharging (negative) detailed schedules from the battery schedule. # - # @return [void] + # @return [nil] def create_battery_charging_discharging_schedules battery_col_name = Columns[:Battery].name return if !@schedules.keys.include?(battery_col_name) diff --git a/HPXMLtoOpenStudio/resources/simcontrols.rb b/HPXMLtoOpenStudio/resources/simcontrols.rb index 24253b594a..63ba569103 100644 --- a/HPXMLtoOpenStudio/resources/simcontrols.rb +++ b/HPXMLtoOpenStudio/resources/simcontrols.rb @@ -6,7 +6,7 @@ module SimControls # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param hpxml_header [HPXML::Header] HPXML Header object (one per HPXML file) - # @return [void] + # @return [nil] def self.apply(model, hpxml_header) sim = model.getSimulationControl sim.setRunSimulationforSizingPeriods(false) diff --git a/HPXMLtoOpenStudio/resources/util.rb b/HPXMLtoOpenStudio/resources/util.rb index 78583a83e7..d80edce489 100644 --- a/HPXMLtoOpenStudio/resources/util.rb +++ b/HPXMLtoOpenStudio/resources/util.rb @@ -9,7 +9,7 @@ module UrlResolver # @param agent [String] a string of text that a web browser sends to a web server to identify itself and provide information about the browser's capabilities # @param max_attempts [Integer] the maximum number of attempts # @param timeout [Integer] both the number of seconds to (1) wait for the connection to open and (2) wait for one block to be read (via one read(2) call) - # @return [void] + # @return [nil] def self.fetch(uri_str, outfile, agent = 'curl/7.43.0', max_attempts = 10, timeout = 10) attempts = 0 cookie = nil diff --git a/HPXMLtoOpenStudio/resources/version.rb b/HPXMLtoOpenStudio/resources/version.rb index 3c03803962..d08173f7e5 100644 --- a/HPXMLtoOpenStudio/resources/version.rb +++ b/HPXMLtoOpenStudio/resources/version.rb @@ -9,7 +9,7 @@ module Version # Checks whether the version of OpenStudio that is running OpenStudio-HPXML # meets the version requirements; throws an error if not. # - # @return [void] + # @return [nil] def self.check_openstudio_version if not OpenStudio.openStudioVersion.start_with? OS_Version if OS_Version.count('.') == 2 @@ -24,7 +24,7 @@ def self.check_openstudio_version # meets the version requirements; throws an error if not. # # @param hpxml_version [String] Version of HPXML input file - # @return [void] + # @return [nil] def self.check_hpxml_version(hpxml_version) if hpxml_version != HPXML_Version fail "HPXML version #{HPXML_Version} is required." diff --git a/HPXMLtoOpenStudio/resources/weather.rb b/HPXMLtoOpenStudio/resources/weather.rb index f8e90481c6..35b71fe73f 100644 --- a/HPXMLtoOpenStudio/resources/weather.rb +++ b/HPXMLtoOpenStudio/resources/weather.rb @@ -27,7 +27,7 @@ def initialize(epw_path:, runner:, hpxml: nil) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param epw_path [String] Path to the EPW weather file # @param hpxml [HPXML] HPXML object - # @return [void] + # @return [nil] def process_epw(runner, epw_path, hpxml) epw_file = OpenStudio::EpwFile.new(epw_path, true) @@ -108,7 +108,7 @@ def process_epw(runner, epw_path, hpxml) # Calculates and stores heating/cooling degree days for different base temperatures. # # @param dailydbs [Array] Daily average drybulb temperatures (C) - # @return [void] + # @return [nil] def calc_heat_cool_degree_days(dailydbs) data.HDD65F = calc_degree_days(dailydbs, 65, true) data.HDD50F = calc_degree_days(dailydbs, 50, true) @@ -151,7 +151,7 @@ def calc_degree_days(daily_dbs, base_temp_f, is_heating) # # @param daily_high_dbs [Array] Daily maximum drybulb temperatures (C) # @param daily_low_dbs [Array] Daily minimum drybulb temperatures (C) - # @return [void] + # @return [nil] def calc_avg_monthly_highs_lows(daily_high_dbs, daily_low_dbs) data.MonthlyAvgDailyHighDrybulbs = [] data.MonthlyAvgDailyLowDrybulbs = [] @@ -232,7 +232,7 @@ def calc_ashrae_622_wsf(rowdata) # Gets and stores various EPW header data. # # @param epw_file [OpenStudio::EpwFile] OpenStudio EpwFile object - # @return [void] + # @return [nil] def get_header_info_from_epw(epw_file) header.City = epw_file.city header.StateProvinceRegion = epw_file.stateProvinceRegion @@ -286,7 +286,7 @@ def get_design_info_from_epw(runner, epw_file) # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param rowdata [Array] Weather data for each EPW record - # @return [void] + # @return [nil] def calc_design_info(runner, rowdata) if not runner.nil? runner.registerWarning('No design condition info found; calculating design conditions from EPW weather data.') @@ -321,7 +321,7 @@ def calc_design_info(runner, rowdata) # Calculates and stores shallow monthly/annual ground temperatures. # This correlation is the same that is used in DOE-2's src\WTH.f file, subroutine GTEMP. # - # @return [void] + # @return [nil] def calc_shallow_ground_temperatures() amon = [15.0, 46.0, 74.0, 95.0, 135.0, 166.0, 196.0, 227.0, 258.0, 288.0, 319.0, 349.0] po = 0.6 @@ -355,7 +355,7 @@ def calc_shallow_ground_temperatures() # source heat pump in the building. # # @param hpxml [HPXML] HPXML object - # @return [void] + # @return [nil] def calc_deep_ground_temperatures(hpxml) # Avoid this lookup/calculation if there's no GSHP since there is a (small) runtime penalty. if !hpxml.nil? @@ -398,7 +398,7 @@ def calc_deep_ground_temperatures(hpxml) # "Towards Development of an Algorithm for Mains Water Temperature". # # @param n_days [Integer] Number of days (typically 365 or 366 if a leap year) in the EPW file - # @return [void] + # @return [nil] def calc_mains_temperatures(n_days) deg_rad = Math::PI / 180 diff --git a/HPXMLtoOpenStudio/resources/xmlhelper.rb b/HPXMLtoOpenStudio/resources/xmlhelper.rb index 1835544b45..4c0b64620e 100644 --- a/HPXMLtoOpenStudio/resources/xmlhelper.rb +++ b/HPXMLtoOpenStudio/resources/xmlhelper.rb @@ -243,7 +243,7 @@ def self.create_doc(version = nil, encoding = nil, standalone = nil) # TODO # - # @param hpxml_path [TODO] TODO + # @param hpxml_path [String] Path to the HPXML file # @return [TODO] TODO def self.parse_file(hpxml_path) file_read = File.read(hpxml_path) diff --git a/HPXMLtoOpenStudio/tests/test_defaults.rb b/HPXMLtoOpenStudio/tests/test_defaults.rb index bf8b2329ca..6ea7e7f576 100644 --- a/HPXMLtoOpenStudio/tests/test_defaults.rb +++ b/HPXMLtoOpenStudio/tests/test_defaults.rb @@ -22,6 +22,8 @@ def setup @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path) @args_hash['debug'] = true @args_hash['output_dir'] = File.absolute_path(@tmp_output_path) + + @default_schedules_csv_data = HPXMLDefaults.get_default_schedules_csv_data() end def teardown @@ -442,8 +444,8 @@ def test_occupancy hpxml_bldg.building_occupancy.general_water_use_monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_occupancy_values(default_hpxml_bldg, Schedule.OccupantsWeekdayFractions, Schedule.OccupantsWeekendFractions, Schedule.OccupantsMonthlyMultipliers, - Schedule.GeneralWaterUseWeekdayFractions, Schedule.GeneralWaterUseWeekendFractions, Schedule.GeneralWaterUseMonthlyMultipliers, 1.0) + _test_default_occupancy_values(default_hpxml_bldg, @default_schedules_csv_data[Constants.ObjectNameOccupants]['WeekdayScheduleFractions'], @default_schedules_csv_data[Constants.ObjectNameOccupants]['WeekendScheduleFractions'], @default_schedules_csv_data[Constants.ObjectNameOccupants]['MonthlyScheduleMultipliers'], + @default_schedules_csv_data[SchedulesFile::Columns[:GeneralWaterUse].name]['GeneralWaterUseWeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:GeneralWaterUse].name]['GeneralWaterUseWeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:GeneralWaterUse].name]['GeneralWaterUseMonthlyScheduleMultipliers'], 1.0) end def test_building_construction @@ -3143,7 +3145,7 @@ def test_hot_water_distribution hpxml_bldg.hot_water_distributions[0].recirculation_pump_monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_recirc_distribution_values(default_hpxml_bldg.hot_water_distributions[0], 166.96, 10.0, 50.0, 0.0, Schedule.RecirculationPumpDemandControlledWeekdayFractions, Schedule.RecirculationPumpDemandControlledWeekendFractions, Schedule.RecirculationPumpMonthlyMultipliers) + _test_default_recirc_distribution_values(default_hpxml_bldg.hot_water_distributions[0], 166.96, 10.0, 50.0, 0.0, @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekdayScheduleFractions'], @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers']) # Test defaults w/ recirculation & unconditioned basement hpxml, hpxml_bldg = _create_hpxml('base-foundation-unconditioned-basement.xml') @@ -3153,7 +3155,7 @@ def test_hot_water_distribution recirculation_control_type: HPXML::DHWRecircControlTypeSensor) XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_recirc_distribution_values(default_hpxml_bldg.hot_water_distributions[0], 156.96, 10.0, 50.0, 0.0, Schedule.RecirculationPumpDemandControlledWeekdayFractions, Schedule.RecirculationPumpDemandControlledWeekendFractions, Schedule.RecirculationPumpMonthlyMultipliers) + _test_default_recirc_distribution_values(default_hpxml_bldg.hot_water_distributions[0], 156.96, 10.0, 50.0, 0.0, @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekdayScheduleFractions'], @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers']) # Test defaults w/ recirculation & 2-story building hpxml, hpxml_bldg = _create_hpxml('base-enclosure-2stories.xml') @@ -3163,7 +3165,7 @@ def test_hot_water_distribution recirculation_control_type: HPXML::DHWRecircControlTypeSensor) XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_recirc_distribution_values(default_hpxml_bldg.hot_water_distributions[0], 186.96, 10.0, 50.0, 0.0, Schedule.RecirculationPumpDemandControlledWeekdayFractions, Schedule.RecirculationPumpDemandControlledWeekendFractions, Schedule.RecirculationPumpMonthlyMultipliers) + _test_default_recirc_distribution_values(default_hpxml_bldg.hot_water_distributions[0], 186.96, 10.0, 50.0, 0.0, @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekdayScheduleFractions'], @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers']) # Test defaults w/ shared recirculation hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-water-heater-recirc.xml') @@ -3173,7 +3175,7 @@ def test_hot_water_distribution hpxml_bldg.hot_water_distributions[0].recirculation_pump_monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_shared_recirc_distribution_values(default_hpxml_bldg.hot_water_distributions[0], 220.0, Schedule.RecirculationPumpWithoutControlWeekdayFractions, Schedule.RecirculationPumpWithoutControlWeekendFractions, Schedule.RecirculationPumpMonthlyMultipliers) + _test_default_shared_recirc_distribution_values(default_hpxml_bldg.hot_water_distributions[0], 220.0, @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekdayScheduleFractions'], @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers']) end def test_water_fixtures @@ -3201,7 +3203,7 @@ def test_water_fixtures hpxml_bldg.water_fixtures[1].flow_rate = 2 XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_water_fixture_values(default_hpxml_bldg, 1.0, Schedule.FixturesWeekdayFractions, Schedule.FixturesWeekendFractions, Schedule.FixturesMonthlyMultipliers, true, true) + _test_default_water_fixture_values(default_hpxml_bldg, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterFixtures].name]['WaterFixturesWeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterFixtures].name]['WaterFixturesWeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterFixtures].name]['WaterFixturesMonthlyScheduleMultipliers'], true, true) end def test_solar_thermal_systems @@ -3426,7 +3428,7 @@ def test_clothes_washers hpxml_bldg.clothes_washers[0].monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_clothes_washer_values(default_hpxml_bldg.clothes_washers[0], false, HPXML::LocationConditionedSpace, 1.0, 400.0, 0.12, 1.09, 27.0, 3.0, 6.0, 1.0, Schedule.ClothesWasherWeekdayFractions, Schedule.ClothesWasherWeekendFractions, Schedule.ClothesWasherMonthlyMultipliers) + _test_default_clothes_washer_values(default_hpxml_bldg.clothes_washers[0], false, HPXML::LocationConditionedSpace, 1.0, 400.0, 0.12, 1.09, 27.0, 3.0, 6.0, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['MonthlyScheduleMultipliers']) # Test defaults before 301-2019 Addendum A hpxml, hpxml_bldg = _create_hpxml('base.xml') @@ -3446,7 +3448,7 @@ def test_clothes_washers hpxml_bldg.clothes_washers[0].monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_clothes_washer_values(default_hpxml_bldg.clothes_washers[0], false, HPXML::LocationConditionedSpace, 0.331, 704.0, 0.08, 0.58, 23.0, 2.874, 999, 1.0, Schedule.ClothesWasherWeekdayFractions, Schedule.ClothesWasherWeekendFractions, Schedule.ClothesWasherMonthlyMultipliers) + _test_default_clothes_washer_values(default_hpxml_bldg.clothes_washers[0], false, HPXML::LocationConditionedSpace, 0.331, 704.0, 0.08, 0.58, 23.0, 2.874, 999, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['MonthlyScheduleMultipliers']) end def test_clothes_dryers @@ -3475,26 +3477,26 @@ def test_clothes_dryers hpxml_bldg.clothes_dryers[0].monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_clothes_dryer_values(default_hpxml_bldg.clothes_dryers[0], false, HPXML::LocationConditionedSpace, 3.01, 1.0, Schedule.ClothesDryerWeekdayFractions, Schedule.ClothesDryerWeekendFractions, Schedule.ClothesDryerMonthlyMultipliers) + _test_default_clothes_dryer_values(default_hpxml_bldg.clothes_dryers[0], false, HPXML::LocationConditionedSpace, 3.01, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['MonthlyScheduleMultipliers']) # Test defaults w/ gas clothes dryer hpxml_bldg.clothes_dryers[0].fuel_type = HPXML::FuelTypeNaturalGas XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_clothes_dryer_values(default_hpxml_bldg.clothes_dryers[0], false, HPXML::LocationConditionedSpace, 3.01, 1.0, Schedule.ClothesDryerWeekdayFractions, Schedule.ClothesDryerWeekendFractions, Schedule.ClothesDryerMonthlyMultipliers) + _test_default_clothes_dryer_values(default_hpxml_bldg.clothes_dryers[0], false, HPXML::LocationConditionedSpace, 3.01, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['MonthlyScheduleMultipliers']) # Test defaults w/ electric clothes dryer before 301-2019 Addendum A hpxml.header.eri_calculation_version = '2019' hpxml_bldg.clothes_dryers[0].fuel_type = HPXML::FuelTypeElectricity XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_clothes_dryer_values(default_hpxml_bldg.clothes_dryers[0], false, HPXML::LocationConditionedSpace, 2.62, 1.0, Schedule.ClothesDryerWeekdayFractions, Schedule.ClothesDryerWeekendFractions, Schedule.ClothesDryerMonthlyMultipliers) + _test_default_clothes_dryer_values(default_hpxml_bldg.clothes_dryers[0], false, HPXML::LocationConditionedSpace, 2.62, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['MonthlyScheduleMultipliers']) # Test defaults w/ gas clothes dryer before 301-2019 Addendum A hpxml_bldg.clothes_dryers[0].fuel_type = HPXML::FuelTypeNaturalGas XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_clothes_dryer_values(default_hpxml_bldg.clothes_dryers[0], false, HPXML::LocationConditionedSpace, 2.32, 1.0, Schedule.ClothesDryerWeekdayFractions, Schedule.ClothesDryerWeekendFractions, Schedule.ClothesDryerMonthlyMultipliers) + _test_default_clothes_dryer_values(default_hpxml_bldg.clothes_dryers[0], false, HPXML::LocationConditionedSpace, 2.32, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['MonthlyScheduleMultipliers']) end def test_clothes_dryer_exhaust @@ -3553,13 +3555,13 @@ def test_dishwashers hpxml_bldg.dishwashers[0].monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_dishwasher_values(default_hpxml_bldg.dishwashers[0], false, HPXML::LocationConditionedSpace, 467.0, 0.12, 1.09, 33.12, 4.0, 12, 1.0, Schedule.DishwasherWeekdayFractions, Schedule.DishwasherWeekendFractions, Schedule.DishwasherMonthlyMultipliers) + _test_default_dishwasher_values(default_hpxml_bldg.dishwashers[0], false, HPXML::LocationConditionedSpace, 467.0, 0.12, 1.09, 33.12, 4.0, 12, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['MonthlyScheduleMultipliers']) # Test defaults before 301-2019 Addendum A hpxml.header.eri_calculation_version = '2019' XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_dishwasher_values(default_hpxml_bldg.dishwashers[0], false, HPXML::LocationConditionedSpace, 467.0, 999, 999, 999, 999, 12, 1.0, Schedule.DishwasherWeekdayFractions, Schedule.DishwasherWeekendFractions, Schedule.DishwasherMonthlyMultipliers) + _test_default_dishwasher_values(default_hpxml_bldg.dishwashers[0], false, HPXML::LocationConditionedSpace, 467.0, 999, 999, 999, 999, 12, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['MonthlyScheduleMultipliers']) end def test_refrigerators @@ -3600,7 +3602,7 @@ def test_refrigerators hpxml_bldg.refrigerators[0].temperature_coefficients = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_refrigerator_values(default_hpxml_bldg, HPXML::LocationConditionedSpace, 691.0, 1.0, Schedule.RefrigeratorWeekdayFractions, ConstantDaySchedule, Schedule.RefrigeratorMonthlyMultipliers, nil, nil) + _test_default_refrigerator_values(default_hpxml_bldg, HPXML::LocationConditionedSpace, 691.0, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['WeekdayScheduleFractions'], ConstantDaySchedule, @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['MonthlyScheduleMultipliers'], nil, nil) # Test defaults 2 hpxml_bldg.refrigerators[0].location = nil @@ -3613,20 +3615,20 @@ def test_refrigerators hpxml_bldg.refrigerators[0].temperature_coefficients = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_refrigerator_values(default_hpxml_bldg, HPXML::LocationConditionedSpace, 691.0, 1.0, nil, nil, nil, Schedule.RefrigeratorConstantCoefficients, Schedule.RefrigeratorTemperatureCoefficients) + _test_default_refrigerator_values(default_hpxml_bldg, HPXML::LocationConditionedSpace, 691.0, 1.0, nil, nil, nil, @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['ConstantScheduleCoefficients'], @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['TemperatureScheduleCoefficients']) # Test defaults w/ refrigerator in 5-bedroom house hpxml_bldg.building_construction.number_of_bedrooms = 5 XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_refrigerator_values(default_hpxml_bldg, HPXML::LocationConditionedSpace, 727.0, 1.0, nil, nil, nil, Schedule.RefrigeratorConstantCoefficients, Schedule.RefrigeratorTemperatureCoefficients) + _test_default_refrigerator_values(default_hpxml_bldg, HPXML::LocationConditionedSpace, 727.0, 1.0, nil, nil, nil, @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['ConstantScheduleCoefficients'], @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['TemperatureScheduleCoefficients']) # Test defaults before 301-2019 Addendum A hpxml.header.eri_calculation_version = '2019' hpxml_bldg.building_construction.number_of_bedrooms = 3 XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_refrigerator_values(default_hpxml_bldg, HPXML::LocationConditionedSpace, 691.0, 1.0, nil, nil, nil, Schedule.RefrigeratorConstantCoefficients, Schedule.RefrigeratorTemperatureCoefficients) + _test_default_refrigerator_values(default_hpxml_bldg, HPXML::LocationConditionedSpace, 691.0, 1.0, nil, nil, nil, @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['ConstantScheduleCoefficients'], @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['TemperatureScheduleCoefficients']) end def test_extra_refrigerators @@ -3675,7 +3677,7 @@ def test_extra_refrigerators end XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_extra_refrigerators_values(default_hpxml_bldg, HPXML::LocationBasementConditioned, 244.0, 1.0, nil, nil, nil, Schedule.ExtraRefrigeratorConstantCoefficients, Schedule.ExtraRefrigeratorTemperatureCoefficients) + _test_default_extra_refrigerators_values(default_hpxml_bldg, HPXML::LocationBasementConditioned, 244.0, 1.0, nil, nil, nil, @default_schedules_csv_data[SchedulesFile::Columns[:ExtraRefrigerator].name]['ConstantScheduleCoefficients'], @default_schedules_csv_data[SchedulesFile::Columns[:ExtraRefrigerator].name]['TemperatureScheduleCoefficients']) end def test_freezers @@ -3724,7 +3726,7 @@ def test_freezers end XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_freezers_values(default_hpxml_bldg, HPXML::LocationBasementConditioned, 320.0, 1.0, Schedule.FreezerWeekdayFractions, Schedule.FreezerWeekendFractions, Schedule.FreezerMonthlyMultipliers, nil, nil) + _test_default_freezers_values(default_hpxml_bldg, HPXML::LocationBasementConditioned, 320.0, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:Freezer].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:Freezer].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:Freezer].name]['MonthlyScheduleMultipliers'], nil, nil) end def test_cooking_ranges @@ -3749,13 +3751,13 @@ def test_cooking_ranges hpxml_bldg.cooking_ranges[0].monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_cooking_range_values(default_hpxml_bldg.cooking_ranges[0], HPXML::LocationConditionedSpace, false, 1.0, Schedule.CookingRangeWeekdayFractions, Schedule.CookingRangeWeekendFractions, Schedule.CookingRangeMonthlyMultipliers) + _test_default_cooking_range_values(default_hpxml_bldg.cooking_ranges[0], HPXML::LocationConditionedSpace, false, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['MonthlyScheduleMultipliers']) # Test defaults before 301-2019 Addendum A hpxml.header.eri_calculation_version = '2019' XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_cooking_range_values(default_hpxml_bldg.cooking_ranges[0], HPXML::LocationConditionedSpace, false, 1.0, Schedule.CookingRangeWeekdayFractions, Schedule.CookingRangeWeekendFractions, Schedule.CookingRangeMonthlyMultipliers) + _test_default_cooking_range_values(default_hpxml_bldg.cooking_ranges[0], HPXML::LocationConditionedSpace, false, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['MonthlyScheduleMultipliers']) end def test_ovens @@ -3839,12 +3841,12 @@ def test_lighting XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() _test_default_lighting_values(default_hpxml_bldg, 1.0, 1.0, 1.0, - { int_wk_sch: Schedule.LightingInteriorWeekdayFractions, - int_wknd_sch: Schedule.LightingInteriorWeekendFractions, - int_month_mult: Schedule.LightingMonthlyMultipliers, - ext_wk_sch: Schedule.LightingExteriorWeekdayFractions, - ext_wknd_sch: Schedule.LightingExteriorWeekendFractions, - ext_month_mult: Schedule.LightingMonthlyMultipliers }) + { int_wk_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorWeekdayScheduleFractions'], + int_wknd_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorWeekendScheduleFractions'], + int_month_mult: @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers'], + ext_wk_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorWeekdayScheduleFractions'], + ext_wknd_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorWeekdayScheduleFractions'], + ext_month_mult: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorMonthlyScheduleMultipliers'] }) # Test defaults w/ holiday lighting hpxml_bldg.lighting.holiday_exists = true @@ -3858,19 +3860,19 @@ def test_lighting XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() _test_default_lighting_values(default_hpxml_bldg, 1.0, 1.0, 1.0, - { int_wk_sch: Schedule.LightingInteriorWeekdayFractions, - int_wknd_sch: Schedule.LightingInteriorWeekendFractions, - int_month_mult: Schedule.LightingMonthlyMultipliers, - ext_wk_sch: Schedule.LightingExteriorWeekdayFractions, - ext_wknd_sch: Schedule.LightingExteriorWeekendFractions, - ext_month_mult: Schedule.LightingMonthlyMultipliers, + { int_wk_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorWeekdayScheduleFractions'], + int_wknd_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorWeekendScheduleFractions'], + int_month_mult: @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers'], + ext_wk_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorWeekdayScheduleFractions'], + ext_wknd_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorWeekdayScheduleFractions'], + ext_month_mult: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorMonthlyScheduleMultipliers'], hol_kwh_per_day: 1.1, hol_begin_month: 11, hol_begin_day: 24, hol_end_month: 1, hol_end_day: 6, - hol_wk_sch: Schedule.LightingExteriorHolidayWeekdayFractions, - hol_wknd_sch: Schedule.LightingExteriorHolidayWeekendFractions }) + hol_wk_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExteriorHoliday].name]['WeekdayScheduleFractions'], + hol_wknd_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExteriorHoliday].name]['WeekendScheduleFractions'] }) # Test defaults w/ garage hpxml, hpxml_bldg = _create_hpxml('base-enclosure-garage.xml') hpxml_bldg.lighting.interior_usage_multiplier = nil @@ -3879,15 +3881,15 @@ def test_lighting XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() _test_default_lighting_values(default_hpxml_bldg, 1.0, 1.0, 1.0, - { int_wk_sch: Schedule.LightingInteriorWeekdayFractions, - int_wknd_sch: Schedule.LightingInteriorWeekendFractions, - int_month_mult: Schedule.LightingMonthlyMultipliers, - ext_wk_sch: Schedule.LightingExteriorWeekdayFractions, - ext_wknd_sch: Schedule.LightingExteriorWeekendFractions, - ext_month_mult: Schedule.LightingMonthlyMultipliers, - grg_wk_sch: Schedule.LightingGarageWeekdayFractions, - grg_wknd_sch: Schedule.LightingGarageWeekendFractions, - grg_month_mult: Schedule.LightingMonthlyMultipliers }) + { int_wk_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorWeekdayScheduleFractions'], + int_wknd_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorWeekendScheduleFractions'], + int_month_mult: @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers'], + ext_wk_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorWeekdayScheduleFractions'], + ext_wknd_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorWeekdayScheduleFractions'], + ext_month_mult: @default_schedules_csv_data[SchedulesFile::Columns[:LightingExterior].name]['ExteriorMonthlyScheduleMultipliers'], + grg_wk_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingGarage].name]['GarageWeekdayScheduleFractions'], + grg_wknd_sch: @default_schedules_csv_data[SchedulesFile::Columns[:LightingGarage].name]['GarageWeekendScheduleFractions'], + grg_month_mult: @default_schedules_csv_data[SchedulesFile::Columns[:LightingGarage].name]['GarageMonthlyScheduleMultipliers'] }) end def test_ceiling_fans @@ -3927,7 +3929,7 @@ def test_ceiling_fans end XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_ceiling_fan_values(default_hpxml_bldg.ceiling_fans[0], 4, nil, 42.6, Schedule.CeilingFanWeekdayFractions, Schedule.CeilingFanWeekendFractions, '0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0') + _test_default_ceiling_fan_values(default_hpxml_bldg.ceiling_fans[0], 4, nil, 42.6, @default_schedules_csv_data[SchedulesFile::Columns[:CeilingFan].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:CeilingFan].name]['WeekendScheduleFractions'], '0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0') end def test_pools @@ -3965,8 +3967,8 @@ def test_pools pool.pump_monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_pool_heater_values(default_hpxml_bldg.pools[0], HPXML::UnitsThermPerYear, 236, 1.0, Schedule.PoolHeaterWeekdayFractions, Schedule.PoolHeaterWeekendFractions, Schedule.PoolHeaterMonthlyMultipliers) - _test_default_pool_pump_values(default_hpxml_bldg.pools[0], 2496, 1.0, Schedule.PoolPumpWeekdayFractions, Schedule.PoolPumpWeekendFractions, Schedule.PoolPumpMonthlyMultipliers) + _test_default_pool_heater_values(default_hpxml_bldg.pools[0], HPXML::UnitsThermPerYear, 236, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PoolHeater].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PoolHeater].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PoolHeater].name]['MonthlyScheduleMultipliers']) + _test_default_pool_pump_values(default_hpxml_bldg.pools[0], 2496, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PoolPump].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PoolPump].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PoolPump].name]['MonthlyScheduleMultipliers']) # Test defaults 2 hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon2.xml') @@ -3985,7 +3987,7 @@ def test_pools XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() _test_default_pool_heater_values(default_hpxml_bldg.pools[0], nil, nil, nil, nil, nil, nil) - _test_default_pool_pump_values(default_hpxml_bldg.pools[0], 2496, 1.0, Schedule.PoolPumpWeekdayFractions, Schedule.PoolPumpWeekendFractions, Schedule.PoolPumpMonthlyMultipliers) + _test_default_pool_pump_values(default_hpxml_bldg.pools[0], 2496, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PoolPump].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PoolPump].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PoolPump].name]['MonthlyScheduleMultipliers']) end def test_permanent_spas @@ -4023,8 +4025,8 @@ def test_permanent_spas spa.pump_monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_permanent_spa_heater_values(default_hpxml_bldg.permanent_spas[0], HPXML::UnitsKwhPerYear, 1125, 1.0, Schedule.PermanentSpaHeaterWeekdayFractions, Schedule.PermanentSpaHeaterWeekendFractions, Schedule.PermanentSpaHeaterMonthlyMultipliers) - _test_default_permanent_spa_pump_values(default_hpxml_bldg.permanent_spas[0], 1111, 1.0, Schedule.PermanentSpaPumpWeekdayFractions, Schedule.PermanentSpaPumpWeekendFractions, Schedule.PermanentSpaPumpMonthlyMultipliers) + _test_default_permanent_spa_heater_values(default_hpxml_bldg.permanent_spas[0], HPXML::UnitsKwhPerYear, 1125, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaHeater].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaHeater].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaHeater].name]['MonthlyScheduleMultipliers']) + _test_default_permanent_spa_pump_values(default_hpxml_bldg.permanent_spas[0], 1111, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaPump].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaPump].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaPump].name]['MonthlyScheduleMultipliers']) # Test defaults 2 hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon2.xml') @@ -4042,8 +4044,8 @@ def test_permanent_spas spa.pump_monthly_multipliers = nil XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_permanent_spa_heater_values(default_hpxml_bldg.permanent_spas[0], HPXML::UnitsKwhPerYear, 225, 1.0, Schedule.PermanentSpaHeaterWeekdayFractions, Schedule.PermanentSpaHeaterWeekendFractions, Schedule.PermanentSpaHeaterMonthlyMultipliers) - _test_default_permanent_spa_pump_values(default_hpxml_bldg.permanent_spas[0], 1111, 1.0, Schedule.PermanentSpaPumpWeekdayFractions, Schedule.PermanentSpaPumpWeekendFractions, Schedule.PermanentSpaPumpMonthlyMultipliers) + _test_default_permanent_spa_heater_values(default_hpxml_bldg.permanent_spas[0], HPXML::UnitsKwhPerYear, 225, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaHeater].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaHeater].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaHeater].name]['MonthlyScheduleMultipliers']) + _test_default_permanent_spa_pump_values(default_hpxml_bldg.permanent_spas[0], 1111, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaPump].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaPump].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PermanentSpaPump].name]['MonthlyScheduleMultipliers']) end def test_plug_loads @@ -4100,10 +4102,10 @@ def test_plug_loads end XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_plug_load_values(default_hpxml_bldg, HPXML::PlugLoadTypeTelevision, 620, 1.0, 0.0, 1.0, Schedule.PlugLoadsTVWeekdayFractions, Schedule.PlugLoadsTVWeekendFractions, Schedule.PlugLoadsTVMonthlyMultipliers) - _test_default_plug_load_values(default_hpxml_bldg, HPXML::PlugLoadTypeOther, 2457, 0.855, 0.045, 1.0, Schedule.PlugLoadsOtherWeekdayFractions, Schedule.PlugLoadsOtherWeekendFractions, Schedule.PlugLoadsOtherMonthlyMultipliers) - _test_default_plug_load_values(default_hpxml_bldg, HPXML::PlugLoadTypeElectricVehicleCharging, 1667, 0.0, 0.0, 1.0, Schedule.PlugLoadsVehicleWeekdayFractions, Schedule.PlugLoadsVehicleWeekendFractions, Schedule.PlugLoadsVehicleMonthlyMultipliers) - _test_default_plug_load_values(default_hpxml_bldg, HPXML::PlugLoadTypeWellPump, 441, 0.0, 0.0, 1.0, Schedule.PlugLoadsWellPumpWeekdayFractions, Schedule.PlugLoadsWellPumpWeekendFractions, Schedule.PlugLoadsWellPumpMonthlyMultipliers) + _test_default_plug_load_values(default_hpxml_bldg, HPXML::PlugLoadTypeTelevision, 620, 1.0, 0.0, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['MonthlyScheduleMultipliers']) + _test_default_plug_load_values(default_hpxml_bldg, HPXML::PlugLoadTypeOther, 2457, 0.855, 0.045, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['MonthlyScheduleMultipliers']) + _test_default_plug_load_values(default_hpxml_bldg, HPXML::PlugLoadTypeElectricVehicleCharging, 1667, 0.0, 0.0, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsVehicle].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsVehicle].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsVehicle].name]['MonthlyScheduleMultipliers']) + _test_default_plug_load_values(default_hpxml_bldg, HPXML::PlugLoadTypeWellPump, 441, 0.0, 0.0, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsWellPump].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsWellPump].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsWellPump].name]['MonthlyScheduleMultipliers']) end def test_fuel_loads @@ -4151,9 +4153,9 @@ def test_fuel_loads end XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _default_hpxml, default_hpxml_bldg = _test_measure() - _test_default_fuel_load_values(default_hpxml_bldg, HPXML::FuelLoadTypeGrill, 33, 0.0, 0.0, 1.0, Schedule.FuelLoadsGrillWeekdayFractions, Schedule.FuelLoadsGrillWeekendFractions, Schedule.FuelLoadsGrillMonthlyMultipliers) - _test_default_fuel_load_values(default_hpxml_bldg, HPXML::FuelLoadTypeLighting, 20, 0.0, 0.0, 1.0, Schedule.FuelLoadsLightingWeekdayFractions, Schedule.FuelLoadsLightingWeekendFractions, Schedule.FuelLoadsLightingMonthlyMultipliers) - _test_default_fuel_load_values(default_hpxml_bldg, HPXML::FuelLoadTypeFireplace, 67, 0.5, 0.1, 1.0, Schedule.FuelLoadsFireplaceWeekdayFractions, Schedule.FuelLoadsFireplaceWeekendFractions, Schedule.FuelLoadsFireplaceMonthlyMultipliers) + _test_default_fuel_load_values(default_hpxml_bldg, HPXML::FuelLoadTypeGrill, 33, 0.0, 0.0, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsGrill].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsGrill].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsGrill].name]['MonthlyScheduleMultipliers']) + _test_default_fuel_load_values(default_hpxml_bldg, HPXML::FuelLoadTypeLighting, 20, 0.0, 0.0, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsLighting].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsLighting].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsLighting].name]['MonthlyScheduleMultipliers']) + _test_default_fuel_load_values(default_hpxml_bldg, HPXML::FuelLoadTypeFireplace, 67, 0.5, 0.1, 1.0, @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsFireplace].name]['WeekdayScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsFireplace].name]['WeekendScheduleFractions'], @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsFireplace].name]['MonthlyScheduleMultipliers']) end def _test_measure() diff --git a/HPXMLtoOpenStudio/tests/test_schedules.rb b/HPXMLtoOpenStudio/tests/test_schedules.rb index 0182adca39..534c9aad69 100644 --- a/HPXMLtoOpenStudio/tests/test_schedules.rb +++ b/HPXMLtoOpenStudio/tests/test_schedules.rb @@ -16,6 +16,8 @@ def setup @year = 2007 @tol = 0.005 + + @default_schedules_csv_data = HPXMLDefaults.get_default_schedules_csv_data() end def teardown @@ -115,19 +117,19 @@ def test_simple_vacancy_schedules unavailable_month_hrs = { 0 => 31.0 * 24.0, 11 => 31.0 * 24.0 } - assert_in_epsilon(6020 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.OccupantsMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameOccupants + ' schedule'), @tol) - assert_in_epsilon(3049 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.LightingMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingInterior + ' schedule'), @tol) - assert_in_epsilon(2895 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.LightingMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) + assert_in_epsilon(6020 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:Occupants].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameOccupants + ' schedule'), @tol) + assert_in_epsilon(3049 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingInterior + ' schedule'), @tol) + assert_in_epsilon(2895 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) assert_in_epsilon(6673, get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameRefrigerator + ' schedule'), @tol) - assert_in_epsilon(2441 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.CookingRangeMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameCookingRange + ' schedule'), @tol) - assert_in_epsilon(3285 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.DishwasherMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameDishwasher + ' schedule'), @tol) - assert_in_epsilon(4248 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.ClothesWasherMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameClothesWasher + ' schedule'), @tol) - assert_in_epsilon(4502 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.ClothesDryerMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameClothesDryer + ' schedule'), @tol) - assert_in_epsilon(6880 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.PlugLoadsOtherMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameMiscPlugLoads + ' schedule'), @tol) - assert_in_epsilon(3373 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.PlugLoadsTVMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameMiscTelevision + ' schedule'), @tol) - assert_in_epsilon(4204 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.FixturesMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameFixtures + ' schedule'), @tol) - assert_in_epsilon(4244 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.RecirculationPumpMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameHotWaterRecircPump + ' schedule'), @tol) - assert_in_epsilon(5000 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.GeneralWaterUseMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameGeneralWaterUse + ' schedule'), @tol) + assert_in_epsilon(2441 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameCookingRange + ' schedule'), @tol) + assert_in_epsilon(3285 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameDishwasher + ' schedule'), @tol) + assert_in_epsilon(4248 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameClothesWasher + ' schedule'), @tol) + assert_in_epsilon(4502 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameClothesDryer + ' schedule'), @tol) + assert_in_epsilon(6880 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameMiscPlugLoads + ' schedule'), @tol) + assert_in_epsilon(3373 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameMiscTelevision + ' schedule'), @tol) + assert_in_epsilon(4204 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterFixtures].name]['WaterFixturesMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameFixtures + ' schedule'), @tol) + assert_in_epsilon(4244 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameHotWaterRecircPump + ' schedule'), @tol) + assert_in_epsilon(5000 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:GeneralWaterUse].name]['GeneralWaterUseMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameGeneralWaterUse + ' schedule'), @tol) assert_in_epsilon(8760, get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameMechanicalVentilationHouseFan + ' schedule'), @tol) end @@ -167,17 +169,17 @@ def test_simple_power_outage_schedules unavailable_month_hrs = { 6 => 31.0 * 24.0 - 15.0 } assert_in_epsilon(6020, get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameOccupants + ' schedule'), @tol) - assert_in_epsilon(3049 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.LightingMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingInterior + ' schedule'), @tol) - assert_in_epsilon(2895 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.LightingMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) - assert_in_epsilon(6673 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.RefrigeratorMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameRefrigerator + ' schedule'), @tol) - assert_in_epsilon(2441 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.CookingRangeMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameCookingRange + ' schedule'), @tol) - assert_in_epsilon(3285 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.DishwasherMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameDishwasher + ' schedule'), @tol) - assert_in_epsilon(4248 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.ClothesWasherMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameClothesWasher + ' schedule'), @tol) - assert_in_epsilon(4502 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.ClothesDryerMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameClothesDryer + ' schedule'), @tol) - assert_in_epsilon(6880 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.PlugLoadsOtherMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameMiscPlugLoads + ' schedule'), @tol) - assert_in_epsilon(3373 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.PlugLoadsTVMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameMiscTelevision + ' schedule'), @tol) - assert_in_epsilon(4204 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.FixturesMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameFixtures + ' schedule'), @tol) - assert_in_epsilon(4244 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.RecirculationPumpMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameHotWaterRecircPump + ' schedule'), @tol) + assert_in_epsilon(3049 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingInterior + ' schedule'), @tol) + assert_in_epsilon(2895 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) + assert_in_epsilon(6673 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:Refrigerator].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameRefrigerator + ' schedule'), @tol) + assert_in_epsilon(2441 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:CookingRange].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameCookingRange + ' schedule'), @tol) + assert_in_epsilon(3285 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:Dishwasher].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameDishwasher + ' schedule'), @tol) + assert_in_epsilon(4248 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:ClothesWasher].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameClothesWasher + ' schedule'), @tol) + assert_in_epsilon(4502 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:ClothesDryer].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameClothesDryer + ' schedule'), @tol) + assert_in_epsilon(6880 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameMiscPlugLoads + ' schedule'), @tol) + assert_in_epsilon(3373 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['MonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameMiscTelevision + ' schedule'), @tol) + assert_in_epsilon(4204 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterFixtures].name]['WaterFixturesMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameFixtures + ' schedule'), @tol) + assert_in_epsilon(4244 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameHotWaterRecircPump + ' schedule'), @tol) assert_in_epsilon(5000, get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameGeneralWaterUse + ' schedule'), @tol) assert_in_epsilon(8760 * get_available_hrs_ratio(unavailable_month_hrs), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameMechanicalVentilationHouseFan + ' schedule'), @tol) end @@ -265,7 +267,7 @@ def test_stochastic_vacancy_schedules assert_in_epsilon(6689 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Occupants].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Occupants].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(2086 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingInterior].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingInterior].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(2086 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingGarage].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingGarage].name, schedules: sf.tmp_schedules), @tol) - assert_in_epsilon(4342 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.LightingMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) + assert_in_epsilon(4342 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) assert_in_epsilon(534 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:CookingRange].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:CookingRange].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(213 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Dishwasher].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Dishwasher].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(134 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:ClothesWasher].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:ClothesWasher].name, schedules: sf.tmp_schedules), @tol) @@ -323,7 +325,7 @@ def test_stochastic_vacancy_schedules2 assert_in_epsilon(6689 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Occupants].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Occupants].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(2086 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingInterior].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingInterior].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(2086 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingGarage].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingGarage].name, schedules: sf.tmp_schedules), @tol) - assert_in_epsilon(4342 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.LightingMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) + assert_in_epsilon(4342 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) assert_in_epsilon(534 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:CookingRange].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:CookingRange].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(213 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Dishwasher].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Dishwasher].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(134 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:ClothesWasher].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:ClothesWasher].name, schedules: sf.tmp_schedules), @tol) @@ -407,7 +409,7 @@ def test_stochastic_power_outage_schedules assert_in_epsilon(6689, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Occupants].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(2086 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingInterior].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingInterior].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(2086 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingGarage].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingGarage].name, schedules: sf.tmp_schedules), @tol) - assert_in_epsilon(4342 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.LightingMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) + assert_in_epsilon(4342 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) assert_in_epsilon(534 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:CookingRange].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:CookingRange].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(213 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Dishwasher].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Dishwasher].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(134 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:ClothesWasher].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:ClothesWasher].name, schedules: sf.tmp_schedules), @tol) @@ -467,7 +469,7 @@ def test_stochastic_power_outage_schedules2 assert_in_epsilon(6689, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Occupants].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(2086 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingInterior].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingInterior].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(2086 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingGarage].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:LightingGarage].name, schedules: sf.tmp_schedules), @tol) - assert_in_epsilon(4342 * get_available_hrs_ratio(unavailable_month_hrs, Schedule.LightingMonthlyMultipliers), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) + assert_in_epsilon(4342 * get_available_hrs_ratio(unavailable_month_hrs, @default_schedules_csv_data[SchedulesFile::Columns[:LightingInterior].name]['InteriorMonthlyScheduleMultipliers']), get_annual_equivalent_full_load_hrs(model, Constants.ObjectNameLightingExterior + ' schedule'), @tol) assert_in_epsilon(534 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:CookingRange].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:CookingRange].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(213 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Dishwasher].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:Dishwasher].name, schedules: sf.tmp_schedules), @tol) assert_in_epsilon(134 - sf.period_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:ClothesWasher].name, period: unavailable_period), sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::Columns[:ClothesWasher].name, schedules: sf.tmp_schedules), @tol) diff --git a/HPXMLtoOpenStudio/tests/test_validation.rb b/HPXMLtoOpenStudio/tests/test_validation.rb index 11f3d3f4e7..c76d9ef15a 100644 --- a/HPXMLtoOpenStudio/tests/test_validation.rb +++ b/HPXMLtoOpenStudio/tests/test_validation.rb @@ -22,6 +22,8 @@ def setup @tmp_csv_path = File.join(@sample_files_path, 'tmp.csv') @tmp_output_path = File.join(@sample_files_path, 'tmp_output') FileUtils.mkdir_p(@tmp_output_path) + + @default_schedules_csv_data = HPXMLDefaults.get_default_schedules_csv_data() end def teardown @@ -1898,9 +1900,9 @@ def test_ruby_warning_messages hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/occupancy-non-stochastic.csv') hpxml_bldg.hot_water_distributions[0].system_type = HPXML::DHWDistTypeRecirc hpxml_bldg.hot_water_distributions[0].recirculation_control_type = HPXML::DHWRecircControlTypeNone - hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekday_fractions = Schedule.RecirculationPumpWithoutControlWeekdayFractions - hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekend_fractions = Schedule.RecirculationPumpWithoutControlWeekendFractions - hpxml_bldg.hot_water_distributions[0].recirculation_pump_monthly_multipliers = Schedule.RecirculationPumpMonthlyMultipliers + hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekday_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekdayScheduleFractions'] + hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekend_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekendScheduleFractions'] + hpxml_bldg.hot_water_distributions[0].recirculation_pump_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers'] elsif ['schedule-file-and-refrigerators-freezer-coefficients'].include? warning_case hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/occupancy-stochastic.csv') diff --git a/ReportUtilityBills/measure.rb b/ReportUtilityBills/measure.rb index aefdda9489..b5585b7e4c 100644 --- a/ReportUtilityBills/measure.rb +++ b/ReportUtilityBills/measure.rb @@ -530,7 +530,7 @@ def report_monthly_output_results(runner, args, timestamps, monthly_data, monthl # Fill each UtilityRate object based on simple or detailed utility rate information. # - # @param hpxml_path [String] path of the input HPXML file + # @param hpxml_path [String] Path to the HPXML file # @param fuels [Hash] Fuel type, is_production => Fuel object # @param utility_rates [Hash] Fuel Type => UtilityRate object # @param bill_scenario [HPXML::UtilityBillScenario] HPXML Utility Bill Scenario object diff --git a/ReportUtilityBills/measure.xml b/ReportUtilityBills/measure.xml index a067601655..1d012784cd 100644 --- a/ReportUtilityBills/measure.xml +++ b/ReportUtilityBills/measure.xml @@ -3,8 +3,8 @@ 3.1 report_utility_bills ca88a425-e59a-4bc4-af51-c7e7d1e960fe - e7a1eb0f-f485-45ad-9448-2e5f6c145c5f - 2024-07-17T17:05:04Z + 0c47ee05-9a2a-427e-8b71-bcef50fcd28c + 2024-08-16T19:31:35Z 15BF4E57 ReportUtilityBills Utility Bills Report @@ -180,7 +180,7 @@ measure.rb rb script - DE8B3221 + 8CDD4264 detailed_rates/Sample Flat Rate Min Annual Charge.json @@ -306,7 +306,7 @@ util.rb rb resource - 0B994914 + A6C75E8E Contains Demand Charges.json diff --git a/ReportUtilityBills/resources/util.rb b/ReportUtilityBills/resources/util.rb index 5323295194..3c0ced113f 100644 --- a/ReportUtilityBills/resources/util.rb +++ b/ReportUtilityBills/resources/util.rb @@ -127,7 +127,7 @@ def self.simple(fuel_type, header, fuel_time_series, is_production, rate, bill, # @param fuels [Hash] Fuel type, is_production => Fuel object # @param rate [UtilityRate] UtilityRate object # @param bill [UtilityBill] UtilityBill object - # @return [void] + # @return [nil] def self.detailed_electric(header, fuels, rate, bill) fuel_time_series = fuels[[FT::Elec, false]].timeseries production_fuel_time_series = fuels[[FT::Elec, true]].timeseries diff --git a/docs/source/workflow_inputs.rst b/docs/source/workflow_inputs.rst index 30616a80f7..957792ea5d 100644 --- a/docs/source/workflow_inputs.rst +++ b/docs/source/workflow_inputs.rst @@ -591,11 +591,11 @@ Building occupancy is entered in ``/HPXML/Building/BuildingDetails/BuildingSumma \- **single-family attached or apartment unit**: NumberofBedrooms = -0.68 + 1.09 * NumberofResidents - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.035, 0.035, 0.035, 0.035, 0.035, 0.059, 0.082, 0.055, 0.027, 0.014, 0.014, 0.014, 0.014, 0.014, 0.019, 0.027, 0.041, 0.055, 0.068, 0.082, 0.082, 0.070, 0.053, 0.035". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values are used: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. .. [#] Sensible and latent internal gains from general water use (floor mopping, shower evaporation, water films on showers, tubs & sinks surfaces, plant watering, etc.), as defined by `ANSI/RESNET/ICC 301-2019 `_. - .. [#] If GeneralWaterUseWeekdayScheduleFractions or GeneralWaterUseWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.023, 0.021, 0.021, 0.025, 0.027, 0.038, 0.044, 0.039, 0.037, 0.037, 0.034, 0.035, 0.035, 0.035, 0.039, 0.043, 0.051, 0.064, 0.065, 0.072, 0.073, 0.063, 0.045, 0.034". - .. [#] If GeneralWaterUseMonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values are used: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If GeneralWaterUseWeekdayScheduleFractions or GeneralWaterUseWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If GeneralWaterUseMonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. .. _building_construction: @@ -668,7 +668,7 @@ Detailed schedule inputs are provided via one or more CSV file that should be re The column names available in the schedule CSV files are: ================================ ======= ================================================================================= =============================== - Column Name Units Description Can Be Stochastically Generated + Column Name Units Description Can Be Stochastically Generated [#]_ ================================ ======= ================================================================================= =============================== ``occupants`` frac Occupant heat gain schedule. Yes ``lighting_interior`` frac Interior lighting energy use schedule. Yes @@ -707,6 +707,22 @@ The column names available in the schedule CSV files are: ``battery`` -1 to 1 Battery schedule. Positive for charging, negative for discharging. No ================================ ======= ================================================================================= =============================== + .. [#] A detailed stochastic occupancy schedule CSV file can also be automatically generated for these columns; see the :ref:`usage_instructions` for the commands. + The stochastic occupancy schedules are generated using the methodology described in `Stochastic simulation of occupant-driven energy use in a bottom-up residential building stock model `_. + Inputs for the stochastic schedule generator are entered in: + + \- ``/HPXML/Building/BuildingDetails/BuildingSummary/BuildingOccupancy/NumberofResidents`` + + \- ``/HPXML/Building/Site/Address/StateCode`` (optional) + + \- ``/HPXML/Building/Site/GeoLocation/Latitude`` (optional) + + \- ``/HPXML/Building/Site/GeoLocation/Longitude`` (optional) + + \- ``/HPXML/Building/Site/TimeZone/UTCOffset`` (optional) + + See :ref:`building_occupancy` and :ref:`building_site` for more information. + .. [#] This feature is an advanced research capability. This schedule allows modeling shedding controls for variable speed HVAC systems (instead of setpoint changes) to limit the power of HVAC per `AHRI 1380 `_. While any fraction value can be entered, this is primarily intended to reflect the AHRI capabilities, which has two levels of load shed: "General Curtailment" and "Critical Curtailment". A "General Curtailment" signal prevents the equipment from running at more than 70% of max power and "Critical Curtailment" limits it to 40% of max power until comfort constraints are violated (4F off the setpoint). @@ -721,18 +737,6 @@ The schedule file must have a full year of data even if the simulation is not an Frequency of schedule values do not need to match the simulation timestep. For example, hourly schedules can be used with a 10-minute simulation timestep, or 10-minute schedules can be used with an hourly simulation timestep. -A detailed stochastic occupancy schedule CSV file can also be automatically generated for you (see "Can Be Stochastically Generated" above for applicable columns); see the :ref:`usage_instructions` for the commands. -The stochastic occupancy schedules are generated using the methodology described in `Stochastic simulation of occupant-driven energy use in a bottom-up residential building stock model `_. -Inputs for the stochastic schedule generator are entered in: - -- ``/HPXML/Building/BuildingDetails/BuildingSummary/BuildingOccupancy/NumberofResidents`` -- ``/HPXML/Building/Site/Address/StateCode`` (optional) -- ``/HPXML/Building/Site/GeoLocation/Latitude`` (optional) -- ``/HPXML/Building/Site/GeoLocation/Longitude`` (optional) -- ``/HPXML/Building/Site/TimeZone/UTCOffset`` (optional) - -See :ref:`building_occupancy` and :ref:`building_site` for more information. - .. warning:: For simulations with daylight saving enabled (which is the default), EnergyPlus will skip forward an hour in the CSV on the "spring forward" day and repeat an hour on the "fall back" day. @@ -744,7 +748,12 @@ Default Schedules If neither simple nor detailed inputs are provided, then schedules are defaulted. Default schedules are typically smooth, averaged schedules. -These default schedules are described elsewhere in the documentation (e.g., see :ref:`building_occupancy` for the default occupant heat gain schedule). +These default schedules (and data sources) are described in the table below (e.g., see "occupants" rows for the default occupant heat gain schedule). +They can also be found at ``HPXMLtoOpenStudio/resources/data/default_schedules.csv``. + +.. csv-table:: + :file: ../../HPXMLtoOpenStudio/resources/data/default_schedules.csv + :header-rows: 1 .. _hvac_sizing_control: @@ -2865,6 +2874,7 @@ If a backup type ("integrated" or "separate") is provided, additional informatio .. note:: Provide ``BackupHeatingSwitchoverTemperature`` for a situation where there is a discrete outdoor temperature below which the heat pump stops operating and above which the backup heating system stops operating. + Note that this control strategy has risk of the heating setpoint not being maintained (i.e., unmet hours) when the outdoor temperature is just above the switchover temperature, as the heat pump may not have sufficient capacity to meet the heating load and the backup is disabled. Alternatively, provide A) ``CompressorLockoutTemperature`` to specify the outdoor temperature below which the heat pump stops operating and/or B) ``BackupHeatingLockoutTemperature`` to specify the outdoor temperature above which the heat pump backup system stops operating. If both are provided, the compressor and backup system can both operate between the two temperatures (e.g., simultaneous operation or cycling). @@ -3451,7 +3461,8 @@ Each heat recovery ventilator (HRV) is entered as a ``/HPXML/Building/BuildingDe OpenStudio-HPXML does not currently support defaulting flow rates for multiple mechanical ventilation fans. - .. [#] Providing AdjustedSensibleRecoveryEfficiency (ASRE) is preferable to SensibleRecoveryEfficiency (SRE). + .. [#] AdjustedSensibleRecoveryEfficiency (ASRE) is similar to SensibleRecoveryEfficiency (SRE), in that it reflects heating season performance, but excludes fan electric consumption. + Since OpenStudio-HPXML separately models fan electric consumption, ASRE is a preferable input to SRE because it can be directly used in the energy model. .. [#] If FanPower not provided, defaults to 1.0 W/cfm based on `ANSI/RESNET/ICC 301-2019 `_. .. _vent_fan_erv: @@ -3493,8 +3504,10 @@ Each energy recovery ventilator (ERV) is entered as a ``/HPXML/Building/Building OpenStudio-HPXML does not currently support defaulting flow rates for multiple mechanical ventilation fans. - .. [#] Providing AdjustedTotalRecoveryEfficiency (ATRE) is preferable to TotalRecoveryEfficiency (TRE). - .. [#] Providing AdjustedSensibleRecoveryEfficiency (ASRE) is preferable to SensibleRecoveryEfficiency (SRE). + .. [#] AdjustedTotalRecoveryEfficiency (ATRE) is similar to TotalRecoveryEfficiency (TRE), in that it reflects cooling season performance, but excludes fan electric consumption. + Since OpenStudio-HPXML separately models fan electric consumption, ATRE is a preferable input to TRE because it can be directly used in the energy model. + .. [#] AdjustedSensibleRecoveryEfficiency (ASRE) is similar to SensibleRecoveryEfficiency (SRE), in that it reflects heating season performance, but excludes fan electric consumption. + Since OpenStudio-HPXML separately models fan electric consumption, ASRE is a preferable input to SRE because it can be directly used in the energy model. .. [#] If FanPower not provided, defaults to 1.0 W/cfm based on `ANSI/RESNET/ICC 301-2019 `_. .. _vent_fan_cfis: @@ -4010,15 +4023,8 @@ An in-unit recirculation hot water distribution system is entered as a ``/HPXML/ .. [#] BranchPipingLength is the length of the branch hot water piping from the recirculation loop to the farthest hot water fixture from the recirculation loop, measured longitudinally from plans, assuming the branch hot water piping does not run diagonally. .. [#] PumpPower default based on `ANSI/RESNET/ICC 301-2019 `_. .. [#] Additional drain water heat recovery inputs are described in :ref:`water_heater_dwhr`. - .. [#] If RecirculationPumpWeekdayScheduleFractions or RecirculationPumpWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), defaults as: - - \- **no control**, **timer**: "0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042" (based on Equation 4.2-43a of ANSI/RESNET/ICC 301-2022 Addendum C) - - \- **manual demand control**, **presence sensor demand control**: "0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026" (based on Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C) - - \- **temperature**: "0.067, 0.072, 0.074, 0.073, 0.069, 0.048, 0.011, 0.003, 0.009, 0.020, 0.030, 0.037, 0.043, 0.047, 0.050, 0.051, 0.044, 0.034, 0.026, 0.026, 0.030, 0.036, 0.045, 0.055" (based on Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C) - - .. [#] If RecirculationPumpMonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values are used: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If RecirculationPumpWeekdayScheduleFractions or RecirculationPumpWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If RecirculationPumpMonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. .. _hot_water_dist_recirc_shared: @@ -4072,15 +4078,8 @@ A shared recirculation hot water distribution system (serving multiple dwelling \- **no control**: The pump runs continuously. - .. [#] If RecirculationPumpWeekdayScheduleFractions or RecirculationPumpWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), defaults as: - - \- **no control**, **timer**: "0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042" (based on Equation 4.2-43a of ANSI/RESNET/ICC 301-2022 Addendum C) - - \- **manual demand control**, **presence sensor demand control**: "0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026" (based on Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C) - - \- **temperature**: "0.067, 0.072, 0.074, 0.073, 0.069, 0.048, 0.011, 0.003, 0.009, 0.020, 0.030, 0.037, 0.043, 0.047, 0.050, 0.051, 0.044, 0.034, 0.026, 0.026, 0.030, 0.036, 0.045, 0.055" (based on Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C) - - .. [#] If RecirculationPumpMonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), defaults to: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If RecirculationPumpWeekdayScheduleFractions or RecirculationPumpWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If RecirculationPumpMonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. .. note:: @@ -4140,8 +4139,8 @@ Additional information can be entered in ``/HPXML/Building/BuildingDetails/Syste ``extension/WaterFixturesMonthlyScheduleMultipliers`` array No See [#]_ 12 comma-separated monthly multipliers ===================================================== ======= ===== =========== ======== ======== =============================================== - .. [#] If WaterFixturesWeekdayScheduleFractions or WaterFixturesWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.012, 0.006, 0.004, 0.005, 0.010, 0.034, 0.078, 0.086, 0.080, 0.067, 0.056, 0.047, 0.040, 0.035, 0.033, 0.031, 0.038, 0.051, 0.060, 0.060, 0.055, 0.048, 0.038, 0.026". - .. [#] If WaterFixturesMonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values are used: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If WaterFixturesWeekdayScheduleFractions or WaterFixturesWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If WaterFixturesMonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. Water fixture hot water use is calculated per the Energy Rating Rated Home in `ANSI/RESNET/ICC 301-2019 `_. @@ -4399,8 +4398,8 @@ If not entered, the simulation will not include a clothes washer. IMEF may be found using the manufacturer’s data sheet, the `California Energy Commission Appliance Database `_, the `EPA ENERGY STAR website `_, or another reputable source. .. [#] AttachedToWaterHeatingSystem must reference a ``WaterHeatingSystem``; AttachedToHotWaterDistribution must reference a ``HotWaterDistribution``. .. [#] AttachedToWaterHeatingSystem (or AttachedToHotWaterDistribution) only required if IsSharedAppliance is true. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.009, 0.007, 0.004, 0.004, 0.007, 0.011, 0.022, 0.049, 0.073, 0.086, 0.084, 0.075, 0.067, 0.060, 0.049, 0.051, 0.050, 0.049, 0.049, 0.049, 0.049, 0.047, 0.032, 0.017". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values are used: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. If IntegratedModifiedEnergyFactor or ModifiedEnergyFactor is provided, a complete set of EnergyGuide label information is entered in ``ClothesWasher``. @@ -4449,8 +4448,8 @@ If not entered, the simulation will not include a clothes dryer. CEF = EF / 1.15. CEF may be found using the manufacturer’s data sheet, the `California Energy Commission Appliance Database `_, the `EPA ENERGY STAR website `_, or another reputable source. .. [#] VentedFlowRate default based on the `2010 BAHSP `_. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.010, 0.006, 0.004, 0.002, 0.004, 0.006, 0.016, 0.032, 0.048, 0.068, 0.078, 0.081, 0.074, 0.067, 0.058, 0.061, 0.055, 0.054, 0.051, 0.051, 0.052, 0.054, 0.044, 0.024". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values are used: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. Clothes dryer energy use is calculated per the Energy Rating Rated Home in `ANSI/RESNET/ICC 301-2019 Addendum A `_. @@ -4488,8 +4487,8 @@ If not entered, the simulation will not include a dishwasher. RatedAnnualkWh = 215.0 / EF. .. [#] AttachedToWaterHeatingSystem must reference a ``WaterHeatingSystem``; AttachedToHotWaterDistribution must reference a ``HotWaterDistribution``. .. [#] AttachedToWaterHeatingSystem (or AttachedToHotWaterDistribution) only required if IsSharedAppliance is true. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.015, 0.007, 0.005, 0.003, 0.003, 0.010, 0.020, 0.031, 0.058, 0.065, 0.056, 0.048, 0.042, 0.046, 0.036, 0.038, 0.038, 0.049, 0.087, 0.111, 0.090, 0.067, 0.044, 0.031". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values are used: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. If the RatedAnnualkWh or EnergyFactor is provided, a complete set of EnergyGuide label information is entered in ``Dishwasher``. @@ -4534,10 +4533,10 @@ If not entered, the simulation will not include a refrigerator. RatedAnnualkWh = 637.0 + 18.0 * NumberofBedrooms. .. [#] If multiple refrigerators are specified, there must be exactly one refrigerator described with PrimaryIndicator=true. .. [#] Either schedule fraction inputs (WeekdayScheduleFractions/WeekendScheduleFractions/MonthlyScheduleMultipliers) or schedule coefficient inputs (ConstantScheduleCoefficients/TemperatureScheduleCoefficients) may be used, but not both. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` or schedule coefficients not used), default values from Figure 16 of the `2010 BAHSP `_ are used: "0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` or schedule coefficients not used), default values from Figure 24 of the `2010 BAHSP `_ are used: "0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837". - .. [#] If ConstantScheduleCoefficients not provided (and :ref:`schedules_detailed` or schedule fractions not used), default values from Table C.3(2) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "-0.487, -0.340, -0.370, -0.361, -0.515, -0.684, -0.471, -0.159, -0.079, -0.417, -0.411, -0.386, -0.240, -0.314, -0.160, -0.121, -0.469, -0.412, -0.091, 0.077, -0.118, -0.247, -0.445, -0.544". - .. [#] If TemperatureScheduleCoefficients not provided (and :ref:`schedules_detailed` or schedule fractions not used), default values from Table C.3(2) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.019, 0.016, 0.017, 0.016, 0.018, 0.021, 0.019, 0.015, 0.015, 0.019, 0.018, 0.018, 0.016, 0.017, 0.015, 0.015, 0.020, 0.020, 0.017, 0.014, 0.016, 0.017, 0.019, 0.020". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` or schedule coefficients not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` or schedule coefficients not used), then :ref:`schedules_default` are used. + .. [#] If ConstantScheduleCoefficients not provided (and :ref:`schedules_detailed` or schedule fractions not used), then :ref:`schedules_default` are used. + .. [#] If TemperatureScheduleCoefficients not provided (and :ref:`schedules_detailed` or schedule fractions not used), then :ref:`schedules_default` are used. .. note:: @@ -4572,8 +4571,8 @@ If not entered, the simulation will not include a standalone freezer. .. [#] If Location not provided, defaults to "garage" if present, otherwise "basement - unconditioned" if present, otherwise "basement - conditioned" if present, otherwise "conditioned space". .. [#] RatedAnnualkWh default based on the `2010 BAHSP `_. .. [#] Either schedule fraction inputs (WeekdayScheduleFractions/WeekendScheduleFractions/MonthlyScheduleMultipliers) or schedule coefficient inputs (ConstantScheduleCoefficients/TemperatureScheduleCoefficients) may be used, but not both. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` or schedule coefficients not used), default values from Figure 16 of the `2010 BAHSP `_ are used: "0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` or schedule coefficients not used), default values from Figure 24 of the `2010 BAHSP `_ are used: "0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` or schedule coefficients not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` or schedule coefficients not used), then :ref:`schedules_default` are used. .. note:: @@ -4635,8 +4634,8 @@ If not entered, the simulation will not include a cooking range/oven. .. [#] Location choices are "conditioned space", "basement - conditioned", "basement - unconditioned", "garage", "other housing unit", "other heated space", "other multifamily buffer space", or "other non-freezing space". See :ref:`hpxml_locations` for descriptions. .. [#] FuelType choices are "natural gas", "fuel oil", "fuel oil 1", "fuel oil 2", "fuel oil 4", "fuel oil 5/6", "diesel", "propane", "kerosene", "coal", "coke", "bituminous coal", "anthracite coal", "electricity", "wood", or "wood pellets". - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.008, 0.008, 0.008, 0.008, 0.008, 0.015, 0.023, 0.039, 0.046, 0.046, 0.046, 0.054, 0.062, 0.046, 0.039, 0.054, 0.076, 0.134, 0.114, 0.058, 0.039, 0.031, 0.023, 0.015". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values are used: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. If a cooking range is specified, a single oven is also entered as a ``/HPXML/Building/BuildingDetails/Appliances/Oven``. @@ -4684,12 +4683,12 @@ With either lighting specification, additional information can be entered in ``/ ``extension/ExteriorMonthlyScheduleMultipliers`` array No See [#]_ 12 comma-separated exterior monthly multipliers ================================================ ======= ====== =========== ======== ======== =============================================== - .. [#] If InteriorWeekdayScheduleFractions or InteriorWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(3) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.012, 0.010, 0.010, 0.010, 0.011, 0.018, 0.030, 0.038, 0.041, 0.041, 0.039, 0.037, 0.036, 0.035, 0.037, 0.041, 0.050, 0.065, 0.086, 0.106, 0.110, 0.079, 0.040, 0.018". - .. [#] If InteriorMonthlyScheduleMultipliers not provided (or :ref:`schedules_detailed` not used), default values from Table C.3(4) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "1.19, 1.11, 1.02, 0.93, 0.84, 0.80, 0.82, 0.88, 0.98, 1.07, 1.16, 1.20". - .. [#] If GarageWeekdayScheduleFractions or GarageWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(3) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.023, 0.019, 0.015, 0.017, 0.021, 0.031, 0.042, 0.041, 0.034, 0.029, 0.027, 0.025, 0.021, 0.021, 0.021, 0.026, 0.031, 0.044, 0.084, 0.117, 0.113, 0.096, 0.063, 0.039". - .. [#] If GarageMonthlyScheduleMultipliers not provided (or :ref:`schedules_detailed` not used), default values from Table C.3(4) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "1.19, 1.11, 1.02, 0.93, 0.84, 0.80, 0.82, 0.88, 0.98, 1.07, 1.16, 1.20". - .. [#] If ExteriorWeekdayScheduleFractions or ExteriorWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(3) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.040, 0.037, 0.037, 0.035, 0.035, 0.039, 0.044, 0.041, 0.031, 0.025, 0.024, 0.024, 0.025, 0.028, 0.030, 0.035, 0.044, 0.056, 0.064, 0.068, 0.070, 0.065, 0.056, 0.047". - .. [#] If ExteriorMonthlyScheduleMultipliers not provided (or :ref:`schedules_detailed` not used), default values from Table C.3(4) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "1.19, 1.11, 1.02, 0.93, 0.84, 0.80, 0.82, 0.88, 0.98, 1.07, 1.16, 1.20". + .. [#] If InteriorWeekdayScheduleFractions or InteriorWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If InteriorMonthlyScheduleMultipliers not provided (or :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If GarageWeekdayScheduleFractions or GarageWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If GarageMonthlyScheduleMultipliers not provided (or :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If ExteriorWeekdayScheduleFractions or ExteriorWeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If ExteriorMonthlyScheduleMultipliers not provided (or :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. .. _lighting_fractions: @@ -4751,7 +4750,7 @@ If exterior holiday lighting is specified, additional information is entered in =============================== ======= ======= =========== ======== ============= ============================================ .. [#] If Value not provided, defaults to 1.1 for single-family detached and 0.55 for others. - .. [#] If WeekdayScheduleFractions not provided (and :ref:`schedules_detailed` not used), defaults to: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.008, 0.098, 0.168, 0.194, 0.284, 0.192, 0.037, 0.019. + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. HPXML Ceiling Fans ****************** @@ -4773,7 +4772,7 @@ If not entered, the simulation will not include a ceiling fan. .. [#] If Efficiency and LabelEnergyUse not provided, LabelEnergyUse defaults to 42.6 W based on ANSI/RESNET/ICC 301-2022 Addendum C. If both are provided, LabelEnergyUse will be used in the model. .. [#] If Count not provided, defaults to NumberofBedrooms + 1 based on `ANSI/RESNET/ICC 301-2019 `_. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C are used: "0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.024, 0.052, 0.057, 0.057, 0.057, 0.057, 0.057". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), defaults based on monthly average outdoor temperatures per `ANSI/RESNET/ICC 301-2019 `_ Ceiling fan energy use is calculated per the Energy Rating Rated Home in `ANSI/RESNET/ICC 301-2019 `_. @@ -4824,8 +4823,8 @@ If not entered, the simulation will not include a pool pump. If "none" is entered, the simulation will not include a pool pump. .. [#] If Value not provided, defaults based on the `2010 BAHSP `_: 158.5 / 0.070 * (0.5 + 0.25 * NumberofBedrooms / 3 + 0.25 * ConditionedFloorArea / 1920). If NumberofResidents provided, this value will be adjusted using the :ref:`building_occupancy`. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Figure 23 of the `2010 BAHSP `_ are used: "0.003, 0.003, 0.003, 0.004, 0.008, 0.015, 0.026, 0.044, 0.084, 0.121, 0.127, 0.121, 0.120, 0.090, 0.075, 0.061, 0.037, 0.023, 0.013, 0.008, 0.004, 0.003, 0.003, 0.003". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values from Figure 24 of the `2010 BAHSP `_ are used: "1.154, 1.161, 1.013, 1.010, 1.013, 0.888, 0.883, 0.883, 0.888, 0.978, 0.974, 1.154". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. Pool Heater ~~~~~~~~~~~ @@ -4857,8 +4856,8 @@ If not entered, the simulation will not include a pool heater. If NumberofResidents provided, this value will be adjusted using the :ref:`building_occupancy`. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Figure 23 of the `2010 BAHSP `_ are used: "0.003, 0.003, 0.003, 0.004, 0.008, 0.015, 0.026, 0.044, 0.084, 0.121, 0.127, 0.121, 0.120, 0.090, 0.075, 0.061, 0.037, 0.023, 0.013, 0.008, 0.004, 0.003, 0.003, 0.003". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values from Figure 24 of the `2010 BAHSP `_ are used: "1.154, 1.161, 1.013, 1.010, 1.013, 0.888, 0.883, 0.883, 0.888, 0.978, 0.974, 1.154". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. HPXML Permanent Spas ******************** @@ -4898,8 +4897,8 @@ If not entered, the simulation will not include a permanent spa pump. If "none" is entered, the simulation will not include a permanent spa pump. .. [#] If Value not provided, defaults based on the `2010 BAHSP `_: 59.5 / 0.059 * (0.5 + 0.25 * NumberofBedrooms / 3 + 0.25 * ConditionedFloorArea / 1920). If NumberofResidents provided, this value will be adjusted using the :ref:`building_occupancy`. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Figure 23 of the `2010 BAHSP `_ are used: "0.024, 0.029, 0.024, 0.029, 0.047, 0.067, 0.057, 0.024, 0.024, 0.019, 0.015, 0.014, 0.014, 0.014, 0.024, 0.058, 0.126, 0.122, 0.068, 0.061, 0.051, 0.043, 0.024, 0.024". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values from Figure 24 of the `2010 BAHSP `_ are used: "0.921, 0.928, 0.921, 0.915, 0.921, 1.160, 1.158, 1.158, 1.160, 0.921, 0.915, 0.921". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. Permanent Spa Heater ~~~~~~~~~~~~~~~~~~~~ @@ -4931,8 +4930,8 @@ If not entered, the simulation will not include a permanent spa heater. If NumberofResidents provided, this value will be adjusted using the :ref:`building_occupancy`. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Figure 23 of the `2010 BAHSP `_ are used: "0.024, 0.029, 0.024, 0.029, 0.047, 0.067, 0.057, 0.024, 0.024, 0.019, 0.015, 0.014, 0.014, 0.014, 0.024, 0.058, 0.126, 0.122, 0.068, 0.061, 0.051, 0.043, 0.024, 0.024". - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values from Figure 24 of the `2010 BAHSP `_ are used: "0.837, 0.835, 1.084, 1.084, 1.084, 1.096, 1.096, 1.096, 1.096, 0.931, 0.925, 0.837". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. HPXML Misc Loads ---------------- @@ -4999,17 +4998,8 @@ If not entered, the simulation will not include that type of plug load. \- **electric vehicle charging**: 0.0 - .. [#] If WeekdayScheduleFractions or WeekdendScheduleFractions not provided (and :ref:`schedules_detailed` not used), defaults as: - - \- **other**: "0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.038, 0.041, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.044, 0.047, 0.050, 0.051, 0.050, 0.048, 0.044, 0.040, 0.037" (based on Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C) - - \- **TV other**: "0.014, 0.007, 0.004, 0.003, 0.004, 0.006, 0.010, 0.015, 0.020, 0.025, 0.028, 0.031, 0.033, 0.038, 0.042, 0.046, 0.054, 0.062, 0.080, 0.110, 0.132, 0.125, 0.077, 0.034" (based on Table C.3(1) of ANSI/RESNET/ICC 301-2022 Addendum C) - - \- **well pump**: "0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065" (based on Figure 23 of the `2010 BAHSP `_) - - \- **electric vehicle charging**: "0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042, 0.042" - - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values are used: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If WeekdayScheduleFractions or WeekdendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. .. _fuel_loads: @@ -5051,15 +5041,8 @@ If not entered, the simulation will not include that type of fuel load. .. [#] If FracSensible not provided, defaults to 0.5 for fireplace and 0.0 for all other types. .. [#] The remaining fraction (i.e., 1.0 - FracSensible - FracLatent) must be > 0 and is assumed to be heat gain outside conditioned space and thus lost. .. [#] If FracLatent not provided, defaults to 0.1 for fireplace and 0.0 for all other types. - .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), default values from Figure 23 of the `2010 BAHSP `_ are used: - - \- **grill**: "0.004, 0.001, 0.001, 0.002, 0.007, 0.012, 0.029, 0.046, 0.044, 0.041, 0.044, 0.046, 0.042, 0.038, 0.049, 0.059, 0.110, 0.161, 0.115, 0.070, 0.044, 0.019, 0.013, 0.007"; - - \- **fireplace**: "0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065"; - - \- **lighting**: "0.044, 0.023, 0.019, 0.015, 0.016, 0.018, 0.026, 0.033, 0.033, 0.032, 0.033, 0.033, 0.032, 0.032, 0.032, 0.033, 0.045, 0.057, 0.066, 0.076, 0.081, 0.086, 0.075, 0.065". - - .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), default values are used: "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0". + .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. + .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. .. _hpxml_locations: diff --git a/tasks.rb b/tasks.rb index ba21032970..2ab5edb35c 100644 --- a/tasks.rb +++ b/tasks.rb @@ -284,6 +284,8 @@ def apply_hpxml_modification_hers_hot_water(hpxml) end def apply_hpxml_modification_sample_files(hpxml_path, hpxml) + default_schedules_csv_data = HPXMLDefaults.get_default_schedules_csv_data() + # Set detailed HPXML values for sample files hpxml_file = File.basename(hpxml_path) hpxml_bldg = hpxml.buildings[0] @@ -2050,13 +2052,13 @@ def apply_hpxml_modification_sample_files(hpxml_path, hpxml) 'base-schedules-simple.xml', 'base-schedules-simple-vacancy.xml', 'base-schedules-simple-power-outage.xml'].include? hpxml_file - hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekday_fractions = Schedule.RecirculationPumpDemandControlledWeekdayFractions - hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekend_fractions = Schedule.RecirculationPumpDemandControlledWeekendFractions - hpxml_bldg.hot_water_distributions[0].recirculation_pump_monthly_multipliers = Schedule.RecirculationPumpMonthlyMultipliers + hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekday_fractions = default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekdayScheduleFractions'] + hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekend_fractions = default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekendScheduleFractions'] + hpxml_bldg.hot_water_distributions[0].recirculation_pump_monthly_multipliers = default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers'] elsif ['base-bldgtype-mf-unit-shared-water-heater-recirc-scheduled.xml'].include? hpxml_file - hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekday_fractions = Schedule.RecirculationPumpWithoutControlWeekdayFractions - hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekend_fractions = Schedule.RecirculationPumpWithoutControlWeekendFractions - hpxml_bldg.hot_water_distributions[0].recirculation_pump_monthly_multipliers = Schedule.RecirculationPumpMonthlyMultipliers + hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekday_fractions = default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekdayScheduleFractions'] + hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekend_fractions = default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekendScheduleFractions'] + hpxml_bldg.hot_water_distributions[0].recirculation_pump_monthly_multipliers = default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers'] end # -------------------- #