Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

{DE4329F6-6EAF-4B82-8324-7937D1818AC9}

CarCharging

EV charging decision backend that analyzes UK grid carbon-intensity data and recommends the cleanest charging window in the next 48 hours.

CI

GitHub Java 17 Spring Boot 3.3.5 NESO API Docker

Live frontend preview · Frontend repository


Overview

CarCharging is a Spring Boot backend that helps EV owners charge when the grid is cleanest rather than simply when electricity is available.

It integrates with the UK carbon intensity API and exposes a simple REST interface for:

  • retrieving forecasted daily energy mix,
  • calculating the clean-energy percentage,
  • finding the best charging window for a selected duration.

This is a compact but strong portfolio project because it shows:

  • external API integration,
  • domain-specific data transformation,
  • optimization logic over time-series intervals,
  • clean REST endpoint design,
  • Dockerized deployment.

Value Proposition

For EV users, charging at the right time can reduce carbon impact without changing hardware. CarCharging turns raw generation-mix data into an actionable recommendation:

  • When should I charge?
  • How clean is the grid over the next few days?
  • What is the best 1-6 hour charging window in the next 48 hours?

Features

  • Best charging window calculation for a user-selected duration
  • 48-hour optimization window based on forecasted generation data
  • Daily energy mix summaries for the coming days
  • Clean energy percentage calculation using selected low-carbon sources
  • Simple REST API designed for frontend consumption
  • CORS-enabled endpoints for web integration
  • Dockerized runtime for easy deployment
  • Frontend-ready backend with a linked React/TypeScript UI

Tech Stack

Category Technologies
Language Java 17
Framework Spring Boot 3.3.5
API Style REST
External Data Source NESO / UK Carbon Intensity API
Build Tool Maven
Containerization Docker
Frontend Consumer React + TypeScript frontend repo
Testing Spring Boot Test

Stack badges

Spring Web Maven REST Time Series


High-level flow

Frontend / Client
      |
      v
Spring Boot REST Controllers
      |
      v
Service Layer
  |             |
  |             +--> Charging window optimization
  |
  +-----------------> Carbon intensity API client
                         |
                         v
                 UK generation forecast data

Main modules

client/
config/
controller/
model/dto/
model/external/
service/
util/

Main components

  • CarbonIntensityClient - fetches external generation data
  • EnergyService - aggregates daily energy mix and clean-energy percentage
  • ChargingService - computes the best charging window
  • ChargingController - exposes charging recommendation endpoint
  • EnergyController - exposes energy mix endpoint

Project Structure

src/main/java/org/qualv13/carcharging/
├── client/
│   └── CarbonIntensityClient.java
├── config/
│   ├── RestClientConfig.java
│   └── WebConfig.java
├── controller/
│   ├── ChargingController.java
│   └── EnergyController.java
├── model/
│   ├── dto/
│   │   ├── ChargingWindowDto.java
│   │   └── DailyMixDto.java
│   └── external/
│       ├── CarbonApiResponse.java
│       ├── FuelMix.java
│       └── GenerationData.java
├── service/
│   ├── ChargingService.java
│   └── EnergyService.java
├── util/
│   └── EnergyConstants.java
└── CarChargingApplication.java

Installation and Setup

Prerequisites

  • Java 17
  • Maven 3.9+
  • Docker

Run locally with Maven

git clone https://github.com/qualv13/CarCharging.git
cd CarCharging
mvn spring-boot:run

The application starts as a standard Spring Boot service on port 8080 unless overridden.

Run with Docker

git clone https://github.com/qualv13/CarCharging.git
cd CarCharging
docker build -t carcharging .
docker run -p 8080:8080 carcharging

Verified Dockerfile behavior

  • Builds with maven:3.9.6-eclipse-temurin-17
  • Runs on eclipse-temurin:17-jre-alpine
  • Exposes port 8080

Usage Examples

Get the best charging window for 3h charging

curl "http://localhost:8080/api/charging/best-window?hours=3"

Example response

{
  "startTime": "2025-12-01T02:30Z",
  "endTime": "2025-12-01T05:30Z",
  "cleanEnergyPercent": 78.4
}

Get forecasted daily energy mix

curl "http://localhost:8080/api/energy/mix"

Example response

[
  {
    "date": "2025-11-30",
    "cleanEnergyPercent": 58.69791666666666,
    "dailyMix": {
      "hydro": 0.0,
      "other": 0.0,
      "biomass": 9.78958333333333,
      "imports": 10.422916666666666,
      "gas": 30.872916666666665,
      "solar": 2.3854166666666665,
      "coal": 0.0,
      "nuclear": 13.022916666666665,
      "wind": 33.49999999999999
    }
  }
]

Frontend integration example

const response = await fetch("http://localhost:8080/api/charging/best-window?hours=2");
const data = await response.json();

console.log(data.startTime, data.endTime, data.cleanEnergyPercent);

API Documentation

Endpoints

Method Endpoint Description
GET /api/charging/best-window?hours={n} Returns the cleanest charging window for 1-6 hours
GET /api/energy/mix Returns forecasted daily energy mix and clean-energy percentage

Request constraints

GET /api/charging/best-window

  • hours must be between 1 and 6
  • the service evaluates the next 48 hours
  • the algorithm uses half-hour forecast slots from the external API

If the requested duration cannot be computed from available future data, the service throws an error.


How the Charging Algorithm Works

The charging recommendation logic is simple

Verified behavior from the service implementation

  • Fetches generation data from today through the next 3 days
  • Filters intervals to the next 48 hours
  • Converts requested hours into 30-minute slots
  • Computes clean-energy percentage per slot
  • Uses a sliding window to find the highest average clean-energy period

Simplified logic

int slotsNeeded = hours * 2;

for (int i = 0; i < sortedData.size(); i++) {
    currentWindowSum += cleanPercentage(sortedData.get(i));

    if (i >= slotsNeeded) {
        currentWindowSum -= cleanPercentage(sortedData.get(i - slotsNeeded));
    }

    if (i >= slotsNeeded - 1 && currentWindowSum > maxCleanSum) {
        maxCleanSum = currentWindowSum;
        bestStartIndex = i - slotsNeeded + 1;
    }
}

This is a good example of applying a classic sliding-window optimization pattern to a real-world sustainability use case.


Screenshots

{462E77EF-FD64-42F9-82F1-5ACA86030080} {BB9D0CFD-95A8-4F8A-9424-7E7B1D0BF894} {0212E5F0-C149-451D-9DC8-1DD6B8AB1EDD}

Configuration

The verified repository only includes:

spring.application.name=CarCharging

That means the application is intentionally lightweight and relies primarily on code-level defaults and external API access.

Operational notes

  • Default runtime port is Spring Boot's standard 8080
  • Endpoints are annotated with @CrossOrigin(origins = "*")
  • No database is required

This simplicity is a strength for a focused API utility service.


Testing

18 tests, run on every push by CI.

Class Covers Tests
ChargingServiceTest the sliding window over half-hourly slots, including ties and short horizons 10
EnergyServiceTest daily mix aggregation with a mocked client 6
CarChargingApplicationTests the Spring context loads 1
EnergyServiceIntegrationTest the real NESO API, end to end 1
mvn test                                  # everything
mvn test -DexcludedGroups=integration     # what CI runs

The last one is tagged integration and left out of CI on purpose. It calls the live NESO Carbon Intensity API, so an outage upstream would fail a build that has nothing wrong with it. Worth running by hand when the client or the response shape changes.


Deployment

Build JAR

mvn clean package

Run packaged application

java -jar target/*.jar

Run containerized application

docker build -t carcharging .
docker run -p 8080:8080 carcharging

Production improvement ideas

  • Add response caching for external API calls
  • Add OpenAPI/Swagger docs
  • Add validation/error response standardization
  • Add rate limiting and resilience patterns
  • Add CI pipeline and container publishing
  • Add observability metrics

Contributing

Contributions are welcome.


Contact and Links

About

Spring Boot REST service that finds the cleanest 1-6 h EV charging window inside the next 48 hours from UK Carbon Intensity data, with a sliding window over half-hourly generation slots.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages