Beispiel #1
0
def test_initread():
    """Test for IDF.initread() with filename in unicode and as python str."""
    # setup
    idf = IDF()
    idf.initreadtxt(idfsnippet)
    idf.saveas("tmp.idf")

    # test fname as unicode
    fname = "tmp.idf"
    assert isinstance(fname, string_types)
    idf = IDF()
    idf.initread(fname)
    assert idf.getobject("BUILDING", "Building")

    # test fname as str
    fname = str("tmp.idf")
    assert isinstance(fname, string_types)
    idf = IDF()
    idf.initread(fname)
    assert idf.getobject("BUILDING", "Building")

    # test that a nonexistent file raises an IOError
    fname = "notarealfilename.notreal"
    idf = IDF()
    try:
        idf.initread(fname)
        assert False  # shouldn't reach here
    except IOError:
        pass

    # teardown
    os.remove("tmp.idf")
Beispiel #2
0
def auto_generate_from_template(peak_heating_w, peak_cooling_w, base_LP_idf,
                                base_plant_idf, plant_configuration_json_file,
                                out_dir, final_idf_name, idd_file):
    expanded_plant_loop_idf = 'expanded.idf'
    LP_plant_loop_idf = 'plant_loop.idf'
    temp_base_LP_idf = 'temp_base_LP.idf'

    # Update the flow rate for the loadprofile:plant objects
    IDF.setiddname(idd_file)
    idf = IDF(base_LP_idf)
    idf = auto_update_LP_flow_rates(idf, peak_heating_w, peak_cooling_w)
    idf.saveas(temp_base_LP_idf)

    modify_template_idf(plant_configuration_json_file,
                        base_plant_idf,
                        idd_file=idd_file)
    expand_template_idf()
    prepare_LP_plantloop(expanded_plant_loop_idf,
                         LP_plant_loop_idf,
                         idd_file=idd_file)
    append_files(temp_base_LP_idf, LP_plant_loop_idf, final_idf_name)

    cleanup(temp_base_LP_idf)
    cleanup(expanded_plant_loop_idf)
    cleanup(LP_plant_loop_idf)
    cleanup('expandedidf.err')
    cleanup('in.idf')
    if not os.path.exists(out_dir):
        os.mkdir(out_dir)
    shutil.move(final_idf_name, f"{out_dir}{final_idf_name}")
Beispiel #3
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
Beispiel #4
0
    def write_to_idf(self, edited_schedule, idf_file, new_file):
        """
        method to write schedule to IDF
        :param edited_schedule: str -> schedule that is edited
        :param idf_file: original IDF from which base schedule is extracted
        :param new_file: name of new file to which the schedule is written
        """

        idf_0 = IDF(idfname=idf_file)
        idf_0.saveas(new_file)

        with open(new_file, "a") as file:
            file.write("\n\n")
            file.write(edited_schedule)

        idf = IDF(idfname=new_file)
        # IDF.setiddname(self.idd_file)
        DualSetpoints = idf.idfobjects["ThermostatSetpoint:DualSetpoint"]

        if self.schedule_type == "CLGSETP":
            for DualSetpoint in DualSetpoints:
                DualSetpoint[
                    "Cooling_Setpoint_Temperature_Schedule_Name"] = self.schedule_name_edited
        elif self.schedule_type == "HTGSETP":
            for DualSetpoint in DualSetpoints:
                DualSetpoint[
                    "Heating_Setpoint_Temperature_Schedule_Name"] = self.schedule_name_edited
        else:
            print("Enter Valid SETP")

        idf.saveas(new_file)

        return None
Beispiel #5
0
def test_initread():
    """Test for IDF.initread() with filename in unicode and as python str.
    """
    # setup
    idf = IDF()
    idf.initreadtxt(idfsnippet)
    idf.saveas('tmp.idf')

    # test fname as unicode
    fname = 'tmp.idf'
    assert isinstance(fname, string_types)
    idf = IDF()
    idf.initread(fname)
    assert idf.getobject('BUILDING', 'Building')

    # test fname as str
    fname = str('tmp.idf')
    assert isinstance(fname, string_types)
    idf = IDF()
    idf.initread(fname)
    assert idf.getobject('BUILDING', 'Building')

    # test that a nonexistent file raises an IOError
    fname = "notarealfilename.notreal"
    idf = IDF()
    try:
        idf.initread(fname)
        assert False  # shouldn't reach here
    except IOError:
        pass

    # teardown
    os.remove('tmp.idf')
Beispiel #6
0
def modify_template_idf(plant_configuration_json_file,
                        base_template_idf='base_plant.idf',
                        modified_template_idf='in.idf',
                        idd_file="C:/EnergyPlusV9-1-0/Energy+.idd"):

    IDF.setiddname(idd_file)
    idf = IDF(base_template_idf)
    with open(plant_configuration_json_file) as json_file:
        data = json.load(json_file)

    def add_template_chiller(idf,
                             chiller_name,
                             chiller_type='ElectricCentrifugalChiller',
                             cop=3.5,
                             condenser_type='WaterCooled'):
        idf.newidfobject("HVACTemplate:Plant:Chiller")
        idf_new_template_chiller = idf.idfobjects[
            'HVACTemplate:Plant:Chiller'][-1]
        idf_new_template_chiller.Name = chiller_name
        idf_new_template_chiller.Chiller_Type = chiller_type
        idf_new_template_chiller.Nominal_COP = cop
        idf_new_template_chiller.Condenser_Type = condenser_type
        idf_new_template_chiller.Priority = 1
        idf_new_template_chiller.Sizing_Factor = ''
        idf_new_template_chiller.Minimum_Part_Load_Ratio = ''
        idf_new_template_chiller.Maximum_Part_Load_Ratio = ''
        idf_new_template_chiller.Optimum_Part_Load_Ratio = ''
        idf_new_template_chiller.Minimum_Unloading_Ratio = ''
        idf_new_template_chiller.Leaving_Chilled_Water_Lower_Temperature_Limit = ''
        return idf

    def add_template_boiler(idf,
                            boiler_name,
                            efficiency=0.8,
                            fuel_type="NaturalGas"):
        idf.newidfobject("HVACTemplate:Plant:Boiler")
        idf_new_template_boiler = idf.idfobjects['HVACTemplate:Plant:Boiler'][
            -1]
        idf_new_template_boiler.Name = boiler_name
        idf_new_template_boiler.Efficiency = efficiency
        idf_new_template_boiler.Fuel_Type = fuel_type
        return idf

    for count, chiller in enumerate(data['chillers']):
        idf = add_template_chiller(idf, f"Chiller No. {count+1}",
                                   chiller['type'], chiller['COP'],
                                   chiller['condenser'])

    for count, boiler in enumerate(data['boilers']):
        idf = add_template_boiler(idf,
                                  f"Boiler No. {count+1}",
                                  boiler['efficiency'],
                                  fuel_type=boiler['fuel'])

    print('---> Adding template chiller and boiler done.')
    idf.saveas(modified_template_idf)
Beispiel #7
0
def batch():
    t_id = []
    city_id = []
    length = []
    width = []
    height = []
    window = []
    orient = []
    i = 1
    for fname1 in fname:
        idf1 = IDF('baseline/' + fname1)
        for orientation1 in orientation:
            for length1 in lengths:
                for width1 in widths:
                    for height1 in heights:
                        for fenes in fenestration:
                            idf1.idfobjects["ZONE"][
                                0].Direction_of_Relative_North = orientation1
                            idf1 = surfaces(idf1,
                                            x=length1,
                                            y=width1,
                                            z=height1)
                            idf1 = windows(idf1, p=fenes)
                            city1 = re.search('(.*).idf', fname1).group(1)
                            t_id.append(i)
                            city_id.append(city1)
                            length.append(length1)
                            width.append(width1)
                            height.append(height1)
                            window.append(fenes)
                            orient.append(orientation1)
                            idf1.saveas('idf_files/' + city1 + str(i) + '.idf')
                            print(str(i) + "/" + str(total))
                            i += 1
    data_raw = {
        'id': t_id,
        'city': city_id,
        'length': length,
        'width': width,
        'height': height,
        'orientation': orient,
        'window_ratio': window
    }
    df = pd.DataFrame(data_raw)
    df.to_csv("model_inputs.csv", index=False)
Beispiel #8
0
    def test_save_as(self):
        """Test saveas with a changed filename.
        
        IDF.saveas(fname) changes the filename. The next save should save with 
        new name.
        
        Fails if the filename isn't changed on the file with the new name.
        """
        idf = IDF(self.startfile)
        idf.saveas(self.saveasfile)  # sets the new filename
        setversion(idf, '7.4')
        idf.save()  # should also save with the new filename
        idf2 = IDF(self.saveasfile)
        
        result = getversion(idf2)
        expected = '7.4'

        assert result == expected
Beispiel #9
0
    def test_save_as(self):
        """Test saveas with a changed filename.

        IDF.saveas(fname) changes the filename. The next save should save with
        new name.

        Fails if the filename isn't changed on the file with the new name.
        """
        idf = IDF(self.startfile)
        idf.saveas(self.saveasfile)  # sets the new filename
        setversion(idf, "7.4")
        idf.save()  # should also save with the new filename
        idf2 = IDF(self.saveasfile)

        result = getversion(idf2)
        expected = "7.4"

        assert result == expected
Beispiel #10
0
def modify_idf(design, designs, idf_path):
    # Load idf file
    idf1 = IDF('./Models/ss1_idfs/ss1_{:02d}.idf'.format(design))

    # Setup fields to be changed
    building = 'Building'
    building = idf1.idfobjects[building.upper()][0]

    # Set object information
    building.Name = 'Building Design {:02d}/{:02d}'.format(design, designs)
    building.North_Axis = '0'

    print('IDF file setup for {} completed'.format(building.Name))

    idf_path = './Models/ss1_idfs'

    idf1.saveas('{}/ss1_{:02d}.idf'.format(idf_path, design))
    idf_file = '{}/ss1_{:02d}.idf'.format(idf_path, design)

    return idf_file
