Coverage for aixweather/imports/ERC.py: 22%

50 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2025-01-06 16:01 +0000

1""" 

2contains functions to handle data within ERC 

3""" 

4 

5from tkinter import * 

6import json 

7import pandas as pd 

8from datetime import datetime 

9 

10import requests 

11 

12from aixweather.imports.utils_import import MetaData 

13 

14key_list = [ 

15 "4121.weatherstation.temperature", 

16 "4121.weatherstation.diffuse-radiation", 

17 "4121.weatherstation.global-radiation", 

18 "4121.weatherstation.pressure", 

19 "4121.weatherstation.rainfall", 

20 "4121.weatherstation.relative-humidity", 

21 "4121.weatherstation.wind-direction", 

22 "4121.weatherstation.wind-speed", 

23] 

24 

25 

26def load_credentials_ERC_weather_data() -> tuple: 

27 """ 

28 GUI to return the username and password needed to access ERC weather data. 

29 

30 Returns: 

31 tuple: The username and password required for accessing ERC weather data. 

32 """ 

33 

34 

35 tk_window = Tk() 

36 tk_window.geometry("400x150") 

37 tk_window.title( 

38 "ERC is a private database, credentials are required to acquire the data" 

39 ) 

40 

41 # username label and text entry box 

42 username_label = Label(tk_window, text="User Name").grid(row=0, column=0) 

43 username = StringVar() 

44 username_entry = Entry(tk_window, textvariable=username).grid(row=0, column=1) 

45 

46 # password label and password entry box 

47 password_label = Label(tk_window, text="Password").grid(row=1, column=0) 

48 password = StringVar() 

49 password_entry = Entry(tk_window, textvariable=password, show="*").grid( 

50 row=1, column=1 

51 ) 

52 # login button 

53 login_button = Button(tk_window, text="Login", command=tk_window.destroy).grid( 

54 row=4, column=0 

55 ) 

56 

57 tk_window.mainloop() 

58 

59 return (username.get(), password.get()) 

60 

61 

62def import_ERC(start: datetime, stop: datetime, cred: tuple) -> pd.DataFrame: 

63 """ 

64 Import weather data from aedifion ERC weather station (credentials required). 

65 

66 Args: 

67 start (datetime): Datetime object representing the data start. 

68 stop (datetime): Datetime object representing the data stop. 

69 cred (tuple): Aedifion credentials. 

70 

71 Returns: 

72 pd.DataFrame: DataFrame containing as raw as possible weather data from aedifion ERC. 

73 """ 

74 

75 # import cred if not given 

76 if cred is None: 

77 cred = load_credentials_ERC_weather_data() 

78 

79 weather_df_tot = pd.DataFrame() 

80 

81 for key in key_list: 

82 request = { 

83 "project_id": 37, # 11 refers to data older than February 2024 

84 "dataPointID": key, 

85 "start": start, 

86 "end": stop, 

87 "interpolation": "null", 

88 "samplerate": "1h", 

89 "short": "True", 

90 } 

91 response = requests.get( 

92 "https://api.ercebc.aedifion.io/v2/" + "datapoint/timeseries", 

93 auth=cred, 

94 params=request, 

95 ) 

96 # Check for errors 

97 response.raise_for_status() 

98 

99 # continue loading 

100 api_response = response.json() 

101 weather_df = _json2df(api_response, data_point_id=key) 

102 

103 if not weather_df.empty: 

104 if weather_df_tot.empty: 

105 # If the main DataFrame is empty, simply assign the first DataFrame to it 

106 weather_df_tot = weather_df 

107 else: 

108 weather_df_tot = pd.merge( 

109 weather_df_tot, weather_df, how="outer", left_index=True, right_index=True 

110 ) 

111 

112 return weather_df_tot 

113 

114 

115def import_meta_from_ERC() -> MetaData: 

116 """ 

117 Import (specify) metadata from ERC. 

118 

119 Returns: 

120 MetaData: A MetaData object containing station information for ERC. 

121 """ 

122 

123 meta = MetaData() 

124 meta.station_id = "ERC" 

125 meta.station_name = "Old_Experimental_Hall" 

126 meta.altitude = 230 # ca. 200m + building height 30m 

127 meta.latitude = 50.7893 

128 meta.longitude = 6.0516 

129 return meta 

130 

131 

132def _json2df( 

133 data: json = None, data_point_id: str = None, short: bool = True 

134) -> pd.DataFrame: 

135 """ 

136 Transform the JSON returned by GET /v2/datapoint/timeseries to a Pandas DataFrame 

137 indexed by time. 

138 

139 Args: 

140 data (json): The JSON data to be transformed into a DataFrame. 

141 data_point_id (str): Use dataPointID as the column name for values (default: value). 

142 short (bool): Whether the given JSON is in short format or not. 

143 

144 Returns: 

145 pd.DataFrame: A Pandas DataFrame containing the transformed data. 

146 """ 

147 if short: 

148 data = [[pd.to_datetime(t[0], utc=True), t[1]] for t in data] 

149 else: 

150 data = [[pd.to_datetime(t["time"], utc=True), t["value"]] for t in data["data"]] 

151 dataframe = pd.DataFrame(data, columns=["Time", data_point_id or "Value"]) 

152 dataframe = dataframe.set_index("Time") 

153 return dataframe