BrickSchema / Brick

Uniform metadata schema for buildings
http://brickschema.org/
BSD 3-Clause "New" or "Revised" License
289 stars 78 forks source link

Redefining Setpoint Classifications: Target and Threshold #608

Closed connorjcantrell closed 2 months ago

connorjcantrell commented 9 months ago

How do we define setpoint? I personally like Wikipedia's definition:

The desired or target value for an essential variable, or process value (PV) of a control system which may differ from the actual measured value of the variable.

Let's call this a "Target Based Setpoint"

Target-Based

These are values that is the desired target for a process variable (PV). Examples include:


However, there are many terms used to describe different types of setpoints, such as:

These setpoints are an attempt to describe something else.. and it doesn't fit into the definition mentioned above. So how do we distinguish these types of setpoints? I would like to propose a term, "Threshold Setpoint".

Threshold-Based

These values initiates a specific action when a process variable crosses a certain threshold. They can be further categorized into upper and lower thresholds:

Upper Thresholds

Initiates a specific action when the process variable exceeds specified value.


Example

237245173-4f704b44-a4a1-4de6-8125-2941bbf88b4e

Let's compare "Effective Cooling/Heating Setpoint" to "Effective Target Setpoint" as an example:

Key Takeaway

Clearer setpoint classification is essential for understanding the nature of a setpoint. The distinction between target-based and threshold-based setpoints enhances our ability to represent all types of setpoints observed in building systems.

Action items

We could introduce some variation of the following:

brick:Target_Setpoint rdfs:subClassOf brick:Setpoint.
brick:Threshold_Setpoint rdfs:subClassOf brick:Setpoint.
brick:Upper_Threshold_Setpoint rdfs:subClassOf brick:Threshold_Setpoint.
brick:Lower_Threshold_Setpoint rdfs:subClassOf brick:Threshold_Setpoint.

Next, we can categorize all existing setpoint classes under the following superclasses.

Note: I don't have a strong opinion on "Threshold Setpoint" and I am open to other suggestions.

Discussion

JoelBender commented 9 months ago

I like the additional refinement, even though I prefer a shallow hierarchy rather than a deeper one, and the new names are better.

I think of deadband as an additional parameter to a threshold calculation, so in the case where a deadband is manipulated to allow for "tight" or "loose" control there might be some additional range that the deadband is expected to vary between, but is there going to be an alarm when the deadband exceeds some value?

I thought Time Setpoints where things like minimum/maximum on/off time, but looking at the version 1.3 hierarchy they are something different.

connorjcantrell commented 5 months ago

Hi @gtfierro,

I'd like to move forward with this PR, but want to get your feedback first. Here are a few options we could consider:

1. Add additional parents to each Setpoint

In this approach, we would avoid restructuring existing class hierarchies and add one of the following classes as a parent:

setpoints = {
    "Setpoint": {
        "subclasses": {
            "Target_Setpoint": {},
            "Threshold_Setpoint": {
                "subclasses": {
                    "Upper_Threshold_Setpoint": {},   
                    "Lower_Threshold_Setpoint": {},
                }
            },
            "Pressure_Setpoint": {
                BRICK.hasQuantity: BRICK.Pressure,
                "parents": [
                    BRICK.Target_Setpoint,
                ],
                "subclasses": {}
            },
            "Cooling_Temperature_Setpoint": {
                BRICK.hasQuantity: BRICK.Temperature,
                "tags": [TAG.Point, TAG.Temperature, TAG.Setpoint, TAG.Cool],
                "parents": [
                    BRICK.Upper_Threshold_Setpoint,
                ],
                "subclasses": {}
            },
            "Heating_Temperature_Setpoint": {
                BRICK.hasQuantity: BRICK.Temperature,
                "tags": [TAG.Point, TAG.Temperature, TAG.Setpoint, TAG.Heat],
                "parents": [
                    BRICK.Lower_Threshold_Setpoint,
                ],
                "subclasses": {},
            },
            # etc.
        }
    }
}

