urbanopt-geojson 0.2.0.pre2 → 0.3.1
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 +5 -5
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +61 -0
- data/Gemfile +0 -3
- data/Rakefile +1 -1
- data/docs/package-lock.json +15 -15
- data/docs/package.json +3 -1
- data/lib/measures/.rubocop.yml +1 -1
- data/lib/measures/urban_geometry_creation/README.md +1 -1
- data/lib/measures/urban_geometry_creation/measure.rb +4 -0
- data/lib/measures/urban_geometry_creation/measure.xml +17 -20
- data/lib/measures/urban_geometry_creation_zoning/README.md +1 -1
- data/lib/measures/urban_geometry_creation_zoning/measure.rb +6 -3
- data/lib/measures/urban_geometry_creation_zoning/measure.xml +15 -18
- data/lib/urbanopt/geojson/building.rb +22 -19
- data/lib/urbanopt/geojson/feature.rb +37 -1
- data/lib/urbanopt/geojson/geo_file.rb +39 -39
- data/lib/urbanopt/geojson/helper.rb +12 -5
- data/lib/urbanopt/geojson/mapper_classes.rb +46 -46
- data/lib/urbanopt/geojson/model.rb +2 -3
- data/lib/urbanopt/geojson/schema/building_properties.json +244 -77
- data/lib/urbanopt/geojson/schema/electrical_connector_properties.json +8 -8
- data/lib/urbanopt/geojson/schema/electrical_junction_properties.json +4 -5
- data/lib/urbanopt/geojson/schema/thermal_connector_properties.json +1 -1
- data/lib/urbanopt/geojson/schema/thermal_junction_properties.json +1 -1
- data/lib/urbanopt/geojson/update_areas.rb +1 -1
- data/lib/urbanopt/geojson/validate_geojson.rb +2 -0
- data/lib/urbanopt/geojson/version.rb +1 -1
- data/lib/urbanopt/geojson/workflows/building.osw.out +4 -4
- data/urbanopt-geojson-gem.gemspec +9 -13
- metadata +21 -41
- data/lib/change_log.rb +0 -147
- data/lib/measures/urban_geometry_creation/tests/nrel_stm_footprints.geojson +0 -3238
- data/lib/measures/urban_geometry_creation/tests/shadowed_tests.rb +0 -80
- data/lib/measures/urban_geometry_creation/tests/urban_geometry_creation_test.rb +0 -139
- data/lib/measures/urban_geometry_creation_zoning/tests/nrel_stm_footprints.geojson +0 -3238
- data/lib/measures/urban_geometry_creation_zoning/tests/urban_geometry_creation_zoning_test.rb +0 -139
| @@ -44,8 +44,11 @@ module URBANopt | |
| 44 44 | 
             
                    @feature_json = validate_feat(feature)
         | 
| 45 45 | 
             
                  end
         | 
| 46 46 |  | 
| 47 | 
            +
                  # rubocop:disable Style/MethodMissing
         | 
| 47 48 | 
             
                  def method_missing(name, *args, &blk)
         | 
| 49 | 
            +
                    # rubocop:enable Style/MethodMissing
         | 
| 48 50 | 
             
                    if @feature_json[:properties].keys.map(&:to_sym).include? name.to_sym
         | 
| 51 | 
            +
                      # rubocop:enable Style/GuardClause
         | 
| 49 52 | 
             
                      return @feature_json[:properties][name.to_sym]
         | 
| 50 53 | 
             
                    else
         | 
| 51 54 | 
             
                      super
         | 
| @@ -164,13 +167,46 @@ module URBANopt | |
| 164 167 | 
             
                    return OpenStudio::PointLatLon.new(min_lat, min_lon, 0)
         | 
| 165 168 | 
             
                  end
         | 
| 166 169 |  | 
| 170 | 
            +
                  ##
         | 
| 171 | 
            +
                  # Used to determine the centroid for the feature's coordinates.
         | 
| 172 | 
            +
                  #
         | 
| 173 | 
            +
                  # [Parameters]
         | 
| 174 | 
            +
                  # * +vertices+ - The first set polygon vertices in the array of feature coordinates.
         | 
| 175 | 
            +
                  def find_feature_center(vertices)
         | 
| 176 | 
            +
                    number_of_locations = vertices.length
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                    return vertices.first if number_of_locations == 1
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                    x = y = z = 0.0
         | 
| 181 | 
            +
                    vertices.each do |station|
         | 
| 182 | 
            +
                      latitude = station[0] * Math::PI / 180
         | 
| 183 | 
            +
                      longitude = station[1] * Math::PI / 180
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                      x += Math.cos(latitude) * Math.cos(longitude)
         | 
| 186 | 
            +
                      y += Math.cos(latitude) * Math.sin(longitude)
         | 
| 187 | 
            +
                      z += Math.sin(latitude)
         | 
| 188 | 
            +
                    end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                    x /= number_of_locations
         | 
| 191 | 
            +
                    y /= number_of_locations
         | 
| 192 | 
            +
                    z /= number_of_locations
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                    central_longitude = Math.atan2(y, x)
         | 
| 195 | 
            +
                    central_square_root = Math.sqrt(x * x + y * y)
         | 
| 196 | 
            +
                    central_latitude = Math.atan2(z, central_square_root)
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                    [central_latitude * 180 / Math::PI,
         | 
| 199 | 
            +
                     central_longitude * 180 / Math::PI]
         | 
| 200 | 
            +
                  end
         | 
| 201 | 
            +
             | 
| 167 202 | 
             
                  private
         | 
| 168 203 |  | 
| 169 204 | 
             
                  ##
         | 
| 170 205 | 
             
                  # Used to validate the feature by checking +feature_id+ , +geometry+, +properties+
         | 
| 171 206 | 
             
                  # and +geometry_type+ .
         | 
| 172 | 
            -
             | 
| 207 | 
            +
                  # rubocop:disable Style/CommentedKeyword
         | 
| 173 208 | 
             
                  def validate_feat(feature) #:doc:
         | 
| 209 | 
            +
                    # rubocop:enable Style/CommentedKeyword
         | 
| 174 210 | 
             
                    if feature.nil? || feature.empty?
         | 
| 175 211 | 
             
                      raise("Feature '#{feature_id}' could not be found")
         | 
| 176 212 | 
             
                      return false
         | 
| @@ -80,7 +80,7 @@ module URBANopt | |
| 80 80 |  | 
| 81 81 | 
             
                    # initialize @@logger
         | 
| 82 82 | 
             
                    @@logger ||= URBANopt::GeoJSON.logger
         | 
| 83 | 
            -
             | 
| 83 | 
            +
             | 
| 84 84 | 
             
                    # validate each feature against schema
         | 
| 85 85 | 
             
                    geojson_file[:features].each do |feature|
         | 
| 86 86 | 
             
                      properties = feature[:properties]
         | 
