openstudio-standards 0.2.17.rc1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/openstudio_standards_duplicates_log.csv +5 -0
- data/lib/openstudio-standards/btap/btap_result.rb +138 -138
- data/lib/openstudio-standards/btap/economics.rb +58 -53
- data/lib/openstudio-standards/btap/envelope.rb +1 -1
- data/lib/openstudio-standards/btap/fileio.rb +12 -12
- data/lib/openstudio-standards/btap/measures.rb +63 -59
- data/lib/openstudio-standards/btap/vintagizer.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +7 -7
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +5 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +8 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +9 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +53 -23
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +15 -1
- data/lib/openstudio-standards/standards/Standards.Construction.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.Model.rb +18 -18
- data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +5 -5
- data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +3 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +43 -40
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +2 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.entryways.json +19 -8
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.parking.json +13 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirLoopHVAC.rb +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirLoopHVAC.rb +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +9 -9
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +5 -1
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +5 -1
- data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +8 -4
- data/lib/openstudio-standards/standards/necb/ECMS/nv.rb +8 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +7 -3
- data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +4 -4
- data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +1 -1
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards/weather/Weather.Model.rb +5 -0
- metadata +4 -2
| @@ -24,28 +24,28 @@ require "#{File.dirname(__FILE__)}/btap" | |
| 24 24 |  | 
| 25 25 | 
             
            class OSMArg
         | 
| 26 26 | 
             
              ARGUMENT_TYPES = [
         | 
| 27 | 
            -
                "BOOL", | 
| 28 | 
            -
                "STRING", | 
| 29 | 
            -
                "INTEGER", | 
| 30 | 
            -
                "FLOAT", | 
| 27 | 
            +
                "BOOL",
         | 
| 28 | 
            +
                "STRING",
         | 
| 29 | 
            +
                "INTEGER",
         | 
| 30 | 
            +
                "FLOAT",
         | 
| 31 31 | 
             
                "STRINGCHOICE",
         | 
| 32 | 
            -
                "WSCHOICE" | 
| 32 | 
            +
                "WSCHOICE"
         | 
| 33 33 | 
             
              ]
         | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
              attr_accessor :runner, | 
| 38 | 
            -
                :variable_name, | 
| 34 | 
            +
             | 
| 35 | 
            +
             | 
| 36 | 
            +
             | 
| 37 | 
            +
              attr_accessor :runner,
         | 
| 38 | 
            +
                :variable_name,
         | 
| 39 39 | 
             
                :type,
         | 
| 40 | 
            -
                :required, | 
| 40 | 
            +
                :required,
         | 
| 41 41 | 
             
                :model_dependant,
         | 
| 42 | 
            -
                :display_name, | 
| 43 | 
            -
                :default_value, | 
| 44 | 
            -
                :min_value, | 
| 45 | 
            -
                :max_value, | 
| 46 | 
            -
                :string_choice_array, | 
| 42 | 
            +
                :display_name,
         | 
| 43 | 
            +
                :default_value,
         | 
| 44 | 
            +
                :min_value,
         | 
| 45 | 
            +
                :max_value,
         | 
| 46 | 
            +
                :string_choice_array,
         | 
| 47 47 | 
             
                :os_object_type
         | 
| 48 | 
            -
             | 
| 48 | 
            +
             | 
| 49 49 | 
             
              def self.bool( variable_name,display_name,required,default_value )
         | 
| 50 50 | 
             
                raise "#{default_value} defaut value is not a bool." unless default_value.is_a?(Bool)
         | 
| 51 51 | 
             
                default_value.respond_to?(:to_s)
         | 
| @@ -53,47 +53,47 @@ class OSMArg | |
| 53 53 | 
             
                arg.default_value = default_value
         | 
| 54 54 | 
             
                return arg
         | 
| 55 55 | 
             
              end
         | 
| 56 | 
            -
             | 
| 56 | 
            +
             | 
| 57 57 | 
             
              def self.string( variable_name,display_name,required,default_value )
         | 
| 58 58 | 
             
                raise "#{default_value} defaut value is not a string." unless default_value.respond_to?(:to_s)
         | 
| 59 59 | 
             
                arg = OSMArg.new( "STRING", variable_name, display_name, required)
         | 
| 60 60 | 
             
                arg.default_value = default_value
         | 
| 61 61 | 
             
                return arg
         | 
| 62 62 | 
             
              end
         | 
| 63 | 
            -
             | 
| 63 | 
            +
             | 
| 64 64 | 
             
              def self.integer( variable_name,display_name,required,default_value,min_value,max_value )
         | 
| 65 65 | 
             
                raise "#{default_value} defaut value is not a integer." unless default_value.respond_to?(:to_i)
         | 
| 66 66 | 
             
                arg = OSMArg.new( "INTEGER", variable_name, display_name, required)
         | 
| 67 67 | 
             
                arg.default_value = default_value
         | 
| 68 68 | 
             
                arg.min_value = min_value
         | 
| 69 69 | 
             
                arg.max_value = max_value
         | 
| 70 | 
            -
                return arg | 
| 70 | 
            +
                return arg
         | 
| 71 71 | 
             
              end
         | 
| 72 | 
            -
             | 
| 72 | 
            +
             | 
| 73 73 | 
             
              def self.float( variable_name, display_name, required,default_value,min_value, max_value )
         | 
| 74 74 | 
             
                raise "#{default_value} defaut value is not a float." unless default_value.respond_to?(:to_f)
         | 