2. Add a new tag to each Setpoint

setpoints = {
        "subclasses": {
            "Pressure_Setpoint": {
                BRICK.hasQuantity: BRICK.Pressure,
                 "tags": [TAG.Target, TAG.Pressure, TAG.Setpoint],
                "subclasses": {}
            },
            "Cooling_Temperature_Setpoint": {
                BRICK.hasQuantity: BRICK.Temperature,
                "tags": [TAG.Upper_Threshold, TAG.Point, TAG.Temperature, TAG.Setpoint, TAG.Cool],
                "subclasses": {}
            },
            "Heating_Temperature_Setpoint": {
                BRICK.hasQuantity: BRICK.Temperature,
                "tags": [TAG.Lower_Threshold, TAG.Point, TAG.Temperature, TAG.Setpoint, TAG.Heat],
                "subclasses": {},
            },
            # etc.
        }
    }
}

3. Restructure class hierarchy (Preferred)

Existing class hierarchies are altered, but nearly all class names remain. (See notes below)

Though this approach requires the most changes, it addresses the issue of incorrect semantics by clearly defining each class within its respective Setpoint type. This eliminates ambiguity and ensures that each class accurately represents its intended function.

.
├── target_setpoint
│   ├── pressure_setpoint
│   ├── humidity_setpoint
│   ├── temperature_setpoint
│   └── ...
└── threshold_setpoint
    ├── lower_threshold_setpoint
    │   ├── heating_setpoint
    │   ├── humidification_setpoint
    │   └── ...
    └── upper_threshold_setpoint
        ├── co2_setpoint
        ├── cooling_setpoint
        ├── dehumidification_setpoint
        └── ...

Some superclasses such as Temperature_Setpoint currently contain both Target and Threshold Setpoints. I propose repurposing Temperature Setpoint to be exclusively for "(Target) Temperature Setpoints". Alternatively, we could deprecate Temperature_Setpoint and replace it with Target_Temperature_Setpoint.

cc @jbkoh

gtfierro commented 5 months ago

Options 1 and 3 feel like duals. They both organize the setpoints along 2 dimensions: by quantity (e.g., Temperature) and by the setpoint type (e.g., Threshold). The difference between them is whether we organize the Python files by quantity or by setpoint type. Do I understand this right?

connorjcantrell commented 5 months ago

Option 1 adds new parent classes while keeping the existing hierarchy. This means some classes will still have mixed setpoint types as subclasses (e.g., Zone Air Temperature Setpoint has both target and threshold subclasses). For example, Zone Air Temperature Setpoint currently has the following subclasses:

Option 3 completely reorganizes the hierarchy, grouping classes by setpoint type first (target, lower threshold, upper threshold), then by quantity (temperature, pressure, etc.). This ensures all superclasses share the same setpoint type. Continuing with the previous example, it would look something like this:

.
├── lower_threshold_setpoint
│   └── lower_threshold_temperature_setpoint
│       └── heating_temperature_setpoint
│           └── air_heating_temperature_setpoint
│               └── zone_air_heating_temperature_setpoint
├── target_setpoint
│   └── target_temperature_setpoint
│       └── target_air_temperature_setpoint
│           └── target_zone_air_temperature_setpoint
│               ├── effective_zone_air_temperature_setpoint
│               ├── occupied_zone_air_temperature_setpoint
│               └── unoccupied_zone_air_temperature_setpoint
└── upper_threshold_setpoint
    └── upper_threshold_temperature_setpoint
        └── cooling_temperature_setpoint
            └── air_cooling_temperature_setpoint
                └── zone_air_cooling_temperature_setpoint

The primary focus with Option 3 is to prioritize setpoint type (target, upper threshold, lower threshold) over the when (i.e. Occupied, Unoccupied), substance (i.e. Air, Water), and measurement (i.e. Temperature, Pressure).

connorjcantrell commented 2 months ago

This issue has served its purpose in guiding the implementation of the setpoint-restructure PR