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:
import eppy. Read the IDF using eppy and then do the conversion
Use eppy3000 to directly convert IDF to epJSON. Don’t use eppy at all
Convert to epJSON with eppy¶
[3]:
# 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
[4]:
fname = "../eppy3000/resources/snippets/V9_3/smallfile.idf"
weatherfile = "../eppy3000/resources/weatherfiles/USA_CA_San.Francisco.Intl.AP.724940_TMY3.epw"
idf = eppy.openidf(fname, epw=weatherfile) # needs a weather file to work. TODO: open an issue and fix this
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
[5]:
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
[6]:
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
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
[7]:
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:
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 displayedAny 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)
The second reason, is that the JSON fromat is not as human readable as it claims to be. At least not for most humans :-).
as an example see this link https://marianoguerra.github.io/json.human.js/
Presenting it in the IDF fromat makes it clearer
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
[8]:
# 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 with eppy (in one line)¶
[9]:
import eppy3000.experimental.openidf
fname = "../eppy3000/resources/snippets/V9_3/smallfile.idf"
wfile = "../eppy3000/resources/weatherfiles/USA_CA_San.Francisco.Intl.AP.724940_TMY3.epw"
epj = eppy3000.experimental.openidf.openidf(fname, wfile)
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 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