EVerest / libocpp

C++ implementation of the Open Charge Point Protocol
Apache License 2.0
80 stars 39 forks source link

C++ implementation of OCPP

Github Actions

This is a C++ library implementation of OCPP for version 1.6 and 2.0.1 (see OCPP protocols at OCA website).

It enables charging stations to communicate with cloud backends for remote control, monitoring and billing of charging processes.

Libocpp can be used for the communication of one charging station and multiple EVSE using a single websocket connection.

Libocpp provides a complete implementation of OCPP 1.6. The implementation of OCPP 2.0.1 is currently under development.

Get Involved

See the COMMUNITY.md and CONTRIBUTING.md of the EVerest project to get involved.

Table of contents

OCPP 1.6 Support

The following tables show the current support for the listed OCPP 1.6 feature profiles / functional blocks and application notes.

All documentation and the issue tracking can be found in our main repository here: https://github.com/EVerest/

Feature Profile Support OCPP 1.6

Feature Profile Supported
Core :heavy_check_mark: yes
Firmware Management :heavy_check_mark: yes
Local Auth List Management :heavy_check_mark: yes
Reservation :heavy_check_mark: yes
Smart Charging :heavy_check_mark: yes
Remote Trigger :heavy_check_mark: yes
Whitepapers & Application Notes Supported
OCPP 1.6 Security Whitepaper (3rd edition) :heavy_check_mark: yes
Using ISO 15118 Plug & Charge with OCPP 1.6 :heavy_check_mark: yes
OCPP & California Pricing Requirements

Support for OCPP 2.0.1

The development of OCPP2.0.1 is in progress. Current implementation status.

Feature Profile Support OCPP 2.0.1

Feature Profile Supported
Core :heavy_check_mark: yes
Advanced Security WIP
Local Auth List Management
Smart Charging WIP
Advanced Device Management
Advanced User Interface
Reservation
ISO 15118 support WIP
Whitepapers & Application Notes Supported
OCPP & California Pricing Requirements

CSMS Compatibility

CSMS Compatibility OCPP 1.6

The EVerest implementation of OCPP 1.6 has been tested against the OCPP Compliance Test Tool (OCTT and OCTT2) during the implementation.

The following table shows CSMS with which this library was tested. If you provide a CSMS that is not yet listed here, feel free to contact us!

CSMS Compatibility OCPP 2.0.1

The current, ongoing implementation of OCPP 2.0.1 has been tested against a few CSMS and is continuously tested against OCTT2.

Additionally, the implementation has been tested against those CSMS:

Integration with EVerest

This library is automatically integrated as the OCPP and OCPP201 module within everest-core - the complete software stack for your charging station. It is recommended to use EVerest together with this OCPP implementation.

Run OCPP1.6 with EVerest

If you run libocpp with OCPP1.6 with EVerest, the build process of everest-core will take care of installing all necessary dependencies for you.

Run OCPP2.0.1 with EVerest

If you run libocpp with OCPP1.6 with EVerest, the build process of everest-core will take care of installing all necessary dependencies for you. This includes the initialization of the device model database using the config.json file.

Integrate this library with your Charging Station Implementation for OCPP1.6

OCPP is a protocol that affects, controls and monitors many areas of a charging station's operation.

If you want to integrate this library with your charging station implementation, you have to register a couple of callbacks and integrate event handlers. This is necessary for the library to interact with your charging station according to the requirements of OCPP.

Libocpp needs registered callbacks in order to execute control commands defined within OCPP (e.g Reset.req or RemoteStartTransaction.req)

The implementation must call event handlers of libocpp so that the library can track the state of the charging station and trigger OCPP messages accordingly (e.g. MeterValues.req , StatusNotification.req)

Your reference within libocpp to interact is a single instance to the class ChargePoint for OCPP 1.6 or to the class ChargePoint for OCPP 2.0.1.

Overview of the required callbacks and events and what libocpp expects to happen

The following section will give you a high level overview of how to integrate libocpp with your application. Please use the Doxygen Documentation as an additional source for the ChargePoint API.

In EVerest the OCPP module leverages several other modules to perform tasks that relate to authorization, reservations, charging session handling and system tasks like rebooting or firmware updates.

