Class: FromHoneybeeModel

Inherits:
OpenStudio::Measure::ModelMeasure
  • Object
show all
Defined in:
lib/measures/from_honeybee_model/measure.rb

Overview

start the measure

Instance Method Summary collapse

Instance Method Details

#arguments(model) ⇒ Object

define the arguments that the user will input



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/measures/from_honeybee_model/measure.rb', line 60

def arguments(model)
  args = OpenStudio::Measure::OSArgumentVector.new

  # Make an argument for the honyebee model json
  model_json = OpenStudio::Measure::OSArgument.makeStringArgument('model_json', true)
  model_json.setDisplayName('Path to the Honeybee Model JSON file')
  args << model_json

  # Make an argument for schedule csv dir
  schedule_csv_dir = OpenStudio::Measure::OSArgument.makeStringArgument('schedule_csv_dir', false)
  schedule_csv_dir.setDisplayName('Directory for exported CSV Schedules')
  schedule_csv_dir.setDescription('If set, Fixed Interval Schedules will be translated to CSV Schedules in this directory')
  schedule_csv_dir.setDefaultValue('')
  args << schedule_csv_dir

  # Make an argument for include datetimes
  include_datetimes = OpenStudio::Measure::OSArgument.makeBoolArgument('include_datetimes', false)
  include_datetimes.setDisplayName('Include date time column in exported CSV Schedules')
  include_datetimes.setDefaultValue(false)
  args << include_datetimes

  return args
end

#descriptionObject

human readable description



50
51
52
# File 'lib/measures/from_honeybee_model/measure.rb', line 50

def description
  return 'Translate a JSON file of a Honeybee Model into an OpenStudio Model.'
end

#modeler_descriptionObject

human readable description of modeling approach



55
56
57
# File 'lib/measures/from_honeybee_model/measure.rb', line 55

def modeler_description
  return 'Translate a JSON file of a Honeybee Model into an OpenStudio Model.'
end

#nameObject

human readable name



45
46
47
# File 'lib/measures/from_honeybee_model/measure.rb', line 45

def name
  return 'From Honeybee Model'
end

#run(model, runner, user_arguments) ⇒ Object

define what happens when the measure is run



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/measures/from_honeybee_model/measure.rb', line 85

def run(model, runner, user_arguments)
  super(model, runner, user_arguments)
  STDOUT.flush
  if !runner.validateUserArguments(arguments(model), user_arguments)
    return false
  end

  # get the input arguments
  model_json = runner.getStringArgumentValue('model_json', user_arguments)
  schedule_csv_dir = runner.getStringArgumentValue('schedule_csv_dir', user_arguments)
  include_datetimes = runner.getBoolArgumentValue('include_datetimes', user_arguments)

  # load the HBJSON file
  if !File.exist?(model_json)
    runner.registerError("Cannot find file '#{model_json}'")
    return false
  end
  honeybee_model = Honeybee::Model.read_from_disk(model_json)

  # setup the schedule directory
  if schedule_csv_dir && !schedule_csv_dir.empty?
    schedule_csv_dir = Pathname.new(schedule_csv_dir).cleanpath
    if !Dir.exist?(schedule_csv_dir)
      runner.registerError("Directory for exported CSV Schedules does not exist '#{schedule_csv_dir}'")
      return false
    end
    honeybee_model.set_schedule_csv_dir(schedule_csv_dir, include_datetimes)
  end

  # translate the Honeybee Model to OSM
  STDOUT.flush
  honeybee_model.to_openstudio_model(model)
  STDOUT.flush

  # if there are any detailed HVACs, incorproate them into the OSM
  generated_files_dir = "#{runner.workflow.absoluteRootDir}/generated_files"
  unless $detailed_hvac_hash.nil? || $detailed_hvac_hash.empty?
    runner.registerInfo("Translating Detailed HVAC systems in '#{generated_files_dir}'")
    if $ironbug_exe.nil?
      runner.registerError("No Ironbug installation was found on the system.")
    end
    FileUtils.mkdir_p(generated_files_dir)
    $detailed_hvac_hash.each do |hvac_id, hvac_spec|
      # write the JSON and OSM files
      hvac_json_path = generated_files_dir + '/' + hvac_id + '.json'
      osm_path = generated_files_dir + '/' + hvac_id + '.osm'
      File.open(hvac_json_path, 'w') do |f|
        f.write(hvac_spec.to_json)
      end
      model.save(osm_path, true)
      # call the Ironbug console to add the HVAC to the OSM
      ironbug_exe = '"' + $ironbug_exe + '"'
      ib_cmd = ironbug_exe + ' "' + osm_path + '" "' + hvac_json_path + '"'
      stdout, stderr, status = Open3.capture3(ib_cmd)
      if status.exitstatus != 0
        runner.registerError('Failed to apply IronBug HVAC:' + stderr)
        return false
      end
      # load the new model
      translator = OpenStudio::OSVersion::VersionTranslator.new
      o_model = translator.loadModel(osm_path)
      if o_model.empty?
        runner.registerError("Could not load Ironbug model from '" + osm_path.to_s + "'.")
        return false
      end
      new_model = o_model.get
      # replace the current model with the contents of the loaded model
      handles = OpenStudio::UUIDVector.new
      model.objects.each do |obj|
        handles << obj.handle
      end
      model.removeObjects(handles)
      # add new file to empty model
      model.addObjects(new_model.toIdfFile.objects)
    end
  end

  # if an efficiency standard has been set on the model, then run sizing and set everything
  building = model.getBuilding
  unless $bypass_eff_sizing == true || building.standardsTemplate.empty?
    puts 'Autosizing HVAC systems and assigning efficiencies'
    standard_id = building.standardsTemplate.get
    require 'openstudio-standards'
    standard = Standard.build(standard_id)
    # Set the heating and cooling sizing parameters
    standard.model_apply_prm_sizing_parameters(model)
    # Perform a sizing run
    if standard.model_run_sizing_run(model, "#{Dir.pwd}/SR1") == false
      log_messages_to_runner(runner, debug = true)
      return false
    end
    # If there are any multizone systems, reset damper positions
    # to achieve a 60% ventilation effectiveness minimum for the system
    # following the ventilation rate procedure from 62.1
    standard.model_apply_multizone_vav_outdoor_air_sizing(model)
    # get the climate zone  
    climate_zone_obj = model.getClimateZones.getClimateZone('ASHRAE', 2006)
    if climate_zone_obj.empty
      climate_zone_obj = model.getClimateZones.getClimateZone('ASHRAE', 2013)
    end
    climate_zone = climate_zone_obj.value
    # get the building type
    bldg_type = nil
    unless building.standardsBuildingType.empty?
      bldg_type = building.standardsBuildingType.get
    end
    # Apply the prototype HVAC assumptions
    standard.model_apply_prototype_hvac_assumptions(model, bldg_type, climate_zone)
    # Apply the HVAC efficiency standard
    standard.model_apply_hvac_efficiency_standard(model, climate_zone)
    puts 'Done with autosizing HVAC systems!'
  end

  puts 'Done with Model translation!'

  # copy the CSV schedules into the directory where EnergyPlus can find them
  if schedule_csv_dir && !schedule_csv_dir.empty?
    if Dir.exist?(schedule_csv_dir)
      runner.registerInfo("Copying exported schedules from '#{schedule_csv_dir}' to '#{generated_files_dir}'")
      FileUtils.mkdir_p(generated_files_dir)
      Dir.glob("#{schedule_csv_dir}/*.csv").each do |file|
        FileUtils.cp(file, generated_files_dir)
      end
    end
  end

  return true
end