Beispiel #11
0
def test_saveas():
    """Test the IDF.saveas() function."""
    file_text = "Material,TestMaterial,  !- Name"
    idf = IDF(StringIO(file_text))
    idf.idfname = "test.idf"

    try:
        idf.saveas()  # this should raise an error as no filename is passed
        assert False
    except TypeError:
        pass

    file_handle = StringIO()
    idf.saveas(file_handle)  # save with a filehandle
    expected = "TestMaterial"
    file_handle.seek(0)
    result = file_handle.read()
    assert expected in result

    # test the idfname attribute has been changed
    assert idf.idfname != "test.idf"
Beispiel #12
0
def test_saveas():
    """Test the IDF.saveas() function.
    """
    file_text = "Material,TestMaterial,  !- Name"
    idf = IDF(StringIO(file_text))
    idf.idfname = 'test.idf'

    try:
        idf.saveas()  # this should raise an error as no filename is passed
        assert False
    except TypeError:
        pass

    file_handle = StringIO()
    idf.saveas(file_handle)  # save with a filehandle
    expected = "TestMaterial"
    file_handle.seek(0)
    result = file_handle.read()
    assert expected in result

    # test the idfname attribute has been changed
    assert idf.idfname != 'test.idf'
Beispiel #13
0
def createidfinafolder():
    """make a temp dir and save an idf in it

    :Teardown: remove the temp dir and it'a contents"""
    # make a temp dir
    tdirname = "./atempdir1"
    abspath = os.path.abspath(tdirname)
    os.mkdir(tdirname)
    # make blank file
    idftxt = ""  # empty string
    fhandle = StringIO(idftxt)
    idf = IDF(fhandle)
    # put in some objects - building and version
    building = idf.newidfobject("building")
    building.Name = "Taj"
    idf.newidfobject("version")
    # save it in subdir1
    fname = f"{tdirname}/a.idf"
    idf.saveas(fname)

    yield idf
    # Teardown
    # remove the temp dir
    shutil.rmtree(abspath)
Beispiel #14
0
def datacomp(yc_keys, xc_keys, tc_keys):
    iddfile = "./Energy+9.1.idd"
    IDF.setiddname(iddfile)

    yc_df = pd.DataFrame(columns=yc_keys)
    xc_df = pd.DataFrame(columns=xc_keys)
    tc_df = pd.DataFrame(columns=tc_keys)
    for n in range(len(LHS_result)):
        idfname = "./RefBldgLargeOfficeNew2004_Chicago.idf"
        idf = IDF(idfname)

        # change the output variable and meter
        # output_frequency='Daily'
        output_frequency = 'Monthly'

        variable = []
        for i in range(len(xc_keys)):
            variable1 = idf.newidfobject("Output:Variable".upper())
            variable1.Key_Value = '*'
            variable1.Variable_Name = xc_keys[i]
            variable1.Reporting_Frequency = output_frequency
            variable.append(variable1)
        idf.idfobjects['Output:Variable'.upper()] = variable

        meter = []
        for i in range(len(yc_keys)):
            meter1 = idf.newidfobject("Output:Meter".upper())
            meter1.Key_Name = yc_keys[i]
            meter1.Reporting_Frequency = output_frequency
            meter.append(meter1)
        idf.idfobjects['Output:Meter'.upper()] = meter

        # change the runperiod and other idf objects
        for i in range(len(idf.idfobjects['LIGHTS'])):
            idf.idfobjects['LIGHTS'][i].Watts_per_Zone_Floor_Area = LHS_result[
                n][0]

        for i in range(len(idf.idfobjects['ELECTRICEQUIPMENT'])):
            idf.idfobjects['ELECTRICEQUIPMENT'][
                i].Watts_per_Zone_Floor_Area = LHS_result[n][1]

        for i in range(len(idf.idfobjects['FAN:VARIABLEVOLUME'])):
            # idf.idfobjects['FAN:VARIABLEVOLUME'][i].Pressure_Rise=LHS_result[n][2]
            idf.idfobjects['FAN:VARIABLEVOLUME'][
                i].Fan_Total_Efficiency = LHS_result[n][2]

        for i in range(len(idf.idfobjects['ZONEINFILTRATION:DESIGNFLOWRATE'])):
            idf.idfobjects['ZONEINFILTRATION:DESIGNFLOWRATE'][
                i].Flow_per_Exterior_Surface_Area = LHS_result[n][3]

        for i in range(len(
                idf.idfobjects['CHILLER:ELECTRIC:REFORMULATEDEIR'])):
            idf.idfobjects['CHILLER:ELECTRIC:REFORMULATEDEIR'][
                i].Reference_COP = LHS_result[n][4]

        for i in range(len(idf.idfobjects['BOILER:HOTWATER'])):
            idf.idfobjects['BOILER:HOTWATER'][
                i].Nominal_Thermal_Efficiency = LHS_result[n][5]
        # for i in range(len(idf.idfobjects['SCHEDULE:COMPACT'])):
        #     if 'Building_Cooling_Sp_Schedule' in idf.idfobjects['SCHEDULE:COMPACT'][i].Name:
        #         idf.idfobjects['SCHEDULE:COMPACT'][i].Field_4=LHS_result[n][4]

        idf.idfobjects['RUNPERIOD'][0].Begin_Month = 1
        idf.idfobjects['RUNPERIOD'][0].Begin_Day_of_Month = 1
        idf.idfobjects['RUNPERIOD'][0].End_Month = 12
        idf.idfobjects['RUNPERIOD'][0].End_Day_of_Month = 31

        idf.saveas('C:/Users/songc/Desktop/work file/Updated_Model.idf')
        idfname1 = 'C:/Users/songc/Desktop/work file/Updated_Model.idf'  # This IDF file is updated at each iteration.
        epwfile = './SPtMasterTable_52384_2011_amy.epw'
        subprocess.call([
            'C:/EnergyPlusV9-1-0/energyplus.exe', '-d',
            "C:/Users/songc/Desktop/work file/result_folder", '-w', epwfile,
            idfname1
        ])

        eso_file = './result_folder/eplusout.eso'
        [ycoutput, xcoutput] = comp_data_reader(eso_file, yc_keys, xc_keys)
        yc_df = yc_df.append(pd.DataFrame(ycoutput, index=yc_keys).T)
        xc_df = xc_df.append(pd.DataFrame(xcoutput, index=xc_keys).T)
        tc_df = tc_df.append(
            pd.DataFrame(np.reshape(
                list(LHS_result[n]) * len(ycoutput[0]),
                (len(ycoutput[0]), len(tc_keys))),
                         columns=tc_keys))

    df = pd.concat([yc_df, xc_df, tc_df], axis=1)
    df.to_csv('DATACOMP_Multi.csv', index=False)
    df_single = pd.concat([yc_df.iloc[:, 0], xc_df, tc_df], axis=1)
    df_single.to_csv('DATACOMP_Single.csv', index=False)
