Migration Guide 2.0.1 → 2.1 Section F

Remote Control Section — Migration Guide

Use cases F01–F06 (2.0.1) / F01–F07 (2.1). Perspective: CSMS Developer.

6 Sections
7 Use Cases
F01 – F07

Created by tzi.app — your guide to migrating from OCPP 2.0.1 to OCPP 2.1.

1. Summary of Changes

High-Level Overview

Area Change Type Description
Connector status reporting Replaced StatusNotificationRequest replaced by NotifyEventRequest in F01, F02, F03 sequences
IdTokenType Increased idToken max length: 36 → 255 chars
IdTokenEnumType → IdTokenEnumStringType Changed Changed from a closed enum to a string type (max 20 chars); new value OCPP2WhiteList added
StatusInfoType Increased additionalInfo max length: 512 → 1024 chars
TransactionEventResponse Extended New fields: transactionLimit, updatedPersonalMessageExtra
TransactionEventRequest Extended New fields in TransactionType: operationMode, transactionLimit; new top-level: costDetails, preconditioningStatus, evseSleep
ReasonEnumType (stoppedReason) New values EnergyLimitReached, TimeLimitReached, SOCLimitReached, LocalOutOfCredit added for F07 limit scenarios
ChargingProfileType Extended New chargingProfileKind value: "Dynamic"
ChargingSchedulePeriod Changed limit field changed from required to conditional; new phaseToUse field added
TriggerMessageRequest (F06) Extended New customTrigger field; new enum values CustomTrigger and SignV2G20Certificate
F06 BootNotification trigger New CS will reject BootNotification trigger if last BootNotification was already Accepted (F06.FR.17)
UnlockConnectorRequest (F05) Clarified evseId and connectorId now explicitly allow ≥0; clarified scope (cable retention lock only)
F05 error handling New CS with no lock mechanism or manual lock SHOULD respond with CALLERROR NotSupported
F03 Remote Stop Changed 2.1 shows two-phase stop: first Updated (energy stopped), then Ended (cable unplugged); adds TxStopPoint impact documentation
F07 New use case Remote Start with transaction limits (maxCost, maxEnergy, maxTime, maxSoC)

2. Cross-Cutting Change: StatusNotification Replaced by NotifyEvent

In OCPP 2.0.1, connector state changes in remote control flows used StatusNotificationRequest. In OCPP 2.1, these are replaced by NotifyEventRequest.

Affected Use Cases

Use Case 2.0.1 2.1
F01 (Cable Plugin First) CS sends StatusNotificationRequest (connector = Occupied) when cable plugged in CS sends NotifyEventRequest when cable plugged in
F02 (Remote Start First) CS sends StatusNotificationRequest (Occupied) when cable plugged in after remote start CS sends NotifyEventRequest when cable plugged in after remote start
F03 (Remote Stop) Not explicitly shown in sequence CS sends NotifyEventRequest after EV driver unplugs cable

Message Format Comparison

OCPP 2.0.1 — StatusNotificationRequest:

JSON — StatusNotificationRequest (2.0.1)
{
  "timestamp": "2025-06-15T14:30:05.000Z",
  "connectorStatus": "Occupied",
  "evseId": 1,
  "connectorId": 1
}

OCPP 2.1 — NotifyEventRequest (replacement):

JSON — NotifyEventRequest (2.1)
{
  "generatedAt": "2025-06-15T14:30:05.000Z",
  "seqNo": 0,
  "eventData": [
    {
      "eventId": 1,
      "timestamp": "2025-06-15T14:30:05.000Z",
      "trigger": "Delta",
      "actualValue": "Occupied",
      "eventNotificationType": "HardWiredNotification",
      "component": {
        "name": "Connector",
        "evse": { "id": 1, "connectorId": 1 }
      },
      "variable": {
        "name": "AvailabilityState"
      }
    }
  ]
}

CSMS Migration Action

Replace your StatusNotificationRequest handler (in remote control flows) with a NotifyEventRequest handler that filters for component.name = "Connector" and variable.name = "AvailabilityState". Extract the connector state from actualValue instead of connectorStatus.

3. Data Type & Schema Changes

3.1 IdTokenType

Field 2.0.1 2.1 Action
idToken string (max 36) string (max 255, case-insensitive) Increase max length validation from 36 to 255
type IdTokenEnumType (closed enum) IdTokenEnumStringType (string, max 20) Change from enum validation to string validation; accept unknown values gracefully
New type value "OCPP2WhiteList" Handle new token type for OCPP2 whitelist-based authorization

3.2 StatusInfoType

