open-fdd 0.1.3__py3-none-any.whl → 0.1.5__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 +2253 -0
- open_fdd/air_handling_unit/faults/fault_condition.py +12 -10
- open_fdd/air_handling_unit/faults/fault_condition_eight.py +38 -2
- open_fdd/air_handling_unit/faults/fault_condition_eleven.py +38 -2
- open_fdd/air_handling_unit/faults/fault_condition_fifteen.py +38 -2
- open_fdd/air_handling_unit/faults/fault_condition_five.py +38 -2
- open_fdd/air_handling_unit/faults/fault_condition_four.py +34 -2
- open_fdd/air_handling_unit/faults/fault_condition_fourteen.py +38 -2
- open_fdd/air_handling_unit/faults/fault_condition_nine.py +38 -2
- open_fdd/air_handling_unit/faults/fault_condition_one.py +37 -6
- open_fdd/air_handling_unit/faults/fault_condition_seven.py +38 -2
- open_fdd/air_handling_unit/faults/fault_condition_six.py +39 -2
- open_fdd/air_handling_unit/faults/fault_condition_ten.py +39 -3
- open_fdd/air_handling_unit/faults/fault_condition_thirteen.py +38 -2
- open_fdd/air_handling_unit/faults/fault_condition_three.py +32 -2
- open_fdd/air_handling_unit/faults/fault_condition_twelve.py +40 -3
- open_fdd/air_handling_unit/faults/fault_condition_two.py +32 -2
- open_fdd/air_handling_unit/faults/helper_utils.py +1 -29
- open_fdd/air_handling_unit/reports/__init__.py +894 -0
- open_fdd/air_handling_unit/reports/fault_report.py +41 -0
- open_fdd/tests/ahu/test_ahu_fc1.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc10.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc11.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc12.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc13.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc14.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc15.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc2.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc3.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc4.py +199 -127
- open_fdd/tests/ahu/test_ahu_fc5.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc6.py +2 -2
- open_fdd/tests/ahu/test_ahu_fc7.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc8.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc9.py +1 -1
- {open_fdd-0.1.3.dist-info → open_fdd-0.1.5.dist-info}/METADATA +21 -14
- {open_fdd-0.1.3.dist-info → open_fdd-0.1.5.dist-info}/RECORD +40 -39
- {open_fdd-0.1.3.dist-info → open_fdd-0.1.5.dist-info}/LICENSE +0 -0
- {open_fdd-0.1.3.dist-info → open_fdd-0.1.5.dist-info}/WHEEL +0 -0
- {open_fdd-0.1.3.dist-info → open_fdd-0.1.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
import matplotlib.pyplot as plt
|
2
|
+
import pandas as pd
|
3
|
+
import numpy as np
|
4
|
+
import sys
|
5
|
+
|
6
|
+
|
7
|
+
class BaseFaultReport:
|
8
|
+
def __init__(self, config, fault_col):
|
9
|
+
self.config = config
|
10
|
+
self.fault_col = fault_col
|
11
|
+
|
12
|
+
def create_plot(self, df: pd.DataFrame):
|
13
|
+
raise NotImplementedError
|
14
|
+
|
15
|
+
def summarize_fault_times(self, df: pd.DataFrame) -> dict:
|
16
|
+
raise NotImplementedError
|
17
|
+
|
18
|
+
def create_hist_plot(self, df: pd.DataFrame):
|
19
|
+
df[f"hour_of_the_day_{self.fault_col}"] = df.index.hour.where(
|
20
|
+
df[self.fault_col] == 1
|
21
|
+
)
|
22
|
+
fig, ax = plt.subplots(tight_layout=True, figsize=(25, 8))
|
23
|
+
ax.hist(df[f"hour_of_the_day_{self.fault_col}"].dropna())
|
24
|
+
ax.set_xlabel("Hour of the Day")
|
25
|
+
ax.set_ylabel("Frequency")
|
26
|
+
ax.set_title(f"Hour-Of-Day When Fault Flag {self.fault_col} is TRUE")
|
27
|
+
plt.show()
|
28
|
+
plt.close()
|
29
|
+
|
30
|
+
def display_report_in_ipython(self, df: pd.DataFrame):
|
31
|
+
summary = self.summarize_fault_times(df)
|
32
|
+
for key, value in summary.items():
|
33
|
+
formatted_key = key.replace("_", " ")
|
34
|
+
print(f"{formatted_key}: {value}")
|
35
|
+
sys.stdout.flush()
|
36
|
+
|
37
|
+
if df[self.fault_col].max() != 0:
|
38
|
+
self.create_hist_plot(df)
|
39
|
+
else:
|
40
|
+
print("NO FAULTS FOUND - Skipping time-of-day Histogram plot")
|
41
|
+
sys.stdout.flush()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import pytest
|
3
|
-
from open_fdd.air_handling_unit.faults
|
3
|
+
from open_fdd.air_handling_unit.faults import FaultConditionOne
|
4
4
|
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
5
|
from open_fdd.air_handling_unit.faults.fault_condition import MissingColumnError
|
6
6
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import pytest
|
3
|
-
from open_fdd.air_handling_unit.faults
|
3
|
+
from open_fdd.air_handling_unit.faults import FaultConditionTen
|
4
4
|
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
5
|
|
6
6
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import pytest
|
3
|
-
from open_fdd.air_handling_unit.faults
|
3
|
+
from open_fdd.air_handling_unit.faults import FaultConditionTwo
|
4
4
|
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
5
|
|
6
6
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import pytest
|
3
|
-
from open_fdd.air_handling_unit.faults
|
3
|
+
from open_fdd.air_handling_unit.faults import FaultConditionThree
|
4
4
|
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
5
|
|
6
6
|
"""
|
@@ -1,128 +1,200 @@
|
|
1
1
|
import pandas as pd
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
2
|
+
import pytest
|
3
|
+
from open_fdd.air_handling_unit.faults import FaultConditionFour
|
4
|
+
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
|
+
from datetime import datetime, timezone
|
6
|
+
|
7
|
+
"""
|
8
|
+
To see print statements in pytest run with:
|
9
|
+
$ py -3.12 -m pytest tests/ahu/test_ahu_fc4.py -rP -s
|
10
|
+
|
11
|
+
Too much hunting in control system
|
12
|
+
OS state changes greater than 7 in an hour
|
13
|
+
"""
|
14
|
+
|
15
|
+
# Constants
|
16
|
+
DELTA_OS_MAX = 7
|
17
|
+
AHU_MIN_OA = 0.20
|
18
|
+
TEST_MIX_AIR_DAMPER_COL = "economizer_sig_col"
|
19
|
+
TEST_HEATING_COIL_SIG_COL = "heating_sig_col"
|
20
|
+
TEST_COOLING_COIL_SIG_COL = "cooling_sig_col"
|
21
|
+
TEST_SUPPLY_VFD_SPEED_COL = "fan_vfd_speed_col"
|
22
|
+
TEST_DATASET_ROWS = 60
|
23
|
+
|
24
|
+
# Initialize FaultConditionFour with a dictionary
|
25
|
+
fault_condition_params = {
|
26
|
+
"DELTA_OS_MAX": DELTA_OS_MAX,
|
27
|
+
"AHU_MIN_OA_DPR": AHU_MIN_OA,
|
28
|
+
"ECONOMIZER_SIG_COL": TEST_MIX_AIR_DAMPER_COL,
|
29
|
+
"HEATING_SIG_COL": TEST_HEATING_COIL_SIG_COL,
|
30
|
+
"COOLING_SIG_COL": TEST_COOLING_COIL_SIG_COL,
|
31
|
+
"SUPPLY_VFD_SPEED_COL": TEST_SUPPLY_VFD_SPEED_COL,
|
32
|
+
"TROUBLESHOOT_MODE": False, # default value
|
33
|
+
}
|
34
|
+
|
35
|
+
fc4 = FaultConditionFour(fault_condition_params)
|
36
|
+
|
37
|
+
|
38
|
+
def generate_timestamp() -> pd.Series:
|
39
|
+
df = pd.DataFrame()
|
40
|
+
date_range = pd.period_range(
|
41
|
+
# make a time stamp starting at top of
|
42
|
+
# the hour with one min intervals
|
43
|
+
start=datetime(2022, 6, 6, 14, 30, 0, 0, tzinfo=timezone.utc),
|
44
|
+
periods=TEST_DATASET_ROWS,
|
45
|
+
freq="min",
|
46
|
+
)
|
47
|
+
df["Date"] = [x.to_timestamp() for x in date_range]
|
48
|
+
return df["Date"]
|
49
|
+
|
50
|
+
|
51
|
+
def econ_plus_mech_clg_row() -> dict:
|
52
|
+
data = {
|
53
|
+
TEST_MIX_AIR_DAMPER_COL: 0.6,
|
54
|
+
TEST_HEATING_COIL_SIG_COL: 0.0,
|
55
|
+
TEST_COOLING_COIL_SIG_COL: 0.6,
|
56
|
+
TEST_SUPPLY_VFD_SPEED_COL: 0.8,
|
57
|
+
}
|
58
|
+
return data
|
59
|
+
|
60
|
+
|
61
|
+
def mech_clg_row() -> dict:
|
62
|
+
data = {
|
63
|
+
TEST_MIX_AIR_DAMPER_COL: 0.0,
|
64
|
+
TEST_HEATING_COIL_SIG_COL: 0.0,
|
65
|
+
TEST_COOLING_COIL_SIG_COL: 0.6,
|
66
|
+
TEST_SUPPLY_VFD_SPEED_COL: 0.8,
|
67
|
+
}
|
68
|
+
return data
|
69
|
+
|
70
|
+
|
71
|
+
def econ_plus_mech_clg_row_int() -> dict:
|
72
|
+
data = {
|
73
|
+
TEST_MIX_AIR_DAMPER_COL: 0.6,
|
74
|
+
TEST_HEATING_COIL_SIG_COL: 0.0,
|
75
|
+
TEST_COOLING_COIL_SIG_COL: 0.6,
|
76
|
+
TEST_SUPPLY_VFD_SPEED_COL: 88,
|
77
|
+
}
|
78
|
+
return data
|
79
|
+
|
80
|
+
|
81
|
+
def econ_plus_mech_clg_row_float_greater_than_one() -> dict:
|
82
|
+
data = {
|
83
|
+
TEST_MIX_AIR_DAMPER_COL: 0.6,
|
84
|
+
TEST_HEATING_COIL_SIG_COL: 0.0,
|
85
|
+
TEST_COOLING_COIL_SIG_COL: 0.6,
|
86
|
+
TEST_SUPPLY_VFD_SPEED_COL: 88.8,
|
87
|
+
}
|
88
|
+
return data
|
89
|
+
|
90
|
+
|
91
|
+
class TestFault(object):
|
92
|
+
|
93
|
+
def fault_df(self) -> pd.DataFrame:
|
94
|
+
data = []
|
95
|
+
counter = 0
|
96
|
+
for i in range(TEST_DATASET_ROWS):
|
97
|
+
if i % 2 == 0 and counter < 11:
|
98
|
+
data.append(econ_plus_mech_clg_row())
|
99
|
+
counter += 1 # only simulate 10 OS changes
|
100
|
+
else:
|
101
|
+
data.append(mech_clg_row())
|
102
|
+
return pd.DataFrame(data)
|
103
|
+
|
104
|
+
def test_fault(self):
|
105
|
+
fault_df = self.fault_df().set_index(generate_timestamp())
|
106
|
+
results = fc4.apply(fault_df)
|
107
|
+
actual = results["fc4_flag"].sum()
|
108
|
+
expected = 1
|
109
|
+
message = f"FC4 fault_df actual is {actual} and expected is {expected}"
|
110
|
+
assert actual == expected, message
|
111
|
+
|
112
|
+
|
113
|
+
class TestNoFault(object):
|
114
|
+
|
115
|
+
def no_fault_df(self) -> pd.DataFrame:
|
116
|
+
data = []
|
117
|
+
for i in range(TEST_DATASET_ROWS):
|
118
|
+
data.append(mech_clg_row())
|
119
|
+
return pd.DataFrame(data)
|
120
|
+
|
121
|
+
def test_no_fault(self):
|
122
|
+
no_fault_df = self.no_fault_df().set_index(generate_timestamp())
|
123
|
+
results = fc4.apply(no_fault_df)
|
124
|
+
actual = results["fc4_flag"].sum()
|
125
|
+
expected = 0
|
126
|
+
message = f"FC4 no_fault_df actual is {actual} and expected is {expected}"
|
127
|
+
assert actual == expected, message
|
128
|
+
|
129
|
+
|
130
|
+
class TestFaultOnInt(object):
|
131
|
+
|
132
|
+
def fault_df_on_output_int(self) -> pd.DataFrame:
|
133
|
+
data = []
|
134
|
+
for i in range(TEST_DATASET_ROWS):
|
135
|
+
if i % 2 == 0:
|
136
|
+
data.append(econ_plus_mech_clg_row_int())
|
137
|
+
else:
|
138
|
+
data.append(mech_clg_row())
|
139
|
+
return pd.DataFrame(data)
|
140
|
+
|
141
|
+
def test_fault_on_int(self):
|
142
|
+
fault_df_on_output_int = self.fault_df_on_output_int().set_index(
|
143
|
+
generate_timestamp()
|
144
|
+
)
|
145
|
+
with pytest.raises(
|
146
|
+
TypeError,
|
147
|
+
match=HelperUtils().float_int_check_err(TEST_SUPPLY_VFD_SPEED_COL),
|
148
|
+
):
|
149
|
+
fc4.apply(fault_df_on_output_int)
|
150
|
+
|
151
|
+
|
152
|
+
class TestFaultOnFloatGreaterThanOne(object):
|
153
|
+
|
154
|
+
def fault_df_on_output_greater_than_one(self) -> pd.DataFrame:
|
155
|
+
data = []
|
156
|
+
for i in range(TEST_DATASET_ROWS):
|
157
|
+
if i % 2 == 0:
|
158
|
+
data.append(econ_plus_mech_clg_row_float_greater_than_one())
|
159
|
+
else:
|
160
|
+
data.append(mech_clg_row())
|
161
|
+
return pd.DataFrame(data)
|
162
|
+
|
163
|
+
def test_fault_on_float_greater_than_one(self):
|
164
|
+
fault_df_on_output_greater_than_one = (
|
165
|
+
self.fault_df_on_output_greater_than_one().set_index(generate_timestamp())
|
166
|
+
)
|
167
|
+
with pytest.raises(
|
168
|
+
TypeError,
|
169
|
+
match=HelperUtils().float_max_check_err(TEST_SUPPLY_VFD_SPEED_COL),
|
170
|
+
):
|
171
|
+
fc4.apply(fault_df_on_output_greater_than_one)
|
172
|
+
|
173
|
+
|
174
|
+
class TestFaultOnMixedTypes(object):
|
175
|
+
|
176
|
+
def fault_df_on_mixed_types(self) -> pd.DataFrame:
|
177
|
+
data = []
|
178
|
+
for i in range(TEST_DATASET_ROWS):
|
179
|
+
if i % 2 == 0:
|
180
|
+
data.append(
|
181
|
+
{
|
182
|
+
TEST_MIX_AIR_DAMPER_COL: 0.6,
|
183
|
+
TEST_HEATING_COIL_SIG_COL: 0.0,
|
184
|
+
TEST_COOLING_COIL_SIG_COL: 0.6,
|
185
|
+
TEST_SUPPLY_VFD_SPEED_COL: 1.1,
|
186
|
+
}
|
187
|
+
)
|
188
|
+
else:
|
189
|
+
data.append(mech_clg_row())
|
190
|
+
return pd.DataFrame(data)
|
191
|
+
|
192
|
+
def test_fault_on_mixed_types(self):
|
193
|
+
fault_df_on_mixed_types = self.fault_df_on_mixed_types().set_index(
|
194
|
+
generate_timestamp()
|
195
|
+
)
|
196
|
+
with pytest.raises(
|
197
|
+
TypeError,
|
198
|
+
match=HelperUtils().float_max_check_err(TEST_SUPPLY_VFD_SPEED_COL),
|
199
|
+
):
|
200
|
+
fc4.apply(fault_df_on_mixed_types)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import pytest
|
3
|
-
from open_fdd.air_handling_unit.faults
|
3
|
+
from open_fdd.air_handling_unit.faults import FaultConditionFive
|
4
4
|
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
5
|
|
6
6
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import pytest
|
3
|
-
from open_fdd.air_handling_unit.faults
|
3
|
+
from open_fdd.air_handling_unit.faults import FaultConditionSix
|
4
4
|
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
5
|
|
6
6
|
"""
|
@@ -12,7 +12,7 @@ OA FRACTION TOO LOW OR TOO HIGH; SHOULD BE EQUAL TO %OAmin
|
|
12
12
|
|
13
13
|
# Constants
|
14
14
|
TEST_AIRFLOW_ERR_THRES = 0.3
|
15
|
-
TEST_AHU_MIN_CFM_DESIGN = 3000
|
15
|
+
TEST_AHU_MIN_CFM_DESIGN = 3000.0
|
16
16
|
TEST_OAT_DEGF_ERR_THRES = 5.0
|
17
17
|
TEST_RAT_DEGF_ERR_THRES = 2.0
|
18
18
|
TEST_DELTA_TEMP_MIN = 10.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import pytest
|
3
|
-
from open_fdd.air_handling_unit.faults
|
3
|
+
from open_fdd.air_handling_unit.faults import FaultConditionSeven
|
4
4
|
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
5
|
|
6
6
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import pytest
|
3
|
-
from open_fdd.air_handling_unit.faults
|
3
|
+
from open_fdd.air_handling_unit.faults import FaultConditionEight
|
4
4
|
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
5
|
|
6
6
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import pytest
|
3
|
-
from open_fdd.air_handling_unit.faults
|
3
|
+
from open_fdd.air_handling_unit.faults import FaultConditionNine
|
4
4
|
from open_fdd.air_handling_unit.faults.helper_utils import HelperUtils
|
5
5
|
|
6
6
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: open_fdd
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.5
|
4
4
|
Summary: A package for fault detection and diagnosis in HVAC systems
|
5
5
|
Home-page: https://github.com/bbartling/open-fdd
|
6
6
|
Author: Ben Bartling
|
@@ -39,21 +39,28 @@ pip install open-fdd
|
|
39
39
|
For running Jupyter notebooks, I recommend using Visual Studio Code with the Jupyter notebook extension installed, which offers a seamless experience directly within the editor. Be sure to explore the `examples` directory for Jupyter notebook tutorials. If you have your own FDD experiences to share, feel free to contribute by creating a notebook (`.ipynb`). You’re welcome to reach out to me directly, and I can push your example to GitHub on your behalf, which might be a simpler process than submitting a pull request (PR), especially if you're just sharing an example rather than developing `open-fdd`.
|
40
40
|
|
41
41
|
## Project goals
|
42
|
-
|
43
|
-
- [x] finish `air_handling_unit` faults and reports based on ASHRAE and NIST
|
44
|
-
- [x] publish to PyPI as Python library
|
45
|
-
- [ ] make a few IPython notebook tutorials AHU FDD examples with `BRICK` meta data integration.
|
46
|
-
- [ ] make a guide for fault `parameters` like error thresholds, etc.
|
47
|
-
- [ ] make `central_plant` faults, IPython reports, and examples.
|
48
|
-
- [ ] make `energy_efficiency` faults, IPython reports, and examples to `optimize` in reducing energy consumption.
|
49
|
-
- [ ] make `metering`, faults, IPython reports, and examples to possibly model utility metering data.
|
50
|
-
- [ ] create SQL example to read data from time series db and write back to SQL to then read faults in Grafana.
|
51
|
-
- [ ] other?
|
52
|
-
|
53
|
-
Certainly! Here's a revised version of your contribution guidelines:
|
42
|
+
The following are key objectives to enhance this project into a fully interactive Fault Detection and Diagnostics (FDD) application.
|
54
43
|
|
55
|
-
|
44
|
+
### Completed
|
45
|
+
- [x] Develop and finalize `air_handling_unit` fault conditions and reports, aligning with ASHRAE and NIST standards.
|
46
|
+
- [x] Publish the project as a Python library on PyPI.
|
47
|
+
|
48
|
+
### In Progress
|
49
|
+
- [ ] Create IPython notebook tutorials showcasing AHU FDD examples, incorporating BRICK metadata integration.
|
50
|
+
- [ ] Develop a comprehensive guide on a github.io website (or other?) for defining fault parameters, including error thresholds and other critical settings.
|
51
|
+
|
52
|
+
### Upcoming
|
53
|
+
- [ ] Extend the project to include `central_plant` fault conditions, IPython reports, and example applications.
|
54
|
+
- [ ] Design `energy_efficiency` fault detection modules, including IPython reports and examples focused on optimizing energy consumption.
|
55
|
+
- [ ] Develop `metering` fault conditions, along with IPython reports and examples, potentially modeling utility metering data.
|
56
|
+
- [ ] Implement SQL integration examples for reading data from a time series database, writing back to SQL, and visualizing faults in Grafana.
|
56
57
|
|
58
|
+
### Future Considerations
|
59
|
+
Explore additional features and enhancements as the project evolves.
|
60
|
+
- [ ] Explore additional features and enhancements as the project evolves.
|
61
|
+
|
62
|
+
|
63
|
+
## Contribute
|
57
64
|
If you have suggestions for improving developer best practices or solutions, please feel free to reach out to me directly using my contact information or Git issue/discussion. I primarily work on Windows with multiple versions of Python installed, with Python 3.12.x as my default version. You can download the latest version of Python here:
|
58
65
|
* https://www.python.org/downloads/
|
59
66
|
|