Spaces:
Sleeping
Sleeping
File size: 9,013 Bytes
cc2e1db |
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 |
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,
} |