| 75 75 | 
             
                arg = OSMArg.new( "INTEGER", variable_name, display_name, required)
         | 
| 76 76 | 
             
                arg.default_value = default_value
         | 
| 77 77 | 
             
                arg.min_value = min_value
         | 
| 78 78 | 
             
                arg.max_value = max_value
         | 
| 79 | 
            -
                return arg | 
| 79 | 
            +
                return arg
         | 
| 80 80 | 
             
              end
         | 
| 81 | 
            -
             | 
| 81 | 
            +
             | 
| 82 82 | 
             
              def self.choice(variable_name,display_name,required,default_value,string_choice_array)
         | 
| 83 | 
            -
                raise "#{default_value} defaut value is not an array." unless default_value.is_a?(Array) | 
| 83 | 
            +
                raise "#{default_value} defaut value is not an array." unless default_value.is_a?(Array)
         | 
| 84 84 | 
             
                arg = OSMArg.new( "STRINGCHOICE", variable_name, display_name, required)
         | 
| 85 85 | 
             
                arg.default_value = default_value
         | 
| 86 86 | 
             
                arg.string_choice_array = string_choice_array
         | 
| 87 87 | 
             
                return arg
         | 
| 88 88 | 
             
              end
         | 
| 89 | 
            -
             | 
| 89 | 
            +
             | 
| 90 90 | 
             
              def self.wschoice( variable_name, display_name, required, default_value, os_object_type)
         | 
| 91 91 | 
             
                arg = OSMArg.new( "WSCHOICE", variable_name, display_name, required )
         | 
| 92 92 | 
             
                arg.default_value = default_value
         | 
| 93 93 | 
             
                arg.os_object_type = os_object_type
         | 
| 94 | 
            -
                return arg | 
| 94 | 
            +
                return arg
         | 
| 95 95 | 
             
              end
         | 
| 96 | 
            -
             | 
| 96 | 
            +
             | 
| 97 97 | 
             
              def initialize( type, variable_name, display_name, required )
         | 
| 98 98 | 
             
                self.type = type
         | 
| 99 99 | 
             
                self.variable_name = variable_name
         | 
| @@ -106,9 +106,9 @@ class OSMArg | |
| 106 106 | 
             
                  self.model_dependant = false
         | 
| 107 107 | 
             
                end
         | 
| 108 108 | 
             
                return self
         | 
| 109 | 
            -
              end | 
| 109 | 
            +
              end
         | 
| 110 110 | 
             
            end
         | 
| 111 | 
            -
             | 
| 111 | 
            +
             | 
| 112 112 |  | 
| 113 113 |  | 
| 114 114 |  | 
| @@ -116,10 +116,10 @@ end | |
| 116 116 | 
             
            module BTAP
         | 
| 117 117 | 
             
              module Measures
         | 
| 118 118 | 
             
                module OSMeasures
         | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 119 | 
            +
             | 
| 120 | 
            +
             | 
| 121 | 
            +
             | 
| 122 | 
            +
             | 
| 123 123 | 
             
                  class BTAPModelUserScript < OpenStudio::Ruleset::ModelUserScript
         | 
| 124 124 | 
             
                    #if and E+ measure replace OpenStudio::Ruleset::ModelUserScript with OpenStudio::Ruleset::WorkspaceUserScript
         | 
| 125 125 | 
             
                    #Array containing information of all inputs required by measure.
         | 
| @@ -134,8 +134,8 @@ module BTAP | |
| 134 134 | 
             
                      "BTAPModelUserScript"
         | 
| 135 135 | 
             
                      OSMArgument.new
         | 
| 136 136 | 
             
                    end
         | 
| 137 | 
            -
             | 
| 138 | 
            -
                    #this method will output the ruby macro to perform the change. | 
| 137 | 
            +
             | 
| 138 | 
            +
                    #this method will output the ruby macro to perform the change.
         | 
| 139 139 | 
             
                    def generate_ruby_macro(model,runner)
         | 
| 140 140 | 
             
                      if @file == nil or @file == ""
         | 
| 141 141 | 
             
                        @file = "Enter_Path_To_#{self.class.name}_measure.rb_File!"
         | 
| @@ -190,8 +190,8 @@ module BTAP | |
| 190 190 | 
             
                      if not runner.validateUserArguments(self.arguments(model),user_arguments)
         | 
| 191 191 | 
             
                        return false
         | 
| 192 192 | 
             
                      end
         | 
| 193 | 
            -
             | 
| 194 | 
            -
                      #Set argument to instance variables. | 
| 193 | 
            +
             | 
| 194 | 
            +
                      #Set argument to instance variables.
         | 
| 195 195 | 
             
                      self.argument_getter(model, runner,user_arguments)
         | 
| 196 196 | 
             
                      #will run the childs method measure_code
         | 
| 197 197 | 
             
                      result =  self.measure_code(model,runner)
         | 
| @@ -201,7 +201,7 @@ module BTAP | |
| 201 201 |  | 
| 202 202 | 
             
                    def argument_setter(model,args)
         | 
| 203 203 | 
             
                      #***boilerplate code starts. Do not edit...
         | 
| 204 | 
            -
             | 
| 204 | 
            +
             | 
| 205 205 |  | 
| 206 206 | 
             
                      #iterate through array of hashes and make arguments based on type and set
         | 
| 207 207 | 
             
                      # max and min values where applicable.
         | 
