OCPP 2.0.1 vs OCPP 1.6 vs ISO 15118: EV Charging Architecture (2026)

OCPP 2.0.1 vs OCPP 1.6 vs ISO 15118: EV Charging Architecture (2026)

OCPP 2.0.1 vs OCPP 1.6 vs ISO 15118: EV Charging Architecture (2026)

Procurement teams keep asking the wrong question about EV charging protocols: “Is it OCPP 1.6 or OCPP 2.0.1?” The question assumes that OCPP, the Open Charge Point Protocol, and ISO 15118 are rival choices on one axis. They are not. They sit on two different links of the same chain, and the interesting engineering happens where the two meet. OCPP 2.0.1 governs the conversation between a charging station and its cloud backend. ISO 15118 governs the conversation between the car and the charger.

This matters in 2026 because the installed base is overwhelmingly OCPP 1.6, regulators in Europe and elsewhere are pushing toward standardised, secure, contract-free access, and OCPP 2.1 has now extended 2.0.1 to carry bidirectional charging. A station bought today without a clear migration story becomes a stranded asset within a few years.

You will leave this guide with a mental model of the full stack, a message-level comparison of 1.6 and 2.0.1, an honest account of how Plug and Charge actually works across both protocols, and a decision matrix for greenfield and brownfield deployments.

What this covers: the protocol stack and who talks to whom, OCPP 1.6 vs 2.0.1 differences, worked BootNotification and TransactionEvent flows with runnable code, ISO 15118-2 vs -20 and the Plug and Charge PKI, smart charging, security profiles, OCPI roaming, OCPP 2.1, and a migration plan.

Context and Background

Electric vehicle charging grew up as a patchwork. Each charger vendor shipped its own cloud link, each network operator wrote its own backend, and a driver needed a different RFID card or app for every network. OCPP was created to break that lock-in on the station-to-backend link. The Open Charge Alliance (OCA), which maintains it, describes OCPP 1.6 as released in 2015 and widely implemented, with 2.0 appearing in 2018 and 2.0.1 following in 2020 (Open Charge Alliance: OCPP overview). The OCA states that OCPP 1.6 can speak either SOAP or JSON, that 2.0.1 added device management, improved transaction handling, security enhancements, smart charging, ISO 15118 support and display messaging, and that the third edition of 2.0.1 was approved as an IEC standard, IEC 63584, in 2024.

ISO 15118 has a different lineage. It is a family of standards for “Road vehicles: vehicle to grid communication interface”, developed under ISO and IEC committees. Part 2 dates from 2014 and defined the application protocol and the first Plug and Charge model. Part 20 was published in 2022 and added bidirectional power transfer, TLS 1.3 and wireless communication options, according to a comparison by Injet Energy. A third family member sits above both: OCPI, the Open Charge Point Interface, which connects operators to mobility service providers for roaming and is covered later.

If you work in industrial IoT, the shape will be familiar. A constrained edge device holds a long-lived outbound WebSocket to a cloud, speaks a request-response protocol with a device model, and must be remotely managed, patched and secured. The same architectural questions appear in our comparison of OPC UA PubSub over MQTT versus UADP: who owns the information model, how is state synchronised after a disconnect, and where does security terminate? EV charging simply adds a car, a payment contract and a power grid to the picture.

The newest piece is OCPP 2.1. The OCA announced it on 23 January 2025 as an extension of 2.0.1, adding ISO 15118-20 support with bidirectional power transfer, a V2X functional block, a distributed energy resource (DER) control block, richer smart charging, battery swapping, local cost calculation and new payment options such as prepaid cards and secure dynamic QR codes (OCA: OCPP 2.1 is now available). The OCA also says application logic written for 2.0.1 should keep working under 2.1, while 1.6 uses different application logic and is not compatible with either.

The Charging Protocol Stack: Who Talks to Whom

Short answer: OCPP carries messages between a charging station (the EVSE, electric vehicle supply equipment) and a Charging Station Management System (CSMS) over WebSockets. ISO 15118 carries messages between the vehicle and the charging station over the charging cable or wireless link. The station is the translator, and the two protocols are complementary, not competing.

OCPP 2.0.1 and ISO 15118 EV charging protocol stack showing vehicle, charger, CSMS and roaming hub

Figure 1: The end-to-end EV charging protocol stack. ISO 15118 runs on the vehicle side of the charger, OCPP on the backend side, and OCPI between operators and roaming partners.

