Shapes and Templates#

Shapes and Templates interact in interesting ways in BuildingMOTIF. In this document, we explain the utility and function of these interactions.

Recall that a Shape (SHACL shape) is a set of conditions and constraints over RDF graphs, and a Template is a function that generates an RDF graph.

Converting Shapes to Templates#

When Loading a Library#

BuildingMOTIF can automatically convert shapes to templates when loading a Library. Evaluating the resulting template will generate a graph that validates against the shape.

When BuildingMOTIF loads a Library, it makes an attempt to find any shapes defined within it. The way this happens depends on how the library is loaded:

  • Loading library from directory or git repository: BuildingMOTIF searches for any RDF files in the directory (recursively) and loads them into a Shape Collection; loads any instances of sh:NodeShape in the union of these RDF files

  • Loading library from ontology file: loads all instances of sh:NodeShape in the provided graphc

Important

BuildingMOTIF only loads shapes which are instances of both sh:NodeShape and owl:Class. The assumption is that owl:Class-ified shapes could be “instantiated”.

Each shape is “decompiled” into components from which a Template can be constructed. The implementation of this decompilation is in the get_template_parts_from_shape method. BuildingMOTIF currently recognizes the following SHACL properties:

  • sh:property

  • sh:qualifiedValueShape

  • sh:node

  • sh:class

  • sh:targetClass

  • sh:datatype

  • sh:minCount / sh:qualifiedMinCount

  • sh:maxCount / sh:qualifiedMaxCount

BuildingMOTIF currently uses the name of the SHACL shape as the name of the generated Template. All other parameters (i.e., nodes corresponding to sh:property) are given invented names unless there is a sh:name attribute on the property shape.

This feature can be disabled by setting infer_templates=False when calling Library.load

From Shape Collections#

It is also possible to convert the shapes defined in a Shape Collection to templates. This is done by calling the infer_templates method on the Shape Collection. If infer_templates is True when calling Library.load, then BuildingMOTIF will automatically call infer_templates on the Shape Collection within that Library.

Being able to call infer_templates on a Shape Collection is useful when you have a graph of shapes that you programmatically created or loaded without packaging them in a Library.

from buildingmotif import BuildingMOTIF
from buildingmotif.dataclasses import Library, ShapeCollection

# in-memory instance
bm = BuildingMOTIF("sqlite://")

my_shapes_source = """
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix brick: <https://brickschema.org/schema/Brick#> .
@prefix ex: <http://example.org/> .

ex:SimpleShape a sh:NodeShape, owl:Class ;
    sh:property [
        sh:path ex:hasPoint ;
        sh:qualifiedValueShape [ sh:class brick:Sensor ] ;
        sh:qualifiedMinCount 1 ;
    ] .
"""

# create a ShapeCollection to hold the shapes
my_shapes = ShapeCollection.create()
my_shapes.graph.parse(data=my_shapes_source, format="ttl")

# create a Library to hold the generated templates
lib = Library.create("my-library")
my_shapes.infer_templates(lib)

print(lib.get_templates())
[Template(_id=1, _name='http://example.org/SimpleShape', body=<Graph identifier=75b6f229-5aa1-44b9-b48a-0e2959ce0f01 (<class 'rdflib.graph.Graph'>)>, optional_args=[], _bm=<buildingmotif.building_motif.building_motif.BuildingMOTIF object at 0x7fbeb02964d0>)]

Example#

Consider the following shape which has been loaded into BuildingMOTIF as part of a Library:

# myshapes.ttl
@prefix brick: <https://brickschema.org/schema/Brick#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix : <urn:example/> .

: a owl:Ontology .

