Redhotchilipoppy commited on
Commit
be6ba39
2 Parent(s): c182e60 724eb6a

Merge branch 'main' of https://huggingface.co/spaces/Redhotchilipoppy/solprognos

Browse files
Files changed (1) hide show
  1. app.py +164 -164
app.py CHANGED
@@ -1,165 +1,165 @@
1
- # Import gradio
2
- import gradio as gr
3
-
4
- # Data import from open-meteo.com
5
- import openmeteo_requests
6
- import requests_cache
7
- from retry_requests import retry
8
-
9
- # Data management and visualization
10
- import pandas as pd
11
- import numpy as np
12
- import datetime
13
- import pickle
14
- import matplotlib
15
- import matplotlib.pyplot as plt
16
- import matplotlib.dates as mdates
17
-
18
- # Machine Learning
19
- import sklearn
20
-
21
- # Print version info
22
- print("Version info:")
23
- print('pandas: %s' % pd.__version__)
24
- print('numpy: %s' % np.__version__)
25
- print('sklearn: %s' % sklearn.__version__)
26
- print(" ")
27
-
28
-
29
- def makeprediction():
30
- #%% 1. User Inputs
31
- # These inputs may be changed by the user
32
- model_file_name = "Solar RF Model_2024-01-03T08-53-53_.pkl" # This is the name of the file generated by the script "Build_solar_RF_model.py" (must be located in same folder)
33
- horizon = 2 # Forecast horizon in days, limit is 16 days.
34
- # Note that the further we look into the future, the less accurate the weather forecast is likely to be
35
- PV_capacity = 15 # The maximum capacity of your PV installation in kW, only used for plotting.
36
-
37
- #%% 2. Read Model
38
- # Read in the model
39
- f_model = open(model_file_name, 'rb') # Opens the file
40
- model_dict = pickle.load(f_model) # Reads the dictionary from the file
41
- f_model.close() # closes the file again
42
-
43
- #%% 3. Fetch weather forecast
44
-
45
- # Setup the Open-Meteo API client with cache and retry on error
46
- cache_session = requests_cache.CachedSession('.cache', expire_after = -1)
47
- retry_session = retry(cache_session, retries = 5, backoff_factor = 0.2)
48
- openmeteo = openmeteo_requests.Client(session = retry_session)
49
-
50
- # Make sure all required weather variables are listed here
51
- url = "https://api.open-meteo.com/v1/forecast"
52
-
53
- # Calcualte start and end date
54
- start_date = datetime.datetime.now()
55
- end_date = start_date + datetime.timedelta(days=horizon)
56
- sdate_str = str(start_date)[0:10] # First date in file as string (yyyy-mm-dd)
57
- edate_str = str(end_date)[0:10] # Last date in file as string (yyyy-mm-dd)
58
-
59
- # Use the same parameters as was used for training the model.
60
- params = {
61
- "latitude": model_dict['API Request Params']['latitude'],
62
- "longitude": model_dict['API Request Params']['longitude'],
63
- "hourly": model_dict['API Request Params']['hourly'],
64
- "start_date": sdate_str,
65
- "end_date": edate_str,
66
- }
67
- responses = openmeteo.weather_api(url, params=params)
68
-
69
- # Process & print request info.
70
- response = responses[0]
71
- print("Request info:")
72
- print(f"Coordinates {response.Latitude()}°E {response.Longitude()}°N")
73
- print(f"Elevation {response.Elevation()} m asl")
74
- print(f"Timezone {response.Timezone()} {response.TimezoneAbbreviation()}")
75
- print(f"Timezone difference to GMT+0 {response.UtcOffsetSeconds()} s")
76
- #print(f"From: " + sdate_str + " To: " + edate_str)
77
- print(" ")
78
-
79
- # Process hourly data. The order of variables needs to be the same as requested.
80
- hourly = response.Hourly() # API Response
81
- hourly_data = {"date": pd.date_range( # Dictionary that we add the API respnse to
82
- start = pd.to_datetime(hourly.Time(), unit = "s"),
83
- end = pd.to_datetime(hourly.TimeEnd(), unit = "s"),
84
- freq = pd.Timedelta(seconds = hourly.Interval()),
85
- inclusive = "left"
86
- )}
87
-
88
- # We iterate through the variables and add the API response data to our dictionary
89
- print("Adding variables to dataframe...")
90
- index_variable = 0
91
- for variable in params['hourly']:
92
- hourly_data[variable] = hourly.Variables(index_variable).ValuesAsNumpy() # Add the variable to dataframe
93
- print("Added " + variable)
94
- index_variable += 1 # Increment counter
95
-
96
- print(" ")
97
- # Create dataframe
98
- weather_data = pd.DataFrame(data = hourly_data)
99
- weather_data = weather_data.set_index('date') # Set index to be dates
100
-
101
- #%% 4. Data manipulation & encoding
102
- # Create a new dataframe to hold all data, also encode new features.
103
-
104
- # Create a main dataframe that holds all data
105
- main_df = weather_data.copy()
106
-
107
- for index, row in main_df.iterrows():
108
- main_df.loc[index,'month'] = index.month
109
- main_df.loc[index,'day'] = index.day
110
- main_df.loc[index,'hour'] = index.hour
111
- main_df.loc[index,'sine month'] = np.sin((index.month - 1)*np.pi/11)
112
- main_df.loc[index,'cos month'] = np.cos((index.month - 1)*np.pi/11)
113
- main_df.loc[index,'sine hour'] = np.sin((index.month - 1)*np.pi/23)
114
- main_df.loc[index,'cos hour'] = np.cos((index.month - 1)*np.pi/23)
115
-
116
- # Index to keep track of which hours the sun is up for.
117
- Sun_index = main_df[main_df['is_day'] == 1].index
118
-
119
- # Create a new dataframe with only relevant data, this will be used for statistical
120
- sun_is_up_data = main_df.copy() # Create copy
121
- sun_is_up_data = sun_is_up_data.loc[Sun_index] # Only include rows when the sun is up
122
- sun_is_up_data = sun_is_up_data[model_dict['Input features']] # Only include columns needed for model
123
-
124
-
125
- #%% 5. Make Predictions
126
- print("Making predictions...")
127
- # Create dataframe to hold predictions and initialize with 0.
128
- predictions = pd.DataFrame(0, index = weather_data.index, columns = ['Main Forecast', 'Lower Bound', 'Upper Bound'])
129
- predictions['Date'] = predictions.index.tolist() # Make dates also to a column for easier plotting
130
-
131
- # Make predictions
132
- predictions.loc[Sun_index,'Main Forecast'] = model_dict['Random Forest Model'].predict(sun_is_up_data)
133
- predictions.loc[Sun_index,['Lower Bound', 'Upper Bound']] = model_dict['Random Forest Quantile Model'].predict(sun_is_up_data, quantiles=[0.1, 0.9], interpolation='linear')
134
- print(" ")
135
- #%% 6. Make Plot
136
-
137
- # Plotting
138
- plt.style.use('_mpl-gallery') # Set plot style
139
- matplotlib.rc('font', **{'size' : 20}) # Change font size
140
- fig, ax = plt.subplots() # Create plot
141
- fig.set_size_inches(18.5, 10.5, forward=True) # Set figure size
142
- fig.set_dpi(100) # Set resolution
143
- ax.fill_between(predictions['Date'], predictions['Lower Bound'], predictions['Upper Bound'], alpha=.5, linewidth=0) # Plot prediction interval
144
- ax.plot(predictions['Date'], predictions['Main Forecast'], linewidth=4, color='black') # Plot main forecast
145
-
146
- # Calculate x-ticks
147
- step_length = int(predictions.shape[0]/32)
148
- ax.set(ylim = [0,PV_capacity*1.05], xticks = predictions['Date'].iloc[::step_length])
149
- ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d %H:%M'))
150
- plt.ylabel('Solar power [kW]')
151
- plt.xticks(rotation=90)
152
- plt.legend(['Prediction Interval (10 - 90%)', 'Main Forecast'])
153
- plt.title('Solar Power Forecast from ' + sdate_str + ' to ' + edate_str)
154
- # plt.show()
155
-
156
- return fig
157
-
158
-
159
- def greet(name):
160
- return "Hello " + name + "!!"
161
-
162
-
163
-
164
- iface = gr.Interface(fn=makeprediction, inputs=None, outputs=gr.Plot())
165
  iface.launch()
 
