Provisioning Flows - CSMS Developer Guide
Based on OCPP 2.1 Edition 2 Specification (Part 2), Section B (Provisioning). This guide covers all provisioning flows (B01–B13), variable management, network configuration, and reset operations from the CSMS perspective using OCPP-J (JSON over WebSocket).
1. Overview
IntroductionThe Provisioning functional block covers the lifecycle management of Charging Stations from initial boot through configuration, reporting, network management, and reset operations. All flows are described from the CSMS (Charging Station Management System) developer perspective.
Functional Areas
Booting (B01–B03)
Accepting, pending, or rejecting Charging Stations upon connection after power-up or reboot.
Offline Behavior (B04)
How the CSMS handles reconnection after offline periods and state synchronization.
Configuration (B05–B06)
Reading and writing Charging Station variables via SetVariables and GetVariables.
Reporting (B07–B08)
Requesting device model reports (base and custom) with async delivery.
Network Management (B09–B10)
Setting connection profiles and migrating Charging Stations to a new CSMS.
Resetting (B11–B13)
Resetting Charging Stations or individual EVSEs, with or without ongoing transactions.
Transactions Before Acceptance
The CSMS is advised to deny all charging services at a Charging Station that
has never been Accepted. This is
controllable via configuration variable TxBeforeAcceptedEnabled.
2. B01 — Cold Boot Charging Station (Accepted)
CS-Initiated| Use Case ID | B01 |
| Direction | CS → CSMS (CS initiates) |
| Trigger | Charging Station powers up or reboots |
| OCPP Messages | BootNotificationRequest/Response, HeartbeatRequest/Response, NotifyEventRequest/Response |
Flow Diagram
Charging Station CSMS
| |
| [Power up / Reboot] |
| |
| BootNotificationRequest(reason, cs) |
|------------------------------------------>|
| |
| BootNotificationResponse(Accepted, |
| currentTime, interval) |
|<------------------------------------------|
| |
| [opt] NotifyEventRequest(Connector, |
| AvailabilityState=Unavailable) |
|------------------------------------------>|
| NotifyEventResponse() |
|<------------------------------------------|
| |
| [for each Connector with final state] |
| NotifyEventRequest(Connector, |
| AvailabilityState=<state>) |
|------------------------------------------>|
| NotifyEventResponse() |
|<------------------------------------------|
| |
| [loop] HeartbeatRequest() |
|------------------------------------------>|
| HeartbeatResponse(currentTime) |
|<------------------------------------------|Handle BootNotificationRequest
When a Charging Station powers up or reboots, it sends a BootNotificationRequest containing its identity and metadata.
{
"reason": "PowerUp",
"chargingStation": {
"model": "SuperCharger-500",
"vendorName": "VendorX",
"serialNumber": "CS-001-2024",
"firmwareVersion": "2.3.1",
"modem": {
"iccid": "89860000000000000001",
"imsi": "460000000000001"
}
}
}{
"type": "object",
"required": ["reason", "chargingStation"],
"properties": {
"reason": {
"type": "string",
"enum": ["ApplicationReset", "FirmwareUpdate", "LocalReset", "PowerUp",
"RemoteReset", "ScheduledReset", "Triggered", "Unknown", "Watchdog"]
},
"chargingStation": {
"type": "object",
"required": ["model", "vendorName"],
"properties": {
"serialNumber": { "type": "string", "maxLength": 25 },
"model": { "type": "string", "maxLength": 20 },
"vendorName": { "type": "string", "maxLength": 50 },
"firmwareVersion": { "type": "string", "maxLength": 50 },
"modem": {
"type": "object",
"properties": {
"iccid": { "type": "string", "maxLength": 20 },
"imsi": { "type": "string", "maxLength": 20 }
}
}
}
}
}
}CSMS Processing Logic
- Identify the Charging Station from the WebSocket connection URL / TLS certificate.
- [B01.FR.11] If Security Profile 3 is used, check that the
serialNumberin the request matches the Serial Number in the TLS client certificate Common Name. - [B01.FR.12] If the serial numbers do NOT match, close the WebSocket connection immediately.
- [B01.FR.02] Decide whether to accept, reject, or put the CS in pending state.
- Store/update the CS metadata (model, vendor, firmware version, modem info).
Send BootNotificationResponse
{
"currentTime": "2025-06-15T14:30:00.000Z",
"interval": 300,
"status": "Accepted"
}{
"type": "object",
"required": ["currentTime", "interval", "status"],
"properties": {
"currentTime": {
"type": "string",
"format": "date-time",
"description": "CSMS's current time. CS will sync its clock to this."
},
"interval": {
"type": "integer",
"description": "When Accepted: heartbeat interval in seconds. When Pending/Rejected: minimum wait before next BootNotification."
},
"status": {
"type": "string",
"enum": ["Accepted", "Pending", "Rejected"]
},
"statusInfo": {
"type": "object",
"required": ["reasonCode"],
"properties": {
"reasonCode": { "type": "string", "maxLength": 20 },
"additionalInfo": { "type": "string", "maxLength": 1024 }
}
}
}
}| Decision | Status | Interval Meaning | Use When... |
|---|---|---|---|
| Accept | Accepted | Heartbeat interval (seconds) | CS is known, authorized, properly configured |
| Defer | Pending | Min wait before next BootNotification | CS needs configuration, credential update, or provisioning |
| Deny | Rejected | Min wait before next BootNotification | CS is blacklisted, unknown, or permanently denied |
Post-Acceptance: Connector Status
After the CSMS accepts a boot, the CS sends NotifyEventRequest messages reporting the AvailabilityState of each
Connector.
{
"generatedAt": "2025-06-15T14:30:05.000Z",
"seqNo": 0,
"eventData": [
{
"eventId": 1,
"timestamp": "2025-06-15T14:30:05.000Z",
"trigger": "Delta",
"actualValue": "Available",
"eventNotificationType": "HardWiredNotification",
"component": {
"name": "Connector",
"evse": { "id": 1, "connectorId": 1 }
},
"variable": {
"name": "AvailabilityState"
}
}
]
}CSMS Response
Send an empty NotifyEventResponse:
{}CSMS Processing
Update the internal connector availability state. Possible values:
AvailableOccupiedReservedUnavailableFaulted- [B01.FR.07] If a Connector was set to
Unavailableby aChangeAvailabilitycommand, theUnavailablestatus MUST persist across reboots. - [B01.FR.13] If an EVSE was
Reserved, theReservedstate MUST persist across reboots.
Post-Acceptance: Heartbeat
[B01.FR.04] The CS will send heartbeats at the interval specified in the BootNotificationResponse.
{}{
"currentTime": "2025-06-15T14:35:00.000Z"
}{
"type": "object",
"required": ["currentTime"],
"properties": {
"currentTime": {
"type": "string",
"format": "date-time",
"description": "Current time of the CSMS. CS uses this for clock synchronization."
}
}
}CSMS Responsibilities
- Return accurate
currentTimein ISO 8601 format. - Use the heartbeat as a liveness indicator — if no heartbeat arrives within the expected interval, consider the CS offline.
Message Gating Rules (Critical)
- [B01.FR.08] Between the physical power-on and the successful completion of a
BootNotification (where the CSMS returns
AcceptedorPending), the CS SHALL NOT send any OCPP requests exceptBootNotificationRequest. This includes cached messages from prior sessions. - [B01.FR.10] If a CS that has not been
Acceptedsends any CALL message that is NOT aBootNotificationRequestor a message triggered byTriggerMessageRequest,GetBaseReportRequest, orGetReportRequest, the CSMS SHALL respond with RPC FrameworkCALLERROR: SecurityError.
3. B02 — Cold Boot Charging Station (Pending)
CSMS Decision| Use Case ID | B02 |
| Parent | B01 |
| Direction | CSMS decides to defer acceptance |
| Purpose | Retrieve/set configuration before accepting the CS |
When to Use Pending
Use Pending when the CSMS needs to:
- Retrieve configuration information (
GetVariablesRequest,GetBaseReportRequest,GetReportRequest) - Push configuration changes (
SetVariablesRequest) - Update credentials or certificates
- Rate-limit reconnections after CSMS restarts
Flow Diagram
Charging Station CSMS
| |
| BootNotificationRequest(...) |
|------------------------------------------>|
| |
| BootNotificationResponse(Pending, |
| interval=X) |
|<------------------------------------------|
| |
| [opt] GetVariablesRequest(...) |
|<------------------------------------------|
| GetVariablesResponse(...) |
|------------------------------------------>|
| |
| [opt] SetVariablesRequest(...) |
|<------------------------------------------|
| SetVariablesResponse(...) |
|------------------------------------------>|
| |
| [after interval X seconds] |
| BootNotificationRequest(...) |
|------------------------------------------>|
| |
| BootNotificationResponse(Accepted/Pending)|
|<------------------------------------------|CSMS Behavior During Pending
[B02.FR.01] While the CS is in Pending, the CSMS MAY send messages to retrieve or change configuration:
GetVariablesRequest(B06)SetVariablesRequest(B05)GetBaseReportRequest(B07)GetReportRequest(B08)TriggerMessageRequest
[B02.FR.05] While in Pending, if the CSMS sends RequestStartTransactionRequest or RequestStopTransactionRequest, the CS will respond Rejected. If the CSMS wants to use RequestStartTransaction, it SHALL first accept the CS.
[B02.FR.06] When returning Pending, the CSMS SHALL NOT close the communication channel.
[B02.FR.09] If a CS in Pending sends a CALL message that is NOT a BootNotificationRequest or triggered by TriggerMessageRequest/GetBaseReportRequest/GetReportRequest, the CSMS SHALL respond with CALLERROR: SecurityError.
[B02.FR.04] The CS will not send another BootNotificationRequest earlier than the interval field value, unless triggered by TriggerMessageRequest.
Transition to Accepted
When the CSMS is ready, respond to the next BootNotificationRequest with status = Accepted. The flow then
continues as B01.
4. B03 — Cold Boot Charging Station (Rejected)
CSMS Decision| Use Case ID | B03 |
| Parent | B01 |
| Direction | CSMS decides to reject |
| Purpose | Permanently deny a CS (blacklisted, unknown) |
Flow Diagram
Charging Station CSMS
| |
| BootNotificationRequest(...) |
|------------------------------------------>|
| |
| BootNotificationResponse(Rejected, |
| interval=X) |
|<------------------------------------------|
| |
| [loop: after interval X] |
| BootNotificationRequest(...) |
|------------------------------------------>|
| BootNotificationResponse(Rejected, |
| interval=X) |
|<------------------------------------------|CSMS Behavior During Rejected
[B03.FR.03] The CSMS SHALL NOT initiate any messages to a rejected CS.
[B03.FR.07] If a rejected CS sends a message that is NOT a BootNotificationRequest, the CSMS SHALL respond with CALLERROR: SecurityError.
Additional Notes
- The CSMS MAY close the connection to free resources. The CS will reconnect and retry.
- Set
intervalto a reasonable value (e.g., 300–3600 seconds) to avoid flooding.
5. B04 — Offline Behavior Idle Charging Station
CS-Initiated| Use Case ID | B04 |
| Direction | CS → CSMS (CS reconnects after being offline) |
| Trigger | Connection restored after an offline period |
CSMS Handling
When a CS reconnects after being offline, the CSMS should expect:
[B04.FR.01] If the offline period exceeded the OfflineThreshold configuration variable, the CS will send a NotifyEventRequest with variable.name = "AvailabilityState" for all Connectors (full status report).
[B04.FR.02] If the offline period did NOT exceed OfflineThreshold, the CS
will only send NotifyEventRequest for
Connectors whose state changed during the offline period.
CSMS Actions
- Accept the reconnected WebSocket connection.
- Process incoming
NotifyEventRequestmessages to synchronize connector states. - Respond to each with an empty
NotifyEventResponse({}). - Resume normal heartbeat handling.
6. B05 — Set Variables
CSMS-Initiated| Use Case ID | B05 |
| Direction | CSMS → CS |
| OCPP Messages | SetVariablesRequest / SetVariablesResponse |
| Purpose | Set one or more configuration variables on the CS |
Sending SetVariablesRequest (CSMS → CS)
{
"setVariableData": [
{
"component": { "name": "OCPPCommCtrlr" },
"variable": { "name": "HeartbeatInterval" },
"attributeValue": "60",
"attributeType": "Actual"
},
{
"component": {
"name": "Connector",
"evse": { "id": 1, "connectorId": 1 }
},
"variable": { "name": "Enabled" },
"attributeValue": "true"
}
]
}{
"type": "object",
"required": ["setVariableData"],
"properties": {
"setVariableData": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["attributeValue", "component", "variable"],
"properties": {
"attributeType": {
"type": "string",
"enum": ["Actual", "Target", "MinSet", "MaxSet"],
"default": "Actual"
},
"attributeValue": { "type": "string", "maxLength": 2500 },
"component": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "maxLength": 50 },
"instance": { "type": "string", "maxLength": 50 },
"evse": {
"type": "object",
"required": ["id"],
"properties": {
"id": { "type": "integer", "minimum": 0 },
"connectorId": { "type": "integer", "minimum": 0 }
}
}
}
},
"variable": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "maxLength": 50 },
"instance": { "type": "string", "maxLength": 50 }
}
}
}
}
}
}
}- [B05.FR.11] Do NOT send more
SetVariableDataelements than reported byItemsPerMessageSetVariables. - [B05.FR.13] Do NOT include multiple
SetVariableDataelements with the same Component + Variable + AttributeType combination. An omittedattributeTypecounts asActual.
Handling SetVariablesResponse (CS → CSMS)
{
"setVariableResult": [
{
"attributeStatus": "Accepted",
"component": { "name": "OCPPCommCtrlr" },
"variable": { "name": "HeartbeatInterval" }
},
{
"attributeStatus": "Rejected",
"attributeStatusInfo": {
"reasonCode": "ReadOnly",
"additionalInfo": "Variable is read-only"
},
"component": {
"name": "Connector",
"evse": { "id": 1, "connectorId": 1 }
},
"variable": { "name": "Enabled" }
}
]
}| attributeStatus | Meaning | CSMS Action |
|---|---|---|
Accepted | Value was successfully set | Update internal record |
Rejected | Value format/range invalid, variable is ReadOnly, or technical failure | Check statusInfo for reason; may need different value |
UnknownComponent | Component name does not exist on this CS | CS does not have this component |
UnknownVariable | Variable name does not exist for this component | CS does not support this variable |
NotSupportedAttributeType | Requested attributeType is not supported | Try a different attributeType |
RebootRequired | Value accepted, but a reboot is needed for it to take effect | Consider sending a ResetRequest |
- [B05.FR.01] The response will contain the same number of
setVariableResultentries assetVariableDataentries sent. - [B05.FR.02] Each result entry will match the same component/variable combination.
- [B05.FR.12] If the request omitted
attributeType, the response will containattributeType=Actual.
7. B06 — Get Variables
CSMS-Initiated| Use Case ID | B06 |
| Direction | CSMS → CS |
| OCPP Messages | GetVariablesRequest / GetVariablesResponse |
Sending GetVariablesRequest (CSMS → CS)
{
"getVariableData": [
{
"component": { "name": "OCPPCommCtrlr" },
"variable": { "name": "HeartbeatInterval" },
"attributeType": "Actual"
},
{
"component": { "name": "SecurityCtrlr" },
"variable": { "name": "SecurityProfile" }
}
]
}{
"type": "object",
"required": ["getVariableData"],
"properties": {
"getVariableData": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["component", "variable"],
"properties": {
"attributeType": {
"type": "string",
"enum": ["Actual", "Target", "MinSet", "MaxSet"],
"default": "Actual"
},
"component": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "maxLength": 50 },
"instance": { "type": "string", "maxLength": 50 },
"evse": {
"type": "object",
"required": ["id"],
"properties": {
"id": { "type": "integer", "minimum": 0 },
"connectorId": { "type": "integer", "minimum": 0 }
}
}
}
},
"variable": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "maxLength": 50 },
"instance": { "type": "string", "maxLength": 50 }
}
}
}
}
}
}
}[B06.FR.05] Do NOT send more GetVariableData elements than reported by ItemsPerMessageGetVariables.
Handling GetVariablesResponse (CS → CSMS)
| attributeStatus | Meaning |
|---|---|
Accepted | Value found. attributeValue contains the result. |
Rejected | Variable is WriteOnly. Value cannot be read. |
UnknownComponent | Component not found. attributeValue omitted. |
UnknownVariable | Variable not found. attributeValue omitted. |
NotSupportedAttributeType | AttributeType not supported. attributeValue omitted. |
- [B06.FR.11] If the request omitted
attributeType, the response will containattributeType=Actual. - [B06.FR.13] If the variable has no
attributeValuefor the requested type, the CS returns an empty string.
8. B07 — Get Base Report
CSMS-Initiated| Use Case ID | B07 |
| Direction | CSMS → CS (request), CS → CSMS (async reports) |
| OCPP Messages | GetBaseReportRequest/Response, NotifyReportRequest/Response |
Flow Diagram
CSMS Charging Station
| |
| GetBaseReportRequest(requestId, reportBase)|
|------------------------------------------->|
| |
| GetBaseReportResponse(status) |
|<-------------------------------------------|
| |
| [async: for each report part] |
| NotifyReportRequest(requestId, seqNo, |
| reportData, tbc, generatedAt) |
|<-------------------------------------------|
| |
| NotifyReportResponse() |
|------------------------------------------->|
| |
| [repeat until tbc=false] |Sending GetBaseReportRequest (CSMS → CS)
{
"requestId": 42,
"reportBase": "FullInventory"
}{
"type": "object",
"required": ["requestId", "reportBase"],
"properties": {
"requestId": {
"type": "integer",
"description": "Unique ID to correlate with incoming NotifyReportRequest messages."
},
"reportBase": {
"type": "string",
"enum": ["ConfigurationInventory", "FullInventory", "SummaryInventory"]
}
}
}| reportBase | Content |
|---|---|
ConfigurationInventory | All component-variables that can be set by the operator, including their VariableCharacteristics. |
FullInventory | All component-variables including their VariableCharacteristics. Minimum required variables plus those relevant to each implemented functional block. |
SummaryInventory | Components/variables relating to current charging availability and problem conditions. Includes AvailabilityState for CS, each EVSE, each Connector, and any abnormal state variables (Problem, Tripped, Overload, Fallback). |
[B07.FR.14] CSMS SHOULD request FullInventory when a CS connects for the first time or when the device model may have changed (e.g., after firmware update).
Handling GetBaseReportResponse (CS → CSMS)
| status | Meaning |
|---|---|
Accepted | CS will send report data via NotifyReportRequest. |
Rejected | CS is temporarily unable to execute. Retry later. |
NotSupported | The requested reportBase is not supported. |
EmptyResultSet | Report criteria matched no data. |
Handling NotifyReportRequest — Async Report Parts
{
"requestId": 42,
"generatedAt": "2025-06-15T14:31:00.000Z",
"seqNo": 0,
"tbc": true,
"reportData": [
{
"component": { "name": "OCPPCommCtrlr" },
"variable": { "name": "HeartbeatInterval" },
"variableAttribute": [
{
"type": "Actual",
"value": "300",
"mutability": "ReadWrite",
"persistent": true,
"constant": false
}
],
"variableCharacteristics": {
"dataType": "integer",
"minLimit": 1,
"maxLimit": 86400,
"supportsMonitoring": true
}
}
]
}{
"type": "object",
"required": ["requestId", "generatedAt", "seqNo"],
"properties": {
"requestId": { "type": "integer" },
"generatedAt": { "type": "string", "format": "date-time" },
"seqNo": { "type": "integer", "minimum": 0, "description": "Starts at 0, incremental per report." },
"tbc": { "type": "boolean", "default": false, "description": "true = more parts follow." },
"reportData": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["component", "variable", "variableAttribute"],
"properties": {
"component": { "$ref": "ComponentType" },
"variable": { "$ref": "VariableType" },
"variableAttribute": {
"type": "array", "minItems": 1, "maxItems": 4,
"items": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["Actual","Target","MinSet","MaxSet"], "default": "Actual" },
"value": { "type": "string", "maxLength": 2500 },
"mutability": { "type": "string", "enum": ["ReadOnly","WriteOnly","ReadWrite"], "default": "ReadWrite" },
"persistent": { "type": "boolean", "default": false },
"constant": { "type": "boolean", "default": false }
}
}
},
"variableCharacteristics": {
"type": "object",
"required": ["dataType", "supportsMonitoring"],
"properties": {
"dataType": { "type": "string", "enum": ["string","decimal","integer","dateTime","boolean","OptionList","SequenceList","MemberList"] },
"unit": { "type": "string", "maxLength": 16 },
"minLimit": { "type": "number" },
"maxLimit": { "type": "number" },
"maxElements": { "type": "integer", "minimum": 1 },
"valuesList": { "type": "string", "maxLength": 1000 },
"supportsMonitoring": { "type": "boolean" }
}
}
}
}
}
}
}CSMS Processing
- Collect all parts (correlate by
requestId). - Reassemble using
seqNo(starts at 0, increments). - Continue receiving until
tbc=false(or absent). - Build/update the internal device model from the
reportData. - Respond to each
NotifyReportRequestwith an emptyNotifyReportResponse({}).
9. B08 — Get Custom Report
CSMS-Initiated| Use Case ID | B08 |
| Direction | CSMS → CS (request), CS → CSMS (async reports) |
| OCPP Messages | GetReportRequest/Response, NotifyReportRequest/Response |
Sending GetReportRequest (CSMS → CS)
A custom report allows filtering by ComponentCriteria (state-based) and/or ComponentVariable (specific components/variables).
{
"requestId": 100,
"componentCriteria": ["Active", "Problem"]
}{
"requestId": 101,
"componentVariable": [
{
"component": {
"name": "EVSE",
"evse": { "id": 1 }
},
"variable": {
"name": "AvailabilityState"
}
},
{
"component": {
"name": "Connector",
"evse": { "id": 1, "connectorId": 1 }
}
}
]
}{
"type": "object",
"required": ["requestId"],
"properties": {
"requestId": { "type": "integer" },
"componentCriteria": {
"type": "array",
"items": { "type": "string", "enum": ["Active", "Available", "Enabled", "Problem"] },
"minItems": 1, "maxItems": 4,
"description": "Filter components by state. Multiple criteria = logical OR."
},
"componentVariable": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["component"],
"properties": {
"component": { "$ref": "ComponentType" },
"variable": { "$ref": "VariableType" }
}
}
}
}
}| Criterion | Reports Components Where... |
|---|---|
Active | Variable Active is true or absent |
Available | Variable Available is true or absent |
Enabled | Variable Enabled is true or absent |
Problem | Variable Problem is true |
- [B08.FR.06] Do NOT send more
componentVariableitems thanItemsPerMessageGetReport. - [B08.FR.05] If both
componentCriteriaandcomponentVariableare provided, results are the intersection.
Handling GetReportResponse (CS → CSMS)
| status | Meaning |
|---|---|
Accepted | Report will follow via NotifyReportRequest. |
Rejected | CS is temporarily unable. |
NotSupported | Criteria not supported. |
EmptyResultSet | Criteria matched no components. No NotifyReportRequest will follow. |
Report data handling is the same as B07. The CS sends NotifyReportRequest messages asynchronously, correlated by requestId.
10. B09 — Setting a New NetworkConnectionProfile
CSMS-Initiated| Use Case ID | B09 |
| Direction | CSMS → CS |
| OCPP Messages | SetNetworkProfileRequest/Response (legacy) or SetVariablesRequest/Response (preferred in 2.1) |
| Updated in | OCPP 2.1 |
Key Concepts
- A CS supports at least 2 network configuration slots, identified by numbers.
- Available slots are reported in the
valuesListofNetworkConfigurationPriority(e.g.,"0,1,2"= slots 0, 1, 2). - The active slot is reported in
OCPPCommCtrlr.ActiveNetworkProfile. - The priority order is the
valueofNetworkConfigurationPriority(e.g.,"1,0"means try slot 1 first, then slot 0).
Method A: Using SetNetworkProfileRequest (Legacy)
{
"configurationSlot": 1,
"connectionData": {
"ocppVersion": "OCPP21",
"ocppTransport": "JSON",
"ocppInterface": "Wired0",
"ocppCsmsUrl": "wss://new-csms.example.com/ocpp/",
"messageTimeout": 30,
"securityProfile": 2,
"identity": "CS-001",
"basicAuthPassword": "newSecurePassword123"
}
}{
"type": "object",
"required": ["configurationSlot", "connectionData"],
"properties": {
"configurationSlot": { "type": "integer" },
"connectionData": {
"type": "object",
"required": ["ocppInterface", "ocppTransport", "messageTimeout", "ocppCsmsUrl", "securityProfile"],
"properties": {
"ocppVersion": { "type": "string", "enum": ["OCPP12","OCPP15","OCPP16","OCPP20","OCPP201","OCPP21"] },
"ocppTransport": { "type": "string", "enum": ["SOAP", "JSON"] },
"ocppInterface": { "type": "string", "enum": ["Wired0","Wired1","Wired2","Wired3","Wireless0","Wireless1","Wireless2","Wireless3","Any"] },
"ocppCsmsUrl": { "type": "string", "maxLength": 2000 },
"messageTimeout": { "type": "integer" },
"securityProfile": { "type": "integer", "minimum": 0 },
"identity": { "type": "string", "maxLength": 48 },
"basicAuthPassword": { "type": "string", "maxLength": 64 },
"apn": { "$ref": "APNType" },
"vpn": { "$ref": "VPNType" }
}
}
}
}| status | Meaning |
|---|---|
Accepted | Profile stored successfully. |
Rejected | Invalid content. Check statusInfo.reasonCode: "InvalidNetworkConf", "InvalidConfSlot", "NoSecurityDowngrade". |
Failed | Storage failed. |
Method B: Using SetVariablesRequest for NetworkConfiguration (New in 2.1)
The preferred approach in OCPP 2.1 is to set network configuration via device model variables:
- Ensure the target slot is NOT in the active
NetworkConfigurationPriority. If it is, remove it first viaSetVariablesRequest. - Set variables on
NetworkConfigurationcomponent withinstance=<configurationSlot>. - Add the slot back to
NetworkConfigurationPriority.
[B09.FR.21] The CSMS SHALL NOT send a SetVariablesRequest containing any NetworkConfiguration variable for a slot that is currently in NetworkConfigurationPriority.
[B09.FR.22] If the CS receives such a request, it will respond Rejected with reasonCode = "PriorityNetworkConf".
Security Downgrade Protection
[B09.FR.04/B09.FR.31] If AllowSecurityProfileDowngrade is not implemented or set to false, and the new profile has a lower securityProfile than the current one, the CS will respond Rejected with reasonCode = "NoSecurityDowngrade".
[B09.FR.31] Even when AllowSecurityProfileDowngrade = true, downgrading to Profile 1 is always rejected if the current profile is higher than 1.
11. B10 — Migrate to New CSMS
CSMS-Initiated| Use Case ID | B10 |
| Direction | CSMS → CS (multi-step) |
| Prerequisite | B09 must be completed first (new NetworkConnectionProfile configured) |
| OCPP Messages | SetVariablesRequest/Response, ResetRequest/Response, BootNotificationRequest/Response |
Flow Diagram
Operator CSMS 1 CSMS 2 Charging Station
| | | |
| Change | | |
|------------->| | |
| | |
| | SetVariablesRequest |
| | (NetworkConfigurationPriority) |
| |--------------------------------->|
| | |
| | SetVariablesResponse |
| | (Accepted/RebootRequired) |
| |<---------------------------------|
| | |
| | ResetRequest(OnIdle) |
| |--------------------------------->|
| | |
| | ResetResponse(Accepted) |
| |<---------------------------------|
| | |
| | [Reboot] |
| | |
| | BootNotificationRequest(...) |
| | |<-----------------|
| | | |
| | BootNotificationResponse(...) |
| | |----------------->|CSMS Actions Step-by-Step
Step 1: Set NetworkConfigurationPriority
Reorder so the new CSMS's slot is first:
{
"setVariableData": [
{
"component": { "name": "OCPPCommCtrlr" },
"variable": { "name": "NetworkConfigurationPriority" },
"attributeValue": "1,0"
}
]
}- [B10.FR.01] CS responds
AcceptedorRebootRequiredif all slots contain valid configurations. - [B10.FR.02] CS responds
Rejectedif any slot does not contain a valid configuration. CheckstatusInfo.reasonCode="InvalidNetworkConf".
Step 2: (Recommended) Set CS to Inoperative
[B10.FR.05] Before resetting, it is RECOMMENDED to send ChangeAvailabilityRequest to set the CS to Inoperative,
preventing new transactions. Then use GetTransactionStatusRequest to verify no transactions are queued.
{
"operationalStatus": "Inoperative"
}Step 3: Send ResetRequest
{
"type": "OnIdle"
}Step 4: Handle ResetResponse
| status | Meaning |
|---|---|
Accepted | CS will reset. It will disconnect from this CSMS and connect to the new one. |
Rejected | CS cannot reset now. |
Scheduled | CS will reset when idle (transactions in progress). |
- [B10.FR.04] After reboot, the CS begins connecting to the first entry of
NetworkConfigurationPriority. - [B10.FR.10] The CS will send a
BootNotificationRequestto the new CSMS even if it has not rebooted.
12. B11 — Reset Without Ongoing Transaction
CSMS-Initiated| Use Case ID | B11 |
| Direction | CSMS → CS |
| Prerequisite | No transaction is ongoing |
| OCPP Messages | ResetRequest/Response |
Sending ResetRequest (CSMS → CS)
{
"type": "OnIdle"
}{
"type": "Immediate",
"evseId": 2
}{
"type": "object",
"required": ["type"],
"properties": {
"type": {
"type": "string",
"enum": ["Immediate", "OnIdle", "ImmediateAndResume"],
"description": "Immediate: reset now. OnIdle: reset when no tasks running. ImmediateAndResume: reset and resume transactions (B13)."
},
"evseId": {
"type": "integer",
"minimum": 0,
"description": "If provided, only reset this EVSE (not the entire station)."
}
}
}Handling ResetResponse (CS → CSMS)
{
"type": "object",
"required": ["status"],
"properties": {
"status": {
"type": "string",
"enum": ["Accepted", "Rejected", "Scheduled"]
},
"statusInfo": { "$ref": "StatusInfoType" }
}
}| status | Meaning | CSMS Action |
|---|---|---|
Accepted | CS will reset immediately (or reset the EVSE). | Expect disconnect/reconnect and BootNotificationRequest (full CS reset) or NotifyEventRequest (EVSE reset). |
Rejected | CS cannot perform the reset. | Log failure. Retry later or investigate. [B11.FR.06] CS is at this moment unable. [B11.FR.09] CS doesn't support individual EVSE reset. |
Scheduled | CS cannot reset now but has scheduled it. | Wait for the reset to happen. [B11.FR.07] |
Post-Reset Behavior
Full CS Reset (no evseId)
[B11.FR.03/04] CS sends NotifyEventRequest for
Connectors with AvailabilityState = Unavailable, then reboots
and proceeds as B01 (Cold Boot).
EVSE Reset (with evseId)
[B11.FR.08] CS may send NotifyEventRequest for each
Connector on the EVSE with AvailabilityState = Unavailable, reset the EVSE,
then report Available.
- [B11.FR.02] If the CS was set to
Inoperativeby the CSMS, EVSEs SHALL return toUnavailableafter reboot. - [B11.FR.05] If an EVSE was
Reserved, it SHALL return toReservedafter reboot.
13. B12 — Reset With Ongoing Transaction
CSMS-Initiated| Use Case ID | B12 |
| Direction | CSMS → CS |
| Prerequisite | A transaction IS ongoing |
| OCPP Messages | ResetRequest/Response, TransactionEventRequest/Response |
Same ResetRequest as B11.
The behavior differs based on type:
OnIdle Reset
[B12.FR.01] CS responds with Scheduled. The CS will:
- Wait for all transactions to end normally.
- Optionally set free EVSE connectors to
Unavailable. - Once all transactions end, reboot and proceed as B01.
CSMS should expect: TransactionEventRequest (eventType=Ended)
for each transaction as they complete naturally. Eventually, a BootNotificationRequest when the CS reboots.
Immediate Reset
Full CS Reset
[B12.FR.02] CS responds with Accepted. The CS will:
- Terminate all transactions immediately.
- Send
TransactionEventRequest(eventType=Ended,triggerReason=ResetCommand,stoppedReason=ImmediateReset) for each. - Reboot.
[B12.FR.05] If the TransactionEventResponse is not received within timeout, the CS queues it and resends after reboot.
Specific EVSE Reset
[B12.FR.08] CS terminates the transaction on the specified EVSE, sends TransactionEventRequest (eventType=Ended, triggerReason=ResetCommand, stoppedReason=ImmediateReset),
then resets the EVSE.
Error Cases
| Condition | CS Response |
|---|---|
| CS cannot reset now (any reason except ongoing transactions) | Rejected [B12.FR.10] |
| CS doesn't support individual EVSE reset | Rejected [B12.FR.09] |
14. B13 — Reset With Ongoing Transaction (Resuming)
New in 2.1| Use Case ID | B13 |
| New in | OCPP 2.1 |
| Direction | CSMS → CS |
| Prerequisite | Transaction is ongoing, CS supports TxResumptionTimeout > 0 |
| OCPP Messages | ResetRequest/Response, TransactionEventRequest/Response, SetChargingProfileRequest/Response |
Sending ResetRequest (CSMS → CS)
{
"type": "ImmediateAndResume"
}Optionally with evseId to reset only a specific EVSE.
Handling ResetResponse
| Condition | CS Response |
|---|---|
| TxResumptionTimeout == 0 or not supported | Rejected [B13.FR.01] |
| No transactions ongoing | Accepted — acts as B11 [B13.FR.02] |
| Transactions ongoing | Accepted [B13.FR.03] |
Post-Reset Flow (Transactions Resume)
After Accepted with ongoing transactions:
- CS sends
TransactionEventRequestwitheventType=Updated,triggerReason=ResetCommandfor each ongoing transaction. - CS stops energy transfer, unlocks detachable cables, and reboots.
- After reboot, CS locks cables, resumes connectivity with EVs.
- [B13.FR.13] If
TxAllowEnergyTransferResumption=true, energy transfer resumes. - [B13.FR.14] If
TxAllowEnergyTransferResumption=false,chargingState=SuspendedEVSE. - [B13.FR.30] CS sends
TransactionEventRequestwitheventType=Updated,triggerReason=TxResumed.
CSMS Action After Transaction Resumption
[B13.FR.31] When the CSMS receives a TransactionEventRequest with triggerReason=TxResumed AND the CSMS had a TxProfile for the transaction
AND SmartChargingCtrlr.ChargingProfilePersistence for instance "TxProfile" is false or absent:
The CSMS SHALL re-send the SetChargingProfileRequest with chargingProfilePurpose=TxProfile for these transactions.
15. Message Direction Summary
Reference| Message | Direction | Use Cases |
|---|---|---|
BootNotificationRequest | CS → CSMS | B01, B02, B03, B10 |
BootNotificationResponse | CSMS → CS | B01, B02, B03, B10 |
HeartbeatRequest | CS → CSMS | B01, B04 |
HeartbeatResponse | CSMS → CS | B01, B04 |
NotifyEventRequest | CS → CSMS | B01, B04, B11, B12 |
NotifyEventResponse | CSMS → CS | B01, B04, B11, B12 |
SetVariablesRequest | CSMS → CS | B05, B09, B10 |
SetVariablesResponse | CS → CSMS | B05, B09, B10 |
GetVariablesRequest | CSMS → CS | B06 |
GetVariablesResponse | CS → CSMS | B06 |
GetBaseReportRequest | CSMS → CS | B07 |
GetBaseReportResponse | CS → CSMS | B07 |
GetReportRequest | CSMS → CS | B08 |
GetReportResponse | CS → CSMS | B08 |
NotifyReportRequest | CS → CSMS | B07, B08 |
NotifyReportResponse | CSMS → CS | B07, B08 |
SetNetworkProfileRequest | CSMS → CS | B09 |
SetNetworkProfileResponse | CS → CSMS | B09 |
ResetRequest | CSMS → CS | B10, B11, B12, B13 |
ResetResponse | CS → CSMS | B10, B11, B12, B13 |
ChangeAvailabilityRequest | CSMS → CS | B10 (recommended) |
ChangeAvailabilityResponse | CS → CSMS | B10 (recommended) |
TransactionEventRequest | CS → CSMS | B12, B13 |
TransactionEventResponse | CSMS → CS | B12, B13 |
SetChargingProfileRequest | CSMS → CS | B13 |
SetChargingProfileResponse | CS → CSMS | B13 |
16. Shared Data Types Reference
ReferenceComponentType
{
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "maxLength": 50, "description": "Standardized component name (CamelCase, case-insensitive)" },
"instance": { "type": "string", "maxLength": 50, "description": "Instance name if component exists as multiple instances" },
"evse": {
"type": "object",
"required": ["id"],
"properties": {
"id": { "type": "integer", "minimum": 0, "description": "EVSE ID (> 0)" },
"connectorId": { "type": "integer", "minimum": 0, "description": "Connector index on the EVSE" }
}
}
}
}VariableType
{
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "maxLength": 50, "description": "Standardized variable name (CamelCase, case-insensitive)" },
"instance": { "type": "string", "maxLength": 50, "description": "Instance name for multi-instance variables" }
}
}Enumerations
AttributeEnumType
| Value | Description |
|---|---|
Actual | Current actual value (default when omitted) |
Target | Desired target value |
MinSet | Minimum settable value |
MaxSet | Maximum settable value |
BootReasonEnumType
| Value | Description |
|---|---|
ApplicationReset | Application-level reset |
FirmwareUpdate | Reset after firmware update |
LocalReset | Local reset (button pressed) |
PowerUp | Initial power-on |
RemoteReset | Reset triggered by CSMS (ResetRequest) |
ScheduledReset | Scheduled reset |
Triggered | Triggered by TriggerMessageRequest |
Unknown | Unknown reason |
Watchdog | Watchdog timer reset |
ResetEnumType
| Value | Description |
|---|---|
Immediate | Reset immediately; terminate any active transactions |
OnIdle | Reset when no tasks are active (wait for transactions to end) |
ImmediateAndResume | Reset immediately; resume transactions after reboot (B13) |
ReportBaseEnumType
| Value | Description |
|---|---|
ConfigurationInventory | Operator-configurable variables with their characteristics |
FullInventory | All device model variables with characteristics |
SummaryInventory | Current availability/problem state summary |
StatusInfoType
{
"type": "object",
"required": ["reasonCode"],
"properties": {
"reasonCode": { "type": "string", "maxLength": 20, "description": "Predefined status reason code (case-insensitive)" },
"additionalInfo": { "type": "string", "maxLength": 1024, "description": "Additional human-readable details" }
}
}Key Configuration Variables for Provisioning
| Component | Variable | Description |
|---|---|---|
OCPPCommCtrlr | HeartbeatInterval | Heartbeat interval in seconds |
OCPPCommCtrlr | NetworkConfigurationPriority | Comma-separated ordered list of configuration slot IDs |
OCPPCommCtrlr | ActiveNetworkProfile | Currently active configuration slot |
OCPPCommCtrlr | NetworkProfileConnectionAttempts | Number of connection attempts per network profile |
OCPPCommCtrlr | OfflineThreshold | Seconds offline before full status report on reconnect |
OCPPCommCtrlr | ItemsPerMessageSetVariables | Max SetVariableData items per message |
OCPPCommCtrlr | ItemsPerMessageGetVariables | Max GetVariableData items per message |
OCPPCommCtrlr | ItemsPerMessageGetReport | Max ComponentVariable items per GetReportRequest |
SecurityCtrlr | SecurityProfile | Currently active security profile (1, 2, or 3) |
SecurityCtrlr | Identity | CS identity for basic auth (deprecated; use NetworkConfiguration) |
SecurityCtrlr | BasicAuthPassword | Basic auth password (WriteOnly) |
SecurityCtrlr | AllowSecurityProfileDowngrade | Allow security profile downgrade (boolean) |
DeviceDataCtrlr | ConfigurationValueSize | Max length of configuration values |
DeviceDataCtrlr | ReportingValueSize | Max length of reported values |
TxCtrlr | TxBeforeAcceptedEnabled | Allow transactions before CS is Accepted |
TxCtrlr | TxResumptionTimeout | Seconds to wait for transaction resumption after ImmediateAndResume reset |
TxCtrlr | TxAllowEnergyTransferResumption | Allow energy transfer on resumed transactions |