PHP2Shell alert: critical PHP flaws CVE-2026-109618 / 109619 — check your servers and get patched fast
HashTech Systems
EV Charging
Part 10 of 11

Migrating from OCPP 1.6 to 2.0.1: Message Mapping and Plan

A practical guide to moving a CSMS and fleet from OCPP 1.6-J to 2.0.1: message and configuration mapping, mixed fleets and a migration plan.

HashTech Engineering · October 26, 2026 · 5 min read

Almost nobody migrates a charging network from OCPP 1.6 to 2.0.1 in one step. New hardware arrives with 2.0.1 firmware, some existing models get a firmware upgrade, and a long tail stays on 1.6 for the rest of its life. So the real question is not "how do we switch" but "how does one CSMS run both properly". This article covers the mapping between the two and a plan that works with a mixed fleet. The higher-level business view is in OCPP 1.6 vs 2.0.

Message mapping

OCPP 1.6OCPP 2.0.1What changes
BootNotificationBootNotificationStation fields nested in chargingStation; new reason
HeartbeatHeartbeatUnchanged
StatusNotificationStatusNotification + NotifyEventFive states, per EVSE/connector; no error codes
AuthorizeAuthorizeidTag string becomes IdTokenType object; IdTokenInfo richer
StartTransactionTransactionEvent (Started)Station generates string transactionId
StopTransactionTransactionEvent (Ended)stoppedReason in transactionInfo
MeterValues (in transaction)TransactionEvent (Updated)Values are numbers; MeterValues remains for non-transaction data
RemoteStartTransactionRequestStartTransactionremoteStartId for correlation; EVSE instead of connector
RemoteStopTransactionRequestStopTransactionString transactionId
GetConfigurationGetVariables, GetBaseReport, GetReportDevice model addressing
ChangeConfigurationSetVariablesBatched, per-item status, RebootRequired
Reset (Hard/Soft)Reset (Immediate/OnIdle)Optional evseId; Scheduled status
ChangeAvailabilityChangeAvailabilityoperationalStatus and optional evse
UnlockConnectorUnlockConnectorevseId plus connectorId
SetChargingProfile, ClearChargingProfile, GetCompositeScheduleSame names, plus GetChargingProfiles/ReportChargingProfilesSchedule array, renamed purposes, external limits
SendLocalList, GetLocalListVersion, ClearCacheSame namesIdTokenType entries
ReserveNow, CancelReservationSame names, plus ReservationStatusUpdateReserve per EVSE or by connector type
TriggerMessage / ExtendedTriggerMessageTriggerMessageMerged; certificate triggers included
GetDiagnostics, DiagnosticsStatusNotificationGetLog, LogStatusNotificationDiagnostics and security logs
UpdateFirmware / SignedUpdateFirmwareUpdateFirmwareAlways signed
Security whitepaper messagesCore block A messagesSignCertificate, CertificateSigned, InstallCertificate, SecurityEventNotification and others
DataTransferDataTransferPrefer customData and device model where possible

2.0.1 also has entire areas with no 1.6 equivalent: variable monitoring, display messages, tariff and cost, ISO 15118 certificate management, network connection profiles and customer information requests. Those are the reasons to migrate, and they are covered in parts 2, 8 and 9.

Configuration key mapping

Most standard 1.6 configuration keys have a device model counterpart. These are the ones a typical CSMS sets during provisioning; check names against the device model appendix of the spec edition you implement, since the mapping is not always one-to-one.

1.6 key2.0.1 component.variable
HeartbeatIntervalOCPPCommCtrlr.HeartbeatInterval
MeterValueSampleIntervalSampledDataCtrlr.TxUpdatedInterval
MeterValuesSampledDataSampledDataCtrlr.TxUpdatedMeasurands (and TxStartedMeasurands)
StopTxnSampledDataSampledDataCtrlr.TxEndedMeasurands
ClockAlignedDataIntervalAlignedDataCtrlr.Interval
MeterValuesAlignedDataAlignedDataCtrlr.Measurands
ConnectionTimeOutTxCtrlr.EVConnectionTimeOut
StopTransactionOnInvalidIdTxCtrlr.StopTxOnInvalidId
StopTransactionOnEVSideDisconnectTxCtrlr.StopTxOnEVSideDisconnect
AuthorizeRemoteTxRequestsAuthCtrlr.AuthorizeRemoteStart
LocalAuthorizeOffline, LocalPreAuthorizeAuthCtrlr.LocalAuthorizeOffline, AuthCtrlr.LocalPreAuthorize
AllowOfflineTxForUnknownIdAuthCtrlr.OfflineTxForUnknownIdEnabled
AuthorizationCacheEnabledAuthCacheCtrlr.Enabled
LocalAuthListEnabledLocalAuthListCtrlr.Enabled
TransactionMessageAttempts, TransactionMessageRetryIntervalOCPPCommCtrlr.MessageAttempts / MessageAttemptInterval (instance TransactionEvent)
WebSocketPingIntervalOCPPCommCtrlr.WebSocketPingInterval
ChargeProfileMaxStackLevelSmartChargingCtrlr.ProfileStackLevel
ChargingScheduleAllowedChargingRateUnitSmartChargingCtrlr.RateUnit
SecurityProfile, AuthorizationKeySecurityCtrlr.SecurityProfile, SecurityCtrlr.BasicAuthPassword

