Electricity Bill Analysis - User Flow Demo¶

This notebook demonstrates the complete user workflow:

  1. Process first billing period (Aug-Sep)
  2. Archive data under user account
  3. Generate initial assessment report
  4. Process second billing period (Sep-Oct) with historical comparison
  5. Generate updated reports with trend analysis

Cell 1: Import Packages¶

In [1]:
# Core modules
from csv_reader import read_csv_billing_data
from rule_engine import rule_check
from anomaly_llm import explain_anomalies_with_llm
from report import build_report
from user_manager import UserManager
from history_analyzer import HistoryAnalyzer

# Standard library
import logging
from pathlib import Path

# Setup logging
logging.basicConfig(
    level=logging.INFO,
    format='%(levelname)s | %(message)s'
)

print("Packages imported successfully")
Packages imported successfully

Cell 2: Initialize User System¶

In [2]:
# Configuration
USER_ID = "user_001"
USER_ROOT = "user_data"
REPORT_FORMAT = "text"

# CSV files
CSV_FIRST = "consumers_energy_store_electric_60_Minute_08-20-2025_09-18-2025.csv"
CSV_SECOND = "consumers_energy_store_electric_60_Minute_09-19-2025_10-20-2025.csv"

# Initialize managers
user_mgr = UserManager(root_dir=USER_ROOT)
hist_analyzer = HistoryAnalyzer()

print(f"User system initialized for: {USER_ID}")
print(f"Data root: {USER_ROOT}")
INFO | UserManager initialized with root: user_data
User system initialized for: user_001
Data root: user_data

Cell 3: Process First Period (Aug-Sep) - No History¶

In [3]:
print("=" * 60)
print("PERIOD 1: Aug-Sep (First Bill)")
print("=" * 60)

# Step 1: Read CSV data
print("\n[1/5] Reading CSV file...")
bill_1 = read_csv_billing_data(CSV_FIRST)
print(f"  Usage: {bill_1['usage_kwh']} kWh")
print(f"  Amount: ${bill_1['amount_due']}")
print(f"  Period: {bill_1['billing_period']}")

# Step 2: Archive bill
print("\n[2/5] Archiving bill data...")
archives_1 = user_mgr.archive_bill(
    user_id=USER_ID,
    bill_data=bill_1,
    source_csv=CSV_FIRST,
    bill_label="bill_1_aug_sep"
)
print(f"  CSV archived: {archives_1['csv']}")
print(f"  JSON archived: {archives_1['json']}")

# Step 3: Detect anomalies
print("\n[3/5] Running anomaly detection...")
anomalies_1 = rule_check(bill_1)
print(f"  Detected {len(anomalies_1)} anomalies")

# Step 4: Generate AI explanation
print("\n[4/5] Calling OpenAI API for explanation...")
explanation_1 = explain_anomalies_with_llm(anomalies_1, bill_1)
print(f"  API response received ({len(explanation_1)} chars)")

# Step 5: Build and save report
print("\n[5/5] Generating report...")
report_1 = build_report(bill_1, anomalies_1, explanation_1, format=REPORT_FORMAT)
report_path_1 = user_mgr.save_report(
    user_id=USER_ID,
    report_content=report_1,
    report_name="report_1_aug_sep",
    format="txt"
)
print(f"  Report saved: {report_path_1}")

print("\n" + "=" * 60)
print("PERIOD 1 COMPLETE")
print("=" * 60)
INFO | Reading CSV: consumers_energy_store_electric_60_Minute_08-20-2025_09-18-2025.csv
INFO | Read 720 time-series records
INFO | Data aggregation complete: Total usage 505.46 kWh
INFO | Created directory structure for user: user_001
INFO | Archived CSV: user_data\user_001\bills\bill_1_aug_sep.csv
INFO | Saved billing data: user_data\user_001\bills\bill_1_aug_sep.json
INFO | Starting rule-based detection
INFO | Rule detection complete, found 0 anomalies
INFO | Generating anomaly explanation
============================================================
PERIOD 1: Aug-Sep (First Bill)
============================================================

[1/5] Reading CSV file...
  Usage: 505.46 kWh
  Amount: $60.66
  Period: Aug 20 - Sep 19, 2025

[2/5] Archiving bill data...
  CSV archived: user_data\user_001\bills\bill_1_aug_sep.csv
  JSON archived: user_data\user_001\bills\bill_1_aug_sep.json

[3/5] Running anomaly detection...
  Detected 0 anomalies

[4/5] Calling OpenAI API for explanation...
INFO | Calling OpenAI for anomaly explanation
INFO | HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
INFO | OpenAI call succeeded
INFO | Generating report, format: text
INFO | Created directory structure for user: user_001
INFO | Saved report: user_data\user_001\reports\report_1_aug_sep.txt
  API response received (480 chars)

[5/5] Generating report...
  Report saved: user_data\user_001\reports\report_1_aug_sep.txt

============================================================
PERIOD 1 COMPLETE
============================================================

Cell 4: View First Period Report¶

In [4]:
print(report_1)
============================================================
    Electricity Bill Analysis Report
============================================================
Generated: 2025-11-16 02:09:57
Account: CSV-DATA
Period: Aug 20 - Sep 19, 2025
============================================================

=== Billing Summary ===
Current Period Usage: 505.46 kWh  
Previous Period Usage: N/A (First Bill) kWh  
Change: N/A (First Bill)  
Amount Due: $60.66  

=== Anomaly Analysis ===
Detected 0 issue(s):  
No issues detected. Bill appears normal for this period.

=== Recommendations ===
1. Monitor your usage patterns regularly to identify any unusual spikes in electricity consumption.
2. Review your current rate plan to ensure you are receiving the best rate for your usage needs.

============================================================
Note: For questions, please contact your utility company
============================================================

Cell 5: Process Second Period (Sep-Oct) - With Historical Context¶

CRITICAL: This cell enriches the second bill with historical data BEFORE generating the report!

In [5]:
print("=" * 60)
print("PERIOD 2: Sep-Oct (With Historical Comparison)")
print("=" * 60)

# Step 1: Read CSV data
print("\n[1/7] Reading CSV file...")
bill_2 = read_csv_billing_data(CSV_SECOND)
print(f"  Usage: {bill_2['usage_kwh']} kWh")
print(f"  Amount: ${bill_2['amount_due']}")
print(f"  Period: {bill_2['billing_period']}")

# Step 2: Load historical data (CRITICAL: Before generating report!)
print("\n[2/7] Loading historical data...")
historical_bills = user_mgr.get_historical_bills(USER_ID)
print(f"  Found {len(historical_bills)} historical period(s)")

# Step 3: Add historical context to current bill
print("\n[3/7] Enriching bill with historical context...")
bill_2_with_history = hist_analyzer.add_historical_context(bill_2, historical_bills)
print(f"  Previous usage: {bill_2_with_history['previous_usage_kwh']} kWh")
print(f"  Has real history: {bill_2_with_history['has_real_history']}")

# Step 4: Archive bill (with historical context)
print("\n[4/7] Archiving bill data...")
archives_2 = user_mgr.archive_bill(
    user_id=USER_ID,
    bill_data=bill_2_with_history,
    source_csv=CSV_SECOND,
    bill_label="bill_2_sep_oct"
)
print(f"  CSV archived: {archives_2['csv']}")
print(f"  JSON archived: {archives_2['json']}")

# Step 5: Detect anomalies (with historical comparison)
print("\n[5/7] Running anomaly detection (with history)...")
anomalies_2 = rule_check(bill_2_with_history)
print(f"  Detected {len(anomalies_2)} anomalies")

