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.