Skip to content

savekar-ev/OCPI-2.2.1-EMSP-Simulator

Savekar Logo

OCPI 2.2.1 EMSP Simulator

An open-source, production-quality EMSP simulator for validating OCPI 2.2.1 CPO implementations

License Python OCPI FastAPI PRs Welcome GitHub Issues

Overview Β· Features Β· Quick Start Β· Usage Β· Contributing Β· Contact


🏒 About Savekar

Savekar is an Indian EV technology company building the infrastructure for the electric vehicle revolution. We develop open, standards-based software for EV charging networks β€” including Charge Point Management Systems (CPMS), OCPP & OCPI protocol stacks, and fleet management tooling.

We believe open-source collaboration is key to accelerating EV adoption. This simulator is one of our open-source contributions to the global EV developer community.

🌐 Website: savekar.com
πŸ“§ Contact: savekarev@gmail.com
πŸ’Ό GitHub Org: github.com/savekar


🀝 Test Your OCPI Integration With Us

Are you building a production-grade CPO and want to validate your OCPI implementation against a real EMSP before going live with a roaming partner?

We offer connectivity testing against our hosted EMSP simulator. Reach out to us and we'll help you verify your OCPI handshake, Location pushes, Session updates, and CDR submissions are spec-compliant.


πŸ“– Overview

The OCPI 2.2.1 EMSP Simulator is a lightweight, developer-focused tool designed to simulate an e-Mobility Service Provider (EMSP) that communicates strictly via the Open Charge Point Interface (OCPI) 2.2.1 protocol.

It is primarily used to validate that a Charge Point Operator (CPO) backend correctly implements the OCPI 2.2.1 specification β€” covering credentials exchange, location synchronization, session management, and CDR submission β€” before integrating with real roaming partners.

⚠️ Scope & Limitations

Limitation Details
Not a Production EMSP Testing-only tool. Does not handle real payments, user management, or business logic.
OCPI 2.2.1 Only Strictly adheres to OCPI version 2.2.1.
No Commands Module Does not implement Start/Stop Session via Commands. Session lifecycle is used instead.
Schema Validation Uses official OCPI 2.2.1 JSON schemas. May not cover every edge case of the full specification.

πŸ‘₯ Intended Audience

This simulator is built for:

  • Backend Engineers building CPO platforms who need EMSP validation.
  • EV Platform Developers testing OCPI compliance before going live with roaming partners.
  • QA & Integration Teams running automated protocol validation pipelines.

βœ… What This Simulator Validates

  • βœ… OCPI endpoint direction and correct usage
  • βœ… Credentials handshake (Token A β†’ B β†’ C exchange)
  • βœ… Schema correctness for Locations, Sessions, and CDRs
  • βœ… OCPI response envelope and status code semantics
  • βœ… EVSE status PATCH updates
  • βœ… CDR ingestion and validation

❌ What It Does NOT Validate

  • ❌ Commercial settlement or billing rules
  • ❌ Partner-specific extensions or quirks
  • ❌ Certification-level compliance
  • ❌ Real-world EMSP operational behavior

πŸ—οΈ Architectural Design

The EMSP Simulator is designed with a clear separation between passive endpoints (for CPO-initiated pushes) and active test clients (for EMSP-initiated requests).

flowchart TB
    CPO(("πŸ‘€ Target CPO Backend<br/>(Under Test)"))
    
    subgraph "OCPI 2.2.1 EMSP Simulator"
        direction TB
        UI["πŸ’» Web Dashboard<br/>(ui/)"]
        Tests["πŸ€– Active Test Client<br/>(verify_cpo.py)"]
        
        subgraph "FastAPI Server"
            direction LR
            Endpoints["πŸ”Œ OCPI Endpoints<br/>(app/routes)"]
            Validators{"βœ… Schema Validation<br/>(app/validators)"}
            State[("🧠 State Manager<br/>(app/state.py)")]
            
            Endpoints --> Validators
            Validators --> State
        end
        
        UI -.->|Reads state| State
    end

    CPO == "HTTP POST/PUT/PATCH<br/>(Push Locations, Sessions, CDRs)" ==> Endpoints
    Tests == "HTTP GET/POST<br/>(Test CPO Handshake & Fetch)" ==> CPO
Loading

✨ Features

Feature Description
Strict Schema Validation Validates incoming OCPI data against official 2.2.1 JSON schemas. HTTP status is configurable (200 or 400).
Credentials Handshake Full implementation of the CREDENTIALS module (Receiver & Sender).
Location Updates Accepts PUT and PATCH updates for Location and EVSE status.
CDR Ingestion Accepts and validates Charge Detail Records against the OCPI schema.
Session Management Handles PUT and PATCH session updates and GET queries.
CPO Client Utility Includes an active client to call your CPO's OCPI endpoints ('Sender' role).
Structured Logging Context-rich logs with direction, module, and payload details.
Web UI Simple browser-based dashboard for status monitoring.
Verification Script verify_cpo.py β€” one-command PASS/FAIL validation of your CPO.

πŸš€ Quick Start

Prerequisites

  • Python 3.8 or higher
  • pip (Python package installer)
  • A running CPO implementation to test against

