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

Get Zones Associated with an Air Loop In E+ Measure

asked 2017-01-31 11:49:04 -0500

Adam Hilton gravatar image

updated 2017-02-01 03:20:12 -0500

With Model Objects in an OpenStudio measure this is easy, but how do you go about doing this with Workspace Objects in an EnergyPlus measure?

I'm not able to find a way to establish this dependency without having to manually step through multiple objects.

  1. Seed AirLoopHVAC of interest
  2. Get 'Demand Side Inlet Node Names' of AirLoopHVAC
  3. Get NodeList that has value of step 2 for 'Name' (field 0)
  4. Get 'Node Name' of NodeList from step 3
  5. Get AirLoopHVAC:ZoneSplitter that has value from step 4 for 'Inlet Node Name' (field 1)
  6. Get 'Outlet Node Names' of AirLoopHVAC:ZoneSplitter from step 5 (fields 2 to XX)
  7. Get AirTerminal:XXXXX that have one of the values from the vector created in step 6 for 'Inlet Node Name' (field varies)
  8. Get 'Name' (field 0) of all objects from step 7
  9. Get ZoneHVAC:AirDistributionUnit that have one of the values from the vector created in step 8 for 'Air Terminal Name' (field 3)
  10. Get 'Name' (field 0) of all objects from step 9
  11. Get ZoneHVAC:EquipmentList that have one of the values from the vector created in step 10 for 'Zone Equipment Name 1 to XX '
  12. Get 'Name' (field 0) of all objects from step 11
  13. Get ZoneHVAC:EquipmentConnections that have one of the values from the vector created in step 12 for 'Zone Conditioning Equipment List Name' (field 1)
  14. Get 'Zone Name' (field 0) of all objects from step 13

I expect no one to actually read that, but point is, I see having to step through 7 objects to associate a zone with an air loop. I'm hoping there is a workspace method that can be used help establish this dependency directly, but I've yet to find it. Am I just completely overlooking something obvious?

Edit: As Eric suggested, loading the model is a possibility, but any changes performed in prior energy plus measures will not be captured.

edit retag flag offensive close merge delete

Comments

This doesn't answer your question, but could you instead use an OS measure to get the list of zones, which you then access in an E+ measure?

Eric Ringold gravatar imageEric Ringold ( 2017-01-31 12:27:47 -0500 )edit

I thought about that, but I'm not sure how to call that measure on the *.osm output from OS measures that are run by the application. If I just call it on the osm that's saved, I risk missing something that was altered in those measures.

Adam Hilton gravatar imageAdam Hilton ( 2017-01-31 13:05:13 -0500 )edit
1

Oh yeah, that could be tricky. Alternatively, load up the model with the runner (like here) and use the easy model methods.

Eric Ringold gravatar imageEric Ringold ( 2017-01-31 13:21:19 -0500 )edit

I'm pretty sure model = runner.lastOpenStudioModel should return the last one (after the OS Measures are applied)

Julien Marrec gravatar imageJulien Marrec ( 2017-02-01 03:15:18 -0500 )edit

Right, but my concern is that something will be missed that was changed in a previous EP measure.

