Question-and-Answer Resource for the Building Energy Modeling Community
Get s tarted with the Help page
Ask Your Question

Get Thermal Zone Supply Terminal

asked 2016-05-23 11:42:02 -0600

Adam Hilton gravatar image

updated 2017-08-05 07:59:00 -0600

I'm trying to grab thermal zone supply terminals with the following code.

thermalZones = model.getThermalZones

thermalZones.each do |thermalZone|
    supplyTerminal = thermalZone.airLoopHVACTerminal
    runner.registerInfo("For '#{}' the supply terminal '#{supplyTerminal}' was found.")

Running the previous results in the following.

image description

It seems as though I'm not actually capturing the object because when I try to use it returns undefined. I assume I'm just missing something rudimentary that should be blatantly obvious and after it's pointed out to me I'll have to hold my head in shame for the rest of the day.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2016-05-23 11:49:19 -0600

updated 2016-05-23 12:02:14 -0600

This is because OpenStudio::Model::ThermalZone::airLoopHVACTerminal() returns an optional HVACComponent, see SDK doc. You have to get it first.

Try this:

model.getThermalZones.each do |zone|
  # this returns an optional HVACComponent
  supplyTerminal = zone.airLoopHVACTerminal
  if supplyTerminal.empty?
    runner.registerInfo("Cannot find an airloop terminal for #{}")
    supplyTerminal = supplyTerminal.get
    runner.registerInfo("For '#{}' the supply terminal '#{}' was found.")

Like I said supplyTerminal, even after ".get" will be an HVACComponent, not an actual object such as OpenStudio::Model::AirTerminalSingleDuctUncontrolled for example. If you need to work with the actual underlying object, you'll have to cast it into what it's really.

The clean way is to use to_XXXX method, but you have to test potentially a lot of cases...

if supplyTerminal.to_AirTerminalSingleDuctUncontrolled.is_initialized
  supplyTerminal = supplyTerminal.to_AirTerminalSingleDuctUncontrolled.get
elsif supplyTerminal.to_AirTerminalSingleDuctVAVNoReheat.is_initialized
  supplyTerminal = supplyTerminal.to_AirTerminalSingleDuctVAVNoReheat.get
  runner.registerInfo("I don't know what this object is because there are too many possible ones!")

You want the dirty way? I knew it! But I shall not be liable for any problems you might get :)

Anyways, just add this method to the class ModelObject...

# Extend ModelObject class to add a to_actual_object method
# Casts a ModelObject into what it actually is (OS:Node for example...)
class OpenStudio::Model::ModelObject
  def to_actual_object
    obj_type = self.iddObjectType.valueName
    obj_type_name = obj_type.gsub('OS_','').gsub('_','')
    method_name = "to_#{obj_type_name}"
    if self.respond_to?(method_name)
      actual_thing = self.method(method_name).call
      if !actual_thing.empty?
          return actual_thing.get
    return false

Then you can do supplyTerminal = supplyTerminal.to_actual_object

It'll work with anything, since everything in OpenStudio::Model is after all a ModelObject: ModelObject instances, HVACComponent, even objects such as AirTerminalSingleDuctVAVNoReheat themselves (though that's completely pointless)

edit flag offensive delete link more


Right. I actually had that structure but I was neglecting the .get. Well now I'll also be less confused when I see 'optional' next to the object type. You're the best.

Adam Hilton gravatar image Adam Hilton  ( 2016-05-23 11:55:07 -0600 )edit

I have a feeling there might be like 9 openstudio developpers out of ten that just threw up in their mouth a bit after I posted that to_actual_object method, didn't they?

Julien Marrec gravatar image Julien Marrec  ( 2016-05-23 12:03:28 -0600 )edit

Ha, you enjoy this too much! I just needed the HVAC Component to get the parent air loop. Although, there's no way to get the air loop directly from the thermal zone, right? I didn't see a path other than jumping through the terminal.

Adam Hilton gravatar image Adam Hilton  ( 2016-05-23 12:11:52 -0600 )edit

@adhiltonThermalZone inherits from the HVACComponent class, which has a method to get the Air Loop HVAC that the component is attached to (if applicable). See here for all valid ThermalZone methods.

Eric Ringold gravatar image Eric Ringold  ( 2016-05-23 12:21:40 -0600 )edit

Duh. Didn't think to check that, thanks.

Adam Hilton gravatar image Adam Hilton  ( 2016-05-23 12:40:15 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer


Question Tools



Asked: 2016-05-23 11:42:02 -0600

Seen: 238 times

Last updated: May 23 '16