Brick v1.1

(v1.1.0)


Classes

  • The Brick class namespace is https://brickschema.org/schema/1.1/Brick#
  • Classes belong to owl:Class and are arranged into a hierarchy with rdfs:subClassOf
  • Equivalent classes (the members of the classes are the same) are related with the owl:equivalentClass property
  • Definitions given with skos:definition
  • We are eliminating equipment-flavored classes where it makes sense

    • e.g. brick:AHU_Average_Exhaust_Air_Static_Pressure_Sensor is just a Average_Exhaust_Air_Static_Pressure_Sensor that is a point of an AHU.
  • Classes are equivalent to a set of tags (see below)

The root classes we have defined are:

  • Equipment
  • Location
  • Point
  • Tag
  • Measurable (containing the Substance and Quantity classes)

Relationships

(Relationships are the Brick term for owl ObjectProperties between instances of classes)

At the surface level, relationship work the same as they did in the original Brick. All the same relationships still exist (where I remembered to define them), and they have their inverses defined using owl:inverseOf.

Domains and ranges are defined in terms of classes. Stating that the rdfs:range of a relationship is of class brick:Equipment means that the object of the relationship should be an instance of the brick:Equipment class.

This prototype includes sub-relationships in addition to relationships. Sub-relationships can be used in place of the super-relationship to add more detail to the nature of that relationship. The only example so far is feedsAir being a subproperty of feeds.

Tags

Brick is a "concept-first" ontology, which means that it focuses on modeling the definition and behavior of concepts (equipment, points, locations, and so on) and the relationships between them. This stands in contrast to efforts like Project Haystack, which use combinations of tags (short, atomic words and phrases) to hint at concepts. To facilitate the use of Brick's formal model over existing tag-based models and the use of tag-based "annotations", the Brick v1.1 release includes a mapping between Brick's classes and a set of tags.

Like all entities in Brick, tags are URIs with a consistent prefix (namespace); in the case of tags, the namespace is https://brickschema.org/schema/1.1/BrickTag#, commonly abbreviated as tag:. Examples of tags are tag:Air, tag:Temperature and tag:Sensor. Many of the Brick tags are drawn from Haystack.

The equivalency of a class to a set of tags is accomplished by modeling a Brick class (e.g. Air_Temperature_Sensor) a subclass of an anonymous class which is the intersection of entities that have the required tags. If we instantiate a class directly, an OWL reasoner will infer the correct tags for that entity.

Here is the Brick "class-to-tag" mapping definition for the Temperature_Sensor class:

# in turtle format
brick:Temperature_Sensor a owl:Class ;
    rdfs:subClassOf brick:Sensor ;
    rdfs:subClassOf [ owl:intersectionOf (
                            [ a owl:Restriction ;
                                owl:hasValue tag:Sensor ;
                                owl:onProperty brick:hasTag
                            ]
                            [ a owl:Restriction ;
                                owl:hasValue tag:Temperature ;
                                owl:onProperty brick:hasTag
                            ]
                            [ a owl:Restriction ;
                                owl:hasValue tag:Point ;
                                owl:onProperty brick:hasTag
                            ]
                        ) ] .

The first owl:Restriction is the set of all classes that have tag:Sensor as the value for one of their brick:hasTag properties. Through a reasoning process, all instances of brick:Temperature_Sensor will inherit the tag annotations.

# input Brick model has an instance of brick:Temperature_Sensor
:ts1   a   brick:Temperature_Sensor

# the reasoner infers these tags and adds them to the model
:ts1    brick:hasTag    tag:Temp
:ts1    brick:hasTag    tag:Sensor
:ts1    brick:hasTag    tag:Point

To perform the inference of a class from a set of tags (the inverse of the process above), use the TagInferenceSession from the brickschema package (this cannot currently be performed by an OWL reasoner)

For a sample entity modeled with tags:

# myfile.ttl
@prefix brick: <https://brickschema.org/schema/1.1.0/Brick#> .
@prefix tag: <https://brickschema.org/schema/1.1.0/BrickTag#> .
@prefix bldg: <https://example.org/example#> .

bldg:my_entity  brick:hasTag    tag:Air, tag:Flow, tag:Setpoint, tag:Point .

Load the graph into a brickschema.Graph and run the TagInferenceSession:

import brickschema
g = brickschema.graph.Graph()
g.load_file("myfile.ttl")
g = brickschema.inference.TagInferenceSession(approximate=False).expand(g)

print(g.query("SELECT ?type WHERE { bldg:my_entity a ?type }"))
# => ['Brick:Air_Flow_Setpoint']

Substances

Brick now defines a hierarchy of substances (bricksrc/substances.py) and a hierarchy of quantities (bricksrc/quantities.py). Substances and quantities can be related to equipment and points.

Not all of this is implemented. In the current prototype, sensors are related to substances and quantities through the brick:measures relationship.

:ts1    a       brick:Temperature_Sensor
:ts1    brick:measures      :Air

# this implies the following
:ts1    a       brick:Air_Temperature_Sensor

We can further subclass substances to provide system- or process-level context to their definitions:

:ts1    a       brick:Sensor
:ts1    brick:measures      brick:Return_Air
:ts1    brick:measures      brick:Temperature

# implies...

:ts1    a       brick:Return_Air_Temperature_Sensor

Brick uses OWL restrictions to refine classes based on such relationships. For this example, because :ts1 measures Air (specifically the brick:Air class), OWL infers our sensor as a brick:Air_Temperature_Sensor.

Here's what that the definition looks like in turtle:

brick:Air_Temperature_Sensor a owl:Class ;
    rdfs:subClassOf brick:Temperature_Sensor ;
    owl:equivalentClass [ owl:intersectionOf ( [ a owl:Restriction ;
                        owl:hasValue brick:Temperature ;
                        owl:onProperty brick:measures ] [ a owl:Restriction ;
                        owl:hasValue brick:Air ;
                        owl:onProperty brick:measures ] ) ] .

Note: we are using classes as values here, which is different than the rest of Brick. This is called "punning". This is to avoid having to create instances of substances for our sensors to measure and so on, but reserves the possibility to implement this in the future. Instances of substances can model regions/chunks of "stuff" in a stage of a process, e.g. the water entering a chiller or the mixed air region of an air handling unit.

Release Notes

v1.1.0

See the changelog for more details

Brick v1.1 represents the latest release of Brick since v1.0.3. To update existing Brick models, see the convert tool in the main Brick repository

The class hierarchy in v1.0.3 has been refined to eliminate redundant, misleading or unnecessary classes. The majority of these were classes that incorporated the name of their related equipment in the name of the point, e.g. VFD_Output_Voltage_Sensor. These are redundant with modeling the brick:hasPoint relationship between a VFD equipment instance and an Output_Voltage_Sensor.

The class hierarchy has also been extended to cover Substances and Quantities, which are can be used to model aspects of equipment and point behavior. An expanded set of properties complements the class hierarchy: measures, regulates, hasInputSubstance, hasOutputSubstance and so on. This release also incorporates an improved Python-based framework for editing and generating the Brick ontology so that the Turtle file does not have to be edited directly. Finally, Brick v1.1 incorporates a set of tags --- atomic identifiers --- which can be used to annotate and infer classes.

For technical details on these changes, we refer the reader to a recent publication in BuildSys 2019.

Other changes:

  • definitions have been added to the majority of the Brick classes: please file an issue if you have feedback on any of the definitions or would like to add a new one
  • the ontological reasoning requirements of Brick are consistent with the OWL RL ontology profile
  • some restructuring of the class structure in order to make it more consistent
  • tags have been applied to the majority of classes in the Brick definition: For more information on Brick's tags, see the Tags section of the main README

Backwards incompatible changes:

  • the Brick namespace URI has changed from https://brickschema.org/schema/1.0.3/Brick# to https://brickschema.org/schema/1.1/Brick#. We will use SemVer for the full versions (this release represents 1.1.0), but the patch version will be elided from the Brick namespace URI in order to facilitate migrating to backwards compatible future version of Brick
  • Brick relationships have been moved from the old brickframe namespace to the brick namespace.

Added 378 classes, removed 1597 classes: the vast majority of the removed classes are not truely gone! They have been separated into their constituent "equipment" and "point" parts.

Other Release Notes

  • addition of unit test framework under tests/
  • alignment with the RealEstateCore ontology under alignments/rec/; more alignments coming soon
  • we recommend the brickschema package for working with Brick models from Python
  • tools for comparing and converting between Brick versions have been introduced