| @@ -247,7 +247,7 @@ module BTAP | |
| 247 247 | 
             
                      unless @argument_array == nil
         | 
| 248 248 | 
             
                        @argument_array.each do |row|
         | 
| 249 249 | 
             
                          name = row.variable_name
         | 
| 250 | 
            -
             | 
| 250 | 
            +
             | 
| 251 251 | 
             
                          case row.type
         | 
| 252 252 | 
             
                          when "BOOL"
         | 
| 253 253 | 
             
                            value = runner.getBoolArgumentValue(name, user_arguments)
         | 
| @@ -269,7 +269,7 @@ module BTAP | |
| 269 269 | 
             
                            value = runner.getDoubleArgumentValue(name, user_arguments)
         | 
| 270 270 | 
             
                            instance_variable_set("@#{name}",value)
         | 
| 271 271 | 
             
                            @arg_table << [name,value]
         | 
| 272 | 
            -
             | 
| 272 | 
            +
             | 
| 273 273 | 
             
                            if ( not row.min_value.nil?  and instance_variable_get("@#{name}") < row.min_value ) or ( not row.max_value.nil? and instance_variable_get("@#{name}") > row.max_value )
         | 
| 274 274 | 
             
                              runner.registerError("#{row.display_name} must be greater than or equal to #{row.min_value} and less than or equal to #{row.max_value}.  You entered #{instance_variable_get("@#{name}")}.")
         | 
| 275 275 | 
             
                              return false
         | 
| @@ -288,10 +288,10 @@ module BTAP | |
| 288 288 | 
             
                        end #end do
         | 
| 289 289 | 
             
                      end
         | 
| 290 290 | 
             
                      return @arg_table
         | 
| 291 | 
            -
                    end | 
| 292 | 
            -
             | 
| 291 | 
            +
                    end
         | 
| 292 | 
            +
             | 
| 293 293 | 
             
                  end
         | 
| 294 | 
            -
                  #Measure Template simplified. | 
| 294 | 
            +
                  #Measure Template simplified.
         | 
| 295 295 | 
             
                  class TemplateModelMeasure < BTAPModelUserScript
         | 
| 296 296 |  | 
| 297 297 | 
             
                    def name
         | 
| @@ -391,14 +391,14 @@ module BTAP | |
| 391 391 | 
             
                    def run(model, runner, user_arguments)
         | 
| 392 392 | 
             
                      #run the super
         | 
| 393 393 | 
             
                      parent_method_is_true = super(model, runner, user_arguments)
         | 
| 394 | 
            -
             | 
| 395 | 
            -
             | 
| 394 | 
            +
             | 
| 395 | 
            +
             | 
| 396 396 | 
             
                      ###############
         | 
| 397 | 
            -
             | 
| 398 | 
            -
                      #Set Archetype name in runner. | 
| 397 | 
            +
             | 
| 398 | 
            +
                      #Set Archetype name in runner.
         | 
| 399 399 | 
             
                      runner.registerValue('archetype_name',@archetype_name)
         | 
| 400 | 
            -
             | 
| 401 | 
            -
                      #Set path to OSM files. | 
| 400 | 
            +
             | 
| 401 | 
            +
                      #Set path to OSM files.
         | 
| 402 402 | 
             
                      alternative_model_path = OpenStudio::Path.new("#{File.dirname(__FILE__)}/#{@archetype_name}.osm")
         | 
| 403 403 | 
             
                      #load model and test.
         | 
| 404 404 | 
             
                      translator = OpenStudio::OSVersion::VersionTranslator.new
         | 
| @@ -561,7 +561,7 @@ module BTAP | |
| 561 561 | 
             
                        model = self.load_base_model_building()
         | 
| 562 562 | 
             
                        self.set_weather_file(model)
         | 
| 563 563 | 
             
                        self.set_hourly_output(model)
         | 
| 564 | 
            -
             | 
| 564 | 
            +
             | 
| 565 565 | 
             
                        model,log = self.apply_ecms(model,@csv_data)
         | 
| 566 566 | 
             
                        BTAP::FileIO::save_osm( model, "#{output_folder}/#{BTAP::FileIO::get_name(model)}.osm") unless output_folder.nil?
         | 
| 567 567 | 
             
                        File.open("#{output_folder}/#{BTAP::FileIO::get_name(model)}.log", 'w') { |file| file.write(log) }  unless output_folder.nil?
         | 
| @@ -621,7 +621,7 @@ module BTAP | |
| 621 621 | 
             
                      "cost_per_building"
         | 
| 622 622 | 
             
                    ]
         | 
| 623 623 | 
             
                    self.set_instance_variables( measure_values )
         | 
| 624 | 
            -
             | 
| 624 | 
            +
             | 
| 625 625 | 
             
                    #cost per building and building area
         | 
| 626 626 | 
             
                    building = model.building.get
         | 
| 627 627 | 
             
                    raise ("you did not enter a cost for measure #{@measure_id}. All measures must have a cost of at least 0.0 .  Please add a cost_per_building field.") if @cost_per_building.nil?
         | 
| @@ -753,7 +753,7 @@ module BTAP | |
| 753 753 | 
             
                        @total_building_construction_set_cost
         | 
| 754 754 | 
             
                      )
         | 
| 755 755 |  | 
| 756 | 
            -
                      #Give adiabatic surfaces a construction. Does not matter what. This is a bug in  | 
