Implementing OCPI – How to make it work like a charm
Here are a few tips and tricks for implementing OCPI, the Open Charge Point Interface protocol. You can save yourself a few headaches by covering the few key issues before you start the implementation.
What is OCPI?
First, a bit about OCPI. It is a roaming protocol which connects e-Mobility Services providers (eMSP), Navigation Service Providers (NSP) and other parties to Charge Point Operators (CPO). OCPI mirrors versatile data including Locations, Tokens, Tariffs and Sessions between the parties. The protocol provides (to some extent) fault tolerant mechanisms for communication in order to provide the EV driver with near real-time knowledge about available – and even more importantly – unavailable charging points. OCPI allows for direct connections between parties, as well as connecting a large number of parties to each other through one of more OCPI hubs.
It is good to prepare for roaming early. Designing and building or purchasing a charge point management system for the CPO benefits from an understanding of the requirements posed by roaming. Preparing for roaming should be seen as a valuable investment when building the CPO services.
What is the difference between OCPI and OCPP?
Good question. When OCPI is used for roaming, OCPP on the other hand is the protocol spoken by the charge point. Yes, the physical device that provides electricity for the EV driver. OCPP allows the charge point to say “I’m feeling great and ready to serve the next EV driver” or “now we’ve charged 10 kWh already and BTW, the car is taking 32 amps right now”.
To learn more about OCPP, check out ocpp.online.
What are OCPI Modules and Roles?
In OCPI, a module refers to a set of functional parts of the platform which take care of specific tasks and store data related to that task. Modules such as “Locations”, “Tokens” and “Tariffs” all have their own responsibilities. Locations contains information about the charging points, Tokens identifies the different devices which can be used for payment and Tariffs specifies the pricing logic. Not all modules are required to be implemented by the specification.
The Roles in OCPI determine whom each type of data belongs to. The CPO owns its Locations, Tariffs, Sessions and Charge Detail Records while the eMSP owns its Tokens. See OCPI roles for more details regarding the relation between roles and objects.
Now, let’s dive into some of the key technical questions and the software architecture.
Multiple or single role per OCPI Platform?
OCPI serves different kinds of parties. Some only receive and read certain types of objects, but manage other types. You should decide at first if you will implement multiple roles in the same (database) instance. If your system represents multiple roles, you will need to choose a role when sending information to other parties. For example, if you are pushing Locations to eMSPs, you need to fill out the OCPI routing fields with your CPO identity. When you are pushing Tokens to CPOs, you need to use your eMSP identity. Correspondingly, the object instances need to have the correct party identifier. All Locations owned by the system need to have your CPO country_code and party_id, while all Tokens owned need to have the eMSP country_code and party_id.
Choose the right platform role for each type of object
OCPI 2.0/2.1.1 had a very strict definition of roles: only CPO and eMSP. But this is rare in the real world, there are almost no parties that are strictly CPO or eMSP and have their own platform. In the real world, lots of parties provide service to CPOs that are not running their own platform. A lot of CPOs are also eMSP. With OCPI 2.1.1 and earlier that meant having to set up an OCPI connection per role.
OCPI 2.2 introduces more roles and abstracts the role from the OCPI connection itself. OCPI 2.2 talks about Platforms connecting to Platforms, or Platforms connecting via Hubs to other Platforms. The Platform itself is not a role. The Platform provides services for 1 or more roles.OCPI 2.2 specification
Re-using code for push and pull when implementing OCPI
From the software architectural perspective, there is a great synergy to be had between push and pull mechanisms in OCPI. Implement the HTTP PUT methods for each module in a way that allows you to call them with JSON content coming from another source. This way you can re-use them for the scheduled pull.
Serializers and de-serializers
Depending on your choice of programming language, you may be using class inheritance and object serializers. These can be your strongest allies when implementing OCPI.
By creating a re-usable serializer and deserializer for each type of OCPI object, you can avoid writing duplicate code. Tariffs and Tokens may even require two different serializers and de-serializers, since the objects are referenced in Sessions and Charge Detail Records. You also need to decide how to store immutable versions of Tariffs for billing purposes. More on this in a later blog post.
An OCPI base class method or a function can use the serializers for pushing and pulling json data to and from interested OCPI parties. Most of the time the platform pushes objects to the full list of known parties by iterating through all Credentials and selecting the ones with a suitable role. Sessions and CDRs can and in my opinion should only be accessible to the MSP responsible for that specific charging session. Naturally, the hubs need to relay this information too.
I suggest to include in each OCPI object, such as Location, Tariff and Token, the information:
– how to serialize and deserialize that type of objects,
– who is interested in receiving updates,
– what role owns this type of objects and
– who is the owner of this specific object instance.
When you write code, you’re not only implementing the logic, you’re writing a story for your successor. Make it simple and easy to read, and someone will return the favour.Erkki Tapola
Prevent the creation of non-owned objects
You should prevent the CPO backend and the admin users from:
– Editing objects not owned by the user and
– Creating objects of types not owned by any of the roles indicated for the system.
For example, an eMSP should not create Locations and a CPO should not create Tokens. They should only receive them. However, many of the EV charging systems operate in multiple roles.
Implementing OCPI query parameters
The OCPI specification requires that most modules have to support specific OCPI query parameters. Do your best to make the logic for these parameters re-usable. Implementing the date range query mechanism and paging may not be the most interesting part of the project. However, it would be good to figure out how to do it before starting to implement the actual modules.
When listing objects using the paging logic, remember that the list ordering needs to remain constant in order for the paging to work.
By creating a re-usable serializer and deserializer for each type of OCPI object, you can avoid writing duplicate code.
You have read through the first article in a series, which aims to make your OCPI journey more pleasant and improve your rate of success. So, stay tuned for further postings. Meanwhile, check out our OCPI interoperability testing tool, the OCPI Connector.
What is the easiest way to implement OCPI? The answer is our Roaming API. Instead of months, a CPO can start roaming in two weeks and and MSP in about 3-4 weeks. Book a meeting with our OCPI guru to get started.
Erkki Tapola is a multi-faceted IT professional with a background in technology, leadership and products. Since 2020 he has focused on EV roaming and the OCPI protocol. Erkki founded SolidRoam in 2023 to continue the work of ChargerHub.EU, and he acts as CEO. His passion is to improve the reliability and ease of use of electric mobility. In his spare time he’s into electric road trips, couples dancing, bicycling and photography.