RathodHarish commited on
Commit
7ce506f
·
verified ·
1 Parent(s): 526904f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +12 -49
app.py CHANGED
@@ -11,21 +11,10 @@ import io
11
  import time
12
  import asyncio
13
  from simple_salesforce import Salesforce
14
- import smtplib
15
- from email.mime.text import MIMEText
16
 
17
  # Configure logging
18
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
19
 
20
- # Email configuration
21
- EMAIL_CONFIG = {
22
- 'sender_email': 'your-email@gmail.com', # Replace with your Gmail address
23
- 'app_password': 'your-app-password', # Replace with your Gmail App Password
24
- 'recipient_email': 'recipient@example.com', # Replace with recipient email
25
- 'smtp_server': 'smtp.gmail.com',
26
- 'smtp_port': 587
27
- }
28
-
29
  # Salesforce configuration
30
  try:
31
  sf = Salesforce(
@@ -86,8 +75,7 @@ picklist_mapping = {
86
  'maintenance': 'Smart Log',
87
  'cell': 'Cell Analysis',
88
  'uv': 'UV Verification',
89
- 'weight log': 'Smart Log',
90
- 'wegit log': 'Smart Log' # Added mapping for 'Wegit Log'
91
  }
92
  }
93
 
@@ -176,7 +164,7 @@ def save_to_salesforce(df, reminders_df):
176
  amc_date_str = None
177
  if pd.notna(row['amc_date']):
178
  try:
179
- amc_date = pd.to_datetime(row['amc_date'], format='%m/%d/%Y').strftime('%Y-%m-%d')
180
  amc_date_str = amc_date
181
  amc_date_dt = datetime.strptime(amc_date, '%Y-%m-%d')
182
  if status_mapped == "Active" and current_date.date() <= amc_date_dt.date() <= next_30_days.date():
@@ -212,22 +200,6 @@ def save_to_salesforce(df, reminders_df):
212
  except Exception as e:
213
  logging.error(f"Failed to save to Salesforce: {str(e)}")
214
 
215
- # Send email alert
216
- def send_email_alert(subject, body):
217
- try:
218
- msg = MIMEText(body)
219
- msg['Subject'] = subject
220
- msg['From'] = EMAIL_CONFIG['sender_email']
221
- msg['To'] = EMAIL_CONFIG['recipient_email']
222
-
223
- with smtplib.SMTP(EMAIL_CONFIG['smtp_server'], EMAIL_CONFIG['smtp_port']) as server:
224
- server.starttls()
225
- server.login(EMAIL_CONFIG['sender_email'], EMAIL_CONFIG['app_password'])
226
- server.send_message(msg)
227
- logging.info(f"Email alert sent successfully to {EMAIL_CONFIG['recipient_email']}")
228
- except Exception as e:
229
- logging.error(f"Failed to send email alert: {str(e)}")
230
-
231
  # Summarize logs
232
  def summarize_logs(df):
233
  try:
@@ -251,9 +223,7 @@ def detect_anomalies(df):
251
  anomalies = df[df["anomaly"] == -1][["device_id", "usage_hours", "downtime", "timestamp"]]
252
  if anomalies.empty:
253
  return "No anomalies detected.", anomalies
254
- anomaly_summary = "\n".join([f"- Device ID: {row['device_id']}, Usage: {row['usage_hours']}, Downtime: {row['downtime']}, Timestamp: {row['timestamp']}" for _, row in anomalies.head(5).iterrows()])
255
- send_email_alert("Anomaly Detection Alert", f"Anomalies detected:\n{anomaly_summary}")
256
- return anomaly_summary, anomalies
257
  except Exception as e:
258
  logging.error(f"Anomaly detection failed: {str(e)}")
259
  return f"Anomaly detection failed: {str(e)}", pd.DataFrame()
@@ -263,19 +233,13 @@ def check_amc_reminders(df, current_date):
263
  try:
264
  if "device_id" not in df.columns or "amc_date" not in df.columns:
265
  return "AMC reminders require 'device_id' and 'amc_date' columns.", pd.DataFrame()
266
- # Parse amc_date with explicit format and handle timezone
267
- df["amc_date"] = pd.to_datetime(df["amc_date"], format='%m/%d/%Y', errors='coerce').dt.tz_localize('UTC').dt.tz_convert('Asia/Kolkata')
268
- current_date = pd.to_datetime(current_date).tz_localize('Asia/Kolkata')
269
- logging.info(f"Current date for AMC: {current_date}")
270
- logging.info(f"AMC dates parsed: {df['amc_date'].dropna().tolist()}")
271
  df["days_to_amc"] = (df["amc_date"] - current_date).dt.days
272
- logging.info(f"Days to AMC: {df['days_to_amc'].dropna().tolist()}")
273
- reminders = df[(df["days_to_amc"] >= 0) & (df["days_to_amc"] <= 30) & (df["status"] == "Active")][["device_id", "log_type", "status", "timestamp", "usage_hours", "downtime", "amc_date"]]
274
  if reminders.empty:
275
  return "No AMC reminders due within the next 30 days.", reminders
276
- reminder_summary = "\n".join([f"- Device ID: {row['device_id']}, AMC Date: {row['amc_date'].date()}" for _, row in reminders.head(5).iterrows()])
277
- send_email_alert("AMC Reminder Alert", f"AMC reminders due within 30 days:\n{reminder_summary}")
278
- return reminder_summary, reminders
279
  except Exception as e:
280
  logging.error(f"AMC reminder generation failed: {str(e)}")
281
  return f"AMC reminder generation failed: {str(e)}", pd.DataFrame()
