Using Eppy to extract fenestration from IDF and replace with WWR-derived formulas
Hello, I am trying to write a piece of Eppy code to:
- open an IDF (created with designbuilder or openstudio)
- list all windows in the idf file (under FenestrationSurface:Detailed)
- extract the Building Surface Name parameter from these windows
- create “Window” objects for each surface in the list generated by the previous step
- apply fields Construction_Name and Building_Surface_Name to the newly created windows
assign:
Starting_X_Coordinate (x0) = host wall's XCOORDINATE (X0) + WWR formula [could it be x0 = (X2-X0)/2*sqrt(WWR) ?]
Starting_Z_Coordinate (z0) = host wall's ZCOORDINATE (Z0) + WWR formula
window length (x2-x0) = sqrt(WWR)*(X2-X0)
window height (z2-z0) = sqrt(WWR)*(Z2-Z0)
There is some guidance on that on the jeplus manual
My code looks show a tentative attempt to create a loop but I could not get far. Can anyone help?
## DELETES FENESTRATION SURFACES AND CREATES WINDOWS WITH SAME HOSTS, SAME MATERIALS AND WWR @@LABEL@@
old_fen = idf1.idfobjects['FENESTRATIONSURFACE:DETAILED']
new_win = idf1.idfobjects['WINDOW']
#for w in new_win:
#print w.objls # useful to understand what IDF fields can be called
for w in old_fen:
#print w.objls
old_fen_name = w.Name
new_win1 = idf1.newidfobject('window'.upper()) # the key for the object type has to be in upper case
new_win1.Construction_Name = w.Construction_Name
new_win1.Building_Surface_Name = w.Building_Surface_Name
print new_win1.Building_Surface_Name
# find "new_win1.Building_Surface_Name" (the surface hosting the window) among surfaces
# gather XCOORDINATE and ZCOORDINATE of those host surfaces
# new_win1.Starting_X_Coordinate = XCOORDINATE (host)
# new_win1.Starting_Z_Coordinate = ZCOORDINATE (host)
EDIT: Combining the script suggested by Jamie Bull:
for f in old_fen:
base_wall = idf1.getobject('BUILDINGSURFACE:DETAILED', f.Building_Surface_Name)
w = idf1.newidfobject('WINDOW', f.Name,
Building_Surface_Name=f.Building_Surface_Name,
Construction_Name=f.Construction_Name,
Starting_X_Coordinate=0,
Length=base_wall.width,
Starting_Z_Coordinate="#[%s * #[1 - #[@@wwr@@ / 2.0]]]" % base_wall.height,
Height="#[%s * @@wwr@@]" % base_wall.height,
)
idf1.removeidfobject(f)
with another, aimed at replacing a given ceiling height with a jeplus-compatible label @@ch@@
, (also suggested by Jamie Bull) :
## PRE-PROCESSING FOR JEPLUS - REPLACES ZCOORDINATE WITH CEILING HEIGHT @@LABEL@@
ceiling_height = '@@ch@@'
walls_and_roofs = [s for s in surfaces if s.Surface_Type in ['Wall', 'Roof']]
for s in surfaces:
max_z = max(pt[2] for pt in s.coords)
for field in s.objls: # or "for field in s.objls:" if using version <= 0.5.2
if 'ZCOORDINATE' in field.upper() and s[field] == max_z:
s[field] = ceiling_height
Then the Starting_Z_Coordinate and Height of the parametric windows refer to the original wall heigth - which does not account for the @@ch@@ parameter. This results in windows created with the wwr parameter being too big and going outsite the existing walls. Any idea on how to fix this Jamie? :P
Just a note about a different option. The OpenStudio API (documentation) can be used like eppy to manipulate an IDF (workspace) using Ruby. The OpenStudio Measure Writing Guide has examples for interacting with the IDF through formal EnergyPlus Measures, which can also be run from a command line/terminal.