EV Charger Management Platform

Delivered as part of the engineering team on a staffed engagement with a partner company.

The client manufactures a line of smart EV wallbox chargers — entry-level to app-managed, energy-optimizing models — sold for homes, apartment buildings, offices, hotels, and public parking across dozens of countries. Each unit ships as a connected device: an installer or owner pairs it to a mobile app for scheduling, monitoring, and remote control, and operators running multiple units need a fleet-wide view. White Buffalo built the backend and dashboard that make that connectivity work at scale — from the link into each charger, through telemetry ingestion, to the operations view that turns individual charger data into fleet-level status and usage.

Challenge

The client needed to monitor and manage a network of EV chargers remotely — charger status, session data, and usage in real time — with the ability to push commands and configuration updates back to hardware in the field.

What we built

  • Two-way communication layer between chargers and backend (Go)
  • Message-driven ingestion pipeline for charger telemetry and session events (Kafka/RabbitMQ)
  • Time-series storage for usage and session data (TimescaleDB)
  • Operations dashboard for charger status, session history, and fleet-wide usage (React), plus supporting APIs (Node.js)
  • CI/CD and containerized deployment pipeline (Jenkins, Docker Swarm)

Under the hood

Each charger holds a persistent connection back to a Go service that speaks the charger's control protocol: connect/heartbeat handshakes, status and session-state changes, and remote commands (start/stop a session, push a config or firmware update) flowing back down to hardware in the field. Go's concurrency model let one service hold thousands of long-lived per-charger connections without a thread-per-connection cost.

Every state change and session event is published onto Kafka/RabbitMQ rather than written directly by the connection layer. That decouples the chargers' connection handling from everything downstream — ingestion consumers can be scaled, restarted, or replayed independently, and a slow or failing downstream consumer never backs up onto the charger link itself.

Session and usage data lands in TimescaleDB as hypertables partitioned by time, with continuous aggregates precomputing the rollups (daily/weekly usage, per-charger and fleet-wide) that the dashboard reads, so those views stay fast without scanning raw session history on every request.

A Node.js API layer sits between storage and the frontend, exposing charger status, session history, and fleet usage as REST endpoints and handling the command path for dispatching remote actions back through the Go connection layer.

The React operations dashboard consumes those APIs to show live charger status, session history, and fleet-wide usage, with controls for remote start/stop and configuration pushes. The whole stack — connection layer, ingestion consumers, API, dashboard — deploys as containers on Docker Swarm through a Jenkins CI/CD pipeline.