| @@ -93,16 +93,16 @@ module URBANopt | |
| 93 93 | 
             
                        # Incase detailed_model_filename present check for fewer properties
         | 
| 94 94 | 
             
                        if feature[:properties][:detailed_model_filename]
         | 
| 95 95 | 
             
                          if feature[:properties][:id].nil?
         | 
| 96 | 
            -
                            raise( | 
| 96 | 
            +
                            raise('No id found for Building Feature')
         | 
| 97 97 | 
             
                          end
         | 
| 98 98 | 
             
                          if feature[:properties][:name].nil?
         | 
| 99 | 
            -
                            raise( | 
| 99 | 
            +
                            raise('No name found for Building Feature')
         | 
| 100 100 | 
             
                          end
         | 
| 101 101 | 
             
                          if feature[:properties][:number_of_stories].nil?
         | 
| 102 102 | 
             
                            @@logger.warn("Number of stories is required to calculate shading using the UrbanGeometryCreation measure...ignoring #{feature[:properties][:id]} in shading calculations")
         | 
| 103 103 | 
             
                          end
         | 
| 104 104 | 
             
                          feature[:additionalProperties] = true
         | 
| 105 | 
            -
                        # Else validate for all required properties in the schema | 
| 105 | 
            +
                        # Else validate for all required properties in the schema
         | 
| 106 106 | 
             
                        else
         | 
| 107 107 | 
             
                          errors = validate(@@building_schema, properties)
         | 
| 108 108 | 
             
                        end
         | 
| @@ -114,16 +114,15 @@ module URBANopt | |
| 114 114 | 
             
                        errors = validate(@@electrical_junction_schema, properties)
         | 
| 115 115 | 
             
                      when 'ElectricalConnector'
         | 
| 116 116 | 
             
                        errors = validate(@@electrical_connector_schema, properties)
         | 
| 117 | 
            -
                      when ' | 
| 117 | 
            +
                      when 'ThermalJunction'
         | 
| 118 118 | 
             
                        errors = validate(@@thermal_junction_schema, properties)
         | 
| 119 119 | 
             
                      when 'ThermalConnector'
         | 
| 120 120 | 
             
                        errors = validate(@@thermal_connector_schema, properties)
         | 
| 121 121 | 
             
                      end
         | 
| 122 | 
            -
             | 
| 122 | 
            +
             | 
| 123 123 | 
             
                      unless errors.empty?
         | 
| 124 | 
            -
                        raise  | 
| 124 | 
            +
                        raise "#{type} does not adhere to schema: \n #{errors.join('\n  ')}"
         | 
| 125 125 | 
             
                      end
         | 
| 126 | 
            -
                    
         | 
| 127 126 | 
             
                    end
         | 
| 128 127 | 
             
                    return new(geojson_file, path)
         | 
| 129 128 | 
             
                  end
         | 
| @@ -163,6 +162,7 @@ module URBANopt | |
| 163 162 | 
             
                        # merge site origin properties
         | 
| 164 163 | 
             
                        f = merge_site_properties(f)
         | 
| 165 164 | 
             
                        if f[:properties][:type] == 'Building'
         | 
| 165 | 
            +
                          # rubocop:enable Style/GuardClause
         | 
| 166 166 | 
             
                          return URBANopt::GeoJSON::Building.new(f)
         | 
| 167 167 | 
             
                        elsif f[:properties] && f[:properties][:type] == 'District System'
         | 
| 168 168 | 
             
                          return URBANopt::GeoJSON::DistrictSystem.new(f)
         | 
| @@ -172,47 +172,48 @@ module URBANopt | |
| 172 172 | 
             
                    return nil
         | 
| 173 173 | 
             
                  end
         | 
| 174 174 |  | 
| 175 | 
            -
                  ## | 
| 176 | 
            -
                  # Merge Site Properties in Feature. | 
| 177 | 
            -
                  # | 
| 175 | 
            +
                  ##
         | 
| 176 | 
            +
                  # Merge Site Properties in Feature. Returns feature with site properties added to its properties section. Does not overwrite existing properties.
         | 
| 177 | 
            +
                  #
         | 
| 178 178 | 
             
                  # [Parameters]
         | 
| 179 179 | 
             
                  # +feature+ - _Type:Hash_ - feature object.
         | 
| 180 180 | 
             
                  def merge_site_properties(feature)
         | 
| 181 | 
            -
                     | 
| 182 | 
            -
                    if  | 
| 183 | 
            -
                       | 
| 184 | 
            -
             | 
| 185 | 
            -
                      # this maps site properties to building/district system properties. 
         | 
| 186 | 
            -
                      add_props = [
         | 
| 187 | 
            -
                        {site: :surface_elevation, feature: :surface_elevation}, 
         | 
| 188 | 
            -
                        {site: :timesteps_per_hour, feature: :timesteps_per_hour},
         | 
| 189 | 
            -
                        {site: :begin_date, feature: :begin_date},
         | 
| 190 | 
            -
                        {site: :end_date, feature: :end_date},
         | 
| 191 | 
            -
                        {site: :cec_climate_zone, feature: :cec_climate_zone},
         | 
| 192 | 
            -
                        {site: :climate_zone, feature: :climate_zone},
         | 
| 193 | 
            -
                        {site: :default_template, feature: :template},
         | 
| 194 | 
            -
                        {site: :weather_filename, feature: :weather_filename},
         | 
| 195 | 
            -
                        {site: :tariff_filename, feature: :tariff_filename}
         | 
| 196 | 
            -
                      ]
         | 
| 181 | 
            +
                    project = {}
         | 
| 182 | 
            +
                    if @geojson_file.key?(:project)
         | 
| 183 | 
            +
                      project = @geojson_file[:project]
         | 
| 184 | 
            +
                    end
         | 
| 197 185 |  | 
| 198 | 
            -
             | 
| 199 | 
            -
             | 
| 200 | 
            -
             | 
| 201 | 
            -
             | 
| 202 | 
            -
             | 
| 203 | 
            -
             | 
| 204 | 
            -
             | 
| 186 | 
            +
                    # this maps site properties to building/district system properties.
         | 
| 187 | 
            +
                    add_props = [
         | 
| 188 | 
            +
                      { site: :surface_elevation, feature: :surface_elevation },
         | 
| 189 | 
            +
                      { site: :timesteps_per_hour, feature: :timesteps_per_hour },
         | 
| 190 | 
            +
                      { site: :begin_date, feature: :begin_date },
         | 
| 191 | 
            +
                      { site: :end_date, feature: :end_date },
         | 
| 192 | 
            +
                      { site: :cec_climate_zone, feature: :cec_climate_zone },
         | 
| 193 | 
            +
                      { site: :climate_zone, feature: :climate_zone },
         | 
| 194 | 
            +
                      { site: :default_template, feature: :template },
         | 
| 195 | 
            +
                      { site: :weather_filename, feature: :weather_filename },
         | 
| 196 | 
            +
                      { site: :tariff_filename, feature: :tariff_filename }
         | 
| 197 | 
            +
                    ]
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                    add_props.each do |prop|
         | 
| 200 | 
            +
                      if project.key?(prop[:site]) && project[prop[:site]]
         | 
| 201 | 
            +
                        # property exists in site
         | 
| 202 | 
            +
                        if !feature[:properties].key?(prop[:feature]) || feature[:properties][prop[:feature]].nil? || feature[:properties][prop[:feature]].empty?
         | 
| 203 | 
            +
                          # property does not exist in feature or is nil: add site property (don't overwrite)
         | 
| 204 | 
            +
                          feature[:properties][prop[:feature]] = project[prop[:site]]
         | 
| 205 205 | 
             
                        end
         | 
| 206 206 | 
             
                      end
         | 
| 207 207 | 
             
                    end
         | 
| 208 | 
            +
             | 
| 208 209 | 
             
                    return feature
         | 
| 209 210 | 
             
                  end
         | 
| 210 211 |  | 
| 211 212 | 
             
                  ##
         | 
| 212 | 
            -
                  # Validate GeoJSON against schema
         | 
| 213 | 
            +
                  # Validate GeoJSON against schema.
         | 
| 213 214 | 
             
                  #
         | 
| 214 215 | 
             
                  # [Parameters]
         | 
| 215 | 
            -
                  # * +data+ - + - _Type:Hash_ - Input GeoJSON file | 
| 216 | 
            +
                  # * +data+ - + - _Type:Hash_ - Input GeoJSON file
         | 
| 216 217 | 
             
                  def self.validate(schema_json, data)
         | 
| 217 218 | 
             
                    errors = JSON::Validator.fully_validate(schema_json, data, errors_as_objects: true)
         | 
| 218 219 | 
             
                    return errors
         | 
| @@ -242,7 +243,7 @@ module URBANopt | |
| 242 243 | 
             
                    end
         | 
| 243 244 | 
             
                    return result
         | 
| 244 245 | 
             
                  end
         | 
| 245 | 
            -
             | 
| 246 | 
            +
             | 
| 246 247 | 
             
                  def self.get_district_system_schema(strict)
         | 
| 247 248 | 
             
                    result = nil
         | 
| 248 249 | 
             
                    File.open(File.dirname(__FILE__) + '/schema/district_system_properties.json') do |f|
         | 
| @@ -255,7 +256,7 @@ module URBANopt | |
| 255 256 | 
             
                    end
         | 
| 256 257 | 
             
                    return result
         | 
| 257 258 | 
             
                  end
         | 
| 258 | 
            -
             | 
| 259 | 
            +
             | 
| 259 260 | 
             
                  def self.get_region_schema(strict)
         | 
| 260 261 | 
             
                    result = nil
         | 
| 261 262 | 
             
                    File.open(File.dirname(__FILE__) + '/schema/region_properties.json') do |f|
         | 
| @@ -330,7 +331,6 @@ module URBANopt | |
| 330 331 | 
             
                  @@electrical_junction_schema = get_electrical_junction_schema(strict)
         | 
| 331 332 | 
             
                  @@thermal_connector_schema = get_thermal_connector_schema(strict)
         | 
| 332 333 | 
             
                  @@thermal_junction_schema = get_thermal_junction_schema(strict)
         | 
| 333 | 
            -
             | 
| 334 334 | 
             
                end
         | 
| 335 335 | 
             
              end
         | 
| 336 336 | 
             
            end
         | 
| @@ -154,7 +154,7 @@ module URBANopt | |
| 154 154 | 
             
                    stories.each_index do |i|
         | 
| 155 155 | 
             
                      space_type = nil
         | 
| 156 156 | 
             
                      space = stories[i].spaces.first
         | 
| 157 | 
            -
                      if space | 
| 157 | 
            +
                      if space&.spaceType&.is_initialized
         | 
| 158 158 | 
             
                        space_type = space.spaceType.get
         | 
| 159 159 | 
             
                      else
         | 
| 160 160 | 
             
                        space_type = OpenStudio::Model::SpaceType.new(model)
         | 
| @@ -216,13 +216,13 @@ module URBANopt | |
| 216 216 | 
             
                  #
         | 
| 217 217 | 
             
                  # [Parameters]
         | 
| 218 218 | 
             
                  # * +building+ - _Type:URBANopt::GeoJSON::Building_ - The core building that other buildings will be referenced.
         | 
| 219 | 
            -
                  # * +other_building_type+ - _Type:String_ - Describes the surrounding buildings. | 
| 219 | 
            +
                  # * +other_building_type+ - _Type:String_ - Describes the surrounding buildings.
         | 
| 220 220 | 
             
                  # * +other_buildings+ - _Type:URBANopt::GeoJSON::FeatureCollection_ - List of surrounding buildings to include (self will be ignored if present in list).
         | 
| 221 221 | 
             
                  # * +model+ - _Type:OpenStudio::Model::Model_ - An instance of an OpenStudio Model.
         | 
| 222 222 | 
             
                  # * +origin_lat_lon+ - _Type:Float_ - An instance of +OpenStudio::PointLatLon+ indicating the latitude and longitude of the origin.
         | 
| 223 223 | 
             
                  # * +runner+ - _Type:String_ - An instance of +Openstudio::Measure::OSRunner+ for the measure run.
         | 
| 224 224 | 
             
                  # * +zoning+ - _Type:Boolean_ - Value is +true+ if utilizing detailed zoning, else
         | 
| 225 | 
            -
                  #   +false+. Zoning is set to false by default. | 
| 225 | 
            +
                  #   +false+. Zoning is set to false by default.
         | 
| 226 226 | 
             
                  def self.process_other_buildings(building, other_building_type, other_buildings, model, origin_lat_lon, runner, zoning = false)
         | 
| 227 227 | 
             
                    # Empty array to store the new OpenStudio model spaces that need to be converted to shading objects
         | 
| 228 228 | 
             
                    feature_points = building.feature_points(origin_lat_lon, runner, zoning)
         | 
| @@ -243,6 +243,7 @@ module URBANopt | |
| 243 243 | 
             
                        if number_of_stories_above_ground.nil?
         | 
| 244 244 | 
             
                          number_of_stories_above_ground = number_of_stories
         | 
| 245 245 | 
             
                          number_of_stories_below_ground = 0
         | 
| 246 | 
            +
             | 
| 246 247 | 
             
                        else
         | 
| 247 248 | 
             
                          number_of_stories_below_ground = number_of_stories - number_of_stories_above_ground
         | 
| 248 249 | 
             
                        end
         | 
| @@ -251,11 +252,18 @@ module URBANopt | |
| 251 252 | 
             
                        if number_of_stories_above_ground && number_of_stories_above_ground > 0 && maximum_roof_height
         | 
| 252 253 | 
             
                          floor_to_floor_height = maximum_roof_height / number_of_stories_above_ground
         | 
| 253 254 | 
             
                        end
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                        # check that feature has a # stories
         | 
| 257 | 
            +
                        if number_of_stories_above_ground.nil?
         | 
| 258 | 
            +
                          runner.registerWarning("[geojson process_other_buildings] Unable to include feature #{other_building[:properties][:id]} in shading calculations: no 'number of stories' data")
         | 
| 259 | 
            +
                        end
         | 
| 260 | 
            +
                        next if number_of_stories_above_ground.nil?
         | 
| 261 | 
            +
             | 
| 254 262 | 
             
                        other_height = number_of_stories_above_ground * floor_to_floor_height
         | 
| 255 263 | 
             
                        # find the polygon of the other_building by passing it to the get_multi_polygons method
         | 
| 256 264 | 
             
                        other_building_points = building.other_points(other_building, other_height, origin_lat_lon, runner, zoning)
         | 
| 257 265 | 
             
                        shadowed = URBANopt::GeoJSON::Helper.is_shadowed(feature_points, other_building_points, origin_lat_lon)
         | 
| 258 | 
            -
                        next unless shadowed | 
| 266 | 
            +
                        next unless shadowed
         | 
| 259 267 | 
             
                        new_building = building.create_other_building(:space_per_building, model, origin_lat_lon, runner, zoning, other_building)
         | 
| 260 268 | 
             
                        if new_building.nil? || new_building.empty?
         | 
| 261 269 | 
             
                          runner.registerWarning("Failed to create spaces for other building '#{name}'")
         | 
| @@ -264,7 +272,6 @@ module URBANopt | |
| 264 272 |  | 
| 265 273 | 
             
                      elsif other_building_type == 'None'
         | 
| 266 274 | 
             
                      end
         | 
| 267 | 
            -
             | 
| 268 275 | 
             
                    end
         | 
| 269 276 | 
             
                    return other_spaces
         | 
| 270 277 | 
             
                  end
         | 
| @@ -32,54 +32,54 @@ require 'urbanopt/scenario' | |
| 32 32 | 
             
            require 'json'
         | 
| 33 33 |  | 
| 34 34 | 
             
            module URBANopt
         | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 35 | 
            +
              module GeoJSON
         | 
| 36 | 
            +
                class Mapper < MapperBase
         | 
| 37 | 
            +
                  @@instance_lock = Mutex.new
         | 
| 38 | 
            +
                  @@osw = nil
         | 
| 39 39 |  | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 40 | 
            +
                  ##
         | 
| 41 | 
            +
                  # This class inherits from the +MapperBase+ .
         | 
| 42 | 
            +
                  # Used to perform initializing functions, used to define the osw_path for
         | 
| 43 | 
            +
                  # baseline.osw for the URBANopt GeoJSON example project and the weather file.
         | 
| 44 44 |  | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
                                end
         | 
| 52 | 
            -
                                @@osw[:file_paths] << File.join(File.dirname(__FILE__), '../weather/')
         | 
| 53 | 
            -
                                @@osw = OpenStudio::Extension.configure_osw(@@osw)
         | 
| 54 | 
            -
                            end
         | 
| 55 | 
            -
                        end
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                        ##
         | 
| 58 | 
            -
                        # Creates an OpenStudio Workflow file for a given ScenarioBase object,
         | 
| 59 | 
            -
                        # feature id and feature name.
         | 
| 60 | 
            -
                        #
         | 
| 61 | 
            -
                        # [Parameters]
         | 
| 62 | 
            -
                        # * +scenario+ - _Type:String_ - Used to define the Scenario for the osw. 
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                        # * +feature_id+ - _Type:String/Number_ - Used to define the feature_id for
         | 
| 65 | 
            -
                        #   which the osw is implemented.
         | 
| 66 | 
            -
                        # 
         | 
| 67 | 
            -
                        # * +feature_name+ - _Type:String_ - The name of the feature. 
         | 
| 68 | 
            -
                        def create_osw(scenario, feature_id, feature_name)
         | 
| 69 | 
            -
                            # get the feature from the scenario's feature_file #:nodoc:
         | 
| 70 | 
            -
                            feature_file = scenario.feature_file
         | 
| 71 | 
            -
                            feature = feature_file.get_feature_by_id(feature_id)
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                            raise "Cannot find feature '#{feature_id}' in '#{scenario.geometry_file}'" if feature.nil?
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                            # deep clone of @@osw before we configure it #:nodoc:
         | 
| 76 | 
            -
                            osw = Marshal.load(Marshal.dump(@@osw))
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                            osw[:name] = feature_name
         | 
| 79 | 
            -
                            osw[:description] = feature_name
         | 
| 80 | 
            -
             | 
| 81 | 
            -
                            return osw
         | 
| 45 | 
            +
                  def initialize
         | 
| 46 | 
            +
                    @@instance_lock.synchronize do
         | 
| 47 | 
            +
                      if @@osw.nil?
         | 
| 48 | 
            +
                        osw_path = File.join(File.dirname(__FILE__), 'baseline.osw')
         | 
| 49 | 
            +
                        File.open(osw_path, 'r') do |file|
         | 
| 50 | 
            +
                          @@osw = JSON.parse(file.read, symbolize_names: true)
         | 
| 82 51 | 
             
                        end
         | 
| 52 | 
            +
                        @@osw[:file_paths] << File.join(File.dirname(__FILE__), '../weather/')
         | 
| 53 | 
            +
                        @@osw = OpenStudio::Extension.configure_osw(@@osw)
         | 
| 54 | 
            +
                      end
         | 
| 83 55 | 
             
                    end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    ##
         | 
| 58 | 
            +
                    # Creates an OpenStudio Workflow file for a given ScenarioBase object,
         | 
| 59 | 
            +
                    # feature id and feature name.
         | 
| 60 | 
            +
                    #
         | 
| 61 | 
            +
                    # [Parameters]
         | 
| 62 | 
            +
                    # * +scenario+ - _Type:String_ - Used to define the Scenario for the osw.
         | 
| 63 | 
            +
                    # * +feature_id+ - _Type:String/Number_ - Used to define the feature_id for
         | 
| 64 | 
            +
                    #   which the osw is implemented.
         | 
| 65 | 
            +
                    #
         | 
| 66 | 
            +
                    # * +feature_name+ - _Type:String_ - The name of the feature.
         | 
| 67 | 
            +
                    # rubocop:disable Lint/NestedMethodDefinition
         | 
| 68 | 
            +
                    def create_osw(scenario, feature_id, feature_name)
         | 
| 69 | 
            +
                      # rubocop:enable Lint/NestedMethodDefinition
         | 
| 70 | 
            +
                      # get the feature from the scenario's feature_file #:nodoc:
         | 
| 71 | 
            +
                      feature_file = scenario.feature_file
         | 
| 72 | 
            +
                      feature = feature_file.get_feature_by_id(feature_id)
         | 
| 73 | 
            +
                      raise "Cannot find feature '#{feature_id}' in '#{scenario.geometry_file}'" if feature.nil?
         | 
| 74 | 
            +
                      # deep clone of @@osw before we configure it #:nodoc:
         | 
| 75 | 
            +
                      osw = Marshal.load(Marshal.dump(@@osw))
         | 
| 76 | 
            +
                      osw[:name] = feature_name
         | 
| 77 | 
            +
                      osw[:description] = feature_name
         | 
| 78 | 
            +
                      end
         | 
| 79 | 
            +
                    # rubocop:disable Lint/ReturnInVoidContext
         | 
| 80 | 
            +
                    return osw
         | 
| 81 | 
            +
                   # rubocop:enable Lint/ReturnInVoidContext
         | 
| 82 | 
            +
                 end
         | 
| 84 83 | 
             
                end
         | 
| 85 | 
            -
            end
         | 
| 84 | 
            +
              end
         | 
| 85 | 
            +
            end
         | 
| @@ -65,17 +65,16 @@ module URBANopt | |
| 65 65 | 
             
                  # * +runner+ - _Type:String_ - Measure run's instance of +OpenStudio::Measure::OSRunner+ .
         | 
| 66 66 | 
             
                  def self.change_adjacent_surfaces_to_adiabatic(model, runner)
         | 
| 67 67 | 
             
                    runner.registerInfo('Changing adjacent surfaces to adiabatic')
         | 
| 68 | 
            -
                    model.getSurfaces.each do |surface|
         | 
| 68 | 
            +
                    model.getSurfaces.sort.each do |surface|
         | 
| 69 69 | 
             
                      adjacent_surface = surface.adjacentSurface
         | 
| 70 70 | 
             
                      if !adjacent_surface.empty?
         | 
| 71 71 | 
             
                        surface_construction = surface.construction
         | 
| 72 72 | 
             
                        if !surface_construction.empty?
         | 
| 73 73 | 
             
                          surface.setConstruction(surface_construction.get)
         | 
| 74 74 | 
             
                        end
         | 
| 75 | 
            -
                        surface.setOutsideBoundaryCondition('Adiabatic')
         | 
| 76 | 
            -
             | 
| 77 75 | 
             
                        adjacent_surface_construction = adjacent_surface.get.construction
         | 
| 78 76 | 
             
                        if !adjacent_surface_construction.empty?
         | 
| 77 | 
            +
                          surface.setOutsideBoundaryCondition('Adiabatic')
         | 
| 79 78 | 
             
                          adjacent_surface.get.setConstruction(adjacent_surface_construction.get)
         | 
| 80 79 | 
             
                        end
         | 
| 81 80 | 
             
                        adjacent_surface.get.setOutsideBoundaryCondition('Adiabatic')
         | 
| @@ -111,6 +111,12 @@ | |
| 111 111 | 
             
                    "Hip"
         | 
| 112 112 | 
             
                  ]
         | 
| 113 113 | 
             
                },
         | 