The following sections explain the steps you can follow to implement their functionality on your own and integrate the libocpp directly into your charging station software without relying on EVerest. However, in most cases it's much easier to write an EVerest driver using the everest-core/interfaces/board_support_AC.yaml interface.

ChargePoint() constructor

The main entrypoint for libocpp for OCPP1.6 is the ocpp::v16::ChargePoint constructor. This is defined in libocpp/include/ocpp/v16/charge_point.hpp and takes the following parameters:

registering callbacks

You can (and in many cases MUST) register a number of callbacks so libocpp can interact with the charger. In EVerest most of this functionality is orchestrated by the "EvseManager" module, but you can also register your own callbacks interacting directly with your chargers software. Following is a list of callbacks that you must register and a few words about their purpose.

TODO: in a future version of libocpp the callbacks will be organised in a struct with optional members emphasizing the required and optional callbacks.

Some general notes: the "connector" parameter of some of the callbacks refers to the connector number as understood in the OCPP 1.6 specification, "0" means the whole charging station, the connectors with EVSEs used for charging cars start at "1".

Functions that need to be triggered from the outside after new information is availble (on_... functions in the charge point API)

The following functions are triggered depending on different so called "Session Events" from the EvseManager

each of these functions will have a small note what the Session Event was and what it triggers in libocpp

Authorization

In EVerest authorization is handled by the Auth module and various auth token providers and validators. The OCPP module acts as both a token provider (for pre validated tokens in RemoteStartTransactions) and a token validator (using the authorize requests, or plug & charge) To use libocpp as a auth token validator (e.g. before starting a transaction) you can call the "authorize_id_token" function of the ChargePoint object

Integrate this library with your Charging Station Implementation for OCPP2.0.1

TODO

Register event callbacks and on_handlers

Initialize the database

Install libocpp

For Debian GNU/Linux 11 you will need the following dependencies:

  sudo apt install build-essential cmake python3-pip libboost-all-dev libsqlite3-dev libssl-dev

OpenSSL version 3.0 or above is required.

Clone this repository.

  git clone https://github.com/EVerest/libocpp

In the libocpp folder create a folder named build and cd into it. Execute cmake and then make install:

  mkdir build && cd build
  cmake ..
  make install

Quickstart for OCPP 1.6

Libocpp provides a small standalone OCPP1.6 client that you can control using command line.

Install the dependencies and libocpp as described in Install libocpp.

Make sure you modify the following config entries in the config.json file according to the CSMS you want to connect to before executing make install.

{
  "Internal": {
    "ChargePointId": "",
    "CentralSystemURI": ""
  }
}

Change into libocpp/build and execute cmake and then make install:

  cd build
  cmake -DLIBOCPP16_BUILD_EXAMPLES=ON -DCMAKE_INSTALL_PREFIX=./dist ..
  make -j$(nproc) install

Use the following command to start the charge point. Replace the config with config-docker.json if you want to test with the SteVe CSMS running in a docker container.

  ./dist/bin/charge_point \
    --maindir ./dist \
    --conf config.json

Type help to see a list of possible commands.

Building the doxygen documentation

  cmake -S . -B build
  cmake --build build --target doxygen-ocpp

You will find the generated doxygen documentation at: build/dist/docs/html/index.html

The main reference for the integration of libocpp for OCPP1.6 is the ocpp::v16::ChargePoint class defined in libocpp/include/ocpp/v16/charge_point.hpp .

Unit testing

GTest is required for building the test cases target. To build the target and run the tests you can reference the script .ci/build-kit/install_and_test.sh. The script allows the GitHub Actions runner to execute.

Local testing:

mkdir build
cmake -B build -DBUILD_TESTING=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX="./dist"
cd build
make -j$(nproc) install

Run any required tests from build/tests.

Building with FetchContent instead of EDM

In doc/build-with-fetchcontent you can find an example how to build libocpp with FetchContent instead of EDM.

Support for TPM keys

In order to use the TPM keys, it is mandatory to use the default libwebsocket implementation.

Support for websocket++

The old websocket++ implementation has been deprecated. For enabling websocket++ support use the following cmake option:

  cmake .. -DLIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP=ON

Support for iface

In order to connect through a custom network iface, a custom internal config variable 'IFace' can be used.

"Internal": {        
    "IFace" : "enp43s0"
}