ecopipeline 0.8.11__tar.gz → 0.8.12__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 (25) hide show
  1. {ecopipeline-0.8.11/src/ecopipeline.egg-info → ecopipeline-0.8.12}/PKG-INFO +1 -1
  2. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/setup.cfg +1 -1
  3. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/extract/extract.py +98 -75
  4. {ecopipeline-0.8.11 → ecopipeline-0.8.12/src/ecopipeline.egg-info}/PKG-INFO +1 -1
  5. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/LICENSE +0 -0
  6. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/README.md +0 -0
  7. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/pyproject.toml +0 -0
  8. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/setup.py +0 -0
  9. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/__init__.py +0 -0
  10. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/event_tracking/__init__.py +0 -0
  11. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/event_tracking/event_tracking.py +0 -0
  12. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/extract/__init__.py +0 -0
  13. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/load/__init__.py +0 -0
  14. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/load/load.py +0 -0
  15. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/transform/__init__.py +0 -0
  16. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/transform/bayview.py +0 -0
  17. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/transform/lbnl.py +0 -0
  18. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/transform/transform.py +0 -0
  19. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/utils/ConfigManager.py +0 -0
  20. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/utils/__init__.py +0 -0
  21. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline/utils/unit_convert.py +0 -0
  22. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline.egg-info/SOURCES.txt +0 -0
  23. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline.egg-info/dependency_links.txt +0 -0
  24. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/src/ecopipeline.egg-info/requires.txt +0 -0
  25. {ecopipeline-0.8.11 → ecopipeline-0.8.12}/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.11
3
+ Version: 0.8.12
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.11
3
+ version = 0.8.12
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
@@ -767,7 +767,8 @@ def pull_egauge_data(config: ConfigManager, eGauge_ids: list, eGauge_usr : str,
767
767
 
768
768
  os.chdir(original_directory)
769
769
 
770
- def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: datetime = None, create_csv : bool = True, query_hours : int = 1):
770
+ def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: datetime = None, create_csv : bool = True, query_hours : float = 1,
771
+ sensor_keys : list = [], seperate_keys : bool = False):
771
772
  """
772
773
  Function connects to the things board manager api to pull data and returns a dataframe.
773
774
 
@@ -785,7 +786,7 @@ def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: dat
785
786
  is local time from the data's index.
786
787
  create_csv : bool
787
788
  create csv files as you process such that API need not be relied upon for reprocessing
788
- query_hours : int
789
+ query_hours : float
789
790
  number of hours to query at a time from ThingsBoard API
790
791
 
791
792
  Returns
@@ -794,80 +795,102 @@ def tb_api_to_df(config: ConfigManager, startTime: datetime = None, endTime: dat
794
795
  Pandas Dataframe containing data from the API pull with column headers the same as the variable names in the data from the pull.
795
796
  Will return with index in UTC so needs to be converted after to appropriate timezone
796
797
  """
797
- if endTime is None:
798
- endTime = datetime.now()
799
- if startTime is None:
800
- # 28 hours to ensure encapsulation of last day
801
- startTime = endTime - timedelta(hours=28)
802
-
803
- if endTime - timedelta(hours=query_hours) > startTime:
804
- time_diff = endTime - startTime
805
- midpointTime = startTime + time_diff / 2
806
- # recursively construct the df
807
- df_1 = tb_api_to_df(config, startTime, midpointTime, create_csv=False, query_hours=query_hours)
808
- df_2 = tb_api_to_df(config, midpointTime, endTime, create_csv=False, query_hours=query_hours)
809
- df = pd.concat([df_1, df_2])
810
- df = df.sort_index()
811
- df = df.groupby(df.index).mean()
812
- if create_csv:
813
- filename = f"{startTime.strftime('%Y%m%d%H%M%S')}.csv"
814
- original_directory = os.getcwd()
815
- os.chdir(config.data_directory)
816
- df.to_csv(filename, index_label='time_pt')
817
- os.chdir(original_directory)
818
-
819
- return df
820
- url = f'https://thingsboard.cloud/api/plugins/telemetry/DEVICE/{config.api_device_id}/values/timeseries'
821
- token = config.get_thingsboard_token()
822
- keys = _get_tb_keys(config, token)
823
- if len(keys) <= 0:
824
- raise Exception(f"No sensors available at ThingsBoard site with id {config.api_device_id}")
825
- key_string = ','.join(keys)
826
- params = {
827
- 'keys': key_string,
828
- 'startTs': f'{int(startTime.timestamp())*1000}',
829
- 'endTs': f'{int(endTime.timestamp())*1000}',
830
- 'orderBy': 'ASC',
831
- 'useStrictDataTypes': 'false'
832
- }
833
-
834
- # Headers
835
- headers = {
836
- 'accept': 'application/json',
837
- 'X-Authorization': f'Bearer {token}'
838
- }
839
-
840
- try:
841
- response = requests.get(url, headers=headers, params=params)
842
- if response.status_code == 200:
843
- response_json = response.json()
844
- data = {}
845
- for key, records in response_json.items():
846
- try:
847
- series = pd.Series(
848
- data={record['ts']: float(record['value']) for record in records}
849
- )
850
- data[key] = series
851
- except:
852
- print_statement = f"Could not convert {key} values to floats."
853
- # print(print_statement)
854
- df = pd.DataFrame(data)
855
- df.index = pd.to_datetime(df.index, unit='ms')
798
+ df = pd.DataFrame()
799
+ if len(sensor_keys) <= 0:
800
+ token = config.get_thingsboard_token()
801
+ key_list = _get_tb_keys(config, token)
802
+ if len(key_list) <= 0:
803
+ raise Exception(f"No sensors available at ThingsBoard site with id {config.api_device_id}")
804
+ return tb_api_to_df(config, startTime, endTime, create_csv, query_hours, key_list, seperate_keys)
805
+ if seperate_keys:
806
+ df_list = []
807
+ for sensor_key in sensor_keys:
808
+ df_list.append(tb_api_to_df(config, startTime, endTime, False, query_hours, [sensor_key], False))
809
+ df = pd.concat(df_list)
810
+ else:
811
+ # not seperate_keys:
812
+ if endTime is None:
813
+ endTime = datetime.now()
814
+ if startTime is None:
815
+ # 28 hours to ensure encapsulation of last day
816
+ startTime = endTime - timedelta(hours=28)
817
+
818
+ if endTime - timedelta(hours=query_hours) > startTime:
819
+ time_diff = endTime - startTime
820
+ midpointTime = startTime + time_diff / 2
821
+ 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)
822
+ 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)
823
+ df = pd.concat([df_1, df_2])
856
824
  df = df.sort_index()
857
- # save to file
858
- if create_csv:
859
- filename = f"{startTime.strftime('%Y%m%d%H%M%S')}.csv"
860
- original_directory = os.getcwd()
861
- os.chdir(config.data_directory)
862
- df.to_csv(filename, index_label='time_pt')
863
- os.chdir(original_directory)
864
- return df
865
- print(f"Failed to make GET request. Status code: {response.status_code} {response.json()}")
866
- return pd.DataFrame()
867
- except Exception as e:
868
- traceback.print_exc()
869
- print(f"An error occurred: {e}")
870
- return pd.DataFrame()
825
+ df = df.groupby(df.index).mean()
826
+ else:
827
+ url = f'https://thingsboard.cloud/api/plugins/telemetry/DEVICE/{config.api_device_id}/values/timeseries'
828
+ token = config.get_thingsboard_token()
829
+ key_string = ','.join(sensor_keys)
830
+ params = {
831
+ 'keys': key_string,
832
+ 'startTs': f'{int(startTime.timestamp())*1000}',
833
+ 'endTs': f'{int(endTime.timestamp())*1000}',
834
+ 'orderBy': 'ASC',
835
+ 'useStrictDataTypes': 'false',
836
+ 'interval' : '0',
837
+ 'agg' : 'NONE'
838
+ }
839
+
840
+ # Headers
841
+ headers = {
842
+ 'accept': 'application/json',
843
+ 'X-Authorization': f'Bearer {token}'
844
+ }
845
+
846
+ try:
847
+ response = requests.get(url, headers=headers, params=params)
848
+ if response.status_code == 200:
849
+ response_json = response.json()
850
+ # if create_csv:
851
+ # json_filename = f"{startTime.strftime('%Y%m%d%H%M%S')}.json"
852
+ # print(f"filename: {json_filename}, url: {url}, params: {params}")
853
+ # original_directory = os.getcwd()
854
+ # os.chdir(config.data_directory)
855
+ # with open(json_filename, 'w') as f:
856
+ # json.dump(response_json, f, indent=4) # indent=4 makes it human-readable
857
+ # os.chdir(original_directory)
858
+
859
+ data = {}
860
+ for key, records in response_json.items():
861
+ try:
862
+ series = pd.Series(
863
+ data={record['ts']: _get_float_value(record['value']) for record in records}
864
+ )
865
+ data[key] = series
866
+ except:
867
+ print_statement = f"Could not convert {key} values to floats."
868
+ print(print_statement)
869
+ df = pd.DataFrame(data)
870
+ df.index = pd.to_datetime(df.index, unit='ms')
871
+ df = df.sort_index()
872
+ else:
873
+ print(f"Failed to make GET request. Status code: {response.status_code} {response.json()}")
874
+ df = pd.DataFrame()
875
+ except Exception as e:
876
+ traceback.print_exc()
877
+ print(f"An error occurred: {e}")
878
+ df = pd.DataFrame()
879
+ # save to file
880
+ if create_csv:
881
+ filename = f"{startTime.strftime('%Y%m%d%H%M%S')}.csv"
882
+ original_directory = os.getcwd()
883
+ os.chdir(config.data_directory)
884
+ df.to_csv(filename, index_label='time_pt')
885
+ os.chdir(original_directory)
886
+ return df
887
+
888
+ def _get_float_value(value):
889
+ try:
890
+ ret_val = float(value)
891
+ return ret_val
892
+ except (ValueError, TypeError):
893
+ return None
871
894
 
872
895
  def _get_tb_keys(config: ConfigManager, token : str) -> List[str]:
873
896
  url = f'https://thingsboard.cloud/api/plugins/telemetry/DEVICE/{config.api_device_id}/keys/timeseries'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ecopipeline
3
- Version: 0.8.11
3
+ Version: 0.8.12
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)
File without changes
File without changes
File without changes