Class: GenericQAQC
- Inherits:
-
OpenStudio::Measure::ReportingMeasure
- Object
- OpenStudio::Measure::ReportingMeasure
- GenericQAQC
- Includes:
- OsLib_QAQC
- Defined in:
- lib/measures/generic_qaqc/measure.rb
Overview
start the measure
Instance Method Summary collapse
-
#arguments(model = nil) ⇒ Object
define the arguments that the user will input.
-
#description ⇒ Object
human readable description.
-
#energyPlusOutputRequests(runner, user_arguments) ⇒ Object
return a vector of IdfObject’s to request EnergyPlus objects needed by the run method.
-
#modeler_description ⇒ Object
human readable description of modeling approach.
-
#name ⇒ Object
define the name that a user will see, this method may be deprecated as the display name in PAT comes from the name field in measure.xml.
- #possible_check_categories ⇒ Object
-
#run(runner, user_arguments) ⇒ Object
define what happens when the measure is run.
Methods included from OsLib_QAQC
#bin_part_loads_by_ten_pcts, #check_air_sys_temps, #check_calibration, #check_cond_zns, #check_domestic_hot_water, #check_envelope_conductance, #check_eui_by_end_use, #check_eui_reasonableness, #check_fan_pwr, #check_internal_loads, #check_mech_sys_capacity, #check_mech_sys_efficiency, #check_mech_sys_part_load_eff, #check_mech_sys_type, #check_part_loads, #check_placeholder, #check_plant_cap, #check_plant_temps, #check_plenum_loads, #check_pump_pwr, #check_sch_coord, #check_schedules, #check_simultaneous_heating_and_cooling, #check_supply_air_and_thermostat_temp_difference, #check_weather_files, #generate_load_insc_sch_check_attribute, #get_start_and_end_times, #map_sub_surfaces_props, #map_surface_props
Instance Method Details
#arguments(model = nil) ⇒ Object
define the arguments that the user will input
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/measures/generic_qaqc/measure.rb', line 84 def arguments(model = nil) args = OpenStudio::Measure::OSArgumentVector.new # Make an argument for the template template = OpenStudio::Measure::OSArgument.makeChoiceArgument('template', OpenstudioStandards::CreateTypical.get_doe_templates(false), true) template.setDisplayName('Target ASHRAE Standard') template.setDescription('This used to set the target standard for most checks.') template.setDefaultValue('90.1-2013') # there is override variable in run method for this args << template # add arguments from possible_check_categories possible_check_categories.each do |hash| cat = hash[:cat] cat_input = "\'#{cat}\'" if hash[:standards] standards_input = ",\'selected ASHRAE standard\'" else standards_input = '' end if hash[:data].nil? data_input = '' else data_input = ",#{hash[:data]}" end if !hash[:tol_min] min = nil min_input = '' else min = hash[:tol_min] min_input = ",#{min}" end if hash[:tol_max].is_a? Float max = hash[:tol_max] max_input = ",#{max}" elsif !hash[:tol_max] max = nil max_input = '' else max = hash[:tol_min] max_input = ",#{max}" end name_cat_desc = eval("#{hash[:method_name]}(#{cat_input}#{data_input}#{standards_input}#{min_input}#{max_input},true)") arg = OpenStudio::Measure::OSArgument.makeBoolArgument(hash[:method_name], true) arg.setDisplayName("#{name_cat_desc[0]} (#{hash[:cat]})") arg.setDescription(name_cat_desc[2]) arg.setDefaultValue(true) args << arg if !min.nil? arg_tol = OpenStudio::Measure::OSArgument.makeDoubleArgument("#{hash[:method_name]}_tol", true) arg_tol.setDisplayName("#{name_cat_desc[0]} Tolerance") arg_tol.setDefaultValue(min) arg_tol.setUnits(hash[:units]) args << arg_tol end if hash[:tol_max].is_a? Float arg_max_tol = OpenStudio::Measure::OSArgument.makeDoubleArgument("#{hash[:method_name]}_max_tol", true) arg_max_tol.setDisplayName("#{name_cat_desc[0]} Max Tolerance") arg_max_tol.setDefaultValue(max) arg_max_tol.setUnits(hash[:units]) args << arg_max_tol end end # make an argument for use_upstream_args use_upstream_args = OpenStudio::Measure::OSArgument.makeBoolArgument('use_upstream_args', true) use_upstream_args.setDisplayName('Use Upstream Argument Values') use_upstream_args.setDescription('When true this will look for arguments or registerValues in upstream measures that match arguments from this measure, and will use the value from the upstream measure in place of what is entered for this measure.') use_upstream_args.setDefaultValue(true) args << use_upstream_args return args end |
#description ⇒ Object
human readable description
26 27 28 |
# File 'lib/measures/generic_qaqc/measure.rb', line 26 def description return 'This measure extracts key simulation results and performs basic model QAQC checks. Each category of checks provides a description of the source of the check. In some cases the target standards and tollerances are adjustable.' end |
#energyPlusOutputRequests(runner, user_arguments) ⇒ Object
return a vector of IdfObject’s to request EnergyPlus objects needed by the run method
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/measures/generic_qaqc/measure.rb', line 159 def energyPlusOutputRequests(runner, user_arguments) super(runner, user_arguments) result = OpenStudio::IdfObjectVector.new # assign the user inputs to variables args = runner.getArgumentValues(arguments, user_arguments) args = Hash[args.collect{ |k, v| [k.to_s, v] }] unless args return false end # only add terminalvariables if that check is enabled if args['check_simultaneous_heating_and_cooling'] # get the last model model = runner.lastOpenStudioModel if model.empty? runner.registerError('Cannot find last model.') return false end model = model.get # Request the terminal reheat coil and # terminal cooling rates for every VAV # reheat terminal. model.getAirTerminalSingleDuctVAVReheats.each do |term| # Reheat coil heating rate rht_coil = term.reheatCoil result << OpenStudio::IdfObject.load("Output:Variable,#{rht_coil.name},Heating Coil Heating Rate,Hourly;").get result << OpenStudio::IdfObject.load("Output:Variable,#{rht_coil.name},Heating Coil Air Heating Rate,Hourly;").get # Zone Air Terminal Sensible Heating Rate result << OpenStudio::IdfObject.load("Output:Variable,ADU #{term.name},Zone Air Terminal Sensible Cooling Rate,Hourly;").get end end return result end |
#modeler_description ⇒ Object
human readable description of modeling approach
31 32 33 |
# File 'lib/measures/generic_qaqc/measure.rb', line 31 def modeler_description return "Reads the model and sql file to pull out the necessary information and run the model checks. The check results show up as warning messages in the measure's output on the PAT run tab." end |
#name ⇒ Object
define the name that a user will see, this method may be deprecated as the display name in PAT comes from the name field in measure.xml
21 22 23 |
# File 'lib/measures/generic_qaqc/measure.rb', line 21 def name return 'Generic QAQC' end |
#possible_check_categories ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/measures/generic_qaqc/measure.rb', line 35 def possible_check_categories results = [] # gather options_check_weather_files (example data below not used since check_weather_files commented out for generic QAQC) = {} epw_ch_01 = {} epw_ch_01['climate_zone'] = '5B' ['USA_CO_Golden-NREL.724666_TMY3.epw'] = epw_ch_01 epw_ch_01['summer'] = [] epw_ch_01['summer'] << 'Denver Centennial Golden N Ann Clg .4% Condns DB=>MWB' epw_ch_01['summer'] << 'Denver Centennial Golden N Ann Clg .4% Condns DP=>MDB' epw_ch_01['summer'] << 'Denver Centennial Golden N Ann Clg .4% Condns Enth=>MDB' epw_ch_01['summer'] << 'Denver Centennial Golden N Ann Clg .4% Condns WB=>MDB' epw_ch_01['winter'] = [] epw_ch_01['winter'] << 'Denver Centennial Golden N Ann Htg 99.6% Condns DB' epw_ch_01['winter'] << 'Denver Centennial Golden N Ann Htg Wind 99.6% Condns WS=>MCDB' epw_ch_01['winter'] << 'Denver Centennial Golden N Ann Hum_n 99.6% Condns DP=>MCDB' # add additional weather with design day objects as required # gather inputs for check_mech_sys_capacity. Each option has a target value, min and max fractional tolerance, and units # in the future climate zone specific targets may be in standards # todo - expose these tollerances as user arguments = {} ['chiller_max_flow_rate'] = { 'target' => 2.4, 'min' => 0.1, 'max' => 0.1, 'units' => 'gal/ton*min' } ['air_loop_max_flow_rate'] = { 'target' => 1.0, 'min' => 0.1, 'max' => 0.1, 'units' => 'cfm/ft^2' } ['air_loop_cooling_capacity'] = { 'target' => 0.0033, 'min' => 0.1, 'max' => 0.1, 'units' => 'tons/ft^2' } ['zone_heating_capacity'] = { 'target' => 12.5, 'min' => 0.20, 'max' => 0.40, 'units' => 'Btu/ft^2*h' } # results << {:method_name => 'check_weather_files',:cat => 'General',:standards => false,:data => options_check_weather_files,:min_tol => false,:max_tol => false, :units => nil} # not reporting EUI and end use comparison until update to use newer methods in standards #results << { method_name: 'check_eui_reasonableness', cat: 'General', standards: true, data: nil, tol_min: 0.1, tol_max: true, units: 'fraction' } #results << { method_name: 'check_eui_by_end_use', cat: 'General', standards: true, data: nil, tol_min: 0.25, tol_max: true, units: 'fraction' } results << { method_name: 'check_mech_sys_part_load_eff', cat: 'General', standards: true, data: nil, tol_min: 0.05, tol_max: true, units: 'fraction' } results << { method_name: 'check_mech_sys_capacity', cat: 'General', standards: true, data: , tol_min: false, tol_max: false, units: 'fraction' } results << { method_name: 'check_simultaneous_heating_and_cooling', cat: 'General', standards: false, data: nil, tol_min: false, tol_max: 0.05, units: 'fraction' } results << { method_name: 'check_internal_loads', cat: 'Baseline', standards: true, data: nil, tol_min: 0.1, tol_max: true, units: 'fraction' } results << { method_name: 'check_schedules', cat: 'Baseline', standards: true, data: nil, tol_min: 0.05, tol_max: true, units: 'fraction' } results << { method_name: 'check_envelope_conductance', cat: 'Baseline', standards: true, data: nil, tol_min: 0.1, tol_max: true, units: 'fraction' } results << { method_name: 'check_domestic_hot_water', cat: 'Baseline', standards: true, data: nil, tol_min: 0.25, tol_max: true, units: 'fraction' } results << { method_name: 'check_mech_sys_efficiency', cat: 'Baseline', standards: true, data: nil, tol_min: 0.1, tol_max: true, units: 'fraction' } results << { method_name: 'check_mech_sys_type', cat: 'Baseline', standards: true, data: nil, tol_min: false, tol_max: false, units: nil } results << { method_name: 'check_supply_air_and_thermostat_temp_difference', cat: 'Baseline', standards: true, data: nil, tol_min: 0.5, tol_max: false, units: 'F' } results end |
#run(runner, user_arguments) ⇒ Object
define what happens when the measure is run
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 |
# File 'lib/measures/generic_qaqc/measure.rb', line 199 def run(runner, user_arguments) super(runner, user_arguments) # make the runner a class variable @runner = runner # if true errors on QAQC sections will show full backtrace. Use for diagnostics @error_backtrace = true # register initial condition runner.registerInitialCondition('Starting QAQC report generation') # get sql, model, and web assets setup = OsLib_Reporting.setup(runner) unless setup return false end @model = setup[:model] # workspace = setup[:workspace] @sql = setup[:sqlFile] web_asset_path = setup[:web_asset_path] # temp code to address climate zone problem mentioned in OpenStudio issue# 3148 climateZones = @model.getClimateZones cz = climateZones.getClimateZones('ASHRAE').first.value climateZones.clear climateZones.setClimateZone('ASHRAE', cz) # assign the user inputs to variables args = runner.getArgumentValues(arguments, user_arguments) args = Hash[args.collect{ |k, v| [k.to_s, v] }] unless args return false end # vector to store the results and checks report_elems = OpenStudio::AttributeVector.new # used for edapt programs to populate xml file with extra data # report_elems << create_results # lookup and replace argument values from upstream measures if args['use_upstream_args'] == true args.each do |arg, value| next if arg == 'use_upstream_args' # this argument should not be changed value_from_osw = runner.getPastStepValuesForName(arg) value_from_osw = value_from_osw.collect{ |k, v| Hash[:measure_name => k, :value => v] }.first if !value_from_osw.empty? if !value_from_osw.empty? runner.registerInfo("Replacing argument named #{arg} from current measure with a value of #{value_from_osw[:value]} from #{value_from_osw[:measure_name]}.") new_val = value_from_osw[:value] # TODO: - make code to handle non strings more robust. check_upstream_measure_for_arg coudl pass bakc the argument type if arg == 'total_bldg_floor_area' args[arg] = new_val.to_f elsif arg == 'num_stories_above_grade' args[arg] = new_val.to_f elsif arg == 'zipcode' args[arg] = new_val.to_i else args[arg] = new_val end end end end # utility name to to used by some qaqc checks @utility_name = nil # for utility QAQC string is passed in default_target_standard = args['template'] # for utility QAQC this is hard coded, for generic it is user argument # get building type, different standards path if multifamily building_type = '' if @model.getBuilding.standardsBuildingType.is_initialized building_type = @model.getBuilding.standardsBuildingType.get end # create an attribute vector to hold the checks check_elems = OpenStudio::AttributeVector.new # loop through QAQC categories where bool is true possible_check_categories.each do |hash| # skip if bool arg for this method is false next if args[hash[:method_name]] == false cat = hash[:cat] cat_input = "\'#{cat}\'" if hash[:standards] standards_input = ",\'#{default_target_standard}\'" else standards_input = '' end if hash[:data].nil? data_input = '' else data_input = ",#{hash[:data]}" end # get min tol if args.key?("#{hash[:method_name]}_tol") # get tol value tol = args["#{hash[:method_name]}_tol"] # set min inputs if tol.is_a? Float min_input = ",#{tol}" else min_input = '' end else min_input = '' end # get max tol if args.key?("#{hash[:method_name]}_max_tol") # get tol value max_tol = args["#{hash[:method_name]}_max_tol"] # set max inputs if max_tol.is_a? Float max_input = ",#{max_tol}" elsif (hash[:tol_max] == true) && hash[:tol_min].is_a?(Float) # if true then use double from min_tol max_input = ",#{args["#{hash[:method_name]}_tol"]}" else max_input = '' end else if (hash[:tol_max] == true) && hash[:tol_min].is_a?(Float) # if true then use double from min_tol max_input = ",#{args["#{hash[:method_name]}_tol"]}" else max_input = '' end end # run QAQC check eval("check_elems << #{hash[:method_name]}(#{cat_input}#{data_input}#{standards_input}#{min_input}#{max_input},false)") end # add checks to report_elems report_elems << OpenStudio::Attribute.new('checks', check_elems) # create an extra layer of report. the first level gets thrown away. top_level_elems = OpenStudio::AttributeVector.new top_level_elems << OpenStudio::Attribute.new('report', report_elems) # create the report result = OpenStudio::Attribute.new('summary_report', top_level_elems) result.saveToXml(OpenStudio::Path.new('report.xml')) # closing the sql file @sql.close # reporting final condition runner.registerFinalCondition('Finished generating report.xml.') # populate sections using attributes sections = OsLib_Reporting.sections_from_check_attributes(check_elems, runner) # generate html output OsLib_Reporting.gen_html("#{File.dirname(__FILE__)}report.html.erb", web_asset_path, sections, name) return true end |