ecopipeline 0.8.12__tar.gz → 0.9.0__tar.gz

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.
Files changed (26) hide show
  1. {ecopipeline-0.8.12/src/ecopipeline.egg-info → ecopipeline-0.9.0}/PKG-INFO +1 -1
  2. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/setup.cfg +1 -1
  3. ecopipeline-0.9.0/src/ecopipeline/event_tracking/__init__.py +2 -0
  4. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/event_tracking/event_tracking.py +67 -1
  5. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/transform/__init__.py +2 -2
  6. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/transform/transform.py +27 -1
  7. {ecopipeline-0.8.12 → ecopipeline-0.9.0/src/ecopipeline.egg-info}/PKG-INFO +1 -1
  8. ecopipeline-0.8.12/src/ecopipeline/event_tracking/__init__.py +0 -2
  9. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/LICENSE +0 -0
  10. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/README.md +0 -0
  11. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/pyproject.toml +0 -0
  12. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/setup.py +0 -0
  13. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/__init__.py +0 -0
  14. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/extract/__init__.py +0 -0
  15. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/extract/extract.py +0 -0
  16. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/load/__init__.py +0 -0
  17. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/load/load.py +0 -0
  18. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/transform/bayview.py +0 -0
  19. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/transform/lbnl.py +0 -0
  20. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/utils/ConfigManager.py +0 -0
  21. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/utils/__init__.py +0 -0
  22. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline/utils/unit_convert.py +0 -0
  23. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline.egg-info/SOURCES.txt +0 -0
  24. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline.egg-info/dependency_links.txt +0 -0
  25. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline.egg-info/requires.txt +0 -0
  26. {ecopipeline-0.8.12 → ecopipeline-0.9.0}/src/ecopipeline.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ecopipeline
3
- Version: 0.8.12
3
+ Version: 0.9.0
4
4
  Summary: Contains functions for use in Ecotope Datapipelines
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: License :: OSI Approved :: GNU General Public License (GPL)
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = ecopipeline
3
- version = 0.8.12
3
+ version = 0.9.0
4
4
  authors = ["Carlos Bello, <bellocarlos@seattleu.edu>, Emil Fahrig <fahrigemil@seattleu.edu>, Casey Mang <cmang@seattleu.edu>, Julian Harris <harrisjulian@seattleu.edu>, Roger Tram <rtram@seattleu.edu>, Nolan Price <nolan@ecotope.com>"]
5
5
  description = Contains functions for use in Ecotope Datapipelines
6
6
  long_description = file: README.md