# Step 6: Generate AI explanation (with historical context)
print("\n[6/7] Calling OpenAI API for explanation...")
explanation_2 = explain_anomalies_with_llm(anomalies_2, bill_2_with_history)
print(f"  API response received ({len(explanation_2)} chars)")

# Step 7: Build and save individual report
print("\n[7/7] Generating individual report...")
report_2 = build_report(bill_2_with_history, anomalies_2, explanation_2, format=REPORT_FORMAT)
report_path_2 = user_mgr.save_report(
    user_id=USER_ID,
    report_content=report_2,
    report_name="report_2_sep_oct_individual",
    format="txt"
)
print(f"  Report saved: {report_path_2}")

print("\n" + "=" * 60)
print("PERIOD 2 COMPLETE")
print("=" * 60)
INFO | Reading CSV: consumers_energy_store_electric_60_Minute_09-19-2025_10-20-2025.csv
INFO | Read 768 time-series records
INFO | Data aggregation complete: Total usage 498.56 kWh
INFO | Loaded 2 historical bills for user user_001
INFO | Calculated averages from 2 historical periods
INFO | Usage change: -0.7%, Amount change: -0.7%
INFO | Added historical context
INFO | Created directory structure for user: user_001
INFO | Archived CSV: user_data\user_001\bills\bill_2_sep_oct.csv
INFO | Saved billing data: user_data\user_001\bills\bill_2_sep_oct.json
INFO | Starting rule-based detection
INFO | Rule detection complete, found 0 anomalies
INFO | Generating anomaly explanation
INFO | Calling OpenAI for anomaly explanation
============================================================
PERIOD 2: Sep-Oct (With Historical Comparison)
============================================================

[1/7] Reading CSV file...
  Usage: 498.56 kWh
  Amount: $59.83
  Period: Sep 19 - Oct 21, 2025

[2/7] Loading historical data...
  Found 2 historical period(s)

[3/7] Enriching bill with historical context...
  Previous usage: 498.56 kWh
  Has real history: True

[4/7] Archiving bill data...
  CSV archived: user_data\user_001\bills\bill_2_sep_oct.csv
  JSON archived: user_data\user_001\bills\bill_2_sep_oct.json

[5/7] Running anomaly detection (with history)...
  Detected 0 anomalies

[6/7] Calling OpenAI API for explanation...
INFO | HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
INFO | OpenAI call succeeded
INFO | Generating report, format: text
INFO | Created directory structure for user: user_001
INFO | Saved report: user_data\user_001\reports\report_2_sep_oct_individual.txt
  API response received (449 chars)

[7/7] Generating individual report...
  Report saved: user_data\user_001\reports\report_2_sep_oct_individual.txt

============================================================
PERIOD 2 COMPLETE
============================================================

Cell 6: View Second Period Individual Report¶

This should now show the correct previous usage and percentage change!

In [6]:
print(report_2)
============================================================
    Electricity Bill Analysis Report
============================================================
Generated: 2025-11-16 02:10:01
Account: CSV-DATA
Period: Sep 19 - Oct 21, 2025
============================================================

=== Billing Summary ===
Current Period Usage: 498.56 kWh
Previous Period Usage: 498.56 kWh
Change: N/A (First Bill)
Amount Due: $59.83

=== Anomaly Analysis ===
Detected 0 issue(s):
No issues detected. Bill appears normal for this period.

=== Recommendations ===
1. Monitor your usage patterns regularly to better understand your electricity consumption.
2. Review your rate plans to ensure you are on the most cost-effective option for your needs.

============================================================
Note: For questions, please contact your utility company
============================================================

Cell 7: Generate Overall Assessment with Historical Trends¶

In [7]:
print("=" * 60)
print("OVERALL USER ASSESSMENT")
print("=" * 60)

# Generate trend summary
comparison = bill_2_with_history.get('historical_comparison')