Figure 1 shows four parties. The vehicle (EV) has an on-board charger and a communication controller, the SECC-facing side of which is called the EVCC (Electric Vehicle Communication Controller). The charger runs a Supply Equipment Communication Controller, the SECC, which terminates ISO 15118 sessions. The CSMS sits in the cloud and is what operators call the “central system” or back office. Beyond the CSMS, OCPI links the operator, called the CPO (charge point operator), to e-mobility service providers (eMSPs) so that a driver with one app can charge on many networks.

Notice what the diagram implies about trust. The car does not trust the CSMS directly and the CSMS does not talk to the car. The charging station mediates, and in a Plug and Charge session it must forward certificate material, via OCPP, so the backend can validate a contract the car presents over ISO 15118. That forwarding is exactly where OCPP 1.6 runs out of road and 2.0.1 begins.

The physical layers hide a lot of variation

Before any of this software runs, a basic handshake occurs over the Control Pilot line defined in IEC 61851-1: a pulse-width-modulated signal that tells the car how much current the station can offer. Simple AC charging works with only this analogue signalling. High-level communication, the digital ISO 15118 layer, rides on top using power line communication (PLC) in part 2, and per the Injet comparison also wireless LAN in part 20.

This distinction explains why many “OCPP-compliant” chargers have no ISO 15118 at all. A basic AC wallbox needs only IEC 61851 signalling plus an OCPP link, and authenticates drivers with an RFID card or a phone app. ISO 15118 hardware adds a PLC modem, TLS stack and certificate store, which raises cost. DC fast chargers adopted it first because their price point and customer expectations justify the hardware.

Roles, in the vocabulary the standards use

It helps to fix terms once. The station is called the Charging Station in OCPP 2.0.1 and the Charge Point in 1.6. In 2.0.1 a station contains one or more EVSEs, and each EVSE contains one or more connectors, a three-level hierarchy of Charging Station, EVSE and Connector. In 1.6 the model was flatter: a charge point with numbered connectors and connector 0 representing the whole station. That structural change looks cosmetic but it drives most of the messages we compare next, because 2.0.1 can address a single EVSE on a multi-outlet cabinet without ambiguity.

OCPP 1.6 vs 2.0.1: What Actually Changed

Short answer: OCPP 2.0.1 is not 1.6 with extra messages. It replaces the flat connector model with a three-level device model, merges the transaction lifecycle into one TransactionEvent message, bakes in three security profiles and certificate management, and adds native hooks for ISO 15118. It is not wire-compatible with 1.6, so migration is a protocol project, not a firmware flag.

Both versions use the same basic transport, which is the OCPP-J flavour: JSON messages over a WebSocket opened by the station toward the CSMS. The station declares a WebSocket subprotocol in the handshake, ocpp1.6 for the older protocol and ocpp2.0.1 for the newer, and the server picks one it supports. If the CSMS supports both, that single header is the entire version negotiation, which is the foundation of any dual-stack migration.

The message frame is shared, the payloads are not

Every OCPP-J message is a JSON array. A call from either side is [2, "<uniqueId>", "<Action>", {payload}]. A successful reply is [3, "<uniqueId>", {payload}]. An error is [4, "<uniqueId>", "<errorCode>", "<description>", {details}]. The shared frame is why a protocol gateway can translate between versions at all: the plumbing is identical, and only the semantic mapping differs.

What changes is the semantics inside the payload. In 1.6 a driver tapping an RFID card triggers Authorize, the session start sends StartTransaction, energy readings flow via MeterValues, and the end sends StopTransaction. In 2.0.1 all of that collapses into TransactionEvent with an eventType of Started, Updated or Ended, plus a triggerReason explaining why the message was sent (for example cable plugged in, authorised, or meter value sampled).

Aspect OCPP 1.6 OCPP 2.0.1
Released 2015 2020 (2.0 in 2018)
Transport JSON or SOAP JSON over WebSocket only
Station model Charge point with numbered connectors Charging Station, EVSE, Connector hierarchy
Configuration Flat key-value (GetConfiguration, ChangeConfiguration) Device model of components and variables (GetVariables, SetVariables)
Transactions StartTransaction, MeterValues, StopTransaction Single TransactionEvent with Started/Updated/Ended
Security Added later through an official security whitepaper Built into the specification, profiles 1 to 3
Firmware update UpdateFirmware, signed variant via whitepaper UpdateFirmware with signature support in core
ISO 15118 support None in core Certificate messages and Plug and Charge authorisation
Smart charging Charging profiles, three purposes Extended profiles, external constraints, more control
Display and messaging Minimal SetDisplayMessage, tariff and cost display
Reporting Limited Monitoring and event reporting for variables
Compatibility Not compatible with 2.0.1 or 2.1 2.1 extends it, per OCA

