Skip to content

Commit

Permalink
ahu rules getting err exception handling make over. need to finish ip…
Browse files Browse the repository at this point in the history
…ynb to run individual rulse then publish new version to pypi
  • Loading branch information
bbartling committed Aug 25, 2024
1 parent 90e7476 commit 26f83bd
Show file tree
Hide file tree
Showing 18 changed files with 644 additions and 80 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ These are some basic project goals to make this into an interactive FDD applicat
- [ ] make `energy_efficiency` faults, IPython reports, and examples to `optimize` in reducing energy consumption.
- [ ] make `metering`, faults, IPython reports, and examples to possibly model utility metering data.
- [ ] create SQL example to read data from time series db and write back to SQL to then read faults in Grafana.
- [ ] other?
- [ ] other? Certainly! As ChatGPT would eagerly say!

Certainly! Here's a revised version of your contribution guidelines:

## Contribute

Expand Down
126 changes: 85 additions & 41 deletions examples/csv_data_source/ahu_individual_faults.ipynb

Large diffs are not rendered by default.

40 changes: 38 additions & 2 deletions open_fdd/air_handling_unit/faults/fault_condition_eight.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ def __init__(self, dict_):
self.troubleshoot_mode = bool # default should be False
self.rolling_window_size = int

self.equation_string = (
"fc8_flag = 1 if |SAT - MAT - ΔT_fan| > √(εSAT² + εMAT²) "
"in economizer mode for N consecutive values else 0 \n"
)
self.description_string = (
"Fault Condition 8: Supply air temperature and mixed air temperature should "
"be approximately equal in economizer mode \n"
)
self.required_column_description = (
"Required inputs are the mixed air temperature, supply air temperature, "
"economizer signal, and cooling signal \n"
)
self.error_string = f"One or more required columns are missing or None \n"

self.set_attributes(dict_)

# Set required columns specific to this fault condition
Expand All @@ -36,9 +50,31 @@ def __init__(self, dict_):
self.cooling_sig_col,
]

# Check if any of the required columns are None
if any(col is None for col in self.required_columns):
raise MissingColumnError(
f"{self.error_string}"
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.required_columns}"
)

# Ensure all required columns are strings
self.required_columns = [str(col) for col in self.required_columns]

self.mapped_columns = (
f"Your config dictionary is mapped as: {', '.join(self.required_columns)}"
)

def get_required_columns(self) -> str:
"""Returns a string representation of the required columns."""
return f"Required columns for FaultConditionEight: {', '.join(self.required_columns)}"
return (
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.mapped_columns}"
)

def apply(self, df: pd.DataFrame) -> pd.DataFrame:
try:
Expand Down Expand Up @@ -88,4 +124,4 @@ def apply(self, df: pd.DataFrame) -> pd.DataFrame:
except MissingColumnError as e:
print(f"Error: {e.message}")
sys.stdout.flush()
raise e # Re-raise the exception so it can be caught by pytest
raise e
40 changes: 38 additions & 2 deletions open_fdd/air_handling_unit/faults/fault_condition_eleven.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ def __init__(self, dict_):
self.troubleshoot_mode = bool # default False
self.rolling_window_size = int

self.equation_string = (
"fc11_flag = 1 if OAT < (SATSP - ΔT_fan - εSAT) in "
"economizer cooling mode for N consecutive values else 0 \n"
)
self.description_string = (
"Fault Condition 11: Outside air temperature too low for 100% outdoor air cooling "
"in economizer cooling mode (Economizer performance fault) \n"
)
self.required_column_description = (
"Required inputs are the supply air temperature setpoint, outside air temperature, "
"cooling signal, and economizer signal \n"
)
self.error_string = f"One or more required columns are missing or None \n"

self.set_attributes(dict_)

# Set required columns specific to this fault condition
Expand All @@ -35,9 +49,31 @@ def __init__(self, dict_):
self.economizer_sig_col,
]

# Check if any of the required columns are None
if any(col is None for col in self.required_columns):
raise MissingColumnError(
f"{self.error_string}"
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.required_columns}"
)

# Ensure all required columns are strings
self.required_columns = [str(col) for col in self.required_columns]

self.mapped_columns = (
f"Your config dictionary is mapped as: {', '.join(self.required_columns)}"
)

