1.Audience and prerequisites
This cookbook is for charger vendors, OEM integrators, and CPO firmware engineers wiring an OCPP-capable charging station to the PixellEnergy CSMS. We assume working knowledge of OCPP 1.6J or OCPP 2.0.1 — the cookbook is a hand-rail through the PixellEnergy-specific decisions, not a tutorial on the protocol itself.
You will need, before you start:
- A tenant slug provisioned by PixellEnergy (your CSMS-as-a-Service contact will issue this — e.g.
acme). - One or more stations provisioned in the PixellEnergy operator portal (
central.pixellenergy.com) at/chargers/onboard. Each station ID is thestationIdin the WSS URL. - Security Profile 2 credentials (TLS + Basic Auth), shown once when the station is provisioned. Profile 3 (TLS + client certificate) is mandatory for production tenants.
- Outbound TLS 443 reachability to
gw.pixellenergy.com. The record is DNS-only: the station connects directly to the PixellEnergy gateway, with no Cloudflare proxy in the path.
The staging endpoint is wss://gw.staging.pixellenergy.com/ocpp/<tenant>/<station>. Test against staging until the JT-1 dry-run is green.
2.WSS endpoint format
Stations MUST connect over TLS WebSocket to the PixellEnergy gateway. The URL is deterministic per station:
wss://gw.pixellenergy.com/ocpp/<tenantSlug>/<stationId>Production hostname is gw.pixellenergy.com; staging is gw.staging.pixellenergy.com. Both are DNS-only records (not proxied through Cloudflare): the station opens a direct TLS WebSocket to the uWebSockets.js gateway in Mumbai (ap-south-1) — see the SLO dashboard for current regional latency.
Security
The legacy hostname gw.pixell.energy is NOT owned by PixellEnergy and will fail TLS verification. Any firmware shipped with that literal must be patched before connecting to production.
3.Subprotocol negotiation
Subprotocol negotiation lives in the gateway. The station SHOULD advertise every protocol version it supports as a comma-separated list in the Sec-WebSocket-Protocol header; the gateway picks the highest mutually-supported version and echoes it back.
# Client opens TLS WSS connection. Sec-WebSocket-Protocol is
# negotiated against the CSMS dispatch table.
#
# Single offer (1.6J):
Sec-WebSocket-Protocol: ocpp1.6
# Single offer (2.0.1):
Sec-WebSocket-Protocol: ocpp2.0.1
# Multi-offer (dispatch picks highest mutually-supported):
Sec-WebSocket-Protocol: ocpp2.1, ocpp2.0.1, ocpp1.6| Field | Type | Required | Notes |
|---|---|---|---|
| ocpp1.6 | literal | optional | OCPP 1.6J — JSON over WebSocket. Production-supported. |
| ocpp2.0.1 | literal | optional | OCPP 2.0.1 — recommended for new deployments. Required to access the SignedMeterValue tax-grade path. |
| ocpp2.1 | literal | optional | OCPP 2.1 — early-access. Falls back to 2.0.1 dispatch if a 2.1-only feature is exercised. |
The gateway responds with exactly one negotiated value. If none of the offered protocols are supported, the WSS handshake fails with HTTP 400 + the response body SUBPROTOCOL_MISMATCH.
4.TLS Security Profile 2 / 3
Per the OCPP Security Whitepaper Ed. 3, the PixellEnergy CSMS requires Security Profile 2 minimum (TLS + Basic Auth) for all environments. Profile 3 (TLS + client certificate) is mandatory for production tenants. Profile 1 (TLS-only, no auth) is rejected at the WSS upgrade.
wss://gw.pixellenergy.com/ocpp/<your-tenant-slug>/<your-station-id>
Authorization: Basic <base64(stationId:password)>
# Sec-WebSocket-Protocol negotiation (see §3) MUST also be sent.
# The Basic Auth credential is shown once, when the station is provisioned
# in the operator portal at /chargers/onboard; rotate it from the
# charger's page there. Never embed plaintext credentials in firmware images.Credential hygiene
Basic Auth credentials are shown once, when the station is provisioned at /chargers/onboard. Rotate them from the charger's page, /chargers/<id>, at least every 12 months and on any firmware engineer offboarding. Never embed credentials in firmware images shipped to other tenants.
For Profile 3, the station presents an X.509 client certificate issued by the PixellEnergy Sub-CA. Start the CSR signing flow from the charger's page (/chargers/<id>, TriggerMessage SignChargingStationCertificate); the API uses OCPP 2.0.1 SignCertificate + CertificateSigned to deliver the signed cert in-band on the first successful connection.
5.BootNotification handshake
The first OCPP frame on every fresh WSS connection MUST be BootNotification. The CSMS replies with one of Accepted / Pending / Rejectedplus an interval (seconds) that the station MUST honour as the minimum delay before re-sending a Boot.
[2,
"boot-msg-01",
"BootNotification",
{
"reason": "PowerUp",
"chargingStation": {
"model": "ZenergizeDC60-V2",
"vendorName": "Zenergize",
"firmwareVersion": "2.1.4",
"serialNumber": "ZN-DC60-V2-001"
}
}
][3,
"boot-msg-01",
{
"status": "Accepted",
"currentTime": "2026-05-18T08:00:00Z",
"interval": 300
}
][2,
"boot-msg-01",
"BootNotification",
{
"chargePointVendor": "Zenergize",
"chargePointModel": "ZenergizeDC60-V2",
"firmwareVersion": "1.6.12",
"chargePointSerialNumber": "ZN-DC60-V1-001"
}
]| Field | Type | Required | Notes |
|---|---|---|---|
| reason | enum | required | PowerUp · FirmwareUpdate · LocalReset · RemoteReset · ScheduledReset · Triggered · ApplicationReset · Unknown. |
| chargingStation.model | string | required | Used by the vendor-quirk registry to match a profile. Keep stable across firmware revs. |
| chargingStation.vendorName | string | required | PixellEnergy OEM Compatibility Program badge is keyed off this exact value. |
| chargingStation.firmwareVersion | string | optional | Logged to OTel attributes for fleet-wide firmware-drift dashboards. |
| chargingStation.serialNumber | string | optional | When present, MUST match the station record provisioned in the operator portal — mismatch = `RegistrationStatus: Rejected`. |
Heads up
A Rejected response means the chargingStation.serialNumber does not match any station record provisioned for the tenant. Verify via GET /v1/stations (bearer JWT for the tenant) and check the serial_number field — the list has no serial filter; it filters by site_id, status and connection_state. The list hides decommissioned chargers by default; add ?include_retired=true to see them.
6.Vendor-quirk profile registration
The vendor-quirk profile registry is hot-loadable: a new profile is live within 2 hours of registration with no gateway redeploy. If your firmware has a non-standard behaviour (e.g. emits MeterValues outside an active session, sends a custom Reset.reqreason, or returns non-spec status text), register a profile so the dispatcher applies the appropriate adapter:
curl -X POST 'https://api.pixellenergy.com/v1/admin/vendor-quirks/zenergize-dc60/profile' \
-H 'Authorization: Bearer <your-super-admin-jwt>' \
-H 'Idempotency-Key: vendor-quirk-register-<your-ulid>' \
-H 'Content-Type: application/json' \
-d '{
"profile_jsonb": {
"subprotocolPreference": ["ocpp1.6"],
"meterValuesCadenceSecondsExpected": 60,
"statusNotificationServerTimeFallback": true
},
"model_pattern": "<exact-chargePointModel>",
"firmware_range": null
}'The overrides live in profile_jsonb (field reference in the vendor-quirk cookbook). model_pattern and firmware_range are compared exactly with the BootNotification model and firmware version — not as a regex or a range; omit them or send null to match any value.
Coordinated rollout
Profile registration is a PixellEnergy-side action: send your quirk findings to support@pixellenergy.com with a packet capture or a MicroOcppSimulator scenario. We register, validate, and hot-reload within the 2-hour SLA committed in the OEM Compatibility Program.
7.Joint-test (JT-N) pattern
PixellEnergy uses a four-step joint-test cadence with a real charger and a PixellEnergy bridge engineer on the call. Each JT is gated by exit criteria; you do NOT progress until the prior JT is green.
| Field | Type | Required | Notes |
|---|---|---|---|
| JT-1 | staging dry-run | required | WSS handshake · subprotocol negotiation · BootNotification · 10-min Heartbeat soak. |
| JT-2 | session lifecycle | required | RemoteStart → Authorize → TransactionEvent(Started/Updated/Ended) → MeterValues. Billing parity validated. |
| JT-3 | resilience | required | Loss-of-network mid-session · firmware-update reboot · CSMS restart while session active. |
| JT-4 | production cutover | required | Production tenant slug · Profile 3 client cert · 24h soak · sign-off by tenant CTO + PixellEnergy DPO. |
Heads up
Per Hard Rule #15, the real Zenergize charger is never used for ambient testing — only at JT-1..JT-4 events with Arun (CEO) on the bridge. Apply the same discipline to your own production fleet during partner JTs.
8.Signed firmware (OCPP 2.0.1)
On OCPP 2.0.1, firmware updates pushed by the CSMS are Ed25519-signed. The station MUST verify the signature against the PixellEnergy public key embedded in the boot ROM (delivered via the CSR flow at JT-4) and reject unsigned firmware with FirmwareStatusNotification.status = SignatureVerificationFailed.
OCPP 1.6J does not include a signed-firmware contract. PixellEnergy publishes 1.6J firmware artefacts via Cloudflare R2 with an out-of-band SHA-256 manifest signed via a PixellEnergy GPG key; your firmware bootloader MUST validate the manifest before flashing. Contact the OEM Compatibility team for the public key.
Tax-grade meter values
SignedMeterValue is tax-grade on OCPP 2.0.1 (backs the CDR + IRN) and advisory on OCPP 1.6J (telemetry only). India revenue regulators require an OCPP 2.0.1 path for tariff-driven billing — plan firmware accordingly for production tenants.
9.Production cutover checklist
- Profile 3 (TLS + client cert) presented on every connection.
- JT-1..JT-4 sign-off recorded with the OEM Compatibility team.
- Vendor-quirk profile registered + verified hot-reloaded within 2h SLA.
- BootNotification emits
vendorNamematching the OEM Compatibility Program registration (badge eligibility). - OTel
firmwareVersionattribute populated — appears in fleet-drift dashboards. - Heartbeat interval honoured (300s default; do not aggressively beat — it does not buy you better SLO and burns the
gateway-online-timeSLI). - For OCPP 2.0.1:
SignedMeterValueemitted on everyTransactionEvent(else IRN cannot be issued). - Out-of-hours pager rotation for your firmware on-call — escalate via the JT-4 sign-off contact within 1 hour of any CSMS-side P1 incident.
10.Support and JT booking
Book a JT-N session by emailing oem-compatibility@pixellenergy.com with the vendor-quirk profile draft + a target tenant slug. The OEM Compatibility team responds within one business day (Mumbai, Mon–Fri, 09:00–18:00 IST).
For RemoteStart / RemoteStop wiring against your own automations, the NATS subject pattern is:
// NATS subject the CSMS publishes to when a tenant
// triggers a remote start via the operator-portal.
//
// Subject pattern:
// csms.ocpp.<protocol>.<tenantSlug>.<stationId>.RequestStartTransaction
//
// Example (2.0.1):
csms.ocpp.v201.acme.ZN-DC60-V2-001.RequestStartTransactionSee the API reference for the full REST surface, and the OCPI handshake cookbook for peer-roaming integration.