Closed JKesslerPhD closed 6 months ago
I see the error happening in your example. Let me try a few examples on my own and see what I get
I am not seeing a Space Name
in the IDD file for E+ version 9.5.0
The snippet of the IDD file looks like this:
BuildingSurface:Detailed,
\memo Allows for detailed entry of building heat transfer surfaces. Does not include subsurfaces such as windows or doors.
\extensible:3 -- duplicate last set of x,y,z coordinates (last 3 fields), remembering to remove ; from "inner" fields.
\format vertices
\min-fields 19
A1 , \field Name
\required-field
\type alpha
\reference SurfaceNames
\reference SurfAndSubSurfNames
\reference AllHeatTranSurfNames
\reference OutFaceEnvNames
\reference AllHeatTranAngFacNames
\reference RadiantSurfaceNames
\reference AllShadingAndHTSurfNames
\reference FloorSurfaceNames
A2 , \field Surface Type
\required-field
\type choice
\key Floor
\key Wall
\key Ceiling
\key Roof
A3 , \field Construction Name
\required-field
\note To be matched with a construction in this input file
\type object-list
\object-list ConstructionNames
A4 , \field Zone Name
\required-field
\note Zone the surface is a part of
\type object-list
\object-list ZoneNames
A5 , \field Outside Boundary Condition
\required-field
\type choice
\key Adiabatic
\key Surface
\key Zone
\key Outdoors
\key Foundation
\key Ground
\key GroundFCfactorMethod
\key OtherSideCoefficients
\key OtherSideConditionsModel
\key GroundSlabPreprocessorAverage
\key GroundSlabPreprocessorCore
\key GroundSlabPreprocessorPerimeter
\key GroundBasementPreprocessorAverageWall
\key GroundBasementPreprocessorAverageFloor
\key GroundBasementPreprocessorUpperWall
\key GroundBasementPreprocessorLowerWall
A6, \field Outside Boundary Condition Object
\type object-list
\object-list OutFaceEnvNames
\note Non-blank only if the field Outside Boundary Condition is Surface,
\note Zone, OtherSideCoefficients or OtherSideConditionsModel
\note If Surface, specify name of corresponding surface in adjacent zone or
\note specify current surface name for internal partition separating like zones
\note If Zone, specify the name of the corresponding zone and
\note the program will generate the corresponding interzone surface
\note If Foundation, specify the name of the corresponding Foundation object and
\note the program will calculate the heat transfer appropriately
\note If OtherSideCoefficients, specify name of SurfaceProperty:OtherSideCoefficients
\note If OtherSideConditionsModel, specify name of SurfaceProperty:OtherSideConditionsModel
A7 , \field Sun Exposure
\type choice
\key SunExposed
\key NoSun
\default SunExposed
A8, \field Wind Exposure
\type choice
\key WindExposed
\key NoWind
\default WindExposed
N1, \field View Factor to Ground
\type real
\note From the exterior of the surface
\note Unused if one uses the "reflections" options in Solar Distribution in Building input
\note unless a DaylightingDevice:Shelf or DaylightingDevice:Tubular object has been specified.
\note autocalculate will automatically calculate this value from the tilt of the surface
\autocalculatable
\minimum 0.0
\maximum 1.0
\default autocalculate
N2 , \field Number of Vertices
\note shown with 120 vertex coordinates -- extensible object
\note "extensible" -- duplicate last set of x,y,z coordinates (last 3 fields),
\note remembering to remove ; from "inner" fields.
\note for clarity in any error messages, renumber the fields as well.
\note (and changing z terminator to a comma "," for all but last one which needs a semi-colon ";")
\autocalculatable
\minimum 3
\default autocalculate
\note vertices are given in GlobalGeometryRules coordinates -- if relative, all surface coordinates
\note are "relative" to the Zone Origin. If world, then building and zone origins are used
\note for some internal calculations, but all coordinates are given in an "absolute" system.
N3, \field Vertex 1 X-coordinate
\begin-extensible
\required-field
\units m
\type real
N4 , \field Vertex 1 Y-coordinate
\required-field
\units m
\type real
N5 , \field Vertex 1 Z-coordinate
\required-field
\units m
\type real
N6, \field Vertex 2 X-coordinate
\required-field
\units m
\type real
N7, \field Vertex 2 Y-coordinate
\required-field
\units m
\type real
N8, \field Vertex 2 Z-coordinate
\required-field
\units m
\type real
N9, \field Vertex 3 X-coordinate
\required-field
\units m
\type real
N10, \field Vertex 3 Y-coordinate
\required-field
\units m
\type real
N11, \field Vertex 3 Z-coordinate
\required-field
\units m
\type real
N12, \field Vertex 4 X-coordinate
\units m
\type real
N13, \field Vertex 4 Y-coordinate
\type real
\units m
N14, \field Vertex 4 Z-coordinate
\units m
\type real
N15, \field Vertex 5 X-coordinate
\units m
\type real
N16, \field Vertex 5 Y-coordinate
\type real
\units m
N17, \field Vertex 5 Z-coordinate
\units m
\type real
<------ snip ----->
N360, \field Vertex 120 X-coordinate
\units m
\type real
N361, \field Vertex 120 Y-coordinate
\units m
\type real
N362; \field Vertex 120 Z-coordinate
\units m
\type real
Yeah, there is no 'space name' field in the 9.5 IDD, but the parser seems to want to populate a space name field. I think the issue is that the IDF.setiddname() method isn't forcing the IDF parser to use the specified IDD file, and is instead defaulting to 23.2.
IDF.idd_version
Out[163]: (9, 5, 0)
IDF.idd_info[0]
Out[164]: [{'memo': ['Specifies the EnergyPlus version of the IDF file.'], 'unique-object': [''], 'format': ['singleLine'], 'group': 'Simulation Parameters', 'idfobj': 'Version'}, {'field': ['Version Identifier'], 'default': ['23.2']}]
I also looked at the file Energy+.schema.epJSON
I am not seeing a space_name
there either
I don't think there is a Space Name
in E+ version 9.5.0
I tested with some sample code and it does not add Space Name
field.
(Maybe your IDD is corrupted ? )
import eppy
idf = eppy.newidf(version="9.5")
# I am using an easier to use function - documented here
# https://eppy.readthedocs.io/en/master/eppy.html#module-eppy
surf = idf.newidfobject("BuildingSurface:Detailed", Name='asurface')
surf
BUILDINGSURFACE:DETAILED,
asurface, !- Name
, !- Surface Type
, !- Construction Name
, !- Zone Name
, !- Outside Boundary Condition
, !- Outside Boundary Condition Object
SunExposed, !- Sun Exposure
WindExposed, !- Wind Exposure
autocalculate, !- View Factor to Ground
autocalculate; !- Number of Vertices
tested with E+ version 22.2
This has Space Name
Let me know if you are able to find out what is going on in your example
see code:
import eppy
idf = eppy.newidf(version="22.2")
surf = idf.newidfobject("BuildingSurface:Detailed", Name='asurface')
surf
BUILDINGSURFACE:DETAILED,
asurface, !- Name
, !- Surface Type
, !- Construction Name
, !- Zone Name
, !- Space Name
, !- Outside Boundary Condition
, !- Outside Boundary Condition Object
SunExposed, !- Sun Exposure
WindExposed, !- Wind Exposure
autocalculate, !- View Factor to Ground
autocalculate; !- Number of Vertices
responding to your earlier comment.
eppy
will not use the wrong IDD.
It does not default to any IDD. It can only use what you specified.
Can you look inside the IDD and see if it has Space Name
in it ?
I think I figured it out -- if I load a more recent IDD file first (e.g. 23.2) then the IDF.setiddname() method won't allow the IDD file to be updated. I had been catching and ignoring that exception.
Is there functionality to unset and reset the idd file that is used?
Also try this
print(idf.idd_version)
looks like you already did that idd_version
Can you post your code snippet that created the issue ?
I read your comment more carefully. it is very strange behavior - what you are seeing should not happen
Let me try a few more tests.
In any case please post your code
class IDFModel():
def __init__(self, idf_path, idd_path):
self.version = ()
self.surfaces = []
self.materials = []
self.constructions = []
self.idf = self.load_idf(idf_path, idd_path)
self.floor_space = None
def load_idf(self, idf_path, idd_path):
try:
IDF.setiddname(idd_path)
return IDF(idf_path)
except Exception as e:
print(f"Unable to load IDF file due to error {e}")
...
m1 = IDFModel(idf_1, 23_2path)
m2 = IDFModel(idf_2, 9_5path)
I think I figured it out -- if I load a more recent IDD file first (e.g. 23.2) then the IDF.setiddname() method won't allow the IDD file to be updated. I had been catching and ignoring that exception.
Is there functionality to unset and reset the idd file that is used?
from tests/pytest_helpers.py
.
this can break things badly - if you have one IDF file in one version and another IDF file in another version.
Remember that eppy
can have only one IDD file at any moment
def safeIDDreset():
"""reset the IDD for testing and catch the exception"""
try:
eppy.modeleditor.IDF.resetidd()
except eppy.modeleditor.IDDResetError as e:
pass
I see from your code that you want to to have files of different versions open at the same time.
eppy
will not work for that :-(
Allowing for this open a a whole can of worms. If you try to copy an idfobject from one file to another, they may have different fields I don't know of an easy way to make this happen.
So I explicitly stopped eppy from opening files of different version at the same time
I've gone ahead and modified the modeleditor.py file to better meet my needs by adding an overwrite flag that defaults to false.
@classmethod
def setiddname(cls, iddname, testing=False, overwrite=False):
"""
Set the path to the EnergyPlus IDD for the version of EnergyPlus which
is to be used by eppy.
Parameters
----------
iddname : str
Path to the IDD file.
testing : bool
Flag to use if running tests since we may want to ignore the
`IDDAlreadySetError`.
Raises
------
IDDAlreadySetError
"""
if cls.iddname == None or overwrite:
cls.iddname = iddname
cls.idd_info = None
cls.block = None
elif cls.iddname == iddname:
pass
else:
if testing == False:
errortxt = "IDD file is set to: %s" % (cls.iddname,)
raise IDDAlreadySetError(errortxt)
that will work for your purposes.
Use with care. Allowing for switching IDD midstream can lead to hard to resolve errors. Once you have reset the IDD, you cannot use any files that were opened with a different IDD unless you reset IDD again. This can be hard to keep track of
close this issue if you think it has been resolved. I am signing off :-)
Thanks!
Functionality for reading seems to work, as the dictionary is populated prior to resetting the IDD. I assume writing is absolutely broken as the IDD will be whatever the last-specified IDD is. I assume some namespacing changes could fix that too.
m1.idf.idfobjects["BUILDINGSURFACE:DETAILED"][4]
Out[29]:
BuildingSurface:Detailed,
Dining_Wall_North-PPAutoCreateOther, !- Name
Wall, !- Surface Type
int-walls, !- Construction Name
Kitchen, !- Zone Name
, !- Outside Boundary Condition
Surface, !- Outside Boundary Condition Object
Dining_Wall_North, !- Sun Exposure
NoSun, !- Wind Exposure
NoWind, !- View Factor to Ground
AutoCalculate, !- Number of Vertices
4, !- Vertex 1 Xcoordinate
0, !- Vertex 1 Ycoordinate
16.4427, !- Vertex 1 Zcoordinate
3.0488, !- Vertex 2 Xcoordinate
0, !- Vertex 2 Ycoordinate
16.4427, !- Vertex 2 Zcoordinate
0, !- Vertex 3 Xcoordinate
22.6087, !- Vertex 3 Ycoordinate
16.4427, !- Vertex 3 Zcoordinate
0, !- Vertex 4 Xcoordinate
22.6087, !- Vertex 4 Ycoordinate
16.4427, !- Vertex 4 Zcoordinate
3.0488; !- Vertex 5 Xcoordinate
m2.idf.idfobjects["BUILDINGSURFACE:DETAILED"][4]
Out[30]:
BuildingSurface:Detailed,
Dining_Wall_North-PPAutoCreateOther, !- Name
Wall, !- Surface Type
int-walls, !- Construction Name
Kitchen, !- Zone Name
, !- Space Name
Surface, !- Outside Boundary Condition
Dining_Wall_North, !- Outside Boundary Condition Object
NoSun, !- Sun Exposure
NoWind, !- Wind Exposure
AutoCalculate, !- View Factor to Ground
4, !- Number of Vertices
0, !- Vertex 1 Xcoordinate
16.4427, !- Vertex 1 Ycoordinate
3.0488, !- Vertex 1 Zcoordinate
0, !- Vertex 2 Xcoordinate
16.4427, !- Vertex 2 Ycoordinate
0, !- Vertex 2 Zcoordinate
22.6087, !- Vertex 3 Xcoordinate
16.4427, !- Vertex 3 Ycoordinate
0, !- Vertex 3 Zcoordinate
22.6087, !- Vertex 4 Xcoordinate
16.4427, !- Vertex 4 Ycoordinate
3.0488; !- Vertex 4 Zcoordinate
I'm setting the IDD to 9.5 by providing a path to the EnergyPlus 9.5 IDD:
idd_path = V9-5-0-Energy+.idd
IDF.setiddname(idd_path)
the older IDD files do not have a "Space Name" attribute. However, the IDF parser appears to be adding keys in an order in which it defines a "Space_Name" attribute which then incorrectly populates all other attributes in the IDD file.
I'm not sure if the issue is that the IDF.setiddname function does not actually result in the IDF parser utilizing the IDD file, or if there is something else going on.
Example below. A "Space Name" was added, when the value populated ("Outdoors") actually corresponds to the "Outside Boundary Condition" attribute. As seen, the "Number of vertices" attribute is then populated with a value that should be "Vertex 1 XCoordinate".
BuildingSurface:Detailed, Roof_right_unit1, !- Name Wall, !- Surface Type Gable_end, !- Construction Name attic_unit1, !- Zone Name Outdoors, !- Space Name , !- Outside Boundary Condition SunExposed, !- Outside Boundary Condition Object WindExposed, !- Sun Exposure , !- Wind Exposure 3, !- View Factor to Ground 12.1330909462833, !- Number of Vertices 0, !- Vertex 1 Xcoordinate 5.19302682926829, !- Vertex 1 Ycoordinate 12.1330909462833, !- Vertex 1 Zcoordinate 9.09981820971244, !- Vertex 2 Xcoordinate 5.19302682926829, !- Vertex 2 Ycoordinate 12.1330909462833, !- Vertex 2 Zcoordinate 4.54990910485622, !- Vertex 3 Xcoordinate 6.6995631975537; !- Vertex 3 Ycoordinate