I will attempt an answer just in case helps someone else.
I spent a bit of time studying the openstudio-extension-gem
that has various modules and methods to create models, assign constructions, spaces, etc., and the openstudio-standards
that has all the data for every standard. This is an example code that adds a whole building space type at building level with some additional comments from me.
# OpenStudio
require "/Applications/OpenStudio-3.4.0/Ruby/openstudio.rb"
require "openstudio/extension/core/os_lib_model_generation"
require "openstudio/extension/core/os_lib_helper_methods"
require "openstudio-standards"
include OsLib_ModelGeneration
# include OsLib_HelperMethods
model_name = "testOSM"
model = OpenStudio::Model::Model.new
# pp get_building_types.to_a
building_type = "MediumOffice"
# pp get_templates.to_a
template = "90.1-2019"
# true creates a whole building profile
space_type_hash = get_space_types_from_building_type(building_type, template, true)
puts space_type_hash
# pp get_climate_zones.to_a
climate_zone = "ASHRAE 169-2013-1A"
# reporting initial condition of model
starting_spaceTypes = model.getSpaceTypes.sort
puts starting_spaceTypes.size
# create space_type_map from array
space_type_map = {}
default_space_type_name = nil
space_type_hash.each do |space_type_name, hash|
next if hash[:space_type_gen] == false # space types like undeveloped and basement are skipped.
space_type_map[space_type_name] = [] # no spaces to pass in
if hash[:default]
default_space_type_name = space_type_name
end
end
puts space_type_map
# Make the standard applier
standard = Standard.build(template)
# mapping building_type name is needed for a few methods
lookup_building_type = standard.model_get_lookup_name(building_type)
puts lookup_building_type
# I think this is needed because the standards template only has office type
# remap small medium and large office to office
if building_type.include?("Office") then building_type = "Office" end
puts building_type
# array of starting space types
space_types_starting = model.getSpaceTypes.sort
# create stub space types
space_types_new = []
space_type_hash.each do |space_type_name, hash|
next if hash[:space_type_gen] == false # space types like undeveloped and basement are skipped.
# create space type
space_type = OpenStudio::Model::SpaceType.new(model)
space_type.setStandardsBuildingType(building_type)
space_type.setStandardsSpaceType(space_type_name)
space_type.setName("#{building_type} #{space_type_name}")
# add to array of new space types
space_types_new << space_type
# add internal loads (the nil check isn't ncessary, but I will keep it in as a warning instad of an error)
test = standard.space_type_apply_internal_loads(space_type, true, true, true, true, true, true)
if test.nil?
puts "Could not add loads for #{space_type.name}. Not expected for #{template} #{lookup_building_type}"
end
# the last bool test it to make thermostat schedules. They are added to the model but not assigned
standard.space_type_apply_internal_load_schedules(space_type, true, true, true, true, true, true, true)
# assign colors
standard.space_type_apply_rendering_color(space_type)
# exend space type name to include the template. Consider this as well for load defs
space_type.setName("#{space_type.name} - #{template}")
puts "Added space type named #{space_type.name}"
end
# identify default space type. Not sure about this, just copied from the measure
space_type_standards_info_hash = OsLib_HelperMethods.getSpaceTypeStandardsInformation(space_types_new)
puts space_type_standards_info_hash
default_space_type = nil
space_type_standards_info_hash.each do |space_type, standards_array|
standards_space_type = standards_array[1]
if default_space_type_name == standards_space_type
default_space_type = space_type
end
end
# set default space type
building = model.getBuilding
if !default_space_type.nil?
building.setSpaceType(default_space_type)
end
model.save("#{model_name}.osm", true)