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": "Pole ID: {Pole ID}
"
"Location: {Location Area}
"
"Purpose: {Purpose}
"
"Health Score: {Health Score}
"
"Alert Level: {Alert Level}
"
"Camera: {Camera Status}
"
"Power: {Power Status}
"
"Anomaly: {Anomalies}",
"style": {"color": "white", "backgroundColor": "black"}
}
))
# ---- Data Table ----
st.subheader("π Detailed Pole Information")
st.dataframe(filtered_df, use_container_width=True)