File size: 2,947 Bytes
32841d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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)