File size: 6,818 Bytes
eca7f1c
 
 
 
 
df1528b
eca7f1c
b74770b
eca7f1c
 
 
 
b74770b
eca7f1c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e566f9b
eca7f1c
 
e566f9b
eca7f1c
 
e566f9b
eca7f1c
 
 
 
 
 
ab0f99e
cdd127e
 
eca7f1c
 
cdd127e
eca7f1c
 
 
 
cdd127e
 
 
e566f9b
eca7f1c
 
 
 
 
 
 
e566f9b
eca7f1c
 
aeb661e
52a0c4b
aeb661e
 
 
 
 
 
 
2fc28af
85d0de7
eca7f1c
 
 
e6be835
b4d4277
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eca7f1c
 
97fc45f
 
 
eca7f1c
97fc45f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eca7f1c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e566f9b
eca7f1c
 
 
757d4c6
 
eca7f1c
757d4c6
 
a2fe131
0873766
ee8ddb9
 
 
 
 
 
 
 
 
 
 
 
 
 
69d8933
 
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import random
import pandas as pd
import streamlit as st
import pydeck as pdk
from datetime import datetime, timedelta

# ---- Constants ----
POLES_PER_SITE = 12
SITES = {
    "Hyderabad": [17.385044, 78.486671],
    "Gadwal": [16.2351, 77.8052],
    "Kurnool": [15.8281, 78.0373],
    "Ballari": [12.9716, 77.5946]
}

# ---- Helper Functions ----
def generate_location(base_lat, base_lon):
    return [
        base_lat + random.uniform(-0.02, 0.02),
        base_lon + random.uniform(-0.02, 0.02)
    ]

def simulate_pole(pole_id, site_name):
    lat, lon = generate_location(*SITES[site_name])
    solar_kwh = round(random.uniform(3.0, 7.5), 2)
    wind_kwh = round(random.uniform(0.5, 2.0), 2)
    power_required = round(random.uniform(4.0, 8.0), 2)
    total_power = solar_kwh + wind_kwh
    power_status = 'Sufficient' if total_power >= power_required else 'Insufficient'

    tilt_angle = round(random.uniform(0, 45), 2)
    vibration = round(random.uniform(0, 5), 2)
    camera_status = random.choice(['Online', 'Offline'])

    alert_level = 'Green'
    anomaly_details = []
    if tilt_angle > 30 or vibration > 3:
        alert_level = 'Yellow'
        anomaly_details.append("Tilt or Vibration threshold exceeded.")
    if tilt_angle > 40 or vibration > 4.5:
        alert_level = 'Red'
        anomaly_details.append("Critical tilt or vibration detected.")

    health_score = max(0, 100 - (tilt_angle + vibration * 10))
    timestamp = datetime.now() - timedelta(hours=random.randint(0, 6))

    return {
        'Pole ID': f'{site_name[:3].upper()}-{pole_id:03}',
        'Site': Site__c,
        'Latitude': Location_Latitude__c,
        'Longitude': Location_Longitude__c,
        'Solar (kWh)': solar_kwh,
        'Wind (kWh)': wind_kwh,
        'Power Required (kWh)': Power_Required__c,
        'Total Power (kWh)': total_power,
        'Power Status': power_status,
        'Tilt Angle (Β°)': tilt_angle,
        'Vibration (g)': vibration,
        'Camera Status': Camera_Status__c,
        'Health Score': Health_Score__c,
        'Alert Level': Alert_Level__c,
        'Anomalies': "; ".join(anomaly_details),
        'Last Checked': timestamp.strftime('%Y-%m-%d %H:%M:%S')
    }

# ---- Streamlit UI ----
st.set_page_config(page_title="Smart Pole Monitoring", layout="wide")
st.title("🌍 Smart Renewable Pole Monitoring - Multi-Site")

selected_site = st.text_input("Enter site to view (Hyderabad, Gadwal, Kurnool, Ballari):", "Hyderabad")

if selected_site in SITES:
    SITES = ['Kurnool', 'Hyderabad', 'Ballari', 'Gadwal']
    POLES_PER_SITE = 12
def simulate_pole(pole_id, site):
    return {
        'Id': f'P{pole_id}_{site[:3].upper()}',
        'Site': site,
        'Energy': round(100 + pole_id * 5.5, 2),
        'Status': 'OK'
    }
