EV Charging Station Backend
Hệ thống Trạm Sạc Xe Điện
OCPP 1.6/2.0 backend for an 18-charger cluster — session control, time-of-day tariff, settlement.
Problem
A partner ran a pilot EV-charging cluster for 40 delivery vans. ABB & Schneider chargers speak OCPP, but the OEM management software is expensive and lock-in. They needed a custom backend to control tariffs and reconcile Momo/VietQR payments.
Architecture
OCPP 1.6 JSON over WebSocket (server) → Python aiohttp → Postgres (sessions) + Redis (state cache) → TOU tariff engine → Momo/VietQR webhooks ↔ ledger. End-of-day auto-reconcile; >0.5% mismatch ships a report.
Stack & rationale
- OCPP 1.6 + 2.0 dual support: ABB is 1.6, Schneider is 2.0 — server detects via handshake.
- aiohttp for WebSocket: lightweight, plays nicely with asyncio.
- TOU tariff: 4 brackets (off-peak/normal/peak/super-peak), JSON hot-reload.
Results (5-month run)
| Metric | Value |
|---|---|
| Charging sessions | 14,300 |
| Backend uptime | 99.7% |
| Financial mismatch | 0.12% |
| Avg kWh / session | 24.8 |
Lessons
OCPP version handshake must be robust — ABB reports 1.6 but uses a few 2.0 extensions. Transaction idempotency keys are critical (WebSocket reconnects easily duplicate sessions).