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)
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?
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.
Oh yeah, that could be tricky. Alternatively, load up the model with the runner (like here) and use the easy model methods.
I'm pretty sure
model = runner.lastOpenStudioModel
should return the last one (after the OS Measures are applied)Right, but my concern is that something will be missed that was changed in a previous EP measure.