Spaces:
Sleeping
Sleeping
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) | |