Open Charge Point Protocol (OCPP, http://ocppforum.net) is a communication protocol between multiple charging stations ("charge points") and a single management software ("central system").
Currently (december 2012), two OCPP versions (1.2 and 1.5) have been released. There is a draft in progress for a new version (2.0). Both existing versions use SOAP over HTTP as the RPC/transport protocol:
+---------------+ soap/http client soap/http server +---------------+
| |--------------------------------------->| |
| | Operations initiated by ChargePoint | |
| ChargePoint | | CentralSystem |
| | soap/http server soap/http client | |
| |<---------------------------------------| |
+---------------+ Operations initiated by CentralSystem +---------------+
The two main problems with this solution are:
This project proposes a new RPC/transport for OCPP, that addresses these two issues, using Websocket (http://tools.ietf.org/html/rfc6455) for the transport layer, and SPRC (see Protocol Specification section below) for the RPC layer.
This schema shows objects instances for a system with one ChargePointSimulator and one CentralSystemSimulator.
+------------------------+ +------------------------+
| ChargePointSimulator | | CentralSystemSimulator |
+------------------------+ +------------------------+
|create (param: url) |create (param: listening tcp port)
V V
+------------------------+ connect +------------------------+
| WebSocketClient |------------>| WebSocketServer |
+------------------------+ +------------------------+
When a WebSocket connection (i.e. a transport layer) is established, each peer creates:
This gives two independant RPC channels on a single TCP connection:
+------------------------+ +------------------------+
+-| ChargePointSimulator | | CentralSystemSimulator |-+
| +------------------------+ +------------------------+ |
| create (param: connection) create (param: connection)|
| |
| +------------------------+ +------------------------+ |
+>| WampClientConnection |------------>| WampServerConnection |<+
| +------------------------+ RPC call +------------------------+ |
| (e.g. MeterValue) |
| |
| +------------------------+ +------------------------+ |
+>| WampServerConnection |<------------| WampClientConnection |<+
+------------------------+ RPC call +------------------------+
(e.g. Reset)
This program requires Node.js (http://nodejs.org/). Third-party packages can be installed with the npm utility. Currently, ocppjs depends on 'websocket', 'xml2js', 'node-expat', 'request' and 'jayschema' packages:
% npm install
To run the OCPP.js simulator, just enter
% node gir-ocppjs.js
You will be given a prompt where you can enter commands.
Commands syntax:
start_cs <port> [options]: Start a CentralSystem
simulator, listening on the specified TCP <port>.
This command can be directly specified on the command line.
Options:
-i <pingInterval>: websocket ping interval (default: 300s)
-u <endpoint>: endpoint URL (default: '/')
-p <protocol>: websocket protocol name (default: 'ocpp1.2,ocpp1.5')start_cp <url> <id>: Start a ChargePoint simulator, which will try to
connect to a CentralSystem on the specified URL, using the specified
chargepoint <id>.
This command can be directly specified on the command line.
Options:
-p <protocol>: websocket protocol name (default: 'ocpp1.5')
-i <pingInterval>: websocket ping interval (default: 300s)
-t <transport>: transport layer mode (websocket or soap), default: websocket
-f <from>: in SOAP mode, defines the SOAP From header.
-r <remoteActionPort>: in SOAP mode, defines the remote action port.remote_<cmd> [options] [custom_arguments]: When a CentralSystem simulator is
running and has a connected chargepoint, perform a <cmd>
remote action.
See help for available commands.
Options:
--remote-id <id>: send the remote action to the specified
chargepoint <id>. This parameter can be omitted when a single chargepoint
is connected.
Custom Arguments: see section Argument customization below. <cmd> [options] [custom_arguments]: When a ChargePoint simulator <id> is
running and is connected to a CentralSystem, send a <cmd> message.
See help for available commands.
Options:
--id id: send the message using the specified chargepoint <id>.
This parameter can be omitted when a single chargepoint simulator is running.
Custom Arguments: see section Argument customization below.set <cs|cp> [arguments]: modify the simulator settings from command line
interface.
Arguments: setting=value ... Supported settings: websocket_ping_interval.
set cs websocketpinginterval=120
help: List available commands.
quit: Exit the program.Argument customization:
When typing remote_<cmd> or <cmd>, the fields of the payload can be
customized individually from the command line interface using the following
syntax:
argument=value ...
> bootnotification chargePointVendor="DBT"
> bootnotification chargePointVendor="DBT" chargePointModel="NQC-ACDC"
value handles string, number, object and array types.
% node gir-ocppjs.js start_cs 9000
[2012-12-28 14:54:32] CentralSystem started.
[2012-12-28 14:54:32] cs: Server is listening on port 9000
[2012-12-28 14:54:44] cs: ChargePoint #0 connected from 127.0.0.1.
>
[2012-12-28 14:54:54] cs: <<cp#0 [2,"V7NeDL1MnbkaQcaHcYnvxOpCdcI4gpAV",
"BootNotification",{"chargePointVendor":"DBT",
"chargePointModel":"NQC-ACDC",...}]
[2012-12-28 14:54:54] cs: >>cp#0 [3,"V7NeDL1MnbkaQcaHcYnvxOpCdcI4gpAV",
{"status":"Accepted",
"currentTime":"2012-11-28T13:54:44Z",
"heartbeatInterval":300}]
> remote_reset type="Soft"
[2012-12-28 14:56:50] cs: >>cp#0 [2,"tU8hVs8yY6Aleie1kN8fXD7YUJ0PDuyc",
"Reset",{"type":"Soft"}]
[2012-12-28 14:56:50] cs: <<cp#0 [3,"tU8hVs8yY6Aleie1kN8fXD7YUJ0PDuyc",
{"status":"Accepted"}]
>
[2012-12-28 14:58:22] cs: <<cp#0 [2,"Shfrho1gR2NmsjCVeHpCOjImdNxhPPXq",
"MeterValues",{"connectorId":1,values:[{
"timestamp":"2012-12-28T13:58:22Z","value":0}]}]
[2012-12-28 14:58:22] cs: >>cp#0 [3,"Shfrho1gR2NmsjCVeHpCOjImdNxhPPXq",
{}]
>
[2012-12-28 14:59:44] cs: <<cp#0 [2,"yUtxCAuRRv26dKRuQ1fy1AYvE0fZTZ2Z",
"Heartbeat",{}]
[2012-12-28 14:59:44] cs: >>cp#0 [3,"yUtxCAuRRv26dKRuQ1fy1AYvE0fZTZ2Z",
{"currentTime":"2012-12-28T13:59:44Z"}]
% node gir-ocppjs.js start_cp ws://localhost:9000 0
[2012-12-28 14:54:44] ChargePoint #0 started.
[2012-12-28 14:54:44] cp#0: Connected to CentralSystem.
> bootnotification chargePointVendor="DBT" chargePointModel="NQC-ACDC"
[2012-12-28 14:54:54] cp#0: >>cs [2,"V7NeDL1MnbkaQcaHcYnvxOpCdcI4gpAV",
"BootNotification",{"chargePointVendor":"DBT",
"chargePointModel":"NQC-ACDC",...}]
[2012-12-28 14:54:54] cp#0: <<cs [3,"V7NeDL1MnbkaQcaHcYnvxOpCdcI4gpAV",
{"status":"Accepted",
"currentTime":"2012-12-28T13:54:44Z",
"heartbeatInterval":300}]
>
[2012-12-28 14:56:50] cp#0: <<cs [2,"tU8hVs8yY6Aleie1kN8fXD7YUJ0PDuyc",
"Reset",{"type":"Soft"}]
[2012-12-28 14:56:50] cp#0: >>cs [3,"tU8hVs8yY6Aleie1kN8fXD7YUJ0PDuyc",
{"status":"Accepted"}]
> metervalues
[2012-12-28 14:58:22] cp#0: >>cs [2,"Shfrho1gR2NmsjCVeHpCOjImdNxhPPXq",
"MeterValues", {"connectorId":2,
values:[{"timestamp":"2012-12-28T13:58:22Z",
"value":0}]}]
[2012-12-28 14:58:22] cp#0: <<cs [3,"Shfrho1gR2NmsjCVeHpCOjImdNxhPPXq",
{}]
> heartbeat
[2012-12-28 14:59:44] cp#0: >>cs [2,"yUtxCAuRRv26dKRuQ1fy1AYvE0fZTZ2Z",
"Heartbeat",{}]
[2012-12-28 14:59:44] cp#0: <<cs [3,"yUtxCAuRRv26dKRuQ1fy1AYvE0fZTZ2Z",
{"currentTime":"2012-12-28T13:59:44Z"}]
% node gir-ocppjs.js start_cs 9000 -t soap
[2013-04-22 16:44:44] cs: SOAP Server listening on port 9000
[2013-04-22 16:44:44] CentralSystem started.
[2013-04-22 16:57:52] cs: ChargePoint #boxid connected.
[2013-04-22 16:57:52] cs: <<cp#boxid /BootNotification {"chargePointVendor":
"DBT","chargePointModel":"NQC-ACDC", ...}
[2013-04-22 16:57:52] cs: >>cp#boxid /BootNotification {"status":"Accepted",
"currentTime":"2013-02-01T15:09:18.000Z",
"heartbeatInterval":1200}
> remote_starttransaction
[2013-04-22 17:01:48] cs: >>cp#boxid /RemoteStartTransaction {"idTag":
"044943121F1D80","connectorId":2}
[2013-04-22 17:01:48] cs: <<cp#boxid /RemoteStartTransaction {"status":
"Accepted"}
% node gir-ocppjs.js start_cp http://localhost:9000 boxid -t soap \
-f http://localhost:9001
[2013-04-09 14:27:14] cs: SOAP Server listening on port 9001
> bootnotification
[2013-04-09 14:57:29] cp#boxid: >>cs /BootNotification {"chargePointVendor":
"DBT", "chargePointModel":"NQC-ACDC", ...}
[2013-04-09 14:57:29] cs: >>boxid /BootNotification {"status":"Accepted",
"currentTime":"2013-02-01T15:09:18.000Z",
"heartbeatInterval":1200}
...
[2013-04-22 17:01:48] cs: <<cp#boxid /RemoteStartTransaction {"idTag":
"044943121F1D80","connectorId":2}
[2013-04-22 17:01:48] cs: >>cp#boxid /RemoteStartTransaction {"status":
"Accepted"}
> set cp print_xml=true
> heartbeat
[2013-04-09 15:03:02] cp#boxid: >>cs <soap:Envelope ...>
<soap:Header>...</soap:Header><soap:Body>
<tns:heartbeatRequest></tns:heartbeatRequest>
</soap:Body></soap:Envelope>
[2013-04-09 15:03:02] cs: >>boxid <?xml version="1.0" encoding="utf-8"?>
<soap:Envelope ...><soap:Body><tns:HeartbeatResponse>
<currentTime>2013-02-01T15:09:18Z</currentTime>
</tns:HeartbeatResponse></soap:Body></soap:Envelope>
ocppjs provides a framework and four example files (in the test/ folder) for writing unit tests. If a test fails, the errors are printed on the standard output. If it succeeds then nothing is displayed.
% cd test/
% node test-cp-1.2.js
%
ocppjs provides a plugin system which allows developers to define the simulator behavior without modifying the program source code. Plugins consist of extern JavaScript files listed in the plugins/ folder.
From the prompt of the simulator, 3 commands are available:
The gir-ocppjs-doc.js program generates JSON examples from WSDL files. Run it with:
% npm install xml2js
% cd doc
% make
Output files generated:
A draft specification for a WebSocket-based OCPP transport is available: http://www.gir.fr/ocppjs/ocpp_srpc_spec.shtml
http://www.gir.fr/ocppjs/gir-ocppjs-1.0.2.zip
09 oct 2013; ocppjs 1.0.2
* Added constraints in JSON Schema (enumerations, maxLength, etc)
documentation. Simulator now enforces these constraints when verifying
incoming messages.
* Added JSON Schema control for MeterValues & StopTransaction message.
* Fixed missing namespace for nested object in SOAP.
* Fixed missing value in the "To" header for SOAP remote actions.
04 oct 2013; ocppjs 1.0.1
* Added JSON Schema for requests and responses in the documentation files.
* Changed the way XML attributes are mapped to JSON. In practice, this only
changes the format for OCPP1.5 MeterValues & StopTransaction request
messages.
The central system simulator doesn't enforce this format yet, and will
accept anything under the StopTransactionRequest.transactionData and
MeterValuesRequest.values fields when receiving a message.
* Added package.json file for easier installation.
* Fixed invalid JSON example for OCPP1.2 MeterValuesRequest.
* Fixed action name and namespaces issues with SOAP transport.
03 jun 2013; ocppjs 1.0.0
* Fixed ocpp1.5 JSON payload structure for:
. GetConfiguration request: "key" was a string instead of an array of
strings
. GetConfiguration response: "unknownKey" was a string instead of an array
of strings
. MeterValues & StopTransaction request: "value" was an int instead of
an array of strings, "@value" was a object instead of an array of objects
* Added websocket protocol name when accepting a new connection.
* Added a plugin system allowing to define the behavior of a CS or CP
simulator:
. 'plugins', 'load' and 'unload' commands for listing, loading
and unloading plugins.
. Plugin API documentation and tutorial in
plugins/getting_started_with_plugins.html.
. 'cbxs' chargepoint plugin example with connectors management.
* Minor fixes
02 may 2013; ocppjs 0.0.11
* Added: framework for writing unit tests and 4 example files (in test/).
* Payload errors are now supported in SOAP mode.
* 'send_raw' and 'remote_send_raw' commands are now available in SOAP mode.
. Added parameter -h for printing http headers.
* In SOAP mode, header 'From' retrieves the local IP address instead of using
'localhost'.
22 apr 2013; ocppjs 0.0.10
* Added SOAP transport support in Central system simulator.
* Added SOAP remote actions support:
. Added parameter -r in 'start_cp' command, defining the listening
port for remote actions. If not defined, it defaults to the port specifed
in the 'wsa5:From' URL.
. Added parameter -f in 'start_cp' command, defining the "wsa5:From"
URL in SOAP header. If not defined, it defaults to
'http://localhost:random_port'.
. 'send' and 'send_raw' commands have been disabled for the SOAP mode.
. This version does not detect SOAP payload errors yet.
09 apr 2013; ocppjs 0.0.9
* SOAP client integration:
. Requires third-party libraries: 'node-expat' and 'request'.
. Added parameter -t for the 'start_cp' command in order to choose the
simulator transport layer (websocket or SOAP).
. Added 'set print_xml' command for displaying SOAP envelopes in XML format.
. Remote actions and Central system simulator are not supported yet with
soap transport.
* New JSON attributes syntax: {"node":"value","@node":{"attr1": "value1"}}.
14 mar 2013; ocppjs 0.0.8
* WebSocket ping enhancements :
. Added client websocket ping.
. Added parameter '-i' for the 'start_cp' command in order to set the
WebSocket ping frequency.
. Added 'websocket_ping_cs' and 'websocket_ping_cp' commands for manually
sending one WebSocket ping from a central system simulator or a charge
point simulator.
. Added 'set' command for modifying the WebSocket ping frequency without
interrupting the simulator (0 for disabling WebSocket pings).
* 'tns:MeterValue' type is now supported. doc/gir-ocppjs-doc.js has been
updated with the expected JSON structure for types with XML schema attributes
attributes. The MeterValue type in ocpp 1.5 is currently the only one with
such a structure.
* Added 'InternalError' support when a procedure raises an exception.
* Added payload error checking for CALLRESULT messages.
* Prompt '>' now shows up right after entering a command.
07 mar 2013; ocppjs 0.0.7
* Payload parsing now supports complex types and simple type restrictions.
* Procedure call messages can be customized from command line interface using
the new 'argument=value' syntax.
* OCPP 1.2 & OCPP 1.5 commands are completely covered with the addition of
firmware and diagnostics messages.
* Enhancement of the command line interface reliability: bugfixes and
deletion of multiple spaces.
* Simulator is now tolerant to WSDL absence and can be launched from
any directory.
27 feb 2013; ocppjs 0.0.6
* Basic payload parsing (Property/Occurence/TypeConstraintViolation for
simple types). Complex types and restrictions are not checked yet.
* Commands schema is now loaded from wsdl files. This requires:
. An additional third-party library: xml2js.
. Valid ocpp wsdl files in doc/wdsl subdirectory. They are provided in the
zip file.
* A CentralSystem simulator can now support multiple comma-separated protocol
versions on a single endpoint.
* New commands:
. 'send' & 'remote_send' to send a custom message in a valid envelope, to
simulate invalid procedure names and payloads.
. 'send_raw' & 'remote_send_raw' to send a custom string, to simulate
invalid envelopes.
20 feb 2013; ocppjs 0.0.5
* Conformance to DRAFT1 specification.
* Updated command-line interface. start_cp & start_cs commands can now be
passed directly as shell arguments.
* Removed automatic bootnotification & heartbeat. All messages are
triggered manually (type 'help' to get the list), except websocket ping.
* Completed the command set to cover usual ocpp1.2 and ocpp1.5 commands (not
available yet: firmware & diagnotics messages).
14 feb 2013; DRAFT1
* First public draft specificaton.
* Removed chargeBoxIdentity from message payload.
01 feb 2013; ocppjs 0.0.4
* Added doc/gir-ocppjs-doc.js: autogenerate JSON examples from OCPP wsdl.
23 jan 2013; ocppjs 0.0.3
* Added websocket ping interval in centralsystem simulator.
* Added websocket logging for ping/pong frames.
11 jan 2013; ocppjs 0.0.2
* Updated logs.
* Bugfixes.
28 dec 2012; ocppjs 0.0.1
* Initial version.