|
import streamlit as st |
|
import pandas as pd |
|
import plotly.express as px |
|
import plotly.graph_objects as go |
|
from salesforce_integration import fetch_poles |
|
|
|
|
|
st.title("π‘ VIEP Smart Poles Dashboard") |
|
|
|
|
|
df = fetch_poles() |
|
|
|
|
|
st.sidebar.header("π Filter Data") |
|
|
|
|
|
alert_levels = df["Alert_Level__c"].dropna().unique().tolist() |
|
sites = df["Site__c"].dropna().unique().tolist() |
|
camera_statuses = df["Camera_Status__c"].dropna().unique().tolist() |
|
|
|
selected_alert_levels = st.sidebar.multiselect("Alert Level", alert_levels, default=alert_levels) |
|
selected_sites = st.sidebar.multiselect("Site", sites, default=sites) |
|
selected_camera_status = st.sidebar.selectbox("Camera Status", ["All"] + camera_statuses) |
|
|
|
|
|
filtered_df = df[ |
|
(df["Alert_Level__c"].isin(selected_alert_levels)) & |
|
(df["Site__c"].isin(selected_sites)) |
|
] |
|
|
|
if selected_camera_status != "All": |
|
filtered_df = filtered_df[filtered_df["Camera_Status__c"] == selected_camera_status] |
|
|
|
|
|
st.subheader("π System Summary") |
|
st.metric("Total Poles", len(filtered_df)) |
|
st.metric("Red Alerts", len(filtered_df[filtered_df["Alert_Level__c"] == "Red"])) |
|
st.metric("Offline Cameras", len(filtered_df[filtered_df["Camera_Status__c"] == "Offline"])) |
|
|
|
|
|
st.subheader("π Pole Table") |
|
st.dataframe(filtered_df, use_container_width=True) |
|
|
|
|
|
st.subheader("β Energy Generation (Solar vs Wind)") |
|
if not filtered_df.empty: |
|
energy_chart = px.bar( |
|
filtered_df, |
|
x="Name", |
|
y=["Solar_Generation__c", "Wind_Generation__c"], |
|
barmode="group", |
|
title="Solar vs Wind Energy Generation" |
|
) |
|
st.plotly_chart(energy_chart, use_container_width=True) |
|
else: |
|
st.info("No data available for the selected filters.") |
|
|
|
|
|
st.subheader("π¨ Alert Level Breakdown") |
|
if not filtered_df.empty: |
|
alert_counts = filtered_df["Alert_Level__c"].value_counts().reset_index() |
|
alert_counts.columns = ["Alert Level", "Count"] |
|
alert_pie = px.pie(alert_counts, values="Count", names="Alert Level", title="Alert Distribution") |
|
st.plotly_chart(alert_pie, use_container_width=True) |
|
else: |
|
st.info("No alerts to display.") |
|
|
|
|
|
st.subheader("π Tilt & Vibration from RFID") |
|
|
|
filtered_df["Tilt"] = filtered_df["RFID_Tag__c"].str.extract(r'Tilt[:=](\d+)').astype(float) |
|
filtered_df["Vibration"] = filtered_df["RFID_Tag__c"].str.extract(r'Vib[:=](\d+)').astype(float) |
|
|
|
if not filtered_df[["Tilt", "Vibration"]].dropna().empty: |
|
fig = go.Figure() |
|
fig.add_trace(go.Scatter(x=filtered_df["Name"], y=filtered_df["Tilt"], |
|
mode='lines+markers', name='Tilt')) |
|
fig.add_trace(go.Scatter(x=filtered_df["Name"], y=filtered_df["Vibration"], |
|
mode='lines+markers', name='Vibration')) |
|
fig.update_layout(title="Tilt and Vibration per Pole", xaxis_title="Pole", yaxis_title="Value") |
|
st.plotly_chart(fig, use_container_width=True) |
|
else: |
|
st.info("No Tilt or Vibration data available.") |
|
|