Field 2.0.1 2.1 Action
additionalInfo string (max 512) string (max 1024) Increase max length validation from 512 to 1024

3.3 EVSEType

Field 2.0.1 2.1 Action
id integer (> 0) integer (>= 0) Allow 0 as a valid EVSE ID (represents the Charging Station itself)
connectorId integer integer (>= 0) Explicitly allow 0

3.4 TransactionEventResponse (CSMS → CS)

New fields added in 2.1:

Field Type Description
transactionLimit TransactionLimitType Cost/energy/time/SoC limits for the transaction (used by F07)
updatedPersonalMessageExtra MessageContentType[] Additional display messages (multiple languages)

TransactionLimitType (new in 2.1):

JSON — TransactionLimitType
{
  "maxCost": 50.00,
  "maxEnergy": 30000,
  "maxTime": 7200,
  "maxSoC": 80
}
Field Type Description
maxCost number Maximum cost in tariff currency
maxEnergy number Maximum energy in Wh
maxTime integer Maximum duration in seconds
maxSoC integer (0-100) Maximum State of Charge percentage

3.5 TransactionType (inside TransactionEventRequest)

New fields added in 2.1:

Field Type Description
operationMode OperationModeEnumType Current operation mode of the transaction
transactionLimit TransactionLimitType Echoed-back transaction limit from CSMS (confirms CS received and applied the limit)

3.6 TransactionEventRequest (CS → CSMS)

New top-level fields added in 2.1:

Field Type Description
costDetails CostDetailsType Cost breakdown calculated by CS
preconditioningStatus enum Preconditioning status
evseSleep boolean Whether EVSE is in sleep mode

3.7 ReasonEnumType (stoppedReason) — New Values

Value Description Used By
EnergyLimitReached Energy limit from transactionLimit.maxEnergy was reached F07
TimeLimitReached Time limit from transactionLimit.maxTime was reached F07
SOCLimitReached SoC limit from transactionLimit.maxSoC was reached F07
LocalOutOfCredit Local cost limit from transactionLimit.maxCost was reached F07

3.8 ChargingProfileType / ChargingSchedulePeriod

Change 2.0.1 2.1 Action
chargingProfileKind values Absolute, Recurring, Relative Absolute, Recurring, Relative, Dynamic Support new Dynamic profile kind
ChargingSchedulePeriod.limit Required Conditional Field may be absent in some scenarios
ChargingSchedulePeriod.phaseToUse Not present integer (1-3) New field to specify a specific phase; only valid when numberPhases=1

4. Use Case Changes (F01–F06)

4.1 F01 — Remote Start Transaction: Cable Plugin First

Aspect 2.0.1 2.1 Impact
Connector state notification CS sends StatusNotificationRequest (Occupied) CS sends NotifyEventRequest Replace message handler (see Section 2)
Sequence flow StatusNotification before TransactionEvent NotifyEvent before TransactionEvent Same logical flow, different message type
Charging profile Dynamic kind Not supported Supported Accept Dynamic as valid chargingProfileKind

No breaking changes to RequestStartTransactionRequest or RequestStartTransactionResponse schemas. The message structure is the same; only the supporting event notifications changed.

4.2 F02 — Remote Start Transaction: Remote Start First

Aspect 2.0.1 2.1 Impact
Connector state notification CS sends StatusNotificationRequest (Occupied) when cable plugged in CS sends NotifyEventRequest when cable plugged in Replace message handler (see Section 2)
Sequence detail Less detailed — fewer intermediate events shown More detailed — explicit NotifyEvent + multiple TransactionEventRequest updates shown No code change, but more events to expect

No breaking changes to the core remote start flow. Same RequestStartTransactionRequest/RequestStartTransactionResponse messages.

4.3 F03 — Remote Stop Transaction Changed

Aspect 2.0.1 2.1 Impact
Stop flow Single TransactionEventRequest(Ended) after stop Two-phase: first Updated (energy stopped, chargingState=EVConnected), then Ended (cable unplugged) Handle the additional Updated event with triggerReason=RemoteStop before the Ended event
Cable unplug notification Not shown CS sends NotifyEventRequest after EV unplugs Handle NotifyEventRequest between Updated and Ended
TxStopPoint impact Not documented Documented: behavior differs based on TxStopPoint configuration Implement awareness of TxStopPoint configuration
Unknown transactionId rule F03.FR.06 F03.FR.08 Renumbered only, no behavioral change

TxStopPoint behavior (new in 2.1 documentation)

