Diagnostics — CSMS Developer Guide
Based on OCPP 2.1 Edition 2 Specification (Part 2), Section N (Diagnostics). This guide covers all diagnostics flows (N01–N15), including logging, monitoring configuration, alert and periodic events, customer data management, and periodic event streams from the CSMS perspective.
1. Overview
IntroductionThe Diagnostics functional block enables remote diagnostics of problems with a Charging Station. It covers logging, monitoring configuration, event notifications, customer data management, and high-frequency periodic event streams. All flows are described from the CSMS (Charging Station Management System) developer perspective.
Functional Areas
Logging (N01)
Requesting and receiving diagnostic/security log files from Charging Stations via file upload.
Monitoring Config (N02–N06)
Setting up, querying, and clearing variable monitors on Charging Stations including threshold, delta, and periodic monitors.
Monitoring Events (N07–N08)
Receiving alert and periodic event notifications from Charging Stations when thresholds are exceeded or intervals elapsed.
Customer Information (N09–N10)
Retrieving and clearing customer-related data from Charging Stations for privacy compliance (GDPR).
Periodic Event Streams (N11–N15)
New in OCPP 2.1: High-frequency periodic monitoring data via efficient unconfirmed SEND messages for reduced overhead.
Message Direction Legend
| Direction | Meaning |
|---|---|
| CSMS → CS | CSMS sends a request to the Charging Station |
| CS → CSMS | Charging Station sends a request to the CSMS |
2. N01 — Retrieve Log Information
CSMS-InitiatedRequest a Charging Station to upload a file with log information (diagnostics, security, or data collector logs) to a given URL.
| Use Case ID | N01 |
| Direction | CSMS → CS (CSMS initiates) |
| Trigger | Operator requests log file from a Charging Station |
| OCPP Messages | GetLogRequest/Response, LogStatusNotificationRequest/Response |
Flow Diagram
CSMS Charging Station
| |
| GetLogRequest(logType, log, requestId) |
|------------------------------------------->|
| |
| GetLogResponse(status, filename) |
|<-------------------------------------------|
| |
| [CS uploads log file...] |
| |
| LogStatusNotificationRequest(Uploading) |
|<-------------------------------------------|
| LogStatusNotificationResponse() |
|------------------------------------------->|
| |
| LogStatusNotificationRequest(Uploaded) |
|<-------------------------------------------|
| LogStatusNotificationResponse() |
|------------------------------------------->|Step 1: Send GetLogRequest
{
"logType": "DiagnosticsLog",
"requestId": 123,
"log": {
"remoteLocation": "https://logs.example.com/upload/station-001/",
"oldestTimestamp": "2025-01-01T00:00:00Z",
"latestTimestamp": "2025-12-01T23:59:59Z"
},
"retries": 3,
"retryInterval": 60
}| Field | Type | Required | Description |
|---|---|---|---|
logType | LogEnumType | Yes | Type of log to retrieve |
requestId | integer | Yes | Unique ID for this request. Used to correlate subsequent LogStatusNotificationRequest messages |
log | LogParametersType | Yes | Log upload parameters |
log.remoteLocation | string (max 2000) | Yes | URL where the CS should upload the log file |
log.oldestTimestamp | dateTime | No | Only include log entries from this time onwards |
log.latestTimestamp | dateTime | No | Only include log entries up to this time |
retries | integer (>= 0) | No | Number of upload retry attempts. 0 = no retries. Omit to let CS decide |
retryInterval | integer | No | Seconds between retry attempts. Omit to let CS decide |
LogEnumType Values
| Value | Description |
|---|---|
DiagnosticsLog | Request the Charging Station's diagnostics log |
SecurityLog | Request the Charging Station's security log |
DataCollectorLog | Request the DataCollector log (high-frequency measurand samples) |
CSMS Implementation Notes
- Generate a unique requestId per request. Track this ID to correlate with
incoming
LogStatusNotificationRequestmessages. - [N01.FR.26-28] URL requirements: The upload URL MUST NOT point to a server that responds with a redirect. The URL MUST NOT contain a fragment component (#). If the URL includes a query component, it MUST NOT end with a slash (/).
- [N01.FR.14] Recommended transport: Use HTTP(S) URLs. FTP is also supported.
- [N01.FR.17] HTTP Basic Auth: Use a different password than the one used for
OCPP connectivity. Embed credentials in the URL:
https://user:[email protected]/upload/. - [N01.FR.18] Accept both PUT and POST for log file uploads.
- If a previous log upload is in progress and you send a new
GetLogRequest, the CS SHOULD cancel the ongoing upload and respond with statusAcceptedCanceled.
Step 2: Handle GetLogResponse
{
"status": "Accepted",
"filename": "diagnostics_20250601_station001.zip"
}| Field | Type | Required | Description |
|---|---|---|---|
status | LogStatusEnumType | Yes | Whether the CS accepted the request |
filename | string (max 255) | No | Name of the file that will be uploaded. Absent if no log info available |
statusInfo | StatusInfoType | No | Additional status information |
| Status Value | CSMS Action |
|---|---|
Accepted | Log is available. Expect LogStatusNotificationRequest messages to follow. Store the filename for tracking. |
Rejected | Log information is not available. No upload will happen. |
AcceptedCanceled | Previous upload was canceled, new request accepted. |
Step 3: Handle LogStatusNotificationRequest
The Charging Station sends status updates during log upload. The CSMS must handle these incoming requests.
{
"status": "Uploading",
"requestId": 123
}| Status Value | Meaning | CSMS Action |
|---|---|---|
Uploading | Upload in progress | Log state as "in progress". May receive multiple times (retry attempts). |
Uploaded | Upload completed successfully | Mark upload as complete. Retrieve the file from the upload URL. |
UploadFailure | Upload failed | Mark as failed. All retries exhausted. Check statusInfo for details. |
BadMessage | Malformed request | Investigate CSMS-side issue with the upload URL or parameters. |
PermissionDenied | Auth/permission error | Check upload server credentials and permissions. |
NotSupportedOperation | Operation not supported | Log the error. The CS does not support this log type. |
AcceptedCanceled | Upload canceled | Previous upload was superseded. |
Idle | No upload in progress | Informational only. |
Always respond with an empty LogStatusNotificationResponse:
{} This is an acknowledgment message with no required fields (only optional customData).
3. N02 — Get Monitoring Report
CSMS-InitiatedRequest a report about configured monitoring settings per component and variable from a Charging Station.
| Use Case ID | N02 |
| Direction | CSMS → CS (CSMS initiates) |
| Trigger | Operator or system needs to query current monitoring configuration |
| OCPP Messages | GetMonitoringReportRequest/Response, NotifyMonitoringReportRequest/Response |
Flow Diagram
CSO CSMS Charging Station
| | |
| request | |
|----------->| |
| | GetMonitoringReportRequest |
| |--------------------------------------->|
| | |
| | GetMonitoringReportResponse(status) |
| |<---------------------------------------|
| | |
| | [loop] NotifyMonitoringReportRequest |
| |<---------------------------------------|
| | NotifyMonitoringReportResponse() |
| |--------------------------------------->|
| | ... (repeated for each part) |Step 1: Send GetMonitoringReportRequest
{
"requestId": 42,
"monitoringCriteria": ["ThresholdMonitoring", "DeltaMonitoring"],
"componentVariable": [
{
"component": { "name": "EVSE", "evse": { "id": 1 } },
"variable": { "name": "Temperature" }
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
requestId | integer | Yes | Unique ID for correlating response reports |
monitoringCriteria | array of MonitoringCriterionEnumType (max 3) | No | Filter by monitor type category |
componentVariable | array of ComponentVariableType (min 1) | No | Filter by specific components/variables |
MonitoringCriterionEnumType Values
| Value | Reports Monitors of Type |
|---|---|
ThresholdMonitoring | UpperThreshold, LowerThreshold |
DeltaMonitoring | Delta, TargetDelta, TargetDeltaRelative |
PeriodicMonitoring | Periodic, PeriodicClockAligned |
Filtering Behavior
- If both filters are provided: report monitors matching BOTH.
- If only
monitoringCriteriais provided: report all monitors matching the criteria. - If only
componentVariableis provided: report all monitors for those components/variables. - If neither is provided: report ALL existing monitors.
- Max items in
componentVariableis limited by theItemsPerMessageGetReportConfiguration Variable.
ComponentVariable Expansion Rules
- Missing variable: Reports every variable of the component.
- Missing instance on variable: Reports every instance of that variable.
- Missing evse.connectorId: Reports for every connector of that EVSE.
- Missing evse.id: Reports for every EVSE.
- Specified component.instance: Reports only components with that instance name.
- Missing component.instance: Reports every instance field or components without an instance.
Step 2: Handle GetMonitoringReportResponse
{
"status": "Accepted"
}| Status Value | CSMS Action |
|---|---|
Accepted | Expect NotifyMonitoringReportRequest messages to follow |
Rejected | Request was rejected |
NotSupported | The provided monitoringCriteria is not supported |
EmptyResultSet | No monitors match the filter criteria. No report messages will follow |
Step 3: Handle NotifyMonitoringReportRequest
This is the core data payload. The CS sends one or more of these messages containing the monitoring report.
{
"requestId": 42,
"seqNo": 0,
"generatedAt": "2025-06-01T12:00:00Z",
"tbc": true,
"monitor": [
{
"component": { "name": "EVSE", "evse": { "id": 1 } },
"variable": { "name": "Temperature" },
"variableMonitoring": [
{
"id": 1,
"transaction": false,
"value": 60.0,
"type": "UpperThreshold",
"severity": 4,
"eventNotificationType": "PreconfiguredMonitor"
}
]
}
]
}MonitorEnumType Values
| Value | Description |
|---|---|
UpperThreshold | Triggers when value exceeds threshold |
LowerThreshold | Triggers when value drops below threshold |
Delta | Triggers when value changes by more than +/- delta |
Periodic | Triggers every N seconds |
PeriodicClockAligned | Triggers every N seconds, aligned to clock |
TargetDelta | Triggers when actual differs from target by more than +/- value |
TargetDeltaRelative | Triggers when actual differs from target by more than +/- (value * target) |
EventNotificationEnumType Values
| Value | Description |
|---|---|
HardWiredNotification | Built-in notification (not from a monitor) |
HardWiredMonitor | Built into firmware, cannot be changed |
PreconfiguredMonitor | Factory default, can be enabled/disabled |
CustomMonitor | Set by CSMS via SetVariableMonitoringRequest |
CSMS Implementation Notes
- Reassemble multi-part reports: Collect all messages where
tbc= true, ordered byseqNo. - Store the full monitoring map: Build a map of component/variable → [monitors] for the Charging Station.
seqNostarts at 0 and increments for each report part.
Always respond with an empty NotifyMonitoringReportResponse:
{}4. N03 — Set Monitoring Base
CSMS-InitiatedActivate a set of preconfigured monitoring settings on a Charging Station.
| Use Case ID | N03 |
| Direction | CSMS → CS (CSMS initiates) |
| Trigger | Operator wants to activate a monitoring base preset |
| OCPP Messages | SetMonitoringBaseRequest/Response |
CSMS Charging Station
| |
| SetMonitoringBaseRequest(monitoringBase) |
|------------------------------------------------->|
| |
| SetMonitoringBaseResponse(status) |
|<-------------------------------------------------|Step 1: Send SetMonitoringBaseRequest
{
"monitoringBase": "All"
}| Field | Type | Required | Description |
|---|---|---|---|
monitoringBase | MonitoringBaseEnumType | Yes | Which monitoring base to activate |
MonitoringBaseEnumType Values and Effects
| Value | Effect on Charging Station |
|---|---|
All | Activate all pre-configured monitors. Leave existing custom monitors intact (including custom monitors that replaced pre-configured ones). |
FactoryDefault | Re-activate all PreconfiguredMonitor monitors. Delete all custom monitors. |
HardWiredOnly | Deactivate all pre-configured monitors. Delete all custom monitors. Only HardWiredMonitor monitors remain active. |
Step 2: Handle SetMonitoringBaseResponse
{
"status": "Accepted"
}| Status Value | CSMS Action |
|---|---|
Accepted | Monitoring base was set successfully |
NotSupported | The requested monitoring base is not supported |
Rejected | Request was rejected |
EmptyResultSet | N/A for this use case |
CSMS Implementation Notes
- After setting the monitoring base, it is recommended to send a
GetMonitoringReportRequest(N02) to get the current state of all monitors. - Use
FactoryDefaultto clean up a station and start fresh. - Use
HardWiredOnlyto reduce monitoring to the bare minimum.
5. N04 — Set Variable Monitoring
CSMS-InitiatedSet monitoring triggers on specific variables of a Charging Station. Supports threshold, delta, and periodic monitors.
| Use Case ID | N04 |
| Direction | CSMS → CS (CSMS initiates) |
| Trigger | Operator wants to set monitoring triggers on a Charging Station |
| OCPP Messages | SetVariableMonitoringRequest/Response |
CSMS Charging Station
| |
| SetVariableMonitoringRequest(setMonitoringData[]) |
|------------------------------------------------------>|
| |
| SetVariableMonitoringResponse(setMonitoringResult[]) |
|<------------------------------------------------------|Step 1: Send SetVariableMonitoringRequest
Example: Set a new upper threshold monitor
{
"setMonitoringData": [
{
"value": 60.0,
"type": "UpperThreshold",
"severity": 4,
"component": { "name": "EVSE", "evse": { "id": 1 } },
"variable": { "name": "Temperature" },
"transaction": false
}
]
}Example: Replace an existing monitor (by id)
{
"setMonitoringData": [
{
"id": 5,
"value": 70.0,
"type": "UpperThreshold",
"severity": 3,
"component": { "name": "EVSE", "evse": { "id": 1 } },
"variable": { "name": "Temperature" }
}
]
}Example: Set a periodic monitor with event stream (N11)
{
"setMonitoringData": [
{
"value": 1.0,
"type": "Periodic",
"severity": 8,
"component": { "name": "EVSE", "evse": { "id": 1 } },
"variable": { "name": "Power.Active.Import" },
"periodicEventStream": {
"interval": 60,
"values": 60
}
}
]
}SetMonitoringDataType Structure
| Field | Type | Required | Description |
|---|---|---|---|
value | number | Yes | Threshold/delta value, or interval in seconds for periodic monitors |
type | MonitorEnumType | Yes | Monitor type (see N02 for enum values) |
severity | integer (0-9) | Yes | Event severity level |
component | ComponentType | Yes | Target component |
variable | VariableType | Yes | Target variable |
id | integer (>= 0) | No | Provide ONLY to replace an existing monitor. Omit for new monitors |
transaction | boolean | No | true = active only during transactions. Default: false |
periodicEventStream | PeriodicEventStreamParamsType | No | Parameters for periodic event streaming (see N11) |
PeriodicEventStreamParamsType
| Field | Type | Required | Description |
|---|---|---|---|
interval | integer (>= 0) | No | Seconds between stream data flushes |
values | integer (>= 0) | No | Number of items per stream flush |
Step 2: Handle SetVariableMonitoringResponse
{
"setMonitoringResult": [
{
"status": "Accepted",
"id": 10,
"type": "UpperThreshold",
"severity": 4,
"component": { "name": "EVSE", "evse": { "id": 1 } },
"variable": { "name": "Temperature" }
}
]
}SetMonitoringStatusEnumType Values
| Value | Meaning | CSMS Action |
|---|---|---|
Accepted | Monitor set/replaced | Store the returned id for future reference |
UnknownComponent | Component missing | Check the component name/EVSE ID |
UnknownVariable | Variable missing | Check the variable name |
UnsupportedMonitorType | Not supported | Try a different monitor type |
Rejected | Value out of range, etc. | Check statusInfo for details |
Duplicate | Same type+severity exists | Use a different severity or modify existing |
CSMS Implementation Notes
- Response has 1:1 mapping: Each SetMonitoringResult corresponds to a SetMonitoringData element, matching on component + variable.
- Store monitor IDs: When status = Accepted, store the returned
id. You need it for ClearVariableMonitoringRequest (N06) and for replacing monitors. - Replacing monitors: To modify an existing monitor, provide the
id. The CS will reject if the component/variable combination does not match the existing monitor [N04.FR.16]. - Cannot change hardwired monitors: Sending an id that refers to a HardWiredMonitor will be rejected [N04.FR.18].
- After reboot: IDs may change. Send a GetMonitoringReportRequest to refresh your ID mapping [N04.FR.19].
- Replaced PreconfiguredMonitor becomes CustomMonitor: A replaced monitor is reclassified as CustomMonitor until reset by SetMonitoringBaseRequest [N04.FR.15].
- Max items per request is limited by
ItemsPerMessageSetVariableMonitoringandBytesPerMessageSetVariableMonitoringConfiguration Variables. - Recommended for Delta on non-numeric: Use value of 1 (triggers on every change).
- Delta with value 0: The CS SHOULD reject this.
- Negative Delta values: The CS SHALL reject these.
- When providing a
periodicEventStream, you MUST provide a value for interval or values or both [N11.FR.09].
6. N05 — Set Monitoring Level
CSMS-InitiatedRestrict the severity level of monitoring events reported by the Charging Station. Only events
with severity number <= the set level will be reported via NotifyEventRequest.
| Use Case ID | N05 |
| Direction | CSMS → CS (CSMS initiates) |
| Trigger | Operator wants to filter monitoring events by severity |
| OCPP Messages | SetMonitoringLevelRequest/Response |
CSMS Charging Station
| |
| SetMonitoringLevelRequest(severity) |
|------------------------------------------------->|
| |
| SetMonitoringLevelResponse(status) |
|<-------------------------------------------------|Severity Scale
| Level | Name | Meaning |
|---|---|---|
| 0 | Danger | Lives potentially in danger. Immediate action needed |
| 1 | Hardware Failure | Unable to operate due to hardware. Action required |
| 2 | System Failure | Unable to operate due to software/minor HW. Action required |
| 3 | Critical | Critical error. Action required |
| 4 | Error | Non-urgent error. Action required |
| 5 | Alert | Default severity. Alert event |
| 6 | Warning | May require action |
| 7 | Notice | Unusual event. No immediate action |
| 8 | Informational | Regular operational event |
| 9 | Debug | Developer debugging info |
Example: Setting severity = 4 means the CS will only report events with severity 0, 1, 2, 3, or 4 (Danger through Error). Events with severity 5–9 (Alert through Debug) will be suppressed.
Step 1: Send SetMonitoringLevelRequest
{
"severity": 5
}| Field | Type | Required | Description |
|---|---|---|---|
severity | integer (>= 0) | Yes | Maximum severity level to report. Range 0-9 |
Step 2: Handle SetMonitoringLevelResponse
{
"status": "Accepted"
}| Status Value | CSMS Action |
|---|---|
Accepted | Level was set successfully |
Rejected | Severity value is out of range |
7. N06 — Clear / Remove Monitoring
CSMS-InitiatedRemove monitoring settings from a Charging Station by monitor ID.
| Use Case ID | N06 |
| Direction | CSMS → CS (CSMS initiates) |
| Trigger | Operator wants to remove monitoring settings |
| OCPP Messages | ClearVariableMonitoringRequest/Response |
CSMS Charging Station
| |
| ClearVariableMonitoringRequest(id[]) |
|-------------------------------------------------------->|
| |
| ClearVariableMonitoringResponse(clearMonitoringResult[])|
|<--------------------------------------------------------|Step 1: Send ClearVariableMonitoringRequest
{
"id": [10, 11, 12]
}| Field | Type | Required | Description |
|---|---|---|---|
id | array of integer (min 1) | Yes | List of monitor IDs to clear |
CSMS Implementation Notes
- [N06.FR.04] Max items per request is limited by
ItemsPerMessageClearVariableMonitoringandBytesPerMessageClearVariableMonitoringConfiguration Variables. - Only provide IDs obtained from
SetVariableMonitoringResponseorNotifyMonitoringReportRequest.
Step 2: Handle ClearVariableMonitoringResponse
{
"clearMonitoringResult": [
{ "id": 10, "status": "Accepted" },
{ "id": 11, "status": "NotFound" },
{ "id": 12, "status": "Rejected" }
]
}| Status Value | Meaning | CSMS Action |
|---|---|---|
Accepted | Monitor removed | Remove from local tracking |
Rejected | Cannot be cleared | Monitor remains active (e.g., hardwired monitor) |
NotFound | ID does not exist | Already removed or ID invalid |
- [N06.FR.06] The CS may respond with
CALLERROR(OccurenceConstraintViolation)if too many IDs are sent. - [N06.FR.07] The CS may respond with
CALLERROR(FormatViolation)if message exceeds byte limit. - [N13.FR.05] Clearing a monitor with an associated periodic event stream will automatically close the stream.
8. N07 — Alert Event
CS-InitiatedHandle event notifications from the Charging Station when monitoring thresholds or delta values are exceeded.
| Use Case ID | N07 |
| Direction | CS → CSMS (CS initiates) |
| Trigger | Monitoring threshold or delta value exceeded on the Charging Station |
| OCPP Messages | NotifyEventRequest/Response |
Flow Diagram
Charging Station CSMS
| |
| [threshold/delta exceeded] |
| |
| [loop] NotifyEventRequest |
|--------------------------------------->|
| NotifyEventResponse() |
|<---------------------------------------|Handle NotifyEventRequest
This is a CS-initiated message that the CSMS must handle.
{
"generatedAt": "2025-06-01T12:00:00Z",
"seqNo": 0,
"tbc": false,
"eventData": [
{
"eventId": 1,
"timestamp": "2025-06-01T11:59:58Z",
"trigger": "Alerting",
"eventNotificationType": "CustomMonitor",
"actualValue": "65.5",
"component": { "name": "EVSE", "evse": { "id": 1 } },
"variable": { "name": "Temperature" },
"variableMonitoringId": 10,
"severity": 4,
"cleared": false
}
]
}EventDataType Structure
| Field | Type | Required | Description |
|---|---|---|---|
eventId | integer (>= 0) | Yes | Unique event identifier |
timestamp | dateTime | Yes | When the event occurred |
trigger | EventTriggerEnumType | Yes | What triggered this event |
eventNotificationType | EventNotificationEnumType | Yes | Type of monitor that triggered this |
actualValue | string (max 2500) | Yes | Current value of the variable |
component | ComponentType | Yes | The component |
variable | VariableType | Yes | The variable |
variableMonitoringId | integer (>= 0) | No | ID of the monitor that triggered this event |
severity | integer (0-9) | No | Severity of the monitor (SHOULD be present) |
cleared | boolean | No | true = condition has returned to normal |
cause | integer (>= 0) | No | eventId of another event that caused this one |
transactionId | string (max 36) | No | If linked to a specific transaction |
techCode | string (max 50) | No | Technical error code from the component |
techInfo | string (max 500) | No | Technical detail information |
EventTriggerEnumType Values
| Value | Description | When |
|---|---|---|
Alerting | Threshold exceeded | UpperThreshold exceeded, LowerThreshold dropped below, TargetDelta/TargetDeltaRelative exceeded |
Delta | Value changed by more than delta | Delta monitor triggered |
Periodic | Periodic interval elapsed | Periodic or PeriodicClockAligned monitor triggered |
CSMS Processing Logic
- Parse all eventData entries in the message.
- For each event:
- Match
variableMonitoringIdto your stored monitor records. - Check the
triggertype:Alerting= threshold breach,Delta= significant change,Periodic= scheduled report. - If
cleared= true: the condition has returned to normal. - If
cleared= false or absent: the condition is currently active.
- Match
- Handle tbc: If true, wait for more messages with the same event chain.
- Correlate cause: If present, link this event to the causing event for root-cause analysis.
- Offline queuing: Events with severity <=
OfflineMonitoringEventQueuingSeverityare queued by the CS when offline and delivered when reconnected. Delay evaluation until the station is back online.
[N07.FR.03] Always respond with an empty NotifyEventResponse:
{}9. N08 — Periodic Event
CS-InitiatedHandle periodic monitoring events. These are the same as N07 but triggered by Periodic or PeriodicClockAligned monitors.
| Use Case ID | N08 |
| Direction | CS → CSMS (CS initiates) |
| Trigger | Periodic or PeriodicClockAligned monitor interval elapsed |
| OCPP Messages | NotifyEventRequest/Response (same as N07) |
Behavior
Periodic events use the exact same NotifyEventRequest / NotifyEventResponse message pair as Alert Events (N07). The differences are:
trigger=Periodic- The CS sends them at the configured interval
seqNostarts at 0 for each periodic firing
CSMS Handling
- Identical to N07, but
triggerwill bePeriodic. seqNostarts at 0 for each periodic firing.- Events are queued during offline if severity <=
OfflineMonitoringEventQueuingSeverity.
[N08.FR.02] Respond with an empty NotifyEventResponse:
{}10. N09 — Get Customer Information
CSMS-InitiatedRetrieve raw customer information stored on a Charging Station (e.g., for privacy compliance like GDPR data subject access requests).
| Use Case ID | N09 |
| Direction | CSMS → CS (CSMS initiates) |
| Trigger | Privacy compliance / GDPR data subject access request |
| OCPP Messages | CustomerInformationRequest/Response, NotifyCustomerInformationRequest/Response |
Flow Diagram
CSMS Charging Station
| |
| CustomerInformationRequest(report=true, clear=false)|
|----------------------------------------------------->|
| |
| CustomerInformationResponse(status) |
|<-----------------------------------------------------|
| |
| [loop] NotifyCustomerInformationRequest(data) |
|<-----------------------------------------------------|
| NotifyCustomerInformationResponse() |
|----------------------------------------------------->|Step 1: Send CustomerInformationRequest
{
"requestId": 100,
"report": true,
"clear": false,
"idToken": {
"idToken": "AABB1122",
"type": "ISO14443"
}
}| Field | Type | Required | Description |
|---|---|---|---|
requestId | integer (>= 0) | Yes | Unique ID for correlating responses |
report | boolean | Yes | true = send back customer data via NotifyCustomerInformationRequest |
clear | boolean | Yes | true = clear customer data from the CS (see N10) |
idToken | IdTokenType | Conditional | Customer reference by IdToken |
customerCertificate | CertificateHashDataType | Conditional | Customer reference by certificate hash |
customerIdentifier | string (max 64) | Conditional | Customer reference by vendor-specific identifier |
Customer Identification Rules [N09.FR.04]
- You MUST provide exactly one of:
idToken,customerCertificate, orcustomerIdentifier. - Providing none or more than one will result in
Invalidresponse from the CS.
CertificateHashDataType Structure
| Field | Type | Required | Description |
|---|---|---|---|
hashAlgorithm | HashAlgorithmEnumType | Yes | SHA256, SHA384, or SHA512 |
issuerNameHash | string (max 128) | Yes | Hash of issuer's distinguished name (DER encoding) |
issuerKeyHash | string (max 128) | Yes | Hash of issuer's public key (DER encoding) |
serialNumber | string (max 40) | Yes | Hex serial number without "0x" prefix or leading zeros |
Validation Rules
- [N09.FR.07] If both
reportandclearare false, the CS is recommended to respond withRejected. - [N09.FR.08] When using
customerCertificate, use the hashAlgorithm that was used to install the certificate. Recommended: First useGetInstalledCertificateIdsRequestto determine the correct algorithm.
Step 2: Handle CustomerInformationResponse
{
"status": "Accepted"
}| Status Value | Meaning | CSMS Action |
|---|---|---|
Accepted | Request accepted | Wait for NotifyCustomerInformationRequest if report = true |
Rejected | Cannot process | Check if both flags are false or CS is busy |
Invalid | Invalid identifier | Fix the request: provide exactly one identifier |
Step 3: Handle NotifyCustomerInformationRequest
{
"data": "Customer AABB1122: Last seen 2025-06-01, Total sessions: 42, ...",
"seqNo": 0,
"generatedAt": "2025-06-01T12:00:00Z",
"requestId": 100,
"tbc": false
}| Field | Type | Required | Description |
|---|---|---|---|
data | string (max 512) | Yes | Customer data (human-readable). Empty if no data found |
seqNo | integer (>= 0) | Yes | Sequence number. First = 0 |
generatedAt | dateTime | Yes | Generation timestamp |
requestId | integer (>= 0) | Yes | Correlates with the original request |
tbc | boolean | No | true = more parts follow. Default: false |
CSMS Implementation Notes
- Reassemble multi-part responses: Concatenate
datafields ordered byseqNo. - Empty data: If the CS has no customer data, it sends a single message with an empty string.
- The data format is not specified — treat as human-readable text.
Always respond with an empty NotifyCustomerInformationResponse:
{}11. N10 — Clear Customer Information
CSMS-InitiatedClear (and optionally retrieve) customer data from a Charging Station (e.g., for GDPR right-to-erasure requests).
| Use Case ID | N10 |
| Direction | CSMS → CS (CSMS initiates) |
| Trigger | GDPR right-to-erasure request or operator-initiated data clear |
| OCPP Messages | CustomerInformationRequest/Response, NotifyCustomerInformationRequest/Response |
Flow Diagram
CSMS Charging Station
| |
| CustomerInformationRequest(clear=true, report=true) |
|-------------------------------------------------------->|
| CustomerInformationResponse(status) |
|<--------------------------------------------------------|
| |
| [opt, if report=true] NotifyCustomerInformationRequest |
|<--------------------------------------------------------|
| NotifyCustomerInformationResponse() |
|-------------------------------------------------------->|
| |
| [CS clears customer data] |Send CustomerInformationRequest
Uses the same message as N09, but with clear = true.
Example: Clear and report (get data before deleting)
{
"requestId": 101,
"report": true,
"clear": true,
"customerIdentifier": "CUST-12345"
}Example: Clear only (no report)
{
"requestId": 102,
"report": false,
"clear": true,
"idToken": {
"idToken": "AABB1122",
"type": "ISO14443"
}
}CSMS Implementation Notes
- Same message/response format as N09.
- When
clear= true andreport= true: CS first sends the data, then clears it. - When
clear= true andreport= false: CS clears data and sends a notification indicating data was cleared. - Customer identifier rules: Same as N09 — exactly one of
idToken,customerCertificate, orcustomerIdentifier. - [N10.FR.09] Use the correct hashAlgorithm when referencing by certificate.
[N10.FR.02] Local Authorization List: If the customer is in the CS's Local
Authorization List, the CSMS SHALL update it via SendLocalListRequest. The CS
will remove customer data except from the LocalList (only the CSMS can change the LocalList).
12. N11 — Set Frequent Periodic Variable Monitoring
CSMS-Initiated New in OCPP 2.1Set up high-frequency periodic monitoring that uses efficient "event streams" instead of
individual NotifyEventRequest messages. This reduces overhead for monitors that fire very frequently (e.g., every second).
| Use Case ID | N11 |
| Direction | CSMS → CS, then CS → CSMS |
| Trigger | Operator wants high-frequency periodic monitoring with efficient streaming |
| OCPP Messages | SetVariableMonitoringRequest/Response, OpenPeriodicEventStreamRequest/Response, NotifyPeriodicEventStream |
Flow Diagram
CSMS Charging Station
| |
| SetVariableMonitoringRequest |
| (with periodicEventStream params) |
|------------------------------------------------------>|
| |
| SetVariableMonitoringResponse(setMonitoringResult) |
|<------------------------------------------------------|
| |
| OpenPeriodicEventStreamRequest(constantStreamData) |
|<------------------------------------------------------|
| OpenPeriodicEventStreamResponse(status) |
|------------------------------------------------------>|
| |
| [loop] NotifyPeriodicEventStream (SEND, no response) |
|<------------------------------------------------------|Step 1: Send SetVariableMonitoringRequest with Event Stream
This uses the same SetVariableMonitoringRequest from N04, but with the periodicEventStream field populated.
{
"setMonitoringData": [
{
"value": 1.0,
"type": "Periodic",
"severity": 8,
"component": { "name": "EVSE", "evse": { "id": 1 } },
"variable": { "name": "Power.Active.Import" },
"periodicEventStream": {
"interval": 60,
"values": 60
}
}
]
}This tells the CS: "Monitor Power.Active.Import every 1 second, and flush the data every 60 seconds or when 60 values accumulate."
Step 2: Handle OpenPeriodicEventStreamRequest
After accepting the monitoring request, the CS opens an event stream by sending this to the CSMS.
{
"constantStreamData": {
"id": 5,
"variableMonitoringId": 10,
"params": {
"interval": 60,
"values": 60
}
}
}ConstantStreamDataType Structure
| Field | Type | Required | Description |
|---|---|---|---|
id | integer (>= 0) | Yes | Unique stream identifier |
variableMonitoringId | integer (>= 0) | Yes | ID of the monitor producing the data |
params | PeriodicEventStreamParamsType | Yes | Flushing parameters |
CSMS Implementation
- Store stream metadata: Map the
idto thevariableMonitoringIdand associated monitor data (component, variable, severity, trigger, eventNotificationType). - [N11.FR.04, N11.FR.08] Associate required NotifyEventRequest fields:
variableMonitoringIdtrigger= PeriodiceventNotificationType(from the monitor)severity(from the monitor)component(from the monitor)variable(from the monitor)
Send OpenPeriodicEventStreamResponse
| Status Value | CSMS Action |
|---|---|
Accepted | [N11.FR.06] Ready to receive NotifyPeriodicEventStream messages. |
Rejected | [N11.FR.05] Unable to process this stream. The CS will revert to regular NotifyEventRequest messages. |
{
"status": "Accepted"
}13. N12 — Get Periodic Event Streams
CSMS-Initiated New in OCPP 2.1Retrieve a list of all currently open periodic event streams from a Charging Station. Useful for recovery when the CSMS has lost its stream tracking state.
| Use Case ID | N12 |
| Direction | CSMS → CS (CSMS initiates) |
| Trigger | CSMS restart/reconnection or state recovery |
| OCPP Messages | GetPeriodicEventStreamRequest/Response |
CSMS Charging Station
| |
| GetPeriodicEventStreamRequest() |
|------------------------------------------------------>|
| |
| GetPeriodicEventStreamResponse(constantStreamData[]) |
|<------------------------------------------------------|Step 1: Send GetPeriodicEventStreamRequest
Empty message (no required fields):
{}Step 2: Handle GetPeriodicEventStreamResponse
{
"constantStreamData": [
{
"id": 5,
"variableMonitoringId": 10,
"params": { "interval": 60, "values": 60 }
},
{
"id": 6,
"variableMonitoringId": 11,
"params": { "interval": 30 }
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
constantStreamData | array of ConstantStreamDataType | No | List of open streams. Empty/absent = no open streams |
CSMS Implementation Notes
- Use this after CSMS restart or reconnection to rebuild the stream tracking state.
- For each returned stream, re-associate the constant metadata (component, variable, severity, etc.) from the
variableMonitoringId.
14. N13 — Close Periodic Event Streams
CS-Initiated New in OCPP 2.1Handle a Charging Station closing a periodic event stream, or indirectly close one by clearing the associated monitor.
| Use Case ID | N13 |
| Direction | CS → CSMS (CS initiates) or indirect via CSMS actions |
| Trigger | CS closes stream, or CSMS clears/replaces associated monitor |
| OCPP Messages | ClosePeriodicEventStreamRequest/Response |
Scenario 1: CS Closes a Stream
Charging Station CSMS
| |
| [flush remaining buffered data] |
| NotifyPeriodicEventStream |
|---------------------------------------->|
| |
| ClosePeriodicEventStreamRequest(id) |
|---------------------------------------->|
| ClosePeriodicEventStreamResponse() |
|<----------------------------------------|
| |
| [reverts to NotifyEventRequest] |{
"id": 5
}CSMS Implementation
- Stop expecting
NotifyPeriodicEventStreammessages for this streamid. - Remove the stream from tracking.
- The CS will revert to sending regular
NotifyEventRequestmessages for the associated variable.
Always respond with an empty ClosePeriodicEventStreamResponse:
{}Scenario 2: CSMS Clears a Monitor (Indirect Close)
When the CSMS sends a ClearVariableMonitoringRequest (N06) for a monitor that has an associated periodic event stream:
- The CS clears the monitor.
- [N13.FR.05] The CS automatically closes the associated periodic event stream.
- The CS sends
ClosePeriodicEventStreamRequestto the CSMS.
Scenario 3: CSMS Replaces a Monitor Without Stream (Indirect Close)
When the CSMS sends a SetVariableMonitoringRequest (N04) with an id matching an
existing monitor that has a periodic event stream, but the new request does NOT include a periodicEventStream element:
- The CS replaces the monitor (without the stream).
- [N13.FR.06] The CS closes the associated periodic event stream.
- The CS sends
ClosePeriodicEventStreamRequestto the CSMS.
15. N14 — Adjust Periodic Event Streams
CSMS-Initiated New in OCPP 2.1Adjust the transmission rate (interval/values parameters) of an existing periodic event stream.
| Use Case ID | N14 |
| Direction | CSMS → CS (CSMS initiates) |
| Trigger | Stream backlog growing (pending count increasing) or operator adjustment |
| OCPP Messages | AdjustPeriodicEventStreamRequest/Response |
CSMS Charging Station
| |
| AdjustPeriodicEventStreamRequest(id, params) |
|--------------------------------------------------------->|
| |
| AdjustPeriodicEventStreamResponse(status) |
|<---------------------------------------------------------|Step 1: Send AdjustPeriodicEventStreamRequest
{
"id": 5,
"params": {
"interval": 30,
"values": 30
}
}| Field | Type | Required | Description |
|---|---|---|---|
id | integer (>= 0) | Yes | ID of the event stream to adjust |
params | PeriodicEventStreamParamsType | Yes | New flushing parameters |
CSMS Implementation Notes
Use this when pending values in NotifyPeriodicEventStream messages are growing [N15.FR.05], indicating the CS is producing data faster than it can send.
Consider increasing interval or values to allow larger or
more frequent flushes.
Step 2: Handle AdjustPeriodicEventStreamResponse
{
"status": "Accepted"
}| Status Value | Meaning |
|---|---|
Accepted | Parameters adjusted. CS will change the flushing rate accordingly |
Rejected | CS cannot comply with the new parameters |
16. N15 — Periodic Event Streams (NotifyPeriodicEventStream)
CS-Initiated New in OCPP 2.1Process the high-frequency periodic monitoring data sent by the Charging Station via the
efficient NotifyPeriodicEventStream SEND message.
| Use Case ID | N15 |
| Direction | CS → CSMS (no response) |
| Trigger | Periodic event stream flush interval or value count reached |
| OCPP Messages | NotifyPeriodicEventStream (SEND message — no response) |
Key Protocol Detail
NotifyPeriodicEventStream uses the RPC framework message type "SEND" — an unconfirmed message. This means:
- The CSMS does NOT send any response (no CALLRESULT, no CALLERROR).
- The CS can send these at any time without waiting for a previous CALL response.
- Uses the same WebSocket connection as CALL/CALLRESULT.
Handle NotifyPeriodicEventStream
{
"id": 5,
"basetime": "2025-06-01T12:00:00Z",
"pending": 0,
"data": [
{ "t": 0, "v": "3520.5" },
{ "t": 1.0, "v": "3521.2" },
{ "t": 2.0, "v": "3519.8" },
{ "t": 3.0, "v": "3522.1" }
]
}| Field | Type | Required | Description |
|---|---|---|---|
id | integer (>= 0) | Yes | Stream ID (from OpenPeriodicEventStreamRequest) |
basetime | dateTime | Yes | Base timestamp. basetime + t = actual timestamp of each value |
pending | integer (>= 0) | Yes | Number of data elements still pending to be sent |
data | array of StreamDataElementType | Yes | The data values |
StreamDataElementType Structure
| Field | Type | Required | Description |
|---|---|---|---|
t | number | Yes | Time offset in seconds relative to basetime. First value's t is always 0 |
v | string (max 2500) | Yes | The measured value |
CSMS Processing Logic
- Look up stream metadata using
idto find the associated:variableMonitoringIdcomponentandvariableseverityeventNotificationTypetrigger(= Periodic)
- Reconstruct full event data for each StreamDataElementType:
For each element in data: timestamp = basetime + t (seconds) actualValue = v // Combine with stored constant data to produce // equivalent NotifyEventRequest eventData
- Process as equivalent to NotifyEventRequest: Use the same processing pipeline as for regular events. The only missing field is
eventId— the CSMS can assign its own. - [N15.FR.05] Monitor pending: If
pendingis growing across successive messages, the CS is producing data faster than it can flush. Consider usingAdjustPeriodicEventStreamRequest(N14) to adjust parameters. - No response needed: Do NOT send any response to this message.
- Error handling: The only way for the CSMS to stop a periodic event stream is to clear the associated monitor via
ClearVariableMonitoringRequest(N06).
17. Message Direction Summary
ReferenceMessages the CSMS Initiates (CSMS → CS)
| Message | Use Case | Purpose |
|---|---|---|
GetLogRequest | N01 | Request log file upload |
GetMonitoringReportRequest | N02 | Request monitoring report |
SetMonitoringBaseRequest | N03 | Set monitoring base preset |
SetVariableMonitoringRequest | N04, N11 | Set/replace individual monitors |
SetMonitoringLevelRequest | N05 | Set severity filter |
ClearVariableMonitoringRequest | N06 | Remove monitors by ID |
CustomerInformationRequest | N09, N10 | Get/clear customer data |
GetPeriodicEventStreamRequest | N12 | List open event streams |
AdjustPeriodicEventStreamRequest | N14 | Adjust stream parameters |
Messages the CSMS Must Handle (CS → CSMS)
| Incoming Message | Response to Send | Use Case |
|---|---|---|
LogStatusNotificationRequest | LogStatusNotificationResponse (empty) | N01 — Log upload status |
NotifyMonitoringReportRequest | NotifyMonitoringReportResponse (empty) | N02 — Monitoring report data |
NotifyEventRequest | NotifyEventResponse (empty) | N07, N08 — Alert/periodic events |
NotifyCustomerInformationRequest | NotifyCustomerInformationResponse (empty) | N09, N10 — Customer data |
OpenPeriodicEventStreamRequest | OpenPeriodicEventStreamResponse (Accepted/Rejected) | N11 — Open event stream |
ClosePeriodicEventStreamRequest | ClosePeriodicEventStreamResponse (empty) | N13 — Close event stream |
NotifyPeriodicEventStream | No response (SEND message) | N15 — Stream data |
18. Shared Data Types Reference
ReferenceStatusInfoType
Provides additional detail about status responses.
{
"type": "object",
"required": ["reasonCode"],
"properties": {
"reasonCode": { "type": "string", "maxLength": 20, "description": "Predefined code (case-insensitive)" },
"additionalInfo": { "type": "string", "maxLength": 1024, "description": "Human-readable additional detail" }
}
}ComponentType
Identifies a physical or logical component.
{
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "maxLength": 50, "description": "Component name (case-insensitive, CamelCase recommended)" },
"instance": { "type": "string", "maxLength": 50, "description": "Instance name when component has multiple instances" },
"evse": {
"type": "object",
"required": ["id"],
"properties": {
"id": { "type": "integer", "minimum": 0, "description": "EVSE identifier" },
"connectorId": { "type": "integer", "minimum": 0, "description": "Connector index on the EVSE" }
}
}
}
}VariableType
{
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "maxLength": 50, "description": "Variable name (case-insensitive, CamelCase recommended)" },
"instance": { "type": "string", "maxLength": 50, "description": "Instance name" }
}
}IdTokenType
{
"type": "object",
"required": ["idToken", "type"],
"properties": {
"idToken": { "type": "string", "maxLength": 255, "description": "The token value (case-insensitive)" },
"type": { "type": "string", "maxLength": 20, "description": "Token type (e.g., ISO14443, ISO15693, eMAID, etc.)" },
"additionalInfo": { "type": "array", "description": "Extra authorization info" }
}
}Severity Levels Quick Reference
| Level | Name | Action |
|---|---|---|
| 0 | Danger | Immediate action — lives at risk |
| 1 | Hardware Failure | Action required — HW failure |
| 2 | System Failure | Action required — SW failure |
| 3 | Critical | Action required |
| 4 | Error | Action required (non-urgent) |
| 5 | Alert | Default severity |
| 6 | Warning | Action may be required |
| 7 | Notice | No immediate action |
| 8 | Informational | Operational reporting |
| 9 | Debug | Developer debugging |
Relevant Configuration Variables
| Variable | Affects |
|---|---|
ItemsPerMessageGetReport | Max componentVariable items in GetMonitoringReportRequest |
ItemsPerMessageSetVariableMonitoring | Max setMonitoringData items in SetVariableMonitoringRequest |
BytesPerMessageSetVariableMonitoring | Max bytes for SetVariableMonitoringRequest |
ItemsPerMessageClearVariableMonitoring | Max id items in ClearVariableMonitoringRequest |
BytesPerMessageClearVariableMonitoring | Max bytes for ClearVariableMonitoringRequest |
OfflineMonitoringEventQueuingSeverity | Severity threshold for offline event queuing |
FileTransferProtocols | Supported upload protocols (CS reports this) |