| 756 | 
            +
                      #Give adiabatic surfaces a construction. Does not matter what. This is a bug in OpenStudio that leave these surfaces unassigned by the default construction set.
         | 
| 757 757 | 
             
                      all_adiabatic_surfaces = BTAP::Geometry::Surfaces::filter_by_boundary_condition(model.getSurfaces, "Adiabatic")
         | 
| 758 758 | 
             
                      unless all_adiabatic_surfaces.empty?
         | 
| 759 759 | 
             
                        BTAP::Geometry::Surfaces::set_surfaces_construction( all_adiabatic_surfaces, model.building.get.defaultConstructionSet.get.defaultInteriorSurfaceConstructions.get.wallConstruction.get)
         | 
| @@ -772,7 +772,7 @@ module BTAP | |
| 772 772 | 
             
                      "infiltration_flow_per_exterior_area",
         | 
| 773 773 | 
             
                      "infiltration_air_changes_per_hour"
         | 
| 774 774 | 
             
                    ]
         | 
| 775 | 
            -
             | 
| 775 | 
            +
             | 
| 776 776 | 
             
                    #Set all the above instance variables to the @csv_data values or, if not set or == 'na', to nil.
         | 
| 777 777 | 
             
                    self.set_instance_variables(measure_values)
         | 
| 778 778 |  | 
| @@ -811,7 +811,7 @@ module BTAP | |
| 811 811 | 
             
                        fan.setMotorEfficiency( @fan_motor_eff ) unless @fan_motor_eff.nil?
         | 
| 812 812 | 
             
                        log  << fan.name.get.to_s << ",#{fan.fanEfficiency},#{fan.motorEfficiency}\n"
         | 
| 813 813 | 
             
                      end
         | 
| 814 | 
            -
             | 
| 814 | 
            +
             | 
| 815 815 | 
             
                    end
         | 
| 816 816 |  | 
| 817 817 | 
             
                    case @fan_volume_type
         | 
| @@ -975,7 +975,9 @@ module BTAP | |
| 975 975 | 
             
                      model.getCoilCoolingDXSingleSpeeds.sort.each do |cooling_coil|
         | 
| 976 976 | 
             
                        cooling_coil.setRatedCOP( OpenStudio::OptionalDouble.new( @cop ) ) unless @cop.nil?
         | 
| 977 977 | 
             
                        cop = "NA"
         | 
| 978 | 
            -
                         | 
| 978 | 
            +
                        # Prior to 3.5.0, it was an optional double, now it's a double
         | 
| 979 | 
            +
                        cop_ = OpenStudio::OptionalDouble.new(cooling_coil.ratedCOP)
         | 
| 980 | 
            +
                        cop = cop_.get unless cop_.empty?
         | 
| 979 981 | 
             
                        log  << cooling_coil.name.get.to_s << ",#{cop}\n"
         | 
| 980 982 |  | 
| 981 983 | 
             
                      end
         | 
| @@ -987,9 +989,11 @@ module BTAP | |
| 987 989 | 
             
                        cooling_coil.setRatedHighSpeedCOP( @cop  ) unless @cop.nil?
         | 
| 988 990 | 
             
                        cooling_coil.setRatedLowSpeedCOP(  @cop  ) unless @cop.nil?
         | 
| 989 991 | 
             
                        cop_high = "NA"
         | 
| 990 | 
            -
                         | 
| 992 | 
            +
                        cop_ = OpenStudio::OptionalDouble.new(cooling_coil.ratedHighSpeedCOP)
         | 
| 993 | 
            +
                        cop_high = cop_.get unless cop_.empty?
         | 
| 991 994 | 
             
                        cop_low = "NA"
         | 
| 992 | 
            -
                         | 
| 995 | 
            +
                        cop_ = OpenStudio::OptionalDouble.new(cooling_coil.ratedLowSpeedCOP)
         | 
| 996 | 
            +
                        cop_low = cop_.get unless cop_.empty?
         | 
| 993 997 | 
             
                        log  << cooling_coil.name.get.to_s << ",#{cop_high},#{cop_low}\n"
         | 
| 994 998 | 
             
                      end
         | 
| 995 999 | 
             
                    end
         | 
| @@ -1296,8 +1300,8 @@ module BTAP | |
| 1296 1300 | 
             
                        @erv_nominal_electric_power,
         | 
| 1297 1301 | 
             
                        @erv_economizer_lockout.to_bool
         | 
| 1298 1302 | 
             
                      ).each { |erv| log << erv.to_s }
         | 
| 1299 | 
            -
             | 
| 1300 | 
            -
             | 
| 1303 | 
            +
             | 
| 1304 | 
            +
             | 
| 1301 1305 | 
             
                      #Add setpoint manager to all OA object in airloops.
         | 
| 1302 1306 | 
             
                      model.getHeatExchangerAirToAirSensibleAndLatents.sort.each do |erv|
         | 
| 1303 1307 |  | 
| @@ -99,7 +99,7 @@ class Vintagizer | |
| 99 99 | 
             
                new_construction_set.setName(construction_id)
         | 
| 100 100 | 
             
                constructions_model.building.get.setDefaultConstructionSet( new_construction_set.clone( constructions_model ).to_DefaultConstructionSet.get )
         | 
| 101 101 |  | 
| 102 | 
            -
                #Give adiabatic surfaces a construction. Does not matter what. This is a bug in  | 
