OCPP 2.0.1 Edition 4 Section P

DataTransfer Flows - CSMS Developer Guide

Based on OCPP 2.0.1 Edition 4 Specification (Part 2, Section P, pages 354-359). This guide covers the DataTransfer functional block for extending OCPP with custom vendor-specific functionality.

5 Sections
2 Use Cases
P01 - P02

1. Introduction

Section P

The DataTransfer functional block enables parties to extend OCPP with custom attributes or add new custom commands not standardized in the protocol. OCPP offers two extension mechanisms for vendor-specific functionality.

Extension Mechanisms

DataTransferRequest Message

Allows exchange of data or messages not standardized in OCPP. It provides a framework for experimental functionality that may find its way into future OCPP versions. It also enables vendor-specific functionality agreed upon between specific CSMS and Charging Station vendors.

CustomData Element

An optional element in all JSON schemas that allows adding custom attributes to any type. CustomData is the only class that allows additional properties. It is NOT meant for standard implementations.

Key Characteristics

The data field in both DataTransferRequest and DataTransferResponse has no specified length or type. It can be any valid JSON value (string, number, object, array, boolean, null).

It is RECOMMENDED that the data format/length is agreed upon by all parties involved.

Important: DataTransfer should be used with extreme caution and only for optional functionality, since it impacts compatibility with other systems that do not implement the same vendor extensions.

OCPP Wire Format Example

The data field can conveniently be used as structured JSON content:

OCPP Wire Format - DataTransferRequest
[2,
"<unique msg id>",
"DataTransfer",
{
  "vendorId": "com.mycompany.ice",
  "messageId": "iceParkedAtCs",
  "data": { "start_time": "2020-04-01T11:01:02" }
}
]

2. DataTransfer Message Schema

Reference

2.1 DataTransferRequest

The DataTransferRequest PDU can be sent either by the CSMS to the Charging Station (P01) or by the Charging Station to the CSMS (P02). The same message structure is used in both directions.

Field Type Required Description
vendorId string[0..255] Yes Identifies the vendor-specific implementation. SHOULD be a reversed DNS namespace (e.g., com.vendor.product).
messageId string[0..50] No May be used to indicate a specific message or implementation within the vendor's namespace.
data anyType No Data without specified length or format. This needs to be decided by both parties (open to implementation). Can be any valid JSON value.

2.2 DataTransferResponse

Field Type Required Description
status DataTransferStatusEnumType Yes Indicates the success or failure of the data transfer.
data anyType No Data without specified length or format, in response to request.
statusInfo StatusInfoType No Detailed status information.

2.3 DataTransferStatusEnumType

Value Description
Accepted Message has been accepted and the contained request is accepted.
Rejected Message has been accepted but the contained request is rejected.
UnknownMessageId Message could not be interpreted due to unknown messageId string.
UnknownVendorId Message could not be interpreted due to unknown vendorId string.

2.4 StatusInfoType

Provides additional information about the response status.

Field Type Required Description
reasonCode string[0..20] Yes A predefined code for the reason why the status is returned. Case-insensitive.
additionalInfo string[0..512] No Additional text to provide detailed information.

3. DataTransfer Flows

Use Cases P01-P02
P01

Data Transfer to the Charging Station

To send information from the CSMS to the Charging Station for a function that is not supported by OCPP.

Actors: Charging Station, CSMS

Scenario:

  1. The CSMS sends information to a Charging Station for a function not supported by OCPP with DataTransferRequest.
  2. The Charging Station responds to the CSMS with DataTransferResponse.
Sequence Diagram
┌──────┐                              ┌──────────────────┐
│ CSMS │                              │ Charging Station │
└──┬───┘                              └────────┬─────────┘
   │                                           │
   │  DataTransferRequest(vendorId,            │
   │    [messageId], [data])                   │
   │──────────────────────────────────────────>│
   │                                           │
   │  DataTransferResponse(status, [data])     │
   │<──────────────────────────────────────────│
   │                                           │

Postconditions:

  • Success: DataTransferRequest is received successfully and Accepted.
  • Failure: Message has been accepted but the contained request is Rejected.
  • In all other cases, the usage of status Accepted or Rejected and the data element is part of the vendor-specific agreement between the parties involved.

CSMS Implementation (Initiator):

The CSMS is the initiator in this flow:

  1. Construct the DataTransferRequest with the appropriate vendorId, optional messageId, and optional data.
  2. Send as OCPP CALL message (message type 2) over the WebSocket to the target Charging Station.
  3. Handle the DataTransferResponse from the Charging Station.
Building the Request
{
  "vendorId": "com.yourcompany.feature",
  "messageId": "specificCommand",
  "data": { ... }
}

Response Handling:

Response Status CSMS Action
Accepted The Charging Station recognized the vendorId/messageId and accepted the request. Process any returned data.
Rejected The Charging Station recognized the vendorId/messageId but rejected the request. Check statusInfo for details.
UnknownVendorId The Charging Station has no implementation for the specified vendorId. The vendor extension is not supported on this station.
UnknownMessageId The Charging Station recognizes the vendorId but not the messageId. The specific sub-command is not supported.

Requirements:

ID Precondition Requirement
P01.FR.01 The CSMS SHALL only use DataTransferRequest for a function which is not supported by OCPP.
P01.FR.02 The vendorId SHOULD be a value from the reversed DNS namespace (e.g., com.vendor.product).
P01.FR.03 The messageId in the request message MAY be used to indicate a specific message or implementation.
P01.FR.04 The length of data in both the request and response message is undefined and it is RECOMMENDED that this is agreed upon by all parties involved.
P01.FR.05 Recipient has no implementation for the specific vendorId. The recipient SHALL return a status UnknownVendorId.
P01.FR.06 Receipt of DataTransferRequest with messageId mismatch. The recipient SHALL return status UnknownMessageId.
P01.FR.07 The usage of status Accepted or Rejected and the data element SHALL be part of the vendor-specific agreement.
P02

Data Transfer to the CSMS

To send information from the Charging Station to the CSMS for a function which is not supported by OCPP.

Actors: Charging Station, CSMS

Scenario:

  1. The Charging Station sends information to the CSMS for a function not supported by OCPP with DataTransferRequest.
  2. The CSMS responds to the Charging Station with DataTransferResponse.
Sequence Diagram
┌──────────────────┐                              ┌──────┐
│ Charging Station │                              │ CSMS │
└────────┬─────────┘                              └──┬───┘
         │                                           │
         │  DataTransferRequest(vendorId,            │
         │    [messageId], [data])                   │
         │──────────────────────────────────────────>│
         │                                           │
         │  DataTransferResponse(status, [data])     │
         │<──────────────────────────────────────────│
         │                                           │

Postconditions:

  • Success: DataTransferRequest is received successfully and Accepted.
  • Failure: Message has been accepted but the contained request is Rejected.
  • In all other cases, the usage of status Accepted or Rejected and the data element is part of the vendor-specific agreement between the parties involved.

CSMS Implementation (Recipient):

The CSMS is the recipient in this flow. This is the primary flow a CSMS developer needs to implement as a message handler.

Inbound Message (OCPP CALL):

The CSMS will receive a CALL message (type 2) with action "DataTransfer" on the WebSocket:

Inbound CALL Message
[2, "<messageId>", "DataTransfer", {
  "vendorId": "com.charger-vendor.feature",
  "messageId": "someCustomMessage",
  "data": { ... }
}]

Handler Logic:

Handler Pseudocode
function handleDataTransferRequest(request: DataTransferRequest) -> DataTransferResponse:

    1. Check if the CSMS has an implementation for request.vendorId
       ├── NO  → return { status: "UnknownVendorId" }
       └── YES → continue

    2. If request.messageId is provided, check if it is recognized
       ├── NO  → return { status: "UnknownMessageId" }
       └── YES → continue

    3. Process the vendor-specific logic based on vendorId + messageId
       ├── Parse request.data according to the vendor-specific agreement
       ├── Execute the custom business logic
       └── Build response data (if applicable)

    4. Return DataTransferResponse
       ├── Success → { status: "Accepted", data: { ... } }
       └── Failure → { status: "Rejected", statusInfo: { reasonCode: "...", additionalInfo: "..." } }

Response Construction:

When vendorId is not recognized
{
  "status": "UnknownVendorId"
}
When messageId is not recognized
{
  "status": "UnknownMessageId"
}
When request is accepted
{
  "status": "Accepted",
  "data": { ... }
}
When request is rejected
{
  "status": "Rejected",
  "statusInfo": {
    "reasonCode": "InvalidData",
    "additionalInfo": "The provided data does not conform to the expected format."
  }
}

Requirements:

ID Precondition Requirement
P02.FR.01 The vendorId in the request message SHOULD be known to the Charging Station and uniquely identify the vendor-specific implementation.
P02.FR.02 The Charging Station SHALL only use DataTransferRequest for a function which is not supported by OCPP.
P02.FR.03 The vendorId SHOULD be a value from the reversed DNS namespace.
P02.FR.04 The messageId in the request message MAY be used to indicate a specific message or implementation.
P02.FR.05 The length of data in both the request and response message is undefined and it is RECOMMENDED that this is agreed upon by all parties involved.
P02.FR.06 Recipient has no implementation for the specific vendorId. The recipient SHALL return a status UnknownVendorId.
P02.FR.07 Receipt of DataTransferRequest with messageId mismatch. The recipient SHALL return status UnknownMessageId.
P02.FR.08 The usage of status Accepted or Rejected and the data element SHALL be part of the vendor-specific agreement.

