Purpose: Practical reference for AI agents implementing or debugging the message flows that are new or changed in OCPP 2.1. Each flow is a numbered step table (
Step | Sender → Receiver | Message | Trigger/Notes). Concepts and field-level schemas live in the linked companion docs; this document is the flow ordering.Last updated: 2026-06-11
#How This Document Was Produced
This document covers the OCPP 2.1 sequence flows that are new or changed versus 2.0.1. Its dominant confidence tier is spec-knowledge — message ordering and triggers summarized in original wording from the OCPP 2.1 Edition 2 Part 2 specification (blocks K Smart Charging, R DER Control, Q Bidirectional, S Battery Swap, N Diagnostics). All message names, field names, and enum values are schema-derived — cross-referenced against the mechanically generated SmartCharging, DERControl, BatterySwap, TariffAndCost, RemoteControl, and Diagnostics schema docs, plus the Data Types reference. No spec prose is reproduced verbatim (OCA is CC BY-ND); all text is original.
This document contains 0 escalation points; the policy decisions touching these flows (e.g. push vs. pull dynamic-schedule updates) are flagged with > **ESCALATE:** markers in the companion SmartCharging and DER docs and only cross-referenced here. See METHODOLOGY.md for the confidence and escalation model.
Companion documents:
- OCPP 2.1 Smart Charging deltas — concepts for dynamic schedules, priority charging, battery swap, periodic event streams.
- OCPP 2.1 DER Control — DER control/curve model used in §1.
- OCPP 2.1 Bidirectional / V2X — operation modes and setpoints used in §2.
- OCPP 2.1 Tariff & Cost — web-payment and tariff context for §4.
- OCPP 2.1 Transactions schema —
TransactionEventmessage reference for §4. - Schema docs linked inline for every message.
#1. DER Control Setup
The CSMS configures Distributed Energy Resource (DER) controls on the CS and reads back the result. Full control/curve model and enum values are in the DER Control deep-dive.
| Step | Sender → Receiver | Message | Trigger/Notes |
|---|---|---|---|
| 1 | CSMS → CS | GetDERControl |
(Optional) CSMS reads which DER controls/curves the CS currently has, to plan changes. |
| 2 | CS → CSMS | ReportDERControl |
CS reports the requested DER control settings (may be multiple, paginated by request id). |
| 3 | CSMS → CS | SetDERControl |
CSMS installs or updates a DER control (e.g. a volt-watt or freq-watt curve). CS replies with the set status. |
| 4 | CSMS → CS | ClearDERControl |
(Optional) CSMS removes DER controls by id/type when no longer needed. |
| 5 | CS → CSMS | NotifyDERAlarm |
(Async, if applicable) CS reports a DER-related alarm condition. |
| 6 | CS → CSMS | NotifyDERStartStop |
(Async, if applicable) CS reports that a DER control started or stopped acting. |
#2. Dynamic Schedule Update Loop
A dynamic charging profile is installed once, then its setpoints/limits are updated repeatedly without re-installing. Concept and fields are in the Smart Charging deltas §2; operation-mode/setpoint semantics in the V2X doc.
| Step | Sender → Receiver | Message | Trigger/Notes |
|---|---|---|---|
| 1 | CSMS → CS | SetChargingProfile |
CSMS installs a profile with chargingProfileKind = Dynamic (ChargingProfileKindEnumType). May set dynUpdateInterval to request CS pulls. |
| 2 | — | (charging proceeds) | CS follows the current setpoint / limit / dischargeLimit of the dynamic schedule periods. |
| 3a | CSMS → CS | UpdateDynamicSchedule |
Push path. CSMS sends chargingProfileId + scheduleUpdate (ChargingScheduleUpdateType) with new setpoints/limits. CS replies status = ChargingProfileStatusEnumType. |
| 3b | CS → CSMS | PullDynamicScheduleUpdate |
Pull path. On dynUpdateInterval (or its own logic) the CS sends chargingProfileId; CSMS returns status and optional scheduleUpdate in the response. |
| 4 | — | (apply update) | CS applies the new values; dynUpdateTime on the profile reflects the moment of update. Loop returns to step 2. |
| 5 | CSMS → CS | GetCompositeSchedule |
(Optional) CSMS verifies the effective merged schedule after updates. |
Steps 3a and 3b are alternatives selected per deployment, not both required. Which is used is a policy decision — see the ESCALATE note in Smart Charging deltas §2.3.
#3. Battery Swap
Coordinates a physical battery exchange. Concept and fields are in the Smart Charging deltas §4 and the BatterySwap schema doc.
| Step | Sender → Receiver | Message | Trigger/Notes |
|---|---|---|---|
| 1 | CSMS → CS | RequestBatterySwap |
(Optional initiator) CSMS asks the station to begin a swap for idToken, assigning a requestId. CS replies status = GenericStatusEnumType. |
| 2 | CS → CSMS | BatterySwap |
eventType = BatteryIn (BatterySwapEventEnumType): the driver's depleted pack has been inserted into the station slot. batteryData[] carries evseId (slot), serialNumber, soC, soH; CS assigns the requestId. |
| 3 | — | (charged pack offered) | Station presents/charges a charged pack for the driver to collect from the slot. |
| 4 | CS → CSMS | BatterySwap |
eventType = BatteryOut: the charged pack has been taken out of the station slot by the driver. batteryData[] (incl. serialNumber, soC, soH) describes the collected pack; same requestId as the BatteryIn. |
| 5 | CS → CSMS | BatterySwap |
(Error path) If the charged pack offered after BatteryIn is not collected within BatterySwapOutTimeout, CS reports eventType = BatteryOutTimeout with the same requestId (otherwise CSMS is left with an orphan BatteryIn). |
Event names follow the station-slot perspective: BatteryIn = a battery placed into a slot, BatteryOut = a battery removed from a slot. The spec default order is In-Out (depleted battery in first, charged battery out second); a station using the reverse order reports BatterySwapCtrlr.SwapOrder = Out-In. A CS-initiated swap (no RequestBatterySwap) simply starts at step 2; the requestId then correlates the BatteryIn/BatteryOut pair.
#4. Web-Payment Start
A driver pays via a web flow (e.g. scanning a QR code) and the transaction is started remotely. Tariff/cost context is in the Tariff & Cost doc.
| Step | Sender → Receiver | Message | Trigger/Notes |
|---|---|---|---|
| 1 | CSMS → CS | NotifyWebPaymentStarted |
CSMS tells the CS a web-payment flow has begun for evseId, with a timeout (seconds) after which no result is expected. CS may display "payment in progress". |
| 2 | — | (driver completes payment) | Web/QR payment authorized out-of-band; CSMS receives confirmation from the payment back-end. |
| 3 | CSMS → CS | RequestStartTransaction |
On successful payment within timeout, CSMS remotely starts the transaction on that EVSE. CS replies with the start status. |
| 4 | CS → CSMS | TransactionEvent |
CS reports the transaction Started event as usual. |
| — | — | (timeout path) | If no payment confirmation arrives before timeout, the CSMS does not send RequestStartTransaction; the CS clears the "payment in progress" state. |
#5. Periodic Event Stream Lifecycle
Efficient high-rate telemetry. Concept and the five messages are in the Smart Charging deltas §5 and the Diagnostics schema doc.
| Step | Sender → Receiver | Message | Trigger/Notes |
|---|---|---|---|
| 1 | CS → CSMS | OpenPeriodicEventStream |
CS opens a stream with constantStreamData (ConstantStreamDataType): stream id, variableMonitoringId, and params (PeriodicEventStreamParamsType: interval, values). CSMS replies Accepted/Rejected. |
| 2 | CS → CSMS | NotifyPeriodicEventStream |
One-way SEND, repeated. CS pushes a batch: basetime, data[] (StreamDataElementType: offset t, value v), stream id, pending count. No response. |
| 3 | CSMS → CS | GetPeriodicEventStream |
(Optional) CSMS asks the CS for the list of configured streams (constantStreamData[]). |
| 4 | CSMS → CS | AdjustPeriodicEventStream |
(Optional) CSMS re-paces a stream by id with new params. CS replies Accepted/Rejected; subsequent batches follow the new rate. |
| 5 | CS → CSMS | ClosePeriodicEventStream |
CS closes the stream by id when the monitored situation ends. No further NotifyPeriodicEventStream for that id. |