# frozen_string_literal: true # see the URL below for information on how to write OpenStudio measures # http://nrel.github.io/OpenStudio-user-documentation/reference/measure_writing_guide/ require 'openstudio' require 'oga' require 'csv' require_relative 'resources/constants' require_relative 'resources/geometry' require_relative 'resources/schedules' require_relative '../HPXMLtoOpenStudio/resources/constants' require_relative '../HPXMLtoOpenStudio/resources/constructions' require_relative '../HPXMLtoOpenStudio/resources/geometry' require_relative '../HPXMLtoOpenStudio/resources/hpxml' require_relative '../HPXMLtoOpenStudio/resources/hvac' require_relative '../HPXMLtoOpenStudio/resources/lighting' require_relative '../HPXMLtoOpenStudio/resources/location' require_relative '../HPXMLtoOpenStudio/resources/materials' require_relative '../HPXMLtoOpenStudio/resources/meta_measure' require_relative '../HPXMLtoOpenStudio/resources/psychrometrics' require_relative '../HPXMLtoOpenStudio/resources/schedules' require_relative '../HPXMLtoOpenStudio/resources/unit_conversions' require_relative '../HPXMLtoOpenStudio/resources/validator' require_relative '../HPXMLtoOpenStudio/resources/version' require_relative '../HPXMLtoOpenStudio/resources/xmlhelper' # start the measure class BuildResidentialHPXML < OpenStudio::Measure::ModelMeasure # human readable name def name return 'HPXML Builder' end # human readable description def description return 'Builds a residential HPXML file.' end # human readable description of modeling approach def modeler_description return '' end # define the arguments that the user will input def arguments(model) args = OpenStudio::Measure::OSArgumentVector.new arg = OpenStudio::Measure::OSArgument.makeStringArgument('hpxml_path', true) arg.setDisplayName('HPXML File Path') arg.setDescription('Absolute/relative path of the HPXML file.') args << arg arg = OpenStudio::Measure::OSArgument.makeStringArgument('software_program_used', false) arg.setDisplayName('Software Program Used') arg.setDescription('The name of the software program used.') args << arg arg = OpenStudio::Measure::OSArgument.makeStringArgument('software_program_version', false) arg.setDisplayName('Software Program Version') arg.setDescription('The version of the software program used.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('simulation_control_timestep', false) arg.setDisplayName('Simulation Control: Timestep') arg.setUnits('min') arg.setDescription('Value must be a divisor of 60.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('simulation_control_run_period_begin_month', false) arg.setDisplayName('Simulation Control: Run Period Begin Month') arg.setUnits('#') arg.setDescription('This numeric field should contain the starting month number (1 = January, 2 = February, etc.) for the annual run period desired.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('simulation_control_run_period_begin_day_of_month', false) arg.setDisplayName('Simulation Control: Run Period Begin Day of Month') arg.setUnits('#') arg.setDescription('This numeric field should contain the starting day of the starting month (must be valid for month) for the annual run period desired.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('simulation_control_run_period_end_month', false) arg.setDisplayName('Simulation Control: Run Period End Month') arg.setUnits('#') arg.setDescription('This numeric field should contain the end month number (1 = January, 2 = February, etc.) for the annual run period desired.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('simulation_control_run_period_end_day_of_month', false) arg.setDisplayName('Simulation Control: Run Period End Day of Month') arg.setUnits('#') arg.setDescription('This numeric field should contain the ending day of the ending month (must be valid for month) for the annual run period desired.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('simulation_control_run_period_calendar_year', false) arg.setDisplayName('Simulation Control: Run Period Calendar Year') arg.setUnits('year') arg.setDescription('This numeric field should contain the calendar year that determines the start day of week. If you are running simulations using AMY weather files, the value entered for calendar year will not be used; it will be overridden by the actual year found in the AMY weather file.') args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('simulation_control_daylight_saving_enabled', false) arg.setDisplayName('Simulation Control: Daylight Saving Enabled') arg.setDescription('Whether to use daylight saving.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('simulation_control_daylight_saving_begin_month', false) arg.setDisplayName('Simulation Control: Daylight Saving Begin Month') arg.setUnits('#') arg.setDescription('This numeric field should contain the starting month number (1 = January, 2 = February, etc.) for the annual daylight saving period desired.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('simulation_control_daylight_saving_begin_day_of_month', false) arg.setDisplayName('Simulation Control: Daylight Saving Begin Day of Month') arg.setUnits('#') arg.setDescription('This numeric field should contain the starting day of the starting month (must be valid for month) for the daylight saving period desired.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('simulation_control_daylight_saving_end_month', false) arg.setDisplayName('Simulation Control: Daylight Saving End Month') arg.setUnits('#') arg.setDescription('This numeric field should contain the end month number (1 = January, 2 = February, etc.) for the daylight saving period desired.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('simulation_control_daylight_saving_end_day_of_month', false) arg.setDisplayName('Simulation Control: Daylight Saving End Day of Month') arg.setUnits('#') arg.setDescription('This numeric field should contain the ending day of the ending month (must be valid for month) for the daylight saving period desired.') args << arg schedules_type_choices = OpenStudio::StringVector.new schedules_type_choices << 'default' schedules_type_choices << 'stochastic' schedules_type_choices << 'user-specified' arg = OpenStudio::Measure::OSArgument.makeChoiceArgument('schedules_type', schedules_type_choices, true) arg.setDisplayName('Schedules: Type') arg.setDescription("The type of occupant-related schedules to use. Schedules corresponding to 'default' are average (e.g., Building America). Schedules corresponding to 'stochastic' are generated using time-inhomogeneous Markov chains derived from American Time Use Survey data, and supplemented with sampling duration and power level from NEEA RBSA data as well as DHW draw duration and flow rate from Aquacraft/AWWA data.") arg.setDefaultValue('default') args << arg arg = OpenStudio::Measure::OSArgument.makeStringArgument('schedules_path', false) arg.setDisplayName('Schedules: Path') arg.setDescription('Absolute (or relative) path of the csv file containing user-specified occupancy schedules.') args << arg arg = OpenStudio::Measure::OSArgument.makeIntegerArgument('schedules_vacancy_begin_month', false) arg.setDisplayName('Schedules: Vacancy Start Begin Month') arg.setUnits('#') arg.setDescription("This numeric field should contain the starting month number (1 = January, 2 = February, etc.) for the vacancy period desired. Only applies if the schedules type is 'stochastic'.") args << arg arg = OpenStudio::Measure::OSArgument.makeIntegerArgument('schedules_vacancy_begin_day_of_month', false) arg.setDisplayName('Schedules: Vacancy Begin Day of Month') arg.setUnits('#') arg.setDescription("This numeric field should contain the starting day of the starting month (must be valid for month) for the vacancy period desired. Only applies if the schedules type is 'stochastic'.") args << arg arg = OpenStudio::Measure::OSArgument.makeIntegerArgument('schedules_vacancy_end_month', false) arg.setDisplayName('Schedules: Vacancy Start End Month') arg.setUnits('#') arg.setDescription("This numeric field should contain the end month number (1 = January, 2 = February, etc.) for the vacancy period desired. Only applies if the schedules type is 'stochastic'.") args << arg arg = OpenStudio::Measure::OSArgument.makeIntegerArgument('schedules_vacancy_end_day_of_month', false) arg.setDisplayName('Schedules: Vacancy End Day of Month') arg.setUnits('#') arg.setDescription("This numeric field should contain the ending day of the ending month (must be valid for month) for the vacancy period desired. Only applies if the schedules type is 'stochastic'.") args << arg arg = OpenStudio::Measure::OSArgument.makeIntegerArgument('schedules_random_seed', false) arg.setDisplayName('Schedules: Random Seed') arg.setUnits('#') arg.setDescription("This numeric field is the seed for the random number generator. Only applies if the schedules type is 'stochastic'.") args << arg arg = OpenStudio::Measure::OSArgument.makeStringArgument('weather_station_epw_filepath', true) arg.setDisplayName('EnergyPlus Weather (EPW) Filepath') arg.setDescription('Path of the EPW file.') arg.setDefaultValue('USA_CO_Denver.Intl.AP.725650_TMY3.epw') args << arg site_type_choices = OpenStudio::StringVector.new site_type_choices << HPXML::SiteTypeSuburban site_type_choices << HPXML::SiteTypeUrban site_type_choices << HPXML::SiteTypeRural arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('site_type', site_type_choices, false) arg.setDisplayName('Site: Type') arg.setDescription('The type of site.') args << arg unit_type_choices = OpenStudio::StringVector.new unit_type_choices << HPXML::ResidentialTypeSFD unit_type_choices << HPXML::ResidentialTypeSFA unit_type_choices << HPXML::ResidentialTypeApartment arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geometry_unit_type', unit_type_choices, true) arg.setDisplayName('Geometry: Unit Type') arg.setDescription('The type of unit.') arg.setDefaultValue(HPXML::ResidentialTypeSFD) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_cfa', true) arg.setDisplayName('Geometry: Conditioned Floor Area') arg.setUnits('ft^2') arg.setDescription('The total floor area of the conditioned space (including any conditioned basement floor area).') arg.setDefaultValue(2000.0) args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('geometry_num_floors_above_grade', true) arg.setDisplayName('Geometry: Number of Floors') arg.setUnits('#') arg.setDescription("The number of floors above grade (in the unit if #{HPXML::ResidentialTypeSFD} or #{HPXML::ResidentialTypeSFA}, and in the building if #{HPXML::ResidentialTypeApartment}). Conditioned attics are included.") arg.setDefaultValue(2) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_wall_height', true) arg.setDisplayName('Geometry: Average Wall Height') arg.setUnits('ft') arg.setDescription('The average height of the walls.') arg.setDefaultValue(8.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_orientation', true) arg.setDisplayName('Geometry: Orientation') arg.setUnits('degrees') arg.setDescription("The unit's orientation is measured clockwise from due south when viewed from above (e.g., North=0, East=90, South=180, West=270).") arg.setDefaultValue(180.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_aspect_ratio', true) arg.setDisplayName('Geometry: Aspect Ratio') arg.setUnits('FB/LR') arg.setDescription('The ratio of the front/back wall length to the left/right wall length, excluding any protruding garage wall area.') arg.setDefaultValue(2.0) args << arg corridor_position_choices = OpenStudio::StringVector.new corridor_position_choices << 'Double-Loaded Interior' corridor_position_choices << 'Single Exterior (Front)' corridor_position_choices << 'Double Exterior' corridor_position_choices << 'None' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geometry_corridor_position', corridor_position_choices, true) arg.setDisplayName('Geometry: Corridor Position') arg.setDescription("The position of the corridor. Only applies to #{HPXML::ResidentialTypeSFA} and #{HPXML::ResidentialTypeApartment} units. Exterior corridors are shaded, but not enclosed. Interior corridors are enclosed and conditioned.") arg.setDefaultValue('Double-Loaded Interior') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_corridor_width', true) arg.setDisplayName('Geometry: Corridor Width') arg.setUnits('ft') arg.setDescription("The width of the corridor. Only applies to #{HPXML::ResidentialTypeApartment} units.") arg.setDefaultValue(10.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_inset_width', true) arg.setDisplayName('Geometry: Inset Width') arg.setUnits('ft') arg.setDescription("The width of the inset. Only applies to #{HPXML::ResidentialTypeApartment} units.") arg.setDefaultValue(0.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_inset_depth', true) arg.setDisplayName('Geometry: Inset Depth') arg.setUnits('ft') arg.setDescription("The depth of the inset. Only applies to #{HPXML::ResidentialTypeApartment} units.") arg.setDefaultValue(0.0) args << arg inset_position_choices = OpenStudio::StringVector.new inset_position_choices << 'Right' inset_position_choices << 'Left' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geometry_inset_position', inset_position_choices, true) arg.setDisplayName('Geometry: Inset Position') arg.setDescription("The position of the inset. Only applies to #{HPXML::ResidentialTypeApartment} units.") arg.setDefaultValue('Right') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_balcony_depth', true) arg.setDisplayName('Geometry: Balcony Depth') arg.setUnits('ft') arg.setDescription("The depth of the balcony. Only applies to #{HPXML::ResidentialTypeApartment} units.") arg.setDefaultValue(0.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_garage_width', true) arg.setDisplayName('Geometry: Garage Width') arg.setUnits('ft') arg.setDescription("The width of the garage. Enter zero for no garage. Only applies to #{HPXML::ResidentialTypeSFD} units.") arg.setDefaultValue(0.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_garage_depth', true) arg.setDisplayName('Geometry: Garage Depth') arg.setUnits('ft') arg.setDescription("The depth of the garage. Only applies to #{HPXML::ResidentialTypeSFD} units.") arg.setDefaultValue(20.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_garage_protrusion', true) arg.setDisplayName('Geometry: Garage Protrusion') arg.setUnits('frac') arg.setDescription("The fraction of the garage that is protruding from the living space. Only applies to #{HPXML::ResidentialTypeSFD} units.") arg.setDefaultValue(0.0) args << arg garage_position_choices = OpenStudio::StringVector.new garage_position_choices << 'Right' garage_position_choices << 'Left' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geometry_garage_position', garage_position_choices, true) arg.setDisplayName('Geometry: Garage Position') arg.setDescription("The position of the garage. Only applies to #{HPXML::ResidentialTypeSFD} units.") arg.setDefaultValue('Right') args << arg foundation_type_choices = OpenStudio::StringVector.new foundation_type_choices << HPXML::FoundationTypeSlab foundation_type_choices << HPXML::FoundationTypeCrawlspaceVented foundation_type_choices << HPXML::FoundationTypeCrawlspaceUnvented foundation_type_choices << HPXML::FoundationTypeBasementUnconditioned foundation_type_choices << HPXML::FoundationTypeBasementConditioned foundation_type_choices << HPXML::FoundationTypeAmbient arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geometry_foundation_type', foundation_type_choices, true) arg.setDisplayName('Geometry: Foundation Type') arg.setDescription('The foundation type of the building.') arg.setDefaultValue(HPXML::FoundationTypeSlab) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_foundation_height', true) arg.setDisplayName('Geometry: Foundation Height') arg.setUnits('ft') arg.setDescription('The height of the foundation (e.g., 3ft for crawlspace, 8ft for basement). Only applies to basements/crawlspaces.') arg.setDefaultValue(0.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_foundation_height_above_grade', true) arg.setDisplayName('Geometry: Foundation Height Above Grade') arg.setUnits('ft') arg.setDescription('The depth above grade of the foundation wall. Only applies to basements/crawlspaces.') arg.setDefaultValue(0.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_rim_joist_height', true) arg.setDisplayName('Geometry: Rim Joist Height') arg.setUnits('in') arg.setDescription('The height of the rim joists. Only applies to basements/crawlspaces.') arg.setDefaultValue(9.25) args << arg roof_type_choices = OpenStudio::StringVector.new roof_type_choices << 'gable' roof_type_choices << 'hip' roof_type_choices << 'flat' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geometry_roof_type', roof_type_choices, true) arg.setDisplayName('Geometry: Roof Type') arg.setDescription("The roof type of the building. Assumed flat for #{HPXML::ResidentialTypeApartment} units.") arg.setDefaultValue('gable') args << arg roof_pitch_choices = OpenStudio::StringVector.new roof_pitch_choices << '1:12' roof_pitch_choices << '2:12' roof_pitch_choices << '3:12' roof_pitch_choices << '4:12' roof_pitch_choices << '5:12' roof_pitch_choices << '6:12' roof_pitch_choices << '7:12' roof_pitch_choices << '8:12' roof_pitch_choices << '9:12' roof_pitch_choices << '10:12' roof_pitch_choices << '11:12' roof_pitch_choices << '12:12' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geometry_roof_pitch', roof_pitch_choices, true) arg.setDisplayName('Geometry: Roof Pitch') arg.setDescription('The roof pitch of the attic. Ignored if the building has a flat roof.') arg.setDefaultValue('6:12') args << arg attic_type_choices = OpenStudio::StringVector.new attic_type_choices << HPXML::AtticTypeVented attic_type_choices << HPXML::AtticTypeUnvented attic_type_choices << HPXML::AtticTypeConditioned arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geometry_attic_type', attic_type_choices, true) arg.setDisplayName('Geometry: Attic Type') arg.setDescription('The attic type of the building. Ignored if the building has a flat roof.') arg.setDefaultValue(HPXML::AtticTypeVented) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_eaves_depth', true) arg.setDisplayName('Geometry: Eaves Depth') arg.setUnits('ft') arg.setDescription('The eaves depth of the roof.') arg.setDefaultValue(2.0) args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('geometry_num_bedrooms', true) arg.setDisplayName('Geometry: Number of Bedrooms') arg.setUnits('#') arg.setDescription('Specify the number of bedrooms. Used to determine the energy usage of appliances and plug loads, hot water usage, etc.') arg.setDefaultValue(3) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('geometry_num_bathrooms', true) arg.setDisplayName('Geometry: Number of Bathrooms') arg.setUnits('#') arg.setDescription('Specify the number of bathrooms.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('geometry_num_occupants', true) arg.setDisplayName('Geometry: Number of Occupants') arg.setUnits('#') arg.setDescription("Specify the number of occupants. A value of '#{Constants.Auto}' will calculate the average number of occupants from the number of bedrooms. Used to specify the internal gains from people only.") arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('geometry_has_flue_or_chimney', true) arg.setDisplayName('Geometry: Has Flue or Chimney') arg.setDescription('Whether there is a flue or chimney.') arg.setDefaultValue(Constants.Auto) args << arg level_choices = OpenStudio::StringVector.new level_choices << 'Bottom' level_choices << 'Middle' level_choices << 'Top' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geometry_level', level_choices, false) arg.setDisplayName('Geometry: Level') arg.setDescription("The level of the #{HPXML::ResidentialTypeApartment} unit.") args << arg horizontal_location_choices = OpenStudio::StringVector.new horizontal_location_choices << 'Left' horizontal_location_choices << 'Middle' horizontal_location_choices << 'Right' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geometry_horizontal_location', horizontal_location_choices, false) arg.setDisplayName('Geometry: Horizontal Location') arg.setDescription("The horizontal location of the #{HPXML::ResidentialTypeSFA} or #{HPXML::ResidentialTypeApartment} unit when viewing the front of the building.") args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('geometry_building_num_units', false) arg.setDisplayName('Geometry: Building Number of Units') arg.setUnits('#') arg.setDescription("The number of units in the building. This is required for #{HPXML::ResidentialTypeSFA} and #{HPXML::ResidentialTypeApartment} units.") args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('geometry_building_num_bedrooms', false) arg.setDisplayName('Geometry: Building Number of Bedrooms') arg.setUnits('#') arg.setDescription("The number of bedrooms in the building. This is required for #{HPXML::ResidentialTypeSFA} and #{HPXML::ResidentialTypeApartment} units with shared PV systems.") args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('floor_assembly_r', true) arg.setDisplayName('Floor: Assembly R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('Assembly R-value for the floor (foundation ceiling). Ignored if the building has a slab foundation.') arg.setDefaultValue(30) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('foundation_wall_insulation_r', true) arg.setDisplayName('Foundation: Wall Insulation Nominal R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('Nominal R-value for the foundation wall insulation. Only applies to basements/crawlspaces.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('foundation_wall_insulation_distance_to_top', true) arg.setDisplayName('Foundation: Wall Insulation Distance To Top') arg.setUnits('ft') arg.setDescription('The distance from the top of the foundation wall to the top of the foundation wall insulation. Only applies to basements/crawlspaces.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('foundation_wall_insulation_distance_to_bottom', true) arg.setDisplayName('Foundation: Wall Insulation Distance To Bottom') arg.setUnits('ft') arg.setDescription("The distance from the top of the foundation wall to the bottom of the foundation wall insulation. Only applies to basements/crawlspaces. A value of '#{Constants.Auto}' will use the same height as the foundation.") arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('foundation_wall_assembly_r', false) arg.setDisplayName('Foundation: Wall Assembly R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('Assembly R-value for the foundation walls. Only applies to basements/crawlspaces. If provided, overrides the previous foundation wall insulation inputs.') args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('foundation_wall_thickness', true) arg.setDisplayName('Foundation: Wall Thickness') arg.setDescription('The thickness of the foundation wall.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('rim_joist_assembly_r', true) arg.setDisplayName('Rim Joist: Assembly R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('Assembly R-value for the rim joists. Only applies to basements/crawlspaces.') arg.setDefaultValue(23) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('slab_perimeter_insulation_r', true) arg.setDisplayName('Slab: Perimeter Insulation Nominal R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('Nominal R-value of the vertical slab perimeter insulation. Applies to slab-on-grade foundations and basement/crawlspace floors.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('slab_perimeter_depth', true) arg.setDisplayName('Slab: Perimeter Insulation Depth') arg.setUnits('ft') arg.setDescription('Depth from grade to bottom of vertical slab perimeter insulation. Applies to slab-on-grade foundations and basement/crawlspace floors.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('slab_under_insulation_r', true) arg.setDisplayName('Slab: Under Slab Insulation Nominal R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('Nominal R-value of the horizontal under slab insulation. Applies to slab-on-grade foundations and basement/crawlspace floors.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('slab_under_width', true) arg.setDisplayName('Slab: Under Slab Insulation Width') arg.setUnits('ft') arg.setDescription('Width from slab edge inward of horizontal under-slab insulation. Enter 999 to specify that the under slab insulation spans the entire slab. Applies to slab-on-grade foundations and basement/crawlspace floors.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('slab_thickness', true) arg.setDisplayName('Slab: Thickness') arg.setDescription('The thickness of the slab.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('slab_carpet_fraction', true) arg.setDisplayName('Slab: Carpet Fraction') arg.setUnits('Frac') arg.setDescription('Fraction of the slab floor area that is carpeted.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('slab_carpet_r', true) arg.setDisplayName('Slab: Carpet R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('R-value of the slab carpet.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ceiling_assembly_r', true) arg.setDisplayName('Ceiling: Assembly R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('Assembly R-value for the ceiling (attic floor).') arg.setDefaultValue(30) args << arg roof_material_type_choices = OpenStudio::StringVector.new roof_material_type_choices << HPXML::RoofTypeAsphaltShingles roof_material_type_choices << HPXML::RoofTypeConcrete roof_material_type_choices << HPXML::RoofTypeClayTile roof_material_type_choices << HPXML::RoofTypeMetal roof_material_type_choices << HPXML::RoofTypePlasticRubber roof_material_type_choices << HPXML::RoofTypeWoodShingles arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('roof_material_type', roof_material_type_choices, false) arg.setDisplayName('Roof: Material Type') arg.setDescription('The material type of the roof.') args << arg color_choices = OpenStudio::StringVector.new color_choices << HPXML::ColorDark color_choices << HPXML::ColorLight color_choices << HPXML::ColorMedium color_choices << HPXML::ColorMediumDark color_choices << HPXML::ColorReflective arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('roof_color', color_choices, true) arg.setDisplayName('Roof: Color') arg.setDescription('The color of the roof.') arg.setDefaultValue(HPXML::ColorMedium) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('roof_assembly_r', true) arg.setDisplayName('Roof: Assembly R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('Assembly R-value of the roof.') arg.setDefaultValue(2.3) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('roof_radiant_barrier', true) arg.setDisplayName('Roof: Has Radiant Barrier') arg.setDescription('Specifies whether the attic has a radiant barrier.') arg.setDefaultValue(false) args << arg roof_radiant_barrier_grade_choices = OpenStudio::StringVector.new roof_radiant_barrier_grade_choices << '1' roof_radiant_barrier_grade_choices << '2' roof_radiant_barrier_grade_choices << '3' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('roof_radiant_barrier_grade', roof_radiant_barrier_grade_choices, true) arg.setDisplayName('Roof: Radiant Barrier Grade') arg.setDescription('The grade of the radiant barrier, if it exists.') arg.setDefaultValue('1') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('neighbor_front_distance', true) arg.setDisplayName('Neighbor: Front Distance') arg.setUnits('ft') arg.setDescription('The minimum distance between the simulated unit and the neighboring building to the front (not including eaves). A value of zero indicates no neighbors.') arg.setDefaultValue(0.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('neighbor_back_distance', true) arg.setDisplayName('Neighbor: Back Distance') arg.setUnits('ft') arg.setDescription('The minimum distance between the simulated unit and the neighboring building to the back (not including eaves). A value of zero indicates no neighbors.') arg.setDefaultValue(0.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('neighbor_left_distance', true) arg.setDisplayName('Neighbor: Left Distance') arg.setUnits('ft') arg.setDescription('The minimum distance between the simulated unit and the neighboring building to the left (not including eaves). A value of zero indicates no neighbors.') arg.setDefaultValue(10.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('neighbor_right_distance', true) arg.setDisplayName('Neighbor: Right Distance') arg.setUnits('ft') arg.setDescription('The minimum distance between the simulated unit and the neighboring building to the right (not including eaves). A value of zero indicates no neighbors.') arg.setDefaultValue(10.0) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('neighbor_front_height', true) arg.setDisplayName('Neighbor: Front Height') arg.setUnits('ft') arg.setDescription("The height of the neighboring building to the front. A value of '#{Constants.Auto}' will use the same height as this building.") arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('neighbor_back_height', true) arg.setDisplayName('Neighbor: Back Height') arg.setUnits('ft') arg.setDescription("The height of the neighboring building to the back. A value of '#{Constants.Auto}' will use the same height as this building.") arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('neighbor_left_height', true) arg.setDisplayName('Neighbor: Left Height') arg.setUnits('ft') arg.setDescription("The height of the neighboring building to the left. A value of '#{Constants.Auto}' will use the same height as this building.") arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('neighbor_right_height', true) arg.setDisplayName('Neighbor: Right Height') arg.setUnits('ft') arg.setDescription("The height of the neighboring building to the right. A value of '#{Constants.Auto}' will use the same height as this building.") arg.setDefaultValue(Constants.Auto) args << arg wall_type_choices = OpenStudio::StringVector.new wall_type_choices << HPXML::WallTypeWoodStud wall_type_choices << HPXML::WallTypeCMU wall_type_choices << HPXML::WallTypeDoubleWoodStud wall_type_choices << HPXML::WallTypeICF wall_type_choices << HPXML::WallTypeLog wall_type_choices << HPXML::WallTypeSIP wall_type_choices << HPXML::WallTypeConcrete wall_type_choices << HPXML::WallTypeSteelStud wall_type_choices << HPXML::WallTypeStone wall_type_choices << HPXML::WallTypeStrawBale wall_type_choices << HPXML::WallTypeBrick arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('wall_type', wall_type_choices, true) arg.setDisplayName('Walls: Type') arg.setDescription('The type of exterior walls.') arg.setDefaultValue(HPXML::WallTypeWoodStud) args << arg wall_siding_type_choices = OpenStudio::StringVector.new wall_siding_type_choices << HPXML::SidingTypeAluminum wall_siding_type_choices << HPXML::SidingTypeBrick wall_siding_type_choices << HPXML::SidingTypeFiberCement wall_siding_type_choices << HPXML::SidingTypeStucco wall_siding_type_choices << HPXML::SidingTypeVinyl wall_siding_type_choices << HPXML::SidingTypeWood arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('wall_siding_type', wall_siding_type_choices, false) arg.setDisplayName('Wall: Siding Type') arg.setDescription('The siding type of the exterior walls. Also applies to rim joists.') args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('wall_color', color_choices, true) arg.setDisplayName('Wall: Color') arg.setDescription('The color of the exterior walls. Also applies to rim joists.') arg.setDefaultValue(HPXML::ColorMedium) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('wall_assembly_r', true) arg.setDisplayName('Walls: Assembly R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('Assembly R-value of the exterior walls.') arg.setDefaultValue(13) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_front_wwr', true) arg.setDisplayName('Windows: Front Window-to-Wall Ratio') arg.setDescription("The ratio of window area to wall area for the unit's front facade. Enter 0 if specifying Front Window Area instead.") arg.setDefaultValue(0.18) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_back_wwr', true) arg.setDisplayName('Windows: Back Window-to-Wall Ratio') arg.setDescription("The ratio of window area to wall area for the unit's back facade. Enter 0 if specifying Back Window Area instead.") arg.setDefaultValue(0.18) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_left_wwr', true) arg.setDisplayName('Windows: Left Window-to-Wall Ratio') arg.setDescription("The ratio of window area to wall area for the unit's left facade (when viewed from the front). Enter 0 if specifying Left Window Area instead.") arg.setDefaultValue(0.18) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_right_wwr', true) arg.setDisplayName('Windows: Right Window-to-Wall Ratio') arg.setDescription("The ratio of window area to wall area for the unit's right facade (when viewed from the front). Enter 0 if specifying Right Window Area instead.") arg.setDefaultValue(0.18) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_area_front', true) arg.setDisplayName('Windows: Front Window Area') arg.setDescription("The amount of window area on the unit's front facade. Enter 0 if specifying Front Window-to-Wall Ratio instead.") arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_area_back', true) arg.setDisplayName('Windows: Back Window Area') arg.setDescription("The amount of window area on the unit's back facade. Enter 0 if specifying Back Window-to-Wall Ratio instead.") arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_area_left', true) arg.setDisplayName('Windows: Left Window Area') arg.setDescription("The amount of window area on the unit's left facade (when viewed from the front). Enter 0 if specifying Left Window-to-Wall Ratio instead.") arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_area_right', true) arg.setDisplayName('Windows: Right Window Area') arg.setDescription("The amount of window area on the unit's right facade (when viewed from the front). Enter 0 if specifying Right Window-to-Wall Ratio instead.") arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_aspect_ratio', true) arg.setDisplayName('Windows: Aspect Ratio') arg.setDescription('Ratio of window height to width.') arg.setDefaultValue(1.333) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_fraction_operable', false) arg.setDisplayName('Windows: Fraction Operable') arg.setDescription('Fraction of windows that are operable.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_ufactor', true) arg.setDisplayName('Windows: U-Factor') arg.setUnits('Btu/hr-ft^2-R') arg.setDescription('The heat transfer coefficient of the windows.') arg.setDefaultValue(0.37) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_shgc', true) arg.setDisplayName('Windows: SHGC') arg.setDescription('The ratio of solar heat gain through a glazing system compared to that of an unobstructed opening, for windows.') arg.setDefaultValue(0.3) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_interior_shading_winter', false) arg.setDisplayName('Windows: Winter Interior Shading') arg.setDescription('Interior shading multiplier for the heating season. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_interior_shading_summer', false) arg.setDisplayName('Windows: Summer Interior Shading') arg.setDescription('Interior shading multiplier for the cooling season. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_exterior_shading_winter', false) arg.setDisplayName('Windows: Winter Exterior Shading') arg.setDescription('Exterior shading multiplier for the heating season. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('window_exterior_shading_summer', false) arg.setDisplayName('Windows: Summer Exterior Shading') arg.setDescription('Exterior shading multiplier for the cooling season. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('overhangs_front_depth', true) arg.setDisplayName('Overhangs: Front Facade Depth') arg.setDescription('Specifies the depth of overhangs for windows on the front facade.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('overhangs_front_distance_to_top_of_window', true) arg.setDisplayName('Overhangs: Front Facade Distance to Top of Window') arg.setDescription('Specifies the distance to the top of window of overhangs for windows on the front facade.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('overhangs_back_depth', true) arg.setDisplayName('Overhangs: Back Facade Depth') arg.setDescription('Specifies the depth of overhangs for windows on the back facade.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('overhangs_back_distance_to_top_of_window', true) arg.setDisplayName('Overhangs: Back Facade Distance to Top of Window') arg.setDescription('Specifies the distance to the top of window of overhangs for windows on the back facade.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('overhangs_left_depth', true) arg.setDisplayName('Overhangs: Left Facade Depth') arg.setDescription('Specifies the depth of overhangs for windows on the left facade.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('overhangs_left_distance_to_top_of_window', true) arg.setDisplayName('Overhangs: Left Facade Distance to Top of Window') arg.setDescription('Specifies the distance to the top of window of overhangs for windows on the left facade.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('overhangs_right_depth', true) arg.setDisplayName('Overhangs: Right Facade Depth') arg.setDescription('Specifies the depth of overhangs for windows on the right facade.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('overhangs_right_distance_to_top_of_window', true) arg.setDisplayName('Overhangs: Right Facade Distance to Top of Window') arg.setDescription('Specifies the distance to the top of window of overhangs for windows on the right facade.') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('skylight_area_front', true) arg.setDisplayName('Skylights: Front Roof Area') arg.setDescription("The amount of skylight area on the unit's front conditioned roof facade.") arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('skylight_area_back', true) arg.setDisplayName('Skylights: Back Roof Area') arg.setDescription("The amount of skylight area on the unit's back conditioned roof facade.") arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('skylight_area_left', true) arg.setDisplayName('Skylights: Left Roof Area') arg.setDescription("The amount of skylight area on the unit's left conditioned roof facade (when viewed from the front).") arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('skylight_area_right', true) arg.setDisplayName('Skylights: Right Roof Area') arg.setDescription("The amount of skylight area on the unit's right conditioned roof facade (when viewed from the front).") arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('skylight_ufactor', true) arg.setDisplayName('Skylights: U-Factor') arg.setUnits('Btu/hr-ft^2-R') arg.setDescription('The heat transfer coefficient of the skylights.') arg.setDefaultValue(0.33) args << arg skylight_shgc = OpenStudio::Measure::OSArgument::makeDoubleArgument('skylight_shgc', true) skylight_shgc.setDisplayName('Skylights: SHGC') skylight_shgc.setDescription('The ratio of solar heat gain through a glazing system compared to that of an unobstructed opening, for skylights.') skylight_shgc.setDefaultValue(0.45) args << skylight_shgc arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('door_area', true) arg.setDisplayName('Doors: Area') arg.setUnits('ft^2') arg.setDescription('The area of the opaque door(s).') arg.setDefaultValue(20.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('door_rvalue', true) arg.setDisplayName('Doors: R-value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('R-value of the doors.') arg.setDefaultValue(5.0) args << arg air_leakage_units_choices = OpenStudio::StringVector.new air_leakage_units_choices << HPXML::UnitsACH air_leakage_units_choices << HPXML::UnitsCFM air_leakage_units_choices << HPXML::UnitsACHNatural arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('air_leakage_units', air_leakage_units_choices, true) arg.setDisplayName('Air Leakage: Units') arg.setDescription('The unit of measure for the above-grade living air leakage.') arg.setDefaultValue(HPXML::UnitsACH) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('air_leakage_house_pressure', true) arg.setDisplayName('Air Leakage: House Pressure') arg.setUnits('Pa') arg.setDescription("The pressure of the house for the above-grade living air leakage when the air leakage units are #{HPXML::UnitsACH} or #{HPXML::UnitsCFM}.") arg.setDefaultValue(50) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('air_leakage_value', true) arg.setDisplayName('Air Leakage: Value') arg.setDescription('Air exchange rate, in ACH or CFM at the specified house pressure.') arg.setDefaultValue(3) args << arg air_leakage_shielding_of_home_choices = OpenStudio::StringVector.new air_leakage_shielding_of_home_choices << Constants.Auto air_leakage_shielding_of_home_choices << HPXML::ShieldingExposed air_leakage_shielding_of_home_choices << HPXML::ShieldingNormal air_leakage_shielding_of_home_choices << HPXML::ShieldingWellShielded arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('air_leakage_shielding_of_home', air_leakage_shielding_of_home_choices, true) arg.setDisplayName('Air Leakage: Shielding of Home') arg.setDescription('Presence of nearby buildings, trees, obstructions for infiltration model.') arg.setDefaultValue(Constants.Auto) args << arg heating_system_type_choices = OpenStudio::StringVector.new heating_system_type_choices << 'none' heating_system_type_choices << HPXML::HVACTypeFurnace heating_system_type_choices << HPXML::HVACTypeWallFurnace heating_system_type_choices << HPXML::HVACTypeFloorFurnace heating_system_type_choices << HPXML::HVACTypeBoiler heating_system_type_choices << HPXML::HVACTypeElectricResistance heating_system_type_choices << HPXML::HVACTypeStove heating_system_type_choices << HPXML::HVACTypePortableHeater heating_system_type_choices << HPXML::HVACTypeFireplace heating_system_type_choices << HPXML::HVACTypeFixedHeater heating_system_type_choices << "Shared #{HPXML::HVACTypeBoiler} w/ Baseboard" heating_system_type_choices << "Shared #{HPXML::HVACTypeBoiler} w/ Ductless Fan Coil" heating_system_fuel_choices = OpenStudio::StringVector.new heating_system_fuel_choices << HPXML::FuelTypeElectricity heating_system_fuel_choices << HPXML::FuelTypeNaturalGas heating_system_fuel_choices << HPXML::FuelTypeOil heating_system_fuel_choices << HPXML::FuelTypePropane heating_system_fuel_choices << HPXML::FuelTypeWoodCord heating_system_fuel_choices << HPXML::FuelTypeWoodPellets heating_system_fuel_choices << HPXML::FuelTypeCoal cooling_system_type_choices = OpenStudio::StringVector.new cooling_system_type_choices << 'none' cooling_system_type_choices << HPXML::HVACTypeCentralAirConditioner cooling_system_type_choices << HPXML::HVACTypeRoomAirConditioner cooling_system_type_choices << HPXML::HVACTypeEvaporativeCooler cooling_system_type_choices << HPXML::HVACTypeMiniSplitAirConditioner cooling_efficiency_type_choices = OpenStudio::StringVector.new cooling_efficiency_type_choices << HPXML::UnitsSEER cooling_efficiency_type_choices << HPXML::UnitsEER compressor_type_choices = OpenStudio::StringVector.new compressor_type_choices << HPXML::HVACCompressorTypeSingleStage compressor_type_choices << HPXML::HVACCompressorTypeTwoStage compressor_type_choices << HPXML::HVACCompressorTypeVariableSpeed arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heating_system_type', heating_system_type_choices, true) arg.setDisplayName('Heating System: Type') arg.setDescription("The type of heating system. Use 'none' if there is no heating system.") arg.setDefaultValue(HPXML::HVACTypeFurnace) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heating_system_fuel', heating_system_fuel_choices, true) arg.setDisplayName('Heating System: Fuel Type') arg.setDescription("The fuel type of the heating system. Ignored for #{HPXML::HVACTypeElectricResistance}.") arg.setDefaultValue(HPXML::FuelTypeNaturalGas) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heating_system_heating_efficiency', true) arg.setDisplayName('Heating System: Rated AFUE or Percent') arg.setUnits('Frac') arg.setDescription('The rated heating efficiency value of the heating system.') arg.setDefaultValue(0.78) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('heating_system_heating_capacity', true) arg.setDisplayName('Heating System: Heating Capacity') arg.setDescription("The output heating capacity of the heating system. If using '#{Constants.Auto}', the autosizing algorithm will use ACCA Manual J/S to set the capacity to meet its load served.") arg.setUnits('Btu/hr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heating_system_fraction_heat_load_served', true) arg.setDisplayName('Heating System: Fraction Heat Load Served') arg.setDescription('The heating load served by the heating system.') arg.setUnits('Frac') arg.setDefaultValue(1) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heating_system_airflow_defect_ratio', false) arg.setDisplayName('Heating System: Airflow Defect Ratio') arg.setDescription("The airflow defect ratio, defined as (InstalledAirflow - DesignAirflow) / DesignAirflow, of the heating system per ANSI/RESNET/ACCA Standard 310. A value of zero means no airflow defect. Applies only to #{HPXML::HVACTypeFurnace}.") arg.setUnits('Frac') args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('cooling_system_type', cooling_system_type_choices, true) arg.setDisplayName('Cooling System: Type') arg.setDescription("The type of cooling system. Use 'none' if there is no cooling system.") arg.setDefaultValue(HPXML::HVACTypeCentralAirConditioner) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('cooling_system_cooling_efficiency_type', cooling_efficiency_type_choices, true) arg.setDisplayName('Cooling System: Efficiency Type') arg.setDescription("The efficiency type of the cooling system. System types #{HPXML::HVACTypeCentralAirConditioner} and #{HPXML::HVACTypeMiniSplitAirConditioner} use #{HPXML::UnitsSEER}. System type #{HPXML::HVACTypeRoomAirConditioner} uses #{HPXML::UnitsEER}. Ignored for system type #{HPXML::HVACTypeEvaporativeCooler}.") arg.setDefaultValue(HPXML::UnitsSEER) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('cooling_system_cooling_efficiency', true) arg.setDisplayName('Cooling System: Efficiency') arg.setUnits("#{HPXML::UnitsSEER} or #{HPXML::UnitsEER}") arg.setDescription("The rated efficiency value of the cooling system. Ignored for #{HPXML::HVACTypeEvaporativeCooler}.") arg.setDefaultValue(13.0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('cooling_system_cooling_compressor_type', compressor_type_choices, false) arg.setDisplayName('Cooling System: Cooling Compressor Type') arg.setDescription('The compressor type of the cooling system. Only applies to central air conditioner.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('cooling_system_cooling_sensible_heat_fraction', false) arg.setDisplayName('Cooling System: Cooling Sensible Heat Fraction') arg.setDescription("The sensible heat fraction of the cooling system. Ignored for #{HPXML::HVACTypeEvaporativeCooler}.") arg.setUnits('Frac') args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('cooling_system_cooling_capacity', true) arg.setDisplayName('Cooling System: Cooling Capacity') arg.setDescription("The output cooling capacity of the cooling system. If using '#{Constants.Auto}', the autosizing algorithm will use ACCA Manual J/S to set the capacity to meet its load served.") arg.setUnits('tons') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('cooling_system_fraction_cool_load_served', true) arg.setDisplayName('Cooling System: Fraction Cool Load Served') arg.setDescription('The cooling load served by the cooling system.') arg.setUnits('Frac') arg.setDefaultValue(1) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('cooling_system_is_ducted', true) arg.setDisplayName('Cooling System: Is Ducted') arg.setDescription("Whether the cooling system is ducted or not. Only used for #{HPXML::HVACTypeMiniSplitAirConditioner} and #{HPXML::HVACTypeEvaporativeCooler}.") arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('cooling_system_airflow_defect_ratio', false) arg.setDisplayName('Cooling System: Airflow Defect Ratio') arg.setDescription("The airflow defect ratio, defined as (InstalledAirflow - DesignAirflow) / DesignAirflow, of the cooling system per ANSI/RESNET/ACCA Standard 310. A value of zero means no airflow defect. Applies only to #{HPXML::HVACTypeCentralAirConditioner} and ducted #{HPXML::HVACTypeMiniSplitAirConditioner}.") arg.setUnits('Frac') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('cooling_system_charge_defect_ratio', false) arg.setDisplayName('Cooling System: Charge Defect Ratio') arg.setDescription("The refrigerant charge defect ratio, defined as (InstalledCharge - DesignCharge) / DesignCharge, of the cooling system per ANSI/RESNET/ACCA Standard 310. A value of zero means no refrigerant charge defect. Applies only to #{HPXML::HVACTypeCentralAirConditioner} and #{HPXML::HVACTypeMiniSplitAirConditioner}.") arg.setUnits('Frac') args << arg heat_pump_type_choices = OpenStudio::StringVector.new heat_pump_type_choices << 'none' heat_pump_type_choices << HPXML::HVACTypeHeatPumpAirToAir heat_pump_type_choices << HPXML::HVACTypeHeatPumpMiniSplit heat_pump_type_choices << HPXML::HVACTypeHeatPumpGroundToAir heat_pump_heating_efficiency_type_choices = OpenStudio::StringVector.new heat_pump_heating_efficiency_type_choices << HPXML::UnitsHSPF heat_pump_heating_efficiency_type_choices << HPXML::UnitsCOP heat_pump_fuel_choices = OpenStudio::StringVector.new heat_pump_fuel_choices << HPXML::FuelTypeElectricity heat_pump_backup_fuel_choices = OpenStudio::StringVector.new heat_pump_backup_fuel_choices << 'none' heat_pump_backup_fuel_choices << HPXML::FuelTypeElectricity heat_pump_backup_fuel_choices << HPXML::FuelTypeNaturalGas heat_pump_backup_fuel_choices << HPXML::FuelTypeOil heat_pump_backup_fuel_choices << HPXML::FuelTypePropane arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heat_pump_type', heat_pump_type_choices, true) arg.setDisplayName('Heat Pump: Type') arg.setDescription("The type of heat pump. Use 'none' if there is no heat pump.") arg.setDefaultValue('none') args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heat_pump_heating_efficiency_type', heat_pump_heating_efficiency_type_choices, true) arg.setDisplayName('Heat Pump: Heating Efficiency Type') arg.setDescription("The heating efficiency type of heat pump. System types #{HPXML::HVACTypeHeatPumpAirToAir} and #{HPXML::HVACTypeHeatPumpMiniSplit} use #{HPXML::UnitsHSPF}. System type #{HPXML::HVACTypeHeatPumpGroundToAir} uses #{HPXML::UnitsCOP}.") arg.setDefaultValue(HPXML::UnitsHSPF) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_heating_efficiency', true) arg.setDisplayName('Heat Pump: Heating Efficiency') arg.setUnits("#{HPXML::UnitsHSPF} or #{HPXML::UnitsCOP}") arg.setDescription('The rated heating efficiency value of the heat pump.') arg.setDefaultValue(7.7) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heat_pump_cooling_efficiency_type', cooling_efficiency_type_choices, true) arg.setDisplayName('Heat Pump: Cooling Efficiency Type') arg.setDescription("The cooling efficiency type of heat pump. System types #{HPXML::HVACTypeHeatPumpAirToAir} and #{HPXML::HVACTypeHeatPumpMiniSplit} use #{HPXML::UnitsSEER}. System type #{HPXML::HVACTypeHeatPumpGroundToAir} uses #{HPXML::UnitsEER}.") arg.setDefaultValue(HPXML::UnitsSEER) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_cooling_efficiency', true) arg.setDisplayName('Heat Pump: Cooling Efficiency') arg.setUnits("#{HPXML::UnitsSEER} or #{HPXML::UnitsEER}") arg.setDescription('The rated cooling efficiency value of the heat pump.') arg.setDefaultValue(13.0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heat_pump_cooling_compressor_type', compressor_type_choices, false) arg.setDisplayName('Heat Pump: Cooling Compressor Type') arg.setDescription('The compressor type of the heat pump. Only applies to air-to-air and mini-split.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_cooling_sensible_heat_fraction', false) arg.setDisplayName('Heat Pump: Cooling Sensible Heat Fraction') arg.setDescription('The sensible heat fraction of the heat pump.') arg.setUnits('Frac') args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('heat_pump_heating_capacity', true) arg.setDisplayName('Heat Pump: Heating Capacity') arg.setDescription("The output heating capacity of the heat pump. If using '#{Constants.Auto}', the autosizing algorithm will use ACCA Manual J/S to set the capacity to meet its load served.") arg.setUnits('Btu/hr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('heat_pump_heating_capacity_17_f', true) arg.setDisplayName('Heat Pump: Heating Capacity 17F') arg.setDescription("The output heating capacity of the heat pump at 17F. Only applies to #{HPXML::HVACTypeHeatPumpAirToAir} and #{HPXML::HVACTypeHeatPumpMiniSplit}.") arg.setUnits('Btu/hr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('heat_pump_cooling_capacity', true) arg.setDisplayName('Heat Pump: Cooling Capacity') arg.setDescription("The output cooling capacity of the heat pump. If using '#{Constants.Auto}', the autosizing algorithm will use ACCA Manual J/S to set the capacity to meet its load served.") arg.setUnits('Btu/hr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_fraction_heat_load_served', true) arg.setDisplayName('Heat Pump: Fraction Heat Load Served') arg.setDescription('The heating load served by the heat pump.') arg.setUnits('Frac') arg.setDefaultValue(1) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_fraction_cool_load_served', true) arg.setDisplayName('Heat Pump: Fraction Cool Load Served') arg.setDescription('The cooling load served by the heat pump.') arg.setUnits('Frac') arg.setDefaultValue(1) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heat_pump_backup_fuel', heat_pump_backup_fuel_choices, true) arg.setDisplayName('Heat Pump: Backup Fuel Type') arg.setDescription("The backup fuel type of the heat pump. Use 'none' if there is no backup heating.") arg.setDefaultValue('none') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_backup_heating_efficiency', true) arg.setDisplayName('Heat Pump: Backup Rated Efficiency') arg.setDescription('The backup rated efficiency value of the heat pump. Percent for electricity fuel type. AFUE otherwise.') arg.setDefaultValue(1) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('heat_pump_backup_heating_capacity', true) arg.setDisplayName('Heat Pump: Backup Heating Capacity') arg.setDescription("The backup output heating capacity of the heat pump. If using '#{Constants.Auto}', the autosizing algorithm will use ACCA Manual J/S to set the capacity to meet its load served.") arg.setUnits('Btu/hr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_backup_heating_switchover_temp', false) arg.setDisplayName('Heat Pump: Backup Heating Switchover Temperature') arg.setDescription('The temperature at which the heat pump stops operating and the backup heating system starts running. Only applies to air-to-air and mini-split. If not provided, backup heating will operate as needed when heat pump capacity is insufficient.') arg.setUnits('deg-F') args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('heat_pump_is_ducted', false) arg.setDisplayName('Heat Pump: Is Ducted') arg.setDescription("Whether the heat pump is ducted or not. Only used for #{HPXML::HVACTypeHeatPumpMiniSplit}.") args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_airflow_defect_ratio', false) arg.setDisplayName('Heat Pump: Airflow Defect Ratio') arg.setDescription("The airflow defect ratio, defined as (InstalledAirflow - DesignAirflow) / DesignAirflow, of the heat pump per ANSI/RESNET/ACCA Standard 310. A value of zero means no airflow defect. Applies only to #{HPXML::HVACTypeHeatPumpAirToAir}, ducted #{HPXML::HVACTypeHeatPumpMiniSplit}, and #{HPXML::HVACTypeHeatPumpGroundToAir}.") arg.setUnits('Frac') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_charge_defect_ratio', false) arg.setDisplayName('Heat Pump: Charge Defect Ratio') arg.setDescription('The refrigerant charge defect ratio, defined as (InstalledCharge - DesignCharge) / DesignCharge, of the heat pump per ANSI/RESNET/ACCA Standard 310. A value of zero means no refrigerant charge defect. Applies to all heat pump types.') arg.setUnits('Frac') args << arg heating_system_type_2_choices = OpenStudio::StringVector.new heating_system_type_2_choices << 'none' heating_system_type_2_choices << HPXML::HVACTypeWallFurnace heating_system_type_2_choices << HPXML::HVACTypeFloorFurnace heating_system_type_2_choices << HPXML::HVACTypeBoiler heating_system_type_2_choices << HPXML::HVACTypeElectricResistance heating_system_type_2_choices << HPXML::HVACTypeStove heating_system_type_2_choices << HPXML::HVACTypePortableHeater heating_system_type_2_choices << HPXML::HVACTypeFireplace arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heating_system_type_2', heating_system_type_2_choices, true) arg.setDisplayName('Heating System 2: Type') arg.setDescription('The type of the second heating system.') arg.setDefaultValue('none') args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heating_system_fuel_2', heating_system_fuel_choices, true) arg.setDisplayName('Heating System 2: Fuel Type') arg.setDescription("The fuel type of the second heating system. Ignored for #{HPXML::HVACTypeElectricResistance}.") arg.setDefaultValue(HPXML::FuelTypeElectricity) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heating_system_heating_efficiency_2', true) arg.setDisplayName('Heating System 2: Rated AFUE or Percent') arg.setUnits('Frac') arg.setDescription('For Furnace/WallFurnace/FloorFurnace/Boiler second heating system, the rated AFUE value. For ElectricResistance/Stove/PortableHeater/Fireplace, the rated Percent value.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('heating_system_heating_capacity_2', true) arg.setDisplayName('Heating System 2: Heating Capacity') arg.setDescription("The output heating capacity of the second heating system. If using '#{Constants.Auto}', the autosizing algorithm will use ACCA Manual J/S to set the capacity to meet its load served.") arg.setUnits('Btu/hr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heating_system_fraction_heat_load_served_2', true) arg.setDisplayName('Heating System 2: Fraction Heat Load Served') arg.setDescription('The heat load served fraction of the second heating system.') arg.setUnits('Frac') arg.setDefaultValue(0.25) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('setpoint_heating_weekday', true) arg.setDisplayName('Heating Setpoint: Weekday Schedule') arg.setDescription('Specify the constant or 24-hour comma-separated weekday heating schedule.') arg.setUnits('deg-F') arg.setDefaultValue('71') args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('setpoint_heating_weekend', true) arg.setDisplayName('Heating Setpoint: Weekend Schedule') arg.setDescription('Specify the constant or 24-hour comma-separated weekend heating schedule.') arg.setUnits('deg-F') arg.setDefaultValue('71') args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('setpoint_cooling_weekday', true) arg.setDisplayName('Cooling Setpoint: Weekday Schedule') arg.setDescription('Specify the constant or 24-hour comma-separated weekday cooling schedule.') arg.setUnits('deg-F') arg.setDefaultValue('76') args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('setpoint_cooling_weekend', true) arg.setDisplayName('Cooling Setpoint: Weekend Schedule') arg.setDescription('Specify the constant or 24-hour comma-separated weekend cooling schedule.') arg.setUnits('deg-F') arg.setDefaultValue('76') args << arg duct_leakage_units_choices = OpenStudio::StringVector.new duct_leakage_units_choices << HPXML::UnitsCFM25 duct_leakage_units_choices << HPXML::UnitsPercent duct_location_choices = OpenStudio::StringVector.new duct_location_choices << Constants.Auto duct_location_choices << HPXML::LocationLivingSpace duct_location_choices << HPXML::LocationBasementConditioned duct_location_choices << HPXML::LocationBasementUnconditioned duct_location_choices << HPXML::LocationCrawlspaceVented duct_location_choices << HPXML::LocationCrawlspaceUnvented duct_location_choices << HPXML::LocationAtticVented duct_location_choices << HPXML::LocationAtticUnvented duct_location_choices << HPXML::LocationGarage duct_location_choices << HPXML::LocationExteriorWall duct_location_choices << HPXML::LocationUnderSlab duct_location_choices << HPXML::LocationRoofDeck duct_location_choices << HPXML::LocationOutside duct_location_choices << HPXML::LocationOtherHousingUnit duct_location_choices << HPXML::LocationOtherHeatedSpace duct_location_choices << HPXML::LocationOtherMultifamilyBufferSpace duct_location_choices << HPXML::LocationOtherNonFreezingSpace arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('ducts_supply_leakage_units', duct_leakage_units_choices, true) arg.setDisplayName('Ducts: Supply Leakage Units') arg.setDescription('The leakage units of the supply ducts.') arg.setDefaultValue(HPXML::UnitsCFM25) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('ducts_return_leakage_units', duct_leakage_units_choices, true) arg.setDisplayName('Ducts: Return Leakage Units') arg.setDescription('The leakage units of the return ducts.') arg.setDefaultValue(HPXML::UnitsCFM25) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ducts_supply_leakage_value', true) arg.setDisplayName('Ducts: Supply Leakage Value') arg.setDescription('The leakage value to outside of the supply ducts.') arg.setDefaultValue(75) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ducts_return_leakage_value', true) arg.setDisplayName('Ducts: Return Leakage Value') arg.setDescription('The leakage value to outside of the return ducts.') arg.setDefaultValue(25) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ducts_supply_insulation_r', true) arg.setDisplayName('Ducts: Supply Insulation R-Value') arg.setDescription('The insulation r-value of the supply ducts.') arg.setUnits('h-ft^2-R/Btu') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ducts_return_insulation_r', true) arg.setDisplayName('Ducts: Return Insulation R-Value') arg.setDescription('The insulation r-value of the return ducts.') arg.setUnits('h-ft^2-R/Btu') arg.setDefaultValue(0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('ducts_supply_location', duct_location_choices, true) arg.setDisplayName('Ducts: Supply Location') arg.setDescription('The location of the supply ducts.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('ducts_return_location', duct_location_choices, true) arg.setDisplayName('Ducts: Return Location') arg.setDescription('The location of the return ducts.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('ducts_supply_surface_area', true) arg.setDisplayName('Ducts: Supply Surface Area') arg.setDescription('The surface area of the supply ducts.') arg.setUnits('ft^2') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('ducts_return_surface_area', true) arg.setDisplayName('Ducts: Return Surface Area') arg.setDescription('The surface area of the return ducts.') arg.setUnits('ft^2') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('ducts_number_of_return_registers', true) arg.setDisplayName('Ducts: Number of Return Registers') arg.setDescription("The number of return registers of the ducts. Ignored for ducted #{HPXML::HVACTypeEvaporativeCooler}.") arg.setUnits('#') arg.setDefaultValue(Constants.Auto) args << arg mech_vent_fan_type_choices = OpenStudio::StringVector.new mech_vent_fan_type_choices << 'none' mech_vent_fan_type_choices << HPXML::MechVentTypeExhaust mech_vent_fan_type_choices << HPXML::MechVentTypeSupply mech_vent_fan_type_choices << HPXML::MechVentTypeERV mech_vent_fan_type_choices << HPXML::MechVentTypeHRV mech_vent_fan_type_choices << HPXML::MechVentTypeBalanced mech_vent_fan_type_choices << HPXML::MechVentTypeCFIS mech_vent_recovery_efficiency_type_choices = OpenStudio::StringVector.new mech_vent_recovery_efficiency_type_choices << 'Unadjusted' mech_vent_recovery_efficiency_type_choices << 'Adjusted' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('mech_vent_fan_type', mech_vent_fan_type_choices, true) arg.setDisplayName('Mechanical Ventilation: Fan Type') arg.setDescription("The type of the mechanical ventilation. Use 'none' if there is no mechanical ventilation system.") arg.setDefaultValue('none') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('mech_vent_flow_rate', true) arg.setDisplayName('Mechanical Ventilation: Flow Rate') arg.setDescription('The flow rate of the mechanical ventilation.') arg.setUnits('CFM') arg.setDefaultValue(110) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('mech_vent_hours_in_operation', true) arg.setDisplayName('Mechanical Ventilation: Hours In Operation') arg.setDescription('The hours in operation of the mechanical ventilation.') arg.setUnits('hrs/day') arg.setDefaultValue(24) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('mech_vent_recovery_efficiency_type', mech_vent_recovery_efficiency_type_choices, true) arg.setDisplayName('Mechanical Ventilation: Total Recovery Efficiency Type') arg.setDescription('The total recovery efficiency type of the mechanical ventilation.') arg.setDefaultValue('Unadjusted') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('mech_vent_total_recovery_efficiency', true) arg.setDisplayName('Mechanical Ventilation: Total Recovery Efficiency') arg.setDescription("The Unadjusted or Adjusted total recovery efficiency of the mechanical ventilation. Applies to #{HPXML::MechVentTypeERV}.") arg.setUnits('Frac') arg.setDefaultValue(0.48) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('mech_vent_sensible_recovery_efficiency', true) arg.setDisplayName('Mechanical Ventilation: Sensible Recovery Efficiency') arg.setDescription("The Unadjusted or Adjusted sensible recovery efficiency of the mechanical ventilation. Applies to #{HPXML::MechVentTypeERV} and #{HPXML::MechVentTypeHRV}.") arg.setUnits('Frac') arg.setDefaultValue(0.72) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('mech_vent_fan_power', true) arg.setDisplayName('Mechanical Ventilation: Fan Power') arg.setDescription('The fan power of the mechanical ventilation.') arg.setUnits('W') arg.setDefaultValue(30) args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('mech_vent_num_units_served', true) arg.setDisplayName('Mechanical Ventilation: Number of Units Served') arg.setDescription("Number of dwelling units served by the mechanical ventilation system. Must be 1 if #{HPXML::ResidentialTypeSFD}. Used to apportion flow rate and fan power to the unit.") arg.setUnits('#') arg.setDefaultValue(1) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('shared_mech_vent_frac_recirculation', false) arg.setDisplayName('Shared Mechanical Ventilation: Fraction Recirculation') arg.setDescription('Fraction of the total supply air that is recirculated, with the remainder assumed to be outdoor air. The value must be 0 for exhaust only systems. This is required for a shared mechanical ventilation system.') arg.setUnits('Frac') args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('shared_mech_vent_preheating_fuel', heating_system_fuel_choices, false) arg.setDisplayName('Shared Mechanical Ventilation: Preheating Fuel') arg.setDescription('Fuel type of the preconditioning heating equipment. Only used for a shared mechanical ventilation system.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('shared_mech_vent_preheating_efficiency', false) arg.setDisplayName('Shared Mechanical Ventilation: Preheating Efficiency') arg.setDescription('Efficiency of the preconditioning heating equipment. Only used for a shared mechanical ventilation system.') arg.setUnits('COP') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('shared_mech_vent_preheating_fraction_heat_load_served', false) arg.setDisplayName('Shared Mechanical Ventilation: Preheating Fraction Ventilation Heat Load Served') arg.setDescription('Fraction of heating load introduced by the shared ventilation system that is met by the preconditioning heating equipment.') arg.setUnits('Frac') args << arg cooling_system_fuel_choices = OpenStudio::StringVector.new cooling_system_fuel_choices << HPXML::FuelTypeElectricity arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('shared_mech_vent_precooling_fuel', cooling_system_fuel_choices, false) arg.setDisplayName('Shared Mechanical Ventilation: Precooling Fuel') arg.setDescription('Fuel type of the preconditioning cooling equipment. Only used for a shared mechanical ventilation system.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('shared_mech_vent_precooling_efficiency', false) arg.setDisplayName('Shared Mechanical Ventilation: Precooling Efficiency') arg.setDescription('Efficiency of the preconditioning cooling equipment. Only used for a shared mechanical ventilation system.') arg.setUnits('COP') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('shared_mech_vent_precooling_fraction_cool_load_served', false) arg.setDisplayName('Shared Mechanical Ventilation: Precooling Fraction Ventilation Cool Load Served') arg.setDescription('Fraction of cooling load introduced by the shared ventilation system that is met by the preconditioning cooling equipment.') arg.setUnits('Frac') args << arg mech_vent_fan_type_2_choices = OpenStudio::StringVector.new mech_vent_fan_type_2_choices << 'none' mech_vent_fan_type_2_choices << HPXML::MechVentTypeExhaust mech_vent_fan_type_2_choices << HPXML::MechVentTypeSupply mech_vent_fan_type_2_choices << HPXML::MechVentTypeERV mech_vent_fan_type_2_choices << HPXML::MechVentTypeHRV mech_vent_fan_type_2_choices << HPXML::MechVentTypeBalanced arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('mech_vent_fan_type_2', mech_vent_fan_type_2_choices, true) arg.setDisplayName('Mechanical Ventilation 2: Fan Type') arg.setDescription("The type of the second mechanical ventilation. Use 'none' if there is no second mechanical ventilation system.") arg.setDefaultValue('none') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('mech_vent_flow_rate_2', true) arg.setDisplayName('Mechanical Ventilation 2: Flow Rate') arg.setDescription('The flow rate of the second mechanical ventilation.') arg.setUnits('CFM') arg.setDefaultValue(110) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('mech_vent_hours_in_operation_2', true) arg.setDisplayName('Mechanical Ventilation 2: Hours In Operation') arg.setDescription('The hours in operation of the second mechanical ventilation.') arg.setUnits('hrs/day') arg.setDefaultValue(24) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('mech_vent_recovery_efficiency_type_2', mech_vent_recovery_efficiency_type_choices, true) arg.setDisplayName('Mechanical Ventilation 2: Total Recovery Efficiency Type') arg.setDescription('The total recovery efficiency type of the second mechanical ventilation.') arg.setDefaultValue('Unadjusted') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('mech_vent_total_recovery_efficiency_2', true) arg.setDisplayName('Mechanical Ventilation 2: Total Recovery Efficiency') arg.setDescription("The Unadjusted or Adjusted total recovery efficiency of the second mechanical ventilation. Applies to #{HPXML::MechVentTypeERV}.") arg.setUnits('Frac') arg.setDefaultValue(0.48) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('mech_vent_sensible_recovery_efficiency_2', true) arg.setDisplayName('Mechanical Ventilation 2: Sensible Recovery Efficiency') arg.setDescription("The Unadjusted or Adjusted sensible recovery efficiency of the second mechanical ventilation. Applies to #{HPXML::MechVentTypeERV} and #{HPXML::MechVentTypeHRV}.") arg.setUnits('Frac') arg.setDefaultValue(0.72) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('mech_vent_fan_power_2', true) arg.setDisplayName('Mechanical Ventilation 2: Fan Power') arg.setDescription('The fan power of the second mechanical ventilation.') arg.setUnits('W') arg.setDefaultValue(30) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('kitchen_fans_quantity', true) arg.setDisplayName('Kitchen Fans: Quantity') arg.setDescription('The quantity of the kitchen fans.') arg.setUnits('#') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('kitchen_fans_flow_rate', false) arg.setDisplayName('Kitchen Fans: Flow Rate') arg.setDescription('The flow rate of the kitchen fan.') arg.setUnits('CFM') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('kitchen_fans_hours_in_operation', false) arg.setDisplayName('Kitchen Fans: Hours In Operation') arg.setDescription('The hours in operation of the kitchen fan.') arg.setUnits('hrs/day') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('kitchen_fans_power', false) arg.setDisplayName('Kitchen Fans: Fan Power') arg.setDescription('The fan power of the kitchen fan.') arg.setUnits('W') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('kitchen_fans_start_hour', false) arg.setDisplayName('Kitchen Fans: Start Hour') arg.setDescription('The start hour of the kitchen fan.') arg.setUnits('hr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('bathroom_fans_quantity', true) arg.setDisplayName('Bathroom Fans: Quantity') arg.setDescription('The quantity of the bathroom fans.') arg.setUnits('#') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('bathroom_fans_flow_rate', false) arg.setDisplayName('Bathroom Fans: Flow Rate') arg.setDescription('The flow rate of the bathroom fans.') arg.setUnits('CFM') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('bathroom_fans_hours_in_operation', false) arg.setDisplayName('Bathroom Fans: Hours In Operation') arg.setDescription('The hours in operation of the bathroom fans.') arg.setUnits('hrs/day') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('bathroom_fans_power', false) arg.setDisplayName('Bathroom Fans: Fan Power') arg.setDescription('The fan power of the bathroom fans.') arg.setUnits('W') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('bathroom_fans_start_hour', false) arg.setDisplayName('Bathroom Fans: Start Hour') arg.setDescription('The start hour of the bathroom fans.') arg.setUnits('hr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('whole_house_fan_present', true) arg.setDisplayName('Whole House Fan: Present') arg.setDescription('Whether there is a whole house fan.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('whole_house_fan_flow_rate', true) arg.setDisplayName('Whole House Fan: Flow Rate') arg.setDescription('The flow rate of the whole house fan.') arg.setUnits('CFM') arg.setDefaultValue(4500) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('whole_house_fan_power', true) arg.setDisplayName('Whole House Fan: Fan Power') arg.setDescription('The fan power of the whole house fan.') arg.setUnits('W') arg.setDefaultValue(300) args << arg water_heater_type_choices = OpenStudio::StringVector.new water_heater_type_choices << 'none' water_heater_type_choices << HPXML::WaterHeaterTypeStorage water_heater_type_choices << HPXML::WaterHeaterTypeTankless water_heater_type_choices << HPXML::WaterHeaterTypeHeatPump water_heater_type_choices << HPXML::WaterHeaterTypeCombiStorage water_heater_type_choices << HPXML::WaterHeaterTypeCombiTankless water_heater_fuel_choices = OpenStudio::StringVector.new water_heater_fuel_choices << HPXML::FuelTypeElectricity water_heater_fuel_choices << HPXML::FuelTypeNaturalGas water_heater_fuel_choices << HPXML::FuelTypeOil water_heater_fuel_choices << HPXML::FuelTypePropane water_heater_fuel_choices << HPXML::FuelTypeWoodCord water_heater_fuel_choices << HPXML::FuelTypeCoal water_heater_location_choices = OpenStudio::StringVector.new water_heater_location_choices << Constants.Auto water_heater_location_choices << HPXML::LocationLivingSpace water_heater_location_choices << HPXML::LocationBasementConditioned water_heater_location_choices << HPXML::LocationBasementUnconditioned water_heater_location_choices << HPXML::LocationGarage water_heater_location_choices << HPXML::LocationAtticVented water_heater_location_choices << HPXML::LocationAtticUnvented water_heater_location_choices << HPXML::LocationCrawlspaceVented water_heater_location_choices << HPXML::LocationCrawlspaceUnvented water_heater_location_choices << HPXML::LocationOtherExterior water_heater_location_choices << HPXML::LocationOtherHousingUnit water_heater_location_choices << HPXML::LocationOtherHeatedSpace water_heater_location_choices << HPXML::LocationOtherMultifamilyBufferSpace water_heater_location_choices << HPXML::LocationOtherNonFreezingSpace water_heater_efficiency_type_choices = OpenStudio::StringVector.new water_heater_efficiency_type_choices << 'EnergyFactor' water_heater_efficiency_type_choices << 'UniformEnergyFactor' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('water_heater_type', water_heater_type_choices, true) arg.setDisplayName('Water Heater: Type') arg.setDescription("The type of water heater. Use 'none' if there is no water heater.") arg.setDefaultValue(HPXML::WaterHeaterTypeStorage) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('water_heater_fuel_type', water_heater_fuel_choices, true) arg.setDisplayName('Water Heater: Fuel Type') arg.setDescription("The fuel type of water heater. Ignored for #{HPXML::WaterHeaterTypeHeatPump}.") arg.setDefaultValue(HPXML::FuelTypeNaturalGas) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('water_heater_location', water_heater_location_choices, true) arg.setDisplayName('Water Heater: Location') arg.setDescription('The location of water heater.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('water_heater_tank_volume', true) arg.setDisplayName('Water Heater: Tank Volume') arg.setDescription("Nominal volume of water heater tank. Set to '#{Constants.Auto}' to have volume autosized. Only applies to #{HPXML::WaterHeaterTypeStorage}, #{HPXML::WaterHeaterTypeHeatPump}, and #{HPXML::WaterHeaterTypeCombiStorage}.") arg.setUnits('gal') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('water_heater_efficiency_type', water_heater_efficiency_type_choices, true) arg.setDisplayName('Water Heater: Efficiency Type') arg.setDescription('The efficiency type of water heater. Does not apply to space-heating boilers.') arg.setDefaultValue('EnergyFactor') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('water_heater_efficiency', true) arg.setDisplayName('Water Heater: Efficiency') arg.setDescription('Rated Energy Factor or Uniform Energy Factor. Does not apply to space-heating boilers.') arg.setDefaultValue(0.67) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('water_heater_first_hour_rating', false) arg.setDisplayName('Water Heater: First Hour Rating') arg.setDescription("Rated gallons of hot water supplied in an hour. Required if Efficiency Type is UniformEnergyFactor and Type is not #{HPXML::WaterHeaterTypeTankless}. Does not apply to space-heating boilers.") arg.setUnits('gal/hr') arg.setDefaultValue(56.0) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('water_heater_recovery_efficiency', true) arg.setDisplayName('Water Heater: Recovery Efficiency') arg.setDescription('Ratio of energy delivered to water heater to the energy content of the fuel consumed by the water heater. Only used for non-electric storage water heaters.') arg.setUnits('Frac') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('water_heater_standby_loss', false) arg.setDisplayName('Water Heater: Standby Loss') arg.setDescription('The standby loss of water heater. Only applies to space-heating boilers.') arg.setUnits('deg-F/hr') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('water_heater_jacket_rvalue', false) arg.setDisplayName('Water Heater: Jacket R-value') arg.setDescription("The jacket R-value of water heater. Doesn't apply to #{HPXML::WaterHeaterTypeTankless} or #{HPXML::WaterHeaterTypeCombiTankless}.") arg.setUnits('h-ft^2-R/Btu') args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('water_heater_setpoint_temperature', true) arg.setDisplayName('Water Heater: Setpoint Temperature') arg.setDescription('The setpoint temperature of water heater.') arg.setUnits('deg-F') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('water_heater_num_units_served', true) arg.setDisplayName('Water Heater: Number of Units Served') arg.setDescription("Number of dwelling units served (directly or indirectly) by the water heater. Must be 1 if #{HPXML::ResidentialTypeSFD}. Used to apportion water heater tank losses to the unit.") arg.setUnits('#') arg.setDefaultValue(1) args << arg dhw_distribution_system_type_choices = OpenStudio::StringVector.new dhw_distribution_system_type_choices << HPXML::DHWDistTypeStandard dhw_distribution_system_type_choices << HPXML::DHWDistTypeRecirc arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('dhw_distribution_system_type', dhw_distribution_system_type_choices, true) arg.setDisplayName('Hot Water Distribution: System Type') arg.setDescription('The type of the hot water distribution system.') arg.setDefaultValue(HPXML::DHWDistTypeStandard) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dhw_distribution_standard_piping_length', true) arg.setDisplayName('Hot Water Distribution: Standard Piping Length') arg.setUnits('ft') arg.setDescription("If the distribution system is #{HPXML::DHWDistTypeStandard}, the length of the piping. A value of '#{Constants.Auto}' will use a default.") arg.setDefaultValue(Constants.Auto) args << arg recirculation_control_type_choices = OpenStudio::StringVector.new recirculation_control_type_choices << HPXML::DHWRecirControlTypeNone recirculation_control_type_choices << HPXML::DHWRecirControlTypeTimer recirculation_control_type_choices << HPXML::DHWRecirControlTypeTemperature recirculation_control_type_choices << HPXML::DHWRecirControlTypeSensor recirculation_control_type_choices << HPXML::DHWRecirControlTypeManual arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('dhw_distribution_recirc_control_type', recirculation_control_type_choices, true) arg.setDisplayName('Hot Water Distribution: Recirculation Control Type') arg.setDescription("If the distribution system is #{HPXML::DHWDistTypeRecirc}, the type of hot water recirculation control, if any.") arg.setDefaultValue(HPXML::DHWRecirControlTypeNone) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dhw_distribution_recirc_piping_length', true) arg.setDisplayName('Hot Water Distribution: Recirculation Piping Length') arg.setUnits('ft') arg.setDescription("If the distribution system is #{HPXML::DHWDistTypeRecirc}, the length of the recirculation piping.") arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dhw_distribution_recirc_branch_piping_length', true) arg.setDisplayName('Hot Water Distribution: Recirculation Branch Piping Length') arg.setUnits('ft') arg.setDescription("If the distribution system is #{HPXML::DHWDistTypeRecirc}, the length of the recirculation branch piping.") arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dhw_distribution_recirc_pump_power', true) arg.setDisplayName('Hot Water Distribution: Recirculation Pump Power') arg.setUnits('W') arg.setDescription("If the distribution system is #{HPXML::DHWDistTypeRecirc}, the recirculation pump power.") arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dhw_distribution_pipe_r', true) arg.setDisplayName('Hot Water Distribution: Pipe Insulation Nominal R-Value') arg.setUnits('h-ft^2-R/Btu') arg.setDescription('Nominal R-value of the pipe insulation.') arg.setDefaultValue(Constants.Auto) args << arg dwhr_facilities_connected_choices = OpenStudio::StringVector.new dwhr_facilities_connected_choices << 'none' dwhr_facilities_connected_choices << HPXML::DWHRFacilitiesConnectedOne dwhr_facilities_connected_choices << HPXML::DWHRFacilitiesConnectedAll arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('dwhr_facilities_connected', dwhr_facilities_connected_choices, true) arg.setDisplayName('Drain Water Heat Recovery: Facilities Connected') arg.setDescription("Which facilities are connected for the drain water heat recovery. Use 'none' if there is no drain water heat recovery system.") arg.setDefaultValue('none') args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('dwhr_equal_flow', true) arg.setDisplayName('Drain Water Heat Recovery: Equal Flow') arg.setDescription('Whether the drain water heat recovery has equal flow.') arg.setDefaultValue(true) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('dwhr_efficiency', true) arg.setDisplayName('Drain Water Heat Recovery: Efficiency') arg.setUnits('Frac') arg.setDescription('The efficiency of the drain water heat recovery.') arg.setDefaultValue(0.55) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('water_fixtures_shower_low_flow', true) arg.setDisplayName('Hot Water Fixtures: Is Shower Low Flow') arg.setDescription('Whether the shower fixture is low flow.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('water_fixtures_sink_low_flow', true) arg.setDisplayName('Hot Water Fixtures: Is Sink Low Flow') arg.setDescription('Whether the sink fixture is low flow.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('water_fixtures_usage_multiplier', true) arg.setDisplayName('Hot Water Fixtures: Usage Multiplier') arg.setDescription('Multiplier on the hot water usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg solar_thermal_system_type_choices = OpenStudio::StringVector.new solar_thermal_system_type_choices << 'none' solar_thermal_system_type_choices << 'hot water' solar_thermal_collector_loop_type_choices = OpenStudio::StringVector.new solar_thermal_collector_loop_type_choices << HPXML::SolarThermalLoopTypeDirect solar_thermal_collector_loop_type_choices << HPXML::SolarThermalLoopTypeIndirect solar_thermal_collector_loop_type_choices << HPXML::SolarThermalLoopTypeThermosyphon solar_thermal_collector_type_choices = OpenStudio::StringVector.new solar_thermal_collector_type_choices << HPXML::SolarThermalTypeEvacuatedTube solar_thermal_collector_type_choices << HPXML::SolarThermalTypeSingleGlazing solar_thermal_collector_type_choices << HPXML::SolarThermalTypeDoubleGlazing solar_thermal_collector_type_choices << HPXML::SolarThermalTypeICS arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('solar_thermal_system_type', solar_thermal_system_type_choices, true) arg.setDisplayName('Solar Thermal: System Type') arg.setDescription("The type of solar thermal system. Use 'none' if there is no solar thermal system.") arg.setDefaultValue('none') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('solar_thermal_collector_area', true) arg.setDisplayName('Solar Thermal: Collector Area') arg.setUnits('ft^2') arg.setDescription('The collector area of the solar thermal system.') arg.setDefaultValue(40.0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('solar_thermal_collector_loop_type', solar_thermal_collector_loop_type_choices, true) arg.setDisplayName('Solar Thermal: Collector Loop Type') arg.setDescription('The collector loop type of the solar thermal system.') arg.setDefaultValue(HPXML::SolarThermalLoopTypeDirect) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('solar_thermal_collector_type', solar_thermal_collector_type_choices, true) arg.setDisplayName('Solar Thermal: Collector Type') arg.setDescription('The collector type of the solar thermal system.') arg.setDefaultValue(HPXML::SolarThermalTypeEvacuatedTube) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('solar_thermal_collector_azimuth', true) arg.setDisplayName('Solar Thermal: Collector Azimuth') arg.setUnits('degrees') arg.setDescription('The collector azimuth of the solar thermal system.') arg.setDefaultValue(180) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('solar_thermal_collector_tilt', true) arg.setDisplayName('Solar Thermal: Collector Tilt') arg.setUnits('degrees') arg.setDescription('The collector tilt of the solar thermal system. Can also enter, e.g., RoofPitch, RoofPitch+20, Latitude, Latitude-15, etc.') arg.setDefaultValue('RoofPitch') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('solar_thermal_collector_rated_optical_efficiency', true) arg.setDisplayName('Solar Thermal: Collector Rated Optical Efficiency') arg.setUnits('Frac') arg.setDescription('The collector rated optical efficiency of the solar thermal system.') arg.setDefaultValue(0.5) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('solar_thermal_collector_rated_thermal_losses', true) arg.setDisplayName('Solar Thermal: Collector Rated Thermal Losses') arg.setUnits('Frac') arg.setDescription('The collector rated thermal losses of the solar thermal system.') arg.setDefaultValue(0.2799) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('solar_thermal_storage_volume', true) arg.setDisplayName('Solar Thermal: Storage Volume') arg.setUnits('Frac') arg.setDescription('The storage volume of the solar thermal system.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('solar_thermal_solar_fraction', true) arg.setDisplayName('Solar Thermal: Solar Fraction') arg.setUnits('Frac') arg.setDescription('The solar fraction of the solar thermal system. If provided, overrides all other solar thermal inputs.') arg.setDefaultValue(0) args << arg pv_system_module_type_choices = OpenStudio::StringVector.new pv_system_module_type_choices << 'none' pv_system_module_type_choices << Constants.Auto pv_system_module_type_choices << HPXML::PVModuleTypeStandard pv_system_module_type_choices << HPXML::PVModuleTypePremium pv_system_module_type_choices << HPXML::PVModuleTypeThinFilm pv_system_location_choices = OpenStudio::StringVector.new pv_system_location_choices << Constants.Auto pv_system_location_choices << HPXML::LocationRoof pv_system_location_choices << HPXML::LocationGround pv_system_tracking_choices = OpenStudio::StringVector.new pv_system_tracking_choices << Constants.Auto pv_system_tracking_choices << HPXML::PVTrackingTypeFixed pv_system_tracking_choices << HPXML::PVTrackingType1Axis pv_system_tracking_choices << HPXML::PVTrackingType1AxisBacktracked pv_system_tracking_choices << HPXML::PVTrackingType2Axis arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('pv_system_module_type_1', pv_system_module_type_choices, true) arg.setDisplayName('Photovoltaics 1: Module Type') arg.setDescription("Module type of the PV system 1. Use 'none' if there is no PV system 1.") arg.setDefaultValue('none') args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('pv_system_location_1', pv_system_location_choices, true) arg.setDisplayName('Photovoltaics 1: Location') arg.setDescription('Location of the PV system 1.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('pv_system_tracking_1', pv_system_tracking_choices, true) arg.setDisplayName('Photovoltaics 1: Tracking') arg.setDescription('Tracking of the PV system 1.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('pv_system_array_azimuth_1', true) arg.setDisplayName('Photovoltaics 1: Array Azimuth') arg.setUnits('degrees') arg.setDescription('Array azimuth of the PV system 1.') arg.setDefaultValue(180) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('pv_system_array_tilt_1', true) arg.setDisplayName('Photovoltaics 1: Array Tilt') arg.setUnits('degrees') arg.setDescription('Array tilt of the PV system 1. Can also enter, e.g., RoofPitch, RoofPitch+20, Latitude, Latitude-15, etc.') arg.setDefaultValue('RoofPitch') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('pv_system_max_power_output_1', true) arg.setDisplayName('Photovoltaics 1: Maximum Power Output') arg.setUnits('W') arg.setDescription('Maximum power output of the PV system 1. For a shared system, this is the total building maximum power output.') arg.setDefaultValue(4000) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('pv_system_inverter_efficiency_1', false) arg.setDisplayName('Photovoltaics 1: Inverter Efficiency') arg.setUnits('Frac') arg.setDescription('Inverter efficiency of the PV system 1.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('pv_system_system_losses_fraction_1', false) arg.setDisplayName('Photovoltaics 1: System Losses Fraction') arg.setUnits('Frac') arg.setDescription('System losses fraction of the PV system 1.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('pv_system_num_units_served_1', true) arg.setDisplayName('Photovoltaics 1: Number of Units Served') arg.setDescription("Number of dwelling units served by PV system 1. Must be 1 if #{HPXML::ResidentialTypeSFD}. Used to apportion PV generation to the unit.") arg.setUnits('#') arg.setDefaultValue(1) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('pv_system_module_type_2', pv_system_module_type_choices, true) arg.setDisplayName('Photovoltaics 2: Module Type') arg.setDescription("Module type of the PV system 2. Use 'none' if there is no PV system 2.") arg.setDefaultValue('none') args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('pv_system_location_2', pv_system_location_choices, true) arg.setDisplayName('Photovoltaics 2: Location') arg.setDescription('Location of the PV system 2.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('pv_system_tracking_2', pv_system_tracking_choices, true) arg.setDisplayName('Photovoltaics 2: Tracking') arg.setDescription('Tracking of the PV system 2.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('pv_system_array_azimuth_2', true) arg.setDisplayName('Photovoltaics 2: Array Azimuth') arg.setUnits('degrees') arg.setDescription('Array azimuth of the PV system 2.') arg.setDefaultValue(180) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('pv_system_array_tilt_2', true) arg.setDisplayName('Photovoltaics 2: Array Tilt') arg.setUnits('degrees') arg.setDescription('Array tilt of the PV system 2. Can also enter, e.g., RoofPitch, RoofPitch+20, Latitude, Latitude-15, etc.') arg.setDefaultValue('RoofPitch') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('pv_system_max_power_output_2', true) arg.setDisplayName('Photovoltaics 2: Maximum Power Output') arg.setUnits('W') arg.setDescription('Maximum power output of the PV system 2. For a shared system, this is the total building maximum power output.') arg.setDefaultValue(4000) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('pv_system_inverter_efficiency_2', false) arg.setDisplayName('Photovoltaics 2: Inverter Efficiency') arg.setUnits('Frac') arg.setDescription('Inverter efficiency of the PV system 2.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('pv_system_system_losses_fraction_2', false) arg.setDisplayName('Photovoltaics 2: System Losses Fraction') arg.setUnits('Frac') arg.setDescription('System losses fraction of the PV system 2.') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('pv_system_num_units_served_2', true) arg.setDisplayName('Photovoltaics 2: Number of Units Served') arg.setDescription("Number of dwelling units served by PV system 2. Must be 1 if #{HPXML::ResidentialTypeSFD}. Used to apportion PV generation to the unit.") arg.setUnits('#') arg.setDefaultValue(1) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_fraction_cfl_interior', true) arg.setDisplayName('Lighting: Fraction CFL Interior') arg.setDescription('Fraction of all lamps (interior) that are compact fluorescent. Lighting not specified as CFL, LFL, or LED is assumed to be incandescent.') arg.setDefaultValue(0.4) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_fraction_lfl_interior', true) arg.setDisplayName('Lighting: Fraction LFL Interior') arg.setDescription('Fraction of all lamps (interior) that are linear fluorescent. Lighting not specified as CFL, LFL, or LED is assumed to be incandescent.') arg.setDefaultValue(0.1) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_fraction_led_interior', true) arg.setDisplayName('Lighting: Fraction LED Interior') arg.setDescription('Fraction of all lamps (interior) that are light emitting diodes. Lighting not specified as CFL, LFL, or LED is assumed to be incandescent.') arg.setDefaultValue(0.25) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_usage_multiplier_interior', true) arg.setDisplayName('Lighting: Usage Multiplier Interior') arg.setDescription('Multiplier on the lighting energy usage (interior) that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_fraction_cfl_exterior', true) arg.setDisplayName('Lighting: Fraction CFL Exterior') arg.setDescription('Fraction of all lamps (exterior) that are compact fluorescent. Lighting not specified as CFL, LFL, or LED is assumed to be incandescent.') arg.setDefaultValue(0.4) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_fraction_lfl_exterior', true) arg.setDisplayName('Lighting: Fraction LFL Exterior') arg.setDescription('Fraction of all lamps (exterior) that are linear fluorescent. Lighting not specified as CFL, LFL, or LED is assumed to be incandescent.') arg.setDefaultValue(0.1) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_fraction_led_exterior', true) arg.setDisplayName('Lighting: Fraction LED Exterior') arg.setDescription('Fraction of all lamps (exterior) that are light emitting diodes. Lighting not specified as CFL, LFL, or LED is assumed to be incandescent.') arg.setDefaultValue(0.25) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_usage_multiplier_exterior', true) arg.setDisplayName('Lighting: Usage Multiplier Exterior') arg.setDescription('Multiplier on the lighting energy usage (exterior) that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_fraction_cfl_garage', true) arg.setDisplayName('Lighting: Fraction CFL Garage') arg.setDescription('Fraction of all lamps (garage) that are compact fluorescent. Lighting not specified as CFL, LFL, or LED is assumed to be incandescent.') arg.setDefaultValue(0.4) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_fraction_lfl_garage', true) arg.setDisplayName('Lighting: Fraction LFL Garage') arg.setDescription('Fraction of all lamps (garage) that are linear fluorescent. Lighting not specified as CFL, LFL, or LED is assumed to be incandescent.') arg.setDefaultValue(0.1) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_fraction_led_garage', true) arg.setDisplayName('Lighting: Fraction LED Garage') arg.setDescription('Fraction of all lamps (garage) that are light emitting diodes. Lighting not specified as CFL, LFL, or LED is assumed to be incandescent.') arg.setDefaultValue(0.25) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('lighting_usage_multiplier_garage', true) arg.setDisplayName('Lighting: Usage Multiplier Garage') arg.setDescription('Multiplier on the lighting energy usage (garage) that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('holiday_lighting_present', true) arg.setDisplayName('Holiday Lighting: Present') arg.setDescription('Whether there is holiday lighting.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('holiday_lighting_daily_kwh', true) arg.setDisplayName('Holiday Lighting: Daily Consumption') arg.setUnits('kWh/day') arg.setDescription('The daily energy consumption for holiday lighting (exterior).') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('holiday_lighting_period_begin_month', true) arg.setDisplayName('Holiday Lighting: Period Begin Month') arg.setUnits('month') arg.setDescription('This numeric field should contain the starting month number (1 = January, 2 = February, etc.) for the holiday lighting period desired.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('holiday_lighting_period_begin_day_of_month', true) arg.setDisplayName('Holiday Lighting: Period Begin Day of Month') arg.setUnits('day') arg.setDescription('This numeric field should contain the starting day of the starting month (must be valid for month) for the holiday lighting period desired.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('holiday_lighting_period_end_month', true) arg.setDisplayName('Holiday Lighting: Period End Month') arg.setUnits('month') arg.setDescription('This numeric field should contain the end month number (1 = January, 2 = February, etc.) for the holiday lighting period desired.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('holiday_lighting_period_end_day_of_month', true) arg.setDisplayName('Holiday Lighting: Period End Day of Month') arg.setUnits('day') arg.setDescription('This numeric field should contain the ending day of the ending month (must be valid for month) for the holiday lighting period desired.') arg.setDefaultValue(Constants.Auto) args << arg dehumidifier_type_choices = OpenStudio::StringVector.new dehumidifier_type_choices << 'none' dehumidifier_type_choices << HPXML::DehumidifierTypePortable dehumidifier_type_choices << HPXML::DehumidifierTypeWholeHome dehumidifier_efficiency_type_choices = OpenStudio::StringVector.new dehumidifier_efficiency_type_choices << 'EnergyFactor' dehumidifier_efficiency_type_choices << 'IntegratedEnergyFactor' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('dehumidifier_type', dehumidifier_type_choices, true) arg.setDisplayName('Dehumidifier: Type') arg.setDescription('The type of dehumidifier.') arg.setDefaultValue('none') args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('dehumidifier_efficiency_type', dehumidifier_efficiency_type_choices, true) arg.setDisplayName('Dehumidifier: Efficiency Type') arg.setDescription('The efficiency type of dehumidifier.') arg.setDefaultValue('IntegratedEnergyFactor') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('dehumidifier_efficiency', true) arg.setDisplayName('Dehumidifier: Efficiency') arg.setUnits('liters/kWh') arg.setDescription('The efficiency of the dehumidifier.') arg.setDefaultValue(1.5) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('dehumidifier_capacity', true) arg.setDisplayName('Dehumidifier: Capacity') arg.setDescription('The capacity (water removal rate) of the dehumidifier.') arg.setUnits('pint/day') arg.setDefaultValue(40) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('dehumidifier_rh_setpoint', true) arg.setDisplayName('Dehumidifier: Relative Humidity Setpoint') arg.setDescription('The relative humidity setpoint of the dehumidifier.') arg.setUnits('Frac') arg.setDefaultValue(0.5) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('dehumidifier_fraction_dehumidification_load_served', true) arg.setDisplayName('Dehumidifier: Fraction Dehumidification Load Served') arg.setDescription('The dehumidification load served fraction of the dehumidifier.') arg.setUnits('Frac') arg.setDefaultValue(1) args << arg appliance_location_choices = OpenStudio::StringVector.new appliance_location_choices << Constants.Auto appliance_location_choices << 'none' appliance_location_choices << HPXML::LocationLivingSpace appliance_location_choices << HPXML::LocationBasementConditioned appliance_location_choices << HPXML::LocationBasementUnconditioned appliance_location_choices << HPXML::LocationGarage appliance_location_choices << HPXML::LocationOtherHousingUnit appliance_location_choices << HPXML::LocationOtherHeatedSpace appliance_location_choices << HPXML::LocationOtherMultifamilyBufferSpace appliance_location_choices << HPXML::LocationOtherNonFreezingSpace clothes_washer_efficiency_type_choices = OpenStudio::StringVector.new clothes_washer_efficiency_type_choices << 'ModifiedEnergyFactor' clothes_washer_efficiency_type_choices << 'IntegratedModifiedEnergyFactor' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('clothes_washer_location', appliance_location_choices, true) arg.setDisplayName('Clothes Washer: Location') arg.setDescription('The space type for the clothes washer location.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('clothes_washer_efficiency_type', clothes_washer_efficiency_type_choices, true) arg.setDisplayName('Clothes Washer: Efficiency Type') arg.setDescription('The efficiency type of the clothes washer.') arg.setDefaultValue('IntegratedModifiedEnergyFactor') args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('clothes_washer_efficiency', true) arg.setDisplayName('Clothes Washer: Efficiency') arg.setUnits('ft^3/kWh-cyc') arg.setDescription('The efficiency of the clothes washer.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('clothes_washer_rated_annual_kwh', true) arg.setDisplayName('Clothes Washer: Rated Annual Consumption') arg.setUnits('kWh/yr') arg.setDescription('The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('clothes_washer_label_electric_rate', true) arg.setDisplayName('Clothes Washer: Label Electric Rate') arg.setUnits('$/kWh') arg.setDescription('The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('clothes_washer_label_gas_rate', true) arg.setDisplayName('Clothes Washer: Label Gas Rate') arg.setUnits('$/therm') arg.setDescription('The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('clothes_washer_label_annual_gas_cost', true) arg.setDisplayName('Clothes Washer: Label Annual Cost with Gas DHW') arg.setUnits('$') arg.setDescription('The annual cost of using the system under test conditions. Input is obtained from the EnergyGuide label.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('clothes_washer_label_usage', true) arg.setDisplayName('Clothes Washer: Label Usage') arg.setUnits('cyc/wk') arg.setDescription('The clothes washer loads per week.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('clothes_washer_capacity', true) arg.setDisplayName('Clothes Washer: Drum Volume') arg.setUnits('ft^3') arg.setDescription("Volume of the washer drum. Obtained from the EnergyStar website or the manufacturer's literature.") arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('clothes_washer_usage_multiplier', true) arg.setDisplayName('Clothes Washer: Usage Multiplier') arg.setDescription('Multiplier on the clothes washer energy and hot water usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('clothes_dryer_location', appliance_location_choices, true) arg.setDisplayName('Clothes Dryer: Location') arg.setDescription('The space type for the clothes dryer location.') arg.setDefaultValue(Constants.Auto) args << arg clothes_dryer_fuel_choices = OpenStudio::StringVector.new clothes_dryer_fuel_choices << HPXML::FuelTypeElectricity clothes_dryer_fuel_choices << HPXML::FuelTypeNaturalGas clothes_dryer_fuel_choices << HPXML::FuelTypeOil clothes_dryer_fuel_choices << HPXML::FuelTypePropane clothes_dryer_fuel_choices << HPXML::FuelTypeWoodCord clothes_dryer_fuel_choices << HPXML::FuelTypeCoal clothes_dryer_efficiency_type_choices = OpenStudio::StringVector.new clothes_dryer_efficiency_type_choices << 'EnergyFactor' clothes_dryer_efficiency_type_choices << 'CombinedEnergyFactor' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('clothes_dryer_fuel_type', clothes_dryer_fuel_choices, true) arg.setDisplayName('Clothes Dryer: Fuel Type') arg.setDescription('Type of fuel used by the clothes dryer.') arg.setDefaultValue(HPXML::FuelTypeNaturalGas) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('clothes_dryer_efficiency_type', clothes_dryer_efficiency_type_choices, true) arg.setDisplayName('Clothes Dryer: Efficiency Type') arg.setDescription('The efficiency type of the clothes dryer.') arg.setDefaultValue('CombinedEnergyFactor') args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('clothes_dryer_efficiency', true) arg.setDisplayName('Clothes Dryer: Efficiency') arg.setUnits('lb/kWh') arg.setDescription('The efficiency of the clothes dryer.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('clothes_dryer_vented_flow_rate', true) arg.setDisplayName('Clothes Dryer: Vented Flow Rate') arg.setDescription('The exhaust flow rate of the vented clothes dryer.') arg.setUnits('CFM') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('clothes_dryer_usage_multiplier', true) arg.setDisplayName('Clothes Dryer: Usage Multiplier') arg.setDescription('Multiplier on the clothes dryer energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('dishwasher_location', appliance_location_choices, true) arg.setDisplayName('Dishwasher: Location') arg.setDescription('The space type for the dishwasher location.') arg.setDefaultValue(Constants.Auto) args << arg dishwasher_efficiency_type_choices = OpenStudio::StringVector.new dishwasher_efficiency_type_choices << 'RatedAnnualkWh' dishwasher_efficiency_type_choices << 'EnergyFactor' arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('dishwasher_efficiency_type', dishwasher_efficiency_type_choices, true) arg.setDisplayName('Dishwasher: Efficiency Type') arg.setDescription('The efficiency type of dishwasher.') arg.setDefaultValue('RatedAnnualkWh') args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dishwasher_efficiency', true) arg.setDisplayName('Dishwasher: Efficiency') arg.setUnits('RatedAnnualkWh or EnergyFactor') arg.setDescription('The efficiency of the dishwasher.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dishwasher_label_electric_rate', true) arg.setDisplayName('Dishwasher: Label Electric Rate') arg.setUnits('$/kWh') arg.setDescription('The label electric rate of the dishwasher.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dishwasher_label_gas_rate', true) arg.setDisplayName('Dishwasher: Label Gas Rate') arg.setUnits('$/therm') arg.setDescription('The label gas rate of the dishwasher.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dishwasher_label_annual_gas_cost', true) arg.setDisplayName('Dishwasher: Label Annual Gas Cost') arg.setUnits('$') arg.setDescription('The label annual gas cost of the dishwasher.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dishwasher_label_usage', true) arg.setDisplayName('Dishwasher: Label Usage') arg.setUnits('cyc/wk') arg.setDescription('The dishwasher loads per week.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('dishwasher_place_setting_capacity', true) arg.setDisplayName('Dishwasher: Number of Place Settings') arg.setUnits('#') arg.setDescription("The number of place settings for the unit. Data obtained from manufacturer's literature.") arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('dishwasher_usage_multiplier', true) arg.setDisplayName('Dishwasher: Usage Multiplier') arg.setDescription('Multiplier on the dishwasher energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('refrigerator_location', appliance_location_choices, true) arg.setDisplayName('Refrigerator: Location') arg.setDescription('The space type for the refrigerator location.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('refrigerator_rated_annual_kwh', true) arg.setDisplayName('Refrigerator: Rated Annual Consumption') arg.setUnits('kWh/yr') arg.setDescription('The EnergyGuide rated annual energy consumption for a refrigerator.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('refrigerator_usage_multiplier', true) arg.setDisplayName('Refrigerator: Usage Multiplier') arg.setDescription('Multiplier on the refrigerator energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('extra_refrigerator_location', appliance_location_choices, true) arg.setDisplayName('Extra Refrigerator: Location') arg.setDescription('The space type for the extra refrigerator location.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('extra_refrigerator_rated_annual_kwh', true) arg.setDisplayName('Extra Refrigerator: Rated Annual Consumption') arg.setUnits('kWh/yr') arg.setDescription('The EnergyGuide rated annual energy consumption for an extra rrefrigerator.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('extra_refrigerator_usage_multiplier', true) arg.setDisplayName('Extra Refrigerator: Usage Multiplier') arg.setDescription('Multiplier on the extra refrigerator energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('freezer_location', appliance_location_choices, true) arg.setDisplayName('Freezer: Location') arg.setDescription('The space type for the freezer location.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('freezer_rated_annual_kwh', true) arg.setDisplayName('Freezer: Rated Annual Consumption') arg.setUnits('kWh/yr') arg.setDescription('The EnergyGuide rated annual energy consumption for a freezer.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('freezer_usage_multiplier', true) arg.setDisplayName('Freezer: Usage Multiplier') arg.setDescription('Multiplier on the freezer energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg cooking_range_oven_fuel_choices = OpenStudio::StringVector.new cooking_range_oven_fuel_choices << HPXML::FuelTypeElectricity cooking_range_oven_fuel_choices << HPXML::FuelTypeNaturalGas cooking_range_oven_fuel_choices << HPXML::FuelTypeOil cooking_range_oven_fuel_choices << HPXML::FuelTypePropane cooking_range_oven_fuel_choices << HPXML::FuelTypeWoodCord cooking_range_oven_fuel_choices << HPXML::FuelTypeCoal arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('cooking_range_oven_location', appliance_location_choices, true) arg.setDisplayName('Cooking Range/Oven: Location') arg.setDescription('The space type for the cooking range/oven location.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('cooking_range_oven_fuel_type', cooking_range_oven_fuel_choices, true) arg.setDisplayName('Cooking Range/Oven: Fuel Type') arg.setDescription('Type of fuel used by the cooking range/oven.') arg.setDefaultValue(HPXML::FuelTypeNaturalGas) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('cooking_range_oven_is_induction', false) arg.setDisplayName('Cooking Range/Oven: Is Induction') arg.setDescription('Whether the cooking range is induction.') args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('cooking_range_oven_is_convection', false) arg.setDisplayName('Cooking Range/Oven: Is Convection') arg.setDescription('Whether the oven is convection.') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('cooking_range_oven_usage_multiplier', true) arg.setDisplayName('Cooking Range/Oven: Usage Multiplier') arg.setDescription('Multiplier on the cooking range/oven energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('ceiling_fan_present', true) arg.setDisplayName('Ceiling Fan: Present') arg.setDescription('Whether there is are any ceiling fans.') arg.setDefaultValue(true) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('ceiling_fan_efficiency', true) arg.setDisplayName('Ceiling Fan: Efficiency') arg.setUnits('CFM/W') arg.setDescription('The efficiency rating of the ceiling fan(s) at medium speed.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('ceiling_fan_quantity', true) arg.setDisplayName('Ceiling Fan: Quantity') arg.setUnits('#') arg.setDescription('Total number of ceiling fans.') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('ceiling_fan_cooling_setpoint_temp_offset', true) arg.setDisplayName('Ceiling Fan: Cooling Setpoint Temperature Offset') arg.setUnits('deg-F') arg.setDescription('The setpoint temperature offset during cooling season for the ceiling fan(s). Only applies if ceiling fan quantity is greater than zero.') arg.setDefaultValue(0.5) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('plug_loads_television_annual_kwh', true) arg.setDisplayName('Plug Loads: Television Annual kWh') arg.setDescription('The annual energy consumption of the television plug loads.') arg.setUnits('kWh/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('plug_loads_television_usage_multiplier', true) arg.setDisplayName('Plug Loads: Television Usage Multiplier') arg.setDescription('Multiplier on the television energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('plug_loads_other_annual_kwh', true) arg.setDisplayName('Plug Loads: Other Annual kWh') arg.setDescription('The annual energy consumption of the other residual plug loads.') arg.setUnits('kWh/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('plug_loads_other_frac_sensible', true) arg.setDisplayName('Plug Loads: Other Sensible Fraction') arg.setDescription("Fraction of other residual plug loads' internal gains that are sensible.") arg.setUnits('Frac') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('plug_loads_other_frac_latent', true) arg.setDisplayName('Plug Loads: Other Latent Fraction') arg.setDescription("Fraction of other residual plug loads' internal gains that are latent.") arg.setUnits('Frac') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('plug_loads_other_usage_multiplier', true) arg.setDisplayName('Plug Loads: Other Usage Multiplier') arg.setDescription('Multiplier on the other energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('plug_loads_well_pump_present', true) arg.setDisplayName('Plug Loads: Well Pump Present') arg.setDescription('Whether there is a well pump.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('plug_loads_well_pump_annual_kwh', true) arg.setDisplayName('Plug Loads: Well Pump Annual kWh') arg.setDescription('The annual energy consumption of the well pump plug loads.') arg.setUnits('kWh/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('plug_loads_well_pump_usage_multiplier', true) arg.setDisplayName('Plug Loads: Well Pump Usage Multiplier') arg.setDescription('Multiplier on the well pump energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('plug_loads_vehicle_present', true) arg.setDisplayName('Plug Loads: Vehicle Present') arg.setDescription('Whether there is an electric vehicle.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('plug_loads_vehicle_annual_kwh', true) arg.setDisplayName('Plug Loads: Vehicle Annual kWh') arg.setDescription('The annual energy consumption of the electric vehicle plug loads.') arg.setUnits('kWh/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('plug_loads_vehicle_usage_multiplier', true) arg.setDisplayName('Plug Loads: Vehicle Usage Multiplier') arg.setDescription('Multiplier on the electric vehicle energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg fuel_loads_fuel_choices = OpenStudio::StringVector.new fuel_loads_fuel_choices << HPXML::FuelTypeNaturalGas fuel_loads_fuel_choices << HPXML::FuelTypeOil fuel_loads_fuel_choices << HPXML::FuelTypePropane fuel_loads_fuel_choices << HPXML::FuelTypeWoodCord fuel_loads_fuel_choices << HPXML::FuelTypeWoodPellets fuel_loads_location_choices = OpenStudio::StringVector.new fuel_loads_location_choices << Constants.Auto fuel_loads_location_choices << HPXML::LocationInterior fuel_loads_location_choices << HPXML::LocationExterior arg = OpenStudio::Measure::OSArgument::makeBoolArgument('fuel_loads_grill_present', true) arg.setDisplayName('Fuel Loads: Grill Present') arg.setDescription('Whether there is a fuel loads grill.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('fuel_loads_grill_fuel_type', fuel_loads_fuel_choices, true) arg.setDisplayName('Fuel Loads: Grill Fuel Type') arg.setDescription('The fuel type of the fuel loads grill.') arg.setDefaultValue(HPXML::FuelTypeNaturalGas) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('fuel_loads_grill_annual_therm', true) arg.setDisplayName('Fuel Loads: Grill Annual therm') arg.setDescription('The annual energy consumption of the fuel loads grill.') arg.setUnits('therm/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('fuel_loads_grill_usage_multiplier', true) arg.setDisplayName('Fuel Loads: Grill Usage Multiplier') arg.setDescription('Multiplier on the fuel loads grill energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(0.0) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('fuel_loads_lighting_present', true) arg.setDisplayName('Fuel Loads: Lighting Present') arg.setDescription('Whether there is fuel loads lighting.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('fuel_loads_lighting_fuel_type', fuel_loads_fuel_choices, true) arg.setDisplayName('Fuel Loads: Lighting Fuel Type') arg.setDescription('The fuel type of the fuel loads lighting.') arg.setDefaultValue(HPXML::FuelTypeNaturalGas) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('fuel_loads_lighting_annual_therm', true) arg.setDisplayName('Fuel Loads: Lighting Annual therm') arg.setDescription('The annual energy consumption of the fuel loads lighting.') arg.setUnits('therm/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('fuel_loads_lighting_usage_multiplier', true) arg.setDisplayName('Fuel Loads: Lighting Usage Multiplier') arg.setDescription('Multiplier on the fuel loads lighting energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(0.0) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('fuel_loads_fireplace_present', true) arg.setDisplayName('Fuel Loads: Fireplace Present') arg.setDescription('Whether there is fuel loads fireplace.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('fuel_loads_fireplace_fuel_type', fuel_loads_fuel_choices, true) arg.setDisplayName('Fuel Loads: Fireplace Fuel Type') arg.setDescription('The fuel type of the fuel loads fireplace.') arg.setDefaultValue(HPXML::FuelTypeNaturalGas) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('fuel_loads_fireplace_annual_therm', true) arg.setDisplayName('Fuel Loads: Fireplace Annual therm') arg.setDescription('The annual energy consumption of the fuel loads fireplace.') arg.setUnits('therm/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('fuel_loads_fireplace_frac_sensible', true) arg.setDisplayName('Fuel Loads: Fireplace Sensible Fraction') arg.setDescription("Fraction of fireplace residual fuel loads' internal gains that are sensible.") arg.setUnits('Frac') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('fuel_loads_fireplace_frac_latent', true) arg.setDisplayName('Fuel Loads: Fireplace Latent Fraction') arg.setDescription("Fraction of fireplace residual fuel loads' internal gains that are latent.") arg.setUnits('Frac') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('fuel_loads_fireplace_usage_multiplier', true) arg.setDisplayName('Fuel Loads: Fireplace Usage Multiplier') arg.setDescription('Multiplier on the fuel loads fireplace energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(0.0) args << arg heater_type_choices = OpenStudio::StringVector.new heater_type_choices << HPXML::TypeNone heater_type_choices << HPXML::HeaterTypeElectricResistance heater_type_choices << HPXML::HeaterTypeGas heater_type_choices << HPXML::HeaterTypeHeatPump arg = OpenStudio::Measure::OSArgument::makeBoolArgument('pool_present', true) arg.setDisplayName('Pool: Present') arg.setDescription('Whether there is a pool.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('pool_pump_annual_kwh', true) arg.setDisplayName('Pool: Pump Annual kWh') arg.setDescription('The annual energy consumption of the pool pump.') arg.setUnits('kWh/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('pool_pump_usage_multiplier', true) arg.setDisplayName('Pool: Pump Usage Multiplier') arg.setDescription('Multiplier on the pool pump energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('pool_heater_type', heater_type_choices, true) arg.setDisplayName('Pool: Heater Type') arg.setDescription("The type of pool heater. Use 'none' if there is no pool heater.") arg.setDefaultValue(HPXML::TypeNone) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('pool_heater_annual_kwh', true) arg.setDisplayName('Pool: Heater Annual kWh') arg.setDescription("The annual energy consumption of the #{HPXML::HeaterTypeElectricResistance} pool heater.") arg.setUnits('kWh/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('pool_heater_annual_therm', true) arg.setDisplayName('Pool: Heater Annual therm') arg.setDescription("The annual energy consumption of the #{HPXML::HeaterTypeGas} pool heater.") arg.setUnits('therm/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('pool_heater_usage_multiplier', true) arg.setDisplayName('Pool: Heater Usage Multiplier') arg.setDescription('Multiplier on the pool heater energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeBoolArgument('hot_tub_present', true) arg.setDisplayName('Hot Tub: Present') arg.setDescription('Whether there is a hot tub.') arg.setDefaultValue(false) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('hot_tub_pump_annual_kwh', true) arg.setDisplayName('Hot Tub: Pump Annual kWh') arg.setDescription('The annual energy consumption of the hot tub pump.') arg.setUnits('kWh/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('hot_tub_pump_usage_multiplier', true) arg.setDisplayName('Hot Tub: Pump Usage Multiplier') arg.setDescription('Multiplier on the hot tub pump energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('hot_tub_heater_type', heater_type_choices, true) arg.setDisplayName('Hot Tub: Heater Type') arg.setDescription("The type of hot tub heater. Use 'none' if there is no hot tub heater.") arg.setDefaultValue(HPXML::TypeNone) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('hot_tub_heater_annual_kwh', true) arg.setDisplayName('Hot Tub: Heater Annual kWh') arg.setDescription("The annual energy consumption of the #{HPXML::HeaterTypeElectricResistance} hot tub heater.") arg.setUnits('kWh/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeStringArgument('hot_tub_heater_annual_therm', true) arg.setDisplayName('Hot Tub: Heater Annual therm') arg.setDescription("The annual energy consumption of the #{HPXML::HeaterTypeGas} hot tub heater.") arg.setUnits('therm/yr') arg.setDefaultValue(Constants.Auto) args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('hot_tub_heater_usage_multiplier', true) arg.setDisplayName('Hot Tub: Heater Usage Multiplier') arg.setDescription('Multiplier on the hot tub heater energy usage that can reflect, e.g., high/low usage occupants.') arg.setDefaultValue(1.0) args << arg return args end # define what happens when the measure is run def run(model, runner, user_arguments) super(model, runner, user_arguments) # use the built-in error checking if !runner.validateUserArguments(arguments(model), user_arguments) return false end Geometry.tear_down_model(model, runner) Version.check_openstudio_version() # assign the user inputs to variables args = get_argument_values(runner, arguments(model), user_arguments) args = Hash[args.collect { |k, v| [k.to_sym, v] }] args[:geometry_rim_joist_height] /= 12.0 args[:geometry_roof_pitch] = { '1:12' => 1.0 / 12.0, '2:12' => 2.0 / 12.0, '3:12' => 3.0 / 12.0, '4:12' => 4.0 / 12.0, '5:12' => 5.0 / 12.0, '6:12' => 6.0 / 12.0, '7:12' => 7.0 / 12.0, '8:12' => 8.0 / 12.0, '9:12' => 9.0 / 12.0, '10:12' => 10.0 / 12.0, '11:12' => 11.0 / 12.0, '12:12' => 12.0 / 12.0 }[args[:geometry_roof_pitch]] # Argument error checks warnings, errors = validate_arguments(args) unless warnings.empty? warnings.each do |warning| runner.registerWarning(warning) end end unless errors.empty? errors.each do |error| runner.registerError(error) end return false end # Create EpwFile object epw_path = args[:weather_station_epw_filepath] if not File.exist? epw_path epw_path = File.join(File.expand_path(File.join(File.dirname(__FILE__), '..', 'weather')), epw_path) # a filename was entered for weather_station_epw_filepath end if not File.exist? epw_path runner.registerError("Could not find EPW file at '#{epw_path}'.") return false end epw_file = OpenStudio::EpwFile.new(epw_path) # Create HPXML file hpxml_doc = HPXMLFile.create(runner, model, args, epw_file) if not hpxml_doc runner.registerError('Unsuccessful creation of HPXML file.') return false end hpxml_path = args[:hpxml_path] unless (Pathname.new hpxml_path).absolute? hpxml_path = File.expand_path(File.join(File.dirname(__FILE__), hpxml_path)) end # Check for invalid HPXML file skip_validation = false if not skip_validation if not validate_hpxml(runner, hpxml_path, hpxml_doc) return false end end XMLHelper.write_file(hpxml_doc, hpxml_path) runner.registerInfo("Wrote file: #{hpxml_path}") end def validate_arguments(args) warnings = [] errors = [] # heat pump water heater with natural gas fuel type warning = ([HPXML::WaterHeaterTypeHeatPump].include?(args[:water_heater_type]) && (args[:water_heater_fuel_type] != HPXML::FuelTypeElectricity)) warnings << "water_heater_type=#{args[:water_heater_type]} and water_heater_fuel_type=#{args[:water_heater_fuel_type]}" if warning # heating system and heat pump error = (args[:heating_system_type] != 'none') && (args[:heat_pump_type] != 'none') && (args[:heating_system_fraction_heat_load_served] > 0) && (args[:heat_pump_fraction_heat_load_served] > 0) errors << "heating_system_type=#{args[:heating_system_type]} and heat_pump_type=#{args[:heat_pump_type]}" if error # cooling system and heat pump error = (args[:cooling_system_type] != 'none') && (args[:heat_pump_type] != 'none') && (args[:cooling_system_fraction_cool_load_served] > 0) && (args[:heat_pump_fraction_cool_load_served] > 0) errors << "cooling_system_type=#{args[:cooling_system_type]} and heat_pump_type=#{args[:heat_pump_type]}" if error # non integer number of bathrooms if args[:geometry_num_bathrooms] != Constants.Auto error = (Float(args[:geometry_num_bathrooms]) % 1 != 0) errors << "geometry_num_bathrooms=#{args[:geometry_num_bathrooms]}" if error end # non integer ceiling fan quantity if args[:ceiling_fan_quantity] != Constants.Auto error = (Float(args[:ceiling_fan_quantity]) % 1 != 0) errors << "ceiling_fan_quantity=#{args[:ceiling_fan_quantity]}" if error end # single-family, slab, foundation height > 0 warning = [HPXML::ResidentialTypeSFD, HPXML::ResidentialTypeSFA].include?(args[:geometry_unit_type]) && (args[:geometry_foundation_type] == HPXML::FoundationTypeSlab) && (args[:geometry_foundation_height] > 0) warnings << "geometry_unit_type=#{args[:geometry_unit_type]} and geometry_foundation_type=#{args[:geometry_foundation_type]} and geometry_foundation_height=#{args[:geometry_foundation_height]}" if warning # single-family, non slab, foundation height = 0 error = [HPXML::ResidentialTypeSFD, HPXML::ResidentialTypeSFA].include?(args[:geometry_unit_type]) && (args[:geometry_foundation_type] != HPXML::FoundationTypeSlab) && (args[:geometry_foundation_height] == 0) errors << "geometry_unit_type=#{args[:geometry_unit_type]} and geometry_foundation_type=#{args[:geometry_foundation_type]} and geometry_foundation_height=#{args[:geometry_foundation_height]}" if error # single-family attached, multifamily and ambient foundation error = [HPXML::ResidentialTypeSFA, HPXML::ResidentialTypeApartment].include?(args[:geometry_unit_type]) && (args[:geometry_foundation_type] == HPXML::FoundationTypeAmbient) errors << "geometry_unit_type=#{args[:geometry_unit_type]} and geometry_foundation_type=#{args[:geometry_foundation_type]}" if error # multifamily, bottom, slab, foundation height > 0 if args[:geometry_level].is_initialized warning = (args[:geometry_unit_type] == HPXML::ResidentialTypeApartment) && (args[:geometry_level].get == 'Bottom') && (args[:geometry_foundation_type] == HPXML::FoundationTypeSlab) && (args[:geometry_foundation_height] > 0) warnings << "geometry_unit_type=#{args[:geometry_unit_type]} and geometry_level=#{args[:geometry_level].get} and geometry_foundation_type=#{args[:geometry_foundation_type]} and geometry_foundation_height=#{args[:geometry_foundation_height]}" if warning end # multifamily, bottom, non slab, foundation height = 0 if args[:geometry_level].is_initialized error = (args[:geometry_unit_type] == HPXML::ResidentialTypeApartment) && (args[:geometry_level].get == 'Bottom') && (args[:geometry_foundation_type] != HPXML::FoundationTypeSlab) && (args[:geometry_foundation_height] == 0) errors << "geometry_unit_type=#{args[:geometry_unit_type]} and geometry_level=#{args[:geometry_level].get} and geometry_foundation_type=#{args[:geometry_foundation_type]} and geometry_foundation_height=#{args[:geometry_foundation_height]}" if error end # multifamily and finished basement error = (args[:geometry_unit_type] == HPXML::ResidentialTypeApartment) && (args[:geometry_foundation_type] == HPXML::FoundationTypeBasementConditioned) errors << "geometry_unit_type=#{args[:geometry_unit_type]} and geometry_foundation_type=#{args[:geometry_foundation_type]}" if error # slab and foundation height above grade > 0 warning = (args[:geometry_foundation_type] == HPXML::FoundationTypeSlab) && (args[:geometry_foundation_height_above_grade] > 0) warnings << "geometry_foundation_type=#{args[:geometry_foundation_type]} and geometry_foundation_height_above_grade=#{args[:geometry_foundation_height_above_grade]}" if warning # duct location and surface area not both auto or not both specified error = ((args[:ducts_supply_location] == Constants.Auto) && (args[:ducts_supply_surface_area] != Constants.Auto)) || ((args[:ducts_supply_location] != Constants.Auto) && (args[:ducts_supply_surface_area] == Constants.Auto)) || ((args[:ducts_return_location] == Constants.Auto) && (args[:ducts_return_surface_area] != Constants.Auto)) || ((args[:ducts_return_location] != Constants.Auto) && (args[:ducts_return_surface_area] == Constants.Auto)) errors << "ducts_supply_location=#{args[:ducts_supply_location]} and ducts_supply_surface_area=#{args[:ducts_supply_surface_area]} and ducts_return_location=#{args[:ducts_return_location]} and ducts_return_surface_area=#{args[:ducts_return_surface_area]}" if error # second heating system fraction heat load served non less than 50% warning = (args[:heating_system_type_2] != 'none') && (args[:heating_system_fraction_heat_load_served_2] >= 0.5) && (args[:heating_system_fraction_heat_load_served_2] < 1.0) warnings << "heating_system_type_2=#{args[:heating_system_type_2]} and heating_system_fraction_heat_load_served_2=#{args[:heating_system_fraction_heat_load_served_2]}" if warning # second heating system fraction heat load served is 100% error = (args[:heating_system_type_2] != 'none') && (args[:heating_system_fraction_heat_load_served_2] == 1.0) errors << "heating_system_type_2=#{args[:heating_system_type_2]} and heating_system_fraction_heat_load_served_2=#{args[:heating_system_fraction_heat_load_served_2]}" if error # second heating system but no primary heating system error = (args[:heating_system_type] == 'none') && (args[:heat_pump_type] == 'none') && (args[:heating_system_type_2] != 'none') errors << "heating_system_type=#{args[:heating_system_type]} and heat_pump_type=#{args[:heat_pump_type]} and heating_system_type_2=#{args[:heating_system_type_2]}" if error # single-family attached and num units, horizontal location not specified error = (args[:geometry_unit_type] == HPXML::ResidentialTypeSFA) && (!args[:geometry_building_num_units].is_initialized || !args[:geometry_horizontal_location].is_initialized) errors << "geometry_unit_type=#{args[:geometry_unit_type]} and geometry_building_num_units=#{args[:geometry_building_num_units].is_initialized} and geometry_horizontal_location=#{args[:geometry_horizontal_location].is_initialized}" if error # apartment unit and num units, level, horizontal location not specified error = (args[:geometry_unit_type] == HPXML::ResidentialTypeApartment) && (!args[:geometry_building_num_units].is_initialized || !args[:geometry_level].is_initialized || !args[:geometry_horizontal_location].is_initialized) errors << "geometry_unit_type=#{args[:geometry_unit_type]} and geometry_building_num_units=#{args[:geometry_building_num_units].is_initialized} and geometry_level=#{args[:geometry_level].is_initialized} and geometry_horizontal_location=#{args[:geometry_horizontal_location].is_initialized}" if error # crawlspace or unconditioned basement with foundation wall and ceiling insulation warning = [HPXML::FoundationTypeCrawlspaceVented, HPXML::FoundationTypeCrawlspaceUnvented, HPXML::FoundationTypeBasementUnconditioned].include?(args[:geometry_foundation_type]) && ((args[:foundation_wall_insulation_r] > 0) || (args[:foundation_wall_assembly_r].is_initialized && (args[:foundation_wall_assembly_r].get > 0))) && (args[:floor_assembly_r] > 2.1) warnings << "geometry_foundation_type=#{args[:geometry_foundation_type]} and foundation_wall_insulation_r=#{args[:foundation_wall_insulation_r]} and foundation_wall_assembly_r=#{args[:foundation_wall_assembly_r].is_initialized} and floor_assembly_r=#{args[:floor_assembly_r]}" if warning # vented/unvented attic with floor and roof insulation warning = [HPXML::AtticTypeVented, HPXML::AtticTypeUnvented].include?(args[:geometry_attic_type]) && (args[:geometry_roof_type] != 'flat') && (args[:ceiling_assembly_r] > 2.1) && (args[:roof_assembly_r] > 2.3) warnings << "geometry_attic_type=#{args[:geometry_attic_type]} and ceiling_assembly_r=#{args[:ceiling_assembly_r]} and roof_assembly_r=#{args[:roof_assembly_r]}" if warning # conditioned basement with ceiling insulation warning = (args[:geometry_foundation_type] == HPXML::FoundationTypeBasementConditioned) && (args[:floor_assembly_r] > 2.1) warnings << "geometry_foundation_type=#{args[:geometry_foundation_type]} and floor_assembly_r=#{args[:floor_assembly_r]}" if warning # conditioned attic with floor insulation warning = (args[:geometry_attic_type] == HPXML::AtticTypeConditioned) && (args[:geometry_roof_type] != 'flat') && (args[:ceiling_assembly_r] > 2.1) warnings << "geometry_attic_type=#{args[:geometry_attic_type]} and ceiling_assembly_r=#{args[:ceiling_assembly_r]}" if warning # conditioned attic but only one above-grade floor error = (args[:geometry_num_floors_above_grade] == 1 && args[:geometry_attic_type] == HPXML::AtticTypeConditioned) errors << "geometry_num_floors_above_grade=#{args[:geometry_num_floors_above_grade]} and geometry_attic_type=#{args[:geometry_attic_type]}" if error # dhw indirect but no boiler error = ((args[:water_heater_type] == HPXML::WaterHeaterTypeCombiStorage) || (args[:water_heater_type] == HPXML::WaterHeaterTypeCombiTankless)) && (args[:heating_system_type] != HPXML::HVACTypeBoiler) errors << "water_heater_type=#{args[:water_heater_type]} and heating_system_type=#{args[:heating_system_type]}" if error # no tv plug loads but specifying usage multipliers if args[:plug_loads_television_annual_kwh] != Constants.Auto warning = (args[:plug_loads_television_annual_kwh].to_f == 0.0 && args[:plug_loads_television_usage_multiplier] != 0.0) warnings << "plug_loads_television_annual_kwh=#{args[:plug_loads_television_annual_kwh]} and plug_loads_television_usage_multiplier=#{args[:plug_loads_television_usage_multiplier]}" if warning end # no other plug loads but specifying usage multipliers if args[:plug_loads_other_annual_kwh] != Constants.Auto warning = (args[:plug_loads_other_annual_kwh].to_f == 0.0 && args[:plug_loads_other_usage_multiplier] != 0.0) warnings << "plug_loads_other_annual_kwh=#{args[:plug_loads_other_annual_kwh]} and plug_loads_other_usage_multiplier=#{args[:plug_loads_other_usage_multiplier]}" if warning end # no well pump plug loads but specifying usage multipliers if args[:plug_loads_well_pump_annual_kwh] != Constants.Auto warning = (args[:plug_loads_well_pump_annual_kwh].to_f == 0.0 && args[:plug_loads_well_pump_usage_multiplier] != 0.0) warnings << "plug_loads_well_pump_annual_kwh=#{args[:plug_loads_well_pump_annual_kwh]} and plug_loads_well_pump_usage_multiplier=#{args[:plug_loads_well_pump_usage_multiplier]}" if warning end # no vehicle plug loads but specifying usage multipliers if args[:plug_loads_vehicle_annual_kwh] != Constants.Auto warning = (args[:plug_loads_vehicle_annual_kwh].to_f && args[:plug_loads_vehicle_usage_multiplier] != 0.0) warnings << "plug_loads_vehicle_annual_kwh=#{args[:plug_loads_vehicle_annual_kwh]} and plug_loads_vehicle_usage_multiplier=#{args[:plug_loads_vehicle_usage_multiplier]}" if warning end # no fuel loads but specifying usage multipliers warning = (!args[:fuel_loads_grill_present] && args[:fuel_loads_grill_usage_multiplier] != 0.0) || (!args[:fuel_loads_lighting_present] && args[:fuel_loads_lighting_usage_multiplier] != 0.0) || (!args[:fuel_loads_fireplace_present] && args[:fuel_loads_fireplace_usage_multiplier] != 0.0) warnings << "fuel_loads_grill_present=#{args[:fuel_loads_grill_present]} and fuel_loads_grill_usage_multiplier=#{args[:fuel_loads_grill_usage_multiplier]} and fuel_loads_lighting_present=#{args[:fuel_loads_lighting_present]} and fuel_loads_lighting_usage_multiplier=#{args[:fuel_loads_lighting_usage_multiplier]} and fuel_loads_fireplace_present=#{args[:fuel_loads_fireplace_present]} and fuel_loads_fireplace_usage_multiplier=#{args[:fuel_loads_fireplace_usage_multiplier]}" if warning # foundation wall insulation distance to bottom is greater than foundation wall height if args[:foundation_wall_insulation_distance_to_bottom] != Constants.Auto error = (args[:foundation_wall_insulation_distance_to_bottom].to_f > args[:geometry_foundation_height]) errors << "foundation_wall_insulation_distance_to_bottom=#{args[:foundation_wall_insulation_distance_to_bottom]} and geometry_foundation_height=#{args[:geometry_foundation_height]}" if error end # number of bedrooms not greater than zero error = (args[:geometry_num_bedrooms] <= 0) errors << "geometry_num_bedrooms=#{args[:geometry_num_bedrooms]}" if error # single-family detached with shared system error = [HPXML::ResidentialTypeSFD].include?(args[:geometry_unit_type]) && args[:heating_system_type].include?('Shared') errors << "geometry_unit_type=#{args[:geometry_unit_type]} and heating_system_type=#{args[:heating_system_type]}" if error return warnings, errors end def validate_hpxml(runner, hpxml_path, hpxml_doc) schemas_dir = File.join(File.dirname(__FILE__), '../HPXMLtoOpenStudio/resources') is_valid = true # Validate input HPXML against schema XMLHelper.validate(hpxml_doc.to_xml, File.join(schemas_dir, 'HPXML.xsd'), runner).each do |error| runner.registerError("#{hpxml_path}: #{error}") is_valid = false end # Validate input HPXML against schematron docs stron_paths = [File.join(schemas_dir, 'HPXMLvalidator.xml'), File.join(schemas_dir, 'EPvalidator.xml')] errors, warnings = Validator.run_validators(hpxml_doc, stron_paths) errors.each do |error| runner.registerError("#{hpxml_path}: #{error}") is_valid = false end warnings.each do |warning| runner.registerWarning("#{warning}") end return is_valid end end class HPXMLFile def self.create(runner, model, args, epw_file) success = create_geometry_envelope(runner, model, args) return false if not success success = create_schedules(runner, model, epw_file, args) return false if not success hpxml = HPXML.new set_header(hpxml, runner, args, epw_file) set_site(hpxml, runner, args) set_neighbor_buildings(hpxml, runner, args) set_building_occupancy(hpxml, runner, args) set_building_construction(hpxml, runner, args) set_climate_and_risk_zones(hpxml, runner, args, epw_file) set_air_infiltration_measurements(hpxml, runner, args) set_attics(hpxml, runner, model, args) set_foundations(hpxml, runner, model, args) set_roofs(hpxml, runner, model, args) set_rim_joists(hpxml, runner, model, args) set_walls(hpxml, runner, model, args) set_foundation_walls(hpxml, runner, model, args) set_frame_floors(hpxml, runner, model, args) set_slabs(hpxml, runner, model, args) set_windows(hpxml, runner, model, args) set_skylights(hpxml, runner, model, args) set_doors(hpxml, runner, model, args) set_heating_systems(hpxml, runner, args) set_cooling_systems(hpxml, runner, args) set_heat_pumps(hpxml, runner, args) set_secondary_heating_systems(hpxml, runner, args) set_hvac_distribution(hpxml, runner, args) set_hvac_control(hpxml, runner, args) set_ventilation_fans(hpxml, runner, args) set_water_heating_systems(hpxml, runner, args) set_hot_water_distribution(hpxml, runner, args) set_water_fixtures(hpxml, runner, args) set_solar_thermal(hpxml, runner, args, epw_file) set_pv_systems(hpxml, runner, args, epw_file) set_lighting(hpxml, runner, args) set_dehumidifier(hpxml, runner, args) set_clothes_washer(hpxml, runner, args) set_clothes_dryer(hpxml, runner, args) set_dishwasher(hpxml, runner, args) set_refrigerator(hpxml, runner, args) set_extra_refrigerator(hpxml, runner, args) set_freezer(hpxml, runner, args) set_cooking_range_oven(hpxml, runner, args) set_ceiling_fans(hpxml, runner, args) set_plug_loads_television(hpxml, runner, args) set_plug_loads_other(hpxml, runner, args) set_plug_loads_well_pump(hpxml, runner, args) set_plug_loads_vehicle(hpxml, runner, args) set_fuel_loads_grill(hpxml, runner, args) set_fuel_loads_lighting(hpxml, runner, args) set_fuel_loads_fireplace(hpxml, runner, args) set_pool(hpxml, runner, args) set_hot_tub(hpxml, runner, args) # Check for errors in the HPXML object errors = hpxml.check_for_errors() if errors.size > 0 fail "ERROR: Invalid HPXML object produced.\n#{errors}" end hpxml_doc = hpxml.to_oga() return hpxml_doc end def self.create_geometry_envelope(runner, model, args) if args[:geometry_foundation_type] == HPXML::FoundationTypeSlab args[:geometry_foundation_height] = 0.0 args[:geometry_foundation_height_above_grade] = 0.0 args[:geometry_rim_joist_height] = 0.0 elsif args[:geometry_foundation_type] == HPXML::FoundationTypeAmbient args[:geometry_rim_joist_height] = 0.0 end if args[:geometry_attic_type] == HPXML::AtticTypeConditioned args[:geometry_num_floors_above_grade] -= 1 end if args[:geometry_unit_type] == HPXML::ResidentialTypeSFD success = Geometry.create_single_family_detached(runner: runner, model: model, **args) elsif args[:geometry_unit_type] == HPXML::ResidentialTypeSFA success = Geometry.create_single_family_attached(runner: runner, model: model, **args) elsif args[:geometry_unit_type] == HPXML::ResidentialTypeApartment args[:geometry_roof_type] = 'flat' args[:geometry_attic_type] = HPXML::AtticTypeVented success = Geometry.create_multifamily(runner: runner, model: model, **args) end return false if not success success = Geometry.create_windows_and_skylights(runner: runner, model: model, **args) return false if not success success = Geometry.create_doors(runner: runner, model: model, **args) return false if not success return true end def self.create_schedules(runner, model, epw_file, args) if ['default', 'user-specified'].include? args[:schedules_type] if args[:schedules_type] == 'user-specified' args[:schedules_path] = args[:schedules_path].get else args[:schedules_path] = nil end return true end info_msgs = [] # set the calendar year year_description = model.getYearDescription year_description.setCalendarYear(2007) # default to TMY if args[:simulation_control_run_period_calendar_year].is_initialized year_description.setCalendarYear(args[:simulation_control_run_period_calendar_year].get) end if epw_file.startDateActualYear.is_initialized # AMY year_description.setCalendarYear(epw_file.startDateActualYear.get) end info_msgs << "CalendarYear=#{year_description.calendarYear}" # set the timestep timestep = model.getTimestep timestep.setNumberOfTimestepsPerHour(1) if args[:simulation_control_timestep].is_initialized timestep.setNumberOfTimestepsPerHour(60 / args[:simulation_control_timestep].get) end info_msgs << "NumberOfTimestepsPerHour=#{timestep.numberOfTimestepsPerHour}" # get the seed random_seed = args[:schedules_random_seed].get if args[:schedules_random_seed].is_initialized # instantiate the generator schedule_generator = ScheduleGenerator.new(runner: runner, model: model, epw_file: epw_file, random_seed: random_seed) # create the schedule if args[:geometry_num_occupants] == Constants.Auto args[:geometry_num_occupants] = Geometry.get_occupancy_default_num(args[:geometry_num_bedrooms]) else args[:geometry_num_occupants] = Integer(args[:geometry_num_occupants]) end args[:resources_path] = File.join(File.dirname(__FILE__), 'resources') success = schedule_generator.create(args: args) return false if not success # export the schedule args[:schedules_path] = "../#{File.basename(args[:hpxml_path], '.xml')}_schedules.csv" success = schedule_generator.export(schedules_path: File.expand_path(args[:schedules_path])) return false if not success runner.registerInfo("Created schedule with #{info_msgs.join(', ')}") return true end def self.set_header(hpxml, runner, args, epw_file) hpxml.header.xml_type = 'HPXML' hpxml.header.xml_generated_by = 'BuildResidentialHPXML' hpxml.header.transaction = 'create' if args[:software_program_used].is_initialized hpxml.header.software_program_used = args[:software_program_used].get end if args[:software_program_version].is_initialized hpxml.header.software_program_version = args[:software_program_version].get end if args[:simulation_control_timestep].is_initialized hpxml.header.timestep = args[:simulation_control_timestep].get end if args[:simulation_control_run_period_begin_month].is_initialized hpxml.header.sim_begin_month = args[:simulation_control_run_period_begin_month].get end if args[:simulation_control_run_period_begin_day_of_month].is_initialized hpxml.header.sim_begin_day = args[:simulation_control_run_period_begin_day_of_month].get end if args[:simulation_control_run_period_end_month].is_initialized hpxml.header.sim_end_month = args[:simulation_control_run_period_end_month].get end if args[:simulation_control_run_period_end_day_of_month].is_initialized hpxml.header.sim_end_day = args[:simulation_control_run_period_end_day_of_month].get end if args[:simulation_control_run_period_calendar_year].is_initialized hpxml.header.sim_calendar_year = args[:simulation_control_run_period_calendar_year].get end if args[:simulation_control_daylight_saving_enabled].is_initialized hpxml.header.dst_enabled = args[:simulation_control_daylight_saving_enabled].get end if args[:simulation_control_daylight_saving_begin_month].is_initialized hpxml.header.dst_begin_month = args[:simulation_control_daylight_saving_begin_month].get end if args[:simulation_control_daylight_saving_begin_day_of_month].is_initialized hpxml.header.dst_begin_day = args[:simulation_control_daylight_saving_begin_day_of_month].get end if args[:simulation_control_daylight_saving_end_month].is_initialized hpxml.header.dst_end_month = args[:simulation_control_daylight_saving_end_month].get end if args[:simulation_control_daylight_saving_end_day_of_month].is_initialized hpxml.header.dst_end_day = args[:simulation_control_daylight_saving_end_day_of_month].get end hpxml.header.building_id = 'MyBuilding' hpxml.header.state_code = epw_file.stateProvinceRegion hpxml.header.event_type = 'proposed workscope' hpxml.header.schedules_path = args[:schedules_path] end def self.set_site(hpxml, runner, args) if args[:air_leakage_shielding_of_home] != Constants.Auto shielding_of_home = args[:air_leakage_shielding_of_home] end if args[:site_type].is_initialized hpxml.site.site_type = args[:site_type].get end hpxml.site.shielding_of_home = shielding_of_home end def self.set_neighbor_buildings(hpxml, runner, args) nbr_map = { Constants.FacadeFront => [args[:neighbor_front_distance], args[:neighbor_front_height]], Constants.FacadeBack => [args[:neighbor_back_distance], args[:neighbor_back_height]], Constants.FacadeLeft => [args[:neighbor_left_distance], args[:neighbor_left_height]], Constants.FacadeRight => [args[:neighbor_right_distance], args[:neighbor_right_height]] } nbr_map.each do |facade, data| distance, neighbor_height = data next if distance == 0 azimuth = get_azimuth_from_facade(facade, args) if (distance > 0) && (neighbor_height != Constants.Auto) height = Float(neighbor_height) end hpxml.neighbor_buildings.add(azimuth: azimuth, distance: distance, height: height) end end def self.set_building_occupancy(hpxml, runner, args) if args[:geometry_num_occupants] != Constants.Auto hpxml.building_occupancy.number_of_residents = args[:geometry_num_occupants] end end def self.set_building_construction(hpxml, runner, args) if args[:geometry_unit_type] == HPXML::ResidentialTypeApartment number_of_conditioned_floors_above_grade = 1 number_of_conditioned_floors = 1 else number_of_conditioned_floors_above_grade = args[:geometry_num_floors_above_grade] number_of_conditioned_floors = number_of_conditioned_floors_above_grade if args[:geometry_foundation_type] == HPXML::FoundationTypeBasementConditioned number_of_conditioned_floors += 1 end end if args[:geometry_num_bathrooms] != Constants.Auto number_of_bathrooms = args[:geometry_num_bathrooms] end conditioned_building_volume = args[:geometry_cfa] * args[:geometry_wall_height] hpxml.building_construction.number_of_conditioned_floors = number_of_conditioned_floors hpxml.building_construction.number_of_conditioned_floors_above_grade = number_of_conditioned_floors_above_grade hpxml.building_construction.number_of_bedrooms = args[:geometry_num_bedrooms] hpxml.building_construction.number_of_bathrooms = number_of_bathrooms hpxml.building_construction.conditioned_floor_area = args[:geometry_cfa] hpxml.building_construction.conditioned_building_volume = conditioned_building_volume hpxml.building_construction.average_ceiling_height = args[:geometry_wall_height] hpxml.building_construction.residential_facility_type = args[:geometry_unit_type] if args[:geometry_has_flue_or_chimney] != Constants.Auto has_flue_or_chimney = args[:geometry_has_flue_or_chimney] hpxml.building_construction.has_flue_or_chimney = has_flue_or_chimney end end def self.set_climate_and_risk_zones(hpxml, runner, args, epw_file) hpxml.climate_and_risk_zones.weather_station_id = 'WeatherStation' iecc_zone = Location.get_climate_zone_iecc(epw_file.wmoNumber) unless iecc_zone.nil? hpxml.climate_and_risk_zones.iecc_year = 2006 hpxml.climate_and_risk_zones.iecc_zone = iecc_zone end weather_station_name = File.basename(args[:weather_station_epw_filepath]).gsub('.epw', '') hpxml.climate_and_risk_zones.weather_station_name = weather_station_name hpxml.climate_and_risk_zones.weather_station_epw_filepath = args[:weather_station_epw_filepath] end def self.set_air_infiltration_measurements(hpxml, runner, args) if args[:air_leakage_units] == HPXML::UnitsACH house_pressure = args[:air_leakage_house_pressure] unit_of_measure = HPXML::UnitsACH elsif args[:air_leakage_units] == HPXML::UnitsCFM house_pressure = args[:air_leakage_house_pressure] unit_of_measure = HPXML::UnitsCFM elsif args[:air_leakage_units] == HPXML::UnitsACHNatural house_pressure = nil unit_of_measure = HPXML::UnitsACHNatural end infiltration_volume = args[:geometry_cfa] * args[:geometry_wall_height] hpxml.air_infiltration_measurements.add(id: 'InfiltrationMeasurement', house_pressure: house_pressure, unit_of_measure: unit_of_measure, air_leakage: args[:air_leakage_value], infiltration_volume: infiltration_volume) end def self.set_attics(hpxml, runner, model, args) return if args[:geometry_unit_type] == HPXML::ResidentialTypeApartment if args[:geometry_roof_type] == 'flat' hpxml.attics.add(id: HPXML::AtticTypeFlatRoof, attic_type: HPXML::AtticTypeFlatRoof) else hpxml.attics.add(id: args[:geometry_attic_type], attic_type: args[:geometry_attic_type]) end end def self.set_foundations(hpxml, runner, model, args) return if args[:geometry_unit_type] == HPXML::ResidentialTypeApartment hpxml.foundations.add(id: args[:geometry_foundation_type], foundation_type: args[:geometry_foundation_type]) end def self.set_roofs(hpxml, runner, model, args) args[:geometry_roof_pitch] *= 12.0 if args[:geometry_roof_type] == 'flat' args[:geometry_roof_pitch] = 0.0 end model.getSurfaces.sort.each do |surface| next unless ['Outdoors'].include? surface.outsideBoundaryCondition next if surface.surfaceType != 'RoofCeiling' interior_adjacent_to = get_adjacent_to(surface) next if [HPXML::LocationOtherHousingUnit].include? interior_adjacent_to if args[:roof_material_type].is_initialized roof_type = args[:roof_material_type].get end if args[:roof_color] != Constants.Auto roof_color = args[:roof_color] end radiant_barrier = args[:roof_radiant_barrier] if args[:roof_radiant_barrier] radiant_barrier_grade = args[:roof_radiant_barrier_grade] end if args[:geometry_roof_type] == 'flat' azimuth = nil else azimuth = get_surface_azimuth(surface, args) end hpxml.roofs.add(id: valid_attr(surface.name), interior_adjacent_to: get_adjacent_to(surface), azimuth: azimuth, area: UnitConversions.convert(surface.grossArea, 'm^2', 'ft^2').round, roof_type: roof_type, roof_color: roof_color, pitch: args[:geometry_roof_pitch], radiant_barrier: radiant_barrier, radiant_barrier_grade: radiant_barrier_grade, insulation_assembly_r_value: args[:roof_assembly_r]) end end def self.set_rim_joists(hpxml, runner, model, args) model.getSurfaces.sort.each do |surface| next if surface.surfaceType != 'Wall' next unless ['Outdoors', 'Adiabatic'].include? surface.outsideBoundaryCondition next unless Geometry.surface_is_rim_joist(surface, args[:geometry_rim_joist_height]) interior_adjacent_to = get_adjacent_to(surface) next unless [HPXML::LocationBasementConditioned, HPXML::LocationBasementUnconditioned, HPXML::LocationCrawlspaceUnvented, HPXML::LocationCrawlspaceVented].include? interior_adjacent_to exterior_adjacent_to = HPXML::LocationOutside if surface.outsideBoundaryCondition == 'Adiabatic' # can be adjacent to foundation space adjacent_surface = get_adiabatic_adjacent_surface(model, surface) if adjacent_surface.nil? # adjacent to a space that is not explicitly in the model unless [HPXML::ResidentialTypeSFD].include?(args[:geometry_unit_type]) exterior_adjacent_to = interior_adjacent_to if exterior_adjacent_to == HPXML::LocationLivingSpace # living adjacent to living exterior_adjacent_to = HPXML::LocationOtherHousingUnit end end else # adjacent to a space that is explicitly in the model, e.g., corridor exterior_adjacent_to = get_adjacent_to(adjacent_surface) end end if exterior_adjacent_to == HPXML::LocationOutside && args[:wall_siding_type].is_initialized siding = args[:wall_siding_type].get end if args[:wall_color] != Constants.Auto color = args[:wall_color] end if interior_adjacent_to == exterior_adjacent_to insulation_assembly_r_value = 4.0 # Uninsulated else insulation_assembly_r_value = args[:rim_joist_assembly_r] end hpxml.rim_joists.add(id: valid_attr(surface.name), exterior_adjacent_to: exterior_adjacent_to, interior_adjacent_to: interior_adjacent_to, area: UnitConversions.convert(surface.grossArea, 'm^2', 'ft^2').round(1), siding: siding, color: color, insulation_assembly_r_value: insulation_assembly_r_value) end end def self.get_unexposed_garage_perimeter(hpxml, args) # this is perimeter adjacent to a 100% protruding garage that is not exposed # we need this because it's difficult to set this surface to Adiabatic using our geometry methods if (args[:geometry_garage_protrusion] == 1.0) && (args[:geometry_garage_width] * args[:geometry_garage_depth] > 0) return args[:geometry_garage_width] end return 0 end def self.get_adiabatic_adjacent_surface(model, surface) return if surface.outsideBoundaryCondition != 'Adiabatic' adjacentSurfaceType = 'Wall' if surface.surfaceType == 'RoofCeiling' adjacentSurfaceType = 'Floor' elsif surface.surfaceType == 'Floor' adjacentSurfaceType = 'RoofCeiling' end model.getSurfaces.sort.each do |adjacent_surface| next if surface == adjacent_surface next if adjacent_surface.surfaceType != adjacentSurfaceType next if adjacent_surface.outsideBoundaryCondition != 'Adiabatic' next if Geometry.getSurfaceXValues([surface]) != Geometry.getSurfaceXValues([adjacent_surface]) next if Geometry.getSurfaceYValues([surface]) != Geometry.getSurfaceYValues([adjacent_surface]) next if Geometry.getSurfaceZValues([surface]) != Geometry.getSurfaceZValues([adjacent_surface]) return adjacent_surface end return end def self.set_walls(hpxml, runner, model, args) model.getSurfaces.sort.each do |surface| next if surface.surfaceType != 'Wall' next if Geometry.surface_is_rim_joist(surface, args[:geometry_rim_joist_height]) interior_adjacent_to = get_adjacent_to(surface) next unless [HPXML::LocationLivingSpace, HPXML::LocationAtticUnvented, HPXML::LocationAtticVented, HPXML::LocationGarage].include? interior_adjacent_to exterior_adjacent_to = HPXML::LocationOutside if surface.adjacentSurface.is_initialized exterior_adjacent_to = get_adjacent_to(surface.adjacentSurface.get) elsif surface.outsideBoundaryCondition == 'Adiabatic' # can be adjacent to living space, attic, corridor adjacent_surface = get_adiabatic_adjacent_surface(model, surface) if adjacent_surface.nil? # adjacent to a space that is not explicitly in the model exterior_adjacent_to = interior_adjacent_to if exterior_adjacent_to == HPXML::LocationLivingSpace # living adjacent to living exterior_adjacent_to = HPXML::LocationOtherHousingUnit end else # adjacent to a space that is explicitly in the model, e.g., corridor exterior_adjacent_to = get_adjacent_to(adjacent_surface) end end next if exterior_adjacent_to == HPXML::LocationLivingSpace # already captured these surfaces wall_type = args[:wall_type] if [HPXML::LocationAtticUnvented, HPXML::LocationAtticVented].include? interior_adjacent_to wall_type = HPXML::WallTypeWoodStud end if exterior_adjacent_to == HPXML::LocationOutside && args[:wall_siding_type].is_initialized siding = args[:wall_siding_type].get end if args[:wall_color] == Constants.Auto && args[:wall_solar_absorptance] == Constants.Auto solar_absorptance = 0.7 end if args[:wall_color] != Constants.Auto color = args[:wall_color] end if args[:wall_solar_absorptance] != Constants.Auto solar_absorptance = args[:wall_solar_absorptance] end if args[:wall_emittance] != Constants.Auto emittance = args[:wall_emittance] end azimuth = get_surface_azimuth(surface, args) hpxml.walls.add(id: valid_attr(surface.name), exterior_adjacent_to: exterior_adjacent_to, interior_adjacent_to: interior_adjacent_to, azimuth: azimuth, wall_type: wall_type, siding: siding, color: color, solar_absorptance: solar_absorptance, area: UnitConversions.convert(surface.grossArea, 'm^2', 'ft^2').round, emittance: emittance) is_uncond_attic_roof_insulated = false if [HPXML::LocationAtticUnvented, HPXML::LocationAtticVented].include? interior_adjacent_to hpxml.roofs.each do |roof| next unless (roof.interior_adjacent_to == interior_adjacent_to) && (roof.insulation_assembly_r_value > 4.0) is_uncond_attic_roof_insulated = true end end if hpxml.walls[-1].is_thermal_boundary || is_uncond_attic_roof_insulated # Assume wall is insulated if roof is insulated hpxml.walls[-1].insulation_assembly_r_value = args[:wall_assembly_r] else hpxml.walls[-1].insulation_assembly_r_value = 4.0 # Uninsulated end end end def self.set_foundation_walls(hpxml, runner, model, args) model.getSurfaces.sort.each do |surface| next if surface.surfaceType != 'Wall' next unless ['Foundation', 'Adiabatic'].include? surface.outsideBoundaryCondition next if Geometry.surface_is_rim_joist(surface, args[:geometry_rim_joist_height]) interior_adjacent_to = get_adjacent_to(surface) next unless [HPXML::LocationBasementConditioned, HPXML::LocationBasementUnconditioned, HPXML::LocationCrawlspaceUnvented, HPXML::LocationCrawlspaceVented].include? interior_adjacent_to exterior_adjacent_to = HPXML::LocationGround if surface.outsideBoundaryCondition == 'Adiabatic' # can be adjacent to foundation space adjacent_surface = get_adiabatic_adjacent_surface(model, surface) if adjacent_surface.nil? # adjacent to a space that is not explicitly in the model unless [HPXML::ResidentialTypeSFD].include?(args[:geometry_unit_type]) exterior_adjacent_to = interior_adjacent_to if exterior_adjacent_to == HPXML::LocationLivingSpace # living adjacent to living exterior_adjacent_to = HPXML::LocationOtherHousingUnit end end else # adjacent to a space that is explicitly in the model, e.g., corridor exterior_adjacent_to = get_adjacent_to(adjacent_surface) end end if args[:foundation_wall_assembly_r].is_initialized && (args[:foundation_wall_assembly_r].get > 0) insulation_assembly_r_value = args[:foundation_wall_assembly_r] else if interior_adjacent_to == exterior_adjacent_to # E.g., don't insulate wall between basement and neighbor basement insulation_exterior_r_value = 0 insulation_exterior_distance_to_top = 0 insulation_exterior_distance_to_bottom = 0 else insulation_exterior_r_value = args[:foundation_wall_insulation_r] insulation_exterior_distance_to_top = args[:foundation_wall_insulation_distance_to_top] insulation_exterior_distance_to_bottom = args[:foundation_wall_insulation_distance_to_bottom] if insulation_exterior_distance_to_bottom == Constants.Auto insulation_exterior_distance_to_bottom = args[:geometry_foundation_height] end end insulation_interior_r_value = 0 insulation_interior_distance_to_top = 0 insulation_interior_distance_to_bottom = 0 end if args[:foundation_wall_thickness] != Constants.Auto thickness = args[:foundation_wall_thickness] end hpxml.foundation_walls.add(id: valid_attr(surface.name), exterior_adjacent_to: exterior_adjacent_to, interior_adjacent_to: interior_adjacent_to, height: args[:geometry_foundation_height], area: UnitConversions.convert(surface.grossArea, 'm^2', 'ft^2').round, thickness: thickness, depth_below_grade: args[:geometry_foundation_height] - args[:geometry_foundation_height_above_grade], insulation_assembly_r_value: insulation_assembly_r_value, insulation_interior_r_value: insulation_interior_r_value, insulation_interior_distance_to_top: insulation_interior_distance_to_top, insulation_interior_distance_to_bottom: insulation_interior_distance_to_bottom, insulation_exterior_r_value: insulation_exterior_r_value, insulation_exterior_distance_to_top: insulation_exterior_distance_to_top, insulation_exterior_distance_to_bottom: insulation_exterior_distance_to_bottom) end end def self.set_frame_floors(hpxml, runner, model, args) if [HPXML::FoundationTypeBasementConditioned].include?(args[:geometry_foundation_type]) && (args[:floor_assembly_r] > 2.1) args[:floor_assembly_r] = 2.1 # Uninsulated end if [HPXML::AtticTypeConditioned].include?(args[:geometry_attic_type]) && (args[:geometry_roof_type] != 'flat') && (args[:ceiling_assembly_r] > 2.1) args[:ceiling_assembly_r] = 2.1 # Uninsulated end model.getSurfaces.sort.each do |surface| next if surface.outsideBoundaryCondition == 'Foundation' next unless ['Floor', 'RoofCeiling'].include? surface.surfaceType interior_adjacent_to = get_adjacent_to(surface) next unless [HPXML::LocationLivingSpace, HPXML::LocationGarage].include? interior_adjacent_to exterior_adjacent_to = HPXML::LocationOutside if surface.adjacentSurface.is_initialized exterior_adjacent_to = get_adjacent_to(surface.adjacentSurface.get) elsif surface.outsideBoundaryCondition == 'Adiabatic' exterior_adjacent_to = HPXML::LocationOtherHousingUnit if surface.surfaceType == 'Floor' other_space_above_or_below = HPXML::FrameFloorOtherSpaceBelow elsif surface.surfaceType == 'RoofCeiling' other_space_above_or_below = HPXML::FrameFloorOtherSpaceAbove end end next if interior_adjacent_to == exterior_adjacent_to next if (surface.surfaceType == 'RoofCeiling') && (exterior_adjacent_to == HPXML::LocationOutside) next if [HPXML::LocationLivingSpace, HPXML::LocationBasementConditioned].include? exterior_adjacent_to hpxml.frame_floors.add(id: valid_attr(surface.name), exterior_adjacent_to: exterior_adjacent_to, interior_adjacent_to: interior_adjacent_to, area: UnitConversions.convert(surface.grossArea, 'm^2', 'ft^2').round, other_space_above_or_below: other_space_above_or_below) if hpxml.frame_floors[-1].is_thermal_boundary if [HPXML::LocationAtticUnvented, HPXML::LocationAtticVented, HPXML::LocationGarage].include? exterior_adjacent_to hpxml.frame_floors[-1].insulation_assembly_r_value = args[:ceiling_assembly_r] else hpxml.frame_floors[-1].insulation_assembly_r_value = args[:floor_assembly_r] end else hpxml.frame_floors[-1].insulation_assembly_r_value = 2.1 # Uninsulated end end end def self.set_slabs(hpxml, runner, model, args) model.getSurfaces.sort.each do |surface| next unless ['Foundation'].include? surface.outsideBoundaryCondition next if surface.surfaceType != 'Floor' interior_adjacent_to = get_adjacent_to(surface) next if [HPXML::LocationOutside, HPXML::LocationOtherHousingUnit].include? interior_adjacent_to has_foundation_walls = false if [HPXML::LocationCrawlspaceVented, HPXML::LocationCrawlspaceUnvented, HPXML::LocationBasementUnconditioned, HPXML::LocationBasementConditioned].include? interior_adjacent_to has_foundation_walls = true end exposed_perimeter = Geometry.calculate_exposed_perimeter(model, [surface], has_foundation_walls).round next if exposed_perimeter == 0 # this could be, e.g., the foundation floor of an interior corridor if [HPXML::LocationCrawlspaceVented, HPXML::LocationCrawlspaceUnvented, HPXML::LocationBasementUnconditioned, HPXML::LocationBasementConditioned].include? interior_adjacent_to exposed_perimeter -= get_unexposed_garage_perimeter(hpxml, args) end if [HPXML::LocationLivingSpace, HPXML::LocationGarage].include? interior_adjacent_to depth_below_grade = 0 end if args[:slab_under_width] == 999 under_slab_insulation_spans_entire_slab = true else under_slab_insulation_width = args[:slab_under_width] end if args[:slab_thickness] != Constants.Auto thickness = args[:slab_thickness] end if interior_adjacent_to.include? 'crawlspace' thickness = 0.0 # Assume soil end if args[:slab_carpet_fraction] != Constants.Auto carpet_fraction = args[:slab_carpet_fraction] end if args[:slab_carpet_r] != Constants.Auto carpet_r_value = args[:slab_carpet_r] end hpxml.slabs.add(id: valid_attr(surface.name), interior_adjacent_to: interior_adjacent_to, area: UnitConversions.convert(surface.grossArea, 'm^2', 'ft^2').round, thickness: thickness, exposed_perimeter: exposed_perimeter, perimeter_insulation_depth: args[:slab_perimeter_depth], under_slab_insulation_width: under_slab_insulation_width, perimeter_insulation_r_value: args[:slab_perimeter_insulation_r], under_slab_insulation_r_value: args[:slab_under_insulation_r], under_slab_insulation_spans_entire_slab: under_slab_insulation_spans_entire_slab, depth_below_grade: depth_below_grade, carpet_fraction: carpet_fraction, carpet_r_value: carpet_r_value) end end def self.set_windows(hpxml, runner, model, args) model.getSurfaces.sort.each do |surface| surface.subSurfaces.sort.each do |sub_surface| next if sub_surface.subSurfaceType != 'FixedWindow' sub_surface_height = Geometry.get_surface_height(sub_surface) sub_surface_facade = Geometry.get_facade_for_surface(sub_surface) if (sub_surface_facade == Constants.FacadeFront) && ((args[:overhangs_front_depth] > 0) || args[:overhangs_front_distance_to_top_of_window] > 0) overhangs_depth = args[:overhangs_front_depth] overhangs_distance_to_top_of_window = args[:overhangs_front_distance_to_top_of_window] overhangs_distance_to_bottom_of_window = (overhangs_distance_to_top_of_window + sub_surface_height).round elsif (sub_surface_facade == Constants.FacadeBack) && ((args[:overhangs_back_depth] > 0) || args[:overhangs_back_distance_to_top_of_window] > 0) overhangs_depth = args[:overhangs_back_depth] overhangs_distance_to_top_of_window = args[:overhangs_back_distance_to_top_of_window] overhangs_distance_to_bottom_of_window = (overhangs_distance_to_top_of_window + sub_surface_height).round elsif (sub_surface_facade == Constants.FacadeLeft) && ((args[:overhangs_left_depth] > 0) || args[:overhangs_left_distance_to_top_of_window] > 0) overhangs_depth = args[:overhangs_left_depth] overhangs_distance_to_top_of_window = args[:overhangs_left_distance_to_top_of_window] overhangs_distance_to_bottom_of_window = (overhangs_distance_to_top_of_window + sub_surface_height).round elsif (sub_surface_facade == Constants.FacadeRight) && ((args[:overhangs_right_depth] > 0) || args[:overhangs_right_distance_to_top_of_window] > 0) overhangs_depth = args[:overhangs_right_depth] overhangs_distance_to_top_of_window = args[:overhangs_right_distance_to_top_of_window] overhangs_distance_to_bottom_of_window = (overhangs_distance_to_top_of_window + sub_surface_height).round elsif args[:geometry_eaves_depth] > 0 # Get max z coordinate of eaves eaves_z = args[:geometry_wall_height] * args[:geometry_num_floors_above_grade] + args[:geometry_rim_joist_height] if args[:geometry_attic_type] == HPXML::AtticTypeConditioned eaves_z += Geometry.get_conditioned_attic_height(model.getSpaces) end if args[:geometry_foundation_type] == HPXML::FoundationTypeAmbient eaves_z += args[:geometry_foundation_height] end # Get max z coordinate of this window sub_surface_z = Geometry.getSurfaceZValues([sub_surface]).max + UnitConversions.convert(sub_surface.space.get.zOrigin, 'm', 'ft') overhangs_depth = args[:geometry_eaves_depth] overhangs_distance_to_top_of_window = eaves_z - sub_surface_z # difference between max z coordinates of eaves and this window overhangs_distance_to_bottom_of_window = (overhangs_distance_to_top_of_window + sub_surface_height).round end azimuth = get_azimuth_from_facade(sub_surface_facade, args) if args[:window_interior_shading_winter].is_initialized interior_shading_factor_winter = args[:window_interior_shading_winter].get end if args[:window_interior_shading_summer].is_initialized interior_shading_factor_summer = args[:window_interior_shading_summer].get end if args[:window_exterior_shading_winter].is_initialized exterior_shading_factor_winter = args[:window_exterior_shading_winter].get end if args[:window_exterior_shading_summer].is_initialized exterior_shading_factor_summer = args[:window_exterior_shading_summer].get end if args[:window_fraction_operable].is_initialized fraction_operable = args[:window_fraction_operable].get end hpxml.windows.add(id: "#{valid_attr(sub_surface.name)}_#{sub_surface_facade}", area: UnitConversions.convert(sub_surface.grossArea, 'm^2', 'ft^2').round(1), azimuth: azimuth, ufactor: args[:window_ufactor], shgc: args[:window_shgc], overhangs_depth: overhangs_depth, overhangs_distance_to_top_of_window: overhangs_distance_to_top_of_window, overhangs_distance_to_bottom_of_window: overhangs_distance_to_bottom_of_window, interior_shading_factor_winter: interior_shading_factor_winter, interior_shading_factor_summer: interior_shading_factor_summer, exterior_shading_factor_winter: exterior_shading_factor_winter, exterior_shading_factor_summer: exterior_shading_factor_summer, fraction_operable: fraction_operable, wall_idref: valid_attr(surface.name)) end # sub_surfaces end # surfaces end def self.set_skylights(hpxml, runner, model, args) model.getSurfaces.sort.each do |surface| surface.subSurfaces.sort.each do |sub_surface| next if sub_surface.subSurfaceType != 'Skylight' sub_surface_facade = Geometry.get_facade_for_surface(sub_surface) hpxml.skylights.add(id: "#{valid_attr(sub_surface.name)}_#{sub_surface_facade}", area: UnitConversions.convert(sub_surface.grossArea, 'm^2', 'ft^2').round, azimuth: UnitConversions.convert(sub_surface.azimuth, 'rad', 'deg').round, ufactor: args[:skylight_ufactor], shgc: args[:skylight_shgc], roof_idref: valid_attr(surface.name)) end end end def self.set_doors(hpxml, runner, model, args) model.getSurfaces.sort.each do |surface| interior_adjacent_to = get_adjacent_to(surface) adjacent_surface = surface if [HPXML::LocationOtherHousingUnit].include?(interior_adjacent_to) adjacent_surface = get_adiabatic_adjacent_surface(model, surface) next if adjacent_surface.nil? end surface.subSurfaces.sort.each do |sub_surface| next if sub_surface.subSurfaceType != 'Door' sub_surface_facade = Geometry.get_facade_for_surface(sub_surface) hpxml.doors.add(id: "#{valid_attr(sub_surface.name)}_#{sub_surface_facade}", wall_idref: valid_attr(adjacent_surface.name), area: UnitConversions.convert(sub_surface.grossArea, 'm^2', 'ft^2').round, azimuth: args[:geometry_orientation], r_value: args[:door_rvalue]) end end end def self.set_heating_systems(hpxml, runner, args) heating_system_type = args[:heating_system_type] return if heating_system_type == 'none' if args[:heating_system_heating_capacity] != Constants.Auto heating_capacity = args[:heating_system_heating_capacity] end if heating_system_type == HPXML::HVACTypeElectricResistance heating_system_fuel = HPXML::FuelTypeElectricity else heating_system_fuel = args[:heating_system_fuel] end if [HPXML::HVACTypeFurnace, HPXML::HVACTypeWallFurnace, HPXML::HVACTypeFloorFurnace].include?(heating_system_type) || heating_system_type.include?(HPXML::HVACTypeBoiler) heating_efficiency_afue = args[:heating_system_heating_efficiency] elsif [HPXML::HVACTypeElectricResistance, HPXML::HVACTypeStove, HPXML::HVACTypePortableHeater, HPXML::HVACTypeFireplace, HPXML::HVACTypeFixedHeater].include?(heating_system_type) heating_efficiency_percent = args[:heating_system_heating_efficiency] end if args[:heating_system_airflow_defect_ratio].is_initialized if [HPXML::HVACTypeFurnace].include? heating_system_type airflow_defect_ratio = args[:heating_system_airflow_defect_ratio].get end end fraction_heat_load_served = args[:heating_system_fraction_heat_load_served] if args[:heating_system_type_2] != 'none' && fraction_heat_load_served + args[:heating_system_fraction_heat_load_served_2] > 1.0 fraction_heat_load_served = 1.0 - args[:heating_system_fraction_heat_load_served_2] end if heating_system_type.include?('Shared') is_shared_system = true number_of_units_served = args[:geometry_building_num_units].get heating_capacity = nil end if heating_system_type.include?(HPXML::HVACTypeBoiler) heating_system_type = HPXML::HVACTypeBoiler end hpxml.heating_systems.add(id: 'HeatingSystem', heating_system_type: heating_system_type, heating_system_fuel: heating_system_fuel, heating_capacity: heating_capacity, fraction_heat_load_served: fraction_heat_load_served, heating_efficiency_afue: heating_efficiency_afue, heating_efficiency_percent: heating_efficiency_percent, airflow_defect_ratio: airflow_defect_ratio, is_shared_system: is_shared_system, number_of_units_served: number_of_units_served) end def self.set_cooling_systems(hpxml, runner, args) cooling_system_type = args[:cooling_system_type] return if cooling_system_type == 'none' if args[:cooling_system_cooling_capacity] != Constants.Auto cooling_capacity = args[:cooling_system_cooling_capacity] end if args[:cooling_system_cooling_compressor_type].is_initialized if cooling_system_type == HPXML::HVACTypeCentralAirConditioner compressor_type = args[:cooling_system_cooling_compressor_type].get end end if args[:cooling_system_cooling_sensible_heat_fraction].is_initialized if cooling_system_type != HPXML::HVACTypeEvaporativeCooler cooling_shr = args[:cooling_system_cooling_sensible_heat_fraction].get end end if args[:cooling_system_cooling_efficiency_type] == HPXML::UnitsSEER cooling_efficiency_seer = args[:cooling_system_cooling_efficiency] elsif args[:cooling_system_cooling_efficiency_type] == HPXML::UnitsEER cooling_efficiency_eer = args[:cooling_system_cooling_efficiency] end if args[:cooling_system_airflow_defect_ratio].is_initialized if [HPXML::HVACTypeCentralAirConditioner].include?(cooling_system_type) || ([HPXML::HVACTypeMiniSplitAirConditioner].include?(cooling_system_type) && (args[:cooling_system_is_ducted])) airflow_defect_ratio = args[:cooling_system_airflow_defect_ratio].get end end if args[:cooling_system_charge_defect_ratio].is_initialized if [HPXML::HVACTypeCentralAirConditioner, HPXML::HVACTypeMiniSplitAirConditioner].include?(cooling_system_type) charge_defect_ratio = args[:cooling_system_charge_defect_ratio].get end end hpxml.cooling_systems.add(id: 'CoolingSystem', cooling_system_type: cooling_system_type, cooling_system_fuel: HPXML::FuelTypeElectricity, cooling_capacity: cooling_capacity, fraction_cool_load_served: args[:cooling_system_fraction_cool_load_served], compressor_type: compressor_type, cooling_shr: cooling_shr, cooling_efficiency_seer: cooling_efficiency_seer, cooling_efficiency_eer: cooling_efficiency_eer, airflow_defect_ratio: airflow_defect_ratio, charge_defect_ratio: charge_defect_ratio) end def self.set_heat_pumps(hpxml, runner, args) heat_pump_type = args[:heat_pump_type] return if heat_pump_type == 'none' if args[:heat_pump_heating_capacity] != Constants.Auto heating_capacity = args[:heat_pump_heating_capacity] end if [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpMiniSplit].include? heat_pump_type if args[:heat_pump_heating_capacity_17_f] != Constants.Auto heating_capacity_17F = args[:heat_pump_heating_capacity_17_f] end end if args[:heat_pump_backup_fuel] != 'none' backup_heating_fuel = args[:heat_pump_backup_fuel] if args[:heat_pump_backup_heating_capacity] != Constants.Auto backup_heating_capacity = args[:heat_pump_backup_heating_capacity] end if backup_heating_fuel == HPXML::FuelTypeElectricity backup_heating_efficiency_percent = args[:heat_pump_backup_heating_efficiency] else backup_heating_efficiency_afue = args[:heat_pump_backup_heating_efficiency] end if args[:heat_pump_backup_heating_switchover_temp].is_initialized if [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpMiniSplit].include? heat_pump_type backup_heating_switchover_temp = args[:heat_pump_backup_heating_switchover_temp].get end end end if args[:heat_pump_cooling_capacity] != Constants.Auto cooling_capacity = args[:heat_pump_cooling_capacity] end if args[:heat_pump_cooling_compressor_type].is_initialized if [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpMiniSplit].include? heat_pump_type compressor_type = args[:heat_pump_cooling_compressor_type].get end end if args[:heat_pump_cooling_sensible_heat_fraction].is_initialized cooling_shr = args[:heat_pump_cooling_sensible_heat_fraction].get end if args[:heat_pump_heating_efficiency_type] == HPXML::UnitsHSPF heating_efficiency_hspf = args[:heat_pump_heating_efficiency] elsif args[:heat_pump_heating_efficiency_type] == HPXML::UnitsCOP heating_efficiency_cop = args[:heat_pump_heating_efficiency] end if args[:heat_pump_cooling_efficiency_type] == HPXML::UnitsSEER cooling_efficiency_seer = args[:heat_pump_cooling_efficiency] elsif args[:heat_pump_cooling_efficiency_type] == HPXML::UnitsEER cooling_efficiency_eer = args[:heat_pump_cooling_efficiency] end if args[:heat_pump_airflow_defect_ratio].is_initialized if [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpGroundToAir].include?(heat_pump_type) || ([HPXML::HVACTypeHeatPumpMiniSplit].include?(heat_pump_type) && (args[:heat_pump_is_ducted])) airflow_defect_ratio = args[:heat_pump_airflow_defect_ratio].get end end if args[:heat_pump_charge_defect_ratio].is_initialized charge_defect_ratio = args[:heat_pump_charge_defect_ratio].get end fraction_heat_load_served = args[:heat_pump_fraction_heat_load_served] if args[:heating_system_type_2] != 'none' && fraction_heat_load_served + args[:heating_system_fraction_heat_load_served_2] > 1.0 fraction_heat_load_served = 1.0 - args[:heating_system_fraction_heat_load_served_2] end hpxml.heat_pumps.add(id: 'HeatPump', heat_pump_type: heat_pump_type, heat_pump_fuel: HPXML::FuelTypeElectricity, heating_capacity: heating_capacity, heating_capacity_17F: heating_capacity_17F, compressor_type: compressor_type, cooling_shr: cooling_shr, cooling_capacity: cooling_capacity, fraction_heat_load_served: fraction_heat_load_served, fraction_cool_load_served: args[:heat_pump_fraction_cool_load_served], backup_heating_fuel: backup_heating_fuel, backup_heating_capacity: backup_heating_capacity, backup_heating_efficiency_afue: backup_heating_efficiency_afue, backup_heating_efficiency_percent: backup_heating_efficiency_percent, backup_heating_switchover_temp: backup_heating_switchover_temp, heating_efficiency_hspf: heating_efficiency_hspf, cooling_efficiency_seer: cooling_efficiency_seer, heating_efficiency_cop: heating_efficiency_cop, cooling_efficiency_eer: cooling_efficiency_eer, airflow_defect_ratio: airflow_defect_ratio, charge_defect_ratio: charge_defect_ratio) end def self.set_secondary_heating_systems(hpxml, runner, args) heating_system_type = args[:heating_system_type_2] return if heating_system_type == 'none' if args[:heating_system_heating_capacity_2] != Constants.Auto heating_capacity = args[:heating_system_heating_capacity_2] end if args[:heating_system_fuel_2] == HPXML::HVACTypeElectricResistance heating_system_fuel = HPXML::FuelTypeElectricity else heating_system_fuel = args[:heating_system_fuel_2] end if [HPXML::HVACTypeFurnace, HPXML::HVACTypeWallFurnace, HPXML::HVACTypeFloorFurnace].include?(heating_system_type) || heating_system_type.include?(HPXML::HVACTypeBoiler) heating_efficiency_afue = args[:heating_system_heating_efficiency_2] elsif [HPXML::HVACTypeElectricResistance, HPXML::HVACTypeStove, HPXML::HVACTypePortableHeater, HPXML::HVACTypeFireplace].include?(heating_system_type) heating_efficiency_percent = args[:heating_system_heating_efficiency_2] end if heating_system_type.include?(HPXML::HVACTypeBoiler) heating_system_type = HPXML::HVACTypeBoiler end hpxml.heating_systems.add(id: 'SecondHeatingSystem', heating_system_type: heating_system_type, heating_system_fuel: heating_system_fuel, heating_capacity: heating_capacity, fraction_heat_load_served: args[:heating_system_fraction_heat_load_served_2], heating_efficiency_afue: heating_efficiency_afue, heating_efficiency_percent: heating_efficiency_percent) end def self.set_hvac_distribution(hpxml, runner, args) # HydronicDistribution? hydr_idx = 0 hpxml.heating_systems.each do |heating_system| next unless [heating_system.heating_system_type].include?(HPXML::HVACTypeBoiler) next if args[:heating_system_type].include?('Fan Coil') hydr_idx += 1 hpxml.hvac_distributions.add(id: "HydronicDistribution#{hydr_idx}", distribution_system_type: HPXML::HVACDistributionTypeHydronic, hydronic_type: HPXML::HydronicTypeBaseboard) heating_system.distribution_system_idref = hpxml.hvac_distributions[-1].id end # AirDistribution? air_distribution_systems = [] hpxml.heating_systems.each do |heating_system| if [HPXML::HVACTypeFurnace].include?(heating_system.heating_system_type) air_distribution_systems << heating_system end end hpxml.cooling_systems.each do |cooling_system| if [HPXML::HVACTypeCentralAirConditioner].include?(cooling_system.cooling_system_type) air_distribution_systems << cooling_system elsif [HPXML::HVACTypeEvaporativeCooler, HPXML::HVACTypeMiniSplitAirConditioner].include?(cooling_system.cooling_system_type) && args[:cooling_system_is_ducted] air_distribution_systems << cooling_system end end hpxml.heat_pumps.each do |heat_pump| if [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpGroundToAir].include? heat_pump.heat_pump_type air_distribution_systems << heat_pump elsif [HPXML::HVACTypeHeatPumpMiniSplit].include?(heat_pump.heat_pump_type) if args[:heat_pump_is_ducted].is_initialized air_distribution_systems << heat_pump if to_boolean(args[:heat_pump_is_ducted].get) end end end # FanCoil? fan_coil_distribution_systems = [] hpxml.heating_systems.each do |heating_system| if args[:heating_system_type].include?('Fan Coil') fan_coil_distribution_systems << heating_system end end return if air_distribution_systems.size == 0 && fan_coil_distribution_systems.size == 0 if args[:ducts_number_of_return_registers] != Constants.Auto number_of_return_registers = args[:ducts_number_of_return_registers] end if [HPXML::HVACTypeEvaporativeCooler].include?(args[:cooling_system_type]) && hpxml.heating_systems.size == 0 && hpxml.heat_pumps.size == 0 number_of_return_registers = nil if args[:cooling_system_is_ducted] number_of_return_registers = 0 end end if air_distribution_systems.size > 0 hpxml.hvac_distributions.add(id: 'AirDistribution', distribution_system_type: HPXML::HVACDistributionTypeAir, conditioned_floor_area_served: args[:geometry_cfa], air_type: HPXML::AirTypeRegularVelocity, number_of_return_registers: number_of_return_registers) air_distribution_systems.each do |hvac_system| hvac_system.distribution_system_idref = hpxml.hvac_distributions[-1].id end set_duct_leakages(args, hpxml.hvac_distributions[-1]) set_ducts(args, hpxml.hvac_distributions[-1]) end if fan_coil_distribution_systems.size > 0 hpxml.hvac_distributions.add(id: 'FanCoilDistribution', distribution_system_type: HPXML::HVACDistributionTypeAir, air_type: HPXML::AirTypeFanCoil) fan_coil_distribution_systems.each do |hvac_system| hvac_system.distribution_system_idref = hpxml.hvac_distributions[-1].id end end end def self.set_duct_leakages(args, hvac_distribution) hvac_distribution.duct_leakage_measurements.add(duct_type: HPXML::DuctTypeSupply, duct_leakage_units: args[:ducts_supply_leakage_units], duct_leakage_value: args[:ducts_supply_leakage_value], duct_leakage_total_or_to_outside: HPXML::DuctLeakageToOutside) hvac_distribution.duct_leakage_measurements.add(duct_type: HPXML::DuctTypeReturn, duct_leakage_units: args[:ducts_return_leakage_units], duct_leakage_value: args[:ducts_return_leakage_value], duct_leakage_total_or_to_outside: HPXML::DuctLeakageToOutside) end def self.set_ducts(args, hvac_distribution) if args[:ducts_supply_location] != Constants.Auto ducts_supply_location = args[:ducts_supply_location] end if args[:ducts_return_location] != Constants.Auto ducts_return_location = args[:ducts_return_location] end if args[:ducts_supply_surface_area] != Constants.Auto ducts_supply_surface_area = args[:ducts_supply_surface_area] end if args[:ducts_return_surface_area] != Constants.Auto ducts_return_surface_area = args[:ducts_return_surface_area] end hvac_distribution.ducts.add(duct_type: HPXML::DuctTypeSupply, duct_insulation_r_value: args[:ducts_supply_insulation_r], duct_location: ducts_supply_location, duct_surface_area: ducts_supply_surface_area) if not ([HPXML::HVACTypeEvaporativeCooler].include?(args[:cooling_system_type]) && args[:cooling_system_is_ducted]) hvac_distribution.ducts.add(duct_type: HPXML::DuctTypeReturn, duct_insulation_r_value: args[:ducts_return_insulation_r], duct_location: ducts_return_location, duct_surface_area: ducts_return_surface_area) end end def self.set_hvac_control(hpxml, runner, args) return if (args[:heating_system_type] == 'none') && (args[:cooling_system_type] == 'none') && (args[:heat_pump_type] == 'none') if args[:setpoint_heating_weekday] == args[:setpoint_heating_weekend] && !args[:setpoint_heating_weekday].include?(',') heating_setpoint_temp = args[:setpoint_heating_weekday] else weekday_heating_setpoints = args[:setpoint_heating_weekday] weekend_heating_setpoints = args[:setpoint_heating_weekend] end if args[:setpoint_cooling_weekday] == args[:setpoint_cooling_weekend] && !args[:setpoint_cooling_weekday].include?(',') cooling_setpoint_temp = args[:setpoint_cooling_weekday] else weekday_cooling_setpoints = args[:setpoint_cooling_weekday] weekend_cooling_setpoints = args[:setpoint_cooling_weekend] end ceiling_fan_quantity = nil if args[:ceiling_fan_quantity] != Constants.Auto ceiling_fan_quantity = Float(args[:ceiling_fan_quantity]) end if (args[:ceiling_fan_cooling_setpoint_temp_offset] > 0) && (ceiling_fan_quantity.nil? || ceiling_fan_quantity > 0) ceiling_fan_cooling_setpoint_temp_offset = args[:ceiling_fan_cooling_setpoint_temp_offset] end hpxml.hvac_controls.add(id: 'HVACControl', heating_setpoint_temp: heating_setpoint_temp, cooling_setpoint_temp: cooling_setpoint_temp, weekday_heating_setpoints: weekday_heating_setpoints, weekend_heating_setpoints: weekend_heating_setpoints, weekday_cooling_setpoints: weekday_cooling_setpoints, weekend_cooling_setpoints: weekend_cooling_setpoints, ceiling_fan_cooling_setpoint_temp_offset: ceiling_fan_cooling_setpoint_temp_offset) end def self.set_ventilation_fans(hpxml, runner, args) if args[:mech_vent_fan_type] != 'none' if [HPXML::MechVentTypeERV].include?(args[:mech_vent_fan_type]) if args[:mech_vent_recovery_efficiency_type] == 'Unadjusted' total_recovery_efficiency = args[:mech_vent_total_recovery_efficiency] sensible_recovery_efficiency = args[:mech_vent_sensible_recovery_efficiency] elsif args[:mech_vent_recovery_efficiency_type] == 'Adjusted' total_recovery_efficiency_adjusted = args[:mech_vent_total_recovery_efficiency] sensible_recovery_efficiency_adjusted = args[:mech_vent_sensible_recovery_efficiency] end elsif [HPXML::MechVentTypeHRV].include?(args[:mech_vent_fan_type]) if args[:mech_vent_recovery_efficiency_type] == 'Unadjusted' sensible_recovery_efficiency = args[:mech_vent_sensible_recovery_efficiency] elsif args[:mech_vent_recovery_efficiency_type] == 'Adjusted' sensible_recovery_efficiency_adjusted = args[:mech_vent_sensible_recovery_efficiency] end end distribution_system_idref = nil if args[:mech_vent_fan_type] == HPXML::MechVentTypeCFIS hpxml.hvac_distributions.each do |hvac_distribution| next unless hvac_distribution.distribution_system_type == HPXML::HVACDistributionTypeAir next if hvac_distribution.air_type != HPXML::AirTypeRegularVelocity distribution_system_idref = hvac_distribution.id end end if args[:mech_vent_num_units_served] > 1 is_shared_system = true in_unit_flow_rate = args[:mech_vent_flow_rate] / args[:mech_vent_num_units_served].to_f fraction_recirculation = args[:shared_mech_vent_frac_recirculation].get if args[:shared_mech_vent_preheating_fuel].is_initialized && args[:shared_mech_vent_preheating_efficiency].is_initialized && args[:shared_mech_vent_preheating_fraction_heat_load_served].is_initialized preheating_fuel = args[:shared_mech_vent_preheating_fuel].get preheating_efficiency_cop = args[:shared_mech_vent_preheating_efficiency].get preheating_fraction_load_served = args[:shared_mech_vent_preheating_fraction_heat_load_served].get end if args[:shared_mech_vent_precooling_fuel].is_initialized && args[:shared_mech_vent_precooling_efficiency].is_initialized && args[:shared_mech_vent_precooling_fraction_cool_load_served].is_initialized precooling_fuel = args[:shared_mech_vent_precooling_fuel].get precooling_efficiency_cop = args[:shared_mech_vent_precooling_efficiency].get precooling_fraction_load_served = args[:shared_mech_vent_precooling_fraction_cool_load_served].get end end hpxml.ventilation_fans.add(id: 'MechanicalVentilation', fan_type: args[:mech_vent_fan_type], rated_flow_rate: args[:mech_vent_flow_rate], hours_in_operation: args[:mech_vent_hours_in_operation], used_for_whole_building_ventilation: true, total_recovery_efficiency: total_recovery_efficiency, total_recovery_efficiency_adjusted: total_recovery_efficiency_adjusted, sensible_recovery_efficiency: sensible_recovery_efficiency, sensible_recovery_efficiency_adjusted: sensible_recovery_efficiency_adjusted, fan_power: args[:mech_vent_fan_power], distribution_system_idref: distribution_system_idref, is_shared_system: is_shared_system, in_unit_flow_rate: in_unit_flow_rate, fraction_recirculation: fraction_recirculation, preheating_fuel: preheating_fuel, preheating_efficiency_cop: preheating_efficiency_cop, preheating_fraction_load_served: preheating_fraction_load_served, precooling_fuel: precooling_fuel, precooling_efficiency_cop: precooling_efficiency_cop, precooling_fraction_load_served: precooling_fraction_load_served) end if args[:mech_vent_fan_type_2] != 'none' if [HPXML::MechVentTypeERV].include?(args[:mech_vent_fan_type_2]) if args[:mech_vent_recovery_efficiency_type_2] == 'Unadjusted' total_recovery_efficiency = args[:mech_vent_total_recovery_efficiency_2] sensible_recovery_efficiency = args[:mech_vent_sensible_recovery_efficiency_2] elsif args[:mech_vent_recovery_efficiency_type_2] == 'Adjusted' total_recovery_efficiency_adjusted = args[:mech_vent_total_recovery_efficiency_2] sensible_recovery_efficiency_adjusted = args[:mech_vent_sensible_recovery_efficiency_2] end elsif [HPXML::MechVentTypeHRV].include?(args[:mech_vent_fan_type_2]) if args[:mech_vent_recovery_efficiency_type_2] == 'Unadjusted' sensible_recovery_efficiency = args[:mech_vent_sensible_recovery_efficiency_2] elsif args[:mech_vent_recovery_efficiency_type_2] == 'Adjusted' sensible_recovery_efficiency_adjusted = args[:mech_vent_sensible_recovery_efficiency_2] end end hpxml.ventilation_fans.add(id: 'SecondMechanicalVentilation', fan_type: args[:mech_vent_fan_type_2], rated_flow_rate: args[:mech_vent_flow_rate_2], hours_in_operation: args[:mech_vent_hours_in_operation_2], used_for_whole_building_ventilation: true, total_recovery_efficiency: total_recovery_efficiency, total_recovery_efficiency_adjusted: total_recovery_efficiency_adjusted, sensible_recovery_efficiency: sensible_recovery_efficiency, sensible_recovery_efficiency_adjusted: sensible_recovery_efficiency_adjusted, fan_power: args[:mech_vent_fan_power_2]) end if (args[:kitchen_fans_quantity] == Constants.Auto) || (args[:kitchen_fans_quantity].to_i > 0) if args[:kitchen_fans_flow_rate].is_initialized if args[:kitchen_fans_flow_rate].get != Constants.Auto rated_flow_rate = args[:kitchen_fans_flow_rate].get.to_f end end if args[:kitchen_fans_power].is_initialized if args[:kitchen_fans_power].get != Constants.Auto fan_power = args[:kitchen_fans_power].get.to_f end end if args[:kitchen_fans_hours_in_operation].is_initialized if args[:kitchen_fans_hours_in_operation].get != Constants.Auto hours_in_operation = args[:kitchen_fans_hours_in_operation].get.to_f end end if args[:kitchen_fans_start_hour].is_initialized if args[:kitchen_fans_start_hour].get != Constants.Auto start_hour = args[:kitchen_fans_start_hour].get.to_i end end if args[:kitchen_fans_quantity] != Constants.Auto quantity = args[:kitchen_fans_quantity].to_i end hpxml.ventilation_fans.add(id: 'KitchenRangeFan', rated_flow_rate: rated_flow_rate, used_for_local_ventilation: true, hours_in_operation: hours_in_operation, fan_location: 'kitchen', fan_power: fan_power, start_hour: start_hour, quantity: quantity) end if (args[:bathroom_fans_quantity] == Constants.Auto) || (args[:bathroom_fans_quantity].to_i > 0) if args[:bathroom_fans_flow_rate].is_initialized if args[:bathroom_fans_flow_rate].get != Constants.Auto rated_flow_rate = args[:bathroom_fans_flow_rate].get.to_f end end if args[:bathroom_fans_power].is_initialized if args[:bathroom_fans_power].get != Constants.Auto fan_power = args[:bathroom_fans_power].get.to_f end end if args[:bathroom_fans_hours_in_operation].is_initialized if args[:bathroom_fans_hours_in_operation].get != Constants.Auto hours_in_operation = args[:bathroom_fans_hours_in_operation].get.to_f end end if args[:bathroom_fans_start_hour].is_initialized if args[:bathroom_fans_start_hour].get != Constants.Auto start_hour = args[:bathroom_fans_start_hour].get.to_i end end if args[:bathroom_fans_quantity] != Constants.Auto quantity = args[:bathroom_fans_quantity].to_i end hpxml.ventilation_fans.add(id: 'BathFans', rated_flow_rate: rated_flow_rate, used_for_local_ventilation: true, hours_in_operation: hours_in_operation, fan_location: 'bath', fan_power: fan_power, start_hour: start_hour, quantity: quantity) end if args[:whole_house_fan_present] hpxml.ventilation_fans.add(id: 'WholeHouseFan', rated_flow_rate: args[:whole_house_fan_flow_rate], used_for_seasonal_cooling_load_reduction: true, fan_power: args[:whole_house_fan_power]) end end def self.set_water_heating_systems(hpxml, runner, args) water_heater_type = args[:water_heater_type] return if water_heater_type == 'none' if water_heater_type != HPXML::WaterHeaterTypeHeatPump fuel_type = args[:water_heater_fuel_type] else fuel_type = HPXML::FuelTypeElectricity end if args[:water_heater_location] != Constants.Auto location = args[:water_heater_location] end if args[:geometry_num_bathrooms] != Constants.Auto num_bathrooms = args[:geometry_num_bathrooms] end if args[:water_heater_tank_volume] != Constants.Auto tank_volume = args[:water_heater_tank_volume] end if args[:water_heater_setpoint_temperature] != Constants.Auto temperature = args[:water_heater_setpoint_temperature] end if not [HPXML::WaterHeaterTypeCombiStorage, HPXML::WaterHeaterTypeCombiTankless].include? water_heater_type if args[:water_heater_efficiency_type] == 'EnergyFactor' energy_factor = args[:water_heater_efficiency] elsif args[:water_heater_efficiency_type] == 'UniformEnergyFactor' uniform_energy_factor = args[:water_heater_efficiency] if water_heater_type != HPXML::WaterHeaterTypeTankless first_hour_rating = args[:water_heater_first_hour_rating] end end end if (fuel_type != HPXML::FuelTypeElectricity) && (water_heater_type == HPXML::WaterHeaterTypeStorage) if args[:water_heater_recovery_efficiency] != Constants.Auto recovery_efficiency = args[:water_heater_recovery_efficiency] end end if [HPXML::WaterHeaterTypeTankless, HPXML::WaterHeaterTypeCombiTankless].include? water_heater_type tank_volume = nil end if [HPXML::WaterHeaterTypeTankless].include? water_heater_type heating_capacity = nil recovery_efficiency = nil elsif [HPXML::WaterHeaterTypeCombiTankless, HPXML::WaterHeaterTypeCombiStorage].include? water_heater_type fuel_type = nil heating_capacity = nil energy_factor = nil if hpxml.heating_systems.size == 0 fail 'Combi boiler water heater specified but no heating system found.' end related_hvac_idref = hpxml.heating_systems[0].id end if [HPXML::WaterHeaterTypeCombiTankless, HPXML::WaterHeaterTypeCombiStorage].include? water_heater_type if args[:water_heater_standby_loss].is_initialized if args[:water_heater_standby_loss].get > 0 standby_loss = args[:water_heater_standby_loss].get end end end if not [HPXML::WaterHeaterTypeTankless, HPXML::WaterHeaterTypeCombiTankless].include? water_heater_type if args[:water_heater_jacket_rvalue].is_initialized if args[:water_heater_jacket_rvalue].get > 0 jacket_r_value = args[:water_heater_jacket_rvalue].get end end end if args[:water_heater_num_units_served] > 1 is_shared_system = true number_of_units_served = args[:water_heater_num_units_served] end hpxml.water_heating_systems.add(id: 'WaterHeater', water_heater_type: water_heater_type, fuel_type: fuel_type, location: location, tank_volume: tank_volume, fraction_dhw_load_served: 1.0, energy_factor: energy_factor, uniform_energy_factor: uniform_energy_factor, first_hour_rating: first_hour_rating, recovery_efficiency: recovery_efficiency, related_hvac_idref: related_hvac_idref, standby_loss: standby_loss, jacket_r_value: jacket_r_value, temperature: temperature, is_shared_system: is_shared_system, number_of_units_served: number_of_units_served) end def self.set_hot_water_distribution(hpxml, runner, args) return if args[:water_heater_type] == 'none' if args[:dwhr_facilities_connected] != 'none' dwhr_facilities_connected = args[:dwhr_facilities_connected] dwhr_equal_flow = args[:dwhr_equal_flow] dwhr_efficiency = args[:dwhr_efficiency] end if args[:dhw_distribution_system_type] == HPXML::DHWDistTypeStandard if args[:dhw_distribution_standard_piping_length] != Constants.Auto standard_piping_length = args[:dhw_distribution_standard_piping_length] end else recirculation_control_type = args[:dhw_distribution_recirc_control_type] if args[:dhw_distribution_recirc_piping_length] != Constants.Auto recirculation_piping_length = args[:dhw_distribution_recirc_piping_length] end if args[:dhw_distribution_recirc_branch_piping_length] != Constants.Auto recirculation_branch_piping_length = args[:dhw_distribution_recirc_branch_piping_length] end if args[:dhw_distribution_recirc_pump_power] != Constants.Auto recirculation_pump_power = args[:dhw_distribution_recirc_pump_power] end end if args[:dhw_distribution_pipe_r] != Constants.Auto pipe_r_value = args[:dhw_distribution_pipe_r] end hpxml.hot_water_distributions.add(id: 'HotWaterDistribution', system_type: args[:dhw_distribution_system_type], standard_piping_length: standard_piping_length, recirculation_control_type: recirculation_control_type, recirculation_piping_length: recirculation_piping_length, recirculation_branch_piping_length: recirculation_branch_piping_length, recirculation_pump_power: recirculation_pump_power, pipe_r_value: pipe_r_value, dwhr_facilities_connected: dwhr_facilities_connected, dwhr_equal_flow: dwhr_equal_flow, dwhr_efficiency: dwhr_efficiency) end def self.set_water_fixtures(hpxml, runer, args) return if args[:water_heater_type] == 'none' hpxml.water_fixtures.add(id: 'ShowerFixture', water_fixture_type: HPXML::WaterFixtureTypeShowerhead, low_flow: args[:water_fixtures_shower_low_flow]) hpxml.water_fixtures.add(id: 'SinkFixture', water_fixture_type: HPXML::WaterFixtureTypeFaucet, low_flow: args[:water_fixtures_sink_low_flow]) if args[:water_fixtures_usage_multiplier] != 1.0 hpxml.water_heating.water_fixtures_usage_multiplier = args[:water_fixtures_usage_multiplier] end end def self.get_absolute_tilt(tilt_str, roof_pitch, epw_file) tilt_str = tilt_str.downcase if tilt_str.start_with? 'roofpitch' roof_angle = Math.atan(roof_pitch / 12.0) * 180.0 / Math::PI return Float(eval(tilt_str.gsub('roofpitch', roof_angle.to_s))) elsif tilt_str.start_with? 'latitude' return Float(eval(tilt_str.gsub('latitude', epw_file.latitude.to_s))) else return Float(tilt_str) end end def self.set_solar_thermal(hpxml, runner, args, epw_file) return if args[:solar_thermal_system_type] == 'none' if args[:solar_thermal_solar_fraction] > 0 solar_fraction = args[:solar_thermal_solar_fraction] else collector_area = args[:solar_thermal_collector_area] collector_loop_type = args[:solar_thermal_collector_loop_type] collector_type = args[:solar_thermal_collector_type] collector_azimuth = args[:solar_thermal_collector_azimuth] collector_tilt = get_absolute_tilt(args[:solar_thermal_collector_tilt], args[:geometry_roof_pitch], epw_file) collector_frta = args[:solar_thermal_collector_rated_optical_efficiency] collector_frul = args[:solar_thermal_collector_rated_thermal_losses] if args[:solar_thermal_storage_volume] != Constants.Auto storage_volume = args[:solar_thermal_storage_volume] end end if hpxml.water_heating_systems.size == 0 fail 'Solar thermal system specified but no water heater found.' end hpxml.solar_thermal_systems.add(id: 'SolarThermalSystem', system_type: args[:solar_thermal_system_type], collector_area: collector_area, collector_loop_type: collector_loop_type, collector_type: collector_type, collector_azimuth: collector_azimuth, collector_tilt: collector_tilt, collector_frta: collector_frta, collector_frul: collector_frul, storage_volume: storage_volume, water_heating_system_idref: hpxml.water_heating_systems[0].id, solar_fraction: solar_fraction) end def self.set_pv_systems(hpxml, runner, args, epw_file) [args[:pv_system_module_type_1], args[:pv_system_module_type_2]].each_with_index do |pv_system_module_type, i| next if pv_system_module_type == 'none' if [args[:pv_system_module_type_1], args[:pv_system_module_type_2]][i] != Constants.Auto module_type = [args[:pv_system_module_type_1], args[:pv_system_module_type_2]][i] end if [args[:pv_system_location_1], args[:pv_system_location_2]][i] != Constants.Auto location = [args[:pv_system_location_1], args[:pv_system_location_2]][i] end if [args[:pv_system_tracking_1], args[:pv_system_tracking_2]][i] != Constants.Auto tracking = [args[:pv_system_tracking_1], args[:pv_system_tracking_2]][i] end max_power_output = [args[:pv_system_max_power_output_1], args[:pv_system_max_power_output_2]][i] if [args[:pv_system_inverter_efficiency_1], args[:pv_system_inverter_efficiency_2]][i].is_initialized inverter_efficiency = [args[:pv_system_inverter_efficiency_1], args[:pv_system_inverter_efficiency_2]][i].get end if [args[:pv_system_system_losses_fraction_1], args[:pv_system_system_losses_fraction_2]][i].is_initialized system_losses_fraction = [args[:pv_system_system_losses_fraction_1], args[:pv_system_system_losses_fraction_2]][i].get end num_units_served = [args[:pv_system_num_units_served_1], args[:pv_system_num_units_served_2]][i] if num_units_served > 1 is_shared_system = true number_of_bedrooms_served = (args[:geometry_building_num_bedrooms].get * num_units_served / args[:geometry_building_num_units].get).to_i end hpxml.pv_systems.add(id: "PVSystem#{i + 1}", location: location, module_type: module_type, tracking: tracking, array_azimuth: [args[:pv_system_array_azimuth_1], args[:pv_system_array_azimuth_2]][i], array_tilt: get_absolute_tilt([args[:pv_system_array_tilt_1], args[:pv_system_array_tilt_2]][i], args[:geometry_roof_pitch], epw_file), max_power_output: max_power_output, inverter_efficiency: inverter_efficiency, system_losses_fraction: system_losses_fraction, is_shared_system: is_shared_system, number_of_bedrooms_served: number_of_bedrooms_served) end end def self.set_lighting(hpxml, runner, args) hpxml.lighting_groups.add(id: 'Lighting_CFL_Interior', location: HPXML::LocationInterior, fraction_of_units_in_location: args[:lighting_fraction_cfl_interior], lighting_type: HPXML::LightingTypeCFL) hpxml.lighting_groups.add(id: 'Lighting_CFL_Exterior', location: HPXML::LocationExterior, fraction_of_units_in_location: args[:lighting_fraction_cfl_exterior], lighting_type: HPXML::LightingTypeCFL) hpxml.lighting_groups.add(id: 'Lighting_CFL_Garage', location: HPXML::LocationGarage, fraction_of_units_in_location: args[:lighting_fraction_cfl_garage], lighting_type: HPXML::LightingTypeCFL) hpxml.lighting_groups.add(id: 'Lighting_LFL_Interior', location: HPXML::LocationInterior, fraction_of_units_in_location: args[:lighting_fraction_lfl_interior], lighting_type: HPXML::LightingTypeLFL) hpxml.lighting_groups.add(id: 'Lighting_LFL_Exterior', location: HPXML::LocationExterior, fraction_of_units_in_location: args[:lighting_fraction_lfl_exterior], lighting_type: HPXML::LightingTypeLFL) hpxml.lighting_groups.add(id: 'Lighting_LFL_Garage', location: HPXML::LocationGarage, fraction_of_units_in_location: args[:lighting_fraction_lfl_garage], lighting_type: HPXML::LightingTypeLFL) hpxml.lighting_groups.add(id: 'Lighting_LED_Interior', location: HPXML::LocationInterior, fraction_of_units_in_location: args[:lighting_fraction_led_interior], lighting_type: HPXML::LightingTypeLED) hpxml.lighting_groups.add(id: 'Lighting_LED_Exterior', location: HPXML::LocationExterior, fraction_of_units_in_location: args[:lighting_fraction_led_exterior], lighting_type: HPXML::LightingTypeLED) hpxml.lighting_groups.add(id: 'Lighting_LED_Garage', location: HPXML::LocationGarage, fraction_of_units_in_location: args[:lighting_fraction_led_garage], lighting_type: HPXML::LightingTypeLED) if args[:lighting_usage_multiplier_interior] != 1.0 hpxml.lighting.interior_usage_multiplier = args[:lighting_usage_multiplier_interior] end if args[:lighting_usage_multiplier_exterior] != 1.0 hpxml.lighting.exterior_usage_multiplier = args[:lighting_usage_multiplier_exterior] end if args[:lighting_usage_multiplier_garage] != 1.0 hpxml.lighting.garage_usage_multiplier = args[:lighting_usage_multiplier_garage] end return unless args[:holiday_lighting_present] hpxml.lighting.holiday_exists = true if args[:holiday_lighting_daily_kwh] != Constants.Auto hpxml.lighting.holiday_kwh_per_day = args[:holiday_lighting_daily_kwh] end if args[:holiday_lighting_period_begin_month] != Constants.Auto hpxml.lighting.holiday_period_begin_month = args[:holiday_lighting_period_begin_month] end if args[:holiday_lighting_period_begin_day_of_month] != Constants.Auto hpxml.lighting.holiday_period_begin_day = args[:holiday_lighting_period_begin_day_of_month] end if args[:holiday_lighting_period_end_month] != Constants.Auto hpxml.lighting.holiday_period_end_month = args[:holiday_lighting_period_end_month] end if args[:holiday_lighting_period_end_day_of_month] != Constants.Auto hpxml.lighting.holiday_period_end_day = args[:holiday_lighting_period_end_day_of_month] end end def self.set_dehumidifier(hpxml, runner, args) return if args[:dehumidifier_type] == 'none' if args[:dehumidifier_efficiency_type] == 'EnergyFactor' energy_factor = args[:dehumidifier_efficiency] elsif args[:dehumidifier_efficiency_type] == 'IntegratedEnergyFactor' integrated_energy_factor = args[:dehumidifier_efficiency] end hpxml.dehumidifiers.add(id: 'Dehumidifier', type: args[:dehumidifier_type], capacity: args[:dehumidifier_capacity], energy_factor: energy_factor, integrated_energy_factor: integrated_energy_factor, rh_setpoint: args[:dehumidifier_rh_setpoint], fraction_served: args[:dehumidifier_fraction_dehumidification_load_served], location: HPXML::LocationLivingSpace) end def self.set_clothes_washer(hpxml, runner, args) if args[:water_heater_type] == 'none' args[:clothes_washer_location] = 'none' end return if args[:clothes_washer_location] == 'none' if args[:clothes_washer_rated_annual_kwh] != Constants.Auto rated_annual_kwh = args[:clothes_washer_rated_annual_kwh] return if Float(rated_annual_kwh) == 0 end if args[:clothes_washer_location] != Constants.Auto location = args[:clothes_washer_location] end if args[:clothes_washer_efficiency] != Constants.Auto if args[:clothes_washer_efficiency_type] == 'ModifiedEnergyFactor' modified_energy_factor = args[:clothes_washer_efficiency].to_f elsif args[:clothes_washer_efficiency_type] == 'IntegratedModifiedEnergyFactor' integrated_modified_energy_factor = args[:clothes_washer_efficiency].to_f end end if args[:clothes_washer_label_electric_rate] != Constants.Auto label_electric_rate = args[:clothes_washer_label_electric_rate] end if args[:clothes_washer_label_gas_rate] != Constants.Auto label_gas_rate = args[:clothes_washer_label_gas_rate] end if args[:clothes_washer_label_annual_gas_cost] != Constants.Auto label_annual_gas_cost = args[:clothes_washer_label_annual_gas_cost] end if args[:clothes_washer_label_usage] != Constants.Auto label_usage = args[:clothes_washer_label_usage] end if args[:clothes_washer_capacity] != Constants.Auto capacity = args[:clothes_washer_capacity] end if args[:clothes_washer_usage_multiplier] != 1.0 usage_multiplier = args[:clothes_washer_usage_multiplier] end hpxml.clothes_washers.add(id: 'ClothesWasher', location: location, modified_energy_factor: modified_energy_factor, integrated_modified_energy_factor: integrated_modified_energy_factor, rated_annual_kwh: rated_annual_kwh, label_electric_rate: label_electric_rate, label_gas_rate: label_gas_rate, label_annual_gas_cost: label_annual_gas_cost, label_usage: label_usage, capacity: capacity, usage_multiplier: usage_multiplier) end def self.set_clothes_dryer(hpxml, runner, args) return if args[:clothes_washer_location] == 'none' return if args[:clothes_dryer_location] == 'none' if args[:clothes_dryer_efficiency] != Constants.Auto if args[:clothes_dryer_efficiency_type] == 'EnergyFactor' energy_factor = args[:clothes_dryer_efficiency].to_f elsif args[:clothes_dryer_efficiency_type] == 'CombinedEnergyFactor' combined_energy_factor = args[:clothes_dryer_efficiency].to_f end end if args[:clothes_dryer_location] != Constants.Auto location = args[:clothes_dryer_location] end if args[:clothes_dryer_vented_flow_rate] != Constants.Auto is_vented = false if Float(args[:clothes_dryer_vented_flow_rate]) > 0 is_vented = true vented_flow_rate = args[:clothes_dryer_vented_flow_rate] end end if args[:clothes_dryer_usage_multiplier] != 1.0 usage_multiplier = args[:clothes_dryer_usage_multiplier] end hpxml.clothes_dryers.add(id: 'ClothesDryer', location: location, fuel_type: args[:clothes_dryer_fuel_type], energy_factor: energy_factor, combined_energy_factor: combined_energy_factor, is_vented: is_vented, vented_flow_rate: vented_flow_rate, usage_multiplier: usage_multiplier) end def self.set_dishwasher(hpxml, runner, args) return if args[:dishwasher_location] == 'none' if args[:dishwasher_location] != Constants.Auto location = args[:dishwasher_location] end if args[:dishwasher_efficiency_type] == 'RatedAnnualkWh' if args[:dishwasher_efficiency] != Constants.Auto rated_annual_kwh = args[:dishwasher_efficiency] return if Float(rated_annual_kwh) == 0 end elsif args[:dishwasher_efficiency_type] == 'EnergyFactor' energy_factor = args[:dishwasher_efficiency] end if args[:dishwasher_label_electric_rate] != Constants.Auto label_electric_rate = args[:dishwasher_label_electric_rate] end if args[:dishwasher_label_gas_rate] != Constants.Auto label_gas_rate = args[:dishwasher_label_gas_rate] end if args[:dishwasher_label_annual_gas_cost] != Constants.Auto label_annual_gas_cost = args[:dishwasher_label_annual_gas_cost] end if args[:dishwasher_label_usage] != Constants.Auto label_usage = args[:dishwasher_label_usage] end if args[:dishwasher_place_setting_capacity] != Constants.Auto place_setting_capacity = args[:dishwasher_place_setting_capacity] end if args[:dishwasher_usage_multiplier] != 1.0 usage_multiplier = args[:dishwasher_usage_multiplier] end hpxml.dishwashers.add(id: 'Dishwasher', location: location, rated_annual_kwh: rated_annual_kwh, energy_factor: energy_factor, label_electric_rate: label_electric_rate, label_gas_rate: label_gas_rate, label_annual_gas_cost: label_annual_gas_cost, label_usage: label_usage, place_setting_capacity: place_setting_capacity, usage_multiplier: usage_multiplier) end def self.set_refrigerator(hpxml, runner, args) return if args[:refrigerator_location] == 'none' if args[:refrigerator_rated_annual_kwh] != Constants.Auto rated_annual_kwh = args[:refrigerator_rated_annual_kwh] return if Float(rated_annual_kwh) == 0 end if args[:refrigerator_location] != Constants.Auto location = args[:refrigerator_location] end if args[:refrigerator_usage_multiplier] != 1.0 usage_multiplier = args[:refrigerator_usage_multiplier] end if args[:extra_refrigerator_location] != 'none' primary_indicator = true end hpxml.refrigerators.add(id: 'Refrigerator', location: location, rated_annual_kwh: rated_annual_kwh, primary_indicator: primary_indicator, usage_multiplier: usage_multiplier) end def self.set_extra_refrigerator(hpxml, runner, args) return if args[:extra_refrigerator_location] == 'none' if args[:extra_refrigerator_rated_annual_kwh] != Constants.Auto rated_annual_kwh = args[:extra_refrigerator_rated_annual_kwh] return if Float(rated_annual_kwh) == 0 end if args[:extra_refrigerator_location] != Constants.Auto location = args[:extra_refrigerator_location] end if args[:extra_refrigerator_usage_multiplier] != 1.0 usage_multiplier = args[:extra_refrigerator_usage_multiplier] end hpxml.refrigerators.add(id: 'ExtraRefrigerator', location: location, rated_annual_kwh: rated_annual_kwh, primary_indicator: false, usage_multiplier: usage_multiplier) end def self.set_freezer(hpxml, runner, args) return if args[:freezer_location] == 'none' if args[:freezer_rated_annual_kwh] != Constants.Auto rated_annual_kwh = args[:freezer_rated_annual_kwh] return if Float(rated_annual_kwh) == 0 end if args[:freezer_location] != Constants.Auto location = args[:freezer_location] end if args[:freezer_usage_multiplier] != 1.0 usage_multiplier = args[:freezer_usage_multiplier] end hpxml.freezers.add(id: 'Freezer', location: location, rated_annual_kwh: rated_annual_kwh, usage_multiplier: usage_multiplier) end def self.set_cooking_range_oven(hpxml, runner, args) return if args[:cooking_range_oven_location] == 'none' if args[:cooking_range_oven_location] != Constants.Auto location = args[:cooking_range_oven_location] end if args[:cooking_range_oven_is_induction].is_initialized is_induction = args[:cooking_range_oven_is_induction].get end if args[:cooking_range_oven_usage_multiplier] != 1.0 usage_multiplier = args[:cooking_range_oven_usage_multiplier] end hpxml.cooking_ranges.add(id: 'CookingRange', location: location, fuel_type: args[:cooking_range_oven_fuel_type], is_induction: is_induction, usage_multiplier: usage_multiplier) if args[:cooking_range_oven_is_convection].is_initialized is_convection = args[:cooking_range_oven_is_convection].get end hpxml.ovens.add(id: 'Oven', is_convection: is_convection) end def self.set_ceiling_fans(hpxml, runner, args) return unless args[:ceiling_fan_present] if args[:ceiling_fan_efficiency] != Constants.Auto efficiency = args[:ceiling_fan_efficiency] end if args[:ceiling_fan_quantity] != Constants.Auto quantity = args[:ceiling_fan_quantity] end hpxml.ceiling_fans.add(id: 'CeilingFan', efficiency: efficiency, quantity: quantity) end def self.set_plug_loads_television(hpxml, runner, args) if args[:plug_loads_television_annual_kwh] != Constants.Auto kWh_per_year = args[:plug_loads_television_annual_kwh] end usage_multiplier = args[:plug_loads_television_usage_multiplier] if usage_multiplier == 1.0 usage_multiplier = nil end hpxml.plug_loads.add(id: 'PlugLoadsTelevision', plug_load_type: HPXML::PlugLoadTypeTelevision, kWh_per_year: kWh_per_year, usage_multiplier: usage_multiplier) end def self.set_plug_loads_other(hpxml, runner, args) if args[:plug_loads_other_annual_kwh] != Constants.Auto kWh_per_year = args[:plug_loads_other_annual_kwh] end if args[:plug_loads_other_frac_sensible] != Constants.Auto frac_sensible = args[:plug_loads_other_frac_sensible] end if args[:plug_loads_other_frac_latent] != Constants.Auto frac_latent = args[:plug_loads_other_frac_latent] end usage_multiplier = args[:plug_loads_other_usage_multiplier] if usage_multiplier == 1.0 usage_multiplier = nil end hpxml.plug_loads.add(id: 'PlugLoadsOther', plug_load_type: HPXML::PlugLoadTypeOther, kWh_per_year: kWh_per_year, frac_sensible: frac_sensible, frac_latent: frac_latent, usage_multiplier: usage_multiplier) end def self.set_plug_loads_well_pump(hpxml, runner, args) return unless args[:plug_loads_well_pump_present] if args[:plug_loads_well_pump_annual_kwh] != Constants.Auto kWh_per_year = args[:plug_loads_well_pump_annual_kwh] end usage_multiplier = args[:plug_loads_well_pump_usage_multiplier] if usage_multiplier == 1.0 usage_multiplier = nil end hpxml.plug_loads.add(id: 'PlugLoadsWellPump', plug_load_type: HPXML::PlugLoadTypeWellPump, kWh_per_year: kWh_per_year, usage_multiplier: usage_multiplier) end def self.set_plug_loads_vehicle(hpxml, runner, args) return unless args[:plug_loads_vehicle_present] if args[:plug_loads_vehicle_annual_kwh] != Constants.Auto kWh_per_year = args[:plug_loads_vehicle_annual_kwh] end usage_multiplier = args[:plug_loads_vehicle_usage_multiplier] if usage_multiplier == 1.0 usage_multiplier = nil end hpxml.plug_loads.add(id: 'PlugLoadsVehicle', plug_load_type: HPXML::PlugLoadTypeElectricVehicleCharging, kWh_per_year: kWh_per_year, usage_multiplier: usage_multiplier) end def self.set_fuel_loads_grill(hpxml, runner, args) if args[:fuel_loads_grill_present] if args[:fuel_loads_grill_annual_therm] != Constants.Auto therm_per_year = args[:fuel_loads_grill_annual_therm] end if args[:fuel_loads_grill_usage_multiplier] != 1.0 usage_multiplier = args[:fuel_loads_grill_usage_multiplier] end hpxml.fuel_loads.add(id: 'FuelLoadsGrill', fuel_load_type: HPXML::FuelLoadTypeGrill, fuel_type: args[:fuel_loads_grill_fuel_type], therm_per_year: therm_per_year, usage_multiplier: usage_multiplier) end end def self.set_fuel_loads_lighting(hpxml, runner, args) if args[:fuel_loads_lighting_present] if args[:fuel_loads_lighting_annual_therm] != Constants.Auto therm_per_year = args[:fuel_loads_lighting_annual_therm] end if args[:fuel_loads_lighting_usage_multiplier] != 1.0 usage_multiplier = args[:fuel_loads_lighting_usage_multiplier] end hpxml.fuel_loads.add(id: 'FuelLoadsLighting', fuel_load_type: HPXML::FuelLoadTypeLighting, fuel_type: args[:fuel_loads_lighting_fuel_type], therm_per_year: therm_per_year, usage_multiplier: usage_multiplier) end end def self.set_fuel_loads_fireplace(hpxml, runner, args) if args[:fuel_loads_fireplace_present] if args[:fuel_loads_fireplace_annual_therm] != Constants.Auto therm_per_year = args[:fuel_loads_fireplace_annual_therm] end if args[:fuel_loads_fireplace_frac_sensible] != Constants.Auto frac_sensible = args[:fuel_loads_fireplace_frac_sensible] end if args[:fuel_loads_fireplace_frac_latent] != Constants.Auto frac_latent = args[:fuel_loads_fireplace_frac_latent] end if args[:fuel_loads_fireplace_usage_multiplier] != 1.0 usage_multiplier = args[:fuel_loads_fireplace_usage_multiplier] end hpxml.fuel_loads.add(id: 'FuelLoadsFireplace', fuel_load_type: HPXML::FuelLoadTypeFireplace, fuel_type: args[:fuel_loads_fireplace_fuel_type], therm_per_year: therm_per_year, frac_sensible: frac_sensible, frac_latent: frac_latent, usage_multiplier: usage_multiplier) end end def self.set_pool(hpxml, runner, args) return unless args[:pool_present] if args[:pool_pump_annual_kwh] != Constants.Auto pump_kwh_per_year = args[:pool_pump_annual_kwh] end if args[:pool_pump_usage_multiplier] != 1.0 pump_usage_multiplier = args[:pool_pump_usage_multiplier] end pool_heater_type = args[:pool_heater_type] if [HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump].include?(pool_heater_type) if args[:pool_heater_annual_kwh] != Constants.Auto heater_load_units = 'kWh/year' heater_load_value = args[:pool_heater_annual_kwh] end end if [HPXML::HeaterTypeGas].include?(pool_heater_type) if args[:pool_heater_annual_therm] != Constants.Auto heater_load_units = 'therm/year' heater_load_value = args[:pool_heater_annual_therm] end end if args[:pool_heater_usage_multiplier] != 1.0 heater_usage_multiplier = args[:pool_heater_usage_multiplier] end hpxml.pools.add(id: 'Pool', type: HPXML::TypeUnknown, pump_type: HPXML::TypeUnknown, pump_kwh_per_year: pump_kwh_per_year, pump_usage_multiplier: pump_usage_multiplier, heater_type: pool_heater_type, heater_load_units: heater_load_units, heater_load_value: heater_load_value, heater_usage_multiplier: heater_usage_multiplier) end def self.set_hot_tub(hpxml, runner, args) return unless args[:hot_tub_present] if args[:hot_tub_pump_annual_kwh] != Constants.Auto pump_kwh_per_year = args[:hot_tub_pump_annual_kwh] end if args[:hot_tub_pump_usage_multiplier] != 1.0 pump_usage_multiplier = args[:hot_tub_pump_usage_multiplier] end hot_tub_heater_type = args[:hot_tub_heater_type] if [HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump].include?(hot_tub_heater_type) if args[:hot_tub_heater_annual_kwh] != Constants.Auto heater_load_units = 'kWh/year' heater_load_value = args[:hot_tub_heater_annual_kwh] end end if [HPXML::HeaterTypeGas].include?(hot_tub_heater_type) if args[:hot_tub_heater_annual_therm] != Constants.Auto heater_load_units = 'therm/year' heater_load_value = args[:hot_tub_heater_annual_therm] end end if args[:hot_tub_heater_usage_multiplier] != 1.0 heater_usage_multiplier = args[:hot_tub_heater_usage_multiplier] end hpxml.hot_tubs.add(id: 'HotTub', type: HPXML::TypeUnknown, pump_type: HPXML::TypeUnknown, pump_kwh_per_year: pump_kwh_per_year, pump_usage_multiplier: pump_usage_multiplier, heater_type: hot_tub_heater_type, heater_load_units: heater_load_units, heater_load_value: heater_load_value, heater_usage_multiplier: heater_usage_multiplier) end def self.valid_attr(attr) attr = attr.to_s attr = attr.gsub(' ', '_') attr = attr.gsub('|', '_') return attr end def self.get_adjacent_to(surface) space = surface.space.get st = space.spaceType.get space_type = st.standardsSpaceType.get return space_type end def self.get_surface_azimuth(surface, args) facade = Geometry.get_facade_for_surface(surface) return get_azimuth_from_facade(facade, args) end def self.get_azimuth_from_facade(facade, args) if facade == Constants.FacadeFront azimuth = Geometry.get_abs_azimuth(Constants.CoordRelative, 0, args[:geometry_orientation], 0) elsif facade == Constants.FacadeBack azimuth = Geometry.get_abs_azimuth(Constants.CoordRelative, 180, args[:geometry_orientation], 0) elsif facade == Constants.FacadeLeft azimuth = Geometry.get_abs_azimuth(Constants.CoordRelative, 90, args[:geometry_orientation], 0) elsif facade == Constants.FacadeRight azimuth = Geometry.get_abs_azimuth(Constants.CoordRelative, 270, args[:geometry_orientation], 0) else fail 'Unexpected facade.' end end end # register the measure to be used by the application BuildResidentialHPXML.new.registerWithApplication