def get_required_columns(self) -> str:
"""Returns a string representation of the required columns."""
return f"Required columns for FaultConditionEleven: {', '.join(self.required_columns)}"
return (
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.mapped_columns}"
)

def apply(self, df: pd.DataFrame) -> pd.DataFrame:
try:
Expand Down Expand Up @@ -87,4 +123,4 @@ def apply(self, df: pd.DataFrame) -> pd.DataFrame:
except MissingColumnError as e:
print(f"Error: {e.message}")
sys.stdout.flush()
raise e # Re-raise the exception so it can be caught by pytest
raise e
40 changes: 38 additions & 2 deletions open_fdd/air_handling_unit/faults/fault_condition_fifteen.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ def __init__(self, dict_):
self.troubleshoot_mode = bool # default to False
self.rolling_window_size = int

self.equation_string = (
"fc15_flag = 1 if ΔT_coil >= √(εcoil_enter² + εcoil_leave²) + ΔT_fan "
"in inactive heating coil mode for N consecutive values else 0 \n"
)
self.description_string = (
"Fault Condition 15: Temperature rise across inactive heating coil "
"detected, requiring coil leaving temperature sensor \n"
)
self.required_column_description = (
"Required inputs are the heating coil entering temperature, heating coil leaving temperature, "
"cooling signal, heating signal, economizer signal, and supply fan VFD speed \n"
)
self.error_string = f"One or more required columns are missing or None \n"

self.set_attributes(dict_)

# Set required columns specific to this fault condition
Expand All @@ -40,9 +54,31 @@ def __init__(self, dict_):
self.supply_vfd_speed_col,
]

# Check if any of the required columns are None
if any(col is None for col in self.required_columns):
raise MissingColumnError(
f"{self.error_string}"
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.required_columns}"
)

# Ensure all required columns are strings
self.required_columns = [str(col) for col in self.required_columns]

self.mapped_columns = (
f"Your config dictionary is mapped as: {', '.join(self.required_columns)}"
)

def get_required_columns(self) -> str:
"""Returns a string representation of the required columns."""
return f"Required columns for FaultConditionFifteen: {', '.join(self.required_columns)}"
return (
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.mapped_columns}"
)

def apply(self, df: pd.DataFrame) -> pd.DataFrame:
try:
Expand Down Expand Up @@ -113,4 +149,4 @@ def apply(self, df: pd.DataFrame) -> pd.DataFrame:
except MissingColumnError as e:
print(f"Error: {e.message}")
sys.stdout.flush()
raise e # Re-raise the exception so it can be caught by pytest
raise e
40 changes: 38 additions & 2 deletions open_fdd/air_handling_unit/faults/fault_condition_five.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ def __init__(self, dict_):
self.troubleshoot_mode = bool # default to False
self.rolling_window_size = int

self.equation_string = (
"fc5_flag = 1 if (SAT + εSAT <= MAT - εMAT + ΔT_supply_fan) and "
"(heating signal > 0) and (VFDSPD > 0) for N consecutive values else 0 \n"
)
self.description_string = (
"Fault Condition 5: SAT too low; should be higher than MAT in HTG MODE, "
"potential broken heating valve or mechanical issue \n"
)
self.required_column_description = (
"Required inputs are the mixed air temperature, supply air temperature, "
"heating signal, and supply fan VFD speed \n"
)
self.error_string = f"One or more required columns are missing or None \n"

self.set_attributes(dict_)

# Set required columns specific to this fault condition
Expand All @@ -36,9 +50,31 @@ def __init__(self, dict_):
self.supply_vfd_speed_col,
]

# Check if any of the required columns are None
if any(col is None for col in self.required_columns):
raise MissingColumnError(
f"{self.error_string}"
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.required_columns}"
)

# Ensure all required columns are strings
self.required_columns = [str(col) for col in self.required_columns]

self.mapped_columns = (
f"Your config dictionary is mapped as: {', '.join(self.required_columns)}"
)

def get_required_columns(self) -> str:
"""Returns a string representation of the required columns."""
return f"Required columns for FaultConditionFive: {', '.join(self.required_columns)}"
return (
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.mapped_columns}"
)