1. Clone the Repository

git clone https://github.com/savekar/OCPI-2.2.1-EMSP-Simulator.git
cd OCPI-2.2.1-EMSP-Simulator

2. Install Dependencies

pip install -r requirements.txt

Tip: Use a virtual environment to keep your dependencies isolated:

python -m venv venv
source venv/bin/activate        # Linux/macOS
venv\Scripts\activate.bat       # Windows
pip install -r requirements.txt

3. Configure

Copy the example configuration and edit it for your environment:

cp config.example.yaml config.yaml
# On Windows (if cp is not available):
# copy config.example.yaml config.yaml

Edit config.yaml with your CPO's details:

Setting Description Default
host Interface to bind to 127.0.0.1
port Port to listen on 8000
log_level Logging verbosity (info, debug) info
validation_error_http_status Status code for schema errors (200 = strict OCPI, 400 = clearer debugging) 400
bootstrap_token Token expected from CPO for initial handshake (Token A) β€”
emsp_token_to_cpo Token sent by Simulator to CPO in requests (Token C) β€”
cpo_token_to_emsp Token expected from CPO after handshake (Token B) β€”
cpo_url Base URL of your CPO's OCPI API β€”

4. Start the Simulator

python run.py

The simulator will start at http://127.0.0.1:8000 (or your configured host/port).

Open your browser and navigate to http://localhost:8000 to access the Web UI.


πŸ“š Usage Guide

OCPI Endpoints Exposed

Module Method Endpoint
Versions GET /ocpi/versions
Credentials GET, POST, PUT /ocpi/emsp/2.2.1/credentials
Locations GET, PUT, PATCH /ocpi/emsp/2.2.1/locations/{...}
Sessions GET, PUT, PATCH /ocpi/emsp/2.2.1/sessions/{...}
CDRs GET, POST /ocpi/emsp/2.2.1/cdrs/{...}

Step 1: Credentials Handshake

Your CPO must initiate the connection by performing the OCPI credentials exchange:

  1. Ensure bootstrap_token in config.yaml matches what your CPO will send.
  2. From your CPO, send a POST request to:
    POST http://localhost:8000/ocpi/emsp/2.2.1/credentials
    Authorization: Token <bootstrap_token>
    
  3. The simulator validates your request, stores your credentials, and returns its own (including emsp_token_to_cpo).

Step 2: Run the Verification Script

Use the bundled script to actively test your CPO's OCPI endpoints:

python verify_cpo.py

This script will:

  • Confirm the CPO is reachable at the configured URL.
  • Attempt to fetch locations and tariffs.
  • Provide a high-level PASS/FAIL summary for each check.

Logs & Debugging

The simulator writes structured logs to stdout and optionally to a file (configured in config.yaml):

[CPO→EMSP][credentials] Invalid Token {Token=abc123...}
[EMSP→CPO][sessions]    Session update accepted {session_id=xyz}

Format: [Direction][Module] Message {Context}


πŸ“ Project Structure

OCPI-2.2.1-EMSP-Simulator/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ routes/              # Server-side OCPI endpoint handlers
β”‚   β”œβ”€β”€ client/              # Client-side logic to call CPO endpoints
β”‚   β”œβ”€β”€ validators/
β”‚   β”‚   └── json_schemas/    # Official OCPI 2.2.1 JSON schemas
β”‚   β”œβ”€β”€ config.py            # Configuration loader
β”‚   β”œβ”€β”€ log_utils.py         # Structured logging utilities
β”‚   β”œβ”€β”€ state.py             # In-memory state management
β”‚   └── main.py              # FastAPI application setup
β”œβ”€β”€ tests/                   # Automated verification scripts
β”œβ”€β”€ ui/                      # Simple HTML/JS frontend dashboard
β”œβ”€β”€ config.example.yaml      # Example configuration file
β”œβ”€β”€ run.py                   # Application entrypoint
β”œβ”€β”€ verify_cpo.py            # Active CPO validation script
└── requirements.txt         # Python dependencies

🀝 Contributing

We welcome contributions from the community! Whether it's a bug fix, new feature, or documentation improvement β€” all contributions are appreciated.

Please read our Contributing Guide before submitting a pull request.

Quick steps:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature-name
  3. Make your changes and write tests
  4. Commit: git commit -m "feat: add your feature"
  5. Push: git push origin feature/your-feature-name
  6. Open a Pull Request

πŸ›‘οΈ Security

If you discover a security vulnerability, please do not open a public GitHub issue. Instead, follow our Security Policy and report it privately.


πŸ“„ License

This project is licensed under the BSD 3-Clause License. See the LICENSE file for details.


πŸ“¬ Contact & Support

Channel Link
πŸ“§ Email savekarev@gmail.com
πŸ› Bug Reports Open an Issue
πŸ’¬ Discussions GitHub Discussions
🌐 Website savekar.com
πŸ”Œ OCPI Testing savekar.com/ocpi-simulator

Built with ❀️ by the Savekar team · Powering the EV revolution with open standards

About

A lightweight Python-based OCPI 2.2.1 EMSP Simulator to validate CPO protocol correctness, credentials handshake, and schema compliance

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors