OCPP 2.1 Edition 2 Section F

Remote Control Flows - CSMS Developer Guide

Based on OCPP 2.1 Edition 2 Specification (Part 2), Section F (Remote Control). This guide covers all remote control flows (F01–F07), including remote start/stop transactions, unlock connector, trigger messages, and transaction limits from the CSMS perspective using OCPP-J (JSON over WebSocket).

10 Sections
7 Use Cases
F01 – F07

1. Overview

Introduction

The Remote Control functional block covers three categories of CSMS-initiated operations. These allow the CSMS to remotely start and stop charging transactions, unlock connectors, and trigger specific messages from Charging Stations.

Remote Transaction Control

F01 — Cable Plugin First

Remote start when the cable is already plugged in. CSMS sends RequestStartTransactionRequest after the CS reports a cable connection.

F02 — Remote Start First

Remote start sent before the cable is plugged in. The CS creates a transaction and waits for the EV driver to connect within EVConnectionTimeOut.

F03 — Remote Stop

Stop an active transaction remotely via RequestStopTransactionRequest. The CS stops energy transfer and ends the transaction.

F07 — Start with Limits

Remote start with fixed cost, energy, SoC, or time limits. The CSMS includes transactionLimit in the TransactionEventResponse.

Unlock Connector

F05 — Remotely Unlock Connector

Remotely unlock a connector to help EV drivers unplug cables. CSMS sends UnlockConnectorRequest. Only unlocks the cable retention lock, NOT connector access doors.

Remote Trigger

F06 — Trigger Message

Request a Charging Station to send a specific CS-initiated message on demand via TriggerMessageRequest. Supports triggering heartbeats, meter values, status notifications, transaction events, and more.

Message Direction Summary

Flow CSMS Sends (to CS) CSMS Receives (from CS)
F01/F02 RequestStartTransactionRequest RequestStartTransactionResponse
F01/F02 TransactionEventRequest (multiple)
F01/F02 TransactionEventResponse
F03/F04 RequestStopTransactionRequest RequestStopTransactionResponse
F03/F04 TransactionEventRequest (multiple)
F03/F04 TransactionEventResponse
F05 UnlockConnectorRequest UnlockConnectorResponse
F06 TriggerMessageRequest TriggerMessageResponse
F07 RequestStartTransactionRequest RequestStartTransactionResponse
F07 TransactionEventResponse (with limits) TransactionEventRequest

2. Common Data Types & Schemas

Reference

IdTokenType

IdTokenType Schema
{
  "idToken": "string (max 255, case-insensitive)",
  "type": "string (max 20)",
  "additionalInfo": [
    {
      "additionalIdToken": "string (max 255)",
      "type": "string (max 50)"
    }
  ]
}

Common type values (IdTokenEnumStringType):

Type Description
Central Server-generated token for CSMS-initiated transactions. CS will skip local authorization.
eMAID Electro-Mobility Account Identifier (ISO 15118 Plug & Charge)
ISO14443 RFID UID per ISO 14443 (most common physical RFID)
ISO15693 RFID UID per ISO 15693
KeyCode PIN-code entered by user
Local Locally generated identifier (e.g., parking ticket)
MacAddress MAC address based identifier
NoAuthorization No authorization needed — anyone can stop the transaction if CS supports local stop
OCPP2WhiteList OCPP 2.0 whitelist token

StatusInfoType

StatusInfoType Schema
{
  "reasonCode": "string (max 20, case-insensitive, REQUIRED)",
  "additionalInfo": "string (max 1024)"
}

EVSEType

EVSEType Schema
{
  "id": "integer (>= 0, REQUIRED)",
  "connectorId": "integer (>= 0)"
}

ChargingProfileType (for RequestStartTransaction)

When including a ChargingProfile in RequestStartTransactionRequest:

ChargingProfileType Schema
{
  "id": 1,
  "stackLevel": 0,
  "chargingProfilePurpose": "TxProfile",
  "chargingProfileKind": "Relative",
  "chargingSchedule": [
    {
      "id": 1,
      "chargingRateUnit": "W",
      "chargingSchedulePeriod": [
        {
          "startPeriod": 0,
          "limit": 11000,
          "numberPhases": 3
        }
      ]
    }
  ]
}

Constraints for Remote Start:

  • chargingProfilePurpose MUST be "TxProfile"
  • transactionId MUST NOT be set (unknown at request time)
  • chargingProfileKind: "Absolute", "Recurring", "Relative", or "Dynamic"
  • chargingRateUnit: "W" (Watts) or "A" (Amps)
Field Type Required Description
startPeriod integer Yes Start in seconds from schedule start
limit number Conditional Charging rate limit in the applicable unit
numberPhases integer (0-3) No Number of phases. Default 3 for AC, omit for DC.
phaseToUse integer (1-3) No Specific phase, only when numberPhases=1

TransactionEventRequest Key Fields (Incoming to CSMS)

Direction: Charging Station → CSMS

Field Type Required Description
eventType enum Yes "Started", "Updated", or "Ended"
timestamp dateTime Yes When the event occurred
triggerReason TriggerReasonEnum Yes Why the event was triggered
seqNo integer (>= 0) Yes Sequence number for ordering
transactionInfo TransactionType Yes Transaction details
meterValue MeterValueType[] No Meter readings
evse EVSEType No EVSE where transaction is happening
idToken IdTokenType No The token associated with the transaction
offline boolean No true if event occurred while CS was offline. Default: false
numberOfPhasesUsed integer (0-3) No Phases used
cableMaxCurrent integer No Max current of connected cable in Amps
reservationId integer No Reservation ID if transaction ends a reservation
costDetails CostDetailsType No Cost breakdown calculated by CS

TransactionType (inside TransactionEventRequest)

Field Type Required Description
transactionId string (max 36) Yes Unique transaction identifier
chargingState enum No "EVConnected", "Charging", "SuspendedEV", "SuspendedEVSE", "Idle"
timeSpentCharging integer No Seconds of actual energy transfer
stoppedReason ReasonEnumType No Why the transaction stopped (only on Ended)
remoteStartId integer No Matches the remoteStartId from RequestStartTransactionRequest
operationMode OperationModeEnum No Current operation mode
transactionLimit TransactionLimitType No Echoed-back transaction limit from CSMS

TriggerReasonEnumType Values (Relevant to Remote Control)

Value When Used
RemoteStart Transaction event triggered by a RequestStartTransactionRequest
RemoteStop Energy transfer stopped by RequestStopTransactionRequest
Trigger Message triggered by TriggerMessageRequest
CablePluggedIn Cable was plugged in
ChargingStateChanged Charging state changed
EVConnectTimeout EV didn't connect within timeout (F02)
Authorized Authorization was obtained
Deauthorized Authorization was revoked

ReasonEnumType (stoppedReason) Values

Value When Used
Remote Transaction stopped by CSMS via RequestStopTransactionRequest
Timeout EV connection timeout (F02 scenario)
DeAuthorized CSMS revoked authorization
Local Local stop by user
EnergyLimitReached Energy limit from transactionLimit reached (F07)
TimeLimitReached Time limit reached (F07)
SOCLimitReached SoC limit reached (F07)
LocalOutOfCredit Local cost limit reached (F07)

3. F01 — Remote Start Transaction (Cable Plugin First)

CSMS-Initiated
Use Case ID F01
Direction CSMS → CS (CSMS initiates)
Trigger External trigger (e.g. mobile app, CSO operator panel, EV Driver app)
Precondition Charging cable is already plugged in at the Charging Station
OCPP Messages RequestStartTransactionRequest / RequestStartTransactionResponse, TransactionEventRequest / TransactionEventResponse

Sequence Flow (CSMS Perspective)

Sequence Diagram — F01 Cable Plugin First
EV Driver              Charging Station                    CSMS
    |                        |                               |
    |--- Plugin cable ------>|                               |
    |                        |-- NotifyEventRequest -------->|  (1)
    |                        |<- NotifyEventResponse --------|  (2)
    |                        |-- TransactionEventRequest --->|  (3) eventType=Started
    |                        |<- TransactionEventResponse ---|  (4)
    |                        |                               |
    |                        |                    remote start trigger
    |                        |<- RequestStartTransactionReq -|  (5) CSMS SENDS
    |                        |-- RequestStartTransactionRes->|  (6) CSMS RECEIVES
    |                        |                               |
    |                        |                     Match remoteStartId
    |                        |                     with transactionId
    |                        |                               |
    |                        |-- TransactionEventRequest --->|  (7) eventType=Updated,
    |                        |<- TransactionEventResponse ---|  (8) chargingState=Charging

Step-by-Step CSMS Implementation

Step 1: Handle incoming NotifyEventRequest

The Charging Station notifies that a connector became Occupied (cable plugged in).

CSMS Action: Respond with NotifyEventResponse (empty acknowledgment). Track the connector state internally.

Step 2: Handle incoming TransactionEventRequest (eventType = Started)

The Charging Station reports a new transaction has started (even before driver is known).

Incoming payload key fields:

eventType "Started"
triggerReason "CablePluggedIn"
transactionInfo.transactionId The CS-generated transaction ID (string, max 36 chars)
transactionInfo.chargingState "EVConnected"
evse.id EVSE identifier
evse.connectorId Connector identifier

CSMS Action: Respond with TransactionEventResponse. Store the transactionId for later matching.

Step 3: Send RequestStartTransactionRequest

When an external trigger initiates a remote start, the CSMS sends this message to the Charging Station.

RequestStartTransactionRequest (CSMS → CS)
{
  "remoteStartId": 123,
  "idToken": {
    "idToken": "ABCD1234",
    "type": "ISO14443"
  },
  "evseId": 1,
  "groupIdToken": { ... },
  "chargingProfile": { ... }
}
Field Type Required Description
remoteStartId integer Yes Unique ID assigned by CSMS. Used to correlate with subsequent TransactionEventRequest messages.
idToken IdTokenType Yes The token to use for this transaction.
evseId integer (>= 1) No Target EVSE. If omitted, the Charging Station selects one.
groupIdToken IdTokenType No Group token for group reservation matching.
chargingProfile ChargingProfileType No Optional charging profile for smart charging. chargingProfilePurpose MUST be TxProfile and transactionId MUST NOT be set.

Important Rules for CSMS

  • idToken.type = "NoAuthorization" is allowed — but anyone can stop the transaction if CS supports local stop
  • idToken.type = "Central" is allowed — CS will skip local authorization
  • When AuthorizeRemoteStart = false OR idToken.type is Central or NoAuthorization, the CS will start without checking authorization
  • If a chargingProfile is included, chargingProfilePurpose MUST be "TxProfile"
  • transactionId in the ChargingProfile MUST NOT be set (the CS doesn't know it yet)

Step 5: Handle subsequent TransactionEventRequest messages

After accepting the remote start, the CS will send TransactionEventRequest with:

  • triggerReason: "RemoteStart"
  • transactionInfo.remoteStartId: matching the remoteStartId you sent
  • eventType: "Updated"
  • transactionInfo.chargingState: "Charging" (when energy transfer begins)

CSMS Action: Match remoteStartId to correlate this transaction event with your original request. Respond with TransactionEventResponse.

Step 6: Handle AuthorizeRequest (if AuthorizeRemoteStart = true)

If the CS is configured with AuthorizeRemoteStart = true, it will send an AuthorizeRequest with the idToken you provided.

CSMS Action: Validate the token and respond with AuthorizeResponse containing idTokenInfo.status = "Accepted" (or reject).

Handle RequestStartTransactionResponse

RequestStartTransactionResponse (CS → CSMS)
{
  "status": "Accepted",
  "transactionId": "AB1234",
  "statusInfo": {
    "reasonCode": "...",
    "additionalInfo": "..."
  }
}
Field Type Required Description
status enum Yes "Accepted" or "Rejected"
transactionId string (max 36) No Present when a transaction was already started before this request (cable-plugin-first scenario).
statusInfo StatusInfoType No Additional info about rejection.
CSMS Handling Logic
IF status == "Accepted":
    IF transactionId is present:
        // Cable was plugged in first - transaction already exists
        // Match this remoteStartId with the returned transactionId
        store_mapping(remoteStartId, transactionId)
    ELSE:
        // Wait for TransactionEventRequest(Started) with this remoteStartId
        mark_pending(remoteStartId)

IF status == "Rejected":
    // Start was rejected
    IF statusInfo.reasonCode == "InvalidProfile":
        log("ChargingProfile was invalid")
    ELSE IF statusInfo.reasonCode == "InvalidSchedule":
        log("ChargingSchedule was invalid")
    notify_external_trigger(FAILED)

Rejection Reasons (per requirements)

  • EVSE reserved for a different idToken (F01.FR.21, F01.FR.22)
  • EVSE is Unavailable or Faulted (F01.FR.23)
  • EVSE is Occupied with an authorized transaction (F01.FR.24)
  • Invalid ChargingProfile on a smart-charging-capable CS (F01.FR.26) — reasonCode = "InvalidProfile" or "InvalidSchedule"

TransactionEventResponse Schema (CSMS sends)

All fields are optional. The CSMS responds to every TransactionEventRequest:

TransactionEventResponse (CSMS → CS)
{
  "totalCost": 12.50,
  "chargingPriority": 0,
  "idTokenInfo": {
    "status": "Accepted",
    "cacheExpiryDateTime": "2025-12-31T23:59:59Z",
    "chargingPriority": 0,
    "groupIdToken": { ... },
    "language1": "en",
    "evseId": [1, 2],
    "personalMessage": {
      "format": "UTF8",
      "content": "Welcome!"
    }
  },
  "transactionLimit": {
    "maxCost": 50.00,
    "maxEnergy": 30000,
    "maxTime": 7200,
    "maxSoC": 80
  },
  "updatedPersonalMessage": {
    "format": "UTF8",
    "content": "Updated message"
  }
}
Field Type Description
totalCost number Running cost (for Updated) or final cost (for Ended). Send 0.00 to indicate free. Absence does NOT mean free.
chargingPriority integer (-9 to 9) Temporary priority override. Higher = higher priority. Default 0.
idTokenInfo IdTokenInfoType Authorization status of the idToken.
transactionLimit TransactionLimitType Cost/energy/time/SoC limits for the transaction.
updatedPersonalMessage MessageContentType Updated message for display.
IdTokenInfo Status Meaning
Accepted Token is valid, allow charging
Blocked Token is blocked
ConcurrentTx Token already has active transaction
Expired Token has expired
Invalid Token is unknown/invalid
NoCredit No credit remaining
NotAllowedTypeEVSE Token not allowed on this EVSE type
NotAtThisLocation Token not valid at this location
NotAtThisTime Token not valid at this time
Unknown Token status unknown (offline)

4. F02 — Remote Start Transaction (Remote Start First)

CSMS-Initiated
Use Case ID F02
Parent F01 (same RequestStartTransactionRequest message)
Direction CSMS → CS (CSMS initiates)
Trigger External trigger — remote start is sent BEFORE the cable is plugged in
Precondition Charging cable NOT plugged in. Remote start is sent first.

Sequence Flow (CSMS Perspective) — TxStartPoint=Authorized

Sequence Diagram — F02 Remote Start First
External Trigger        CSMS                          Charging Station
    |                     |                                |
    |-- remote start ---->|                                |
    |                     |-- RequestStartTransactionReq ->|  (1) CSMS SENDS
    |                     |<- RequestStartTransactionRes --|  (2) status=Accepted
    |  [opt: notification]|                                |
    |                     |                                |
    |                     |  [opt: AuthorizeRequest if AuthorizeRemoteStart=true]
    |                     |<- AuthorizeRequest ------------|  (3)
    |                     |-- AuthorizeResponse ---------->|  (4)
    |                     |                                |
    |                     |<- TransactionEventRequest -----|  (5) eventType=Started
    |                     |   triggerReason=RemoteStart     |     remoteStartId=123
    |                     |-- TransactionEventResponse --->|  (6)
    |                     |                                |
    |                     |    [alt: within ConnectionTimeOut]
    |                     |    EV Driver plugs in cable     |
    |                     |<- NotifyEventRequest ----------|  (7)
    |                     |-- NotifyEventResponse -------->|  (8)
    |                     |<- TransactionEventRequest -----|  (9) Updated, EVConnected
    |                     |-- TransactionEventResponse --->| (10)
    |                     |<- TransactionEventRequest -----| (11) Updated, Charging
    |                     |-- TransactionEventResponse --->| (12)
    |                     |                                |
    |                     |    [alt: NOT within ConnectionTimeOut]
    |                     |<- TransactionEventRequest -----| (13) Ended, Timeout
    |                     |-- TransactionEventResponse --->| (14)

Key Differences from F01

No Pre-existing Transaction

The RequestStartTransactionResponse will NOT contain a transactionId (since no cable was plugged in yet).

Transaction Starts After Remote Command

The CS creates the transaction upon accepting the RequestStartTransactionRequest.

Connection Timeout

If the EV driver doesn't plug in within EVConnectionTimeOut, the transaction ends with stoppedReason = "Timeout" and triggerReason = "EVConnectTimeout".

Trigger Reason

triggerReason in TransactionEventRequest will be "RemoteStart" (NOT "CablePluggedIn" or "Authorized"), even if TxStartPoint = EVConnected.

CSMS Implementation Details

The RequestStartTransactionRequest payload is identical to F01. The key difference is in how you handle responses:

CSMS Handling Logic — F02
SEND RequestStartTransactionRequest(remoteStartId, idToken, [evseId], [chargingProfile])

ON RequestStartTransactionResponse:
    IF status == "Accepted":
        // Transaction will be created by CS
        // Wait for TransactionEventRequest with remoteStartId matching
        start_timeout_timer(EVConnectionTimeOut)
    IF status == "Rejected":
        handle_rejection()

ON TransactionEventRequest(eventType=Started, remoteStartId=123):
    // Transaction has been created
    store_transaction(transactionInfo.transactionId, remoteStartId)
    // Respond with TransactionEventResponse

ON TransactionEventRequest(eventType=Updated, chargingState=EVConnected):
    // Cable plugged in - charging will start soon
    cancel_timeout_timer()

ON TransactionEventRequest(eventType=Updated, chargingState=Charging):
    // Energy transfer started

ON TransactionEventRequest(eventType=Ended, stoppedReason=Timeout):
    // EV was not connected in time
    clean_up_transaction()

Connection Timeout Behavior

TxStopPoint Configuration Timeout Behavior
Does NOT contain ParkingBayOccupancy CS ends transaction, sends TransactionEventRequest(Ended, stoppedReason=Timeout, triggerReason=EVConnectTimeout)
Contains ParkingBayOccupancy CS deauthorizes transaction, sends TransactionEventRequest(triggerReason=EVConnectionTimeout) — transaction ends normally when driver leaves

Recommendations for Remote Start First

  • It is advised to include evseId to avoid uncertainty about which EVSE is activated (especially for Logic Controllers with many EVSEs)
  • Always track remoteStartId to correlate with subsequent TransactionEventRequest messages
  • Implement a timeout mechanism matching the CS's EVConnectionTimeOut setting

5. F03 — Remote Stop Transaction

CSMS-Initiated
Use Case ID F03
Direction CSMS → CS (CSMS initiates)
Trigger External trigger (e.g. mobile app termination, prepaid credit exceeded, CSO action)
Precondition An active transaction exists
OCPP Messages RequestStopTransactionRequest / RequestStopTransactionResponse, TransactionEventRequest / TransactionEventResponse

Sequence Flow (CSMS Perspective)

Sequence Diagram — F03 Remote Stop
External Trigger        CSMS                          Charging Station
    |                     |                                |
    |-- remote stop ----->|                                |
    |                     |-- RequestStopTransactionReq -->|  (1) CSMS SENDS
    |                     |<- RequestStopTransactionRes ---|  (2) CSMS RECEIVES
    |  [opt: notification]|                                |
    |                     |                                |  stop energy offer
    |                     |                                |  unlock connector
    |                     |                                |
    |                     |<- TransactionEventRequest -----|  (3) Updated,
    |                     |   triggerReason=RemoteStop      |  chargingState=EVConnected
    |                     |-- TransactionEventResponse --->|  (4)
    |                     |                                |
    |  [opt: notification]|                                |
    |                     |                                |  EV Driver unplugs cable
    |                     |<- NotifyEventRequest ----------|  (5)
    |                     |-- NotifyEventResponse -------->|  (6)
    |                     |<- TransactionEventRequest -----|  (7) Ended,
    |                     |   stoppedReason=Remote          |
    |                     |-- TransactionEventResponse --->|  (8)

Sending RequestStopTransactionRequest

Direction: CSMS → Charging Station

RequestStopTransactionRequest (CSMS → CS)
{
  "transactionId": "AB1234-5678-90EF"
}
Field Type Required Max Length Description
transactionId string Yes 36 The ID of the transaction to stop. Must match a currently active transaction on the CS.

Handling RequestStopTransactionResponse

Direction: Charging Station → CSMS

RequestStopTransactionResponse (CS → CSMS)
{
  "status": "Accepted",
  "statusInfo": {
    "reasonCode": "...",
    "additionalInfo": "..."
  }
}
Field Type Required Description
status enum Yes "Accepted" or "Rejected"
statusInfo StatusInfoType No Additional details about rejection
CSMS Handling Logic
IF status == "Accepted":
    // Transaction will be stopped
    // Wait for TransactionEventRequest(eventType=Updated, triggerReason=RemoteStop)
    // Then wait for TransactionEventRequest(eventType=Ended, stoppedReason=Remote)

IF status == "Rejected":
    // TransactionId could not be matched to an active transaction (F03.FR.08)
    log_error("Transaction not found or cannot be stopped")
    notify_external_trigger(FAILED)

Handling Subsequent TransactionEventRequest Messages

After accepting the stop, the CS sends the following events:

Event 1 — Energy Stopped (Updated)

eventType "Updated"
triggerReason "RemoteStop"
transactionInfo.chargingState "EVConnected" (energy stopped, cable still connected)

Event 2 — Transaction Ended (Ended)

eventType "Ended"
stoppedReason "Remote"
meterValue Includes final meter values

CSMS must respond to each TransactionEventRequest with TransactionEventResponse. For the Ended event, include totalCost with the final cost.

TxStopPoint Impact on Behavior

TxStopPoint Effect on Remote Stop
NOT Authorized or PowerPathClosed (e.g. EVConnected) CS stops energy offer, sends Updated with triggerReason=RemoteStop. Transaction does NOT end until EV disconnects.
Authorized or PowerPathClosed CS sends TransactionEventRequest(Ended, triggerReason=RemoteStop, stoppedReason=Remote) immediately.

Meter Data in Final TransactionEventRequest

When the transaction ends, the CS should include final meter values. The CSMS should validate the final meter readings, calculate final cost, and send totalCost in the TransactionEventResponse for the Ended event.

6. F04 — Remote Stop ISO 15118 Charging from CSMS

CSMS-Initiated
Use Case ID F04
Direction CSMS → CS (same as F03)
Trigger Same as F03 — external trigger for remote stop
Difference The Charging Station is using ISO 15118-2 or ISO 15118-20 for communication with the EV

CSMS Implementation

From the CSMS perspective, F04 is identical to F03. The CSMS sends the same RequestStopTransactionRequest and handles the same responses. No additional ISO 15118-specific handling is needed at the CSMS level.

The differences are internal to the Charging Station:

ISO 15118-2

CS sends EVSENotification = StopCharging via ChargingStatusRes (AC) or CurrentDemandRes (DC)

ISO 15118-20

CS sends EVSENotification = Terminate via AC_ChargeLoopRes or DC_ChargeLoopRes

Sequence (CSMS sees the same as F03)

Sequence Diagram — F04 ISO 15118 Remote Stop
CSMS                              Charging Station              EV
  |                                     |                        |
  |-- RequestStopTransactionReq ------->|                        |
  |<- RequestStopTransactionRes(Accepted)|                       |
  |                                     |-- [ISO 15118 stop] -->|
  |                                     |                        |
  |<- TransactionEventReq(Updated) -----|  (energy stopped)      |
  |-- TransactionEventRes ------------>|                        |
  |<- TransactionEventReq(Ended) ------|  (cable unplugged)      |
  |-- TransactionEventRes ------------>|                        |

CSMS Action: Implement exactly as F03. No additional ISO 15118-specific handling is needed at the CSMS level.

7. F05 — Remotely Unlock Connector

CSMS-Initiated
Use Case ID F05
Direction CSMS → CS (CSMS initiates)
Trigger External trigger (e.g. driver reports stuck cable via app, CSO support action)
Precondition No ongoing authorized transaction on the connector. The connector has a lock mechanism.
OCPP Messages UnlockConnectorRequest / UnlockConnectorResponse

Sequence Flow

Sequence Diagram — F05 Unlock Connector
External Trigger        CSMS                          Charging Station
    |                     |                                |
    |-- unlock request -->|                                |
    |                     |-- UnlockConnectorRequest ----->|  (1) CSMS SENDS
    |                     |                                |  [attempts unlock]
    |                     |<- UnlockConnectorResponse -----|  (2) CSMS RECEIVES
    |  [opt: notification]|                                |

Sending UnlockConnectorRequest

Direction: CSMS → Charging Station

UnlockConnectorRequest (CSMS → CS)
{
  "evseId": 1,
  "connectorId": 1
}
Field Type Required Description
evseId integer (>= 0) Yes EVSE identifier
connectorId integer (>= 0) Yes Connector identifier on the EVSE

Note: UnlockConnectorRequest is intended ONLY for unlocking the cable retention lock on the connector, NOT for unlocking a connector access door.

Handling UnlockConnectorResponse

Direction: Charging Station → CSMS

UnlockConnectorResponse (CS → CSMS)
{
  "status": "Unlocked",
  "statusInfo": {
    "reasonCode": "...",
    "additionalInfo": "..."
  }
}
Status Meaning CSMS Action
Unlocked Connector was successfully unlocked Notify trigger that unlock succeeded
UnlockFailed CS attempted but failed to unlock Notify trigger of failure. May suggest manual intervention.
OngoingAuthorizedTransaction Cannot unlock — there's an authorized transaction on this connector The CS will NOT unlock and will NOT stop the transaction. CSMS should stop the transaction first (F03), then retry unlock.
UnknownConnector The specified connector is not known to the CS Check evseId/connectorId values and retry with correct values.

Error Handling

  • If the connector has no lock mechanism or has a manual lock (e.g. Type 1), the CS SHOULD respond with RPC Framework CALLERROR: NotSupported
  • The CS will attempt to unlock even if no cable is connected, and returns the result of the attempt

Implementation Logic

CSMS Unlock Connector Logic
FUNCTION unlock_connector(evseId, connectorId):
    // Check if there's an active authorized transaction
    IF has_active_authorized_transaction(evseId, connectorId):
        // Must stop transaction first
        send RequestStopTransactionRequest(transactionId)
        wait_for_transaction_end()

    send UnlockConnectorRequest(evseId, connectorId)

    ON UnlockConnectorResponse:
        SWITCH status:
            CASE "Unlocked":
                return SUCCESS
            CASE "UnlockFailed":
                return FAILURE("Mechanical unlock failed")
            CASE "OngoingAuthorizedTransaction":
                return FAILURE("Stop transaction first")
            CASE "UnknownConnector":
                return FAILURE("Invalid connector")

8. F06 — Trigger Message

CSMS-Initiated
Use Case ID F06
Direction CSMS → CS (CSMS initiates)
Objective Request a Charging Station to send a specific CS-initiated message on demand
Precondition The Functional Block "Remote Trigger" is installed on the CS
OCPP Messages TriggerMessageRequest / TriggerMessageResponse

Sequence Flow

Sequence Diagram — F06 Trigger Message
CSMS                              Charging Station
  |                                     |
  |-- TriggerMessageRequest ----------->|  (1) CSMS SENDS
  |<- TriggerMessageResponse -----------|  (2) CSMS RECEIVES
  |                                     |
  |<- [Requested Message] --------------|  (3) CS sends the triggered message
  |-- [Response to Requested Message] ->|  (4) CSMS responds normally

Sending TriggerMessageRequest

Direction: CSMS → Charging Station

TriggerMessageRequest (CSMS → CS)
{
  "requestedMessage": "TransactionEvent",
  "evse": {
    "id": 1,
    "connectorId": 1
  },
  "customTrigger": "SomeCustomMessage"
}
Field Type Required Description
requestedMessage MessageTriggerEnumType Yes The type of message to trigger
evse EVSEType No Target EVSE. If absent, interpreted as "all EVSEs".
customTrigger string (max 50) No Custom trigger name. Only used when requestedMessage = "CustomTrigger".

EVSE Field Rules

  • If evse is omitted, the CS interprets it as "all applicable EVSEs" (F06.FR.11)
  • For StatusNotification: CSMS MUST set connectorId in the EVSE field (F06.FR.13) — StatusNotification can only be requested at connector level
  • If the specified evseId is not relevant to the message type, the CS ignores it but still sends the message (F06.FR.03)

requestedMessage Enum Values

Value Triggered Message Notes
BootNotification BootNotificationRequest Only useful when the last BootNotification was NOT yet Accepted (F06.FR.17). CS will reject if already accepted.
LogStatusNotification LogStatusNotificationRequest Returns current upload status: Uploading if uploading, Idle otherwise.
FirmwareStatusNotification FirmwareStatusNotificationRequest Returns Idle if not performing firmware tasks.
Heartbeat HeartbeatRequest Triggers an immediate heartbeat.
MeterValues MeterValuesRequest Returns most recent measurements for measurands in AlignedDataMeasurands.
SignChargingStationCertificate SignCertificateRequest Triggers CSR for Charging Station certificate.
SignV2GCertificate SignCertificateRequest Triggers CSR for V2G certificate (ISO 15118-2).
SignV2G20Certificate SignCertificateRequest Triggers CSR for V2G certificate (ISO 15118-20).
StatusNotification StatusNotificationRequest Must include evse with connectorId. CS MAY reject if evse or connectorId is omitted (F06.FR.12).
TransactionEvent TransactionEventRequest Sends with triggerReason=Trigger, includes transactionInfo, chargingState, and meter values per SampledDataTxUpdatedMeasurands.
SignCombinedCertificate SignCertificateRequest Triggers CSR for combined certificate.
PublishFirmwareStatusNotification PublishFirmwareStatusNotificationRequest Returns current publish firmware status.
CustomTrigger Custom message Requires customTrigger field. Check CS's CustomizationCtrlr.CustomTriggers for supported values.

Handling TriggerMessageResponse

Direction: Charging Station → CSMS

TriggerMessageResponse (CS → CSMS)
{
  "status": "Accepted",
  "statusInfo": {
    "reasonCode": "...",
    "additionalInfo": "..."
  }
}
Status Meaning CSMS Action
Accepted CS will send the requested message Wait for the triggered message to arrive. Note: the CS sends the TriggerMessageResponse FIRST, then the requested message.
Rejected CS refuses to send the message Log and handle. Possible reasons: BootNotification already accepted, StatusNotification without connector, etc.
NotImplemented CS does not support this message type The CS has not implemented this specific message. Do not retry.
CSMS Implementation Logic
FUNCTION trigger_message(requestedMessage, evseId=None, connectorId=None, customTrigger=None):
    request = { "requestedMessage": requestedMessage }

    IF evseId is not None:
        request["evse"] = { "id": evseId }
        IF connectorId is not None:
            request["evse"]["connectorId"] = connectorId

    IF requestedMessage == "StatusNotification":
        // MUST include connectorId
        ASSERT connectorId is not None

    IF requestedMessage == "CustomTrigger":
        ASSERT customTrigger is not None
        request["customTrigger"] = customTrigger

    send TriggerMessageRequest(request)

    ON TriggerMessageResponse:
        IF status == "Accepted":
            // Message will arrive shortly - handle it via normal message handlers
            start_timeout(TRIGGER_RESPONSE_TIMEOUT)
        ELSE IF status == "Rejected":
            log("Trigger rejected")
        ELSE IF status == "NotImplemented":
            log("Message type not supported by this CS")

Handling the Triggered Message

After receiving Accepted, the CSMS should expect the corresponding message via the normal message handler. The triggered messages are handled with the same response logic as when they arrive spontaneously.

Key Notes

  • Triggered messages only provide current information, not historical data (F06.FR.09)
  • If the same message arrives via normal operations between acceptance and the triggered send, it MAY count as fulfilling the trigger (F06.FR.10)
  • For TransactionEvent triggers: the triggerReason will be "Trigger" in the incoming TransactionEventRequest

9. F07 — Remote Start with Fixed Cost, Energy, SoC or Time

CSMS-Initiated New in OCPP 2.1
Use Case ID F07
Direction CSMS → CS (CSMS initiates)
Trigger EV Driver or CSMS specifies a limit (cost, energy, SoC, or time) for the transaction
Use Case Prepaid balance, ad-hoc payment reservation amount, energy/time limits
OCPP Messages RequestStartTransactionRequest / RequestStartTransactionResponse, TransactionEventRequest / TransactionEventResponse (with transactionLimit)

Sequence Flow

Sequence Diagram — F07 Remote Start with Limits
EV Driver               CSMS                          Charging Station
    |                     |                                |
    |-- request start --->|                                |
    |  (with limits)      |                                |
    |                     |-- RequestStartTransactionReq ->|  (1)
    |                     |<- RequestStartTransactionRes --|  (2) Accepted
    |                     |                                |
    |                     |  [opt: AuthorizeRequest/Response]
    |                     |                                |
    |                     |<- TransactionEventReq ---------|  (3) Started, remoteStartId=123
    |                     |-- TransactionEventRes -------->|  (4) WITH transactionLimit
    |                     |                                |
    |                     |<- TransactionEventReq ---------|  (5) Updated,
    |                     |   transactionInfo               |  transactionLimit echoed back
    |                     |-- TransactionEventRes -------->|  (6)
    |                     |                                |
    |                     |     [When limit reached]        |
    |                     |<- TransactionEventReq ---------|  (7) Updated,
    |                     |   chargingState=SuspendedEVSE  |
    |                     |-- TransactionEventRes -------->|  (8)

Transaction Limits

When the CS sends the first TransactionEventRequest with eventType = "Started", the CSMS responds with a TransactionEventResponse that includes the transactionLimit:

TransactionEventResponse with transactionLimit (CSMS → CS)
{
  "transactionLimit": {
    "maxCost": 25.00,
    "maxEnergy": 20000,
    "maxTime": 3600,
    "maxSoC": 80
  }
}
Field Type Required Description
maxCost number No Maximum cost in the currency of the tariff
maxEnergy number No Maximum energy in Wh
maxTime integer No Maximum duration in seconds (start to end)
maxSoC integer (0-100) No Maximum State of Charge percentage

Rules

  • At least one limit should be provided
  • If multiple limits are given (e.g. both maxTime and maxEnergy), whichever is reached first determines the end of energy transfer
  • For maxCost, the CS must calculate cost locally to stop exactly on time

CSMS Implementation

Step 1: Send RequestStartTransactionRequest

Same as F01/F02. The request payload is identical — limits are NOT included in the start request.

Step 2: Include transactionLimit in TransactionEventResponse

When the CS sends the first TransactionEventRequest with eventType = "Started", include the transactionLimit in your response.

Step 3: CS echoes back the limit

The Charging Station will include the limit in the transactionInfo.transactionLimit field of the next TransactionEventRequest, confirming it received and applied the limit.

Step 4: When the limit is reached

The CS stops energy transfer and sends a TransactionEventRequest with chargingState = "SuspendedEVSE".

CSMS Handling Logic — F07
ON TransactionEventRequest(eventType=Started, remoteStartId=matching):
    respond with TransactionEventResponse:
        transactionLimit = {
            maxCost: user_requested_cost_limit,
            maxEnergy: user_requested_energy_limit,
            maxTime: user_requested_time_limit,
            maxSoC: user_requested_soc_limit
        }

ON TransactionEventRequest(transactionInfo.transactionLimit is present):
    // CS confirmed it received the limit
    verify_limit_matches(expected_limit)

ON TransactionEventRequest(chargingState=SuspendedEVSE):
    // Limit was reached - charging suspended
    notify_user("Charging limit reached")

10. Message Schema Quick Reference

Reference

Outgoing from CSMS (CSMS → Charging Station)

Message Required Fields Optional Fields Use Cases
RequestStartTransactionRequest remoteStartId (int), idToken (IdTokenType) evseId (int >=1), groupIdToken (IdTokenType), chargingProfile (ChargingProfileType) F01, F02, F07
RequestStopTransactionRequest transactionId (string max 36) F03, F04
UnlockConnectorRequest evseId (int >=0), connectorId (int >=0) F05
TriggerMessageRequest requestedMessage (MessageTriggerEnumType) evse (EVSEType), customTrigger (string max 50) F06
TransactionEventResponse — (all fields optional) totalCost, chargingPriority, idTokenInfo, transactionLimit, updatedPersonalMessage F01–F07

Incoming to CSMS (Charging Station → CSMS)

Message Required Fields Optional Fields Use Cases
RequestStartTransactionResponse status (Accepted|Rejected) transactionId (string max 36), statusInfo (StatusInfoType) F01, F02, F07
RequestStopTransactionResponse status (Accepted|Rejected) statusInfo (StatusInfoType) F03, F04
UnlockConnectorResponse status (Unlocked|UnlockFailed|OngoingAuthorizedTransaction|UnknownConnector) statusInfo (StatusInfoType) F05
TriggerMessageResponse status (Accepted|Rejected|NotImplemented) statusInfo (StatusInfoType) F06
TransactionEventRequest eventType, timestamp, triggerReason, seqNo, transactionInfo meterValue[], evse, idToken, offline, numberOfPhasesUsed, cableMaxCurrent, reservationId, costDetails F01–F07

OCPP 2.1 Remote Control Flows (F01–F07) - CSMS Developer Guide. Based on OCPP 2.1 Edition 2 Specification (Part 2), Section F.