Electricity Bill Analysis - User Flow Demo¶
This notebook demonstrates the complete user workflow:
- Process first billing period (Aug-Sep)
- Archive data under user account
- Generate initial assessment report
- Process second billing period (Sep-Oct) with historical comparison
- 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 ============================================================