Skip to content

Retain IDF order and comments #261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions eppy/modeleditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
from eppy.idfreader import makeabunch
from eppy.runner.run_functions import run
from eppy.runner.run_functions import wrapped_help_text
import eppy.EPlusInterfaceFunctions.mylib2 as mylib2
import re


class NoObjectError(Exception):
Expand Down Expand Up @@ -497,6 +499,39 @@ def zonevolume(idf, zonename):
def refname2key(idf, refname):
"""return all keys that have the reference name"""
return [item[0] for item in getallobjlists(idf, refname)]

def withcomment(astr, idfog_keys):
alist = astr.splitlines()
blist = []
mode = 'on'
for i in range(len(alist)):
#if re.search('!- Thermal Resistance {m2-K/W}',alist[i]):
# blist.append(alist[i])
temp_key = str(alist[i].split(',')[0]).strip().upper()
if temp_key in idfog_keys:
mode = 'off' # mode variable is included to catch comments within the objects and not append ## at the end of those comments
temp_key = ''
if re.search('^\s*!',alist[i]):
alist[i] = alist[i].replace(',','@com@')
alist[i] = alist[i].replace(';','@col@')

if re.search('^\s*!',alist[i]) and mode == 'on':
blist.append(alist[i]+'#@#')
elif re.search('.*,.*!-.*;',alist[i]): #to catch the error in SizingPeriod:DesignDay object
blist.append(alist[i])
elif re.search('.*;',alist[i]):
blist.append(alist[i]+'#@#')
mode = 'on'
else: blist.append(alist[i])
return '\n'.join(blist)

def check_obj(objog, obj1):
if obj1 == None:
return 'deleted', objog, obj1
elif obj1.obj == objog.obj:
return 'unchanged', objog, obj1
else:
return 'modified', objog, obj1


class IDF(object):
Expand Down Expand Up @@ -1030,3 +1065,92 @@ def getiddgroupdict(self):
dict
"""
return iddgroups.commdct2grouplist(self.idd_info)


def saveinorder(self, filename=None):
if filename == None:
filename = self.idfname
idfog = IDF(self.idfname)
idfog_keys = idfog.model.dtls
special_objs = ['OUTPUT:VARIABLE'] #objects which require 3 identifiers unlike most others which require 2
special_objs1 = [] #objects which dont have identifiers(all objects with first input value as int/float)
g2 = open(filename, 'w+', encoding='utf8') #encoding here fixed the charmap coded error in ApartmentHighRise
astr = mylib2.readfile(self.idfname)
withcom = withcomment(astr, idfog_keys)
blist = withcom.split('#@#')
for astr in blist:
if re.search('^\s*!',astr.strip()):
astr = astr.replace('@com@',',')
astr = astr.replace('@col@',';')
g2.write(astr)

else:
alist = astr.splitlines()
for i in range(len(alist)):
alist1 = alist[i].split('!')
alist[i] = alist1[0]
alist = '\n'.join(alist)

alist = alist.split(';')
lss1 = []
lss1 = alist[0].split(',')
for i in range(0,len(lss1)):
lss1[i] = lss1[i].strip()
if lss1 == ['']: continue
key = lss1[0].upper()
name = str(lss1[1])
check_name_type = type(idfog.idfobjects[key][0].obj[1])
if check_name_type == int or check_name_type == float: #objects with 1 identifier (key)
special_objs1.append(key)
objog = idfog.idfobjects[key][0]
obj1 = self.idfobjects[key][0]
elif key in special_objs: #objects with 3 identifiers (key, name, name1)
name1 = str(lss1[2])

for i in idfog.idfobjects[key]:
if i.obj[1] == name and i.obj[2] == name1:
objog = i
for i in self.idfobjects[key]:
if i.obj[1] == name and i.obj[2] == name1:
obj1 = i
break
else: obj1 = None

else: #all other objects with 2 identifiers (key, name)
objog = idfog.getobject(key,name)
obj1 = self.getobject(key,name)

status, objog, obj1 = check_obj(objog, obj1)

if status == 'deleted':
continue
#g2.write('\n! '+objog.obj[0]+' : '+objog.obj[1]+' was deleted\n') #uncomment this if you want to add this line for every object you delete
elif status == 'unchanged':
astr = astr.replace('@com@',',')
astr = astr.replace('@col@',';')
g2.write(astr)
elif status == 'modified':
g2.write(str(obj1))


#for new objects added
idf1_keysnames, idfog_keysnames = [], []
for i in self.model.dtls:
for j in self.idfobjects[i]:
if i in special_objs : idf1_keysnames.append([i,str(j.obj[1]).upper(),str(j.obj[2]).upper()])
else: idf1_keysnames.append([i,str(j.obj[1]).upper()])
for i in idfog.model.dtls:
for j in idfog.idfobjects[i]:
if i in special_objs : idfog_keysnames.append([i,str(j.obj[1]).upper(),str(j.obj[2]).upper()])
else: idfog_keysnames.append([i,str(j.obj[1]).upper()])

for i in idf1_keysnames:
if i in idfog_keysnames or i[0] in special_objs1: continue
else:
if i[0] in special_objs:
for j in self.idfobjects[i[0]]:
if j.obj[1].upper() == i[1] and j.obj[2].upper() == i[2]:
g2.write(str(j))
else:
g2.write('\n'+str(self.getobject(i[0], i[1])))
g2.close()