An open-source, production-quality EMSP simulator for validating OCPI 2.2.1 CPO implementations
Overview Β· Features Β· Quick Start Β· Usage Β· Contributing Β· Contact
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
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.
- π§ Email: savekarev@gmail.com
- π¬ GitHub: Open an issue or discussion on this repository
- π More details: https://savekar.com/ocpi-simulator
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.
| 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. |
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.
- β 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
- β Commercial settlement or billing rules
- β Partner-specific extensions or quirks
- β Certification-level compliance
- β Real-world EMSP operational behavior
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
| 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. |
- Python 3.8 or higher
- pip (Python package installer)
- A running CPO implementation to test against
git clone https://github.com/savekar/OCPI-2.2.1-EMSP-Simulator.git
cd OCPI-2.2.1-EMSP-Simulatorpip install -r requirements.txtTip: 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
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.yamlEdit 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 | β |
python run.pyThe 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.
| 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/{...} |
Your CPO must initiate the connection by performing the OCPI credentials exchange:
- Ensure
bootstrap_tokeninconfig.yamlmatches what your CPO will send. - From your CPO, send a
POSTrequest to:POST http://localhost:8000/ocpi/emsp/2.2.1/credentials Authorization: Token <bootstrap_token> - The simulator validates your request, stores your credentials, and returns its own (including
emsp_token_to_cpo).
Use the bundled script to actively test your CPO's OCPI endpoints:
python verify_cpo.pyThis 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.
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}
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
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:
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature-name - Make your changes and write tests
- Commit:
git commit -m "feat: add your feature" - Push:
git push origin feature/your-feature-name - Open a Pull Request
If you discover a security vulnerability, please do not open a public GitHub issue. Instead, follow our Security Policy and report it privately.
This project is licensed under the BSD 3-Clause License. See the LICENSE file for details.
| Channel | Link |
|---|---|
| π§ Email | savekarev@gmail.com |
| π Bug Reports | Open an Issue |
| π¬ Discussions | GitHub Discussions |
| π Website | savekar.com |
| π OCPI Testing | savekar.com/ocpi-simulator |