File size: 4,398 Bytes
5095fe6
 
 
 
 
9c657f2
 
 
e13d102
9c657f2
 
 
 
e13d102
9c657f2
 
 
 
e13d102
9c657f2
 
 
 
e13d102
9c657f2
 
 
9156c8e
 
09497f1
9156c8e
e13d102
9c657f2
09497f1
e13d102
 
 
 
09497f1
9c657f2
 
09497f1
e13d102
09497f1
 
 
 
 
 
 
 
 
9c657f2
 
e13d102
 
09497f1
 
 
9c657f2
09497f1
9c657f2
 
 
09497f1
 
9156c8e
 
9c657f2
 
9156c8e
9c657f2
 
9156c8e
09497f1
 
9156c8e
9c657f2
 
 
 
 
09497f1
 
9c657f2
 
9156c8e
9c657f2
09497f1
 
 
 
 
 
 
 
 
 
9c657f2
 
09497f1
 
9c657f2
 
 
09497f1
 
 
 
 
 
 
 
9c657f2
09497f1
 
 
 
 
9c657f2
 
09497f1
 
 
e13d102
 
09497f1
 
 
9156c8e
9c657f2
 
09497f1
e13d102
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import random
import pandas as pd
import streamlit as st
import pydeck as pdk

# ---- Area-Specific Configuration ----
AREA_DETAILS = {
    "Hyderabad": {
        "coords": [17.4036, 78.5247],
        "area_name": "Ramanthapur Dairy Farm",
        "purpose": "Dairy Farm"
    },
    "Ballari": {
        "coords": [15.1468, 76.9237],
        "area_name": "Cowl Bazar Power Station",
        "purpose": "Power Station"
    },
    "Gadwal": {
        "coords": [16.2315, 77.7965],
        "area_name": "Bheem Nagar Solar Station",
        "purpose": "Solar Station"
    },
    "Kurnool": {
        "coords": [15.8281, 78.0373],
        "area_name": "Venkata Ramana Agriculture Field",
        "purpose": "Agriculture Monitoring"
    }
}

POLES_PER_SITE = 12

# ---- Generate Poles with Anomalies ----
def generate_open_area_poles(site_name, center_lat, center_lon, area, purpose):
    poles = []
    spacing = 0.0006
    anomalies_options = ['None', 'Sensor Fault', 'Overheat', 'Power Surge']
    anomaly_weights = [0.6, 0.2, 0.1, 0.1]

    for i in range(POLES_PER_SITE):
        lat = center_lat + random.uniform(-0.0002, 0.0002)
        lon = center_lon + (i - POLES_PER_SITE // 2) * spacing
        alert_level = random.choices(['Green', 'Yellow', 'Red'], weights=[6, 4, 2])[0]
        anomaly = random.choices(anomalies_options, weights=anomaly_weights)[0]

        poles.append({
            "Pole ID": f"{site_name[:3].upper()}-{i+1:03}",
            "Site": site_name,
            "Latitude": lat,
            "Longitude": lon,
            "Alert Level": alert_level,
            "Health Score": round(random.uniform(70, 100), 2),
            "Power Status": random.choice(['Sufficient', 'Insufficient']),
            "Camera Status": random.choice(['Online', 'Offline']),
            "Location Area": area,
            "Purpose": purpose,
            "Anomalies": anomaly
        })
    return poles

# ---- Prepare Full DataFrame ----
all_poles = []
for site, details in AREA_DETAILS.items():
    poles = generate_open_area_poles(site, *details['coords'], details['area_name'], details['purpose'])
    all_poles.extend(poles)

df = pd.DataFrame(all_poles)

# ---- Streamlit UI ----
st.set_page_config(page_title="Smart Pole Visual Dashboard", layout="wide")
st.title("🌐 Smart Renewable Pole Monitoring Dashboard")

site = st.selectbox("πŸ“ Select a site location:", list(AREA_DETAILS.keys()))
selected = AREA_DETAILS[site]

# ---- Filtered View ----
filtered_df = df[df["Site"] == site]

# ---- Display Site Description ----
st.markdown(f"### πŸ“Œ Location: **{selected['area_name']}**")
st.markdown(f"πŸ”§ **Poles Purpose**: {selected['purpose']}")

# ---- KPI Metrics ----
col1, col2, col3 = st.columns(3)
col1.metric("Total Poles", POLES_PER_SITE)
col2.metric("πŸ”΄ Red Alerts", filtered_df[filtered_df["Alert Level"] == "Red"].shape[0])
col3.metric("πŸ“· Offline Cameras", filtered_df[filtered_df["Camera Status"] == "Offline"].shape[0])

# ---- Alert Level to Color ----
def alert_color(alert):
    return {
        "Green": [0, 255, 0, 160],
        "Yellow": [255, 255, 0, 160],
        "Red": [255, 0, 0, 160]
    }[alert]

filtered_df = filtered_df.copy()
filtered_df["Color"] = filtered_df["Alert Level"].apply(alert_color)

# ---- Map Visualization ----
st.subheader("πŸ—ΊοΈ Pole Location & Health Status")
st.pydeck_chart(pdk.Deck(
    initial_view_state=pdk.ViewState(
        latitude=selected['coords'][0],
        longitude=selected['coords'][1],
        zoom=16.5,
        pitch=45
    ),
    layers=[
        pdk.Layer(
            "ScatterplotLayer",
            data=filtered_df,
            get_position='[Longitude, Latitude]',
            get_color='Color',
            get_radius=30,
            pickable=True
        )
    ],
    tooltip={
        "html": "<b>Pole ID:</b> {Pole ID}<br/>"
                "<b>Location:</b> {Location Area}<br/>"
                "<b>Purpose:</b> {Purpose}<br/>"
                "<b>Health Score:</b> {Health Score}<br/>"
                "<b>Alert Level:</b> {Alert Level}<br/>"
                "<b>Camera:</b> {Camera Status}<br/>"
                "<b>Power:</b> {Power Status}<br/>"
                "<b>Anomaly:</b> {Anomalies}",
        "style": {"color": "white", "backgroundColor": "black"}
    }
))

# ---- Data Table ----
st.subheader("πŸ“‹ Detailed Pole Information")
st.dataframe(filtered_df, use_container_width=True)