| 102 | 
            +
                #Give adiabatic surfaces a construction. Does not matter what. This is a bug in OpenStudio that leave these surfaces unassigned by the default construction set.
         | 
| 103 103 | 
             
                all_adiabatic_surfaces = BTAP::Geometry::Surfaces::filter_by_boundary_condition(constructions_model.getSurfaces, "Adiabatic")
         | 
| 104 104 | 
             
                BTAP::Geometry::Surfaces::set_surfaces_construction( all_adiabatic_surfaces, constructions_model.building.get.defaultConstructionSet.get.defaultInteriorSurfaceConstructions.get.wallConstruction.get)
         | 
| 105 105 |  | 
| @@ -59,7 +59,7 @@ class Standard | |
| 59 59 | 
             
                end
         | 
| 60 60 |  | 
| 61 61 | 
             
                # add exterior lights for parking area
         | 
| 62 | 
            -
                if area_length_count_hash[:parking_area_and_drives_area] > 0
         | 
| 62 | 
            +
                if !area_length_count_hash[:parking_area_and_drives_area].nil? && area_length_count_hash[:parking_area_and_drives_area] > 0
         | 
| 63 63 |  | 
| 64 64 | 
             
                  # lighting values
         | 
| 65 65 | 
             
                  multiplier = area_length_count_hash[:parking_area_and_drives_area] * onsite_parking_fraction
         | 
| @@ -86,7 +86,7 @@ class Standard | |
| 86 86 | 
             
                end
         | 
| 87 87 |  | 
| 88 88 | 
             
                # add exterior lights for facades
         | 
| 89 | 
            -
                if area_length_count_hash[:building_facades] > 0
         | 
| 89 | 
            +
                if !area_length_count_hash[:building_facades].nil? && area_length_count_hash[:building_facades] > 0
         | 
| 90 90 |  | 
| 91 91 | 
             
                  # lighting values
         | 
| 92 92 | 
             
                  multiplier = area_length_count_hash[:building_facades]
         | 
| @@ -113,7 +113,7 @@ class Standard | |
| 113 113 | 
             
                end
         | 
| 114 114 |  | 
| 115 115 | 
             
                # add exterior lights for main entries
         | 
| 116 | 
            -
                if area_length_count_hash[:main_entries] > 0
         | 
| 116 | 
            +
                if !area_length_count_hash[:main_entries].nil? && area_length_count_hash[:main_entries] > 0
         | 
| 117 117 |  | 
| 118 118 | 
             
                  # lighting values
         | 
| 119 119 | 
             
                  multiplier = area_length_count_hash[:main_entries]
         | 
| @@ -140,7 +140,7 @@ class Standard | |
| 140 140 | 
             
                end
         | 
| 141 141 |  | 
| 142 142 | 
             
                # add exterior lights for other doors
         | 
| 143 | 
            -
                if area_length_count_hash[:other_doors] > 0
         | 
| 143 | 
            +
                if !area_length_count_hash[:other_doors].nil? && area_length_count_hash[:other_doors] > 0
         | 
| 144 144 |  | 
| 145 145 | 
             
                  # lighting values
         | 
| 146 146 | 
             
                  multiplier = area_length_count_hash[:other_doors]
         | 
| @@ -167,7 +167,7 @@ class Standard | |
| 167 167 | 
             
                end
         | 
| 168 168 |  | 
| 169 169 | 
             
                # add exterior lights for entry canopies
         | 
| 170 | 
            -
                if area_length_count_hash[:canopy_entry_area] > 0
         | 
| 170 | 
            +
                if !area_length_count_hash[:canopy_entry_area].nil? && area_length_count_hash[:canopy_entry_area] > 0
         | 
| 171 171 |  | 
| 172 172 | 
             
                  # lighting values
         | 
| 173 173 | 
             
                  multiplier = area_length_count_hash[:canopy_entry_area]
         | 
| @@ -194,7 +194,7 @@ class Standard | |
| 194 194 | 
             
                end
         | 
| 195 195 |  | 
| 196 196 | 
             
                # add exterior lights for emergency canopies
         | 
| 197 | 
            -
                if area_length_count_hash[:canopy_emergency_area] > 0
         | 
| 197 | 
            +
                if !area_length_count_hash[:canopy_emergency_area].nil? && area_length_count_hash[:canopy_emergency_area] > 0
         | 
| 198 198 |  | 
| 199 199 | 
             
                  # lighting values
         | 
| 200 200 | 
             
                  multiplier = area_length_count_hash[:canopy_emergency_area]
         | 
| @@ -221,7 +221,7 @@ class Standard | |
| 221 221 | 
             
                end
         | 
| 222 222 |  | 
| 223 223 | 
             
                # add exterior lights for drive through windows
         | 
| 224 | 
            -
                if area_length_count_hash[:drive_through_windows] > 0
         | 
| 224 | 
            +
                if !area_length_count_hash[:drive_through_windows].nil? && area_length_count_hash[:drive_through_windows] > 0
         | 
| 225 225 |  | 
| 226 226 | 
             
                  # lighting values
         | 
| 227 227 | 
             
                  multiplier = area_length_count_hash[:drive_through_windows]
         | 
| @@ -2721,7 +2721,11 @@ Standard.class_eval do | |
| 2721 2721 | 
             
                    end
         | 
| 2722 2722 | 
             
                  end
         | 
| 2723 2723 | 
             
                end
         | 
| 2724 | 
            -
             | 
| 2724 | 
            +
             | 
| 2725 | 
            +
                # check wall area is non-zero
         | 
| 2726 | 
            +
                if wwr && wall_area > 0
         | 
| 2727 | 
            +
                  return window_area / wall_area * 100
         | 
| 2728 | 
            +
                end
         | 
| 2725 2729 |  | 
| 2726 2730 | 
             
                # else
         | 
| 2727 2731 | 
             
                return window_area
         | 
| @@ -546,6 +546,14 @@ class Standard | |
| 546 546 | 
             
                  default_water_heater_ambient_temp_sch = model_add_constant_schedule_ruleset(model,
         | 
| 547 547 | 
             
                                                                                              OpenStudio.convert(70.0, 'F', 'C').get,
         | 
| 548 548 | 
             
                                                                                              name = 'Water Heater Ambient Temp Schedule - 70F')
         | 
| 549 | 
            +
                  if temp_sch_type_limits.nil?
         | 
| 550 | 
            +
                    temp_sch_type_limits = model_add_schedule_type_limits(model,
         | 
| 551 | 
            +
                                                                          name: 'Temperature Schedule Type Limits',
         | 
| 552 | 
            +
                                                                          lower_limit_value: 0.0,
         | 
| 553 | 
            +
                                                                          upper_limit_value: 100.0,
         | 
| 554 | 
            +
                                                                          numeric_type: 'Continuous',
         | 
| 555 | 
            +
                                                                          unit_type: 'Temperature')
         | 
| 556 | 
            +
                  end
         | 
| 549 557 | 
             
                  default_water_heater_ambient_temp_sch.setScheduleTypeLimits(temp_sch_type_limits)
         | 
| 550 558 | 
             
                  tank.setAmbientTemperatureIndicator('Schedule')
         | 
| 551 559 | 
             
                  tank.setAmbientTemperatureSchedule(default_water_heater_ambient_temp_sch)
         | 
| @@ -57,14 +57,20 @@ class Standard | |
| 57 57 | 
             
                end
         | 
| 58 58 |  | 
| 59 59 | 
             
                sizing_system = air_loop_hvac.sizingSystem
         | 
| 60 | 
            -
                 | 
| 61 | 
            -
             | 
| 60 | 
            +
                if air_loop_hvac.model.version < OpenStudio::VersionString.new('3.3.0')
         | 
| 61 | 
            +
                  sizing_system.setSystemOutdoorAirMethod('VentilationRateProcedure')
         | 
| 62 | 
            +
                else
         | 
| 63 | 
            +
                  sizing_system.setSystemOutdoorAirMethod('Standard62.1VentilationRateProcedure')
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                # Set the minimum zone ventilation efficiency
         | 
| 67 | 
            +
                min_ventilation_efficiency = air_loop_hvac_minimum_zone_ventilation_efficiency(air_loop_hvac)
         | 
| 62 68 | 
             
                air_loop_hvac.thermalZones.sort.each do |zone|
         | 
| 63 69 | 
             
                  sizing_zone = zone.sizingZone
         | 
| 64 70 | 
             
                  if air_loop_hvac.model.version < OpenStudio::VersionString.new('3.0.0')
         | 
| 65 71 | 
             
                    OpenStudio.logFree(OpenStudio::Warn, 'openstudio.prototype.SizingSystem', "The design minimum zone ventilation efficiency cannot be set for #{sizing_system.name}. It can only be set OpenStudio 3.0.0 and later.")
         | 
| 66 72 | 
             
                  else
         | 
