#!/usr/bin/env python3 """ Import charging station transaction data from CSV to existing MySQL database Aangepast voor bestaande 'transactions' tabel structuur """ import re import mysql.connector from datetime import datetime from decimal import Decimal import sys # Database configuration DB_CONFIG = { 'host': '192.168.178.201', 'port': 3307, 'user': 'alfen_user', 'password': '5uVgr%f%s2P5GR@3q!', 'database': 'alfen', # Jouw database naam 'charset': 'utf8mb4' } class ChargingDataImporter: def __init__(self, config): self.config = config self.conn = None self.cursor = None self.pending_transactions = {} # Track transactions waiting for stop def connect(self): """Connect to MySQL database""" try: self.conn = mysql.connector.connect(**self.config) self.cursor = self.conn.cursor() print("✓ Database verbinding succesvol") except mysql.connector.Error as err: print(f"✗ Fout bij verbinden met database: {err}") sys.exit(1) def close(self): """Close database connection""" if self.cursor: self.cursor.close() if self.conn: self.conn.close() def parse_txstart(self, line): """Parse transaction start line and store temporarily""" # txstart2: id 0x0000000000000001, socket 1, 2025-10-28 18:27:42 5518.267kWh 04BB29EAFD0F94 3 2 Y pattern = r'txstart2: id (0x[0-9a-fA-F]+), socket (\d+), ([\d-]+ [\d:]+) ([\d.]+)kWh (\w+)' match = re.match(pattern, line) if match: tx_id = match.group(1) # Keep as hex string socket_num = int(match.group(2)) timestamp = datetime.strptime(match.group(3), '%Y-%m-%d %H:%M:%S') kwh = Decimal(match.group(4)) card = match.group(5) # Store temporarily until we get the stop self.pending_transactions[tx_id] = { 'transaction_id': tx_id, 'socket': socket_num, 'start_timestamp': timestamp, 'start_kWh': kwh, 'card': card } print(f" → Transactie {tx_id} gestart (wacht op stop...)") return True return False def parse_txstop(self, line): """Parse transaction stop line and insert complete transaction""" # txstop2: id 0x0000000000000001, socket 1, 2025-10-31 15:59:29 5540.316kWh 04BB29EAFD0F94 6 5 Y pattern = r'txstop2: id (0x[0-9a-fA-F]+), socket (\d+), ([\d-]+ [\d:]+) ([\d.]+)kWh' match = re.match(pattern, line) if match: tx_id = match.group(1) socket_num = int(match.group(2)) timestamp = datetime.strptime(match.group(3), '%Y-%m-%d %H:%M:%S') kwh = Decimal(match.group(4)) # Check if we have the start for this transaction if tx_id not in self.pending_transactions: print(f" ⚠ Stop gevonden voor {tx_id} maar geen start - overgeslagen") return False tx_data = self.pending_transactions[tx_id] # Calculate total consumption total_kwh = kwh - tx_data['start_kWh'] try: # Check if transaction already exists self.cursor.execute( "SELECT id FROM transactions WHERE transaction_id = %s", (tx_id,) ) existing = self.cursor.fetchone() if existing: print(f" ⚠ Transactie {tx_id} bestaat al - overgeslagen") del self.pending_transactions[tx_id] return False # Insert complete transaction self.cursor.execute(""" INSERT INTO transactions (transaction_id, socket, start_timestamp, start_kWh, stop_timestamp, stop_kWh, total_kWh, card) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) """, ( tx_id, tx_data['socket'], tx_data['start_timestamp'], tx_data['start_kWh'], timestamp, kwh, total_kwh, tx_data['card'] )) self.conn.commit() # Remove from pending del self.pending_transactions[tx_id] print(f" ✓ Transactie {tx_id} opgeslagen ({total_kwh:.3f} kWh)") return True except mysql.connector.Error as err: print(f" ✗ Fout bij opslaan transactie {tx_id}: {err}") return False return False def import_file(self, filepath): """Import CSV file into database""" print(f"\n=== Import gestart: {filepath} ===\n") line_count = 0 tx_start_count = 0 tx_stop_count = 0 tx_saved_count = 0 try: with open(filepath, 'r') as file: for line_num, line in enumerate(file, 1): line = line.strip() # Skip empty lines and comments if not line or line.startswith('# Generated'): continue line_count += 1 # Parse transaction start if line.startswith('txstart2:'): if self.parse_txstart(line): tx_start_count += 1 # Parse transaction stop elif line.startswith('txstop2:'): if self.parse_txstop(line): tx_stop_count += 1 tx_saved_count += 1 # Skip meter values (mv:) - niet opgeslagen in deze tabel elif line.startswith('mv:'): continue print(f"\n=== Import voltooid ===") print(f"✓ Totaal regels verwerkt: {line_count}") print(f"✓ Transacties gestart: {tx_start_count}") print(f"✓ Transacties gestopt: {tx_stop_count}") print(f"✓ Transacties opgeslagen: {tx_saved_count}") # Check for incomplete transactions if self.pending_transactions: print(f"\n⚠ Let op: {len(self.pending_transactions)} transactie(s) nog actief (geen stop gevonden):") for tx_id in self.pending_transactions: print(f" - {tx_id}") # Show summary statistics self.show_statistics() except FileNotFoundError: print(f"✗ Bestand niet gevonden: {filepath}") sys.exit(1) except Exception as err: print(f"✗ Onverwachte fout: {err}") import traceback traceback.print_exc() self.conn.rollback() sys.exit(1) def show_statistics(self): """Show database statistics after import""" print("\n=== Database Statistieken ===") # Total transactions self.cursor.execute("SELECT COUNT(*) FROM transactions") total_tx = self.cursor.fetchone()[0] print(f"Totaal transacties in database: {total_tx}") # Total consumption self.cursor.execute("SELECT SUM(total_kWh) FROM transactions") result = self.cursor.fetchone() total_consumption = result[0] if result[0] else 0 print(f"Totaal verbruik: {total_consumption:.3f} kWh") # Latest transaction self.cursor.execute(""" SELECT transaction_id, start_timestamp, stop_timestamp, total_kWh FROM transactions ORDER BY stop_timestamp DESC LIMIT 1 """) latest = self.cursor.fetchone() if latest: print(f"\nLaatste transactie:") print(f" ID: {latest[0]}") print(f" Periode: {latest[1]} - {latest[2]}") print(f" Verbruik: {latest[3]:.3f} kWh") def main(): if len(sys.argv) < 2: print("Gebruik: python3 import_to_existing_db.py ") print("\nVoorbeeld: python3 import_to_existing_db.py VAN_01971_Transactions.csv") sys.exit(1) csv_file = sys.argv[1] print("=" * 60) print("Charging Station Data Importer") print("Import naar bestaande 'transactions' tabel") print("=" * 60) # Create importer instance importer = ChargingDataImporter(DB_CONFIG) try: # Connect to database importer.connect() # Import the file importer.import_file(csv_file) finally: # Close connection importer.close() print("\n✓ Database verbinding gesloten") if __name__ == "__main__": main()