Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import plotly.express as px | |
import numpy as np | |
import time | |
# Simulated data (you can replace this with data from salesforce_integration.py or simulator.py) | |
def generate_mock_data(n=100): | |
np.random.seed(42) | |
data = { | |
"PoleID": [f"Pole_{i:05}" for i in range(n)], | |
"Site": np.random.choice(["Site 1", "Site 2", "Site 3", "Site 4"], n), | |
"SolarGen(kWh)": np.random.uniform(2.0, 6.0, n), | |
"WindGen(kWh)": np.random.uniform(0.5, 2.0, n), | |
"Tilt(Β°)": np.random.uniform(0, 15, n), | |
"Vibration(g)": np.random.uniform(0, 3, n), | |
"CameraStatus": np.random.choice(["Online", "Offline"], n), | |
"PowerSufficient": np.random.choice(["Yes", "No"], n), | |
} | |
df = pd.DataFrame(data) | |
# Rule-based alert level | |
df["Anomalies"] = df.apply(lambda row: [ | |
"LowSolarOutput" if row["SolarGen(kWh)"] < 4.0 else "", | |
"LowWindOutput" if row["WindGen(kWh)"] < 0.7 else "", | |
"PoleTiltRisk" if row["Tilt(Β°)"] > 10 else "", | |
"VibrationAlert" if row["Vibration(g)"] > 2.0 else "", | |
"CameraOffline" if row["CameraStatus"] == "Offline" else "", | |
"PowerInsufficient" if row["PowerSufficient"] == "No" else "", | |
], axis=1) | |
df["Anomalies"] = df["Anomalies"].apply(lambda x: [a for a in x if a]) | |
df["AlertLevel"] = df["Anomalies"].apply(lambda x: "Green" if len(x) == 0 else "Yellow" if len(x) == 1 else "Red") | |
return df | |
# Visuals | |
def show_heatmap(df): | |
st.subheader("π‘οΈ Fault Distribution Heatmap") | |
map_data = df.groupby(['Site', 'AlertLevel']).size().reset_index(name="Count") | |
fig = px.density_heatmap( | |
map_data, x="Site", y="AlertLevel", z="Count", color_continuous_scale="Reds", title="Alerts per Site" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
def show_red_alerts(df): | |
st.subheader("π¨ Blinking Red Alert Poles") | |
red_df = df[df["AlertLevel"] == "Red"] | |
if red_df.empty: | |
st.success("No red alerts right now!") | |
return | |
for _, row in red_df.iterrows(): | |
with st.container(): | |
st.markdown( | |
f"<div style='padding:8px; background-color:#ffcccc; animation: blink 1s infinite;'>" | |
f"<strong>{row['PoleID']}</strong>: {', '.join(row['Anomalies'])}</div>", | |
unsafe_allow_html=True | |
) | |
st.markdown( | |
""" | |
<style> | |
@keyframes blink { | |
50% { background-color: #ff4d4d; } | |
} | |
</style> | |
""", | |
unsafe_allow_html=True | |
) | |
# Main | |
st.set_page_config("VIEP Heatmap Dashboard", layout="wide") | |
st.title("π Vedavathi Smart Pole Monitoring Dashboard") | |
df = generate_mock_data() | |
# Filters | |
alert_filter = st.selectbox("Filter by Alert Level", ["All", "Green", "Yellow", "Red"]) | |
if alert_filter != "All": | |
df = df[df["AlertLevel"] == alert_filter] | |
# Views | |
show_heatmap(df) | |
show_red_alerts(df) | |