@@ -0,0 +1,2 @@
1
+ from .event_tracking import *
2
+ __all__ = ['flag_boundary_alarms','power_ratio_alarm']
@@ -77,6 +77,10 @@ def flag_boundary_alarms(df: pd.DataFrame, config : ConfigManager, default_fault
77
77
  print(f"Could not process alarm for {bound_var}. Fault time must be greater than or equal to 1 minute.")
78
78
  _check_and_add_alarm(df, lower_mask, alarms, day, bounds["fault_time"], bound_var, bounds['pretty_name'], 'Lower')
79
79
  _check_and_add_alarm(df, upper_mask, alarms, day, bounds["fault_time"], bound_var, bounds['pretty_name'], 'Upper')
80
+
81
+ return _convert_silent_alarm_dict_to_df(alarms)
82
+
83
+ def _convert_silent_alarm_dict_to_df(alarm_dict : dict) -> pd.DataFrame:
80
84
  events = {
81
85
  'start_time_pt' : [],
82
86
  'end_time_pt' : [],
@@ -84,7 +88,7 @@ def flag_boundary_alarms(df: pd.DataFrame, config : ConfigManager, default_fault
84
88
  'event_detail' : [],
85
89
  'variable_name' : []
86
90
  }
87
- for key, value_list in alarms.items():
91
+ for key, value_list in alarm_dict.items():
88
92
  for value in value_list:
89
93
  events['start_time_pt'].append(key)
90
94
  events['end_time_pt'].append(key)
@@ -124,6 +128,68 @@ def _check_and_add_alarm(df : pd.DataFrame, mask : pd.Series, alarms_dict, day,
124
128
  else:
125
129
  alarms_dict[day] = [[var_name, alarm_string]]
126
130
 
131
+ def power_ratio_alarm(daily_df: pd.DataFrame, config : ConfigManager, system: str = "") -> pd.DataFrame:
132
+ daily_df_copy = daily_df.copy()
133
+ variable_names_path = config.get_var_names_path()
134
+ try:
135
+ ratios_df = pd.read_csv(variable_names_path)
136
+ except FileNotFoundError:
137
+ print("File Not Found: ", variable_names_path)
138
+ return pd.DataFrame()
139
+ if (system != ""):
140
+ if not 'system' in ratios_df.columns:
141
+ raise Exception("system parameter is non null, however, system is not present in Variable_Names.csv")
142
+ ratios_df = ratios_df.loc[ratios_df['system'] == system]
143
+ required_columns = ["variable_name", "alarm_codes"]
144
+ for required_column in required_columns:
145
+ if not required_column in ratios_df.columns:
146
+ raise Exception(f"{required_column} is not present in Variable_Names.csv")
147
+ if not 'pretty_name' in ratios_df.columns:
148
+ ratios_df['pretty_name'] = ratios_df['variable_name']
149
+ ratios_df = ratios_df.loc[:, ["variable_name", "alarm_codes", "pretty_name"]]
150
+ ratios_df = ratios_df[ratios_df['alarm_codes'].str.contains('PR', na=False)]
151
+ ratios_df.dropna(axis=0, thresh=2, inplace=True)
152
+ ratios_df.set_index(['variable_name'], inplace=True)
153
+
154
+ ratio_dict = {}
155
+ for ratios_var, ratios in ratios_df.iterrows():
156
+ if not ratios_var in daily_df_copy.columns:
157
+ daily_df_copy[ratios_var] = 0
158
+ alarm_codes = str(ratios['alarm_codes']).split(";")
159
+ for alarm_code in alarm_codes:
160
+ if alarm_code[:2] == "PR":
161
+ split_out_alarm = alarm_code.split(":")
162
+ low_high = split_out_alarm[1].split("-")
163
+ pr_id = split_out_alarm[0].split("_")[1]
164
+ if len(low_high) != 2:
165
+ raise Exception(f"Error processing alarm code {alarm_code}")
166
+ if pr_id in ratio_dict:
167
+ ratio_dict[pr_id][0].append(ratios_var)
168
+ ratio_dict[pr_id][1].append(float(low_high[0]))
169
+ ratio_dict[pr_id][2].append(float(low_high[1]))
170
+ ratio_dict[pr_id][3].append(ratios['pretty_name'])
171
+ else:
172
+ ratio_dict[pr_id] = [[ratios_var],[float(low_high[0])],[float(low_high[1])],[ratios['pretty_name']]]
173
+
174
+ alarms = {}
175
+ for key, value_list in ratio_dict.items():
176
+ daily_df_copy[key] = daily_df_copy[value_list[0]].sum(axis=1)
177
+ for i in range(len(value_list[0])):
178
+ column_name = value_list[0][i]
179
+ daily_df_copy[f'{column_name}_{key}'] = (daily_df_copy[column_name]/daily_df_copy[key]) * 100
180
+ _check_and_add_ratio_alarm(daily_df_copy, key, column_name, value_list[3][i], alarms, value_list[2][i], value_list[1][i])
181
+ return _convert_silent_alarm_dict_to_df(alarms)
182
+
183
+ def _check_and_add_ratio_alarm(daily_df: pd.DataFrame, alarm_key : str, column_name : str, pretty_name : str, alarms_dict : dict, high_bound : float, low_bound : float):
184
+ alarm_daily_df = daily_df.loc[(daily_df[f"{column_name}_{alarm_key}"] < low_bound) | (daily_df[f"{column_name}_{alarm_key}"] > high_bound)]
185
+ if not alarm_daily_df.empty:
186
+ for day, values in alarm_daily_df.iterrows():
187
+ alarm_str = f"Power ratio alarm: {pretty_name} accounted for {round(values[f'{column_name}_{alarm_key}'], 2)}% of {alarm_key} energy use."
188
+ if day in alarms_dict:
189
+ alarms_dict[day].append([column_name, alarm_str])
190
+ else:
191
+ alarms_dict[day] = [[column_name, alarm_str]]
192
+
127
193
  # def flag_dhw_outage(df: pd.DataFrame, daily_df : pd.DataFrame, dhw_outlet_column : str, supply_temp : int = 110, consecutive_minutes : int = 15) -> pd.DataFrame:
128
194
  # """
129
195
  # Parameters
@@ -1,7 +1,7 @@
1
1
  from .transform import rename_sensors, avg_duplicate_times, remove_outliers, ffill_missing, nullify_erroneous, sensor_adjustment, round_time, \
2
2
  aggregate_df, join_to_hourly, concat_last_row, join_to_daily, cop_method_1, cop_method_2, create_summary_tables, remove_partial_days, \
3
3
  convert_c_to_f,convert_l_to_g, convert_on_off_col_to_bool, flag_dhw_outage,generate_event_log_df,convert_time_zone, shift_accumulative_columns, \
4
- heat_output_calc, add_relative_humidity, apply_equipment_cop_derate, create_data_statistics_df, delete_erroneous_from_time_pt
4
+ heat_output_calc, add_relative_humidity, apply_equipment_cop_derate, create_data_statistics_df, delete_erroneous_from_time_pt,column_name_change
5
5
  from .lbnl import nclarity_filter_new, site_specific, condensate_calculations, gas_valve_diff, gather_outdoor_conditions, aqsuite_prep_time, \
6
6
  nclarity_csv_to_df, _add_date, add_local_time, aqsuite_filter_new, get_refrig_charge, elev_correction, change_ID_to_HVAC, get_hvac_state, \
7
7
  get_cop_values, get_cfm_values, replace_humidity, create_fan_curves, lbnl_temperature_conversions, lbnl_pressure_conversions, \
@@ -13,4 +13,4 @@ __all__ = ["rename_sensors", "avg_duplicate_times", "remove_outliers", "ffill_mi
13
13
  "create_fan_curves", "lbnl_temperature_conversions", "lbnl_pressure_conversions", "lbnl_sat_calculations", "get_site_cfm_info", "get_site_info", "merge_indexlike_rows", "calculate_cop_values", "aggregate_values",
14
14
  "get_energy_by_min", "verify_power_energy", "get_temp_zones120", "get_storage_gals120","convert_c_to_f","convert_l_to_g", "convert_on_off_col_to_bool", "flag_dhw_outage","generate_event_log_df","convert_time_zone",
15
15
  "shift_accumulative_columns","heat_output_calc", "add_relative_humidity","apply_equipment_cop_derate","create_data_statistics_df",
16
- "delete_erroneous_from_time_pt"]
16
+ "delete_erroneous_from_time_pt","column_name_change"]
@@ -378,6 +378,31 @@ def nullify_erroneous(original_df: pd.DataFrame, config : ConfigManager) -> pd.D
378
378
 
379
379
  return df
380
380
 
381
+ def column_name_change(df : pd.DataFrame, dt : pd.Timestamp, new_column : str, old_column : str, remove_old_column : bool = True) -> pd.DataFrame:
382
+ """
383
+ Overwrites values in `new_column` with values from `old_column`
384
+ for all rows before `dt`, if `dt` is within the index range.
385
+
386
+ Parameters
387
+ ----------
388
+ df: pd.DataFrame
389
+ Pandas dataframe with minute-to-minute data
390
+ dt: pd.Timestamp
391
+ timestamp of the varriable name change
392
+ new_column: str
393
+ column to be overwritten
394
+ old_column: str
395
+ column to copy from
396
+ remove_old_column : bool
397
+ remove old column when done
398
+ """
399
+ if df.index.min() < dt:
400
+ mask = df.index < dt
401
+ df.loc[mask, new_column] = df.loc[mask, old_column]
402
+ if remove_old_column:
403
+ df = df.drop(columns=[old_column])
404
+ return df
405
+
381
406
  def heat_output_calc(df: pd.DataFrame, flow_var : str, hot_temp : str, cold_temp : str, heat_out_col_name : str, return_as_kw : bool = True) -> pd.DataFrame:
382
407
  """
383
408
  Function will take a flow varriable and two temperature inputs to calculate heat output
@@ -903,7 +928,8 @@ def shift_accumulative_columns(df : pd.DataFrame, column_names : list = []):
903
928
  if len(column_names) == 0:
904
929
  return df_diff
905
930
  for column_name in column_names:
906
- df[column_name] = df_diff[column_name]
931
+ if column_name in df.columns:
932
+ df[column_name] = df_diff[column_name]
907
933
  return df
908
934
 
909
935
  def create_summary_tables(df: pd.DataFrame):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ecopipeline
3
- Version: 0.8.12
3
+ Version: 0.9.0
4
4
  Summary: Contains functions for use in Ecotope Datapipelines
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: License :: OSI Approved :: GNU General Public License (GPL)
@@ -1,2 +0,0 @@
1
- from .event_tracking import *
2
- __all__ = ['flag_boundary_alarms']
File without changes
File without changes
File without changes
File without changes