Class: ImportEnvelopeAndInternalLoadsFromIdf

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

Overview

start the measure

Instance Method Summary collapse

Instance Method Details

#arguments(model) ⇒ Object

define the arguments that the user will input



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/measures/ImportEnvelopeAndInternalLoadsFromIdf/measure.rb', line 24

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

  # make an argument for external idf
  source_idf_path = OpenStudio::Measure::OSArgument.makeStringArgument('source_idf_path', true)
  source_idf_path.setDisplayName('External IDF File Name')
  source_idf_path.setDescription('Name of the IDF file to import objects from. This is the filename with the extension (e.g. MyModel.idf). Optionally this can inclucde the full file path, but for most use cases should just be file name.')
  args << source_idf_path

  # make an argument for importing site objects
  import_site_objects = OpenStudio::Measure::OSArgument.makeBoolArgument('import_site_objects', true)
  import_site_objects.setDisplayName('Import Site Shading.')
  # import_site_objects.setDisplayName("Import Site objects (site shading and exterior lights).")  # todo - use this once exterior lights are supported
  import_site_objects.setDefaultValue(true)
  args << import_site_objects

  return args
end

#nameObject

define the name that a user will see, this method may be deprecated as the display name in PAT comes from the name field in measure.xml



19
20
21
# File 'lib/measures/ImportEnvelopeAndInternalLoadsFromIdf/measure.rb', line 19

def name
  return 'ImportEnvelopeAndInternalLoadsFromIdf'
end

#run(model, runner, user_arguments) ⇒ Object

define what happens when the measure is run



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/measures/ImportEnvelopeAndInternalLoadsFromIdf/measure.rb', line 44

def run(model, runner, user_arguments)
  super(model, runner, user_arguments)

  # assign the user inputs to variables
  import_site_objects = runner.getBoolArgumentValue('import_site_objects', user_arguments)

  # use the built-in error checking
  if !runner.validateUserArguments(arguments(model), user_arguments)
    return false
  end

  # assign the user inputs to variables
  source_idf_path = runner.getStringArgumentValue('source_idf_path', user_arguments)

  # find source_idf_path
  osw_file = runner.workflow.findFile(source_idf_path)
  if osw_file.is_initialized
    source_idf_path = osw_file.get.to_s
  else
    runner.registerError("Did not find #{source_idf_path} in paths described in OSW file.")
    return false
  end

  # reporting initial condition of model
  starting_spaces = model.getSpaces
  runner.registerInitialCondition("The building started with #{starting_spaces.size} spaces.")

  # translate IDF file to OSM
  workspace = OpenStudio::Workspace.load(OpenStudio::Path.new(source_idf_path))
  rt = OpenStudio::EnergyPlus::ReverseTranslator.new
  model2 = rt.translateWorkspace(workspace.get)

  # remove original building
  building = model.getBuilding
  building.remove

  # clone in building from IDF
  building2 = model2.getBuilding
  building2.clone(model)

  # hash of old and new thermostats
  thermostatOldNewHash = {}

  # cloning thermostats
  thermostats = model2.getThermostatSetpointDualSetpoints
  thermostats.each do |thermostat|
    newThermostat = thermostat.clone(model)
    # populate hash
    thermostatOldNewHash[thermostat] = newThermostat
  end

  # loop through thermal zone to match old to new and assign thermostat
  thermalZonesOld = model2.getThermalZones
  thermalZonesNew = model.getThermalZones
  thermalZonesOld.each do |thermalZoneOld|
    thermalZonesNew.each do |thermalZoneNew|
      if thermalZoneOld.name.to_s == thermalZoneNew.name.to_s
        # wire thermal zone to thermostat
        if !thermalZoneOld.thermostatSetpointDualSetpoint.empty?
          thermostatOld = thermalZoneOld.thermostatSetpointDualSetpoint.get
          thermalZoneNew.setThermostatSetpointDualSetpoint(thermostatOldNewHash[thermostatOld].to_ThermostatSetpointDualSetpoint.get)
        end
        next
      end
    end
  end

  # fix for space type and thermal zone connections
  spaces = model.getSpaces
  spaces.each do |space|
    thermalZonesNew.each do |zone|
      # since I know the names here I can look for match, but this work around only works with imported IDF's where names are known
      if zone.name.to_s == "#{space.name} Thermal Zone"
        space.setThermalZone(zone)
      end
    end
  end

  # TODO: - surface matching is also messed up, but I'll add a stand alone measure for that vs. adding it here.

  # import site objects if requested
  if import_site_objects

    # TODO: - this doesn't do anything because exterior lights don't make it through reverse translation
    # get exterior lights
    facility = model2.getFacility
    exteriorLights = facility.exteriorLights
    exteriorLights.each do |exteriorLight|
      exteriorLight.clone(model)
      runner.registerInfo("Cloning exterior light #{exteriorLight.name} into model.")
    end

    # get site shading
    shadingSurfaceGroups = model2.getShadingSurfaceGroups
    shadingSurfaceGroups.each do |group|
      if group.shadingSurfaceType == 'Site'
        group.clone(model)
        runner.registerInfo("Cloning shading group #{group.name} into model.")
      end
    end

  end

  # reporting final condition of model
  finishing_spaces = model.getSpaces
  runner.registerFinalCondition("The building finished with #{finishing_spaces.size} spaces.")

  # TODO: - see if SHW comes in, if not think of solution

  return true
end