Network management dashboard for OCPP Core.
FastAPI + Jinja2 + HTMX. No React, no npm, no build step.
β Built-in authentication. JWT-based login with bcrypt password hashing. First-time setup wizard on first visit. No hardcoded credentials.
| Feature | Description |
|---|---|
| π Dashboard | Network overview β charger status, session counts, PKI health |
| π Chargers | List, filter, manage chargers; remote control (start/stop/reset/unlock) |
| β‘ Sessions | Live session monitoring with enriched data (RFID, energy, duration) |
| π° Tariffs | Create and manage pricing configurations |
| π·οΈ RFID / Tokens | Token management, whitelist/blacklist, group assignment |
| π₯ Groups | Charger groups and load-balancing configuration |
| π§Ύ Invoices | Session-based invoicing and export |
| π PKI | Certificate lifecycle dashboard β issue, revoke, inspect |
| π‘ OCPP Messages | Real-time OCPP event stream viewer |
| π‘οΈ Security | Security events, alert history, PKI health |
| ποΈ Features | Feature flags and runtime configuration |
| π Onboarding | Self-service PKI onboarding for operators (Root CA + personal cert) |
The admin panel uses JWT-based authentication against the OCPP Core API. On first access, you'll be redirected to /setup β a 6-step wizard where you create your admin account, configure the organization name, and set up SMTP. After setup, login uses email + password with bcrypt-hashed credentials stored in the ocpp.users table. Session tokens are stored as HTTP-only cookies (opencpo_session).
- Visit
http://localhost:8080β redirected to/setup - Step 1: Create admin account (email + password)
- Step 2: Configure organization name and public URL
- Step 3: SMTP settings (can be skipped)
- Step 4: PKI configuration (can be skipped)
- Step 5: Default pricing (can be skipped)
- Step 6: Feature flags (can be skipped)
- Redirected to
/loginβ sign in with your new credentials
All steps are skippable. You can return to /setup anytime to fill in missing configuration.
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtCopy the example env file and fill in your values:
cp .env.example .envAt minimum you need:
OCPP_CORE_API=http://localhost:8000# With .env file
python-dotenv run -- python main.py
# Or export vars manually
export OCPP_CORE_API=http://localhost:8000
python main.pyOpen http://localhost:8080 β you'll be redirected to the setup wizard on first visit.
All configuration is via environment variables (.env file supported via python-dotenv).
| Variable | Default | Description |
|---|---|---|
APP_TITLE |
OCPP Admin |
Application name shown in UI |
HOST |
127.0.0.1 |
Bind address for uvicorn |
PORT |
8080 |
Bind port |
DB_HOST |
127.0.0.1 |
PostgreSQL host |
DB_PORT |
5432 |
PostgreSQL port |
DB_NAME |
ocppcore |
PostgreSQL database name |
DB_USER |
ocpp |
PostgreSQL user |
DB_PASS |
(required) | PostgreSQL password |
OCPP_CORE_API |
http://localhost:8000 |
OCPP Core REST API base URL |
PKI_DATA_DIR |
../ocpp-core/data/pki |
Path to PKI data dir (contains root-ca.crt and users/) |
Browser ββHTMXββ CPO Admin (FastAPI)
β
ββ PostgreSQL (sessions, tokens, tariffs, groups)
β
ββ OCPP Core API (chargers, PKI, OCPP commands)
- OCPP Core handles the WebSocket charger connections and exposes a REST API
- CPO Admin is a pure UI layer β it reads from Postgres and calls OCPP Core
- HTMX powers live updates via SSE and partial HTML swaps (no WebSocket from browser)
- Tailwind CSS (CDN) β no build step required
python main.pyand it runs
The UI supports swappable skins via the skins/ directory.
skins/
base/ β generic default skin
The logo.svg in static/ is the primary branding asset (generic OpenCPO lightning bolt). Replace static/logo.png with your own PNG logo; it is not generated automatically.
Set SKIN=base (default) to use the generic skin. To use a custom skin:
- Copy
skins/base/toskins/my-brand/ - Edit colors, logo, and CSS in your skin directory
- Set
SKIN=my-brandin your.env
Copy skins/base/ as a starting point for your own branded skin.
The /onboarding page provides self-service certificate distribution:
- Operators visit
/onboarding - They download the Root CA certificate and install it in their OS trust store
- They enter their email to request a personal certificate (PKCS#12 or PEM)
- The admin authenticates via mutual TLS with their personal cert
PKI operations are delegated to OCPP Core via POST /api/v1/pki/issue/user.
The PKI data directory (cert storage) is configured via PKI_DATA_DIR.
- Python 3.11+
- PostgreSQL 14+
- OCPP Core service running (for charger control and PKI)
opensslCLI available (for DER conversion in onboarding)
Apache 2.0 β see LICENSE.