1
+ # Import gradio
2
+ import gradio as gr
3
+
4
+ # Data import from open-meteo.com
5
+ import openmeteo_requests
6
+ import requests_cache
7
+ from retry_requests import retry
8
+
9
+ # Data management and visualization
10
+ import pandas as pd
11
+ import numpy as np
12
+ import datetime
13
+ import pickle
14
+ import matplotlib
15
+ import matplotlib.pyplot as plt
16
+ import matplotlib.dates as mdates
17
+
18
+ # Machine Learning
19
+ import sklearn
20
+
21
+ # Print version info
22
+ print("Version info:")
23
+ print('pandas: %s' % pd.__version__)
24
+ print('numpy: %s' % np.__version__)
25
+ print('sklearn: %s' % sklearn.__version__)
26
+ print(" ")
27
+
28
+
29
+ def makeprediction():
30
+ #%% 1. User Inputs
31
+ # These inputs may be changed by the user
32
+ model_file_name = "Solar RF Model_2024-01-03T08-53-53_.pkl" # This is the name of the file generated by the script "Build_solar_RF_model.py" (must be located in same folder)
33
+ horizon = 2 # Forecast horizon in days, limit is 16 days.
34
+ # Note that the further we look into the future, the less accurate the weather forecast is likely to be
35
+ PV_capacity = 15 # The maximum capacity of your PV installation in kW, only used for plotting.
36
+
37
+ #%% 2. Read Model
38
+ # Read in the model
39
+ f_model = open(model_file_name, 'rb') # Opens the file
40
+ model_dict = pickle.load(f_model) # Reads the dictionary from the file
41
+ f_model.close() # closes the file again
42
+
43
+ #%% 3. Fetch weather forecast
44
+
45
+ # Setup the Open-Meteo API client with cache and retry on error
46
+ cache_session = requests_cache.CachedSession('.cache', expire_after = -1)
47
+ retry_session = retry(cache_session, retries = 5, backoff_factor = 0.2)
48
+ openmeteo = openmeteo_requests.Client(session = retry_session)
49
+
50
+ # Make sure all required weather variables are listed here
51
+ url = "https://api.open-meteo.com/v1/forecast"
52
+
53
+ # Calcualte start and end date
54
+ start_date = datetime.datetime.now()
55
+ end_date = start_date + datetime.timedelta(days=horizon)
56
+ sdate_str = str(start_date)[0:10] # First date in file as string (yyyy-mm-dd)
57
+ edate_str = str(end_date)[0:10] # Last date in file as string (yyyy-mm-dd)
58
+
59
+ # Use the same parameters as was used for training the model.
60
+ params = {
61
+ "latitude": model_dict['API Request Params']['latitude'],
62
+ "longitude": model_dict['API Request Params']['longitude'],
63
+ "hourly": model_dict['API Request Params']['hourly'],
64
+ "start_date": sdate_str,
65
+ "end_date": edate_str,
66
+ }
67
+ responses = openmeteo.weather_api(url, params=params)
68
+
69
+ # Process & print request info.
70
+ response = responses[0]
71
+ print("Request info:")
72
+ print(f"Coordinates {response.Latitude()}°E {response.Longitude()}°N")
73
+ print(f"Elevation {response.Elevation()} m asl")
74
+ print(f"Timezone {response.Timezone()} {response.TimezoneAbbreviation()}")
75
+ print(f"Timezone difference to GMT+0 {response.UtcOffsetSeconds()} s")
76
+ #print(f"From: " + sdate_str + " To: " + edate_str)
77
+ print(" ")
78
+
79
+ # Process hourly data. The order of variables needs to be the same as requested.
80
+ hourly = response.Hourly() # API Response
81
+ hourly_data = {"date": pd.date_range( # Dictionary that we add the API respnse to
82
+ start = pd.to_datetime(hourly.Time(), unit = "s"),
83
+ end = pd.to_datetime(hourly.TimeEnd(), unit = "s"),
84
+ freq = pd.Timedelta(seconds = hourly.Interval()),
85
+ inclusive = "left"
86
+ )}
87
+
88
+ # We iterate through the variables and add the API response data to our dictionary
89
+ print("Adding variables to dataframe...")
90
+ index_variable = 0
91
+ for variable in params['hourly']:
92
+ hourly_data[variable] = hourly.Variables(index_variable).ValuesAsNumpy() # Add the variable to dataframe
93
+ print("Added " + variable)
94
+ index_variable += 1 # Increment counter
95
+
96
+ print(" ")
97
+ # Create dataframe
98
+ weather_data = pd.DataFrame(data = hourly_data)
99
+ weather_data = weather_data.set_index('date') # Set index to be dates
100
+
101
+ #%% 4. Data manipulation & encoding
102
+ # Create a new dataframe to hold all data, also encode new features.
103
+
104
+ # Create a main dataframe that holds all data
105
+ main_df = weather_data.copy()
106
+
107
+ for index, row in main_df.iterrows():
108
+ main_df.loc[index,'month'] = index.month
109
+ main_df.loc[index,'day'] = index.day
110
+ main_df.loc[index,'hour'] = index.hour
111
+ main_df.loc[index,'sine month'] = np.sin((index.month - 1)*np.pi/11)
112
+ main_df.loc[index,'cos month'] = np.cos((index.month - 1)*np.pi/11)
113
+ main_df.loc[index,'sine hour'] = np.sin((index.month - 1)*np.pi/23)
114
+ main_df.loc[index,'cos hour'] = np.cos((index.month - 1)*np.pi/23)
115
+
116
+ # Index to keep track of which hours the sun is up for.
117
+ Sun_index = main_df[main_df['is_day'] == 1].index
118
+
119
+ # Create a new dataframe with only relevant data, this will be used for statistical
120
+ sun_is_up_data = main_df.copy() # Create copy
121
+ sun_is_up_data = sun_is_up_data.loc[Sun_index] # Only include rows when the sun is up
122
+ sun_is_up_data = sun_is_up_data[model_dict['Input features']] # Only include columns needed for model
123
+
124
+
125
+ #%% 5. Make Predictions
126
+ print("Making predictions...")
127
+ # Create dataframe to hold predictions and initialize with 0.
128
+ predictions = pd.DataFrame(0, index = weather_data.index, columns = ['Main Forecast', 'Lower Bound', 'Upper Bound'])
129
+ predictions['Date'] = predictions.index.tolist() # Make dates also to a column for easier plotting
130
+
131
+ # Make predictions
132
+ predictions.loc[Sun_index,'Main Forecast'] = model_dict['Random Forest Model'].predict(sun_is_up_data)
133
+ predictions.loc[Sun_index,['Lower Bound', 'Upper Bound']] = model_dict['Random Forest Quantile Model'].predict(sun_is_up_data, quantiles=[0.1, 0.9], interpolation='linear')
134
+ print(" ")
135
+ #%% 6. Make Plot
136
+
137
+ # Plotting
138
+ plt.style.use('_mpl-gallery') # Set plot style
139
+ matplotlib.rc('font', **{'size' : 20}) # Change font size
140
+ fig, ax = plt.subplots() # Create plot
141
+ fig.set_size_inches(18.5, 10.5, forward=True) # Set figure size
142
+ fig.set_dpi(100) # Set resolution
143
+ ax.fill_between(predictions['Date'], predictions['Lower Bound'], predictions['Upper Bound'], alpha=.5, linewidth=0) # Plot prediction interval
144
+ ax.plot(predictions['Date'], predictions['Main Forecast'], linewidth=4, color='black') # Plot main forecast
145
+
146
+ # Calculate x-ticks
147
+ step_length = int(predictions.shape[0]/32)
148
+ ax.set(ylim = [0,PV_capacity*1.05], xticks = predictions['Date'].iloc[::step_length])
149
+ ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d %H:%M'))
150
+ plt.ylabel('Solar power [kW]')
151
+ plt.xticks(rotation=90)
152
+ plt.legend(['Prediction Interval (10 - 90%)', 'Main Forecast'])
153
+ plt.title('Solar Power Forecast from ' + sdate_str + ' to ' + edate_str)
154
+ # plt.show()
155
+
156
+ return fig
157
+
158
+
159
+ def greet(name):
160
+ return "Hello " + name + "!!"
161
+
162
+
163
+
164
+ iface = gr.Interface(fn=makeprediction, inputs=None, outputs=gr.Plot())
165
  iface.launch()