if comparison:
    trend_summary = hist_analyzer.generate_trend_summary(
        user_id=USER_ID,
        current_bill=bill_2_with_history,
        comparison=comparison
    )
    
    # Combine trend summary with individual report
    overall_report = trend_summary + "\n\n" + "=" * 60 + "\n\n" + report_2
    
    # Save overall report
    overall_path = user_mgr.save_report(
        user_id=USER_ID,
        report_content=overall_report,
        report_name="report_2_sep_oct_overall",
        format="txt"
    )
    
    print(f"Overall report saved: {overall_path}")
    print("\n" + trend_summary)
else:
    print("No historical comparison data available")

print("\n" + "=" * 60)
print("ALL REPORTS GENERATED")
print("=" * 60)
INFO | Created directory structure for user: user_001
INFO | Saved report: user_data\user_001\reports\report_2_sep_oct_overall.txt
============================================================
OVERALL USER ASSESSMENT
============================================================
Overall report saved: user_data\user_001\reports\report_2_sep_oct_overall.txt

============================================================
OVERALL USER ASSESSMENT
============================================================

User: user_001
Analysis Period: Sep 19 - Oct 21, 2025
Historical Data Points: 2

CURRENT PERIOD SUMMARY:
  - Total Usage: 498.56 kWh
  - Amount Due: $59.83
  - Daily Average: 15.58 kWh/day

COMPARISON WITH HISTORICAL AVERAGE:
  - Usage Change: -0.7%
  - Amount Change: -0.7%

TREND ANALYSIS:
  ✅ Usage is within normal range (-0.7% vs historical average)
  Recommendation: No action needed


============================================================
ALL REPORTS GENERATED
============================================================

Cell 8: Summary Statistics¶

In [8]:
print("=" * 60)
print("WORKFLOW SUMMARY")
print("=" * 60)

print(f"\nUser ID: {USER_ID}")
print(f"\nPeriod 1 (Aug-Sep):")
print(f"  Usage: {bill_1['usage_kwh']} kWh")
print(f"  Amount: ${bill_1['amount_due']}")
print(f"  Anomalies: {len(anomalies_1)}")

print(f"\nPeriod 2 (Sep-Oct):")
print(f"  Usage: {bill_2_with_history['usage_kwh']} kWh")
print(f"  Amount: ${bill_2_with_history['amount_due']}")
print(f"  Anomalies: {len(anomalies_2)}")
print(f"  Previous Usage: {bill_2_with_history['previous_usage_kwh']} kWh")

if comparison:
    print(f"\nHistorical Comparison:")
    print(f"  Usage Change: {comparison['usage_vs_avg_percent']:+.1f}%")
    print(f"  Amount Change: {comparison['amount_vs_avg_percent']:+.1f}%")
    print(f"  Historical Periods: {comparison['num_historical_periods']}")

print(f"\nReports Generated:")
print(f"  1. {report_path_1}")
print(f"  2. {report_path_2}")
# Check if overall_path exists (only created when comparison is available)
if comparison and 'overall_path' in locals():
    print(f"  3. {overall_path}")

print("\n" + "=" * 60)
print("WORKFLOW COMPLETE")
print("=" * 60)
============================================================
WORKFLOW SUMMARY
============================================================

User ID: user_001

Period 1 (Aug-Sep):
  Usage: 505.46 kWh
  Amount: $60.66
  Anomalies: 0

Period 2 (Sep-Oct):
  Usage: 498.56 kWh
  Amount: $59.83
  Anomalies: 0
  Previous Usage: 498.56 kWh

Historical Comparison:
  Usage Change: -0.7%
  Amount Change: -0.7%
  Historical Periods: 2

Reports Generated:
  1. user_data\user_001\reports\report_1_aug_sep.txt
  2. user_data\user_001\reports\report_2_sep_oct_individual.txt
  3. user_data\user_001\reports\report_2_sep_oct_overall.txt

============================================================
WORKFLOW COMPLETE
============================================================