The original Window to Wall Ratio measure does just look at surface orientation along with surface type, but you can really filter any way you want to. This could be based on surface, space, building story, or space type name, or some other attribute of one of those objects.
When we made the AEDG measures we had added the plenum object to OpenStudio so those fenestration measures do skip plenums, but it figures out the plenum by a user specified standards space type (more reliable then just using the name of a space type). The office and school have different logic on the size of the window based on how the guides were written. This includes a customized version of what is north, south, east, west vs. the way our basic measure works (which splits at the 45 degrees).
AEDG Small to Medium Office - Fenestration and Daylighting Controls
AEDG K12 - Fenestration and Daylighting Controls
Below I pasted in a block of code from our basic measure. It loops through each surafces without regard to which space they come from, but it could very easily be changed to first loop through spaces or even space types, and then for each space it could loop through surfaces.
You could add any kind of logic to skip a space type such as what is below
next if not space_type.name.to_s.include? "plenum"
There is an OpenStudio option to check of a zone is a plenum, but that would only be useful after the HVAC system has been added, which typically would be after fenestration is created. Any sort of name or space type filter requires the user to take some action to identify spaces that they later intend to use as plenums. One alternate solution would be to keep the logic similar to what is in the main block below, but check each surface to see that it is higher than a target test height. This could be a hard coded height or could be a user argument. This would work without much prior thought from the modeler, other than what would be typical for a plenum.
#data for final condition wwr
surfaces = model.getSurfaces
surfaces.each do |s|
next if not s.surfaceType == "Wall"
next if not s.outsideBoundaryCondition == "Outdoors"
if s.space.empty?
runner.registerWarning("#{s.name} doesn't have a parent space and won't be included in the measure reporting or modifications.")
next
end
# get the absoluteAzimuth for the surface so we can categorize it
absoluteAzimuth = OpenStudio::convert(s.azimuth,"rad","deg").get + s.space.get.directionofRelativeNorth + model.getBuilding.northAxis
until absoluteAzimuth < 360.0
absoluteAzimuth = absoluteAzimuth - 360.0
end
if facade == "North"
next if not (absoluteAzimuth >= 315.0 or absoluteAzimuth < 45.0)
elsif facade == "East"
next if not (absoluteAzimuth >= 45.0 and absoluteAzimuth < 135.0)
elsif facade == "South"
next if not (absoluteAzimuth >= 135.0 and absoluteAzimuth < 225.0)
elsif facade == "West"
next if not (absoluteAzimuth >= 225.0 and absoluteAzimuth < 315.0)
else
runner.registerError("Unexpected value of facade ...
(more)