Adam Hilton gravatar imageAdam Hilton ( 2017-02-01 06:40:38 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
4

answered 2017-02-01 11:01:59 -0500

Adam Hilton gravatar image

updated 2017-02-02 08:54:14 -0500

After I wrote all this I realized it would be more efficient and scalable to go backward though the mixer rather than forward through the splitter. Oh well.

def airLoopThermalZones(workspace, runner, air_loop, zone_names)
    air_loop_name = air_loop.getString(0).get.to_s

    # splitters
    splitters = workspace.getObjectsByType("AirLoopHVAC:ZoneSplitter".to_IddObjectType)

    # terminals
    uncontrolleds = workspace.getObjectsByType("AirTerminal:SingleDuct:Uncontrolled".to_IddObjectType)
    cv_reheats = workspace.getObjectsByType("AirTerminal:SingleDuct:ConstantVolume:Reheat".to_IddObjectType)
    vav_reheats = workspace.getObjectsByType("AirTerminal:SingleDuct:VAV:Reheat".to_IddObjectType)
    vav_noreheats = workspace.getObjectsByType("AirTerminal:SingleDuct:VAV:NoReheat".to_IddObjectType)
    vav_hc_noreheats = workspace.getObjectsByType("AirTerminal:SingleDuct:VAV:HeatAndCool:NoReheat".to_IddObjectType)
    piu_series_reheats = workspace.getObjectsByType("AirTerminal:SingleDuct:SeriesPIU:Reheat".to_IddObjectType)
    piu_parallel_reheats = workspace.getObjectsByType("AirTerminal:SingleDuct:ParallelPIU:Reheat".to_IddObjectType)

    # adus
    adus = workspace.getObjectsByType("ZoneHVAC:AirDistributionUnit".to_IddObjectType)

    # equipment lists
    equip_lists = workspace.getObjectsByType("ZoneHVAC:EquipmentList".to_IddObjectType)

    # equipment connections
    equip_connections = workspace.getObjectsByType("ZoneHVAC:EquipmentConnections".to_IddObjectType)
    # required intermediate arrays
    adu_terminal_names = []
    other_terminal_names = []
    adu_names = []
    equip_list_names = []

    # get air loop inlet node list
    inlet_nodelist_name = air_loop.getString(8).get.to_s
    inlet_nodelist = workspace.getObjectByTypeAndName("NodeList".to_IddObjectType, inlet_nodelist_name).get

    # get air loop demand inlet node name
    node_name = inlet_nodelist.getString(1).get.to_s

    # find cooresponding splitter
    splitter = nil
    splitters.each do |splitter_temp|
        if splitter_temp.getString(1).get.to_s == node_name
            splitter = splitter_temp
        end
    end

    # store all splitter outlet node names 
    splitter_outlet_node_names = []
    for i in 2..splitter.numFields.to_i-1
        splitter_outlet_node_names << splitter.getString(i).get.to_s
    end

    # find terminals that use stored splitter outlet nodes
    splitter_outlet_node_names = checkTerminalNodeMatch(splitter_outlet_node_names, other_terminal_names, uncontrolleds, 2, runner)
    splitter_outlet_node_names = checkTerminalNodeMatch(splitter_outlet_node_names, adu_terminal_names, cv_reheats, 3, runner)
    splitter_outlet_node_names = checkTerminalNodeMatch(splitter_outlet_node_names, adu_terminal_names, vav_reheats, 3, runner)
    splitter_outlet_node_names = checkTerminalNodeMatch(splitter_outlet_node_names, adu_terminal_names, vav_noreheats, 3, runner)
    splitter_outlet_node_names = checkTerminalNodeMatch(splitter_outlet_node_names, adu_terminal_names, vav_hc_noreheats, 3, runner)
    splitter_outlet_node_names = checkTerminalNodeMatch(splitter_outlet_node_names, adu_terminal_names, piu_series_reheats, 5, runner)
    splitter_outlet_node_names = checkTerminalNodeMatch(splitter_outlet_node_names, adu_terminal_names, piu_parallel_reheats, 6, runner) 

    if splitter_outlet_node_names.size >= 1
        runner.registerError("There were #{splitter_outlet_node_names.size} that were not able to be matched to terminals for #{air_loop_name}.")
        return false
    end

    adus.each do |adu|
        adu_terminal_name = adu.getString(3).get.to_s
        adu_terminal_names.each do |air_terminal_name|
            if air_terminal_name == adu_terminal_name
                adu_names << adu.getString(0).get.to_s
            end
        end
    end


    equip_lists.each do |equip_list|
    i = 2
    length = equip_list.numFields.to_i
    while i < length
        equip_list_adu_name = equip_list.getString(i).get.to_s
        if adu_names.size > 0
            adu_names.each do |adu_name|
                if adu_name == equip_list_adu_name
                    equip_list_names << equip_list.getString(0).get.to_s
                end
            end
        elsif other_terminal_names.size > 0
            other_terminal_names.each do |other_terminal_name|
                if other_terminal_name == equip_list_adu_name
                    equip_list_names << equip_list.getString(0).get.to_s
                end
            end
        else
            runner.registerError("No equipment able to be matched to air terminal names for #{air_loop_name}.")
            return false
        end
        i = i + 4
    end
end

if equip_list_names.size == 0
    runner.registerError("No equipment lists were able to be matched to air distribution units for #{air_loop_name}.")
    return false
end

    equip_connections.each do |equip_connection|
        equip_connection_equip_list_name= equip_connection.getString(1).get.to_s
        equip_list_names.each do |equip_list_name|
            runner.registerInfo("Checked #{equip_list_name} with #{equip_connection_equip_list_name}")
            if equip_list_name == equip_connection_equip_list_name
                zone_names << equip_connection.getString(0).get.to_s
            end
        end
    end

    if zone_names.size == 0
        runner.registerError("No zones were able to be matched to air loops for #{air_loop_name}.")
        return false
    end

    return zone_names

end

def checkTerminalNodeMatch(splitter_nodes, air_terminal_names, terminals, field, runner)
    #NESTED IFS END LIVES
    if splitter_nodes.size >= 1
        splitter_nodes.each do |splitter_node|
            # for uncontrolled terminals
            terminals.each do |terminal|
                if ...
(more)
edit flag offensive delete link more

Comments

Thanks for sharing your solution!

Lyle K gravatar imageLyle K ( 2017-02-01 17:50:57 -0500 )edit

You forgot to include checkTerminalNodeMatch no?

Julien Marrec gravatar imageJulien Marrec ( 2017-02-02 01:57:37 -0500 )edit

Okay fine. I guess some things are free in life.

Adam Hilton gravatar imageAdam Hilton ( 2017-02-02 08:47:37 -0500 )edit
2

The best things in life are free.

__AmirRoth__ gravatar image__AmirRoth__ ( 2017-02-02 09:01:34 -0500 )edit

Like sitting in traffic.

Adam Hilton gravatar imageAdam Hilton ( 2017-02-02 09:03:03 -0500 )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

2 followers

Stats

Asked: 2017-01-31 11:49:04 -0500

Seen: 160 times

Last updated: Feb 02 '17