Files
import_alfen_transactions/import_to_alfendb.py
2025-11-02 10:41:41 +01:00

259 lines
9.1 KiB
Python

#!/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 <csv_bestand>")
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()