AI-OMS-Analyze / scripts /summary.py
kawaiipeace's picture
Update Function
cc2e1db
raw
history blame
9.01 kB
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,
}