open-fdd 0.1.7__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 +29 -2283
- 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/__init__.py +0 -0
- open_fdd/chiller_plant/faults/__init__.py +7 -0
- 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 +24 -33
- open_fdd/tests/ahu/test_ahu_fc12.py +56 -18
- open_fdd/tests/ahu/test_ahu_fc13.py +15 -8
- open_fdd/tests/ahu/test_ahu_fc14.py +11 -3
- open_fdd/tests/ahu/test_ahu_fc15.py +15 -4
- open_fdd/tests/ahu/test_ahu_fc16.py +15 -6
- 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/__init__.py +0 -0
- open_fdd/tests/chiller/test_chiller_fc1.py +122 -0
- open_fdd/tests/chiller/test_chiller_fc2.py +95 -0
- open_fdd-0.1.9.dist-info/METADATA +137 -0
- open_fdd-0.1.9.dist-info/RECORD +52 -0
- {open_fdd-0.1.7.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.7.dist-info/METADATA +0 -95
- open_fdd-0.1.7.dist-info/RECORD +0 -31
- {open_fdd-0.1.7.dist-info → open_fdd-0.1.9.dist-info/licenses}/LICENSE +0 -0
- {open_fdd-0.1.7.dist-info → open_fdd-0.1.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,112 @@
|
|
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.mixins import FaultConditionMixin
|
7
|
+
|
8
|
+
INPUT_COLS = [
|
9
|
+
FaultInputColumn(
|
10
|
+
name="mat_col",
|
11
|
+
constant_form="MAT_COL",
|
12
|
+
description="Mixed air temperature",
|
13
|
+
unit="°F",
|
14
|
+
required=True,
|
15
|
+
type=float,
|
16
|
+
),
|
17
|
+
FaultInputColumn(
|
18
|
+
name="rat_col",
|
19
|
+
constant_form="RAT_COL",
|
20
|
+
description="Return air temperature",
|
21
|
+
unit="°F",
|
22
|
+
required=True,
|
23
|
+
type=float,
|
24
|
+
),
|
25
|
+
FaultInputColumn(
|
26
|
+
name="oat_col",
|
27
|
+
constant_form="OAT_COL",
|
28
|
+
description="Outside air temperature",
|
29
|
+
unit="°F",
|
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="mix_degf_err_thres",
|
46
|
+
constant_form="MIX_DEGF_ERR_THRES",
|
47
|
+
description="Mixed air temperature error threshold",
|
48
|
+
unit="°F",
|
49
|
+
type=float,
|
50
|
+
range=(0.0, 10.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="return_degf_err_thres",
|
62
|
+
constant_form="RETURN_DEGF_ERR_THRES",
|
63
|
+
description="Return air temperature error threshold",
|
64
|
+
unit="°F",
|
65
|
+
type=float,
|
66
|
+
range=(0.0, 10.0),
|
67
|
+
),
|
68
|
+
]
|
69
|
+
|
70
|
+
|
71
|
+
class FaultConditionThree(BaseFaultCondition, FaultConditionMixin):
|
72
|
+
"""Class provides the definitions for Fault Condition 3.
|
73
|
+
Mix temperature too high; should be between outside and return air.
|
74
|
+
"""
|
75
|
+
|
76
|
+
input_columns = INPUT_COLS
|
77
|
+
fault_params = FAULT_PARAMS
|
78
|
+
equation_string = "fc3_flag = 1 if (MAT - εMAT > max(RAT + εRAT, OAT + εOAT)) and (VFDSPD > 0) for N consecutive values else 0 \n"
|
79
|
+
description_string = "Fault Condition 3: Mix temperature too high; should be between outside and return air \n"
|
80
|
+
error_string = "One or more required columns are missing or None \n"
|
81
|
+
|
82
|
+
@FaultConditionMixin._handle_errors
|
83
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
84
|
+
self._apply_common_checks(df)
|
85
|
+
|
86
|
+
# Get column values using accessor methods
|
87
|
+
supply_vfd_speed_col = self.get_input_column("supply_vfd_speed_col")
|
88
|
+
mat_col = self.get_input_column("mat_col")
|
89
|
+
rat_col = self.get_input_column("rat_col")
|
90
|
+
oat_col = self.get_input_column("oat_col")
|
91
|
+
|
92
|
+
# Get parameter values using accessor methods
|
93
|
+
mix_degf_err_thres = self.get_param("mix_degf_err_thres")
|
94
|
+
return_degf_err_thres = self.get_param("return_degf_err_thres")
|
95
|
+
outdoor_degf_err_thres = self.get_param("outdoor_degf_err_thres")
|
96
|
+
|
97
|
+
self._apply_analog_checks(
|
98
|
+
df, [supply_vfd_speed_col], check_greater_than_one=True
|
99
|
+
)
|
100
|
+
|
101
|
+
# Specific checks
|
102
|
+
mat_check = df[mat_col] - mix_degf_err_thres
|
103
|
+
temp_max_check = np.maximum(
|
104
|
+
df[rat_col] + return_degf_err_thres,
|
105
|
+
df[oat_col] + outdoor_degf_err_thres,
|
106
|
+
)
|
107
|
+
combined_check = (mat_check > temp_max_check) & (
|
108
|
+
df[supply_vfd_speed_col] > 0.01
|
109
|
+
)
|
110
|
+
|
111
|
+
self._set_fault_flag(df, combined_check, "fc3_flag")
|
112
|
+
return df
|
@@ -0,0 +1,164 @@
|
|
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="sat_col",
|
12
|
+
constant_form="SAT_COL",
|
13
|
+
description="Supply air temperature",
|
14
|
+
unit="°F",
|
15
|
+
required=True,
|
16
|
+
type=float,
|
17
|
+
),
|
18
|
+
FaultInputColumn(
|
19
|
+
name="mat_col",
|
20
|
+
constant_form="MAT_COL",
|
21
|
+
description="Mixed air temperature",
|
22
|
+
unit="°F",
|
23
|
+
required=True,
|
24
|
+
type=float,
|
25
|
+
),
|
26
|
+
FaultInputColumn(
|
27
|
+
name="oat_col",
|
28
|
+
constant_form="OAT_COL",
|
29
|
+
description="Outside air temperature",
|
30
|
+
unit="°F",
|
31
|
+
required=True,
|
32
|
+
type=float,
|
33
|
+
),
|
34
|
+
FaultInputColumn(
|
35
|
+
name="cooling_sig_col",
|
36
|
+
constant_form="COOLING_SIG_COL",
|
37
|
+
description="Cooling 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
|
+
]
|
51
|
+
|
52
|
+
FAULT_PARAMS = [
|
53
|
+
InstanceAttribute(
|
54
|
+
name="delta_t_supply_fan",
|
55
|
+
constant_form="DELTA_T_SUPPLY_FAN",
|
56
|
+
description="Temperature rise across supply fan",
|
57
|
+
unit="°F",
|
58
|
+
type=float,
|
59
|
+
),
|
60
|
+
InstanceAttribute(
|
61
|
+
name="mix_degf_err_thres",
|
62
|
+
constant_form="MIX_DEGF_ERR_THRES",
|
63
|
+
description="Mixed air temperature error threshold",
|
64
|
+
unit="°F",
|
65
|
+
type=float,
|
66
|
+
),
|
67
|
+
InstanceAttribute(
|
68
|
+
name="supply_degf_err_thres",
|
69
|
+
constant_form="SUPPLY_DEGF_ERR_THRES",
|
70
|
+
description="Supply air temperature error threshold",
|
71
|
+
unit="°F",
|
72
|
+
type=float,
|
73
|
+
),
|
74
|
+
InstanceAttribute(
|
75
|
+
name="outdoor_degf_err_thres",
|
76
|
+
constant_form="OUTDOOR_DEGF_ERR_THRES",
|
77
|
+
description="Outdoor air temperature error threshold",
|
78
|
+
unit="°F",
|
79
|
+
type=float,
|
80
|
+
),
|
81
|
+
InstanceAttribute(
|
82
|
+
name="ahu_min_oa_dpr",
|
83
|
+
constant_form="AHU_MIN_OA_DPR",
|
84
|
+
description="Minimum outdoor air damper position",
|
85
|
+
unit="fraction",
|
86
|
+
type=float,
|
87
|
+
),
|
88
|
+
]
|
89
|
+
|
90
|
+
|
91
|
+
class FaultConditionTwelve(BaseFaultCondition, FaultConditionMixin):
|
92
|
+
"""Class provides the definitions for Fault Condition 12.
|
93
|
+
Supply air temperature too high; should be less than mixed air temperature
|
94
|
+
in OS3 (economizer + mechanical cooling) and OS4 (mechanical cooling only) modes.
|
95
|
+
|
96
|
+
py -3.12 -m pytest open_fdd/tests/ahu/test_ahu_fc12.py -rP -s
|
97
|
+
"""
|
98
|
+
|
99
|
+
input_columns = INPUT_COLS
|
100
|
+
fault_params = FAULT_PARAMS
|
101
|
+
equation_string = (
|
102
|
+
"fc12_flag = 1 if (SAT > MAT + εSAT) and "
|
103
|
+
"((CLG > 0 and ECO > 0.9) or (CLG > 0.9 and ECO = MIN_OA)) "
|
104
|
+
"for N consecutive values else 0 \n"
|
105
|
+
)
|
106
|
+
description_string = (
|
107
|
+
"Fault Condition 12: Supply air temperature too high; should be less than "
|
108
|
+
"mixed air temperature in OS3 (economizer + mechanical cooling) and "
|
109
|
+
"OS4 (mechanical cooling only) modes \n"
|
110
|
+
)
|
111
|
+
error_string = "One or more required columns are missing or None \n"
|
112
|
+
|
113
|
+
@FaultConditionMixin._handle_errors
|
114
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
115
|
+
"""Apply the fault condition to the DataFrame."""
|
116
|
+
# Apply common checks
|
117
|
+
self._apply_common_checks(df)
|
118
|
+
|
119
|
+
# Get column values using accessor methods
|
120
|
+
sat_col = self.get_input_column("sat_col")
|
121
|
+
mat_col = self.get_input_column("mat_col")
|
122
|
+
oat_col = self.get_input_column("oat_col")
|
123
|
+
cooling_sig_col = self.get_input_column("cooling_sig_col")
|
124
|
+
economizer_sig_col = self.get_input_column("economizer_sig_col")
|
125
|
+
|
126
|
+
# Get parameter values using accessor methods
|
127
|
+
delta_t_supply_fan = self.get_param("delta_t_supply_fan")
|
128
|
+
mix_degf_err_thres = self.get_param("mix_degf_err_thres")
|
129
|
+
supply_degf_err_thres = self.get_param("supply_degf_err_thres")
|
130
|
+
outdoor_degf_err_thres = self.get_param("outdoor_degf_err_thres")
|
131
|
+
ahu_min_oa_dpr = self.get_param("ahu_min_oa_dpr")
|
132
|
+
|
133
|
+
# Check analog outputs [data with units of %] are floats only
|
134
|
+
columns_to_check = [
|
135
|
+
economizer_sig_col,
|
136
|
+
cooling_sig_col,
|
137
|
+
]
|
138
|
+
self._apply_analog_checks(df, columns_to_check, check_greater_than_one=True)
|
139
|
+
|
140
|
+
# Calculate the threshold for SAT vs MAT comparison
|
141
|
+
sat_mat_threshold = np.sqrt(supply_degf_err_thres**2 + mix_degf_err_thres**2)
|
142
|
+
|
143
|
+
# Check if SAT is too high compared to MAT (accounting for supply fan heat)
|
144
|
+
sat_too_high = df[sat_col] > (
|
145
|
+
df[mat_col] + sat_mat_threshold + delta_t_supply_fan
|
146
|
+
)
|
147
|
+
|
148
|
+
# Check operating modes:
|
149
|
+
# OS3: Economizer + mechanical cooling (ECO > 0.9 and CLG > 0)
|
150
|
+
os3_mode = (df[economizer_sig_col] > 0.9) & (df[cooling_sig_col] > 0)
|
151
|
+
|
152
|
+
# OS4: Mechanical cooling only (ECO = MIN_OA and CLG > 0.9)
|
153
|
+
os4_mode = (df[economizer_sig_col] <= ahu_min_oa_dpr) & (
|
154
|
+
df[cooling_sig_col] > 0.9
|
155
|
+
)
|
156
|
+
|
157
|
+
# Combine conditions:
|
158
|
+
# Fault occurs when SAT is too high in either OS3 or OS4 mode
|
159
|
+
combined_check = sat_too_high & (os3_mode | os4_mode)
|
160
|
+
|
161
|
+
# Set fault flag
|
162
|
+
self._set_fault_flag(df, combined_check, "fc12_flag")
|
163
|
+
|
164
|
+
return df
|
@@ -0,0 +1,112 @@
|
|
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.mixins import FaultConditionMixin
|
7
|
+
|
8
|
+
INPUT_COLS = [
|
9
|
+
FaultInputColumn(
|
10
|
+
name="mat_col",
|
11
|
+
constant_form="MAT_COL",
|
12
|
+
description="Mixed air temperature",
|
13
|
+
unit="°F",
|
14
|
+
required=True,
|
15
|
+
type=float,
|
16
|
+
),
|
17
|
+
FaultInputColumn(
|
18
|
+
name="rat_col",
|
19
|
+
constant_form="RAT_COL",
|
20
|
+
description="Return air temperature",
|
21
|
+
unit="°F",
|
22
|
+
required=True,
|
23
|
+
type=float,
|
24
|
+
),
|
25
|
+
FaultInputColumn(
|
26
|
+
name="oat_col",
|
27
|
+
constant_form="OAT_COL",
|
28
|
+
description="Outside air temperature",
|
29
|
+
unit="°F",
|
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="mix_degf_err_thres",
|
46
|
+
constant_form="MIX_DEGF_ERR_THRES",
|
47
|
+
description="Mixed air temperature error threshold",
|
48
|
+
unit="°F",
|
49
|
+
type=float,
|
50
|
+
range=(0.0, 10.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="return_degf_err_thres",
|
62
|
+
constant_form="RETURN_DEGF_ERR_THRES",
|
63
|
+
description="Return air temperature error threshold",
|
64
|
+
unit="°F",
|
65
|
+
type=float,
|
66
|
+
range=(0.0, 10.0),
|
67
|
+
),
|
68
|
+
]
|
69
|
+
|
70
|
+
|
71
|
+
class FaultConditionTwo(BaseFaultCondition, FaultConditionMixin):
|
72
|
+
"""Class provides the definitions for Fault Condition 2.
|
73
|
+
Mix temperature too low; should be between outside and return air.
|
74
|
+
"""
|
75
|
+
|
76
|
+
input_columns = INPUT_COLS
|
77
|
+
fault_params = FAULT_PARAMS
|
78
|
+
equation_string = "fc2_flag = 1 if (MAT - εMAT < min(RAT - εRAT, OAT - εOAT)) and (VFDSPD > 0) for N consecutive values else 0 \n"
|
79
|
+
description_string = "Fault Condition 2: Mix temperature too low; should be between outside and return air \n"
|
80
|
+
error_string = "One or more required columns are missing or None \n"
|
81
|
+
|
82
|
+
@FaultConditionMixin._handle_errors
|
83
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
84
|
+
self._apply_common_checks(df)
|
85
|
+
|
86
|
+
# Get column values using accessor methods
|
87
|
+
supply_vfd_speed_col = self.get_input_column("supply_vfd_speed_col")
|
88
|
+
mat_col = self.get_input_column("mat_col")
|
89
|
+
rat_col = self.get_input_column("rat_col")
|
90
|
+
oat_col = self.get_input_column("oat_col")
|
91
|
+
|
92
|
+
# Get parameter values using accessor methods
|
93
|
+
mix_degf_err_thres = self.get_param("mix_degf_err_thres")
|
94
|
+
return_degf_err_thres = self.get_param("return_degf_err_thres")
|
95
|
+
outdoor_degf_err_thres = self.get_param("outdoor_degf_err_thres")
|
96
|
+
|
97
|
+
self._apply_analog_checks(
|
98
|
+
df, [supply_vfd_speed_col], check_greater_than_one=True
|
99
|
+
)
|
100
|
+
|
101
|
+
# Specific checks
|
102
|
+
mat_check = df[mat_col] - mix_degf_err_thres
|
103
|
+
temp_min_check = np.minimum(
|
104
|
+
df[rat_col] - return_degf_err_thres,
|
105
|
+
df[oat_col] - outdoor_degf_err_thres,
|
106
|
+
)
|
107
|
+
combined_check = (mat_check < temp_min_check) & (
|
108
|
+
df[supply_vfd_speed_col] > 0.01
|
109
|
+
)
|
110
|
+
|
111
|
+
self._set_fault_flag(df, combined_check, "fc2_flag")
|
112
|
+
return df
|
@@ -1,7 +1,17 @@
|
|
1
1
|
import sys
|
2
|
-
|
2
|
+
|
3
3
|
import pandas as pd
|
4
4
|
|
5
|
+
from open_fdd.core.utils import (
|
6
|
+
apply_rolling_average_if_needed,
|
7
|
+
clean_nan_values,
|
8
|
+
convert_to_float,
|
9
|
+
float_int_check_err,
|
10
|
+
float_max_check_err,
|
11
|
+
is_float,
|
12
|
+
not_greater_than_one,
|
13
|
+
)
|
14
|
+
|
5
15
|
|
6
16
|
class HelperUtils:
|
7
17
|
|
@@ -12,25 +22,25 @@ class HelperUtils:
|
|
12
22
|
self.config_dict = config_dict
|
13
23
|
|
14
24
|
def clean_nan_values(self, df):
|
15
|
-
return
|
25
|
+
return clean_nan_values(df)
|
16
26
|
|
17
27
|
def float_int_check_err(self, col):
|
18
|
-
return
|
28
|
+
return float_int_check_err(col)
|
19
29
|
|
20
30
|
def float_max_check_err(self, col):
|
21
|
-
return
|
31
|
+
return float_max_check_err(col)
|
22
32
|
|
23
33
|
def isfloat(self, num):
|
24
|
-
return
|
34
|
+
return is_float(num)
|
25
35
|
|
26
36
|
def isLessThanOnePointOne(self, num):
|
27
|
-
return
|
37
|
+
return not_greater_than_one(num)
|
28
38
|
|
29
39
|
def convert_to_float(self, df, col):
|
30
|
-
return
|
40
|
+
return convert_to_float(df, col)
|
31
41
|
|
32
42
|
def apply_rolling_average_if_needed(self, df, freq="1min", rolling_window="5min"):
|
33
|
-
return
|
43
|
+
return apply_rolling_average_if_needed(df, freq, rolling_window)
|
34
44
|
|
35
45
|
def validate_config(self, required_columns):
|
36
46
|
"""
|
@@ -45,21 +55,21 @@ class HelperUtils:
|
|
45
55
|
self.set_config_dict(config_dict)
|
46
56
|
|
47
57
|
from open_fdd.air_handling_unit.faults import (
|
48
|
-
FaultConditionOne,
|
49
|
-
FaultConditionTwo,
|
50
|
-
FaultConditionThree,
|
51
|
-
FaultConditionFour,
|
52
|
-
FaultConditionFive,
|
53
|
-
FaultConditionSix,
|
54
|
-
FaultConditionSeven,
|
55
58
|
FaultConditionEight,
|
59
|
+
FaultConditionEleven,
|
60
|
+
FaultConditionFifteen,
|
61
|
+
FaultConditionFive,
|
62
|
+
FaultConditionFour,
|
63
|
+
FaultConditionFourteen,
|
56
64
|
FaultConditionNine,
|
65
|
+
FaultConditionOne,
|
66
|
+
FaultConditionSeven,
|
67
|
+
FaultConditionSix,
|
57
68
|
FaultConditionTen,
|
58
|
-
FaultConditionEleven,
|
59
|
-
FaultConditionTwelve,
|
60
69
|
FaultConditionThirteen,
|
61
|
-
|
62
|
-
|
70
|
+
FaultConditionThree,
|
71
|
+
FaultConditionTwelve,
|
72
|
+
FaultConditionTwo,
|
63
73
|
)
|
64
74
|
|
65
75
|
fault_counts = {}
|
@@ -1,9 +1,11 @@
|
|
1
|
+
import sys
|
2
|
+
|
1
3
|
import matplotlib.pyplot as plt
|
2
|
-
from open_fdd.air_handling_unit.reports.fault_report import BaseFaultReport
|
3
|
-
from open_fdd.air_handling_unit.faults import FaultConditionSixteen
|
4
|
-
import pandas as pd
|
5
4
|
import numpy as np
|
6
|
-
import
|
5
|
+
import pandas as pd
|
6
|
+
|
7
|
+
from open_fdd.air_handling_unit.faults import FaultConditionSixteen
|
8
|
+
from open_fdd.air_handling_unit.reports.fault_report import BaseFaultReport
|
7
9
|
|
8
10
|
|
9
11
|
class FaultCodeOneReport(BaseFaultReport):
|
File without changes
|
@@ -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="diff_pressure_col",
|
10
|
+
constant_form="DIFF_PRESSURE_COL",
|
11
|
+
description="Differential pressure",
|
12
|
+
unit="PSI",
|
13
|
+
required=True,
|
14
|
+
type=str,
|
15
|
+
),
|
16
|
+
FaultInputColumn(
|
17
|
+
name="pump_speed_col",
|
18
|
+
constant_form="PUMP_SPEED_COL",
|
19
|
+
description="Pump speed",
|
20
|
+
unit="%",
|
21
|
+
required=True,
|
22
|
+
type=str,
|
23
|
+
),
|
24
|
+
FaultInputColumn(
|
25
|
+
name="diff_pressure_setpoint_col",
|
26
|
+
constant_form="DIFF_PRESSURE_SETPOINT_COL",
|
27
|
+
description="Differential pressure setpoint",
|
28
|
+
unit="PSI",
|
29
|
+
required=True,
|
30
|
+
type=str,
|
31
|
+
),
|
32
|
+
]
|
33
|
+
|
34
|
+
FAULT_PARAMS = [
|
35
|
+
InstanceAttribute(
|
36
|
+
name="pump_speed_percent_err_thres",
|
37
|
+
constant_form="PUMP_SPEED_PERCENT_ERR_THRES",
|
38
|
+
description="Pump speed error threshold",
|
39
|
+
unit="%",
|
40
|
+
type=float,
|
41
|
+
range=(0.0, 1.0),
|
42
|
+
),
|
43
|
+
InstanceAttribute(
|
44
|
+
name="pump_speed_percent_max",
|
45
|
+
constant_form="PUMP_SPEED_PERCENT_MAX",
|
46
|
+
description="Maximum pump speed percentage",
|
47
|
+
unit="%",
|
48
|
+
type=float,
|
49
|
+
range=(0.0, 1.0),
|
50
|
+
),
|
51
|
+
InstanceAttribute(
|
52
|
+
name="diff_pressure_psi_err_thres",
|
53
|
+
constant_form="DIFF_PRESSURE_PSI_ERR_THRES",
|
54
|
+
description="Differential pressure error threshold",
|
55
|
+
unit="PSI",
|
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 for pumps.
|
64
|
+
Variable pump does not meet differential pressure setpoint.
|
65
|
+
|
66
|
+
py -3.12 -m pytest open_fdd/tests/chiller/test_chiller_fc1.py -rP -s
|
67
|
+
"""
|
68
|
+
|
69
|
+
input_columns = INPUT_COLS
|
70
|
+
fault_params = FAULT_PARAMS
|
71
|
+
equation_string = (
|
72
|
+
"fc_pump_flag = 1 if (DP < DPSP - εDP) and (PUMPSPD >= PUMPSPD_max - εPUMPSPD) "
|
73
|
+
"for N consecutive values else 0 \n"
|
74
|
+
)
|
75
|
+
description_string = (
|
76
|
+
"Fault Condition: Differential pressure too low with pump at full speed \n"
|
77
|
+
)
|
78
|
+
error_string = "One or more required columns are missing or None \n"
|
79
|
+
|
80
|
+
@FaultConditionMixin._handle_errors
|
81
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
82
|
+
self._apply_common_checks(df)
|
83
|
+
|
84
|
+
# Get column values using accessor methods
|
85
|
+
diff_pressure_col = self.get_input_column("diff_pressure_col")
|
86
|
+
pump_speed_col = self.get_input_column("pump_speed_col")
|
87
|
+
diff_pressure_setpoint_col = self.get_input_column("diff_pressure_setpoint_col")
|
88
|
+
|
89
|
+
# Get parameter values using accessor methods
|
90
|
+
pump_speed_percent_max = self.get_param("pump_speed_percent_max")
|
91
|
+
pump_speed_percent_err_thres = self.get_param("pump_speed_percent_err_thres")
|
92
|
+
diff_pressure_psi_err_thres = self.get_param("diff_pressure_psi_err_thres")
|
93
|
+
|
94
|
+
# Check analog outputs are floats only
|
95
|
+
columns_to_check = [pump_speed_col]
|
96
|
+
self._apply_analog_checks(df, columns_to_check)
|
97
|
+
|
98
|
+
# Perform checks
|
99
|
+
pressure_check = (
|
100
|
+
df[diff_pressure_col]
|
101
|
+
< df[diff_pressure_setpoint_col] - diff_pressure_psi_err_thres
|
102
|
+
)
|
103
|
+
pump_check = (
|
104
|
+
df[pump_speed_col] >= pump_speed_percent_max - pump_speed_percent_err_thres
|
105
|
+
)
|
106
|
+
|
107
|
+
# Combined condition check
|
108
|
+
combined_check = pressure_check & pump_check
|
109
|
+
|
110
|
+
# Set fault flag
|
111
|
+
self._set_fault_flag(df, combined_check, "fc_pump_flag")
|
112
|
+
|
113
|
+
return df
|