YashDave commited on
Commit
3060862
·
verified ·
1 Parent(s): 2f6480b

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +191 -0
  2. requirements.txt +46 -0
  3. voltage_monitor_.py +239 -0
app.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import time
4
+ from datetime import datetime
5
+ import plotly.express as px
6
+ import plotly.graph_objects as go
7
+ from voltage_monitor_ import WeatherSimulator, VoltageMonitor, VoltageStabilizer, NotificationSystem
8
+
9
+ # Page configuration
10
+ st.set_page_config(
11
+ page_title="Voltage Monitoring System",
12
+ page_icon="⚡",
13
+ layout="wide"
14
+ )
15
+
16
+ # Initialize session state
17
+ if 'historical_data' not in st.session_state:
18
+ st.session_state.historical_data = []
19
+ if 'alerts' not in st.session_state:
20
+ st.session_state.alerts = []
21
+ if 'is_monitoring' not in st.session_state:
22
+ st.session_state.is_monitoring = False
23
+
24
+ # Initialize system components
25
+ weather_sim = WeatherSimulator()
26
+ voltage_monitor = VoltageMonitor()
27
+ notification_system = NotificationSystem()
28
+ stabilizer = VoltageStabilizer()
29
+
30
+ # Function to add alert to session state
31
+ def add_alert(alert):
32
+ st.session_state.alerts.append(alert)
33
+
34
+ # Function to clear all alerts
35
+ def clear_alerts():
36
+ st.session_state.alerts = []
37
+
38
+ # Title and description
39
+ st.title("⚡ Real-time Voltage Monitoring System")
40
+ st.markdown("""
41
+ This dashboard provides real-time monitoring of voltage levels with weather impact consideration.
42
+ Monitor voltage fluctuations, weather conditions, and system notifications in one place.
43
+ """)
44
+
45
+ # Alerts Section - Outside the monitoring loop to persist
46
+ if st.session_state.alerts:
47
+ st.sidebar.divider()
48
+ st.sidebar.subheader("🚨 Alert History")
49
+ col_alerts, col_clear = st.sidebar.columns([3, 1])
50
+ with col_clear:
51
+ if st.button("Clear Alerts"):
52
+ clear_alerts()
53
+
54
+ for alert in st.session_state.alerts:
55
+ severity_color = "red" if alert.get('severity') == "Severe" else "orange"
56
+ st.sidebar.markdown(
57
+ f"""
58
+ <div style='padding: 10px; border-left: 3px solid {severity_color}; margin: 5px 0;'>
59
+ <small>{alert['timestamp']}</small><br>
60
+ <strong style='color: {severity_color};'>{alert['severity']} Alert</strong><br>
61
+ Voltage: {alert['voltage']}V<br>
62
+ Weather: {alert['weather']}
63
+ </div>
64
+ """,
65
+ unsafe_allow_html=True
66
+ )
67
+
68
+ # Sidebar controls
69
+ with st.sidebar:
70
+ st.header("Control Panel")
71
+
72
+ if not st.session_state.is_monitoring:
73
+ if st.button("Start Monitoring", type="primary"):
74
+ st.session_state.is_monitoring = True
75
+ else:
76
+ if st.button("Stop Monitoring", type="secondary"):
77
+ st.session_state.is_monitoring = False
78
+
79
+ st.divider()
80
+ st.subheader("System Settings")
81
+ nominal_voltage = st.slider("Nominal Voltage", 200.0, 250.0, 230.0, 0.5)
82
+ update_interval = st.slider("Update Interval (seconds)", 1, 10, 2)
83
+
84
+ # Create three columns for metrics
85
+ col1, col2, col3 = st.columns(3)
86
+
87
+ # Main monitoring loop
88
+ if st.session_state.is_monitoring:
89
+ placeholder = st.empty()
90
+
91
+ with placeholder.container():
92
+ # Get current readings
93
+ weather_data = weather_sim.get_current_weather()
94
+ current_voltage = voltage_monitor.measure_voltage(weather_data['impact_factor'])
95
+ voltage_analysis = voltage_monitor.analyze_voltage(current_voltage)
96
+
97
+ # Update historical data
98
+ st.session_state.historical_data.append({
99
+ 'timestamp': datetime.now(),
100
+ 'voltage': voltage_analysis['voltage'],
101
+ 'weather': weather_data['condition'],
102
+ 'status': voltage_analysis['status'],
103
+ 'severity': voltage_analysis['severity'],
104
+ 'impact_factor': weather_data['impact_factor']
105
+ })
106
+
107
+ # Add alert if status is not normal
108
+ if voltage_analysis['status'] != "Normal":
109
+ add_alert({
110
+ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
111
+ 'voltage': voltage_analysis['voltage'],
112
+ 'weather': weather_data['condition'],
113
+ 'status': voltage_analysis['status'],
114
+ 'severity': voltage_analysis['severity']
115
+ })
116
+
117
+ # Display current metrics
118
+ with col1:
119
+ st.metric(
120
+ label="Current Voltage",
121
+ value=f"{voltage_analysis['voltage']}V",
122
+ delta=f"{voltage_analysis['deviation_percentage']}%",
123
+ delta_color="inverse"
124
+ )
125
+
126
+ with col2:
127
+ st.metric(
128
+ label="Weather Condition",
129
+ value=weather_data['condition'],
130
+ delta=f"Impact: {weather_data['impact_factor']:.2f}"
131
+ )
132
+
133
+ with col3:
134
+ status_color = "normal" if voltage_analysis['status'] == "Normal" else "inverse"
135
+ st.metric(
136
+ label="System Status",
137
+ value=voltage_analysis['status'],
138
+ delta=voltage_analysis['severity'],
139
+ delta_color=status_color
140
+ )
141
+
142
+ # Create DataFrame from historical data
143
+ df = pd.DataFrame(st.session_state.historical_data)
144
+
145
+ # Display charts
146
+ if not df.empty:
147
+ # Voltage trend chart
148
+ fig_voltage = px.line(
149
+ df,
150
+ x='timestamp',
151
+ y='voltage',
152
+ title='Voltage Trend Over Time'
153
+ )
154
+ fig_voltage.add_hline(y=nominal_voltage, line_dash="dash", line_color="green", annotation_text="Nominal")
155
+ st.plotly_chart(fig_voltage, use_container_width=True)
156
+
157
+ # Weather impact chart
158
+ col_weather, col_status = st.columns(2)
159
+
160
+ with col_weather:
161
+ weather_counts = df['weather'].value_counts()
162
+ fig_weather = px.pie(
163
+ values=weather_counts.values,
164
+ names=weather_counts.index,
165
+ title='Weather Conditions Distribution'
166
+ )
167
+ st.plotly_chart(fig_weather)
168
+
169
+ with col_status:
170
+ status_counts = df['status'].value_counts()
171
+ fig_status = px.bar(
172
+ x=status_counts.index,
173
+ y=status_counts.values,
174
+ title='Voltage Status Distribution',
175
+ labels={'x': 'Status', 'y': 'Count'}
176
+ )
177
+ st.plotly_chart(fig_status)
178
+
179
+ # Display historical data table
180
+ if st.session_state.historical_data:
181
+ st.divider()
182
+ st.subheader("Historical Data")
183
+ df_display = pd.DataFrame(st.session_state.historical_data).tail(50)
184
+ st.dataframe(df_display, use_container_width=True)
185
+
186
+ # Add a small delay before next update
187
+ time.sleep(update_interval)
188
+ st.rerun()
189
+
190
+ else:
191
+ st.info("Click 'Start Monitoring' in the sidebar to begin voltage monitoring.")
requirements.txt ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ altair==5.5.0
2
+ attrs==24.3.0
3
+ blinker==1.9.0
4
+ cachetools==5.5.0
5
+ certifi==2024.12.14
6
+ charset-normalizer==3.4.1
7
+ click==8.1.8
8
+ gitdb==4.0.12
9
+ GitPython==3.1.44
10
+ idna==3.10
11
+ Jinja2==3.1.5
12
+ joblib==1.4.2
13
+ jsonschema==4.23.0
14
+ jsonschema-specifications==2024.10.1
15
+ markdown-it-py==3.0.0
16
+ MarkupSafe==3.0.2
17
+ mdurl==0.1.2
18
+ narwhals==1.21.1
19
+ numpy==2.2.1
20
+ packaging==24.2
21
+ pandas==2.2.3
22
+ pillow==11.1.0
23
+ plotly==5.24.1
24
+ protobuf==5.29.3
25
+ pyarrow==18.1.0
26
+ pydeck==0.9.1
27
+ Pygments==2.19.1
28
+ python-dateutil==2.9.0.post0
29
+ pytz==2024.2
30
+ referencing==0.35.1
31
+ requests==2.32.3
32
+ rich==13.9.4
33
+ rpds-py==0.22.3
34
+ scikit-learn==1.6.0
35
+ scipy==1.15.0
36
+ six==1.17.0
37
+ smmap==5.0.2
38
+ streamlit==1.41.1
39
+ tenacity==9.0.0
40
+ threadpoolctl==3.5.0
41
+ toml==0.10.2
42
+ tornado==6.4.2
43
+ typing_extensions==4.12.2
44
+ tzdata==2024.2
45
+ urllib3==2.3.0
46
+ watchdog==6.0.0
voltage_monitor_.py ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pandas as pd
3
+ from datetime import datetime, timedelta
4
+ import time
5
+ from typing import Dict, List, Tuple
6
+ import random
7
+ import json
8
+ from sklearn.linear_model import LinearRegression
9
+
10
+ class WeatherSimulator:
11
+ """Simulates weather conditions with more dramatic impact on voltage"""
12
+
13
+ def __init__(self):
14
+ self.weather_conditions = ['Clear', 'Rain', 'Storm', 'Heavy Storm']
15
+ # Increased impact factors for more dramatic effect
16
+ self.weather_impact = {
17
+ 'Clear': 1.0,
18
+ 'Rain': 0.85, # More impact
19
+ 'Storm': 0.65, # Significant impact
20
+ 'Heavy Storm': 0.45 # Severe impact
21
+ }
22
+ # Sudden weather change probability
23
+ self.sudden_change_prob = 0.1
24
+
25
+ def get_current_weather(self) -> Dict:
26
+ """Simulates current weather with possible sudden changes"""
27
+ # Sudden severe weather chance
28
+ if random.random() < self.sudden_change_prob:
29
+ condition = 'Heavy Storm'
30
+ print("\n⚠️ SUDDEN SEVERE WEATHER EVENT DETECTED! ⚠️")
31
+ else:
32
+ weights = [0.5, 0.3, 0.15, 0.05]
33
+ condition = np.random.choice(self.weather_conditions, p=weights)
34
+
35
+ return {
36
+ 'condition': condition,
37
+ 'impact_factor': self.weather_impact[condition],
38
+ 'temperature': round(random.uniform(15, 35), 1),
39
+ 'humidity': round(random.uniform(30, 90), 1),
40
+ 'wind_speed': round(random.uniform(0, 50), 1)
41
+ }
42
+
43
+ class VoltageMonitor:
44
+ """Enhanced voltage monitoring with more sensitive thresholds"""
45
+
46
+ def __init__(self, nominal_voltage: float = 230.0, tolerance: float = 0.1):
47
+ self.nominal_voltage = nominal_voltage
48
+ self.tolerance = tolerance
49
+ self.min_voltage = nominal_voltage * (1 - tolerance)
50
+ self.max_voltage = nominal_voltage * (1 + tolerance)
51
+
52
+ def measure_voltage(self, weather_impact: float) -> float:
53
+ """Simulates voltage measurement with more dramatic weather impact"""
54
+ # Increased base variation
55
+ base_variation = random.uniform(-10, 10)
56
+
57
+ # More dramatic weather impact
58
+ weather_variation = (1 - weather_impact) * 40 # Doubled impact
59
+
60
+ # Add sudden spikes during bad weather
61
+ if weather_impact < 0.7: # During storms
62
+ spike_chance = random.random()
63
+ if spike_chance < 0.3: # 30% chance of spike
64
+ weather_variation *= random.uniform(1.5, 2.0)
65
+ print("\n⚡ VOLTAGE SPIKE DETECTED! ⚡")
66
+
67
+ measured_voltage = self.nominal_voltage + base_variation + weather_variation
68
+ return round(measured_voltage, 2)
69
+
70
+ def analyze_voltage(self, voltage: float) -> Dict:
71
+ """Analyzes voltage with detailed status information"""
72
+ if voltage < self.min_voltage:
73
+ status = "Low"
74
+ severity = "Severe" if voltage < self.min_voltage * 0.9 else "Moderate"
75
+ elif voltage > self.max_voltage:
76
+ status = "High"
77
+ severity = "Severe" if voltage > self.max_voltage * 1.1 else "Moderate"
78
+ else:
79
+ status = "Normal"
80
+ severity = "Normal"
81
+
82
+ return {
83
+ 'voltage': voltage,
84
+ 'status': status,
85
+ 'severity': severity,
86
+ 'deviation': round(abs(voltage - self.nominal_voltage), 2),
87
+ 'deviation_percentage': round((abs(voltage - self.nominal_voltage) / self.nominal_voltage) * 100, 2),
88
+ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
89
+ }
90
+
91
+ class VoltageStabilizer:
92
+ """Enhanced voltage stabilization system"""
93
+
94
+ def __init__(self):
95
+ self.correction_factor = 1.0
96
+ self.correction_history = []
97
+
98
+ def calculate_correction(self, voltage: float, nominal_voltage: float) -> float:
99
+ """Calculates required correction with improved accuracy"""
100
+ base_correction = nominal_voltage / voltage if voltage != 0 else 1.0
101
+
102
+ # Add fine-tuning based on deviation
103
+ deviation = abs(voltage - nominal_voltage)
104
+ if deviation > 20: # Large deviation
105
+ fine_tune = 0.05 # Additional 5% correction
106
+ base_correction *= (1 + fine_tune if voltage < nominal_voltage else 1 - fine_tune)
107
+
108
+ return base_correction
109
+
110
+ def apply_correction(self, voltage: float, weather_impact: float) -> float:
111
+ """Applies voltage correction with weather consideration"""
112
+ correction = self.calculate_correction(voltage, 230.0)
113
+ corrected_voltage = round(voltage * correction, 2)
114
+
115
+ self.correction_history.append({
116
+ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
117
+ 'original_voltage': voltage,
118
+ 'corrected_voltage': corrected_voltage,
119
+ 'correction_factor': round(correction, 4)
120
+ })
121
+
122
+ return corrected_voltage
123
+
124
+ class NotificationSystem:
125
+ """Enhanced notification system with detailed alerts"""
126
+
127
+ def __init__(self):
128
+ self.alert_history = []
129
+ self.notification_count = 0
130
+
131
+ def check_and_notify(self, voltage_data: Dict, weather_data: Dict) -> None:
132
+ """Checks conditions and generates detailed notifications"""
133
+ message = None
134
+
135
+ if voltage_data['status'] != "Normal":
136
+ message = self._generate_alert_message(voltage_data, weather_data)
137
+ self.alert_history.append({
138
+ 'timestamp': voltage_data['timestamp'],
139
+ 'message': message,
140
+ 'voltage': voltage_data['voltage'],
141
+ 'weather': weather_data['condition'],
142
+ 'severity': voltage_data['severity']
143
+ })
144
+ self.notification_count += 1
145
+
146
+ if message:
147
+ self._send_notification(message)
148
+
149
+ def _generate_alert_message(self, voltage_data: Dict, weather_data: Dict) -> str:
150
+ """Generates detailed alert message with severity and recommendations"""
151
+ severity_symbol = "🔴" if voltage_data['severity'] == "Severe" else "🟡"
152
+
153
+ message = (
154
+ f"{severity_symbol} VOLTAGE ALERT {severity_symbol}\n"
155
+ f"Status: {voltage_data['status']} ({voltage_data['severity']})\n"
156
+ f"Current Voltage: {voltage_data['voltage']}V\n"
157
+ f"Deviation: {voltage_data['deviation']}V ({voltage_data['deviation_percentage']}%)\n"
158
+ f"Weather Condition: {weather_data['condition']}\n"
159
+ f"Time: {voltage_data['timestamp']}\n"
160
+ f"Recommended Action: "
161
+ )
162
+
163
+ if voltage_data['severity'] == "Severe":
164
+ message += "Immediate voltage stabilization required!"
165
+ else:
166
+ message += "Monitor situation closely and prepare stabilization if needed."
167
+
168
+ return message
169
+
170
+ def _send_notification(self, message: str) -> None:
171
+ """Sends formatted notification"""
172
+ print("\n" + "=" * 60)
173
+ print("🚨 NOTIFICATION ALERT 🚨")
174
+ print(message)
175
+ print("=" * 60 + "\n")
176
+
177
+ def main():
178
+ """Main simulation loop with enhanced visualization"""
179
+ print("Starting Enhanced Weather-based Voltage Monitoring System...")
180
+ print("Monitoring for voltage fluctuations and weather impacts...\n")
181
+
182
+ weather_sim = WeatherSimulator()
183
+ voltage_monitor = VoltageMonitor()
184
+ notification_system = NotificationSystem()
185
+ stabilizer = VoltageStabilizer()
186
+
187
+ historical_data = []
188
+
189
+ try:
190
+ while True:
191
+ # Get weather and measure voltage
192
+ weather_data = weather_sim.get_current_weather()
193
+ current_voltage = voltage_monitor.measure_voltage(weather_data['impact_factor'])
194
+
195
+ # Analyze voltage
196
+ voltage_analysis = voltage_monitor.analyze_voltage(current_voltage)
197
+
198
+ # Store historical data
199
+ historical_data.append({
200
+ 'timestamp': voltage_analysis['timestamp'],
201
+ 'voltage': voltage_analysis['voltage'],
202
+ 'weather': weather_data['condition'],
203
+ 'status': voltage_analysis['status'],
204
+ 'severity': voltage_analysis['severity']
205
+ })
206
+
207
+ # Check for notifications
208
+ notification_system.check_and_notify(voltage_analysis, weather_data)
209
+
210
+ # Apply correction if needed
211
+ if voltage_analysis['status'] != "Normal":
212
+ corrected_voltage = stabilizer.apply_correction(
213
+ current_voltage,
214
+ weather_data['impact_factor']
215
+ )
216
+ print(f"⚡ VOLTAGE CORRECTION APPLIED:")
217
+ print(f"Original: {current_voltage}V → Corrected: {corrected_voltage}V")
218
+
219
+ # Display current status
220
+ print(f"\nTime: {voltage_analysis['timestamp']}")
221
+ print(f"Weather Condition: {weather_data['condition']} "
222
+ f"(Impact Factor: {weather_data['impact_factor']:.2f})")
223
+ print(f"Voltage Status: {voltage_analysis['status']} "
224
+ f"({voltage_analysis['severity']})")
225
+ print(f"Current Voltage: {voltage_analysis['voltage']}V "
226
+ f"(Deviation: {voltage_analysis['deviation_percentage']}%)")
227
+
228
+ print("-" * 60)
229
+ time.sleep(2)
230
+
231
+ except KeyboardInterrupt:
232
+ print("\nSimulation stopped by user")
233
+ df = pd.DataFrame(historical_data)
234
+ df.to_csv('voltage_monitoring_history.csv', index=False)
235
+ print(f"Total alerts generated: {notification_system.notification_count}")
236
+ print("Historical data saved to voltage_monitoring_history.csv")
237
+
238
+ if __name__ == "__main__":
239
+ main()