Skip to main content

The problem with explicit types

Without class hierarchy, querying building data means knowing every specific type you’re looking for:
# Without hierarchy: you must list every type
equipment(type: ["AHU", "VAV", "FCU", "Heat_Exchanger",
                  "Heat_Pump", "Cooling_Tower", "Pump"]) {
  ...
}
Miss a type? You miss data. Add a new equipment type next year? Every query breaks. This doesn’t scale.

How is works

The is argument queries by Brick class and automatically includes all subtypes:
# With hierarchy: one class, all subtypes
equipment(is: "HVAC_Equipment") {
  name
  type
}
This returns AHUs, VAVs, FCUs, heat exchangers, and every equipment type that is a subclass of HVAC_Equipment in the Brick hierarchy. Add a new type next year? It automatically matches.

The class hierarchy

Brick organizes building concepts into a tree. Every class inherits from its parent, and querying a parent matches all descendants.
Point
└── Sensor
    └── Temperature_Sensor
        ├── Supply_Air_Temperature_Sensor
        ├── Return_Air_Temperature_Sensor
        ├── Zone_Air_Temperature_Sensor
        ├── Chilled_Water_Temperature_Sensor
        └── Outside_Air_Temperature_Sensor
When you query for Temperature_Sensor, you get all five subtypes. When you query for Sensor, you get temperature sensors plus humidity sensors, pressure sensors, CO2 sensors, and everything else. The hierarchy does the filtering for you.

Common hierarchies

Equipment

Equipment
├── HVAC_Equipment
│   ├── AHU
│   ├── VAV
│   ├── FCU
│   ├── Chiller
│   ├── Boiler
│   ├── Heat_Exchanger
│   ├── Heat_Pump
│   ├── Cooling_Tower
│   ├── Pump
│   │   ├── Chilled_Water_Pump
│   │   ├── Hot_Water_Pump
│   │   └── Condenser_Water_Pump
│   └── Fan
│       ├── Supply_Fan
│       ├── Return_Fan
│       └── Exhaust_Fan
├── Lighting_Equipment
└── Electrical_Equipment

Points (sensors)

Sensor
├── Temperature_Sensor
│   ├── Supply_Air_Temperature_Sensor
│   ├── Return_Air_Temperature_Sensor
│   ├── Zone_Air_Temperature_Sensor
│   ├── Outside_Air_Temperature_Sensor
│   ├── Chilled_Water_Temperature_Sensor
│   └── Hot_Water_Temperature_Sensor
├── Humidity_Sensor
│   ├── Relative_Humidity_Sensor
│   └── Zone_Humidity_Sensor
├── Pressure_Sensor
│   ├── Static_Pressure_Sensor
│   └── Differential_Pressure_Sensor
├── Flow_Sensor
│   ├── Air_Flow_Sensor
│   └── Water_Flow_Sensor
└── CO2_Sensor

Points (setpoints and commands)

Setpoint
├── Temperature_Setpoint
│   ├── Zone_Air_Temperature_Setpoint
│   ├── Supply_Air_Temperature_Setpoint
│   └── Chilled_Water_Temperature_Setpoint
├── Pressure_Setpoint
└── Flow_Setpoint

Command
├── Damper_Command
├── Valve_Command
├── Fan_Command
└── On_Off_Command

Narrow vs broad queries

is argumentWhat matches
PointEvery sensor, setpoint, command, and status
SensorAll sensors (temperature, humidity, pressure, etc.)
Temperature_SensorAll temperature sensors (supply, return, zone, etc.)
Supply_Air_Temperature_SensorOnly supply air temperature sensors
The broader the class, the more results. Start broad to explore, narrow when you know what you need.

Query examples

All sensors on an AHU

{
  equipment(siteId: "your-site-id", id: "TE01-XX-AHU-001") {
    points(is: "Sensor") {
      name
      type
      currentValue { value timestamp }
    }
  }
}
Returns temperature sensors, humidity sensors, pressure sensors, flow sensors, and every other sensor type attached to this AHU.

All setpoints in a building

{
  equipment(siteId: "your-site-id", is: "HVAC_Equipment") {
    name
    points(is: "Setpoint") {
      type
      currentValue { value timestamp }
    }
  }
}

Combining is with other arguments

is composes with every other filter argument:
# is + id (specific equipment, type-checked)
equipment(id: "TE01-XX-AHU-001", is: "AHU") { ... }

# is + name
points(is: "Temperature_Sensor", name: "Supply") { ... }

# Nested is arguments
equipment(is: "HVAC_Equipment") {
  points(is: "Sensor") { ... }
}

How it works under the hood

When you pass is: "HVAC_Equipment", Tacit resolves the Brick class hierarchy to find all subclasses:
  1. Look up HVAC_Equipment in the Brick ontology
  2. Find all classes where X rdfs:subClassOf* HVAC_Equipment
  3. Match any entity whose class is in that set
This is the same resolution that SPARQL’s a/rdfs:subClassOf* performs, but expressed as a single argument in a GraphQL query.

Equivalent SPARQL

The is argument replaces this SPARQL pattern:
?entity a/rdfs:subClassOf* brick:HVAC_Equipment .
Same resolution, expressed as a single argument instead of a property path.

Next steps

Relationships & traversal

Follow equipment chains with upstream and downstream queries.

GraphQL query reference

Full reference for all query arguments and return fields.