| 114 | 
            +
                "foundation_type": {
         | 
| 115 | 
            +
                  "$ref": "#/definitions/foundationType"
         | 
| 116 | 
            +
                },
         | 
| 117 | 
            +
                "attic_type": {
         | 
| 118 | 
            +
                  "$ref": "#/definitions/atticType"
         | 
| 119 | 
            +
                },
         | 
| 114 120 | 
             
                "footprint_area": {
         | 
| 115 121 | 
             
                  "description": "Area of the footprint (ft^2).  Calculated on export.",
         | 
| 116 122 | 
             
                  "type": "number"
         | 
| @@ -132,6 +138,9 @@ | |
| 132 138 | 
             
                "system_type": {
         | 
| 133 139 | 
             
                  "$ref": "#/definitions/systemType"
         | 
| 134 140 | 
             
                },
         | 
| 141 | 
            +
                "heating_system_fuel_type": {
         | 
| 142 | 
            +
                  "$ref": "#/definitions/heatingSystemFuelType"
         | 
| 143 | 
            +
                },
         | 
| 135 144 | 
             
                "weekday_start_time": {
         | 
| 136 145 | 
             
                  "description": "Weekday operating hours start time in 08:30 format, using 24-hr clock. Leave blank to use default. Should this be part of a mixed type struct?",
         | 
| 137 146 | 
             
                  "type": "string"
         | 
| @@ -185,7 +194,11 @@ | |
| 185 194 | 
             
                  "maximum": 100
         | 
| 186 195 | 
             
                },
         | 
| 187 196 | 
             
                "number_of_residential_units": {
         | 
| 188 | 
            -
                  "description": "Total number of residential units in the building. Required for  | 
| 197 | 
            +
                  "description": "Total number of residential units in the building. Required for single-family attached or multifamily residential buildings.",
         | 
| 198 | 
            +
                  "type": "integer"
         | 
| 199 | 
            +
                },
         | 
| 200 | 
            +
                "number_of_bedrooms": {
         | 
| 201 | 
            +
                  "description": "Total number of bedrooms in the building. Required for residential buildings. Must be divisible by the number of residential units.",
         | 
| 189 202 | 
             
                  "type": "integer"
         | 
| 190 203 | 
             
                },
         | 
| 191 204 | 
             
                "exterior_lighting_zone": {
         | 
| @@ -214,14 +227,113 @@ | |
| 214 227 | 
             
                  "description": "Arbitrary user data"
         | 
| 215 228 | 
             
                }
         | 
| 216 229 | 
             
              },
         | 