The device model is the quiet revolution

In OCPP 1.6 configuration is a bag of strings. You call GetConfiguration, receive keys such as HeartbeatInterval or MeterValueSampleInterval, and change them with ChangeConfiguration. Vendors added custom keys, and no two stations exposed the same set. A CSMS had to carry per-model quirks tables.

OCPP 2.0.1 replaces that with a device model. Everything is a variable that belongs to a component: a component such as EVSE, Connector, SecurityCtrlr or TxCtrlr exposes variables such as Enabled, Available or AuthorizeRemoteStart, each with typed attributes (Actual, Target, MinSet, MaxSet). A CSMS can query the whole inventory with GetBaseReport and receive a streamed NotifyReport, then set values with SetVariables. The practical result is that capability discovery becomes machine-readable. A backend can ask the station what it supports instead of consulting a spreadsheet of model numbers, which is the same shift that OPC UA brought to factory equipment.

2.0.1 also adds variable monitoring: the CSMS can install monitors with SetVariableMonitoring so the station reports threshold crossings or periodic values, and it can raise events through NotifyEvent. This turns diagnostics from polling into subscription, which cuts both chatter and mean time to detect a failing contactor or overheating connector.

OCPP 2.0.1 versus OCPP 1.6 message lifecycle comparison from plug-in to session end

Figure 2: A single charging session as seen on the wire. OCPP 1.6 uses four distinct actions, while OCPP 2.0.1 expresses the same lifecycle as repeated TransactionEvent messages with different trigger reasons.

Figure 2 contrasts the two flows for one session. The 1.6 flow depends on correct ordering of separate request types. Because 2.0.1 numbers each event with a seqNo inside the transaction and ties them to a transactionId generated by the station, the backend can detect gaps and reorder, which makes offline buffering more robust. In 1.6 the CSMS assigns the transaction id in the StartTransaction response, which means an offline station cannot know its own id and must queue messages awkwardly. That inversion is a genuine reliability win.

Worked flow: BootNotification

Every session begins with a boot. When a 2.0.1 station connects, it sends BootNotification, introducing itself. The request carries a reason (such as PowerUp or ApplicationReset) and a chargingStation object with model and vendorName required, and serialNumber and firmwareVersion optional.

[2, "19223201", "BootNotification", {
  "reason": "PowerUp",
  "chargingStation": {
    "model": "WB-22",
    "vendorName": "ExampleCorp",
    "serialNumber": "EC-0042",
    "firmwareVersion": "2.4.1"
  }
}]

The CSMS replies with the current time, a heartbeat interval in seconds and a status of Accepted, Pending or Rejected:

[3, "19223201", {
  "currentTime": "2026-10-14T01:35:00.000Z",
  "interval": 300,
  "status": "Accepted"
}]

Pending is more useful than it looks. A CSMS can hold a station in Pending while it pushes configuration with SetVariables or queries the inventory, and the specification restricts what the station may do until it is Accepted. This gives operators a safe provisioning window that 1.6 handled only informally.

Worked flow: TransactionEvent

When a driver plugs in and authorises, the station sends a TransactionEvent with eventType: Started. A condensed example, including an idToken, an EVSE reference and a meter reading, looks like this:

[2, "8812", "TransactionEvent", {
  "eventType": "Started",
  "timestamp": "2026-10-14T01:40:12.000Z",
  "triggerReason": "Authorized",
  "seqNo": 0,
  "transactionInfo": { "transactionId": "tx-7f3a-0001", "chargingState": "Charging" },
  "evse": { "id": 1, "connectorId": 1 },
  "idToken": { "idToken": "04A2B3C4D5", "type": "ISO14443" },
  "meterValue": [{
    "timestamp": "2026-10-14T01:40:12.000Z",
    "sampledValue": [{ "value": 12873.4, "measurand": "Energy.Active.Import.Register",
                       "unitOfMeasure": { "unit": "Wh" } }]
  }]
}]

The response confirms the token status through an idTokenInfo object. Subsequent messages use Updated with seqNo 1, 2, 3 and so on, and a final Ended carries the stop reason (for example EVDisconnected or Local) and the closing meter reading. The values above are illustrative, but the field names follow the 2.0.1 schema.

A minimal runnable CSMS

The following Python server uses the open-source ocpp library (the Mobility House implementation) to accept 2.0.1 stations and answer both messages. Install with pip install ocpp websockets. The library’s API has moved between releases, so treat this as a starting point and check the version you install.