TxStopPoint 2.1 Behavior
Does NOT contain Authorized or PowerPathClosed (e.g. EVConnected) CS stops energy, sends Updated(RemoteStop). Transaction does NOT end until EV disconnects.
Contains Authorized or PowerPathClosed CS sends Ended(RemoteStop, Remote) immediately.

CSMS Migration Action

Update your remote stop handler to expect an Updated event with triggerReason=RemoteStop and chargingState=EVConnected before the final Ended event, rather than receiving a single Ended event.

4.4 F04 — Remote Stop ISO 15118 Charging from CSMS

Aspect 2.0.1 2.1 Impact
ISO 15118-20 Not mentioned Explicitly supports ISO 15118-20 (EVSENotification = Terminate via AC_ChargeLoopRes / DC_ChargeLoopRes) No CSMS code change needed (CS-internal detail), but good to be aware of

No CSMS-visible changes. F04 remains identical to F03 from the CSMS perspective.

4.5 F05 — Remotely Unlock Connector Changed

Aspect 2.0.1 2.1 Impact
evseId / connectorId range Implicit integer > 0 Explicit integer >= 0 Allow 0 values in validation
Scope clarification Not specified "ONLY for unlocking the cable retention lock on the connector, NOT for unlocking a connector access door" Document and enforce usage limitation in your API/UI
No lock mechanism Not specified CS SHOULD respond with CALLERROR NotSupported Handle NotSupported CALLERROR in addition to the four status values
Unlock without cable Not specified CS will attempt unlock even if no cable is connected No code change, but be aware of this behavior
Sequence with active transaction Two sequences shown (with/without ongoing unauthorized transaction; CS auto-stops) Single simplified sequence; CSMS expected to stop transaction first Update workflow: always stop the transaction via F03 before sending UnlockConnectorRequest

CSMS Migration Action

Add error handling for CALLERROR NotSupported response. Update validation to allow evseId >= 0 and connectorId >= 0.

4.6 F06 — Trigger Message Extended

Aspect 2.0.1 2.1 Impact
customTrigger field Not present New field: string (max 50) Add support for custom trigger names
CustomTrigger enum value Not present New requestedMessage value Implement custom trigger functionality; check CS's CustomizationCtrlr.CustomTriggers for supported values
SignV2G20Certificate enum value Not present New requestedMessage value for ISO 15118-20 Add to trigger enum handling
BootNotification trigger restriction No restriction documented CS MUST reject if last BootNotification was already Accepted (F06.FR.17) Expect Rejected when triggering BootNotification on an already-accepted CS
evse field behavior Optional If absent, interpreted as "all EVSEs" (F06.FR.11) Be explicit with evse field when you want a specific EVSE, omit for all
StatusNotification connectorId Not explicitly required CSMS MUST set connectorId in evse field (F06.FR.13) Always include connectorId when triggering StatusNotification
MeterValues measurands Not specified Returns measurands from AlignedDataMeasurands configuration Be aware of which measurands to expect based on CS configuration
TransactionEvent trigger triggerReason not specified Triggered message will have triggerReason = "Trigger" Handle Trigger as a valid triggerReason value
Triggered message fulfillment Not specified If the same message arrives normally between acceptance and triggered send, it MAY count as fulfilling the trigger (F06.FR.10) Don't assume the next message of that type is always the triggered one

MessageTriggerEnumType — Full Comparison

Value 2.0.1 2.1 Notes
BootNotification Yes Yes 2.1 adds rejection rule (F06.FR.17)
LogStatusNotification Yes Yes No change
FirmwareStatusNotification Yes Yes No change
Heartbeat Yes Yes No change
MeterValues Yes Yes 2.1 specifies AlignedDataMeasurands
SignChargingStationCertificate Yes Yes No change
SignV2GCertificate Yes Yes No change
SignV2G20Certificate No Yes New — ISO 15118-20
StatusNotification Yes Yes 2.1 adds connectorId requirement
TransactionEvent Yes Yes 2.1 specifies triggerReason=Trigger
SignCombinedCertificate Yes Yes No change
PublishFirmwareStatusNotification Yes Yes No change
CustomTrigger No Yes New — requires customTrigger field

5. New Use Case: F07 — Remote Start with Fixed Cost, Energy, SoC or Time

New in 2.1

Overview

F07 is a new use case in OCPP 2.1 that enables the CSMS to set transaction limits (cost, energy, SoC, or time) during a remote start. When a limit is reached, the CS automatically suspends energy transfer.

Use cases: Prepaid balance, ad-hoc payment reservation amounts, energy/time-limited sessions.

Mechanism

F07 does not introduce any new request/response messages. Instead, it leverages the existing RequestStartTransactionRequest (same as F01/F02) combined with the new transactionLimit field in TransactionEventResponse.