| 217 | 
            -
              " | 
| 218 | 
            -
                 | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 221 | 
            -
             | 
| 222 | 
            -
             | 
| 223 | 
            -
             | 
| 224 | 
            -
             | 
| 230 | 
            +
              "oneOf": [
         | 
| 231 | 
            +
                {
         | 
| 232 | 
            +
                  "properties": {
         | 
| 233 | 
            +
                    "building_type": {
         | 
| 234 | 
            +
                      "enum": [
         | 
| 235 | 
            +
                        "Single-Family Detached"
         | 
| 236 | 
            +
                      ]
         | 
| 237 | 
            +
                    }
         | 
| 238 | 
            +
                  },
         | 
| 239 | 
            +
                  "required": [
         | 
| 240 | 
            +
                    "id",
         | 
| 241 | 
            +
                    "type",
         | 
| 242 | 
            +
                    "name",
         | 
| 243 | 
            +
                    "floor_area",
         | 
| 244 | 
            +
                    "number_of_stories",
         | 
| 245 | 
            +
                    "footprint_area",
         | 
| 246 | 
            +
                    "building_type",
         | 
| 247 | 
            +
                    "number_of_bedrooms",
         | 
| 248 | 
            +
                    "foundation_type",
         | 
| 249 | 
            +
                    "attic_type"
         | 
| 250 | 
            +
                  ]
         | 
| 251 | 
            +
                },
         | 
| 252 | 
            +
                {
         | 
| 253 | 
            +
                  "properties": {
         | 
| 254 | 
            +
                    "building_type": {
         | 
| 255 | 
            +
                      "enum": [
         | 
| 256 | 
            +
                        "Single-Family Attached"
         | 
| 257 | 
            +
                       ]
         | 
| 258 | 
            +
                    }
         | 
| 259 | 
            +
                  },
         | 
| 260 | 
            +
                  "required": [
         | 
| 261 | 
            +
                    "id",
         | 
| 262 | 
            +
                    "type",
         | 
| 263 | 
            +
                    "name",
         | 
| 264 | 
            +
                    "floor_area",
         | 
| 265 | 
            +
                    "number_of_stories",
         | 
| 266 | 
            +
                    "footprint_area",
         | 
| 267 | 
            +
                    "building_type",
         | 
| 268 | 
            +
                    "number_of_residential_units",
         | 
| 269 | 
            +
                    "number_of_bedrooms",
         | 
| 270 | 
            +
                    "foundation_type",
         | 
| 271 | 
            +
                    "attic_type"
         | 
| 272 | 
            +
                  ]
         | 
| 273 | 
            +
                },
         | 
| 274 | 
            +
                {
         | 
| 275 | 
            +
                  "properties": {
         | 
| 276 | 
            +
                    "building_type": {
         | 
| 277 | 
            +
                      "enum": [
         | 
| 278 | 
            +
                        "Multifamily"
         | 
| 279 | 
            +
                       ]
         | 
| 280 | 
            +
                    }
         | 
| 281 | 
            +
                  },
         | 
| 282 | 
            +
                  "required": [
         | 
| 283 | 
            +
                    "id",
         | 
| 284 | 
            +
                    "type",
         | 
| 285 | 
            +
                    "name",
         | 
| 286 | 
            +
                    "floor_area",
         | 
| 287 | 
            +
                    "number_of_stories",
         | 
| 288 | 
            +
                    "footprint_area",
         | 
| 289 | 
            +
                    "building_type",
         | 
| 290 | 
            +
                    "number_of_residential_units",
         | 
| 291 | 
            +
                    "number_of_bedrooms",
         | 
| 292 | 
            +
                    "foundation_type"
         | 
| 293 | 
            +
                  ]
         | 
| 294 | 
            +
                },
         | 
| 295 | 
            +
                {
         | 
| 296 | 
            +
                  "properties": {
         | 
| 297 | 
            +
                    "building_type": {
         | 
| 298 | 
            +
                      "enum": [
         | 
| 299 | 
            +
                        "Single-Family",
         | 
| 300 | 
            +
                        "Multifamily (2 to 4 units)",
         | 
| 301 | 
            +
                        "Multifamily (5 or more units)",
         | 
| 302 | 
            +
                        "Vacant",
         | 
| 303 | 
            +
                        "Office",
         | 
| 304 | 
            +
                        "Laboratory",
         | 
| 305 | 
            +
                        "Nonrefrigerated warehouse",
         | 
| 306 | 
            +
                        "Food sales",
         | 
| 307 | 
            +
                        "Public order and safety",
         | 
| 308 | 
            +
                        "Outpatient health care",
         | 
| 309 | 
            +
                        "Refrigerated warehouse",
         | 
| 310 | 
            +
                        "Religious worship",
         | 
| 311 | 
            +
                        "Public assembly",
         | 
| 312 | 
            +
                        "Education",
         | 
| 313 | 
            +
                        "Food service",
         | 
| 314 | 
            +
                        "Inpatient health care",
         | 
| 315 | 
            +
                        "Nursing",
         | 
| 316 | 
            +
                        "Lodging",
         | 
| 317 | 
            +
                        "Strip shopping mall",
         | 
| 318 | 
            +
                        "Enclosed mall",
         | 
| 319 | 
            +
                        "Retail other than mall",
         | 
| 320 | 
            +
                        "Service",
         | 
| 321 | 
            +
                        "Mixed use",
         | 
| 322 | 
            +
                        "Uncovered Parking",
         | 
| 323 | 
            +
                        "Covered Parking"
         | 
| 324 | 
            +
                      ]
         | 
| 325 | 
            +
                    }
         | 
| 326 | 
            +
                  },
         | 
| 327 | 
            +
                  "required": [
         | 
| 328 | 
            +
                    "id",
         | 
| 329 | 
            +
                    "type",
         | 
| 330 | 
            +
                    "name",
         | 
| 331 | 
            +
                    "floor_area",
         | 
| 332 | 
            +
                    "number_of_stories",
         | 
| 333 | 
            +
                    "footprint_area",
         | 
| 334 | 
            +
                    "building_type"
         | 
| 335 | 
            +
                  ]
         | 
| 336 | 
            +
                }
         | 
| 225 337 | 
             
              ],
         | 