Beispiel #15
0
def create_IdealLoads_objects(originalidf_path,savefolder_path):
    """
    Function to get inputs from the interim file and using them to create new IdealLoads objects

    :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
    interimidf = IDF(f"{savefolder_path}\\{building}_BuildME_interim.idf")
    editedidf= IDF(f"{savefolder_path}\\{building}_BuildME_cleaned.idf")

    zone_names = editedidf.idfobjects["Zone".upper()]

    for zone in zone_names:
        # Generic Parameter Definition
        newzone = editedidf.newidfobject("HVACTemplate:Zone:IdealLoadsAirSystem")
        newthermos = editedidf.newidfobject("HVACTemplate:Thermostat")

        newzone.Zone_Name = zone.Name
        newthermos.Name = "dual_thermostat_" + zone.Name
        newzone.Template_Thermostat_Name = newthermos.Name
        newzone.System_Availability_Schedule_Name = "ALWAYS_ON"
        newzone.Heating_Availability_Schedule_Name = "ALWAYS_ON"
        newzone.Cooling_Availability_Schedule_Name = "ALWAYS_ON"
        newzone.Maximum_Heating_Air_Flow_Rate = "autosize"
        newzone.Maximum_Sensible_Heating_Capacity = "autosize"
        newzone.Maximum_Total_Cooling_Capacity = "autosize"
        newzone.Maximum_Cooling_Air_Flow_Rate = "autosize"
        newzone.Humidification_Setpoint = "65"
        newzone.Dehumidification_Setpoint = ""
        newzone.Heating_Limit = "LimitFlowRateAndCapacity"
        newzone.Cooling_Limit = "LimitFlowRateAndCapacity"

        # Customization Part: Getting the approximate values from the complex HVAC version of the IDF
        for items in interimidf.idfobjects["DesignSpecification:OutdoorAir".upper()]:
            if newzone.Zone_Name in items.Name:
                newzone.Outdoor_Air_Flow_Rate_per_Zone_Floor_Area = items.Outdoor_Air_Flow_per_Zone_Floor_Area
                newzone.Outdoor_Air_Method = items.Outdoor_Air_Method
        for items in interimidf.idfobjects["Sizing:Zone".upper()]:
            if newzone.Zone_Name == items.Zone_or_ZoneList_Name:
                newzone.Minimum_Cooling_Supply_Air_Humidity_Ratio = items.Zone_Cooling_Design_Supply_Air_Humidity_Ratio
                newzone.Maximum_Heating_Supply_Air_Humidity_Ratio = items.Zone_Heating_Design_Supply_Air_Humidity_Ratio
                newzone.Minimum_Cooling_Supply_Air_Temperature = items.Zone_Cooling_Design_Supply_Air_Temperature
                newzone.Maximum_Heating_Supply_Air_Temperature = items.Zone_Heating_Design_Supply_Air_Temperature

        for items in interimidf.idfobjects["Controller:OutdoorAir".upper()]:
            newzone.Outdoor_Air_Economizer_Type = items.Economizer_Control_Type

        for items in interimidf.idfobjects["AirLoopHVAC:UnitarySystem".upper()]:
            newzone.Dehumidification_Control_Type = items.Dehumidification_Control_Type

        # Warning: The following code creates missing fields if the schedule names do not correspond the zone name
        for items in interimidf.idfobjects["ThermostatSetpoint:DualSetpoint".upper()]:
            if newzone.Zone_Name in items.Name:
                newthermos.Heating_Setpoint_Schedule_Name = items.Heating_Setpoint_Temperature_Schedule_Name
                newthermos.Cooling_Setpoint_Schedule_Name = items.Cooling_Setpoint_Temperature_Schedule_Name

        building = str(editedidf.idfobjects["Building".upper()][0].Name)
        editedidf.saveas(f"IdealLoads_{building}_converted.idf")

    os.remove(f"{savefolder_path}\\{building}_BuildME_interim.idf")
    os.remove(f"{savefolder_path}\\{building}_BuildME_cleaned.idf")
    return print("The conversion process is completed, the new IDF with Ideal Loads is saved")
Beispiel #16
0
# <markdowncell>

# This is easy:

# <codecell>

idf1.save()

# <markdowncell>

# If you'd like to do a "Save as..." use this:

# <codecell>

idf1.saveas('something.idf')

# <headingcell level=2>

# Working with E+ objects

# <markdowncell>

# Let us open a small idf file that has only "CONSTRUCTION" and "MATERIAL" objects in it. You can go into "../idffiles/V_7_2/constructions.idf" and take a look at the file. We are not printing it here because it is too big.  
# 
# So let us open it using the idfreader -

# <codecell>

from eppy import modeleditor
from eppy.modeleditor import IDF
Beispiel #17
0
iddfile = "../../eppy/resources/iddfiles/Energy+V8_1_0.idd"
fname1 = "../../eppy/resources/idffiles/V8_1_0/Boiler.idf"

# In[2]:

IDF.setiddname(iddfile)
idf1 = IDF(fname1)

# In[3]:

idf1 = IDF(fname1)

# In[4]:

idf1.saveas("bl_original.idf")

# In[5]:

keys = list(idf1.idfobjects.keys())

# In[6]:

# rename object name with a colon and any field that refers to that name
from eppy.bunch_subclass import BadEPFieldError

renamednames = []
for key in keys:
    for idfobject in idf1.idfobjects[key]:
        try:
            name = idfobject.Name
Beispiel #18
0
def main():
    idf_name_in = 'Baseline.idf'
    idf_name_out_1 = 'Calibrating.idf'
    idf_name_out_2 = 'Calibrating_HM_Occ.idf'
    idf_name_out_3 = 'Calibrating_v0.3.idf'

    epw_name = 'in.epw'

    dir_name = os.path.dirname(os.path.realpath(__file__))
    idd_file = "C:/EnergyPlusV8-9-0/Energy+.idd"
    IDF.setiddname(idd_file)

    idf_path = dir_name + '/' + idf_name_in
    epw_path = dir_name + '/' + epw_name

    out = dir_name + '/out_' + idf_name_in.split('.idf')[0]

    idf = IDF(idf_path, epw_path)
    # idf.saveas('Baseline_v0.0.idf')

    # idf.saveas("tweaked_CBES_model_v0.0.idf")

    v_materials = idf.idfobjects['MATERIAL']
    v_window_materials = idf.idfobjects['WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM']
    v_constructions = idf.idfobjects['CONSTRUCTION']
    v_lights = idf.idfobjects['LIGHTS']
    v_equipment = idf.idfobjects['ELECTRICEQUIPMENT']
    v_people = idf.idfobjects['PEOPLE']

    v_boilers = idf.idfobjects['BOILER:HOTWATER']
    v_waterHeaters = idf.idfobjects['WATERHEATER:MIXED']
    v_chillers = idf.idfobjects['COIL:COOLING:DX:TWOSPEED']

    v_infiltrations = idf.idfobjects['ZONEINFILTRATION:DESIGNFLOWRATE']
    v_DS_OA = idf.idfobjects['DESIGNSPECIFICATION:OUTDOORAIR']

    # print([construction.Name for construction in v_constructions])

    # Calibrating settings
    t_ext_wall_thickness = 0.8
    t_ext_wall_conductivity = 1.5
    t_ext_floor_thickness = 1
    t_ext_floor_conductivity = 1
    t_window_U = 1.2
    t_window_SHGC = 0.8
    t_LPD = 1
    t_EPD = 1
    t_occ_density = 1.5
    t_boiler_eff = 0.9
    t_waterHeater_eff = 0.9
    t_chiller_eff = 0.9
    t_infiltration = 2.5
    t_OA_per_person = 1.4

    ############################## Tweak the model #################################
    for construction in v_constructions:
        # 1. Change the exterior wall construction
        # Change exterior wall construction
        if ('ext wall' in construction.Name):
            # print(construction)
            # Find and change the material of the outside layer
            material_1st_layer = construction.get_referenced_object(
                'Outside_Layer')
            material_2nd_layer = construction.get_referenced_object('Layer_2')
            material_3rd_layer = construction.get_referenced_object('Layer_3')
            material_4th_layer = construction.get_referenced_object('Layer_4')
            material_1st_layer = modify_object_property(
                material_1st_layer, 'Thickness', times=t_ext_wall_thickness)
            material_2nd_layer = modify_object_property(
                material_2nd_layer, 'Thickness', times=t_ext_wall_thickness)
            material_3rd_layer = modify_object_property(
                material_3rd_layer, 'Thickness', times=t_ext_wall_thickness)
            material_4th_layer = modify_object_property(
                material_4th_layer, 'Thickness', times=t_ext_wall_thickness)
            material_1st_layer = modify_object_property(
                material_1st_layer,
                'Conductivity',
                times=t_ext_wall_conductivity)
            material_2nd_layer = modify_object_property(
                material_2nd_layer,
                'Conductivity',
                times=t_ext_wall_conductivity)
            material_3rd_layer = modify_object_property(
                material_3rd_layer,
                'Conductivity',
                times=t_ext_wall_conductivity)
            material_4th_layer = modify_object_property(
                material_4th_layer,
                'Conductivity',
                times=t_ext_wall_conductivity)

        # Change interior wall construction
        if ('int wall' in construction.Name):
            # print(construction)
            material_1st_layer = construction.get_referenced_object(
                'Outside_Layer')
            material_2nd_layer = construction.get_referenced_object('Layer_2')
            # print(material_1st_layer)
            # print(material_2nd_layer)
            continue
            # print(construction)
        # Change exterior floor construction
        if ('ext floor' in construction.Name):
            # print(construction)
            material_1st_layer = construction.get_referenced_object(
                'Outside_Layer')
            material_2nd_layer = construction.get_referenced_object('Layer_2')
            material_1st_layer = modify_object_property(
                material_1st_layer, 'Thickness', times=t_ext_floor_thickness)
            material_2nd_layer = modify_object_property(
                material_2nd_layer, 'Thickness', times=t_ext_floor_thickness)
            material_1st_layer = modify_object_property(
                material_1st_layer,
                'Conductivity',
                times=t_ext_floor_conductivity)
            material_2nd_layer = modify_object_property(
                material_2nd_layer,
                'Conductivity',
                times=t_ext_floor_conductivity)
            continue

    # 2. Change the window properties
    for construction in v_constructions:
        if ('glazing' in construction.Name):
            material_1st_layer = construction.get_referenced_object(
                'Outside_Layer')
            material_1st_layer = modify_object_property(material_1st_layer,
                                                        'UFactor',
                                                        times=t_window_U)
            material_1st_layer = modify_object_property(
                material_1st_layer,
                'Solar_Heat_Gain_Coefficient',
                times=t_window_SHGC)

    # idf.saveas(idf_name_out_2)

    # 3. Change the lighting power density
    for light in v_lights:
        light = modify_object_property(light,
                                       'Watts_per_Zone_Floor_Area',
                                       times=t_LPD)
        continue

    # 4. Change the interior equipment power density
    for equipment in v_equipment:
        equipment = modify_object_property(equipment,
                                           'Watts_per_Zone_Floor_Area',
                                           times=t_EPD)
        continue

    # idf.saveas(idf_name_out_3)

    # 5. Change the occupancy settings
    for people in v_people:
        people = modify_object_property(people,
                                        'People_per_Zone_Floor_Area',
                                        times=t_occ_density)
        continue

    # 6. Change HVAC equipment
    for boiler in v_boilers:
        boiler = modify_object_property(boiler,
                                        'Nominal_Thermal_Efficiency',
                                        times=t_boiler_eff)
        continue

    for waterHeater in v_waterHeaters:
        waterHeater = modify_object_property(waterHeater,
                                             'Heater_Thermal_Efficiency',
                                             times=t_waterHeater_eff)
        continue

    for chiller in v_chillers:
        chiller = modify_object_property(chiller,
                                         'High_Speed_Gross_Rated_Cooling_COP',
                                         times=t_chiller_eff)
        continue

    # Change infiltration settings
    for infiltration in v_infiltrations:
        infiltration = modify_object_property(infiltration,
                                              'Air_Changes_per_Hour',
                                              times=t_infiltration)
        continue

    # Change outdoor air design specification
    for ds_OA in v_DS_OA:
        ds_OA = modify_object_property(ds_OA,
                                       'Outdoor_Air_Flow_per_Person',
                                       times=t_OA_per_person)

    idf.saveas(idf_name_out_1)
Beispiel #19
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
Beispiel #20
0
def main():
    idf_name_in = 'tweaked_CBES_model_v0.0.idf'
    idf_name_out_1 = 'tweaked_CBES_model_v0.1.idf'
    idf_name_out_2 = 'tweaked_CBES_model_v0.2.idf'
    idf_name_out_3 = 'tweaked_CBES_model_v0.3.idf'

    epw_name = 'USA_PA_Pittsburgh.Intl.AP.725200_TMY3.epw'

    dir_name = os.path.dirname(os.path.realpath(__file__))
    idd_file = "C:/EnergyPlusV8-9-0/Energy+.idd"
    IDF.setiddname(idd_file)

    idf_path = dir_name + '/' + idf_name_in
    epw_path = dir_name + '/' + epw_name

    out = dir_name + '/out_' + idf_name_in.split('.idf')[0]

    idf = IDF(idf_path, epw_path)

    # idf.saveas("tweaked_CBES_model_v0.0.idf")

    v_materials = idf.idfobjects['MATERIAL']
    v_window_materials = idf.idfobjects['WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM']
    v_constructions = idf.idfobjects['CONSTRUCTION']
    v_lights = idf.idfobjects['LIGHTS']

    # print([construction.Name for construction in v_constructions])

    ############################## Tweak the model #################################
    for construction in v_constructions:
        # 1. Change the exterior wall construction
        # Change exterior wall construction
        if ('ext wall' in construction.Name):
            # print(construction)
            # Find and change the material of the outside layer
            material_1st_layer = construction.get_referenced_object(
                'Outside_Layer')
            material_2nd_layer = construction.get_referenced_object('Layer_2')
            material_3rd_layer = construction.get_referenced_object('Layer_3')
            material_4th_layer = construction.get_referenced_object('Layer_4')
            material_1st_layer = modify_material_property(material_1st_layer,
                                                          'Thickness',
                                                          times=2)
            material_2nd_layer = modify_material_property(material_2nd_layer,
                                                          'Thickness',
                                                          times=2)
            material_3rd_layer = modify_material_property(material_3rd_layer,
                                                          'Thickness',
                                                          times=2)
            material_4th_layer = modify_material_property(material_4th_layer,
                                                          'Thickness',
                                                          times=2)
            material_1st_layer = modify_material_property(material_1st_layer,
                                                          'Conductivity',
                                                          times=0.5)
            material_2nd_layer = modify_material_property(material_2nd_layer,
                                                          'Conductivity',
                                                          times=0.5)
            material_3rd_layer = modify_material_property(material_3rd_layer,
                                                          'Conductivity',
                                                          times=0.5)
            material_4th_layer = modify_material_property(material_4th_layer,
                                                          'Conductivity',
                                                          times=0.5)

        # Change interior wall construction
        if ('int wall' in construction.Name):
            # print(construction)
            material_1st_layer = construction.get_referenced_object(
                'Outside_Layer')
            material_2nd_layer = construction.get_referenced_object('Layer_2')
            # print(material_1st_layer)
            # print(material_2nd_layer)
            continue
            # print(construction)
        # Change exterior floor construction
        if ('ext floor' in construction.Name):
            # print(construction)
            material_1st_layer = construction.get_referenced_object(
                'Outside_Layer')
            material_2nd_layer = construction.get_referenced_object('Layer_2')
            material_1st_layer = modify_material_property(material_1st_layer,
                                                          'Thickness',
                                                          times=2)
            material_2nd_layer = modify_material_property(material_2nd_layer,
                                                          'Thickness',
                                                          times=2)
            material_1st_layer = modify_material_property(material_1st_layer,
                                                          'Conductivity',
                                                          times=0.5)
            material_2nd_layer = modify_material_property(material_2nd_layer,
                                                          'Conductivity',
                                                          times=0.5)
            continue

    idf.saveas(idf_name_out_1)

    # 2. Change the window properties
    for construction in v_constructions:
        if ('glazing' in construction.Name):
            material_1st_layer = construction.get_referenced_object(
                'Outside_Layer')
            material_1st_layer = modify_material_property(material_1st_layer,
                                                          'UFactor',
                                                          new_val=6)
            material_1st_layer = modify_material_property(
                material_1st_layer, 'Solar_Heat_Gain_Coefficient', new_val=0.8)

    idf.saveas(idf_name_out_2)

    # 3. Change the lighting power density
    for light in v_lights:
        light['Watts_per_Zone_Floor_Area'] = 18

    idf.saveas(idf_name_out_3)
Beispiel #21
0
surfaces = idf1.idfobjects['BUILDINGSURFACE:DETAILED']
csurfaces = copy(surfaces)

count = 0
print len(surfaces)
for surface in csurfaces:
    s = simplesurface.simplesufrace(idf1, surface, deletebsd=True, setto000=True)
    if not s:
        print surface.Name
    count += 1
print count
print len(csurfaces)    
print len(surfaces)    

fens = idf1.idfobjects['FENESTRATIONSURFACE:DETAILED']
cfens = copy(fens)
print len(fens)  
count = 0
for fen in cfens:
    f = simplesurface.simplefenestration(idf1, fen, deletebsd=True, setto000=True)
    if not f:
        print fen.Name
    count += 1
print count 
print len(cfens) 
print len(fens) 

newfname1 = "/Volumes/Server/Staff/Santosh/mike_eplus/working/5ZoneSupRetPlenRAB_flat.idf"

idf1.saveas(newfname1)
Beispiel #22
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
Beispiel #23
0
# <markdowncell>

# This is easy:

# <codecell>

idf1.save()

# <markdowncell>

# If you'd like to do a "Save as..." use this:

# <codecell>

idf1.saveas('something.idf')

# <headingcell level=2>

# Working with E+ objects

# <markdowncell>

# Let us open a small idf file that has only "CONSTRUCTION" and "MATERIAL" objects in it. You can go into "../idffiles/V_7_2/constructions.idf" and take a look at the file. We are not printing it here because it is too big.
#
# So let us open it using the idfreader -

# <codecell>

from eppy import modeleditor
from eppy.modeleditor import IDF
Beispiel #24
0
def prepare_LP_plantloop(expanded_plant_loop_idf='expanded.idf',
                         LP_plant_loop_idf='plant_loop.idf',
                         idd_file="C:/EnergyPlusV9-1-0/Energy+.idd"):
    # constants
    BRANCH_TO_DELETE = [
        'Test room Cooling Coil ChW Branch', 'Test room Heating Coil HW Branch'
    ]
    DEMAND_BRANCH_LISTS = [
        'Hot Water Loop HW Demand Side Branches',
        'Chilled Water Loop ChW Demand Side Branches'
    ]
    DEMAND_SPLITTER_LISTS = [
        'Hot Water Loop HW Demand Splitter',
        'Chilled Water Loop ChW Demand Splitter'
    ]
    DEMAND_MIXER_LISTS = [
        'Hot Water Loop HW Demand Mixer', 'Chilled Water Loop ChW Demand Mixer'
    ]
    OLD_HW_LP_BRANCH_NAME = 'Test room Heating Coil HW Branch'
    OLD_CW_LP_BRANCH_NAME = 'Test room Cooling Coil ChW Branch'
    NEW_HW_LP_BRANCH_NAME = 'Hot Water Loop Load Profile Demand Branch'
    NEW_CW_LP_BRANCH_NAME = 'Chilled Water Loop Load Profile Demand Branch'

    idf_file = expanded_plant_loop_idf
    IDF.setiddname(idd_file)
    idf = IDF(idf_file)

    branches = idf.idfobjects['Branch']
    branche_lists = idf.idfobjects['BranchList']
    splitter_lists = idf.idfobjects['Connector:Splitter']
    mixer_lists = idf.idfobjects['Connector:Mixer']

    # 1. Remove unnecessary objects
    def remove_all_obj_by_type(idf, obj_type_name, exception_name_list=[]):
        if exception_name_list == []:
            idf.idfobjects[obj_type_name] = []
        else:
            old_objcts = idf.idfobjects[obj_type_name]
            idf.idfobjects[obj_type_name] = [
                obj for obj in old_objcts if obj.Name in exception_name_list
            ]
        return idf

    remove_all_obj_by_type(idf, 'Sizing:Parameters')
    remove_all_obj_by_type(idf, 'ScheduleTypeLimits',
                           ['HVACTemplate Any Number'])
    remove_all_obj_by_type(
        idf, 'Schedule:Compact',
        ['HVACTemplate-Always 1', 'HVACTemplate-Always 29.4'])
    remove_all_obj_by_type(idf, 'DesignSpecification:OutdoorAir')
    remove_all_obj_by_type(idf, 'Sizing:Zone')
    remove_all_obj_by_type(idf, 'DesignSpecification:ZoneAirDistribution')
    remove_all_obj_by_type(idf, 'ZoneHVAC:EquipmentConnections')
    remove_all_obj_by_type(idf, 'ZoneHVAC:EquipmentList')
    remove_all_obj_by_type(idf, 'ZoneHVAC:FourPipeFanCoil')
    remove_all_obj_by_type(idf, 'ZoneControl:Thermostat')
    remove_all_obj_by_type(idf, 'Fan:SystemModel')
    remove_all_obj_by_type(idf, 'OutdoorAir:Mixer')
    remove_all_obj_by_type(idf, 'OutdoorAir:NodeList')
    remove_all_obj_by_type(idf, 'Coil:Cooling:Water')
    remove_all_obj_by_type(idf, 'Coil:Heating:Water')
    remove_all_obj_by_type(idf, 'Output:PreprocessorMessage')

    # 2. Delete the old zone coil branch objects
    new_branches = [
        branch for branch in branches if branch.Name not in BRANCH_TO_DELETE
    ]
    idf.idfobjects['Branch'] = new_branches

    # 3. Rename the demand branches from zone coil branch to load profile branch in the BranchList and  Mixer/Splitter objects
    for branch_list in branche_lists:
        if branch_list.Name in DEMAND_BRANCH_LISTS:
            if branch_list.Branch_2_Name == OLD_HW_LP_BRANCH_NAME:
                branch_list.Branch_2_Name = NEW_HW_LP_BRANCH_NAME
            elif branch_list.Branch_2_Name == OLD_CW_LP_BRANCH_NAME:
                branch_list.Branch_2_Name = NEW_CW_LP_BRANCH_NAME

    for splitter in splitter_lists:
        if splitter.Name in DEMAND_SPLITTER_LISTS:
            if splitter.Outlet_Branch_2_Name == OLD_HW_LP_BRANCH_NAME:
                splitter.Outlet_Branch_2_Name = NEW_HW_LP_BRANCH_NAME
            if splitter.Outlet_Branch_2_Name == OLD_CW_LP_BRANCH_NAME:
                splitter.Outlet_Branch_2_Name = NEW_CW_LP_BRANCH_NAME

    for mixer in mixer_lists:
        if mixer.Name in DEMAND_MIXER_LISTS:
            if mixer.Inlet_Branch_2_Name == OLD_HW_LP_BRANCH_NAME:
                mixer.Inlet_Branch_2_Name = NEW_HW_LP_BRANCH_NAME
            if mixer.Inlet_Branch_2_Name == OLD_CW_LP_BRANCH_NAME:
                mixer.Inlet_Branch_2_Name = NEW_CW_LP_BRANCH_NAME

    # 4. Save the idf.
    idf.saveas(LP_plant_loop_idf)
Beispiel #25
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
Beispiel #26
0
class EpisodicModel:
    model_import_flag = False

    # TODO - user should define actions outside of the model

    # EnergyManagementSystem:Actuator Available,
    #   VAV SYS 1 OUTLET NODE,
    #   System Node Setpoint,
    #   Temperature Setpoint,[C]
    component_type = "System Node Setpoint"
    control_type = "Temperature Setpoint"
    actuator_key = "VAV SYS 1 OUTLET NODE"

    # EnergyManagementSystem:Actuator Available,
    #   SEASONAL RESET SUPPLY AIR TEMP SCH,
    #   Schedule:Compact,
    #   Schedule Value
    # component_type = "Schedule:Compact"
    # control_type = "Schedule Value"
    # actuator_key = "SEASONAL RESET SUPPLY AIR TEMP SCH"

    component_type = "Schedule:Constant"
    control_type = "Schedule Value"
    actuator_key = "SAT_SP"

    @classmethod
    def set_energyplus_folder(cls, path):
        sys.path.insert(0, path)
        IDF.setiddname(f"{path}Energy+.idd")
        cls.model_import_flag = True

    def __init__(
        self,
        idf_file_name: str,
        weather_file: str,
        year: int,
        step: int,
        eplus_naming_dict: dict,
        eplus_var_types: dict,
        state_name: list = None,
        max_episodes: int = None,
        max_episode_steps: int = None,
        agent: Agent = None,
    ):
        """
        Refer to EMS application guide:
        https://bigladdersoftware.com/epx/docs/9-3/ems-application-guide/ems-calling-points.html#ems-calling-points
        for infomration on control flow

        :param idf_file_name: The path to the idf file
        :param weather_file: The path to the epw file
        :param tol_eps: An integer representing the total amount of episodes
        :param n_step: An integer representing the max number of steps per episode
        :param agent: An agent object. Used for control.
        """
        # Setup Energy Plus
        self.api = None
        self.year = year
        if not EpisodicModel.model_import_flag:
            raise ImportError("You have to set the energyplus folder first")
        self.run_parameters = ["-d", "result", "input.idf"]
        if weather_file:
            self.run_parameters = ["-w", weather_file] + self.run_parameters
        try:
            self.idf = IDF(idf_file_name)
        except Exception:
            raise ValueError(
                "IDF file is damaged or not match with your EnergyPlus version."
            )

        # Flags for completed warmups: based on EMS documentation
        self.warmup_design_complete = False
        self.warmup_run_complete = False
        self.after_warmup_call_num = 1
        self.warmup_complete = False

        # Set Agent and controller vars
        self.agent = agent
        self.last_action = None
        self.last_state = None
        self.total_reward = 0
        self.state_name = state_name
        self.start_time = None
        self.step = step
        #         self.queue = EventQueue()

        # Set Episodic Variables
        self.max_episodes = max_episodes
        self.max_episode_steps = max_episode_steps
        self.i_episode = 0
        self.i_episode_step = 0
        self.i_timestep = 0

        # set dicts to control energy plus naming
        self.eplus_naming_dict = eplus_naming_dict
        self.eplus_var_types = eplus_var_types

    def get_date(self):
        year = self.year
        month = self.api.exchange.month()
        day = self.api.exchange.day_of_month()
        hour = self.api.exchange.hour()
        minute = self.api.exchange.minutes()
        return year, month, day, hour, minute

    def get_observation(self):
        obs_dict = {}
        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():
                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[var_name]
                else:
                    key_val = entry['Key_Value']
                handle = self.api.exchange.get_variable_handle(
                    var_name, key_val)
                # name the state value based on Gnu-RL paper
                key = self.eplus_naming_dict.get(
                    (var_name, entry['Key_Value']))
                obs_dict[key] = self.api.exchange.get_variable_value(handle)

        state = torch.tensor([obs_dict[name] for name in self.state_name
                              ]).unsqueeze(0).double()

        if self.start_time is None:
            self.start_time = pd.datetime(year=self.year,
                                          month=self.api.exchange.month(),
                                          day=self.api.exchange.day_of_month())
            cur_time = self.start_time
        else:
            cur_time = self.start_time + pd.Timedelta(seconds=self.step *
                                                      (self.i_timestep + 1))
        observation = (state, obs_dict, obs_dict, cur_time)
        return observation

    def get_reward(self, obs_dict):
        reward = r_func(obs_dict, self.last_action, self.agent.learner.eta)
        return reward

    def is_terminal(self):
        return self.i_episode_step == (self.max_episode_steps - 1)
        # if self.i_episode_step == (self.max_episode_steps-1):
        #     return True
        # else:
        #     return False

    # def trigger_events(self):
    #     events = self.queue.trigger(self.i_timestep)
    #     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)
    #         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)
    #         self.api.exchange.set_global_value(handle, value)

    def env_make(self):
        """ Wait until the warmup periods are complete before starting simulation """
        if not self.api.exchange.api_data_fully_ready():
            return
        self.warmup_complete = True
        self.last_state = self.get_observation()

    def env_reset(self):
        """ Resets the environment and returns an initial observation

        In our episodic case every episode is a day, so the environment is not reset.
        The initial observation just needs to be returned.
        """
        if not self.api.exchange.api_data_fully_ready():
            return
        if not self.warmup_complete:
            return
        if self.i_episode >= self.max_episodes:
            return

        if self.i_episode_step == 0:
            self.last_action = self.agent.agent_start(self.last_state,
                                                      self.i_episode)

    def env_action(self):
        """ Trigger actions using EMS actuators

        """
        if not self.api.exchange.api_data_fully_ready():
            return
        if not self.warmup_complete:
            return
        if self.i_episode >= self.max_episodes:
            return

        action, SAT_stpt = self.last_action

        handle = self.api.exchange.get_actuator_handle(self.component_type,
                                                       self.control_type,
                                                       self.actuator_key)

        if handle == -1:
            raise ValueError('Actuator handle could not be found')

        self.api.exchange.set_actuator_value(handle, SAT_stpt)

        # self.queue.schedule_event(SAT_stpt, self.i_timestep+1, 0,
        #                           component_type=component_type,
        #                           control_type=control_type,
        #                           actuator_key=actuator_key)
        #
        # self.trigger_events()

    def env_step(self):
        """ Takes an action and triggers agent afterwards

        Returns:
            observation: object
            reward: float
            done: boolean
            info: dict
        """
        if not self.api.exchange.api_data_fully_ready():
            return
        if not self.warmup_complete:
            return
        if self.i_episode >= self.max_episodes:
            return

        self.last_state = self.get_observation()

        handle_act = self.api.exchange.get_actuator_handle(
            self.component_type, self.control_type, self.actuator_key)
        val_act = self.api.exchange.get_actuator_value(handle_act)

        handle_obv = self.api.exchange.get_variable_handle(
            'System Node Temperature', 'VAV SYS 1 OUTLET NODE')

        val_obvs = self.api.exchange.get_variable_value(handle_obv)
        # print(val_act, val_obvs, self.last_state[1]['Indoor Temp.'])
        # pdb.set_trace()

        reward = self.get_reward(self.last_state[1])
        term = self.is_terminal()

        handle = self.api.exchange.get_actuator_handle(self.component_type,
                                                       self.control_type,
                                                       self.actuator_key)
        val = self.api.exchange.get_actuator_value(handle)
        # print('actuator value in step function', val)

        if term:
            self.agent.agent_end(reward, self.last_state, self.i_episode)
            self.i_episode += 1
            self.i_episode_step = 0
        else:
            self.last_action = self.agent.agent_step(reward, self.last_state)
            self.i_episode_step += 1

        self.i_timestep += 1

    def simulate(self):
        from pyenergyplus.api import EnergyPlusAPI

        self.idf.saveas("input.idf")
        self.api = EnergyPlusAPI()
        self.api.runtime.callback_after_new_environment_warmup_complete(
            self.env_make)
        self.api.runtime.callback_begin_system_timestep_before_predictor(
            self.env_reset)
        # self.api.runtime.callback_begin_zone_timestep_before_init_heat_balance(self.env_action)
        # self.api.runtime.callback_after_predictor_before_hvac_managers(self.env_action)
        self.api.runtime.callback_begin_system_timestep_before_predictor(
            self.env_action)
        self.api.runtime.callback_end_zone_timestep_after_zone_reporting(
            self.env_step)
        status = self.api.runtime.run_energyplus(self.run_parameters)
        print('Simulator return status: ', status)
Beispiel #27
0
# <markdowncell>

# This is easy:

# <codecell>

idf1.save()

# <markdowncell>

# If you'd like to do a "Save as..." use this:

# <codecell>

idf1.saveas("something.idf")

# <headingcell level=2>

# Working with E+ objects

# <markdowncell>

# Let us open a small idf file that has only "CONSTRUCTION" and "MATERIAL" objects in it. You can go into "../idffiles/V_7_2/constructions.idf" and take a look at the file. We are not printing it here because it is too big.
#
# So let us open it using the idfreader -

# <codecell>

from eppy import modeleditor
from eppy.modeleditor import IDF
Beispiel #28
0

# In[2]:

IDF.setiddname(iddfile)
idf1 = IDF(fname1)


# In[3]:

idf1 = IDF(fname1)


# In[4]:

idf1.saveas("bl_original.idf")


# In[5]:

keys = list(idf1.idfobjects.keys())


# In[6]:

# rename object name with a colon and any field that refers to that name
from eppy.bunch_subclass import BadEPFieldError
renamednames = []
for key in keys:
    for idfobject in idf1.idfobjects[key]:
        try:
Beispiel #29
0
def create_idf_file(
    input_file_path,
    iddfile,
    nbiterations,
    baselineIDF,
    versionIDF,
    pathnameto_eppy=r'C:/Users/mkj32/Documents/2016-2019 PhD/School Theoretical/Energy Plus/IdealLoads'
):
    """creates idf based on baseline IDF, and three inputs: file path to baseline
    IDF, pathname to EnergyPlus Package, and nb of iterations to run the simulation 
    i.e. number of simulations based on the uncertainty input file."""
    printversionIDF(versionIDF)  # Using the user defined function

    # Prepare the idd file and file paths
    IDF.setiddname(iddfile)

    os.chdir(input_file_path)

    # Three possibilities of window to wall ratio
    #    baselineIDF =  pathnameto_eppy+r'/baseline_V890.idf'
    idfname_wwr1 = pathnameto_eppy + r'/FenestrationSurface_WWR_1.idf'
    idfname_wwr2 = pathnameto_eppy + r'/FenestrationSurface_WWR_2.idf'
    idfname_wwr3 = pathnameto_eppy + r'/FenestrationSurface_WWR_3.idf'

    idf_baseline_wwr = [idfname_wwr1, idfname_wwr2, idfname_wwr3]

    # Load all the input files
    zonename = pd.read_csv("zonename.csv")
    allzones = pd.read_csv("zonetype.csv")
    heatgains = pd.read_csv("heatgains.csv")
    uncertainty = pd.read_csv("uncertainty_NoDaylighting_raw.csv")
    daylighting_refpoints = pd.read_csv("daylightingcontrol_refpoints.csv")
    scheduletime = pd.read_csv(
        "scheduletimes_on_avoiderror.csv"
    )  #removed store and toilet equipment schedule as it was already present in basefile

    idfwindowfile = pathnameto_eppy + r'/TopSouthClassroom_RoofWindow.idf'

    Equipment_sch = scheduletime[scheduletime.ScheduleType == "Equipment"]
    Ventilation_sch = scheduletime[scheduletime.ScheduleType == "Ventilation"]
    Heat_sch = scheduletime[scheduletime.ScheduleType == "Heat"]

    for runindex, run in uncertainty.head(
            n=nbiterations).iterrows():  # only run for the first iteration
        wallC, roofC, groundC, Infil = calc_wall_prop(
            run)  # load wall properties from calc_wall_property function

        daylighting = run.DaylightingControl
        Schedule = run.schedule
        Boiler = run.BoilerEfficiency
        heating = run.HeatingSP  # heating setpoint operative temperature
        ventilation = run.ventilation  # 0 means no ventilation while 1 means full ventilation, ventilation schedule only 0 or 1.
        wwr = run.WWR  # window wall ratio; wwr 1 means 20, 2 means 40, 3 means 60 only for classroom

        idf1 = IDF(baselineIDF)

        ## ..........................IDF FILE BASED ON WWR............................................
        for wwr_test in range(1, 4):  #creates a dummy value equal to 1, 2 or 3
            if wwr == wwr_test:  #checks if the WWR is 1, 2 or 3
                print(wwr)
                fenestrationfile = idf_baseline_wwr[wwr_test - 1]
                add_window_component(
                    idf1, fenestrationfile
                )  # assigns the correct IDF file for the corresponding WWR value

        ## ..........................MATERIALS.....................................................
        # make four new materials with the specified u values and ratios above
        materials = idf1.idfobjects["MATERIAL"]

        for i in range(0, 3):
            idf1.newidfobject("MATERIAL")  # add three empty materials

        for material in materials:
            if material.Name == "":
                material.Roughness = "MediumRough"
                material.Thickness = 0.508
                material.Density = 43
                material.Specific_Heat = 1210

        materials[len(materials) - 3].Name = "wall insulation"
        materials[len(materials) - 3].Conductivity = wallC

        materials[len(materials) - 2].Name = "ground insulation"
        materials[len(materials) - 2].Conductivity = groundC

        materials[len(materials) - 1].Name = "roof insulation"
        materials[len(materials) - 1].Conductivity = roofC

        # make window glazing:
        windowglazing = idf1.newidfobject("WINDOWMATERIAL:SIMPLEGLAZINGSYSTEM")
        windowglazing.Name = "simple window"
        windowglazing.UFactor = run.WinU
        windowglazing.Solar_Heat_Gain_Coefficient = run.WinSHGC

        ## ..........................INPUT OF CONDITIONAL DAYLIGHTING CONTROLS.....................................................
        # Add branch and branch list information
        if daylighting == 1:
            # Add daylighting control to  idf, conditionally on daylighting being = 1
            for zoneindex, zone in daylighting_refpoints.iterrows():
                print(zoneindex)
                daylighting_control(
                    idf1, zone, zoneindex
                )  # this inputs daylighting control and reference point
                # from the daylighting_controls_on csv file

        if run.roofwindow == 1:
            add_window_component(idf1, idfwindowfile)

        addco2(idf1, 400, 500)

        ## ..........................ZONE PROPERTIES.....................................................

        # Create a for loop with all the info for each zone
        for zoneindex, zone in allzones.iterrows():
            zonename = zone.zonename
            zonetype = zone.type
            typecode = zone.typecode
            for roomindex, hg in heatgains.iterrows():
                zonetype2 = hg.zonetype
                if zonetype == zonetype2:
                    equip = hg.equipment
                    lighting = hg.lightingW
                    occupancy = hg.occupancy
                    meta = hg.metabolicWPerson
                    latent = hg.LatentGains
                    heating = hg.heating
                    heatingsetback = hg.heatingsetback
                    ventilationrate = hg.ventilation * ventilation / 1000.0  #change unit from l/s to m3/s per person for ventilation

                    #schedules:
                    schequip = hg.equipmentSchl
                    schheat = hg.heatSchl
                    schlight = hg.lightSchl
                    schoccu = hg.occupancySchl
                    schventilation = hg.ventilationSchl

            #print(zoneindex,zonename, zonetype, typecode, equip,lighting, people,meta,schoccu)
            # Create a new object for the zone:
            idf1.newidfobject(
                "PEOPLE")  #everytime you do that you add a new empty material
            idf1.newidfobject(
                "ELECTRICEQUIPMENT"
            )  #everytime you do that you add a new empty material
            idf1.newidfobject(
                "LIGHTS")  #everytime you do that you add a new empty material
            idf1.newidfobject(
                "ZONEINFILTRATION:DESIGNFLOWRATE"
            )  #everytime you do that you add a new empty material
            idf1.newidfobject('ZONEVENTILATION:DESIGNFLOWRATE')

            # pop the object out with a given name so that we will be able to assign specific values for each:
            people = idf1.idfobjects['PEOPLE'][zoneindex]
            lights = idf1.idfobjects['LIGHTS'][zoneindex]
            elecequip = idf1.idfobjects['ELECTRICEQUIPMENT'][zoneindex]
            zoneinfildfr = idf1.idfobjects['ZONEINFILTRATION:DESIGNFLOWRATE'][
                zoneindex]
            zoneventdfr = idf1.idfobjects['ZONEVENTILATION:DESIGNFLOWRATE'][
                zoneindex]

            # people:
            people[people.fieldnames[1]] = zonename + "occupancy"  #name
            people[people.fieldnames[2]] = zonename  # Zone or ZoneList Name"
            people[people.fieldnames[3]] = schoccu
            people[people.fieldnames[4]] = "People/Area"
            people[
                people.fieldnames[6]] = occupancy  #People per Zone Floor Area
            people[people.fieldnames[8]] = latent  # Fraction Radiant
            people[people.
                   fieldnames[9]] = "autocalculate"  # sensible heat fraction
            people[people.fieldnames[
                10]] = zonetype + "activity"  # activity level schedule name

            # zone infiltration rate:
            zoneinfildfr[
                zoneinfildfr.fieldnames[1]] = zonename + "infiltration"
            zoneinfildfr[
                zoneinfildfr.fieldnames[2]] = zonename  # Zone or ZoneList Name
            zoneinfildfr[
                zoneinfildfr.fieldnames[3]] = "INFIL_SCH"  # Schedule Name
            zoneinfildfr[zoneinfildfr.fieldnames[
                4]] = "AirChanges/Hour"  #Design Flow Rate Calculation Method
            zoneinfildfr[
                zoneinfildfr.fieldnames[8]] = 0.3  # Air Changes per Hour

            # lights:
            lights.Name = zonename + "light"
            lights.Zone_or_ZoneList_Name = zonename
            lights.Schedule_Name = schlight
            lights.Design_Level_Calculation_Method = "Watts/Area"
            lights.Watts_per_Zone_Floor_Area = lighting
            lights.Fraction_Radiant = 0.42
            lights.Fraction_Visible = 0.18

            # elecequip:
            elecequip.Name = zonename + "equip"
            elecequip.Zone_or_ZoneList_Name = zonename
            elecequip.Schedule_Name = schequip
            elecequip.Design_Level_Calculation_Method = "Watts/Area"
            elecequip.Watts_per_Zone_Floor_Area = equip
            elecequip.Fraction_Latent = 0
            elecequip.Fraction_Radiant = 0.5

            # VENETILATION DESIGN FLOW RATE
            zoneventdfr.Name = zonename + "ventilation"
            zoneventdfr.Zone_or_ZoneList_Name = zonename
            zoneventdfr.Schedule_Name = schventilation
            zoneventdfr.Design_Flow_Rate_Calculation_Method = "Flow/Person"
            zoneventdfr.Flow_Rate_per_Person = ventilationrate

            create_sizing_hvac_objects(
                idf1,
                zone)  # inputs objects for zone sizing and boiling properties,
            # defined in the function create_sizing_objects

            # Water use equipment ...........................
            WUE = idf1.newidfobject("WATERUSE:EQUIPMENT")
            WUE.Name = zonename + "DHW"
            WUE.EndUse_Subcategory = "DHW_default"
            WUE.Peak_Flow_Rate = zone.waterflow
            WUE.Flow_Rate_Fraction_Schedule_Name = schoccu
            WUE.Target_Temperature_Schedule_Name = "SHW_default Temp Sched"
            WUE.Hot_Water_Supply_Temperature_Schedule_Name = "Hot Supply Temp Sched"
            WUE.Zone_Name = zonename

        # .......................... SCHEDULES FOR EQUIPMENT, LIGHTING, VENTILATION ----------------------
    # Create a for loop to populate schedules for ventilation, heat and equipment. You can change the schedule using the csv file
    # called scheduletimes_on
        schedules_all = idf1.idfobjects['SCHEDULE:COMPACT']

        for sch_index, schtype in Equipment_sch.iterrows():
            create_simple_schedule(idf1, schedules_all, schtype, "Fraction")

        for sch_index, schtype in Heat_sch.iterrows():
            create_simple_schedule(idf1, schedules_all, schtype, "Temperature")

        if versionIDF == "v860":
            for sch_index, schtype in Ventilation_sch.iterrows():
                create_simple_schedule(idf1, schedules_all, schtype,
                                       "Fraction")

        # .......................... THERMOSTAT FOR HEATING ----------------------

        # This for loop creates a Thermostat set point for each Type of Zone (but must not iterate through each zone)
        for roomindex, hg in heatgains.iterrows():
            HVACTemp_Thermo = idf1.newidfobject("HVACTEMPLATE:THERMOSTAT")
            HVACTemp_Thermo.Name = hg.zonetype + "_Thermostat"
            HVACTemp_Thermo.Heating_Setpoint_Schedule_Name = hg.heatSchl
            HVACTemp_Thermo.Cooling_Setpoint_Schedule_Name = "Cooling Setpoint Schedule"  # hg.ventilationSchl

        # Add to csv file the run number
        print("run=", run.number)
        # Create a new folder for the date so that they can be saved in a clean way
        now = datetime.datetime.now()
        newpath = r"C:/Users/mkj32/Documents/2016-2019 PhD/School Theoretical/Code/" + now.strftime(
            '%Y%m%d')
        if not os.path.exists(newpath):
            os.mkdir(newpath)
        os.chdir(newpath)
        filename = str(now)[:10] + "_school_run_%d.idf" % run.number
        idf1.saveas(filename)

        print(filename)
Beispiel #30
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
Beispiel #31
0
from eppy import hvacbuilder

from io import StringIO

iddfile = "../eppy/resources/iddfiles/Energy+V7_0_0_036.idd"
IDF.setiddname(iddfile)

# <codecell>

# make the topology of the loop
idf = IDF(StringIO(""))  # makes an empty idf file in memory with no file name
loopname = "p_loop"
sloop = ["sb0", ["sb1", "sb2", "sb3"], "sb4"]  # supply side of the loop
dloop = ["db0", ["db1", "db2", "db3"], "db4"]  # demand side of the loop
hvacbuilder.makeplantloop(idf, loopname, sloop, dloop)
idf.saveas("hhh1.idf")

# <markdowncell>

# We have made plant loop and saved it as hhh1.idf.
# Now let us look at what the loop looks like.

# <headingcell level=3>

# Diagram of the loop

# <markdowncell>

# Let us use the script "eppy/useful_scripts/loopdiagrams.py" to draw this diagram

# <markdowncell>
Beispiel #32
0
def datafield(yc_keys, xc_keys):
    iddfile = "./Energy+9.1.idd"
    IDF.setiddname(iddfile)

    idfname = "./RefBldgLargeOfficeNew2004_Chicago.idf"
    idf = IDF(idfname)

    # change the output variable and meter
    # output_frequency='Daily'
    output_frequency = 'Monthly'

    variable = []
    for i in range(len(xc_keys)):
        variable1 = idf.newidfobject("Output:Variable".upper())
        variable1.Key_Value = '*'
        variable1.Variable_Name = xc_keys[i]
        variable1.Reporting_Frequency = output_frequency
        variable.append(variable1)
    idf.idfobjects['Output:Variable'.upper()] = variable

    meter = []
    for i in range(len(yc_keys)):
        meter1 = idf.newidfobject("Output:Meter".upper())
        meter1.Key_Name = yc_keys[i]
        meter1.Reporting_Frequency = output_frequency
        meter.append(meter1)
    idf.idfobjects['Output:Meter'.upper()] = meter

    idf.idfobjects['RUNPERIOD'][0].Begin_Month = 1
    idf.idfobjects['RUNPERIOD'][0].Begin_Day_of_Month = 1
    idf.idfobjects['RUNPERIOD'][0].End_Month = 12
    idf.idfobjects['RUNPERIOD'][0].End_Day_of_Month = 31

    idf.saveas('C:/Users/songc/Desktop/work file/Updated_Model.idf')
    idfname1 = 'C:/Users/songc/Desktop/work file/Updated_Model.idf'  # This IDF file is updated at each iteration.
    epwfile = './SPtMasterTable_52384_2011_amy.epw'
    subprocess.call([
        'C:/EnergyPlusV9-1-0/energyplus.exe', '-d',
        "C:/Users/songc/Desktop/work file/result_folder", '-w', epwfile,
        idfname1
    ])

    eso_file = './result_folder/eplusout.eso'
    [ycoutput, xcoutput] = comp_data_reader(eso_file, yc_keys, xc_keys)

    yc_df1 = pd.DataFrame(ycoutput, index=yc_keys).T
    xc_df1 = pd.DataFrame(xcoutput, index=xc_keys).T

    epwfile2 = './SPtMasterTable_52384_2012_amy.epw'
    subprocess.call([
        'C:/EnergyPlusV9-1-0/energyplus.exe', '-d',
        "C:/Users/songc/Desktop/work file/result_folder", '-w', epwfile2,
        idfname1
    ])

    eso_file = './result_folder/eplusout.eso'
    [ycoutput, xcoutput] = comp_data_reader(eso_file, yc_keys, xc_keys)

    yc_df2 = pd.DataFrame(ycoutput, index=yc_keys).T
    xc_df2 = pd.DataFrame(xcoutput, index=xc_keys).T

    yc_df = pd.concat([yc_df1, yc_df2], axis=0)
    xc_df = pd.concat([xc_df1, xc_df2], axis=0)

    df = pd.concat([yc_df, xc_df], axis=1)
    df.to_csv('DATAFIELD_Multi.csv', index=False)
    df_single = pd.concat([yc_df.iloc[:, 0], xc_df], axis=1)
    df_single.to_csv('DATAFIELD_Single.csv', index=False)
Beispiel #33
0
CSVDir = DirName+'/runtrial/WeatherFileNameList.csv'
WriteEPWNameToCSV(epwDir, CSVDir , 8)
weatherfilename_list = ReadFileNameInCsv(CSVDir)

print(weatherfilename_list)

##run with different locations
for i in weatherfilename_list:
    epwname = epwDir + i +'.epw'         ##Before write the path, put weather files in EnergyPlus WeatherData folder
    ddyname = ddyDir + i +'.ddy'
    fname1 = DirName + '/runtrial/TrialKA2_Unsized.idf'
    idf1 = IDF(fname1, epwname)
    UpdateLocationInfinIDF(idf1,ddyname)
    ##idf1.printidf()
    building = idf1.idfobjects['BUILDING'][0]
    building.Name = "KA2 A Flatroof Sample Building"
    objectlist = idf1.idfobjects
    rundirname = u'../eppy_energy-/runtrial/'
    resultsdir = rundirname+'results'+i
    ##os.makedirs(resultsdir)
    idf1.saveas(DirName + "/idfs/"+i+'.idf')
    idf1.run(output_directory = resultsdir)

Axis = 0
while Axis in range(0,360):
    building.North_Axis = Axis
    ##idf1.saveas(DirName+'/idfs/Axises/'+str(Axis)+".idf")
    resultsdirAxis= rundirname+'results'+i+'Axis'+str(Axis)
    ##os.makedirs(resultsdirAxis)
    ##idf1.run(output_directory = resultsdirAxis)
    Axis += 45
def modify_IDF_global(input_file_path, iddfile, nbiterations, sa_fname,
                      nbbatches, start_month, end_month, m_file1, m_file2,
                      monthprefix):
    """creates idf based on baseline IDF, and three inputs: file path to baseline
    IDF, pathname to EnergyPlus Package, and nb of iterations to run the simulation 
    i.e. number of simulations based on the sensitivity analysis input file."""

    # Prepare the idd file and file paths
    IDF.setiddname(iddfile)

    os.chdir(input_file_path)

    # Name baseline IDF file
    baselineIDF = input_file_path + r'/CosimulationFiles/GlobalSA_BaselineIDF_Cosim.idf'

    # Load all the input files
    sa_inputs = pd.read_csv(sa_fname)

    #Planted_area
    # maybe used to modify size on internal mass?
    #

    # now we divide into 4 batches
    #nbiterations=100
    #nbbatches=4
    nbiterations_inbatch = int(nbiterations / nbbatches)
    #letters_batch =('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J')
    letters_batch = list(itertools.islice(excel_cols(), nbbatches))
    batch_index = range(0, int(nbiterations_inbatch))
    for batch in range(0, nbbatches):
        print("-----------------Batch number is now", batch)
        for runindex in batch_index:
            print("Index number is now", runindex)
            runindex = runindex + nbiterations_inbatch * batch
            print("******Index number is now", runindex)

            # Now we can select the correct row from sa_inputs
            run = sa_inputs.iloc[int(runindex), ]
            # for runindex, run in sa_inputs.head(n=nbiterations).iterrows(): # only run for the first iteration

            print(runindex, run)
            idf1 = IDF(baselineIDF)
            # modify run period
            mofify_run_period(idf1,
                              from_day=1,
                              from_month=start_month,
                              to_day=31,
                              to_month=end_month)

            ## Heating and cooling setpoints  of the greenhouse =============================================
            #Cooling_SP_GH
            #Heating_SP_GH
            # modify the scheduled cooling and heating setpoints, objects 72 and 73 respectively
            heatingsched = idf1.idfobjects["SCHEDULE:COMPACT"][51 - 1]
            coolingsched = idf1.idfobjects["SCHEDULE:COMPACT"][52 - 1]
            # nightheating
            for night_fieldname in [6, 10, 13, 17, 20]:
                #print(night_fieldname)
                heatingsched[heatingsched.fieldnames[night_fieldname]] = round(
                    run.Heating_SP_GH * 0.9,
                    1)  #it can get 10% colder at night
                coolingsched[coolingsched.fieldnames[night_fieldname]] = round(
                    run.Cooling_SP_GH * 1.1,
                    1)  #it can get 10% warmer at night
            for day_fieldname in [8, 15]:
                heatingsched[heatingsched.fieldnames[day_fieldname]] = round(
                    run.Heating_SP_GH, 1)  #it can get 10% colder at night
                coolingsched[coolingsched.fieldnames[day_fieldname]] = round(
                    run.Cooling_SP_GH, 1)  #it can get 10% warmer at night

            #shading =======================================================
            #rooftop_window
            ## ..........................SHADING.....................................................
            solar_transmittance = round(run.shading, 2)
            solar_reflectance = 0.99 - solar_transmittance
            # only one shading control to add:
            # to view the field names use shade.fieldnames
            shade = idf1.idfobjects["WINDOWMATERIAL:SHADE"][0]
            shade.Solar_Transmittance = solar_transmittance
            shade.Solar_Reflectance = solar_reflectance
            shade.Visible_Transmittance = solar_transmittance
            shade.Visible_Reflectance = solar_reflectance

            ## ..........................ROOFTOP WINDOW.....................................................
            windowsize = round(run.rooftop_window,
                               2)  # percentage of rooftop size
            #  max_x = 74.15       max_y = -34.44
            min_x = 38.15
            min_y = -41.44

            new_min_x = min_x + (36 - sqrt(windowsize) * 36) / 2
            new_min_y = min_y + (7 - sqrt(windowsize) * 7) / 2
            new_max_x = new_min_x + 36 * sqrt(windowsize)
            new_max_y = new_min_y + 7 * sqrt(windowsize)

            # verification: (new_max_x-new_min_x)*(new_max_y-new_min_y)-252*windowsize
            # create window object
            # count how many windows there are
            nbwindows = len(idf1.idfobjects["FENESTRATIONSURFACE:DETAILED"])
            ghwindow = idf1.idfobjects["FENESTRATIONSURFACE:DETAILED"][
                nbwindows - 1]  # select the last window

            # identify the fieldnames of the window object
            #ghwindow.fieldnames
            # modify the coordinates
            ghwindow.Vertex_1_Xcoordinate = new_min_x
            ghwindow.Vertex_1_Ycoordinate = new_max_y

            ghwindow.Vertex_2_Xcoordinate = new_min_x
            ghwindow.Vertex_2_Ycoordinate = new_min_y

            ghwindow.Vertex_3_Xcoordinate = new_max_x
            ghwindow.Vertex_3_Ycoordinate = new_min_y

            ghwindow.Vertex_4_Xcoordinate = new_max_x
            ghwindow.Vertex_4_Ycoordinate = new_max_y

            #ratio_airmix_GH
            #ratio_airmix_CR

            ## AIR MIXING GREENHOUSE =========================================
            zonemixing = idf1.idfobjects["ZONEMIXING"]

            # Greenhouse ventilation rate:
            ach_GH = round(run.ACH_GH, 2)  # total ventilation rate
            # the ratio of mixing is run.ratio_airmix_GH
            zonemixing[0].Air_Changes_per_Hour = ach_GH * run.ratio_airmix_GH
            ghventilation = idf1.idfobjects["ZONEVENTILATION:DESIGNFLOWRATE"][
                6]
            ghventilation.Air_Changes_per_Hour = ach_GH * (1 -
                                                           run.ratio_airmix_GH)

            # AIR MIXING CLASSROOM -------------------------------------
            ACH_CR = round(run.ACH_CR, 2)  # total ventilation rate
            # the ratio of mixing is run.ratio_airmix_CR
            zonemixing[1].Air_Changes_per_Hour = ACH_CR * run.ratio_airmix_CR
            crventilation = idf1.idfobjects["ZONEVENTILATION:DESIGNFLOWRATE"][
                8]
            crventilation.Air_Changes_per_Hour = ACH_CR * (1 -
                                                           run.ratio_airmix_CR)

            ## CREATE THE IDF FILE ===========================
            # Add to csv file the run number
            print("run=", runindex)
            # Create a new folder for the date so that they can be saved in a clean way
            now = datetime.datetime.now()
            # monthprefix = "Jan"
            newpath = input_file_path + "/" + now.strftime(
                '%Y%m%d') + "_" + monthprefix + "_Batch" + letters_batch[batch]

            if not os.path.exists(newpath):
                os.mkdir(newpath)
            variables_file_path = input_file_path + "/CosimulationFiles/variables.cfg"
            shutil.copy(variables_file_path, newpath)
            cosim_file_path1 = input_file_path + "/CosimulationFiles/" + m_file1
            cosim_file_path2 = input_file_path + "/CosimulationFiles/" + m_file2
            cosim_new_file_path1 = newpath + "/Run_Cosim_" + monthprefix + "_Batch_" + letters_batch[
                batch] + "_C1.m"
            cosim_new_file_path2 = newpath + "/Run_Cosim_" + monthprefix + "_Batch_" + letters_batch[
                batch] + "_C2.m"
            shutil.copy(cosim_file_path1, cosim_new_file_path1)
            shutil.copy(cosim_file_path2, cosim_new_file_path2)
            os.chdir(newpath)
            filename = str(now)[:10] + "_SA_run_%d.idf" % runindex
            idf1.saveas(filename)

            print(filename)
Beispiel #35
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
Beispiel #36
0
from eppy import modeleditor
from eppy.modeleditor import IDF
from eppy import bunch_subclass


def autosize_fieldname(idfobject):
    """return autsizeable field names in idfobject"""
    # undocumented stuff in this code
    return [
        fname for (fname, dct) in zip(idfobject.objls, idfobject["objidd"])
        if "autosizable" in dct
    ]


iddfile = "../resources/iddfiles/Energy+V8_0_0.idd"
fname1 = "../resources/idffiles/V8_0_0/5ZoneWaterLoopHeatPump.idf"

IDF.setiddname(iddfile)
idf = IDF(fname1)
idf.saveas("./a.idf")

allidfobjects = idf.idfobjects
for objname in list(allidfobjects.keys()):
    idfobjects = allidfobjects[objname]
    for idfobject in idfobjects:
        autofields = autosize_fieldname(idfobject)
        for autofield in autofields:
            idfobject[autofield] = "autosize"

idf.saveas("./b.idf")
Beispiel #37
0
from eppy.modeleditor import IDF
from eppy import hvacbuilder

from StringIO import StringIO
iddfile = "../eppy/resources/iddfiles/Energy+V7_0_0_036.idd"
IDF.setiddname(iddfile)

# <codecell>

# make the topology of the loop
idf = IDF(StringIO('')) # makes an empty idf file in memory with no file name
loopname = "p_loop"
sloop = ['sb0', ['sb1', 'sb2', 'sb3'], 'sb4'] # supply side of the loop
dloop = ['db0', ['db1', 'db2', 'db3'], 'db4'] # demand side of the loop
hvacbuilder.makeplantloop(idf, loopname, sloop, dloop)
idf.saveas("hhh1.idf")

# <markdowncell>

# We have made plant loop and saved it as hhh1.idf.  
# Now let us look at what the loop looks like.  

# <headingcell level=3>

# Diagram of the loop

# <markdowncell>

# Let us use the script "eppy/useful_scripts/loopdiagrams.py" to draw this diagram

# <markdowncell>
Beispiel #38
0
from eppy import modeleditor
from eppy.modeleditor import IDF
from eppy import bunch_subclass

def autosize_fieldname(idfobject):
    """return autsizeable field names in idfobject"""
    # undocumented stuff in this code
    return [fname for (fname, dct) in zip(idfobject.objls,
                                          idfobject['objidd'])
            if 'autosizable' in dct]

iddfile = "../resources/iddfiles/Energy+V8_0_0.idd"
fname1 = "../resources/idffiles/V8_0_0/5ZoneWaterLoopHeatPump.idf"

IDF.setiddname(iddfile)
idf = IDF(fname1)
idf.saveas("./a.idf")




allidfobjects = idf.idfobjects
for objname in list(allidfobjects.keys()):
    idfobjects = allidfobjects[objname]
    for idfobject in idfobjects:
        autofields = autosize_fieldname(idfobject)
        for autofield in autofields:
            idfobject[autofield] = "autosize"

idf.saveas("./b.idf")
Beispiel #39
0
# <markdowncell>

# This is easy:

# <codecell>

idf1.save()

# <markdowncell>

# If you'd like to do a "Save as..." use this:

# <codecell>

idf1.saveas("something.idf")

# <headingcell level=2>

# Working with E+ objects

# <markdowncell>

# Let us open a small idf file that has only "CONSTRUCTION" and "MATERIAL" objects in it. You can go into "../idffiles/V_7_2/constructions.idf" and take a look at the file. We are not printing it here because it is too big.
#
# So let us open it using the idfreader -

# <codecell>

from eppy import modeleditor
from eppy.modeleditor import IDF
Beispiel #40
0
Idx = 0

for i in range(0,len(BatchProcessing)):
	# Display the progress of the script
	if Idx >= 2:
		print "Creating "+str(Idx-1)+" out of "+str(len(BatchProcessing)-2)+" models."
	
	# Initialization #2
	NbRows = BatchProcessing[i]
	if NbRows[0] <> 'idf' and NbRows[0] <> '-':
		# Initialization #3
		idf_file = IDF(NbRows[0])
		
		# Iterates throught the CSV file and execute the specified functions
		for j in range(2,len(NbRows)):
		
			# Retrieve the user input arguments
			arguments = NbRows[j].split(",")
			
			#print str(len(arguments))+" " +str(arguments[0])
			# If not argument is specified do not execute the function
			if not(len(arguments) == 1 and arguments[0] == "-"):
				item = BatchProcessing[0][j]
				func = getattr(eval(item),item)
				func(idf_file, arguments)
		
		# Save the modified IDF file		
		idf_file.saveas(NbRows[1][:-4]+".idf")
	Idx = Idx + 1

print "Done."