:vav a sh:NodeShape, owl:Class ;
    sh:targetClass brick:Terminal_Unit ;
    sh:property [
        sh:path brick:hasPart ;
        sh:qualifiedValueShape [ sh:node :heating-coil ] ;
        sh:name "hc" ;
        sh:qualifiedMinCount 1 ;
    ] ;
    sh:property [
        sh:path brick:hasPoint ;
        sh:qualifiedValueShape [ sh:class brick:Supply_Air_Flow_Sensor ] ;
        sh:qualifiedMinCount 1 ;
    ] ;
    sh:property [
        sh:path brick:hasPoint ;
        sh:qualifiedValueShape [ sh:class brick:Supply_Air_Temperature_Sensor ] ;
        sh:name "sat" ;
        sh:qualifiedMinCount 1 ;
    ] ;
.

:heating-coil a sh:NodeShape, owl:Class ;
    sh:targetClass brick:Heating_Coil ;
    sh:property [
        sh:path brick:hasPoint ;
        sh:qualifiedValueShape [ sh:class brick:Position_Command ] ;
        sh:name "damper_pos" ; # will be used as the parameter name
        sh:qualifiedMinCount 1 ;
    ] ;
.

This code creates myshapes.ttl for you in the current directory.

with open("myshapes.ttl", "w") as f:
    f.write("""
@prefix brick: <https://brickschema.org/schema/Brick#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix : <urn:example/> .

: a owl:Ontology .

:vav a sh:NodeShape, owl:Class ;
    sh:targetClass brick:Terminal_Unit ;
    sh:property [
        sh:path brick:hasPart ;
        sh:qualifiedValueShape [ sh:node :heating-coil ] ;
        sh:name "hc" ;
        sh:qualifiedMinCount 1 ;
    ] ;
    sh:property [
        sh:path brick:hasPoint ;
        sh:qualifiedValueShape [ sh:class brick:Supply_Air_Flow_Sensor ] ;
        sh:qualifiedMinCount 1 ;
    ] ;
    sh:property [
        sh:path brick:hasPoint ;
        sh:qualifiedValueShape [ sh:class brick:Supply_Air_Temperature_Sensor ] ;
        sh:name "sat" ;
        sh:qualifiedMinCount 1 ;
    ] ;
.

:heating-coil a sh:NodeShape, owl:Class ;
    sh:targetClass brick:Heating_Coil ;
    sh:property [
        sh:path brick:hasPoint ;
        sh:qualifiedValueShape [ sh:class brick:Position_Command ] ;
        sh:name "damper_pos" ; # will be used as the parameter name
        sh:qualifiedMinCount 1 ;
    ] ;
.
""")

If this was in a file myshapes.ttl, we would load it into BuildingMOTIF as follows:

from buildingmotif import BuildingMOTIF
from buildingmotif.dataclasses import Library

# in-memory instance
bm = BuildingMOTIF("sqlite://")

# load library
brick = Library.load(ontology_graph="https://github.com/BrickSchema/Brick/releases/download/nightly/Brick.ttl")
lib = Library.load(ontology_graph="myshapes.ttl")
/opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages/pyshacl/extras/__init__.py:46: Warning: Extra "js" is not satisfied because requirement pyduktape2 is not installed.
  warn(Warning(f"Extra \"{extra_name}\" is not satisfied because requirement {req} is not installed."))
