Model
EVPanda records a connection: everything on one WebSocket, from handshake to close, under one connection ID. The session mints the connection ID and carries the identity, so per frame calls pass neither. A reconnect callsconnection() again and gets a fresh ID.
FROM_CP is a frame the charge point sent you. TO_CP is one you sent it.
Steps
1
Start the client
One client at boot, shared across the process. It needs a charger network API key.
2
Identify the charge point at the handshake
Your CSMS already does this before it decides whether to accept the connection. Use the same value.
3
Open a session when the socket opens
connection() records the connect and returns the handle.4
Capture inbound frames
Capture before you handle, so a frame that breaks your handler is still recorded.
5
Capture outbound frames
A CSMS writes from more than one place: replies from the read loop, and calls your operators or schedulers start. Put the write and the capture behind one helper so nothing reaches the socket uncaptured.Capture after a successful write. A frame that failed to send never reached the charge point, and recording it as sent makes the validation engine look for a response that was never coming.
6
Close the session when the socket closes
Attach it where you clean up your own connection state, somewhere that runs on an abrupt drop and not only on a clean shutdown.
Complete example
- Go
- Node
- Python
Uses gorilla/websocket. Nothing here depends on it.
csms.go
Per-SDK notes
Go: serialize your writes
Go: serialize your writes
The client and session are safe from multiple goroutines, but most WebSocket libraries allow only one concurrent writer. Keep the capture call inside the helper that holds the write lock, so capture and write cannot disagree about what was sent.
Node: frames may be a string or bytes
Node: frames may be a string or bytes
message() takes a BodyInput, so raw.toString() and the raw Buffer both work. A string is encoded as UTF-8.Python: capture is safe from async code
Python: capture is safe from async code
Delivery runs on a background daemon thread, so the calls never block the event loop and never await. Frames may be
bytes or str.Multi-tenant CSMS
Add the tenant pair at the handshake. Optional but all or nothing.Flat primitives
connection() is built on three lower level calls. Use them when a session handle does not fit, such as replaying an archive.
Common mistakes
Tune the network
Two settings shape what OCPP traffic becomes an issue. Both under the network’s Settings tab.Next
Data flow
Event shapes and limits.
Getting started
Config, stats, shutdown, troubleshooting.