4. JSON Schema Reference

Schemas

4.1 DataTransferRequest JSON Schema

DataTransferRequest JSON Schema
{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "$id": "urn:OCPP:Cp:2:2020:3:DataTransferRequest",
  "comment": "OCPP 2.0.1 FINAL",
  "definitions": {
    "CustomDataType": {
      "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.",
      "javaType": "CustomData",
      "type": "object",
      "properties": {
        "vendorId": {
          "type": "string",
          "maxLength": 255
        }
      },
      "required": ["vendorId"]
    }
  },
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "customData": {
      "$ref": "#/definitions/CustomDataType"
    },
    "messageId": {
      "description": "May be used to indicate a specific message or implementation.",
      "type": "string",
      "maxLength": 50
    },
    "data": {
      "description": "Data without specified length or format. This needs to be decided by both parties (Open to implementation)."
    },
    "vendorId": {
      "description": "This identifies the Vendor specific implementation.",
      "type": "string",
      "maxLength": 255
    }
  },
  "required": ["vendorId"]
}

Key observations:

  • vendorId is the only required field (max 255 chars).
  • messageId is optional (max 50 chars).
  • data has no type constraint — it accepts any valid JSON value (string, number, boolean, null, object, array).
  • customData is the standard OCPP extension point (separate from vendor DataTransfer logic).
  • additionalProperties: false means no extra top-level fields beyond the defined ones.

4.2 DataTransferResponse JSON Schema

DataTransferResponse JSON Schema
{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "$id": "urn:OCPP:Cp:2:2020:3:DataTransferResponse",
  "comment": "OCPP 2.0.1 FINAL",
  "definitions": {
    "CustomDataType": {
      "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.",
      "javaType": "CustomData",
      "type": "object",
      "properties": {
        "vendorId": {
          "type": "string",
          "maxLength": 255
        }
      },
      "required": ["vendorId"]
    },
    "DataTransferStatusEnumType": {
      "description": "This indicates the success or failure of the data transfer.",
      "javaType": "DataTransferStatusEnum",
      "type": "string",
      "additionalProperties": false,
      "enum": ["Accepted", "Rejected", "UnknownMessageId", "UnknownVendorId"]
    },
    "StatusInfoType": {
      "description": "Element providing more information about the status.",
      "javaType": "StatusInfo",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "customData": {
          "$ref": "#/definitions/CustomDataType"
        },
        "reasonCode": {
          "description": "A predefined code for the reason why the status is returned in this response. The string is case-insensitive.",
          "type": "string",
          "maxLength": 20
        },
        "additionalInfo": {
          "description": "Additional text to provide detailed information.",
          "type": "string",
          "maxLength": 512
        }
      },
      "required": ["reasonCode"]
    }
  },
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "customData": {
      "$ref": "#/definitions/CustomDataType"
    },
    "status": {
      "$ref": "#/definitions/DataTransferStatusEnumType"
    },
    "statusInfo": {
      "$ref": "#/definitions/StatusInfoType"
    },
    "data": {
      "description": "Data without specified length or format, in response to request."
    }
  },
  "required": ["status"]
}

Key observations:

  • status is the only required field (one of the 4 enum values).
  • data has no type constraint — any valid JSON value.
  • statusInfo provides optional detail via reasonCode (required within, max 20 chars) and additionalInfo (optional, max 512 chars).

5. CSMS Implementation Summary

Checklist

Messages the CSMS Sends (Initiator)

Flow Action Message Direction
P01 DataTransfer DataTransferRequest CSMS → Charging Station

Messages the CSMS Receives and Must Handle

Flow Action Message Direction CSMS Response
P02 DataTransfer DataTransferRequest Charging Station → CSMS DataTransferResponse

CSMS Handler Checklist for P02

  • Register handler for incoming DataTransfer action in the OCPP message router
  • Implement vendorId registry/lookup to match incoming vendorId values
  • For each supported vendorId, implement messageId dispatch (if messageId is used)
  • Return UnknownVendorId for unrecognized vendorId values
  • Return UnknownMessageId for recognized vendorId but unrecognized messageId
  • Implement vendor-specific business logic for each supported vendorId+messageId combination
  • Return Accepted with optional response data on success
  • Return Rejected with optional statusInfo on failure
  • Ensure the data field parser handles the agreed-upon format for each vendor extension

OCPP 2.0.1 DataTransfer Flows - CSMS Developer Guide. Based on OCPP 2.0.1 Edition 4 Specification (Part 2, Section P).