2025-02-26 15:06:02,143 | root |  WARNING: An ontology could not resolve a dependency on http://qudt.org/2.1/collection/usertest (Name: http://qudt.org/2.1/collection/usertest). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,144 | root |  WARNING: An ontology could not resolve a dependency on http://qudt.org/2.1/schema/shacl/qudt (Name: http://qudt.org/2.1/schema/shacl/qudt). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,145 | root |  WARNING: An ontology could not resolve a dependency on http://qudt.org/2.1/vocab/prefix (Name: http://qudt.org/2.1/vocab/prefix). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,146 | root |  WARNING: An ontology could not resolve a dependency on http://qudt.org/2.1/schema/shacl/overlay/qudt (Name: http://qudt.org/2.1/schema/shacl/overlay/qudt). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,147 | root |  WARNING: An ontology could not resolve a dependency on http://qudt.org/2.1/vocab/dimensionvector (Name: http://qudt.org/2.1/vocab/dimensionvector). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,148 | root |  WARNING: An ontology could not resolve a dependency on http://qudt.org/2.1/vocab/quantitykind (Name: http://qudt.org/2.1/vocab/quantitykind). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,148 | root |  WARNING: An ontology could not resolve a dependency on http://data.ashrae.org/bacnet/2020 (Name: http://data.ashrae.org/bacnet/2020). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,149 | root |  WARNING: An ontology could not resolve a dependency on http://qudt.org/2.1/vocab/unit (Name: http://qudt.org/2.1/vocab/unit). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,150 | root |  WARNING: An ontology could not resolve a dependency on http://qudt.org/2.1/vocab/sou (Name: http://qudt.org/2.1/vocab/sou). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,151 | root |  WARNING: An ontology could not resolve a dependency on https://w3id.org/rec/recimports (Name: https://w3id.org/rec/recimports). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,152 | root |  WARNING: An ontology could not resolve a dependency on http://qudt.org/2.1/schema/facade/qudt (Name: http://qudt.org/2.1/schema/facade/qudt). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:02,152 | root |  WARNING: An ontology could not resolve a dependency on https://brickschema.org/schema/Brick/ref (Name: https://brickschema.org/schema/Brick/ref). Check this is loaded into BuildingMOTIF
2025-02-26 15:06:05,172 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7634 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,192 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7636 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,211 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7638 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,229 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7640 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,247 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7642 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,265 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7632 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,285 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7714 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,303 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7710 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,322 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7718 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,340 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7712 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,358 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7716 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,378 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7600 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,396 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7602 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,414 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7592 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,433 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7598 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,452 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7594 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,472 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7596 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,490 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7657 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,508 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7649 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,526 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7653 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,545 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7655 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]
2025-02-26 15:06:05,563 | root |  WARNING: Warning: could not find dependee n5dd3915443df42daaff3ae10e410f900b7651 in libraries [rdflib.term.URIRef('http://qudt.org/2.1/collection/usertest'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/prefix'), rdflib.term.URIRef('http://qudt.org/2.1/schema/shacl/overlay/qudt'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/dimensionvector'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/quantitykind'), rdflib.term.URIRef('http://data.ashrae.org/bacnet/2020'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/unit'), rdflib.term.URIRef('http://qudt.org/2.1/vocab/sou'), rdflib.term.URIRef('https://w3id.org/rec/recimports'), rdflib.term.URIRef('http://qudt.org/2.1/schema/facade/qudt'), rdflib.term.URIRef('https://brickschema.org/schema/Brick/ref')]

Once the library has been loaded, all of the shapes have been turned into templates. We can load the template by name (using its full URI from the shape) as if it were defined explicitly:

# reading the template out by name
template = lib.get_template_by_name("urn:example/vav")

# dump the body of the template
print(template.body.serialize())
@prefix brick: <https://brickschema.org/schema/Brick#> .

<urn:___param___#name> a brick:Terminal_Unit,
        <urn:example/vav> ;
    brick:hasPart <urn:___param___#hc0> ;
    brick:hasPoint <urn:___param___#p14>,
        <urn:___param___#sat0> .

<urn:___param___#hc0> a <urn:example/heating-coil> .

As with other templates, we often want to inline all dependencies to get a sense of what metadata will be added to the graph.

# reading the template out by name
template = lib.get_template_by_name("urn:example/vav").inline_dependencies()

# dump the body of the template
print(template.body.serialize())
@prefix brick: <https://brickschema.org/schema/Brick#> .

<urn:___param___#name> a brick:Terminal_Unit,
        <urn:example/vav> ;
    brick:hasPart <urn:___param___#hc0> ;
    brick:hasPoint <urn:___param___#p14>,
        <urn:___param___#sat0> .

<urn:___param___#hc0> a brick:Heating_Coil,
        <urn:example/heating-coil> ;
    brick:hasPoint <urn:___param___#hc0-damper_pos0> .

Observe that the generated template uses the sh:name property of each property shape to inform the paramter name. If this is not provided (e.g. for the brick:Supply_Air_Flow_Sensor property shape), then a generated parameter will be used.