import asyncio
import logging
from datetime import datetime, timezone

import websockets
from ocpp.routing import on
from ocpp.v201 import ChargePoint as cp
from ocpp.v201 import call_result
from ocpp.v201.enums import RegistrationStatusType

logging.basicConfig(level=logging.INFO)


class CentralSystem(cp):
    @on("BootNotification")
    async def on_boot(self, charging_station, reason, **kwargs):
        logging.info("Boot from %s (%s)", charging_station.get("model"), reason)
        return call_result.BootNotification(
            current_time=datetime.now(timezone.utc).isoformat(),
            interval=300,
            status=RegistrationStatusType.accepted,
        )

    @on("TransactionEvent")
    async def on_txn(self, event_type, trigger_reason, seq_no,
                     transaction_info, **kwargs):
        logging.info("tx %s %s seq=%s", transaction_info["transaction_id"],
                     event_type, seq_no)
        return call_result.TransactionEvent()

    @on("Heartbeat")
    async def on_heartbeat(self, **kwargs):
        return call_result.Heartbeat(
            current_time=datetime.now(timezone.utc).isoformat())


async def handler(ws):
    # The station identity is the last path segment, e.g. wss://csms/ocpp/CP001
    station_id = ws.request.path.strip("/").split("/")[-1]
    if ws.subprotocol != "ocpp2.0.1":
        return await ws.close(reason="subprotocol not supported")
    await CentralSystem(station_id, ws).start()


async def main():
    server = await websockets.serve(
        handler, "0.0.0.0", 9000, subprotocols=["ocpp2.0.1"])
    await server.wait_closed()


asyncio.run(main())

This is deliberately small. A production CSMS adds persistence for transactions, idempotent handling of replayed messages after reconnect, authorisation lookups, TLS termination and rate limiting. What the sketch shows is how little ceremony the protocol itself needs: a subprotocol check, a station identity from the URL and a router for actions.

ISO 15118 and Plug and Charge: The Vehicle Side

Short answer: ISO 15118 Plug and Charge lets a car authenticate and pay by presenting a digital certificate when the cable is plugged in, with no card or app. The car holds a contract certificate, the charger validates it against a trusted PKI, and the backend settles billing through the mobility provider. OCPP 2.0.1 supplies the certificate-handling messages that make this work end to end.

ISO 15118 Plug and Charge sequence between vehicle, charging station, CSMS and PKI

Figure 3: A Plug and Charge session. The vehicle presents a contract certificate over ISO 15118, the station relays validation material to the CSMS over OCPP 2.0.1, and the backend checks revocation through the PKI before authorising power.

What the vehicle and charger negotiate

In an ISO 15118 session the EVCC and SECC first discover each other over IPv6 using the SECC Discovery Protocol, then open a TCP connection, optionally upgraded to TLS, and agree on an application protocol. They exchange supported services, payment options and charging parameters: how much energy the car wants, the departure time, and the limits of the car’s battery and the charger’s output. The charger then sends the car a schedule of what it can deliver. In part 2 the session messages are encoded as EXI (Efficient XML Interchange), a compact binary form of XML. I could not confirm from the sources I fetched whether -20 changes that encoding, so check the standard text before building a decoder.

The two payment modes matter for architecture. In “external identification means” (EIM) mode the driver authenticates outside the car, using an RFID card or app, and ISO 15118 only carries the charging parameters. In Plug and Charge (PnC) mode the car itself authenticates using the certificate chain. Many ISO 15118 stations support both and fall back to EIM when a car has no valid contract.

The Plug and Charge PKI

Plug and Charge is a public-key infrastructure story more than a messaging story. A contract certificate, issued to the car by an e-mobility service provider, binds an identifier (the eMA, e-mobility account identifier) to a key pair stored in the car. A chain of CA certificates leads from the contract certificate up to a V2G root certificate authority, and the charger must hold a trusted root to verify that chain. The chargers’ own server certificates must also chain to a root the car trusts, so TLS is mutual in practice for PnC.

Issuing the contract certificate to the car requires some party to be trusted by both car makers and operators. Hubject operates a prominent PKI for this purpose and has announced services based on ISO 15118-20 (Hubject announcement). It is one of several trust anchors in the market. Interoperability gaps between PKIs and between implementations remain a recurring source of failed PnC sessions, and CharIN, the industry association behind much of the testing, publishes implementation guidance on TLS with ISO 15118 for exactly that reason.

