Example #1
0
def test_newidfobject():
    """py.test for newidfobject"""
    # make a blank idf
    # make a function for this and then continue.
    idf = IDF()
    idf.new()
    objtype = 'material:airgap'.upper()
    obj = idf.newidfobject(objtype, Name='Argon')
    obj = idf.newidfobject(objtype, Name='Krypton')
    obj = idf.newidfobject(objtype, Name='Xenon')
    assert idf.model.dt[objtype] == [['MATERIAL:AIRGAP', 'Argon'],
                                     ['MATERIAL:AIRGAP', 'Krypton'],
                                     ['MATERIAL:AIRGAP', 'Xenon'],
                                     ]
    # remove an object
    idf.popidfobject(objtype, 1)
    assert idf.model.dt[objtype] == [['MATERIAL:AIRGAP', 'Argon'],
                                     ['MATERIAL:AIRGAP', 'Xenon'],
                                     ]
    lastobject = idf.idfobjects[objtype][-1]
    idf.removeidfobject(lastobject)
    assert idf.model.dt[objtype] == [['MATERIAL:AIRGAP', 'Argon'], ]
    # copyidfobject
    onlyobject = idf.idfobjects[objtype][0]
    idf.copyidfobject(onlyobject)

    assert idf.model.dt[objtype] == [['MATERIAL:AIRGAP', 'Argon'],
                                     ['MATERIAL:AIRGAP', 'Argon'],
                                     ]
    # test some functions
    objtype = 'FENESTRATIONSURFACE:DETAILED'
    obj = idf.newidfobject(objtype, Name='A Wall')
    assert obj.coords == []
    assert obj.fieldvalues[1] == 'A Wall'
Example #2
0
def test_newidfobject():
    """py.test for newidfobject"""
    # make a blank idf
    # make a function for this and then continue.
    idf = IDF()
    idf.new()
    objtype = "material:airgap".upper()
    obj = idf.newidfobject(objtype, Name="Argon")
    obj = idf.newidfobject(objtype, Name="Krypton")
    obj = idf.newidfobject(objtype, Name="Xenon")
    assert idf.model.dt[objtype] == [
        ["MATERIAL:AIRGAP", "Argon"],
        ["MATERIAL:AIRGAP", "Krypton"],
        ["MATERIAL:AIRGAP", "Xenon"],
    ]
    # remove an object
    idf.popidfobject(objtype, 1)
    assert idf.model.dt[objtype] == [
        ["MATERIAL:AIRGAP", "Argon"],
        ["MATERIAL:AIRGAP", "Xenon"],
    ]
    lastobject = idf.idfobjects[objtype][-1]
    idf.removeidfobject(lastobject)
    assert idf.model.dt[objtype] == [["MATERIAL:AIRGAP", "Argon"]]
    # copyidfobject
    onlyobject = idf.idfobjects[objtype][0]
    idf.copyidfobject(onlyobject)

    assert idf.model.dt[objtype] == [
        ["MATERIAL:AIRGAP", "Argon"],
        ["MATERIAL:AIRGAP", "Argon"],
    ]
    # remove all objects
    idf.removeallidfobjects(objtype)
    assert len(idf.idfobjects[objtype]) == 0
    # test some functions
    objtype = "FENESTRATIONSURFACE:DETAILED"
    obj = idf.newidfobject(objtype, Name="A Wall")
    assert obj.coords == []
    assert obj.fieldvalues[1] == "A Wall"

    # test defaultvalues=True and defaultvalues=False
    sim_deftrue = idf.newidfobject("SimulationControl".upper(),
                                   defaultvalues=True)
    assert sim_deftrue.Do_Zone_Sizing_Calculation == "No"
    sim_deffalse = idf.newidfobject("SimulationControl".upper(),
                                    defaultvalues=False)
    assert sim_deffalse.Do_Zone_Sizing_Calculation == ""
Example #3
0
def test_newidfobject():
    """py.test for newidfobject"""
    # make a blank idf
    # make a function for this and then continue.
    idf = IDF()
    idf.new()
    objtype = 'material:airgap'.upper()
    obj = idf.newidfobject(objtype, Name='Argon')
    obj = idf.newidfobject(objtype, Name='Krypton')
    obj = idf.newidfobject(objtype, Name='Xenon')
    assert idf.model.dt[objtype] == [
        ['MATERIAL:AIRGAP', 'Argon'],
        ['MATERIAL:AIRGAP', 'Krypton'],
        ['MATERIAL:AIRGAP', 'Xenon'],
    ]
    # remove an object
    idf.popidfobject(objtype, 1)
    assert idf.model.dt[objtype] == [
        ['MATERIAL:AIRGAP', 'Argon'],
        ['MATERIAL:AIRGAP', 'Xenon'],
    ]
    lastobject = idf.idfobjects[objtype][-1]
    idf.removeidfobject(lastobject)
    assert idf.model.dt[objtype] == [
        ['MATERIAL:AIRGAP', 'Argon'],
    ]
    # copyidfobject
    onlyobject = idf.idfobjects[objtype][0]
    idf.copyidfobject(onlyobject)

    assert idf.model.dt[objtype] == [
        ['MATERIAL:AIRGAP', 'Argon'],
        ['MATERIAL:AIRGAP', 'Argon'],
    ]
    # test some functions
    objtype = 'FENESTRATIONSURFACE:DETAILED'
    obj = idf.newidfobject(objtype, Name='A Wall')
    assert obj.coords == []
    assert obj.fieldvalues[1] == 'A Wall'

    # test defaultvalues=True and defaultvalues=False
    sim_deftrue = idf.newidfobject('SimulationControl'.upper(),
                                   defaultvalues=True)
    assert sim_deftrue.Do_Zone_Sizing_Calculation == 'No'
    sim_deffalse = idf.newidfobject('SimulationControl'.upper(),
                                    defaultvalues=False)
    assert sim_deffalse.Do_Zone_Sizing_Calculation == ''
Example #4
0
def test_newidfobject():
    """py.test for newidfobject"""
    # make a blank idf
    # make a function for this and then continue.
    idf = IDF()
    idf.new()
    objtype = 'material:airgap'.upper()
    obj = idf.newidfobject(objtype, Name='Argon')
    obj = idf.newidfobject(objtype, Name='Krypton')
    obj = idf.newidfobject(objtype, Name='Xenon')
    assert idf.model.dt[objtype] == [['MATERIAL:AIRGAP', 'Argon'],
                                     ['MATERIAL:AIRGAP', 'Krypton'],
                                     ['MATERIAL:AIRGAP', 'Xenon'],
                                     ]
    # remove an object
    idf.popidfobject(objtype, 1)
    assert idf.model.dt[objtype] == [['MATERIAL:AIRGAP', 'Argon'],
                                     ['MATERIAL:AIRGAP', 'Xenon'],
                                     ]
    lastobject = idf.idfobjects[objtype][-1]
    idf.removeidfobject(lastobject)
    assert idf.model.dt[objtype] == [['MATERIAL:AIRGAP', 'Argon'], ]
    # copyidfobject
    onlyobject = idf.idfobjects[objtype][0]
    idf.copyidfobject(onlyobject)

    assert idf.model.dt[objtype] == [['MATERIAL:AIRGAP', 'Argon'],
                                     ['MATERIAL:AIRGAP', 'Argon'],
                                     ]
    # test some functions
    objtype = 'FENESTRATIONSURFACE:DETAILED'
    obj = idf.newidfobject(objtype, Name='A Wall')
    assert obj.coords == []
    assert obj.fieldvalues[1] == 'A Wall'
    
    # test defaultvalues=True and defaultvalues=False
    sim_deftrue = idf.newidfobject('SimulationControl'.upper(), defaultvalues=True)
    assert sim_deftrue.Do_Zone_Sizing_Calculation == 'No'
    sim_deffalse = idf.newidfobject('SimulationControl'.upper(), defaultvalues=False)
    assert sim_deffalse.Do_Zone_Sizing_Calculation == ''
Example #5
0
def test_newidfobject():
    """py.test for newidfobject"""
    # make a blank idf
    # make a function for this and then continue.
    idf = IDF()
    idf.new()
    objtype = 'material:airgap'.upper()
    obj = idf.newidfobject(objtype, Name='Argon')
    obj = idf.newidfobject(objtype, Name='Krypton')
    obj = idf.newidfobject(objtype, Name='Xenon')
    assert idf.model.dt[objtype] == [
        ['MATERIAL:AIRGAP', 'Argon'],
        ['MATERIAL:AIRGAP', 'Krypton'],
        ['MATERIAL:AIRGAP', 'Xenon'],
    ]
    # remove an object
    idf.popidfobject(objtype, 1)
    assert idf.model.dt[objtype] == [
        ['MATERIAL:AIRGAP', 'Argon'],
        ['MATERIAL:AIRGAP', 'Xenon'],
    ]
    lastobject = idf.idfobjects[objtype][-1]
    idf.removeidfobject(lastobject)
    assert idf.model.dt[objtype] == [
        ['MATERIAL:AIRGAP', 'Argon'],
    ]
    # copyidfobject
    onlyobject = idf.idfobjects[objtype][0]
    idf.copyidfobject(onlyobject)

    assert idf.model.dt[objtype] == [
        ['MATERIAL:AIRGAP', 'Argon'],
        ['MATERIAL:AIRGAP', 'Argon'],
    ]
    # test some functions
    objtype = 'FENESTRATIONSURFACE:DETAILED'
    obj = idf.newidfobject(objtype, Name='A Wall')
    assert obj.coords == []
    assert obj.fieldvalues[1] == 'A Wall'
Example #6
0
materials[-1].Conductivity = 0.16
materials[-1].Density = 600
materials[-1].Specific_Heat = 1500

# <codecell>

print(materials[-1])

# <headingcell level=4>

# Copy an existing material

# <codecell>

Peanutbuttermaterial = materials[-1]
idf1.copyidfobject(Peanutbuttermaterial)
materials = idf1.idfobjects["MATERIAL"]
len(materials)
materials[-1]

# <headingcell level=2>

# Python lesson 3: indentation and looping through lists

# <markdowncell>

# I'm tired of doing all this work, it's time to make python do some heavy lifting for us!

# <markdowncell>

# Python can go through each item in a list and perform an operation on any (or every) item in the list.
Example #7
0
def delete_cmplx_HVAC_keep_DHW(originalidf_path,savefolder_path):
    """
    An advanced automatic version of the delete_cmplx_HVAC() in version 1.0.
    Now it is possible to seperate DHW and HVAC systems without manual intervention
    The only requirement is that DHW elements should have an identifier, or common string throughout.
    This could be "DHW" or "SHW" or any other string portion that is used repeatedly in all DHW objects.

    Run Order:
    1) Identify HVAC keys in IDF
    2) Getting objects from the HVAC keys
    3) Searching for DHW objects
    4) Deleting all HVAC keys
    5) Recreating DHW objects and defining into the IDF

    :param originalidf_path: Path for the original IDF with a complex HVAC data
    :param savefolder_path: Path to use where all converted files will be saved
    :return:
    """

    # Backup
    originalidf = IDF(originalidf_path)
    building=originalidf.idfobjects["Building".upper()][0].Name
    originalidf.saveas(f"{savefolder_path}\\{building}_BuildME_interim.idf")
    idf=IDF(f"{savefolder_path}\\{building}_BuildME_interim.idf")

    name=input(colored(0, 255, 255, "Please enter str value for the common DHW naming used in your IDF file:"))

    # Lets find out all available keys in the IDF file
    allkeys = idfobjectkeys(idf)

    # Getting all possible HVAC-related keys by filtering...
    HVAC_related_list= allkeys[allkeys.index('HVACTEMPLATE:THERMOSTAT'):]
    HVAC_related_list = HVAC_related_list[:HVAC_related_list.index('MATRIX:TWODIMENSION')]

    findDHWlist=HVAC_related_list

    # Gathering all objects individually in our HVAC list and creating a homogenous list
    list=[]
    for items in findDHWlist:
        HVACobjects=idf.idfobjects[items.upper()]
        for obj in HVACobjects:
            list.append(obj)

    # Finding all DHW fields and their corresponding overarching objects
    objectswithDHW = []
    allparameterfields=[]
    for newobj in list:
        for fields in newobj.fieldnames:
            if newobj[fields]!="":
                if type(newobj[fields])==str:
                    if name in newobj[fields]:
                        allparameterfields.append(newobj[fields])
                        objectswithDHW.append(newobj)

    # Deleting all HVAC and DHW objects in our filtered list
    for HVAC_obj in HVAC_related_list:
        idf.removeallidfobjects(HVAC_obj)
    # Recreating DHW elements
    objectswithDHW_reduced=reduce(lambda l, x: l.append(x) or l if x not in l else l, objectswithDHW, [])
    for newobjects in objectswithDHW_reduced:
        idf.copyidfobject(newobjects)

    idf.saveas(f"{savefolder_path}\\{building}_BuildME_cleaned.idf")
    editedidf=idf

    return editedidf
def createnurbsshading(idd_filename, idf_filename, base_surface, shading_str, ctrl_points, evaluated_points=20):
    ##########################################
    # loading base surface data from idf file 
    ##########################################
    
    # check if IDD has been already set
    try:
        IDF.setiddname(idd_filename)
    except modeleditor.IDDAlreadySetError as e:
        pass

    # load idf file into idf collection
    idf_collection = IDF(idf_filename)

    # find the named base_surface in idf collection
    walls = idf_collection.idfobjects['BuildingSurface:Detailed'.upper()]
    for wall in walls:
        if wall.Name == base_surface:
            # named base_surface is now contained in wall
            break
    else:
        # named base_surface was not found in idf file
        print('epnurbs.createshading: unable to find the base surface', base_surface, 'in', idf_filename)
        return

    #################################
    # calculating NURBS curve points
    #################################
    from geomdl import NURBS
    from geomdl import utilities

    curve = NURBS.Curve()

    # 1/delta corresponds to the number of trapezoids used in approximation of NURBS shading
    curve.delta = 1/evaluated_points
    curve.degree = 3

    # add weight 1 to each control point
    # unless it has been already weighted
    for cpt in ctrl_points:
        if len(cpt)<4:
            cpt.append(1.0)

    # sets curve control points
    curve.set_ctrlpts(ctrl_points)

    # sets curve knot vector
    curve.knotvector = utilities.generate_knot_vector(curve.degree, len(curve.ctrlpts))

    # evaluates curve points
    curve.evaluate()

    # make a local copy of evaluated curve points
    crv_points = curve.curvepts

    ###################################################################################
    # feet of perpendiculars from the remaining NURBS curve points to the base surface
    ###################################################################################

    # getting the found base_surface's coordinates
    coord = wall.coords
    ulc = coord[0]
    blc = coord[1]
    brc = coord[2]

    # find the base_surface's plane normal and normalize it
    N = crossproduct( (blc[0]-ulc[0], blc[1]-ulc[1], blc[2]-ulc[2]), \
                      (brc[0]-ulc[0], brc[1]-ulc[1], brc[2]-ulc[2]) )
    N = normalize(N)

    # calculate feet of perpendiculars
    feet_points = [foot(crv_points[i], ulc, N) for i in range(len(crv_points))]

    #################################################################################
    # create string of idf definitions for trapezoids that approximate NURBS shading
    #################################################################################
    idf_total_shading_def = ""
    for i in range(1, len(crv_points)):
        # the width of a trapezoid must be at least 0.01
        if distance(crv_points[i-1], crv_points[i])>=0.01 and \
           distance(feet_points[i-1], feet_points[i])>=0.01:
            # are trapezoid arms at least 0.01 or do we have a triangle?
            if distance(crv_points[i-1], feet_points[i-1])>=0.01:
                if distance(crv_points[i], feet_points[i])>=0.01:
                    # both arms are at least 0.01, so we have a trapezoid
                    vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                   feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2],
                                   crv_points[i-1][0],  crv_points[i-1][1],  crv_points[i-1][2],
                                   crv_points[i][0],    crv_points[i][1],    crv_points[i][2],
                                   feet_points[i][0],   feet_points[i][1],   feet_points[i][2])
                    countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                          feet_points[i][0],   feet_points[i][1],   feet_points[i][2],
                                          crv_points[i][0],    crv_points[i][1],    crv_points[i][2],
                                          crv_points[i-1][0],  crv_points[i-1][1],  crv_points[i-1][2],
                                          feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2])
                    single_shading_def = shading_str.replace('<IDX>', str(i)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vertices_str).replace('<COUNTERVERTICES>', countervertices_str)
                    idf_total_shading_def = idf_total_shading_def + single_shading_def
                else: 
                    # arm i is less than 0.01, so we have a triangle
                    vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                   feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2],
                                   crv_points[i-1][0],  crv_points[i-1][1],  crv_points[i-1][2],
                                   feet_points[i][0],   feet_points[i][1],   feet_points[i][2])
                    countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                          feet_points[i][0],   feet_points[i][1],   feet_points[i][2], 
                                          crv_points[i-1][0],  crv_points[i-1][1],  crv_points[i-1][2],
                                          feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2])               
                    single_shading_def = shading_str.replace('<IDX>', str(i)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vertices_str).replace('<COUNTERVERTICES>', countervertices_str)
                    idf_total_shading_def = idf_total_shading_def + single_shading_def
            else:
                # arm i-1 is less than 0.01, but do we still have a triangle?
                if distance(crv_points[i], feet_points[i])>=0.01:
                    # we have a triangle
                    vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                   feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2],
                                   crv_points[i][0],    crv_points[i][1],    crv_points[i][2],
                                   feet_points[i][0],   feet_points[i][1],   feet_points[i][2])
                    countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                          feet_points[i][0],   feet_points[i][1],   feet_points[i][2],
                                          crv_points[i][0],    crv_points[i][1],    crv_points[i][2],
                                          feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2])              
                    single_shading_def = shading_str.replace('<IDX>', str(i)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vertices_str).replace('<COUNTERVERTICES>', countervertices_str)
                    idf_total_shading_def = idf_total_shading_def + single_shading_def
                else:
                    # we do not have a shading element in this case
                    pass
    
    # create idf shading objects from the string containing shading definitions   
    from io import StringIO
    idf_shading = IDF(StringIO(idf_total_shading_def))

    # copy idf shading objects to the existing idf file
    shadings = idf_shading.idfobjects["SHADING:ZONE:DETAILED"]
    for shading in shadings:
        idf_collection.copyidfobject(shading)

    ###############################
    # at the end, save the changes
    ###############################
    idf_collection.save()
