Spaces:
Sleeping
Sleeping
| import os | |
| import pandas as pd | |
| from typing import Dict | |
| from pathlib import Path | |
| # Prefer HF router via OpenAI-compatible client. Use env `HF_TOKEN`. | |
| # HF_TOKEN loaded lazily to allow dotenv loading after import | |
| def get_hf_token(): | |
| return os.environ.get('HF_TOKEN') | |
| def openai_summary(text: str, verbosity: str = 'brief', model: str = 'meta-llama/Llama-3.1-8B-Instruct:novita') -> str: | |
| HF_TOKEN = get_hf_token() | |
| if not HF_TOKEN: | |
| return None | |
| try: | |
| # Import here to avoid requiring OpenAI client unless HF_TOKEN set | |
| from openai import OpenAI | |
| client = OpenAI(base_url="https://router.huggingface.co/v1", api_key=HF_TOKEN) | |
| if verbosity == 'analyze': | |
| instruction = 'วิเคราะห์สาเหตุไฟฟ้าจากข้อมูลนี้ สรุปไม่เกิน 3-4 บรรทัด (ไทย) ระบุสาเหตุทางเทคนิค ผลกระทบต่อลูกค้าและระบบ และช่วงเวลา:' | |
| elif verbosity == 'recommend': | |
| instruction = 'วิเคราะห์สาเหตุไฟฟ้าจากข้อมูลนี้ พร้อมแนะนำการแก้ไข สรุปไม่เกิน 3-4 บรรทัด (ไทย) ระบุสาเหตุทางเทคนิค ผลกระทบต่อลูกค้าและระบบ ช่วงเวลาและข้อเสนอแนะในการป้องกัน:' | |
| prompt = f"{instruction}\n\n{text}\n\nสรุป:" | |
| completion = client.chat.completions.create( | |
| model=model, | |
| messages=[{"role": "user", "content": prompt}], | |
| max_tokens=1000, | |
| ) | |
| # Extract text from response | |
| choice = completion.choices[0] | |
| msg = choice.message | |
| content = msg.content | |
| return content.strip() if content else None | |
| except Exception: | |
| return None | |
| def summarize_overall(df: pd.DataFrame, use_hf: bool = False, model: str = 'meta-llama/Llama-3.1-8B-Instruct:novita', total_customers: float = None) -> Dict: | |
| """Summarize overall outage data with GenAI and reliability metrics.""" | |
| # Basic statistics | |
| total_events = len(df) | |
| date_cols = ['OutageDateTime', 'FirstRestoDateTime', 'LastRestoDateTime', 'CreateEventDateTime', 'CloseEventDateTime'] | |
| # Parse dates | |
| df_copy = df.copy() | |
| for col in date_cols: | |
| if col in df_copy.columns: | |
| df_copy[col] = pd.to_datetime(df_copy[col], dayfirst=True, errors='coerce') | |
| # Calculate basic metrics | |
| if 'OutageDateTime' in df_copy.columns: | |
| date_range = f"{df_copy['OutageDateTime'].min()} ถึง {df_copy['OutageDateTime'].max()}" if pd.notna(df_copy['OutageDateTime'].min()) else "ไม่ระบุ" | |
| else: | |
| date_range = "ไม่ระบุ" | |
| # Event types | |
| event_types = df_copy.get('EventType', pd.Series()).value_counts().head(5).to_dict() | |
| # Affected customers | |
| total_affected = 0 | |
| if 'AffectedCustomer' in df_copy.columns: | |
| total_affected = pd.to_numeric(df_copy['AffectedCustomer'], errors='coerce').sum() | |
| # Create summary text for GenAI | |
| summary_text = f""" | |
| ข้อมูลไฟฟ้าล้มทั้งหมด: | |
| - จำนวนเหตุการณ์ทั้งหมด: {total_events} | |
| - ช่วงเวลาที่เกิดเหตุการณ์: {date_range} | |
| - ประเภทเหตุการณ์หลัก: {', '.join([f'{k}: {v}' for k, v in event_types.items()])} | |
| - จำนวนลูกค้าที่ได้รับผลกระทบทั้งหมด: {int(total_affected) if not pd.isna(total_affected) else 'ไม่ระบุ'} | |
| """ | |
| # Reliability metrics DataFrame | |
| reliability_df = pd.DataFrame() | |
| reliability_summary = "" | |
| if total_customers and total_customers > 0: | |
| try: | |
| from scripts.compute_reliability import compute_reliability | |
| import tempfile | |
| import os | |
| # Save df to temp CSV for compute_reliability | |
| with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as f: | |
| df_copy.to_csv(f.name, index=False) | |
| temp_path = f.name | |
| try: | |
| reliability_results = compute_reliability(temp_path, total_customers=total_customers, exclude_planned=True) | |
| overall_metrics = reliability_results.get('overall', pd.DataFrame()) | |
| if not overall_metrics.empty: | |
| row = overall_metrics.iloc[0] | |
| # Create reliability DataFrame with proper metric names | |
| reliability_data = [ | |
| { | |
| 'Metric': 'SAIFI', | |
| 'Full Name': 'System Average Interruption Frequency Index', | |
| 'Value': f"{row.get('SAIFI', 'N/A'):.4f}", | |
| 'Unit': 'ครั้ง/ลูกค้า', | |
| 'Description': 'ความถี่เฉลี่ยของการขัดข้องต่อลูกค้า' | |
| }, | |
| { | |
| 'Metric': 'SAIDI', | |
| 'Full Name': 'System Average Interruption Duration Index', | |
| 'Value': f"{row.get('SAIDI', 'N/A'):.2f}", | |
| 'Unit': 'นาที/ลูกค้า', | |
| 'Description': 'ระยะเวลาขัดข้องเฉลี่ยต่อลูกค้า' | |
| }, | |
| { | |
| 'Metric': 'CAIDI', | |
| 'Full Name': 'Customer Average Interruption Duration Index', | |
| 'Value': f"{row.get('CAIDI', 'N/A'):.2f}", | |
| 'Unit': 'นาที/ครั้ง', | |
| 'Description': 'ระยะเวลาขัดข้องเฉลี่ยต่อครั้ง' | |
| }, | |
| { | |
| 'Metric': 'MAIFI', | |
| 'Full Name': 'Momentary Average Interruption Frequency Index', | |
| 'Value': f"{row.get('MAIFI', 'N/A'):.4f}", | |
| 'Unit': 'ครั้ง/ลูกค้า', | |
| 'Description': 'ความถี่เฉลี่ยของการขัดข้องชั่วคราวต่อลูกค้า' | |
| } | |
| ] | |
| reliability_df = pd.DataFrame(reliability_data) | |
| reliability_summary = f""" | |
| ดัชนีความน่าเชื่อถือ: | |
| - SAIFI (System Average Interruption Frequency Index): {row.get('SAIFI', 'N/A'):.4f} ครั้ง/ลูกค้า | |
| - SAIDI (System Average Interruption Duration Index): {row.get('SAIDI', 'N/A'):.2f} นาที/ลูกค้า | |
| - CAIDI (Customer Average Interruption Duration Index): {row.get('CAIDI', 'N/A'):.2f} นาที/ครั้ง | |
| - MAIFI (Momentary Average Interruption Frequency Index): {row.get('MAIFI', 'N/A'):.4f} ครั้ง/ลูกค้า | |
| """ | |
| summary_text += reliability_summary | |
| finally: | |
| os.unlink(temp_path) | |
| except Exception as e: | |
| reliability_summary = f"ไม่สามารถคำนวณดัชนีความน่าเชื่อถือได้: {str(e)}" | |
| # Use GenAI for overall summary | |
| ai_summary = None | |
| if use_hf and get_hf_token(): | |
| try: | |
| instruction = "สรุปภาพรวมข้อมูลไฟฟ้าล้มจากข้อมูลนี้ สรุปเป็นย่อหน้าเดียว (ไทย) ระบุจำนวนเหตุการณ์ สาเหตุหลัก ผลกระทบ และข้อเสนอแนะในการปรับปรุงระบบไฟฟ้า:" | |
| prompt = f"{instruction}\n\n{summary_text}\n\nสรุปภาพรวม:" | |
| ai_summary = openai_summary(prompt, verbosity='recommend', model=model) | |
| except Exception as e: | |
| ai_summary = f"ไม่สามารถสร้างสรุปด้วย AI ได้: {str(e)}" | |
| return { | |
| 'total_events': total_events, | |
| 'date_range': date_range, | |
| 'event_types': event_types, | |
| 'total_affected_customers': int(total_affected) if not pd.isna(total_affected) else None, | |
| 'basic_summary': summary_text.strip(), | |
| 'reliability_summary': reliability_summary.strip() if reliability_summary else None, | |
| 'reliability_df': reliability_df, | |
| 'ai_summary': ai_summary, | |
| } |