Source code for eppy.useful_scripts.idfdiff_missing

# Copyright (c) 2012 Santosh Philip
# =======================================================================
#  Distributed under the MIT License.
#  (See accompanying file LICENSE or copy at
#  http://opensource.org/licenses/MIT)
# =======================================================================

# along with Eppy.  If not, see <http://www.gnu.org/licenses/>.

"""
Do a diff between two idf files.
Prints the diff in csv  or html file format.
You can redirect the output to a file and open the file using as a spreadsheet or by using a browser
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import argparse

import sys
import itertools
from bs4 import BeautifulSoup, Tag

pathnameto_eplusscripting = "../../"
sys.path.append(pathnameto_eplusscripting)

from eppy.bunch_subclass import BadEPFieldError
from eppy.modeleditor import IDF


help_message = """
The help message goes here.
"""


[docs]class Usage(Exception): def __init__(self, msg): self.msg = msg
[docs]def getobjname(item): """return obj name or blank""" try: objname = item.Name except BadEPFieldError as e: objname = " " return objname
[docs]def theheader(n1, n2): """return the csv header""" s = "Object Key, Object Name, Field Name, %s, %s" % ("file1", "file2") return s.split(",")
[docs]class DtlsSorter(object): """helps me to sort it using the order of keys in idd file""" def __init__(self, dtls): self.dtlsorder = {j: i for i, j in enumerate(dtls)}
[docs] def getkey(self, item): return self.dtlsorder[item[0]] # item[0] is the object key
[docs]def makecsvdiffs(thediffs, dtls, n1, n2): """return the csv to be displayed""" def ishere(val): if val == None: return "not here" else: return "is here" rows = [] rows.append(["file1 = %s" % (n1,)]) rows.append(["file2 = %s" % (n2,)]) rows.append("") rows.append(theheader(n1, n2)) keys = list(thediffs.keys()) # ensures sorting by Name keys.sort() # sort the keys in the same order as in the idd dtlssorter = DtlsSorter(dtls) keys = sorted(keys, key=dtlssorter.getkey) for key in keys: if len(key) == 2: rw2 = [""] + [ishere(i) for i in thediffs[key]] else: rw2 = list(thediffs[key]) rw1 = list(key) rows.append(rw1 + rw2) return rows
[docs]def idfdiffs(idf1, idf2): """return the diffs between the two idfs""" thediffs = {} keys = idf1.model.dtls # undocumented variable for akey in keys: idfobjs1 = idf1.idfobjects[akey] idfobjs2 = idf2.idfobjects[akey] names = set( [getobjname(i) for i in idfobjs1] + [getobjname(i) for i in idfobjs2] ) names = sorted(names) idfobjs1 = sorted(idfobjs1, key=lambda idfobj: idfobj["obj"]) idfobjs2 = sorted(idfobjs2, key=lambda idfobj: idfobj["obj"]) for name in names: n_idfobjs1 = [item for item in idfobjs1 if getobjname(item) == name] n_idfobjs2 = [item for item in idfobjs2 if getobjname(item) == name] for idfobj1, idfobj2 in itertools.zip_longest(n_idfobjs1, n_idfobjs2): if idfobj1 == None: thediffs[(idfobj2.key.upper(), getobjname(idfobj2))] = ( None, idf1.idfname, ) # (idf1.idfname, None) break if idfobj2 == None: thediffs[(idfobj1.key.upper(), getobjname(idfobj1))] = ( idf2.idfname, None, ) # (None, idf2.idfname) break # for i, (f1, f2) in enumerate(zip(idfobj1.obj, idfobj2.obj)): # if i == 0: # f1, f2 = f1.upper(), f2.upper() # if f1 != f2: # thediffs[(akey, # getobjname(idfobj1), # idfobj1.objidd[i]['field'][0])] = (f1, f2) return thediffs
[docs]def printcsv(csvdiffs): """print the csv""" for row in csvdiffs: print(",".join([str(cell) for cell in row]))
[docs]def heading2table(soup, table, row): """add heading row to table""" tr = Tag(soup, name="tr") table.append(tr) for attr in row: th = Tag(soup, name="th") tr.append(th) th.append(attr)
[docs]def row2table(soup, table, row): """ad a row to the table""" tr = Tag(soup, name="tr") table.append(tr) for attr in row: td = Tag(soup, name="td") tr.append(td) td.append(attr)
[docs]def printhtml(csvdiffs): """print the html""" soup = BeautifulSoup() html = Tag(soup, name="html") para1 = Tag(soup, name="p") para1.append(csvdiffs[0][0]) para2 = Tag(soup, name="p") para2.append(csvdiffs[1][0]) table = Tag(soup, name="table") table.attrs.update(dict(border="1")) soup.append(html) html.append(para1) html.append(para2) html.append(table) heading2table(soup, table, csvdiffs[3]) for row in csvdiffs[4:]: row = [str(cell) for cell in row] row2table(soup, table, row) # print soup.prettify() print(soup)
if __name__ == "__main__": # do the argparse stuff parser = argparse.ArgumentParser(usage=None, description=__doc__) parser.add_argument( "idd", action="store", help="location of idd file = ./somewhere/eplusv8-0-1.idd" ) parser.add_argument( "file1", action="store", help="location of first with idf files = ./somewhere/f1.idf", ) parser.add_argument( "file2", action="store", help="location of second with idf files = ./somewhere/f2.idf", ) group = parser.add_mutually_exclusive_group(required=True) group.add_argument("--csv", action="store_true") group.add_argument("--html", action="store_true") nspace = parser.parse_args() fname1 = nspace.file1 fname2 = nspace.file2 iddfile = nspace.idd IDF.setiddname(iddfile) idf1 = IDF(fname1) idf2 = IDF(fname2) dtls = idf1.model.dtls # undocumented variable thediffs = idfdiffs(idf1, idf2) csvdiffs = makecsvdiffs(thediffs, dtls, idf1.idfname, idf2.idfname) if nspace.csv: printcsv(csvdiffs) elif nspace.html: printhtml(csvdiffs) # python idfdiff.py --csv ../resources/iddfiles/Energy+V7_2_0.idd ../resources/idffiles/V_7_2/constr.idf ../resources/idffiles/V_7_2/constr_diff.idf # python idfdiff.py --html ../resources/iddfiles/Energy+V7_2_0.idd ../resources/idffiles/V_7_2/constr.idf ../resources/idffiles/V_7_2/constr_diff.idf # python idfdiff2.py --html ../resources/iddfiles/Energy+V8_0_0.idd ../resources/idffiles/V8_0_0/5ZoneSupRetPlenRAB.idf ../resources/idffiles/V8_0_0/5ZoneWaterLoopHeatPump.idf