Example #9
0
def GeoGen(sheet):
    num_of_zones = sheet.Range("A7").Value
    construction_template = sheet.Range("AN7").Value

    #Initialize a blank idf file
    ts = time.time()
    #st = datetime.datetime.fromtimestamp(ts).strftime('%Y%m%d %H%M%S')
    st = datetime.datetime.fromtimestamp(ts).strftime('%Y%m%d-%H%M')
    blankstr = ""
    new_idf = IDF(StringIO(blankstr))
    new_idf.idfname = "NongeoXport " + st + ".idf"

    #Import Constructoin Templates
    const_fname = "ahshrae901_construction_templates.idf"
    my_const = IDF(const_fname)

    #Copy All Construction Templates into New idf file
    materials = my_const.idfobjects['material'.upper()]
    for i in range(len(materials)):
        new_idf.copyidfobject(materials[i])

    materials_nomass = my_const.idfobjects['material:nomass'.upper()]
    for i in range(len(materials_nomass)):
        new_idf.copyidfobject(materials_nomass[i])

    materials_airgap = my_const.idfobjects['material:airgap'.upper()]
    for i in range(len(materials_airgap)):
        new_idf.copyidfobject(materials_airgap[i])

    window_materials_sgs = my_const.idfobjects[
        'windowmaterial:simpleglazingsystem'.upper()]
    for i in range(len(window_materials_sgs)):
        new_idf.copyidfobject(window_materials_sgs[i])

    window_materials_glz = my_const.idfobjects[
        'windowmaterial:glazing'.upper()]
    for i in range(len(window_materials_glz)):
        new_idf.copyidfobject(window_materials_glz[i])

    constructions = my_const.idfobjects['construction'.upper()]
    for i in range(len(constructions)):
        new_idf.copyidfobject(constructions[i])

    #Assign Surface Construction Names Based on User Templates Selections
    interior_floor_const = "Interior Floor"
    interior_wall_const = "Interior Wall"
    interior_ceiling_const = "Interior Ceiling"
    exterior_floor_const = "ExtSlabCarpet 4in ClimateZone 1-8"
    if construction_template == "ASHRAE 90.1 2010 Climate Zone 1":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 1"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 1"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 1"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 2":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 2"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 2"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 3":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 3"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 3"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 4":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 4"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 4-6"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 5":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 5"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 4-6"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 6":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 6"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 4-6"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 7":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 7-8"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 7-8"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 8":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 7-8"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 7-8"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    ####Start Writing idf Objects
    ##General idf Objects for IDFXporter

    #Define Version Objects
    version = new_idf.newidfobject("version".upper())
    version.Version_Identifier = 8.5

    #Define Simulation Control Objects
    simctrl = new_idf.newidfobject("simulationcontrol".upper())
    simctrl.Do_Zone_Sizing_Calculation = "Yes"
    simctrl.Do_System_Sizing_Calculation = "Yes"
    simctrl.Do_Plant_Sizing_Calculation = "Yes"
    simctrl.Run_Simulation_for_Sizing_Periods = "No"
    simctrl.Run_Simulation_for_Weather_File_Run_Periods = "Yes"

    #Define Building Object
    building = new_idf.newidfobject("building".upper())
    building.Name = "My Building"
    building.North_Axis = 0

    #Define Run Periods Object
    run_period = new_idf.newidfobject("runperiod".upper())
    run_period.Name = "Run Period 1"
    run_period.Begin_Month = 1
    run_period.Begin_Day_of_Month = 1
    run_period.End_Month = 12
    run_period.End_Day_of_Month = 31
    run_period.Day_of_Week_for_Start_Day = "Thursday"
    run_period.Use_Weather_File_Rain_Indicators = "Yes"
    run_period.Use_Weather_File_Snow_Indicators = "Yes"

    #Define Schedule Type Limits Objects
    sch_tp_limit_1 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_1.Name = "Any Number"
    sch_tp_limit_2 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_2.Name = "Fraction"
    sch_tp_limit_3 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_3.Name = "Temperature"
    sch_tp_limit_4 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_4.Name = "On/Off"
    sch_tp_limit_5 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_5.Name = "Control Type"
    sch_tp_limit_6 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_6.Name = "Humidity"
    sch_tp_limit_7 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_7.Name = "Number"

    ##Additional idf Objects from Params

    #Define Shadow Calculation Objects
    shadow_calc = new_idf.newidfobject("shadowcalculation".upper())
    shadow_calc.Calculation_Method = "AverageOverDaysInFrequency"

    #Define SurfaceConvectionAlgorithm:Inside Objects
    surf_conv_algorithm_in = new_idf.newidfobject(
        "SurfaceConvectionAlgorithm:Inside".upper())
    surf_conv_algorithm_in.Algorithm = "TARP"

    #Define SurfaceConvectionAlgorithm:Outside Objects
    surf_conv_algorithm_out = new_idf.newidfobject(
        "SurfaceConvectionAlgorithm:Outside".upper())
    surf_conv_algorithm_out.Algorithm = "DOE-2"

    #Define HeatBalanceAlgorithm Objects
    hb_algorithm = new_idf.newidfobject("HeatBalanceAlgorithm".upper())
    hb_algorithm.Algorithm = "ConductionTransferFunction"

    #Define SurfaceProperty:OtherSideConditionsModel Objects
    surf_prop_oscm = new_idf.newidfobject(
        "SurfaceProperty:OtherSideConditionsModel".upper())
    surf_prop_oscm.Name = "GapConvectionModel"

    #Define ConvergenceLimits Objects
    conv_limits = new_idf.newidfobject("ConvergenceLimits".upper())
    conv_limits.Minimum_System_Timestep = 0

    #Define Global Geometry Rules Objects
    rule = new_idf.newidfobject("globalgeometryrules".upper())
    rule.Starting_Vertex_Position = "UpperLeftCorner"
    rule.Vertex_Entry_Direction = "Counterclockwise"
    rule.Coordinate_System = "Relative"
    rule.Daylighting_Reference_Point_Coordinate_System = "Relative"
    rule.Rectangular_Surface_Coordinate_System = "Relative"

    #Define SizingParameters Objects
    szparams = new_idf.newidfobject("sizing:parameters".upper())
    szparams.Heating_Sizing_Factor = 1.25
    szparams.Cooling_Sizing_Factor = 1.15

    ####Non-Geometric Generator Starts

    for id in range(7, int(7 + num_of_zones)):
        zone_name = sheet.Range("B" + str(id)).Value
        #        zone_name = "Thermal Zone: " + zone_name
        #        zone_name = zone_name
        zone_origin_x = sheet.Range("C" + str(id)).Value
        zone_origin_y = sheet.Range("D" + str(id)).Value
        zone_origin_z = sheet.Range("E" + str(id)).Value
        #        prmtr_or_not =  sheet.Range("F"+str(id)).Value
        roof_or_not = sheet.Range("M" + str(id)).Value
        zone_height = sheet.Range("H" + str(id)).Value
        zone_length = sheet.Range("I" + str(id)).Value
        zone_width = sheet.Range("G" +
                                 str(id)).Value / sheet.Range("I" +
                                                              str(id)).Value
        prmtr1_normal = sheet.Range("K" + str(id)).Value
        prmtr2_normal = sheet.Range("L" + str(id)).Value
        grndflr_or_not = sheet.Range("N" + str(id)).Value
        wind2wall_ratio = sheet.Range("O" + str(id)).Value
        wind_sill_height = sheet.Range("P" + str(id)).Value

        #Define Zone Objects
        zone = new_idf.newidfobject("zone".upper())
        zone.Name = zone_name
        zone.X_Origin = zone_origin_x
        zone.Y_Origin = zone_origin_y
        zone.Z_Origin = zone_origin_z
        zone.Ceiling_Height = zone_height

        #Define BuildingSurface:Detailed Objects, default as adiabatic, and interior constructions
        surface_1 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_1.Name = zone_name + " Surface 1"
        surface_1.Surface_Type = "Floor"
        surface_1.Construction_Name = interior_floor_const
        surface_1.Zone_Name = zone_name
        surface_1.Outside_Boundary_Condition = "Adiabatic"
        surface_1.Sun_Exposure = "NoSun"
        surface_1.Wind_Exposure = "NoWind"
        surface_1.Vertex_1_Xcoordinate = zone_length
        surface_1.Vertex_1_Ycoordinate = zone_width
        surface_1.Vertex_1_Zcoordinate = 0
        surface_1.Vertex_2_Xcoordinate = zone_length
        surface_1.Vertex_2_Ycoordinate = 0
        surface_1.Vertex_2_Zcoordinate = 0
        surface_1.Vertex_3_Xcoordinate = 0
        surface_1.Vertex_3_Ycoordinate = 0
        surface_1.Vertex_3_Zcoordinate = 0
        surface_1.Vertex_4_Xcoordinate = 0
        surface_1.Vertex_4_Ycoordinate = zone_width
        surface_1.Vertex_4_Zcoordinate = 0

        surface_2 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_2.Name = zone_name + " Surface 2"
        surface_2.Surface_Type = "Wall"
        surface_2.Construction_Name = interior_wall_const
        surface_2.Zone_Name = zone_name
        surface_2.Outside_Boundary_Condition = "Adiabatic"
        surface_2.Sun_Exposure = "NoSun"
        surface_2.Wind_Exposure = "NoWind"
        surface_2.Vertex_1_Xcoordinate = 0
        surface_2.Vertex_1_Ycoordinate = zone_width
        surface_2.Vertex_1_Zcoordinate = zone_height
        surface_2.Vertex_2_Xcoordinate = 0
        surface_2.Vertex_2_Ycoordinate = zone_width
        surface_2.Vertex_2_Zcoordinate = 0
        surface_2.Vertex_3_Xcoordinate = 0
        surface_2.Vertex_3_Ycoordinate = 0
        surface_2.Vertex_3_Zcoordinate = 0
        surface_2.Vertex_4_Xcoordinate = 0
        surface_2.Vertex_4_Ycoordinate = 0
        surface_2.Vertex_4_Zcoordinate = zone_height

        surface_3 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_3.Name = zone_name + " Surface 3"
        surface_3.Surface_Type = "Wall"
        surface_3.Construction_Name = interior_wall_const
        surface_3.Zone_Name = zone_name
        surface_3.Outside_Boundary_Condition = "Adiabatic"
        surface_3.Sun_Exposure = "NoSun"
        surface_3.Wind_Exposure = "NoWind"
        surface_3.Vertex_1_Xcoordinate = zone_length
        surface_3.Vertex_1_Ycoordinate = zone_width
        surface_3.Vertex_1_Zcoordinate = zone_height
        surface_3.Vertex_2_Xcoordinate = zone_length
        surface_3.Vertex_2_Ycoordinate = zone_width
        surface_3.Vertex_2_Zcoordinate = 0
        surface_3.Vertex_3_Xcoordinate = 0
        surface_3.Vertex_3_Ycoordinate = zone_width
        surface_3.Vertex_3_Zcoordinate = 0
        surface_3.Vertex_4_Xcoordinate = 0
        surface_3.Vertex_4_Ycoordinate = zone_width
        surface_3.Vertex_4_Zcoordinate = zone_height

        surface_4 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_4.Name = zone_name + " Surface 4"
        surface_4.Surface_Type = "Wall"
        surface_4.Construction_Name = interior_wall_const
        surface_4.Zone_Name = zone_name
        surface_4.Outside_Boundary_Condition = "Adiabatic"
        surface_4.Sun_Exposure = "NoSun"
        surface_4.Wind_Exposure = "NoWind"
        surface_4.Vertex_1_Xcoordinate = zone_length
        surface_4.Vertex_1_Ycoordinate = 0
        surface_4.Vertex_1_Zcoordinate = zone_height
        surface_4.Vertex_2_Xcoordinate = zone_length
        surface_4.Vertex_2_Ycoordinate = 0
        surface_4.Vertex_2_Zcoordinate = 0
        surface_4.Vertex_3_Xcoordinate = zone_length
        surface_4.Vertex_3_Ycoordinate = zone_width
        surface_4.Vertex_3_Zcoordinate = 0
        surface_4.Vertex_4_Xcoordinate = zone_length
        surface_4.Vertex_4_Ycoordinate = zone_width
        surface_4.Vertex_4_Zcoordinate = zone_height

        surface_5 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_5.Name = zone_name + " Surface 5"
        surface_5.Surface_Type = "Wall"
        surface_5.Construction_Name = interior_wall_const
        surface_5.Zone_Name = zone_name
        surface_5.Outside_Boundary_Condition = "Adiabatic"
        surface_5.Sun_Exposure = "NoSun"
        surface_5.Wind_Exposure = "NoWind"
        surface_5.Vertex_1_Xcoordinate = 0
        surface_5.Vertex_1_Ycoordinate = 0
        surface_5.Vertex_1_Zcoordinate = zone_height
        surface_5.Vertex_2_Xcoordinate = 0
        surface_5.Vertex_2_Ycoordinate = 0
        surface_5.Vertex_2_Zcoordinate = 0
        surface_5.Vertex_3_Xcoordinate = zone_length
        surface_5.Vertex_3_Ycoordinate = 0
        surface_5.Vertex_3_Zcoordinate = 0
        surface_5.Vertex_4_Xcoordinate = zone_length
        surface_5.Vertex_4_Ycoordinate = 0
        surface_5.Vertex_4_Zcoordinate = zone_height

        surface_6 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_6.Name = zone_name + " Surface 6"
        surface_6.Zone_Name = zone_name
        surface_6.Vertex_1_Xcoordinate = zone_length
        surface_6.Vertex_1_Ycoordinate = 0
        surface_6.Vertex_1_Zcoordinate = zone_height
        surface_6.Vertex_2_Xcoordinate = zone_length
        surface_6.Vertex_2_Ycoordinate = zone_width
        surface_6.Vertex_2_Zcoordinate = zone_height
        surface_6.Vertex_3_Xcoordinate = 0
        surface_6.Vertex_3_Ycoordinate = zone_width
        surface_6.Vertex_3_Zcoordinate = zone_height
        surface_6.Vertex_4_Xcoordinate = 0
        surface_6.Vertex_4_Ycoordinate = 0
        surface_6.Vertex_4_Zcoordinate = zone_height

        #Change Surface Type if Roof
        if roof_or_not == "y":
            surface_6.Surface_Type = "Roof"
            surface_6.Construction_Name = exterior_roof_const
            surface_6.Outside_Boundary_Condition = "Outdoors"
            surface_6.Sun_Exposure = "SunExposed"
            surface_6.Wind_Exposure = "WindExposed"
        else:
            surface_6.Surface_Type = "Ceiling"
            surface_6.Construction_Name = interior_ceiling_const
            surface_6.Outside_Boundary_Condition = "Adiabatic"
            surface_6.Sun_Exposure = "NoSun"
            surface_6.Wind_Exposure = "NoWind"

        #Change Surface Type if Ground Floor
        if grndflr_or_not == "y":
            surface_1.Construction_Name = exterior_floor_const
            surface_1.Outside_Boundary_Condition = "Ground"
        else:
            pass

        #Change Surface Type if Perimeter 1 Normal is non-zero
        if prmtr1_normal == 0:
            surface_3.Construction_Name = exterior_wall_const
            surface_3.Outside_Boundary_Condition = "Outdoors"
            surface_3.Sun_Exposure = "SunExposed"
            surface_3.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 3"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_3.Name
                sub_surface.Vertex_1_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_1_Ycoordinate = zone_width
                sub_surface.Vertex_1_Zcoordinate = zone_length * zone_height * wind2wall_ratio / (
                    zone_length - 0.0254 * 2) + wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_2_Ycoordinate = zone_width
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = 0.0254
                sub_surface.Vertex_3_Ycoordinate = zone_width
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = 0.0254
                sub_surface.Vertex_4_Ycoordinate = zone_width
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr1_normal == 90:
            surface_4.Construction_Name = exterior_wall_const
            surface_4.Outside_Boundary_Condition = "Outdoors"
            surface_4.Sun_Exposure = "SunExposed"
            surface_4.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 4"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_4.Name
                sub_surface.Vertex_1_Xcoordinate = zone_length
                sub_surface.Vertex_1_Ycoordinate = 0.0254
                sub_surface.Vertex_1_Zcoordinate = zone_width * zone_height * wind2wall_ratio / (
                    zone_width - 0.0254 * 2) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = zone_length
                sub_surface.Vertex_2_Ycoordinate = 0.0254
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = zone_length
                sub_surface.Vertex_3_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = zone_length
                sub_surface.Vertex_4_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr1_normal == 180:
            surface_5.Construction_Name = exterior_wall_const
            surface_5.Outside_Boundary_Condition = "Outdoors"
            surface_5.Sun_Exposure = "SunExposed"
            surface_5.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 5"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_5.Name
                sub_surface.Vertex_1_Xcoordinate = 0.0254
                sub_surface.Vertex_1_Ycoordinate = 0
                sub_surface.Vertex_1_Zcoordinate = zone_length * zone_height * wind2wall_ratio / (
                    zone_length - 0.0254 * 2) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = 0.0254
                sub_surface.Vertex_2_Ycoordinate = 0
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_3_Ycoordinate = 0
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_4_Ycoordinate = 0
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr1_normal == 270:
            surface_2.Construction_Name = exterior_wall_const
            surface_2.Outside_Boundary_Condition = "Outdoors"
            surface_2.Sun_Exposure = "SunExposed"
            surface_2.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 2"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_2.Name
                sub_surface.Vertex_1_Xcoordinate = 0
                sub_surface.Vertex_1_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_1_Zcoordinate = zone_width * zone_height * wind2wall_ratio / (
                    zone_width - 2 * 0.0254) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = 0
                sub_surface.Vertex_2_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = 0
                sub_surface.Vertex_3_Ycoordinate = 0.0254
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = 0
                sub_surface.Vertex_4_Ycoordinate = 0.0254
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        else:
            pass

        #Change Surface Type if Perimeter 2 Normal is non-zero

        if prmtr2_normal == 0:
            surface_3.Construction_Name = exterior_wall_const
            surface_3.Outside_Boundary_Condition = "Outdoors"
            surface_3.Sun_Exposure = "SunExposed"
            surface_3.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 3"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_3.Name
                sub_surface.Vertex_1_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_1_Ycoordinate = zone_width
                sub_surface.Vertex_1_Zcoordinate = zone_length * zone_height * wind2wall_ratio / (
                    zone_length - 0.0254 * 2) + wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_2_Ycoordinate = zone_width
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = 0.0254
                sub_surface.Vertex_3_Ycoordinate = zone_width
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = 0.0254
                sub_surface.Vertex_4_Ycoordinate = zone_width
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr2_normal == 90:
            surface_4.Construction_Name = exterior_wall_const
            surface_4.Outside_Boundary_Condition = "Outdoors"
            surface_4.Sun_Exposure = "SunExposed"
            surface_4.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 4"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_4.Name
                sub_surface.Vertex_1_Xcoordinate = zone_length
                sub_surface.Vertex_1_Ycoordinate = 0.0254
                sub_surface.Vertex_1_Zcoordinate = zone_width * zone_height * wind2wall_ratio / (
                    zone_width - 0.0254 * 2) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = zone_length
                sub_surface.Vertex_2_Ycoordinate = 0.0254
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = zone_length
                sub_surface.Vertex_3_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = zone_length
                sub_surface.Vertex_4_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr2_normal == 180:
            surface_5.Construction_Name = exterior_wall_const
            surface_5.Outside_Boundary_Condition = "Outdoors"
            surface_5.Sun_Exposure = "SunExposed"
            surface_5.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 5"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_5.Name
                sub_surface.Vertex_1_Xcoordinate = 0.0254
                sub_surface.Vertex_1_Ycoordinate = 0
                sub_surface.Vertex_1_Zcoordinate = zone_length * zone_height * wind2wall_ratio / (
                    zone_length - 0.0254 * 2) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = 0.0254
                sub_surface.Vertex_2_Ycoordinate = 0
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_3_Ycoordinate = 0
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_4_Ycoordinate = 0
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr2_normal == 270:
            surface_2.Construction_Name = exterior_wall_const
            surface_2.Outside_Boundary_Condition = "Outdoors"
            surface_2.Sun_Exposure = "SunExposed"
            surface_2.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 2"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_2.Name
                sub_surface.Vertex_1_Xcoordinate = 0
                sub_surface.Vertex_1_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_1_Zcoordinate = zone_width * zone_height * wind2wall_ratio / (
                    zone_width - 2 * 0.0254) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = 0
                sub_surface.Vertex_2_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = 0
                sub_surface.Vertex_3_Ycoordinate = 0.0254
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = 0
                sub_surface.Vertex_4_Ycoordinate = 0.0254
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        else:
            pass

    new_idf.save()
    this_idf = new_idf.idfname
    #    dir_path = os.path.dirname(os.path.realpath(this_idf))
    #
    #    os.chdir('..')
    #    shutil.copy2(dir_path, '/templates/)
    # complete target filename given
    #    shutil.copy2('/src/file.ext', '/dst/dir') # target filename is /dst/dir/file.ext
    pre, ext = os.path.splitext(this_idf)
    os.rename(this_idf, pre + ".pxt")
Example #10
0
def convert_idf_to_BuildME(idf_path,
                           save_folder_path,
                           replace_string="-en-std-replaceme",
                           replace_string_value="-non-standard",
                           base=False):
    """
    This function creates an individual edited IDF file that is compatible with BuildME framework

    Requirements for a clear run:
    1)Window-Skylight Difference should be addressed in construction name (e.g. name contains "sky")

    Run Order:
    -Adds replaceme fields,
    -Renames Materials,
    -Renames Constructions,
    -Defines non-standard U values; if replace_string_value is set accordingly.

    :param idf_path: path for idf file to be converted, standard file should be used forthe non-standard IDF creation
    :param save_folder_path: New location folder path, where the new IDF will be saved
    :param replace_string: Replaceme content (i.e., -en-std-replaceme-res-replacemem-chrt-replaceme), should start with "-"
    :param replace_string_value: Replacer string corresponding to the replace string (i.e., -standard-RES0-1920), should start with "-"
    :param base: Boolean value to declare whether the IDF file corresponding to a base IDF
    :return: A compatible file with BuildME for an IDF with specific features
    """

    idf1 = IDF(idf_path)
    print(
        "Conversion is initialized, construction and surface objects are being converted..."
    )
    # CONVERTING CONSTRUCTION NAMES AND INSERTING REPLACEME STRINGS:
    # It inserts a replaceme string to the building surface object's construction field, adds a new identical construction to the construction object
    # and renames the construction name corresponding to the replaceme string
    for items in idf1.idfobjects["BuildingSurface:Detailed".upper()]:
        for obj in idf1.idfobjects["Construction".upper()]:
            if obj.Name == items.Construction_Name:

                if items.Surface_Type == "Roof":
                    items.Construction_Name = f"ext-roof{replace_string}"
                    newcons = idf1.copyidfobject(obj)
                    newcons.Name = f"ext-roof{replace_string_value}"

                if items.Surface_Type == "Ceiling":
                    if "int" or "ceiling" in items.Construction_Name:
                        items.Construction_Name = f"int-ceiling{replace_string}"
                        newcons = idf1.copyidfobject(obj)
                        newcons.Name = f"int-ceiling{replace_string_value}"

                if items.Surface_Type == "Floor":
                    if items.Outside_Boundary_Condition == "Surface":
                        items.Construction_Name = f"int-floor{replace_string}"
                        newcons = idf1.copyidfobject(obj)
                        newcons.Name = f"int-floor{replace_string_value}"
                    if items.Outside_Boundary_Condition == "Adiabatic" or items.Outside_Boundary_Condition == "Ground" or items.Outside_Boundary_Condition == "Outdoors" or items.Outside_Boundary_Condition == "GroundSlabPreprocessorAverage":
                        items.Construction_Name = f"ext-floor{replace_string}"
                        newcons = idf1.copyidfobject(obj)
                        newcons.Name = f"ext-floor{replace_string_value}"

                if items.Surface_Type == "Wall":
                    if "int" in items.Construction_Name:
                        items.Construction_Name = f"int-wall{replace_string}"
                        newcons = idf1.copyidfobject(obj)
                        newcons.Name = f"int-wall{replace_string_value}"
                    else:
                        items.Construction_Name = f"ext-wall{replace_string}"
                        newcons = idf1.copyidfobject(obj)
                        newcons.Name = f"ext-wall{replace_string_value}"

        if 'CONSTRUCTION:FFACTORGROUNDFLOOR' in [x for x in idf1.idfobjects]:
            for floor in idf1.idfobjects[
                    "Construction:FfactorGroundFloor".upper()]:
                if floor.Name == items.Construction_Name:
                    if items.Surface_Type == "Floor":
                        if items.Outside_Boundary_Condition == "GroundFCfactorMethod":
                            items.Construction_Name = f"{items.Construction_Name}{replace_string}"
                            newcons = idf1.copyidfobject(floor)
                            newcons.Name = f"{floor.Name}{replace_string_value}"

        if 'CONSTRUCTION:CFACTORUNDERGROUNDWALL' in [
                x for x in idf1.idfobjects
        ]:
            for wall in idf1.idfobjects[
                    "Construction:CfactorUndergroundWall".upper()]:
                if wall.Name == items.Construction_Name:
                    if items.Surface_Type == "Wall":
                        if items.Outside_Boundary_Condition == "GroundFCfactorMethod" or items.Outside_Boundary_Condition == "Adiabatic":
                            items.Construction_Name = f"{items.Construction_Name}{replace_string}"
                            newcons = idf1.copyidfobject(wall)
                            newcons.Name = f"{wall.Name}{replace_string_value}"

    if 'WINDOW' in [x for x in idf1.idfobjects]:
        for fenest in idf1.idfobjects["Window".upper()]:
            fenest.Construction_Name = f"ext-window{replace_string}"

    if 'DOOR' in [x for x in idf1.idfobjects]:
        for fenest in idf1.idfobjects["Door".upper()]:
            fenest.Construction_Name = f"ext-door{replace_string}"

    if 'FENESTRATIONSURFACE:DETAILED' in [x for x in idf1.idfobjects]:
        for fenest in idf1.idfobjects["FenestrationSurface:Detailed".upper()]:
            for obj in idf1.idfobjects["Construction".upper()]:
                if fenest.Construction_Name == obj.Name:
                    if fenest.Surface_Type == "Window":
                        # there might be skylights:
                        if "sky" in fenest.Construction_Name:
                            fenest.Construction_Name = f"ext-skywindow{replace_string}"
                            newcons = idf1.copyidfobject(obj)
                            newcons.Name = f"ext-skywindow{replace_string_value}"
                        else:
                            fenest.Construction_Name = f"ext-window{replace_string}"
                            newcons = idf1.copyidfobject(obj)
                            newcons.Name = f"ext-window{replace_string_value}"
                    if fenest.Surface_Type == "GlassDoor":
                        fenest.Construction_Name = f"ext-window{replace_string}"
                        newcons = idf1.copyidfobject(obj)
                        newcons.Name = f"ext-window{replace_string_value}"
                    if fenest.Surface_Type == "Door":
                        fenest.Construction_Name = f"ext-door{replace_string}"
                        newcons = idf1.copyidfobject(obj)
                        newcons.Name = f"ext-door{replace_string_value}"

    # Deleting duplicated construction names
    unique = reduce(lambda l, x: l.append(x) or l if x not in l else l,
                    idf1.idfobjects["Construction".upper()], [])
    idf1.removeallidfobjects("CONSTRUCTION")
    for newcons in unique:
        idf1.copyidfobject(newcons)
    if 'CONSTRUCTION:FFACTORGROUNDFLOOR' in [x for x in idf1.idfobjects]:
        unique = reduce(
            lambda l, x: l.append(x) or l if x not in l else l,
            idf1.idfobjects["Construction:FfactorGroundFloor".upper()], [])
        idf1.removeallidfobjects("CONSTRUCTION:FFACTORGROUNDFLOOR")
    for newcons in unique:
        idf1.copyidfobject(newcons)
    if 'CONSTRUCTION:CFACTORUNDERGROUNDWALL' in [x for x in idf1.idfobjects]:
        unique = reduce(
            lambda l, x: l.append(x) or l if x not in l else l,
            idf1.idfobjects["Construction:CfactorUndergroundWall".upper()], [])
        idf1.removeallidfobjects("CONSTRUCTION:CFACTORUNDERGROUNDWALL")
    for newcons in unique:
        idf1.copyidfobject(newcons)

    print("Material objects are being converted...")
    # CONVERTING MATERIALS
    # For the -non-standard version, values are replaced with %30 worse performing numbers based on the standard/base version.
    if "-non-standard" in replace_string_value:
        for items in idf1.idfobjects["Material".upper()]:
            items.Conductivity = float(items.Conductivity) * 1.3
            items.Name = f"{items.Name}{replace_string_value}"
        for items in idf1.idfobjects["Material:NoMass".upper()]:
            items.Thermal_Resistance = float(items.Thermal_Resistance) * 0.7
            items.Name = f"{items.Name}{replace_string_value}"
        for items in idf1.idfobjects[
                "WindowMaterial:SimpleGlazingSystem".upper()]:
            items.UFactor = float(items.UFactor) * 1.3
            items.Name = f"{items.Name}{replace_string_value}"
        if 'CONSTRUCTION:FFACTORGROUNDFLOOR' in [x for x in idf1.idfobjects]:
            for items in idf1.idfobjects[
                    "Construction:FfactorGroundFloor".upper()]:
                items.FFactor = float(items.FFactor) * 0.7
        if 'CONSTRUCTION:CFACTORUNDERGROUNDWALL' in [
                x for x in idf1.idfobjects
        ]:
            for items in idf1.idfobjects[
                    "Construction:CfactorUndergroundWall".upper()]:
                items.CFactor = float(items.CFactor) * 1.3

    # Material names are changed as they represent different values across standards, some identifiers are added based on replacer_string.
    else:
        for items in idf1.idfobjects["Material".upper()]:
            items.Name = f"{items.Name}{replace_string_value}"
        for items in idf1.idfobjects["Material:NoMass".upper()]:
            items.Name = f"{items.Name}{replace_string_value}"
        for items in idf1.idfobjects[
                "WindowMaterial:SimpleGlazingSystem".upper()]:
            items.Name = f"{items.Name}{replace_string_value}"

    # Construction material layer names are matched with above material changes
    for items in idf1.idfobjects["Construction".upper()]:
        for fields in items.fieldnames:
            if fields == "key":
                continue
            if fields == "Name":
                continue
            else:
                if items[fields] == "":
                    continue
                else:
                    items[fields] = items[fields] + f"{replace_string_value}"

    # SAVING THE IDF FILE
    building = str(idf1.idfobjects["Building".upper()][0].Name)
    if base == True:
        idf1.idfobjects["Building".upper(
        )][0].Name = f"BASE{building}{replace_string_value}"
        idf1.saveas(
            f"{save_folder_path}/BASE{building}{replace_string_value}-converted.idf"
        )
    else:
        idf1.idfobjects[
            "Building".upper()][0].Name = f"{building}{replace_string_value}"
        idf1.saveas(
            f"{save_folder_path}/{building}{replace_string_value}-converted.idf"
        )
    print(
        f'{idf1.idfobjects["Building".upper()][0].Name} IDF file is converted and saved...'
    )
    return idf1
Example #11
0
# <headingcell level=3>

# Copying/Adding an idf object

# <markdowncell>

# Having deleted two "MATERIAL" objects, we have only one left. Let us make a copy of this object and add it to our idf file

# <codecell>

onlymaterial = idf.idfobjects["MATERIAL"][0]

# <codecell>

idf.copyidfobject(onlymaterial)

# <codecell>

print(idf.idfobjects["MATERIAL"])

# <markdowncell>

# So now we have a copy of the material. You can use this method to copy idf objects from other idf files too.

# <headingcell level=2>

# Making an idf object with named arguments

# <markdowncell>
Example #12
0
class Model:
    """
    The environment class.
    """
    model_import_flag = False

    @classmethod
    def set_energyplus_folder(cls, path):
        """
        Add the pyenergyplus into the path so the program can find the EnergyPlus.

        :parameter path: The installation path of the EnergyPlus 9.3.0.
        :type path: str

        :return: None
        """
        sys.path.insert(0, path)
        IDF.setiddname(f"{path}Energy+.idd")
        cls.model_import_flag = True

    def __init__(self,
                 idf_file_name: str = None,
                 prototype: str = None,
                 climate_zone: str = None,
                 weather_file: str = None,
                 heating_type: str = None,
                 foundation_type: str = None,
                 agent: Agent = None,
                 reward=None,
                 eplus_naming_dict=None,
                 eplus_var_types=None,
                 buffer_capacity=None,
                 buffer_seed=None,
                 buffer_chkpt_dir=None,
                 tmp_idf_path=None):
        """
        Initialize the building by loading the IDF file to the model.

        :parameter idf_file_name: The relative path to the IDF file. Use it if you want to use your own model.
        :parameter prototype: Either "multi" and "single", indicates the Multi-family low-rise apartment building and Single-family detached house.
        :parameter climate_zone: The climate zone code of the building. Please refer to https://codes.iccsafe.org/content/iecc2018/chapter-3-ce-general-requirements.
        :parameter weather_file: The relative path to the weather file associate with the building.
        :parameter heating_type: Select one from "electric", "gas", "oil", and "pump"
        :parameter foundation_type: Select one from "crawspace", "heated", "slab", and "unheated"
        :parameter agent: The user-defined Agent class object if the agent is implemented in a class.
        :parameter reward: The user-defined reward class object that contains a reward(state, actions) method.
        :parameter eplus_naming_dict: A dictionary map the state variable name to some specified names.
        :parameter eplus_var_types: A dictionary contains the state name and the state source location.
        :parameter buffer_capacity: The maximum number of historical state, action, new_state pair store in the buffer.
        :parameter buffer_seed: The random seed when sample from the buffer.
        :parameter buffer_chkpt_dir: The location of the buffer checkpoint should save.
        """
        if not Model.model_import_flag:
            raise ImportError("You have to set the energyplus folder first")
        self.api = None
        self.current_state = dict()
        self.idf = None
        self.occupancy = None
        self.run_parameters = None
        self.queue = EventQueue()
        self.agent = agent
        self.ignore_list = set()
        self.zone_names = None
        self.thermal_names = None
        self.counter = 0
        self.replay = ReplayBuffer(buffer_capacity, buffer_seed,
                                   buffer_chkpt_dir)
        self.warmup_complete = False
        self.terminate = False
        self.wait_for_step = Event()
        self.wait_for_state = Event()
        self.parent, self.child_energy = Pipe(duplex=True)
        self.child = None
        self.use_lock = False
        self.reward = reward
        self.eplus_naming_dict = dict(
        ) if eplus_naming_dict is None else eplus_naming_dict
        self.eplus_var_types = dict(
        ) if eplus_var_types is None else eplus_var_types
        self.prev_reward = None
        self.total_timestep = -1
        self.leap_weather = False
        self.state_modifier = StateModifier()

        # TODO: Validate input parameters

        if idf_file_name is None and climate_zone is not None:
            idf_file_name = f"./buildings/{prototype}_{climate_zone}_{heating_type}_{foundation_type}.idf"
            if weather_file is None and climate_zone is not None:
                weather_file = f"./weathers/{climate_zone}.epw"

        if tmp_idf_path is None:
            self.input_idf = "input.idf"
        else:
            self.input_idf = os.path.join(tmp_idf_path, "input.idf")

        self.run_parameters = ["-d", "result", self.input_idf]
        if weather_file:
            self.run_parameters = ["-w", weather_file] + self.run_parameters
            with open(weather_file, 'r') as w_file:
                for line in w_file:
                    line = line.split(',')
                    if len(line) > 3 and line[0].upper(
                    ) == "HOLIDAYS/DAYLIGHT SAVINGS":
                        self.leap_weather = True if line[1].upper(
                        ) == "YES" else False
                        break

        try:
            self.idf = IDF(idf_file_name)
        except:
            raise ValueError(
                "IDF file is damaged or not match with your EnergyPlus version."
            )

    @staticmethod
    def name_reformat(name):
        """
        Convert the entry from the space separated entry to the underline separated entry to match the IDF.

        :parameter name: The space separated entry.

        :return: The underline separated entry.
        """
        name = name.replace(' ', '_').replace(':', '').split('_')
        return '_'.join([word for word in name])

    def list_all_available_configurations(self):
        """
        Generate a list of all type of components appeared in the current building.

        :return: list of components entry.
        """
        return list(self.idf.idfobjects.keys())

    def get_all_configurations(self):
        """
        Read the IDF file, and return the content formatted with the IDD file.

        :return: the full IDF file with names and comments aside.
        """
        return self.idf.idfobjects

    def get_sub_configuration(self, idf_header_name: str):
        """
        Show all available settings for the given type of component.

        :parameter idf_header_name: The type of the component.

        :return: List of settings entry.
        """
        idf_header_name = idf_header_name.upper()
        if not self.idf.idfobjects.get(idf_header_name):
            raise KeyError(f"No {idf_header_name} section in current IDF file")
        return self.idf.idfobjects[idf_header_name][0].fieldnames

    def get_available_names_under_group(self, idf_header_name: str):
        """
        Given the type of components, find all available components in the building by their entry.

        :parameter idf_header_name: The type of the component.

        :return: List of names.
        """
        idf_header_name = idf_header_name.upper()
        available_names = self.get_sub_configuration(idf_header_name)
        if "Name" in available_names:
            return [
                entry["Name"] for entry in self.idf.idfobjects[idf_header_name]
            ]
        else:
            for field_name in available_names:
                if "name" in field_name.lower():
                    return [
                        entry[field_name]
                        for entry in self.idf.idfobjects[idf_header_name]
                    ]
            raise KeyError(f"No entry field available for {idf_header_name}")

    def get_configuration(self,
                          idf_header_name: str,
                          component_name: str = None):
        """
        Given the type of component, the entry of the target component, find the settings of that component.

        :parameter idf_header_name: The type of the component.

        :parameter component_name: The entry of the component.

        :return: Settings of this component.
        """
        idf_header_name = idf_header_name.upper()
        if component_name is None:
            return self.idf.idfobjects[idf_header_name]
        else:
            names = self.get_available_names_under_group(idf_header_name)
            if component_name in names:
                return self.idf.idfobjects[idf_header_name][names.index(
                    component_name)]
            else:
                raise KeyError(
                    f"Failed to locate {component_name} in {idf_header_name}")

    def get_value_range(self,
                        idf_header_name: str,
                        field_name: str,
                        validate: bool = False):
        """
        Get the range of acceptable values of the specific setting.

        :parameter idf_header_name: The type of the component.

        :parameter field_name: The setting entry.

        :parameter validate: Set to True to check the current value is valid or not.

        :return: Validation result or the range of all acceptable values retrieved from the IDD file.
        """
        idf_header_name = idf_header_name.upper()
        field_name = field_name.replace(' ', '_')
        if field_name not in self.get_sub_configuration(idf_header_name):
            raise KeyError(
                f"Failed to locate {field_name} in {idf_header_name}")
        if validate:
            return self.idf.idfobjects[idf_header_name][0].checkrange(
                field_name)
        else:
            return self.idf.idfobjects[idf_header_name][0].getrange(field_name)

    def add_configuration(self, idf_header_name: str, values: dict = None):
        """
        Create and add a new component into the building model with the specific type and setting values.

        :parameter idf_header_name: The type of the component.

        :parameter values: A dictionary map the setting entry and the setting value.

        :return: The new component.
        """
        idf_header_name = idf_header_name.upper()
        object = self.idf.newidfobject(idf_header_name.upper())
        if values is None:
            return object
        for key, value in values.items():
            key = Model.name_reformat(key)
            if isinstance(value, (int, float)):
                exec(f"object.{key} = {value}")
            else:
                exec(f"object.{key} = '{value}'")
        return object

    def delete_configuration(self,
                             idf_header_name: str,
                             component_name: str = None):
        """
        Delete an existing component from the building model.

        :parameter idf_header_name: The type of the component.

        :parameter component_name: The entry of the component.

        :return: None.
        """
        idf_header_name = idf_header_name.upper()
        if not self.idf.idfobjects.get(idf_header_name):
            raise KeyError(f"No {idf_header_name} section in current IDF file")
        if component_name is None:
            while len(self.idf.idfobjects[idf_header_name]):
                self.idf.popidfobject(idf_header_name, 0)
        else:
            names = self.get_available_names_under_group(idf_header_name)
            if component_name in names:
                self.idf.popidfobject(idf_header_name,
                                      names.index(component_name))
            else:
                raise KeyError(
                    f"Failed to locate {component_name} in {idf_header_name}")

    def edit_configuration(self, idf_header_name: str, identifier: dict,
                           update_values: dict):
        """
        Edit an existing component in the building model.

        :parameter idf_header_name: The type of the component.

        :parameter identifier: A dictionary map the setting entry and the setting value to locate the target component.

        :parameter update_values: A dictionary map the setting entry and the setting value that needs to update.

        :return: None.
        """
        idf_header_name = idf_header_name.upper()
        if not self.idf.idfobjects.get(idf_header_name):
            raise KeyError(f"No {idf_header_name} section in current IDF file")
        fields = self.get_sub_configuration(idf_header_name)
        for entry in self.idf.idfobjects[idf_header_name]:
            valid = True
            for key, value in identifier.items():
                key = Model.name_reformat(key)
                if key in fields:
                    if entry[key] != value:
                        valid = False
            if valid:
                for key, value in update_values.items():
                    key = Model.name_reformat(key)
                    if isinstance(value, (int, float)):
                        exec(f"entry.{key} = {value}")
                    else:
                        exec(f"entry.{key} = '{value}'")

    def _get_thermal_names(self):
        """
        Initialize all available thermal zones.

        :return: None
        """
        people_zones = self.get_configuration("People")
        self.thermal_names = dict()
        for zone in people_zones:
            try:
                if zone[Model.name_reformat("Thermal Comfort Model 1 Type")]:
                    self.thermal_names[zone["Name"]] = zone[
                        Model.name_reformat("Zone or ZoneList Name")]
            except BadEPFieldError:
                pass

    def save_idf_file(self, path: str):
        """
        Save the modified building model for EnergyPlus simulation

        :parameter path: The relative path to the modified IDF file.

        :return: None.
        """
        self.idf.saveas(path)

    def _initialization(self):
        """
        Initialize the EnergyPlus simulation by letting the EnergyPlus finish the warmup.

        :return: None
        """
        if not self.api.exchange.api_data_fully_ready():
            return
        self.warmup_complete = True

    def _generate_output_files(self):
        """
        Assert errors to terminate the simulation after the warmup in order to generate the EDD file to list all available actions for the current building.

        :return: None
        """
        assert False

    def _step_callback(self):
        """
        Get the state value at each timestep, and modify the building model based on the actions from the ``EventQueue``.

        :return: None

        """
        # print("Child: Not ready")
        if not self.api.exchange.api_data_fully_ready(
        ) or not self.warmup_complete:
            return
        current_state = dict()
        # print("Child: Simulating")
        current_state["timestep"] = self.counter
        # print(self.get_date())
        current_state["time"] = self.get_date()
        current_state["temperature"] = dict()
        current_state["occupancy"] = dict()
        current_state["terminate"] = self.total_timestep == self.counter
        # if self.occupancy is not None:
        #     current_state["occupancy"] = {zone: value[self.counter] for zone, value in self.occupancy.items()}
        for name in self.zone_names:
            handle = self.api.exchange.get_variable_handle(
                "Zone People Occupant Count", name)
            if handle == -1:
                continue
            current_state["occupancy"][
                name] = self.api.exchange.get_variable_value(handle)
        for name in self.zone_names:
            handle = self.api.exchange.get_variable_handle(
                "Zone Air Temperature", name)
            if handle == -1:
                continue
            # print("Child: Simulating 2")
            current_state["temperature"][
                name] = self.api.exchange.get_variable_value(handle)
        handle = self.api.exchange.get_meter_handle("Heating:EnergyTransfer")
        current_state["energy"] = self.api.exchange.get_meter_value(handle)
        if self.reward is not None:
            current_state["reward"] = self.prev_reward

        # print("Child: Simulating 1")

        if "Zone Thermal Comfort Fanger Model PMV" in self.get_available_names_under_group(
                "Output:Variable"):
            current_state["PMV"] = dict()
            for zone in self.thermal_names:
                handle = self.api.exchange.get_variable_handle(
                    "Zone Thermal Comfort Fanger Model PMV", zone)
                if handle == -1:
                    continue
                current_state["PMV"][self.thermal_names[
                    zone]] = self.api.exchange.get_variable_value(handle)

        # Add state values
        state_vars = self.get_current_state_variables()

        # Add for temp extra output
        for entry in self.idf.idfobjects['OUTPUT:VARIABLE']:
            # we only care about the output vars for Gnu-RL
            if (entry['Variable_Name'], entry['Key_Value']) in self.eplus_naming_dict.keys() or \
               (entry['Variable_Name'], entry['Key_Value']) in state_vars:
                var_name = entry['Variable_Name']

                # if the key value is not associated with a zone return None for variable handler
                # key_val = entry['Key_Value'] if entry['Key_Value'] != '*' else None
                if entry['Key_Value'] == '*':
                    key_val = self.eplus_var_types.get(var_name, None)
                    if key_val is None:
                        continue
                else:
                    key_val = entry['Key_Value']
                handle = self.api.exchange.get_variable_handle(
                    var_name, key_val)
                if handle == -1:
                    continue
                # name the state value based on Gnu-RL paper
                key = self.eplus_naming_dict.get(
                    (var_name, entry['Key_Value']), f"{var_name}_{key_val}")
                current_state[key] = self.api.exchange.get_variable_value(
                    handle)

        self.state_modifier.get_update_states(current_state, self)
        # current_state.update(update_dict)
        # print(current_state)

        if self.use_lock:
            # print("Child: Sending current states")
            self.child_energy.send(current_state)
            self.wait_for_state.set()
            # Take all actions
            self.wait_for_step.clear()
            # print("Child: Waiting for actions")
            if not self.child_energy.poll():
                self.wait_for_step.wait()
            # print("Child: Receiving actions")
            events = self.child_energy.recv()
        else:
            # print(self.current_state)
            if self.counter != 0:
                self.replay.push(
                    self.current_state,
                    self.queue.get_event(self.current_state["timestep"]),
                    current_state, current_state["terminate"])
            self.current_state = current_state
            # self.historical_values.append(self.current_state)
            events = self.queue.trigger(self.counter)
        self.counter += 1

        # Trigger modifiers
        # for modifier in self.modifier:
        #     modifier.update(current_state)
        # print("Child: executing actions")

        # print("Child: Printing Reward")
        # Calculate Reward
        if self.reward is not None:
            self.prev_reward = self.reward.reward(current_state, events)

        # Trigger events
        for key in events["actuator"]:
            component_type, control_type, actuator_key = key.split("|*|")
            value = events["actuator"][key][1]
            handle = self.api.exchange.get_actuator_handle(
                component_type, control_type, actuator_key)
            if handle == -1:
                raise ValueError('Actuator handle could not be found: ',
                                 component_type, control_type, actuator_key)
            self.api.exchange.set_actuator_value(handle, value)
        for key in events["global"]:
            var_name = key
            value = events["global"][key][1]
            handle = self.api.exchange.get_global_handle(var_name)
            if handle == -1:
                raise ValueError('Actuator handle could not be found: ',
                                 component_type, control_type, actuator_key)
            self.api.exchange.set_global_value(handle, value)

        # if self.use_lock:
        #     # wait for next call of step
        #     self.wait_for_step.clear()
        #     self.wait_for_step.wait()
        # else:
        if not self.use_lock and self.agent:
            self.agent.step(self.current_state, self.queue, self.counter - 1)

    def step(self, action_list=None):
        """
        Add all actions into the ``EventQueue``, and then generate the state value of the next timestep.

        :parameter action_list: list of dictionarys contains the arguments for ``EventQueue.schedule_event()``.

        :return: The state value of the current timestep.
        """
        if action_list is not None:
            for action in action_list:
                self.queue.schedule_event(**action)
        # print("Parent: Sending actions")
        self.parent.send(self.queue.trigger(self.counter))
        self.counter += 1
        # Let process grab and execute actions
        # print("Parent: Releasing child's lock")
        self.wait_for_state.clear()
        self.wait_for_step.set()
        # print("Parent: Waiting for state values")
        if not self.parent.poll():
            self.wait_for_state.wait()
        self.wait_for_state.clear()
        current_state = self.parent.recv()
        # if isinstance(current_state, dict):
        self.replay.push(self.current_state,
                         self.queue.get_event(self.current_state["timestep"]),
                         current_state, current_state["terminate"])
        self.current_state = current_state
        # self.historical_values.append(self.current_state)
        if current_state["terminate"]:
            self.terminate = True
            self.parent.send(self.queue.trigger(self.counter))
            self.wait_for_step.set()
            self.child.join()
            # self.replay.terminate()
        self.wait_for_state.clear()
        # print("Parent: received state values")
        return self.current_state

    def is_terminate(self):
        """
        Determine if the simulation is finished or not.

        :return: True if the simulation is done, and False otherwise.
        """
        return self.terminate

    def reset(self):
        """
        Clear the actions and buffer, reset the environment and start the simulation.

        :return: The initial state of the simulation.
        """
        self._init_simulation()
        self.counter = 0
        self.total_timestep = self.get_total_timestep() - 1
        self.queue = EventQueue()
        self.replay.reset()
        # self.ignore_list = set()
        self.wait_for_state.clear()
        self.wait_for_step.clear()
        self.terminate = False
        self.use_lock = True
        self.parent, self.child_energy = Pipe(duplex=True)
        self.child = Process(target=self.simulate)
        self.child.start()
        # print("Waiting")
        if not self.parent.poll():
            self.wait_for_state.wait()
        self.current_state = self.parent.recv()
        # self.historical_values.append(self.current_state)
        self.wait_for_state.clear()
        return self.current_state

    def get_total_timestep(self):
        if "-w" not in self.run_parameters:
            return self.get_configuration(
                "Timestep")[0].Number_of_Timesteps_per_Hour * 24 * 8
        elif len(self.get_configuration("RunPeriod")) == 0:
            raise ValueError(
                "Your IDF files does not specify the run period."
                "Please manually edit the IDF file or use Model().set_runperiod(...)"
            )
        run_period = self.get_configuration("RunPeriod")[0]
        start = datetime(
            year=run_period.Begin_Year if run_period.Begin_Year else 2000,
            month=run_period.Begin_Month,
            day=run_period.Begin_Day_of_Month)
        end = datetime(
            year=run_period.End_Year if run_period.End_Year else start.year,
            month=run_period.End_Month,
            day=run_period.End_Day_of_Month)
        end += timedelta(days=1)

        if not self.leap_weather:
            offset = 0
            for year in range(start.year, end.year + 1):
                if isleap(year) and datetime(year, 2, 29) > start and datetime(
                        year, 2, 29) < end:
                    offset += 1
            end -= timedelta(days=offset)

        timestep = self.get_configuration(
            "Timestep")[0].Number_of_Timesteps_per_Hour
        if 60 % timestep != 0:
            timestep = 60 // round(60 / timestep)

        return int((end - start).total_seconds() // 3600 * timestep)

    def simulate(self, terminate_after_warmup=False):
        """
        Run the whole simulation once. If user use this method instead of the reset function, the user need to provide the Agent.

        :parameter terminate_after_warmup: True if the simulation should terminate after the warmup.

        :return: None.
        """
        from pyenergyplus.api import EnergyPlusAPI

        self.replay.set_ignore(self.state_modifier.get_ignore_by_checkpoint())
        if not self.use_lock:
            self._init_simulation()
        # for entry in self.zone_names:
        #     print(entry)
        #     self.current_handle["temperature"][entry] = \
        #         self.api.exchange.get_variable_handle("Zone Air Temperature", entry)
        # self.current_handle["temperature"] = self.api.exchange.get_variable_handle("SITE OUTDOOR AIR DRYBULB TEMPERATURE", "ENVIRONMENT")
        # self.current_handle["energy"] = self.api.exchange.get_meter_handle("Electricity:Facility")
        self.api = EnergyPlusAPI()
        if not terminate_after_warmup:
            self.api.runtime.callback_after_new_environment_warmup_complete(
                self._initialization)
            self.api.runtime.callback_begin_system_timestep_before_predictor(
                self._step_callback)
        else:
            self.api.runtime.callback_begin_new_environment(
                self._generate_output_files)
        self.api.runtime.run_energyplus(self.run_parameters)
        # if self.use_lock:
        #     self.child_energy.send("Terminated")
        #     self.wait_for_state.set()
        # else:
        #     self.replay.terminate()

    def _init_simulation(self):
        """
        Save the modified building model and initialize the zones for states.

        :return: None.
        """
        try:
            self.get_configuration("Output:Variable",
                                   "Zone People Occupant Count")
        except KeyError:
            self.add_configuration(
                "Output:Variable", {
                    "Key Value": '*',
                    "Variable Name": "Zone People Occupant Count",
                    "Reporting Frequency": "Timestep"
                })
        self.idf.saveas(self.input_idf)
        self.use_lock = False
        self.zone_names = self.get_available_names_under_group("Zone")
        self._get_thermal_names()
        self.warmup_complete = False

    def get_current_state_variables(self):
        """
        Find the current entries in the state.

        :return: List of entry names that is currently available in the state.
        """
        state_values = list(
            set(self.get_possible_state_variables()) - self.ignore_list)
        state_values.sort()
        return state_values

    def select_state_variables(self, entry=None, index=None):
        """
        Select interested state entries. If selected entry is not available for the current building, it will be ignored.

        :parameter entry: Entry names and corresponding objects that the state of the environment should have.

        :parameter index: Index of all available entries that the state of the environment should have.

        :return: None.
        """
        current_state = self.get_current_state_variables()
        if entry is None:
            entry = list()
        elif isinstance(entry, tuple):
            entry = list(entry)
        if index is not None:
            if isinstance(index, int):
                index = [index]
            for i in index:
                if i < len(current_state):
                    entry.append(current_state[i])
        self.ignore_list = set(
            self.get_possible_state_variables()) - set(entry)

    def add_state_variables(self, entry):
        """
        Add entries to the state. If selected entry is not available for the current building, it will be ignored.

        :parameter entry: Entry names and corresponding objects that the state of the environment should have.

        :return: None.
        """
        if not self.ignore_list:
            return
        if isinstance(entry, tuple):
            entry = [entry]

        self.ignore_list -= set(entry)

    def remove_state_variables(self, entry):
        """
        Remove entries from the state. If selected entry is not available in the state, it will be ignored.

        :parameter entry: Entry names and corresponding objects that the state of the environment should not have.

        :return: None.
        """
        if isinstance(entry, tuple):
            entry = [entry]
        self.ignore_list = self.ignore_list.union(set(entry))

    def pop_state_variables(self, index):
        """
        Remove entries from the state by its index. If selected index is not available in the state, it will be ignored.

        :parameter index: Entry index that the state of the environment should not have.

        :return: All entry names that is removed.
        """
        current_state = self.get_current_state_variables()
        pop_values = list()
        if isinstance(index, int):
            index = [index]
        for i in index:
            if i < len(current_state):
                self.ignore_list.add(current_state[i])
                pop_values.append(current_state[i])

        return pop_values

    def get_possible_state_variables(self):
        """
        Get all available state entries. This list of entries only depends on the building architecture.

        :return: List of available state entry names.
        """

        output = [(var["Variable_Name"], var["Key_Value"])
                  for var in self.get_configuration("Output:Variable")
                  if var["Key_Value"] != "*"]
        output.sort()
        return output

    def get_possible_actions(self):
        """
        Get all available actions that the user-defined agent can take. This list of actions only depends on the building architecture.

        :return: List of available actions in dictionaries.
        """
        if not os.path.isfile("./result/eplusout.edd"):
            if not self.get_configuration("Output:EnergyManagementSystem"):
                self.add_configuration(
                    "Output:EnergyManagementSystem",
                    values={
                        "Actuator Availability Dictionary Reporting":
                        "Verbose",
                        "Internal Variable Availability Dictionary Reporting":
                        "Verbose",
                        "EMS Runtime Language Debug Output Level": "ErrorsOnly"
                    })
            try:
                self.simulate(terminate_after_warmup=True)
            except AssertionError:
                pass

        actions = list()
        with open("./result/eplusout.edd", 'r') as edd:
            for line in edd:
                line = line.strip()
                if len(line) == 0 or line[0] == '!':
                    continue
                line = line.split(',')
                actions.append({
                    "Component Type": line[2],
                    "Control Type": line[3],
                    "Actuator Key": line[1]
                })
        return actions

    def get_link_zones(self):
        """
        Generate a graph that shows the connectivity of zones of the current building.

        :return: A bi-directional graph represented by a dictionary where the key is the source zone name and the value is a set of all neighbor zone name.
        """
        link_zones = {"Outdoor": set()}

        wall_to_zone = {}
        walls = self.get_configuration("BuildingSurface:Detailed")
        for wall in walls:
            if wall.Surface_Type != "WALL":
                continue
            wall_to_zone[wall.Name] = wall.Zone_Name
            link_zones[wall.Zone_Name] = set()
        for wall in walls:
            if wall.Surface_Type != "WALL":
                continue
            if wall.Outside_Boundary_Condition == "Outdoors":
                link_zones[wall.Zone_Name].add("Outdoor")
                link_zones["Outdoor"].add(wall.Zone_Name)
            elif wall.Outside_Boundary_Condition_Object:
                link_zones[wall_to_zone[
                    wall.Outside_Boundary_Condition_Object]].add(
                        wall.Zone_Name)
                link_zones[wall.Zone_Name].add(
                    wall_to_zone[wall.Outside_Boundary_Condition_Object])

        return link_zones

    def get_date(self):
        """
        Get the current time in the simulation environment.

        :return: None
        """
        year = self.api.exchange.year()
        month = self.api.exchange.month()
        day = self.api.exchange.day_of_month()
        hour = self.api.exchange.hour()
        minute = self.api.exchange.minutes()
        current_time = datetime(year, month, day,
                                hour) + timedelta(minutes=minute)
        return current_time

    def get_windows(self):
        """
        Get the zone-window matching dictionary based on the IDF file.

        :return: A dictionary where key is the zone name, and the value is a set of window available in the zone.
        """
        zone_window = {
            name: set()
            for name in self.get_available_names_under_group("Zone")
        }
        all_window = dict()
        for window in self.get_configuration("FenestrationSurface:Detailed"):
            if window.Surface_Type != "WINDOW":
                continue
            all_window[window.Building_Surface_Name] = window.Name

        for wall in self.get_configuration("BuildingSurface:Detailed"):
            if wall.Surface_Type != "WALL":
                continue
            if wall.Name in all_window:
                zone_window[wall.Zone_Name].add(all_window[wall.Name])
        return zone_window

    def get_doors(self):
        """
        Get the zone-door matching dictionary based on the IDF file.

        :return: A dictionary where key is the zone name, and the value is a set of door available in the zone.
        """
        zone_door = {
            name: set()
            for name in self.get_available_names_under_group("Zone")
        }
        all_door = dict()
        for door in self.get_configuration("FenestrationSurface:Detailed"):
            if door.Surface_Type != "GLASSDOOR":
                continue
            all_door[door.Building_Surface_Name] = door.Name

        for wall in self.get_configuration("BuildingSurface:Detailed"):
            if wall.Surface_Type != "WALL":
                continue
            if wall.Name in all_door:
                zone_door[wall.Zone_Name].add(all_door[wall.Name])
        return zone_door

    def get_lights(self):
        """
        Get the zone-light matching dictionary based on the IDF file.

        :return: A dictionary where key is the zone name, and the value is a set of light available in the zone.
        """
        zone_light = {
            name: set()
            for name in self.get_available_names_under_group("Zone")
        }
        for light in self.get_configuration("Lights"):
            zone_light[light.Zone_or_ZoneList_Name].add(light.Name)
        return zone_light

    def get_blinds(self):
        """
        Get the zone-blind matching dictionary based on the IDF file.

        :return: A dictionary where key is the zone name, and the value is a set of blind available in the zone.
        """
        window_with_blinds = set()
        for shade in self.get_configuration("WindowShadingControl"):
            window_with_blinds.add(shade.Fenestration_Surface_1_Name)

        zone_blinds = self.get_windows()
        for zone in zone_blinds:
            zone_blinds[zone] = zone_blinds[zone].intersection(
                window_with_blinds)

        return zone_blinds

    def set_blinds(self,
                   windows,
                   blind_material_name=None,
                   shading_control_type='AlwaysOff',
                   setpoint=50,
                   agent_control=False):
        """
        Install blinds that can be controlled on some given windows.

        :param windows: An iterable object that includes all windows' name that plan to install the blind.
        :param blind_material_name: The name of an existing blind in the IDF file  as the blind for all windows.
        :param shading_control_type: Specify default EPlus control strategy (only works if control=False)
        :param setpoint: Specify default blind angle.
        :param agent_control: False if using a default EPlus control strategy or no control (ie blinds always off). True if using an external agent to control the blinds.
        :return: None
        """
        if agent_control:
            shading_control_type = 'OnIfScheduleAllows'

        blind_material = None
        if blind_material_name:
            try:
                blind_material = self.get_configuration(
                    "WindowMaterial:Blind", blind_material_name)
            except KeyError:
                pass

        zone_window = self.get_windows()

        for zone in zone_window:
            for window in zone_window[zone]:
                if window in windows:
                    window_idf = self.get_configuration(
                        "FenestrationSurface:Detailed", window)
                    if blind_material is None:
                        blind = {
                            "Name": f"{window}_blind",
                            "Slat Orientation": "Horizontal",
                            "Slat Width": 0.025,
                            "Slat Separation": 0.01875,
                            "Front Side Slat Beam Solar Reflectance": 0.8,
                            "Back Side Slat Beam Solar Reflectance": 0.8,
                            "Front Side Slat Diffuse Solar Reflectance": 0.8,
                            "Back Side Slat Diffuse Solar Reflectance": 0.8,
                            "Slat Beam Visible Transmittance": 0.0
                        }
                        blind_mat = self.add_configuration(
                            "WindowMaterial:Blind", values=blind)
                    else:
                        blind_mat = self.idf.copyidfobject(blind_material)
                        blind_mat.Name = blind_mat.Name + f" {window}"

                    shading = {
                        "Name": f"{window}_blind_shading",
                        "Zone Name": zone,
                        "Shading Type": "InteriorBlind",
                        "Shading Device Material Name": f"{blind_mat.Name}",
                        "Shading Control Type": shading_control_type,
                        "Setpoint": setpoint,
                        "Type of Slat Angle Control for Blinds":
                        "ScheduledSlatAngle",
                        "Fenestration Surface 1 Name": window_idf.Name
                    }

                    if agent_control:
                        shading[
                            "Slat Angle Schedule Name"] = f"{window}_shading_schedule"
                        shading["Multiple Surface Control Type"] = "Group"
                        shading["Shading Control Is Scheduled"] = "Yes"
                        angle_schedule = {
                            "Name": f"{window}_shading_schedule",
                            "Schedule Type Limits Name": "Angle",
                            "Hourly Value": 45
                        }
                        self.add_configuration("Schedule:Constant",
                                               values=angle_schedule)

                    self.add_configuration("WindowShadingControl",
                                           values=shading)

    def set_occupancy(self, occupancy, locations):
        """
        Include the occupancy schedule generated by the OccupancyGenerator to the model as the occupancy data in
        EnergyPlus simulated environment is broken.

        :param occupancy: Numpy matrix contains the number of occupanct in each zone at each time slot.
        :param locations: List of zone names.
        :return: None
        """
        occupancy = occupancy.astype(int)
        self.occupancy = {
            locations[i]: occupancy[i, :]
            for i in range(len(locations))
        }
        if "Outdoor" in self.occupancy.keys():
            self.occupancy.pop("Outdoor")
        if "busy" in self.occupancy.keys():
            self.occupancy.pop("busy")

    def set_runperiod(self,
                      days,
                      start_year: int = 2000,
                      start_month: int = 1,
                      start_day: int = 1,
                      specify_year: bool = False):
        """
        Set the simulation run period.

        :param days: How many days in total the simulation should perform.
        :param start_year: Start from which year
        :param start_month: Start from which month of the year
        :param start_day: Start from which day of the month
        :param specify_year: Use default year or a specific year when simulation is within a year.
        :return: None
        """
        if "-w" not in self.run_parameters:
            raise KeyError("You must include a weather file to set run period")
        start = datetime(start_year, start_month, start_day)
        end = start + timedelta(days=days - 1)
        if not self.leap_weather:
            test_year = start_year - 1
            while datetime(test_year, 1, 1) < end:
                test_year += 1
                if not isleap(test_year):
                    continue
                if datetime(test_year, 2, 29) > start and datetime(
                        test_year, 2, 29) < end:
                    end += timedelta(days=1)

        values = {
            "Begin Month": start_month,
            "Begin Day of Month": start_day,
            "End Month": end.month,
            "End Day of Month": end.day
        }
        if end.year != start_year or specify_year:
            values.update({"Begin Year": start_year, "End Year": end.year})
        run_setting = self.get_configuration("RunPeriod")
        if len(run_setting) == 0:
            values["Name"] = "RunPeriod 1"
            self.add_configuration("RunPeriod", values)
        else:
            name = self.get_configuration("RunPeriod")[0].Name
            self.edit_configuration("RunPeriod", {"Name": name}, values)

    def set_timestep(self, timestep_per_hour):
        """
        Set the timestep per hour for the simulation.

        :param timestep_per_hour: How many timesteps within a hour.
        :return: None
        """
        self.get_configuration(
            "Timestep")[0].Number_of_Timesteps_per_Hour = timestep_per_hour

    def add_state_modifier(self, model):
        """
        Add a state modifier model, including predictive model, state estimator, controller, etc.

        :param model: A class object that follows the template (contains step(true_state, environment) method).
        :return: None
        """
        self.state_modifier.add_model(model)

    def flatten_state(self, order, state=None):
        """
        Flatten the state to a list of values by a given order.

        :param order: The order that the values should follow.
        :param state: The state to flatten. If not specified, then the current state is selected.
        :return: List of values follows the given order.
        """
        if state is None:
            state = self.current_state
        return [self.current_state.get(name, None) for name in order]

    def sample_buffer(self, batch_size):
        """
        Sample a batch of experience from the replay buffer.

        :param batch_size: Number of entries in a batch.
        :return: (state, action, next state, is terminate)
        """
        return self.replay.sample(batch_size)

    def sample_flattened_buffer(self, order, batch_size):
        """
        Sample a batch of experience from the replay buffer and flatten the states by a given order.

        :param order: The order that the values should follow.
        :param batch_size: Number of entries in a batch.
        :return: (state, action, next state, is terminate) where states are flatten.
        """
        state, action, next_state, done = self.replay.sample(batch_size)
        for i, row in state:
            state[i] = self.flatten_state(order, row)
        for i, row in next_state:
            next_state[i] = self.flatten_state(order, row)
        return state, action, next_state, done
Example #13
0
def pickupHVACsystem(idfHVACfile, idfObject, zoneloadlist, NodeNumb):
    idfHVAC = IDF(idfHVACfile)
    loopLen = len(idfObject.idfobjects['SIZING:ZONE'])
    for j in range(1, loopLen):
        idfHVAC.copyidfobject(idfHVAC.idfobjects["SIZING:SYSTEM"][0])
        addedobject = idfHVAC.idfobjects["SIZING:SYSTEM"][j]
        addedobject.AirLoop_Name = 'Air Loop HVAC ' + str(j + 1)
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects["AIRTERMINAL:SINGLEDUCT:UNCONTROLLED"][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects["ZONEHVAC:EQUIPMENTLIST"][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects["ZONEHVAC:EQUIPMENTCONNECTIONS"][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['FAN:ONOFF'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['COIL:COOLING:DX:SINGLESPEED'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['COIL:HEATING:ELECTRIC'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['COIL:HEATING:DX:SINGLESPEED'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['AIRLOOPHVAC:UNITARYSYSTEM'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['CONTROLLER:OUTDOORAIR'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['CONTROLLER:MECHANICALVENTILATION'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['AIRLOOPHVAC:CONTROLLERLIST'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['AVAILABILITYMANAGER:SCHEDULED'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['AVAILABILITYMANAGER:SCHEDULED'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['AVAILABILITYMANAGERASSIGNMENTLIST'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['AVAILABILITYMANAGERASSIGNMENTLIST'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['OUTDOORAIR:NODELIST'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['NODELIST'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['NODELIST'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['NODELIST'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['AIRLOOPHVAC'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['OUTDOORAIR:MIXER'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['AIRLOOPHVAC:OUTDOORAIRSYSTEM:EQUIPMENTLIST']
            [0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['AIRLOOPHVAC:OUTDOORAIRSYSTEM'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['AIRLOOPHVAC:ZONESPLITTER'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['AIRLOOPHVAC:SUPPLYPATH'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['AIRLOOPHVAC:ZONEMIXER'][0])
        idfHVAC.copyidfobject(
            idfHVAC.idfobjects['AirLoopHVAC:ReturnPath'.upper()][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['BRANCH'][0])
        idfHVAC.copyidfobject(idfHVAC.idfobjects['BRANCHLIST'][0])

    ##idfHVAC.printidf()
    for i in range(0, loopLen):
        ZoneName = idfObject.idfobjects['SIZING:ZONE'][
            i].Zone_or_ZoneList_Name.upper()
        ClgLoad = zoneloadlist['LoadClg_' + ZoneName]
        HtgLoad = zoneloadlist['LoadHtg_' + ZoneName]
        SingleDuct = idfHVAC.idfobjects['AIRTERMINAL:SINGLEDUCT:UNCONTROLLED'][
            i]
        SingleDuct.Name = 'Diffuser ' + str(i + 1)
        SingleDuct.Zone_Supply_Air_Node_Name = 'Node ' + str(loopLen + 5 +
                                                             i * 5 + NodeNumb)
        EquipmentLs = idfHVAC.idfobjects['ZONEHVAC:EQUIPMENTLIST'][i]
        EquipmentLs.Name = ZoneName + ' Equipment List'
        EquipmentLs.Zone_Equipment_1_Name = SingleDuct.Name
        EquipmentConnect = idfHVAC.idfobjects['ZONEHVAC:EQUIPMENTCONNECTIONS'][
            i]
        EquipmentConnect.Zone_Name = ZoneName
        EquipmentConnect.Zone_Conditioning_Equipment_List_Name = ZoneName + ' Equipment List'
        EquipmentConnect.Zone_Air_Inlet_Node_or_NodeList_Name = ZoneName + ' Inlet Node List'
        EquipmentConnect.Zone_Air_Node_Name = 'Node ' + str(i + 1 + NodeNumb)
        EquipmentConnect.Zone_Return_Air_Node_or_NodeList_Name = 'Node ' + str(
            6 * loopLen + 4 + 4 * i + NodeNumb)
        FAN = idfHVAC.idfobjects['FAN:ONOFF'][i]
        FAN.Name = 'Fan On Off ' + str(i + 1)
        FAN.Air_Inlet_Node_Name = 'Node ' + str(6 * loopLen + 3 + 4 * i +
                                                NodeNumb)
        FAN.Air_Outlet_Node_Name = 'Unitary - DX Heat Pump - Cycling - Elec reheat ' + str(
            i + 1) + ' Fan - Cooling Coil Node'
        CoolingDX = idfHVAC.idfobjects['COIL:COOLING:DX:SINGLESPEED'][i]
        CoolingDX.Name = '1 Spd DX Clg Coil ' + str(i + 1)
        CoolingDX.Air_Inlet_Node_Name = 'Unitary - DX Heat Pump - Cycling - Elec reheat ' + str(
            i + 1) + ' Fan - Cooling Coil Node'
        CoolingDX.Air_Outlet_Node_Name = 'Unitary - DX Heat Pump - Cycling - Elec reheat ' + str(
            i + 1) + ' Cooling Coil - Heating Coil Node'
        HeatingElec = idfHVAC.idfobjects['COIL:HEATING:ELECTRIC'][i]
        HeatingElec.Name = 'Elec Htg Coil ' + str(i + 1)
        HeatingElec.Air_Inlet_Node_Name = 'Unitary - DX Heat Pump - Cycling - Elec reheat ' + str(
            i + 1) + ' Heating Coil - Supplemental Coil Node'
        HeatingElec.Air_Outlet_Node_Name = 'Node ' + str(loopLen + 2 + 5 * i +
                                                         NodeNumb)
        HeatingDX = idfHVAC.idfobjects['COIL:HEATING:DX:SINGLESPEED'][i]
        HeatingDX.Name = '1 Spd DX Htg Coil ' + str(i + 1)
        HeatingDX.Air_Inlet_Node_Name = 'Unitary - DX Heat Pump - Cycling - Elec reheat ' + str(
            i + 1) + ' Cooling Coil - Heating Coil Node'
        HeatingDX.Air_Outlet_Node_Name = 'Unitary - DX Heat Pump - Cycling - Elec reheat ' + str(
            i + 1) + ' Heating Coil - Supplemental Coil Node'
        UnitarySystem = idfHVAC.idfobjects['AIRLOOPHVAC:UNITARYSYSTEM'][i]
        UnitarySystem.Name = 'Unitary - DX Heat Pump - Cycling - Elec reheat ' + str(
            i + 1)
        UnitarySystem.Controlling_Zone_or_Thermostat_Location = ZoneName
        UnitarySystem.Air_Inlet_Node_Name = 'Node ' + str(loopLen * 6 + 3 +
                                                          4 * i + NodeNumb)
        UnitarySystem.Air_Outlet_Node_Name = 'Node ' + str(loopLen + 2 +
                                                           5 * i + NodeNumb)
        UnitarySystem.Supply_Fan_Name = FAN.Name
        UnitarySystem.Heating_Coil_Name = HeatingDX.Name
        UnitarySystem.Cooling_Coil_Name = CoolingDX.Name
        UnitarySystem.Supplemental_Heating_Coil_Name = HeatingElec.Name
        ControllerOA = idfHVAC.idfobjects['CONTROLLER:OUTDOORAIR'][i]
        ControllerOA.Name = 'Outdoor Air Controller ' + str(i + 1)
        ControllerOA.Relief_Air_Outlet_Node_Name = 'Node ' + str(loopLen * 6 +
                                                                 2 + 4 * i +
                                                                 NodeNumb)
        ControllerOA.Return_Air_Node_Name = 'Node ' + str(loopLen + 1 + 5 * i +
                                                          NodeNumb)
        ControllerOA.Mixed_Air_Node_Name = 'Node ' + str(loopLen * 6 + 3 +
                                                         4 * i + NodeNumb)
        ControllerOA.Actuator_Node_Name = 'Node ' + str(loopLen * 6 + 1 +
                                                        4 * i + NodeNumb)
        ControllerOA.Mechanical_Ventilation_Controller_Name = 'Controller Mechanical Ventilation ' + str(
            i + 1)
        ControllerVent = idfHVAC.idfobjects[
            'CONTROLLER:MECHANICALVENTILATION'][i]
        ControllerVent.Name = 'Controller Mechanical Ventilation ' + str(i + 1)
        ControllerVent.Zone_1_Name = ZoneName
        ControllerVent.Design_Specification_Outdoor_Air_Object_Name_1 = idfObject.idfobjects[
            'SIZING:ZONE'][i].Design_Specification_Outdoor_Air_Object_Name
        ControllerVent.Design_Specification_Zone_Air_Distribution_Object_Name_1 = idfObject.idfobjects[
            'SIZING:ZONE'][
                i].Design_Specification_Zone_Air_Distribution_Object_Name
        OAControllerls = idfHVAC.idfobjects['AIRLOOPHVAC:CONTROLLERLIST'][i]
        OAControllerls.Name = 'OA System ' + str(i + 1) + ' Controller List'
        OAControllerls.Controller_1_Name = ControllerOA.Name
        AVAILALHVAC = idfHVAC.idfobjects['AVAILABILITYMANAGER:SCHEDULED'][2 *
                                                                          i]
        AVAILALHVAC.Name = 'Air Loop HVAC ' + str(i +
                                                  1) + ' Availability Manager'
        AVAILALHVAC.Schedule_Name = 'Always On Discrete'
        AVAILOA = idfHVAC.idfobjects['AVAILABILITYMANAGER:SCHEDULED'][2 * i +
                                                                      1]
        AVAILOA.Name = 'OA System ' + str(i + 1) + ' Availability Manager'
        AVAILOA.Schedule_Name = 'Always On Discrete'
        AMAL = idfHVAC.idfobjects['AVAILABILITYMANAGERASSIGNMENTLIST'][2 * i]
        AMAL.Name = 'Air Loop HVAC ' + str(i + 1) + 'Availability Manager List'
        AMAL.Availability_Manager_1_Name = AVAILALHVAC.Name
        AMAL2 = idfHVAC.idfobjects['AVAILABILITYMANAGERASSIGNMENTLIST'][2 * i +
                                                                        1]
        AMAL2.Name = 'OA System ' + str(i + 1) + ' Availability Manager List'
        AMAL2.Availability_Manager_1_Name = AVAILOA.Name
        OANodeLs = idfHVAC.idfobjects['OUTDOORAIR:NODELIST'][i]
        OANodeLs.Node_or_NodeList_Name_1 = 'Node ' + str(6 * loopLen + 1 +
                                                         4 * i + NodeNumb)
        NodeLs_ZoneInlet = idfHVAC.idfobjects['NODELIST'][i]
        NodeLs_ZoneInlet.Name = ZoneName + " Inlet Node List"
        NodeLs_ZoneInlet.Node_1_Name = 'Node ' + str(loopLen + 5 + 5 * i +
                                                     NodeNumb)
        NodeLs_ALSupplyOut = idfHVAC.idfobjects['NODELIST'][loopLen + 2 * i]
        NodeLs_ALDemandIn = idfHVAC.idfobjects['NODELIST'][loopLen + 2 * i + 1]
        NodeLs_ALSupplyOut.Name = 'Air Loop HVAC ' + str(
            i + 1) + ' Supply Outlet Nodes'
        NodeLs_ALDemandIn.Name = 'Air Loop HVAC ' + str(
            i + 1) + ' Demand Inlet Nodes'
        NodeLs_ALSupplyOut.Node_1_Name = 'Node ' + str(loopLen + 2 + 5 * i +
                                                       NodeNumb)
        NodeLs_ALDemandIn.Node_1_Name = 'Node ' + str(loopLen + 3 + 5 * i +
                                                      NodeNumb)
        ALHVAC = idfHVAC.idfobjects['AIRLOOPHVAC'][i]
        ALHVAC.Name = 'Air Loop HVAC ' + str(i + 1)
        ALHVAC.Availability_Manager_List_Name = AMAL.Name
        ALHVAC.Branch_List_Name = 'Air Loop HVAC ' + str(
            i + 1) + ' Supply Branches'
        ALHVAC.Supply_Side_Inlet_Node_Name = 'Node ' + str(loopLen + 1 +
                                                           5 * i + NodeNumb)
        ALHVAC.Demand_Side_Outlet_Node_Name = 'Node ' + str(loopLen + 4 +
                                                            5 * i + NodeNumb)
        ALHVAC.Demand_Side_Inlet_Node_Names = NodeLs_ALDemandIn.Name
        ALHVAC.Supply_Side_Outlet_Node_Names = NodeLs_ALSupplyOut.Name
        OAMixer = idfHVAC.idfobjects['OUTDOORAIR:MIXER'][i]
        OAMixer.Name = 'OA System ' + str(i + 1) + ' Outdoor Air Mixer'
        OAMixer.Mixed_Air_Node_Name = 'Node ' + str(6 * loopLen + 3 + 4 * i +
                                                    NodeNumb)
        OAMixer.Outdoor_Air_Stream_Node_Name = 'Node ' + str(6 * loopLen + 1 +
                                                             4 * i + NodeNumb)
        OAMixer.Relief_Air_Stream_Node_Name = 'Node ' + str(6 * loopLen + 2 +
                                                            4 * i + NodeNumb)
        OAMixer.Return_Air_Stream_Node_Name = 'Node ' + str(loopLen + 1 +
                                                            5 * i + NodeNumb)
        ALOASysEquip = idfHVAC.idfobjects[
            'AIRLOOPHVAC:OUTDOORAIRSYSTEM:EQUIPMENTLIST'][i]
        ALOASysEquip.Name = 'OA System ' + str(i + 1) + ' Equipment List'
        ALOASysEquip.Component_1_Name = OAMixer.Name
        OASys = idfHVAC.idfobjects['AIRLOOPHVAC:OUTDOORAIRSYSTEM'][i]
        OASys.Name = 'OA System ' + str(i + 1)
        OASys.Controller_List_Name = OAControllerls.Name
        OASys.Outdoor_Air_Equipment_List_Name = ALOASysEquip.Name
        OASys.Availability_Manager_List_Name = AMAL2.Name
        ZoneSplitter = idfHVAC.idfobjects['AIRLOOPHVAC:ZONESPLITTER'][i]
        ZoneSplitter.Name = 'Air Loop HVAC Zone Splitter ' + str(i + 1)
        ZoneSplitter.Inlet_Node_Name = 'Node ' + str(loopLen + 3 + 5 * i +
                                                     NodeNumb)
        ZoneSplitter.Outlet_1_Node_Name = 'Node ' + str(loopLen + 5 + 5 * i +
                                                        NodeNumb)
        SupplyPath = idfHVAC.idfobjects['AIRLOOPHVAC:SUPPLYPATH'][i]
        NodeNumber = str(loopLen + 3 + 5 * i + NodeNumb)
        SupplyPath.Name = 'Air Loop HVAC ' + str(
            i + 1) + ' Node ' + NodeNumber + ' Supply Path'
        SupplyPath.Supply_Air_Path_Inlet_Node_Name = 'Node ' + NodeNumber
        SupplyPath.Component_1_Name = 'Air Loop HVAC Zone Splitter ' + str(i +
                                                                           1)
        ZoneMixer = idfHVAC.idfobjects['AIRLOOPHVAC:ZONEMIXER'][i]
        ZoneMixer.Name = 'Air Loop HVAC Zone Mixer ' + str(i + 1)
        ZoneMixer.Outlet_Node_Name = 'Node ' + str(loopLen + 4 + 5 * i +
                                                   NodeNumb)
        ZoneMixer.Inlet_1_Node_Name = 'Node ' + str(loopLen * 6 + 4 + 4 * i +
                                                    NodeNumb)
        RetPath = idfHVAC.idfobjects['AirLoopHVAC:ReturnPath'.upper()][i]
        RetPath.Name = 'Air Loop HVAC ' + str(i + 1) + ' Return Path'
        RetPath.Return_Air_Path_Outlet_Node_Name = 'Node ' + str(loopLen + 4 +
                                                                 5 * i +
                                                                 NodeNumb)
        RetPath.Component_1_Name = ZoneMixer.Name
        Branch = idfHVAC.idfobjects['BRANCH'][i]
        Branch.Name = 'Air Loop HVAC ' + str(i + 1) + ' Main Branch'
        Branch.Component_1_Name = OASys.Name
        Branch.Component_1_Inlet_Node_Name = 'Node ' + str(loopLen + 1 +
                                                           i * 5 + NodeNumb)
        Branch.Component_1_Outlet_Node_Name = 'Node ' + str(loopLen * 6 + 3 +
                                                            4 * i + NodeNumb)
        Branch.Component_2_Name = UnitarySystem.Name
        Branch.Component_2_Inlet_Node_Name = Branch.Component_1_Outlet_Node_Name
        Branch.Component_2_Outlet_Node_Name = 'Node ' + str(loopLen + 2 +
                                                            5 * i + NodeNumb)
        BranchLs = idfHVAC.idfobjects['BRANCHLIST'][i]
        BranchLs.Name = ALHVAC.Branch_List_Name
        BranchLs.Branch_1_Name = Branch.Name
        if abs(int(HtgLoad)) in range(0, 4689) and abs(int(ClgLoad)) in range(
                0, 3399):
            FAN.Maximum_Flow_Rate = '0.1665974474496'
            CoolingDX.Gross_Rated_Total_Cooling_Capacity = '3399.62441399778'
            CoolingDX.Gross_Rated_Cooling_COP = '3.78'
            HeatingDX.Gross_Rated_Heating_Capacity = '4689.13712275556'
            HeatingDX.Gross_Rated_Heating_COP = '3.08'
        elif abs(int(HtgLoad)) in range(0, 7912) and abs(
                int(ClgLoad)) in range(0, 7033):
            FAN.Maximum_Flow_Rate = '0.3246998409216'
            CoolingDX.Gross_Rated_Total_Cooling_Capacity = '7033.705684133'
            CoolingDX.Gross_Rated_Cooling_COP = '3.52'
            HeatingDX.Gross_Rated_Heating_Capacity = '7912.91889465'
            HeatingDX.Gross_Rated_Heating_COP = '2.93'
        elif abs(int(HtgLoad)) in range(0, 11722) and abs(
                int(ClgLoad)) in range(0, 10550):
            FAN.Maximum_Flow_Rate = '0.533300610816'
            CoolingDX.Gross_Rated_Total_Cooling_Capacity = '10550.5585262'
            CoolingDX.Gross_Rated_Cooling_COP = '3.55'
            HeatingDX.Gross_Rated_Heating_Capacity = '11722.8428068889'
            HeatingDX.Gross_Rated_Heating_COP = '2.7'
        else:
            print("HVAC Sizes could not meet demand")
            print(abs(HtgLoad), abs(ClgLoad))
    return idfHVAC
Example #14
0
def createrectshading(idd_filename, idf_filename, base_surface, shading_str,
                      start_point, end_point, depths):
    ##########################################
    # loading base surface data from idf file
    ##########################################

    # check if IDD has been already set
    try:
        IDF.setiddname(idd_filename)
    except modeleditor.IDDAlreadySetError as e:
        pass

    # load idf file into idf collection
    idf_collection = IDF(idf_filename)

    # find the named base_surface in idf collection
    walls = idf_collection.idfobjects['BuildingSurface:Detailed'.upper()]
    for wall in walls:
        if wall.Name == base_surface:
            # named base_surface is now contained in wall
            break
    else:
        # named base_surface was not found in idf file
        print('epnurbs.createrectshading: unable to find the base surface',
              base_surface, 'in', idf_filename)
        return

    ##############################################################################
    # feet of perpendiculars from the start and the end point to the base surface
    ##############################################################################

    # getting the found base_surface's coordinates
    coord = wall.coords
    ulc = coord[0]
    blc = coord[1]
    brc = coord[2]

    # find the base_surface's plane normal and normalize it
    N = crossproduct( (blc[0]-ulc[0], blc[1]-ulc[1], blc[2]-ulc[2]), \
                      (brc[0]-ulc[0], brc[1]-ulc[1], brc[2]-ulc[2]) )
    N = normalize(N)

    # calculate feet of perpendiculars
    start_foot = foot(start_point, ulc, N)
    end_foot = foot(end_point, ulc, N)

    # steps between the start and the end point
    num = len(depths)
    step = [(end_foot[0] - start_foot[0]) / num,
            (end_foot[1] - start_foot[1]) / num,
            (end_foot[2] - start_foot[2]) / num]

    ########################################################################
    # create string of idf definitions for a sequence of shading rectangles
    ########################################################################
    idf_total_shading_def = ""
    for i in range(num):
        if depths[i] > 0.01:
            # two base_surface vertices are start_foot + i*step and start_foot + (i+1)*step
            # the other two vertices are at depth[i] distance from the base surface
            v1 = [
                start_foot[0] + i * step[0], start_foot[1] + i * step[1],
                start_foot[2] + i * step[2]
            ]
            v2 = [
                v1[0] + depths[i] * N[0], v1[1] + depths[i] * N[1],
                v1[2] + depths[i] * N[2]
            ]

            v4 = [
                start_foot[0] + (i + 1) * step[0],
                start_foot[1] + (i + 1) * step[1],
                start_foot[2] + (i + 1) * step[2]
            ]
            v3 = [
                v4[0] + depths[i] * N[0], v4[1] + depths[i] * N[1],
                v4[2] + depths[i] * N[2]
            ]

            vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2],
                v4[0], v4[1], v4[2])
            countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                v4[0], v4[1], v4[2], v3[0], v3[1], v3[2], v2[0], v2[1], v2[2],
                v1[0], v1[1], v1[2])
            single_shading_def = shading_str.replace('<IDX>', str(i)).replace(
                '<BASESURFACE>',
                base_surface).replace('<VERTICES>', vertices_str).replace(
                    '<COUNTERVERTICES>', countervertices_str)
            idf_total_shading_def = idf_total_shading_def + single_shading_def
        else:
            # we do not have a shading rectangle if it is not deep enough
            pass

    # create idf shading objects from the string containing shading definitions
    from io import StringIO
    idf_shading = IDF(StringIO(idf_total_shading_def))

    # copy idf shading objects to the existing idf file
    shadings = idf_shading.idfobjects["SHADING:ZONE:DETAILED"]
    for shading in shadings:
        idf_collection.copyidfobject(shading)

    ###############################
    # at the end, save the changes
    ###############################
    idf_collection.save()
Example #15
0
# <headingcell level=3>

# Copying/Adding an idf object

# <markdowncell>

# Having deleted two "MATERIAL" objects, we have only one left. Let us make a copy of this object and add it to our idf file

# <codecell>

onlymaterial = idf.idfobjects["MATERIAL"][0]

# <codecell>

idf.copyidfobject(onlymaterial)

# <codecell>

print(idf.idfobjects["MATERIAL"])

# <markdowncell>

# So now we have a copy of the material. You can use this method to copy idf objects from other idf files too.

# <headingcell level=2>

# Making an idf object with named arguments

# <markdowncell>
Example #16
0
def create_combined_idf_archetype(save_folder_path, idflist=list):
    """
    Combines all materials, constructions stored in different idfs and merges them into a single idf file

    Run Order:
    1)Gathers all material and construction objects into lists stored in idfs
    2)Selects the base IDF and deletes all construction and material objects
    3)Creates new materials and constructions from the lists created in 1.
    4)Redefines output variables in a way that BuildME accepts
    5)Saves a new idf file, ready to be used with BuildME

    :param save_folder_path: save folder, where the new merged IDF will be saved
    :param idflist: idf list containing the idf files to be merged
                    this list should only contain an archetype type at a time (e.g. only SFH)
    :return: a new merged archetype idf for BuildME
    """
    cons_list = []
    mat_list = []
    matnomass_list = []
    matwin_list = []
    ffloor_list = []
    cwall_list = []
    merged_idf = ""

    # Gets required objects in all idf files and puts in a list
    for idf in idflist:
        fhandle = StringIO(idf)
        idf = IDF(fhandle)
        for cons in idf.idfobjects["Construction".upper()]:
            cons_list.append(cons)
        for mat in idf.idfobjects["Material".upper()]:
            mat_list.append(mat)
        for matnomass in idf.idfobjects["Material:NoMass".upper()]:
            matnomass_list.append(matnomass)
        for matwin in idf.idfobjects[
                "WindowMaterial:SimpleGlazingSystem".upper()]:
            matwin_list.append(matwin)
        for ffloor in idf.idfobjects[
                "Construction:FfactorGroundFloor".upper()]:
            ffloor_list.append(ffloor)
        for cwall in idf.idfobjects[
                "Construction:CfactorUndergroundWall".upper()]:
            cwall_list.append(cwall)

    # Removes duplicate elements
    cons_list = reduce(lambda l, x: l.append(x) or l
                       if x not in l else l, cons_list, [])
    mat_list = reduce(lambda l, x: l.append(x) or l
                      if x not in l else l, mat_list, [])
    matnomass_list = reduce(lambda l, x: l.append(x) or l
                            if x not in l else l, matnomass_list, [])
    matwin_list = reduce(lambda l, x: l.append(x) or l
                         if x not in l else l, matwin_list, [])
    ffloor_list = reduce(lambda l, x: l.append(x) or l
                         if x not in l else l, ffloor_list, [])
    cwall_list = reduce(lambda l, x: l.append(x) or l
                        if x not in l else l, cwall_list, [])
    newobjects = cons_list + matnomass_list + matwin_list + ffloor_list + mat_list + cwall_list
    reduced_newobjects = reduce(
        lambda l, x: l.append(x) or l if x not in l else l, newobjects, [])

    # Selects the base IDF, deletes all of the objects and rewrites new objects from other IDFs
    for idf in idflist:
        fhandle = StringIO(idf)
        idf = IDF(fhandle)
        print(
            f'Now, {idf.idfobjects["Building".upper()][0].Name} values are being written to the merged IDF...'
        )
        if "BASE" in idf.idfobjects["Building".upper()][0].Name:
            idf.removeallidfobjects("CONSTRUCTION")
            idf.removeallidfobjects("MATERIAL")
            idf.removeallidfobjects("MATERIAL:NOMASS")
            idf.removeallidfobjects("WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM")
            idf.removeallidfobjects("CONSTRUCTION:FFACTORGROUNDFLOOR")
            idf.removeallidfobjects("CONSTRUCTION:CFACTORUNDERGROUNDWALL")
            # Output Variables needs to be redefined for BuildME
            idf.removeallidfobjects("OUTPUT:VARIABLEDICTIONARY")
            idf.removeallidfobjects("OUTPUT:SURFACES:DRAWING")
            idf.removeallidfobjects("OUTPUT:CONSTRUCTIONS")
            idf.removeallidfobjects("OUTPUT:TABLE:SUMMARYREPORTS")
            idf.removeallidfobjects("OUTPUT:TABLE:MONTHLY")
            idf.removeallidfobjects("OUTPUTCONTROL:TABLE:STYLE")
            idf.removeallidfobjects("OUTPUT:VARIABLE")
            idf.removeallidfobjects("OUTPUT:METER")

            print("Output Variables are being changed...")
            # New output variables are defined by using existing SFH archetype located in data/archetype folder
            SFH_IDF = IDF("..//data//archetype//USA//SFH.idf")
            outputlist = []
            objlist = [
                "OUTPUT:METER", "OUTPUT:VARIABLEDICTIONARY",
                "OUTPUT:SURFACES:DRAWING", "OUTPUT:CONSTRUCTIONS",
                "OUTPUT:TABLE:SUMMARYREPORTS", "OUTPUT:TABLE:MONTHLY",
                "OUTPUTCONTROL:TABLE:STYLE", "OUTPUT:VARIABLE"
            ]
            for obj in objlist:
                if obj in [x for x in SFH_IDF.idfobjects]:
                    for item in SFH_IDF.idfobjects[f"{obj}"]:
                        outputlist.append(item)
            for newobj in outputlist:
                idf.copyidfobject(newobj)

            # Checks if there are still duplicates
            seen = set()
            dupes = []
            for x in reduced_newobjects:
                if x.Name in seen:
                    dupes.append(x.Name)
                else:
                    seen.add(x.Name)
                    idf.copyidfobject(x)

            # Renames the merged IDF
            building = idf.idfobjects["Building".upper()][0].Name
            building = building.split("-")[0]
            idf.idfobjects["Building".upper()][0].Name = building
            building = building.split("BASE")[1]
            idf.saveas(f"{save_folder_path}/{building}-BuildME.idf")
            merged_idf = idf

    print("The new merged idf file is successfully created")
    return merged_idf
Example #17
0
def generate_idf3(save_path, idf_data, idf_surfaces, idf_fenestration, wall_type, window_type, save_as):
    mater = 'Material'  # All
    glazi = 'WindowMaterial:SimpleGlazingSystem'  # All
    const = 'Construction'  # All
    surfa = 'BuildingSurface:Detailed'  # For geometry
    fenes = 'FenestrationSurface:Detailed'  # For geometry
    gen00 = 'Version'  # All
    gen01 = 'SimulationControl'  # All
    gen02 = 'RunPeriod'  # All
    gen03 = 'Building'  # All
    gen04 = 'Timestep'  # All
    gen05 = 'SizingPeriod:WeatherFileDays'  # All
    gen06 = 'RunPeriodControl:DaylightSavingTime'  # All
    gen07 = 'Site:GroundTemperature:BuildingSurface'  # All
    gen08 = 'GlobalGeometryRules'  # All
    zon01 = 'ZoneVentilation:DesignFlowRate'  # For geometry
    zon02 = 'ZoneInfiltration:DesignFlowRate'  # For geometry
    zon03 = 'ZoneList'  # For geometry
    zon04 = 'Zone'  # For geometry
    lds01 = 'People'  # For geometry
    lds02 = 'Lights'  # For geometry
    lds03 = 'ElectricEquipment'  # For geometry
    sch01 = 'Schedule:Compact'
    sch02 = 'ScheduleTypeLimits'
    sch03 = 'Schedule:Day:Interval'
    sch04 = 'Schedule:Week:Daily'
    sch05 = 'Schedule:Year'
    sch06 = 'Schedule:Constant'
    hvc01 = 'HVACTemplate:Thermostat'  # All
    hvc02 = 'HVACTemplate:Zone:VAV'  # For geometry
    hvc03 = 'HVACTemplate:System:PackagedVAV'  # All
    out01 = 'Output:Surfaces:Drawing'
    out02 = 'OutputControl:Table:Style'
    out03 = 'Output:Table:SummaryReports'
    del_01 = 'LifeCycleCost:Parameters'
    del_02 = 'LifeCycleCost:UsePriceEscalation'
    del_03 = 'ZoneControl:Thermostat'
    del_04 = 'ThermostatSetpoint:DualSetpoint'
    del_05 = 'HVACTemplate:Zone:IdealLoadsAirSystem'
    del_06 = 'DesignSpecification:OutdoorAir'
    del_07 = 'Sizing:Parameters'
    del_08 = 'Material:AirGap'
    del_09 = 'WindowMaterial:Blind'
    del_10 = 'WindowMaterial:Glazing'
    del_11 = 'WindowProperty:FrameAndDivider'
    del_12 = 'WindowProperty:ShadingControl'
    del_13 = 'Site:Location'
    del_14 = 'Output:VariableDictionary'
    del_15 = 'Output:SQLite'
    del_16 = 'LifeCycleCost:NonrecurringCost'

    # Assignments
    gen00 = idf_data.idfobjects[gen00.upper()][0]
    gen01 = idf_data.idfobjects[gen01.upper()][0]
    gen02 = idf_data.idfobjects[gen02.upper()][0]
    gen03 = idf_data.idfobjects[gen03.upper()][0]
    gen04 = idf_data.idfobjects[gen04.upper()][0]
    gen05 = idf_data.idfobjects[gen05.upper()][0]
    gen06 = idf_data.idfobjects[gen06.upper()][0]
    gen07 = idf_data.idfobjects[gen07.upper()][0]
    gen08 = idf_data.idfobjects[gen08.upper()][0]
    zon01 = idf_surfaces.idfobjects[zon01.upper()][0]
    zon02 = idf_surfaces.idfobjects[zon02.upper()][0]
    zon03 = idf_surfaces.idfobjects[zon03.upper()][0]
    zon04 = idf_surfaces.idfobjects[zon04.upper()]
    lds01 = idf_surfaces.idfobjects[lds01.upper()][0]
    lds02 = idf_surfaces.idfobjects[lds02.upper()][0]
    lds03 = idf_surfaces.idfobjects[lds03.upper()][0]
    sch01 = idf_data.idfobjects[sch01.upper()]
    sch02 = idf_data.idfobjects[sch02.upper()]
    sch03 = idf_data.idfobjects[sch03.upper()]
    sch04 = idf_data.idfobjects[sch04.upper()]
    sch05 = idf_data.idfobjects[sch05.upper()]
    sch06 = idf_data.idfobjects[sch06.upper()]
    hvc01 = idf_data.idfobjects[hvc01.upper()][0]
    hvc02 = idf_surfaces.idfobjects[hvc02.upper()]
    hvc03 = idf_data.idfobjects[hvc03.upper()][0]
    out01 = idf_data.idfobjects[out01.upper()][0]
    out02 = idf_data.idfobjects[out02.upper()][0]
    out03 = idf_data.idfobjects[out03.upper()][0]

    # MATERIALS
    mater = idf_data.idfobjects[mater.upper()]
    glazi = idf_data.idfobjects[glazi.upper()]
    # CONSTRUCTION
    const = idf_data.idfobjects[const.upper()]
    # GEOMETRY
    surface_objects = idf_surfaces.idfobjects[surfa.upper()]
    fenestration_objects = idf_fenestration.idfobjects[fenes.upper()]

    # CREATE NEW IDF FILE
    # with common info and specific geometry
    idf2 = IDF()
    idf2.new()

    # copy over relevant info from source idfs
    # GENERAL
    idf2.copyidfobject(gen00)
    idf2.copyidfobject(gen01)
    idf2.copyidfobject(gen02)
    idf2.copyidfobject(gen03)
    idf2.copyidfobject(gen04)
    idf2.copyidfobject(gen05)
    idf2.copyidfobject(gen06)
    idf2.copyidfobject(gen07)
    idf2.copyidfobject(gen08)
    # ZONE
    idf2.copyidfobject(zon01)
    idf2.copyidfobject(zon02)
    idf2.copyidfobject(zon03)
    # idf2.copyidfobject(zon04)
    # LOADS
    idf2.copyidfobject(lds01)
    idf2.copyidfobject(lds02)
    idf2.copyidfobject(lds03)
    # HVAC
    idf2.copyidfobject(hvc01)
    # idf2.copyidfobject(hvc02)
    idf2.copyidfobject(hvc03)
    # OUTPUT
    idf2.copyidfobject(out01)
    idf2.copyidfobject(out02)
    idf2.copyidfobject(out03)
    # SCHEDULES
    for i in sch01:
        idf2.copyidfobject(i)
    for i in sch02:
        idf2.copyidfobject(i)
    for i in sch03:
        idf2.copyidfobject(i)
    for i in sch04:
        idf2.copyidfobject(i)
    for i in sch05:
        idf2.copyidfobject(i)
    for i in sch06:
        idf2.copyidfobject(i)

    for i in zon04:
        idf2.copyidfobject(i)
    for i in hvc02:
        idf2.copyidfobject(i)

    # MATERIALS
    for i in mater:
        idf2.copyidfobject(i)
    # GLAZING
    for i in glazi:
        idf2.copyidfobject(i)
    # CONSTRUCTIONS
    for i in const:
        idf2.copyidfobject(i)

    # Basic setup done
    # Now I need geometry from a specific file.
    # GEOMETRY
    for i in surface_objects:
        idf2.copyidfobject(i)
    for i in fenestration_objects:
        idf2.copyidfobject(i)

    new_surface = idf2.idfobjects[surfa.upper()]
    new_subsurface = idf2.idfobjects[fenes.upper()]

    # Now I want to change the construction of each surface and glazing.
    floor_type = 'Slab A'
    ceiling_type = 'Slab A'
    roof_type = 'Roof A'

    for surface in new_surface:
        if surface['Surface_Type'] == 'Floor':
            surface.Construction_Name = floor_type

    for surface in new_surface:
        if surface['Surface_Type'] == 'Ceiling':
            surface.Construction_Name = ceiling_type

    for surface in new_surface:
        if surface['Surface_Type'] == 'Roof':
            surface.Construction_Name = roof_type

    for surface in new_surface:
        if surface['Surface_Type'] == 'Wall':
            surface.Construction_Name = wall_type

    for subsurface in new_subsurface:
        if subsurface['Surface_Type'] == 'Window':
            subsurface.Construction_Name = window_type

    # Save it to the disk.
    idf2.saveas('{}/{}.idf'.format(save_path, save_as))
    idf_file = '{}/{}.idf'.format(save_path, save_as)

    return idf_file
Example #18
0
materials[-1].Conductivity = 0.16
materials[-1].Density = 600
materials[-1].Specific_Heat = 1500

# <codecell>

print(materials[-1])

# <headingcell level=4>

# Copy an existing material

# <codecell>

Peanutbuttermaterial = materials[-1]
idf1.copyidfobject(Peanutbuttermaterial)
materials = idf1.idfobjects["MATERIAL"]
len(materials)
materials[-1]

# <headingcell level=2>

# Python lesson 3: indentation and looping through lists

# <markdowncell>

# I'm tired of doing all this work, it's time to make python do some heavy lifting for us!

# <markdowncell>

# Python can go through each item in a list and perform an operation on any (or every) item in the list.
Example #19
0
def createnurbsopening(idd_filename, idf_filename, base_surface, opening_str, ctrl_points, evaluated_points=50):
    ##########################################
    # loading base surface data from idf file 
    ##########################################
    
    # check if IDD has been already set
    try:
        IDF.setiddname(idd_filename)
    except modeleditor.IDDAlreadySetError as e:
        pass

    # load idf file into idf collection
    idf_collection = IDF(idf_filename)

    # find the named base_surface in idf collection
    walls = idf_collection.idfobjects['BuildingSurface:Detailed'.upper()]
    for wall in walls:
        if wall.Name == base_surface:
            # named base_surface is now contained in wall
            break
    else:
        # named base_surface was not found in idf file
        print('epnurbs.createopening: unable to find the base surface', base_surface, 'in', idf_filename)
        return

    #################################
    # calculating NURBS curve points
    #################################
    from geomdl import NURBS
    from geomdl import utilities

    # one has to exclude checks for leading zeros and trailing ones in geomdl.utilities.check_knot_vector
    # in order for this knotvector to be allowed!
    utilities.check_knot_vector = new_check_knot_vector
    
    curve = NURBS.Curve()

    # 1/delta corresponds to the number of evaluated points of a NURBS curve that defines the opening
    curve.delta = 1/evaluated_points
    curve.degree = 3

    # add weight 1 to each control point
    for cpt in ctrl_points:
        if len(cpt)<4:
            cpt.append(1.0)

    # add copy of the first degree control points in order to close NURBS curve
    extra_points = ctrl_points[:curve.degree]
    ctrl_points.extend(extra_points)

    # sets curve control points
    curve.set_ctrlpts(ctrl_points)

    # sets knot vector for closed NURBS curve
    # note that the length of ctrl_points has increased for curve.degree due to extend operation
    knotstep = 1/(len(ctrl_points) + curve.degree)
    curve.knotvector = [i*knotstep for i in range(len(ctrl_points)+curve.degree+1)]

    # note that for the closed NURBS curve
    # we have to use only the domain [knotvector[curve.degree], knotvector[len(ctrl_points)]]!!!
    # evaluates curve points
    curve.evaluate(curve.degree*knotstep, len(ctrl_points)*knotstep)

    # make a local copy of evaluated curve points
    crv_points = curve.curvepts

    #########################################################################
    # feet of perpendiculars from the NURBS curve points to the base surface,
    # just to make sure we are not getting out of its plane
    #########################################################################

    # getting the found base_surface's coordinates
    coord = wall.coords
    ulc = coord[0]
    blc = coord[1]
    brc = coord[2]

    # find the base_surface's plane normal and normalize it
    u = [ blc[0]-ulc[0], blc[1]-ulc[1], blc[2]-ulc[2] ]
    v = [ brc[0]-blc[0], brc[1]-blc[1], brc[2]-blc[2] ]
    N = crossproduct(u,v)
    N = normalize(N)

    # calculate feet of perpendiculars
    feet_points = [foot(crv_points[i], ulc, N) for i in range(len(crv_points))]

    #######################################################################################
    # create a list of 0.1m squares that partition the whole wall surface
    # !!! it is assumed that the wall surface is a rectangle
    # !!! three of whose vertices are ulc, blc and brc (and the fourth one is ulc+brc-blc)
    #######################################################################################

    # a new orthonormal system for the wall surface
    u = normalize(u)
    v = crossproduct(N,u)
    v = normalize(v)

    # transform feet_point coordinates to the uv system
    # since N, u, v is an orthonormal system we have that
    # for each vector X = <X,N>N + <X,u>u + <X,v>v
    # this will be applied to vectors feet_points-ulc which belong to the wall surface plane
    feet_points_uv = [ [dotproduct(subtract(fp, ulc), u),
                        dotproduct(subtract(fp, ulc), v)] for fp in feet_points]

    # form a list of squares and a list of their centers in uv coordinates
    squaresize = 0.1
    maxi = int(length(subtract(blc, ulc))/squaresize)-1
    maxj = int(length(subtract(brc, blc))/squaresize)-1

    squarelist = [ [ [ ((i+0.5)*squaresize, (j+0.5)*squaresize), ((i+1.5)*squaresize, (j+0.5)*squaresize),
                       ((i+1.5)*squaresize, (j+1.5)*squaresize), ((i+0.5)*squaresize, (j+1.5)*squaresize) ]
                   for j in range(maxj) ]
                 for i in range(maxi)]
    squarecenters = [ ( (i+1)*squaresize, (j+1)*squaresize ) for i in range(maxi) for j in range(maxj) ]

    # for each square check whether its center belongs to the polygon defined by NURBS curve points
    import matplotlib.path as mplPath
    path = mplPath.Path(feet_points_uv)
    inside = path.contains_points(squarecenters)

    # select only those squares whose centers are inside the NURBS curve
    insideindices = [ [ j for j in range(maxj) if inside[i*maxj+j] ] for i in range(maxi) ]

    # now insideindices[i] contains all j such that squarelist[i][j] is inside a NURBS curve

    #################################################################################
    # create string of idf definitions for rectangles that approximate NURBS opening
    #################################################################################
    idf_total_opening_def = ""

    for i in range(maxi):
        # go through all inside squares within i-th column, if there are any
        if len(insideindices[i])>0:
            # pn and kn contain the beginning and the end of
            # subsequences of consecutive numbers within the insideindices[i] list
            pn = insideindices[i][0]
            kn = insideindices[i][0]

            for k in range(1, len(insideindices[i])+1):
                if k<len(insideindices[i]) and insideindices[i][k]==insideindices[i][k-1]+1:
                    # consecutive subsequence goes on
                    kn = insideindices[i][k]
                else:
                    # consecutive subsequence had ended, so create an opening element
                    # squarelist[i][pn][0],[1] contain its first two vertices in uv system,
                    # squarelist[i][kn][2],[3] contain its last two vertices in uv system
                    # recalculate vertices in xyz system first
                    vertex1 = [ ulc[0] + squarelist[i][pn][0][0] * u[0] + squarelist[i][pn][0][1] * v[0],
                                ulc[1] + squarelist[i][pn][0][0] * u[1] + squarelist[i][pn][0][1] * v[1],
                                ulc[2] + squarelist[i][pn][0][0] * u[2] + squarelist[i][pn][0][1] * v[2] ]
                    vertex2 = [ ulc[0] + squarelist[i][pn][1][0] * u[0] + squarelist[i][pn][1][1] * v[0],
                                ulc[1] + squarelist[i][pn][1][0] * u[1] + squarelist[i][pn][1][1] * v[1],
                                ulc[2] + squarelist[i][pn][1][0] * u[2] + squarelist[i][pn][1][1] * v[2] ]
                    vertex3 = [ ulc[0] + squarelist[i][kn][2][0] * u[0] + squarelist[i][kn][2][1] * v[0],
                                ulc[1] + squarelist[i][kn][2][0] * u[1] + squarelist[i][kn][2][1] * v[1],
                                ulc[2] + squarelist[i][kn][2][0] * u[2] + squarelist[i][kn][2][1] * v[2] ]
                    vertex4 = [ ulc[0] + squarelist[i][kn][3][0] * u[0] + squarelist[i][kn][3][1] * v[0],
                                ulc[1] + squarelist[i][kn][3][0] * u[1] + squarelist[i][kn][3][1] * v[1],
                                ulc[2] + squarelist[i][kn][3][0] * u[2] + squarelist[i][kn][3][1] * v[2] ]
                    
                    vert_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                               vertex1[0], vertex1[1], vertex1[2],
                               vertex2[0], vertex2[1], vertex2[2],
                               vertex3[0], vertex3[1], vertex3[2],
                               vertex4[0], vertex4[1], vertex4[2])
                    countervert_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                      vertex1[0], vertex1[1], vertex1[2],
                                      vertex4[0], vertex4[1], vertex4[2],
                                      vertex3[0], vertex3[1], vertex3[2],
                                      vertex2[0], vertex2[1], vertex2[2])
                    
                    # fill out the entries in the opening string definition
                    single_opening_def = opening_str.replace('<IDX>', str(i)+'_'+str(pn)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vert_str).replace('<COUNTERVERTICES>', countervert_str)
                    idf_total_opening_def = idf_total_opening_def + single_opening_def

                    # a new consecutive subsequence has just begun provided that k<len(insideindices[i])
                    if k<len(insideindices[i]):
                        pn = insideindices[i][k]
                        kn = insideindices[i][k]
     
    # create idf opening objects from the string containing opening definitions   
    from io import StringIO
    idf_opening = IDF(StringIO(idf_total_opening_def))

    # copy idf shading objects to the existing idf file
    openings = idf_opening.idfobjects["FENESTRATIONSURFACE:DETAILED"]
    for opening in openings:
        idf_collection.copyidfobject(opening)
    
    ###############################
    # at the end, save the changes
    ###############################
    idf_collection.save()