Tutorial - What you can do¶
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.
Quick Start¶
Here is a short EPJ file that I’ll be using as an example to start us off
{
"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
}
}
}
To use eppy3000 to look at this model, we have to run a little code first:
[1]:
# you would normaly install eppy3000 by doing
# python setup.py install
# or
# pip install eppy3000
# or
# easy_install eppy3000
# if you have not done so, uncomment the following three lines
import sys
# pathnameto_eppy = 'c:/eppy3000'
pathnameto_eppy3000 = '../'
sys.path.append(pathnameto_eppy3000)
from eppy3000.modelmaker import EPJ
schema_file = "../eppy3000/resources/schema/V9_3/Energy+.schema.epJSON"
ep_file = "../eppy3000/resources/epJSON/V9_3/smallfile.epJSON"
[2]:
epj = EPJ(epjname=ep_file, epschemaname=schema_file)
[3]:
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
Looks like the same file as before, except that it is written in the idf format
As you can see, this file has four objects:
Version
SimulationControl
Building
Site:Location
You may notice some weird fields like EP_KEY
and EPJOBJECT_NAME
Let us look at the Version
object and tease out what is going on
The EPjson
for version
object looks like this:
{
"Version": {
"Version 1": {
"version_identifier": "9.3",
"idf_order": 1
}
},
... <snip> ...
More objects below
}
But eppy3000
prints it like this
Version !- EP_KEY # use .eppykey
Version 1 !- EPJOBJECT_NAME # use .eppyname
9.3 !- version_identifier
1 !- idf_order
E+ and eppy3000
see the E+ objects slightly differently.
Eppy3000 sees each object as having fields
E+ and EPjson see each object as key-value pairs
If you stare at the above representation in EPjson
and eppy3000
you will see how they are different and how they work.
Let us play with the eppy3000
version
[4]:
versions = epj.epobjects["Version"]
version = versions[0]
print(version)
Version !- EP_KEY # use .eppykey
Version 1 !- EPJOBJECT_NAME # use .eppyname
9.3 !- version_identifier
1 !- idf_order
[23]:
print(version.eppykey)
Version
[25]:
print(version.eppyname)
Version 1
[27]:
print(version.version_identifier)
9.3
[28]:
print(version.idf_order)
1
TODO: test what happens when user changes eppykey
and eppyname
Let us do the same with the EPjson
object. Let us treat it as a pure json
object
[37]:
import json
jsonstr = """ {
"Version": {
"Version 1": {
"version_identifier": "9.3",
"idf_order": 1
}
}
}"""
print(jsonstr)
{
"Version": {
"Version 1": {
"version_identifier": "9.3",
"idf_order": 1
}
}
}
[38]:
epjson = json.loads(jsonstr)
print(epjson)
{'Version': {'Version 1': {'version_identifier': '9.3', 'idf_order': 1}}}
[39]:
ep_versions = epjson["Version"]
print(ep_versions)
{'Version 1': {'version_identifier': '9.3', 'idf_order': 1}}
[40]:
ep_version = ep_versions["Version 1"]
print(ep_version)
{'version_identifier': '9.3', 'idf_order': 1}
[41]:
print(ep_version["version_identifier"])
9.3
[42]:
print(ep_version["idf_order"])
1
Do you notice how much easier it is to operate with the eppy3000
than direclty with the json
structure of EPjson
So, let us look take a closer look at the BUILDING object. We can do this using this command:
print(epjfile.epobjects[‘OBJECTNAME’])
[4]:
print(epj.epobjects['Building']) # put the name of the object you'd like to look at in brackets
[
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]
We can also zoom in on the object and look just at its individual parts.
For example, let us look at the name of the building.
[5]:
building = epj.epobjects['Building'][0]
Now we can do this:
[6]:
building.eppyname
[6]:
'Empire State Building'
Now that we’ve isolated the building name, we can change it.
[7]:
building.eppyname = "Taj Mahal"
Did this actually change the name in the model ? Let us print the entire model and see.
[8]:
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
Taj Mahal !- 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
Yes! It did. So now you have a taste of what eppy can do. Let’s get started!
Modifying EPJ Fields¶
That was just a quick example – we were showing off. Let’s look a little closer.
As you might have guessed, changing an EPJ field follows this structure:
object.fieldname = "New Field Name"
Plugging the object name (building), the field name (Name) and our new field name (“Empire State Building”) into this command gave us this:
object.fieldname = "New Field Name"
But how did we know that “Name” is one of the fields in the object “building”?
Are there other fields?
What are they called?
[9]:
# TODO: need to implement the function fieldnames()
Python lesson 1: lists¶
do this later ?
How many items in the list¶
Do this later
Saving an epj file¶
This is easy:
epj.save()
# OR
epj.saveas("newname.epJSON")
Working with E+ objects¶
Let us open a small epj file that has only “CONSTRUCTION” and “MATERIAL” objects in it. You can go into “../eppy3000/resources/epJSON/V9_3/constructions.epJSON” 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 -
[10]:
from eppy3000 import modelmaker
from eppy3000.modelmaker import EPJ
fname = "../eppy3000/resources/epJSON/V9_3/constructions.epJSON"
epschemaname ="../eppy3000/resources/schema/V9_0/Energy+.schema.epJSON"
epj = EPJ(fname, epschemaname)
Let us print all the “MATERIAL” objects in this model.
[11]:
materials = epj.epobjects["Material"]
print(materials)
[
Material !- EP_KEY # use .eppykey
F08 Metal surface !- EPJOBJECT_NAME # use .eppyname
Smooth !- roughness
0.0008 !- thickness
45.28 !- conductivity
7824 !- density
500 !- specific_heat
2 !- idf_order,
Material !- EP_KEY # use .eppykey
I01 25mm insulation board !- EPJOBJECT_NAME # use .eppyname
MediumRough !- roughness
0.0254 !- thickness
0.03 !- conductivity
43 !- density
1210 !- specific_heat
3 !- idf_order,
Material !- EP_KEY # use .eppykey
I02 50mm insulation board !- EPJOBJECT_NAME # use .eppyname
MediumRough !- roughness
0.0508 !- thickness
0.03 !- conductivity
43 !- density
1210 !- specific_heat
4 !- idf_order,
Material !- EP_KEY # use .eppykey
G01a 19mm gypsum board !- EPJOBJECT_NAME # use .eppyname
MediumSmooth !- roughness
0.019 !- thickness
0.16 !- conductivity
800 !- density
1090 !- specific_heat
5 !- idf_order,
Material !- EP_KEY # use .eppykey
M11 100mm lightweight concrete !- EPJOBJECT_NAME # use .eppyname
MediumRough !- roughness
0.1016 !- thickness
0.53 !- conductivity
1280 !- density
840 !- specific_heat
6 !- idf_order,
Material !- EP_KEY # use .eppykey
F16 Acoustic tile !- EPJOBJECT_NAME # use .eppyname
MediumSmooth !- roughness
0.0191 !- thickness
0.06 !- conductivity
368 !- density
590 !- specific_heat
7 !- idf_order,
Material !- EP_KEY # use .eppykey
M01 100mm brick !- EPJOBJECT_NAME # use .eppyname
MediumRough !- roughness
0.1016 !- thickness
0.89 !- conductivity
1920 !- density
790 !- specific_heat
8 !- idf_order,
Material !- EP_KEY # use .eppykey
M15 200mm heavyweight concrete !- EPJOBJECT_NAME # use .eppyname
MediumRough !- roughness
0.2032 !- thickness
1.95 !- conductivity
2240 !- density
900 !- specific_heat
9 !- idf_order,
Material !- EP_KEY # use .eppykey
M05 200mm concrete block !- EPJOBJECT_NAME # use .eppyname
MediumRough !- roughness
0.2032 !- thickness
1.11 !- conductivity
800 !- density
920 !- specific_heat
10 !- idf_order,
Material !- EP_KEY # use .eppykey
G05 25mm wood !- EPJOBJECT_NAME # use .eppyname
MediumSmooth !- roughness
0.0254 !- thickness
0.15 !- conductivity
608 !- density
1630 !- specific_heat
11 !- idf_order]
As you can see, there are many material objects in this epj file.
The variable “materials” now contains a list of “MATERIAL” objects.
You already know a little about lists, so let us take a look at the items in this list.
[12]:
firstmaterial = materials[0]
secondmaterial = materials[1]
[13]:
print(firstmaterial)
Material !- EP_KEY # use .eppykey
F08 Metal surface !- EPJOBJECT_NAME # use .eppyname
Smooth !- roughness
0.0008 !- thickness
45.28 !- conductivity
7824 !- density
500 !- specific_heat
2 !- idf_order
Let us print secondmaterial
[18]:
print(secondmaterial)
Material !- EP_KEY
I01 25mm insulation board !- EPJOBJECT_NAME
MediumRough !- roughness
0.0254 !- thickness
0.03 !- conductivity
43 !- density
1210 !- specific_heat
3 !- idf_order
This is awesome!! Why?
To understand what you can do with your objects organized as lists, you’ll have to learn a little more about lists.
Python lesson 2: more about lists¶
More ways to access items in a list¶
Do this later
Continuing to work with E+ objects¶
Let us get those “MATERIAL” objects again
[21]:
materials = epj.epobjects["Material"]
With our newfound knowledge of lists, we can do a lot of things.
Let us get the last material:
[22]:
print(materials[-1])
Material !- EP_KEY
G05 25mm wood !- EPJOBJECT_NAME
MediumSmooth !- roughness
0.0254 !- thickness
0.15 !- conductivity
608 !- density
1630 !- specific_heat
11 !- idf_order
How about the last two?
[23]:
print(materials[-2:])
[
Material !- EP_KEY
M05 200mm concrete block !- EPJOBJECT_NAME
MediumRough !- roughness
0.2032 !- thickness
1.11 !- conductivity
800 !- density
920 !- specific_heat
10 !- idf_order,
Material !- EP_KEY
G05 25mm wood !- EPJOBJECT_NAME
MediumSmooth !- roughness
0.0254 !- thickness
0.15 !- conductivity
608 !- density
1630 !- specific_heat
11 !- idf_order]
More stuff to do later
Python lesson 3: indentation and looping through lists¶
Do later
Looping through E+ objects¶
If you have read the python explanation of loops, you are now masters of using loops.
Let us use the loops with E+ objects.
We’ll continue to work with the materials list.
[25]:
for material in materials:
print(material.eppyname)
F08 Metal surface
I01 25mm insulation board
I02 50mm insulation board
G01a 19mm gypsum board
M11 100mm lightweight concrete
F16 Acoustic tile
M01 100mm brick
M15 200mm heavyweight concrete
M05 200mm concrete block
G05 25mm wood
[26]:
[material.eppyname for material in materials]
[26]:
['F08 Metal surface',
'I01 25mm insulation board',
'I02 50mm insulation board',
'G01a 19mm gypsum board',
'M11 100mm lightweight concrete',
'F16 Acoustic tile',
'M01 100mm brick',
'M15 200mm heavyweight concrete',
'M05 200mm concrete block',
'G05 25mm wood']
[28]:
[material.roughness for material in materials]
[28]:
['Smooth',
'MediumRough',
'MediumRough',
'MediumSmooth',
'MediumRough',
'MediumSmooth',
'MediumRough',
'MediumRough',
'MediumRough',
'MediumSmooth']
[31]:
[material.thickness for material in materials if material.thickness > 0.1]
[31]:
[0.1016, 0.1016, 0.2032, 0.2032]
[32]:
[material.eppyname for material in materials if material.thickness > 0.1]
[32]:
['M11 100mm lightweight concrete',
'M01 100mm brick',
'M15 200mm heavyweight concrete',
'M05 200mm concrete block']
[33]:
thick_materials = [material for material in materials if material.thickness > 0.1]
[34]:
thick_materials
[34]:
[
Material !- EP_KEY
M11 100mm lightweight concrete !- EPJOBJECT_NAME
MediumRough !- roughness
0.1016 !- thickness
0.53 !- conductivity
1280 !- density
840 !- specific_heat
6 !- idf_order,
Material !- EP_KEY
M01 100mm brick !- EPJOBJECT_NAME
MediumRough !- roughness
0.1016 !- thickness
0.89 !- conductivity
1920 !- density
790 !- specific_heat
8 !- idf_order,
Material !- EP_KEY
M15 200mm heavyweight concrete !- EPJOBJECT_NAME
MediumRough !- roughness
0.2032 !- thickness
1.95 !- conductivity
2240 !- density
900 !- specific_heat
9 !- idf_order,
Material !- EP_KEY
M05 200mm concrete block !- EPJOBJECT_NAME
MediumRough !- roughness
0.2032 !- thickness
1.11 !- conductivity
800 !- density
920 !- specific_heat
10 !- idf_order]
[35]:
# change the names of the thick materials
for material in thick_materials:
material.eppyname = "THICK " + material.eppyname
[36]:
thick_materials
[36]:
[
Material !- EP_KEY
THICK M11 100mm lightweight concrete !- EPJOBJECT_NAME
MediumRough !- roughness
0.1016 !- thickness
0.53 !- conductivity
1280 !- density
840 !- specific_heat
6 !- idf_order,
Material !- EP_KEY
THICK M01 100mm brick !- EPJOBJECT_NAME
MediumRough !- roughness
0.1016 !- thickness
0.89 !- conductivity
1920 !- density
790 !- specific_heat
8 !- idf_order,
Material !- EP_KEY
THICK M15 200mm heavyweight concrete !- EPJOBJECT_NAME
MediumRough !- roughness
0.2032 !- thickness
1.95 !- conductivity
2240 !- density
900 !- specific_heat
9 !- idf_order,
Material !- EP_KEY
THICK M05 200mm concrete block !- EPJOBJECT_NAME
MediumRough !- roughness
0.2032 !- thickness
1.11 !- conductivity
800 !- density
920 !- specific_heat
10 !- idf_order]
Do the rest later
Geometry functions in eppy3000¶
No geometry functions yet in eppy3000
TODO: Add geometry functions