Skip to content

Commit

Permalink
Merge pull request #55 from pnnl/VAV_turndown
Browse files Browse the repository at this point in the history
VAV Turndown verification item development
  • Loading branch information
leijerry888 authored Nov 8, 2024
2 parents 53d20aa + 462b89b commit 34acb9b
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 25 deletions.
2 changes: 2 additions & 0 deletions constrain/library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .heat_rejection_fan_var_flow_controls_cells import *
from .hot_water_reset import *
from .vav_static_pressure_sensor_location import *
from .vav_minimum_turndown_during_reheat import *
from .vav_turndown_during_reheat import *
from .ventilation_fan_controls import *
from .wlhp_loop_heat_rejection_controls import *
Expand Down Expand Up @@ -68,6 +69,7 @@
# "optimum_start", # missing
# "swh_restroom_outlet_maximum_temperature_controls", # missing
"VAVStaticPressureSensorLocation",
"VAVMinimumTurndownDuringReheat",
"VAVTurndownDuringReheat",
"VentilationFanControl",
"WLHPLoopHeatRejectionControl",
Expand Down
63 changes: 63 additions & 0 deletions constrain/library/vav_minimum_turndown_during_reheat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""
### Description
When a VAV box is in reheat mode, the ratio of VAV airflow rate to VAV max airflow rate must not be greater than the min design turndown ratio
### Code requirement
- Code Name: ASHRAE 90.1
- Code Year: 2016
- Code Section: 6.5.2 Simultaneous Heating and Cooling Limitation
- Code Subsection: 6.5.2.1 Zone Controls
### Verification Approach
- We aim to identify how VAV airflow rate varies when the VAV box is and isn't in reheat mode.
### Verification logic
```
if reheat_coil_flag:
if V_dot_VAV_max == 0
Untested
if V_dot_VAV_max > 0.0 and V_dot_VAV / V_dot_VAV_max > VAV_min_turndown_design + turndown_tol
fail
else:
pass
else
Untested
```
### Data requirements
- reheat_coil_flag: VAV box reheat coil operation status
- V_dot_VAV: actual VAV volume flow
- V_dot_VAV_max: max VAV volume flow
- VAV_min_turndown_design: design VAV box min turndown ratio
- turndown_tol: VAV turndown tolerance
"""

from constrain.checklib import RuleCheckBase


class VAVMinimumTurndownDuringReheat(RuleCheckBase):
points = [
"reheat_coil_flag", # boolean
"V_dot_VAV", # actual VAV volume flow
"V_dot_VAV_max", # max VAV volume flow
"VAV_min_turndown_design",
"turndown_tol",
]

def vav_turndown_check(self, data):
if data["reheat_coil_flag"]:
if data["V_dot_VAV_max"] == 0:
return "Untested"
elif (
data["V_dot_VAV"] / data["V_dot_VAV_max"]
> data["VAV_min_turndown_design"] + data["turndown_tol"]
):
return False
else:
return True
else:
return "Untested"

def verify(self):
self.result = self.df.apply(lambda d: self.vav_turndown_check(d), axis=1)
78 changes: 53 additions & 25 deletions schema/library.json
Original file line number Diff line number Diff line change
Expand Up @@ -1559,31 +1559,59 @@
"end"
]
},
"VAVMinimumTurndownDuringReheat": {
"library_item_id": 68,
"description_brief": "When a VAV box is in reheat mode, the ratio of VAV airflow rate to VAV max airflow rate must not be greater than the min design turndown ratio",
"description_index": [
"Section 6.5.2.1 ASHRAE 90.1-2016"
],
"description_datapoints": {
"reheat_coil_flag": "VAV box reheat coil operation status",
"V_dot_VAV": "VAV airflow rate",
"V_dot_VAV_max": "VAV max airflow rate",
"VAV_min_turndown_design": "design VAV box min turndown ratio",
"turndown_tol": "VAV turndown tolerance"
},
"description_verification_type": "rule-based",
"assertions_type": "pass",
"description_assertions": [
"if reheat_coil_flag:",
" if V_dot_VAV_max == 0",
" Untested",
" if V_dot_VAV_max > 0.0 and V_dot_VAV / V_dot_VAV_max > VAV_min_turndown_design + turndown_tol",
" fail",
" else:",
" pass",
"else",
" Untested",
"end"
]
},
"VAVTurndownDuringReheat": {
"library_item_id": 68,
"description_brief": "When a VAV box is in reheat mode, the ratio of V_dot_VAV to V_dot_VAV_max should be higher than when it isn't in reheat mode",
"description_index": [
"Section 6.5.2.1 ASHRAE 90.1-2016"
],
"description_datapoints": {
"reheat_coil_flag": "VAV box reheat coil operation status",
"V_dot_VAV": "VAV airflow rate",
"V_dot_VAV_max": "VAV max airflow rate"
},
"description_verification_type": "procedure-based",
"assertions_type": "pass",
"description_assertions": [
"if (reheat_coil_flag == False).all():",
" Untested",
"else: ",
" V_dot_VAV_ratio = V_dot_VAV/V_dot_VAV_max",
" mean_reheat_ratio = df.loc[self.df[`reheat_coil_flag`], `V_dot_VAV_ratio`].mean()",
" mean_no_reheat_ratio = df.loc[~self.df[`reheat_coil_flag`], `V_dot_VAV_ratio`].mean()",
" if mean_reheat_ratio < mean_no_reheat_ratio:",
" pass",
" else: ",
" fail",
"end"
]
"library_item_id": 69,
"description_brief": "When a VAV box is in reheat mode, the ratio of V_dot_VAV to V_dot_VAV_max should be higher than when it isn't in reheat mode",
"description_index": [
"Section 6.5.2.1 ASHRAE 90.1-2016"
],
"description_datapoints": {
"reheat_coil_flag": "VAV box reheat coil operation status",
"V_dot_VAV": "VAV airflow rate",
"V_dot_VAV_max": "VAV max airflow rate"
},
"description_verification_type": "procedure-based",
"assertions_type": "pass",
"description_assertions": [
"if (reheat_coil_flag == False).all():",
" Untested",
"else: ",
" V_dot_VAV_ratio = V_dot_VAV/V_dot_VAV_max",
" mean_reheat_ratio = df.loc[self.df[`reheat_coil_flag`], `V_dot_VAV_ratio`].mean()",
" mean_no_reheat_ratio = df.loc[~self.df[`reheat_coil_flag`], `V_dot_VAV_ratio`].mean()",
" if mean_reheat_ratio < mean_no_reheat_ratio:",
" pass",
" else: ",
" fail",
"end"
]
}
}
150 changes: 150 additions & 0 deletions tests/test_vav_minimum_turndown_during_reheat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import sys
import unittest

sys.path.append("./constrain")
import datetime

import pandas as pd
from lib_unit_test_runner import *


class TestVAVTurndown(unittest.TestCase):
def test_vav_turndown_untested(self):
points = [
"reheat_coil_flag",
"V_dot_VAV",
"V_dot_VAV_max",
"VAV_min_turndown_design",
"turndown_tol",
]

timestamp = [
datetime(2024, 8, 1, 12, 0, 0),
datetime(2024, 8, 1, 13, 0, 0),
]

data = [
[False, 0.005, 0.01, 0.3, 0.01],
[False, 0.005, 0.01, 0.3, 0.01],
]

df = pd.DataFrame(data, columns=points, index=timestamp)

verification_obj = run_test_verification_with_data(
"VAVMinimumTurndownDuringReheat", df
)
results = list(verification_obj.result)
expected_results = [
"Untested",
"Untested",
]

self.assertEqual(results, expected_results)
self.assertEqual(verification_obj.check_bool(), "Untested")

def test_vav_turndown_V_dot_max_zero_untested(self):
points = [
"reheat_coil_flag",
"V_dot_VAV",
"V_dot_VAV_max",
"VAV_min_turndown_design",
"turndown_tol",
]

timestamp = [
datetime(2024, 8, 1, 12, 0, 0),
datetime(2024, 8, 1, 13, 0, 0),
]

data = [
[True, 0.005, 0.0, 0.3, 0.01],
[True, 0.005, 0.0, 0.3, 0.01],
]

df = pd.DataFrame(data, columns=points, index=timestamp)

verification_obj = run_test_verification_with_data(
"VAVMinimumTurndownDuringReheat", df
)
results = list(verification_obj.result)
expected_results = [
"Untested",
"Untested",
]

self.assertEqual(results, expected_results)
self.assertEqual(verification_obj.check_bool(), "Untested")

def test_vav_turndown_pass(self):
points = [
"reheat_coil_flag",
"V_dot_VAV",
"V_dot_VAV_max",
"VAV_min_turndown_design",
"turndown_tol",
]

timestamp = [
datetime(2024, 8, 1, 12, 0, 0),
datetime(2024, 8, 1, 13, 0, 0),
]

data = [
[True, 0.005, 0.06, 0.3, 0.01],
[True, 0.005, 0.06, 0.3, 0.01],
]

df = pd.DataFrame(data, columns=points, index=timestamp)

verification_obj = run_test_verification_with_data(
"VAVMinimumTurndownDuringReheat", df
)

results = pd.Series(list(verification_obj.result))
expected_results = pd.Series(
[
True,
True,
]
)
self.assertTrue(results.equals(expected_results))

binary_result = verification_obj.check_bool()
self.assertTrue(binary_result)

def test_vav_turndown_fail(self):
points = [
"reheat_coil_flag",
"V_dot_VAV",
"V_dot_VAV_max",
"VAV_min_turndown_design",
"turndown_tol",
]

timestamp = [
datetime(2024, 8, 1, 12, 0, 0),
datetime(2024, 8, 1, 13, 0, 0),
]

data = [
[True, 0.005, 0.01, 0.3, 0.01],
[True, 0.005, 0.01, 0.3, 0.01],
]

df = pd.DataFrame(data, columns=points, index=timestamp)

verification_obj = run_test_verification_with_data(
"VAVMinimumTurndownDuringReheat", df
)

results = pd.Series(list(verification_obj.result))
expected_results = pd.Series(
[
False,
False,
]
)
self.assertTrue(results.equals(expected_results))

binary_result = verification_obj.check_bool()
self.assertFalse(binary_result)

0 comments on commit 34acb9b

Please sign in to comment.