| 226 338 | 
             
              "additionalProperties": true,
         | 
| 227 339 | 
             
              "definitions": {
         | 
| @@ -229,10 +341,12 @@ | |
| 229 341 | 
             
                  "description": "Primary building space type.",
         | 
| 230 342 | 
             
                  "type": "string",
         | 
| 231 343 | 
             
                  "enum": [
         | 
| 344 | 
            +
                    "Single-Family Detached",
         | 
| 345 | 
            +
                    "Single-Family Attached",
         | 
| 346 | 
            +
                    "Multifamily",
         | 
| 232 347 | 
             
                    "Single-Family",
         | 
| 233 348 | 
             
                    "Multifamily (2 to 4 units)",
         | 
| 234 349 | 
             
                    "Multifamily (5 or more units)",
         | 
| 235 | 
            -
                    "Mobile Home",
         | 
| 236 350 | 
             
                    "Vacant",
         | 
| 237 351 | 
             
                    "Office",
         | 
| 238 352 | 
             
                    "Laboratory",
         | 
| @@ -262,85 +376,116 @@ | |
| 262 376 | 
             
                  "description": "Building HVAC system type. Should this be part of a mixed type struct?",
         | 
| 263 377 | 
             
                  "type": "string",
         | 
| 264 378 | 
             
                  "enum": [
         | 
| 265 | 
            -
                    " | 
| 266 | 
            -
                    "PTAC with  | 
| 267 | 
            -
                    "PTAC with hot water | 
| 268 | 
            -
                    "PTAC with gas  | 
| 269 | 
            -
                    "PTAC with electric  | 
| 379 | 
            +
                    "PTAC with baseboard electric",
         | 
| 380 | 
            +
                    "PTAC with baseboard gas boiler",
         | 
| 381 | 
            +
                    "PTAC with baseboard district hot water",
         | 
| 382 | 
            +
                    "PTAC with gas unit heaters",
         | 
| 383 | 
            +
                    "PTAC with electric coil",
         | 
| 384 | 
            +
                    "PTAC with gas coil",
         | 
| 385 | 
            +
                    "PTAC with gas boiler",
         | 
| 270 386 | 
             
                    "PTAC with no heat",
         | 
| 271 | 
            -
                    "PTAC with district hot water | 
| 272 | 
            -
                    "PTAC with central air source heat pump | 
| 387 | 
            +
                    "PTAC with district hot water",
         | 
| 388 | 
            +
                    "PTAC with central air source heat pump",
         | 
| 273 389 | 
             
                    "PTHP",
         | 
| 274 | 
            -
                    "PSZ-AC with gas coil | 
| 275 | 
            -
                    "PSZ-AC with  | 
| 390 | 
            +
                    "PSZ-AC with gas coil",
         | 
| 391 | 
            +
                    "PSZ-AC with baseboard electric",
         | 
| 276 392 | 
             
                    "PSZ-AC with no heat",
         | 
| 277 | 
            -
                    "PSZ-AC with district hot water | 
| 278 | 
            -
                    "PSZ-AC with central air source heat pump | 
| 393 | 
            +
                    "PSZ-AC with district hot water",
         | 
| 394 | 
            +
                    "PSZ-AC with central air source heat pump",
         | 
| 279 395 | 
             
                    "PSZ-HP",
         | 
| 280 396 | 
             
                    "Fan coil district chilled water with no heat",
         | 
| 281 | 
            -
                    "Fan coil district chilled water  | 
| 282 | 
            -
                    "Fan coil district chilled water  | 
| 283 | 
            -
                    "Fan coil district chilled water unit heaters",
         | 
| 284 | 
            -
                    "Fan coil district chilled water  | 
| 285 | 
            -
                    "Fan coil district  | 
| 286 | 
            -
                    "Fan coil district hot water | 
| 287 | 
            -
                    "Fan coil district hot water | 
| 288 | 
            -
                    "Fan coil chiller  | 
| 289 | 
            -
                    "Fan coil air-cooled chiller  | 
| 290 | 
            -
                    "Fan coil chiller  | 
| 291 | 
            -
                    "Fan coil air-cooled chiller  | 
| 397 | 
            +
                    "Fan coil district chilled water with boiler",
         | 
| 398 | 
            +
                    "Fan coil district chilled water with central air source heat pump",
         | 
| 399 | 
            +
                    "Fan coil district chilled water with gas unit heaters",
         | 
| 400 | 
            +
                    "Fan coil district chilled water with baseboard electric",
         | 
| 401 | 
            +
                    "Fan coil district chilled water with district hot water",
         | 
| 402 | 
            +
                    "Fan coil chiller with district hot water",
         | 
| 403 | 
            +
                    "Fan coil air-cooled chiller with district hot water",
         | 
| 404 | 
            +
                    "Fan coil chiller with boiler",
         | 
| 405 | 
            +
                    "Fan coil air-cooled chiller with boiler",
         | 
| 406 | 
            +
                    "Fan coil chiller with central air source heat pump",
         | 
| 407 | 
            +
                    "Fan coil air-cooled chiller with central air source heat pump",
         | 
| 292 408 | 
             
                    "Fan coil chiller with no heat",
         | 
| 293 409 | 
             
                    "DOAS with fan coil district chilled water with no heat",
         | 
| 294 410 | 
             
                    "DOAS with fan coil district chilled water and boiler",
         | 
| 295 | 
            -
                    "DOAS with fan coil district chilled water  | 
| 296 | 
            -
                    "DOAS with fan coil district chilled water unit heaters",
         | 
| 297 | 
            -
                    "DOAS with fan coil district chilled water  | 
| 298 | 
            -
                    "DOAS with fan coil district  | 
| 299 | 
            -
                    "DOAS with fan coil district hot water | 
| 300 | 
            -
                    "DOAS with fan coil district hot water | 
| 301 | 
            -
                    "DOAS with fan coil chiller  | 
| 302 | 
            -
                    "DOAS with fan coil air | 
| 303 | 
            -
                    "DOAS with fan coil chiller  | 
| 304 | 
            -
                    "DOAS with fan coil air-cooled chiller and central air source heat pump",
         | 
| 411 | 
            +
                    "DOAS with fan coil district chilled water with central air source heat pump",
         | 
| 412 | 
            +
                    "DOAS with fan coil district chilled water with gas unit heaters",
         | 
| 413 | 
            +
                    "DOAS with fan coil district chilled water with baseboard electric",
         | 
| 414 | 
            +
                    "DOAS with fan coil district chilled water with district hot water",
         | 
| 415 | 
            +
                    "DOAS with fan coil chiller with district hot water",
         | 
| 416 | 
            +
                    "DOAS with fan coil air-cooled chiller with district hot water",
         | 
| 417 | 
            +
                    "DOAS with fan coil air-cooled chiller with boiler",
         | 
| 418 | 
            +
                    "DOAS with fan coil chiller with central air source heat pump",
         | 
| 419 | 
            +
                    "DOAS with fan coil air-cooled chiller with central air source heat pump",
         | 
| 305 420 | 
             
                    "DOAS with fan coil chiller with no heat",
         | 
| 306 | 
            -
                    " | 
| 307 | 
            -
                    " | 
| 308 | 
            -
                    " | 
| 309 | 
            -
                    " | 
| 310 | 
            -
                    "Baseboard  | 
| 311 | 
            -
                    "Baseboard electric | 
| 312 | 
            -
                    "Baseboard  | 
| 313 | 
            -
                    "Baseboard  | 
| 421 | 
            +
                    "DOAS with VRF",
         | 
| 422 | 
            +
                    "VRF",
         | 
| 423 | 
            +
                    "DOAS with water source heat pumps with ground source heat pump",
         | 
| 424 | 
            +
                    "Forced air furnace",
         | 
| 425 | 
            +
                    "Baseboard district hot water",
         | 
| 426 | 
            +
                    "Baseboard electric",
         | 
| 427 | 
            +
                    "Baseboard gas boiler",
         | 
| 428 | 
            +
                    "Baseboard central air source heat pump",
         | 
| 314 429 | 
             
                    "Window AC with no heat",
         | 
| 315 430 | 
             
                    "Window AC with forced air furnace",
         | 
| 316 | 
            -
                    "Window AC with district hot water | 
| 317 | 
            -
                    "Window AC with  | 
| 318 | 
            -
                    "Window AC with electric baseboard heat",
         | 
| 431 | 
            +
                    "Window AC with baseboard district hot water",
         | 
| 432 | 
            +
                    "Window AC with baseboard electric",
         | 
| 319 433 | 
             
                    "Window AC with unit heaters",
         | 
| 320 | 
            -
                    " | 
| 321 | 
            -
                    " | 
| 322 | 
            -
                    " | 
| 323 | 
            -
                    " | 
| 324 | 
            -
                    " | 
| 325 | 
            -
                    " | 
| 326 | 
            -
                    " | 
| 327 | 
            -
                    " | 
| 328 | 
            -
                    " | 
| 329 | 
            -
                    " | 
| 330 | 
            -
                    "VAV with  | 
| 331 | 
            -
                    "VAV  | 
| 332 | 
            -
                    " | 
| 333 | 
            -
                    " | 
| 434 | 
            +
                    "Window AC with baseboard gas boiler",
         | 
| 435 | 
            +
                    "Window AC with baseboard central air source heat pump",
         | 
| 436 | 
            +
                    "Direct evap coolers with baseboard district hot water",
         | 
| 437 | 
            +
                    "Direct evap coolers with baseboard electric",
         | 
| 438 | 
            +
                    "Direct evap coolers with baseboard gas boiler",
         | 
| 439 | 
            +
                    "Direct evap coolers with baseboard central air source heat pump",
         | 
| 440 | 
            +
                    "Direct evap coolers with no heat",  
         | 
| 441 | 
            +
                    "Direct evap coolers with gas unit heaters",
         | 
| 442 | 
            +
                    "Direct evap coolers with forced air furnace",
         | 
| 443 | 
            +
                    "Gas unit heaters",
         | 
| 444 | 
            +
                    "VAV chiller with gas boiler reheat",
         | 
| 445 | 
            +
                    "VAV chiller with gas coil reheat",
         | 
| 446 | 
            +
                    "VAV chiller with central air source heat pump reheat",
         | 
| 447 | 
            +
                    "VAV chiller with PFP boxes",
         | 
| 448 | 
            +
                    "VAV air-cooled chiller with gas boiler reheat",
         | 
| 449 | 
            +
                    "VAV air-cooled chiller with central air source heat pump reheat",
         | 
| 450 | 
            +
                    "VAV air-cooled chiller with district hot water reheat",
         | 
| 451 | 
            +
                    "VAV air-cooled chiller with gas coil reheat",
         | 
| 452 | 
            +
                    "VAV air-cooled chiller with no reheat with gas unit heaters",
         | 
| 453 | 
            +
                    "VAV district chilled water with gas boiler reheat",
         | 
| 454 | 
            +
                    "VAV district chilled water with central air source heat pump reheat",
         | 
| 455 | 
            +
                    "VAV district chilled water with no reheat with zone heat pump",
         | 
| 456 | 
            +
                    "VAV chiller with no reheat with baseboard electric",
         | 
| 457 | 
            +
                    "VAV air-cooled chiller with no reheat with zone heat pump",
         | 
| 458 | 
            +
                    "VAV district chilled water with district hot water reheat",
         | 
| 459 | 
            +
                    "VAV district chilled water with gas coil reheat",
         | 
| 460 | 
            +
                    "PVAV with gas heat with electric reheat",
         | 
| 461 | 
            +
                    "PVAV with central air source heat pump reheat",
         | 
| 334 462 | 
             
                    "PVAV with PFP boxes",
         | 
| 335 | 
            -
                    "Residential  | 
| 336 | 
            -
                    "Residential  | 
| 337 | 
            -
                    "Residential  | 
| 338 | 
            -
                    "Residential  | 
| 339 | 
            -
                    " | 
| 340 | 
            -
                    " | 
| 341 | 
            -
                    " | 
| 342 | 
            -
                    "Residential  | 
| 343 | 
            -
                    "Residential  | 
| 463 | 
            +
                    "Residential - electric resistance and no cooling",
         | 
| 464 | 
            +
                    "Residential - electric resistance and central air conditioner",
         | 
| 465 | 
            +
                    "Residential - electric resistance and room air conditioner",
         | 
| 466 | 
            +
                    "Residential - electric resistance and evaporative cooler",
         | 
| 467 | 
            +
                    "Residential - furnace and no cooling",
         | 
| 468 | 
            +
                    "Residential - furnace and central air conditioner",
         | 
| 469 | 
            +
                    "Residential - furnace and room air conditioner",
         | 
| 470 | 
            +
                    "Residential - furnace and evaporative cooler",
         | 
| 471 | 
            +
                    "Residential - boiler and no cooling",
         | 
| 472 | 
            +
                    "Residential - boiler and central air conditioner",
         | 
| 473 | 
            +
                    "Residential - boiler and room air conditioner",
         | 
| 474 | 
            +
                    "Residential - boiler and evaporative cooler",
         | 
| 475 | 
            +
                    "Residential - air-to-air heat pump",
         | 
| 476 | 
            +
                    "Residential - mini-split heat pump",
         | 
| 477 | 
            +
                    "Residential - ground-to-air heat pump"
         | 
| 478 | 
            +
                  ]
         | 
| 479 | 
            +
                },
         | 
| 480 | 
            +
                "heatingSystemFuelType": {
         | 
| 481 | 
            +
                  "description": "The fuel type of the heating system. This does not apply for certain system types (e.g., electric resistance or heat pumps).",
         | 
| 482 | 
            +
                  "type": "string",
         | 
| 483 | 
            +
                  "enum": [
         | 
| 484 | 
            +
                    "electricity",
         | 
| 485 | 
            +
                    "natural gas",
         | 
| 486 | 
            +
                    "fuel oil",
         | 
| 487 | 
            +
                    "propane",
         | 
| 488 | 
            +
                    "wood"
         | 
| 344 489 | 
             
                  ]
         | 
| 345 490 | 
             
                },
         | 
| 346 491 | 
             
                "templateType": {
         | 
| @@ -376,6 +521,28 @@ | |
| 376 521 | 
             
                    "DEER 2070",
         | 
| 377 522 | 
             
                    "DEER 2075"
         | 
| 378 523 | 
             
                  ]
         | 
| 524 | 
            +
                },
         | 