Part 20 tightens security. Per the Injet comparison, -20 requires TLS 1.3 with mandatory mutual authentication, where part 2 used TLS 1.2 and left TLS optional in many contexts. It also supports multiple contracts per session, bidirectional transfer (V2G, V2H, V2B) and wireless transport, and needs more processing, memory and larger certificates. The same source cautions that -20 is not a firmware patch for -2 hardware: chargers designed with headroom and over-the-air update capability can migrate, others cannot.

Where OCPP 2.0.1 plugs in

OCPP 2.0.1 contains the messages that let a station act as the relay. When the car sends a contract certificate chain, the station can pass it to the CSMS inside an Authorize request that carries iso15118CertificateHashData so the backend can check status via OCSP (Online Certificate Status Protocol); the station can ask the CSMS to check certificate status with GetCertificateStatus. If the car needs a fresh contract certificate, the station forwards the car’s request through Get15118EVCertificate. The station’s own certificates are provisioned through SignCertificate (the station sends a certificate signing request) and CertificateSigned (the CSMS returns the signed certificate), while InstallCertificate and DeleteCertificate manage trust anchors.

None of this exists in OCPP 1.6 core. Vendors have implemented Plug and Charge on 1.6 via the DataTransfer escape hatch, a generic message with a vendor identifier and an opaque payload. That works, but it is by definition non-interoperable: two backends need to agree on the private schema. This is the strongest single argument for 2.0.1 in new premium DC deployments.

Security Profiles, Certificates and Firmware

OCPP’s transport security is expressed as profiles. The specification for 2.0.1 defines three, and the OCPP 1.6 security whitepaper later backported the same idea:

  • Profile 1: unsecured transport with HTTP basic authentication. Suitable only on private networks, such as a closed APN or VPN.
  • Profile 2: TLS with a server certificate, plus basic authentication using a per-station password.
  • Profile 3: TLS with mutual authentication, where the station presents a client certificate.

I describe the profiles from my knowledge of the specification rather than a fetched primary source, so verify minimum TLS versions and cipher requirements against the current OCPP 2.0.1 text before you write procurement language. As a rule, Profile 3 is the right target for public infrastructure: a stolen basic-auth password lets an attacker impersonate a station, while a client certificate in a hardware-backed store raises the bar substantially.

Firmware updates are a security feature

A charger is a network-connected device that switches kilowatts and handles payment tokens. Signed firmware updates are therefore not optional. In 2.0.1 UpdateFirmware can carry a signing certificate and signature so the station verifies authenticity before installing, and FirmwareStatusNotification reports progress. Combined with SecurityEventNotification, where a station reports tampering, invalid certificates or failed authentication, this gives the CSMS an audit trail. The same discipline is argued for container workloads in our piece on runtime security with Cilium and Tetragon: attestation and runtime telemetry matter more than perimeter defences.

Certificate lifecycle is the operational cost

The hard part of Profile 3 and Plug and Charge is not the first certificate, it is the thousandth renewal. Station certificates expire, trust anchors rotate, and revocation must propagate. A fleet of 10,000 stations with two-year certificates needs roughly 14 renewals a day on average, each of which can fail if the station has been offline or its clock has drifted. Build monitoring on certificate expiry as a first-class metric, and test renewal on a staging fleet before the first production expiry, not after.

Smart Charging: Where 2.0.1 Pulls Ahead

Smart charging is the other area where the versions diverge in substance. The goal is to shape power over time to respect grid limits, site connection capacity, tariffs and driver needs. Both versions use charging profiles, a schedule of power or current limits over time, and a SetChargingProfile message to install them.

In 1.6 a profile has a purpose: ChargePointMaxProfile (a site-level cap), TxDefaultProfile (default for new transactions) or TxProfile (for one active transaction). The station merges them by stack level, picking the most restrictive applicable limit. In 2.0.1 the purposes are extended: per the specification as I know it, they include ChargingStationExternalConstraints (limits imposed by an outside energy manager), ChargingStationMaxProfile, TxDefaultProfile and TxProfile. That extra purpose lets a local energy management system impose constraints the CSMS cannot override, which models the real hierarchy of authority at a site with a grid operator or building controller.

Why ISO 15118 changes the smart charging picture

Smart charging in 1.6 is open-loop from the car’s viewpoint: the charger limits the current via the Control Pilot, and the car obeys without saying what it needs. With ISO 15118, the car states its energy request and departure time, and in 2.0.1 the station can forward that to the CSMS via a NotifyEVChargingNeeds message. The CSMS computes a schedule and returns it in SetChargingProfile, and the station relays it as a NotifyEVChargingSchedule to the car. This closed loop is what makes true “charge by 7 am at the cheapest cost” planning possible rather than blunt current clamping.