There is no 1.6 equivalent of TxCtrlr.TxStartPoint and TxStopPoint. 1.6 stations had implicit, vendor-specific start and stop points. When the same hardware model moves from 1.6 to 2.0.1 firmware, compare its old behaviour with its new TxStartPoint before assuming session durations and idle times stay comparable in your reports. The 1.6 keys themselves are covered in 1.6 configuration keys.

Architecture for a mixed fleet

The approach that holds up is a version-specific adapter per connection and a version-neutral domain model behind it:

  1. Negotiate the version at the WebSocket handshake. Serve one endpoint that accepts both ocpp1.6 and ocpp2.0.1 subprotocols and pick per station, or separate paths per version. Record the negotiated version on the connection.
  2. Adapters translate to domain events. A 1.6 StartTransaction and a 2.0.1 TransactionEvent Started both become "session started" in your domain. Billing, OCPI, analytics and support tools only see domain events.
  3. Model the domain on 2.0.1, not 1.6. Station, EVSE, connector; string transaction ids; tokens with types. A 1.6 station maps cleanly into this model (each 1.6 connector becomes an EVSE with one connector, and the integer transaction id is stored as a string). Going the other way loses information.
  4. Commands go through the same adapters. "Start session on EVSE 2" becomes RemoteStartTransaction with connectorId 2 for 1.6 or RequestStartTransaction with evseId 2 for 2.0.1.
  5. Configuration is per-version. Keep a logical configuration ("meter interval 60 s") and render it as 1.6 keys or 2.0.1 variables per station.

Migrating stations in the field

Moving an installed station from 1.6 to 2.0.1 is a firmware change, and 1.6 has no standard way to switch protocol or CSMS URL (2.0.1's network profiles are new). In practice the vendor's 2.0.1 firmware ships with a default or migrated connection configuration, or the vendor provides a 1.6 configuration key for it. Plan for:

  • Keeping the same station identity and credentials, so the station reconnects to the same CSMS record on the new protocol.
  • No transactions in flight during the switch. A transaction started under 1.6 and finished under 2.0.1 has no clean representation; schedule upgrades on idle stations.
  • Re-provisioning after the first 2.0.1 boot: run GetBaseReport, apply your configuration, set fallback messages, install certificates. Use Pending on the first boot for this (see part 3).
  • A rollback path. Keep the 1.6 endpoint running and know how to downgrade firmware if a model misbehaves.
  • Updating OCPI EVSE ids if your identifiers depended on 1.6 connector numbering. See OCPP to OCPI mapping.

A migration plan that works

  1. Refactor the domain model to station/EVSE/connector and string transaction ids while still 1.6-only. This is most of the work, and it is risk-free to ship first.
  2. Build the 2.0.1 adapter for blocks B, C, E, F and G first: boot, authorization, transactions, remote control, availability. That is enough to charge and bill.
  3. Test against simulators and real hardware. Use a simulator for regression and edge cases, then at least one real station per model. See testing OCPP with a charge point simulator.
  4. Pilot one site with new 2.0.1 hardware. Watch transaction completeness (gaps in seqNo), status accuracy and authorization latency.
  5. Add security, device model tooling and monitoring, then smart charging, display messages and ISO 15118 as the business needs them.
  6. Upgrade existing models selectively, where the vendor's 2.0.1 firmware is mature and there is a feature you need. Leave the rest on 1.6.

Key takeaways

  • Plan for permanent coexistence of 1.6 and 2.0.1, not a cutover.
  • Model the domain on 2.0.1 concepts; adapt 1.6 into it.
  • Map configuration deliberately, and check TxStartPoint/TxStopPoint on upgraded hardware.
  • Only upgrade field stations when idle, with re-provisioning and a rollback path.

Running both protocols on one platform is how HashTech builds CSMS platforms; see EV charging or get in touch if you are planning a migration.

Let's Talk

Ready to build something that lasts?

Whether it's a charging network, an AI rollout, or a core enterprise system — let's talk about what you're building.