def apply(self, df: pd.DataFrame) -> pd.DataFrame:
try:
Expand Down Expand Up @@ -84,4 +120,4 @@ def apply(self, df: pd.DataFrame) -> pd.DataFrame:
except MissingColumnError as e:
print(f"Error: {e.message}")
sys.stdout.flush()
raise e # Re-raise the exception so it can be caught by pytest
raise e
36 changes: 34 additions & 2 deletions open_fdd/air_handling_unit/faults/fault_condition_four.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ def __init__(self, dict_):
self.supply_vfd_speed_col = str
self.troubleshoot_mode = bool # default to False

self.equation_string = (
"fc4_flag = 1 if excessive mode changes (> δOS_max) occur "
"within an hour across heating, econ, econ+mech, mech clg, and min OA modes \n"
)
self.description_string = "Fault Condition 4: Excessive AHU operating state changes detected (hunting behavior) \n"
self.required_column_description = (
"Required inputs are the economizer signal, supply fan VFD speed, "
"and optionally heating and cooling signals \n"
)
self.error_string = f"One or more required columns are missing or None \n"

self.set_attributes(dict_)

# Set required columns, making heating and cooling optional
Expand All @@ -40,9 +51,30 @@ def __init__(self, dict_):
if self.cooling_sig_col:
self.required_columns.append(self.cooling_sig_col)

# Check if any of the required columns are None
if any(col is None for col in self.required_columns):
raise MissingColumnError(
f"{self.error_string}"
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.required_columns}"
)
# Ensure all required columns are strings
self.required_columns = [str(col) for col in self.required_columns]

self.mapped_columns = (
f"Your config dictionary is mapped as: {', '.join(self.required_columns)}"
)

def get_required_columns(self) -> str:
"""Returns a string representation of the required columns."""
return f"Required columns for FaultConditionFour: {', '.join(self.required_columns)}"
return (
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.mapped_columns}"
)

def apply(self, df: pd.DataFrame) -> pd.DataFrame:
try:
Expand Down Expand Up @@ -133,4 +165,4 @@ def apply(self, df: pd.DataFrame) -> pd.DataFrame:
except MissingColumnError as e:
print(f"Error: {e.message}")
sys.stdout.flush()
raise e # Re-raise the exception so it can be caught by pytest
raise e
40 changes: 38 additions & 2 deletions open_fdd/air_handling_unit/faults/fault_condition_fourteen.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ def __init__(self, dict_):
self.troubleshoot_mode = bool # default to False
self.rolling_window_size = int

self.equation_string = (
"fc14_flag = 1 if ΔT_coil >= √(εcoil_enter² + εcoil_leave²) + ΔT_fan "
"in inactive cooling coil mode for N consecutive values else 0 \n"
)
self.description_string = (
"Fault Condition 14: Temperature drop across inactive cooling coil "
"detected, requiring coil leaving temperature sensor \n"
)
self.required_column_description = (
"Required inputs are the cooling coil entering temperature, cooling coil leaving temperature, "
"cooling signal, heating signal, economizer signal, and supply fan VFD speed \n"
)
self.error_string = f"One or more required columns are missing or None \n"

self.set_attributes(dict_)

# Set required columns specific to this fault condition
Expand All @@ -41,9 +55,31 @@ def __init__(self, dict_):
self.supply_vfd_speed_col,
]

# Check if any of the required columns are None
if any(col is None for col in self.required_columns):
raise MissingColumnError(
f"{self.error_string}"
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.required_columns}"
)

# Ensure all required columns are strings
self.required_columns = [str(col) for col in self.required_columns]

self.mapped_columns = (
f"Your config dictionary is mapped as: {', '.join(self.required_columns)}"
)

def get_required_columns(self) -> str:
"""Returns a string representation of the required columns."""
return f"Required columns for FaultConditionFourteen: {', '.join(self.required_columns)}"
return (
f"{self.equation_string}"
f"{self.description_string}"
f"{self.required_column_description}"
f"{self.mapped_columns}"
)

def apply(self, df: pd.DataFrame) -> pd.DataFrame:
try:
Expand Down Expand Up @@ -104,4 +140,4 @@ def apply(self, df: pd.DataFrame) -> pd.DataFrame:
except MissingColumnError as e:
print(f"Error: {e.message}")
sys.stdout.flush()
raise e # Re-raise the exception so it can be caught by pytest
raise e
Loading

0 comments on commit 26f83bd

Please sign in to comment.