- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
269 lines
13 KiB
Markdown
269 lines
13 KiB
Markdown

|
|

|
|
|
|
<div align="center">
|
|
<img src="OCPP_201_Logo_core_and_advanced_security.png" alt="CitrineOS Certification Logo" width="200" height="100" />
|
|
</div>
|
|
|
|
# Welcome to CitrineOS
|
|
|
|
CitrineOS is an open-source project aimed at providing a modular server runtime for managing Electric Vehicle (EV)
|
|
charging infrastructure. This repository (`citrineos-core`) is a **pnpm monorepo** containing the charging station
|
|
management logic, OCPP message routing, the related services, and the operator-facing web UI.
|
|
|
|
This README covers the repository as a whole: how it is structured, how to install and build it, and how to run the
|
|
full stack. Each application and package also has its own README with deeper, component-specific documentation —
|
|
see [Repository Structure](#repository-structure) and [Component Documentation](#component-documentation).
|
|
|
|
All other documentation and the issue tracking can be found in our main repository
|
|
here: <https://github.com/citrineos/citrineos>.
|
|
|
|
## Table of Contents
|
|
|
|
- [Overview](#overview)
|
|
- [Architecture Flow](#architecture-flow)
|
|
- [Repository Structure](#repository-structure)
|
|
- [Prerequisites](#prerequisites)
|
|
- [Installation](#installation)
|
|
- [Running the Full Stack with Docker](#running-the-full-stack-with-docker)
|
|
- [Information on Docker Setup](#information-on-docker-setup)
|
|
- [Workspace Scripts](#workspace-scripts)
|
|
- [Component Documentation](#component-documentation)
|
|
- [Contributing](#contributing)
|
|
- [Licensing](#licensing)
|
|
- [Support and Contact](#support-and-contact)
|
|
- [Roadmap](#roadmap)
|
|
|
|
## Overview
|
|
|
|
CitrineOS is developed in TypeScript and runs on `NodeJS` with [ws](https://github.com/websockets/ws)
|
|
and [fastify](https://fastify.dev/). The operator UI is built with [Next.js](https://nextjs.org/) and
|
|
[Refine](https://refine.dev/).
|
|
|
|
The system features:
|
|
|
|
- Dynamic **OCPP 1.6 and 2.0.1** message schema validation, prior to transmission using `AJV`
|
|
- Generated OpenAPIv3 specification for easy developer access
|
|
- Configurable logical modules with decorators
|
|
- `@AsHandler` to handle incoming OCPP messages (1.6 or 2.0.1)
|
|
- `@AsMessageEndpoint` to expose functions allowing sending messages to charging stations
|
|
- `@AsDataEndpoint` to expose CRUD access to data entities
|
|
- Utilities to connect and extend various message broker and cache mechanisms
|
|
- Currently supported broker is **RabbitMQ**
|
|
- Currently supported caches are **In Memory** and **Redis**
|
|
- A web-based **Operator UI** for managing locations, stations, transactions, and authorizations
|
|
|
|
For more information on the project go to [citrineos.github.io](https://citrineos.github.io).
|
|
|
|
## Architecture Flow
|
|
|
|
Here's a **flowchart-style overview** of CitrineOS architecture and message flow:
|
|
|
|
```text
|
|
┌───────────────────┐ ┌───────────────────┐
|
|
│ Charging Stations │ │ Operator UI │
|
|
│ (OCPP 1.6 & │ │ (Next.js + Refine)│
|
|
│ 2.0.1) │ └───┬───────────┬───┘
|
|
└────────┬──────────┘ REST (Data │ │ GraphQL
|
|
│ WebSocket & Message API)│ │
|
|
▼ ▼ ▼
|
|
┌───────────────────┐ ┌───────────────────┐ ┌──────────────┐
|
|
│ CitrineOS Server │ │ CitrineOS Server │ │ Hasura │
|
|
│ (OCPP Router + │ │ (HTTP / REST) │ │GraphQL Engine│
|
|
│ Modules) │ └───────────────────┘ └──────┬───────┘
|
|
└────────┬──────────┘ │
|
|
│ │
|
|
┌─────┴─────────┐ ┌─────────────┐ │
|
|
▼ ▼ │ File Storage│ ▼
|
|
┌─────────────┐ ┌─────────────┐ │ (S3 / GCS / │ ┌─────────────┐
|
|
│ Message │ │ PostgreSQL │ │ MinIO) │ │ PostgreSQL │
|
|
│ Broker │ │ (PostGIS) │ └─────────────┘ │ (PostGIS) │
|
|
│ (RabbitMQ) │ │ Persistence │ │ (same DB) │
|
|
└─────────────┘ └─────────────┘ └─────────────┘
|
|
```
|
|
|
|
### Flow Overview
|
|
|
|
1. **Charging Stations** send messages using **OCPP 1.6** or **OCPP 2.0.1**.
|
|
2. **CitrineOS Server** receives and routes messages via **WebSocket** to the **OCPP Router**.
|
|
3. The **Message Broker (RabbitMQ)** handles **inter-module communication**, enabling asynchronous processing between the OCPP Router and other server modules.
|
|
4. Operational and configuration data are persisted in **PostgreSQL** (with the PostGIS extension).
|
|
5. Files and assets are stored in **Amazon S3** or **Google Cloud Storage (GCS)** in supported environments. **MinIO** is used for **local development**, providing **S3-compatible storage**. Local development does **not** support a GCS-compatible storage backend.
|
|
6. The **Operator UI** reads data through the **Hasura GraphQL Engine** (which queries the same PostgreSQL database) and sends commands and manages entities through the server's **REST Data and Message APIs**.
|
|
|
|
## Repository Structure
|
|
|
|
This repository is a **pnpm monorepo** with the following workspace members:
|
|
|
|
```
|
|
citrineos-core/
|
|
├── apps/
|
|
│ ├── Server/ # OCPP server entrypoint, Docker setup, migrations (@citrineos/server)
|
|
│ └── operator-ui/ # Operator web UI — Next.js + Refine (@citrineos/operator-ui)
|
|
├── packages/
|
|
│ ├── base/ # Shared types, interfaces, and utilities (@citrineos/base)
|
|
│ └── core/ # Core OCPP modules and logic (@citrineos/core)
|
|
├── docker-compose.yml # Full stack from published ghcr.io images (server + UI)
|
|
├── docker-compose.local.yml # Full stack, server built from local source
|
|
├── package.json # Root workspace scripts
|
|
└── pnpm-workspace.yaml # pnpm workspace configuration
|
|
```
|
|
|
|
Each workspace member documents itself:
|
|
|
|
- **Server** — running the server, configuration, bootstrap env vars, migrations, OCPP interfaces, EVerest testing: [`apps/Server/README.md`](./apps/Server/README.md)
|
|
- **Operator UI** — running and developing the web UI, bringing a station online end-to-end: [`apps/operator-ui/README.MD`](./apps/operator-ui/README.MD)
|
|
|
|
## Prerequisites
|
|
|
|
Before you begin, make sure you have the following installed on your system:
|
|
|
|
- Node.js (v24.16.0 or higher): [Download Node.js](https://nodejs.org/)
|
|
- pnpm (the workspace's package manager): [Download pnpm](https://pnpm.io/installation)
|
|
- Docker (Optional). Version >= 20.10: [Download Docker](https://docs.docker.com/get-docker/)
|
|
|
|
## Installation
|
|
|
|
1. Clone the CitrineOS repository to your local machine:
|
|
|
|
```shell
|
|
git clone https://github.com/citrineos/citrineos-core
|
|
```
|
|
|
|
1. Install all workspace dependencies from the root directory:
|
|
|
|
```shell
|
|
pnpm install
|
|
```
|
|
|
|
1. Build all packages from the root directory:
|
|
|
|
```shell
|
|
pnpm run build
|
|
```
|
|
|
|
## Running the Full Stack with Docker
|
|
|
|
The quickest way to get a complete environment running is via the root-level Docker Compose files, which start the
|
|
server, the operator UI, RabbitMQ, PostgreSQL, MinIO, and Hasura together.
|
|
|
|
- **From published images** (no build required) — run from the repository root:
|
|
|
|
```shell
|
|
docker compose up -d
|
|
```
|
|
|
|
- **With the server built from local source** — run from the repository root:
|
|
|
|
```shell
|
|
docker compose -f docker-compose.local.yml up -d
|
|
```
|
|
|
|
Once everything is up, the operator UI is available at [http://localhost:3000](http://localhost:3000) and the server's
|
|
Swagger docs at [http://localhost:8080/docs](http://localhost:8080/docs).
|
|
|
|
To run just the backend (no operator UI), or to run the server directly with pnpm for development, see the
|
|
[Server README](./apps/Server/README.md). To develop the UI on its own, see the
|
|
[Operator UI README](./apps/operator-ui/README.MD).
|
|
|
|
## Information on Docker Setup
|
|
|
|
You need to install
|
|
[docker](https://docs.docker.com/engine/install/#server) (>= 20.10) and
|
|
[docker-compose](https://docs.docker.com/compose/install/#install-compose).
|
|
Furthermore, [Visual Studio Code](https://code.visualstudio.com/docs/setup/linux) might be handy as a common
|
|
integrated development environment.
|
|
|
|
There are three Compose files:
|
|
|
|
- `docker-compose.yml` (repository root) — full stack from published `ghcr.io` images, including the operator UI.
|
|
- `docker-compose.local.yml` (repository root) — full stack with the server built from local source.
|
|
- `apps/Server/docker-compose.yml` — backend only (no operator UI), server built from local source (see the [Server README](./apps/Server/README.md)).
|
|
|
|
Once a stack is running, the following services should be available:
|
|
|
|
- **CitrineOS Server** (service name: citrine)
|
|
- `8080`: webserver HTTP - [Swagger](http://localhost:8080/docs)
|
|
- `8081`: websocket server TCP connection without auth
|
|
- `8082`: websocket server TCP connection with basic HTTP auth
|
|
- `8083`: additional websocket server
|
|
- `8443` / `8444`: TLS websocket servers
|
|
- `9229`: Node.js debugger
|
|
- **Operator UI** (service name: citrine-ui) — only in the root-level Compose files
|
|
- `3000`: [Operator UI](http://localhost:3000)
|
|
- **RabbitMQ Broker** (service name: amqp-broker)
|
|
- `5672`: AMQP TCP connection
|
|
- `15672`: RabbitMQ [management interface](http://localhost:15672)
|
|
- **PostgreSQL** (service name: ocpp-db), PostGIS-enabled PostgreSQL database for persistence
|
|
- `5432`: SQL TCP connection
|
|
- **MinIO** (service name: minio) for S3-compatible local file storage
|
|
- `9000`: S3 API endpoint
|
|
- `9001`: MinIO [web console](http://localhost:9001)
|
|
- **Hasura GraphQL Engine** (service name: graphql-engine)
|
|
- `8090`: [Hasura console](http://localhost:8090)
|
|
|
|
These services live inside the docker network with their respective ports. By default these ports are directly
|
|
accessible using `localhost:8080` for example.
|
|
|
|
## Workspace Scripts
|
|
|
|
These scripts are run from the repository root and operate across the whole workspace.
|
|
|
|
### Building
|
|
|
|
- `pnpm run build` - builds all packages
|
|
- `pnpm run start` - starts the CitrineOS server (delegates to `@citrineos/server`)
|
|
|
|
### Running `clean` and `fresh`
|
|
|
|
The workspace consists of multiple `pnpm` packages that are loaded as dependencies when running the application. This
|
|
means packages need to be rebuilt when their files change. In some cases — in particular when switching between
|
|
branches, especially when there are changes in a `package.json` — the already built `dist` as well as the generated
|
|
`pnpm-lock.yaml` may become invalid.
|
|
|
|
To alleviate the above, we created the following commands (run from the root directory):
|
|
|
|
- `pnpm run fresh` - deletes all `node_modules`, `dist`, `tsbuildinfo`, and `pnpm-lock.yaml`, then clears the pnpm cache
|
|
- `pnpm run clean` - subset of `pnpm run fresh`; only deletes build artifacts (`dist` and `tsbuildinfo`)
|
|
- `pnpm run fi` - convenience command that runs `fresh` followed by `pnpm install`
|
|
|
|
### Linting and Prettier
|
|
|
|
ESLint and Prettier have been configured to help support syntactical consistency throughout the codebase.
|
|
|
|
- `pnpm run prettier` - runs Prettier and formats the files
|
|
- `pnpm run lint` - runs the linter
|
|
- `pnpm run lint-fix` - runs Prettier and the linter with the `--fix` flag, which attempts to resolve any linting issues
|
|
|
|
### Testing
|
|
|
|
- `pnpm run test` - runs the test suite with Vitest
|
|
- `pnpm run coverage` - runs the test suite with coverage
|
|
|
|
## Component Documentation
|
|
|
|
- [CitrineOS Server (`@citrineos/server`)](./apps/Server/README.md) — running the server, configuration, bootstrap
|
|
environment variables, database migrations, OCPP interface generation, custom DataTransfer validation,
|
|
auto-commissioning, Hasura metadata, and EVerest testing.
|
|
- [CitrineOS Operator UI (`@citrineos/operator-ui`)](./apps/operator-ui/README.MD) — running and developing the web UI,
|
|
and a step-by-step guide to bringing a charging station online end-to-end.
|
|
- [Testing with EVerest](./apps/Server/everest/README.md) — running the EVerest charger simulator against CitrineOS.
|
|
|
|
## Contributing
|
|
|
|
We welcome contributions from the community. If you would like to contribute to CitrineOS, please follow
|
|
our [contribution guidelines](https://github.com/citrineos/citrineos/blob/main/CONTRIBUTING.md).
|
|
|
|
## Licensing
|
|
|
|
CitrineOS and its subprojects are licensed under the Apache License, Version 2.0. See LICENSE for the full license text.
|
|
|
|
## Support and Contact
|
|
|
|
If you have any questions or need assistance, feel free to reach out to us on our community forum or create an issue on
|
|
the GitHub repository.
|
|
|
|
## Roadmap
|
|
|
|
[Roadmap](https://citrineos.github.io/docs/roadmap.html)
|