| 67 | 
            -
                    sizing_zone.setDesignMinimumZoneVentilationEfficiency( | 
| 73 | 
            +
                    sizing_zone.setDesignMinimumZoneVentilationEfficiency(min_ventilation_efficiency)
         | 
| 68 74 | 
             
                  end
         | 
| 69 75 | 
             
                end
         | 
| 70 76 |  | 
| @@ -1757,13 +1757,21 @@ class Standard | |
| 1757 1757 | 
             
                # set air loop availability controls and night cycle manager, after oa system added
         | 
| 1758 1758 | 
             
                air_loop.setAvailabilitySchedule(hvac_op_sch)
         | 
| 1759 1759 | 
             
                air_loop.setNightCycleControlType('CycleOnAny')
         | 
| 1760 | 
            -
             | 
| 1761 | 
            -
                if  | 
| 1762 | 
            -
                  avail_mgr =  | 
| 1763 | 
            -
                  if avail_mgr. | 
| 1764 | 
            -
                    avail_mgr = avail_mgr. | 
| 1765 | 
            -
             | 
| 1766 | 
            -
             | 
| 1760 | 
            +
             | 
| 1761 | 
            +
                if model.version < OpenStudio::VersionString.new('3.5.0')
         | 
| 1762 | 
            +
                  avail_mgr = air_loop.availabilityManager
         | 
| 1763 | 
            +
                  if avail_mgr.is_initialized
         | 
| 1764 | 
            +
                    avail_mgr = avail_mgr.get
         | 
| 1765 | 
            +
                  else
         | 
| 1766 | 
            +
                    avail_mgr = nil
         | 
| 1767 | 
            +
                  end 
         | 
| 1768 | 
            +
                else 
         | 
| 1769 | 
            +
                  avail_mgr = air_loop.availabilityManagers[0]
         | 
| 1770 | 
            +
                end
         | 
| 1771 | 
            +
             | 
| 1772 | 
            +
                if !avail_mgr.nil? && avail_mgr.to_AvailabilityManagerNightCycle.is_initialized
         | 
| 1773 | 
            +
                  avail_mgr = avail_mgr.to_AvailabilityManagerNightCycle.get
         | 
| 1774 | 
            +
                  avail_mgr.setCyclingRunTime(1800)
         | 
| 1767 1775 | 
             
                end
         | 
| 1768 1776 |  | 
| 1769 1777 | 
             
                # hook the VAV system to each zone
         | 
| @@ -2113,13 +2121,21 @@ class Standard | |
| 2113 2121 | 
             
                # set air loop availability controls and night cycle manager, after oa system added
         | 
| 2114 2122 | 
             
                air_loop.setAvailabilitySchedule(hvac_op_sch)
         | 
| 2115 2123 | 
             
                air_loop.setNightCycleControlType('CycleOnAny')
         | 
| 2116 | 
            -
             | 
| 2117 | 
            -
                if  | 
| 2118 | 
            -
                  avail_mgr =  | 
| 2119 | 
            -
                  if avail_mgr. | 
| 2120 | 
            -
                    avail_mgr = avail_mgr. | 
| 2121 | 
            -
             | 
| 2122 | 
            -
             | 
| 2124 | 
            +
             | 
| 2125 | 
            +
                if model.version < OpenStudio::VersionString.new('3.5.0')
         | 
| 2126 | 
            +
                  avail_mgr = air_loop.availabilityManager
         | 
| 2127 | 
            +
                  if avail_mgr.is_initialized
         | 
| 2128 | 
            +
                    avail_mgr = avail_mgr.get
         | 
| 2129 | 
            +
                  else
         | 
| 2130 | 
            +
                    avail_mgr = nil
         | 
| 2131 | 
            +
                  end 
         | 
| 2132 | 
            +
                else 
         | 
| 2133 | 
            +
                  avail_mgr = air_loop.availabilityManagers[0]
         | 
| 2134 | 
            +
                end
         | 
| 2135 | 
            +
             | 
| 2136 | 
            +
                if !avail_mgr.nil? && avail_mgr.to_AvailabilityManagerNightCycle.is_initialized
         | 
| 2137 | 
            +
                  avail_mgr = avail_mgr.to_AvailabilityManagerNightCycle.get
         | 
| 2138 | 
            +
                  avail_mgr.setCyclingRunTime(1800)
         | 
| 2123 2139 | 
             
                end
         | 
| 2124 2140 |  | 
| 2125 2141 | 
             
                # attach the VAV system to each zone
         | 
| @@ -2727,13 +2743,21 @@ class Standard | |
| 2727 2743 | 
             
                  # set air loop availability controls and night cycle manager, after oa system added
         | 
| 2728 2744 | 
             
                  air_loop.setAvailabilitySchedule(hvac_op_sch)
         | 
| 2729 2745 | 
             
                  air_loop.setNightCycleControlType('CycleOnAny')
         | 
| 2730 | 
            -
             | 
| 2731 | 
            -
                  if  | 
| 2732 | 
            -
                    avail_mgr =  | 
| 2733 | 
            -
                    if avail_mgr. | 
| 2734 | 
            -
                      avail_mgr = avail_mgr. | 
| 2735 | 
            -
             | 
| 2736 | 
            -
             | 
| 2746 | 
            +
             | 
| 2747 | 
            +
                  if model.version < OpenStudio::VersionString.new('3.5.0')
         | 
| 2748 | 
            +
                    avail_mgr = air_loop.availabilityManager
         | 
| 2749 | 
            +
                    if avail_mgr.is_initialized
         | 
| 2750 | 
            +
                      avail_mgr = avail_mgr.get
         | 
| 2751 | 
            +
                    else
         | 
| 2752 | 
            +
                      avail_mgr = nil
         | 
| 2753 | 
            +
                    end 
         | 
| 2754 | 
            +
                  else 
         | 
| 2755 | 
            +
                    avail_mgr = air_loop.availabilityManagers[0]
         | 
| 2756 | 
            +
                  end
         | 
| 2757 | 
            +
             | 
| 2758 | 
            +
                  if !avail_mgr.nil? && avail_mgr.to_AvailabilityManagerNightCycle.is_initialized
         | 
| 2759 | 
            +
                    avail_mgr = avail_mgr.to_AvailabilityManagerNightCycle.get
         | 
| 2760 | 
            +
                    avail_mgr.setCyclingRunTime(1800)
         | 
| 2737 2761 | 
             
                  end
         | 
| 2738 2762 |  | 
| 2739 2763 | 
             
                  # create a diffuser and attach the zone/diffuser pair to the air loop
         | 
| @@ -3240,7 +3264,9 @@ class Standard | |
| 3240 3264 | 
             
                  # To solve the issue, add economizer here for cold climates
         | 
| 3241 3265 | 
             
                  # select the climate zones with winter design temperature lower than -20C (for safer)
         | 
| 3242 3266 | 
             
                  cold_climates = ['ASHRAE 169-2006-6A', 'ASHRAE 169-2006-6B', 'ASHRAE 169-2006-7A',
         | 
| 3243 | 
            -
                                   'ASHRAE 169-2006-7B', 'ASHRAE 169-2006-8A', 'ASHRAE 169-2006-8B' | 
| 3267 | 
            +
                                   'ASHRAE 169-2006-7B', 'ASHRAE 169-2006-8A', 'ASHRAE 169-2006-8B',
         | 
| 3268 | 
            +
                                   'ASHRAE 169-2013-6A', 'ASHRAE 169-2013-6B', 'ASHRAE 169-2013-7A',
         | 
| 3269 | 
            +
                                   'ASHRAE 169-2013-7B', 'ASHRAE 169-2013-8A', 'ASHRAE 169-2013-8B']
         | 
| 3244 3270 | 
             
                  if cold_climates.include? climate_zone
         | 
| 3245 3271 | 
             
                    # Determine the economizer type in the prototype buildings, which depends on climate zone.
         | 
| 3246 3272 | 
             
                    economizer_type = model_economizer_type(model, climate_zone)
         | 
| @@ -5080,7 +5106,11 @@ class Standard | |
| 5080 5106 | 
             
                                                                   name: "#{air_loop.name} heating coil",
         | 
| 5081 5107 | 
             
                                                                   type: 'Residential Central Air Source HP',
         | 
| 5082 5108 | 
             
                                                                   cop: hspf_to_cop_heating_no_fan(hspf))
         | 
| 5083 | 
            -
                     | 
| 5109 | 
            +
                    if model.version < OpenStudio::VersionString.new('3.5.0')
         | 
| 5110 | 
            +
                      htg_coil.setRatedSupplyFanPowerPerVolumeFlowRate(ac_w_per_cfm / OpenStudio.convert(1.0, 'cfm', 'm^3/s').get)
         | 
| 5111 | 
            +
                    else
         | 
| 5112 | 
            +
                      htg_coil.setRatedSupplyFanPowerPerVolumeFlowRate2017(ac_w_per_cfm / OpenStudio.convert(1.0, 'cfm', 'm^3/s').get)
         | 
| 5113 | 
            +
                    end
         | 
| 5084 5114 | 
             
                    htg_coil.setMinimumOutdoorDryBulbTemperatureforCompressorOperation(OpenStudio.convert(min_hp_oat_f, 'F', 'C').get)
         | 
| 5085 5115 | 
             
                    htg_coil.setMaximumOutdoorDryBulbTemperatureforDefrostOperation(OpenStudio.convert(40.0, 'F', 'C').get)
         | 
| 5086 5116 | 
             
                    htg_coil.setCrankcaseHeaterCapacity(crank_case_heat_w)
         | 
| @@ -1895,7 +1895,11 @@ class Standard | |
| 1895 1895 | 
             
                  oa_system = air_loop_hvac.airLoopHVACOutdoorAirSystem.get
         | 
| 1896 1896 | 
             
                  controller_oa = oa_system.getControllerOutdoorAir
         | 
| 1897 1897 | 
             
                  controller_mv = controller_oa.controllerMechanicalVentilation
         | 
| 1898 | 
            -
                   | 
| 1898 | 
            +
                  if air_loop_hvac.model.version < OpenStudio::VersionString.new('3.3.0')
         | 
| 1899 | 
            +
                    controller_mv.setSystemOutdoorAirMethod('VentilationRateProcedure')
         | 
| 1900 | 
            +
                  else
         | 
| 1901 | 
            +
                    controller_mv.setSystemOutdoorAirMethod('Standard62.1VentilationRateProcedureWithLimit')
         | 
| 1902 | 
            +
                  end
         | 
| 1899 1903 | 
             
                  # Change the min flow rate in the controller outdoor air
         | 
| 1900 1904 | 
             
                  controller_oa.setMinimumOutdoorAirFlowRate(0.0)
         | 
| 1901 1905 | 
             
                else
         | 
| @@ -1924,6 +1928,16 @@ class Standard | |
| 1924 1928 | 
             
                end
         | 
| 1925 1929 | 
             
              end
         | 
| 1926 1930 |  | 
| 1931 | 
            +
              # Determine minimum ventilation efficiency for zones.
         | 
| 1932 | 
            +
              # This is used to decrease the overall system minimum OA flow rate
         | 
| 1933 | 
            +
              # such that a few zones do not drive the overall system OA flow rate too
         | 
| 1934 | 
            +
              # high.
         | 
| 1935 | 
            +
              def air_loop_hvac_minimum_zone_ventilation_efficiency(air_loop_hvac)
         | 
| 1936 | 
            +
                min_ventilation_efficiency = 0.6
         | 
| 1937 | 
            +
             | 
| 1938 | 
            +
                return min_ventilation_efficiency
         | 
| 1939 | 
            +
              end
         | 
| 1940 | 
            +
             | 
| 1927 1941 | 
             
              # Set the minimum VAV damper positions.
         | 
| 1928 1942 | 
             
              #
         | 
| 1929 1943 | 
             
              # @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
         | 
| @@ -529,7 +529,7 @@ class Standard | |
| 529 529 | 
             
              # Calculate the fenestration U-Factor base on the glass, frame,
         | 
| 530 530 | 
             
              # and divider performance and area calculated by EnergyPlus.
         | 
| 531 531 | 
             
              #
         | 
| 532 | 
            -
              # @param [OpenStudio:Model:Construction]  | 
| 532 | 
            +
              # @param [OpenStudio:Model:Construction] OpenStudio Construction object
         | 
| 533 533 | 
             
              #
         | 
| 534 534 | 
             
              # @return [Double] the U-Factor in W/m^2*K
         | 
| 535 535 | 
             
              def construction_calculated_fenestration_u_factor_w_frame(construction)
         |