open-fdd 0.1.0__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/__init__.py +39 -0
- open_fdd/air_handling_unit/__init__.py +0 -0
- open_fdd/air_handling_unit/faults/__init__.py +0 -0
- open_fdd/air_handling_unit/faults/fault_condition.py +49 -0
- open_fdd/air_handling_unit/faults/fault_condition_eight.py +67 -0
- open_fdd/air_handling_unit/faults/fault_condition_eleven.py +68 -0
- open_fdd/air_handling_unit/faults/fault_condition_fifteen.py +90 -0
- open_fdd/air_handling_unit/faults/fault_condition_five.py +68 -0
- open_fdd/air_handling_unit/faults/fault_condition_four.py +93 -0
- open_fdd/air_handling_unit/faults/fault_condition_fourteen.py +80 -0
- open_fdd/air_handling_unit/faults/fault_condition_nine.py +68 -0
- open_fdd/air_handling_unit/faults/fault_condition_one.py +60 -0
- open_fdd/air_handling_unit/faults/fault_condition_seven.py +55 -0
- open_fdd/air_handling_unit/faults/fault_condition_six.py +120 -0
- open_fdd/air_handling_unit/faults/fault_condition_ten.py +62 -0
- open_fdd/air_handling_unit/faults/fault_condition_thirteen.py +66 -0
- open_fdd/air_handling_unit/faults/fault_condition_three.py +58 -0
- open_fdd/air_handling_unit/faults/fault_condition_twelve.py +71 -0
- open_fdd/air_handling_unit/faults/fault_condition_two.py +61 -0
- open_fdd/air_handling_unit/faults/helper_utils.py +191 -0
- open_fdd/air_handling_unit/faults/shared_utils.py +75 -0
- open_fdd/air_handling_unit/reports/__init__.py +0 -0
- open_fdd/air_handling_unit/reports/report_fc1.py +115 -0
- open_fdd/air_handling_unit/reports/report_fc10.py +126 -0
- open_fdd/air_handling_unit/reports/report_fc11.py +128 -0
- open_fdd/air_handling_unit/reports/report_fc12.py +126 -0
- open_fdd/air_handling_unit/reports/report_fc13.py +126 -0
- open_fdd/air_handling_unit/reports/report_fc14.py +124 -0
- open_fdd/air_handling_unit/reports/report_fc15.py +124 -0
- open_fdd/air_handling_unit/reports/report_fc2.py +119 -0
- open_fdd/air_handling_unit/reports/report_fc3.py +119 -0
- open_fdd/air_handling_unit/reports/report_fc4.py +148 -0
- open_fdd/air_handling_unit/reports/report_fc5.py +132 -0
- open_fdd/air_handling_unit/reports/report_fc6.py +156 -0
- open_fdd/air_handling_unit/reports/report_fc7.py +124 -0
- open_fdd/air_handling_unit/reports/report_fc8.py +118 -0
- open_fdd/air_handling_unit/reports/report_fc9.py +120 -0
- open_fdd/tests/__init__.py +0 -0
- open_fdd/tests/ahu/__init__.py +0 -0
- open_fdd/tests/ahu/test_ahu_fc1.py +159 -0
- open_fdd/tests/ahu/test_ahu_fc10.py +132 -0
- open_fdd/tests/ahu/test_ahu_fc11.py +136 -0
- open_fdd/tests/ahu/test_ahu_fc12.py +167 -0
- open_fdd/tests/ahu/test_ahu_fc13.py +163 -0
- open_fdd/tests/ahu/test_ahu_fc14.py +197 -0
- open_fdd/tests/ahu/test_ahu_fc15.py +183 -0
- open_fdd/tests/ahu/test_ahu_fc2.py +132 -0
- open_fdd/tests/ahu/test_ahu_fc3.py +131 -0
- open_fdd/tests/ahu/test_ahu_fc4.py +200 -0
- open_fdd/tests/ahu/test_ahu_fc5.py +180 -0
- open_fdd/tests/ahu/test_ahu_fc6.py +246 -0
- open_fdd/tests/ahu/test_ahu_fc7.py +71 -0
- open_fdd/tests/ahu/test_ahu_fc8.py +131 -0
- open_fdd/tests/ahu/test_ahu_fc9.py +136 -0
- open_fdd-0.1.0.dist-info/LICENSE +21 -0
- open_fdd-0.1.0.dist-info/METADATA +65 -0
- open_fdd-0.1.0.dist-info/RECORD +59 -0
- open_fdd-0.1.0.dist-info/WHEEL +5 -0
- open_fdd-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
from open_fdd.air_handling_unit.faults.fault_condition import FaultCondition
|
3
|
+
import sys
|
4
|
+
|
5
|
+
|
6
|
+
class FaultConditionOne(FaultCondition):
|
7
|
+
"""Class provides the definitions for Fault Condition 1.
|
8
|
+
AHU low duct static pressure fan fault.
|
9
|
+
"""
|
10
|
+
|
11
|
+
def __init__(self, dict_):
|
12
|
+
"""
|
13
|
+
:param dict_:
|
14
|
+
"""
|
15
|
+
self.vfd_speed_percent_err_thres = float
|
16
|
+
self.vfd_speed_percent_max = float
|
17
|
+
self.duct_static_inches_err_thres = float
|
18
|
+
self.duct_static_col = str
|
19
|
+
self.supply_vfd_speed_col = str
|
20
|
+
self.duct_static_setpoint_col = str
|
21
|
+
self.troubleshoot_mode = bool # default should be False
|
22
|
+
self.rolling_window_size = int
|
23
|
+
|
24
|
+
self.set_attributes(dict_)
|
25
|
+
|
26
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
27
|
+
if self.troubleshoot_mode:
|
28
|
+
self.troubleshoot_cols(df)
|
29
|
+
|
30
|
+
# check analog outputs [data with units of %] are floats only
|
31
|
+
columns_to_check = [self.supply_vfd_speed_col]
|
32
|
+
self.check_analog_pct(df, columns_to_check)
|
33
|
+
|
34
|
+
df["static_check_"] = (
|
35
|
+
df[self.duct_static_col]
|
36
|
+
< df[self.duct_static_setpoint_col] - self.duct_static_inches_err_thres
|
37
|
+
)
|
38
|
+
df["fan_check_"] = (
|
39
|
+
df[self.supply_vfd_speed_col]
|
40
|
+
>= self.vfd_speed_percent_max - self.vfd_speed_percent_err_thres
|
41
|
+
)
|
42
|
+
|
43
|
+
# Combined condition check
|
44
|
+
df["combined_check"] = df["static_check_"] & df["fan_check_"]
|
45
|
+
|
46
|
+
# Rolling sum to count consecutive trues
|
47
|
+
rolling_sum = (
|
48
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
49
|
+
)
|
50
|
+
# Set flag to 1 if rolling sum equals the window size
|
51
|
+
df["fc1_flag"] = (rolling_sum == self.rolling_window_size).astype(int)
|
52
|
+
|
53
|
+
if self.troubleshoot_mode:
|
54
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
55
|
+
sys.stdout.flush()
|
56
|
+
del df["static_check_"]
|
57
|
+
del df["fan_check_"]
|
58
|
+
del df["combined_check"]
|
59
|
+
|
60
|
+
return df
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
import numpy as np
|
3
|
+
from open_fdd.air_handling_unit.faults.fault_condition import FaultCondition
|
4
|
+
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
|
+
import sys
|
6
|
+
|
7
|
+
|
8
|
+
class FaultConditionSeven(FaultCondition):
|
9
|
+
"""Class provides the definitions for Fault Condition 7.
|
10
|
+
Very similar to FC 13 but uses heating valve.
|
11
|
+
Supply air temperature too low in full heating.
|
12
|
+
"""
|
13
|
+
|
14
|
+
def __init__(self, dict_):
|
15
|
+
self.supply_degf_err_thres = float
|
16
|
+
self.sat_col = str
|
17
|
+
self.sat_setpoint_col = str
|
18
|
+
self.heating_sig_col = str
|
19
|
+
self.supply_vfd_speed_col = str
|
20
|
+
self.troubleshoot_mode = bool # default to False
|
21
|
+
self.rolling_window_size = int
|
22
|
+
|
23
|
+
self.set_attributes(dict_)
|
24
|
+
|
25
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
26
|
+
if self.troubleshoot_mode:
|
27
|
+
self.troubleshoot_cols(df)
|
28
|
+
|
29
|
+
# Check analog outputs [data with units of %] are floats only
|
30
|
+
columns_to_check = [self.supply_vfd_speed_col, self.heating_sig_col]
|
31
|
+
self.check_analog_pct(df, columns_to_check)
|
32
|
+
|
33
|
+
# Fault condition-specific checks / flags
|
34
|
+
df["sat_check"] = df[self.sat_setpoint_col] - self.supply_degf_err_thres
|
35
|
+
|
36
|
+
df["combined_check"] = (
|
37
|
+
(df[self.sat_col] < df["sat_check"])
|
38
|
+
& (df[self.heating_sig_col] > 0.9)
|
39
|
+
& (df[self.supply_vfd_speed_col] > 0)
|
40
|
+
)
|
41
|
+
|
42
|
+
# Rolling sum to count consecutive trues
|
43
|
+
rolling_sum = (
|
44
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
45
|
+
)
|
46
|
+
# Set flag to 1 if rolling sum equals the window size
|
47
|
+
df["fc7_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
48
|
+
|
49
|
+
if self.troubleshoot_mode:
|
50
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
51
|
+
sys.stdout.flush()
|
52
|
+
del df["sat_check"]
|
53
|
+
del df["combined_check"]
|
54
|
+
|
55
|
+
return df
|
@@ -0,0 +1,120 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
import pandas.api.types as pdtypes
|
3
|
+
from open_fdd.air_handling_unit.faults.fault_condition import FaultCondition
|
4
|
+
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
|
+
import operator
|
6
|
+
import sys
|
7
|
+
|
8
|
+
|
9
|
+
class FaultConditionSix(FaultCondition):
|
10
|
+
"""Class provides the definitions for Fault Condition 6.
|
11
|
+
|
12
|
+
This fault related to knowing the design air flow for
|
13
|
+
ventilation AHU_MIN_CFM_DESIGN which comes from the
|
14
|
+
design mech engineered records where then the fault
|
15
|
+
tries to calculate that based on totalized measured
|
16
|
+
AHU air flow and outside air fraction calc from
|
17
|
+
AHU temp sensors. The fault could flag issues where
|
18
|
+
flow stations are either not in calibration, temp
|
19
|
+
sensors used in the OA frac calc, or possibly the AHU
|
20
|
+
not bringing in design air flow when not operating in
|
21
|
+
economizer free cooling modes. Troubleshoot by TAB tech
|
22
|
+
verifying flow sensor and temp sensor precisions from
|
23
|
+
3rd party sensing tools.
|
24
|
+
|
25
|
+
this fault is confusing if you want to play around
|
26
|
+
in py code sandbox try this:
|
27
|
+
https://gist.github.com/bbartling/e0fb8427b1e0d148a06e3f09121ed5dc#file-fc6-py
|
28
|
+
"""
|
29
|
+
|
30
|
+
def __init__(self, dict_):
|
31
|
+
self.airflow_err_thres = float
|
32
|
+
self.ahu_min_oa_cfm_design = float
|
33
|
+
self.outdoor_degf_err_thres = float
|
34
|
+
self.return_degf_err_thres = float
|
35
|
+
self.oat_rat_delta_min = float
|
36
|
+
self.ahu_min_oa_dpr = float
|
37
|
+
self.supply_fan_air_volume_col = str
|
38
|
+
self.mat_col = str
|
39
|
+
self.oat_col = str
|
40
|
+
self.rat_col = str
|
41
|
+
self.supply_vfd_speed_col = str
|
42
|
+
self.economizer_sig_col = str
|
43
|
+
self.heating_sig_col = str
|
44
|
+
self.cooling_sig_col = str
|
45
|
+
self.troubleshoot_mode = bool # default should be False
|
46
|
+
self.rolling_window_size = int
|
47
|
+
|
48
|
+
self.set_attributes(dict_)
|
49
|
+
|
50
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
51
|
+
if self.troubleshoot_mode:
|
52
|
+
self.troubleshoot_cols(df)
|
53
|
+
|
54
|
+
# check analog outputs [data with units of %] are floats only
|
55
|
+
columns_to_check = [
|
56
|
+
self.supply_vfd_speed_col,
|
57
|
+
self.economizer_sig_col,
|
58
|
+
self.heating_sig_col,
|
59
|
+
self.cooling_sig_col,
|
60
|
+
]
|
61
|
+
|
62
|
+
for col in columns_to_check:
|
63
|
+
self.check_analog_pct(df, [col])
|
64
|
+
|
65
|
+
# create helper columns
|
66
|
+
df["rat_minus_oat"] = abs(df[self.rat_col] - df[self.oat_col])
|
67
|
+
df["percent_oa_calc"] = (df[self.mat_col] - df[self.rat_col]) / (
|
68
|
+
df[self.oat_col] - df[self.rat_col]
|
69
|
+
)
|
70
|
+
|
71
|
+
# weed out any negative values
|
72
|
+
df["percent_oa_calc"] = df["percent_oa_calc"].apply(lambda x: x if x > 0 else 0)
|
73
|
+
|
74
|
+
df["perc_OAmin"] = (
|
75
|
+
self.ahu_min_oa_cfm_design / df[self.supply_fan_air_volume_col]
|
76
|
+
)
|
77
|
+
|
78
|
+
df["percent_oa_calc_minus_perc_OAmin"] = abs(
|
79
|
+
df["percent_oa_calc"] - df["perc_OAmin"]
|
80
|
+
)
|
81
|
+
|
82
|
+
df["combined_check"] = operator.or_(
|
83
|
+
# OS 1 htg mode
|
84
|
+
(
|
85
|
+
(df["rat_minus_oat"] >= self.oat_rat_delta_min)
|
86
|
+
& (df["percent_oa_calc_minus_perc_OAmin"] > self.airflow_err_thres)
|
87
|
+
)
|
88
|
+
# verify ahu is running in OS 1 htg mode in min OA
|
89
|
+
& (
|
90
|
+
(df[self.heating_sig_col] > 0.0) & (df[self.supply_vfd_speed_col] > 0.0)
|
91
|
+
), # OR
|
92
|
+
# OS 4 mech clg mode
|
93
|
+
(
|
94
|
+
(df["rat_minus_oat"] >= self.oat_rat_delta_min)
|
95
|
+
& (df["percent_oa_calc_minus_perc_OAmin"] > self.airflow_err_thres)
|
96
|
+
)
|
97
|
+
# verify ahu is running in OS 4 clg mode in min OA
|
98
|
+
& (df[self.heating_sig_col] == 0.0)
|
99
|
+
& (df[self.cooling_sig_col] > 0.0)
|
100
|
+
& (df[self.supply_vfd_speed_col] > 0.0)
|
101
|
+
& (df[self.economizer_sig_col] == self.ahu_min_oa_dpr),
|
102
|
+
)
|
103
|
+
|
104
|
+
# Rolling sum to count consecutive trues
|
105
|
+
rolling_sum = (
|
106
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
107
|
+
)
|
108
|
+
# Set flag to 1 if rolling sum equals the window size
|
109
|
+
df["fc6_flag"] = (rolling_sum == self.rolling_window_size).astype(int)
|
110
|
+
|
111
|
+
if self.troubleshoot_mode:
|
112
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
113
|
+
sys.stdout.flush()
|
114
|
+
del df["rat_minus_oat"]
|
115
|
+
del df["percent_oa_calc"]
|
116
|
+
del df["perc_OAmin"]
|
117
|
+
del df["percent_oa_calc_minus_perc_OAmin"]
|
118
|
+
del df["combined_check"]
|
119
|
+
|
120
|
+
return df
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
import numpy as np
|
3
|
+
from open_fdd.air_handling_unit.faults.fault_condition import FaultCondition
|
4
|
+
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
|
+
import sys
|
6
|
+
|
7
|
+
|
8
|
+
class FaultConditionTen(FaultCondition):
|
9
|
+
"""Class provides the definitions for Fault Condition 10.
|
10
|
+
Outdoor air temperature and mix air temperature should
|
11
|
+
be approx equal in economizer plus mech cooling mode.
|
12
|
+
"""
|
13
|
+
|
14
|
+
def __init__(self, dict_):
|
15
|
+
self.outdoor_degf_err_thres = float
|
16
|
+
self.mix_degf_err_thres = float
|
17
|
+
self.oat_col = str
|
18
|
+
self.mat_col = str
|
19
|
+
self.cooling_sig_col = str
|
20
|
+
self.economizer_sig_col = str
|
21
|
+
self.troubleshoot_mode = bool # default False,
|
22
|
+
self.rolling_window_size = int
|
23
|
+
|
24
|
+
self.set_attributes(dict_)
|
25
|
+
|
26
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
27
|
+
if self.troubleshoot_mode:
|
28
|
+
self.troubleshoot_cols(df)
|
29
|
+
|
30
|
+
# Check analog outputs [data with units of %] are floats only
|
31
|
+
columns_to_check = [
|
32
|
+
self.economizer_sig_col,
|
33
|
+
self.cooling_sig_col,
|
34
|
+
]
|
35
|
+
self.check_analog_pct(df, columns_to_check)
|
36
|
+
|
37
|
+
df["abs_mat_minus_oat"] = abs(df[self.mat_col] - df[self.oat_col])
|
38
|
+
df["mat_oat_sqrted"] = np.sqrt(
|
39
|
+
self.mix_degf_err_thres**2 + self.outdoor_degf_err_thres**2
|
40
|
+
)
|
41
|
+
|
42
|
+
df["combined_check"] = (
|
43
|
+
(df["abs_mat_minus_oat"] > df["mat_oat_sqrted"])
|
44
|
+
# verify ahu is running in OS 3 clg mode in min OA
|
45
|
+
& (df[self.cooling_sig_col] > 0.01)
|
46
|
+
& (df[self.economizer_sig_col] > 0.9)
|
47
|
+
)
|
48
|
+
|
49
|
+
# Rolling sum to count consecutive trues
|
50
|
+
rolling_sum = (
|
51
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
52
|
+
)
|
53
|
+
# Set flag to 1 if rolling sum equals the window size
|
54
|
+
df["fc10_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
55
|
+
|
56
|
+
if self.troubleshoot_mode:
|
57
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
58
|
+
del df["abs_mat_minus_oat"]
|
59
|
+
del df["mat_oat_sqrted"]
|
60
|
+
del df["combined_check"]
|
61
|
+
|
62
|
+
return df
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
import numpy as np
|
3
|
+
import operator
|
4
|
+
from open_fdd.air_handling_unit.faults.fault_condition import FaultCondition
|
5
|
+
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
6
|
+
import sys
|
7
|
+
|
8
|
+
|
9
|
+
class FaultConditionThirteen(FaultCondition):
|
10
|
+
"""Class provides the definitions for Fault Condition 13.
|
11
|
+
Supply air temperature too high in full cooling
|
12
|
+
in economizer plus mech cooling mode
|
13
|
+
"""
|
14
|
+
|
15
|
+
def __init__(self, dict_):
|
16
|
+
self.supply_degf_err_thres = float
|
17
|
+
self.ahu_min_oa_dpr = float
|
18
|
+
self.sat_col = str
|
19
|
+
self.sat_setpoint_col = str
|
20
|
+
self.cooling_sig_col = str
|
21
|
+
self.economizer_sig_col = str
|
22
|
+
self.troubleshoot_mode = bool # default False
|
23
|
+
self.rolling_window_size = int
|
24
|
+
|
25
|
+
self.set_attributes(dict_)
|
26
|
+
|
27
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
28
|
+
if self.troubleshoot_mode:
|
29
|
+
self.troubleshoot_cols(df)
|
30
|
+
|
31
|
+
# Check analog outputs [data with units of %] are floats only
|
32
|
+
columns_to_check = [
|
33
|
+
self.economizer_sig_col,
|
34
|
+
self.cooling_sig_col,
|
35
|
+
]
|
36
|
+
self.check_analog_pct(df, columns_to_check)
|
37
|
+
|
38
|
+
# Create helper columns
|
39
|
+
df["sat_greater_than_sp_calc"] = (
|
40
|
+
df[self.sat_col] > df[self.sat_setpoint_col] + self.supply_degf_err_thres
|
41
|
+
)
|
42
|
+
|
43
|
+
df["combined_check"] = operator.or_(
|
44
|
+
((df["sat_greater_than_sp_calc"]))
|
45
|
+
# OS4 AHU state clg @ min OA
|
46
|
+
& (df[self.cooling_sig_col] > 0.01)
|
47
|
+
& (df[self.economizer_sig_col] == self.ahu_min_oa_dpr), # OR
|
48
|
+
((df["sat_greater_than_sp_calc"]))
|
49
|
+
# verify ahu is running in OS 3 clg mode in 100 OA
|
50
|
+
& (df[self.cooling_sig_col] > 0.01) & (df[self.economizer_sig_col] > 0.9),
|
51
|
+
)
|
52
|
+
|
53
|
+
# Rolling sum to count consecutive trues
|
54
|
+
rolling_sum = (
|
55
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
56
|
+
)
|
57
|
+
# Set flag to 1 if rolling sum equals the window size
|
58
|
+
df["fc13_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
59
|
+
|
60
|
+
if self.troubleshoot_mode:
|
61
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
62
|
+
sys.stdout.flush()
|
63
|
+
del df["sat_greater_than_sp_calc"]
|
64
|
+
del df["combined_check"]
|
65
|
+
|
66
|
+
return df
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
import numpy as np
|
3
|
+
from open_fdd.air_handling_unit.faults.fault_condition import FaultCondition
|
4
|
+
import sys
|
5
|
+
|
6
|
+
|
7
|
+
class FaultConditionThree(FaultCondition):
|
8
|
+
"""Class provides the definitions for Fault Condition 3.
|
9
|
+
Mix temperature too high; should be between outside and return air.
|
10
|
+
"""
|
11
|
+
|
12
|
+
def __init__(self, dict_):
|
13
|
+
self.mix_degf_err_thres = float
|
14
|
+
self.return_degf_err_thres = float
|
15
|
+
self.outdoor_degf_err_thres = float
|
16
|
+
self.mat_col = str
|
17
|
+
self.rat_col = str
|
18
|
+
self.oat_col = str
|
19
|
+
self.supply_vfd_speed_col = str
|
20
|
+
self.troubleshoot_mode = bool # default to False
|
21
|
+
self.rolling_window_size = int
|
22
|
+
|
23
|
+
self.set_attributes(dict_)
|
24
|
+
|
25
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
26
|
+
if self.troubleshoot_mode:
|
27
|
+
self.troubleshoot_cols(df)
|
28
|
+
|
29
|
+
# Check analog outputs [data with units of %] are floats only
|
30
|
+
columns_to_check = [self.supply_vfd_speed_col]
|
31
|
+
self.check_analog_pct(df, columns_to_check)
|
32
|
+
|
33
|
+
# Fault condition-specific checks / flags
|
34
|
+
df["mat_check"] = df[self.mat_col] - self.mix_degf_err_thres
|
35
|
+
df["temp_min_check"] = np.maximum(
|
36
|
+
df[self.rat_col] + self.return_degf_err_thres,
|
37
|
+
df[self.oat_col] + self.outdoor_degf_err_thres,
|
38
|
+
)
|
39
|
+
|
40
|
+
df["combined_check"] = (df["mat_check"] > df["temp_min_check"]) & (
|
41
|
+
df[self.supply_vfd_speed_col] > 0.01
|
42
|
+
)
|
43
|
+
|
44
|
+
# Rolling sum to count consecutive trues
|
45
|
+
rolling_sum = (
|
46
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
47
|
+
)
|
48
|
+
# Set flag to 1 if rolling sum equals the window size
|
49
|
+
df["fc3_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
50
|
+
|
51
|
+
if self.troubleshoot_mode:
|
52
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
53
|
+
sys.stdout.flush()
|
54
|
+
del df["mat_check"]
|
55
|
+
del df["temp_min_check"]
|
56
|
+
del df["combined_check"]
|
57
|
+
|
58
|
+
return df
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
import numpy as np
|
3
|
+
import operator
|
4
|
+
from open_fdd.air_handling_unit.faults.fault_condition import FaultCondition
|
5
|
+
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
6
|
+
import sys
|
7
|
+
|
8
|
+
|
9
|
+
class FaultConditionTwelve(FaultCondition):
|
10
|
+
"""Class provides the definitions for Fault Condition 12.
|
11
|
+
Supply air temperature too high; should be less than
|
12
|
+
mix air temperature in economizer plus mech cooling mode.
|
13
|
+
"""
|
14
|
+
|
15
|
+
def __init__(self, dict_):
|
16
|
+
self.delta_t_supply_fan = float
|
17
|
+
self.mix_degf_err_thres = float
|
18
|
+
self.supply_degf_err_thres = float
|
19
|
+
self.ahu_min_oa_dpr = float
|
20
|
+
self.sat_col = str
|
21
|
+
self.mat_col = str
|
22
|
+
self.cooling_sig_col = str
|
23
|
+
self.economizer_sig_col = str
|
24
|
+
self.troubleshoot_mode = bool # default False
|
25
|
+
self.rolling_window_size = int
|
26
|
+
|
27
|
+
self.set_attributes(dict_)
|
28
|
+
|
29
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
30
|
+
if self.troubleshoot_mode:
|
31
|
+
self.troubleshoot_cols(df)
|
32
|
+
|
33
|
+
# Check analog outputs [data with units of %] are floats only
|
34
|
+
columns_to_check = [
|
35
|
+
self.economizer_sig_col,
|
36
|
+
self.cooling_sig_col,
|
37
|
+
]
|
38
|
+
self.check_analog_pct(df, columns_to_check)
|
39
|
+
|
40
|
+
# Create helper columns
|
41
|
+
df["sat_minus_saterr_delta_supply_fan"] = (
|
42
|
+
df[self.sat_col] - self.supply_degf_err_thres - self.delta_t_supply_fan
|
43
|
+
)
|
44
|
+
df["mat_plus_materr"] = df[self.mat_col] + self.mix_degf_err_thres
|
45
|
+
|
46
|
+
df["combined_check"] = operator.or_(
|
47
|
+
# OS4 AHU state clg @ min OA
|
48
|
+
(df["sat_minus_saterr_delta_supply_fan"] > df["mat_plus_materr"])
|
49
|
+
# verify AHU in OS4 mode
|
50
|
+
& (df[self.cooling_sig_col] > 0.01)
|
51
|
+
& (df[self.economizer_sig_col] == self.ahu_min_oa_dpr), # OR
|
52
|
+
(df["sat_minus_saterr_delta_supply_fan"] > df["mat_plus_materr"])
|
53
|
+
# verify ahu is running in OS 3 clg mode in 100 OA
|
54
|
+
& (df[self.cooling_sig_col] > 0.01) & (df[self.economizer_sig_col] > 0.9),
|
55
|
+
)
|
56
|
+
|
57
|
+
# Rolling sum to count consecutive trues
|
58
|
+
rolling_sum = (
|
59
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
60
|
+
)
|
61
|
+
# Set flag to 1 if rolling sum equals the window size
|
62
|
+
df["fc12_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
63
|
+
|
64
|
+
if self.troubleshoot_mode:
|
65
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
66
|
+
sys.stdout.flush()
|
67
|
+
del df["sat_minus_saterr_delta_supply_fan"]
|
68
|
+
del df["mat_plus_materr"]
|
69
|
+
del df["combined_check"]
|
70
|
+
|
71
|
+
return df
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
import numpy as np
|
3
|
+
from open_fdd.air_handling_unit.faults.fault_condition import FaultCondition
|
4
|
+
import sys
|
5
|
+
|
6
|
+
|
7
|
+
class FaultConditionTwo(FaultCondition):
|
8
|
+
"""Class provides the definitions for Fault Condition 2.
|
9
|
+
Mix temperature too low; should be between outside and return air.
|
10
|
+
"""
|
11
|
+
|
12
|
+
def __init__(self, dict_):
|
13
|
+
"""
|
14
|
+
:param dict_:
|
15
|
+
"""
|
16
|
+
self.mix_degf_err_thres = float
|
17
|
+
self.return_degf_err_thres = float
|
18
|
+
self.outdoor_degf_err_thres = float
|
19
|
+
self.mat_col = str
|
20
|
+
self.rat_col = str
|
21
|
+
self.oat_col = str
|
22
|
+
self.supply_vfd_speed_col = str
|
23
|
+
self.troubleshoot_mode = bool # default to False
|
24
|
+
self.rolling_window_size = int
|
25
|
+
|
26
|
+
self.set_attributes(dict_)
|
27
|
+
|
28
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
29
|
+
if self.troubleshoot_mode:
|
30
|
+
self.troubleshoot_cols(df)
|
31
|
+
|
32
|
+
# Check analog outputs [data with units of %] are floats only
|
33
|
+
columns_to_check = [self.supply_vfd_speed_col]
|
34
|
+
self.check_analog_pct(df, columns_to_check)
|
35
|
+
|
36
|
+
# Fault condition-specific checks / flags
|
37
|
+
df["mat_check"] = df[self.mat_col] + self.mix_degf_err_thres
|
38
|
+
df["temp_min_check"] = np.minimum(
|
39
|
+
df[self.rat_col] - self.return_degf_err_thres,
|
40
|
+
df[self.oat_col] - self.outdoor_degf_err_thres,
|
41
|
+
)
|
42
|
+
|
43
|
+
df["combined_check"] = (df["mat_check"] < df["temp_min_check"]) & (
|
44
|
+
df[self.supply_vfd_speed_col] > 0.01
|
45
|
+
)
|
46
|
+
|
47
|
+
# Rolling sum to count consecutive trues
|
48
|
+
rolling_sum = (
|
49
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
50
|
+
)
|
51
|
+
# Set flag to 1 if rolling sum equals the window size
|
52
|
+
df["fc2_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
53
|
+
|
54
|
+
if self.troubleshoot_mode:
|
55
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
56
|
+
sys.stdout.flush()
|
57
|
+
del df["mat_check"]
|
58
|
+
del df["temp_min_check"]
|
59
|
+
del df["combined_check"]
|
60
|
+
|
61
|
+
return df
|