ecopipeline 0.11.9__tar.gz → 1.0.1__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.
- ecopipeline-1.0.1/MANIFEST.in +2 -0
- {ecopipeline-0.11.9/src/ecopipeline.egg-info → ecopipeline-1.0.1}/PKG-INFO +1 -1
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/setup.cfg +1 -1
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/extract/extract.py +17 -20
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/transform/transform.py +17 -8
- ecopipeline-1.0.1/src/ecopipeline/utils/pkls/tasseron_resistance_to_temp_3.pkl +0 -0
- ecopipeline-1.0.1/src/ecopipeline/utils/pkls/tasseron_temp_to_resistance_2.pkl +0 -0
- ecopipeline-1.0.1/src/ecopipeline/utils/pkls/veris_resistance_to_temp_3.pkl +0 -0
- ecopipeline-1.0.1/src/ecopipeline/utils/pkls/veris_temp_to_resistance_2.pkl +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1/src/ecopipeline.egg-info}/PKG-INFO +1 -1
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline.egg-info/SOURCES.txt +6 -1
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/LICENSE +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/README.md +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/pyproject.toml +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/setup.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/__init__.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/event_tracking/__init__.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/event_tracking/event_tracking.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/extract/__init__.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/load/__init__.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/load/load.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/transform/__init__.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/transform/bayview.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/transform/lbnl.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/utils/ConfigManager.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/utils/NOAADataDownloader.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/utils/__init__.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/utils/pkls/__init__.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline/utils/unit_convert.py +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline.egg-info/dependency_links.txt +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline.egg-info/requires.txt +0 -0
- {ecopipeline-0.11.9 → ecopipeline-1.0.1}/src/ecopipeline.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[metadata]
|
|
2
2
|
name = ecopipeline
|
|
3
|
-
version = 0.
|
|
3
|
+
version = 1.0.1
|
|
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
|
|
@@ -776,7 +776,7 @@ def pull_egauge_data(config: ConfigManager, eGauge_ids: list, eGauge_usr : str,
|
|
|
776
776
|
os.chdir(original_directory)
|
|
777
777
|
|
|
778
778
|
def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: datetime = None, create_csv : bool = True, query_hours : float = 1,
|
|
779
|
-
sensor_keys : list = [], seperate_keys : bool = False):
|
|
779
|
+
sensor_keys : list = [], seperate_keys : bool = False, device_id_overwrite : str = None, csv_prefix : str = ""):
|
|
780
780
|
"""
|
|
781
781
|
Function connects to the things board manager api to pull data and returns a dataframe.
|
|
782
782
|
|
|
@@ -796,6 +796,11 @@ def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: dat
|
|
|
796
796
|
create csv files as you process such that API need not be relied upon for reprocessing
|
|
797
797
|
query_hours : float
|
|
798
798
|
number of hours to query at a time from ThingsBoard API
|
|
799
|
+
|
|
800
|
+
device_id_overwrite : str
|
|
801
|
+
Overwrites device ID for API pull
|
|
802
|
+
csv_prefix : str
|
|
803
|
+
prefix to add to the csv title
|
|
799
804
|
|
|
800
805
|
Returns
|
|
801
806
|
-------
|
|
@@ -804,16 +809,17 @@ def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: dat
|
|
|
804
809
|
Will return with index in UTC so needs to be converted after to appropriate timezone
|
|
805
810
|
"""
|
|
806
811
|
df = pd.DataFrame()
|
|
812
|
+
api_device_id = device_id_overwrite if not device_id_overwrite is None else config.api_device_id
|
|
807
813
|
if len(sensor_keys) <= 0:
|
|
808
814
|
token = config.get_thingsboard_token()
|
|
809
|
-
key_list = _get_tb_keys(
|
|
815
|
+
key_list = _get_tb_keys(token, api_device_id)
|
|
810
816
|
if len(key_list) <= 0:
|
|
811
|
-
raise Exception(f"No sensors available at ThingsBoard site with id {
|
|
812
|
-
return tb_api_to_df(config, startTime, endTime, create_csv, query_hours, key_list, seperate_keys)
|
|
817
|
+
raise Exception(f"No sensors available at ThingsBoard site with id {api_device_id}")
|
|
818
|
+
return tb_api_to_df(config, startTime, endTime, create_csv, query_hours, key_list, seperate_keys, device_id_overwrite, csv_prefix)
|
|
813
819
|
if seperate_keys:
|
|
814
820
|
df_list = []
|
|
815
821
|
for sensor_key in sensor_keys:
|
|
816
|
-
df_list.append(tb_api_to_df(config, startTime, endTime, False, query_hours, [sensor_key], False))
|
|
822
|
+
df_list.append(tb_api_to_df(config, startTime, endTime, False, query_hours, [sensor_key], False, device_id_overwrite, csv_prefix))
|
|
817
823
|
df = pd.concat(df_list)
|
|
818
824
|
else:
|
|
819
825
|
# not seperate_keys:
|
|
@@ -826,13 +832,13 @@ def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: dat
|
|
|
826
832
|
if endTime - timedelta(hours=query_hours) > startTime:
|
|
827
833
|
time_diff = endTime - startTime
|
|
828
834
|
midpointTime = startTime + time_diff / 2
|
|
829
|
-
df_1 = tb_api_to_df(config, startTime, midpointTime, query_hours=query_hours, sensor_keys=sensor_keys, create_csv=False)#True if startTime >= datetime(2025,7,13,9) and startTime <= datetime(2025,7,13,10) else csv_pass_down)
|
|
830
|
-
df_2 = tb_api_to_df(config, midpointTime, endTime, query_hours=query_hours, sensor_keys=sensor_keys,create_csv=False)#True if endTime >= datetime(2025,7,13,9) and endTime <= datetime(2025,7,13,10) else csv_pass_down)
|
|
835
|
+
df_1 = tb_api_to_df(config, startTime, midpointTime, query_hours=query_hours, sensor_keys=sensor_keys, create_csv=False, device_id_overwrite = device_id_overwrite)#True if startTime >= datetime(2025,7,13,9) and startTime <= datetime(2025,7,13,10) else csv_pass_down)
|
|
836
|
+
df_2 = tb_api_to_df(config, midpointTime, endTime, query_hours=query_hours, sensor_keys=sensor_keys,create_csv=False, device_id_overwrite = device_id_overwrite)#True if endTime >= datetime(2025,7,13,9) and endTime <= datetime(2025,7,13,10) else csv_pass_down)
|
|
831
837
|
df = pd.concat([df_1, df_2])
|
|
832
838
|
df = df.sort_index()
|
|
833
839
|
df = df.groupby(df.index).mean()
|
|
834
840
|
else:
|
|
835
|
-
url = f'https://thingsboard.cloud/api/plugins/telemetry/DEVICE/{
|
|
841
|
+
url = f'https://thingsboard.cloud/api/plugins/telemetry/DEVICE/{api_device_id}/values/timeseries'
|
|
836
842
|
token = config.get_thingsboard_token()
|
|
837
843
|
key_string = ','.join(sensor_keys)
|
|
838
844
|
params = {
|
|
@@ -844,7 +850,6 @@ def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: dat
|
|
|
844
850
|
'interval' : '0',
|
|
845
851
|
'agg' : 'NONE'
|
|
846
852
|
}
|
|
847
|
-
|
|
848
853
|
# Headers
|
|
849
854
|
headers = {
|
|
850
855
|
'accept': 'application/json',
|
|
@@ -855,14 +860,6 @@ def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: dat
|
|
|
855
860
|
response = requests.get(url, headers=headers, params=params)
|
|
856
861
|
if response.status_code == 200:
|
|
857
862
|
response_json = response.json()
|
|
858
|
-
# if create_csv:
|
|
859
|
-
# json_filename = f"{startTime.strftime('%Y%m%d%H%M%S')}.json"
|
|
860
|
-
# print(f"filename: {json_filename}, url: {url}, params: {params}")
|
|
861
|
-
# original_directory = os.getcwd()
|
|
862
|
-
# os.chdir(config.data_directory)
|
|
863
|
-
# with open(json_filename, 'w') as f:
|
|
864
|
-
# json.dump(response_json, f, indent=4) # indent=4 makes it human-readable
|
|
865
|
-
# os.chdir(original_directory)
|
|
866
863
|
|
|
867
864
|
data = {}
|
|
868
865
|
for key, records in response_json.items():
|
|
@@ -886,7 +883,7 @@ def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: dat
|
|
|
886
883
|
df = pd.DataFrame()
|
|
887
884
|
# save to file
|
|
888
885
|
if create_csv:
|
|
889
|
-
filename = f"{startTime.strftime('%Y%m%d%H%M%S')}.csv"
|
|
886
|
+
filename = f"{csv_prefix}{startTime.strftime('%Y%m%d%H%M%S')}.csv"
|
|
890
887
|
original_directory = os.getcwd()
|
|
891
888
|
os.chdir(config.data_directory)
|
|
892
889
|
df.to_csv(filename, index_label='time_pt')
|
|
@@ -900,8 +897,8 @@ def _get_float_value(value):
|
|
|
900
897
|
except (ValueError, TypeError):
|
|
901
898
|
return None
|
|
902
899
|
|
|
903
|
-
def _get_tb_keys(
|
|
904
|
-
url = f'https://thingsboard.cloud/api/plugins/telemetry/DEVICE/{
|
|
900
|
+
def _get_tb_keys(token : str, api_device_id : str) -> List[str]:
|
|
901
|
+
url = f'https://thingsboard.cloud/api/plugins/telemetry/DEVICE/{api_device_id}/keys/timeseries'
|
|
905
902
|
|
|
906
903
|
# Headers
|
|
907
904
|
headers = {
|
|
@@ -157,20 +157,29 @@ def _rm_cols(col, bounds_df): # Helper function for remove_outliers
|
|
|
157
157
|
"""
|
|
158
158
|
Function will take in a pandas series and bounds information
|
|
159
159
|
stored in a dataframe, then check each element of that column and set it to nan
|
|
160
|
-
if it is outside the given bounds.
|
|
160
|
+
if it is outside the given bounds.
|
|
161
161
|
|
|
162
|
-
Args:
|
|
163
|
-
col: pd.Series
|
|
162
|
+
Args:
|
|
163
|
+
col: pd.Series
|
|
164
164
|
Pandas dataframe column from data being processed
|
|
165
165
|
bounds_df: pd.DataFrame
|
|
166
166
|
Pandas dataframe indexed by the names of the columns from the dataframe that col came from. There should be at least
|
|
167
167
|
two columns in this dataframe, lower_bound and upper_bound, for use in removing outliers
|
|
168
|
-
Returns:
|
|
169
|
-
None
|
|
168
|
+
Returns:
|
|
169
|
+
None
|
|
170
170
|
"""
|
|
171
171
|
if (col.name in bounds_df.index):
|
|
172
|
-
c_lower =
|
|
173
|
-
c_upper =
|
|
172
|
+
c_lower = bounds_df.loc[col.name]["lower_bound"]
|
|
173
|
+
c_upper = bounds_df.loc[col.name]["upper_bound"]
|
|
174
|
+
|
|
175
|
+
# Skip if both bounds are NaN
|
|
176
|
+
if pd.isna(c_lower) and pd.isna(c_upper):
|
|
177
|
+
return
|
|
178
|
+
|
|
179
|
+
# Convert bounds to float, handling NaN values
|
|
180
|
+
c_lower = float(c_lower) if not pd.isna(c_lower) else -np.inf
|
|
181
|
+
c_upper = float(c_upper) if not pd.isna(c_upper) else np.inf
|
|
182
|
+
|
|
174
183
|
col.mask((col > c_upper) | (col < c_lower), other=np.NaN, inplace=True)
|
|
175
184
|
|
|
176
185
|
# TODO: remove_outliers STRETCH GOAL: Functionality for alarms being raised based on bounds needs to happen here.
|
|
@@ -784,7 +793,7 @@ def convert_on_off_col_to_bool(df: pd.DataFrame, column_names: list) -> pd.DataF
|
|
|
784
793
|
pd.DataFrame: Dataframe with specified columns converted from Celsius to Farenhiet.
|
|
785
794
|
"""
|
|
786
795
|
|
|
787
|
-
mapping = {'ON': True, 'OFF': False}
|
|
796
|
+
mapping = {'ON': True, 'OFF': False, 'On': True, 'Off': False}
|
|
788
797
|
|
|
789
798
|
for column_name in column_names:
|
|
790
799
|
df[column_name] = df[column_name].map(mapping).where(df[column_name].notna(), df[column_name])
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
LICENSE
|
|
2
|
+
MANIFEST.in
|
|
2
3
|
README.md
|
|
3
4
|
pyproject.toml
|
|
4
5
|
setup.cfg
|
|
@@ -23,4 +24,8 @@ src/ecopipeline/utils/ConfigManager.py
|
|
|
23
24
|
src/ecopipeline/utils/NOAADataDownloader.py
|
|
24
25
|
src/ecopipeline/utils/__init__.py
|
|
25
26
|
src/ecopipeline/utils/unit_convert.py
|
|
26
|
-
src/ecopipeline/utils/pkls/__init__.py
|
|
27
|
+
src/ecopipeline/utils/pkls/__init__.py
|
|
28
|
+
src/ecopipeline/utils/pkls/tasseron_resistance_to_temp_3.pkl
|
|
29
|
+
src/ecopipeline/utils/pkls/tasseron_temp_to_resistance_2.pkl
|
|
30
|
+
src/ecopipeline/utils/pkls/veris_resistance_to_temp_3.pkl
|
|
31
|
+
src/ecopipeline/utils/pkls/veris_temp_to_resistance_2.pkl
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|