Skip to content

Commit

Permalink
Merge pull request #1830 from SEED-platform/parser_update
Browse files Browse the repository at this point in the history
BuildingSync Version 1.0 Support, Remove Unused Tables, Add ULID and Footprints
  • Loading branch information
nllong committed Mar 7, 2019
2 parents 9c83048 + 2302b9d commit 0469a1d
Show file tree
Hide file tree
Showing 23 changed files with 4,289 additions and 3,962 deletions.
1 change: 1 addition & 0 deletions requirements/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ vcrpy==2.0.1

# static code analysis
flake8==3.5.0
pycodestyle==2.3.1

# documentation and spelling
Sphinx==1.8.1
Expand Down
49 changes: 25 additions & 24 deletions seed/building_sync/building_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

class BuildingSync(object):
ADDRESS_STRUCT = {
"root": "auc:Audits.auc:Audit.auc:Sites.auc:Site.auc:Address",
"root": "auc:BuildingSync.auc:Facilities.auc:Facility.auc:Sites.auc:Site.auc:Address",
"return": {
"address_line_1": {
"path": "auc:StreetAddressDetail.auc:Simplified.auc:StreetAddress",
Expand All @@ -45,7 +45,7 @@ class BuildingSync(object):
}

BRICR_STRUCT = {
"root": "auc:Audits.auc:Audit",
"root": "auc:BuildingSync.auc:Facilities.auc:Facility",
"return": {
"address_line_1": {
"path": "auc:Sites.auc:Site.auc:Address.auc:StreetAddressDetail.auc:Simplified.auc:StreetAddress",
Expand Down Expand Up @@ -78,59 +78,59 @@ class BuildingSync(object):
"type": "double",
},
"property_name": {
"path": "auc:Sites.auc:Site.auc:Facilities.auc:Facility.@ID",
"path": "auc:Sites.auc:Site.auc:Buildings.auc:Building.@ID",
"required": True,
"type": "string",
},
"year_built": {
"path": "auc:Sites.auc:Site.auc:Facilities.auc:Facility.auc:YearOfConstruction",
"path": "auc:Sites.auc:Site.auc:Buildings.auc:Building.auc:YearOfConstruction",
"required": True,
"type": "integer",
},
"floors_above_grade": {
"path": "auc:Sites.auc:Site.auc:Facilities.auc:Facility.auc:FloorsAboveGrade",
"path": "auc:Sites.auc:Site.auc:Buildings.auc:Building.auc:FloorsAboveGrade",
"required": False,
"type": "integer",
},
"floors_below_grade": {
"path": "auc:Sites.auc:Site.auc:Facilities.auc:Facility.auc:FloorsBelowGrade",
"path": "auc:Sites.auc:Site.auc:Buildings.auc:Building.auc:FloorsBelowGrade",
"required": False,
"type": "integer",
},
"premise_identifier": {
"path": "auc:Sites.auc:Site.auc:Facilities.auc:Facility.auc:PremisesIdentifiers.auc:PremisesIdentifier",
"path": "auc:Sites.auc:Site.auc:Buildings.auc:Building.auc:PremisesIdentifiers.auc:PremisesIdentifier",
"key_path_name": "auc:IdentifierLabel",
"key_path_value": "Assessor parcel number",
"value_path_name": "auc:IdentifierValue",
"required": False, # temporarily make this False until AT can handle it correctly.
"type": "string",
},
"custom_id_1": {
"path": "auc:Sites.auc:Site.auc:Facilities.auc:Facility.auc:PremisesIdentifiers.auc:PremisesIdentifier",
"path": "auc:Sites.auc:Site.auc:Buildings.auc:Building.auc:PremisesIdentifiers.auc:PremisesIdentifier",
"key_path_name": "auc:IdentifierCustomName",
"key_path_value": "Custom ID 1",
"value_path_name": "auc:IdentifierValue",
"required": False,
"type": "string",
},
"gross_floor_area": {
"path": "auc:Sites.auc:Site.auc:Facilities.auc:Facility.auc:FloorAreas.auc:FloorArea",
"path": "auc:Sites.auc:Site.auc:Buildings.auc:Building.auc:FloorAreas.auc:FloorArea",
"key_path_name": "auc:FloorAreaType",
"key_path_value": "Gross",
"value_path_name": "auc:FloorAreaValue",
"required": True,
"type": "double",
},
"net_floor_area": {
"path": "auc:Sites.auc:Site.auc:Facilities.auc:Facility.auc:FloorAreas.auc:FloorArea",
"path": "auc:Sites.auc:Site.auc:Buildings.auc:Building.auc:FloorAreas.auc:FloorArea",
"key_path_name": "auc:FloorAreaType",
"key_path_value": "Net",
"value_path_name": "auc:FloorAreaValue",
"required": False,
"type": "double",
},
"footprint_floor_area": {
"path": "auc:Sites.auc:Site.auc:Facilities.auc:Facility.auc:FloorAreas.auc:FloorArea",
"path": "auc:Sites.auc:Site.auc:Buildings.auc:Building.auc:FloorAreas.auc:FloorArea",
"key_path_name": "auc:FloorAreaType",
"key_path_value": "Footprint",
"value_path_name": "auc:FloorAreaValue",
Expand Down Expand Up @@ -162,10 +162,11 @@ def import_file(self, filename):
xmlfile.read(),
process_namespaces=True,
namespaces={
'http://nrel.gov/schemas/bedes-auc/2014': 'auc',
'http://buildingsync.net/schemas/bedes-auc/2019': 'auc',
'http://www.w3.org/2001/XMLSchema-instance': 'xsi',
}
)

else:
raise Exception("File not found: {}".format(filename))

Expand All @@ -192,13 +193,13 @@ def export(self, property_state, process_struct=ADDRESS_STRUCT):
new_dict = OrderedDict(
[
(
'auc:Audits', OrderedDict(
'auc:BuildingSync', OrderedDict(
[
('@xsi:schemaLocation',
'http://nrel.gov/schemas/bedes-auc/2014 https://github.com/BuildingSync/schema/releases/download/v0.3/BuildingSync.xsd'),
'http://buildingsync.net/schemas/bedes-auc/2019 https://github.com/BuildingSync/schema/releases/download/v1.0.0/BuildingSync.xsd'),
('@xmlns', OrderedDict(
[
('auc', 'http://nrel.gov/schemas/bedes-auc/2014'),
('auc', 'http://buildingsync.net/schemas/bedes-auc/2019'),
('xsi', 'http://www.w3.org/2001/XMLSchema-instance')
]
))
Expand All @@ -209,18 +210,15 @@ def export(self, property_state, process_struct=ADDRESS_STRUCT):
)
else:
# check that the appropriate headers are set or XML won't render correctly in the browser
if '@xsi:schemaLocation' not in new_dict['auc:Audits'] or '@xmlns' not in new_dict['auc:Audits']:
new_dict['auc:Audits']['@xsi:schemaLocation'] = 'http://nrel.gov/schemas/bedes-auc/2014 https://github.com/BuildingSync/schema/releases/download/v0.3/BuildingSync.xsd'
new_dict['auc:Audits']['@xmlns'] = OrderedDict
if '@xsi:schemaLocation' not in new_dict['auc:BuildingSync'] or '@xmlns' not in new_dict['auc:BuildingSync']:
new_dict['auc:BuildingSync']['@xsi:schemaLocation'] = 'http://buildingsync.net/schemas/bedes-auc/2019 https://github.com/BuildingSync/schema/releases/download/v1.0.0/BuildingSync.xsd'
new_dict['auc:BuildingSync']['@xmlns'] = OrderedDict
(
[
('auc', 'http://nrel.gov/schemas/bedes-auc/2014'),
('auc', 'http://buildingsync.net/schemas/bedes-auc/2019'),
('xsi', 'http://www.w3.org/2001/XMLSchema-instance')
]
)
# for some reason the auc header gets put on Audits.Audit instead of Audit by the building_sync parser...remove
if '@xmlns' in new_dict['auc:Audits']['auc:Audit']:
del new_dict['auc:Audits']['auc:Audit']['@xmlns']

for field, v in process_struct['return'].items():
value = None
Expand Down Expand Up @@ -404,9 +402,11 @@ def _get_node(self, path, node, results=[], kwargs={}):
:param results: list or value, results
:return: list, results
"""

path = path.split(".")

for idx, p in enumerate(path):

if p == '':
if node:
results.append(node)
Expand Down Expand Up @@ -459,6 +459,7 @@ def _lookup_sub(node, key_path_name, key_path_value, value_path_name):

res = {'measures': [], 'scenarios': []}
messages = {'errors': [], 'warnings': []}

for k, v in struct['return'].items():
path = ".".join([struct['root'], v['path']])
value = self._get_node(path, data, [])
Expand Down Expand Up @@ -532,7 +533,7 @@ def _lookup_sub(node, key_path_name, key_path_value, value_path_name):
# <auc:MeasureInstallationCost>0.0</auc:MeasureInstallationCost>
# <auc:MeasureMaterialCost>0.0</auc:MeasureMaterialCost>
# </auc:Measure>
measures = self._get_node('auc:Audits.auc:Audit.auc:Measures.auc:Measure', data, [])
measures = self._get_node('auc:BuildingSync.auc:Facilities.auc:Facility.auc:Measures.auc:Measure', data, [])
# check that this is a list, if not, make it a list or the loop won't work correctly
if isinstance(measures, dict):
# print("measures is a dict...converting it to a list")
Expand Down Expand Up @@ -576,7 +577,7 @@ def _lookup_sub(node, key_path_name, key_path_value, value_path_name):
# </auc:PackageOfMeasures>
# </auc:ScenarioType>
# </auc:Scenario>
scenarios = self._get_node('auc:Audits.auc:Audit.auc:Report.auc:Scenarios.auc:Scenario',
scenarios = self._get_node('auc:BuildingSync.auc:Facilities.auc:Facility.auc:Report.auc:Scenarios.auc:Scenario',
data, [])

# check that this is a list; if not, make it a list or the loop won't work correctly
Expand Down

0 comments on commit 0469a1d

Please sign in to comment.