Everything shared across protocols — installing the SDK, getting an API key, configuration, monitoring, shutdown — is in Getting started. This page is the OCPP-specific part.
The model
EVPanda records an OCPP connection: everything that happened on one WebSocket, from handshake to close, under one connection ID. The session handle owns the connection ID, so per-frame calls don’t carry one. A reconnect callsconnection() again and gets a fresh ID — which is how the dashboard tells one long session from twenty short ones.
Direction is from the charge point’s perspective
Record it where the actual socket read or write happens. A helper that both sides call is where directions get flipped, and flipped directions make every request look like a response.
Integration steps
1
Start one client at boot
Share it across your process — it is safe for concurrent use. Each client runs its own worker and buffer, so one per socket means thousands of workers and no batching.The client needs a charger network API key. A roaming network’s key is rejected.
2
Identify the charge point at the handshake
The SDK doesn’t identify chargers for you — your CSMS already does, before it decides whether to accept the connection. Whatever you use for that is what you pass to EVPanda.If you’re multi-tenant, add the tenant pair here — it is the one place you know it for certain. See Identity.
3
Open a session when the socket opens
connection() records the connect, mints the connection ID, and returns a handle that carries both.4
Capture every inbound frame
Capture before you handle, so a frame that breaks your handler is still recorded — that is exactly the frame you want to see in EVPanda.
5
Capture every outbound frame
A CSMS writes from more than one place — replies from the read loop, and calls your operators or schedulers initiate. Put the write and the capture behind one helper so nothing can reach the socket uncaptured.
6
Close the session when the socket closes
Attach this where you clean up your own connection state — somewhere that runs on an abrupt drop, not just a clean shutdown.
A complete example
- Go
- Node
- Python
Uses gorilla/websocket, but nothing here is specific to it — swap in
nhooyr.io/websocket and the capture calls stay where they are.csms.go
Per-SDK notes
Go — serialize your writes
Go — serialize your writes
The client and session are safe to use from multiple goroutines, but most WebSocket libraries allow only one concurrent writer. Keep the capture call inside the same helper that holds the write lock, so capture and write can never disagree about what was sent.
Node — the session handle needs 0.1.0
Node — the session handle needs 0.1.0
On earlier published versions
connection() does not exist. Use the flat primitives below; everything else on this page is unchanged.Python — frames may be str or bytes
Python — frames may be str or bytes
message() accepts either, and encodes a str as UTF-8, so you can pass whatever your WebSocket library hands you.OCPP frames are captured verbatim
OCPP frames are captured verbatim
There is no OCPP redaction — an altered frame is not evidence of what your charger did. If a payload carries data you don’t want stored, an
idTag for example, mask it before you hand the frame to the SDK.Multi-tenant CSMS
Add the tenant pair to the identity at the handshake. It is optional but all-or-nothing — set both fields or neither.The flat primitives
connection() is built on three lower-level calls. Use them when a session handle doesn’t fit — replaying an archive, capturing from a component that only sees frames, or on a Node version without the handle.
Common mistakes
Tune the network
Two per-network settings shape what OCPP traffic gets reported as an issue. Both are under the network’s Settings tab.Next
What gets captured
Event shapes, size limits, and what the SDK deliberately leaves out.
Getting started
Configuration, monitoring, shutdown, and troubleshooting.