Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -69,7 +69,14 @@ with tab1:
|
|
| 69 |
on="facility_id"
|
| 70 |
)
|
| 71 |
|
| 72 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
merged_df["size"] = np.interp(merged_df["power_usage"], [150, 250], [10, 30])
|
| 74 |
merged_df["status"] = np.where(merged_df["connectivity_score"] < 50, "At Risk", "Stable")
|
| 75 |
|
|
@@ -80,40 +87,45 @@ with tab1:
|
|
| 80 |
color="status",
|
| 81 |
size="size",
|
| 82 |
hover_name="type",
|
| 83 |
-
hover_data=["connectivity_score", "power_usage"],
|
| 84 |
mapbox_style="carto-positron",
|
| 85 |
zoom=4,
|
| 86 |
color_discrete_map={"At Risk": "#e74c3c", "Stable": "#2ecc71"}
|
| 87 |
)
|
| 88 |
fig.update_layout(margin={"r":0,"t":40,"l":0,"b":0})
|
| 89 |
st.plotly_chart(fig, use_container_width=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
|
| 91 |
with tab2:
|
| 92 |
st.subheader("Energy Consumption Forecast")
|
| 93 |
|
| 94 |
-
# Time series analysis
|
| 95 |
selected_facility = st.selectbox("Select Facility", facilities["facility_id"])
|
| 96 |
facility_data = equipment[equipment["facility_id"] == selected_facility]
|
| 97 |
|
| 98 |
-
#
|
| 99 |
try:
|
| 100 |
prophet_df = facility_data.rename(columns={"timestamp": "ds", "power_usage": "y"})
|
| 101 |
model = Prophet()
|
| 102 |
model.fit(prophet_df)
|
| 103 |
-
future = model.make_future_dataframe(periods=
|
| 104 |
forecast = model.predict(future)
|
| 105 |
|
| 106 |
fig = px.line(forecast, x="ds", y="yhat",
|
| 107 |
-
title="
|
| 108 |
labels={"ds": "Time", "yhat": "Predicted Power Usage (kWh)"})
|
| 109 |
fig.add_scatter(x=prophet_df["ds"], y=prophet_df["y"], name="Actual Usage")
|
| 110 |
st.plotly_chart(fig, use_container_width=True)
|
| 111 |
except Exception as e:
|
| 112 |
st.error(f"Forecasting error: {str(e)}")
|
| 113 |
|
| 114 |
-
# ----------------------
|
| 115 |
-
# Predictive Maintenance
|
| 116 |
-
# ----------------------
|
| 117 |
with tab3:
|
| 118 |
st.subheader("Equipment Health Monitoring")
|
| 119 |
|
|
@@ -122,12 +134,19 @@ with tab3:
|
|
| 122 |
equipment["anomaly_score"] = model.decision_function(equipment[["temperature", "vibration", "power_usage"]])
|
| 123 |
equipment["needs_maintenance"] = equipment["anomaly_score"] < np.percentile(equipment["anomaly_score"], 10)
|
| 124 |
|
| 125 |
-
# Display critical alerts
|
| 126 |
critical_issues = equipment[equipment["needs_maintenance"]].merge(facilities, on="facility_id")
|
| 127 |
if not critical_issues.empty:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
st.write("🚨 Critical Maintenance Needed")
|
| 129 |
st.dataframe(
|
| 130 |
-
critical_issues[["facility_id", "type", "
|
| 131 |
hide_index=True,
|
| 132 |
column_config={
|
| 133 |
"timestamp": "Last Reading",
|
|
@@ -143,9 +162,6 @@ with tab3:
|
|
| 143 |
else:
|
| 144 |
st.success("✅ All equipment operating normally")
|
| 145 |
|
| 146 |
-
# ----------------------
|
| 147 |
-
# Cost-Benefit Analysis
|
| 148 |
-
# ----------------------
|
| 149 |
with tab4:
|
| 150 |
st.subheader("Financial & Environmental Impact")
|
| 151 |
|
|
@@ -163,7 +179,7 @@ with tab4:
|
|
| 163 |
savings = (total_power - predicted_power) * energy_cost
|
| 164 |
|
| 165 |
# Maintenance costs
|
| 166 |
-
num_issues = len(critical_issues)
|
| 167 |
maint_cost = num_issues * labor_cost * maint_duration
|
| 168 |
|
| 169 |
# Environmental impact
|
|
|
|
| 69 |
on="facility_id"
|
| 70 |
)
|
| 71 |
|
| 72 |
+
# Add AI recommendations
|
| 73 |
+
merged_df["recommendation"] = np.where(
|
| 74 |
+
merged_df["power_usage"] > 200,
|
| 75 |
+
"🛠️ Adjust router sleep cycles",
|
| 76 |
+
"✅ Stable configuration"
|
| 77 |
+
)
|
| 78 |
+
|
| 79 |
+
# Create visualization parameters
|
| 80 |
merged_df["size"] = np.interp(merged_df["power_usage"], [150, 250], [10, 30])
|
| 81 |
merged_df["status"] = np.where(merged_df["connectivity_score"] < 50, "At Risk", "Stable")
|
| 82 |
|
|
|
|
| 87 |
color="status",
|
| 88 |
size="size",
|
| 89 |
hover_name="type",
|
| 90 |
+
hover_data=["connectivity_score", "power_usage", "recommendation"],
|
| 91 |
mapbox_style="carto-positron",
|
| 92 |
zoom=4,
|
| 93 |
color_discrete_map={"At Risk": "#e74c3c", "Stable": "#2ecc71"}
|
| 94 |
)
|
| 95 |
fig.update_layout(margin={"r":0,"t":40,"l":0,"b":0})
|
| 96 |
st.plotly_chart(fig, use_container_width=True)
|
| 97 |
+
|
| 98 |
+
# Export functionality
|
| 99 |
+
csv = merged_df[["facility_id", "type", "power_usage", "recommendation"]].to_csv(index=False)
|
| 100 |
+
st.download_button(
|
| 101 |
+
"📥 Export Facility Report",
|
| 102 |
+
data=csv,
|
| 103 |
+
file_name="gridguardians_report.csv",
|
| 104 |
+
mime="text/csv"
|
| 105 |
+
)
|
| 106 |
|
| 107 |
with tab2:
|
| 108 |
st.subheader("Energy Consumption Forecast")
|
| 109 |
|
|
|
|
| 110 |
selected_facility = st.selectbox("Select Facility", facilities["facility_id"])
|
| 111 |
facility_data = equipment[equipment["facility_id"] == selected_facility]
|
| 112 |
|
| 113 |
+
# Enhanced 72-hour forecast
|
| 114 |
try:
|
| 115 |
prophet_df = facility_data.rename(columns={"timestamp": "ds", "power_usage": "y"})
|
| 116 |
model = Prophet()
|
| 117 |
model.fit(prophet_df)
|
| 118 |
+
future = model.make_future_dataframe(periods=72, freq="H") # 72-hour forecast
|
| 119 |
forecast = model.predict(future)
|
| 120 |
|
| 121 |
fig = px.line(forecast, x="ds", y="yhat",
|
| 122 |
+
title="72-Hour Power Usage Forecast",
|
| 123 |
labels={"ds": "Time", "yhat": "Predicted Power Usage (kWh)"})
|
| 124 |
fig.add_scatter(x=prophet_df["ds"], y=prophet_df["y"], name="Actual Usage")
|
| 125 |
st.plotly_chart(fig, use_container_width=True)
|
| 126 |
except Exception as e:
|
| 127 |
st.error(f"Forecasting error: {str(e)}")
|
| 128 |
|
|
|
|
|
|
|
|
|
|
| 129 |
with tab3:
|
| 130 |
st.subheader("Equipment Health Monitoring")
|
| 131 |
|
|
|
|
| 134 |
equipment["anomaly_score"] = model.decision_function(equipment[["temperature", "vibration", "power_usage"]])
|
| 135 |
equipment["needs_maintenance"] = equipment["anomaly_score"] < np.percentile(equipment["anomaly_score"], 10)
|
| 136 |
|
| 137 |
+
# Display critical alerts with priority
|
| 138 |
critical_issues = equipment[equipment["needs_maintenance"]].merge(facilities, on="facility_id")
|
| 139 |
if not critical_issues.empty:
|
| 140 |
+
# Calculate priority scores
|
| 141 |
+
critical_issues["priority"] = np.interp(
|
| 142 |
+
critical_issues["anomaly_score"],
|
| 143 |
+
[critical_issues["anomaly_score"].min(), critical_issues["anomaly_score"].max()],
|
| 144 |
+
[1, 10]
|
| 145 |
+
).astype(int)
|
| 146 |
+
|
| 147 |
st.write("🚨 Critical Maintenance Needed")
|
| 148 |
st.dataframe(
|
| 149 |
+
critical_issues.sort_values("priority", ascending=False)[["facility_id", "type", "priority", "timestamp", "temperature"]],
|
| 150 |
hide_index=True,
|
| 151 |
column_config={
|
| 152 |
"timestamp": "Last Reading",
|
|
|
|
| 162 |
else:
|
| 163 |
st.success("✅ All equipment operating normally")
|
| 164 |
|
|
|
|
|
|
|
|
|
|
| 165 |
with tab4:
|
| 166 |
st.subheader("Financial & Environmental Impact")
|
| 167 |
|
|
|
|
| 179 |
savings = (total_power - predicted_power) * energy_cost
|
| 180 |
|
| 181 |
# Maintenance costs
|
| 182 |
+
num_issues = len(critical_issues) if 'critical_issues' in locals() else 0
|
| 183 |
maint_cost = num_issues * labor_cost * maint_duration
|
| 184 |
|
| 185 |
# Environmental impact
|