diff --git a/bricksrc/definitions.csv b/bricksrc/definitions.csv index 3758c48a..f3143f01 100644 --- a/bricksrc/definitions.csv +++ b/bricksrc/definitions.csv @@ -87,6 +87,7 @@ https://brickschema.org/schema/Brick#Building_Chilled_Water_Meter,A meter that m https://brickschema.org/schema/Brick#Building_Disconnect_Switch,, https://brickschema.org/schema/Brick#Building_Electrical_Meter,A meter that measures the usage or consumption of electricity of a whole building, https://brickschema.org/schema/Brick#Building_Gas_Meter,A meter that measures the usage or consumption of gas of a whole building, +https://brickschema.org/schema/Brick#Building_Hot_Water,Heating hot water on the building or load side of an interface such as a heat exchanger, https://brickschema.org/schema/Brick#Building_Hot_Water_Meter,A meter that measures the usage or consumption of hot water of a whole building, https://brickschema.org/schema/Brick#Building_Meter,A meter that measures usage or consumption of some media for a whole building, https://brickschema.org/schema/Brick#Building_Water_Meter,A meter that measures the usage or consumption of water of a whole building, @@ -281,6 +282,7 @@ https://brickschema.org/schema/Brick#Discharge_Air,the air exiting the registers https://brickschema.org/schema/Brick#Discharge_Chilled_Water,, https://brickschema.org/schema/Brick#Disconnect_Switch,A switch that isolates a circuit or equipment by physically breaking the electrical connection., https://brickschema.org/schema/Brick#Displacement_Flow_Air_Diffuser,An air diffuser that is designed for low discharge air speeds to minimize turbulence and induction of room air. This diffuser is used with displacement ventilation systems., +https://brickschema.org/schema/Brick#District_Hot_Water,Heating hot water on the district or utility side of an interface such as a heat exchanger, https://brickschema.org/schema/Brick#Domestic_Hot_Water,, https://brickschema.org/schema/Brick#Domestic_Hot_Water_Circulator_Pump,"Used to move domestic hot water in a closed circuit, ensuring continuous flow.", https://brickschema.org/schema/Brick#Domestic_Hot_Water_Differential_Pressure_Sensor,Measures the pressure difference in domestic hot water systems., @@ -354,6 +356,9 @@ https://brickschema.org/schema/Brick#Energy_Storage,Devices or equipment that st https://brickschema.org/schema/Brick#Energy_Storage_System,A collection of devices that stores electricity, https://brickschema.org/schema/Brick#Energy_System,"A collection of devices that generates, stores or transports electricity", https://brickschema.org/schema/Brick#Energy_Usage_Sensor,Measures the total amount of energy used over some period of time, +https://brickschema.org/schema/Brick#Entering_Building_Hot_Water,Building hot water entering a piece of equipment or interface, +https://brickschema.org/schema/Brick#Entering_Building_Hot_Water_Temperature_Sensor,Measures the temperature of building hot water entering a piece of equipment or interface, +https://brickschema.org/schema/Brick#Entering_Building_Hot_Water_Temperature_Setpoint,Sets the temperature of building hot water entering a piece of equipment or interface, https://brickschema.org/schema/Brick#Entering_Chilled_Water,Chilled water that is entering a piece of equipment or system, https://brickschema.org/schema/Brick#Entering_Chilled_Water_Flow_Sensor,Measures the rate of flow of chilled entering water, https://brickschema.org/schema/Brick#Entering_Chilled_Water_Flow_Setpoint,Sets the target flow rate of chilled entering water, @@ -363,9 +368,15 @@ https://brickschema.org/schema/Brick#Entering_Condenser_Water,"In a condenser wa https://brickschema.org/schema/Brick#Entering_Condenser_Water_Flow_Sensor,Measures the flow of the entering condenser water, https://brickschema.org/schema/Brick#Entering_Condenser_Water_Temperature_Sensor,Measures the temperature of the entering condenser water, https://brickschema.org/schema/Brick#Entering_Condenser_Water_Temperature_Setpoint,The temperature setpoint for the entering condenser water, +https://brickschema.org/schema/Brick#Entering_District_Hot_Water,District hot water entering a piece of equipment or interface, +https://brickschema.org/schema/Brick#Entering_District_Hot_Water_Temperature_Sensor,Measures the temperature of district hot water entering a piece of equipment or interface, +https://brickschema.org/schema/Brick#Entering_District_Hot_Water_Temperature_Setpoint,Sets the temperature of district hot water entering a piece of equipment or interface, https://brickschema.org/schema/Brick#Entering_Domestic_Hot_Water,Domestic hot water that is entering a piece of equipment or system, https://brickschema.org/schema/Brick#Entering_Domestic_Hot_Water_Temperature_Sensor,, https://brickschema.org/schema/Brick#Entering_Domestic_Hot_Water_Temperature_Setpoint,, +https://brickschema.org/schema/Brick#Entering_Heating_Hot_Water,Heating hot water entering a piece of equipment or system, +https://brickschema.org/schema/Brick#Entering_Heating_Hot_Water_Temperature_Sensor,Measures the temperature of heating hot water entering a piece of equipment or system, +https://brickschema.org/schema/Brick#Entering_Heating_Hot_Water_Temperature_Setpoint,Sets the temperature of heating hot water entering a piece of equipment or system, https://brickschema.org/schema/Brick#Entering_High_Temperature_Hot_Water,High-temperature hot water entering a hot water system, https://brickschema.org/schema/Brick#Entering_High_Temperature_Hot_Water_Temperature_Sensor,Measures the temperature of high-temperature hot water entering a hot water system, https://brickschema.org/schema/Brick#Entering_Hot_Water,, @@ -382,7 +393,7 @@ https://brickschema.org/schema/Brick#Entering_Medium_Temperature_Hot_Water_Tempe https://brickschema.org/schema/Brick#Entering_Medium_Temperature_Hot_Water_Temperature_Load_Shed_Status,, https://brickschema.org/schema/Brick#Entering_Medium_Temperature_Hot_Water_Temperature_Low_Reset_Setpoint,, https://brickschema.org/schema/Brick#Entering_Medium_Temperature_Hot_Water_Temperature_Sensor,Measures the temperature of medium-temperature hot water entering a hot water system, -https://brickschema.org/schema/Brick#Entering_Water,Water that is entering a piece of equipment or system, +https://brickschema.org/schema/Brick#Entering_Water,Water that is entering a piece of equipment within a water system; contrasts with returning water which is specifically water coming back from the load side of the system., https://brickschema.org/schema/Brick#Entering_Water_Differential_Pressure_Deadband_Setpoint,Sets the size of a deadband of differential pressure of entering water, https://brickschema.org/schema/Brick#Entering_Water_Differential_Pressure_Integral_Time_Parameter,, https://brickschema.org/schema/Brick#Entering_Water_Differential_Pressure_Proportional_Band_Parameter,, @@ -509,6 +520,9 @@ https://brickschema.org/schema/Brick#Heating_Command,Controls the amount of heat https://brickschema.org/schema/Brick#Heating_Demand_Sensor,Measures the amount of power consumed by a heating process; typically found by multiplying the tonnage of a unit (e.g. RTU) by the efficiency rating in kW/ton, https://brickschema.org/schema/Brick#Heating_Demand_Setpoint,Sets the rate required for heating, https://brickschema.org/schema/Brick#Heating_Enable_Command,"Command that enables heating functionality in equipment but certain condition(s) must be met first before actively heating. For the actively heating control, see Heating_Command.", +https://brickschema.org/schema/Brick#Heating_Hot_Water,Hot water used for HVAC or process heating and not intended as domestic hot water, +https://brickschema.org/schema/Brick#Heating_Hot_Water_Temperature_Sensor,Measures the temperature of heating hot water, +https://brickschema.org/schema/Brick#Heating_Hot_Water_Temperature_Setpoint,Sets the temperature of heating hot water, https://brickschema.org/schema/Brick#Heating_Mode_Status,"Indicates whether a system, device or control loop is in a heating mode", https://brickschema.org/schema/Brick#Heating_Start_Stop_Status,, https://brickschema.org/schema/Brick#Heating_Supply_Air_Flow_Setpoint,Sets supply air flow rate for heating, @@ -604,6 +618,9 @@ https://brickschema.org/schema/Brick#Lead_Lag_Status,Indicates if lead/lag opera https://brickschema.org/schema/Brick#Lead_On_Off_Command,"Controls the active/inactive status of the ""lead"" part of a lead/lag system", https://brickschema.org/schema/Brick#Leak_Alarm,An alarm that indicates leaks occured in systems containing fluids, https://brickschema.org/schema/Brick#Leak_Detector_Equipment,, +https://brickschema.org/schema/Brick#Leaving_Building_Hot_Water,Building hot water leaving a piece of equipment or interface, +https://brickschema.org/schema/Brick#Leaving_Building_Hot_Water_Temperature_Sensor,Measures the temperature of building hot water leaving a piece of equipment or interface, +https://brickschema.org/schema/Brick#Leaving_Building_Hot_Water_Temperature_Setpoint,Sets the temperature of building hot water leaving a piece of equipment or interface, https://brickschema.org/schema/Brick#Leaving_Chilled_Water,Chilled water that is leaving a piece of equipment or system, https://brickschema.org/schema/Brick#Leaving_Chilled_Water_Flow_Sensor,Measures the rate of flow of chilled leaving water, https://brickschema.org/schema/Brick#Leaving_Chilled_Water_Flow_Setpoint,Sets the target flow rate of chilled leaving water, @@ -613,9 +630,15 @@ https://brickschema.org/schema/Brick#Leaving_Condenser_Water,"In a condenser wat https://brickschema.org/schema/Brick#Leaving_Condenser_Water_Flow_Sensor,Measures the flow of the leaving condenser water, https://brickschema.org/schema/Brick#Leaving_Condenser_Water_Temperature_Sensor,Measures the temperature of the leaving condenser water, https://brickschema.org/schema/Brick#Leaving_Condenser_Water_Temperature_Setpoint,The temperature setpoint for the leaving condenser water, +https://brickschema.org/schema/Brick#Leaving_District_Hot_Water,District hot water leaving a piece of equipment or interface, +https://brickschema.org/schema/Brick#Leaving_District_Hot_Water_Temperature_Sensor,Measures the temperature of district hot water leaving a piece of equipment or interface, +https://brickschema.org/schema/Brick#Leaving_District_Hot_Water_Temperature_Setpoint,Sets the temperature of district hot water leaving a piece of equipment or interface, https://brickschema.org/schema/Brick#Leaving_Domestic_Hot_Water,Domestic hot water that is leaving a piece of equipment or system, https://brickschema.org/schema/Brick#Leaving_Domestic_Hot_Water_Temperature_Sensor,Measures the temperature of domestic water supplied by a hot water system, https://brickschema.org/schema/Brick#Leaving_Domestic_Hot_Water_Temperature_Setpoint,Sets temperature of leavinging part of domestic hot water, +https://brickschema.org/schema/Brick#Leaving_Heating_Hot_Water,Heating hot water leaving a piece of equipment or system, +https://brickschema.org/schema/Brick#Leaving_Heating_Hot_Water_Temperature_Sensor,Measures the temperature of heating hot water leaving a piece of equipment or system, +https://brickschema.org/schema/Brick#Leaving_Heating_Hot_Water_Temperature_Setpoint,Sets the temperature of heating hot water leaving a piece of equipment or system, https://brickschema.org/schema/Brick#Leaving_High_Temperature_Hot_Water,High-temperature hot water leaving a hot water system, https://brickschema.org/schema/Brick#Leaving_High_Temperature_Hot_Water_Temperature_Sensor,Measures the temperature of high-temperature hot water supplied by a hot water system, https://brickschema.org/schema/Brick#Leaving_Hot_Water,, @@ -632,7 +655,7 @@ https://brickschema.org/schema/Brick#Leaving_Medium_Temperature_Hot_Water_Temper https://brickschema.org/schema/Brick#Leaving_Medium_Temperature_Hot_Water_Temperature_Load_Shed_Status,, https://brickschema.org/schema/Brick#Leaving_Medium_Temperature_Hot_Water_Temperature_Low_Reset_Setpoint,, https://brickschema.org/schema/Brick#Leaving_Medium_Temperature_Hot_Water_Temperature_Sensor,Measures the temperature of medium-temperature hot water supplied by a hot water system, -https://brickschema.org/schema/Brick#Leaving_Water,Water that is leaving a piece of equipment or system, +https://brickschema.org/schema/Brick#Leaving_Water,Water that is leaving a piece of equipment within a water system; contrasts with supply water which is water being supplied to the load side of the system., https://brickschema.org/schema/Brick#Leaving_Water_Differential_Pressure_Deadband_Setpoint,Sets the size of a deadband of differential pressure of leaving water, https://brickschema.org/schema/Brick#Leaving_Water_Differential_Pressure_Integral_Time_Parameter,, https://brickschema.org/schema/Brick#Leaving_Water_Differential_Pressure_Proportional_Band_Parameter,, @@ -977,9 +1000,15 @@ https://brickschema.org/schema/Brick#Return_Air_Temperature_High_Reset_Setpoint, https://brickschema.org/schema/Brick#Return_Air_Temperature_Low_Reset_Setpoint,, https://brickschema.org/schema/Brick#Return_Air_Temperature_Sensor,Measures the temperature of return air, https://brickschema.org/schema/Brick#Return_Air_Temperature_Setpoint,"The target temperature for return air, often used as an approximation of zone air temperature", +https://brickschema.org/schema/Brick#Return_Building_Hot_Water,Building hot water returning from the load side of a system or interface, +https://brickschema.org/schema/Brick#Return_Chilled_Water,Chilled water in the return side of a chilled water loop, https://brickschema.org/schema/Brick#Return_Damper,A damper that modulates the flow of return air, +https://brickschema.org/schema/Brick#Return_District_Hot_Water,District hot water returning from the load side of a system or interface, https://brickschema.org/schema/Brick#Return_Fan,Fan moving return air -- air that is circulated from the building back into the HVAC system, +https://brickschema.org/schema/Brick#Return_Heating_Hot_Water,Heating hot water returning from the load side of a system, https://brickschema.org/schema/Brick#Return_Heating_Valve,A valve installed on the return side of a heat exchanger, +https://brickschema.org/schema/Brick#Return_Hot_Water,Hot water in the return side of a hot water loop, +https://brickschema.org/schema/Brick#Return_Water,Water in the return side of a water loop, https://brickschema.org/schema/Brick#Reversing_Valve,, https://brickschema.org/schema/Brick#Rooftop_Unit,"Packaged air conditioner mounted on a roof, the conditioned air being discharged directly into the rooms below or through a duct system.", https://brickschema.org/schema/Brick#Room_Air,, @@ -1094,7 +1123,13 @@ https://brickschema.org/schema/Brick#Supply_Air_Temperature_Setpoint,Temperature https://brickschema.org/schema/Brick#Supply_Air_Temperature_Setpoint_Limit,, https://brickschema.org/schema/Brick#Supply_Air_Temperature_Step_Parameter,, https://brickschema.org/schema/Brick#Supply_Air_Velocity_Pressure_Sensor,, +https://brickschema.org/schema/Brick#Supply_Building_Hot_Water,Building hot water being supplied on the building or load side of a system or interface, +https://brickschema.org/schema/Brick#Supply_Chilled_Water,Chilled water in the supply side of a chilled water loop, +https://brickschema.org/schema/Brick#Supply_District_Hot_Water,District hot water being supplied on the district or utility side of a system or interface, https://brickschema.org/schema/Brick#Supply_Fan,Fan moving supply air -- air that is supplied from the HVAC system into the building, +https://brickschema.org/schema/Brick#Supply_Heating_Hot_Water,Heating hot water being supplied on the load side of a water system, +https://brickschema.org/schema/Brick#Supply_Hot_Water,Hot water in the supply side of a hot water loop, +https://brickschema.org/schema/Brick#Supply_Water,Water being supplied to the load-side of a water system, https://brickschema.org/schema/Brick#Surveillance_Camera,, https://brickschema.org/schema/Brick#Switch,A switch used to operate all or part of a lighting installation, https://brickschema.org/schema/Brick#Switch_Status,Status of a switch, diff --git a/bricksrc/deprecations.py b/bricksrc/deprecations.py index acdded7e..088a648c 100644 --- a/bricksrc/deprecations.py +++ b/bricksrc/deprecations.py @@ -175,20 +175,6 @@ BRICK.Chilled_Water_Flow_Sensor, ], }, - BRICK.Supply_Water: { - "version": "1.3.0", - "mitigation_message": "Swapped supply/return for entering/leaving with water-related points", - "replace_with": BRICK.Leaving_Water, - SKOS.broader: BRICK.Water, - A: BRICK.Substance, - }, - BRICK.Supply_Chilled_Water: { - "version": "1.3.0", - "mitigation_message": "Swapped supply/return for entering/leaving with water-related points", - "replace_with": BRICK.Leaving_Chilled_Water, - SKOS.broader: BRICK.Chilled_Water, - A: BRICK.Substance, - }, BRICK.Discharge_Water: { "version": "1.3.0", "mitigation_message": "Swapped supply/return for entering/leaving with water-related points", @@ -203,13 +189,6 @@ SKOS.broader: BRICK.Chilled_Water, A: BRICK.Substance, }, - BRICK.Supply_Hot_Water: { - "version": "1.3.0", - "mitigation_message": "Swapped supply/return for entering/leaving with water-related points", - "replace_with": BRICK.Leaving_Hot_Water, - SKOS.broader: BRICK.Hot_Water, - A: BRICK.Substance, - }, BRICK.Discharge_Hot_Water: { "version": "1.3.0", "mitigation_message": "Swapped supply/return for entering/leaving with water-related points", @@ -217,20 +196,6 @@ SKOS.broader: BRICK.Hot_Water, A: BRICK.Substance, }, - BRICK.Return_Water: { - "version": "1.3.0", - "mitigation_message": "Swapped supply/return for entering/leaving with water-related points", - "replace_with": BRICK.Entering_Water, - SKOS.broader: BRICK.Water, - A: BRICK.Substance, - }, - BRICK.Return_Hot_Water: { - "version": "1.3.0", - "mitigation_message": "Swapped supply/return for entering/leaving with water-related points", - "replace_with": BRICK.Entering_Hot_Water, - SKOS.broader: BRICK.Hot_Water, - A: BRICK.Substance, - }, BRICK.Supply_Condenser_Water: { "version": "1.3.0", "mitigation_message": "Swapped supply/return for entering/leaving with water-related points", @@ -474,7 +439,8 @@ "replace_with": BRICK.Leaving_Hot_Water_Flow_Setpoint, "version": "1.3.0", RDFS.subClassOf: [ - BRICK.Supply_Water_Temperature_Sensor, + BRICK.Supply_Water_Flow_Setpoint, + BRICK.Hot_Water_Flow_Setpoint, ], }, BRICK.Hot_Water_Supply_Temperature_Sensor: { @@ -602,7 +568,7 @@ "replace_with": BRICK.Leaving_Condenser_Water_Temperature_Setpoint, "version": "1.3.0", RDFS.subClassOf: [ - BRICK.Supply_Water_Temperature_Sensor, + BRICK.Leaving_Condenser_Water_Temperature_Setpoint, ], }, BRICK.Discharge_Condenser_Water_Temperature_Setpoint: { @@ -610,7 +576,7 @@ "replace_with": BRICK.Leaving_Condenser_Water_Temperature_Setpoint, "version": "1.3.0", RDFS.subClassOf: [ - BRICK.Discharge_Water_Temperature_Sensor, + BRICK.Leaving_Condenser_Water_Temperature_Setpoint, ], }, BRICK.Supply_Hot_Water_Temperature_Setpoint: { @@ -618,7 +584,8 @@ "replace_with": BRICK.Leaving_Hot_Water_Temperature_Setpoint, "version": "1.3.0", RDFS.subClassOf: [ - BRICK.Supply_Water_Temperature_Sensor, + BRICK.Leaving_Hot_Water_Temperature_Setpoint, + BRICK.Hot_Water_Temperature_Setpoint, ], }, BRICK.Discharge_Hot_Water_Temperature_Setpoint: { @@ -626,10 +593,10 @@ "replace_with": BRICK.Leaving_Hot_Water_Temperature_Setpoint, "version": "1.3.0", RDFS.subClassOf: [ - BRICK.Discharge_Water_Temperature_Sensor, + BRICK.Leaving_Hot_Water_Temperature_Setpoint, + BRICK.Hot_Water_Temperature_Setpoint, ], }, - BRICK.Electric_Current: { "version": "1.4.4", "mitigation_message": "Brick-defined quantity 'Electric_Current' is deprecated. Use the equivalent QUDT quantity 'qudt:QuantityKind/ElectricCurrent' directly.", @@ -670,7 +637,7 @@ "mitigation_message": "Brick-defined quantity 'Atmospheric_Pressure' is deprecated. Use the equivalent QUDT quantity 'qudt:QuantityKind/AtmosphericPressure' directly.", "replace_with": QUDTQK.AtmosphericPressure, }, - BRICK.Gauge_Pressure: { + BRICK.Gauge_Pressure: { "version": "1.4.4", "mitigation_message": "Brick-defined quantity 'Gauge_Pressure' is deprecated. Use the QUDT quantity 'qudt:QuantityKind/Pressure' and indicate contextually that it is gauge pressure if necessary.", "replace_with": QUDTQK.Pressure, @@ -755,7 +722,6 @@ "mitigation_message": "Brick-defined quantity 'Radioactivity_Concentration_Sensor' is deprecated. Use Air_Quality_Sensor instead, or the provided sensor class for the specific kind or source of radioactivity (e.g. Radon gas)", "replace_with": BRICK.Air_Quality_Sensor, }, - BRICK.Phasor: { "version": "1.4.4", "mitigation_message": "Brick-defined quantity 'Phasor' is deprecated.", diff --git a/bricksrc/meters.py b/bricksrc/meters.py index 9f317b94..eafcf28b 100644 --- a/bricksrc/meters.py +++ b/bricksrc/meters.py @@ -61,7 +61,7 @@ "tags": [TAG.Meter, TAG.Equipment, TAG.Water, TAG.Hot], "subclasses": { "Building_Hot_Water_Meter": { - BRICK.hasSubstance: BRICK.Hot_Water, + BRICK.hasSubstance: BRICK.Building_Hot_Water, "tags": [ TAG.Building, TAG.Hot, diff --git a/bricksrc/sensor.py b/bricksrc/sensor.py index ff11db29..e9da0fa5 100644 --- a/bricksrc/sensor.py +++ b/bricksrc/sensor.py @@ -1941,6 +1941,18 @@ TAG.Sensor, ], }, + "Heating_Hot_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Heating, + TAG.Hot, + TAG.Water, + TAG.Temperature, + TAG.Sensor, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Heating_Hot_Water, + }, "Entering_Hot_Water_Temperature_Sensor": { "tags": [ TAG.Point, @@ -1967,6 +1979,54 @@ BRICK.Domestic_Hot_Water_Temperature_Sensor ], }, + "Entering_Heating_Hot_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Heating, + TAG.Hot, + TAG.Water, + TAG.Entering, + TAG.Temperature, + TAG.Sensor, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Entering_Heating_Hot_Water, + "parents": [ + BRICK.Heating_Hot_Water_Temperature_Sensor + ], + }, + "Entering_Building_Hot_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Building, + TAG.Hot, + TAG.Water, + TAG.Entering, + TAG.Temperature, + TAG.Sensor, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Entering_Building_Hot_Water, + "parents": [ + BRICK.Entering_Heating_Hot_Water_Temperature_Sensor + ], + }, + "Entering_District_Hot_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.District, + TAG.Hot, + TAG.Water, + TAG.Entering, + TAG.Temperature, + TAG.Sensor, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Entering_District_Hot_Water, + "parents": [ + BRICK.Entering_Heating_Hot_Water_Temperature_Sensor + ], + }, "Entering_High_Temperature_Hot_Water_Temperature_Sensor": { "tags": [ TAG.Point, @@ -2019,6 +2079,54 @@ BRICK.Domestic_Hot_Water_Temperature_Sensor ], }, + "Leaving_Heating_Hot_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Heating, + TAG.Hot, + TAG.Water, + TAG.Leaving, + TAG.Temperature, + TAG.Sensor, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Leaving_Heating_Hot_Water, + "parents": [ + BRICK.Heating_Hot_Water_Temperature_Sensor + ], + }, + "Leaving_Building_Hot_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Building, + TAG.Hot, + TAG.Water, + TAG.Leaving, + TAG.Temperature, + TAG.Sensor, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Leaving_Building_Hot_Water, + "parents": [ + BRICK.Leaving_Heating_Hot_Water_Temperature_Sensor + ], + }, + "Leaving_District_Hot_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.District, + TAG.Hot, + TAG.Water, + TAG.Leaving, + TAG.Temperature, + TAG.Sensor, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Leaving_District_Hot_Water, + "parents": [ + BRICK.Leaving_Heating_Hot_Water_Temperature_Sensor + ], + }, "Leaving_High_Temperature_Hot_Water_Temperature_Sensor": { "tags": [ TAG.Point, @@ -2045,6 +2153,30 @@ }, }, }, + "Return_Hot_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Sensor, + TAG.Temperature, + TAG.Water, + TAG.Hot, + TAG.Return, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Return_Hot_Water, + }, + "Supply_Hot_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Sensor, + TAG.Temperature, + TAG.Water, + TAG.Hot, + TAG.Supply, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Supply_Hot_Water, + }, "Chilled_Water_Temperature_Sensor": { "tags": [ TAG.Point, @@ -2071,6 +2203,23 @@ BRICK.Water_Differential_Temperature_Sensor ], }, + "Differential_Entering_Leaving_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Sensor, + TAG.Temperature, + TAG.Water, + TAG.Chilled, + TAG.Leaving, + TAG.Entering, + TAG.Differential, + ], + BRICK.hasSubstance: [ + BRICK.Leaving_Chilled_Water, + BRICK.Entering_Chilled_Water, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + }, "Entering_Chilled_Water_Temperature_Sensor": { "tags": [ TAG.Point, @@ -2095,22 +2244,29 @@ BRICK.hasQuantity: QUDTQK.Temperature, BRICK.hasSubstance: BRICK.Leaving_Chilled_Water, }, - "Differential_Entering_Leaving_Water_Temperature_Sensor": { + "Return_Chilled_Water_Temperature_Sensor": { "tags": [ TAG.Point, TAG.Sensor, TAG.Temperature, TAG.Water, TAG.Chilled, - TAG.Leaving, - TAG.Entering, - TAG.Differential, + TAG.Return, ], - BRICK.hasSubstance: [ - BRICK.Leaving_Chilled_Water, - BRICK.Entering_Chilled_Water, + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Return_Chilled_Water, + }, + "Supply_Chilled_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Sensor, + TAG.Temperature, + TAG.Water, + TAG.Chilled, + TAG.Supply, ], BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Supply_Chilled_Water, }, }, }, @@ -2160,6 +2316,28 @@ }, }, }, + "Return_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Sensor, + TAG.Temperature, + TAG.Water, + TAG.Return, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Return_Water, + }, + "Supply_Water_Temperature_Sensor": { + "tags": [ + TAG.Point, + TAG.Sensor, + TAG.Temperature, + TAG.Water, + TAG.Supply, + ], + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Supply_Water, + }, "Collection_Basin_Water_Temperature_Sensor": { BRICK.hasQuantity: QUDTQK.Temperature, BRICK.hasSubstance: BRICK.Collection_Basin_Water, diff --git a/bricksrc/setpoint.py b/bricksrc/setpoint.py index 17689007..45351c6e 100644 --- a/bricksrc/setpoint.py +++ b/bricksrc/setpoint.py @@ -1928,6 +1928,19 @@ }, }, }, + "Heating_Hot_Water_Temperature_Setpoint": { + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Heating_Hot_Water, + "tags": [ + TAG.Point, + TAG.Heating, + TAG.Hot, + TAG.Water, + TAG.Temperature, + TAG.Setpoint, + ], + "parents": [BRICK.Hot_Water_Temperature_Setpoint], + }, "Chilled_Water_Temperature_Setpoint": { BRICK.hasQuantity: QUDTQK.Temperature, BRICK.hasSubstance: BRICK.Chilled_Water, @@ -1984,6 +1997,54 @@ BRICK.Hot_Water_Temperature_Setpoint ], }, + "Leaving_Heating_Hot_Water_Temperature_Setpoint": { + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Leaving_Heating_Hot_Water, + "tags": [ + TAG.Point, + TAG.Heating, + TAG.Leaving, + TAG.Water, + TAG.Temperature, + TAG.Setpoint, + TAG.Hot, + ], + "parents": [ + BRICK.Heating_Hot_Water_Temperature_Setpoint + ], + }, + "Leaving_Building_Hot_Water_Temperature_Setpoint": { + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Leaving_Building_Hot_Water, + "tags": [ + TAG.Point, + TAG.Building, + TAG.Leaving, + TAG.Water, + TAG.Temperature, + TAG.Setpoint, + TAG.Hot, + ], + "parents": [ + BRICK.Leaving_Heating_Hot_Water_Temperature_Setpoint + ], + }, + "Leaving_District_Hot_Water_Temperature_Setpoint": { + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Leaving_District_Hot_Water, + "tags": [ + TAG.Point, + TAG.District, + TAG.Leaving, + TAG.Water, + TAG.Temperature, + TAG.Setpoint, + TAG.Hot, + ], + "parents": [ + BRICK.Leaving_Heating_Hot_Water_Temperature_Setpoint + ], + }, "Leaving_Chilled_Water_Temperature_Setpoint": { "tags": [ TAG.Point, @@ -2037,6 +2098,54 @@ BRICK.Hot_Water_Temperature_Setpoint ], }, + "Entering_Heating_Hot_Water_Temperature_Setpoint": { + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Entering_Heating_Hot_Water, + "tags": [ + TAG.Point, + TAG.Heating, + TAG.Entering, + TAG.Water, + TAG.Temperature, + TAG.Setpoint, + TAG.Hot, + ], + "parents": [ + BRICK.Heating_Hot_Water_Temperature_Setpoint + ], + }, + "Entering_Building_Hot_Water_Temperature_Setpoint": { + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Entering_Building_Hot_Water, + "tags": [ + TAG.Point, + TAG.Building, + TAG.Entering, + TAG.Water, + TAG.Temperature, + TAG.Setpoint, + TAG.Hot, + ], + "parents": [ + BRICK.Entering_Heating_Hot_Water_Temperature_Setpoint + ], + }, + "Entering_District_Hot_Water_Temperature_Setpoint": { + BRICK.hasQuantity: QUDTQK.Temperature, + BRICK.hasSubstance: BRICK.Entering_District_Hot_Water, + "tags": [ + TAG.Point, + TAG.District, + TAG.Entering, + TAG.Water, + TAG.Temperature, + TAG.Setpoint, + TAG.Hot, + ], + "parents": [ + BRICK.Entering_Heating_Hot_Water_Temperature_Setpoint + ], + }, "Entering_Chilled_Water_Temperature_Setpoint": { BRICK.hasQuantity: QUDTQK.Temperature, BRICK.hasSubstance: BRICK.Entering_Chilled_Water, diff --git a/bricksrc/substances.py b/bricksrc/substances.py index d9da6c05..a4ffd8e1 100644 --- a/bricksrc/substances.py +++ b/bricksrc/substances.py @@ -30,15 +30,15 @@ }, "Formaldehyde": {}, "Methane": {}, - "CO": {}, # Carbon Monoxide - "CO2": {}, # Carbon Dioxide + "CO": {}, # Carbon Monoxide + "CO2": {}, # Carbon Dioxide "Natural_Gas": {}, "Ammonia": {}, - "NO2": {}, # Nitrogen Dioxide + "NO2": {}, # Nitrogen Dioxide "Ozone": {}, "Radon": {}, "Steam": {}, - "TVOC": {}, # Total Volatile Organic Compounds + "TVOC": {}, # Total Volatile Organic Compounds }, }, "Liquid": { @@ -61,6 +61,12 @@ "Leaving_Chilled_Water": { "parents": [BRICK.Leaving_Water], }, + "Return_Chilled_Water": { + "parents": [BRICK.Return_Water], + }, + "Supply_Chilled_Water": { + "parents": [BRICK.Supply_Water], + }, }, }, "Collection_Basin_Water": {}, @@ -88,33 +94,105 @@ }, "Potable_Water": {}, "Leaving_Water": {}, + "Return_Water": {}, + "Supply_Water": {}, "Entering_Water": {}, "Hot_Water": { SKOS.narrower: { "Entering_Hot_Water": { "parents": [BRICK.Entering_Water], }, + "Return_Hot_Water": { + "parents": [BRICK.Return_Water], + }, + "Supply_Hot_Water": { + "parents": [BRICK.Supply_Water], + }, "Leaving_Hot_Water": { "parents": [BRICK.Leaving_Water], }, - "High_Temperature_Hot_Water": { + "Heating_Hot_Water": { SKOS.narrower: { - "Entering_High_Temperature_Hot_Water": { + "Entering_Heating_Hot_Water": { "parents": [BRICK.Entering_Water], }, - "Leaving_High_Temperature_Hot_Water": { - "parents": [BRICK.Leaving_Water], + "Return_Heating_Hot_Water": { + "parents": [BRICK.Return_Water], }, - }, - }, - "Medium_Temperature_Hot_Water": { - SKOS.narrower: { - "Entering_Medium_Temperature_Hot_Water": { - "parents": [BRICK.Entering_Water], + "Supply_Heating_Hot_Water": { + "parents": [BRICK.Supply_Water], }, - "Leaving_Medium_Temperature_Hot_Water": { + "Leaving_Heating_Hot_Water": { "parents": [BRICK.Leaving_Water], }, + "Building_Hot_Water": { + SKOS.narrower: { + "Entering_Building_Hot_Water": { + "parents": [ + BRICK.Entering_Water + ], + }, + "Return_Building_Hot_Water": { + "parents": [BRICK.Return_Water], + }, + "Supply_Building_Hot_Water": { + "parents": [BRICK.Supply_Water], + }, + "Leaving_Building_Hot_Water": { + "parents": [ + BRICK.Leaving_Water + ], + }, + }, + }, + "District_Hot_Water": { + SKOS.narrower: { + "Entering_District_Hot_Water": { + "parents": [ + BRICK.Entering_Water + ], + }, + "Return_District_Hot_Water": { + "parents": [BRICK.Return_Water], + }, + "Supply_District_Hot_Water": { + "parents": [BRICK.Supply_Water], + }, + "Leaving_District_Hot_Water": { + "parents": [ + BRICK.Leaving_Water + ], + }, + }, + }, + "High_Temperature_Hot_Water": { + SKOS.narrower: { + "Entering_High_Temperature_Hot_Water": { + "parents": [ + BRICK.Entering_Water + ], + }, + "Leaving_High_Temperature_Hot_Water": { + "parents": [ + BRICK.Leaving_Water + ], + }, + }, + }, + "Medium_Temperature_Hot_Water": { + SKOS.narrower: { + "Entering_Medium_Temperature_Hot_Water": { + "parents": [ + BRICK.Entering_Water + ], + }, + "Leaving_Medium_Temperature_Hot_Water": { + "parents": [ + BRICK.Leaving_Water + ], + }, + }, + }, }, }, }, diff --git a/examples/chiller-system/chiller-plant-haystack.ttl b/examples/chiller-system/chiller-plant-haystack.ttl new file mode 100644 index 00000000..63968bd4 --- /dev/null +++ b/examples/chiller-system/chiller-plant-haystack.ttl @@ -0,0 +1,47 @@ +# modeling the system in https://project-haystack.org/doc/docHaystack/chilled-water-plant.svg +@prefix : . +@prefix brick: . +@prefix unit: . +@prefix xsd: . +@prefix rdf: . +@prefix rdfs: . +@prefix owl: . + + a owl:Ontology ; + owl:imports . + +:plant a brick:Chilled_Water_System ; + brick:hasPart :ct, :chiller . +# currently can't put points on the system itself in Brick +# brick:hasPoint :plant-chilled-water-supply-temp, :plant-chilled-water-return-temp . +# :plant-chilled-water-supply-temp a brick:Supply_Chilled_Water_Temperature_Sensor ; +# rdfs:label "Plant Chilled Water Supply Temp Sensor (supply to load)" ; +# brick:hasUnit unit:DEG_C . +# :plant-chilled-water-return-temp a brick:Return_Chilled_Water_Temperature_Sensor ; +# rdfs:label "Plant Chilled Water Return Temp Sensor (return from load)" ; +# brick:hasUnit unit:DEG_C . + +:ct a brick:Cooling_Tower ; + brick:hasPoint :ct-cond-water-leave-temp, :ct-cond-water-enter-temp . +:ct-cond-water-leave-temp a brick:Leaving_Condenser_Water_Temperature_Sensor ; + rdfs:label "Condenser Water Leaving Temp Sensor, measured at cooling tower (to chiller)" ; + brick:hasUnit unit:DEG_C . +:ct-cond-water-enter-temp a brick:Entering_Condenser_Water_Temperature_Sensor ; + rdfs:label "Condenser Water Entering Temp Sensor, measured at cooling tower (from chiller)" ; + brick:hasUnit unit:DEG_C . + +:chiller a brick:Chiller ; + brick:hasPoint :cond-water-enter-temp, :cond-water-leave-temp, + :chilled-water-return-temp, :chilled-water-supply-temp . +:chilled-water-return-temp a brick:Return_Chilled_Water_Temperature_Sensor ; + rdfs:label "Chilled Water Return Temp Sensor, measured at chiller (return from load)" ; + brick:hasUnit unit:DEG_C . +:chilled-water-supply-temp a brick:Supply_Chilled_Water_Temperature_Sensor ; + rdfs:label "Chilled Water Supply Temp Sensor, measured at chiller (supply to load)" ; + brick:hasUnit unit:DEG_C . +:cond-water-enter-temp a brick:Entering_Condenser_Water_Temperature_Sensor ; + rdfs:label "Condenser Water Entering Temp Sensor, measured at chiller (from cooling tower)" ; + brick:hasUnit unit:DEG_C . +:cond-water-leave-temp a brick:Leaving_Condenser_Water_Temperature_Sensor ; + rdfs:label "Condenser Water Leaving Temp Sensor, measured at chiller (to cooling tower)" ; + brick:hasUnit unit:DEG_C . diff --git a/examples/district-heating/district-heating.ttl b/examples/district-heating/district-heating.ttl new file mode 100644 index 00000000..5cd9e215 --- /dev/null +++ b/examples/district-heating/district-heating.ttl @@ -0,0 +1,84 @@ +# District-heating substation with separate space-heating and domestic-hot-water +# interfaces. The district side and building side are distinguished with +# dedicated hot-water substances; domestic hot water remains separate. +@prefix : . +@prefix brick: . +@prefix owl: . +@prefix rdfs: . +@prefix unit: . + + a owl:Ontology ; + owl:imports . + +:building a brick:Building ; + brick:isMeteredBy :building-meter . + +:substation a brick:Hot_Water_System ; + brick:hasPart :space-heating-hx, :dhw-hx, :heating-pump, :building-meter . + +:building-meter a brick:Building_Hot_Water_Meter ; + brick:meters :building . + +:space-heating-loop a brick:Hot_Water_System ; + brick:hasPart :heating-coil, :heating-pump . + +:space-heating-hx a brick:Plate_Heat_Exchanger ; + rdfs:label "Space heating district heat exchanger" ; + brick:hasPoint + :district-heating-entering-temp, + :district-heating-leaving-temp, + :building-heating-entering-temp, + :building-heating-leaving-temp, + :building-heating-leaving-temp-sp . + +:district-heating-entering-temp a brick:Entering_District_Hot_Water_Temperature_Sensor ; + rdfs:label "District-side inlet temperature to space-heating heat exchanger" ; + brick:hasUnit unit:DEG_C . + +:district-heating-leaving-temp a brick:Leaving_District_Hot_Water_Temperature_Sensor ; + rdfs:label "District-side outlet temperature from space-heating heat exchanger" ; + brick:hasUnit unit:DEG_C . + +:building-heating-entering-temp a brick:Entering_Building_Hot_Water_Temperature_Sensor ; + rdfs:label "Building-side return temperature into space-heating heat exchanger" ; + brick:hasUnit unit:DEG_C . + +:building-heating-leaving-temp a brick:Leaving_Building_Hot_Water_Temperature_Sensor ; + rdfs:label "Building-side supply temperature from space-heating heat exchanger" ; + brick:hasUnit unit:DEG_C . + +:building-heating-leaving-temp-sp a brick:Leaving_Building_Hot_Water_Temperature_Setpoint ; + rdfs:label "Building-side leaving temperature setpoint for space heating" ; + brick:hasUnit unit:DEG_C . + +:dhw-hx a brick:Plate_Heat_Exchanger ; + rdfs:label "Domestic hot water district heat exchanger" ; + brick:hasPoint + :district-dhw-entering-temp, + :district-dhw-leaving-temp, + :dhw-entering-temp, + :dhw-leaving-temp . + +:district-dhw-entering-temp a brick:Entering_District_Hot_Water_Temperature_Sensor ; + rdfs:label "District-side inlet temperature to domestic hot water heat exchanger" ; + brick:hasUnit unit:DEG_C . + +:district-dhw-leaving-temp a brick:Leaving_District_Hot_Water_Temperature_Sensor ; + rdfs:label "District-side outlet temperature from domestic hot water heat exchanger" ; + brick:hasUnit unit:DEG_C . + +:dhw-entering-temp a brick:Entering_Domestic_Hot_Water_Temperature_Sensor ; + rdfs:label "Domestic hot water return temperature into domestic hot water heat exchanger" ; + brick:hasUnit unit:DEG_C . + +:dhw-leaving-temp a brick:Leaving_Domestic_Hot_Water_Temperature_Sensor ; + rdfs:label "Domestic hot water supply temperature from domestic hot water heat exchanger" ; + brick:hasUnit unit:DEG_C . + +:heating-pump a brick:Hot_Water_Pump ; + brick:feeds :heating-coil ; + brick:isFedBy :space-heating-hx . + +:heating-coil a brick:Hot_Water_Coil ; + brick:feeds :space-heating-hx ; + brick:isFedBy :heating-pump . diff --git a/tests/test_class_structure.py b/tests/test_class_structure.py index 81f5049f..9714151a 100644 --- a/tests/test_class_structure.py +++ b/tests/test_class_structure.py @@ -88,14 +88,37 @@ def _cond(x) -> bool: def test_non_root_classes_are_subclasses(brick_with_imports): # find all owl:Class which are in the Brick namespace # and are not subclasses of any other class - query = f""" + query = """ SELECT ?class WHERE {{ ?class a owl:Class . - FILTER STRSTARTS(STR(?class), "{BRICK}") . + FILTER STRSTARTS(STR(?class), "{brick}") . FILTER NOT EXISTS {{ ?class rdfs:subClassOf ?parent . }} - FILTER ( ?class NOT IN (brick:Class, brick:Entity, brick:EntityPropertyValue, brick:EntityProperty, brick:Tag) ) - }}""" + FILTER (?class NOT IN ( + brick:Class, + brick:Entity, + brick:EntityPropertyValue, + brick:EntityProperty, + brick:Tag + )) + }}""".format( + brick=BRICK + ) for result in brick_with_imports.query(query): assert False, f"Class {result} is not a subclass of any other class" + + +def test_deprecated_water_setpoints_are_not_sensors(brick_with_imports): + query = """ + SELECT ?klass ?parent WHERE {{ + ?klass a owl:Class . + FILTER STRSTARTS(STR(?klass), "{brick}") . + FILTER STRENDS(STR(?klass), "Setpoint") . + ?klass rdfs:subClassOf ?parent . + ?parent rdfs:subClassOf* brick:Sensor . + }}""".format( + brick=BRICK + ) + bad = list(brick_with_imports.query(query)) + assert not bad, f"Setpoints should not inherit from sensors: {bad}" diff --git a/tests/test_matching_classes.py b/tests/test_matching_classes.py index d94afc6d..aaf8593e 100644 --- a/tests/test_matching_classes.py +++ b/tests/test_matching_classes.py @@ -1,200 +1,155 @@ -from rdflib import Graph, URIRef from collections import defaultdict +BRICK_PREFIX = "https://brickschema.org/schema/Brick#" -def getDict(g, q): - d = defaultdict(list) - res = g.query(q) +def _brick_name(value): + return value.toPython().replace(BRICK_PREFIX, "") - for row in res: - c1 = row.c.toPython().replace("https://brickschema.org/schema/Brick#", "") + +def _query_class_relations(g, query): + relations = defaultdict(list) + for row in g.query(query): + class_name = _brick_name(row.c) if row.p: - c2 = row.p.toPython().replace("https://brickschema.org/schema/Brick#", "") - d[c1].append(c2) - - return d - - -def matchMinMax(d): - ds = {} - ds["MissingMatchingMin"] = [] - ds["MissingMatchingMax"] = [] - ds["AllGood"] = [] - dislist = [] - countmatch = 0 - countobutnotu = 0 - countubutnoto = 0 - for c in d: - if "Min" in c: - s = c.replace("Min", "Max") - if s in d: - # print('debug:',s,e[s]) - ds["AllGood"].append((s, c)) - countmatch += 1 - dislist.append(c) - else: - ds["MissingMatchingMax"].append(c) - dislist.append(c) - countobutnotu += 1 - for c in d: - if "Max" in c: - dis = c.replace("Max", "Min") - if dis in dislist: - pass - else: - ds["MissingMatchingMin"].append(c) - countubutnoto += 1 - # print(json.dumps(ds,indent=4),file=open('tests/mm.json','w')) - assert not ds[ - "MissingMatchingMin" - ], "There are {0} classes that have Max but not Min".format( - len(ds["MissingMatchingMin"]) - ) - assert not ds[ - "MissingMatchingMax" - ], "There are {0} classes that have Min but not Max".format( - len(ds["MissingMatchingMax"]) + relations[class_name].append(_brick_name(row.p)) + return relations + + +def _query_class_names(g, query): + return {_brick_name(row.c) for row in g.query(query)} + + +def _all_non_deprecated_class_relations(g): + # This is the shared universe of active Brick class names for the + # name-pair checks below. The relation values are only needed for the + # supply/discharge equivalence check. + return _query_class_relations( + g, + """ + SELECT DISTINCT ?c ?p + WHERE { + ?c (rdfs:subClassOf | owl:equivalentClass)+ ?p . + FILTER NOT EXISTS { ?c owl:deprecated true } . + FILTER NOT EXISTS { ?p owl:deprecated true } . + } + """, ) -def matchOccupiedUnoccupied(d): - ds = {} - ds["MissingMatchingOccupied"] = [] - ds["MissingMatchingUnoccupied"] = [] - ds["AllGood"] = [] - dislist = [] - countmatch = 0 - countobutnotu = 0 - countubutnoto = 0 - for c in d: - if "Occupied" in c: - s = c.replace("Occupied", "Unoccupied") - if s in d: - # print('debug:',s,e[s]) - ds["AllGood"].append((s, c)) - countmatch += 1 - dislist.append(c) - else: - ds["MissingMatchingUnoccupied"].append(c) - dislist.append(c) - countobutnotu += 1 - for c in d: - if "Unoccupied" in c: - dis = c.replace("Unoccupied", "Occupied") - if dis in dislist: - pass - else: - ds["MissingMatchingOccupied"].append(c) - countubutnoto += 1 - - # print(json.dumps(ds,indent=4),file=open('tests/uo.json','w')) - assert not ds[ - "MissingMatchingOccupied" - ], "There are {0} classes that have Unoccupied but not Occupied".format( - len(ds["MissingMatchingOccupied"]) +def _explicit_equivalent_classes(g): + # The supply/discharge naming convention is not enough by itself: those + # class pairs should also be connected with an explicit equivalentClass. + return _query_class_relations( + g, + """ + SELECT DISTINCT ?c ?p + WHERE { + ?c (rdfs:subClassOf | owl:equivalentClass)* brick:Class . + ?c owl:equivalentClass ?p . + FILTER NOT EXISTS { ?c owl:deprecated true } . + } + """, ) - assert not ds[ - "MissingMatchingUnoccupied" - ], "There are {0} classes that have Occupied but not Unoccupied".format( - len(ds["MissingMatchingUnoccupied"]) + + +def _supply_discharge_air_classes(g): + # Water supply/return terminology is distinct from air supply/discharge. + # Limit this check to classes tied to the aliased air substances. + return _query_class_names( + g, + """ + SELECT DISTINCT ?c + WHERE { + ?c (owl:equivalentClass|^owl:equivalentClass)* ?e . + ?e brick:hasSubstance ?s . + FILTER (?s IN (brick:Supply_Air, brick:Discharge_Air)) . + FILTER NOT EXISTS { ?c owl:deprecated true } . + } + """, ) -def matchSupplyDischarge(d, e): - ds = {} - ds["MissingMatchingDischarge"] = [] - ds["MissingMatchingSupply"] = [] - ds["NoEquivalenceDefined"] = {} - ds["AllGood"] = {} - dislist = [] - countmatch = 0 - countdbutnots = 0 - countsbutnotd = 0 - for c in d: - if "Discharge" in c: - s = c.replace("Discharge", "Supply") - if s in d: - if s in e: - # print('debug:',s,e[s]) - if c in e[s]: - pass - else: - print("*ERROR* ", s, e[s]) - ds["AllGood"][c] = s - elif c in e: - if s in e[c]: - pass - else: - print("*ERROR* ", c, e[c]) - ds["AllGood"][c] = s - else: - ds["NoEquivalenceDefined"][c] = s - countmatch += 1 - dislist.append(c) - else: - ds["MissingMatchingSupply"].append(c) - dislist.append(c) - countdbutnots += 1 - for c in d: - if "Supply" in c: - dis = c.replace("Supply", "Discharge") - if dis in dislist: - pass - else: - ds["MissingMatchingDischarge"].append(c) - countsbutnotd += 1 - - # print(json.dumps(ds,indent=4),file=open('tests/ds.json','w')) - assert not ds[ - "MissingMatchingSupply" - ], "There are {0} classes that have Discharge but not Supply".format( - len(ds["MissingMatchingSupply"]) +def _assert_matching_name_pairs(classes, left, right, *, allowed=None): + # For every active class containing one side of a conventional name pair, + # make sure the corresponding class name also exists. + classes_to_check = set(classes) + if allowed is not None: + classes_to_check &= set(allowed) + + missing_right = [] + missing_left = [] + for class_name in classes_to_check: + if left in class_name: + counterpart = class_name.replace(left, right) + if counterpart not in classes: + missing_right.append((class_name, counterpart)) + if right in class_name: + counterpart = class_name.replace(right, left) + if counterpart not in classes: + missing_left.append((class_name, counterpart)) + + assert ( + not missing_left + ), "Missing {left} counterparts for {right} classes: {missing}".format( + left=left, + right=right, + missing=sorted(missing_left), ) - assert not ds[ - "MissingMatchingDischarge" - ], "There are {0} classes that have Supply but not Discharge".format( - len(ds["MissingMatchingDischarge"]) + assert ( + not missing_right + ), "Missing {right} counterparts for {left} classes: {missing}".format( + left=left, + right=right, + missing=sorted(missing_right), ) - assert not ds[ - "NoEquivalenceDefined" - ], "There are {0} classes that don't have Supply = Discharge defined".format( - len(ds["NoEquivalenceDefined"]) + + +def _assert_supply_discharge_equivalence(classes, equivalent_classes, allowed): + # Supply/Discharge air class names are aliases, so the ontology should + # encode that aliasing explicitly instead of only relying on similar names. + classes_to_check = set(classes) & set(allowed) + missing_equivalence = {} + + for class_name in classes_to_check: + if "Discharge" in class_name: + counterpart = class_name.replace("Discharge", "Supply") + if counterpart in classes: + if class_name not in equivalent_classes.get( + counterpart, [] + ) and counterpart not in equivalent_classes.get(class_name, []): + missing_equivalence[class_name] = counterpart + + assert not missing_equivalence, ( + "Missing Supply/Discharge owl:equivalentClass definitions: " + f"{missing_equivalence}" ) -# maincode -def test_matching_classes(brick_with_imports): - g = brick_with_imports - # DeductiveClosure(OWLRL_Semantics).expand(g) +def test_min_max_classes_have_matching_counterparts(brick_with_imports): + relations = _all_non_deprecated_class_relations(brick_with_imports) + _assert_matching_name_pairs(relations, "Min", "Max") - d = getDict( - g, - """ - SELECT DISTINCT ?c ?p - WHERE { - ?c (rdfs:subClassOf | owl:equivalentClass)+ ?p . - FILTER NOT EXISTS { ?c owl:deprecated true } . - FILTER NOT EXISTS { ?p owl:deprecated true } . - } - """, - ) - print("verifying min max classes...") - matchMinMax(d) - print("verifying occupied unoccupied classes...") - matchOccupiedUnoccupied(d) +def test_occupied_unoccupied_classes_have_matching_counterparts(brick_with_imports): + relations = _all_non_deprecated_class_relations(brick_with_imports) + _assert_matching_name_pairs(relations, "Occupied", "Unoccupied") - deq = getDict( - g, - """ - SELECT DISTINCT ?c ?p - WHERE { - ?c (rdfs:subClassOf | owl:equivalentClass)* brick:Class . - ?c owl:equivalentClass ?p . - FILTER NOT EXISTS { ?c owl:deprecated true } . - } - """, + +def test_supply_discharge_air_classes_have_matching_equivalent_counterparts( + brick_with_imports, +): + relations = _all_non_deprecated_class_relations(brick_with_imports) + supply_discharge_air_classes = _supply_discharge_air_classes(brick_with_imports) + + _assert_matching_name_pairs( + relations, + "Discharge", + "Supply", + allowed=supply_discharge_air_classes, + ) + _assert_supply_discharge_equivalence( + relations, + _explicit_equivalent_classes(brick_with_imports), + supply_discharge_air_classes, ) - print("verifying supply discharge classes...") - matchSupplyDischarge(d, deq)