OlamideKayode commited on
Commit
12763b7
ยท
verified ยท
1 Parent(s): 3780227

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -35
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import os
2
  import time
3
  import pandas as pd
@@ -6,6 +7,9 @@ import joblib
6
  import requests
7
  import streamlit as st
8
  from streamlit_autorefresh import st_autorefresh
 
 
 
9
 
10
  # Auto-refresh every 5 seconds
11
  st_autorefresh(interval=5000, key="refresh")
@@ -62,12 +66,12 @@ def get_next_row():
62
 
63
  # Feature engineering
64
  def engineer(df):
65
- # Handle timestamp
66
  if pd.api.types.is_numeric_dtype(df["timestamp"]):
67
  df["datetime"] = pd.to_datetime(df["timestamp"], unit="s")
68
  else:
69
  df["datetime"] = pd.to_datetime(df["timestamp"])
70
 
 
71
  df["hour_of_day"] = df["datetime"].dt.hour
72
  df["lag_30min"] = df["power_consumption_kwh"].shift(1)
73
  df["lag_1h"] = df["power_consumption_kwh"].shift(2)
@@ -77,17 +81,11 @@ def engineer(df):
77
  df["hour_sin"] = np.sin(2 * np.pi * df["hour_of_day"] / 24)
78
  df["hour_cos"] = np.cos(2 * np.pi * df["hour_of_day"] / 24)
79
 
80
- # One-hot encode property_type and region
81
  df = pd.get_dummies(df, columns=["property_type", "region"], drop_first=False)
82
 
