Tutorial - The Preamble

Author(s): Santosh Philip

We am using this tutorial/documentation as a way of identifying alformed API and gaps in the software. When eppy was developed, writing the user documentation forced us to rewrite the software. This documentation is written with the same intent. It is a little easier in the case of eppy3000, since we are trying to mimic eppy using it as a starting point.

Any places where the word TODO occurs is where we find some recoding has to be done. An issue has to be opened and then resolved.

Start with Eppy

We are now at E+ version 9.3. If you install E+ version 9.3, you will find only one epJSON file in the installation. All the files are IDF files. So how do we work with and explore eppy300 and epJSON ?

We will have to read the IDF file, convert it to epJSON and then work with it. The key is to do the conversion from IDF to epJSON. There are two ways of doing this:

  1. import eppy. Read the IDF using eppy and then do the conversion
  2. Use eppy3000 to directly convert IDF to epJSON. Don’t use eppy at all

Convert to epJSON with eppy

[1]:
# you would normaly install eppy by doing
# python setup.py install
# or
# pip install eppy
# or
# easy_install eppy

# if you have not done so, uncomment the following three lines
import sys
# pathnameto_eppy = 'c:/eppy3000'
pathnameto_eppy3000 = '../'
sys.path.append(pathnameto_eppy3000)

import eppy
[2]:
fname = "../eppy3000/resources/snippets/V9_3/smallfile.idf"
idf = eppy.openidf(fname)
idf.printidf()

VERSION,
    9.3;                      !- Version Identifier

SIMULATIONCONTROL,
    Yes,                      !- Do Zone Sizing Calculation
    Yes,                      !- Do System Sizing Calculation
    Yes,                      !- Do Plant Sizing Calculation
    No,                       !- Run Simulation for Sizing Periods
    Yes;                      !- Run Simulation for Weather File Run Periods

BUILDING,
    Empire State Building,    !- Name
    30,                       !- North Axis
    City,                     !- Terrain
    0.04,                     !- Loads Convergence Tolerance Value
    0.4,                      !- Temperature Convergence Tolerance Value
    FullExterior,             !- Solar Distribution
    25,                       !- Maximum Number of Warmup Days
    6;                        !- Minimum Number of Warmup Days

SITE:LOCATION,
    CHICAGO_IL_USA TMY2-94846,    !- Name
    41.78,                    !- Latitude
    -87.75,                   !- Longitude
    -6,                       !- Time Zone
    190;                      !- Elevation

Looks good. Now we need to convert it

[3]:
import eppy3000.oldeppy as oldeppy
epschema = '../eppy3000/resources/schema/V9_3/Energy+.schema.epJSON'
epj = oldeppy.idf2epj(idf, open(epschema, 'r'))

#TODO: would be nice to have the code find the schema file in the E+ installation.
# Like how eppy2000.openidf() does

Let us print this epj and see what it looks like

[4]:
print(epj)

Version                                          !-  EP_KEY
            Version 1                            !-  EPJOBJECT_NAME
            9.3                                  !-  version_identifier
            1                                    !-  idf_order

SimulationControl                                !-  EP_KEY
            SimulationControl 1                  !-  EPJOBJECT_NAME
            Yes                                  !-  do_zone_sizing_calculation
            Yes                                  !-  do_system_sizing_calculation
            Yes                                  !-  do_plant_sizing_calculation
            No                                   !-  run_simulation_for_sizing_periods
            Yes                                  !-  run_simulation_for_weather_file_run_periods
            2                                    !-  idf_order

Building                                         !-  EP_KEY
            Empire State Building                !-  EPJOBJECT_NAME
            30                                   !-  north_axis
            City                                 !-  terrain
            0.04                                 !-  loads_convergence_tolerance_value
            0.4                                  !-  temperature_convergence_tolerance_value
            FullExterior                         !-  solar_distribution
            25                                   !-  maximum_number_of_warmup_days
            6                                    !-  minimum_number_of_warmup_days
            3                                    !-  idf_order

Site:Location                                    !-  EP_KEY
            CHICAGO_IL_USA TMY2-94846            !-  EPJOBJECT_NAME
            41.78                                !-  latitude
            -87.75                               !-  longitude
            -6                                   !-  time_zone
            190                                  !-  elevation
            4                                    !-  idf_order

Thats weird . I looks like the idf file. Shouldn’t it look like the JSON ?

Good point. The actual JSON in epj looks different. Let us take a look at that

[5]:
 print(epj.jsonstr())
{
    "Version": {
        "Version 1": {
            "version_identifier": "9.3",
            "idf_order": 1
        }
    },
    "SimulationControl": {
        "SimulationControl 1": {
            "do_zone_sizing_calculation": "Yes",
            "do_system_sizing_calculation": "Yes",
            "do_plant_sizing_calculation": "Yes",
            "run_simulation_for_sizing_periods": "No",
            "run_simulation_for_weather_file_run_periods": "Yes",
            "idf_order": 2
        }
    },
    "Building": {
        "Empire State Building": {
            "north_axis": 30,
            "terrain": "City",
            "loads_convergence_tolerance_value": 0.04,
            "temperature_convergence_tolerance_value": 0.4,
            "solar_distribution": "FullExterior",
            "maximum_number_of_warmup_days": 25,
            "minimum_number_of_warmup_days": 6,
            "idf_order": 3
        }
    },
    "Site:Location": {
        "CHICAGO_IL_USA TMY2-94846": {
            "latitude": 41.78,
            "longitude": -87.75,
            "time_zone": -6,
            "elevation": 190,
            "idf_order": 4
        }
    }
}

So why are you printing it to look like an IDF file.

Couple of reasons:

  1. It is was easier to do the development with epj expressed in the IDF format.
    • Note that there are some extra fields in the idf format that are not there in the JSON format.
      • One of them is EP_KEY
      • the other is EPJOBJECT_NAME
    • These fields are used internally by eppy3000
    • epJSON allows you to add your own fields. A very useful attribute
    • Any field name that starts with EP will be used internally by eppy3000 and will be displayed
    • Any field name that starts with eppy_ will be used internally by eppy3000, but will not be displayed in the print (these are hidden fields, that the user does not need to see)
  2. The second reason, is that the JSON fromat is not as human readable as it claims to be. At least not for most humans :-).

It is not clear if this is the best pathway to take. But it is useful for the moment. So we are going to stick with it until something better comes along

EPJ schema

With the IDF file, we also have the IDD file that holds the structure of the IDF file. In eppy we can access IDD file. What happens in epJSON file in EPJ

Let us get to the fieldnames of Building object as seen by the schema

[6]:
# building_fieldnames = epj.epschema.epschemaobjects['Building'].fieldnames()
#
# There is bug that does not capture the epschema
# happens when idf2epj is used
# this is a TODO: open an issue on it

Convert to epJSON without eppy

If you simply want to convert a file

[2]:
import eppy3000.idfjsonconverter as idfjsonconverter

idffilename = "../eppy3000/resources/snippets/V9_3/smallfile.idf"
schemapath = "../eppy3000/resources/schema/V9_3/Energy+.schema.epJSON"

epjfilename = idfjsonconverter.idffile2epjfile(idffilename, schemapath=schemapath)
print(f'The epj file is saved at: {epjfilename}')
The epj file is saved at: ../eppy3000/resources/snippets/V9_3/smallfile.epJSON

Usually you can call it by idfjsonconverter.idffile2epjfile(idffilename(idffilename) You don’t need to give it the schema name. It will find the schema file by searching in the usual install locations

Let us read the epJSON file and see if it actually happened. Yes! It worked - the file looks good

[3]:
print(open(epjfilename, 'r').read())
{
  "Version": {
    "Version 1": {
      "version_identifier": "9.3",
      "idf_order": 1
    }
  },
  "SimulationControl": {
    "SimulationControl 1": {
      "do_zone_sizing_calculation": "Yes",
      "do_system_sizing_calculation": "Yes",
      "do_plant_sizing_calculation": "Yes",
      "run_simulation_for_sizing_periods": "No",
      "run_simulation_for_weather_file_run_periods": "Yes",
      "idf_order": 2
    }
  },
  "Building": {
    "Empire State Building": {
      "north_axis": 30,
      "terrain": "City",
      "loads_convergence_tolerance_value": 0.04,
      "temperature_convergence_tolerance_value": 0.4,
      "solar_distribution": "FullExterior",
      "maximum_number_of_warmup_days": 25,
      "minimum_number_of_warmup_days": 6,
      "idf_order": 3
    }
  },
  "Site:Location": {
    "CHICAGO_IL_USA TMY2-94846": {
      "latitude": 41.78,
      "longitude": -87.75,
      "time_zone": -6,
      "elevation": 190,
      "idf_order": 4
    }
  }
}

Now that we have the epJSON file, Let us open it using eppy3000 and look at it.

[4]:
from eppy3000.modelmaker import EPJ
epj = EPJ(epjfilename)
[5]:
print(epj)

Version                                          !-  EP_KEY         # use .eppykey
            Version 1                            !-  EPJOBJECT_NAME # use .eppyname
            9.3                                  !-  version_identifier
            1                                    !-  idf_order

SimulationControl                                !-  EP_KEY         # use .eppykey
            SimulationControl 1                  !-  EPJOBJECT_NAME # use .eppyname
            Yes                                  !-  do_zone_sizing_calculation
            Yes                                  !-  do_system_sizing_calculation
            Yes                                  !-  do_plant_sizing_calculation
            No                                   !-  run_simulation_for_sizing_periods
            Yes                                  !-  run_simulation_for_weather_file_run_periods
            2                                    !-  idf_order

Building                                         !-  EP_KEY         # use .eppykey
            Empire State Building                !-  EPJOBJECT_NAME # use .eppyname
            30                                   !-  north_axis
            City                                 !-  terrain
            0.04                                 !-  loads_convergence_tolerance_value
            0.4                                  !-  temperature_convergence_tolerance_value
            FullExterior                         !-  solar_distribution
            25                                   !-  maximum_number_of_warmup_days
            6                                    !-  minimum_number_of_warmup_days
            3                                    !-  idf_order

Site:Location                                    !-  EP_KEY         # use .eppykey
            CHICAGO_IL_USA TMY2-94846            !-  EPJOBJECT_NAME # use .eppyname
            41.78                                !-  latitude
            -87.75                               !-  longitude
            -6                                   !-  time_zone
            190                                  !-  elevation
            4                                    !-  idf_order

Convert all IDF files in a folder to epJSON

Sometimes you want to convert all the idf files in a folder. You can use idffolder2epjfolder to do that

[6]:
import eppy3000.idfjsonconverter as idfjsonconverter

startfolder = "./eppy3000/resources/snippets/V9_3"
schemapath = "../eppy3000/resources/schema/V9_3/Energy+.schema.epJSON"

idfjsonconverter.idffolder2epjfolder(startfolder, schemapath=schemapath)
# You don't need to use schemapath if you have Energyplus installed

The files are saved in the same folder as the IDF files. You can also save them in a different folder. See the documentation of idffolder2epjfolder below

[7]:
# def idffolder2epjfolder(
#     idffolder, epjfolder=None, idfext=None, epjext=None, schemapath=None, verbose=False
# ):
print(idfjsonconverter.idffolder2epjfolder.__doc__)
Convert all the idf files in idffolder into epj files and save them in epjfolder

    The function finds the idf files by searching for the all files in the idffolder that have the extension 'idf'. This extension can be overridden by giving a value to idfext

    Parameters
    ----------
    idffolder: str, pathlib.Path
        This is the folder with the idf files
    epjfolder: str, pathlib.Path
        This is the folder where you want to store the generated epj files. When epjfolder=None, the epj files are saved in the idffolder
    idfext: str
        This is the extension of the idf files. Default value is `idf`
    epjext: str
        This is the extension of the epj files. Default value is `epJSON`
    schemapath: str, pathlib.Path
        path to Energy+.schema.epJSON usuallty found in the install location of EnergyPlus. If schemapah=None, the function will attempt to find the schema path in the standard install locations
    verbose: Boolean
        When verbose=True, it will print file names on screen. The default for verbose is False

    Returns
    -------
    None


Opening a file without the schema (IDD)

Eppy3000 lets you open the epJSON as EPJ file without refering to the schema.epJSON. The code in the previous section does exactly that. A lot of functionality is avaliable without the schema. There are use cases for this, where you you want to quickly make some changes to epj and don’t have access to the schema.

TODO: It is not explicit in the API whether the schema is read or not. One way to make it explicit is to force the user to enter the arg for the schema. If the arg is None: no schema is read; else: the schema is read