open-fdd 0.1.8__py3-none-any.whl → 0.1.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- open_fdd/air_handling_unit/faults/__init__.py +30 -1487
- open_fdd/air_handling_unit/faults/fault_condition_eight.py +135 -0
- open_fdd/air_handling_unit/faults/fault_condition_eleven.py +108 -0
- open_fdd/air_handling_unit/faults/fault_condition_fifteen.py +189 -0
- open_fdd/air_handling_unit/faults/fault_condition_five.py +126 -0
- open_fdd/air_handling_unit/faults/fault_condition_four.py +128 -0
- open_fdd/air_handling_unit/faults/fault_condition_fourteen.py +177 -0
- open_fdd/air_handling_unit/faults/fault_condition_nine.py +140 -0
- open_fdd/air_handling_unit/faults/fault_condition_one.py +113 -0
- open_fdd/air_handling_unit/faults/fault_condition_seven.py +106 -0
- open_fdd/air_handling_unit/faults/fault_condition_six.py +228 -0
- open_fdd/air_handling_unit/faults/fault_condition_sixteen.py +196 -0
- open_fdd/air_handling_unit/faults/fault_condition_ten.py +119 -0
- open_fdd/air_handling_unit/faults/fault_condition_thirteen.py +139 -0
- open_fdd/air_handling_unit/faults/fault_condition_three.py +112 -0
- open_fdd/air_handling_unit/faults/fault_condition_twelve.py +164 -0
- open_fdd/air_handling_unit/faults/fault_condition_two.py +112 -0
- open_fdd/air_handling_unit/faults/helper_utils.py +29 -19
- open_fdd/air_handling_unit/reports/__init__.py +6 -4
- open_fdd/air_handling_unit/reports/fault_report.py +3 -2
- open_fdd/chiller_plant/faults/__init__.py +6 -2279
- open_fdd/chiller_plant/faults/fault_condition_one.py +113 -0
- open_fdd/chiller_plant/faults/fault_condition_two.py +100 -0
- open_fdd/tests/ahu/test_ahu_fc1.py +2 -2
- open_fdd/tests/ahu/test_ahu_fc10.py +1 -0
- open_fdd/tests/ahu/test_ahu_fc11.py +3 -4
- open_fdd/tests/ahu/test_ahu_fc12.py +3 -4
- open_fdd/tests/ahu/test_ahu_fc13.py +3 -4
- open_fdd/tests/ahu/test_ahu_fc14.py +3 -4
- open_fdd/tests/ahu/test_ahu_fc15.py +3 -4
- open_fdd/tests/ahu/test_ahu_fc16.py +4 -3
- open_fdd/tests/ahu/test_ahu_fc2.py +1 -0
- open_fdd/tests/ahu/test_ahu_fc3.py +1 -0
- open_fdd/tests/ahu/test_ahu_fc4.py +3 -1
- open_fdd/tests/ahu/test_ahu_fc5.py +1 -0
- open_fdd/tests/ahu/test_ahu_fc6.py +1 -0
- open_fdd/tests/ahu/test_ahu_fc7.py +1 -0
- open_fdd/tests/ahu/test_ahu_fc8.py +1 -0
- open_fdd/tests/ahu/test_ahu_fc9.py +1 -0
- open_fdd/tests/chiller/test_chiller_fc1.py +2 -2
- open_fdd/tests/chiller/test_chiller_fc2.py +2 -2
- {open_fdd-0.1.8.dist-info → open_fdd-0.1.9.dist-info}/METADATA +4 -3
- open_fdd-0.1.9.dist-info/RECORD +52 -0
- {open_fdd-0.1.8.dist-info → open_fdd-0.1.9.dist-info}/WHEEL +1 -1
- open_fdd/air_handling_unit/faults/fault_condition.py +0 -69
- open_fdd/air_handling_unit/faults/shared_utils.py +0 -90
- open_fdd-0.1.8.dist-info/RECORD +0 -36
- {open_fdd-0.1.8.dist-info → open_fdd-0.1.9.dist-info/licenses}/LICENSE +0 -0
- {open_fdd-0.1.8.dist-info → open_fdd-0.1.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,177 @@
|
|
1
|
+
import numpy as np
|
2
|
+
import pandas as pd
|
3
|
+
|
4
|
+
from open_fdd.core.base_fault import BaseFaultCondition
|
5
|
+
from open_fdd.core.components import FaultInputColumn, InstanceAttribute
|
6
|
+
from open_fdd.core.exceptions import InvalidParameterError
|
7
|
+
from open_fdd.core.mixins import FaultConditionMixin
|
8
|
+
|
9
|
+
INPUT_COLS = [
|
10
|
+
FaultInputColumn(
|
11
|
+
name="clg_coil_enter_temp_col",
|
12
|
+
constant_form="CLG_COIL_ENTER_TEMP_COL",
|
13
|
+
description="Cooling coil entering air temperature",
|
14
|
+
unit="°F",
|
15
|
+
required=True,
|
16
|
+
type=float,
|
17
|
+
),
|
18
|
+
FaultInputColumn(
|
19
|
+
name="clg_coil_leave_temp_col",
|
20
|
+
constant_form="CLG_COIL_LEAVE_TEMP_COL",
|
21
|
+
description="Cooling coil leaving air temperature",
|
22
|
+
unit="°F",
|
23
|
+
required=True,
|
24
|
+
type=float,
|
25
|
+
),
|
26
|
+
FaultInputColumn(
|
27
|
+
name="cooling_sig_col",
|
28
|
+
constant_form="COOLING_SIG_COL",
|
29
|
+
description="Cooling signal",
|
30
|
+
unit="%",
|
31
|
+
required=True,
|
32
|
+
type=float,
|
33
|
+
),
|
34
|
+
FaultInputColumn(
|
35
|
+
name="heating_sig_col",
|
36
|
+
constant_form="HEATING_SIG_COL",
|
37
|
+
description="Heating signal",
|
38
|
+
unit="%",
|
39
|
+
required=True,
|
40
|
+
type=float,
|
41
|
+
),
|
42
|
+
FaultInputColumn(
|
43
|
+
name="economizer_sig_col",
|
44
|
+
constant_form="ECONOMIZER_SIG_COL",
|
45
|
+
description="Economizer signal",
|
46
|
+
unit="%",
|
47
|
+
required=True,
|
48
|
+
type=float,
|
49
|
+
),
|
50
|
+
FaultInputColumn(
|
51
|
+
name="supply_vfd_speed_col",
|
52
|
+
constant_form="SUPPLY_VFD_SPEED_COL",
|
53
|
+
description="Supply fan VFD speed",
|
54
|
+
unit="%",
|
55
|
+
required=True,
|
56
|
+
type=float,
|
57
|
+
),
|
58
|
+
]
|
59
|
+
|
60
|
+
FAULT_PARAMS = [
|
61
|
+
InstanceAttribute(
|
62
|
+
name="delta_t_supply_fan",
|
63
|
+
constant_form="DELTA_T_SUPPLY_FAN",
|
64
|
+
description="Temperature rise across supply fan",
|
65
|
+
unit="°F",
|
66
|
+
type=float,
|
67
|
+
range=(0.0, 5.0),
|
68
|
+
),
|
69
|
+
InstanceAttribute(
|
70
|
+
name="coil_temp_enter_err_thres",
|
71
|
+
constant_form="COIL_TEMP_ENTER_ERR_THRES",
|
72
|
+
description="Cooling coil entering air temperature error threshold",
|
73
|
+
unit="°F",
|
74
|
+
type=float,
|
75
|
+
range=(0.0, 10.0),
|
76
|
+
),
|
77
|
+
InstanceAttribute(
|
78
|
+
name="coil_temp_leave_err_thres",
|
79
|
+
constant_form="COIL_TEMP_LEAV_ERR_THRES",
|
80
|
+
description="Cooling coil leaving air temperature error threshold",
|
81
|
+
unit="°F",
|
82
|
+
type=float,
|
83
|
+
range=(0.0, 10.0),
|
84
|
+
),
|
85
|
+
InstanceAttribute(
|
86
|
+
name="ahu_min_oa_dpr",
|
87
|
+
constant_form="AHU_MIN_OA_DPR",
|
88
|
+
description="Minimum outdoor air damper position",
|
89
|
+
unit="fraction",
|
90
|
+
type=float,
|
91
|
+
range=(0.0, 1.0),
|
92
|
+
),
|
93
|
+
]
|
94
|
+
|
95
|
+
|
96
|
+
class FaultConditionFourteen(BaseFaultCondition, FaultConditionMixin):
|
97
|
+
"""Class provides the definitions for Fault Condition 14.
|
98
|
+
Temperature drop across inactive cooling coil in OS1 (heating) and OS2 (economizer) modes.
|
99
|
+
This fault checks if there is an unexpected temperature drop across the cooling coil
|
100
|
+
when it should be inactive.
|
101
|
+
|
102
|
+
py -3.12 -m pytest open_fdd/tests/ahu/test_ahu_fc14.py -rP -s
|
103
|
+
"""
|
104
|
+
|
105
|
+
input_columns = INPUT_COLS
|
106
|
+
fault_params = FAULT_PARAMS
|
107
|
+
equation_string = (
|
108
|
+
"fc14_flag = 1 if (CLG_LEAVE < CLG_ENTER - √(εENTER² + εLEAVE²)) "
|
109
|
+
"in OS1 (heating) or OS2 (economizer) modes for N consecutive values else 0 \n"
|
110
|
+
)
|
111
|
+
description_string = (
|
112
|
+
"Fault Condition 14: Temperature drop across inactive cooling coil "
|
113
|
+
"in OS1 (heating) and OS2 (economizer) modes \n"
|
114
|
+
)
|
115
|
+
error_string = "One or more required columns are missing or None \n"
|
116
|
+
|
117
|
+
@FaultConditionMixin._handle_errors
|
118
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
119
|
+
"""Apply the fault condition to the DataFrame."""
|
120
|
+
# Apply common checks
|
121
|
+
self._apply_common_checks(df)
|
122
|
+
|
123
|
+
# Get column values using accessor methods
|
124
|
+
cooling_sig_col = self.get_input_column("cooling_sig_col")
|
125
|
+
heating_sig_col = self.get_input_column("heating_sig_col")
|
126
|
+
economizer_sig_col = self.get_input_column("economizer_sig_col")
|
127
|
+
supply_vfd_speed_col = self.get_input_column("supply_vfd_speed_col")
|
128
|
+
clg_coil_enter_temp_col = self.get_input_column("clg_coil_enter_temp_col")
|
129
|
+
clg_coil_leave_temp_col = self.get_input_column("clg_coil_leave_temp_col")
|
130
|
+
|
131
|
+
# Get parameter values using accessor methods
|
132
|
+
coil_temp_enter_err_thres = self.get_param("coil_temp_enter_err_thres")
|
133
|
+
coil_temp_leave_err_thres = self.get_param("coil_temp_leave_err_thres")
|
134
|
+
ahu_min_oa_dpr = self.get_param("ahu_min_oa_dpr")
|
135
|
+
|
136
|
+
# Check analog outputs [data with units of %] are floats only
|
137
|
+
columns_to_check = [
|
138
|
+
cooling_sig_col,
|
139
|
+
heating_sig_col,
|
140
|
+
economizer_sig_col,
|
141
|
+
supply_vfd_speed_col,
|
142
|
+
]
|
143
|
+
self._apply_analog_checks(df, columns_to_check, check_greater_than_one=True)
|
144
|
+
|
145
|
+
# Calculate the threshold for temperature drop
|
146
|
+
temp_drop_threshold = np.sqrt(
|
147
|
+
coil_temp_enter_err_thres**2 + coil_temp_leave_err_thres**2
|
148
|
+
)
|
149
|
+
|
150
|
+
# Check if there's a significant temperature drop across the cooling coil
|
151
|
+
temp_drop = df[clg_coil_enter_temp_col] - df[clg_coil_leave_temp_col]
|
152
|
+
significant_temp_drop = temp_drop > temp_drop_threshold
|
153
|
+
|
154
|
+
# Check operating modes:
|
155
|
+
# OS1: Heating mode (HTG > 0, CLG = 0, ECO = MIN_OA)
|
156
|
+
os1_mode = (
|
157
|
+
(df[heating_sig_col] > 0.0)
|
158
|
+
& (df[cooling_sig_col] == 0.0)
|
159
|
+
& (df[economizer_sig_col] <= ahu_min_oa_dpr)
|
160
|
+
)
|
161
|
+
|
162
|
+
# OS2: Economizer mode (HTG = 0, CLG = 0, ECO > MIN_OA)
|
163
|
+
os2_mode = (
|
164
|
+
(df[heating_sig_col] == 0.0)
|
165
|
+
& (df[cooling_sig_col] == 0.0)
|
166
|
+
& (df[economizer_sig_col] > ahu_min_oa_dpr)
|
167
|
+
)
|
168
|
+
|
169
|
+
# Combine conditions:
|
170
|
+
# Fault occurs when there's a significant temperature drop across an inactive cooling coil
|
171
|
+
# in either OS1 (heating) or OS2 (economizer) mode
|
172
|
+
combined_check = significant_temp_drop & (os1_mode | os2_mode)
|
173
|
+
|
174
|
+
# Set fault flag
|
175
|
+
self._set_fault_flag(df, combined_check, "fc14_flag")
|
176
|
+
|
177
|
+
return df
|
@@ -0,0 +1,140 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
|
3
|
+
from open_fdd.core.base_fault import BaseFaultCondition
|
4
|
+
from open_fdd.core.components import FaultInputColumn, InstanceAttribute
|
5
|
+
from open_fdd.core.exceptions import InvalidParameterError
|
6
|
+
from open_fdd.core.mixins import FaultConditionMixin
|
7
|
+
|
8
|
+
INPUT_COLS = [
|
9
|
+
FaultInputColumn(
|
10
|
+
name="sat_setpoint_col",
|
11
|
+
constant_form="SAT_SETPOINT_COL",
|
12
|
+
description="Supply air temperature setpoint",
|
13
|
+
unit="°F",
|
14
|
+
required=True,
|
15
|
+
type=float,
|
16
|
+
),
|
17
|
+
FaultInputColumn(
|
18
|
+
name="oat_col",
|
19
|
+
constant_form="OAT_COL",
|
20
|
+
description="Outside air temperature",
|
21
|
+
unit="°F",
|
22
|
+
required=True,
|
23
|
+
type=float,
|
24
|
+
),
|
25
|
+
FaultInputColumn(
|
26
|
+
name="cooling_sig_col",
|
27
|
+
constant_form="COOLING_SIG_COL",
|
28
|
+
description="Cooling signal",
|
29
|
+
unit="%",
|
30
|
+
required=True,
|
31
|
+
type=float,
|
32
|
+
),
|
33
|
+
FaultInputColumn(
|
34
|
+
name="economizer_sig_col",
|
35
|
+
constant_form="ECONOMIZER_SIG_COL",
|
36
|
+
description="Economizer signal",
|
37
|
+
unit="%",
|
38
|
+
required=True,
|
39
|
+
type=float,
|
40
|
+
),
|
41
|
+
]
|
42
|
+
|
43
|
+
FAULT_PARAMS = [
|
44
|
+
InstanceAttribute(
|
45
|
+
name="delta_t_supply_fan",
|
46
|
+
constant_form="DELTA_T_SUPPLY_FAN",
|
47
|
+
description="Temperature rise across supply fan",
|
48
|
+
unit="°F",
|
49
|
+
type=float,
|
50
|
+
range=(0.0, 5.0),
|
51
|
+
),
|
52
|
+
InstanceAttribute(
|
53
|
+
name="outdoor_degf_err_thres",
|
54
|
+
constant_form="OUTDOOR_DEGF_ERR_THRES",
|
55
|
+
description="Outdoor air temperature error threshold",
|
56
|
+
unit="°F",
|
57
|
+
type=float,
|
58
|
+
range=(0.0, 10.0),
|
59
|
+
),
|
60
|
+
InstanceAttribute(
|
61
|
+
name="supply_degf_err_thres",
|
62
|
+
constant_form="SUPPLY_DEGF_ERR_THRES",
|
63
|
+
description="Supply air temperature error threshold",
|
64
|
+
unit="°F",
|
65
|
+
type=float,
|
66
|
+
range=(0.0, 10.0),
|
67
|
+
),
|
68
|
+
InstanceAttribute(
|
69
|
+
name="ahu_min_oa_dpr",
|
70
|
+
constant_form="AHU_MIN_OA_DPR",
|
71
|
+
description="Minimum outdoor air damper position",
|
72
|
+
unit="fraction",
|
73
|
+
type=float,
|
74
|
+
range=(0.0, 1.0),
|
75
|
+
),
|
76
|
+
]
|
77
|
+
|
78
|
+
|
79
|
+
class FaultConditionNine(BaseFaultCondition, FaultConditionMixin):
|
80
|
+
"""Class provides the definitions for Fault Condition 9.
|
81
|
+
Outside air temperature too high in free cooling without
|
82
|
+
additional mechanical cooling in economizer mode.
|
83
|
+
|
84
|
+
py -3.12 -m pytest open_fdd/tests/ahu/test_ahu_fc9.py -rP -s
|
85
|
+
"""
|
86
|
+
|
87
|
+
input_columns = INPUT_COLS
|
88
|
+
fault_params = FAULT_PARAMS
|
89
|
+
equation_string = (
|
90
|
+
"fc9_flag = 1 if OAT > (SATSP - ΔT_fan + εSAT) "
|
91
|
+
"in free cooling mode for N consecutive values else 0 \n"
|
92
|
+
)
|
93
|
+
description_string = (
|
94
|
+
"Fault Condition 9: Outside air temperature too high in free cooling mode "
|
95
|
+
"without additional mechanical cooling in economizer mode \n"
|
96
|
+
)
|
97
|
+
error_string = "One or more required columns are missing or None \n"
|
98
|
+
|
99
|
+
@FaultConditionMixin._handle_errors
|
100
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
101
|
+
"""Apply the fault condition to the DataFrame."""
|
102
|
+
# Apply common checks
|
103
|
+
self._apply_common_checks(df)
|
104
|
+
|
105
|
+
# Get column values using accessor methods
|
106
|
+
oat_col = self.get_input_column("oat_col")
|
107
|
+
sat_setpoint_col = self.get_input_column("sat_setpoint_col")
|
108
|
+
economizer_sig_col = self.get_input_column("economizer_sig_col")
|
109
|
+
cooling_sig_col = self.get_input_column("cooling_sig_col")
|
110
|
+
|
111
|
+
# Get parameter values using accessor methods
|
112
|
+
outdoor_degf_err_thres = self.get_param("outdoor_degf_err_thres")
|
113
|
+
delta_t_supply_fan = self.get_param("delta_t_supply_fan")
|
114
|
+
supply_degf_err_thres = self.get_param("supply_degf_err_thres")
|
115
|
+
ahu_min_oa_dpr = self.get_param("ahu_min_oa_dpr")
|
116
|
+
|
117
|
+
# Check analog outputs [data with units of %] are floats only
|
118
|
+
columns_to_check = [
|
119
|
+
economizer_sig_col,
|
120
|
+
cooling_sig_col,
|
121
|
+
]
|
122
|
+
self._apply_analog_checks(df, columns_to_check, check_greater_than_one=True)
|
123
|
+
|
124
|
+
# Perform calculations
|
125
|
+
oat_minus_oaterror = df[oat_col] - outdoor_degf_err_thres
|
126
|
+
satsp_delta_saterr = (
|
127
|
+
df[sat_setpoint_col] - delta_t_supply_fan + supply_degf_err_thres
|
128
|
+
)
|
129
|
+
|
130
|
+
combined_check = (
|
131
|
+
(oat_minus_oaterror > satsp_delta_saterr)
|
132
|
+
# verify AHU is in OS2 only free cooling mode
|
133
|
+
& (df[economizer_sig_col] > ahu_min_oa_dpr)
|
134
|
+
& (df[cooling_sig_col] < 0.1)
|
135
|
+
)
|
136
|
+
|
137
|
+
# Set fault flag
|
138
|
+
self._set_fault_flag(df, combined_check, "fc9_flag")
|
139
|
+
|
140
|
+
return df
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
|
3
|
+
from open_fdd.core.base_fault import BaseFaultCondition
|
4
|
+
from open_fdd.core.components import FaultInputColumn, InstanceAttribute
|
5
|
+
from open_fdd.core.mixins import FaultConditionMixin
|
6
|
+
|
7
|
+
INPUT_COLS = [
|
8
|
+
FaultInputColumn(
|
9
|
+
name="duct_static_col",
|
10
|
+
constant_form="DUCT_STATIC_COL",
|
11
|
+
description="Duct static pressure",
|
12
|
+
unit="inches of water",
|
13
|
+
required=True,
|
14
|
+
type=float,
|
15
|
+
),
|
16
|
+
FaultInputColumn(
|
17
|
+
name="supply_vfd_speed_col",
|
18
|
+
constant_form="SUPPLY_VFD_SPEED_COL",
|
19
|
+
description="Supply fan VFD speed",
|
20
|
+
unit="%",
|
21
|
+
required=True,
|
22
|
+
type=float,
|
23
|
+
),
|
24
|
+
FaultInputColumn(
|
25
|
+
name="duct_static_setpoint_col",
|
26
|
+
constant_form="DUCT_STATIC_SETPOINT_COL",
|
27
|
+
description="Duct static pressure setpoint",
|
28
|
+
unit="inches of water",
|
29
|
+
required=True,
|
30
|
+
type=float,
|
31
|
+
),
|
32
|
+
]
|
33
|
+
|
34
|
+
FAULT_PARAMS = [
|
35
|
+
InstanceAttribute(
|
36
|
+
name="duct_static_inches_err_thres",
|
37
|
+
constant_form="DUCT_STATIC_INCHES_ERR_THRES",
|
38
|
+
description="Duct static pressure error threshold",
|
39
|
+
unit="inches of water",
|
40
|
+
type=float,
|
41
|
+
range=(0.0, 1.0),
|
42
|
+
),
|
43
|
+
InstanceAttribute(
|
44
|
+
name="vfd_speed_percent_max",
|
45
|
+
constant_form="VFD_SPEED_PERCENT_MAX",
|
46
|
+
description="Maximum VFD speed percentage",
|
47
|
+
unit="%",
|
48
|
+
type=float,
|
49
|
+
range=(0.0, 100.0),
|
50
|
+
),
|
51
|
+
InstanceAttribute(
|
52
|
+
name="vfd_speed_percent_err_thres",
|
53
|
+
constant_form="VFD_SPEED_PERCENT_ERR_THRES",
|
54
|
+
description="VFD speed error threshold",
|
55
|
+
unit="%",
|
56
|
+
type=float,
|
57
|
+
range=(0.0, 100.0),
|
58
|
+
),
|
59
|
+
]
|
60
|
+
|
61
|
+
|
62
|
+
class FaultConditionOne(BaseFaultCondition, FaultConditionMixin):
|
63
|
+
"""Class provides the definitions for Fault Condition 1.
|
64
|
+
AHU low duct static pressure fan fault.
|
65
|
+
|
66
|
+
py -3.12 -m pytest open_fdd/tests/ahu/test_ahu_fc1.py -rP -s
|
67
|
+
"""
|
68
|
+
|
69
|
+
input_columns = INPUT_COLS
|
70
|
+
fault_params = FAULT_PARAMS
|
71
|
+
equation_string = "fc1_flag = 1 if (DP < DPSP - εDP) and (VFDSPD >= VFDSPD_max - εVFDSPD) for N consecutive values else 0 \n"
|
72
|
+
description_string = (
|
73
|
+
"Fault Condition 1: Duct static too low at fan at full speed \n"
|
74
|
+
)
|
75
|
+
|
76
|
+
error_string = "One or more required columns are missing or None \n"
|
77
|
+
|
78
|
+
@FaultConditionMixin._handle_errors
|
79
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
80
|
+
self._apply_common_checks(df)
|
81
|
+
|
82
|
+
# Get column values using accessor methods
|
83
|
+
supply_vfd_speed_col = self.get_input_column("supply_vfd_speed_col")
|
84
|
+
duct_static_col = self.get_input_column("duct_static_col")
|
85
|
+
duct_static_setpoint_col = self.get_input_column("duct_static_setpoint_col")
|
86
|
+
|
87
|
+
# Get parameter values using accessor methods
|
88
|
+
vfd_speed_percent_max = self.get_param("vfd_speed_percent_max")
|
89
|
+
vfd_speed_percent_err_thres = self.get_param("vfd_speed_percent_err_thres")
|
90
|
+
duct_static_inches_err_thres = self.get_param("duct_static_inches_err_thres")
|
91
|
+
|
92
|
+
self._apply_analog_checks(
|
93
|
+
df, [supply_vfd_speed_col], check_greater_than_one=True
|
94
|
+
)
|
95
|
+
|
96
|
+
# Convert VFD speed from percentage to fraction if needed
|
97
|
+
if (df[supply_vfd_speed_col] > 1.0).any():
|
98
|
+
df[supply_vfd_speed_col] = df[supply_vfd_speed_col] / 100.0
|
99
|
+
|
100
|
+
# Convert thresholds from percentage to fraction
|
101
|
+
vfd_speed_max = vfd_speed_percent_max / 100.0
|
102
|
+
vfd_speed_err_thres = vfd_speed_percent_err_thres / 100.0
|
103
|
+
|
104
|
+
# Specific checks
|
105
|
+
static_check = (
|
106
|
+
df[duct_static_col]
|
107
|
+
< df[duct_static_setpoint_col] - duct_static_inches_err_thres
|
108
|
+
)
|
109
|
+
fan_check = df[supply_vfd_speed_col] >= vfd_speed_max - vfd_speed_err_thres
|
110
|
+
combined_check = static_check & fan_check
|
111
|
+
|
112
|
+
self._set_fault_flag(df, combined_check, "fc1_flag")
|
113
|
+
return df
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
|
3
|
+
from open_fdd.core.base_fault import BaseFaultCondition
|
4
|
+
from open_fdd.core.components import FaultInputColumn, InstanceAttribute
|
5
|
+
from open_fdd.core.exceptions import InvalidParameterError, MissingColumnError
|
6
|
+
from open_fdd.core.mixins import FaultConditionMixin
|
7
|
+
|
8
|
+
INPUT_COLS = [
|
9
|
+
FaultInputColumn(
|
10
|
+
name="sat_col",
|
11
|
+
constant_form="SAT_COL",
|
12
|
+
description="Supply air temperature",
|
13
|
+
unit="°F",
|
14
|
+
required=True,
|
15
|
+
type=float,
|
16
|
+
),
|
17
|
+
FaultInputColumn(
|
18
|
+
name="sat_setpoint_col",
|
19
|
+
constant_form="SAT_SETPOINT_COL",
|
20
|
+
description="Supply air temperature setpoint",
|
21
|
+
unit="°F",
|
22
|
+
required=True,
|
23
|
+
type=float,
|
24
|
+
),
|
25
|
+
FaultInputColumn(
|
26
|
+
name="heating_sig_col",
|
27
|
+
constant_form="HEATING_SIG_COL",
|
28
|
+
description="Heating signal",
|
29
|
+
unit="%",
|
30
|
+
required=True,
|
31
|
+
type=float,
|
32
|
+
),
|
33
|
+
FaultInputColumn(
|
34
|
+
name="supply_vfd_speed_col",
|
35
|
+
constant_form="SUPPLY_VFD_SPEED_COL",
|
36
|
+
description="Supply fan VFD speed",
|
37
|
+
unit="%",
|
38
|
+
required=True,
|
39
|
+
type=float,
|
40
|
+
),
|
41
|
+
]
|
42
|
+
|
43
|
+
FAULT_PARAMS = [
|
44
|
+
InstanceAttribute(
|
45
|
+
name="supply_degf_err_thres",
|
46
|
+
constant_form="SUPPLY_DEGF_ERR_THRES",
|
47
|
+
description="Supply air temperature error threshold",
|
48
|
+
unit="°F",
|
49
|
+
type=float,
|
50
|
+
range=(0.0, 10.0),
|
51
|
+
),
|
52
|
+
]
|
53
|
+
|
54
|
+
|
55
|
+
class FaultConditionSeven(BaseFaultCondition, FaultConditionMixin):
|
56
|
+
"""Class provides the definitions for Fault Condition 7.
|
57
|
+
Very similar to FC 13 but uses heating valve.
|
58
|
+
Supply air temperature too low in full heating.
|
59
|
+
|
60
|
+
py -3.12 -m pytest open_fdd/tests/ahu/test_ahu_fc7.py -rP -s
|
61
|
+
"""
|
62
|
+
|
63
|
+
input_columns = INPUT_COLS
|
64
|
+
fault_params = FAULT_PARAMS
|
65
|
+
equation_string = (
|
66
|
+
"fc7_flag = 1 if SAT < (SATSP - εSAT) in full heating mode "
|
67
|
+
"and VFD speed > 0 for N consecutive values else 0 \n"
|
68
|
+
)
|
69
|
+
description_string = (
|
70
|
+
"Fault Condition 7: Supply air temperature too low in full heating mode "
|
71
|
+
"with heating valve fully open \n"
|
72
|
+
)
|
73
|
+
error_string = "One or more required columns are missing or None \n"
|
74
|
+
|
75
|
+
@FaultConditionMixin._handle_errors
|
76
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
77
|
+
"""Apply the fault condition to the DataFrame."""
|
78
|
+
# Apply common checks
|
79
|
+
self._apply_common_checks(df)
|
80
|
+
|
81
|
+
# Get column values using accessor methods
|
82
|
+
sat_col = self.get_input_column("sat_col")
|
83
|
+
sat_setpoint_col = self.get_input_column("sat_setpoint_col")
|
84
|
+
supply_vfd_speed_col = self.get_input_column("supply_vfd_speed_col")
|
85
|
+
heating_sig_col = self.get_input_column("heating_sig_col")
|
86
|
+
|
87
|
+
# Get parameter values using accessor methods
|
88
|
+
supply_degf_err_thres = self.get_param("supply_degf_err_thres")
|
89
|
+
|
90
|
+
# Check analog outputs [data with units of %] are floats only
|
91
|
+
columns_to_check = [supply_vfd_speed_col, heating_sig_col]
|
92
|
+
self._apply_analog_checks(df, columns_to_check, check_greater_than_one=True)
|
93
|
+
|
94
|
+
# Perform checks
|
95
|
+
sat_check = df[sat_setpoint_col] - supply_degf_err_thres
|
96
|
+
|
97
|
+
combined_check = (
|
98
|
+
(df[sat_col] < sat_check)
|
99
|
+
& (df[heating_sig_col] > 0.9)
|
100
|
+
& (df[supply_vfd_speed_col] > 0)
|
101
|
+
)
|
102
|
+
|
103
|
+
# Set fault flag
|
104
|
+
self._set_fault_flag(df, combined_check, "fc7_flag")
|
105
|
+
|
106
|
+
return df
|