Flow

  1. CSMS sends RequestStartTransactionRequest (identical to F01/F02)
  2. CS sends TransactionEventRequest with eventType=Started
  3. CSMS responds with TransactionEventResponse that includes transactionLimit
  4. CS echoes back the limit in the next TransactionEventRequest via transactionInfo.transactionLimit (confirming receipt)
  5. When limit is reached, CS sends TransactionEventRequest with chargingState=SuspendedEVSE

TransactionLimit in TransactionEventResponse

JSON — TransactionEventResponse with transactionLimit
{
  "transactionLimit": {
    "maxCost": 25.00,
    "maxEnergy": 20000,
    "maxTime": 3600,
    "maxSoC": 80
  }
}
Field Type Description
maxCost number Maximum cost in tariff currency. CS must calculate cost locally.
maxEnergy number Maximum energy in Wh
maxTime integer Maximum duration in seconds (start to end)
maxSoC integer (0-100) Maximum State of Charge percentage

Rules

  • At least one limit should be provided
  • If multiple limits are given, whichever is reached first stops energy transfer
  • The CS echoes back the limits in transactionInfo.transactionLimit to confirm receipt

New stoppedReason Values for F07

When a transaction ends because a limit was reached, the stoppedReason in TransactionEventRequest will use one of these new values:

stoppedReason Limit
EnergyLimitReached maxEnergy reached
TimeLimitReached maxTime reached
SOCLimitReached maxSoC reached
LocalOutOfCredit maxCost reached

Implementation Requirements

  • Add transactionLimit field support to your TransactionEventResponse builder
  • Track which transactions have limits and verify the CS echoes them back
  • Handle the new stoppedReason values (EnergyLimitReached, TimeLimitReached, SOCLimitReached, LocalOutOfCredit)
  • Handle chargingState=SuspendedEVSE as an indicator that a limit was reached

6. Migration Checklist

Message Handler Updates Breaking / Behavioral

F01/F02/F03

Replace StatusNotificationRequest handler with NotifyEventRequest handler for connector state changes.

F05

Handle CALLERROR NotSupported from UnlockConnectorRequest (CS has no lock mechanism).

F03

Handle two-phase remote stop: expect Updated(RemoteStop) before Ended(Remote).

F06

Update TriggerMessageRequest builder to support customTrigger field.

F06

Handle Rejected response when triggering BootNotification on already-accepted CS (F06.FR.17).

Schema Validation Updates Validation

IdTokenType.idToken max length: 36 → 255.

IdTokenType.type: closed enum → string (max 20); accept OCPP2WhiteList and unknown values.

StatusInfoType.additionalInfo max length: 512 → 1024.

EVSEType.id: allow >= 0 (was > 0).

EVSEType.connectorId: allow >= 0.

UnlockConnectorRequest.evseId / connectorId: allow >= 0.

ChargingSchedulePeriod.limit: required → conditional.

New Fields to Support New

TransactionEventResponse.transactionLimit (TransactionLimitType) — for F07.

TransactionEventResponse.updatedPersonalMessageExtra (MessageContentType[]).

TransactionType.operationMode (OperationModeEnumType).

TransactionType.transactionLimit (TransactionLimitType) — echo-back from CS.

TransactionEventRequest.costDetails (CostDetailsType).

TransactionEventRequest.preconditioningStatus.

TransactionEventRequest.evseSleep.

ChargingSchedulePeriod.phaseToUse (integer 1-3).

New Enum Values Enum

MessageTriggerEnumType: add CustomTrigger, SignV2G20Certificate.

ChargingProfileKindEnumType: add Dynamic.

ReasonEnumType (stoppedReason): add EnergyLimitReached, TimeLimitReached, SOCLimitReached, LocalOutOfCredit.

New Use Case Implementation F07

F07

Implement transactionLimit in TransactionEventResponse for limit-based remote starts.

F07

Verify CS echoes back limits in transactionInfo.transactionLimit.

F07

Handle chargingState=SuspendedEVSE when limits are reached.

F07

Handle new stoppedReason values for limit-reached scenarios.

Behavioral Changes Behavioral

F05

Update unlock workflow — always stop transaction via F03 before sending UnlockConnectorRequest.

F06

Always include connectorId in evse when triggering StatusNotification (F06.FR.13).

F06

Be aware that BootNotification trigger will be rejected on already-accepted CS (F06.FR.17).

F06

Handle triggerReason = "Trigger" in triggered TransactionEventRequest messages.

OCPP 2.1 Remote Control Section Migration Guide — Use Cases F01–F07 — CSMS Developer Perspective