Version | Date | Author | Description |
---|---|---|---|
DRAFT1 | 2013-02-14 | gir | Initial version |
Historically, OCPP uses SOAP over HTTP as a transport. This document defines a new transport binding for OCPP, using SRPC over WebSocket.
The words "MUST", "MUST NOT", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", and "MAY" in this document are to be interpreted as described in RFC 2119.
OCPP: the Open Charge Point Protocol is an open standard which describes a method enabling vehicles to communicate with a central system. Current version is 1.5 described by OCPP 1.5.
PDU: OCPP Protocol Data Unit. A PDU is either a request or a response.
Central System: the central system that manages charge points, and has the information for authorizing users to use its charge points.
Charge Point: the charge point is the physical system where an electric vehicle can be charged. A charge point will have one or more connectors.
WebSocket: web technology providing full-duplex communications channels over a TCP connection. WebSocket is defined by RFC 6455.
WebSocket Server: manages incoming connections from WebSocket clients.
WebSocket Client: initiates a connection to a WebSocket server.
RPC: Remote Procedure Call. In this document, a RPC can always be specified by a procedure name, input parameters ('request'), and output parameters ('response').
Caller: the entity that triggers a RPC, providing a request and expecting a response.
Callee: the entity that handles a RPC, computing a response for an incoming request.
SRPC: Symmetric Remote Procedure Call. The protocol defined in this document, allowing bi-directional RPC between two endpoints.
JSON: JavaScript Object Notation. A data interchange format, defined by RFC 4627.
The central system embeds a WebSocket server, and the charge point embeds a WebSocket client. Connections are initiated from the charge point to the central system.
+------------------------+ +------------------------+
| Charge Point | | Central System |
+------------------------+ +------------------------+
| |
V V
+------------------------+ connect +------------------------+
| WebSocket Client |------------>| WebSocket Server |
+------------------------+ +------------------------+
SRPC is designed to answer the need for bi-directional RPC between two endpoints. Once a WebSocket connection has been established, both charge point and central system can trigger and handle remote calls: each endpoint is both caller and callee.
+------------------------+ +------------------------+
| Charge Point | | Central System |
+------------------------+ +------------------------+
| |
| |
| +------------------------+ +------------------------+ |
+>| Caller |------------>| Callee |<+
| +------------------------+ SRPC +------------------------+ |
| (e.g. MeterValue) |
| |
| +------------------------+ +------------------------+ |
+>| Callee |<------------| Caller |<+
+------------------------+ SRPC +------------------------+
(e.g. Reset)
SPRC messages were inspired by the WAMP protocol.
SRPC requires:
a reliable, ordered, full-duplex message channel as transport layer. Default binding is WebSocket.
a serialization format that handles integers, strings, composition and lists. Default binding is JSON.
SRPC is based on 3 messages:
Message name | Message ID | Direction |
---|---|---|
CALL | 2 | Caller to Callee |
CALLRESULT | 3 | Callee to Caller |
CALLERROR | 4 | Callee to Caller |
The caller initiates a RPC by sending a CALL
message to the callee.
When receiving a CALL
message, the callee executes the corresponding remote
procedure, then replies with a CALLRESULT
or CALLERROR
message.
The callee MUST use the callID
obtained from a CALL
message in the
associated CALLRESULT
or CALLERROR
response.
When receiving a CALLRESULT
or CALLERROR
message, the caller uses the
callId
field to associate the message with the originating call.
The execution and sending is asynchronous, and there MAY be more than one RPC
outstanding.
From the caller point of view, a RPC is outstanding when a CALL
message has
been sent, and no corresponding CALLRESULT
or CALLERROR
message has been
received yet.
A CALL
message is a JSON list with 4 items:
[ 2 , callID , procedureName, request ]
2: Constant JSON integer value identifying a CALL
message, as defined in 2.2.
callID
: JSON string randomly generated by the caller. It is limited to 36 alphanumerical characters ([0-9A-Za-z]).
procedureName
: JSON string identifying the remote procedure to be called.
request
: JSON object representing an OCPP request PDU.
Empty PDUs MUST be represented by an empty JSON object ({}
).
null
is not a valid value.See 2.8 for PDUs definition.
Examples:
Heartbeat request PDU:
[2,"V7NeDL1MnbkaQcaHcYnvxOpCdcI4gpAV","Heartbeat",{}]
MeterValues request PDU:
[2,"wgj8YxiwLmw1IAHIe5w5bzXEvDxpI8Me","MeterValues", {"connectorId":2,"values":[{"timestamp":"2013-02-01T15:09:18Z","value":11}]}]
When remote procedure execution succeeds, the callee replies with a CALLRESULT
message.
A CALLRESULT
message is a JSON list with 3 items:
[ 3 , callID , response ]
CALLRESULT
message, as defined in 2.2.callID
: JSON string obtained from the initial CALL
message.response
: JSON object representing an OCPP response PDU.
Empty PDUs MUST be represented by an empty JSON object ({}
).
null
is not a valid value.See 2.8 for PDUs definition.
Examples:
Heartbeat response PDU:
[3,"V7NeDL1MnbkaQcaHcYnvxOpCdcI4gpAV",{"currentTime":"2013-02-01T15:09:18Z"}]
MeterValues response PDU:
[3,"wgj8YxiwLmw1IAHIe5w5bzXEvDxpI8Me",{}]
When the callee cannot process the request and the corresponding response PDU
doesn't have to ability to report the error, a CALLERROR
message SHOULD be
used.
A CALLERROR
message is a JSON list with 5 items:
[ 4 , callID , errorName , errorDesc , errorDetails ]
CALLERROR
message, as defined in 2.2.callID
: JSON string obtained from the initial CALL
message.errorName
: JSON string identifying the error, as defined in 2.7.errorDesc
: JSON string providing a human-readable description of the error. It MAY be empty.errorDetails
: JSON object providing structured information on the error, for use by the caller application. It MAY be an empty JSON object ({}
).
null
is not a valid value.Example:
Unknown procedure name:
[4,"YsQVCRvh8KnpRa8bAXbY2siY7C5vcNfU","NotImplemented","Method name is not recognized.",{}]
Internal error:
[4,"YsQVCRvh8KnpRa8bAXbY2siY7C5vcNfU","InternalError","An internal error occured and the receiver is not able to complete the operation.",{}]
To allow the central system to uniquely identify a charge point, a charge point MUST send its identifier by appending it to the central system URL. The identifier MUST be properly encoded if needed, as defined by RFC 3986.
The charge point MUST specify the OCPP protocol version as the WebSocket
subprotocol, using the Sec-WebSocket-Protocol
header.
Valid protocol versions are:
Version | Services |
---|---|
ocpp1.2 |
Central System service: urn://Ocpp/Cp/2010/08/ Charge Point service: urn://Ocpp/Cs/2010/08/ |
ocpp1.5 |
Central System service: urn://Ocpp/Cp/2012/06/ Charge Point service: urn://Ocpp/Cs/2012/06/ |
The central system MAY use the protocol version to handle multiple versions on a single endpoint.
WebSocket defines ping/pong frames that may be used for keepalive, or to check that the remote endpoint is still responsive. This is also the purpose of the OCPP Heartbeat call. Additionally, OCPP Heartbeat provides a mean for the chargepoint to stay synchronized with the central system clock.
When using SRPC over WebSocket as a transport, a charge point still sends heartbeats as defined in the OCPP specification.
A new standard configuration keyword is added to define the WebSocket ping frequency (section 6.9.1, "Standard Configuration Key Names & Values", in OCPP 1.5 specification):
Key-Name | Format | Units | Key-Value |
---|---|---|---|
WebSocketPingInterval | int | seconds | Interval of inactivity (no WebSocket exchanges) with central system after which the charge point should send a WebSocket ping frame. |
For optimal bandwidth consumption, it is RECOMMENDED to use WebSocket ping as a keepalive (small interval, typically a few minutes), and to use OCPP Heartbeat only for clock synchronization (larger interval, typically a few hours).
Given a central system URL "http://example.com/my/end/point", and a charge point identifier "foobar 1234", the charge point initiates the WebSocket handshake with:
GET /my/end/point/foobar%201234 HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Protocol: ocpp1.5
...
This section defines possible values for the errorName
field in CALLERROR
messages. This list is exhaustive.
Names try to be consistent with similar errors in SOAP, to facilitate the
transition from SOAP to SRPC.
The IdentityMismatch
error was dropped, as it is no longer relevant for
this OCPP transport specification (see 2.6.1).
errorName | Description |
---|---|
NotImplemented | Method name is not recognized. |
NotSupported | Method name is recognized but not supported by the receiver. |
InternalError | An internal error occured and the receiver is not able to complete the operation. |
ProtocolError | Sender's message does not comply with protocol specification. |
SecurityError | Sender failed authentication or is not authorized to use the requested operation. |
FormationViolation | Sender's message is not well-formed. |
PropertyConstraintViolation | A property name in sender's message is not conform to the PDU structure. |
OccurenceConstraintViolation | Sender's message violates occurence constraints. |
TypeConstraintViolation | Sender's message violates data type constraints. |
GenericError | Other error. |