Suppose a depot has 20 buses each needing 200 kWh overnight, with a site import limit of 400 kW over a 10-hour window. Total demand is 4,000 kWh, and 400 kW times 10 hours is exactly 4,000 kWh, so there is zero slack. Any station that wastes capacity, a bus that arrives late, or a phase imbalance will leave some bus short. Knowing each bus’s departure time and state of charge is the difference between a feasible schedule and a surprise at 6 am. This arithmetic is illustrative, not from a deployment, but it shows why per-vehicle information beats blunt limits.

Smart charging load management architecture with CSMS, local energy manager and charging profiles

Figure 4: Smart charging hierarchy. A grid or building constraint caps the site, the CSMS allocates the budget across stations as charging profiles, and ISO 15118 vehicle needs flow upward to inform the schedule.

Figure 4 puts the authorities in order. The outermost limit is physical: the site connection or transformer. A local energy management system (LEMS) enforces it. The CSMS distributes the remaining budget as profiles, and each station honours the most restrictive of its stacked profiles. When a connection to the CSMS drops, the station keeps running with the last installed profile, which is why profiles should always have a conservative default or a finite validity period.

OCPI Roaming and OCPP 2.1: The Layers Above and Beside

OCPP does not move money or settle roaming. That is the job of OCPI, the Open Charge Point Interface, which links a CPO to eMSPs. A recent technical guide describes OCPI 2.2.1 as the current mainstream version in 2026, adding smart charging profiles, combined time and energy tariffs, signed meter value fields for German-style calibration law compliance, and hub client information (Codibly: OCPI protocol guide). The same guide says OCPI 2.3.0 responds to the EU’s Alternative Fuels Infrastructure Regulation (AFIR) with structured exchange with national access points, better ad hoc payment flows and richer location attributes. I could not find an official release date for either version in the sources I checked, so confirm against the EVRoaming Foundation before citing one.

The core OCPI modules map neatly onto the OCPP data. Locations describe stations, EVSEs and connectors. Sessions carry live energy and cost. Charge Detail Records (CDRs) are the billing record, produced when a session ends. Tariffs describe pricing, Tokens carry driver authorisation, and Commands let an eMSP remotely start or stop a session. Practically, an OCPP TransactionEvent of type Ended arrives at the CSMS, which then produces a CDR and pushes it to the roaming partner through OCPI.

This is why the CSMS is the real integration point in the architecture. It must translate OCPP’s per-station view into OCPI’s per-location, per-tariff, per-contract view, and it must keep both consistent when a station goes offline mid-session. The data-modelling discipline here resembles the asset hierarchy work in ISO 19650 and BIM data models for digital twins: a clean identifier scheme for sites, assets and components saves more engineering time than any individual protocol feature.

OCPP 2.1 in context

OCPP 2.1 arrives as an extension, not a rewrite. The OCA states that it supports ISO 15118-20 including bidirectional power transfer, adds a V2X block and DER control, and brings more transaction options: fixed-cost, energy-based or time-based, and resumption after a forced reboot. It also adds local cost calculation on the station, battery swapping for light electric vehicles, and payment methods such as prepaid cards and secure dynamic QR codes. Importantly for planners, the OCA says 2.0.1 and 1.6 remain supported.

Two things follow. First, going to 2.0.1 now is not a dead end, because the OCA intends application logic written for 2.0.1 to keep working under 2.1. Second, bidirectional charging needs a coordinated stack: per the Injet comparison, ISO 15118-20 on the charger is the communications foundation, but vehicles, backend software (typically OCPP 2.1) and local grid rules must also permit export. A charger advertising “V2G ready” with only one of those layers will not discharge a car into the grid.

Migrating from OCPP 1.6 to OCPP 2.0.1: Patterns and Pitfalls

Most operators cannot flip a fleet overnight. The installed base includes thousands of 1.6 stations that may not receive a 2.0.1 firmware at all, because the hardware lacks the memory or the vendor has ended support. The pragmatic answer is a dual-stack CSMS that negotiates the subprotocol per station and keeps one internal domain model.

In short, the dual-stack CSMS has three layers: version adapters at the edge, a canonical session model in the middle and business services on top. The design principle is to never let protocol semantics leak into business logic. Build two thin adapters, one per OCPP version, that convert wire messages into a canonical internal event: SessionStarted, MeterSampled, SessionEnded, StationStatusChanged. Smart charging, billing, roaming and dashboards then consume the canonical events. When the last 1.6 station is retired, you delete one adapter.

