Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- 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
This commit is contained in:
268
tools/citrineos-core-main/README.md
Normal file
268
tools/citrineos-core-main/README.md
Normal file
@@ -0,0 +1,268 @@
|
||||

|
||||

|
||||
|
||||
<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)
|
||||
Reference in New Issue
Block a user