83
-
84
-
85
- # Ensure all expected features exist
86
  expected_features = [
87
- 'lag_30min', 'lag_1h',
88
- 'rolling_avg_1h', 'rolling_avg_2h',
89
- 'hour_of_day', 'is_weekend',
90
- 'hour_sin', 'hour_cos',
91
  'temperature_c', 'ev_owner', 'solar_installed',
92
  'property_type_commercial', 'property_type_residential',
93
  'region_north', 'region_south', 'region_east', 'region_west'
@@ -99,37 +97,68 @@ def engineer(df):
99
 
100
  return df
101
 
102
- # UI layout
103
- st.title("โšก Gridflux: Live Smart-Meter Forecast")
104
-
105
- placeholder_chart = st.empty()
106
- placeholder_metric = st.empty()
107
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  new_row = get_next_row()
109
-
110
  if not new_row.empty:
111
  st.session_state.history = pd.concat([st.session_state.history, new_row], ignore_index=True)
112
  df_feat = engineer(st.session_state.history).dropna()
113
-
114
  if not df_feat.empty:
115
- latest_input = df_feat.iloc[[-1]][[
116
- 'lag_30min', 'lag_1h',
117
- 'rolling_avg_1h', 'rolling_avg_2h',
118
- 'hour_of_day', 'is_weekend',
119
- 'hour_sin', 'hour_cos',
120
- 'temperature_c', 'ev_owner', 'solar_installed',
121
- 'property_type_commercial', 'property_type_residential',
122
- 'region_north', 'region_south', 'region_east', 'region_west'
123
- ]]
124
-
125
  prediction = model.predict(latest_input)[0]
126
-
127
- # Show outputs
128
- chart_df = st.session_state.history.copy()
129
- chart_df["datetime"] = pd.to_datetime(chart_df["timestamp"])
130
- chart_df.set_index("datetime", inplace=True)
131
-
132
- placeholder_chart.line_chart(chart_df["power_consumption_kwh"])
133
- placeholder_metric.metric("๐Ÿ”ฎ Predicted Power Usage (kWh)", f"{prediction:.3f}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  else:
135
  st.success("โœ… All data processed.")
 
1
+
2
  import os
3
  import time
4
  import pandas as pd
 
7
  import requests
8
  import streamlit as st
9
  from streamlit_autorefresh import st_autorefresh
10
+ from sklearn.metrics import mean_absolute_error
11
+ import plotly.express as px
12
+ import plotly.graph_objects as go
13
 
14
  # Auto-refresh every 5 seconds
15
  st_autorefresh(interval=5000, key="refresh")
 
66
 
67
  # Feature engineering
68
  def engineer(df):
 
69
  if pd.api.types.is_numeric_dtype(df["timestamp"]):
70
  df["datetime"] = pd.to_datetime(df["timestamp"], unit="s")
71
  else:
72
  df["datetime"] = pd.to_datetime(df["timestamp"])
73
 
74
+ df = df.sort_values("datetime")
75
  df["hour_of_day"] = df["datetime"].dt.hour
76
  df["lag_30min"] = df["power_consumption_kwh"].shift(1)
77
  df["lag_1h"] = df["power_consumption_kwh"].shift(2)
 
81
  df["hour_sin"] = np.sin(2 * np.pi * df["hour_of_day"] / 24)
82
  df["hour_cos"] = np.cos(2 * np.pi * df["hour_of_day"] / 24)
83
 
 
84
  df = pd.get_dummies(df, columns=["property_type", "region"], drop_first=False)
85
 
 
 
 
86
  expected_features = [
87
+ 'lag_30min', 'lag_1h', 'rolling_avg_1h', 'rolling_avg_2h',
88
+ 'hour_of_day', 'is_weekend', 'hour_sin', 'hour_cos',
 
 
89
  'temperature_c', 'ev_owner', 'solar_installed',
90
  'property_type_commercial', 'property_type_residential',
91
  'region_north', 'region_south', 'region_east', 'region_west'
 
97
 
98
  return df
99
 
100
+ # Forecast ahead logic
101
+ def forecast_next(df, model, steps=5):
102
+ forecasts = []
103
+ df_copy = df.copy()
104
+ for i in range(steps):
105
+ df_copy = engineer(df_copy).dropna()
106
+ input_row = df_copy.iloc[[-1]][[col for col in df_copy.columns if col in model.feature_names_in_]]
107
+ y_pred = model.predict(input_row)[0]
108
+ df_copy.loc[df_copy.index[-1], "power_consumption_kwh"] = y_pred
109
+ df_copy = df_copy.append({**df_copy.iloc[-1], "power_consumption_kwh": y_pred, "timestamp": df_copy.iloc[-1].timestamp + 1800}, ignore_index=True)
110
+ forecasts.append({"timestamp": df_copy.iloc[-1].timestamp, "forecast_kwh": y_pred})
111
+ return pd.DataFrame(forecasts)
112
+
113
+ # UI Layout
114
+ st.set_page_config(layout="wide")
115
+ st.title("โšก Gridflux: Real-Time Smart Meter Dashboard")
116
+
117
+ # Layout structure
118
+ col1, col2 = st.columns([2, 1])
119
+
120
+ # Data ingestion and prediction
121
  new_row = get_next_row()
 
122
  if not new_row.empty:
123
  st.session_state.history = pd.concat([st.session_state.history, new_row], ignore_index=True)
124
  df_feat = engineer(st.session_state.history).dropna()
 
125
  if not df_feat.empty:
126
+ latest_input = df_feat.iloc[[-1]][[col for col in df_feat.columns if col in model.feature_names_in_]]
 
 
 
 
 
 
 
 
 
127
  prediction = model.predict(latest_input)[0]
128
+ actual = new_row["power_consumption_kwh"].values[0]
129
+ mae = mean_absolute_error([actual], [prediction])
130
+
131
+ with col1:
132
+ st.subheader("๐Ÿ“Š Real-Time Power Usage")
133
+ chart_df = st.session_state.history.copy()
134
+ chart_df["datetime"] = pd.to_datetime(chart_df["timestamp"])
135
+ chart_df.set_index("datetime", inplace=True)
136
+ st.line_chart(chart_df["power_consumption_kwh"], use_container_width=True)
137
+
138
+ st.subheader("๐Ÿ”ฎ Forecast (Next 2.5 Hours)")
139
+ future_df = forecast_next(df_feat, model, steps=5)
140
+ future_df["datetime"] = pd.to_datetime(future_df["timestamp"])
141
+ fig = px.line(future_df, x="datetime", y="forecast_kwh", title="Forecasted Power Usage (Next 2.5h)")
142
+ st.plotly_chart(fig, use_container_width=True)
143
+
144
+ with col2:
145
+ st.metric("๐Ÿ”ฎ Predicted Power Usage (kWh)", f"{prediction:.3f}")
146
+ st.metric("โœ… Actual Power Usage (kWh)", f"{actual:.3f}")
147
+ st.metric("๐Ÿ“ MAE", f"{mae:.3f}")
148
+
149
+ st.subheader("๐ŸŒ Region-Wise Forecast")
150
+ for region in ["east", "west", "north", "south"]:
151
+ regional = df_feat[df_feat[f"region_{region}"] == 1]
152
+ if not regional.empty:
153
+ pred = model.predict(regional[[col for col in regional.columns if col in model.feature_names_in_]])
154
+ st.write(f"**{region.title()} Region**: Avg Forecast: {np.mean(pred):.3f} kWh")
155
+
156
+ st.subheader("๐Ÿ  Property Type Forecast")
157
+ for region in ["east", "west", "north", "south"]:
158
+ for ptype in ["commercial", "residential"]:
159
+ filtered = df_feat[(df_feat[f"region_{region}"] == 1) & (df_feat[f"property_type_{ptype}"] == 1)]
160
+ if not filtered.empty:
161
+ preds = model.predict(filtered[[col for col in filtered.columns if col in model.feature_names_in_]])
162
+ st.write(f"{region.title()} / {ptype.title()}: {np.mean(preds):.2f} kWh")
163
  else:
164
  st.success("โœ… All data processed.")