Deriving Views over RDF Graphs
2025-02-23
(the model is in the eye of the beholder)
Ontologies are a formal representation of a perspective on a domain. They are specific in what details they care about, and which details they don’t. This means that some ontologies are more appropriate for certain applications than others. Correspondingly, knowledge graphs using such an ontology may be better suited to answer certain questions over others. Some applications may require us to derive a new perspective on a particular knowledge graph. It is convenient to think of this derivation as a “view” or “projection” of the underlying knowledge graph which abstracts away the unnecessary detail for a particular application.
Let’s make this concrete.
Example: 223P and Brick
The ontologies that I work with – Brick and 223P – are both oriented towards modeling building assets, systems, and data during their operation. 223P models the pipes, wires, connections, composition of building assets (equipment, sensors) and their relationship to architectural space. This includes rigorous modeling of substances, flows (with direction!), and quantities within the building. The plan is for a 223P model to be created from the architectural documents as part of the building commissioning process, where this information is known and still up-to-date.
Here is a partial 223P model focusing on a supply air temperature sensor:
@prefix bldg: <urn:ex/> .
@prefix s223: <http://data.ashrae.org/standard223#> .
@prefix qudt: <http://qudt.org/schema/qudt/> .
@prefix qudtqk: <http://qudt.org/vocab/quantitykind/> .
@prefix unit: <http://qudt.org/vocab/unit/> .
bldg:damper a s223:Damper ;
s223:cnx bldg:damper-out .
bldg:sensor a s223:Sensor ;
s223:hasObservationLocation bldg:damper-out ;
s223:hasPhysicalLocation bldg:damper ;
s223:observes bldg:air-temp .
bldg:damper-out a s223:OutletConnectionPoint ;
s223:cnx bldg:out-connection ;
s223:hasMedium s223:Medium-Air ;
s223:hasProperty bldg:air-temp .
bldg:air-temp a s223:QuantifiableObservableProperty,
qudt:hasQuantityKind qudtqk:Temperature ;
s223:hasAspect s223:Role-Supply ;
qudt:hasUnit unit:DEG_C .
bldg:air-temp
is a supply air temperature sensor, which observes the temperature of the air flowing out of a damper (bldg:damper-out
).
However, it is not explicitly labeled as a “supply air temperature sensor” in the model – this is an application-specific interpretation of the model.
Brick captures the I/O “points” in a building and how they relate to the major architectural, mechanical, electrical components. This involves some modeling of upstream/downstream relationships between components. A Brick model (a specific knowledge graph of a building) is a simplification of the corresponding 223P model: A Brick model:
- includes major equipment with significant components, excluding connection points and pipes and other details
- abstracts explicit models of physical sensors and properties into simple I/O points that directly relate to data sources
Following our example, here is a partial Brick model focusing on the same supply air temperature sensor:
@prefix bldg: <urn:ex/> .
@prefix s223: <http://data.ashrae.org/standard223#> .
@prefix qudt: <http://qudt.org/schema/qudt/> .
@prefix qudtqk: <http://qudt.org/vocab/quantitykind/> .
@prefix unit: <http://qudt.org/vocab/unit/> .
@prefix brick: <https://brickschema.org/schema/Brick#> .
bldg:damper a s223:Damper ;
brick:hasPoint bldg:air-temp .
bldg:air-temp a s223:QuantifiableObservableProperty,
brick:Supply_Air_Temperature_Sensor ;
qudt:hasQuantityKind qudtqk:Temperature ;
s223:hasAspect s223:Role-Supply ;
qudt:hasUnit unit:DEG_C .
The relationship between the damper and the sensor (the digital I/O point “sensor”) is now a direct link (brick:hasPoint
) and the sensor has an application-friendly type of “Supply_Air_Temperature_Sensor”.
An illustration of this abstraction is below
I am experimenting with using Claude to generate SVGs instead of me putting them together by hand
.
Modeling Loops
Loops are a common pattern in building systems. Air loops are a common example in HVAC systems: air is conditioned by a unit, distributed to various zones, and then returned to the unit where it can be mixed with fresh air and conditioned again. Several types of water loops are also common in buildings: hot water loops circulate water between a boiler and various heating coils, chilled water loops circulate water between a chiller and various cooling coils, etc.
How should we model these loops in a knowledge graph? We would like to define the loop using some process so that the loop information can be queried and analyzed. We will approach this using the same “view” concept discussed above.
Starting with a 223P model gives us detailed information on all the components that make up a loop:
- equipment (e.g., boilers, chillers, air handlers)
- connections (e.g., pipes, ducts)
- connection points (e.g., inlets, outlets)
- junctions
Substances flow from an equipment outlet to a connection point, though a connection, and into an equipment inlet. An equipment may have multiple inlets and outlets, and a connection point may have multiple connections. Connection points within an equipment may be paired with one another to illustrate how substances flow through the equipment (this can be helpful for modeling the two sides of a heat exchanger, for example).
It seems like we have enough detail here to model loops, but how do we actually define the loop? The nature of this definition depends on the application, but it also impacts the method we can use to define the loop. Here are a few possible definitions of “loops” for different use cases:
- this paper from Villez, Vanrolleghem and Corominas provides a method for computing Pareto-optimal placement of sensors for applications like mass balance. The method works on an directed graph where the nodes are unit processes and the edges are connections (e.g., pipes) between them. The method also introduces a global “Environment” node which captures the flow of substances into and out of the system.
- gbXML’s AirLoop only contains the list of equipment in the loop (e.g. AHU and VAV for an air loop, or VAV and Boiler for a hydronic heating loop). The upstream/downstream relationships between equipment are not explicitly modeled as they are not required for the gbXML use case. This is similar to the
brick:Air_Loop
class in Brick. - Stepping back, we must also decide what specific components go into the loop definition. Is it just the equipment? Or do we include affected architectural spaces? The pipes and ducts and connections between these components? Any sensors or actuators along the way? What about the connection points on equipment?
Here’s a specific example of a simple HVAC system in 223P:
Expand for Turtle definition of the 223P model
@prefix s223: <http://data.ashrae.org/standard223#> .
@prefix qudt: <http://qudt.org/schema/qudt/> .
@prefix qudtqk: <http://qudt.org/vocab/quantitykind/> .
@prefix unit: <http://qudt.org/vocab/unit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix ex: <http://example.com/hvac/> .
<http://example.com/hvac> a owl:Ontology ;
owl:imports <http://data.ashrae.org/standard223/1.0/model/all> .
# Air Handling Unit (AHU) and its connections
ex:AHU a s223:AirHandlingUnit ;
s223:hasConnectionPoint ex:AHU_Inlet1, ex:AHU_Inlet2;
s223:hasConnectionPoint ex:AHU_Outlet .
ex:AHU_Inlet1 a s223:InletConnectionPoint ;
s223:cnx ex:Return_Duct1 ;
s223:isConnectionPointOf ex:AHU ;
s223:hasMedium s223:Fluid-Air .
ex:AHU_Inlet2 a s223:InletConnectionPoint ;
s223:cnx ex:Return_Duct2 ;
s223:isConnectionPointOf ex:AHU ;
s223:hasMedium s223:Fluid-Air .
ex:AHU_Outlet a s223:OutletConnectionPoint ;
s223:cnx ex:Supply_Duct ;
s223:isConnectionPointOf ex:AHU ;
s223:hasMedium s223:Fluid-Air .
# Supply Main Duct connections
ex:Supply_Duct a s223:Duct ;
s223:hasMedium s223:Fluid-Air ;
s223:cnx ex:AHU_Outlet, ex:VAV1_Inlet, ex:VAV2_Inlet .
# return ducts
ex:Return_Duct1 a s223:Duct ;
s223:hasMedium s223:Fluid-Air ;
s223:cnx ex:Room1_Outlet, ex:AHU_Inlet1 .
# VAV 1 and its internal components
ex:VAV1 a s223:SingleDuctTerminal ;
s223:contains ex:VAV1_Damper, ex:Heating_Coil1 ;
s223:hasConnectionPoint ex:VAV1_Inlet, ex:VAV1_Outlet .
ex:VAV1_Inlet a s223:InletConnectionPoint ;
s223:isConnectionPointOf ex:VAV1 ;
s223:cnx ex:Supply_Duct ;
s223:hasMedium s223:Fluid-Air .
ex:VAV1_Outlet a s223:OutletConnectionPoint ;
s223:isConnectionPointOf ex:VAV1 ;
s223:cnx ex:Supply_Duct ;
s223:hasMedium s223:Fluid-Air .
ex:VAV1_Damper a s223:Damper ;
s223:hasConnectionPoint ex:VAV1_Damper_In, ex:VAV1_Damper_Out .
ex:VAV1_Damper_In a s223:InletConnectionPoint ;
s223:mapsTo ex:VAV1_Inlet ;
s223:hasMedium s223:Fluid-Air .
ex:VAV1_Damper_Out a s223:OutletConnectionPoint ;
s223:isConnectionPointOf ex:VAV1_Damper ;
s223:hasMedium s223:Fluid-Air .
ex:VAV1_Damper_Coil_Duct a s223:Duct ;
s223:hasMedium s223:Fluid-Air ;
s223:cnx ex:VAV1_Damper_Out, ex:Heating_Coil1_In .
ex:Heating_Coil1 a s223:HeatingCoil ;
s223:hasConnectionPoint ex:Heating_Coil1_In, ex:Heating_Coil1_Out .
ex:Heating_Coil1_In a s223:InletConnectionPoint ;
s223:isConnectionPointOf ex:Heating_Coil1 ;
s223:hasMedium s223:Fluid-Air .
ex:Heating_Coil1_Out a s223:OutletConnectionPoint ;
s223:mapsTo ex:VAV1_Outlet ;
s223:hasMedium s223:Fluid-Air .
# Room 1 and its connection
ex:Room1 a s223:PhysicalSpace ;
s223:encloses ex:Room1HVAC .
ex:Room1HVAC a s223:DomainSpace ;
s223:hasDomain s223:Domain-HVAC ;
s223:hasConnectionPoint ex:Room1_Inlet, ex:Room1_Outlet .
ex:Room1_Inlet a s223:InletConnectionPoint ;
s223:isConnectionPointOf ex:Room1HVAC ;
s223:cnx ex:Supply_Duct_Room1 ;
s223:hasMedium s223:Fluid-Air .
ex:Room1_Outlet a s223:OutletConnectionPoint ;
s223:isConnectionPointOf ex:Room1HVAC ;
s223:cnx ex:Return_Duct1 ;
s223:hasMedium s223:Fluid-Air .
# Supply Duct to Room 1
ex:Supply_Duct_Room1 a s223:Duct ;
s223:hasMedium s223:Fluid-Air ;
s223:cnx ex:VAV1_Outlet, ex:Room1_Inlet .
####### VAV 2
# return ducts
ex:Return_Duct2 a s223:Duct ;
s223:hasMedium s223:Fluid-Air ;
s223:cnx ex:Room2_Outlet, ex:AHU_Inlet2 .
# VAV 2 and its internal components
ex:VAV2 a s223:SingleDuctTerminal ;
s223:contains ex:VAV2_Damper, ex:Heating_Coil2 ;
s223:hasConnectionPoint ex:VAV2_Inlet, ex:VAV2_Outlet .
ex:VAV2_Inlet a s223:InletConnectionPoint ;
s223:isConnectionPointOf ex:VAV2 ;
s223:cnx ex:Supply_Duct ;
s223:hasMedium s223:Fluid-Air .
ex:VAV2_Outlet a s223:OutletConnectionPoint ;
s223:isConnectionPointOf ex:VAV2 ;
s223:cnx ex:Supply_Duct ;
s223:hasMedium s223:Fluid-Air .
ex:VAV2_Damper a s223:Damper ;
s223:hasConnectionPoint ex:VAV2_Damper_In, ex:VAV2_Damper_Out .
ex:VAV2_Damper_In a s223:InletConnectionPoint ;
s223:mapsTo ex:VAV2_Inlet ;
s223:hasMedium s223:Fluid-Air .
ex:VAV2_Damper_Out a s223:OutletConnectionPoint ;
s223:isConnectionPointOf ex:VAV2_Damper ;
s223:hasMedium s223:Fluid-Air .
ex:VAV2_Damper_Coil_Duct a s223:Duct ;
s223:hasMedium s223:Fluid-Air ;
s223:cnx ex:VAV2_Damper_Out, ex:Heating_Coil2_In .
ex:Heating_Coil2 a s223:HeatingCoil ;
s223:hasConnectionPoint ex:Heating_Coil2_In, ex:Heating_Coil2_Out .
ex:Heating_Coil2_In a s223:InletConnectionPoint ;
s223:isConnectionPointOf ex:Heating_Coil2 ;
s223:hasMedium s223:Fluid-Air .
ex:Heating_Coil2_Out a s223:OutletConnectionPoint ;
s223:mapsTo ex:VAV2_Outlet ;
s223:hasMedium s223:Fluid-Air .
# Room 2 and its connection
ex:Room2 a s223:PhysicalSpace ;
s223:encloses ex:Room2HVAC .
ex:Room2HVAC a s223:DomainSpace ;
s223:hasDomain s223:Domain-HVAC ;
s223:hasConnectionPoint ex:Room2_Inlet, ex:Room2_Outlet .
ex:Room2_Inlet a s223:InletConnectionPoint ;
s223:isConnectionPointOf ex:Room2HVAC ;
s223:cnx ex:Supply_Duct_Room2 ;
s223:hasMedium s223:Fluid-Air .
ex:Room2_Outlet a s223:OutletConnectionPoint ;
s223:isConnectionPointOf ex:Room2HVAC ;
s223:cnx ex:Return_Duct2 ;
s223:hasMedium s223:Fluid-Air .
# Supply Duct to Room 2
ex:Supply_Duct_Room2 a s223:Duct ;
s223:hasMedium s223:Fluid-Air ;
s223:cnx ex:VAV2_Outlet, ex:Room2_Inlet .
I’ve been sitting on this draft for over a week. If I don’t publish this now, I’ll never finish it. I will continue these thoughts in part 2.