Mapping the awkward parts

Three mappings cause most of the pain. The first is transaction identity: 1.6 has the CSMS issue a numeric transaction id, while 2.0.1 has the station issue a string. Your internal model should use its own session id and store both external ids. The second is configuration: 1.6 key-value pairs must be mapped to 2.0.1 component-variable pairs, and a table of equivalents per vendor model is unavoidable. The third is status: 1.6 uses connector status values such as Available, Preparing, Charging and Faulted, while 2.0.1 reports status through StatusNotification with a reduced set of connector states and richer detail in the device model. Normalise into your own state machine and test the edges: a cable unplugged during suspension, a power loss during a transaction, and a reboot mid-session.

Test with a certification mindset

The OCA runs a certification programme and publishes test specifications; the OCA page I fetched links to it but gave no detail, so check the Alliance site for the current procedure and the list of recognised test labs. Even if you do not certify, run a conformance suite, because the most common 2.0.1 field failures are not exotic. They are optional fields treated as required, enumerations extended by a vendor, and clock drift producing timestamps from 1970. Interoperability events and independent test tools exist to catch these, and fleet-level soak tests with deliberately flaky connections catch the rest.

Decision Matrix: Which Stack for Which Deployment

The right answer depends on what the charger does, how long it must live, and who pays when something breaks. The matrix below summarises defensible defaults; treat them as starting points rather than rules.

Scenario Recommended OCPP ISO 15118 Reason
Home or small commercial AC wallbox, RFID or app auth 1.6 now, plan for 2.0.1 None needed Simplicity; large ecosystem; low hardware cost
New public AC network, 5+ year life 2.0.1 Optional Security profiles, device model and monitoring reduce lifetime cost
New public DC fast network 2.0.1, with an upgrade path to 2.1 Part 2 minimum, design for part 20 Plug and Charge, smart charging, certificate lifecycle
Depot or fleet charging 2.0.1 Part 2 or 20 where vehicles support it Vehicle needs inform scheduling; deterministic energy budgets
V2G or V2H pilot 2.1 Part 20 required Bidirectional blocks only exist in 2.1 and part 20
Legacy fleet of 1.6 stations Stay on 1.6 with security whitepaper profiles; migrate on hardware refresh N/A Avoids risky mass firmware updates

If you can only remember one rule, remember this: choose the OCPP version for the backend relationship and the ISO 15118 part for the vehicle relationship, and make sure the hardware can be updated over the air because both will change during the asset’s life.

Trade-offs, Gotchas, and What Goes Wrong

Newer is not automatically safer. OCPP 2.0.1 is a large specification with optional functional blocks. A station can claim 2.0.1 and implement only the core, leaving out ISO 15118 certificate handling, display messaging or variable monitoring. Read the vendor’s profile conformance statement, not the marketing sheet, and compare the declared functional blocks against what your use case requires.

Dual-stack costs real money. Supporting both versions doubles test matrices, and bugs hide in the translation layer. A transaction that starts on a 1.6 station and is billed through a pipeline built around 2.0.1 semantics can lose its meter values if the adapter rounds timestamps or loses sequence order. Budget for a canonical model early rather than bolting adapters on later.

Plug and Charge fails in boring ways. The textbook flow assumes valid certificates, synchronised clocks, reachable OCSP responders and a trusted root in both car and charger. In practice, failures come from an expired root in a car that never received an update, a charger that cannot reach a revocation endpoint from a locked-down network, or a contract provisioned with one PKI while the charger trusts another. The standard graceful behaviour is fallback to EIM, so make sure your stations and your app support it, and measure the PnC success rate as a headline operational metric.

Offline behaviour is where designs differ. Stations lose connectivity regularly. A good implementation keeps a local authorisation list, queues transaction events with sequence numbers, and resumes with consistent state. A poor one drops transactions or double-bills. Test with the network cable pulled mid-session, then reconnect and reconcile. Heartbeat intervals also matter: a 300-second interval means a station silently dead for five minutes looks healthy, so pair heartbeats with StatusNotification and a server-side timeout.

Security profile 1 is a trap. Basic authentication over unencrypted WebSockets leaks station credentials to anyone on the path. If you must use it, because a legacy modem or private network demands it, keep it on an isolated APN or VPN and document the compensating controls. Public-network stations deserve TLS and, ideally, client certificates.

Do not trust a single number for charging time. Real sessions are shaped by the car’s battery management, temperature, state of charge and the charger’s thermal limits, so identical stations deliver different energy curves. This is why smart charging algorithms need measured, per-session feedback rather than nameplate power. The worked depot arithmetic earlier is a planning bound, not a prediction.

