Example #1
0
def delete_cmplx_HVAC(originalidf_path,savefolder_path):
    """
    Deletes All HVAC fields
    It is useful if there is no DHW system modeled in the IDF file

    :param originalidf_path: Path for the original IDF with a complex HVAC data
    :return: savefolder_path: Path to use where all converted files will be saved
    """
    # 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")

    # 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')]

    # Deleting all HVAC and DHW objects in our filtered list
    for HVAC_obj in HVAC_related_list:
        idf.removeallidfobjects(HVAC_obj)

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

    return editedidf
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 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 #4
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 #5
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