with st.spinner(f"Simulating poles at {selected_site}..."):
        poles_data = [simulate_pole(i + 1, site) for site in SITES for i in range(POLES_PER_SITE)]
        df = pd.DataFrame(poles_data)
        site_df = df[df['Site'] == selected_site]

# 1. Debug: Print columns in site_df
st.write("DEBUG: Columns in site_df ➜", site_df.columns.tolist())

# 2. Safely access 'AlertLevel' and count red alerts
if 'AlertLevel' in site_df.columns:
    red_alerts = site_df[site_df['AlertLevel'] == 'Red'].shape[0]
else:
    red_alerts = 0

# 3. Use Streamlit to display red alert count
col1, col2, col3 = st.columns(3)

col1.metric("Total Poles", len(site_df))

# Show the red alerts in the second column
col2.metric("Red Alerts", red_alerts)

# If you have other metrics like energy:
col3.metric("Energy", int(site_df['Energy'].sum()))


    # Table View
   # Check if the selected site exists (ensure indentation here is consistent)
if selected_site:
    # Display the subheader with the selected site name
    st.subheader(f"πŸ“‹ Pole Data Table for {selected_site}")

    # Add the rest of your logic here if needed for the table
    # For example, showing a data table for the selected site
    st.dataframe(site_df)

    # Other code related to displaying the metrics can go here too
    col1, col2, col3 = st.columns(3)

    col1.metric("Total Poles", len(site_df))

    # Safely access 'AlertLevel' and count red alerts
    if 'AlertLevel' in site_df.columns:
        red_alerts = site_df[site_df['AlertLevel'] == 'Red'].shape[0]
    else:
        red_alerts = 0

    col2.metric("Red Alerts", red_alerts)

    # If you have other metrics like energy:
    col3.metric("Energy", int(site_df['Energy'].sum()))
else:
    st.warning("Please select a valid site.")

    with st.expander("Filter Options"):
        alert_filter = st.multiselect("Alert Level", options=site_df['Alert Level'].unique(), default=site_df['Alert Level'].unique())
        camera_filter = st.multiselect("Camera Status", options=site_df['Camera Status'].unique(), default=site_df['Camera Status'].unique())

    filtered_df = site_df[(site_df['Alert Level'].isin(alert_filter)) & (site_df['Camera Status'].isin(camera_filter))]
    st.dataframe(filtered_df, use_container_width=True)

    # Charts
    st.subheader("πŸ“Š Energy Generation Comparison")
    st.bar_chart(site_df[['Solar (kWh)', 'Wind (kWh)']].mean())

    st.subheader("πŸ“ˆ Tilt vs. Vibration")
    st.scatter_chart(site_df[['Tilt Angle (Β°)', 'Vibration (g)']])

    # Map with Red Alerts
    st.subheader("πŸ“ Red Alert Pole Locations")
    red_df = site_df[site_df['Alert Level'] == 'Red']
    if not red_df.empty:
        st.pydeck_chart(pdk.Deck(
            initial_view_state=pdk.ViewState(
                latitude=SITES[selected_site][0],
                longitude=SITES[selected_site][1],
                zoom=12,
                pitch=50
            ),
            layers=[
                pdk.Layer(
                    'ScatterplotLayer',
                    data=red_df,
                    get_position='[Longitude, Latitude]',
                    get_color='[255, 0, 0, 160]',
                    get_radius=100,
                )
            ]
        ))
        st.markdown("<h3 style='text-align: center;'>Red Alert Poles are Blinking</h3>", unsafe_allow_html=True)
    else:
        st.info("No red alerts at this time.")

if selected_site == "Kurnool":
    st.write("Simulating for Kurnool")
else:
    st.write("Simulating for another site")


    st.warning("Invalid site. Please enter one of: Hyderabad, Gadwal, Kurnool, Ballari")
import streamlit as st
from salesforce_integration import fetch_salesforce_data
from utils import process_data  # Optional, if you need data processing

# Fetch data from Salesforce
poles_data = fetch_salesforce_data()

# Process the data (optional, based on your model needs)
processed_data = process_data(poles_data)

# Display the processed data in Streamlit
st.title("Poles Data Visualization")
st.write("Processed Poles Data", processed_data)