Bidirectional charging is still emerging. The standards exist, but a working V2G deployment needs a compliant car, charger, backend, tariff structure and a grid connection agreement that allows export. Treat any vendor claim of “V2G ready” as a request for evidence: which vehicle models, which grid code, which version of ISO 15118-20 and which OCPP revision.

Practical Recommendations

Start from the use case, not the version number. If you are buying chargers for a public network that must remain in service for a decade, require OCPP 2.0.1 with Security Profile 3, signed firmware updates and an over-the-air upgrade path to 2.1. Ask for ISO 15118-2 support at a minimum on DC units, with demonstrated -20 readiness where bidirectional use is plausible, and ask for the conformance statements in writing.

On the backend, keep one internal session model and treat each OCPP version as an adapter. Make certificate lifecycle, offline reconciliation and Plug and Charge success rate first-class metrics, with alerts rather than quarterly reports. Keep OCPI integration separate from OCPP handling, so a roaming change does not touch station communication.

For existing 1.6 fleets, resist forced migration. Apply the security whitepaper profiles where hardware allows, segment the network, and schedule the migration to 2.0.1 around hardware refresh, because that is when firmware capacity and vendor support improve together.

A short checklist before signing a charger or CSMS contract:

  • Does the vendor list supported OCPP functional blocks, and is certification evidence available?
  • Is Security Profile 3 supported, with secure key storage and a documented certificate renewal process?
  • Can firmware be updated over the air with signature verification, including the ISO 15118 stack?
  • Does the station store and replay transaction events correctly after an outage?
  • Is the ISO 15118 part declared (2 or 20), and which PKI roots are pre-installed?
  • What is the stated path to OCPP 2.1 and OCPI 2.2.1 or 2.3 compatibility?
  • Are smart charging profiles honoured through reboot and loss of connection?

Frequently Asked Questions

Is OCPP 2.0.1 backward compatible with OCPP 1.6?

No. The Open Charge Alliance states that 1.6 uses different application logic and is not compatible with 2.0.1 or 2.1. Both use JSON over WebSockets in their OCPP-J form, so a CSMS can negotiate the version through the WebSocket subprotocol header and run two adapters side by side. Stations, however, must be running firmware that speaks the new protocol, so migration is a station-by-station decision and not a simple backend switch.

What is the difference between OCPP and ISO 15118?

OCPP is the protocol between a charging station and its cloud backend, the CSMS. ISO 15118 is the protocol between the electric vehicle and the charging station. They address different links in the chain. A station commonly speaks both: ISO 15118 to the car and OCPP to the backend, with OCPP 2.0.1 including messages that carry ISO 15118 certificate information so Plug and Charge can be authorised centrally.

Does OCPP 1.6 support Plug and Charge?

Not in its core specification. Plug and Charge needs certificate handling and ISO 15118 authorisation, which OCPP 2.0.1 added as standard messages. Some vendors implemented it on 1.6 through the generic DataTransfer message, but those schemas are private, so interoperability between a given station and backend is not guaranteed. For new Plug and Charge deployments, OCPP 2.0.1 is the safer foundation.

What does OCPP 2.1 add over 2.0.1?

According to the Open Charge Alliance, OCPP 2.1 extends 2.0.1 with ISO 15118-20 support including bidirectional power transfer, a V2X block, DER control, improved smart charging, more transaction options, battery swapping, local cost calculation and new payment methods such as prepaid cards and secure dynamic QR codes. The OCA says application logic written for 2.0.1 should continue to work under 2.1, so choosing 2.0.1 now keeps the upgrade path open.

How do OCPP security profiles work?

OCPP defines three profiles for the station connection. Profile 1 uses basic authentication over an unsecured link, Profile 2 adds TLS with a server certificate plus basic authentication, and Profile 3 uses mutual TLS with a client certificate on the station. For public networks, Profile 3 is the strongest choice. Verify exact TLS version requirements in the current specification before drafting requirements.

Is OCPI the same as OCPP?

No. OCPP connects a charging station to its operator’s backend. OCPI connects operators (CPOs) with e-mobility service providers for roaming, exchanging locations, tariffs, sessions, charge detail records, tokens and remote commands. A typical network uses both: OCPP at the edge and OCPI between companies. A guide from Codibly describes OCPI 2.2.1 as the mainstream version in 2026, with 2.3.0 adding AFIR-driven features.

Further Reading

By Riju — about

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *