import rdflib import pdb from rdflib import Namespace import json import os from collections import defaultdict schema_g = rdflib.Graph() # TODO: Migrate everyhting here under rdf_wrapper def get_prefixes(version): BRICK = Namespace('https://brickschema.org/schema/{0}/Brick#'.format(version)) BRICKFRAME = Namespace('https://brickschema.org/schema/{0}/BrickFrame#'.format(version)) BRICKTAG = Namespace('https://brickschema.org/schema/{0}/BrickTag#'.format(version)) return { 'brick': BRICK, 'bf': BRICKFRAME, 'tag': BRICKTAG, 'rdfs': rdflib.RDFS, 'rdf': rdflib.RDF, 'owl': rdflib.OWL, } def get_schema_graph(version): if not schema_g: schema_g.parse('/home/jbkoh/repo/Brick_jbkoh/dist/Brick.ttl', format='turtle') schema_g.parse('/home/jbkoh/repo/Brick_jbkoh/dist/BrickFrame.ttl', format='turtle') # TODO: Parameterize this or use an online link. return schema_g def extract_tagset(uri): return uri.split('#')[-1].lower() def get_subclasses(version, topclass): qstr = """ SELECT ?point where {{ ?point rdfs:subClassOf+ {0}. }} """.format(topclass) g = get_schema_graph(version) return [extract_tagset(row[0]) for row in g.query(qstr, initNs=get_prefixes(version))] def get_direct_subclasses_dict(version, topclass='bf:TagSet'): qstr = """ SELECT ?child ?parent where {{ ?child rdfs:subClassOf ?parent. }} """.format(topclass) g = get_schema_graph(version) subclasses = defaultdict(set) for [child, parent] in g.query(qstr, initNs=get_prefixes(version)): subclasses[extract_tagset(parent)].add(extract_tagset(child)) for k, v in subclasses.items(): subclasses[k] = list(v) return subclasses def get_subclasses_dict(version, topclass='bf:TagSet'): # NOTE: Maybe this should consider equivalentClassOF too. qstr = """ SELECT ?child ?parent where {{ ?child rdfs:subClassOf+ ?parent. ?parent rdfs:subClassOf* {0}. }} """.format(topclass) g = get_schema_graph(version) subclasses = defaultdict(set) for [child, parent] in g.query(qstr, initNs=get_prefixes(version)): subclasses[extract_tagset(parent)].add(extract_tagset(child)) for k, v in subclasses.items(): subclasses[k] = list(v) return subclasses pointPostfixes = ['alarm', 'sensor', 'setpoint', 'command', 'status', 'meter'] equipPostfixes = ['system', 'dhws', 'tower', 'chiller', 'coil', 'fan', 'hws', 'storage', 'battery', 'condenser', 'unit', 'fcu', 'vav', 'volume', 'economizer', 'hood', 'filter', 'vfd', 'valve', 'condensor', 'damper', 'hx', 'exchanger', 'thermostat', 'ahu', 'drive', 'heater', 'pump', 'conditioning', 'ws', 'dhws', 'elevator', 'fcp', 'panel', 'weather', 'generator', 'inverter', 'response', 'cws', 'crac', 'equipment', 'hvac'] def construct_subclass_tree(head, tagset_type, subclasses_dict): upper_tagset = head.split(':')[-1].lower() #res = g.query(directSubclassesQuery(head)) try: res = subclasses_dict[upper_tagset] except: pdb.set_trace() subclasses = list() tagsets = list() branches = list() for row in res: thing = row[0] subclass = thing.split('#')[-1] tagset = subclass.lower() if tagset_type == 'point' and tagset.split('_')[-1]\ not in pointPostfixes: continue if tagset_type == 'equip' and tagset.split('_')[-1] \ not in equipPostfixes: continue subclasses.append(subclass) tagsets.append(tagset) branches.append(construct_subclass_tree('brick:'+subclass, tagset_type, subclasses_dict)) tree = {upper_tagset: branches} return tree def get_tagset_tree(version): subclasses = get_direct_subclasses_dict(version) tagsetTree = dict() for head in ['Sensor', 'Alarm', 'Status', 'Setpoint', 'Command', 'Meter']: tagsetTree.update(construct_subclass_tree('brick:'+head, 'point', subclasses)) for head in ['Equipment']: tagsetTree.update(construct_subclass_tree('brick:'+head, 'equip', subclasses)) for head in ['Location']: tagsetTree.update(construct_subclass_tree('brick:'+head, 'location', subclasses))