| 525 | 
            +
                "foundationType": {
         | 
| 526 | 
            +
                  "description": "The foundation type of the building. Required for residential buildings.",
         | 
| 527 | 
            +
                  "type": "string",
         | 
| 528 | 
            +
                  "enum": [
         | 
| 529 | 
            +
                    "slab",
         | 
| 530 | 
            +
                    "crawlspace - vented",
         | 
| 531 | 
            +
                    "crawlspace - unvented",
         | 
| 532 | 
            +
                    "basement - unconditioned",
         | 
| 533 | 
            +
                    "basement - conditioned",
         | 
| 534 | 
            +
                    "ambient"
         | 
| 535 | 
            +
                  ]
         | 
| 536 | 
            +
                },
         | 
| 537 | 
            +
                "atticType": {
         | 
| 538 | 
            +
                  "description": "The attic type of the building. Required for single-family residential buildings.",
         | 
| 539 | 
            +
                  "type": "string",
         | 
| 540 | 
            +
                  "enum": [
         | 
| 541 | 
            +
                    "attic - vented",
         | 
| 542 | 
            +
                    "attic - unvented",
         | 
| 543 | 
            +
                    "attic - conditioned",
         | 
| 544 | 
            +
                    "flat roof"
         | 
| 545 | 
            +
                  ]
         | 
| 379 546 | 
             
                }
         | 
| 380 547 | 
             
              }
         | 
| 381 | 
            -
            }
         | 
| 548 | 
            +
            }
         |