@@ -554,11 +518,10 @@ async def process_logs(file_obj, lab_site_filter, equipment_type_filter, date_ra
554
  if missing_columns:
555
  return f"Missing columns: {missing_columns}", "<p>Missing required columns.</p>", None, '<p>No device cards available.</p>', None, None, None, None, "", "", "", None, cached_df_state, last_modified_state
556
 
557
- # Handle mixed timestamp formats with ISO8601 and coerce errors
558
- df["timestamp"] = pd.to_datetime(df["timestamp"], format='ISO8601', errors='coerce')
559
- # Convert UTC-aware timestamps to IST directly
560
- df["timestamp"] = df["timestamp"].dt.tz_convert('Asia/Kolkata')
561
- df["amc_date"] = pd.to_datetime(df["amc_date"], format='%m/%d/%Y', errors='coerce').dt.tz_localize('UTC').dt.tz_convert('Asia/Kolkata')
562
  if df.empty:
563
  return "No data available.", "<p>No data available.</p>", None, '<p>No device cards available.</p>', None, None, None, None, "", "", "", None, df, current_modified_time
564
  else:
@@ -602,7 +565,7 @@ async def process_logs(file_obj, lab_site_filter, equipment_type_filter, date_ra
602
  # Run critical tasks concurrently
603
  with ThreadPoolExecutor(max_workers=2) as executor:
604
  future_anomalies = executor.submit(detect_anomalies, filtered_df)
605
- future_amc = executor.submit(check_amc_reminders, df) # Use full df for AMC
606
 
607
  summary = f"Step 1: Summary Report\n{summarize_logs(filtered_df)}"
608
  anomalies, anomalies_df = future_anomalies.result()
 
11
  import time
12
  import asyncio
13
  from simple_salesforce import Salesforce
 
 
14
 
15
  # Configure logging
16
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
17
 
 
 
 
 
 
 
 
 
 
18
  # Salesforce configuration
19
  try:
20
  sf = Salesforce(
 
75
  'maintenance': 'Smart Log',
76
  'cell': 'Cell Analysis',
77
  'uv': 'UV Verification',
78
+ 'weight log': 'Smart Log'
 
79
  }
80
  }
81
 
 
164
  amc_date_str = None
165
  if pd.notna(row['amc_date']):
166
  try:
167
+ amc_date = pd.to_datetime(row['amc_date']).strftime('%Y-%m-%d')
168
  amc_date_str = amc_date
169
  amc_date_dt = datetime.strptime(amc_date, '%Y-%m-%d')
170
  if status_mapped == "Active" and current_date.date() <= amc_date_dt.date() <= next_30_days.date():
 
200
  except Exception as e:
201
  logging.error(f"Failed to save to Salesforce: {str(e)}")
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  # Summarize logs
204
  def summarize_logs(df):
205
  try:
 
223
  anomalies = df[df["anomaly"] == -1][["device_id", "usage_hours", "downtime", "timestamp"]]
224
  if anomalies.empty:
225
  return "No anomalies detected.", anomalies
226
+ return "\n".join([f"- Device ID: {row['device_id']}, Usage: {row['usage_hours']}, Downtime: {row['downtime']}, Timestamp: {row['timestamp']}" for _, row in anomalies.head(5).iterrows()]), anomalies
 
 
227
  except Exception as e:
228
  logging.error(f"Anomaly detection failed: {str(e)}")
229
  return f"Anomaly detection failed: {str(e)}", pd.DataFrame()
 
233
  try:
234
  if "device_id" not in df.columns or "amc_date" not in df.columns:
235
  return "AMC reminders require 'device_id' and 'amc_date' columns.", pd.DataFrame()
236
+ df["amc_date"] = pd.to_datetime(df["amc_date"], errors='coerce')
237
+ current_date = pd.to_datetime(current_date)
 
 
 
238
  df["days_to_amc"] = (df["amc_date"] - current_date).dt.days
239
+ reminders = df[(df["days_to_amc"] >= 0) & (df["days_to_amc"] <= 30)][["device_id", "log_type", "status", "timestamp", "usage_hours", "downtime", "amc_date"]]
 
240
  if reminders.empty:
241
  return "No AMC reminders due within the next 30 days.", reminders
242
+ return "\n".join([f"- Device ID: {row['device_id']}, AMC Date: {row['amc_date']}" for _, row in reminders.head(5).iterrows()]), reminders
 
 
243
  except Exception as e:
244
  logging.error(f"AMC reminder generation failed: {str(e)}")
245
  return f"AMC reminder generation failed: {str(e)}", pd.DataFrame()
 
518
  if missing_columns:
519
  return f"Missing columns: {missing_columns}", "<p>Missing required columns.</p>", None, '<p>No device cards available.</p>', None, None, None, None, "", "", "", None, cached_df_state, last_modified_state
520
 
521
+ df["timestamp"] = pd.to_datetime(df["timestamp"], errors='coerce')
522
+ df["amc_date"] = pd.to_datetime(df["amc_date"], errors='coerce')
523
+ if df["timestamp"].dt.tz is None:
524
+ df["timestamp"] = df["timestamp"].dt.tz_localize('UTC').dt.tz_convert('Asia/Kolkata')
 
525
  if df.empty:
526
  return "No data available.", "<p>No data available.</p>", None, '<p>No device cards available.</p>', None, None, None, None, "", "", "", None, df, current_modified_time
527
  else:
 
565
  # Run critical tasks concurrently
566
  with ThreadPoolExecutor(max_workers=2) as executor:
567
  future_anomalies = executor.submit(detect_anomalies, filtered_df)
568
+ future_amc = executor.submit(check_amc_reminders, filtered_df, datetime.now())
569
 
570
  summary = f"Step 1: Summary Report\n{summarize_logs(filtered_df)}"
571
  anomalies, anomalies_df = future_anomalies.result()